From 8c110a6147b98d526c1261bdc7176a957846e726 Mon Sep 17 00:00:00 2001 From: Roman Khimov Date: Thu, 25 Mar 2021 22:11:55 +0300 Subject: [PATCH] state: drop Network from MPTRoot structure It's only needed to verify/sign. --- pkg/core/state/mpt_root.go | 18 ------------------ pkg/core/stateroot/module.go | 5 ++--- pkg/core/stateroot/store.go | 2 +- pkg/core/stateroot_test.go | 10 +++++----- pkg/rpc/server/server_test.go | 2 +- pkg/services/stateroot/message.go | 7 ++----- pkg/services/stateroot/network.go | 4 ++-- pkg/services/stateroot/service.go | 2 +- pkg/services/stateroot/signature.go | 6 +++--- pkg/services/stateroot/validators.go | 6 +++--- 10 files changed, 20 insertions(+), 42 deletions(-) diff --git a/pkg/core/state/mpt_root.go b/pkg/core/state/mpt_root.go index 0a4e4c183..5d91d0c76 100644 --- a/pkg/core/state/mpt_root.go +++ b/pkg/core/state/mpt_root.go @@ -1,9 +1,6 @@ package state import ( - "encoding/binary" - - "github.com/nspcc-dev/neo-go/pkg/config/netmode" "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/io" @@ -12,27 +9,12 @@ import ( // MPTRoot represents storage state root together with sign info. type MPTRoot struct { - Network netmode.Magic `json:"-"` Version byte `json:"version"` Index uint32 `json:"index"` Root util.Uint256 `json:"stateroot"` Witness *transaction.Witness `json:"witness,omitempty"` } -// GetSignedPart returns part of MPTRootBase which needs to be signed. -func (s *MPTRoot) GetSignedPart() []byte { - b := make([]byte, 4+32) - binary.LittleEndian.PutUint32(b, uint32(s.Network)) - h := s.Hash() - copy(b[4:], h[:]) - return b -} - -// GetSignedHash returns hash of MPTRootBase which needs to be signed. -func (s *MPTRoot) GetSignedHash() util.Uint256 { - return hash.Sha256(s.GetSignedPart()) -} - // Hash returns hash of s. func (s *MPTRoot) Hash() util.Uint256 { buf := io.NewBufBinWriter() diff --git a/pkg/core/stateroot/module.go b/pkg/core/stateroot/module.go index 49b5b2661..117606d1d 100644 --- a/pkg/core/stateroot/module.go +++ b/pkg/core/stateroot/module.go @@ -116,9 +116,8 @@ func (s *Module) AddMPTBatch(index uint32, b mpt.Batch) error { } s.mpt.Flush() err := s.addLocalStateRoot(&state.MPTRoot{ - Network: s.network, - Index: index, - Root: s.mpt.StateRoot(), + Index: index, + Root: s.mpt.StateRoot(), }) if err != nil { return err diff --git a/pkg/core/stateroot/store.go b/pkg/core/stateroot/store.go index d2f7fd4c4..5a834217b 100644 --- a/pkg/core/stateroot/store.go +++ b/pkg/core/stateroot/store.go @@ -46,7 +46,7 @@ func (s *Module) getStateRoot(key []byte) (*state.MPTRoot, error) { return nil, err } - sr := &state.MPTRoot{Network: s.network} + sr := &state.MPTRoot{} r := io.NewBinReaderFromBuf(data) sr.DecodeBinary(r) return sr, r.Err diff --git a/pkg/core/stateroot_test.go b/pkg/core/stateroot_test.go index 27cad0cd0..550c6e73f 100644 --- a/pkg/core/stateroot_test.go +++ b/pkg/core/stateroot_test.go @@ -33,7 +33,7 @@ func testSignStateRoot(t *testing.T, r *state.MPTRoot, pubs keys.PublicKeys, acc n := smartcontract.GetMajorityHonestNodeCount(len(accs)) w := io.NewBufBinWriter() for i := 0; i < n; i++ { - sig := accs[i].PrivateKey().SignHash(r.GetSignedHash()) + sig := accs[i].PrivateKey().SignHashable(uint32(netmode.UnitTestNet), r) emit.Bytes(w.BinWriter, sig) } require.NoError(t, w.Err) @@ -44,7 +44,7 @@ func testSignStateRoot(t *testing.T, r *state.MPTRoot, pubs keys.PublicKeys, acc VerificationScript: script, InvocationScript: w.Bytes(), } - data, err := testserdes.EncodeBinary(stateroot.NewMessage(netmode.UnitTestNet, stateroot.RootT, r)) + data, err := testserdes.EncodeBinary(stateroot.NewMessage(stateroot.RootT, r)) require.NoError(t, err) return data } @@ -97,7 +97,7 @@ func TestStateRoot(t *testing.T) { t.Run("drop zero index", func(t *testing.T) { r, err := srv.GetStateRoot(0) require.NoError(t, err) - data, err := testserdes.EncodeBinary(stateroot.NewMessage(netmode.UnitTestNet, stateroot.RootT, r)) + data, err := testserdes.EncodeBinary(stateroot.NewMessage(stateroot.RootT, r)) require.NoError(t, err) require.NoError(t, srv.OnPayload(&payload.Extensible{Data: data})) require.EqualValues(t, 0, srv.CurrentValidatedHeight()) @@ -221,7 +221,7 @@ func TestStateRootFull(t *testing.T) { r, err := srv.GetStateRoot(2) require.NoError(t, err) - require.NoError(t, srv.AddSignature(2, 0, accs[0].PrivateKey().SignHash(r.GetSignedHash()))) + require.NoError(t, srv.AddSignature(2, 0, accs[0].PrivateKey().SignHashable(uint32(netmode.UnitTestNet), r))) require.NotNil(t, lastValidated.Load().(*payload.Extensible)) msg := new(stateroot.Message) @@ -250,5 +250,5 @@ func checkVoteBroadcasted(t *testing.T, bc *Blockchain, p *payload.Extensible, pubs, _, err := bc.contracts.Designate.GetDesignatedByRole(bc.dao, noderoles.StateValidator, bc.BlockHeight()) require.True(t, len(pubs) > int(valIndex)) - require.True(t, pubs[valIndex].Verify(vote.Signature, r.GetSignedHash().BytesBE())) + require.True(t, pubs[valIndex].VerifyHashable(vote.Signature, uint32(netmode.UnitTestNet), r)) } diff --git a/pkg/rpc/server/server_test.go b/pkg/rpc/server/server_test.go index 97b4dbdc3..d4d6d052c 100644 --- a/pkg/rpc/server/server_test.go +++ b/pkg/rpc/server/server_test.go @@ -1364,7 +1364,7 @@ func testRPCProtocol(t *testing.T, doRPCCall func(string, string, *testing.T) [] body := doRPCCall(rpc, httpSrv.URL, t) rawRes := checkErrGetResult(t, body, false) - res := &state.MPTRoot{Network: netmode.UnitTestNet} + res := &state.MPTRoot{} require.NoError(t, json.Unmarshal(rawRes, res)) require.NotEqual(t, util.Uint256{}, res.Root) // be sure this test uses valid height diff --git a/pkg/services/stateroot/message.go b/pkg/services/stateroot/message.go index 2e65acf1d..5b1e32e73 100644 --- a/pkg/services/stateroot/message.go +++ b/pkg/services/stateroot/message.go @@ -3,7 +3,6 @@ package stateroot import ( "fmt" - "github.com/nspcc-dev/neo-go/pkg/config/netmode" "github.com/nspcc-dev/neo-go/pkg/core/state" "github.com/nspcc-dev/neo-go/pkg/io" ) @@ -14,7 +13,6 @@ type ( // Message represents state-root related message. Message struct { - Network netmode.Magic Type MessageType Payload io.Serializable } @@ -27,9 +25,8 @@ const ( ) // NewMessage creates new message of specified type. -func NewMessage(net netmode.Magic, typ MessageType, p io.Serializable) *Message { +func NewMessage(typ MessageType, p io.Serializable) *Message { return &Message{ - Network: net, Type: typ, Payload: p, } @@ -47,7 +44,7 @@ func (m *Message) DecodeBinary(r *io.BinReader) { case VoteT: m.Payload = new(Vote) case RootT: - m.Payload = &state.MPTRoot{Network: m.Network} + m.Payload = new(state.MPTRoot) default: r.Err = fmt.Errorf("invalid type: %x", m.Type) return diff --git a/pkg/services/stateroot/network.go b/pkg/services/stateroot/network.go index 203478b17..21174c3a5 100644 --- a/pkg/services/stateroot/network.go +++ b/pkg/services/stateroot/network.go @@ -40,7 +40,7 @@ func (s *service) AddSignature(height uint32, validatorIndex int32, sig []byte) incRoot.Lock() if incRoot.root != nil { - ok := pub.Verify(sig, incRoot.root.GetSignedHash().BytesBE()) + ok := pub.VerifyHashable(sig, uint32(s.Network), incRoot.root) if !ok { incRoot.Unlock() return fmt.Errorf("invalid state root signature for %d", validatorIndex) @@ -78,7 +78,7 @@ func (s *service) getIncompleteRoot(height uint32) *incompleteRoot { func (s *service) sendValidatedRoot(r *state.MPTRoot, priv *keys.PrivateKey) { w := io.NewBufBinWriter() - m := NewMessage(s.Network, RootT, r) + m := NewMessage(RootT, r) m.EncodeBinary(w.BinWriter) ep := &payload.Extensible{ ValidBlockStart: r.Index, diff --git a/pkg/services/stateroot/service.go b/pkg/services/stateroot/service.go index 55a86ab4e..d8ebc4249 100644 --- a/pkg/services/stateroot/service.go +++ b/pkg/services/stateroot/service.go @@ -95,7 +95,7 @@ func New(cfg config.StateRoot, log *zap.Logger, bc blockchainer.Blockchainer) (S // OnPayload implements Service interface. func (s *service) OnPayload(ep *payload.Extensible) error { - m := &Message{Network: s.Network} + m := &Message{} r := io.NewBinReaderFromBuf(ep.Data) m.DecodeBinary(r) if r.Err != nil { diff --git a/pkg/services/stateroot/signature.go b/pkg/services/stateroot/signature.go index b579f91fe..a49ff733f 100644 --- a/pkg/services/stateroot/signature.go +++ b/pkg/services/stateroot/signature.go @@ -3,6 +3,7 @@ package stateroot import ( "sync" + "github.com/nspcc-dev/neo-go/pkg/config/netmode" "github.com/nspcc-dev/neo-go/pkg/core/state" "github.com/nspcc-dev/neo-go/pkg/core/transaction" "github.com/nspcc-dev/neo-go/pkg/crypto/keys" @@ -38,11 +39,10 @@ func newIncompleteRoot() *incompleteRoot { } } -func (r *incompleteRoot) reverify() { - txHash := r.root.GetSignedHash() +func (r *incompleteRoot) reverify(net netmode.Magic) { for _, sig := range r.sigs { if !sig.ok { - sig.ok = sig.pub.Verify(sig.sig, txHash.BytesBE()) + sig.ok = sig.pub.VerifyHashable(sig.sig, uint32(net), r.root) } } } diff --git a/pkg/services/stateroot/validators.go b/pkg/services/stateroot/validators.go index 2e48bacc5..fbd9a88d2 100644 --- a/pkg/services/stateroot/validators.go +++ b/pkg/services/stateroot/validators.go @@ -47,16 +47,16 @@ func (s *service) signAndSend(r *state.MPTRoot) error { return nil } - sig := acc.PrivateKey().SignHash(r.GetSignedHash()) + sig := acc.PrivateKey().SignHashable(uint32(s.Network), r) incRoot := s.getIncompleteRoot(r.Index) incRoot.root = r incRoot.addSignature(acc.PrivateKey().PublicKey(), sig) - incRoot.reverify() + incRoot.reverify(s.Network) s.accMtx.RLock() myIndex := s.myIndex s.accMtx.RUnlock() - msg := NewMessage(s.Network, VoteT, &Vote{ + msg := NewMessage(VoteT, &Vote{ ValidatorIndex: int32(myIndex), Height: r.Index, Signature: sig,