-
Notifications
You must be signed in to change notification settings - Fork 3.8k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat!: implement basic core API genesis source and target (#14329)
- Loading branch information
Showing
4 changed files
with
152 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,31 @@ | ||
package genesis | ||
|
||
import ( | ||
"bytes" | ||
"encoding/json" | ||
"io" | ||
|
||
"cosmossdk.io/core/appmodule" | ||
) | ||
|
||
// SourceFromRawJSON returns a genesis source based on a raw JSON message. | ||
func SourceFromRawJSON(message json.RawMessage) (appmodule.GenesisSource, error) { | ||
var m map[string]json.RawMessage | ||
err := json.Unmarshal(message, &m) | ||
if err != nil { | ||
return nil, err | ||
} | ||
return func(field string) (io.ReadCloser, error) { | ||
j, ok := m[field] | ||
if !ok { | ||
return nil, nil | ||
} | ||
return readCloserWrapper{bytes.NewReader(j)}, nil | ||
}, nil | ||
} | ||
|
||
type readCloserWrapper struct { | ||
io.Reader | ||
} | ||
|
||
func (r readCloserWrapper) Close() error { return nil } |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,44 @@ | ||
package genesis | ||
|
||
import ( | ||
"encoding/json" | ||
"io" | ||
"testing" | ||
|
||
"github.com/stretchr/testify/require" | ||
|
||
"cosmossdk.io/core/appmodule" | ||
) | ||
|
||
func TestSource(t *testing.T) { | ||
source, err := SourceFromRawJSON(json.RawMessage(testJSON)) | ||
require.NoError(t, err) | ||
|
||
expectJSON(t, source, "foo", fooContents) | ||
expectJSON(t, source, "bar", barContents) | ||
|
||
// missing fields just return nil, nil | ||
r, err := source("baz") | ||
require.NoError(t, err) | ||
require.Nil(t, r) | ||
} | ||
|
||
func expectJSON(t *testing.T, source appmodule.GenesisSource, field, contents string) { | ||
r, err := source(field) | ||
require.NoError(t, err) | ||
bz, err := io.ReadAll(r) | ||
require.NoError(t, err) | ||
require.Equal(t, contents, string(bz)) | ||
|
||
} | ||
|
||
const ( | ||
testJSON = ` | ||
{ | ||
"foo":{"x":1,"y":"abc"}, | ||
"bar":[1,2,3,4] | ||
} | ||
` | ||
fooContents = `{"x":1,"y":"abc"}` | ||
barContents = `[1,2,3,4]` | ||
) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,44 @@ | ||
package genesis | ||
|
||
import ( | ||
"bytes" | ||
"encoding/json" | ||
"io" | ||
|
||
"cosmossdk.io/core/appmodule" | ||
) | ||
|
||
// RawJSONTarget returns a struct which encapsulates a genesis target that is | ||
// backed by raw JSON messages. Its Target method should be used to retrieve | ||
// an actual genesis target function. When genesis writing is done, the JSON | ||
// method should be called to retrieve the raw message that has been written. | ||
type RawJSONTarget struct { | ||
m map[string]json.RawMessage | ||
} | ||
|
||
// Target returns the actual genesis target function. | ||
func (r *RawJSONTarget) Target() appmodule.GenesisTarget { | ||
return func(field string) (io.WriteCloser, error) { | ||
if r.m == nil { | ||
r.m = map[string]json.RawMessage{} | ||
} | ||
|
||
return &genesisWriter{Buffer: &bytes.Buffer{}, sink: r, field: field}, nil | ||
} | ||
} | ||
|
||
// JSON returns the raw JSON message that has been written. | ||
func (r *RawJSONTarget) JSON() (json.RawMessage, error) { | ||
return json.MarshalIndent(r.m, "", " ") | ||
} | ||
|
||
type genesisWriter struct { | ||
*bytes.Buffer | ||
field string | ||
sink *RawJSONTarget | ||
} | ||
|
||
func (r genesisWriter) Close() error { | ||
r.sink.m[r.field] = r.Buffer.Bytes() | ||
return nil | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,33 @@ | ||
package genesis | ||
|
||
import ( | ||
"testing" | ||
|
||
"github.com/stretchr/testify/require" | ||
) | ||
|
||
func TestTarget(t *testing.T) { | ||
target := &RawJSONTarget{} | ||
|
||
w, err := target.Target()("foo") | ||
require.NoError(t, err) | ||
_, err = w.Write([]byte("1")) | ||
require.NoError(t, err) | ||
require.NoError(t, w.Close()) | ||
|
||
w, err = target.Target()("bar") | ||
require.NoError(t, err) | ||
_, err = w.Write([]byte(`"abc"`)) | ||
require.NoError(t, err) | ||
require.NoError(t, w.Close()) | ||
|
||
bz, err := target.JSON() | ||
require.NoError(t, err) | ||
|
||
// test that it's correct by reading back with a source | ||
source, err := SourceFromRawJSON(bz) | ||
require.NoError(t, err) | ||
|
||
expectJSON(t, source, "foo", "1") | ||
expectJSON(t, source, "bar", `"abc"`) | ||
} |