mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-07-18 02:40:45 +00:00
verify vote (#50)
* verify vote * fix vote tests and add temporary solution for initialize * remove the drop peer comment
This commit is contained in:
parent
0ab7bfbcbd
commit
431c870fa0
5 changed files with 79 additions and 13 deletions
|
|
@ -63,6 +63,8 @@ type XDPoS struct {
|
||||||
// The exact consensus engine with different versions
|
// The exact consensus engine with different versions
|
||||||
EngineV1 *engine_v1.XDPoS_v1
|
EngineV1 *engine_v1.XDPoS_v1
|
||||||
EngineV2 *engine_v2.XDPoS_v2
|
EngineV2 *engine_v2.XDPoS_v2
|
||||||
|
|
||||||
|
isV2Initilised bool
|
||||||
}
|
}
|
||||||
|
|
||||||
// New creates a XDPoS delegated-proof-of-stake consensus engine with the initial
|
// New creates a XDPoS delegated-proof-of-stake consensus engine with the initial
|
||||||
|
|
@ -90,6 +92,7 @@ func New(config *params.XDPoSConfig, db ethdb.Database) *XDPoS {
|
||||||
signingTxsCache: signingTxsCache,
|
signingTxsCache: signingTxsCache,
|
||||||
EngineV1: engine_v1.New(config, db),
|
EngineV1: engine_v1.New(config, db),
|
||||||
EngineV2: engine_v2.New(config, db, waitPeriodCh),
|
EngineV2: engine_v2.New(config, db, waitPeriodCh),
|
||||||
|
isV2Initilised: false,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -321,9 +324,18 @@ func (x *XDPoS) YourTurn(chain consensus.ChainReader, parent *types.Header, sign
|
||||||
log.Error("[YourTurn] Error while initilising first v2 block from the last v1 block", "ParentBlockHash", parent.Hash(), "Error", err)
|
log.Error("[YourTurn] Error while initilising first v2 block from the last v1 block", "ParentBlockHash", parent.Hash(), "Error", err)
|
||||||
return false, err
|
return false, err
|
||||||
}
|
}
|
||||||
} else if parent.Number.Cmp(x.config.V2.SwitchBlock) == 1 { // TODO: XIN-147
|
x.isV2Initilised = true
|
||||||
|
} else if parent.Number.Cmp(x.config.V2.SwitchBlock) == 1 && !x.isV2Initilised { // TODO: XIN-147, temporary solution for now
|
||||||
log.Info("[YourTurn] Initilising v2 after sync or restarted", "currentBlockNum", chain.CurrentHeader().Number, "currentBlockHash", chain.CurrentHeader().Hash())
|
log.Info("[YourTurn] Initilising v2 after sync or restarted", "currentBlockNum", chain.CurrentHeader().Number, "currentBlockHash", chain.CurrentHeader().Hash())
|
||||||
|
lastv1BlockHeader := chain.GetHeaderByNumber(x.config.V2.SwitchBlock.Uint64())
|
||||||
|
err := x.initialV2FromLastV1(chain, lastv1BlockHeader)
|
||||||
|
if err != nil {
|
||||||
|
log.Error("[YourTurn] Temporary solution! Error when initialise v2", "lastv1BlockHeader", lastv1BlockHeader.Hash(), "Error", err)
|
||||||
|
return false, err
|
||||||
|
}
|
||||||
|
x.isV2Initilised = true
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
switch x.config.BlockConsensusVersion(big.NewInt(parent.Number.Int64() + 1)) {
|
switch x.config.BlockConsensusVersion(big.NewInt(parent.Number.Int64() + 1)) {
|
||||||
case params.ConsensusEngineVersion2:
|
case params.ConsensusEngineVersion2:
|
||||||
|
|
|
||||||
|
|
@ -368,8 +368,10 @@ func PrepareXDCTestBlockChainForV2Engine(t *testing.T, numOfBlocks int, chainCon
|
||||||
blockchain := backend.GetBlockChain()
|
blockchain := backend.GetBlockChain()
|
||||||
blockchain.Client = backend
|
blockchain.Client = backend
|
||||||
|
|
||||||
|
engine := blockchain.Engine().(*XDPoS.XDPoS)
|
||||||
|
|
||||||
// Authorise
|
// Authorise
|
||||||
blockchain.Engine().(*XDPoS.XDPoS).Authorize(signer, signFn)
|
engine.Authorize(signer, signFn)
|
||||||
|
|
||||||
currentBlock := blockchain.Genesis()
|
currentBlock := blockchain.Genesis()
|
||||||
|
|
||||||
|
|
@ -410,6 +412,19 @@ func PrepareXDCTestBlockChainForV2Engine(t *testing.T, numOfBlocks int, chainCon
|
||||||
blockchain.InsertBlock(forkedBlock)
|
blockchain.InsertBlock(forkedBlock)
|
||||||
currentForkBlock = forkedBlock
|
currentForkBlock = forkedBlock
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// First v2 block
|
||||||
|
if (int64(i) - chainConfig.XDPoS.V2.SwitchBlock.Int64()) == 1 {
|
||||||
|
lastv1BlockNumber := block.Header().Number.Uint64() - 1
|
||||||
|
checkpointBlockNumber := lastv1BlockNumber - lastv1BlockNumber%chainConfig.XDPoS.Epoch
|
||||||
|
checkpointHeader := blockchain.GetHeaderByNumber(checkpointBlockNumber)
|
||||||
|
masternodes := engine.EngineV1.GetMasternodesFromCheckpointHeader(checkpointHeader)
|
||||||
|
err := engine.EngineV2.Initial(blockchain, block.Header(), masternodes)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
currentBlock = block
|
currentBlock = block
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -374,3 +374,35 @@ func TestVoteMessageShallNotThrowErrorIfBlockNotYetExist(t *testing.T) {
|
||||||
assert.Equal(t, utils.Round(4), highestCommitBlock.Round)
|
assert.Equal(t, utils.Round(4), highestCommitBlock.Round)
|
||||||
assert.Equal(t, big.NewInt(904), highestCommitBlock.Number)
|
assert.Equal(t, big.NewInt(904), highestCommitBlock.Number)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestVerifyVoteMsg(t *testing.T) {
|
||||||
|
blockchain, _, currentBlock, signer, signFn, _ := PrepareXDCTestBlockChainForV2Engine(t, 915, params.TestXDPoSMockChainConfig, 0)
|
||||||
|
engineV2 := blockchain.Engine().(*XDPoS.XDPoS).EngineV2
|
||||||
|
|
||||||
|
blockInfo := &utils.BlockInfo{
|
||||||
|
Hash: currentBlock.Hash(),
|
||||||
|
Round: utils.Round(15),
|
||||||
|
Number: big.NewInt(915),
|
||||||
|
}
|
||||||
|
|
||||||
|
// Invalid vote msg
|
||||||
|
voteMsg := &utils.Vote{
|
||||||
|
ProposedBlockInfo: blockInfo,
|
||||||
|
Signature: []byte{1},
|
||||||
|
}
|
||||||
|
|
||||||
|
verified, err := engineV2.VerifyVoteMessage(blockchain, voteMsg)
|
||||||
|
assert.False(t, verified)
|
||||||
|
assert.NotNil(t, err)
|
||||||
|
|
||||||
|
// Valid vote message from a master node
|
||||||
|
signHash, _ := signFn(accounts.Account{Address: signer}, utils.VoteSigHash(blockInfo).Bytes())
|
||||||
|
voteMsg = &utils.Vote{
|
||||||
|
ProposedBlockInfo: blockInfo,
|
||||||
|
Signature: signHash,
|
||||||
|
}
|
||||||
|
|
||||||
|
verified, err = engineV2.VerifyVoteMessage(blockchain, voteMsg)
|
||||||
|
assert.True(t, verified)
|
||||||
|
assert.Nil(t, err)
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -54,9 +54,9 @@ func TestSequentialVotes(t *testing.T) {
|
||||||
broadcastCounter := uint32(0)
|
broadcastCounter := uint32(0)
|
||||||
targetVotes := 10
|
targetVotes := 10
|
||||||
|
|
||||||
tester.bfter.consensus.verifyVote = func(vote *utils.Vote) error {
|
tester.bfter.consensus.verifyVote = func(chain consensus.ChainReader, vote *utils.Vote) (bool, error) {
|
||||||
atomic.AddUint32(&verifyCounter, 1)
|
atomic.AddUint32(&verifyCounter, 1)
|
||||||
return nil
|
return true, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
tester.bfter.consensus.voteHandler = func(chain consensus.ChainReader, vote *utils.Vote) error {
|
tester.bfter.consensus.voteHandler = func(chain consensus.ChainReader, vote *utils.Vote) error {
|
||||||
|
|
@ -91,9 +91,9 @@ func TestDuplicateVotes(t *testing.T) {
|
||||||
broadcastCounter := uint32(0)
|
broadcastCounter := uint32(0)
|
||||||
targetVotes := 1
|
targetVotes := 1
|
||||||
|
|
||||||
tester.bfter.consensus.verifyVote = func(vote *utils.Vote) error {
|
tester.bfter.consensus.verifyVote = func(chain consensus.ChainReader, vote *utils.Vote) (bool, error) {
|
||||||
atomic.AddUint32(&verifyCounter, 1)
|
atomic.AddUint32(&verifyCounter, 1)
|
||||||
return nil
|
return true, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
tester.bfter.consensus.voteHandler = func(chain consensus.ChainReader, vote *utils.Vote) error {
|
tester.bfter.consensus.voteHandler = func(chain consensus.ChainReader, vote *utils.Vote) error {
|
||||||
|
|
@ -124,8 +124,8 @@ func TestNotBoardcastInvalidVote(t *testing.T) {
|
||||||
broadcastCounter := uint32(0)
|
broadcastCounter := uint32(0)
|
||||||
targetVotes := 0
|
targetVotes := 0
|
||||||
|
|
||||||
tester.bfter.consensus.verifyVote = func(vote *utils.Vote) error {
|
tester.bfter.consensus.verifyVote = func(chain consensus.ChainReader, vote *utils.Vote) (bool, error) {
|
||||||
return fmt.Errorf("This is invalid vote")
|
return false, fmt.Errorf("This is invalid vote")
|
||||||
}
|
}
|
||||||
|
|
||||||
tester.bfter.consensus.voteHandler = func(chain consensus.ChainReader, vote *utils.Vote) error {
|
tester.bfter.consensus.voteHandler = func(chain consensus.ChainReader, vote *utils.Vote) error {
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,8 @@
|
||||||
package bft
|
package bft
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"fmt"
|
||||||
|
|
||||||
"github.com/XinFinOrg/XDPoSChain/consensus"
|
"github.com/XinFinOrg/XDPoSChain/consensus"
|
||||||
"github.com/XinFinOrg/XDPoSChain/consensus/XDPoS"
|
"github.com/XinFinOrg/XDPoSChain/consensus/XDPoS"
|
||||||
"github.com/XinFinOrg/XDPoSChain/consensus/XDPoS/utils"
|
"github.com/XinFinOrg/XDPoSChain/consensus/XDPoS/utils"
|
||||||
|
|
@ -32,7 +34,7 @@ type Bfter struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
type ConsensusFns struct {
|
type ConsensusFns struct {
|
||||||
verifyVote func(*utils.Vote) error
|
verifyVote func(chain consensus.ChainReader, vote *utils.Vote) (bool, error)
|
||||||
voteHandler func(consensus.ChainReader, *utils.Vote) error
|
voteHandler func(consensus.ChainReader, *utils.Vote) error
|
||||||
|
|
||||||
verifyTimeout func(*utils.Timeout) error
|
verifyTimeout func(*utils.Timeout) error
|
||||||
|
|
@ -68,7 +70,7 @@ func (b *Bfter) SetConsensusFuns(engine consensus.Engine) {
|
||||||
b.broadcastCh = e.EngineV2.BroadcastCh
|
b.broadcastCh = e.EngineV2.BroadcastCh
|
||||||
b.consensus = ConsensusFns{
|
b.consensus = ConsensusFns{
|
||||||
verifySyncInfo: e.VerifySyncInfo,
|
verifySyncInfo: e.VerifySyncInfo,
|
||||||
verifyVote: e.VerifyVote,
|
verifyVote: e.EngineV2.VerifyVoteMessage,
|
||||||
verifyTimeout: e.VerifyTimeout,
|
verifyTimeout: e.VerifyTimeout,
|
||||||
|
|
||||||
voteHandler: e.EngineV2.VoteHandler,
|
voteHandler: e.EngineV2.VoteHandler,
|
||||||
|
|
@ -85,11 +87,16 @@ func (b *Bfter) Vote(vote *utils.Vote) error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
err := b.consensus.verifyVote(vote)
|
verified, err := b.consensus.verifyVote(b.blockChainReader, vote)
|
||||||
if err != nil {
|
|
||||||
log.Error("Verify BFT Vote", "error", err)
|
if err != nil || !verified {
|
||||||
|
log.Error("Verify BFT Vote", "error", err, "verified", verified)
|
||||||
|
if !verified {
|
||||||
|
return fmt.Errorf("Fail to verify vote")
|
||||||
|
}
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
b.broadcastCh <- vote
|
b.broadcastCh <- vote
|
||||||
|
|
||||||
err = b.consensus.voteHandler(b.blockChainReader, vote)
|
err = b.consensus.voteHandler(b.blockChainReader, vote)
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue