Skip to content

Commit

Permalink
feat!: implement basic core API genesis source and target (#14329)
Browse files Browse the repository at this point in the history
  • Loading branch information
aaronc authored Jan 5, 2023
1 parent 701aaa8 commit 5d62366
Show file tree
Hide file tree
Showing 4 changed files with 152 additions and 0 deletions.
31 changes: 31 additions & 0 deletions core/genesis/source.go
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 }
44 changes: 44 additions & 0 deletions core/genesis/source_test.go
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]`
)
44 changes: 44 additions & 0 deletions core/genesis/target.go
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
}
33 changes: 33 additions & 0 deletions core/genesis/target_test.go
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"`)
}

0 comments on commit 5d62366

Please sign in to comment.