forked from TrueCloudLab/neoneo-go
Merge pull request #3371 from nspcc-dev/upd-dbft
consensus: integrate dBFT pre-0.2.0
This commit is contained in:
commit
627a0abb57
23 changed files with 266 additions and 333 deletions
3
go.mod
3
go.mod
|
@ -14,7 +14,7 @@ require (
|
||||||
github.com/holiman/uint256 v1.2.4
|
github.com/holiman/uint256 v1.2.4
|
||||||
github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51
|
github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51
|
||||||
github.com/mr-tron/base58 v1.2.0
|
github.com/mr-tron/base58 v1.2.0
|
||||||
github.com/nspcc-dev/dbft v0.0.0-20230515113611-25db6ba61d5c
|
github.com/nspcc-dev/dbft v0.1.1-0.20240321205542-332ff86ba4c6
|
||||||
github.com/nspcc-dev/go-ordered-json v0.0.0-20240301084351-0246b013f8b2
|
github.com/nspcc-dev/go-ordered-json v0.0.0-20240301084351-0246b013f8b2
|
||||||
github.com/nspcc-dev/neo-go/pkg/interop v0.0.0-20240322141543-1840c057bdd7
|
github.com/nspcc-dev/neo-go/pkg/interop v0.0.0-20240322141543-1840c057bdd7
|
||||||
github.com/nspcc-dev/neofs-sdk-go v1.0.0-rc.11
|
github.com/nspcc-dev/neofs-sdk-go v1.0.0-rc.11
|
||||||
|
@ -55,7 +55,6 @@ require (
|
||||||
github.com/nspcc-dev/neofs-api-go/v2 v2.14.0 // indirect
|
github.com/nspcc-dev/neofs-api-go/v2 v2.14.0 // indirect
|
||||||
github.com/nspcc-dev/neofs-crypto v0.4.0 // indirect
|
github.com/nspcc-dev/neofs-crypto v0.4.0 // indirect
|
||||||
github.com/nspcc-dev/tzhash v1.7.0 // indirect
|
github.com/nspcc-dev/tzhash v1.7.0 // indirect
|
||||||
github.com/pkg/errors v0.9.1 // indirect
|
|
||||||
github.com/prometheus/client_model v0.5.0 // indirect
|
github.com/prometheus/client_model v0.5.0 // indirect
|
||||||
github.com/prometheus/common v0.48.0 // indirect
|
github.com/prometheus/common v0.48.0 // indirect
|
||||||
github.com/prometheus/procfs v0.12.0 // indirect
|
github.com/prometheus/procfs v0.12.0 // indirect
|
||||||
|
|
5
go.sum
5
go.sum
|
@ -88,8 +88,8 @@ github.com/mmcloughlin/addchain v0.4.0/go.mod h1:A86O+tHqZLMNO4w6ZZ4FlVQEadcoqky
|
||||||
github.com/mmcloughlin/profile v0.1.1/go.mod h1:IhHD7q1ooxgwTgjxQYkACGA77oFTDdFVejUS1/tS/qU=
|
github.com/mmcloughlin/profile v0.1.1/go.mod h1:IhHD7q1ooxgwTgjxQYkACGA77oFTDdFVejUS1/tS/qU=
|
||||||
github.com/mr-tron/base58 v1.2.0 h1:T/HDJBh4ZCPbU39/+c3rRvE0uKBQlU27+QI8LJ4t64o=
|
github.com/mr-tron/base58 v1.2.0 h1:T/HDJBh4ZCPbU39/+c3rRvE0uKBQlU27+QI8LJ4t64o=
|
||||||
github.com/mr-tron/base58 v1.2.0/go.mod h1:BinMc/sQntlIE1frQmRFPUoPA1Zkr8VRgBdjWI2mNwc=
|
github.com/mr-tron/base58 v1.2.0/go.mod h1:BinMc/sQntlIE1frQmRFPUoPA1Zkr8VRgBdjWI2mNwc=
|
||||||
github.com/nspcc-dev/dbft v0.0.0-20230515113611-25db6ba61d5c h1:uyK5aLbAhrnZtnvobJLN24gGUrlxIJAAFqiWl+liZuo=
|
github.com/nspcc-dev/dbft v0.1.1-0.20240321205542-332ff86ba4c6 h1:6rpKY0AvXQpL2ZpLTxGDJAM54ak6ziXghi4uLGUrSdg=
|
||||||
github.com/nspcc-dev/dbft v0.0.0-20230515113611-25db6ba61d5c/go.mod h1:kjBC9F8L25GR+kIHy/1KgG/KfcoGnVwIiyovgq1uszk=
|
github.com/nspcc-dev/dbft v0.1.1-0.20240321205542-332ff86ba4c6/go.mod h1:oFE6paSC/yfFh9mcNU6MheMGOYXK9+sPiRk3YMoz49o=
|
||||||
github.com/nspcc-dev/go-ordered-json v0.0.0-20240301084351-0246b013f8b2 h1:mD9hU3v+zJcnHAVmHnZKt3I++tvn30gBj2rP2PocZMk=
|
github.com/nspcc-dev/go-ordered-json v0.0.0-20240301084351-0246b013f8b2 h1:mD9hU3v+zJcnHAVmHnZKt3I++tvn30gBj2rP2PocZMk=
|
||||||
github.com/nspcc-dev/go-ordered-json v0.0.0-20240301084351-0246b013f8b2/go.mod h1:U5VfmPNM88P4RORFb6KSUVBdJBDhlqggJZYGXGPxOcc=
|
github.com/nspcc-dev/go-ordered-json v0.0.0-20240301084351-0246b013f8b2/go.mod h1:U5VfmPNM88P4RORFb6KSUVBdJBDhlqggJZYGXGPxOcc=
|
||||||
github.com/nspcc-dev/hrw v1.0.9 h1:17VcAuTtrstmFppBjfRiia4K2wA/ukXZhLFS8Y8rz5Y=
|
github.com/nspcc-dev/hrw v1.0.9 h1:17VcAuTtrstmFppBjfRiia4K2wA/ukXZhLFS8Y8rz5Y=
|
||||||
|
@ -119,7 +119,6 @@ github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1y
|
||||||
github.com/pierrec/lz4 v2.6.1+incompatible h1:9UY3+iC23yxF0UfGaYrGplQ+79Rg+h/q9FV9ix19jjM=
|
github.com/pierrec/lz4 v2.6.1+incompatible h1:9UY3+iC23yxF0UfGaYrGplQ+79Rg+h/q9FV9ix19jjM=
|
||||||
github.com/pierrec/lz4 v2.6.1+incompatible/go.mod h1:pdkljMzZIN41W+lC3N2tnIh5sFi+IEE17M5jbnwPHcY=
|
github.com/pierrec/lz4 v2.6.1+incompatible/go.mod h1:pdkljMzZIN41W+lC3N2tnIh5sFi+IEE17M5jbnwPHcY=
|
||||||
github.com/pkg/diff v0.0.0-20210226163009-20ebb0f2a09e/go.mod h1:pJLUxLENpZxwdsKMEsNbx1VGcRFpLqf3715MtcvvzbA=
|
github.com/pkg/diff v0.0.0-20210226163009-20ebb0f2a09e/go.mod h1:pJLUxLENpZxwdsKMEsNbx1VGcRFpLqf3715MtcvvzbA=
|
||||||
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
|
|
||||||
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||||
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
||||||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||||
|
|
|
@ -3,8 +3,7 @@ package consensus
|
||||||
import (
|
import (
|
||||||
"errors"
|
"errors"
|
||||||
|
|
||||||
"github.com/nspcc-dev/dbft/block"
|
"github.com/nspcc-dev/dbft"
|
||||||
"github.com/nspcc-dev/dbft/crypto"
|
|
||||||
"github.com/nspcc-dev/neo-go/pkg/config/netmode"
|
"github.com/nspcc-dev/neo-go/pkg/config/netmode"
|
||||||
coreb "github.com/nspcc-dev/neo-go/pkg/core/block"
|
coreb "github.com/nspcc-dev/neo-go/pkg/core/block"
|
||||||
"github.com/nspcc-dev/neo-go/pkg/core/transaction"
|
"github.com/nspcc-dev/neo-go/pkg/core/transaction"
|
||||||
|
@ -20,10 +19,10 @@ type neoBlock struct {
|
||||||
signature []byte
|
signature []byte
|
||||||
}
|
}
|
||||||
|
|
||||||
var _ block.Block = (*neoBlock)(nil)
|
var _ dbft.Block[util.Uint256] = (*neoBlock)(nil)
|
||||||
|
|
||||||
// Sign implements the block.Block interface.
|
// Sign implements the block.Block interface.
|
||||||
func (n *neoBlock) Sign(key crypto.PrivateKey) error {
|
func (n *neoBlock) Sign(key dbft.PrivateKey) error {
|
||||||
k := key.(*privateKey)
|
k := key.(*privateKey)
|
||||||
sig := k.PrivateKey.SignHashable(uint32(n.network), &n.Block)
|
sig := k.PrivateKey.SignHashable(uint32(n.network), &n.Block)
|
||||||
n.signature = sig
|
n.signature = sig
|
||||||
|
@ -31,7 +30,7 @@ func (n *neoBlock) Sign(key crypto.PrivateKey) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Verify implements the block.Block interface.
|
// Verify implements the block.Block interface.
|
||||||
func (n *neoBlock) Verify(key crypto.PublicKey, sign []byte) error {
|
func (n *neoBlock) Verify(key dbft.PublicKey, sign []byte) error {
|
||||||
k := key.(*publicKey)
|
k := key.(*publicKey)
|
||||||
if k.PublicKey.VerifyHashable(sign, uint32(n.network), &n.Block) {
|
if k.PublicKey.VerifyHashable(sign, uint32(n.network), &n.Block) {
|
||||||
return nil
|
return nil
|
||||||
|
@ -40,8 +39,8 @@ func (n *neoBlock) Verify(key crypto.PublicKey, sign []byte) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Transactions implements the block.Block interface.
|
// Transactions implements the block.Block interface.
|
||||||
func (n *neoBlock) Transactions() []block.Transaction {
|
func (n *neoBlock) Transactions() []dbft.Transaction[util.Uint256] {
|
||||||
txes := make([]block.Transaction, len(n.Block.Transactions))
|
txes := make([]dbft.Transaction[util.Uint256], len(n.Block.Transactions))
|
||||||
for i, tx := range n.Block.Transactions {
|
for i, tx := range n.Block.Transactions {
|
||||||
txes[i] = tx
|
txes[i] = tx
|
||||||
}
|
}
|
||||||
|
@ -50,16 +49,13 @@ func (n *neoBlock) Transactions() []block.Transaction {
|
||||||
}
|
}
|
||||||
|
|
||||||
// SetTransactions implements the block.Block interface.
|
// SetTransactions implements the block.Block interface.
|
||||||
func (n *neoBlock) SetTransactions(txes []block.Transaction) {
|
func (n *neoBlock) SetTransactions(txes []dbft.Transaction[util.Uint256]) {
|
||||||
n.Block.Transactions = make([]*transaction.Transaction, len(txes))
|
n.Block.Transactions = make([]*transaction.Transaction, len(txes))
|
||||||
for i, tx := range txes {
|
for i, tx := range txes {
|
||||||
n.Block.Transactions[i] = tx.(*transaction.Transaction)
|
n.Block.Transactions[i] = tx.(*transaction.Transaction)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Version implements the block.Block interface.
|
|
||||||
func (n *neoBlock) Version() uint32 { return n.Block.Version }
|
|
||||||
|
|
||||||
// PrevHash implements the block.Block interface.
|
// PrevHash implements the block.Block interface.
|
||||||
func (n *neoBlock) PrevHash() util.Uint256 { return n.Block.PrevHash }
|
func (n *neoBlock) PrevHash() util.Uint256 { return n.Block.PrevHash }
|
||||||
|
|
||||||
|
@ -72,11 +68,5 @@ func (n *neoBlock) Timestamp() uint64 { return n.Block.Timestamp * nsInMs }
|
||||||
// Index implements the block.Block interface.
|
// Index implements the block.Block interface.
|
||||||
func (n *neoBlock) Index() uint32 { return n.Block.Index }
|
func (n *neoBlock) Index() uint32 { return n.Block.Index }
|
||||||
|
|
||||||
// ConsensusData implements the block.Block interface.
|
|
||||||
func (n *neoBlock) ConsensusData() uint64 { return n.Block.Nonce }
|
|
||||||
|
|
||||||
// NextConsensus implements the block.Block interface.
|
|
||||||
func (n *neoBlock) NextConsensus() util.Uint160 { return n.Block.NextConsensus }
|
|
||||||
|
|
||||||
// Signature implements the block.Block interface.
|
// Signature implements the block.Block interface.
|
||||||
func (n *neoBlock) Signature() []byte { return n.signature }
|
func (n *neoBlock) Signature() []byte { return n.signature }
|
||||||
|
|
|
@ -3,7 +3,7 @@ package consensus
|
||||||
import (
|
import (
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/nspcc-dev/dbft/block"
|
"github.com/nspcc-dev/dbft"
|
||||||
"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/util"
|
"github.com/nspcc-dev/neo-go/pkg/util"
|
||||||
|
@ -22,9 +22,6 @@ func TestNeoBlock_Sign(t *testing.T) {
|
||||||
func TestNeoBlock_Setters(t *testing.T) {
|
func TestNeoBlock_Setters(t *testing.T) {
|
||||||
b := new(neoBlock)
|
b := new(neoBlock)
|
||||||
|
|
||||||
b.Block.Version = 1
|
|
||||||
require.EqualValues(t, 1, b.Version())
|
|
||||||
|
|
||||||
b.Block.Index = 12
|
b.Block.Index = 12
|
||||||
require.EqualValues(t, 12, b.Index())
|
require.EqualValues(t, 12, b.Index())
|
||||||
|
|
||||||
|
@ -35,13 +32,10 @@ func TestNeoBlock_Setters(t *testing.T) {
|
||||||
b.Block.MerkleRoot = util.Uint256{1, 2, 3, 4}
|
b.Block.MerkleRoot = util.Uint256{1, 2, 3, 4}
|
||||||
require.Equal(t, util.Uint256{1, 2, 3, 4}, b.MerkleRoot())
|
require.Equal(t, util.Uint256{1, 2, 3, 4}, b.MerkleRoot())
|
||||||
|
|
||||||
b.Block.NextConsensus = util.Uint160{9, 2}
|
|
||||||
require.Equal(t, util.Uint160{9, 2}, b.NextConsensus())
|
|
||||||
|
|
||||||
b.Block.PrevHash = util.Uint256{9, 8, 7}
|
b.Block.PrevHash = util.Uint256{9, 8, 7}
|
||||||
require.Equal(t, util.Uint256{9, 8, 7}, b.PrevHash())
|
require.Equal(t, util.Uint256{9, 8, 7}, b.PrevHash())
|
||||||
|
|
||||||
txx := []block.Transaction{transaction.New([]byte{byte(opcode.PUSH1)}, 1)}
|
txx := []dbft.Transaction[util.Uint256]{transaction.New([]byte{byte(opcode.PUSH1)}, 1)}
|
||||||
b.SetTransactions(txx)
|
b.SetTransactions(txx)
|
||||||
require.Equal(t, txx, b.Transactions())
|
require.Equal(t, txx, b.Transactions())
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,7 +3,6 @@ package consensus
|
||||||
import (
|
import (
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/nspcc-dev/dbft/payload"
|
|
||||||
"github.com/nspcc-dev/neo-go/internal/random"
|
"github.com/nspcc-dev/neo-go/internal/random"
|
||||||
"github.com/stretchr/testify/require"
|
"github.com/stretchr/testify/require"
|
||||||
)
|
)
|
||||||
|
@ -52,8 +51,8 @@ func getDifferentPayloads(t *testing.T, n int) (payloads []Payload) {
|
||||||
var sign [signatureSize]byte
|
var sign [signatureSize]byte
|
||||||
random.Fill(sign[:])
|
random.Fill(sign[:])
|
||||||
|
|
||||||
payloads[i].SetValidatorIndex(uint16(i))
|
payloads[i].message.ValidatorIndex = byte(i)
|
||||||
payloads[i].SetType(payload.MessageType(commitType))
|
payloads[i].message.Type = commitType
|
||||||
payloads[i].payload = &commit{
|
payloads[i].payload = &commit{
|
||||||
signature: sign,
|
signature: sign,
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
package consensus
|
package consensus
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/nspcc-dev/dbft/payload"
|
"github.com/nspcc-dev/dbft"
|
||||||
"github.com/nspcc-dev/neo-go/pkg/io"
|
"github.com/nspcc-dev/neo-go/pkg/io"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -9,10 +9,10 @@ import (
|
||||||
type changeView struct {
|
type changeView struct {
|
||||||
newViewNumber byte
|
newViewNumber byte
|
||||||
timestamp uint64
|
timestamp uint64
|
||||||
reason payload.ChangeViewReason
|
reason dbft.ChangeViewReason
|
||||||
}
|
}
|
||||||
|
|
||||||
var _ payload.ChangeView = (*changeView)(nil)
|
var _ dbft.ChangeView = (*changeView)(nil)
|
||||||
|
|
||||||
// EncodeBinary implements the io.Serializable interface.
|
// EncodeBinary implements the io.Serializable interface.
|
||||||
func (c *changeView) EncodeBinary(w *io.BinWriter) {
|
func (c *changeView) EncodeBinary(w *io.BinWriter) {
|
||||||
|
@ -23,23 +23,11 @@ func (c *changeView) EncodeBinary(w *io.BinWriter) {
|
||||||
// DecodeBinary implements the io.Serializable interface.
|
// DecodeBinary implements the io.Serializable interface.
|
||||||
func (c *changeView) DecodeBinary(r *io.BinReader) {
|
func (c *changeView) DecodeBinary(r *io.BinReader) {
|
||||||
c.timestamp = r.ReadU64LE()
|
c.timestamp = r.ReadU64LE()
|
||||||
c.reason = payload.ChangeViewReason(r.ReadB())
|
c.reason = dbft.ChangeViewReason(r.ReadB())
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewViewNumber implements the payload.ChangeView interface.
|
// NewViewNumber implements the payload.ChangeView interface.
|
||||||
func (c changeView) NewViewNumber() byte { return c.newViewNumber }
|
func (c changeView) NewViewNumber() byte { return c.newViewNumber }
|
||||||
|
|
||||||
// SetNewViewNumber implements the payload.ChangeView interface.
|
|
||||||
func (c *changeView) SetNewViewNumber(view byte) { c.newViewNumber = view }
|
|
||||||
|
|
||||||
// Timestamp implements the payload.ChangeView interface.
|
|
||||||
func (c changeView) Timestamp() uint64 { return c.timestamp * nsInMs }
|
|
||||||
|
|
||||||
// SetTimestamp implements the payload.ChangeView interface.
|
|
||||||
func (c *changeView) SetTimestamp(ts uint64) { c.timestamp = ts / nsInMs }
|
|
||||||
|
|
||||||
// Reason implements the payload.ChangeView interface.
|
// Reason implements the payload.ChangeView interface.
|
||||||
func (c changeView) Reason() payload.ChangeViewReason { return c.reason }
|
func (c changeView) Reason() dbft.ChangeViewReason { return c.reason }
|
||||||
|
|
||||||
// SetReason implements the payload.ChangeView interface.
|
|
||||||
func (c *changeView) SetReason(reason payload.ChangeViewReason) { c.reason = reason }
|
|
||||||
|
|
|
@ -3,15 +3,16 @@ package consensus
|
||||||
import (
|
import (
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
|
"github.com/nspcc-dev/dbft"
|
||||||
"github.com/stretchr/testify/require"
|
"github.com/stretchr/testify/require"
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestChangeView_Setters(t *testing.T) {
|
func TestChangeView_Getters(t *testing.T) {
|
||||||
var c changeView
|
var c = &changeView{
|
||||||
|
newViewNumber: 2,
|
||||||
|
reason: dbft.CVTimeout,
|
||||||
|
}
|
||||||
|
|
||||||
c.SetTimestamp(123 * nsInMs)
|
|
||||||
require.EqualValues(t, 123*nsInMs, c.Timestamp())
|
|
||||||
|
|
||||||
c.SetNewViewNumber(2)
|
|
||||||
require.EqualValues(t, 2, c.NewViewNumber())
|
require.EqualValues(t, 2, c.NewViewNumber())
|
||||||
|
require.EqualValues(t, dbft.CVTimeout, c.Reason())
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
package consensus
|
package consensus
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/nspcc-dev/dbft/payload"
|
"github.com/nspcc-dev/dbft"
|
||||||
"github.com/nspcc-dev/neo-go/pkg/io"
|
"github.com/nspcc-dev/neo-go/pkg/io"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -14,7 +14,7 @@ type commit struct {
|
||||||
// without a leading byte (0x04, uncompressed).
|
// without a leading byte (0x04, uncompressed).
|
||||||
const signatureSize = 64
|
const signatureSize = 64
|
||||||
|
|
||||||
var _ payload.Commit = (*commit)(nil)
|
var _ dbft.Commit = (*commit)(nil)
|
||||||
|
|
||||||
// EncodeBinary implements the io.Serializable interface.
|
// EncodeBinary implements the io.Serializable interface.
|
||||||
func (c *commit) EncodeBinary(w *io.BinWriter) {
|
func (c *commit) EncodeBinary(w *io.BinWriter) {
|
||||||
|
@ -28,8 +28,3 @@ func (c *commit) DecodeBinary(r *io.BinReader) {
|
||||||
|
|
||||||
// Signature implements the payload.Commit interface.
|
// Signature implements the payload.Commit interface.
|
||||||
func (c commit) Signature() []byte { return c.signature[:] }
|
func (c commit) Signature() []byte { return c.signature[:] }
|
||||||
|
|
||||||
// SetSignature implements the payload.Commit interface.
|
|
||||||
func (c *commit) SetSignature(signature []byte) {
|
|
||||||
copy(c.signature[:], signature)
|
|
||||||
}
|
|
||||||
|
|
|
@ -7,11 +7,12 @@ import (
|
||||||
"github.com/stretchr/testify/require"
|
"github.com/stretchr/testify/require"
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestCommit_Setters(t *testing.T) {
|
func TestCommit_Getters(t *testing.T) {
|
||||||
var sign [signatureSize]byte
|
var sign [signatureSize]byte
|
||||||
random.Fill(sign[:])
|
random.Fill(sign[:])
|
||||||
|
|
||||||
var c commit
|
var c = &commit{
|
||||||
c.SetSignature(sign[:])
|
signature: sign,
|
||||||
|
}
|
||||||
require.Equal(t, sign[:], c.Signature())
|
require.Equal(t, sign[:], c.Signature())
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,9 +8,7 @@ import (
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/nspcc-dev/dbft"
|
"github.com/nspcc-dev/dbft"
|
||||||
"github.com/nspcc-dev/dbft/block"
|
"github.com/nspcc-dev/dbft/timer"
|
||||||
"github.com/nspcc-dev/dbft/crypto"
|
|
||||||
"github.com/nspcc-dev/dbft/payload"
|
|
||||||
"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/config/netmode"
|
||||||
coreb "github.com/nspcc-dev/neo-go/pkg/core/block"
|
coreb "github.com/nspcc-dev/neo-go/pkg/core/block"
|
||||||
|
@ -88,7 +86,7 @@ type service struct {
|
||||||
log *zap.Logger
|
log *zap.Logger
|
||||||
// txx is a fifo cache which stores miner transactions.
|
// txx is a fifo cache which stores miner transactions.
|
||||||
txx *relayCache
|
txx *relayCache
|
||||||
dbft *dbft.DBFT
|
dbft *dbft.DBFT[util.Uint256]
|
||||||
// messages and transactions are channels needed to process
|
// messages and transactions are channels needed to process
|
||||||
// everything in single thread.
|
// everything in single thread.
|
||||||
messages chan Payload
|
messages chan Payload
|
||||||
|
@ -181,48 +179,46 @@ func NewService(cfg Config) (Service, error) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
srv.dbft = dbft.New(
|
srv.dbft, err = dbft.New[util.Uint256](
|
||||||
dbft.WithLogger(srv.log),
|
dbft.WithTimer[util.Uint256](timer.New()),
|
||||||
dbft.WithSecondsPerBlock(cfg.TimePerBlock),
|
dbft.WithLogger[util.Uint256](srv.log),
|
||||||
dbft.WithGetKeyPair(srv.getKeyPair),
|
dbft.WithSecondsPerBlock[util.Uint256](cfg.TimePerBlock),
|
||||||
|
dbft.WithGetKeyPair[util.Uint256](srv.getKeyPair),
|
||||||
dbft.WithRequestTx(cfg.RequestTx),
|
dbft.WithRequestTx(cfg.RequestTx),
|
||||||
dbft.WithStopTxFlow(cfg.StopTxFlow),
|
dbft.WithStopTxFlow[util.Uint256](cfg.StopTxFlow),
|
||||||
dbft.WithGetTx(srv.getTx),
|
dbft.WithGetTx[util.Uint256](srv.getTx),
|
||||||
dbft.WithGetVerified(srv.getVerifiedTx),
|
dbft.WithGetVerified[util.Uint256](srv.getVerifiedTx),
|
||||||
dbft.WithBroadcast(srv.broadcast),
|
dbft.WithBroadcast[util.Uint256](srv.broadcast),
|
||||||
dbft.WithProcessBlock(srv.processBlock),
|
dbft.WithProcessBlock[util.Uint256](srv.processBlock),
|
||||||
dbft.WithVerifyBlock(srv.verifyBlock),
|
dbft.WithVerifyBlock[util.Uint256](srv.verifyBlock),
|
||||||
dbft.WithGetBlock(srv.getBlock),
|
dbft.WithGetBlock[util.Uint256](srv.getBlock),
|
||||||
dbft.WithWatchOnly(func() bool { return false }),
|
dbft.WithWatchOnly[util.Uint256](func() bool { return false }),
|
||||||
dbft.WithNewBlockFromContext(srv.newBlockFromContext),
|
dbft.WithNewBlockFromContext[util.Uint256](srv.newBlockFromContext),
|
||||||
dbft.WithCurrentHeight(cfg.Chain.BlockHeight),
|
dbft.WithCurrentHeight[util.Uint256](cfg.Chain.BlockHeight),
|
||||||
dbft.WithCurrentBlockHash(cfg.Chain.CurrentBlockHash),
|
dbft.WithCurrentBlockHash(cfg.Chain.CurrentBlockHash),
|
||||||
dbft.WithGetValidators(srv.getValidators),
|
dbft.WithGetValidators[util.Uint256](srv.getValidators),
|
||||||
dbft.WithGetConsensusAddress(srv.getConsensusAddress),
|
|
||||||
|
|
||||||
dbft.WithNewConsensusPayload(srv.newPayload),
|
dbft.WithNewConsensusPayload[util.Uint256](srv.newPayload),
|
||||||
dbft.WithNewPrepareRequest(srv.newPrepareRequest),
|
dbft.WithNewPrepareRequest[util.Uint256](srv.newPrepareRequest),
|
||||||
dbft.WithNewPrepareResponse(func() payload.PrepareResponse { return new(prepareResponse) }),
|
dbft.WithNewPrepareResponse[util.Uint256](srv.newPrepareResponse),
|
||||||
dbft.WithNewChangeView(func() payload.ChangeView { return new(changeView) }),
|
dbft.WithNewChangeView[util.Uint256](srv.newChangeView),
|
||||||
dbft.WithNewCommit(func() payload.Commit { return new(commit) }),
|
dbft.WithNewCommit[util.Uint256](srv.newCommit),
|
||||||
dbft.WithNewRecoveryRequest(func() payload.RecoveryRequest { return new(recoveryRequest) }),
|
dbft.WithNewRecoveryRequest[util.Uint256](srv.newRecoveryRequest),
|
||||||
dbft.WithNewRecoveryMessage(func() payload.RecoveryMessage {
|
dbft.WithNewRecoveryMessage[util.Uint256](srv.newRecoveryMessage),
|
||||||
return &recoveryMessage{stateRootEnabled: srv.ProtocolConfiguration.StateRootInHeader}
|
dbft.WithVerifyPrepareRequest[util.Uint256](srv.verifyRequest),
|
||||||
}),
|
dbft.WithVerifyPrepareResponse[util.Uint256](srv.verifyResponse),
|
||||||
dbft.WithVerifyPrepareRequest(srv.verifyRequest),
|
|
||||||
dbft.WithVerifyPrepareResponse(func(_ payload.ConsensusPayload) error { return nil }),
|
|
||||||
)
|
)
|
||||||
|
|
||||||
if srv.dbft == nil {
|
if err != nil {
|
||||||
return nil, errors.New("can't initialize dBFT")
|
return nil, fmt.Errorf("can't initialize dBFT: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
return srv, nil
|
return srv, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
var (
|
var (
|
||||||
_ block.Transaction = (*transaction.Transaction)(nil)
|
_ dbft.Transaction[util.Uint256] = (*transaction.Transaction)(nil)
|
||||||
_ block.Block = (*neoBlock)(nil)
|
_ dbft.Block[util.Uint256] = (*neoBlock)(nil)
|
||||||
)
|
)
|
||||||
|
|
||||||
// NewPayload creates a new consensus payload for the provided network.
|
// NewPayload creates a new consensus payload for the provided network.
|
||||||
|
@ -238,17 +234,17 @@ func NewPayload(m netmode.Magic, stateRootEnabled bool) *Payload {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *service) newPayload(c *dbft.Context, t payload.MessageType, msg any) payload.ConsensusPayload {
|
func (s *service) newPayload(c *dbft.Context[util.Uint256], t dbft.MessageType, msg any) dbft.ConsensusPayload[util.Uint256] {
|
||||||
cp := NewPayload(s.ProtocolConfiguration.Magic, s.ProtocolConfiguration.StateRootInHeader)
|
cp := NewPayload(s.ProtocolConfiguration.Magic, s.ProtocolConfiguration.StateRootInHeader)
|
||||||
cp.SetHeight(c.BlockIndex)
|
cp.BlockIndex = c.BlockIndex
|
||||||
cp.SetValidatorIndex(uint16(c.MyIndex))
|
cp.message.ValidatorIndex = byte(c.MyIndex)
|
||||||
cp.SetViewNumber(c.ViewNumber)
|
cp.message.ViewNumber = c.ViewNumber
|
||||||
cp.SetType(t)
|
cp.message.Type = messageType(t)
|
||||||
if pr, ok := msg.(*prepareRequest); ok {
|
if pr, ok := msg.(*prepareRequest); ok {
|
||||||
pr.SetPrevHash(s.dbft.PrevHash)
|
pr.prevHash = s.dbft.PrevHash
|
||||||
pr.SetVersion(s.dbft.Version)
|
pr.version = coreb.VersionInitial
|
||||||
}
|
}
|
||||||
cp.SetPayload(msg)
|
cp.payload = msg.(io.Serializable)
|
||||||
|
|
||||||
cp.Extensible.ValidBlockStart = 0
|
cp.Extensible.ValidBlockStart = 0
|
||||||
cp.Extensible.ValidBlockEnd = c.BlockIndex
|
cp.Extensible.ValidBlockEnd = c.BlockIndex
|
||||||
|
@ -257,8 +253,12 @@ func (s *service) newPayload(c *dbft.Context, t payload.MessageType, msg any) pa
|
||||||
return cp
|
return cp
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *service) newPrepareRequest() payload.PrepareRequest {
|
func (s *service) newPrepareRequest(ts uint64, nonce uint64, transactionsHashes []util.Uint256) dbft.PrepareRequest[util.Uint256] {
|
||||||
r := new(prepareRequest)
|
r := &prepareRequest{
|
||||||
|
timestamp: ts / nsInMs,
|
||||||
|
nonce: nonce,
|
||||||
|
transactionHashes: transactionsHashes,
|
||||||
|
}
|
||||||
if s.ProtocolConfiguration.StateRootInHeader {
|
if s.ProtocolConfiguration.StateRootInHeader {
|
||||||
r.stateRootEnabled = true
|
r.stateRootEnabled = true
|
||||||
if sr, err := s.Chain.GetStateRoot(s.dbft.BlockIndex - 1); err == nil {
|
if sr, err := s.Chain.GetStateRoot(s.dbft.BlockIndex - 1); err == nil {
|
||||||
|
@ -270,6 +270,38 @@ func (s *service) newPrepareRequest() payload.PrepareRequest {
|
||||||
return r
|
return r
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (s *service) newPrepareResponse(preparationHash util.Uint256) dbft.PrepareResponse[util.Uint256] {
|
||||||
|
return &prepareResponse{
|
||||||
|
preparationHash: preparationHash,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *service) newChangeView(newViewNumber byte, reason dbft.ChangeViewReason, ts uint64) dbft.ChangeView {
|
||||||
|
return &changeView{
|
||||||
|
newViewNumber: newViewNumber,
|
||||||
|
timestamp: ts / nsInMs,
|
||||||
|
reason: reason,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *service) newCommit(signature []byte) dbft.Commit {
|
||||||
|
c := new(commit)
|
||||||
|
copy(c.signature[:], signature)
|
||||||
|
return c
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *service) newRecoveryRequest(ts uint64) dbft.RecoveryRequest {
|
||||||
|
return &recoveryRequest{
|
||||||
|
timestamp: ts / nsInMs,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *service) newRecoveryMessage() dbft.RecoveryMessage[util.Uint256] {
|
||||||
|
return &recoveryMessage{
|
||||||
|
stateRootEnabled: s.ProtocolConfiguration.StateRootInHeader,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Name returns service name.
|
// Name returns service name.
|
||||||
func (s *service) Name() string {
|
func (s *service) Name() string {
|
||||||
return "consensus"
|
return "consensus"
|
||||||
|
@ -315,18 +347,18 @@ events:
|
||||||
s.Chain.UnsubscribeFromBlocks(s.blockEvents)
|
s.Chain.UnsubscribeFromBlocks(s.blockEvents)
|
||||||
break events
|
break events
|
||||||
case <-s.dbft.Timer.C():
|
case <-s.dbft.Timer.C():
|
||||||
hv := s.dbft.Timer.HV()
|
h, v := s.dbft.Timer.Height(), s.dbft.Timer.View()
|
||||||
s.log.Debug("timer fired",
|
s.log.Debug("timer fired",
|
||||||
zap.Uint32("height", hv.Height),
|
zap.Uint32("height", h),
|
||||||
zap.Uint("view", uint(hv.View)))
|
zap.Uint("view", uint(v)))
|
||||||
s.dbft.OnTimeout(hv)
|
s.dbft.OnTimeout(h, v)
|
||||||
case msg := <-s.messages:
|
case msg := <-s.messages:
|
||||||
fields := []zap.Field{
|
fields := []zap.Field{
|
||||||
zap.Uint8("from", msg.message.ValidatorIndex),
|
zap.Uint8("from", msg.message.ValidatorIndex),
|
||||||
zap.Stringer("type", msg.Type()),
|
zap.Stringer("type", msg.Type()),
|
||||||
}
|
}
|
||||||
|
|
||||||
if msg.Type() == payload.RecoveryMessageType {
|
if msg.Type() == dbft.RecoveryMessageType {
|
||||||
rec := msg.GetRecoveryMessage().(*recoveryMessage)
|
rec := msg.GetRecoveryMessage().(*recoveryMessage)
|
||||||
if rec.preparationHash == nil {
|
if rec.preparationHash == nil {
|
||||||
req := rec.GetPrepareRequest(&msg, s.dbft.Validators, uint16(s.dbft.PrimaryIndex))
|
req := rec.GetPrepareRequest(&msg, s.dbft.Validators, uint16(s.dbft.PrimaryIndex))
|
||||||
|
@ -389,7 +421,7 @@ func (s *service) handleChainBlock(b *coreb.Block) {
|
||||||
zap.Uint32("dbft index", s.dbft.BlockIndex),
|
zap.Uint32("dbft index", s.dbft.BlockIndex),
|
||||||
zap.Uint32("chain index", s.Chain.BlockHeight()))
|
zap.Uint32("chain index", s.Chain.BlockHeight()))
|
||||||
s.postBlock(b)
|
s.postBlock(b)
|
||||||
s.dbft.InitializeConsensus(0, b.Timestamp*nsInMs)
|
s.dbft.Reset(b.Timestamp * nsInMs)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -404,7 +436,7 @@ func (s *service) validatePayload(p *Payload) bool {
|
||||||
return p.Sender == h
|
return p.Sender == h
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *service) getKeyPair(pubs []crypto.PublicKey) (int, crypto.PrivateKey, crypto.PublicKey) {
|
func (s *service) getKeyPair(pubs []dbft.PublicKey) (int, dbft.PrivateKey, dbft.PublicKey) {
|
||||||
if s.wallet != nil {
|
if s.wallet != nil {
|
||||||
for i := range pubs {
|
for i := range pubs {
|
||||||
sh := pubs[i].(*publicKey).GetScriptHash()
|
sh := pubs[i].(*publicKey).GetScriptHash()
|
||||||
|
@ -466,7 +498,7 @@ func (s *service) OnTransaction(tx *transaction.Transaction) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *service) broadcast(p payload.ConsensusPayload) {
|
func (s *service) broadcast(p dbft.ConsensusPayload[util.Uint256]) {
|
||||||
if err := p.(*Payload).Sign(s.dbft.Priv.(*privateKey)); err != nil {
|
if err := p.(*Payload).Sign(s.dbft.Priv.(*privateKey)); err != nil {
|
||||||
s.log.Warn("can't sign consensus payload", zap.Error(err))
|
s.log.Warn("can't sign consensus payload", zap.Error(err))
|
||||||
}
|
}
|
||||||
|
@ -475,7 +507,7 @@ func (s *service) broadcast(p payload.ConsensusPayload) {
|
||||||
s.Config.Broadcast(ep)
|
s.Config.Broadcast(ep)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *service) getTx(h util.Uint256) block.Transaction {
|
func (s *service) getTx(h util.Uint256) dbft.Transaction[util.Uint256] {
|
||||||
if tx := s.txx.Get(h); tx != nil {
|
if tx := s.txx.Get(h); tx != nil {
|
||||||
return tx.(*transaction.Transaction)
|
return tx.(*transaction.Transaction)
|
||||||
}
|
}
|
||||||
|
@ -491,7 +523,7 @@ func (s *service) getTx(h util.Uint256) block.Transaction {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *service) verifyBlock(b block.Block) bool {
|
func (s *service) verifyBlock(b dbft.Block[util.Uint256]) bool {
|
||||||
coreb := &b.(*neoBlock).Block
|
coreb := &b.(*neoBlock).Block
|
||||||
|
|
||||||
if s.Chain.BlockHeight() >= coreb.Index {
|
if s.Chain.BlockHeight() >= coreb.Index {
|
||||||
|
@ -558,12 +590,12 @@ var (
|
||||||
errInvalidTransactionsCount = errors.New("invalid transactions count")
|
errInvalidTransactionsCount = errors.New("invalid transactions count")
|
||||||
)
|
)
|
||||||
|
|
||||||
func (s *service) verifyRequest(p payload.ConsensusPayload) error {
|
func (s *service) verifyRequest(p dbft.ConsensusPayload[util.Uint256]) error {
|
||||||
req := p.GetPrepareRequest().(*prepareRequest)
|
req := p.GetPrepareRequest().(*prepareRequest)
|
||||||
if req.prevHash != s.dbft.PrevHash {
|
if req.prevHash != s.dbft.PrevHash {
|
||||||
return errInvalidPrevHash
|
return errInvalidPrevHash
|
||||||
}
|
}
|
||||||
if req.version != s.dbft.Version {
|
if req.version != coreb.VersionInitial {
|
||||||
return errInvalidVersion
|
return errInvalidVersion
|
||||||
}
|
}
|
||||||
if s.ProtocolConfiguration.StateRootInHeader {
|
if s.ProtocolConfiguration.StateRootInHeader {
|
||||||
|
@ -583,7 +615,11 @@ func (s *service) verifyRequest(p payload.ConsensusPayload) error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *service) processBlock(b block.Block) {
|
func (s *service) verifyResponse(p dbft.ConsensusPayload[util.Uint256]) error {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *service) processBlock(b dbft.Block[util.Uint256]) {
|
||||||
bb := &b.(*neoBlock).Block
|
bb := &b.(*neoBlock).Block
|
||||||
bb.Script = *(s.getBlockWitness(bb))
|
bb.Script = *(s.getBlockWitness(bb))
|
||||||
|
|
||||||
|
@ -638,7 +674,7 @@ func (s *service) getBlockWitness(b *coreb.Block) *transaction.Witness {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *service) getBlock(h util.Uint256) block.Block {
|
func (s *service) getBlock(h util.Uint256) dbft.Block[util.Uint256] {
|
||||||
b, err := s.Chain.GetBlock(h)
|
b, err := s.Chain.GetBlock(h)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil
|
return nil
|
||||||
|
@ -647,7 +683,7 @@ func (s *service) getBlock(h util.Uint256) block.Block {
|
||||||
return &neoBlock{network: s.ProtocolConfiguration.Magic, Block: *b}
|
return &neoBlock{network: s.ProtocolConfiguration.Magic, Block: *b}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *service) getVerifiedTx() []block.Transaction {
|
func (s *service) getVerifiedTx() []dbft.Transaction[util.Uint256] {
|
||||||
pool := s.Config.Chain.GetMemPool()
|
pool := s.Config.Chain.GetMemPool()
|
||||||
|
|
||||||
var txx []*transaction.Transaction
|
var txx []*transaction.Transaction
|
||||||
|
@ -671,7 +707,7 @@ func (s *service) getVerifiedTx() []block.Transaction {
|
||||||
txx = s.Config.Chain.ApplyPolicyToTxSet(txx)
|
txx = s.Config.Chain.ApplyPolicyToTxSet(txx)
|
||||||
}
|
}
|
||||||
|
|
||||||
res := make([]block.Transaction, len(txx))
|
res := make([]dbft.Transaction[util.Uint256], len(txx))
|
||||||
for i := range txx {
|
for i := range txx {
|
||||||
res[i] = txx[i]
|
res[i] = txx[i]
|
||||||
}
|
}
|
||||||
|
@ -679,7 +715,7 @@ func (s *service) getVerifiedTx() []block.Transaction {
|
||||||
return res
|
return res
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *service) getValidators(txes ...block.Transaction) []crypto.PublicKey {
|
func (s *service) getValidators(txes ...dbft.Transaction[util.Uint256]) []dbft.PublicKey {
|
||||||
var (
|
var (
|
||||||
pKeys []*keys.PublicKey
|
pKeys []*keys.PublicKey
|
||||||
err error
|
err error
|
||||||
|
@ -699,7 +735,7 @@ func (s *service) getValidators(txes ...block.Transaction) []crypto.PublicKey {
|
||||||
s.log.Error("error while trying to get validators", zap.Error(err))
|
s.log.Error("error while trying to get validators", zap.Error(err))
|
||||||
}
|
}
|
||||||
|
|
||||||
pubs := make([]crypto.PublicKey, len(pKeys))
|
pubs := make([]dbft.PublicKey, len(pKeys))
|
||||||
for i := range pKeys {
|
for i := range pKeys {
|
||||||
pubs[i] = &publicKey{PublicKey: pKeys[i]}
|
pubs[i] = &publicKey{PublicKey: pKeys[i]}
|
||||||
}
|
}
|
||||||
|
@ -707,11 +743,7 @@ func (s *service) getValidators(txes ...block.Transaction) []crypto.PublicKey {
|
||||||
return pubs
|
return pubs
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *service) getConsensusAddress(validators ...crypto.PublicKey) util.Uint160 {
|
func convertKeys(validators []dbft.PublicKey) (pubs []*keys.PublicKey) {
|
||||||
return util.Uint160{}
|
|
||||||
}
|
|
||||||
|
|
||||||
func convertKeys(validators []crypto.PublicKey) (pubs []*keys.PublicKey) {
|
|
||||||
pubs = make([]*keys.PublicKey, len(validators))
|
pubs = make([]*keys.PublicKey, len(validators))
|
||||||
for i, k := range validators {
|
for i, k := range validators {
|
||||||
pubs[i] = k.(*publicKey).PublicKey
|
pubs[i] = k.(*publicKey).PublicKey
|
||||||
|
@ -720,7 +752,7 @@ func convertKeys(validators []crypto.PublicKey) (pubs []*keys.PublicKey) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *service) newBlockFromContext(ctx *dbft.Context) block.Block {
|
func (s *service) newBlockFromContext(ctx *dbft.Context[util.Uint256]) dbft.Block[util.Uint256] {
|
||||||
block := &neoBlock{network: s.ProtocolConfiguration.Magic}
|
block := &neoBlock{network: s.ProtocolConfiguration.Magic}
|
||||||
|
|
||||||
block.Block.Timestamp = ctx.Timestamp / nsInMs
|
block.Block.Timestamp = ctx.Timestamp / nsInMs
|
||||||
|
@ -750,9 +782,9 @@ func (s *service) newBlockFromContext(ctx *dbft.Context) block.Block {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
s.log.Fatal(fmt.Sprintf("failed to create multisignature script: %s", err.Error()))
|
s.log.Fatal(fmt.Sprintf("failed to create multisignature script: %s", err.Error()))
|
||||||
}
|
}
|
||||||
block.Block.NextConsensus = crypto.Hash160(script)
|
block.Block.NextConsensus = hash.Hash160(script)
|
||||||
block.Block.PrevHash = ctx.PrevHash
|
block.Block.PrevHash = ctx.PrevHash
|
||||||
block.Block.Version = ctx.Version
|
block.Block.Version = coreb.VersionInitial
|
||||||
|
|
||||||
primaryIndex := byte(ctx.PrimaryIndex)
|
primaryIndex := byte(ctx.PrimaryIndex)
|
||||||
block.Block.PrimaryIndex = primaryIndex
|
block.Block.PrimaryIndex = primaryIndex
|
||||||
|
|
|
@ -4,9 +4,7 @@ import (
|
||||||
"testing"
|
"testing"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/nspcc-dev/dbft/block"
|
"github.com/nspcc-dev/dbft"
|
||||||
"github.com/nspcc-dev/dbft/payload"
|
|
||||||
"github.com/nspcc-dev/dbft/timer"
|
|
||||||
"github.com/nspcc-dev/neo-go/internal/random"
|
"github.com/nspcc-dev/neo-go/internal/random"
|
||||||
"github.com/nspcc-dev/neo-go/internal/testchain"
|
"github.com/nspcc-dev/neo-go/internal/testchain"
|
||||||
"github.com/nspcc-dev/neo-go/pkg/config"
|
"github.com/nspcc-dev/neo-go/pkg/config"
|
||||||
|
@ -38,7 +36,7 @@ func TestNewService(t *testing.T) {
|
||||||
signTx(t, srv.Chain, tx)
|
signTx(t, srv.Chain, tx)
|
||||||
require.NoError(t, srv.Chain.PoolTx(tx))
|
require.NoError(t, srv.Chain.PoolTx(tx))
|
||||||
|
|
||||||
var txx []block.Transaction
|
var txx []dbft.Transaction[util.Uint256]
|
||||||
require.NotPanics(t, func() { txx = srv.getVerifiedTx() })
|
require.NotPanics(t, func() { txx = srv.getVerifiedTx() })
|
||||||
require.Len(t, txx, 1)
|
require.Len(t, txx, 1)
|
||||||
require.Equal(t, tx, txx[0])
|
require.Equal(t, tx, txx[0])
|
||||||
|
@ -65,10 +63,10 @@ func TestNewWatchingService(t *testing.T) {
|
||||||
|
|
||||||
func collectBlock(t *testing.T, bc *core.Blockchain, srv *service) {
|
func collectBlock(t *testing.T, bc *core.Blockchain, srv *service) {
|
||||||
h := bc.BlockHeight()
|
h := bc.BlockHeight()
|
||||||
srv.dbft.OnTimeout(timer.HV{Height: srv.dbft.Context.BlockIndex}) // Collect and add block to the chain.
|
srv.dbft.OnTimeout(srv.dbft.Context.BlockIndex, 0) // Collect and add block to the chain.
|
||||||
header, err := bc.GetHeader(bc.GetHeaderHash(h + 1))
|
header, err := bc.GetHeader(bc.GetHeaderHash(h + 1))
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
srv.dbft.InitializeConsensus(0, header.Timestamp*nsInMs) // Init consensus manually at the next height, as we don't run the consensus service.
|
srv.dbft.Reset(header.Timestamp * nsInMs) // Init consensus manually at the next height, as we don't run the consensus service.
|
||||||
}
|
}
|
||||||
|
|
||||||
func initServiceNextConsensus(t *testing.T, newAcc *wallet.Account, offset uint32) (*service, *wallet.Account) {
|
func initServiceNextConsensus(t *testing.T, newAcc *wallet.Account, offset uint32) (*service, *wallet.Account) {
|
||||||
|
@ -102,7 +100,7 @@ func initServiceNextConsensus(t *testing.T, newAcc *wallet.Account, offset uint3
|
||||||
srv.dbft.Start(0)
|
srv.dbft.Start(0)
|
||||||
header, err := bc.GetHeader(bc.GetHeaderHash(h + 1))
|
header, err := bc.GetHeader(bc.GetHeaderHash(h + 1))
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
srv.dbft.InitializeConsensus(0, header.Timestamp*nsInMs) // Init consensus manually at the next height, as we don't run the consensus service.
|
srv.dbft.Reset(header.Timestamp * nsInMs) // Init consensus manually at the next height, as we don't run the consensus service.
|
||||||
|
|
||||||
// Register new candidate.
|
// Register new candidate.
|
||||||
b.Reset()
|
b.Reset()
|
||||||
|
@ -214,14 +212,14 @@ func TestService_GetVerified(t *testing.T) {
|
||||||
p := new(Payload)
|
p := new(Payload)
|
||||||
// One PrepareRequest and three ChangeViews.
|
// One PrepareRequest and three ChangeViews.
|
||||||
if i == 1 {
|
if i == 1 {
|
||||||
p.SetType(payload.PrepareRequestType)
|
p.message.Type = messageType(dbft.PrepareRequestType)
|
||||||
p.SetPayload(&prepareRequest{prevHash: srv.Chain.CurrentBlockHash(), transactionHashes: hashes})
|
p.payload = &prepareRequest{prevHash: srv.Chain.CurrentBlockHash(), transactionHashes: hashes}
|
||||||
} else {
|
} else {
|
||||||
p.SetType(payload.ChangeViewType)
|
p.message.Type = messageType(dbft.ChangeViewType)
|
||||||
p.SetPayload(&changeView{newViewNumber: 1, timestamp: uint64(time.Now().UnixNano() / nsInMs)})
|
p.payload = &changeView{newViewNumber: 1, timestamp: uint64(time.Now().UnixNano() / nsInMs)}
|
||||||
}
|
}
|
||||||
p.SetHeight(1)
|
p.BlockIndex = 1
|
||||||
p.SetValidatorIndex(uint16(i))
|
p.message.ValidatorIndex = byte(i)
|
||||||
|
|
||||||
priv, _ := getTestValidator(i)
|
priv, _ := getTestValidator(i)
|
||||||
require.NoError(t, p.Sign(priv))
|
require.NoError(t, p.Sign(priv))
|
||||||
|
@ -255,10 +253,10 @@ func TestService_ValidatePayload(t *testing.T) {
|
||||||
priv, _ := getTestValidator(1)
|
priv, _ := getTestValidator(1)
|
||||||
p := new(Payload)
|
p := new(Payload)
|
||||||
p.Sender = priv.GetScriptHash()
|
p.Sender = priv.GetScriptHash()
|
||||||
p.SetPayload(&prepareRequest{})
|
p.payload = &prepareRequest{}
|
||||||
|
|
||||||
t.Run("invalid validator index", func(t *testing.T) {
|
t.Run("invalid validator index", func(t *testing.T) {
|
||||||
p.SetValidatorIndex(11)
|
p.message.ValidatorIndex = 11
|
||||||
require.NoError(t, p.Sign(priv))
|
require.NoError(t, p.Sign(priv))
|
||||||
|
|
||||||
var ok bool
|
var ok bool
|
||||||
|
@ -267,20 +265,20 @@ func TestService_ValidatePayload(t *testing.T) {
|
||||||
})
|
})
|
||||||
|
|
||||||
t.Run("wrong validator index", func(t *testing.T) {
|
t.Run("wrong validator index", func(t *testing.T) {
|
||||||
p.SetValidatorIndex(2)
|
p.message.ValidatorIndex = 2
|
||||||
require.NoError(t, p.Sign(priv))
|
require.NoError(t, p.Sign(priv))
|
||||||
require.False(t, srv.validatePayload(p))
|
require.False(t, srv.validatePayload(p))
|
||||||
})
|
})
|
||||||
|
|
||||||
t.Run("invalid sender", func(t *testing.T) {
|
t.Run("invalid sender", func(t *testing.T) {
|
||||||
p.SetValidatorIndex(1)
|
p.message.ValidatorIndex = 1
|
||||||
p.Sender = util.Uint160{}
|
p.Sender = util.Uint160{}
|
||||||
require.NoError(t, p.Sign(priv))
|
require.NoError(t, p.Sign(priv))
|
||||||
require.False(t, srv.validatePayload(p))
|
require.False(t, srv.validatePayload(p))
|
||||||
})
|
})
|
||||||
|
|
||||||
t.Run("normal case", func(t *testing.T) {
|
t.Run("normal case", func(t *testing.T) {
|
||||||
p.SetValidatorIndex(1)
|
p.message.ValidatorIndex = 1
|
||||||
p.Sender = priv.GetScriptHash()
|
p.Sender = priv.GetScriptHash()
|
||||||
require.NoError(t, p.Sign(priv))
|
require.NoError(t, p.Sign(priv))
|
||||||
require.True(t, srv.validatePayload(p))
|
require.True(t, srv.validatePayload(p))
|
||||||
|
@ -330,12 +328,12 @@ func TestService_PrepareRequest(t *testing.T) {
|
||||||
|
|
||||||
priv, _ := getTestValidator(1)
|
priv, _ := getTestValidator(1)
|
||||||
p := new(Payload)
|
p := new(Payload)
|
||||||
p.SetValidatorIndex(1)
|
p.message.ValidatorIndex = 1
|
||||||
|
|
||||||
prevHash := srv.Chain.CurrentBlockHash()
|
prevHash := srv.Chain.CurrentBlockHash()
|
||||||
|
|
||||||
checkRequest := func(t *testing.T, expectedErr error, req *prepareRequest) {
|
checkRequest := func(t *testing.T, expectedErr error, req *prepareRequest) {
|
||||||
p.SetPayload(req)
|
p.payload = req
|
||||||
require.NoError(t, p.Sign(priv))
|
require.NoError(t, p.Sign(priv))
|
||||||
err := srv.verifyRequest(p)
|
err := srv.verifyRequest(p)
|
||||||
if expectedErr == nil {
|
if expectedErr == nil {
|
||||||
|
@ -377,8 +375,8 @@ func TestService_OnPayload(t *testing.T) {
|
||||||
|
|
||||||
priv, _ := getTestValidator(1)
|
priv, _ := getTestValidator(1)
|
||||||
p := new(Payload)
|
p := new(Payload)
|
||||||
p.SetValidatorIndex(1)
|
p.message.ValidatorIndex = 1
|
||||||
p.SetPayload(&prepareRequest{})
|
p.payload = &prepareRequest{}
|
||||||
p.encodeData()
|
p.encodeData()
|
||||||
|
|
||||||
// sender is invalid
|
// sender is invalid
|
||||||
|
@ -386,9 +384,9 @@ func TestService_OnPayload(t *testing.T) {
|
||||||
shouldNotReceive(t, srv.messages)
|
shouldNotReceive(t, srv.messages)
|
||||||
|
|
||||||
p = new(Payload)
|
p = new(Payload)
|
||||||
p.SetValidatorIndex(1)
|
p.message.ValidatorIndex = 1
|
||||||
p.Sender = priv.GetScriptHash()
|
p.Sender = priv.GetScriptHash()
|
||||||
p.SetPayload(&prepareRequest{})
|
p.payload = &prepareRequest{}
|
||||||
require.NoError(t, p.Sign(priv))
|
require.NoError(t, p.Sign(priv))
|
||||||
require.NoError(t, srv.OnPayload(&p.Extensible))
|
require.NoError(t, srv.OnPayload(&p.Extensible))
|
||||||
shouldReceive(t, srv.messages)
|
shouldReceive(t, srv.messages)
|
||||||
|
|
|
@ -4,6 +4,7 @@ import (
|
||||||
"crypto/sha256"
|
"crypto/sha256"
|
||||||
"errors"
|
"errors"
|
||||||
|
|
||||||
|
"github.com/nspcc-dev/dbft"
|
||||||
"github.com/nspcc-dev/neo-go/pkg/crypto/keys"
|
"github.com/nspcc-dev/neo-go/pkg/crypto/keys"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -13,6 +14,8 @@ type privateKey struct {
|
||||||
*keys.PrivateKey
|
*keys.PrivateKey
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var _ dbft.PrivateKey = &privateKey{}
|
||||||
|
|
||||||
// Sign implements the dbft's crypto.PrivateKey interface.
|
// Sign implements the dbft's crypto.PrivateKey interface.
|
||||||
func (p *privateKey) Sign(data []byte) ([]byte, error) {
|
func (p *privateKey) Sign(data []byte) ([]byte, error) {
|
||||||
return p.PrivateKey.Sign(data), nil
|
return p.PrivateKey.Sign(data), nil
|
||||||
|
@ -24,6 +27,8 @@ type publicKey struct {
|
||||||
*keys.PublicKey
|
*keys.PublicKey
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var _ dbft.PublicKey = &publicKey{}
|
||||||
|
|
||||||
// MarshalBinary implements the encoding.BinaryMarshaler interface.
|
// MarshalBinary implements the encoding.BinaryMarshaler interface.
|
||||||
func (p publicKey) MarshalBinary() (data []byte, err error) {
|
func (p publicKey) MarshalBinary() (data []byte, err error) {
|
||||||
return p.PublicKey.Bytes(), nil
|
return p.PublicKey.Bytes(), nil
|
||||||
|
|
|
@ -3,7 +3,7 @@ package consensus
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
|
||||||
"github.com/nspcc-dev/dbft/payload"
|
"github.com/nspcc-dev/dbft"
|
||||||
"github.com/nspcc-dev/neo-go/pkg/config/netmode"
|
"github.com/nspcc-dev/neo-go/pkg/config/netmode"
|
||||||
"github.com/nspcc-dev/neo-go/pkg/io"
|
"github.com/nspcc-dev/neo-go/pkg/io"
|
||||||
npayload "github.com/nspcc-dev/neo-go/pkg/network/payload"
|
npayload "github.com/nspcc-dev/neo-go/pkg/network/payload"
|
||||||
|
@ -44,6 +44,8 @@ const (
|
||||||
payloadGasLimit = 2000000 // 0.02 GAS
|
payloadGasLimit = 2000000 // 0.02 GAS
|
||||||
)
|
)
|
||||||
|
|
||||||
|
var _ dbft.ConsensusPayload[util.Uint256] = &Payload{}
|
||||||
|
|
||||||
// ViewNumber implements the payload.ConsensusPayload interface.
|
// ViewNumber implements the payload.ConsensusPayload interface.
|
||||||
func (p Payload) ViewNumber() byte {
|
func (p Payload) ViewNumber() byte {
|
||||||
return p.message.ViewNumber
|
return p.message.ViewNumber
|
||||||
|
@ -55,13 +57,8 @@ func (p *Payload) SetViewNumber(view byte) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Type implements the payload.ConsensusPayload interface.
|
// Type implements the payload.ConsensusPayload interface.
|
||||||
func (p Payload) Type() payload.MessageType {
|
func (p Payload) Type() dbft.MessageType {
|
||||||
return payload.MessageType(p.message.Type)
|
return dbft.MessageType(p.message.Type)
|
||||||
}
|
|
||||||
|
|
||||||
// SetType implements the payload.ConsensusPayload interface.
|
|
||||||
func (p *Payload) SetType(t payload.MessageType) {
|
|
||||||
p.message.Type = messageType(t)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Payload implements the payload.ConsensusPayload interface.
|
// Payload implements the payload.ConsensusPayload interface.
|
||||||
|
@ -69,35 +66,30 @@ func (p Payload) Payload() any {
|
||||||
return p.payload
|
return p.payload
|
||||||
}
|
}
|
||||||
|
|
||||||
// SetPayload implements the payload.ConsensusPayload interface.
|
|
||||||
func (p *Payload) SetPayload(pl any) {
|
|
||||||
p.payload = pl.(io.Serializable)
|
|
||||||
}
|
|
||||||
|
|
||||||
// GetChangeView implements the payload.ConsensusPayload interface.
|
// GetChangeView implements the payload.ConsensusPayload interface.
|
||||||
func (p Payload) GetChangeView() payload.ChangeView { return p.payload.(payload.ChangeView) }
|
func (p Payload) GetChangeView() dbft.ChangeView { return p.payload.(dbft.ChangeView) }
|
||||||
|
|
||||||
// GetPrepareRequest implements the payload.ConsensusPayload interface.
|
// GetPrepareRequest implements the payload.ConsensusPayload interface.
|
||||||
func (p Payload) GetPrepareRequest() payload.PrepareRequest {
|
func (p Payload) GetPrepareRequest() dbft.PrepareRequest[util.Uint256] {
|
||||||
return p.payload.(payload.PrepareRequest)
|
return p.payload.(dbft.PrepareRequest[util.Uint256])
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetPrepareResponse implements the payload.ConsensusPayload interface.
|
// GetPrepareResponse implements the payload.ConsensusPayload interface.
|
||||||
func (p Payload) GetPrepareResponse() payload.PrepareResponse {
|
func (p Payload) GetPrepareResponse() dbft.PrepareResponse[util.Uint256] {
|
||||||
return p.payload.(payload.PrepareResponse)
|
return p.payload.(dbft.PrepareResponse[util.Uint256])
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetCommit implements the payload.ConsensusPayload interface.
|
// GetCommit implements the payload.ConsensusPayload interface.
|
||||||
func (p Payload) GetCommit() payload.Commit { return p.payload.(payload.Commit) }
|
func (p Payload) GetCommit() dbft.Commit { return p.payload.(dbft.Commit) }
|
||||||
|
|
||||||
// GetRecoveryRequest implements the payload.ConsensusPayload interface.
|
// GetRecoveryRequest implements the payload.ConsensusPayload interface.
|
||||||
func (p Payload) GetRecoveryRequest() payload.RecoveryRequest {
|
func (p Payload) GetRecoveryRequest() dbft.RecoveryRequest {
|
||||||
return p.payload.(payload.RecoveryRequest)
|
return p.payload.(dbft.RecoveryRequest)
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetRecoveryMessage implements the payload.ConsensusPayload interface.
|
// GetRecoveryMessage implements the payload.ConsensusPayload interface.
|
||||||
func (p Payload) GetRecoveryMessage() payload.RecoveryMessage {
|
func (p Payload) GetRecoveryMessage() dbft.RecoveryMessage[util.Uint256] {
|
||||||
return p.payload.(payload.RecoveryMessage)
|
return p.payload.(dbft.RecoveryMessage[util.Uint256])
|
||||||
}
|
}
|
||||||
|
|
||||||
// ValidatorIndex implements the payload.ConsensusPayload interface.
|
// ValidatorIndex implements the payload.ConsensusPayload interface.
|
||||||
|
@ -115,11 +107,6 @@ func (p Payload) Height() uint32 {
|
||||||
return p.message.BlockIndex
|
return p.message.BlockIndex
|
||||||
}
|
}
|
||||||
|
|
||||||
// SetHeight implements the payload.ConsensusPayload interface.
|
|
||||||
func (p *Payload) SetHeight(h uint32) {
|
|
||||||
p.message.BlockIndex = h
|
|
||||||
}
|
|
||||||
|
|
||||||
// EncodeBinary implements the io.Serializable interface.
|
// EncodeBinary implements the io.Serializable interface.
|
||||||
func (p *Payload) EncodeBinary(w *io.BinWriter) {
|
func (p *Payload) EncodeBinary(w *io.BinWriter) {
|
||||||
p.encodeData()
|
p.encodeData()
|
||||||
|
|
|
@ -6,7 +6,7 @@ import (
|
||||||
"math/rand"
|
"math/rand"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/nspcc-dev/dbft/payload"
|
"github.com/nspcc-dev/dbft"
|
||||||
"github.com/nspcc-dev/neo-go/internal/random"
|
"github.com/nspcc-dev/neo-go/internal/random"
|
||||||
"github.com/nspcc-dev/neo-go/internal/testserdes"
|
"github.com/nspcc-dev/neo-go/internal/testserdes"
|
||||||
"github.com/nspcc-dev/neo-go/pkg/config/netmode"
|
"github.com/nspcc-dev/neo-go/pkg/config/netmode"
|
||||||
|
@ -29,50 +29,45 @@ var messageTypes = []messageType{
|
||||||
recoveryMessageType,
|
recoveryMessageType,
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestConsensusPayload_Setters(t *testing.T) {
|
func TestConsensusPayload_Getters(t *testing.T) {
|
||||||
var p Payload
|
var p = &Payload{
|
||||||
|
Extensible: npayload.Extensible{},
|
||||||
|
message: message{
|
||||||
|
Type: prepareRequestType,
|
||||||
|
BlockIndex: 11,
|
||||||
|
ValidatorIndex: 4,
|
||||||
|
ViewNumber: 2,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
//p.SetVersion(1)
|
|
||||||
//assert.EqualValues(t, 1, p.Version())
|
|
||||||
|
|
||||||
//p.SetPrevHash(util.Uint256{1, 2, 3})
|
|
||||||
//assert.Equal(t, util.Uint256{1, 2, 3}, p.PrevHash())
|
|
||||||
|
|
||||||
p.SetValidatorIndex(4)
|
|
||||||
assert.EqualValues(t, 4, p.ValidatorIndex())
|
assert.EqualValues(t, 4, p.ValidatorIndex())
|
||||||
|
|
||||||
p.SetHeight(11)
|
|
||||||
assert.EqualValues(t, 11, p.Height())
|
assert.EqualValues(t, 11, p.Height())
|
||||||
|
|
||||||
p.SetViewNumber(2)
|
|
||||||
assert.EqualValues(t, 2, p.ViewNumber())
|
assert.EqualValues(t, 2, p.ViewNumber())
|
||||||
|
assert.Equal(t, dbft.PrepareRequestType, p.Type())
|
||||||
p.SetType(payload.PrepareRequestType)
|
|
||||||
assert.Equal(t, payload.PrepareRequestType, p.Type())
|
|
||||||
|
|
||||||
pl := randomMessage(t, prepareRequestType)
|
pl := randomMessage(t, prepareRequestType)
|
||||||
p.SetPayload(pl)
|
p.payload = pl
|
||||||
require.Equal(t, pl, p.Payload())
|
require.Equal(t, pl, p.Payload())
|
||||||
require.Equal(t, pl, p.GetPrepareRequest())
|
require.Equal(t, pl, p.GetPrepareRequest())
|
||||||
|
|
||||||
pl = randomMessage(t, prepareResponseType)
|
pl = randomMessage(t, prepareResponseType)
|
||||||
p.SetPayload(pl)
|
p.payload = pl
|
||||||
require.Equal(t, pl, p.GetPrepareResponse())
|
require.Equal(t, pl, p.GetPrepareResponse())
|
||||||
|
|
||||||
pl = randomMessage(t, commitType)
|
pl = randomMessage(t, commitType)
|
||||||
p.SetPayload(pl)
|
p.payload = pl
|
||||||
require.Equal(t, pl, p.GetCommit())
|
require.Equal(t, pl, p.GetCommit())
|
||||||
|
|
||||||
pl = randomMessage(t, changeViewType)
|
pl = randomMessage(t, changeViewType)
|
||||||
p.SetPayload(pl)
|
p.payload = pl
|
||||||
require.Equal(t, pl, p.GetChangeView())
|
require.Equal(t, pl, p.GetChangeView())
|
||||||
|
|
||||||
pl = randomMessage(t, recoveryRequestType)
|
pl = randomMessage(t, recoveryRequestType)
|
||||||
p.SetPayload(pl)
|
p.payload = pl
|
||||||
require.Equal(t, pl, p.GetRecoveryRequest())
|
require.Equal(t, pl, p.GetRecoveryRequest())
|
||||||
|
|
||||||
pl = randomMessage(t, recoveryMessageType)
|
pl = randomMessage(t, recoveryMessageType)
|
||||||
p.SetPayload(pl)
|
p.payload = pl
|
||||||
require.Equal(t, pl, p.GetRecoveryMessage())
|
require.Equal(t, pl, p.GetRecoveryMessage())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -290,7 +285,7 @@ func TestPayload_DecodeFromPrivnet(t *testing.T) {
|
||||||
p := NewPayload(netmode.PrivNet, false)
|
p := NewPayload(netmode.PrivNet, false)
|
||||||
p.DecodeBinary(buf)
|
p.DecodeBinary(buf)
|
||||||
require.NoError(t, buf.Err)
|
require.NoError(t, buf.Err)
|
||||||
require.Equal(t, payload.CommitType, p.Type())
|
require.Equal(t, dbft.CommitType, p.Type())
|
||||||
require.Equal(t, uint32(2), p.Height())
|
require.Equal(t, uint32(2), p.Height())
|
||||||
require.Equal(t, uint16(3), p.ValidatorIndex())
|
require.Equal(t, uint16(3), p.ValidatorIndex())
|
||||||
require.Equal(t, byte(0), p.ViewNumber())
|
require.Equal(t, byte(0), p.ViewNumber())
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
package consensus
|
package consensus
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/nspcc-dev/dbft/payload"
|
"github.com/nspcc-dev/dbft"
|
||||||
"github.com/nspcc-dev/neo-go/pkg/core/block"
|
"github.com/nspcc-dev/neo-go/pkg/core/block"
|
||||||
"github.com/nspcc-dev/neo-go/pkg/io"
|
"github.com/nspcc-dev/neo-go/pkg/io"
|
||||||
"github.com/nspcc-dev/neo-go/pkg/util"
|
"github.com/nspcc-dev/neo-go/pkg/util"
|
||||||
|
@ -18,7 +18,7 @@ type prepareRequest struct {
|
||||||
stateRoot util.Uint256
|
stateRoot util.Uint256
|
||||||
}
|
}
|
||||||
|
|
||||||
var _ payload.PrepareRequest = (*prepareRequest)(nil)
|
var _ dbft.PrepareRequest[util.Uint256] = (*prepareRequest)(nil)
|
||||||
|
|
||||||
// EncodeBinary implements the io.Serializable interface.
|
// EncodeBinary implements the io.Serializable interface.
|
||||||
func (p *prepareRequest) EncodeBinary(w *io.BinWriter) {
|
func (p *prepareRequest) EncodeBinary(w *io.BinWriter) {
|
||||||
|
@ -47,46 +47,11 @@ func (p *prepareRequest) DecodeBinary(r *io.BinReader) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Version implements the payload.PrepareRequest interface.
|
|
||||||
func (p prepareRequest) Version() uint32 {
|
|
||||||
return p.version
|
|
||||||
}
|
|
||||||
|
|
||||||
// SetVersion implements the payload.PrepareRequest interface.
|
|
||||||
func (p *prepareRequest) SetVersion(v uint32) {
|
|
||||||
p.version = v
|
|
||||||
}
|
|
||||||
|
|
||||||
// PrevHash implements the payload.PrepareRequest interface.
|
|
||||||
func (p prepareRequest) PrevHash() util.Uint256 {
|
|
||||||
return p.prevHash
|
|
||||||
}
|
|
||||||
|
|
||||||
// SetPrevHash implements the payload.PrepareRequest interface.
|
|
||||||
func (p *prepareRequest) SetPrevHash(h util.Uint256) {
|
|
||||||
p.prevHash = h
|
|
||||||
}
|
|
||||||
|
|
||||||
// Timestamp implements the payload.PrepareRequest interface.
|
// Timestamp implements the payload.PrepareRequest interface.
|
||||||
func (p *prepareRequest) Timestamp() uint64 { return p.timestamp * nsInMs }
|
func (p *prepareRequest) Timestamp() uint64 { return p.timestamp * nsInMs }
|
||||||
|
|
||||||
// SetTimestamp implements the payload.PrepareRequest interface.
|
|
||||||
func (p *prepareRequest) SetTimestamp(ts uint64) { p.timestamp = ts / nsInMs }
|
|
||||||
|
|
||||||
// Nonce implements the payload.PrepareRequest interface.
|
// Nonce implements the payload.PrepareRequest interface.
|
||||||
func (p *prepareRequest) Nonce() uint64 { return p.nonce }
|
func (p *prepareRequest) Nonce() uint64 { return p.nonce }
|
||||||
|
|
||||||
// SetNonce implements the payload.PrepareRequest interface.
|
|
||||||
func (p *prepareRequest) SetNonce(nonce uint64) { p.nonce = nonce }
|
|
||||||
|
|
||||||
// TransactionHashes implements the payload.PrepareRequest interface.
|
// TransactionHashes implements the payload.PrepareRequest interface.
|
||||||
func (p *prepareRequest) TransactionHashes() []util.Uint256 { return p.transactionHashes }
|
func (p *prepareRequest) TransactionHashes() []util.Uint256 { return p.transactionHashes }
|
||||||
|
|
||||||
// SetTransactionHashes implements the payload.PrepareRequest interface.
|
|
||||||
func (p *prepareRequest) SetTransactionHashes(hs []util.Uint256) { p.transactionHashes = hs }
|
|
||||||
|
|
||||||
// NextConsensus implements the payload.PrepareRequest interface.
|
|
||||||
func (p *prepareRequest) NextConsensus() util.Uint160 { return util.Uint160{} }
|
|
||||||
|
|
||||||
// SetNextConsensus implements the payload.PrepareRequest interface.
|
|
||||||
func (p *prepareRequest) SetNextConsensus(_ util.Uint160) {}
|
|
||||||
|
|
|
@ -10,24 +10,17 @@ import (
|
||||||
"github.com/stretchr/testify/require"
|
"github.com/stretchr/testify/require"
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestPrepareRequest_Setters(t *testing.T) {
|
func TestPrepareRequest_Getters(t *testing.T) {
|
||||||
var p prepareRequest
|
hashes := []util.Uint256{random.Uint256(), random.Uint256()}
|
||||||
|
var p = &prepareRequest{
|
||||||
|
version: 123,
|
||||||
|
prevHash: util.Uint256{1, 2, 3},
|
||||||
|
timestamp: 123,
|
||||||
|
transactionHashes: hashes,
|
||||||
|
}
|
||||||
|
|
||||||
p.SetTimestamp(123)
|
require.EqualValues(t, 123000000, p.Timestamp())
|
||||||
// 123ns -> 0ms -> 0ns
|
require.Equal(t, hashes, p.TransactionHashes())
|
||||||
require.EqualValues(t, 0, p.Timestamp())
|
|
||||||
|
|
||||||
p.SetTimestamp(1230000)
|
|
||||||
// 1230000ns -> 1ms -> 1000000ns
|
|
||||||
require.EqualValues(t, 1000000, p.Timestamp())
|
|
||||||
|
|
||||||
p.SetNextConsensus(util.Uint160{5, 6, 7})
|
|
||||||
require.Equal(t, util.Uint160{}, p.NextConsensus())
|
|
||||||
|
|
||||||
hashes := [2]util.Uint256{random.Uint256(), random.Uint256()}
|
|
||||||
|
|
||||||
p.SetTransactionHashes(hashes[:])
|
|
||||||
require.Equal(t, hashes[:], p.TransactionHashes())
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestPrepareRequest_EncodeDecodeBinary(t *testing.T) {
|
func TestPrepareRequest_EncodeDecodeBinary(t *testing.T) {
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
package consensus
|
package consensus
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/nspcc-dev/dbft/payload"
|
"github.com/nspcc-dev/dbft"
|
||||||
"github.com/nspcc-dev/neo-go/pkg/io"
|
"github.com/nspcc-dev/neo-go/pkg/io"
|
||||||
"github.com/nspcc-dev/neo-go/pkg/util"
|
"github.com/nspcc-dev/neo-go/pkg/util"
|
||||||
)
|
)
|
||||||
|
@ -11,7 +11,7 @@ type prepareResponse struct {
|
||||||
preparationHash util.Uint256
|
preparationHash util.Uint256
|
||||||
}
|
}
|
||||||
|
|
||||||
var _ payload.PrepareResponse = (*prepareResponse)(nil)
|
var _ dbft.PrepareResponse[util.Uint256] = (*prepareResponse)(nil)
|
||||||
|
|
||||||
// EncodeBinary implements the io.Serializable interface.
|
// EncodeBinary implements the io.Serializable interface.
|
||||||
func (p *prepareResponse) EncodeBinary(w *io.BinWriter) {
|
func (p *prepareResponse) EncodeBinary(w *io.BinWriter) {
|
||||||
|
@ -25,6 +25,3 @@ func (p *prepareResponse) DecodeBinary(r *io.BinReader) {
|
||||||
|
|
||||||
// PreparationHash implements the payload.PrepareResponse interface.
|
// PreparationHash implements the payload.PrepareResponse interface.
|
||||||
func (p *prepareResponse) PreparationHash() util.Uint256 { return p.preparationHash }
|
func (p *prepareResponse) PreparationHash() util.Uint256 { return p.preparationHash }
|
||||||
|
|
||||||
// SetPreparationHash implements the payload.PrepareResponse interface.
|
|
||||||
func (p *prepareResponse) SetPreparationHash(h util.Uint256) { p.preparationHash = h }
|
|
||||||
|
|
|
@ -8,8 +8,9 @@ import (
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestPrepareResponse_Setters(t *testing.T) {
|
func TestPrepareResponse_Setters(t *testing.T) {
|
||||||
var p prepareResponse
|
var p = prepareResponse{
|
||||||
|
preparationHash: util.Uint256{1, 2, 3},
|
||||||
|
}
|
||||||
|
|
||||||
p.SetPreparationHash(util.Uint256{1, 2, 3})
|
|
||||||
require.Equal(t, util.Uint256{1, 2, 3}, p.PreparationHash())
|
require.Equal(t, util.Uint256{1, 2, 3}, p.PreparationHash())
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,8 +3,7 @@ package consensus
|
||||||
import (
|
import (
|
||||||
"errors"
|
"errors"
|
||||||
|
|
||||||
"github.com/nspcc-dev/dbft/crypto"
|
"github.com/nspcc-dev/dbft"
|
||||||
"github.com/nspcc-dev/dbft/payload"
|
|
||||||
"github.com/nspcc-dev/neo-go/pkg/io"
|
"github.com/nspcc-dev/neo-go/pkg/io"
|
||||||
npayload "github.com/nspcc-dev/neo-go/pkg/network/payload"
|
npayload "github.com/nspcc-dev/neo-go/pkg/network/payload"
|
||||||
"github.com/nspcc-dev/neo-go/pkg/util"
|
"github.com/nspcc-dev/neo-go/pkg/util"
|
||||||
|
@ -41,7 +40,7 @@ type (
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
var _ payload.RecoveryMessage = (*recoveryMessage)(nil)
|
var _ dbft.RecoveryMessage[util.Uint256] = (*recoveryMessage)(nil)
|
||||||
|
|
||||||
// DecodeBinary implements the io.Serializable interface.
|
// DecodeBinary implements the io.Serializable interface.
|
||||||
func (m *recoveryMessage) DecodeBinary(r *io.BinReader) {
|
func (m *recoveryMessage) DecodeBinary(r *io.BinReader) {
|
||||||
|
@ -139,11 +138,11 @@ func (p *preparationCompact) EncodeBinary(w *io.BinWriter) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// AddPayload implements the payload.RecoveryMessage interface.
|
// AddPayload implements the payload.RecoveryMessage interface.
|
||||||
func (m *recoveryMessage) AddPayload(p payload.ConsensusPayload) {
|
func (m *recoveryMessage) AddPayload(p dbft.ConsensusPayload[util.Uint256]) {
|
||||||
validator := uint8(p.ValidatorIndex())
|
validator := uint8(p.ValidatorIndex())
|
||||||
|
|
||||||
switch p.Type() {
|
switch p.Type() {
|
||||||
case payload.PrepareRequestType:
|
case dbft.PrepareRequestType:
|
||||||
m.prepareRequest = &message{
|
m.prepareRequest = &message{
|
||||||
Type: prepareRequestType,
|
Type: prepareRequestType,
|
||||||
ViewNumber: p.ViewNumber(),
|
ViewNumber: p.ViewNumber(),
|
||||||
|
@ -156,24 +155,24 @@ func (m *recoveryMessage) AddPayload(p payload.ConsensusPayload) {
|
||||||
ValidatorIndex: validator,
|
ValidatorIndex: validator,
|
||||||
InvocationScript: p.(*Payload).Witness.InvocationScript,
|
InvocationScript: p.(*Payload).Witness.InvocationScript,
|
||||||
})
|
})
|
||||||
case payload.PrepareResponseType:
|
case dbft.PrepareResponseType:
|
||||||
m.preparationPayloads = append(m.preparationPayloads, &preparationCompact{
|
m.preparationPayloads = append(m.preparationPayloads, &preparationCompact{
|
||||||
ValidatorIndex: validator,
|
ValidatorIndex: validator,
|
||||||
InvocationScript: p.(*Payload).Witness.InvocationScript,
|
InvocationScript: p.(*Payload).Witness.InvocationScript,
|
||||||
})
|
})
|
||||||
|
|
||||||
if m.preparationHash == nil {
|
if m.preparationHash == nil {
|
||||||
h := p.GetPrepareResponse().PreparationHash()
|
h := p.GetPrepareResponse().(*prepareResponse).preparationHash
|
||||||
m.preparationHash = &h
|
m.preparationHash = &h
|
||||||
}
|
}
|
||||||
case payload.ChangeViewType:
|
case dbft.ChangeViewType:
|
||||||
m.changeViewPayloads = append(m.changeViewPayloads, &changeViewCompact{
|
m.changeViewPayloads = append(m.changeViewPayloads, &changeViewCompact{
|
||||||
ValidatorIndex: validator,
|
ValidatorIndex: validator,
|
||||||
OriginalViewNumber: p.ViewNumber(),
|
OriginalViewNumber: p.ViewNumber(),
|
||||||
Timestamp: p.GetChangeView().Timestamp() / nsInMs,
|
Timestamp: p.GetChangeView().(*changeView).timestamp,
|
||||||
InvocationScript: p.(*Payload).Witness.InvocationScript,
|
InvocationScript: p.(*Payload).Witness.InvocationScript,
|
||||||
})
|
})
|
||||||
case payload.CommitType:
|
case dbft.CommitType:
|
||||||
m.commitPayloads = append(m.commitPayloads, &commitCompact{
|
m.commitPayloads = append(m.commitPayloads, &commitCompact{
|
||||||
ValidatorIndex: validator,
|
ValidatorIndex: validator,
|
||||||
ViewNumber: p.ViewNumber(),
|
ViewNumber: p.ViewNumber(),
|
||||||
|
@ -184,7 +183,7 @@ func (m *recoveryMessage) AddPayload(p payload.ConsensusPayload) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetPrepareRequest implements the payload.RecoveryMessage interface.
|
// GetPrepareRequest implements the payload.RecoveryMessage interface.
|
||||||
func (m *recoveryMessage) GetPrepareRequest(p payload.ConsensusPayload, validators []crypto.PublicKey, primary uint16) payload.ConsensusPayload {
|
func (m *recoveryMessage) GetPrepareRequest(p dbft.ConsensusPayload[util.Uint256], validators []dbft.PublicKey, primary uint16) dbft.ConsensusPayload[util.Uint256] {
|
||||||
if m.prepareRequest == nil {
|
if m.prepareRequest == nil {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
@ -202,7 +201,7 @@ func (m *recoveryMessage) GetPrepareRequest(p payload.ConsensusPayload, validato
|
||||||
}
|
}
|
||||||
|
|
||||||
req := fromPayload(prepareRequestType, p.(*Payload), m.prepareRequest.payload)
|
req := fromPayload(prepareRequestType, p.(*Payload), m.prepareRequest.payload)
|
||||||
req.SetValidatorIndex(primary)
|
req.message.ValidatorIndex = byte(primary)
|
||||||
req.Sender = validators[primary].(*publicKey).GetScriptHash()
|
req.Sender = validators[primary].(*publicKey).GetScriptHash()
|
||||||
req.Witness.InvocationScript = compact.InvocationScript
|
req.Witness.InvocationScript = compact.InvocationScript
|
||||||
req.Witness.VerificationScript = getVerificationScript(uint8(primary), validators)
|
req.Witness.VerificationScript = getVerificationScript(uint8(primary), validators)
|
||||||
|
@ -211,18 +210,18 @@ func (m *recoveryMessage) GetPrepareRequest(p payload.ConsensusPayload, validato
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetPrepareResponses implements the payload.RecoveryMessage interface.
|
// GetPrepareResponses implements the payload.RecoveryMessage interface.
|
||||||
func (m *recoveryMessage) GetPrepareResponses(p payload.ConsensusPayload, validators []crypto.PublicKey) []payload.ConsensusPayload {
|
func (m *recoveryMessage) GetPrepareResponses(p dbft.ConsensusPayload[util.Uint256], validators []dbft.PublicKey) []dbft.ConsensusPayload[util.Uint256] {
|
||||||
if m.preparationHash == nil {
|
if m.preparationHash == nil {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
ps := make([]payload.ConsensusPayload, len(m.preparationPayloads))
|
ps := make([]dbft.ConsensusPayload[util.Uint256], len(m.preparationPayloads))
|
||||||
|
|
||||||
for i, resp := range m.preparationPayloads {
|
for i, resp := range m.preparationPayloads {
|
||||||
r := fromPayload(prepareResponseType, p.(*Payload), &prepareResponse{
|
r := fromPayload(prepareResponseType, p.(*Payload), &prepareResponse{
|
||||||
preparationHash: *m.preparationHash,
|
preparationHash: *m.preparationHash,
|
||||||
})
|
})
|
||||||
r.SetValidatorIndex(uint16(resp.ValidatorIndex))
|
r.message.ValidatorIndex = resp.ValidatorIndex
|
||||||
r.Sender = validators[resp.ValidatorIndex].(*publicKey).GetScriptHash()
|
r.Sender = validators[resp.ValidatorIndex].(*publicKey).GetScriptHash()
|
||||||
r.Witness.InvocationScript = resp.InvocationScript
|
r.Witness.InvocationScript = resp.InvocationScript
|
||||||
r.Witness.VerificationScript = getVerificationScript(resp.ValidatorIndex, validators)
|
r.Witness.VerificationScript = getVerificationScript(resp.ValidatorIndex, validators)
|
||||||
|
@ -234,8 +233,8 @@ func (m *recoveryMessage) GetPrepareResponses(p payload.ConsensusPayload, valida
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetChangeViews implements the payload.RecoveryMessage interface.
|
// GetChangeViews implements the payload.RecoveryMessage interface.
|
||||||
func (m *recoveryMessage) GetChangeViews(p payload.ConsensusPayload, validators []crypto.PublicKey) []payload.ConsensusPayload {
|
func (m *recoveryMessage) GetChangeViews(p dbft.ConsensusPayload[util.Uint256], validators []dbft.PublicKey) []dbft.ConsensusPayload[util.Uint256] {
|
||||||
ps := make([]payload.ConsensusPayload, len(m.changeViewPayloads))
|
ps := make([]dbft.ConsensusPayload[util.Uint256], len(m.changeViewPayloads))
|
||||||
|
|
||||||
for i, cv := range m.changeViewPayloads {
|
for i, cv := range m.changeViewPayloads {
|
||||||
c := fromPayload(changeViewType, p.(*Payload), &changeView{
|
c := fromPayload(changeViewType, p.(*Payload), &changeView{
|
||||||
|
@ -243,7 +242,7 @@ func (m *recoveryMessage) GetChangeViews(p payload.ConsensusPayload, validators
|
||||||
timestamp: cv.Timestamp,
|
timestamp: cv.Timestamp,
|
||||||
})
|
})
|
||||||
c.message.ViewNumber = cv.OriginalViewNumber
|
c.message.ViewNumber = cv.OriginalViewNumber
|
||||||
c.SetValidatorIndex(uint16(cv.ValidatorIndex))
|
c.message.ValidatorIndex = cv.ValidatorIndex
|
||||||
c.Sender = validators[cv.ValidatorIndex].(*publicKey).GetScriptHash()
|
c.Sender = validators[cv.ValidatorIndex].(*publicKey).GetScriptHash()
|
||||||
c.Witness.InvocationScript = cv.InvocationScript
|
c.Witness.InvocationScript = cv.InvocationScript
|
||||||
c.Witness.VerificationScript = getVerificationScript(cv.ValidatorIndex, validators)
|
c.Witness.VerificationScript = getVerificationScript(cv.ValidatorIndex, validators)
|
||||||
|
@ -255,12 +254,12 @@ func (m *recoveryMessage) GetChangeViews(p payload.ConsensusPayload, validators
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetCommits implements the payload.RecoveryMessage interface.
|
// GetCommits implements the payload.RecoveryMessage interface.
|
||||||
func (m *recoveryMessage) GetCommits(p payload.ConsensusPayload, validators []crypto.PublicKey) []payload.ConsensusPayload {
|
func (m *recoveryMessage) GetCommits(p dbft.ConsensusPayload[util.Uint256], validators []dbft.PublicKey) []dbft.ConsensusPayload[util.Uint256] {
|
||||||
ps := make([]payload.ConsensusPayload, len(m.commitPayloads))
|
ps := make([]dbft.ConsensusPayload[util.Uint256], len(m.commitPayloads))
|
||||||
|
|
||||||
for i, c := range m.commitPayloads {
|
for i, c := range m.commitPayloads {
|
||||||
cc := fromPayload(commitType, p.(*Payload), &commit{signature: c.Signature})
|
cc := fromPayload(commitType, p.(*Payload), &commit{signature: c.Signature})
|
||||||
cc.SetValidatorIndex(uint16(c.ValidatorIndex))
|
cc.message.ValidatorIndex = c.ValidatorIndex
|
||||||
cc.Sender = validators[c.ValidatorIndex].(*publicKey).GetScriptHash()
|
cc.Sender = validators[c.ValidatorIndex].(*publicKey).GetScriptHash()
|
||||||
cc.Witness.InvocationScript = c.InvocationScript
|
cc.Witness.InvocationScript = c.InvocationScript
|
||||||
cc.Witness.VerificationScript = getVerificationScript(c.ValidatorIndex, validators)
|
cc.Witness.VerificationScript = getVerificationScript(c.ValidatorIndex, validators)
|
||||||
|
@ -276,12 +275,7 @@ func (m *recoveryMessage) PreparationHash() *util.Uint256 {
|
||||||
return m.preparationHash
|
return m.preparationHash
|
||||||
}
|
}
|
||||||
|
|
||||||
// SetPreparationHash implements the payload.RecoveryMessage interface.
|
func getVerificationScript(i uint8, validators []dbft.PublicKey) []byte {
|
||||||
func (m *recoveryMessage) SetPreparationHash(h *util.Uint256) {
|
|
||||||
m.preparationHash = h
|
|
||||||
}
|
|
||||||
|
|
||||||
func getVerificationScript(i uint8, validators []crypto.PublicKey) []byte {
|
|
||||||
if int(i) >= len(validators) {
|
if int(i) >= len(validators) {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,8 +3,7 @@ package consensus
|
||||||
import (
|
import (
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/nspcc-dev/dbft/crypto"
|
"github.com/nspcc-dev/dbft"
|
||||||
"github.com/nspcc-dev/dbft/payload"
|
|
||||||
"github.com/nspcc-dev/neo-go/internal/testchain"
|
"github.com/nspcc-dev/neo-go/internal/testchain"
|
||||||
"github.com/nspcc-dev/neo-go/pkg/config/netmode"
|
"github.com/nspcc-dev/neo-go/pkg/config/netmode"
|
||||||
"github.com/nspcc-dev/neo-go/pkg/util"
|
"github.com/nspcc-dev/neo-go/pkg/util"
|
||||||
|
@ -23,7 +22,7 @@ func TestRecoveryMessageSetters(t *testing.T) {
|
||||||
func testRecoveryMessageSetters(t *testing.T, enableStateRoot bool) {
|
func testRecoveryMessageSetters(t *testing.T, enableStateRoot bool) {
|
||||||
srv := newTestServiceWithState(t, enableStateRoot)
|
srv := newTestServiceWithState(t, enableStateRoot)
|
||||||
privs := make([]*privateKey, testchain.Size())
|
privs := make([]*privateKey, testchain.Size())
|
||||||
pubs := make([]crypto.PublicKey, testchain.Size())
|
pubs := make([]dbft.PublicKey, testchain.Size())
|
||||||
for i := 0; i < testchain.Size(); i++ {
|
for i := 0; i < testchain.Size(); i++ {
|
||||||
privs[i], pubs[i] = getTestValidator(i)
|
privs[i], pubs[i] = getTestValidator(i)
|
||||||
}
|
}
|
||||||
|
@ -32,9 +31,9 @@ func testRecoveryMessageSetters(t *testing.T, enableStateRoot bool) {
|
||||||
|
|
||||||
r := &recoveryMessage{stateRootEnabled: enableStateRoot}
|
r := &recoveryMessage{stateRootEnabled: enableStateRoot}
|
||||||
p := NewPayload(netmode.UnitTestNet, enableStateRoot)
|
p := NewPayload(netmode.UnitTestNet, enableStateRoot)
|
||||||
p.SetType(payload.RecoveryMessageType)
|
p.message.Type = messageType(dbft.RecoveryMessageType)
|
||||||
p.SetHeight(msgHeight)
|
p.BlockIndex = msgHeight
|
||||||
p.SetPayload(r)
|
p.payload = r
|
||||||
// sign payload to have verification script
|
// sign payload to have verification script
|
||||||
require.NoError(t, p.Sign(privs[0]))
|
require.NoError(t, p.Sign(privs[0]))
|
||||||
|
|
||||||
|
@ -44,21 +43,21 @@ func testRecoveryMessageSetters(t *testing.T, enableStateRoot bool) {
|
||||||
stateRootEnabled: enableStateRoot,
|
stateRootEnabled: enableStateRoot,
|
||||||
}
|
}
|
||||||
p1 := NewPayload(netmode.UnitTestNet, enableStateRoot)
|
p1 := NewPayload(netmode.UnitTestNet, enableStateRoot)
|
||||||
p1.SetType(payload.PrepareRequestType)
|
p1.message.Type = messageType(dbft.PrepareRequestType)
|
||||||
p1.SetHeight(msgHeight)
|
p1.BlockIndex = msgHeight
|
||||||
p1.SetPayload(req)
|
p1.payload = req
|
||||||
p1.SetValidatorIndex(0)
|
p1.message.ValidatorIndex = 0
|
||||||
p1.Sender = privs[0].GetScriptHash()
|
p1.Sender = privs[0].GetScriptHash()
|
||||||
require.NoError(t, p1.Sign(privs[0]))
|
require.NoError(t, p1.Sign(privs[0]))
|
||||||
|
|
||||||
t.Run("prepare response is added", func(t *testing.T) {
|
t.Run("prepare response is added", func(t *testing.T) {
|
||||||
p2 := NewPayload(netmode.UnitTestNet, enableStateRoot)
|
p2 := NewPayload(netmode.UnitTestNet, enableStateRoot)
|
||||||
p2.SetType(payload.PrepareResponseType)
|
p2.message.Type = messageType(dbft.PrepareResponseType)
|
||||||
p2.SetHeight(msgHeight)
|
p2.BlockIndex = msgHeight
|
||||||
p2.SetPayload(&prepareResponse{
|
p2.payload = &prepareResponse{
|
||||||
preparationHash: p1.Hash(),
|
preparationHash: p1.Hash(),
|
||||||
})
|
}
|
||||||
p2.SetValidatorIndex(1)
|
p2.message.ValidatorIndex = 1
|
||||||
p2.Sender = privs[1].GetScriptHash()
|
p2.Sender = privs[1].GetScriptHash()
|
||||||
require.NoError(t, p2.Sign(privs[1]))
|
require.NoError(t, p2.Sign(privs[1]))
|
||||||
|
|
||||||
|
@ -91,13 +90,13 @@ func testRecoveryMessageSetters(t *testing.T, enableStateRoot bool) {
|
||||||
|
|
||||||
t.Run("change view is added", func(t *testing.T) {
|
t.Run("change view is added", func(t *testing.T) {
|
||||||
p3 := NewPayload(netmode.UnitTestNet, enableStateRoot)
|
p3 := NewPayload(netmode.UnitTestNet, enableStateRoot)
|
||||||
p3.SetType(payload.ChangeViewType)
|
p3.message.Type = messageType(dbft.ChangeViewType)
|
||||||
p3.SetHeight(msgHeight)
|
p3.BlockIndex = msgHeight
|
||||||
p3.SetPayload(&changeView{
|
p3.payload = &changeView{
|
||||||
newViewNumber: 1,
|
newViewNumber: 1,
|
||||||
timestamp: 12345,
|
timestamp: 12345,
|
||||||
})
|
}
|
||||||
p3.SetValidatorIndex(3)
|
p3.message.ValidatorIndex = 3
|
||||||
p3.Sender = privs[3].GetScriptHash()
|
p3.Sender = privs[3].GetScriptHash()
|
||||||
require.NoError(t, p3.Sign(privs[3]))
|
require.NoError(t, p3.Sign(privs[3]))
|
||||||
|
|
||||||
|
@ -115,10 +114,10 @@ func testRecoveryMessageSetters(t *testing.T, enableStateRoot bool) {
|
||||||
|
|
||||||
t.Run("commit is added", func(t *testing.T) {
|
t.Run("commit is added", func(t *testing.T) {
|
||||||
p4 := NewPayload(netmode.UnitTestNet, enableStateRoot)
|
p4 := NewPayload(netmode.UnitTestNet, enableStateRoot)
|
||||||
p4.SetType(payload.CommitType)
|
p4.message.Type = messageType(dbft.CommitType)
|
||||||
p4.SetHeight(msgHeight)
|
p4.BlockIndex = msgHeight
|
||||||
p4.SetPayload(randomMessage(t, commitType))
|
p4.payload = randomMessage(t, commitType)
|
||||||
p4.SetValidatorIndex(3)
|
p4.message.ValidatorIndex = 3
|
||||||
p4.Sender = privs[3].GetScriptHash()
|
p4.Sender = privs[3].GetScriptHash()
|
||||||
require.NoError(t, p4.Sign(privs[3]))
|
require.NoError(t, p4.Sign(privs[3]))
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
package consensus
|
package consensus
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/nspcc-dev/dbft/payload"
|
"github.com/nspcc-dev/dbft"
|
||||||
"github.com/nspcc-dev/neo-go/pkg/io"
|
"github.com/nspcc-dev/neo-go/pkg/io"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -10,7 +10,7 @@ type recoveryRequest struct {
|
||||||
timestamp uint64
|
timestamp uint64
|
||||||
}
|
}
|
||||||
|
|
||||||
var _ payload.RecoveryRequest = (*recoveryRequest)(nil)
|
var _ dbft.RecoveryRequest = (*recoveryRequest)(nil)
|
||||||
|
|
||||||
// DecodeBinary implements the io.Serializable interface.
|
// DecodeBinary implements the io.Serializable interface.
|
||||||
func (m *recoveryRequest) DecodeBinary(r *io.BinReader) {
|
func (m *recoveryRequest) DecodeBinary(r *io.BinReader) {
|
||||||
|
@ -24,6 +24,3 @@ func (m *recoveryRequest) EncodeBinary(w *io.BinWriter) {
|
||||||
|
|
||||||
// Timestamp implements the payload.RecoveryRequest interface.
|
// Timestamp implements the payload.RecoveryRequest interface.
|
||||||
func (m *recoveryRequest) Timestamp() uint64 { return m.timestamp * nsInMs }
|
func (m *recoveryRequest) Timestamp() uint64 { return m.timestamp * nsInMs }
|
||||||
|
|
||||||
// SetTimestamp implements the payload.RecoveryRequest interface.
|
|
||||||
func (m *recoveryRequest) SetTimestamp(ts uint64) { m.timestamp = ts / nsInMs }
|
|
||||||
|
|
|
@ -6,9 +6,10 @@ import (
|
||||||
"github.com/stretchr/testify/require"
|
"github.com/stretchr/testify/require"
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestRecoveryRequest_Setters(t *testing.T) {
|
func TestRecoveryRequest_Getters(t *testing.T) {
|
||||||
var r recoveryRequest
|
var r = &recoveryRequest{
|
||||||
|
timestamp: 123,
|
||||||
|
}
|
||||||
|
|
||||||
r.SetTimestamp(123 * nsInMs)
|
|
||||||
require.EqualValues(t, 123*nsInMs, r.Timestamp())
|
require.EqualValues(t, 123*nsInMs, r.Timestamp())
|
||||||
}
|
}
|
||||||
|
|
|
@ -13,6 +13,9 @@ import (
|
||||||
"github.com/nspcc-dev/neo-go/pkg/util"
|
"github.com/nspcc-dev/neo-go/pkg/util"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// VersionInitial is the default Neo block version.
|
||||||
|
const VersionInitial uint32 = 0
|
||||||
|
|
||||||
// Header holds the base info of a block.
|
// Header holds the base info of a block.
|
||||||
type Header struct {
|
type Header struct {
|
||||||
// Version of the block.
|
// Version of the block.
|
||||||
|
|
Loading…
Reference in a new issue