forked from TrueCloudLab/neoneo-go
state: implement JSON marshaling for MPT* items
This commit is contained in:
parent
24785f1f50
commit
5794bdb169
2 changed files with 87 additions and 7 deletions
|
@ -1,6 +1,9 @@
|
||||||
package state
|
package state
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"encoding/json"
|
||||||
|
"errors"
|
||||||
|
|
||||||
"github.com/nspcc-dev/neo-go/pkg/core/transaction"
|
"github.com/nspcc-dev/neo-go/pkg/core/transaction"
|
||||||
"github.com/nspcc-dev/neo-go/pkg/crypto/hash"
|
"github.com/nspcc-dev/neo-go/pkg/crypto/hash"
|
||||||
"github.com/nspcc-dev/neo-go/pkg/io"
|
"github.com/nspcc-dev/neo-go/pkg/io"
|
||||||
|
@ -9,16 +12,16 @@ import (
|
||||||
|
|
||||||
// MPTRootBase represents storage state root.
|
// MPTRootBase represents storage state root.
|
||||||
type MPTRootBase struct {
|
type MPTRootBase struct {
|
||||||
Version byte
|
Version byte `json:"version"`
|
||||||
Index uint32
|
Index uint32 `json:"index"`
|
||||||
PrevHash util.Uint256
|
PrevHash util.Uint256 `json:"prehash"`
|
||||||
Root util.Uint256
|
Root util.Uint256 `json:"stateroot"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// MPTRoot represents storage state root together with sign info.
|
// MPTRoot represents storage state root together with sign info.
|
||||||
type MPTRoot struct {
|
type MPTRoot struct {
|
||||||
MPTRootBase
|
MPTRootBase
|
||||||
Witness *transaction.Witness
|
Witness *transaction.Witness `json:"witness,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// MPTRootStateFlag represents verification state of the state root.
|
// MPTRootStateFlag represents verification state of the state root.
|
||||||
|
@ -33,8 +36,8 @@ const (
|
||||||
|
|
||||||
// MPTRootState represents state root together with its verification state.
|
// MPTRootState represents state root together with its verification state.
|
||||||
type MPTRootState struct {
|
type MPTRootState struct {
|
||||||
MPTRoot
|
MPTRoot `json:"stateroot"`
|
||||||
Flag MPTRootStateFlag
|
Flag MPTRootStateFlag `json:"flag"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// EncodeBinary implements io.Serializable.
|
// EncodeBinary implements io.Serializable.
|
||||||
|
@ -103,3 +106,41 @@ func (s *MPTRoot) EncodeBinary(w *io.BinWriter) {
|
||||||
w.WriteArray([]*transaction.Witness{s.Witness})
|
w.WriteArray([]*transaction.Witness{s.Witness})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// String implements fmt.Stringer.
|
||||||
|
func (f MPTRootStateFlag) String() string {
|
||||||
|
switch f {
|
||||||
|
case Unverified:
|
||||||
|
return "Unverified"
|
||||||
|
case Verified:
|
||||||
|
return "Verified"
|
||||||
|
case Invalid:
|
||||||
|
return "Invalid"
|
||||||
|
default:
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// MarshalJSON implements json.Marshaler.
|
||||||
|
func (f MPTRootStateFlag) MarshalJSON() ([]byte, error) {
|
||||||
|
return []byte(`"` + f.String() + `"`), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// UnmarshalJSON implements json.Unmarshaler.
|
||||||
|
func (f *MPTRootStateFlag) UnmarshalJSON(data []byte) error {
|
||||||
|
var s string
|
||||||
|
if err := json.Unmarshal(data, &s); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
switch s {
|
||||||
|
case "Unverified":
|
||||||
|
*f = Unverified
|
||||||
|
case "Verified":
|
||||||
|
*f = Verified
|
||||||
|
case "Invalid":
|
||||||
|
*f = Invalid
|
||||||
|
default:
|
||||||
|
return errors.New("unknown flag")
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
|
@ -1,12 +1,14 @@
|
||||||
package state
|
package state
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"encoding/json"
|
||||||
"math/rand"
|
"math/rand"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/nspcc-dev/neo-go/pkg/core/transaction"
|
"github.com/nspcc-dev/neo-go/pkg/core/transaction"
|
||||||
"github.com/nspcc-dev/neo-go/pkg/internal/random"
|
"github.com/nspcc-dev/neo-go/pkg/internal/random"
|
||||||
"github.com/nspcc-dev/neo-go/pkg/internal/testserdes"
|
"github.com/nspcc-dev/neo-go/pkg/internal/testserdes"
|
||||||
|
"github.com/nspcc-dev/neo-go/pkg/util"
|
||||||
"github.com/stretchr/testify/require"
|
"github.com/stretchr/testify/require"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -59,3 +61,40 @@ func TestMPTRootStateUnverifiedByDefault(t *testing.T) {
|
||||||
var r MPTRootState
|
var r MPTRootState
|
||||||
require.Equal(t, Unverified, r.Flag)
|
require.Equal(t, Unverified, r.Flag)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestMPTRoot_MarshalJSON(t *testing.T) {
|
||||||
|
t.Run("Good", func(t *testing.T) {
|
||||||
|
r := testStateRoot()
|
||||||
|
rs := &MPTRootState{
|
||||||
|
MPTRoot: *r,
|
||||||
|
Flag: Verified,
|
||||||
|
}
|
||||||
|
testserdes.MarshalUnmarshalJSON(t, rs, new(MPTRootState))
|
||||||
|
})
|
||||||
|
|
||||||
|
t.Run("Compatibility", func(t *testing.T) {
|
||||||
|
js := []byte(`{
|
||||||
|
"flag": "Unverified",
|
||||||
|
"stateroot": {
|
||||||
|
"version": 1,
|
||||||
|
"index": 3000000,
|
||||||
|
"prehash": "0x4f30f43af8dd2262fc331c45bfcd9066ebbacda204e6e81371cbd884fe7d6c90",
|
||||||
|
"stateroot": "0xb2fd7e368a848ef70d27cf44940a35237333ed05f1d971c9408f0eb285e0b6f3"
|
||||||
|
}}`)
|
||||||
|
|
||||||
|
rs := new(MPTRootState)
|
||||||
|
require.NoError(t, json.Unmarshal(js, &rs))
|
||||||
|
|
||||||
|
require.EqualValues(t, 1, rs.Version)
|
||||||
|
require.EqualValues(t, 3000000, rs.Index)
|
||||||
|
require.Nil(t, rs.Witness)
|
||||||
|
|
||||||
|
u, err := util.Uint256DecodeStringLE("4f30f43af8dd2262fc331c45bfcd9066ebbacda204e6e81371cbd884fe7d6c90")
|
||||||
|
require.NoError(t, err)
|
||||||
|
require.Equal(t, u, rs.PrevHash)
|
||||||
|
|
||||||
|
u, err = util.Uint256DecodeStringLE("b2fd7e368a848ef70d27cf44940a35237333ed05f1d971c9408f0eb285e0b6f3")
|
||||||
|
require.NoError(t, err)
|
||||||
|
require.Equal(t, u, rs.Root)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in a new issue