state: fix MPTRoot JSONization

Match C# implementation. It's easier to do this by changing the structure
itself.
This commit is contained in:
Roman Khimov 2021-03-26 13:39:37 +03:00
parent 4c4a980cc0
commit 5f7ec6e784
6 changed files with 22 additions and 27 deletions

View file

@ -11,8 +11,8 @@ import (
type MPTRoot struct {
Version byte `json:"version"`
Index uint32 `json:"index"`
Root util.Uint256 `json:"stateroot"`
Witness *transaction.Witness `json:"witness,omitempty"`
Root util.Uint256 `json:"roothash"`
Witness []transaction.Witness `json:"witnesses"`
}
// Hash returns hash of s.
@ -39,20 +39,11 @@ func (s *MPTRoot) EncodeBinaryUnsigned(w *io.BinWriter) {
// DecodeBinary implements io.Serializable.
func (s *MPTRoot) DecodeBinary(r *io.BinReader) {
s.DecodeBinaryUnsigned(r)
var ws []transaction.Witness
r.ReadArray(&ws, 1)
if len(ws) == 1 {
s.Witness = &ws[0]
}
r.ReadArray(&s.Witness, 1)
}
// EncodeBinary implements io.Serializable.
func (s *MPTRoot) EncodeBinary(w *io.BinWriter) {
s.EncodeBinaryUnsigned(w)
if s.Witness == nil {
w.WriteVarUint(0)
} else {
w.WriteArray([]*transaction.Witness{s.Witness})
}
w.WriteArray(s.Witness)
}

View file

@ -17,6 +17,7 @@ func testStateRoot() *MPTRoot {
Version: byte(rand.Uint32()),
Index: rand.Uint32(),
Root: random.Uint256(),
Witness: []transaction.Witness{},
}
}
@ -25,10 +26,10 @@ func TestStateRoot_Serializable(t *testing.T) {
testserdes.EncodeDecodeBinary(t, r, new(MPTRoot))
t.Run("WithWitness", func(t *testing.T) {
r.Witness = &transaction.Witness{
r.Witness = []transaction.Witness{{
InvocationScript: random.Bytes(10),
VerificationScript: random.Bytes(11),
}
}}
testserdes.EncodeDecodeBinary(t, r, new(MPTRoot))
})
}
@ -43,7 +44,7 @@ func TestMPTRoot_MarshalJSON(t *testing.T) {
js := []byte(`{
"version": 1,
"index": 3000000,
"stateroot": "0xb2fd7e368a848ef70d27cf44940a35237333ed05f1d971c9408f0eb285e0b6f3"
"roothash": "0xb2fd7e368a848ef70d27cf44940a35237333ed05f1d971c9408f0eb285e0b6f3"
}`)
rs := new(MPTRoot)
@ -51,7 +52,7 @@ func TestMPTRoot_MarshalJSON(t *testing.T) {
require.EqualValues(t, 1, rs.Version)
require.EqualValues(t, 3000000, rs.Index)
require.Nil(t, rs.Witness)
require.Equal(t, 0, len(rs.Witness))
u, err := util.Uint256DecodeStringLE("b2fd7e368a848ef70d27cf44940a35237333ed05f1d971c9408f0eb285e0b6f3")
require.NoError(t, err)

View file

@ -132,6 +132,9 @@ func (s *Module) VerifyStateRoot(r *state.MPTRoot) error {
if err != nil {
return errors.New("can't get previous state root")
}
if len(r.Witness) != 1 {
return errors.New("no witness")
}
return s.verifyWitness(r)
}
@ -142,5 +145,5 @@ func (s *Module) verifyWitness(r *state.MPTRoot) error {
s.mtx.Lock()
h := s.getKeyCacheForHeight(r.Index).validatorsHash
s.mtx.Unlock()
return s.bc.VerifyWitness(h, r, r.Witness, maxVerificationGAS)
return s.bc.VerifyWitness(h, r, &r.Witness[0], maxVerificationGAS)
}

View file

@ -69,7 +69,7 @@ func (s *Module) AddStateRoot(sr *state.MPTRoot) error {
if err != nil {
return err
}
if local.Witness != nil {
if len(local.Witness) != 0 {
return nil
}
if err := s.putStateRoot(key, sr); err != nil {

View file

@ -40,10 +40,10 @@ func testSignStateRoot(t *testing.T, r *state.MPTRoot, pubs keys.PublicKeys, acc
script, err := smartcontract.CreateMajorityMultiSigRedeemScript(pubs.Copy())
require.NoError(t, err)
r.Witness = &transaction.Witness{
r.Witness = []transaction.Witness{{
VerificationScript: script,
InvocationScript: w.Bytes(),
}
}}
data, err := testserdes.EncodeBinary(stateroot.NewMessage(stateroot.RootT, r))
require.NoError(t, err)
return data
@ -132,8 +132,8 @@ func TestStateRoot(t *testing.T) {
r, err = srv.GetStateRoot(updateIndex + 1)
require.NoError(t, err)
require.NotNil(t, r.Witness)
require.Equal(t, h, r.Witness.ScriptHash())
require.NotEqual(t, 0, len(r.Witness))
require.Equal(t, h, r.Witness[0].ScriptHash())
}
func TestStateRootInitNonZeroHeight(t *testing.T) {

View file

@ -81,8 +81,8 @@ func (r *incompleteRoot) finalize(stateValidators keys.PublicKeys) (*state.MPTRo
for i := range sigs {
emit.Bytes(w.BinWriter, sigs[i])
}
r.root.Witness = &transaction.Witness{
r.root.Witness = []transaction.Witness{{
InvocationScript: w.Bytes(),
}
}}
return r.root, true
}