mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-06-25 07:56:16 +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
|
||||
EngineV1 *engine_v1.XDPoS_v1
|
||||
EngineV2 *engine_v2.XDPoS_v2
|
||||
|
||||
isV2Initilised bool
|
||||
}
|
||||
|
||||
// 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,
|
||||
EngineV1: engine_v1.New(config, db),
|
||||
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)
|
||||
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())
|
||||
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)) {
|
||||
case params.ConsensusEngineVersion2:
|
||||
|
|
|
|||
|
|
@ -368,8 +368,10 @@ func PrepareXDCTestBlockChainForV2Engine(t *testing.T, numOfBlocks int, chainCon
|
|||
blockchain := backend.GetBlockChain()
|
||||
blockchain.Client = backend
|
||||
|
||||
engine := blockchain.Engine().(*XDPoS.XDPoS)
|
||||
|
||||
// Authorise
|
||||
blockchain.Engine().(*XDPoS.XDPoS).Authorize(signer, signFn)
|
||||
engine.Authorize(signer, signFn)
|
||||
|
||||
currentBlock := blockchain.Genesis()
|
||||
|
||||
|
|
@ -410,6 +412,19 @@ func PrepareXDCTestBlockChainForV2Engine(t *testing.T, numOfBlocks int, chainCon
|
|||
blockchain.InsertBlock(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
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -374,3 +374,35 @@ func TestVoteMessageShallNotThrowErrorIfBlockNotYetExist(t *testing.T) {
|
|||
assert.Equal(t, utils.Round(4), highestCommitBlock.Round)
|
||||
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)
|
||||
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)
|
||||
return nil
|
||||
return true, nil
|
||||
}
|
||||
|
||||
tester.bfter.consensus.voteHandler = func(chain consensus.ChainReader, vote *utils.Vote) error {
|
||||
|
|
@ -91,9 +91,9 @@ func TestDuplicateVotes(t *testing.T) {
|
|||
broadcastCounter := uint32(0)
|
||||
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)
|
||||
return nil
|
||||
return true, nil
|
||||
}
|
||||
|
||||
tester.bfter.consensus.voteHandler = func(chain consensus.ChainReader, vote *utils.Vote) error {
|
||||
|
|
@ -124,8 +124,8 @@ func TestNotBoardcastInvalidVote(t *testing.T) {
|
|||
broadcastCounter := uint32(0)
|
||||
targetVotes := 0
|
||||
|
||||
tester.bfter.consensus.verifyVote = func(vote *utils.Vote) error {
|
||||
return fmt.Errorf("This is invalid vote")
|
||||
tester.bfter.consensus.verifyVote = func(chain consensus.ChainReader, vote *utils.Vote) (bool, error) {
|
||||
return false, fmt.Errorf("This is invalid vote")
|
||||
}
|
||||
|
||||
tester.bfter.consensus.voteHandler = func(chain consensus.ChainReader, vote *utils.Vote) error {
|
||||
|
|
|
|||
|
|
@ -1,6 +1,8 @@
|
|||
package bft
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/XinFinOrg/XDPoSChain/consensus"
|
||||
"github.com/XinFinOrg/XDPoSChain/consensus/XDPoS"
|
||||
"github.com/XinFinOrg/XDPoSChain/consensus/XDPoS/utils"
|
||||
|
|
@ -32,7 +34,7 @@ type Bfter 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
|
||||
|
||||
verifyTimeout func(*utils.Timeout) error
|
||||
|
|
@ -68,7 +70,7 @@ func (b *Bfter) SetConsensusFuns(engine consensus.Engine) {
|
|||
b.broadcastCh = e.EngineV2.BroadcastCh
|
||||
b.consensus = ConsensusFns{
|
||||
verifySyncInfo: e.VerifySyncInfo,
|
||||
verifyVote: e.VerifyVote,
|
||||
verifyVote: e.EngineV2.VerifyVoteMessage,
|
||||
verifyTimeout: e.VerifyTimeout,
|
||||
|
||||
voteHandler: e.EngineV2.VoteHandler,
|
||||
|
|
@ -85,11 +87,16 @@ func (b *Bfter) Vote(vote *utils.Vote) error {
|
|||
return nil
|
||||
}
|
||||
|
||||
err := b.consensus.verifyVote(vote)
|
||||
if err != nil {
|
||||
log.Error("Verify BFT Vote", "error", err)
|
||||
verified, err := b.consensus.verifyVote(b.blockChainReader, vote)
|
||||
|
||||
if err != nil || !verified {
|
||||
log.Error("Verify BFT Vote", "error", err, "verified", verified)
|
||||
if !verified {
|
||||
return fmt.Errorf("Fail to verify vote")
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
b.broadcastCh <- vote
|
||||
|
||||
err = b.consensus.voteHandler(b.blockChainReader, vote)
|
||||
|
|
|
|||
Loading…
Reference in a new issue