diff --git a/pkg/core/state/mpt_root.go b/pkg/core/state/mpt_root.go index 5d91d0c76..fa1d6b469 100644 --- a/pkg/core/state/mpt_root.go +++ b/pkg/core/state/mpt_root.go @@ -9,10 +9,10 @@ import ( // MPTRoot represents storage state root together with sign info. type MPTRoot struct { - Version byte `json:"version"` - Index uint32 `json:"index"` - Root util.Uint256 `json:"stateroot"` - Witness *transaction.Witness `json:"witness,omitempty"` + Version byte `json:"version"` + Index uint32 `json:"index"` + 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) } diff --git a/pkg/core/state/mpt_root_test.go b/pkg/core/state/mpt_root_test.go index eaf5c45dd..b38621497 100644 --- a/pkg/core/state/mpt_root_test.go +++ b/pkg/core/state/mpt_root_test.go @@ -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) diff --git a/pkg/core/stateroot/module.go b/pkg/core/stateroot/module.go index 117606d1d..fa6f5127d 100644 --- a/pkg/core/stateroot/module.go +++ b/pkg/core/stateroot/module.go @@ -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) } diff --git a/pkg/core/stateroot/store.go b/pkg/core/stateroot/store.go index 5a834217b..865073159 100644 --- a/pkg/core/stateroot/store.go +++ b/pkg/core/stateroot/store.go @@ -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 { diff --git a/pkg/core/stateroot_test.go b/pkg/core/stateroot_test.go index 550c6e73f..2277fdfac 100644 --- a/pkg/core/stateroot_test.go +++ b/pkg/core/stateroot_test.go @@ -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) { diff --git a/pkg/services/stateroot/signature.go b/pkg/services/stateroot/signature.go index a49ff733f..a180c3474 100644 --- a/pkg/services/stateroot/signature.go +++ b/pkg/services/stateroot/signature.go @@ -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 }