mirror of
https://github.com/nspcc-dev/neo-go.git
synced 2024-12-23 03:41:34 +00:00
state: add network to MPTRoot, change hashing
Fix RC1 incompatibility.
This commit is contained in:
parent
33f54028fb
commit
0248e2c0d2
9 changed files with 39 additions and 22 deletions
|
@ -1,6 +1,9 @@
|
|||
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"
|
||||
|
@ -9,6 +12,7 @@ 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"`
|
||||
|
@ -17,9 +21,11 @@ type MPTRoot struct {
|
|||
|
||||
// GetSignedPart returns part of MPTRootBase which needs to be signed.
|
||||
func (s *MPTRoot) GetSignedPart() []byte {
|
||||
buf := io.NewBufBinWriter()
|
||||
s.EncodeBinaryUnsigned(buf.BinWriter)
|
||||
return buf.Bytes()
|
||||
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.
|
||||
|
@ -29,7 +35,9 @@ func (s *MPTRoot) GetSignedHash() util.Uint256 {
|
|||
|
||||
// Hash returns hash of s.
|
||||
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.
|
||||
|
|
|
@ -6,6 +6,7 @@ import (
|
|||
"fmt"
|
||||
"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/mpt"
|
||||
"github.com/nspcc-dev/neo-go/pkg/core/state"
|
||||
|
@ -19,10 +20,11 @@ import (
|
|||
type (
|
||||
// Module represents module for local processing of state roots.
|
||||
Module struct {
|
||||
Store *storage.MemCachedStore
|
||||
mpt *mpt.Trie
|
||||
bc blockchainer.Blockchainer
|
||||
log *zap.Logger
|
||||
Store *storage.MemCachedStore
|
||||
network netmode.Magic
|
||||
mpt *mpt.Trie
|
||||
bc blockchainer.Blockchainer
|
||||
log *zap.Logger
|
||||
|
||||
currentLocal atomic.Value
|
||||
localHeight atomic.Uint32
|
||||
|
@ -45,9 +47,10 @@ type (
|
|||
// NewModule returns new instance of stateroot module.
|
||||
func NewModule(bc blockchainer.Blockchainer, log *zap.Logger, s *storage.MemCachedStore) *Module {
|
||||
return &Module{
|
||||
bc: bc,
|
||||
log: log,
|
||||
Store: s,
|
||||
network: bc.GetConfig().Magic,
|
||||
bc: bc,
|
||||
log: log,
|
||||
Store: s,
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -113,8 +116,9 @@ func (s *Module) AddMPTBatch(index uint32, b mpt.Batch) error {
|
|||
}
|
||||
s.mpt.Flush()
|
||||
err := s.addLocalStateRoot(&state.MPTRoot{
|
||||
Index: index,
|
||||
Root: s.mpt.StateRoot(),
|
||||
Network: s.network,
|
||||
Index: index,
|
||||
Root: s.mpt.StateRoot(),
|
||||
})
|
||||
if err != nil {
|
||||
return err
|
||||
|
|
|
@ -46,7 +46,7 @@ func (s *Module) getStateRoot(key []byte) (*state.MPTRoot, error) {
|
|||
return nil, err
|
||||
}
|
||||
|
||||
sr := new(state.MPTRoot)
|
||||
sr := &state.MPTRoot{Network: s.network}
|
||||
r := io.NewBinReaderFromBuf(data)
|
||||
sr.DecodeBinary(r)
|
||||
return sr, r.Err
|
||||
|
|
|
@ -10,6 +10,7 @@ import (
|
|||
|
||||
"github.com/nspcc-dev/neo-go/internal/testserdes"
|
||||
"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/state"
|
||||
"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,
|
||||
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)
|
||||
return data
|
||||
}
|
||||
|
@ -96,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(stateroot.RootT, r))
|
||||
data, err := testserdes.EncodeBinary(stateroot.NewMessage(netmode.UnitTestNet, stateroot.RootT, r))
|
||||
require.NoError(t, err)
|
||||
require.NoError(t, srv.OnPayload(&payload.Extensible{Data: data}))
|
||||
require.EqualValues(t, 0, srv.CurrentValidatedHeight())
|
||||
|
|
|
@ -1368,7 +1368,7 @@ func testRPCProtocol(t *testing.T, doRPCCall func(string, string, *testing.T) []
|
|||
body := doRPCCall(rpc, httpSrv.URL, t)
|
||||
rawRes := checkErrGetResult(t, body, false)
|
||||
|
||||
res := new(state.MPTRoot)
|
||||
res := &state.MPTRoot{Network: netmode.UnitTestNet}
|
||||
require.NoError(t, json.Unmarshal(rawRes, res))
|
||||
require.NotEqual(t, util.Uint256{}, res.Root) // be sure this test uses valid height
|
||||
|
||||
|
|
|
@ -3,6 +3,7 @@ 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"
|
||||
)
|
||||
|
@ -13,6 +14,7 @@ type (
|
|||
|
||||
// Message represents state-root related message.
|
||||
Message struct {
|
||||
Network netmode.Magic
|
||||
Type MessageType
|
||||
Payload io.Serializable
|
||||
}
|
||||
|
@ -25,8 +27,9 @@ const (
|
|||
)
|
||||
|
||||
// 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{
|
||||
Network: net,
|
||||
Type: typ,
|
||||
Payload: p,
|
||||
}
|
||||
|
@ -44,7 +47,7 @@ func (m *Message) DecodeBinary(r *io.BinReader) {
|
|||
case VoteT:
|
||||
m.Payload = new(Vote)
|
||||
case RootT:
|
||||
m.Payload = new(state.MPTRoot)
|
||||
m.Payload = &state.MPTRoot{Network: m.Network}
|
||||
default:
|
||||
r.Err = fmt.Errorf("invalid type: %x", m.Type)
|
||||
return
|
||||
|
|
|
@ -72,7 +72,7 @@ func (s *service) getIncompleteRoot(height uint32) *incompleteRoot {
|
|||
|
||||
func (s *service) sendValidatedRoot(r *state.MPTRoot) {
|
||||
w := io.NewBufBinWriter()
|
||||
m := NewMessage(RootT, r)
|
||||
m := NewMessage(s.Network, RootT, r)
|
||||
m.EncodeBinary(w.BinWriter)
|
||||
ep := &payload.Extensible{
|
||||
Network: s.Network,
|
||||
|
|
|
@ -61,6 +61,7 @@ const (
|
|||
func New(cfg config.StateRoot, log *zap.Logger, bc blockchainer.Blockchainer) (Service, error) {
|
||||
s := &service{
|
||||
StateRoot: bc.GetStateModule(),
|
||||
Network: bc.GetConfig().Magic,
|
||||
chain: bc,
|
||||
log: log,
|
||||
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.
|
||||
func (s *service) OnPayload(ep *payload.Extensible) error {
|
||||
m := new(Message)
|
||||
m := &Message{Network: s.Network}
|
||||
r := io.NewBinReaderFromBuf(ep.Data)
|
||||
m.DecodeBinary(r)
|
||||
if r.Err != nil {
|
||||
|
|
|
@ -55,7 +55,7 @@ func (s *service) signAndSend(r *state.MPTRoot) error {
|
|||
s.accMtx.RLock()
|
||||
myIndex := s.myIndex
|
||||
s.accMtx.RUnlock()
|
||||
msg := NewMessage(VoteT, &Vote{
|
||||
msg := NewMessage(s.Network, VoteT, &Vote{
|
||||
ValidatorIndex: int32(myIndex),
|
||||
Height: r.Index,
|
||||
Signature: sig,
|
||||
|
|
Loading…
Reference in a new issue