consensus: add network magic to hash data

Consensus payload's hash now depends on the network node is operating
in.
This commit is contained in:
Evgenii Stratonikov 2020-06-26 18:27:18 +03:00
parent 270377637a
commit 857ced8230
4 changed files with 37 additions and 13 deletions

View file

@ -136,7 +136,7 @@ func NewService(cfg Config) (Service, error) {
dbft.WithGetValidators(srv.getValidators), dbft.WithGetValidators(srv.getValidators),
dbft.WithGetConsensusAddress(srv.getConsensusAddress), dbft.WithGetConsensusAddress(srv.getConsensusAddress),
dbft.WithNewConsensusPayload(func() payload.ConsensusPayload { p := new(Payload); p.message = &message{}; return p }), dbft.WithNewConsensusPayload(srv.newPayload),
dbft.WithNewPrepareRequest(func() payload.PrepareRequest { return new(prepareRequest) }), dbft.WithNewPrepareRequest(func() payload.PrepareRequest { return new(prepareRequest) }),
dbft.WithNewPrepareResponse(func() payload.PrepareResponse { return new(prepareResponse) }), dbft.WithNewPrepareResponse(func() payload.PrepareResponse { return new(prepareResponse) }),
dbft.WithNewChangeView(func() payload.ChangeView { return new(changeView) }), dbft.WithNewChangeView(func() payload.ChangeView { return new(changeView) }),
@ -157,6 +157,17 @@ var (
_ block.Block = (*neoBlock)(nil) _ block.Block = (*neoBlock)(nil)
) )
// NewPayload creates new consensus payloa dfor the provided network.
func NewPayload(m netmode.Magic) *Payload {
return &Payload{
network: m,
}
}
func (s *service) newPayload() payload.ConsensusPayload {
return NewPayload(s.network)
}
func (s *service) Start() { func (s *service) Start() {
s.dbft.Start() s.dbft.Start()
s.Chain.SubscribeForBlocks(s.blockEvents) s.Chain.SubscribeForBlocks(s.blockEvents)

View file

@ -4,6 +4,7 @@ import (
"fmt" "fmt"
"github.com/nspcc-dev/dbft/payload" "github.com/nspcc-dev/dbft/payload"
"github.com/nspcc-dev/neo-go/pkg/config/netmode"
"github.com/nspcc-dev/neo-go/pkg/core" "github.com/nspcc-dev/neo-go/pkg/core"
"github.com/nspcc-dev/neo-go/pkg/core/interop" "github.com/nspcc-dev/neo-go/pkg/core/interop"
"github.com/nspcc-dev/neo-go/pkg/core/interop/crypto" "github.com/nspcc-dev/neo-go/pkg/core/interop/crypto"
@ -30,6 +31,7 @@ type (
Payload struct { Payload struct {
*message *message
network netmode.Magic
data []byte data []byte
version uint32 version uint32
validatorIndex uint16 validatorIndex uint16
@ -108,7 +110,7 @@ func (p Payload) GetRecoveryMessage() payload.RecoveryMessage {
// MarshalUnsigned implements payload.ConsensusPayload interface. // MarshalUnsigned implements payload.ConsensusPayload interface.
func (p Payload) MarshalUnsigned() []byte { func (p Payload) MarshalUnsigned() []byte {
w := io.NewBufBinWriter() w := io.NewBufBinWriter()
p.EncodeBinaryUnsigned(w.BinWriter) p.encodeHashData(w.BinWriter)
return w.Bytes() return w.Bytes()
} }
@ -116,6 +118,7 @@ func (p Payload) MarshalUnsigned() []byte {
// UnmarshalUnsigned implements payload.ConsensusPayload interface. // UnmarshalUnsigned implements payload.ConsensusPayload interface.
func (p *Payload) UnmarshalUnsigned(data []byte) error { func (p *Payload) UnmarshalUnsigned(data []byte) error {
r := io.NewBinReaderFromBuf(data) r := io.NewBinReaderFromBuf(data)
p.network = netmode.Magic(r.ReadU32LE())
p.DecodeBinaryUnsigned(r) p.DecodeBinaryUnsigned(r)
return r.Err return r.Err
@ -184,6 +187,11 @@ func (p *Payload) EncodeBinary(w *io.BinWriter) {
p.Witness.EncodeBinary(w) p.Witness.EncodeBinary(w)
} }
func (p *Payload) encodeHashData(w *io.BinWriter) {
w.WriteU32LE(uint32(p.network))
p.EncodeBinaryUnsigned(w)
}
// Sign signs payload using the private key. // Sign signs payload using the private key.
// It also sets corresponding verification and invocation scripts. // It also sets corresponding verification and invocation scripts.
func (p *Payload) Sign(key *privateKey) error { func (p *Payload) Sign(key *privateKey) error {
@ -241,7 +249,7 @@ func (p *Payload) DecodeBinaryUnsigned(r *io.BinReader) {
// Hash implements payload.ConsensusPayload interface. // Hash implements payload.ConsensusPayload interface.
func (p *Payload) Hash() util.Uint256 { func (p *Payload) Hash() util.Uint256 {
w := io.NewBufBinWriter() w := io.NewBufBinWriter()
p.EncodeBinaryUnsigned(w.BinWriter) p.encodeHashData(w.BinWriter)
if w.Err != nil { if w.Err != nil {
panic("failed to hash payload") panic("failed to hash payload")
} }

View file

@ -1,10 +1,12 @@
package consensus package consensus
import ( import (
"encoding/hex"
"math/rand" "math/rand"
"testing" "testing"
"github.com/nspcc-dev/dbft/payload" "github.com/nspcc-dev/dbft/payload"
"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/keys" "github.com/nspcc-dev/neo-go/pkg/crypto/keys"
"github.com/nspcc-dev/neo-go/pkg/internal/random" "github.com/nspcc-dev/neo-go/pkg/internal/random"
@ -73,18 +75,21 @@ func TestConsensusPayload_Setters(t *testing.T) {
require.Equal(t, pl, p.GetRecoveryMessage()) require.Equal(t, pl, p.GetRecoveryMessage())
} }
//TODO NEO3.0: Update binary func TestConsensusPayload_Verify(t *testing.T) {
/* // signed payload from testnet
func TestConsensusPayload_Hash(t *testing.T) { dataHex := "00000000a70b769e4af60878f6daa72be41770c62592c694bf9ead6b16b30ad90f28c4098cc704000400423000d5b4baae11191ac370a4d7860df01824fcea7f934d6461db6d4b7966ca3c135c8c262b7f23bbac13e73885223604141e062234d999068d9a74b77caeeb5271cf01420c4055ae8c7694c296e92da393f944b0dc1cd70d12de3ee944e9afc872d1db427fe87fcbe913709a8ec73e2f5acdfc0b7f0a96e9d63bad0a20e3226c882237f5c771290c2102a7834be9b32e2981d157cb5bbd3acb42cfd11ea5c3b10224d7a44e98c5910f1b0b410a906ad4"
dataHex := "00000000d8fb8d3b143b5f98468ef701909c976505a110a01e26c5e99be9a90cff979199b6fc33000400000000008d2000184dc95de24018f9ad71f4448a2b438eaca8b4b2ab6b4524b5a69a45d920c35103f3901444320656c390ff39c0062f5e8e138ce446a40c7e4ba1af1f8247ebbdf49295933715d3a67949714ff924f8a28cec5b954c71eca3bfaf0e9d4b1f87b4e21e9ba4ae18f97de71501b5c5d07edc200bd66a46b9b28b1a371f2195c10b0af90000e24018f900000000014140c9faaee59942f58da0e5268bc199632f2a3ad0fcbee68681a4437f140b49512e8d9efc6880eb44d3490782895a5794f35eeccee2923ce0c76fa7a1890f934eac232103c089d7122b840a4935234e82e26ae5efd0c2acb627239dc9f207311337b6f2c1ac"
data, err := hex.DecodeString(dataHex) data, err := hex.DecodeString(dataHex)
require.NoError(t, err) require.NoError(t, err)
var p Payload h, err := util.Uint160DecodeStringBE("31b7e7aea5131f74721e002c6a56b6885813f79e")
require.NoError(t, testserdes.DecodeBinary(data, &p)) require.NoError(t, err)
require.Equal(t, p.Hash().String(), "45859759c8491597804f1922773947e0d37bf54484af82f80cd642f7b063aa56")
p := NewPayload(netmode.TestNet)
require.NoError(t, testserdes.DecodeBinary(data, p))
require.NoError(t, p.decodeData())
require.True(t, p.Verify(h))
} }
*/
func TestConsensusPayload_Serializable(t *testing.T) { func TestConsensusPayload_Serializable(t *testing.T) {
for _, mt := range messageTypes { for _, mt := range messageTypes {
p := randomPayload(t, mt) p := randomPayload(t, mt)
@ -99,7 +104,7 @@ func TestConsensusPayload_Serializable(t *testing.T) {
require.Equal(t, p, actual) require.Equal(t, p, actual)
data = p.MarshalUnsigned() data = p.MarshalUnsigned()
pu := new(Payload) pu := NewPayload(netmode.Magic(rand.Uint32()))
require.NoError(t, pu.UnmarshalUnsigned(data)) require.NoError(t, pu.UnmarshalUnsigned(data))
assert.NoError(t, pu.decodeData()) assert.NoError(t, pu.decodeData())

View file

@ -144,7 +144,7 @@ func (m *Message) decodePayload() error {
case CMDBlock: case CMDBlock:
p = block.New(m.Network) p = block.New(m.Network)
case CMDConsensus: case CMDConsensus:
p = &consensus.Payload{} p = consensus.NewPayload(m.Network)
case CMDGetBlocks: case CMDGetBlocks:
fallthrough fallthrough
case CMDGetHeaders: case CMDGetHeaders: