state: add network to MPTRoot, change hashing

Fix RC1 incompatibility.
This commit is contained in:
Roman Khimov 2021-03-25 11:53:25 +03:00
parent 33f54028fb
commit 0248e2c0d2
9 changed files with 39 additions and 22 deletions

View file

@ -1,6 +1,9 @@
package state package state
import ( 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/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,6 +12,7 @@ import (
// MPTRoot represents storage state root together with sign info. // MPTRoot represents storage state root together with sign info.
type MPTRoot struct { type MPTRoot struct {
Network netmode.Magic `json:"-"`
Version byte `json:"version"` Version byte `json:"version"`
Index uint32 `json:"index"` Index uint32 `json:"index"`
Root util.Uint256 `json:"stateroot"` Root util.Uint256 `json:"stateroot"`
@ -17,9 +21,11 @@ type MPTRoot struct {
// GetSignedPart returns part of MPTRootBase which needs to be signed. // GetSignedPart returns part of MPTRootBase which needs to be signed.
func (s *MPTRoot) GetSignedPart() []byte { func (s *MPTRoot) GetSignedPart() []byte {
buf := io.NewBufBinWriter() b := make([]byte, 4+32)
s.EncodeBinaryUnsigned(buf.BinWriter) binary.LittleEndian.PutUint32(b, uint32(s.Network))
return buf.Bytes() h := s.Hash()
copy(b[4:], h[:])
return b
} }
// GetSignedHash returns hash of MPTRootBase which needs to be signed. // GetSignedHash returns hash of MPTRootBase which needs to be signed.
@ -29,7 +35,9 @@ func (s *MPTRoot) GetSignedHash() util.Uint256 {
// Hash returns hash of s. // Hash returns hash of s.
func (s *MPTRoot) Hash() util.Uint256 { func (s *MPTRoot) Hash() util.Uint256 {
return hash.DoubleSha256(s.GetSignedPart()) buf := io.NewBufBinWriter()
s.EncodeBinaryUnsigned(buf.BinWriter)
return hash.Sha256(buf.Bytes())
} }
// DecodeBinaryUnsigned decodes hashable part of state root. // DecodeBinaryUnsigned decodes hashable part of state root.

View file

@ -6,6 +6,7 @@ import (
"fmt" "fmt"
"sync" "sync"
"github.com/nspcc-dev/neo-go/pkg/config/netmode"
"github.com/nspcc-dev/neo-go/pkg/core/blockchainer" "github.com/nspcc-dev/neo-go/pkg/core/blockchainer"
"github.com/nspcc-dev/neo-go/pkg/core/mpt" "github.com/nspcc-dev/neo-go/pkg/core/mpt"
"github.com/nspcc-dev/neo-go/pkg/core/state" "github.com/nspcc-dev/neo-go/pkg/core/state"
@ -20,6 +21,7 @@ type (
// Module represents module for local processing of state roots. // Module represents module for local processing of state roots.
Module struct { Module struct {
Store *storage.MemCachedStore Store *storage.MemCachedStore
network netmode.Magic
mpt *mpt.Trie mpt *mpt.Trie
bc blockchainer.Blockchainer bc blockchainer.Blockchainer
log *zap.Logger log *zap.Logger
@ -45,6 +47,7 @@ type (
// NewModule returns new instance of stateroot module. // NewModule returns new instance of stateroot module.
func NewModule(bc blockchainer.Blockchainer, log *zap.Logger, s *storage.MemCachedStore) *Module { func NewModule(bc blockchainer.Blockchainer, log *zap.Logger, s *storage.MemCachedStore) *Module {
return &Module{ return &Module{
network: bc.GetConfig().Magic,
bc: bc, bc: bc,
log: log, log: log,
Store: s, Store: s,
@ -113,6 +116,7 @@ func (s *Module) AddMPTBatch(index uint32, b mpt.Batch) error {
} }
s.mpt.Flush() s.mpt.Flush()
err := s.addLocalStateRoot(&state.MPTRoot{ err := s.addLocalStateRoot(&state.MPTRoot{
Network: s.network,
Index: index, Index: index,
Root: s.mpt.StateRoot(), Root: s.mpt.StateRoot(),
}) })

View file

@ -46,7 +46,7 @@ func (s *Module) getStateRoot(key []byte) (*state.MPTRoot, error) {
return nil, err return nil, err
} }
sr := new(state.MPTRoot) sr := &state.MPTRoot{Network: s.network}
r := io.NewBinReaderFromBuf(data) r := io.NewBinReaderFromBuf(data)
sr.DecodeBinary(r) sr.DecodeBinary(r)
return sr, r.Err return sr, r.Err

View file

@ -10,6 +10,7 @@ import (
"github.com/nspcc-dev/neo-go/internal/testserdes" "github.com/nspcc-dev/neo-go/internal/testserdes"
"github.com/nspcc-dev/neo-go/pkg/config" "github.com/nspcc-dev/neo-go/pkg/config"
"github.com/nspcc-dev/neo-go/pkg/config/netmode"
"github.com/nspcc-dev/neo-go/pkg/core/native/noderoles" "github.com/nspcc-dev/neo-go/pkg/core/native/noderoles"
"github.com/nspcc-dev/neo-go/pkg/core/state" "github.com/nspcc-dev/neo-go/pkg/core/state"
"github.com/nspcc-dev/neo-go/pkg/core/storage" "github.com/nspcc-dev/neo-go/pkg/core/storage"
@ -43,7 +44,7 @@ func testSignStateRoot(t *testing.T, r *state.MPTRoot, pubs keys.PublicKeys, acc
VerificationScript: script, VerificationScript: script,
InvocationScript: w.Bytes(), InvocationScript: w.Bytes(),
} }
data, err := testserdes.EncodeBinary(stateroot.NewMessage(stateroot.RootT, r)) data, err := testserdes.EncodeBinary(stateroot.NewMessage(netmode.UnitTestNet, stateroot.RootT, r))
require.NoError(t, err) require.NoError(t, err)
return data return data
} }
@ -96,7 +97,7 @@ func TestStateRoot(t *testing.T) {
t.Run("drop zero index", func(t *testing.T) { t.Run("drop zero index", func(t *testing.T) {
r, err := srv.GetStateRoot(0) r, err := srv.GetStateRoot(0)
require.NoError(t, err) require.NoError(t, err)
data, err := testserdes.EncodeBinary(stateroot.NewMessage(stateroot.RootT, r)) data, err := testserdes.EncodeBinary(stateroot.NewMessage(netmode.UnitTestNet, stateroot.RootT, r))
require.NoError(t, err) require.NoError(t, err)
require.NoError(t, srv.OnPayload(&payload.Extensible{Data: data})) require.NoError(t, srv.OnPayload(&payload.Extensible{Data: data}))
require.EqualValues(t, 0, srv.CurrentValidatedHeight()) require.EqualValues(t, 0, srv.CurrentValidatedHeight())

View file

@ -1368,7 +1368,7 @@ func testRPCProtocol(t *testing.T, doRPCCall func(string, string, *testing.T) []
body := doRPCCall(rpc, httpSrv.URL, t) body := doRPCCall(rpc, httpSrv.URL, t)
rawRes := checkErrGetResult(t, body, false) rawRes := checkErrGetResult(t, body, false)
res := new(state.MPTRoot) res := &state.MPTRoot{Network: netmode.UnitTestNet}
require.NoError(t, json.Unmarshal(rawRes, res)) require.NoError(t, json.Unmarshal(rawRes, res))
require.NotEqual(t, util.Uint256{}, res.Root) // be sure this test uses valid height require.NotEqual(t, util.Uint256{}, res.Root) // be sure this test uses valid height

View file

@ -3,6 +3,7 @@ package stateroot
import ( import (
"fmt" "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/core/state"
"github.com/nspcc-dev/neo-go/pkg/io" "github.com/nspcc-dev/neo-go/pkg/io"
) )
@ -13,6 +14,7 @@ type (
// Message represents state-root related message. // Message represents state-root related message.
Message struct { Message struct {
Network netmode.Magic
Type MessageType Type MessageType
Payload io.Serializable Payload io.Serializable
} }
@ -25,8 +27,9 @@ const (
) )
// NewMessage creates new message of specified type. // NewMessage creates new message of specified type.
func NewMessage(typ MessageType, p io.Serializable) *Message { func NewMessage(net netmode.Magic, typ MessageType, p io.Serializable) *Message {
return &Message{ return &Message{
Network: net,
Type: typ, Type: typ,
Payload: p, Payload: p,
} }
@ -44,7 +47,7 @@ func (m *Message) DecodeBinary(r *io.BinReader) {
case VoteT: case VoteT:
m.Payload = new(Vote) m.Payload = new(Vote)
case RootT: case RootT:
m.Payload = new(state.MPTRoot) m.Payload = &state.MPTRoot{Network: m.Network}
default: default:
r.Err = fmt.Errorf("invalid type: %x", m.Type) r.Err = fmt.Errorf("invalid type: %x", m.Type)
return return

View file

@ -72,7 +72,7 @@ func (s *service) getIncompleteRoot(height uint32) *incompleteRoot {
func (s *service) sendValidatedRoot(r *state.MPTRoot) { func (s *service) sendValidatedRoot(r *state.MPTRoot) {
w := io.NewBufBinWriter() w := io.NewBufBinWriter()
m := NewMessage(RootT, r) m := NewMessage(s.Network, RootT, r)
m.EncodeBinary(w.BinWriter) m.EncodeBinary(w.BinWriter)
ep := &payload.Extensible{ ep := &payload.Extensible{
Network: s.Network, Network: s.Network,

View file

@ -61,6 +61,7 @@ const (
func New(cfg config.StateRoot, log *zap.Logger, bc blockchainer.Blockchainer) (Service, error) { func New(cfg config.StateRoot, log *zap.Logger, bc blockchainer.Blockchainer) (Service, error) {
s := &service{ s := &service{
StateRoot: bc.GetStateModule(), StateRoot: bc.GetStateModule(),
Network: bc.GetConfig().Magic,
chain: bc, chain: bc,
log: log, log: log,
incompleteRoots: make(map[uint32]*incompleteRoot), incompleteRoots: make(map[uint32]*incompleteRoot),
@ -94,7 +95,7 @@ func New(cfg config.StateRoot, log *zap.Logger, bc blockchainer.Blockchainer) (S
// OnPayload implements Service interface. // OnPayload implements Service interface.
func (s *service) OnPayload(ep *payload.Extensible) error { func (s *service) OnPayload(ep *payload.Extensible) error {
m := new(Message) m := &Message{Network: s.Network}
r := io.NewBinReaderFromBuf(ep.Data) r := io.NewBinReaderFromBuf(ep.Data)
m.DecodeBinary(r) m.DecodeBinary(r)
if r.Err != nil { if r.Err != nil {

View file

@ -55,7 +55,7 @@ func (s *service) signAndSend(r *state.MPTRoot) error {
s.accMtx.RLock() s.accMtx.RLock()
myIndex := s.myIndex myIndex := s.myIndex
s.accMtx.RUnlock() s.accMtx.RUnlock()
msg := NewMessage(VoteT, &Vote{ msg := NewMessage(s.Network, VoteT, &Vote{
ValidatorIndex: int32(myIndex), ValidatorIndex: int32(myIndex),
Height: r.Index, Height: r.Index,
Signature: sig, Signature: sig,