move XDC consensus types into core (#93)

This commit is contained in:
Jerome 2022-05-22 11:43:25 +10:00 committed by GitHub
parent 727202cac9
commit 455cacc1b7
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
27 changed files with 646 additions and 620 deletions

View file

@ -46,14 +46,14 @@ type XDPoS_v2 struct {
timeoutPool *utils.Pool timeoutPool *utils.Pool
votePool *utils.Pool votePool *utils.Pool
currentRound utils.Round currentRound types.Round
highestSelfMinedRound utils.Round highestSelfMinedRound types.Round
highestVotedRound utils.Round highestVotedRound types.Round
highestQuorumCert *utils.QuorumCert highestQuorumCert *types.QuorumCert
// lockQuorumCert in XDPoS Consensus 2.0, used in voting rule // lockQuorumCert in XDPoS Consensus 2.0, used in voting rule
lockQuorumCert *utils.QuorumCert lockQuorumCert *types.QuorumCert
highestTimeoutCert *utils.TimeoutCert highestTimeoutCert *types.TimeoutCert
highestCommitBlock *utils.BlockInfo highestCommitBlock *types.BlockInfo
HookReward func(chain consensus.ChainReader, state *state.StateDB, parentState *state.StateDB, header *types.Header) (map[string]interface{}, error) HookReward func(chain consensus.ChainReader, state *state.StateDB, parentState *state.StateDB, header *types.Header) (map[string]interface{}, error)
HookPenalty func(chain consensus.ChainReader, number *big.Int, parentHash common.Hash, candidates []common.Address) ([]common.Address, error) HookPenalty func(chain consensus.ChainReader, number *big.Int, parentHash common.Hash, candidates []common.Address) ([]common.Address, error)
@ -90,22 +90,22 @@ func New(config *params.XDPoSConfig, db ethdb.Database, waitPeriodCh chan int) *
timeoutPool: timeoutPool, timeoutPool: timeoutPool,
votePool: votePool, votePool: votePool,
highestSelfMinedRound: utils.Round(0), highestSelfMinedRound: types.Round(0),
highestTimeoutCert: &utils.TimeoutCert{ highestTimeoutCert: &types.TimeoutCert{
Round: utils.Round(0), Round: types.Round(0),
Signatures: []utils.Signature{}, Signatures: []types.Signature{},
}, },
highestQuorumCert: &utils.QuorumCert{ highestQuorumCert: &types.QuorumCert{
ProposedBlockInfo: &utils.BlockInfo{ ProposedBlockInfo: &types.BlockInfo{
Hash: common.Hash{}, Hash: common.Hash{},
Round: utils.Round(0), Round: types.Round(0),
Number: big.NewInt(0), Number: big.NewInt(0),
}, },
Signatures: []utils.Signature{}, Signatures: []types.Signature{},
GapNumber: 0, GapNumber: 0,
}, },
highestVotedRound: utils.Round(0), highestVotedRound: types.Round(0),
highestCommitBlock: nil, highestCommitBlock: nil,
forensics: NewForensics(), forensics: NewForensics(),
} }
@ -138,17 +138,17 @@ func (x *XDPoS_v2) Initial(chain consensus.ChainReader, header *types.Header) er
return nil return nil
} }
var quorumCert *utils.QuorumCert var quorumCert *types.QuorumCert
var err error var err error
if header.Number.Int64() == x.config.V2.SwitchBlock.Int64() { if header.Number.Int64() == x.config.V2.SwitchBlock.Int64() {
log.Info("[Initial] highest QC for consensus v2 first block") log.Info("[Initial] highest QC for consensus v2 first block")
blockInfo := &utils.BlockInfo{ blockInfo := &types.BlockInfo{
Hash: header.Hash(), Hash: header.Hash(),
Round: utils.Round(0), Round: types.Round(0),
Number: header.Number, Number: header.Number,
} }
quorumCert = &utils.QuorumCert{ quorumCert = &types.QuorumCert{
ProposedBlockInfo: blockInfo, ProposedBlockInfo: blockInfo,
Signatures: nil, Signatures: nil,
GapNumber: header.Number.Uint64() - x.config.Gap, GapNumber: header.Number.Uint64() - x.config.Gap,
@ -252,7 +252,7 @@ func (x *XDPoS_v2) Prepare(chain consensus.ChainReader, header *types.Header) er
return consensus.ErrNotReadyToPropose return consensus.ErrNotReadyToPropose
} }
extra := utils.ExtraFields_v2{ extra := types.ExtraFields_v2{
Round: currentRound, Round: currentRound,
QuorumCert: highestQC, QuorumCert: highestQC,
} }
@ -403,7 +403,7 @@ func (x *XDPoS_v2) Seal(chain consensus.ChainReader, block *types.Block, stop <-
header.Validator = signature header.Validator = signature
// Mark the highestSelfMinedRound to make sure we only mine once per round // Mark the highestSelfMinedRound to make sure we only mine once per round
var decodedExtraField utils.ExtraFields_v2 var decodedExtraField types.ExtraFields_v2
err = utils.DecodeBytesExtraFields(header.Extra, &decodedExtraField) err = utils.DecodeBytesExtraFields(header.Extra, &decodedExtraField)
if err != nil { if err != nil {
log.Error("[Seal] Error when decode extra field to get the round number from v2 block during sealing", "Hash", header.Hash().Hex(), "Number", header.Number.Uint64(), "Error", err) log.Error("[Seal] Error when decode extra field to get the round number from v2 block during sealing", "Hash", header.Hash().Hex(), "Number", header.Number.Uint64(), "Error", err)
@ -520,7 +520,7 @@ func (x *XDPoS_v2) VerifyHeaders(chain consensus.ChainReader, headers []*types.H
SyncInfo workflow SyncInfo workflow
*/ */
// Verify syncInfo and trigger process QC or TC if successful // Verify syncInfo and trigger process QC or TC if successful
func (x *XDPoS_v2) VerifySyncInfoMessage(chain consensus.ChainReader, syncInfo *utils.SyncInfo) (bool, error) { func (x *XDPoS_v2) VerifySyncInfoMessage(chain consensus.ChainReader, syncInfo *types.SyncInfo) (bool, error) {
/* /*
1. Check QC and TC against highest QC TC. Skip if none of them need to be updated 1. Check QC and TC against highest QC TC. Skip if none of them need to be updated
2. Verify items including: 2. Verify items including:
@ -547,7 +547,7 @@ func (x *XDPoS_v2) VerifySyncInfoMessage(chain consensus.ChainReader, syncInfo *
return true, nil return true, nil
} }
func (x *XDPoS_v2) SyncInfoHandler(chain consensus.ChainReader, syncInfo *utils.SyncInfo) error { func (x *XDPoS_v2) SyncInfoHandler(chain consensus.ChainReader, syncInfo *types.SyncInfo) error {
x.lock.Lock() x.lock.Lock()
defer x.lock.Unlock() defer x.lock.Unlock()
/* /*
@ -564,7 +564,7 @@ func (x *XDPoS_v2) SyncInfoHandler(chain consensus.ChainReader, syncInfo *utils.
/* /*
Vote workflow Vote workflow
*/ */
func (x *XDPoS_v2) VerifyVoteMessage(chain consensus.ChainReader, vote *utils.Vote) (bool, error) { func (x *XDPoS_v2) VerifyVoteMessage(chain consensus.ChainReader, vote *types.Vote) (bool, error) {
/* /*
1. Check vote round with current round for fast fail(disqualifed) 1. Check vote round with current round for fast fail(disqualifed)
2. Get masterNode list from snapshot by using vote.GapNumber 2. Get masterNode list from snapshot by using vote.GapNumber
@ -583,7 +583,7 @@ func (x *XDPoS_v2) VerifyVoteMessage(chain consensus.ChainReader, vote *utils.Vo
if err != nil { if err != nil {
log.Error("[VerifyVoteMessage] fail to get snapshot for a vote message", "BlockNum", vote.ProposedBlockInfo.Number, "Hash", vote.ProposedBlockInfo.Hash, "Error", err.Error()) log.Error("[VerifyVoteMessage] fail to get snapshot for a vote message", "BlockNum", vote.ProposedBlockInfo.Number, "Hash", vote.ProposedBlockInfo.Hash, "Error", err.Error())
} }
verified, _, err := x.verifyMsgSignature(utils.VoteSigHash(&utils.VoteForSign{ verified, _, err := x.verifyMsgSignature(types.VoteSigHash(&types.VoteForSign{
ProposedBlockInfo: vote.ProposedBlockInfo, ProposedBlockInfo: vote.ProposedBlockInfo,
GapNumber: vote.GapNumber, GapNumber: vote.GapNumber,
}), vote.Signature, snapshot.NextEpochMasterNodes) }), vote.Signature, snapshot.NextEpochMasterNodes)
@ -597,7 +597,7 @@ func (x *XDPoS_v2) VerifyVoteMessage(chain consensus.ChainReader, vote *utils.Vo
} }
// Consensus entry point for processing vote message to produce QC // Consensus entry point for processing vote message to produce QC
func (x *XDPoS_v2) VoteHandler(chain consensus.ChainReader, voteMsg *utils.Vote) error { func (x *XDPoS_v2) VoteHandler(chain consensus.ChainReader, voteMsg *types.Vote) error {
x.lock.Lock() x.lock.Lock()
defer x.lock.Unlock() defer x.lock.Unlock()
return x.voteHandler(chain, voteMsg) return x.voteHandler(chain, voteMsg)
@ -615,7 +615,7 @@ func (x *XDPoS_v2) VoteHandler(chain consensus.ChainReader, voteMsg *utils.Vote)
- Use the above xdc address to check against the master node list from step 1(For the running epoch) - Use the above xdc address to check against the master node list from step 1(For the running epoch)
3. Broadcast(Not part of consensus) 3. Broadcast(Not part of consensus)
*/ */
func (x *XDPoS_v2) VerifyTimeoutMessage(chain consensus.ChainReader, timeoutMsg *utils.Timeout) (bool, error) { func (x *XDPoS_v2) VerifyTimeoutMessage(chain consensus.ChainReader, timeoutMsg *types.Timeout) (bool, error) {
snap, err := x.getSnapshot(chain, timeoutMsg.GapNumber, true) snap, err := x.getSnapshot(chain, timeoutMsg.GapNumber, true)
if err != nil { if err != nil {
log.Error("[VerifyTimeoutMessage] Fail to get snapshot when verifying timeout message!", "messageGapNumber", timeoutMsg.GapNumber) log.Error("[VerifyTimeoutMessage] Fail to get snapshot when verifying timeout message!", "messageGapNumber", timeoutMsg.GapNumber)
@ -625,7 +625,7 @@ func (x *XDPoS_v2) VerifyTimeoutMessage(chain consensus.ChainReader, timeoutMsg
return false, fmt.Errorf("Empty master node lists from snapshot") return false, fmt.Errorf("Empty master node lists from snapshot")
} }
verified, _, err := x.verifyMsgSignature(utils.TimeoutSigHash(&utils.TimeoutForSign{ verified, _, err := x.verifyMsgSignature(types.TimeoutSigHash(&types.TimeoutForSign{
Round: timeoutMsg.Round, Round: timeoutMsg.Round,
GapNumber: timeoutMsg.GapNumber, GapNumber: timeoutMsg.GapNumber,
}), timeoutMsg.Signature, snap.NextEpochMasterNodes) }), timeoutMsg.Signature, snap.NextEpochMasterNodes)
@ -638,7 +638,7 @@ func (x *XDPoS_v2) VerifyTimeoutMessage(chain consensus.ChainReader, timeoutMsg
2. Collect timeout 2. Collect timeout
3. Once timeout pool reached threshold, it will trigger the call to the function "onTimeoutPoolThresholdReached" 3. Once timeout pool reached threshold, it will trigger the call to the function "onTimeoutPoolThresholdReached"
*/ */
func (x *XDPoS_v2) TimeoutHandler(blockChainReader consensus.ChainReader, timeout *utils.Timeout) error { func (x *XDPoS_v2) TimeoutHandler(blockChainReader consensus.ChainReader, timeout *types.Timeout) error {
x.lock.Lock() x.lock.Lock()
defer x.lock.Unlock() defer x.lock.Unlock()
return x.timeoutHandler(blockChainReader, timeout) return x.timeoutHandler(blockChainReader, timeout)
@ -665,7 +665,7 @@ func (x *XDPoS_v2) ProposedBlockHandler(chain consensus.ChainReader, blockHeader
} }
// Generate blockInfo // Generate blockInfo
blockInfo := &utils.BlockInfo{ blockInfo := &types.BlockInfo{
Hash: blockHeader.Hash(), Hash: blockHeader.Hash(),
Round: round, Round: round,
Number: blockHeader.Number, Number: blockHeader.Number,
@ -699,7 +699,7 @@ func (x *XDPoS_v2) ProposedBlockHandler(chain consensus.ChainReader, blockHeader
*/ */
// To be used by different message verification. Verify local DB block info against the received block information(i.e hash, blockNum, round) // To be used by different message verification. Verify local DB block info against the received block information(i.e hash, blockNum, round)
func (x *XDPoS_v2) VerifyBlockInfo(blockChainReader consensus.ChainReader, blockInfo *utils.BlockInfo, blockHeader *types.Header) error { func (x *XDPoS_v2) VerifyBlockInfo(blockChainReader consensus.ChainReader, blockInfo *types.BlockInfo, blockHeader *types.Header) error {
/* /*
1. Check if is able to get header by hash from the chain 1. Check if is able to get header by hash from the chain
2. Check the header from step 1 matches what's in the blockInfo. This includes the block number and the round 2. Check the header from step 1 matches what's in the blockInfo. This includes the block number and the round
@ -746,7 +746,7 @@ func (x *XDPoS_v2) VerifyBlockInfo(blockChainReader consensus.ChainReader, block
return nil return nil
} }
func (x *XDPoS_v2) verifyQC(blockChainReader consensus.ChainReader, quorumCert *utils.QuorumCert, parentHeader *types.Header) error { func (x *XDPoS_v2) verifyQC(blockChainReader consensus.ChainReader, quorumCert *types.QuorumCert, parentHeader *types.Header) error {
/* /*
1. Check if num of QC signatures is >= x.config.v2.CertThreshold 1. Check if num of QC signatures is >= x.config.v2.CertThreshold
2. Get epoch master node list by hash 2. Get epoch master node list by hash
@ -783,9 +783,9 @@ func (x *XDPoS_v2) verifyQC(blockChainReader consensus.ChainReader, quorumCert *
var haveError error var haveError error
for _, signature := range signatures { for _, signature := range signatures {
go func(sig utils.Signature) { go func(sig types.Signature) {
defer wg.Done() defer wg.Done()
verified, _, err := x.verifyMsgSignature(utils.VoteSigHash(&utils.VoteForSign{ verified, _, err := x.verifyMsgSignature(types.VoteSigHash(&types.VoteForSign{
ProposedBlockInfo: quorumCert.ProposedBlockInfo, ProposedBlockInfo: quorumCert.ProposedBlockInfo,
GapNumber: quorumCert.GapNumber, GapNumber: quorumCert.GapNumber,
}), sig, epochInfo.Masternodes) }), sig, epochInfo.Masternodes)
@ -816,7 +816,7 @@ func (x *XDPoS_v2) verifyQC(blockChainReader consensus.ChainReader, quorumCert *
} }
// Update local QC variables including highestQC & lockQuorumCert, as well as commit the blocks that satisfy the algorithm requirements // Update local QC variables including highestQC & lockQuorumCert, as well as commit the blocks that satisfy the algorithm requirements
func (x *XDPoS_v2) processQC(blockChainReader consensus.ChainReader, incomingQuorumCert *utils.QuorumCert) error { func (x *XDPoS_v2) processQC(blockChainReader consensus.ChainReader, incomingQuorumCert *types.QuorumCert) error {
log.Trace("[ProcessQC][Before]", "HighQC", x.highestQuorumCert) log.Trace("[ProcessQC][Before]", "HighQC", x.highestQuorumCert)
// 1. Update HighestQC // 1. Update HighestQC
if incomingQuorumCert.ProposedBlockInfo.Round > x.highestQuorumCert.ProposedBlockInfo.Round { if incomingQuorumCert.ProposedBlockInfo.Round > x.highestQuorumCert.ProposedBlockInfo.Round {
@ -863,7 +863,7 @@ func (x *XDPoS_v2) processQC(blockChainReader consensus.ChainReader, incomingQuo
2. Reset timer 2. Reset timer
3. Reset vote and timeout Pools 3. Reset vote and timeout Pools
*/ */
func (x *XDPoS_v2) setNewRound(blockChainReader consensus.ChainReader, round utils.Round) error { func (x *XDPoS_v2) setNewRound(blockChainReader consensus.ChainReader, round types.Round) error {
x.currentRound = round x.currentRound = round
x.timeoutCount = 0 x.timeoutCount = 0
//TODO: tell miner now it's a new round and start mine if it's leader //TODO: tell miner now it's a new round and start mine if it's leader
@ -879,15 +879,15 @@ func (x *XDPoS_v2) broadcastToBftChannel(msg interface{}) {
}() }()
} }
func (x *XDPoS_v2) getSyncInfo() *utils.SyncInfo { func (x *XDPoS_v2) getSyncInfo() *types.SyncInfo {
return &utils.SyncInfo{ return &types.SyncInfo{
HighestQuorumCert: x.highestQuorumCert, HighestQuorumCert: x.highestQuorumCert,
HighestTimeoutCert: x.highestTimeoutCert, HighestTimeoutCert: x.highestTimeoutCert,
} }
} }
//Find parent and grandparent, check round number, if so, commit grandparent(grandGrandParent of currentBlock) //Find parent and grandparent, check round number, if so, commit grandparent(grandGrandParent of currentBlock)
func (x *XDPoS_v2) commitBlocks(blockChainReader consensus.ChainReader, proposedBlockHeader *types.Header, proposedBlockRound *utils.Round, incomingQc *utils.QuorumCert) (bool, error) { func (x *XDPoS_v2) commitBlocks(blockChainReader consensus.ChainReader, proposedBlockHeader *types.Header, proposedBlockRound *types.Round, incomingQc *types.QuorumCert) (bool, error) {
// XDPoS v1.0 switch to v2.0, skip commit // XDPoS v1.0 switch to v2.0, skip commit
if big.NewInt(0).Sub(proposedBlockHeader.Number, big.NewInt(2)).Cmp(x.config.V2.SwitchBlock) <= 0 { if big.NewInt(0).Sub(proposedBlockHeader.Number, big.NewInt(2)).Cmp(x.config.V2.SwitchBlock) <= 0 {
return false, nil return false, nil
@ -918,7 +918,7 @@ func (x *XDPoS_v2) commitBlocks(blockChainReader consensus.ChainReader, proposed
} }
// Commit the grandParent block // Commit the grandParent block
if x.highestCommitBlock == nil || (x.highestCommitBlock.Round < round && x.highestCommitBlock.Number.Cmp(grandParentBlock.Number) == -1) { if x.highestCommitBlock == nil || (x.highestCommitBlock.Round < round && x.highestCommitBlock.Number.Cmp(grandParentBlock.Number) == -1) {
x.highestCommitBlock = &utils.BlockInfo{ x.highestCommitBlock = &types.BlockInfo{
Number: grandParentBlock.Number, Number: grandParentBlock.Number,
Hash: grandParentBlock.Hash(), Hash: grandParentBlock.Hash(),
Round: round, Round: round,

View file

@ -6,13 +6,12 @@ import (
"github.com/XinFinOrg/XDPoSChain/common" "github.com/XinFinOrg/XDPoSChain/common"
"github.com/XinFinOrg/XDPoSChain/consensus" "github.com/XinFinOrg/XDPoSChain/consensus"
"github.com/XinFinOrg/XDPoSChain/consensus/XDPoS/utils"
"github.com/XinFinOrg/XDPoSChain/core/types" "github.com/XinFinOrg/XDPoSChain/core/types"
"github.com/XinFinOrg/XDPoSChain/log" "github.com/XinFinOrg/XDPoSChain/log"
) )
// get epoch switch of the previous `limit` epoch // get epoch switch of the previous `limit` epoch
func (x *XDPoS_v2) getPreviousEpochSwitchInfoByHash(chain consensus.ChainReader, hash common.Hash, limit int) (*utils.EpochSwitchInfo, error) { func (x *XDPoS_v2) getPreviousEpochSwitchInfoByHash(chain consensus.ChainReader, hash common.Hash, limit int) (*types.EpochSwitchInfo, error) {
epochSwitchInfo, err := x.getEpochSwitchInfo(chain, nil, hash) epochSwitchInfo, err := x.getEpochSwitchInfo(chain, nil, hash)
if err != nil { if err != nil {
log.Error("[getPreviousEpochSwitchInfoByHash] Adaptor v2 getEpochSwitchInfo has error, potentially bug", "err", err) log.Error("[getPreviousEpochSwitchInfoByHash] Adaptor v2 getEpochSwitchInfo has error, potentially bug", "err", err)
@ -30,11 +29,11 @@ func (x *XDPoS_v2) getPreviousEpochSwitchInfoByHash(chain consensus.ChainReader,
// Given header and its hash, get epoch switch info from the epoch switch block of that epoch, // Given header and its hash, get epoch switch info from the epoch switch block of that epoch,
// header is allow to be nil. // header is allow to be nil.
func (x *XDPoS_v2) getEpochSwitchInfo(chain consensus.ChainReader, header *types.Header, hash common.Hash) (*utils.EpochSwitchInfo, error) { func (x *XDPoS_v2) getEpochSwitchInfo(chain consensus.ChainReader, header *types.Header, hash common.Hash) (*types.EpochSwitchInfo, error) {
e, ok := x.epochSwitches.Get(hash) e, ok := x.epochSwitches.Get(hash)
if ok { if ok {
log.Debug("[getEpochSwitchInfo] cache hit", "hash", hash.Hex()) log.Debug("[getEpochSwitchInfo] cache hit", "hash", hash.Hex())
epochSwitchInfo := e.(*utils.EpochSwitchInfo) epochSwitchInfo := e.(*types.EpochSwitchInfo)
return epochSwitchInfo, nil return epochSwitchInfo, nil
} }
h := header h := header
@ -56,9 +55,9 @@ func (x *XDPoS_v2) getEpochSwitchInfo(chain consensus.ChainReader, header *types
if err != nil { if err != nil {
return nil, err return nil, err
} }
epochSwitchInfo := &utils.EpochSwitchInfo{ epochSwitchInfo := &types.EpochSwitchInfo{
Masternodes: masternodes, Masternodes: masternodes,
EpochSwitchBlockInfo: &utils.BlockInfo{ EpochSwitchBlockInfo: &types.BlockInfo{
Hash: hash, Hash: hash,
Number: h.Number, Number: h.Number,
Round: round, Round: round,
@ -82,7 +81,7 @@ func (x *XDPoS_v2) getEpochSwitchInfo(chain consensus.ChainReader, header *types
} }
// IsEpochSwitchAtRound() is used by miner to check whether it mines a block in the same epoch with parent // IsEpochSwitchAtRound() is used by miner to check whether it mines a block in the same epoch with parent
func (x *XDPoS_v2) isEpochSwitchAtRound(round utils.Round, parentHeader *types.Header) (bool, uint64, error) { func (x *XDPoS_v2) isEpochSwitchAtRound(round types.Round, parentHeader *types.Header) (bool, uint64, error) {
epochNum := x.config.V2.SwitchBlock.Uint64()/x.config.Epoch + uint64(round)/x.config.Epoch epochNum := x.config.V2.SwitchBlock.Uint64()/x.config.Epoch + uint64(round)/x.config.Epoch
// if parent is last v1 block and this is first v2 block, this is treated as epoch switch // if parent is last v1 block and this is first v2 block, this is treated as epoch switch
if parentHeader.Number.Cmp(x.config.V2.SwitchBlock) == 0 { if parentHeader.Number.Cmp(x.config.V2.SwitchBlock) == 0 {
@ -99,7 +98,7 @@ func (x *XDPoS_v2) isEpochSwitchAtRound(round utils.Round, parentHeader *types.H
return false, epochNum, nil return false, epochNum, nil
} }
epochStartRound := round - round%utils.Round(x.config.Epoch) epochStartRound := round - round%types.Round(x.config.Epoch)
return parentRound < epochStartRound, epochNum, nil return parentRound < epochStartRound, epochNum, nil
} }
@ -129,7 +128,7 @@ func (x *XDPoS_v2) IsEpochSwitch(header *types.Header) (bool, uint64, error) {
return false, 0, err return false, 0, err
} }
parentRound := quorumCert.ProposedBlockInfo.Round parentRound := quorumCert.ProposedBlockInfo.Round
epochStartRound := round - round%utils.Round(x.config.Epoch) epochStartRound := round - round%types.Round(x.config.Epoch)
epochNum := x.config.V2.SwitchBlock.Uint64()/x.config.Epoch + uint64(round)/x.config.Epoch epochNum := x.config.V2.SwitchBlock.Uint64()/x.config.Epoch + uint64(round)/x.config.Epoch
// if parent is last v1 block and this is first v2 block, this is treated as epoch switch // if parent is last v1 block and this is first v2 block, this is treated as epoch switch
if quorumCert.ProposedBlockInfo.Number.Cmp(x.config.V2.SwitchBlock) == 0 { if quorumCert.ProposedBlockInfo.Number.Cmp(x.config.V2.SwitchBlock) == 0 {

View file

@ -19,7 +19,7 @@ const (
type ForensicsInfo struct { type ForensicsInfo struct {
HashPath []string // HashesTillSmallerRoundQc or HashesTillLargerRoundQc HashPath []string // HashesTillSmallerRoundQc or HashesTillLargerRoundQc
QuorumCert utils.QuorumCert QuorumCert types.QuorumCert
SignerAddresses []string SignerAddresses []string
} }
@ -32,7 +32,7 @@ type ForensicProof struct {
// Forensics instance. Placeholder for future properties to be added // Forensics instance. Placeholder for future properties to be added
type Forensics struct { type Forensics struct {
HighestCommittedQCs []utils.QuorumCert HighestCommittedQCs []types.QuorumCert
} }
// Initiate a forensics process // Initiate a forensics process
@ -40,22 +40,22 @@ func NewForensics() *Forensics {
return &Forensics{} return &Forensics{}
} }
func (f *Forensics) ForensicsMonitoring(chain consensus.ChainReader, engine *XDPoS_v2, headerQcToBeCommitted []types.Header, incomingQC utils.QuorumCert) error { func (f *Forensics) ForensicsMonitoring(chain consensus.ChainReader, engine *XDPoS_v2, headerQcToBeCommitted []types.Header, incomingQC types.QuorumCert) error {
f.ProcessForensics(chain, engine, incomingQC) f.ProcessForensics(chain, engine, incomingQC)
return f.SetCommittedQCs(headerQcToBeCommitted, incomingQC) return f.SetCommittedQCs(headerQcToBeCommitted, incomingQC)
} }
// Set the forensics committed QCs list. The order is from grandparent to current header. i.e it shall follow the QC in its header as follow [hcqc1, hcqc2, hcqc3] // Set the forensics committed QCs list. The order is from grandparent to current header. i.e it shall follow the QC in its header as follow [hcqc1, hcqc2, hcqc3]
func (f *Forensics) SetCommittedQCs(headers []types.Header, incomingQC utils.QuorumCert) error { func (f *Forensics) SetCommittedQCs(headers []types.Header, incomingQC types.QuorumCert) error {
// highestCommitQCs is an array, assign the parentBlockQc and its child as well as its grandchild QC into this array for forensics purposes. // highestCommitQCs is an array, assign the parentBlockQc and its child as well as its grandchild QC into this array for forensics purposes.
if len(headers) != NUM_OF_FORENSICS_QC-1 { if len(headers) != NUM_OF_FORENSICS_QC-1 {
log.Error("[SetCommittedQcs] Received input length not equal to 2", len(headers)) log.Error("[SetCommittedQcs] Received input length not equal to 2", len(headers))
return fmt.Errorf("Received headers length not equal to 2 ") return fmt.Errorf("Received headers length not equal to 2 ")
} }
var committedQCs []utils.QuorumCert var committedQCs []types.QuorumCert
for i, h := range headers { for i, h := range headers {
var decodedExtraField utils.ExtraFields_v2 var decodedExtraField types.ExtraFields_v2
// Decode the qc1 and qc2 // Decode the qc1 and qc2
err := utils.DecodeBytesExtraFields(h.Extra, &decodedExtraField) err := utils.DecodeBytesExtraFields(h.Extra, &decodedExtraField)
if err != nil { if err != nil {
@ -86,7 +86,7 @@ func (f *Forensics) SetCommittedQCs(headers []types.Header, incomingQC utils.Quo
Forensics runs in a seperate go routine as its no system critical Forensics runs in a seperate go routine as its no system critical
Link to the flow diagram: https://hashlabs.atlassian.net/wiki/spaces/HASHLABS/pages/97878029/Forensics+Diagram+flow Link to the flow diagram: https://hashlabs.atlassian.net/wiki/spaces/HASHLABS/pages/97878029/Forensics+Diagram+flow
*/ */
func (f *Forensics) ProcessForensics(chain consensus.ChainReader, engine *XDPoS_v2, incomingQC utils.QuorumCert) error { func (f *Forensics) ProcessForensics(chain consensus.ChainReader, engine *XDPoS_v2, incomingQC types.QuorumCert) error {
log.Debug("Received a QC in forensics", "QC", incomingQC) log.Debug("Received a QC in forensics", "QC", incomingQC)
// Clone the values to a temporary variable // Clone the values to a temporary variable
highestCommittedQCs := f.HighestCommittedQCs highestCommittedQCs := f.HighestCommittedQCs
@ -127,7 +127,7 @@ func (f *Forensics) ProcessForensics(chain consensus.ChainReader, engine *XDPoS_
} }
// Last step of forensics which sends out detailed proof to report service. // Last step of forensics which sends out detailed proof to report service.
func (f *Forensics) SendForensicProof(chain consensus.ChainReader, engine *XDPoS_v2, firstQc utils.QuorumCert, secondQc utils.QuorumCert) error { func (f *Forensics) SendForensicProof(chain consensus.ChainReader, engine *XDPoS_v2, firstQc types.QuorumCert, secondQc types.QuorumCert) error {
// Re-order the QC by its round number to make the function cleaner. // Re-order the QC by its round number to make the function cleaner.
lowerRoundQC := firstQc lowerRoundQC := firstQc
higherRoundQC := secondQc higherRoundQC := secondQc
@ -172,8 +172,8 @@ func (f *Forensics) SendForensicProof(chain consensus.ChainReader, engine *XDPoS
} }
// Utils function to help find the n-th previous QC. It returns an array of QC in ascending order including the currentQc as the last item in the array // Utils function to help find the n-th previous QC. It returns an array of QC in ascending order including the currentQc as the last item in the array
func (f *Forensics) findAncestorQCs(chain consensus.ChainReader, currentQc utils.QuorumCert, distanceFromCurrrentQc int) ([]utils.QuorumCert, error) { func (f *Forensics) findAncestorQCs(chain consensus.ChainReader, currentQc types.QuorumCert, distanceFromCurrrentQc int) ([]types.QuorumCert, error) {
var quorumCerts []utils.QuorumCert var quorumCerts []types.QuorumCert
quorumCertificate := currentQc quorumCertificate := currentQc
// Append the initial value // Append the initial value
quorumCerts = append(quorumCerts, quorumCertificate) quorumCerts = append(quorumCerts, quorumCertificate)
@ -185,7 +185,7 @@ func (f *Forensics) findAncestorQCs(chain consensus.ChainReader, currentQc utils
log.Error("[findAncestorQCs] Forensics findAncestorQCs unable to find its parent block header", "BlockNum", parentHeader.Number.Int64(), "ParentHash", parentHash.Hex()) log.Error("[findAncestorQCs] Forensics findAncestorQCs unable to find its parent block header", "BlockNum", parentHeader.Number.Int64(), "ParentHash", parentHash.Hex())
return nil, fmt.Errorf("Unable to find parent block header in forensics") return nil, fmt.Errorf("Unable to find parent block header in forensics")
} }
var decodedExtraField utils.ExtraFields_v2 var decodedExtraField types.ExtraFields_v2
err := utils.DecodeBytesExtraFields(parentHeader.Extra, &decodedExtraField) err := utils.DecodeBytesExtraFields(parentHeader.Extra, &decodedExtraField)
if err != nil { if err != nil {
log.Error("[findAncestorQCs] Error while trying to decode from parent block extra", "BlockNum", parentHeader.Number.Int64(), "ParentHash", parentHash.Hex()) log.Error("[findAncestorQCs] Error while trying to decode from parent block extra", "BlockNum", parentHeader.Number.Int64(), "ParentHash", parentHash.Hex())
@ -194,7 +194,7 @@ func (f *Forensics) findAncestorQCs(chain consensus.ChainReader, currentQc utils
quorumCerts = append(quorumCerts, quorumCertificate) quorumCerts = append(quorumCerts, quorumCertificate)
} }
// The quorumCerts is in the reverse order, we need to flip it // The quorumCerts is in the reverse order, we need to flip it
var quorumCertsInAscendingOrder []utils.QuorumCert var quorumCertsInAscendingOrder []types.QuorumCert
for i := len(quorumCerts) - 1; i >= 0; i-- { for i := len(quorumCerts) - 1; i >= 0; i-- {
quorumCertsInAscendingOrder = append(quorumCertsInAscendingOrder, quorumCerts[i]) quorumCertsInAscendingOrder = append(quorumCertsInAscendingOrder, quorumCerts[i])
} }
@ -202,7 +202,7 @@ func (f *Forensics) findAncestorQCs(chain consensus.ChainReader, currentQc utils
} }
// Check whether two provided QC set are on the same chain // Check whether two provided QC set are on the same chain
func (f *Forensics) checkQCsOnTheSameChain(chain consensus.ChainReader, highestCommittedQCs []utils.QuorumCert, incomingQCandItsParents []utils.QuorumCert) (bool, error) { func (f *Forensics) checkQCsOnTheSameChain(chain consensus.ChainReader, highestCommittedQCs []types.QuorumCert, incomingQCandItsParents []types.QuorumCert) (bool, error) {
// Re-order two sets of QCs by block Number // Re-order two sets of QCs by block Number
lowerBlockNumQCs := highestCommittedQCs lowerBlockNumQCs := highestCommittedQCs
higherBlockNumQCs := incomingQCandItsParents higherBlockNumQCs := incomingQCandItsParents
@ -214,7 +214,7 @@ func (f *Forensics) checkQCsOnTheSameChain(chain consensus.ChainReader, highestC
proposedBlockInfo := higherBlockNumQCs[0].ProposedBlockInfo proposedBlockInfo := higherBlockNumQCs[0].ProposedBlockInfo
for i := 0; i < int((big.NewInt(0).Sub(higherBlockNumQCs[0].ProposedBlockInfo.Number, lowerBlockNumQCs[0].ProposedBlockInfo.Number)).Int64()); i++ { for i := 0; i < int((big.NewInt(0).Sub(higherBlockNumQCs[0].ProposedBlockInfo.Number, lowerBlockNumQCs[0].ProposedBlockInfo.Number)).Int64()); i++ {
parentHeader := chain.GetHeaderByHash(proposedBlockInfo.Hash) parentHeader := chain.GetHeaderByHash(proposedBlockInfo.Hash)
var decodedExtraField utils.ExtraFields_v2 var decodedExtraField types.ExtraFields_v2
err := utils.DecodeBytesExtraFields(parentHeader.Extra, &decodedExtraField) err := utils.DecodeBytesExtraFields(parentHeader.Extra, &decodedExtraField)
if err != nil { if err != nil {
log.Error("[checkQCsOnTheSameChain] Fail to decode extra when checking the two QCs set on the same chain", "Error", err) log.Error("[checkQCsOnTheSameChain] Fail to decode extra when checking the two QCs set on the same chain", "Error", err)
@ -231,7 +231,7 @@ func (f *Forensics) checkQCsOnTheSameChain(chain consensus.ChainReader, highestC
} }
// Given the two QCs set, find if there are any QC that have the same round // Given the two QCs set, find if there are any QC that have the same round
func (f *Forensics) findQCsInSameRound(quorumCerts1 []utils.QuorumCert, quorumCerts2 []utils.QuorumCert) (bool, utils.QuorumCert, utils.QuorumCert) { func (f *Forensics) findQCsInSameRound(quorumCerts1 []types.QuorumCert, quorumCerts2 []types.QuorumCert) (bool, types.QuorumCert, types.QuorumCert) {
for _, quorumCert1 := range quorumCerts1 { for _, quorumCert1 := range quorumCerts1 {
for _, quorumCert2 := range quorumCerts2 { for _, quorumCert2 := range quorumCerts2 {
if quorumCert1.ProposedBlockInfo.Round == quorumCert2.ProposedBlockInfo.Round { if quorumCert1.ProposedBlockInfo.Round == quorumCert2.ProposedBlockInfo.Round {
@ -239,15 +239,15 @@ func (f *Forensics) findQCsInSameRound(quorumCerts1 []utils.QuorumCert, quorumCe
} }
} }
} }
return false, utils.QuorumCert{}, utils.QuorumCert{} return false, types.QuorumCert{}, types.QuorumCert{}
} }
// Find the signer list from QC signatures // Find the signer list from QC signatures
func (f *Forensics) getQcSignerAddresses(quorumCert utils.QuorumCert) []string { func (f *Forensics) getQcSignerAddresses(quorumCert types.QuorumCert) []string {
var signerList []string var signerList []string
// The QC signatures are signed by votes special struct VoteForSign // The QC signatures are signed by votes special struct VoteForSign
quorumCertSignedHash := utils.VoteSigHash(&utils.VoteForSign{ quorumCertSignedHash := types.VoteSigHash(&types.VoteForSign{
ProposedBlockInfo: quorumCert.ProposedBlockInfo, ProposedBlockInfo: quorumCert.ProposedBlockInfo,
GapNumber: quorumCert.GapNumber, GapNumber: quorumCert.GapNumber,
}) })
@ -265,7 +265,7 @@ func (f *Forensics) getQcSignerAddresses(quorumCert utils.QuorumCert) []string {
} }
// Check whether the given QCs are on the same chain as the stored committed QCs(f.HighestCommittedQCs) regardless their orders // Check whether the given QCs are on the same chain as the stored committed QCs(f.HighestCommittedQCs) regardless their orders
func (f *Forensics) findAncestorQcThroughRound(chain consensus.ChainReader, highestCommittedQCs []utils.QuorumCert, incomingQCandItsParents []utils.QuorumCert) (utils.QuorumCert, []utils.QuorumCert, []utils.QuorumCert, error) { func (f *Forensics) findAncestorQcThroughRound(chain consensus.ChainReader, highestCommittedQCs []types.QuorumCert, incomingQCandItsParents []types.QuorumCert) (types.QuorumCert, []types.QuorumCert, []types.QuorumCert, error) {
/* /*
Re-order two sets of QCs by Round number Re-order two sets of QCs by Round number
*/ */
@ -280,7 +280,7 @@ func (f *Forensics) findAncestorQcThroughRound(chain consensus.ChainReader, high
ancestorQC := higherRoundQCs[0] ancestorQC := higherRoundQCs[0]
for ancestorQC.ProposedBlockInfo.Round >= lowerRoundQCs[NUM_OF_FORENSICS_QC-1].ProposedBlockInfo.Round { for ancestorQC.ProposedBlockInfo.Round >= lowerRoundQCs[NUM_OF_FORENSICS_QC-1].ProposedBlockInfo.Round {
proposedBlock := chain.GetHeaderByHash(ancestorQC.ProposedBlockInfo.Hash) proposedBlock := chain.GetHeaderByHash(ancestorQC.ProposedBlockInfo.Hash)
var decodedExtraField utils.ExtraFields_v2 var decodedExtraField types.ExtraFields_v2
err := utils.DecodeBytesExtraFields(proposedBlock.Extra, &decodedExtraField) err := utils.DecodeBytesExtraFields(proposedBlock.Extra, &decodedExtraField)
if err != nil { if err != nil {
log.Error("[findAncestorQcThroughRound] Error while trying to decode extra field", "ProposedBlockInfo.Hash", ancestorQC.ProposedBlockInfo.Hash) log.Error("[findAncestorQcThroughRound] Error while trying to decode extra field", "ProposedBlockInfo.Hash", ancestorQC.ProposedBlockInfo.Hash)
@ -295,7 +295,7 @@ func (f *Forensics) findAncestorQcThroughRound(chain consensus.ChainReader, high
return ancestorQC, lowerRoundQCs, higherRoundQCs, fmt.Errorf("[findAncestorQcThroughRound] Could not find ancestor QC") return ancestorQC, lowerRoundQCs, higherRoundQCs, fmt.Errorf("[findAncestorQcThroughRound] Could not find ancestor QC")
} }
func (f *Forensics) FindAncestorBlockHash(chain consensus.ChainReader, firstBlockInfo *utils.BlockInfo, secondBlockInfo *utils.BlockInfo) (common.Hash, []string, []string, error) { func (f *Forensics) FindAncestorBlockHash(chain consensus.ChainReader, firstBlockInfo *types.BlockInfo, secondBlockInfo *types.BlockInfo) (common.Hash, []string, []string, error) {
// Re-arrange by block number // Re-arrange by block number
lowerBlockNumHash := firstBlockInfo.Hash lowerBlockNumHash := firstBlockInfo.Hash
higherBlockNumberHash := secondBlockInfo.Hash higherBlockNumberHash := secondBlockInfo.Hash

View file

@ -12,7 +12,7 @@ import (
"github.com/XinFinOrg/XDPoSChain/accounts" "github.com/XinFinOrg/XDPoSChain/accounts"
"github.com/XinFinOrg/XDPoSChain/accounts/keystore" "github.com/XinFinOrg/XDPoSChain/accounts/keystore"
"github.com/XinFinOrg/XDPoSChain/common" "github.com/XinFinOrg/XDPoSChain/common"
"github.com/XinFinOrg/XDPoSChain/consensus/XDPoS/utils" "github.com/XinFinOrg/XDPoSChain/core/types"
"github.com/XinFinOrg/XDPoSChain/crypto" "github.com/XinFinOrg/XDPoSChain/crypto"
"github.com/stretchr/testify/assert" "github.com/stretchr/testify/assert"
) )
@ -72,69 +72,69 @@ func TestFindQCsInSameRound(t *testing.T) {
gapNumber := 450 gapNumber := 450
// If ONE in common // If ONE in common
var sig []utils.Signature var sig []types.Signature
qc1 := &utils.QuorumCert{ qc1 := &types.QuorumCert{
ProposedBlockInfo: &utils.BlockInfo{ ProposedBlockInfo: &types.BlockInfo{
Hash: common.StringToHash("qc1"), Hash: common.StringToHash("qc1"),
Round: utils.Round(10), Round: types.Round(10),
Number: big.NewInt(910), Number: big.NewInt(910),
}, },
Signatures: sig, Signatures: sig,
GapNumber: uint64(gapNumber), GapNumber: uint64(gapNumber),
} }
qc2 := &utils.QuorumCert{ qc2 := &types.QuorumCert{
ProposedBlockInfo: &utils.BlockInfo{ ProposedBlockInfo: &types.BlockInfo{
Hash: common.StringToHash("qc2"), Hash: common.StringToHash("qc2"),
Round: utils.Round(12), Round: types.Round(12),
Number: big.NewInt(910), Number: big.NewInt(910),
}, },
Signatures: sig, Signatures: sig,
GapNumber: uint64(gapNumber), GapNumber: uint64(gapNumber),
} }
qc3 := &utils.QuorumCert{ qc3 := &types.QuorumCert{
ProposedBlockInfo: &utils.BlockInfo{ ProposedBlockInfo: &types.BlockInfo{
Hash: common.StringToHash("qc3"), Hash: common.StringToHash("qc3"),
Round: utils.Round(13), Round: types.Round(13),
Number: big.NewInt(910), Number: big.NewInt(910),
}, },
Signatures: sig, Signatures: sig,
GapNumber: uint64(gapNumber), GapNumber: uint64(gapNumber),
} }
qc4 := &utils.QuorumCert{ qc4 := &types.QuorumCert{
ProposedBlockInfo: &utils.BlockInfo{ ProposedBlockInfo: &types.BlockInfo{
Hash: common.StringToHash("qc4"), Hash: common.StringToHash("qc4"),
Round: utils.Round(12), Round: types.Round(12),
Number: big.NewInt(910), Number: big.NewInt(910),
}, },
Signatures: sig, Signatures: sig,
GapNumber: uint64(gapNumber), GapNumber: uint64(gapNumber),
} }
qc5 := &utils.QuorumCert{ qc5 := &types.QuorumCert{
ProposedBlockInfo: &utils.BlockInfo{ ProposedBlockInfo: &types.BlockInfo{
Hash: common.StringToHash("qc5"), Hash: common.StringToHash("qc5"),
Round: utils.Round(13), Round: types.Round(13),
Number: big.NewInt(910), Number: big.NewInt(910),
}, },
Signatures: sig, Signatures: sig,
GapNumber: uint64(gapNumber), GapNumber: uint64(gapNumber),
} }
qc6 := &utils.QuorumCert{ qc6 := &types.QuorumCert{
ProposedBlockInfo: &utils.BlockInfo{ ProposedBlockInfo: &types.BlockInfo{
Hash: common.StringToHash("qc6"), Hash: common.StringToHash("qc6"),
Round: utils.Round(15), Round: types.Round(15),
Number: big.NewInt(910), Number: big.NewInt(910),
}, },
Signatures: sig, Signatures: sig,
GapNumber: uint64(gapNumber), GapNumber: uint64(gapNumber),
} }
var qcSet1 []utils.QuorumCert var qcSet1 []types.QuorumCert
var qcSet2 []utils.QuorumCert var qcSet2 []types.QuorumCert
found, first, second := forensics.findQCsInSameRound(append(qcSet1, *qc1, *qc2, *qc3), append(qcSet2, *qc4, *qc5, *qc6)) found, first, second := forensics.findQCsInSameRound(append(qcSet1, *qc1, *qc2, *qc3), append(qcSet2, *qc4, *qc5, *qc6))
assert.True(t, found) assert.True(t, found)

View file

@ -12,7 +12,7 @@ import (
) )
// Using parent and current round to find the finalised master node list(with penalties applied from last epoch) // Using parent and current round to find the finalised master node list(with penalties applied from last epoch)
func (x *XDPoS_v2) yourturn(chain consensus.ChainReader, round utils.Round, parent *types.Header, signer common.Address) (bool, error) { func (x *XDPoS_v2) yourturn(chain consensus.ChainReader, round types.Round, parent *types.Header, signer common.Address) (bool, error) {
if round <= x.highestSelfMinedRound { if round <= x.highestSelfMinedRound {
log.Warn("[yourturn] Already mined on this round", "Round", round, "highestSelfMinedRound", x.highestSelfMinedRound, "ParentHash", parent.Hash().Hex(), "ParentNumber", parent.Number) log.Warn("[yourturn] Already mined on this round", "Round", round, "highestSelfMinedRound", x.highestSelfMinedRound, "ParentHash", parent.Hash().Hex(), "ParentNumber", parent.Number)
return false, utils.ErrAlreadyMined return false, utils.ErrAlreadyMined

View file

@ -3,14 +3,14 @@ package engine_v2
import ( import (
"github.com/XinFinOrg/XDPoSChain/common" "github.com/XinFinOrg/XDPoSChain/common"
"github.com/XinFinOrg/XDPoSChain/consensus" "github.com/XinFinOrg/XDPoSChain/consensus"
"github.com/XinFinOrg/XDPoSChain/consensus/XDPoS/utils" "github.com/XinFinOrg/XDPoSChain/core/types"
) )
/* /*
Testing tools Testing tools
*/ */
func (x *XDPoS_v2) SetNewRoundFaker(blockChainReader consensus.ChainReader, newRound utils.Round, resetTimer bool) { func (x *XDPoS_v2) SetNewRoundFaker(blockChainReader consensus.ChainReader, newRound types.Round, resetTimer bool) {
x.lock.Lock() x.lock.Lock()
defer x.lock.Unlock() defer x.lock.Unlock()
// Reset a bunch of things // Reset a bunch of things
@ -21,32 +21,32 @@ func (x *XDPoS_v2) SetNewRoundFaker(blockChainReader consensus.ChainReader, newR
} }
// for test only // for test only
func (x *XDPoS_v2) ProcessQCFaker(chain consensus.ChainReader, qc *utils.QuorumCert) error { func (x *XDPoS_v2) ProcessQCFaker(chain consensus.ChainReader, qc *types.QuorumCert) error {
x.lock.Lock() x.lock.Lock()
defer x.lock.Unlock() defer x.lock.Unlock()
return x.processQC(chain, qc) return x.processQC(chain, qc)
} }
// Utils for test to check currentRound value // Utils for test to check currentRound value
func (x *XDPoS_v2) GetCurrentRoundFaker() utils.Round { func (x *XDPoS_v2) GetCurrentRoundFaker() types.Round {
x.lock.RLock() x.lock.RLock()
defer x.lock.RUnlock() defer x.lock.RUnlock()
return x.currentRound return x.currentRound
} }
// Utils for test to get current Pool size // Utils for test to get current Pool size
func (x *XDPoS_v2) GetVotePoolSizeFaker(vote *utils.Vote) int { func (x *XDPoS_v2) GetVotePoolSizeFaker(vote *types.Vote) int {
return x.votePool.Size(vote) return x.votePool.Size(vote)
} }
// Utils for test to get Timeout Pool Size // Utils for test to get Timeout Pool Size
func (x *XDPoS_v2) GetTimeoutPoolSizeFaker(timeout *utils.Timeout) int { func (x *XDPoS_v2) GetTimeoutPoolSizeFaker(timeout *types.Timeout) int {
return x.timeoutPool.Size(timeout) return x.timeoutPool.Size(timeout)
} }
// WARN: This function is designed for testing purpose only! // WARN: This function is designed for testing purpose only!
// Utils for test to check currentRound values // Utils for test to check currentRound values
func (x *XDPoS_v2) GetPropertiesFaker() (utils.Round, *utils.QuorumCert, *utils.QuorumCert, *utils.TimeoutCert, utils.Round, *utils.BlockInfo) { func (x *XDPoS_v2) GetPropertiesFaker() (types.Round, *types.QuorumCert, *types.QuorumCert, *types.TimeoutCert, types.Round, *types.BlockInfo) {
x.lock.RLock() x.lock.RLock()
defer x.lock.RUnlock() defer x.lock.RUnlock()
return x.currentRound, x.lockQuorumCert, x.highestQuorumCert, x.highestTimeoutCert, x.highestVotedRound, x.highestCommitBlock return x.currentRound, x.lockQuorumCert, x.highestQuorumCert, x.highestTimeoutCert, x.highestVotedRound, x.highestCommitBlock
@ -54,7 +54,7 @@ func (x *XDPoS_v2) GetPropertiesFaker() (utils.Round, *utils.QuorumCert, *utils.
// WARN: This function is designed for testing purpose only! // WARN: This function is designed for testing purpose only!
// Utils for tests to set engine specific values // Utils for tests to set engine specific values
func (x *XDPoS_v2) SetPropertiesFaker(highestQC *utils.QuorumCert, highestTC *utils.TimeoutCert) { func (x *XDPoS_v2) SetPropertiesFaker(highestQC *types.QuorumCert, highestTC *types.TimeoutCert) {
x.highestQuorumCert = highestQC x.highestQuorumCert = highestQC
x.highestTimeoutCert = highestTC x.highestTimeoutCert = highestTC
} }

View file

@ -10,10 +10,11 @@ import (
"github.com/XinFinOrg/XDPoSChain/common" "github.com/XinFinOrg/XDPoSChain/common"
"github.com/XinFinOrg/XDPoSChain/consensus" "github.com/XinFinOrg/XDPoSChain/consensus"
"github.com/XinFinOrg/XDPoSChain/consensus/XDPoS/utils" "github.com/XinFinOrg/XDPoSChain/consensus/XDPoS/utils"
"github.com/XinFinOrg/XDPoSChain/core/types"
"github.com/XinFinOrg/XDPoSChain/log" "github.com/XinFinOrg/XDPoSChain/log"
) )
func (x *XDPoS_v2) timeoutHandler(blockChainReader consensus.ChainReader, timeout *utils.Timeout) error { func (x *XDPoS_v2) timeoutHandler(blockChainReader consensus.ChainReader, timeout *types.Timeout) error {
// 1. checkRoundNumber // 1. checkRoundNumber
if timeout.Round != x.currentRound { if timeout.Round != x.currentRound {
return &utils.ErrIncomingMessageRoundNotEqualCurrentRound{ return &utils.ErrIncomingMessageRoundNotEqualCurrentRound{
@ -47,13 +48,13 @@ func (x *XDPoS_v2) timeoutHandler(blockChainReader consensus.ChainReader, timeou
3. generateSyncInfo() 3. generateSyncInfo()
*/ */
func (x *XDPoS_v2) onTimeoutPoolThresholdReached(blockChainReader consensus.ChainReader, pooledTimeouts map[common.Hash]utils.PoolObj, currentTimeoutMsg utils.PoolObj, gapNumber uint64) error { func (x *XDPoS_v2) onTimeoutPoolThresholdReached(blockChainReader consensus.ChainReader, pooledTimeouts map[common.Hash]utils.PoolObj, currentTimeoutMsg utils.PoolObj, gapNumber uint64) error {
signatures := []utils.Signature{} signatures := []types.Signature{}
for _, v := range pooledTimeouts { for _, v := range pooledTimeouts {
signatures = append(signatures, v.(*utils.Timeout).Signature) signatures = append(signatures, v.(*types.Timeout).Signature)
} }
// Genrate TC // Genrate TC
timeoutCert := &utils.TimeoutCert{ timeoutCert := &types.TimeoutCert{
Round: currentTimeoutMsg.(*utils.Timeout).Round, Round: currentTimeoutMsg.(*types.Timeout).Round,
Signatures: signatures, Signatures: signatures,
GapNumber: gapNumber, GapNumber: gapNumber,
} }
@ -71,7 +72,7 @@ func (x *XDPoS_v2) onTimeoutPoolThresholdReached(blockChainReader consensus.Chai
return nil return nil
} }
func (x *XDPoS_v2) verifyTC(chain consensus.ChainReader, timeoutCert *utils.TimeoutCert) error { func (x *XDPoS_v2) verifyTC(chain consensus.ChainReader, timeoutCert *types.TimeoutCert) error {
/* /*
1. Get epoch master node list by gapNumber 1. Get epoch master node list by gapNumber
2. Check number of signatures > threshold, as well as it's format. (Same as verifyQC) 2. Check number of signatures > threshold, as well as it's format. (Same as verifyQC)
@ -102,13 +103,13 @@ func (x *XDPoS_v2) verifyTC(chain consensus.ChainReader, timeoutCert *utils.Time
wg.Add(len(timeoutCert.Signatures)) wg.Add(len(timeoutCert.Signatures))
var haveError error var haveError error
signedTimeoutObj := utils.TimeoutSigHash(&utils.TimeoutForSign{ signedTimeoutObj := types.TimeoutSigHash(&types.TimeoutForSign{
Round: timeoutCert.Round, Round: timeoutCert.Round,
GapNumber: timeoutCert.GapNumber, GapNumber: timeoutCert.GapNumber,
}) })
for _, signature := range timeoutCert.Signatures { for _, signature := range timeoutCert.Signatures {
go func(sig utils.Signature) { go func(sig types.Signature) {
defer wg.Done() defer wg.Done()
verified, _, err := x.verifyMsgSignature(signedTimeoutObj, sig, snap.NextEpochMasterNodes) verified, _, err := x.verifyMsgSignature(signedTimeoutObj, sig, snap.NextEpochMasterNodes)
if err != nil { if err != nil {
@ -134,7 +135,7 @@ func (x *XDPoS_v2) verifyTC(chain consensus.ChainReader, timeoutCert *utils.Time
1. Update highestTC 1. Update highestTC
2. Check TC round >= node's currentRound. If yes, call setNewRound 2. Check TC round >= node's currentRound. If yes, call setNewRound
*/ */
func (x *XDPoS_v2) processTC(blockChainReader consensus.ChainReader, timeoutCert *utils.TimeoutCert) error { func (x *XDPoS_v2) processTC(blockChainReader consensus.ChainReader, timeoutCert *types.TimeoutCert) error {
if timeoutCert.Round > x.highestTimeoutCert.Round { if timeoutCert.Round > x.highestTimeoutCert.Round {
x.highestTimeoutCert = timeoutCert x.highestTimeoutCert = timeoutCert
} }
@ -177,7 +178,7 @@ func (x *XDPoS_v2) sendTimeout(chain consensus.ChainReader) error {
log.Debug("[sendTimeout] non-epoch-switch block found its epoch block and calculated the gapNumber", "epochSwitchInfo.EpochSwitchBlockInfo.Number", epochSwitchInfo.EpochSwitchBlockInfo.Number.Uint64(), "gapNumber", gapNumber) log.Debug("[sendTimeout] non-epoch-switch block found its epoch block and calculated the gapNumber", "epochSwitchInfo.EpochSwitchBlockInfo.Number", epochSwitchInfo.EpochSwitchBlockInfo.Number.Uint64(), "gapNumber", gapNumber)
} }
signedHash, err := x.signSignature(utils.TimeoutSigHash(&utils.TimeoutForSign{ signedHash, err := x.signSignature(types.TimeoutSigHash(&types.TimeoutForSign{
Round: x.currentRound, Round: x.currentRound,
GapNumber: gapNumber, GapNumber: gapNumber,
})) }))
@ -185,7 +186,7 @@ func (x *XDPoS_v2) sendTimeout(chain consensus.ChainReader) error {
log.Error("[sendTimeout] signSignature when sending out TC", "Error", err) log.Error("[sendTimeout] signSignature when sending out TC", "Error", err)
return err return err
} }
timeoutMsg := &utils.Timeout{ timeoutMsg := &types.Timeout{
Round: x.currentRound, Round: x.currentRound,
Signature: signedHash, Signature: signedHash,
GapNumber: gapNumber, GapNumber: gapNumber,

View file

@ -72,10 +72,10 @@ func decodeMasternodesFromHeaderExtra(checkpointHeader *types.Header) []common.A
return masternodes return masternodes
} }
func UniqueSignatures(signatureSlice []utils.Signature) ([]utils.Signature, []utils.Signature) { func UniqueSignatures(signatureSlice []types.Signature) ([]types.Signature, []types.Signature) {
keys := make(map[string]bool) keys := make(map[string]bool)
list := []utils.Signature{} list := []types.Signature{}
duplicates := []utils.Signature{} duplicates := []types.Signature{}
for _, signature := range signatureSlice { for _, signature := range signatureSlice {
hexOfSig := common.Bytes2Hex(signature) hexOfSig := common.Bytes2Hex(signature)
if _, value := keys[hexOfSig]; !value { if _, value := keys[hexOfSig]; !value {
@ -88,7 +88,7 @@ func UniqueSignatures(signatureSlice []utils.Signature) ([]utils.Signature, []ut
return list, duplicates return list, duplicates
} }
func (x *XDPoS_v2) signSignature(signingHash common.Hash) (utils.Signature, error) { func (x *XDPoS_v2) signSignature(signingHash common.Hash) (types.Signature, error) {
// Don't hold the signFn for the whole signing operation // Don't hold the signFn for the whole signing operation
x.signLock.RLock() x.signLock.RLock()
signer, signFn := x.signer, x.signFn signer, signFn := x.signer, x.signFn
@ -101,7 +101,7 @@ func (x *XDPoS_v2) signSignature(signingHash common.Hash) (utils.Signature, erro
return signedHash, nil return signedHash, nil
} }
func (x *XDPoS_v2) verifyMsgSignature(signedHashToBeVerified common.Hash, signature utils.Signature, masternodes []common.Address) (bool, common.Address, error) { func (x *XDPoS_v2) verifyMsgSignature(signedHashToBeVerified common.Hash, signature types.Signature, masternodes []common.Address) (bool, common.Address, error) {
var signerAddress common.Address var signerAddress common.Address
if len(masternodes) == 0 { if len(masternodes) == 0 {
return false, signerAddress, fmt.Errorf("Empty masternode list detected when verifying message signatures") return false, signerAddress, fmt.Errorf("Empty masternode list detected when verifying message signatures")
@ -122,22 +122,22 @@ func (x *XDPoS_v2) verifyMsgSignature(signedHashToBeVerified common.Hash, signat
return false, signerAddress, fmt.Errorf("Masternodes list does not contain signer address, Signer address: %v", signerAddress.Hex()) return false, signerAddress, fmt.Errorf("Masternodes list does not contain signer address, Signer address: %v", signerAddress.Hex())
} }
func (x *XDPoS_v2) getExtraFields(header *types.Header) (*utils.QuorumCert, utils.Round, []common.Address, error) { func (x *XDPoS_v2) getExtraFields(header *types.Header) (*types.QuorumCert, types.Round, []common.Address, error) {
var masternodes []common.Address var masternodes []common.Address
// last v1 block // last v1 block
if header.Number.Cmp(x.config.V2.SwitchBlock) == 0 { if header.Number.Cmp(x.config.V2.SwitchBlock) == 0 {
masternodes = decodeMasternodesFromHeaderExtra(header) masternodes = decodeMasternodesFromHeaderExtra(header)
return nil, utils.Round(0), masternodes, nil return nil, types.Round(0), masternodes, nil
} }
// v2 block // v2 block
masternodes = x.GetMasternodesFromEpochSwitchHeader(header) masternodes = x.GetMasternodesFromEpochSwitchHeader(header)
var decodedExtraField utils.ExtraFields_v2 var decodedExtraField types.ExtraFields_v2
err := utils.DecodeBytesExtraFields(header.Extra, &decodedExtraField) err := utils.DecodeBytesExtraFields(header.Extra, &decodedExtraField)
if err != nil { if err != nil {
return nil, utils.Round(0), masternodes, err return nil, types.Round(0), masternodes, err
} }
return decodedExtraField.QuorumCert, decodedExtraField.Round, masternodes, nil return decodedExtraField.QuorumCert, decodedExtraField.Round, masternodes, nil
} }

View file

@ -15,7 +15,7 @@ import (
) )
// Once Hot stuff voting rule has verified, this node can then send vote // Once Hot stuff voting rule has verified, this node can then send vote
func (x *XDPoS_v2) sendVote(chainReader consensus.ChainReader, blockInfo *utils.BlockInfo) error { func (x *XDPoS_v2) sendVote(chainReader consensus.ChainReader, blockInfo *types.BlockInfo) error {
// First step: Update the highest Voted round // First step: Update the highest Voted round
// Second step: Generate the signature by using node's private key(The signature is the blockInfo signature) // Second step: Generate the signature by using node's private key(The signature is the blockInfo signature)
// Third step: Construct the vote struct with the above signature & blockinfo struct // Third step: Construct the vote struct with the above signature & blockinfo struct
@ -28,7 +28,7 @@ func (x *XDPoS_v2) sendVote(chainReader consensus.ChainReader, blockInfo *utils.
} }
epochSwitchNumber := epochSwitchInfo.EpochSwitchBlockInfo.Number.Uint64() epochSwitchNumber := epochSwitchInfo.EpochSwitchBlockInfo.Number.Uint64()
gapNumber := epochSwitchNumber - epochSwitchNumber%x.config.Epoch - x.config.Gap gapNumber := epochSwitchNumber - epochSwitchNumber%x.config.Epoch - x.config.Gap
signedHash, err := x.signSignature(utils.VoteSigHash(&utils.VoteForSign{ signedHash, err := x.signSignature(types.VoteSigHash(&types.VoteForSign{
ProposedBlockInfo: blockInfo, ProposedBlockInfo: blockInfo,
GapNumber: gapNumber, GapNumber: gapNumber,
})) }))
@ -38,7 +38,7 @@ func (x *XDPoS_v2) sendVote(chainReader consensus.ChainReader, blockInfo *utils.
} }
x.highestVotedRound = x.currentRound x.highestVotedRound = x.currentRound
voteMsg := &utils.Vote{ voteMsg := &types.Vote{
ProposedBlockInfo: blockInfo, ProposedBlockInfo: blockInfo,
Signature: signedHash, Signature: signedHash,
GapNumber: gapNumber, GapNumber: gapNumber,
@ -53,7 +53,7 @@ func (x *XDPoS_v2) sendVote(chainReader consensus.ChainReader, blockInfo *utils.
return nil return nil
} }
func (x *XDPoS_v2) voteHandler(chain consensus.ChainReader, voteMsg *utils.Vote) error { func (x *XDPoS_v2) voteHandler(chain consensus.ChainReader, voteMsg *types.Vote) error {
// 1. checkRoundNumber // 1. checkRoundNumber
if (voteMsg.ProposedBlockInfo.Round != x.currentRound) && (voteMsg.ProposedBlockInfo.Round != x.currentRound+1) { if (voteMsg.ProposedBlockInfo.Round != x.currentRound) && (voteMsg.ProposedBlockInfo.Round != x.currentRound+1) {
@ -101,12 +101,12 @@ func (x *XDPoS_v2) onVotePoolThresholdReached(chain consensus.ChainReader, poole
// Filter out non-Master nodes signatures // Filter out non-Master nodes signatures
var wg sync.WaitGroup var wg sync.WaitGroup
wg.Add(len(pooledVotes)) wg.Add(len(pooledVotes))
signatureSlice := make([]utils.Signature, len(pooledVotes)) signatureSlice := make([]types.Signature, len(pooledVotes))
counter := 0 counter := 0
for h, vote := range pooledVotes { for h, vote := range pooledVotes {
go func(hash common.Hash, v *utils.Vote, i int) { go func(hash common.Hash, v *types.Vote, i int) {
defer wg.Done() defer wg.Done()
verified, _, err := x.verifyMsgSignature(utils.VoteSigHash(&utils.VoteForSign{ verified, _, err := x.verifyMsgSignature(types.VoteSigHash(&types.VoteForSign{
ProposedBlockInfo: v.ProposedBlockInfo, ProposedBlockInfo: v.ProposedBlockInfo,
GapNumber: v.GapNumber, GapNumber: v.GapNumber,
}), v.Signature, masternodes) }), v.Signature, masternodes)
@ -115,13 +115,13 @@ func (x *XDPoS_v2) onVotePoolThresholdReached(chain consensus.ChainReader, poole
} else { } else {
signatureSlice[i] = v.Signature signatureSlice[i] = v.Signature
} }
}(h, vote.(*utils.Vote), counter) }(h, vote.(*types.Vote), counter)
counter++ counter++
} }
wg.Wait() wg.Wait()
// The signature list may contain empty entey. we only care the ones with values // The signature list may contain empty entey. we only care the ones with values
var validSignatureSlice []utils.Signature var validSignatureSlice []types.Signature
for _, v := range signatureSlice { for _, v := range signatureSlice {
if len(v) != 0 { if len(v) != 0 {
validSignatureSlice = append(validSignatureSlice, v) validSignatureSlice = append(validSignatureSlice, v)
@ -134,10 +134,10 @@ func (x *XDPoS_v2) onVotePoolThresholdReached(chain consensus.ChainReader, poole
return nil return nil
} }
// Genrate QC // Genrate QC
quorumCert := &utils.QuorumCert{ quorumCert := &types.QuorumCert{
ProposedBlockInfo: currentVoteMsg.(*utils.Vote).ProposedBlockInfo, ProposedBlockInfo: currentVoteMsg.(*types.Vote).ProposedBlockInfo,
Signatures: validSignatureSlice, Signatures: validSignatureSlice,
GapNumber: currentVoteMsg.(*utils.Vote).GapNumber, GapNumber: currentVoteMsg.(*types.Vote).GapNumber,
} }
err := x.processQC(chain, quorumCert) err := x.processQC(chain, quorumCert)
if err != nil { if err != nil {
@ -149,7 +149,7 @@ func (x *XDPoS_v2) onVotePoolThresholdReached(chain consensus.ChainReader, poole
} }
// Hot stuff rule to decide whether this node is eligible to vote for the received block // Hot stuff rule to decide whether this node is eligible to vote for the received block
func (x *XDPoS_v2) verifyVotingRule(blockChainReader consensus.ChainReader, blockInfo *utils.BlockInfo, quorumCert *utils.QuorumCert) (bool, error) { func (x *XDPoS_v2) verifyVotingRule(blockChainReader consensus.ChainReader, blockInfo *types.BlockInfo, quorumCert *types.QuorumCert) (bool, error) {
// Make sure this node has not voted for this round. // Make sure this node has not voted for this round.
if x.currentRound <= x.highestVotedRound { if x.currentRound <= x.highestVotedRound {
return false, nil return false, nil
@ -183,7 +183,7 @@ func (x *XDPoS_v2) verifyVotingRule(blockChainReader consensus.ChainReader, bloc
return false, nil return false, nil
} }
func (x *XDPoS_v2) isExtendingFromAncestor(blockChainReader consensus.ChainReader, currentBlock *utils.BlockInfo, ancestorBlock *utils.BlockInfo) (bool, error) { func (x *XDPoS_v2) isExtendingFromAncestor(blockChainReader consensus.ChainReader, currentBlock *types.BlockInfo, ancestorBlock *types.BlockInfo) (bool, error) {
blockNumDiff := int(big.NewInt(0).Sub(currentBlock.Number, ancestorBlock.Number).Int64()) blockNumDiff := int(big.NewInt(0).Sub(currentBlock.Number, ancestorBlock.Number).Int64())
nextBlockHash := currentBlock.Hash nextBlockHash := currentBlock.Hash

View file

@ -3,6 +3,8 @@ package utils
import ( import (
"errors" "errors"
"fmt" "fmt"
"github.com/XinFinOrg/XDPoSChain/core/types"
) )
// Various error messages to mark blocks invalid. These should be private to // Various error messages to mark blocks invalid. These should be private to
@ -98,8 +100,8 @@ var (
type ErrIncomingMessageRoundNotEqualCurrentRound struct { type ErrIncomingMessageRoundNotEqualCurrentRound struct {
Type string Type string
IncomingRound Round IncomingRound types.Round
CurrentRound Round CurrentRound types.Round
} }
func (e *ErrIncomingMessageRoundNotEqualCurrentRound) Error() string { func (e *ErrIncomingMessageRoundNotEqualCurrentRound) Error() string {
@ -108,8 +110,8 @@ func (e *ErrIncomingMessageRoundNotEqualCurrentRound) Error() string {
type ErrIncomingMessageRoundTooFarFromCurrentRound struct { type ErrIncomingMessageRoundTooFarFromCurrentRound struct {
Type string Type string
IncomingRound Round IncomingRound types.Round
CurrentRound Round CurrentRound types.Round
} }
func (e *ErrIncomingMessageRoundTooFarFromCurrentRound) Error() string { func (e *ErrIncomingMessageRoundTooFarFromCurrentRound) Error() string {

View file

@ -3,6 +3,7 @@ package utils
import ( import (
"testing" "testing"
"github.com/XinFinOrg/XDPoSChain/core/types"
"github.com/stretchr/testify/assert" "github.com/stretchr/testify/assert"
) )
@ -10,10 +11,10 @@ func TestPoolAdd(t *testing.T) {
assert := assert.New(t) assert := assert.New(t)
pool := NewPool(2) // 2 is the cert threshold pool := NewPool(2) // 2 is the cert threshold
timeout1 := Timeout{Round: 1, Signature: []byte{1}} timeout1 := types.Timeout{Round: 1, Signature: []byte{1}}
timeout2 := Timeout{Round: 1, Signature: []byte{2}} timeout2 := types.Timeout{Round: 1, Signature: []byte{2}}
timeout3 := Timeout{Round: 1, Signature: []byte{3}} timeout3 := types.Timeout{Round: 1, Signature: []byte{3}}
timeout4 := Timeout{Round: 1, Signature: []byte{4}} timeout4 := types.Timeout{Round: 1, Signature: []byte{4}}
thresholdReached, numOfItems, pooledTimeouts := pool.Add(&timeout1) thresholdReached, numOfItems, pooledTimeouts := pool.Add(&timeout1)
assert.NotNil(pooledTimeouts) assert.NotNil(pooledTimeouts)
assert.Equal(1, numOfItems) assert.Equal(1, numOfItems)

View file

@ -1,7 +1,6 @@
package utils package utils
import ( import (
"fmt"
"math/big" "math/big"
"time" "time"
@ -12,9 +11,6 @@ import (
"github.com/XinFinOrg/XDPoSChain/consensus/clique" "github.com/XinFinOrg/XDPoSChain/consensus/clique"
"github.com/XinFinOrg/XDPoSChain/core/state" "github.com/XinFinOrg/XDPoSChain/core/state"
"github.com/XinFinOrg/XDPoSChain/core/types" "github.com/XinFinOrg/XDPoSChain/core/types"
"github.com/XinFinOrg/XDPoSChain/crypto/sha3"
"github.com/XinFinOrg/XDPoSChain/log"
"github.com/XinFinOrg/XDPoSChain/rlp"
"gopkg.in/karalabe/cookiejar.v2/collections/prque" "gopkg.in/karalabe/cookiejar.v2/collections/prque"
) )
@ -61,121 +57,3 @@ type PublicApiSnapshot struct {
Votes []*clique.Vote `json:"votes"` // List of votes cast in chronological order Votes []*clique.Vote `json:"votes"` // List of votes cast in chronological order
Tally map[common.Address]clique.Tally `json:"tally"` // Current vote tally to avoid recalculating Tally map[common.Address]clique.Tally `json:"tally"` // Current vote tally to avoid recalculating
} }
// Round number type in XDPoS 2.0
type Round uint64
type Signature []byte
// Block Info struct in XDPoS 2.0, used for vote message, etc.
type BlockInfo struct {
Hash common.Hash
Round Round
Number *big.Int
}
// Vote message in XDPoS 2.0
type Vote struct {
ProposedBlockInfo *BlockInfo
Signature Signature
GapNumber uint64
}
// Timeout message in XDPoS 2.0
type Timeout struct {
Round Round
Signature Signature
GapNumber uint64
}
// BFT Sync Info message in XDPoS 2.0
type SyncInfo struct {
HighestQuorumCert *QuorumCert
HighestTimeoutCert *TimeoutCert
}
// Quorum Certificate struct in XDPoS 2.0
type QuorumCert struct {
ProposedBlockInfo *BlockInfo
Signatures []Signature
GapNumber uint64
}
// Timeout Certificate struct in XDPoS 2.0
type TimeoutCert struct {
Round Round
Signatures []Signature
GapNumber uint64
}
// The parsed extra fields in block header in XDPoS 2.0 (excluding the version byte)
// The version byte (consensus version) is the first byte in header's extra and it's only valid with value >= 2
type ExtraFields_v2 struct {
Round Round
QuorumCert *QuorumCert
}
type EpochSwitchInfo struct {
Masternodes []common.Address
EpochSwitchBlockInfo *BlockInfo
EpochSwitchParentBlockInfo *BlockInfo
}
// Encode XDPoS 2.0 extra fields into bytes
func (e *ExtraFields_v2) EncodeToBytes() ([]byte, error) {
bytes, err := rlp.EncodeToBytes(e)
if err != nil {
return nil, err
}
versionByte := []byte{2}
return append(versionByte, bytes...), nil
}
func rlpHash(x interface{}) (h common.Hash) {
hw := sha3.NewKeccak256()
err := rlp.Encode(hw, x)
if err != nil {
log.Error("[rlpHash] Fail to hash item", "Error", err)
}
hw.Sum(h[:0])
return h
}
func (m *Vote) Hash() common.Hash {
return rlpHash(m)
}
func (m *Timeout) Hash() common.Hash {
return rlpHash(m)
}
func (m *SyncInfo) Hash() common.Hash {
return rlpHash(m)
}
type VoteForSign struct {
ProposedBlockInfo *BlockInfo
GapNumber uint64
}
func VoteSigHash(m *VoteForSign) common.Hash {
return rlpHash(m)
}
type TimeoutForSign struct {
Round Round
GapNumber uint64
}
func TimeoutSigHash(m *TimeoutForSign) common.Hash {
return rlpHash(m)
}
func (m *Vote) PoolKey() string {
// return the voted block hash
return fmt.Sprint(m.ProposedBlockInfo.Round, ":", m.GapNumber, ":", m.ProposedBlockInfo.Number, ":", m.ProposedBlockInfo.Hash.Hex())
}
func (m *Timeout) PoolKey() string {
// timeout pool key is round:gapNumber
return fmt.Sprint(m.Round, ":", m.GapNumber)
}

View file

@ -8,6 +8,7 @@ import (
"strconv" "strconv"
"github.com/XinFinOrg/XDPoSChain/common" "github.com/XinFinOrg/XDPoSChain/common"
"github.com/XinFinOrg/XDPoSChain/crypto/sha3"
"github.com/XinFinOrg/XDPoSChain/log" "github.com/XinFinOrg/XDPoSChain/log"
"github.com/XinFinOrg/XDPoSChain/rlp" "github.com/XinFinOrg/XDPoSChain/rlp"
) )
@ -78,3 +79,13 @@ func DecodeBytesExtraFields(b []byte, val interface{}) error {
return fmt.Errorf("consensus version %d is not defined", b[0]) return fmt.Errorf("consensus version %d is not defined", b[0])
} }
} }
func rlpHash(x interface{}) (h common.Hash) {
hw := sha3.NewKeccak256()
err := rlp.Encode(hw, x)
if err != nil {
log.Error("[rlpHash] Fail to hash item", "Error", err)
}
hw.Sum(h[:0])
return h
}

View file

@ -7,7 +7,6 @@ import (
"github.com/XinFinOrg/XDPoSChain/common" "github.com/XinFinOrg/XDPoSChain/common"
"github.com/XinFinOrg/XDPoSChain/consensus/XDPoS" "github.com/XinFinOrg/XDPoSChain/consensus/XDPoS"
"github.com/XinFinOrg/XDPoSChain/consensus/XDPoS/utils"
"github.com/XinFinOrg/XDPoSChain/core/types" "github.com/XinFinOrg/XDPoSChain/core/types"
"github.com/XinFinOrg/XDPoSChain/params" "github.com/XinFinOrg/XDPoSChain/params"
"github.com/stretchr/testify/assert" "github.com/stretchr/testify/assert"
@ -88,17 +87,17 @@ func TestAdaptorIsEpochSwitch(t *testing.T) {
assert.Nil(t, err) assert.Nil(t, err)
assert.False(t, isEpochSwitchBlock, "header should not be epoch switch", header) assert.False(t, isEpochSwitchBlock, "header should not be epoch switch", header)
// v2 // v2
parentBlockInfo := &utils.BlockInfo{ parentBlockInfo := &types.BlockInfo{
Hash: header.ParentHash, Hash: header.ParentHash,
Round: utils.Round(0), Round: types.Round(0),
Number: big.NewInt(0).Set(blockchain.Config().XDPoS.V2.SwitchBlock), Number: big.NewInt(0).Set(blockchain.Config().XDPoS.V2.SwitchBlock),
} }
quorumCert := &utils.QuorumCert{ quorumCert := &types.QuorumCert{
ProposedBlockInfo: parentBlockInfo, ProposedBlockInfo: parentBlockInfo,
Signatures: nil, Signatures: nil,
GapNumber: blockchain.Config().XDPoS.V2.SwitchBlock.Uint64() - blockchain.Config().XDPoS.Gap, GapNumber: blockchain.Config().XDPoS.V2.SwitchBlock.Uint64() - blockchain.Config().XDPoS.Gap,
} }
extra := utils.ExtraFields_v2{ extra := types.ExtraFields_v2{
Round: 1, Round: 1,
QuorumCert: quorumCert, QuorumCert: quorumCert,
} }
@ -109,17 +108,17 @@ func TestAdaptorIsEpochSwitch(t *testing.T) {
isEpochSwitchBlock, _, err = adaptor.IsEpochSwitch(header) isEpochSwitchBlock, _, err = adaptor.IsEpochSwitch(header)
assert.Nil(t, err) assert.Nil(t, err)
assert.True(t, isEpochSwitchBlock, "header should be epoch switch", header) assert.True(t, isEpochSwitchBlock, "header should be epoch switch", header)
parentBlockInfo = &utils.BlockInfo{ parentBlockInfo = &types.BlockInfo{
Hash: header.ParentHash, Hash: header.ParentHash,
Round: utils.Round(1), Round: types.Round(1),
Number: big.NewInt(0).Add(blockchain.Config().XDPoS.V2.SwitchBlock, big.NewInt(1)), Number: big.NewInt(0).Add(blockchain.Config().XDPoS.V2.SwitchBlock, big.NewInt(1)),
} }
quorumCert = &utils.QuorumCert{ quorumCert = &types.QuorumCert{
ProposedBlockInfo: parentBlockInfo, ProposedBlockInfo: parentBlockInfo,
Signatures: nil, Signatures: nil,
GapNumber: blockchain.Config().XDPoS.V2.SwitchBlock.Uint64() - blockchain.Config().XDPoS.Gap, GapNumber: blockchain.Config().XDPoS.V2.SwitchBlock.Uint64() - blockchain.Config().XDPoS.Gap,
} }
extra = utils.ExtraFields_v2{ extra = types.ExtraFields_v2{
Round: 2, Round: 2,
QuorumCert: quorumCert, QuorumCert: quorumCert,
} }
@ -130,18 +129,18 @@ func TestAdaptorIsEpochSwitch(t *testing.T) {
isEpochSwitchBlock, _, err = adaptor.IsEpochSwitch(header) isEpochSwitchBlock, _, err = adaptor.IsEpochSwitch(header)
assert.Nil(t, err) assert.Nil(t, err)
assert.False(t, isEpochSwitchBlock, "header should not be epoch switch", header) assert.False(t, isEpochSwitchBlock, "header should not be epoch switch", header)
parentBlockInfo = &utils.BlockInfo{ parentBlockInfo = &types.BlockInfo{
Hash: header.ParentHash, Hash: header.ParentHash,
Round: utils.Round(blockchain.Config().XDPoS.Epoch) - 1, Round: types.Round(blockchain.Config().XDPoS.Epoch) - 1,
Number: big.NewInt(0).Add(blockchain.Config().XDPoS.V2.SwitchBlock, big.NewInt(100)), Number: big.NewInt(0).Add(blockchain.Config().XDPoS.V2.SwitchBlock, big.NewInt(100)),
} }
quorumCert = &utils.QuorumCert{ quorumCert = &types.QuorumCert{
ProposedBlockInfo: parentBlockInfo, ProposedBlockInfo: parentBlockInfo,
Signatures: nil, Signatures: nil,
GapNumber: blockchain.Config().XDPoS.V2.SwitchBlock.Uint64() - blockchain.Config().XDPoS.Gap, GapNumber: blockchain.Config().XDPoS.V2.SwitchBlock.Uint64() - blockchain.Config().XDPoS.Gap,
} }
extra = utils.ExtraFields_v2{ extra = types.ExtraFields_v2{
Round: utils.Round(blockchain.Config().XDPoS.Epoch) + 1, Round: types.Round(blockchain.Config().XDPoS.Epoch) + 1,
QuorumCert: quorumCert, QuorumCert: quorumCert,
} }
extraBytes, err = extra.EncodeToBytes() extraBytes, err = extra.EncodeToBytes()
@ -151,18 +150,18 @@ func TestAdaptorIsEpochSwitch(t *testing.T) {
isEpochSwitchBlock, _, err = adaptor.IsEpochSwitch(header) isEpochSwitchBlock, _, err = adaptor.IsEpochSwitch(header)
assert.Nil(t, err) assert.Nil(t, err)
assert.True(t, isEpochSwitchBlock, "header should be epoch switch", header) assert.True(t, isEpochSwitchBlock, "header should be epoch switch", header)
parentBlockInfo = &utils.BlockInfo{ parentBlockInfo = &types.BlockInfo{
Hash: header.ParentHash, Hash: header.ParentHash,
Round: utils.Round(blockchain.Config().XDPoS.Epoch) + 1, Round: types.Round(blockchain.Config().XDPoS.Epoch) + 1,
Number: big.NewInt(0).Add(blockchain.Config().XDPoS.V2.SwitchBlock, big.NewInt(100)), Number: big.NewInt(0).Add(blockchain.Config().XDPoS.V2.SwitchBlock, big.NewInt(100)),
} }
quorumCert = &utils.QuorumCert{ quorumCert = &types.QuorumCert{
ProposedBlockInfo: parentBlockInfo, ProposedBlockInfo: parentBlockInfo,
Signatures: nil, Signatures: nil,
GapNumber: blockchain.Config().XDPoS.V2.SwitchBlock.Uint64() - blockchain.Config().XDPoS.Gap, GapNumber: blockchain.Config().XDPoS.V2.SwitchBlock.Uint64() - blockchain.Config().XDPoS.Gap,
} }
extra = utils.ExtraFields_v2{ extra = types.ExtraFields_v2{
Round: utils.Round(blockchain.Config().XDPoS.Epoch) + 2, Round: types.Round(blockchain.Config().XDPoS.Epoch) + 2,
QuorumCert: quorumCert, QuorumCert: quorumCert,
} }
extraBytes, err = extra.EncodeToBytes() extraBytes, err = extra.EncodeToBytes()

View file

@ -20,23 +20,23 @@ func TestProcessQcShallSetForensicsCommittedQc(t *testing.T) {
engineV2 := blockchain.Engine().(*XDPoS.XDPoS).EngineV2 engineV2 := blockchain.Engine().(*XDPoS.XDPoS).EngineV2
// Assuming we are getting block 906 which have QC pointing at block 905 // Assuming we are getting block 906 which have QC pointing at block 905
blockInfo := &utils.BlockInfo{ blockInfo := &types.BlockInfo{
Hash: currentBlock.Hash(), Hash: currentBlock.Hash(),
Round: utils.Round(5), Round: types.Round(5),
Number: big.NewInt(905), Number: big.NewInt(905),
} }
voteForSign := &utils.VoteForSign{ voteForSign := &types.VoteForSign{
ProposedBlockInfo: blockInfo, ProposedBlockInfo: blockInfo,
GapNumber: 450, GapNumber: 450,
} }
voteSigningHash := utils.VoteSigHash(voteForSign) voteSigningHash := types.VoteSigHash(voteForSign)
// Set round to 5 // Set round to 5
engineV2.SetNewRoundFaker(blockchain, utils.Round(5), false) engineV2.SetNewRoundFaker(blockchain, types.Round(5), false)
// Create two vote messages which will not reach vote pool threshold // Create two vote messages which will not reach vote pool threshold
signedHash, err := signFn(accounts.Account{Address: signer}, voteSigningHash.Bytes()) signedHash, err := signFn(accounts.Account{Address: signer}, voteSigningHash.Bytes())
assert.Nil(t, err) assert.Nil(t, err)
voteMsg := &utils.Vote{ voteMsg := &types.Vote{
ProposedBlockInfo: blockInfo, ProposedBlockInfo: blockInfo,
Signature: signedHash, Signature: signedHash,
GapNumber: 450, GapNumber: 450,
@ -45,7 +45,7 @@ func TestProcessQcShallSetForensicsCommittedQc(t *testing.T) {
err = engineV2.VoteHandler(blockchain, voteMsg) err = engineV2.VoteHandler(blockchain, voteMsg)
assert.Nil(t, err) assert.Nil(t, err)
signedHash = SignHashByPK(acc1Key, voteSigningHash.Bytes()) signedHash = SignHashByPK(acc1Key, voteSigningHash.Bytes())
voteMsg = &utils.Vote{ voteMsg = &types.Vote{
ProposedBlockInfo: blockInfo, ProposedBlockInfo: blockInfo,
Signature: signedHash, Signature: signedHash,
GapNumber: 450, GapNumber: 450,
@ -58,7 +58,7 @@ func TestProcessQcShallSetForensicsCommittedQc(t *testing.T) {
assert.Nil(t, err) assert.Nil(t, err)
randomlySignedHash, err := randomSignFn(accounts.Account{Address: randomSigner}, voteSigningHash.Bytes()) randomlySignedHash, err := randomSignFn(accounts.Account{Address: randomSigner}, voteSigningHash.Bytes())
assert.Nil(t, err) assert.Nil(t, err)
voteMsg = &utils.Vote{ voteMsg = &types.Vote{
ProposedBlockInfo: blockInfo, ProposedBlockInfo: blockInfo,
Signature: randomlySignedHash, Signature: randomlySignedHash,
GapNumber: 450, GapNumber: 450,
@ -68,7 +68,7 @@ func TestProcessQcShallSetForensicsCommittedQc(t *testing.T) {
// Create a vote message that should trigger vote pool hook and increment the round to 6 // Create a vote message that should trigger vote pool hook and increment the round to 6
signedHash = SignHashByPK(acc3Key, voteSigningHash.Bytes()) signedHash = SignHashByPK(acc3Key, voteSigningHash.Bytes())
voteMsg = &utils.Vote{ voteMsg = &types.Vote{
ProposedBlockInfo: blockInfo, ProposedBlockInfo: blockInfo,
Signature: signedHash, Signature: signedHash,
GapNumber: 450, GapNumber: 450,
@ -86,7 +86,7 @@ func TestSetCommittedQCsInOrder(t *testing.T) {
forensics := blockchain.Engine().(*XDPoS.XDPoS).EngineV2.GetForensicsFaker() forensics := blockchain.Engine().(*XDPoS.XDPoS).EngineV2.GetForensicsFaker()
var headers []types.Header var headers []types.Header
var decodedExtraField utils.ExtraFields_v2 var decodedExtraField types.ExtraFields_v2
// Decode the qc1 and qc2 // Decode the qc1 and qc2
err := utils.DecodeBytesExtraFields(currentBlock.Header().Extra, &decodedExtraField) err := utils.DecodeBytesExtraFields(currentBlock.Header().Extra, &decodedExtraField)
assert.Nil(t, err) assert.Nil(t, err)
@ -110,14 +110,14 @@ func TestSetCommittedQCsInOrder(t *testing.T) {
func TestForensicsMonitoring(t *testing.T) { func TestForensicsMonitoring(t *testing.T) {
blockchain, _, currentBlock, _, _, _ := PrepareXDCTestBlockChainForV2Engine(t, 915, params.TestXDPoSMockChainConfig, nil) blockchain, _, currentBlock, _, _, _ := PrepareXDCTestBlockChainForV2Engine(t, 915, params.TestXDPoSMockChainConfig, nil)
forensics := blockchain.Engine().(*XDPoS.XDPoS).EngineV2.GetForensicsFaker() forensics := blockchain.Engine().(*XDPoS.XDPoS).EngineV2.GetForensicsFaker()
var decodedCurrentblockExtraField utils.ExtraFields_v2 var decodedCurrentblockExtraField types.ExtraFields_v2
// Decode the QC from latest block // Decode the QC from latest block
err := utils.DecodeBytesExtraFields(currentBlock.Header().Extra, &decodedCurrentblockExtraField) err := utils.DecodeBytesExtraFields(currentBlock.Header().Extra, &decodedCurrentblockExtraField)
assert.Nil(t, err) assert.Nil(t, err)
incomingQC := decodedCurrentblockExtraField.QuorumCert incomingQC := decodedCurrentblockExtraField.QuorumCert
// Now, let's try set committed blocks, where the highestedCommitted blocks are 905, 906 and 907 // Now, let's try set committed blocks, where the highestedCommitted blocks are 905, 906 and 907
var headers []types.Header var headers []types.Header
var decodedBlock905ExtraField utils.ExtraFields_v2 var decodedBlock905ExtraField types.ExtraFields_v2
err = utils.DecodeBytesExtraFields(blockchain.GetHeaderByNumber(905).Extra, &decodedBlock905ExtraField) err = utils.DecodeBytesExtraFields(blockchain.GetHeaderByNumber(905).Extra, &decodedBlock905ExtraField)
assert.Nil(t, err) assert.Nil(t, err)
@ -139,13 +139,13 @@ func TestForensicsMonitoringNotOnSameChainButHaveSameRoundQC(t *testing.T) {
// Now, let's try set committed blocks, where the highestedCommitted blocks are 913, 914 and 915 // Now, let's try set committed blocks, where the highestedCommitted blocks are 913, 914 and 915
var headers []types.Header var headers []types.Header
var decodedBlock915ExtraField utils.ExtraFields_v2 var decodedBlock915ExtraField types.ExtraFields_v2
err := utils.DecodeBytesExtraFields(blockchain.GetHeaderByNumber(915).Extra, &decodedBlock915ExtraField) err := utils.DecodeBytesExtraFields(blockchain.GetHeaderByNumber(915).Extra, &decodedBlock915ExtraField)
assert.Nil(t, err) assert.Nil(t, err)
err = forensics.SetCommittedQCs(append(headers, *blockchain.GetHeaderByNumber(913), *blockchain.GetHeaderByNumber(914)), *decodedBlock915ExtraField.QuorumCert) err = forensics.SetCommittedQCs(append(headers, *blockchain.GetHeaderByNumber(913), *blockchain.GetHeaderByNumber(914)), *decodedBlock915ExtraField.QuorumCert)
assert.Nil(t, err) assert.Nil(t, err)
var decodedExtraField utils.ExtraFields_v2 var decodedExtraField types.ExtraFields_v2
// Decode the QC from forking chain // Decode the QC from forking chain
err = utils.DecodeBytesExtraFields(currentForkBlock.Header().Extra, &decodedExtraField) err = utils.DecodeBytesExtraFields(currentForkBlock.Header().Extra, &decodedExtraField)
assert.Nil(t, err) assert.Nil(t, err)
@ -173,13 +173,13 @@ func TestForensicsMonitoringNotOnSameChainDoNotHaveSameRoundQC(t *testing.T) {
// Now, let's try set committed blocks, where the highestedCommitted blocks are 913, 914 and 915 // Now, let's try set committed blocks, where the highestedCommitted blocks are 913, 914 and 915
var headers []types.Header var headers []types.Header
var decodedBlock915ExtraField utils.ExtraFields_v2 var decodedBlock915ExtraField types.ExtraFields_v2
err := utils.DecodeBytesExtraFields(blockchain.GetHeaderByNumber(915).Extra, &decodedBlock915ExtraField) err := utils.DecodeBytesExtraFields(blockchain.GetHeaderByNumber(915).Extra, &decodedBlock915ExtraField)
assert.Nil(t, err) assert.Nil(t, err)
err = forensics.SetCommittedQCs(append(headers, *blockchain.GetHeaderByNumber(913), *blockchain.GetHeaderByNumber(914)), *decodedBlock915ExtraField.QuorumCert) err = forensics.SetCommittedQCs(append(headers, *blockchain.GetHeaderByNumber(913), *blockchain.GetHeaderByNumber(914)), *decodedBlock915ExtraField.QuorumCert)
assert.Nil(t, err) assert.Nil(t, err)
var decodedExtraField utils.ExtraFields_v2 var decodedExtraField types.ExtraFields_v2
// Decode the QC from forking chain // Decode the QC from forking chain
err = utils.DecodeBytesExtraFields(currentForkBlock.Header().Extra, &decodedExtraField) err = utils.DecodeBytesExtraFields(currentForkBlock.Header().Extra, &decodedExtraField)
assert.Nil(t, err) assert.Nil(t, err)

View file

@ -583,7 +583,7 @@ func findSignerAndSignFn(bc *BlockChain, header *types.Header, signer common.Add
// If v2 block, we need to use extra data's round to find who is creating the block in order to verify the validator // If v2 block, we need to use extra data's round to find who is creating the block in order to verify the validator
if header.Number.Cmp(config.XDPoS.V2.SwitchBlock) > 0 { if header.Number.Cmp(config.XDPoS.V2.SwitchBlock) > 0 {
var decodedExtraField utils.ExtraFields_v2 var decodedExtraField types.ExtraFields_v2
err := utils.DecodeBytesExtraFields(header.Extra, &decodedExtraField) err := utils.DecodeBytesExtraFields(header.Extra, &decodedExtraField)
if err != nil { if err != nil {
panic(fmt.Errorf("fail to seal header for v2 block")) panic(fmt.Errorf("fail to seal header for v2 block"))
@ -632,49 +632,49 @@ func getMasternodesList(signer common.Address) []common.Address {
} }
func generateV2Extra(roundNumber int64, currentBlock *types.Block, signer common.Address, signFn func(account accounts.Account, hash []byte) ([]byte, error), accKeys []*ecdsa.PrivateKey) []byte { func generateV2Extra(roundNumber int64, currentBlock *types.Block, signer common.Address, signFn func(account accounts.Account, hash []byte) ([]byte, error), accKeys []*ecdsa.PrivateKey) []byte {
var extraField utils.ExtraFields_v2 var extraField types.ExtraFields_v2
var round utils.Round var round types.Round
err := utils.DecodeBytesExtraFields(currentBlock.Extra(), &extraField) err := utils.DecodeBytesExtraFields(currentBlock.Extra(), &extraField)
if err != nil { if err != nil {
round = utils.Round(0) round = types.Round(0)
} else { } else {
round = extraField.Round round = extraField.Round
} }
proposedBlockInfo := &utils.BlockInfo{ proposedBlockInfo := &types.BlockInfo{
Hash: currentBlock.Hash(), Hash: currentBlock.Hash(),
Round: round, Round: round,
Number: currentBlock.Number(), Number: currentBlock.Number(),
} }
gapNumber := currentBlock.Number().Uint64() - currentBlock.Number().Uint64()%params.TestXDPoSMockChainConfig.XDPoS.Epoch - params.TestXDPoSMockChainConfig.XDPoS.Gap gapNumber := currentBlock.Number().Uint64() - currentBlock.Number().Uint64()%params.TestXDPoSMockChainConfig.XDPoS.Epoch - params.TestXDPoSMockChainConfig.XDPoS.Gap
voteForSign := &utils.VoteForSign{ voteForSign := &types.VoteForSign{
ProposedBlockInfo: proposedBlockInfo, ProposedBlockInfo: proposedBlockInfo,
GapNumber: gapNumber, GapNumber: gapNumber,
} }
signedHash, err := signFn(accounts.Account{Address: signer}, utils.VoteSigHash(voteForSign).Bytes()) signedHash, err := signFn(accounts.Account{Address: signer}, types.VoteSigHash(voteForSign).Bytes())
if err != nil { if err != nil {
panic(fmt.Errorf("Error generate QC by creating signedHash: %v", err)) panic(fmt.Errorf("Error generate QC by creating signedHash: %v", err))
} }
var signatures []utils.Signature var signatures []types.Signature
if len(accKeys) == 0 { if len(accKeys) == 0 {
// Sign from acc 1, 2, 3 by default // Sign from acc 1, 2, 3 by default
accKeys = append(accKeys, acc1Key, acc2Key, acc3Key) accKeys = append(accKeys, acc1Key, acc2Key, acc3Key)
} }
for _, acc := range accKeys { for _, acc := range accKeys {
h := SignHashByPK(acc, utils.VoteSigHash(voteForSign).Bytes()) h := SignHashByPK(acc, types.VoteSigHash(voteForSign).Bytes())
signatures = append(signatures, h) signatures = append(signatures, h)
} }
signatures = append(signatures, signedHash) signatures = append(signatures, signedHash)
quorumCert := &utils.QuorumCert{ quorumCert := &types.QuorumCert{
ProposedBlockInfo: proposedBlockInfo, ProposedBlockInfo: proposedBlockInfo,
Signatures: signatures, Signatures: signatures,
GapNumber: gapNumber, GapNumber: gapNumber,
} }
extra := utils.ExtraFields_v2{ extra := types.ExtraFields_v2{
Round: utils.Round(roundNumber), Round: types.Round(roundNumber),
QuorumCert: quorumCert, QuorumCert: quorumCert,
} }
extraInBytes, err := extra.EncodeToBytes() extraInBytes, err := extra.EncodeToBytes()

View file

@ -6,7 +6,6 @@ import (
"github.com/XinFinOrg/XDPoSChain/common" "github.com/XinFinOrg/XDPoSChain/common"
"github.com/XinFinOrg/XDPoSChain/consensus/XDPoS" "github.com/XinFinOrg/XDPoSChain/consensus/XDPoS"
"github.com/XinFinOrg/XDPoSChain/consensus/XDPoS/utils"
"github.com/XinFinOrg/XDPoSChain/core/types" "github.com/XinFinOrg/XDPoSChain/core/types"
"github.com/XinFinOrg/XDPoSChain/params" "github.com/XinFinOrg/XDPoSChain/params"
"github.com/stretchr/testify/assert" "github.com/stretchr/testify/assert"
@ -25,17 +24,17 @@ func TestInitialFirstV2Blcok(t *testing.T) {
assert.Nil(t, err) assert.Nil(t, err)
round, _, highQC, _, _, _ := adaptor.EngineV2.GetPropertiesFaker() round, _, highQC, _, _, _ := adaptor.EngineV2.GetPropertiesFaker()
blockInfo := &utils.BlockInfo{ blockInfo := &types.BlockInfo{
Hash: header.Hash(), Hash: header.Hash(),
Round: utils.Round(0), Round: types.Round(0),
Number: header.Number, Number: header.Number,
} }
expectedQuorumCert := &utils.QuorumCert{ expectedQuorumCert := &types.QuorumCert{
ProposedBlockInfo: blockInfo, ProposedBlockInfo: blockInfo,
Signatures: nil, Signatures: nil,
GapNumber: blockchain.Config().XDPoS.V2.SwitchBlock.Uint64() - blockchain.Config().XDPoS.Gap, GapNumber: blockchain.Config().XDPoS.V2.SwitchBlock.Uint64() - blockchain.Config().XDPoS.Gap,
} }
assert.Equal(t, utils.Round(1), round) assert.Equal(t, types.Round(1), round)
assert.Equal(t, expectedQuorumCert, highQC) assert.Equal(t, expectedQuorumCert, highQC)
// Test snapshot // Test snapshot
@ -50,7 +49,7 @@ func TestInitialFirstV2Blcok(t *testing.T) {
t.Logf("Waiting %d secs for timeout to happen", params.TestXDPoSMockChainConfig.XDPoS.V2.TimeoutPeriod) t.Logf("Waiting %d secs for timeout to happen", params.TestXDPoSMockChainConfig.XDPoS.V2.TimeoutPeriod)
timeoutMsg := <-adaptor.EngineV2.BroadcastCh timeoutMsg := <-adaptor.EngineV2.BroadcastCh
assert.NotNil(t, timeoutMsg) assert.NotNil(t, timeoutMsg)
assert.Equal(t, utils.Round(1), timeoutMsg.(*utils.Timeout).Round) assert.Equal(t, types.Round(1), timeoutMsg.(*types.Timeout).Round)
} }
func TestInitialOtherV2Block(t *testing.T) { func TestInitialOtherV2Block(t *testing.T) {
@ -66,17 +65,17 @@ func TestInitialOtherV2Block(t *testing.T) {
} }
// v2 // v2
blockInfo := &utils.BlockInfo{ blockInfo := &types.BlockInfo{
Hash: currentBlock.Header().Hash(), Hash: currentBlock.Header().Hash(),
Round: utils.Round(10), Round: types.Round(10),
Number: big.NewInt(910), Number: big.NewInt(910),
} }
quorumCert := &utils.QuorumCert{ quorumCert := &types.QuorumCert{
ProposedBlockInfo: blockInfo, ProposedBlockInfo: blockInfo,
Signatures: nil, // after decode it got default value []utils.Signature{} Signatures: nil, // after decode it got default value []utils.Signature{}
GapNumber: 450, GapNumber: 450,
} }
extra := utils.ExtraFields_v2{ extra := types.ExtraFields_v2{
Round: 11, Round: 11,
QuorumCert: quorumCert, QuorumCert: quorumCert,
} }
@ -102,12 +101,12 @@ func TestInitialOtherV2Block(t *testing.T) {
assert.Nil(t, err) assert.Nil(t, err)
round, _, highQC, _, _, _ := adaptor.EngineV2.GetPropertiesFaker() round, _, highQC, _, _, _ := adaptor.EngineV2.GetPropertiesFaker()
expectedQuorumCert := &utils.QuorumCert{ expectedQuorumCert := &types.QuorumCert{
ProposedBlockInfo: blockInfo, ProposedBlockInfo: blockInfo,
Signatures: []utils.Signature{}, Signatures: []types.Signature{},
GapNumber: blockchain.Config().XDPoS.V2.SwitchBlock.Uint64() - blockchain.Config().XDPoS.Gap, GapNumber: blockchain.Config().XDPoS.V2.SwitchBlock.Uint64() - blockchain.Config().XDPoS.Gap,
} }
assert.Equal(t, utils.Round(11), round) assert.Equal(t, types.Round(11), round)
assert.Equal(t, expectedQuorumCert, highQC) assert.Equal(t, expectedQuorumCert, highQC)
// Test snapshot // Test snapshot

View file

@ -49,7 +49,7 @@ func TestYourTurnInitialV2(t *testing.T) {
assert.Nil(t, err) assert.Nil(t, err)
// round=1, so masternode[1] has YourTurn = True // round=1, so masternode[1] has YourTurn = True
assert.True(t, b) assert.True(t, b)
assert.Equal(t, adaptor.EngineV2.GetCurrentRoundFaker(), utils.Round(1)) assert.Equal(t, adaptor.EngineV2.GetCurrentRoundFaker(), types.Round(1))
snap, err := adaptor.EngineV2.GetSnapshot(blockchain, block900.Header()) snap, err := adaptor.EngineV2.GetSnapshot(blockchain, block900.Header())
assert.Nil(t, err) assert.Nil(t, err)
@ -171,7 +171,7 @@ func TestPrepareFail(t *testing.T) {
err = adaptor.Prepare(blockchain, notReadyToMine) err = adaptor.Prepare(blockchain, notReadyToMine)
assert.Equal(t, consensus.ErrNotReadyToMine, err) assert.Equal(t, consensus.ErrNotReadyToMine, err)
adaptor.EngineV2.SetNewRoundFaker(blockchain, utils.Round(4), false) adaptor.EngineV2.SetNewRoundFaker(blockchain, types.Round(4), false)
header901WithoutCoinbase := &types.Header{ header901WithoutCoinbase := &types.Header{
ParentHash: currentBlock.Hash(), ParentHash: currentBlock.Hash(),
Number: big.NewInt(int64(901)), Number: big.NewInt(int64(901)),
@ -201,7 +201,7 @@ func TestPrepareHappyPath(t *testing.T) {
Coinbase: signer, Coinbase: signer,
} }
adaptor.EngineV2.SetNewRoundFaker(blockchain, utils.Round(4), false) adaptor.EngineV2.SetNewRoundFaker(blockchain, types.Round(4), false)
err = adaptor.Prepare(blockchain, header901) err = adaptor.Prepare(blockchain, header901)
assert.Nil(t, err) assert.Nil(t, err)
@ -216,9 +216,9 @@ func TestPrepareHappyPath(t *testing.T) {
} }
assert.Equal(t, validators, header901.Validators) assert.Equal(t, validators, header901.Validators)
var decodedExtraField utils.ExtraFields_v2 var decodedExtraField types.ExtraFields_v2
err = utils.DecodeBytesExtraFields(header901.Extra, &decodedExtraField) err = utils.DecodeBytesExtraFields(header901.Extra, &decodedExtraField)
assert.Nil(t, err) assert.Nil(t, err)
assert.Equal(t, utils.Round(4), decodedExtraField.Round) assert.Equal(t, types.Round(4), decodedExtraField.Round)
assert.Equal(t, utils.Round(0), decodedExtraField.QuorumCert.ProposedBlockInfo.Round) assert.Equal(t, types.Round(0), decodedExtraField.QuorumCert.ProposedBlockInfo.Round)
} }

View file

@ -19,7 +19,7 @@ func TestHookPenaltyV2Mining(t *testing.T) {
adaptor := blockchain.Engine().(*XDPoS.XDPoS) adaptor := blockchain.Engine().(*XDPoS.XDPoS)
hooks.AttachConsensusV2Hooks(adaptor, blockchain, config) hooks.AttachConsensusV2Hooks(adaptor, blockchain, config)
assert.NotNil(t, adaptor.EngineV2.HookPenalty) assert.NotNil(t, adaptor.EngineV2.HookPenalty)
var extraField utils.ExtraFields_v2 var extraField types.ExtraFields_v2
// 901 is the first v2 block // 901 is the first v2 block
header901 := blockchain.GetHeaderByNumber(config.XDPoS.Epoch + 1) header901 := blockchain.GetHeaderByNumber(config.XDPoS.Epoch + 1)
err := utils.DecodeBytesExtraFields(header901.Extra, &extraField) err := utils.DecodeBytesExtraFields(header901.Extra, &extraField)
@ -54,7 +54,7 @@ func TestHookPenaltyV2Mining(t *testing.T) {
} }
// Force to make the node to be at its round to mine, otherwise won't pass the yourturn masternodes check // Force to make the node to be at its round to mine, otherwise won't pass the yourturn masternodes check
// We have 19 nodes in total (20 candidates in snapshot - 1 penalty) and the fake signer is always at the 18th(last) in the list. Hence int(config.XDPoS.Epoch)*3+18-900, the +18 means is to force to next 18 round and -900 is the relative round number to block number int(config.XDPoS.Epoch)*3 // We have 19 nodes in total (20 candidates in snapshot - 1 penalty) and the fake signer is always at the 18th(last) in the list. Hence int(config.XDPoS.Epoch)*3+18-900, the +18 means is to force to next 18 round and -900 is the relative round number to block number int(config.XDPoS.Epoch)*3
adaptor.EngineV2.SetNewRoundFaker(blockchain, utils.Round(int(config.XDPoS.Epoch)*3+18-900), false) adaptor.EngineV2.SetNewRoundFaker(blockchain, types.Round(int(config.XDPoS.Epoch)*3+18-900), false)
// The test default signer is not in the msaternodes, so we set the faker signer // The test default signer is not in the msaternodes, so we set the faker signer
adaptor.EngineV2.AuthorizeFaker(acc1Addr) adaptor.EngineV2.AuthorizeFaker(acc1Addr)
err = adaptor.Prepare(blockchain, headerMining) err = adaptor.Prepare(blockchain, headerMining)
@ -70,7 +70,7 @@ func TestHookPenaltyV2Comeback(t *testing.T) {
adaptor := blockchain.Engine().(*XDPoS.XDPoS) adaptor := blockchain.Engine().(*XDPoS.XDPoS)
hooks.AttachConsensusV2Hooks(adaptor, blockchain, config) hooks.AttachConsensusV2Hooks(adaptor, blockchain, config)
assert.NotNil(t, adaptor.EngineV2.HookPenalty) assert.NotNil(t, adaptor.EngineV2.HookPenalty)
var extraField utils.ExtraFields_v2 var extraField types.ExtraFields_v2
// 901 is the first v2 block // 901 is the first v2 block
header901 := blockchain.GetHeaderByNumber(config.XDPoS.Epoch + 1) header901 := blockchain.GetHeaderByNumber(config.XDPoS.Epoch + 1)
err := utils.DecodeBytesExtraFields(header901.Extra, &extraField) err := utils.DecodeBytesExtraFields(header901.Extra, &extraField)
@ -99,7 +99,7 @@ func TestHookPenaltyV2Jump(t *testing.T) {
adaptor := blockchain.Engine().(*XDPoS.XDPoS) adaptor := blockchain.Engine().(*XDPoS.XDPoS)
hooks.AttachConsensusV2Hooks(adaptor, blockchain, config) hooks.AttachConsensusV2Hooks(adaptor, blockchain, config)
assert.NotNil(t, adaptor.EngineV2.HookPenalty) assert.NotNil(t, adaptor.EngineV2.HookPenalty)
var extraField utils.ExtraFields_v2 var extraField types.ExtraFields_v2
// 901 is the first v2 block // 901 is the first v2 block
header901 := blockchain.GetHeaderByNumber(config.XDPoS.Epoch + 1) header901 := blockchain.GetHeaderByNumber(config.XDPoS.Epoch + 1)
err := utils.DecodeBytesExtraFields(header901.Extra, &extraField) err := utils.DecodeBytesExtraFields(header901.Extra, &extraField)
@ -107,7 +107,7 @@ func TestHookPenaltyV2Jump(t *testing.T) {
masternodes := adaptor.GetMasternodesFromCheckpointHeader(header901) masternodes := adaptor.GetMasternodesFromCheckpointHeader(header901)
assert.Equal(t, 5, len(masternodes)) assert.Equal(t, 5, len(masternodes))
header2085 := blockchain.GetHeaderByNumber(uint64(end)) header2085 := blockchain.GetHeaderByNumber(uint64(end))
adaptor.EngineV2.SetNewRoundFaker(blockchain, utils.Round(config.XDPoS.Epoch*3), false) adaptor.EngineV2.SetNewRoundFaker(blockchain, types.Round(config.XDPoS.Epoch*3), false)
// round 2085-2100 miss blocks, penalty should work as usual // round 2085-2100 miss blocks, penalty should work as usual
penalty, err := adaptor.EngineV2.HookPenalty(blockchain, header2085.Number, header2085.ParentHash, masternodes) penalty, err := adaptor.EngineV2.HookPenalty(blockchain, header2085.Number, header2085.ParentHash, masternodes)
assert.Nil(t, err) assert.Nil(t, err)

View file

@ -8,6 +8,7 @@ import (
"github.com/XinFinOrg/XDPoSChain/accounts/abi/bind/backends" "github.com/XinFinOrg/XDPoSChain/accounts/abi/bind/backends"
"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"
"github.com/XinFinOrg/XDPoSChain/core/types"
"github.com/XinFinOrg/XDPoSChain/params" "github.com/XinFinOrg/XDPoSChain/params"
"github.com/stretchr/testify/assert" "github.com/stretchr/testify/assert"
) )
@ -17,7 +18,7 @@ func TestShouldSendVoteMsgAndCommitGrandGrandParentBlock(t *testing.T) {
blockchain, _, currentBlock, signer, signFn, _ := PrepareXDCTestBlockChainForV2Engine(t, 901, params.TestXDPoSMockChainConfig, nil) blockchain, _, currentBlock, signer, signFn, _ := PrepareXDCTestBlockChainForV2Engine(t, 901, params.TestXDPoSMockChainConfig, nil)
engineV2 := blockchain.Engine().(*XDPoS.XDPoS).EngineV2 engineV2 := blockchain.Engine().(*XDPoS.XDPoS).EngineV2
var extraField utils.ExtraFields_v2 var extraField types.ExtraFields_v2
err := utils.DecodeBytesExtraFields(currentBlock.Extra(), &extraField) err := utils.DecodeBytesExtraFields(currentBlock.Extra(), &extraField)
if err != nil { if err != nil {
t.Fatal("Fail to decode extra data", err) t.Fatal("Fail to decode extra data", err)
@ -29,17 +30,17 @@ func TestShouldSendVoteMsgAndCommitGrandGrandParentBlock(t *testing.T) {
} }
voteMsg := <-engineV2.BroadcastCh voteMsg := <-engineV2.BroadcastCh
poolSize := engineV2.GetVotePoolSizeFaker(voteMsg.(*utils.Vote)) poolSize := engineV2.GetVotePoolSizeFaker(voteMsg.(*types.Vote))
assert.Equal(t, poolSize, 1) assert.Equal(t, poolSize, 1)
assert.NotNil(t, voteMsg) assert.NotNil(t, voteMsg)
assert.Equal(t, currentBlock.Hash(), voteMsg.(*utils.Vote).ProposedBlockInfo.Hash) assert.Equal(t, currentBlock.Hash(), voteMsg.(*types.Vote).ProposedBlockInfo.Hash)
round, _, highestQC, _, _, _ := engineV2.GetPropertiesFaker() round, _, highestQC, _, _, _ := engineV2.GetPropertiesFaker()
// Shoud trigger setNewRound // Shoud trigger setNewRound
assert.Equal(t, utils.Round(1), round) assert.Equal(t, types.Round(1), round)
// Should not update the highestQC // Should not update the highestQC
assert.Equal(t, utils.Round(0), highestQC.ProposedBlockInfo.Round) assert.Equal(t, types.Round(0), highestQC.ProposedBlockInfo.Round)
// Insert another Block, but it won't trigger commit // Insert another Block, but it won't trigger commit
blockNum := 902 blockNum := 902
@ -56,8 +57,8 @@ func TestShouldSendVoteMsgAndCommitGrandGrandParentBlock(t *testing.T) {
assert.NotNil(t, voteMsg) assert.NotNil(t, voteMsg)
round, _, highestQC, _, _, _ = engineV2.GetPropertiesFaker() round, _, highestQC, _, _, _ = engineV2.GetPropertiesFaker()
// Shoud trigger setNewRound // Shoud trigger setNewRound
assert.Equal(t, utils.Round(2), round) assert.Equal(t, types.Round(2), round)
assert.Equal(t, utils.Round(1), highestQC.ProposedBlockInfo.Round) assert.Equal(t, types.Round(1), highestQC.ProposedBlockInfo.Round)
// Insert one more Block, but still won't trigger commit // Insert one more Block, but still won't trigger commit
blockNum = 903 blockNum = 903
@ -74,8 +75,8 @@ func TestShouldSendVoteMsgAndCommitGrandGrandParentBlock(t *testing.T) {
assert.NotNil(t, voteMsg) assert.NotNil(t, voteMsg)
round, _, highestQC, _, _, highestCommitBlock := engineV2.GetPropertiesFaker() round, _, highestQC, _, _, highestCommitBlock := engineV2.GetPropertiesFaker()
// Shoud NOT trigger setNewRound as the new block parent QC is round 1 but the currentRound is already 2 // Shoud NOT trigger setNewRound as the new block parent QC is round 1 but the currentRound is already 2
assert.Equal(t, utils.Round(3), round) assert.Equal(t, types.Round(3), round)
assert.Equal(t, utils.Round(2), highestQC.ProposedBlockInfo.Round) assert.Equal(t, types.Round(2), highestQC.ProposedBlockInfo.Round)
assert.Nil(t, highestCommitBlock) assert.Nil(t, highestCommitBlock)
// Insert one more Block, this time will trigger commit // Insert one more Block, this time will trigger commit
@ -93,11 +94,11 @@ func TestShouldSendVoteMsgAndCommitGrandGrandParentBlock(t *testing.T) {
assert.NotNil(t, voteMsg) assert.NotNil(t, voteMsg)
round, _, highestQC, _, _, highestCommitBlock = engineV2.GetPropertiesFaker() round, _, highestQC, _, _, highestCommitBlock = engineV2.GetPropertiesFaker()
assert.Equal(t, utils.Round(4), round) assert.Equal(t, types.Round(4), round)
assert.Equal(t, utils.Round(3), highestQC.ProposedBlockInfo.Round) assert.Equal(t, types.Round(3), highestQC.ProposedBlockInfo.Round)
assert.Equal(t, currentBlock.Hash(), highestCommitBlock.Hash) assert.Equal(t, currentBlock.Hash(), highestCommitBlock.Hash)
assert.Equal(t, currentBlock.Number(), highestCommitBlock.Number) assert.Equal(t, currentBlock.Number(), highestCommitBlock.Number)
assert.Equal(t, utils.Round(1), highestCommitBlock.Round) assert.Equal(t, types.Round(1), highestCommitBlock.Round)
} }
func TestShouldNotCommitIfRoundsNotContinousFor3Rounds(t *testing.T) { func TestShouldNotCommitIfRoundsNotContinousFor3Rounds(t *testing.T) {
@ -105,7 +106,7 @@ func TestShouldNotCommitIfRoundsNotContinousFor3Rounds(t *testing.T) {
blockchain, _, currentBlock, signer, signFn, _ := PrepareXDCTestBlockChainForV2Engine(t, 905, params.TestXDPoSMockChainConfig, nil) blockchain, _, currentBlock, signer, signFn, _ := PrepareXDCTestBlockChainForV2Engine(t, 905, params.TestXDPoSMockChainConfig, nil)
engineV2 := blockchain.Engine().(*XDPoS.XDPoS).EngineV2 engineV2 := blockchain.Engine().(*XDPoS.XDPoS).EngineV2
var extraField utils.ExtraFields_v2 var extraField types.ExtraFields_v2
err := utils.DecodeBytesExtraFields(currentBlock.Extra(), &extraField) err := utils.DecodeBytesExtraFields(currentBlock.Extra(), &extraField)
if err != nil { if err != nil {
t.Fatal("Fail to decode extra data", err) t.Fatal("Fail to decode extra data", err)
@ -118,17 +119,17 @@ func TestShouldNotCommitIfRoundsNotContinousFor3Rounds(t *testing.T) {
voteMsg := <-engineV2.BroadcastCh voteMsg := <-engineV2.BroadcastCh
assert.NotNil(t, voteMsg) assert.NotNil(t, voteMsg)
assert.Equal(t, currentBlock.Hash(), voteMsg.(*utils.Vote).ProposedBlockInfo.Hash) assert.Equal(t, currentBlock.Hash(), voteMsg.(*types.Vote).ProposedBlockInfo.Hash)
round, _, highestQC, _, _, highestCommitBlock := engineV2.GetPropertiesFaker() round, _, highestQC, _, _, highestCommitBlock := engineV2.GetPropertiesFaker()
grandGrandParentBlock := blockchain.GetBlockByNumber(902) grandGrandParentBlock := blockchain.GetBlockByNumber(902)
// Shoud trigger setNewRound // Shoud trigger setNewRound
assert.Equal(t, utils.Round(5), round) assert.Equal(t, types.Round(5), round)
assert.Equal(t, utils.Round(4), highestQC.ProposedBlockInfo.Round) assert.Equal(t, types.Round(4), highestQC.ProposedBlockInfo.Round)
assert.Equal(t, grandGrandParentBlock.Hash(), highestCommitBlock.Hash) assert.Equal(t, grandGrandParentBlock.Hash(), highestCommitBlock.Hash)
assert.Equal(t, grandGrandParentBlock.Number(), highestCommitBlock.Number) assert.Equal(t, grandGrandParentBlock.Number(), highestCommitBlock.Number)
assert.Equal(t, utils.Round(2), highestCommitBlock.Round) assert.Equal(t, types.Round(2), highestCommitBlock.Round)
// Injecting new block which have gaps in the round number (Round 7 instead of 6) // Injecting new block which have gaps in the round number (Round 7 instead of 6)
blockNum := 906 blockNum := 906
@ -146,12 +147,12 @@ func TestShouldNotCommitIfRoundsNotContinousFor3Rounds(t *testing.T) {
round, _, highestQC, _, _, highestCommitBlock = engineV2.GetPropertiesFaker() round, _, highestQC, _, _, highestCommitBlock = engineV2.GetPropertiesFaker()
grandGrandParentBlock = blockchain.GetBlockByNumber(903) grandGrandParentBlock = blockchain.GetBlockByNumber(903)
assert.Equal(t, utils.Round(6), round) assert.Equal(t, types.Round(6), round)
assert.Equal(t, utils.Round(5), highestQC.ProposedBlockInfo.Round) assert.Equal(t, types.Round(5), highestQC.ProposedBlockInfo.Round)
// It commit its grandgrandparent block // It commit its grandgrandparent block
assert.Equal(t, grandGrandParentBlock.Hash(), highestCommitBlock.Hash) assert.Equal(t, grandGrandParentBlock.Hash(), highestCommitBlock.Hash)
assert.Equal(t, grandGrandParentBlock.Number(), highestCommitBlock.Number) assert.Equal(t, grandGrandParentBlock.Number(), highestCommitBlock.Number)
assert.Equal(t, utils.Round(3), highestCommitBlock.Round) assert.Equal(t, types.Round(3), highestCommitBlock.Round)
blockNum = 907 blockNum = 907
blockCoinBase = fmt.Sprintf("0x111000000000000000000000000000000%03d", blockNum) blockCoinBase = fmt.Sprintf("0x111000000000000000000000000000000%03d", blockNum)
@ -167,12 +168,12 @@ func TestShouldNotCommitIfRoundsNotContinousFor3Rounds(t *testing.T) {
assert.NotNil(t, voteMsg) assert.NotNil(t, voteMsg)
round, _, highestQC, _, _, highestCommitBlock = engineV2.GetPropertiesFaker() round, _, highestQC, _, _, highestCommitBlock = engineV2.GetPropertiesFaker()
assert.Equal(t, utils.Round(8), round) assert.Equal(t, types.Round(8), round)
assert.Equal(t, utils.Round(7), highestQC.ProposedBlockInfo.Round) assert.Equal(t, types.Round(7), highestQC.ProposedBlockInfo.Round)
// Should NOT commit, the `grandGrandParentBlock` is still on blockNum 903 // Should NOT commit, the `grandGrandParentBlock` is still on blockNum 903
assert.Equal(t, grandGrandParentBlock.Hash(), highestCommitBlock.Hash) assert.Equal(t, grandGrandParentBlock.Hash(), highestCommitBlock.Hash)
assert.Equal(t, grandGrandParentBlock.Number(), highestCommitBlock.Number) assert.Equal(t, grandGrandParentBlock.Number(), highestCommitBlock.Number)
assert.Equal(t, utils.Round(3), highestCommitBlock.Round) assert.Equal(t, types.Round(3), highestCommitBlock.Round)
} }
@ -181,9 +182,9 @@ func TestProposedBlockMessageHandlerSuccessfullyGenerateVote(t *testing.T) {
engineV2 := blockchain.Engine().(*XDPoS.XDPoS).EngineV2 engineV2 := blockchain.Engine().(*XDPoS.XDPoS).EngineV2
// Set current round to 5 // Set current round to 5
engineV2.SetNewRoundFaker(blockchain, utils.Round(5), false) engineV2.SetNewRoundFaker(blockchain, types.Round(5), false)
var extraField utils.ExtraFields_v2 var extraField types.ExtraFields_v2
err := utils.DecodeBytesExtraFields(currentBlock.Extra(), &extraField) err := utils.DecodeBytesExtraFields(currentBlock.Extra(), &extraField)
if err != nil { if err != nil {
t.Fatal("Fail to decode extra data", err) t.Fatal("Fail to decode extra data", err)
@ -196,11 +197,11 @@ func TestProposedBlockMessageHandlerSuccessfullyGenerateVote(t *testing.T) {
voteMsg := <-engineV2.BroadcastCh voteMsg := <-engineV2.BroadcastCh
assert.NotNil(t, voteMsg) assert.NotNil(t, voteMsg)
assert.Equal(t, currentBlock.Hash(), voteMsg.(*utils.Vote).ProposedBlockInfo.Hash) assert.Equal(t, currentBlock.Hash(), voteMsg.(*types.Vote).ProposedBlockInfo.Hash)
round, _, highestQC, _, _, _ := engineV2.GetPropertiesFaker() round, _, highestQC, _, _, _ := engineV2.GetPropertiesFaker()
// Shoud trigger setNewRound // Shoud trigger setNewRound
assert.Equal(t, utils.Round(6), round) assert.Equal(t, types.Round(6), round)
assert.Equal(t, extraField.QuorumCert.Signatures, highestQC.Signatures) assert.Equal(t, extraField.QuorumCert.Signatures, highestQC.Signatures)
} }
@ -211,9 +212,9 @@ func TestShouldNotSetNewRound(t *testing.T) {
engineV2 := blockchain.Engine().(*XDPoS.XDPoS).EngineV2 engineV2 := blockchain.Engine().(*XDPoS.XDPoS).EngineV2
// Set current round to 6 // Set current round to 6
engineV2.SetNewRoundFaker(blockchain, utils.Round(6), false) engineV2.SetNewRoundFaker(blockchain, types.Round(6), false)
var extraField utils.ExtraFields_v2 var extraField types.ExtraFields_v2
err := utils.DecodeBytesExtraFields(currentBlock.Extra(), &extraField) err := utils.DecodeBytesExtraFields(currentBlock.Extra(), &extraField)
if err != nil { if err != nil {
t.Fatal("Fail to decode extra data", err) t.Fatal("Fail to decode extra data", err)
@ -226,7 +227,7 @@ func TestShouldNotSetNewRound(t *testing.T) {
round, _, highestQC, _, _, _ := engineV2.GetPropertiesFaker() round, _, highestQC, _, _, _ := engineV2.GetPropertiesFaker()
// Shoud not trigger setNewRound // Shoud not trigger setNewRound
assert.Equal(t, utils.Round(6), round) assert.Equal(t, types.Round(6), round)
assert.Equal(t, extraField.QuorumCert.Signatures, highestQC.Signatures) assert.Equal(t, extraField.QuorumCert.Signatures, highestQC.Signatures)
} }
@ -235,7 +236,7 @@ func TestShouldNotSendVoteMessageIfAlreadyVoteForThisRound(t *testing.T) {
engineV2 := blockchain.Engine().(*XDPoS.XDPoS).EngineV2 engineV2 := blockchain.Engine().(*XDPoS.XDPoS).EngineV2
// Set current round to 5 // Set current round to 5
engineV2.SetNewRoundFaker(blockchain, utils.Round(5), false) engineV2.SetNewRoundFaker(blockchain, types.Round(5), false)
err := engineV2.ProposedBlockHandler(blockchain, currentBlock.Header()) err := engineV2.ProposedBlockHandler(blockchain, currentBlock.Header())
if err != nil { if err != nil {
@ -244,12 +245,12 @@ func TestShouldNotSendVoteMessageIfAlreadyVoteForThisRound(t *testing.T) {
voteMsg := <-engineV2.BroadcastCh voteMsg := <-engineV2.BroadcastCh
assert.NotNil(t, voteMsg) assert.NotNil(t, voteMsg)
assert.Equal(t, currentBlock.Hash(), voteMsg.(*utils.Vote).ProposedBlockInfo.Hash) assert.Equal(t, currentBlock.Hash(), voteMsg.(*types.Vote).ProposedBlockInfo.Hash)
round, _, _, _, highestVotedRound, _ := engineV2.GetPropertiesFaker() round, _, _, _, highestVotedRound, _ := engineV2.GetPropertiesFaker()
// Shoud trigger setNewRound // Shoud trigger setNewRound
assert.Equal(t, utils.Round(6), round) assert.Equal(t, types.Round(6), round)
assert.Equal(t, utils.Round(6), highestVotedRound) assert.Equal(t, types.Round(6), highestVotedRound)
// Let's send again, this time, it shall not broadcast any vote message, because HigestVoteRound is same as currentRound // Let's send again, this time, it shall not broadcast any vote message, because HigestVoteRound is same as currentRound
err = engineV2.ProposedBlockHandler(blockchain, currentBlock.Header()) err = engineV2.ProposedBlockHandler(blockchain, currentBlock.Header())
@ -263,8 +264,8 @@ func TestShouldNotSendVoteMessageIfAlreadyVoteForThisRound(t *testing.T) {
case <-time.After(5 * time.Second): case <-time.After(5 * time.Second):
// Shoud not trigger setNewRound // Shoud not trigger setNewRound
round, _, _, _, highestVotedRound, _ = engineV2.GetPropertiesFaker() round, _, _, _, highestVotedRound, _ = engineV2.GetPropertiesFaker()
assert.Equal(t, utils.Round(6), round) assert.Equal(t, types.Round(6), round)
assert.Equal(t, utils.Round(6), highestVotedRound) assert.Equal(t, types.Round(6), highestVotedRound)
} }
} }
@ -273,9 +274,9 @@ func TestShouldNotSendVoteMsgIfBlockInfoRoundNotEqualCurrentRound(t *testing.T)
engineV2 := blockchain.Engine().(*XDPoS.XDPoS).EngineV2 engineV2 := blockchain.Engine().(*XDPoS.XDPoS).EngineV2
// Set current round to 8 // Set current round to 8
engineV2.SetNewRoundFaker(blockchain, utils.Round(8), false) engineV2.SetNewRoundFaker(blockchain, types.Round(8), false)
var extraField utils.ExtraFields_v2 var extraField types.ExtraFields_v2
err := utils.DecodeBytesExtraFields(currentBlock.Extra(), &extraField) err := utils.DecodeBytesExtraFields(currentBlock.Extra(), &extraField)
if err != nil { if err != nil {
t.Fatal("Fail to decode extra data", err) t.Fatal("Fail to decode extra data", err)
@ -292,7 +293,7 @@ func TestShouldNotSendVoteMsgIfBlockInfoRoundNotEqualCurrentRound(t *testing.T)
case <-time.After(5 * time.Second): case <-time.After(5 * time.Second):
// Shoud not trigger setNewRound // Shoud not trigger setNewRound
round, _, _, _, _, _ := engineV2.GetPropertiesFaker() round, _, _, _, _, _ := engineV2.GetPropertiesFaker()
assert.Equal(t, utils.Round(8), round) assert.Equal(t, types.Round(8), round)
} }
} }
@ -308,23 +309,23 @@ func TestShouldNotSendVoteMsgIfBlockNotExtendedFromAncestor(t *testing.T) {
blockchain, _, currentBlock, _, _, forkedBlock := PrepareXDCTestBlockChainForV2Engine(t, 906, params.TestXDPoSMockChainConfig, &ForkedBlockOptions{numOfForkedBlocks: numOfForks}) blockchain, _, currentBlock, _, _, forkedBlock := PrepareXDCTestBlockChainForV2Engine(t, 906, params.TestXDPoSMockChainConfig, &ForkedBlockOptions{numOfForkedBlocks: numOfForks})
engineV2 := blockchain.Engine().(*XDPoS.XDPoS).EngineV2 engineV2 := blockchain.Engine().(*XDPoS.XDPoS).EngineV2
var extraField utils.ExtraFields_v2 var extraField types.ExtraFields_v2
err := utils.DecodeBytesExtraFields(forkedBlock.Extra(), &extraField) err := utils.DecodeBytesExtraFields(forkedBlock.Extra(), &extraField)
if err != nil { if err != nil {
t.Fatal("Fail to decode extra data", err) t.Fatal("Fail to decode extra data", err)
} }
assert.Equal(t, utils.Round(9), extraField.Round) assert.Equal(t, types.Round(9), extraField.Round)
// Set the lockQC and other pre-requist properties by block 906 // Set the lockQC and other pre-requist properties by block 906
err = engineV2.ProposedBlockHandler(blockchain, currentBlock.Header()) err = engineV2.ProposedBlockHandler(blockchain, currentBlock.Header())
if err != nil { if err != nil {
t.Fatal("Error while handling block 16", err) t.Fatal("Error while handling block 16", err)
} }
vote := <-engineV2.BroadcastCh vote := <-engineV2.BroadcastCh
assert.Equal(t, utils.Round(6), vote.(*utils.Vote).ProposedBlockInfo.Round) assert.Equal(t, types.Round(6), vote.(*types.Vote).ProposedBlockInfo.Round)
// Find the first forked block at block 14th // Find the first forked block at block 14th
firstForkedBlock := blockchain.GetBlockByHash(blockchain.GetBlockByHash(forkedBlock.ParentHash()).ParentHash()) firstForkedBlock := blockchain.GetBlockByHash(blockchain.GetBlockByHash(forkedBlock.ParentHash()).ParentHash())
engineV2.SetNewRoundFaker(blockchain, utils.Round(7), false) engineV2.SetNewRoundFaker(blockchain, types.Round(7), false)
err = engineV2.ProposedBlockHandler(blockchain, firstForkedBlock.Header()) err = engineV2.ProposedBlockHandler(blockchain, firstForkedBlock.Header())
if err != nil { if err != nil {
t.Fatal("Fail propose proposedBlock handler", err) t.Fatal("Fail propose proposedBlock handler", err)
@ -336,7 +337,7 @@ func TestShouldNotSendVoteMsgIfBlockNotExtendedFromAncestor(t *testing.T) {
case <-time.After(5 * time.Second): case <-time.After(5 * time.Second):
// Shoud not trigger setNewRound // Shoud not trigger setNewRound
round, _, _, _, _, _ := engineV2.GetPropertiesFaker() round, _, _, _, _, _ := engineV2.GetPropertiesFaker()
assert.Equal(t, utils.Round(7), round) assert.Equal(t, types.Round(7), round)
} }
} }
@ -353,9 +354,9 @@ func TestShouldSendVoteMsg(t *testing.T) {
t.Fatal(err) t.Fatal(err)
} }
round, _, _, _, _, _ := engineV2.GetPropertiesFaker() round, _, _, _, _, _ := engineV2.GetPropertiesFaker()
assert.Equal(t, utils.Round(i-900), round) assert.Equal(t, types.Round(i-900), round)
vote := <-engineV2.BroadcastCh vote := <-engineV2.BroadcastCh
assert.Equal(t, round, vote.(*utils.Vote).ProposedBlockInfo.Round) assert.Equal(t, round, vote.(*types.Vote).ProposedBlockInfo.Round)
} }
} }
@ -368,9 +369,9 @@ func TestProposedBlockMessageHandlerNotGenerateVoteIfSignerNotInMNlist(t *testin
engineV2.Authorize(differentSigner, differentSignFn) engineV2.Authorize(differentSigner, differentSignFn)
// Set current round to 5 // Set current round to 5
engineV2.SetNewRoundFaker(blockchain, utils.Round(5), false) engineV2.SetNewRoundFaker(blockchain, types.Round(5), false)
var extraField utils.ExtraFields_v2 var extraField types.ExtraFields_v2
err = utils.DecodeBytesExtraFields(currentBlock.Extra(), &extraField) err = utils.DecodeBytesExtraFields(currentBlock.Extra(), &extraField)
if err != nil { if err != nil {
t.Fatal("Fail to decode extra data", err) t.Fatal("Fail to decode extra data", err)

View file

@ -6,6 +6,7 @@ import (
"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"
"github.com/XinFinOrg/XDPoSChain/core/types"
"github.com/XinFinOrg/XDPoSChain/params" "github.com/XinFinOrg/XDPoSChain/params"
"github.com/stretchr/testify/assert" "github.com/stretchr/testify/assert"
) )
@ -15,17 +16,17 @@ func TestSyncInfoShouldSuccessfullyUpdateByQC(t *testing.T) {
blockchain, _, currentBlock, _, _, _ := PrepareXDCTestBlockChainForV2Engine(t, 905, params.TestXDPoSMockChainConfig, nil) blockchain, _, currentBlock, _, _, _ := PrepareXDCTestBlockChainForV2Engine(t, 905, params.TestXDPoSMockChainConfig, nil)
engineV2 := blockchain.Engine().(*XDPoS.XDPoS).EngineV2 engineV2 := blockchain.Engine().(*XDPoS.XDPoS).EngineV2
var extraField utils.ExtraFields_v2 var extraField types.ExtraFields_v2
err := utils.DecodeBytesExtraFields(currentBlock.Extra(), &extraField) err := utils.DecodeBytesExtraFields(currentBlock.Extra(), &extraField)
if err != nil { if err != nil {
t.Fatal("Fail to decode extra data", err) t.Fatal("Fail to decode extra data", err)
} }
syncInfoMsg := &utils.SyncInfo{ syncInfoMsg := &types.SyncInfo{
HighestQuorumCert: extraField.QuorumCert, HighestQuorumCert: extraField.QuorumCert,
HighestTimeoutCert: &utils.TimeoutCert{ HighestTimeoutCert: &types.TimeoutCert{
Round: utils.Round(2), Round: types.Round(2),
Signatures: []utils.Signature{}, Signatures: []types.Signature{},
}, },
} }
@ -35,9 +36,9 @@ func TestSyncInfoShouldSuccessfullyUpdateByQC(t *testing.T) {
} }
round, _, highestQuorumCert, _, _, highestCommitBlock := engineV2.GetPropertiesFaker() round, _, highestQuorumCert, _, _, highestCommitBlock := engineV2.GetPropertiesFaker()
// QC is parent block's qc, which is pointing at round 4, hence 4 + 1 = 5 // QC is parent block's qc, which is pointing at round 4, hence 4 + 1 = 5
assert.Equal(t, utils.Round(5), round) assert.Equal(t, types.Round(5), round)
assert.Equal(t, extraField.QuorumCert, highestQuorumCert) assert.Equal(t, extraField.QuorumCert, highestQuorumCert)
assert.Equal(t, utils.Round(2), highestCommitBlock.Round) assert.Equal(t, types.Round(2), highestCommitBlock.Round)
assert.Equal(t, big.NewInt(902), highestCommitBlock.Number) assert.Equal(t, big.NewInt(902), highestCommitBlock.Number)
} }
@ -46,18 +47,18 @@ func TestSyncInfoShouldSuccessfullyUpdateByTC(t *testing.T) {
blockchain, _, currentBlock, _, _, _ := PrepareXDCTestBlockChainForV2Engine(t, 905, params.TestXDPoSMockChainConfig, nil) blockchain, _, currentBlock, _, _, _ := PrepareXDCTestBlockChainForV2Engine(t, 905, params.TestXDPoSMockChainConfig, nil)
engineV2 := blockchain.Engine().(*XDPoS.XDPoS).EngineV2 engineV2 := blockchain.Engine().(*XDPoS.XDPoS).EngineV2
var extraField utils.ExtraFields_v2 var extraField types.ExtraFields_v2
err := utils.DecodeBytesExtraFields(currentBlock.Extra(), &extraField) err := utils.DecodeBytesExtraFields(currentBlock.Extra(), &extraField)
if err != nil { if err != nil {
t.Fatal("Fail to decode extra data", err) t.Fatal("Fail to decode extra data", err)
} }
highestTC := &utils.TimeoutCert{ highestTC := &types.TimeoutCert{
Round: utils.Round(6), Round: types.Round(6),
Signatures: []utils.Signature{}, Signatures: []types.Signature{},
} }
syncInfoMsg := &utils.SyncInfo{ syncInfoMsg := &types.SyncInfo{
HighestQuorumCert: extraField.QuorumCert, HighestQuorumCert: extraField.QuorumCert,
HighestTimeoutCert: highestTC, HighestTimeoutCert: highestTC,
} }
@ -67,7 +68,7 @@ func TestSyncInfoShouldSuccessfullyUpdateByTC(t *testing.T) {
t.Fatal(err) t.Fatal(err)
} }
round, _, highestQuorumCert, _, _, _ := engineV2.GetPropertiesFaker() round, _, highestQuorumCert, _, _, _ := engineV2.GetPropertiesFaker()
assert.Equal(t, utils.Round(7), round) assert.Equal(t, types.Round(7), round)
assert.Equal(t, extraField.QuorumCert, highestQuorumCert) assert.Equal(t, extraField.QuorumCert, highestQuorumCert)
} }
@ -77,18 +78,18 @@ func TestSkipVerifySyncInfoIfBothQcTcNotQualified(t *testing.T) {
// Make the Highest QC in syncInfo point to an old block to simulate it's no longer qualified // Make the Highest QC in syncInfo point to an old block to simulate it's no longer qualified
parentBlock := blockchain.GetBlockByNumber(903) parentBlock := blockchain.GetBlockByNumber(903)
var extraField utils.ExtraFields_v2 var extraField types.ExtraFields_v2
err := utils.DecodeBytesExtraFields(parentBlock.Extra(), &extraField) err := utils.DecodeBytesExtraFields(parentBlock.Extra(), &extraField)
if err != nil { if err != nil {
t.Fatal("Fail to decode extra data", err) t.Fatal("Fail to decode extra data", err)
} }
highestTC := &utils.TimeoutCert{ highestTC := &types.TimeoutCert{
Round: utils.Round(5), Round: types.Round(5),
Signatures: []utils.Signature{}, Signatures: []types.Signature{},
} }
syncInfoMsg := &utils.SyncInfo{ syncInfoMsg := &types.SyncInfo{
HighestQuorumCert: extraField.QuorumCert, HighestQuorumCert: extraField.QuorumCert,
HighestTimeoutCert: highestTC, HighestTimeoutCert: highestTC,
} }

View file

@ -9,7 +9,7 @@ import (
"github.com/XinFinOrg/XDPoSChain/accounts" "github.com/XinFinOrg/XDPoSChain/accounts"
"github.com/XinFinOrg/XDPoSChain/accounts/abi/bind/backends" "github.com/XinFinOrg/XDPoSChain/accounts/abi/bind/backends"
"github.com/XinFinOrg/XDPoSChain/consensus/XDPoS" "github.com/XinFinOrg/XDPoSChain/consensus/XDPoS"
"github.com/XinFinOrg/XDPoSChain/consensus/XDPoS/utils" "github.com/XinFinOrg/XDPoSChain/core/types"
"github.com/XinFinOrg/XDPoSChain/log" "github.com/XinFinOrg/XDPoSChain/log"
"github.com/XinFinOrg/XDPoSChain/params" "github.com/XinFinOrg/XDPoSChain/params"
"github.com/stretchr/testify/assert" "github.com/stretchr/testify/assert"
@ -20,11 +20,11 @@ func TestCountdownTimeoutToSendTimeoutMessage(t *testing.T) {
engineV2 := blockchain.Engine().(*XDPoS.XDPoS).EngineV2 engineV2 := blockchain.Engine().(*XDPoS.XDPoS).EngineV2
timeoutMsg := <-engineV2.BroadcastCh timeoutMsg := <-engineV2.BroadcastCh
poolSize := engineV2.GetTimeoutPoolSizeFaker(timeoutMsg.(*utils.Timeout)) poolSize := engineV2.GetTimeoutPoolSizeFaker(timeoutMsg.(*types.Timeout))
assert.Equal(t, poolSize, 1) assert.Equal(t, poolSize, 1)
assert.NotNil(t, timeoutMsg) assert.NotNil(t, timeoutMsg)
assert.Equal(t, uint64(450), timeoutMsg.(*utils.Timeout).GapNumber) assert.Equal(t, uint64(450), timeoutMsg.(*types.Timeout).GapNumber)
assert.Equal(t, utils.Round(1), timeoutMsg.(*utils.Timeout).Round) assert.Equal(t, types.Round(1), timeoutMsg.(*types.Timeout).Round)
} }
func TestCountdownTimeoutNotToSendTimeoutMessageIfNotInMasternodeList(t *testing.T) { func TestCountdownTimeoutNotToSendTimeoutMessageIfNotInMasternodeList(t *testing.T) {
@ -55,9 +55,9 @@ func TestSyncInfoAfterReachTimeoutSnycThreadhold(t *testing.T) {
for i := 0; i < 3; i++ { for i := 0; i < 3; i++ {
obj := <-engineV2.BroadcastCh obj := <-engineV2.BroadcastCh
switch v := obj.(type) { switch v := obj.(type) {
case *utils.Timeout: case *types.Timeout:
timeoutCounter++ timeoutCounter++
case *utils.SyncInfo: case *types.SyncInfo:
syncInfoCounter++ syncInfoCounter++
default: default:
log.Error("Unknown message type received", "value", v) log.Error("Unknown message type received", "value", v)
@ -71,9 +71,9 @@ func TestSyncInfoAfterReachTimeoutSnycThreadhold(t *testing.T) {
for i := 0; i < 3; i++ { for i := 0; i < 3; i++ {
obj := <-engineV2.BroadcastCh obj := <-engineV2.BroadcastCh
switch v := obj.(type) { switch v := obj.(type) {
case *utils.Timeout: case *types.Timeout:
timeoutCounter++ timeoutCounter++
case *utils.SyncInfo: case *types.SyncInfo:
syncInfoCounter++ syncInfoCounter++
default: default:
log.Error("Unknown message type received", "value", v) log.Error("Unknown message type received", "value", v)
@ -89,10 +89,10 @@ func TestTimeoutMessageHandlerSuccessfullyGenerateTCandSyncInfo(t *testing.T) {
engineV2 := blockchain.Engine().(*XDPoS.XDPoS).EngineV2 engineV2 := blockchain.Engine().(*XDPoS.XDPoS).EngineV2
// Set round to 1 // Set round to 1
engineV2.SetNewRoundFaker(blockchain, utils.Round(1), false) engineV2.SetNewRoundFaker(blockchain, types.Round(1), false)
// Create two timeout message which will not reach timeout pool threshold // Create two timeout message which will not reach timeout pool threshold
timeoutMsg := &utils.Timeout{ timeoutMsg := &types.Timeout{
Round: utils.Round(1), Round: types.Round(1),
Signature: []byte{1}, Signature: []byte{1},
GapNumber: 450, GapNumber: 450,
} }
@ -100,31 +100,31 @@ func TestTimeoutMessageHandlerSuccessfullyGenerateTCandSyncInfo(t *testing.T) {
err := engineV2.TimeoutHandler(blockchain, timeoutMsg) err := engineV2.TimeoutHandler(blockchain, timeoutMsg)
assert.Nil(t, err) assert.Nil(t, err)
currentRound, _, _, _, _, _ := engineV2.GetPropertiesFaker() currentRound, _, _, _, _, _ := engineV2.GetPropertiesFaker()
assert.Equal(t, utils.Round(1), currentRound) assert.Equal(t, types.Round(1), currentRound)
timeoutMsg = &utils.Timeout{ timeoutMsg = &types.Timeout{
Round: utils.Round(1), Round: types.Round(1),
Signature: []byte{2}, Signature: []byte{2},
GapNumber: 450, GapNumber: 450,
} }
err = engineV2.TimeoutHandler(blockchain, timeoutMsg) err = engineV2.TimeoutHandler(blockchain, timeoutMsg)
assert.Nil(t, err) assert.Nil(t, err)
currentRound, _, _, _, _, _ = engineV2.GetPropertiesFaker() currentRound, _, _, _, _, _ = engineV2.GetPropertiesFaker()
assert.Equal(t, utils.Round(1), currentRound) assert.Equal(t, types.Round(1), currentRound)
// Send a timeout with different gap number, it shall not trigger timeout pool hook // Send a timeout with different gap number, it shall not trigger timeout pool hook
timeoutMsg = &utils.Timeout{ timeoutMsg = &types.Timeout{
Round: utils.Round(1), Round: types.Round(1),
Signature: []byte{3}, Signature: []byte{3},
GapNumber: 1350, GapNumber: 1350,
} }
err = engineV2.TimeoutHandler(blockchain, timeoutMsg) err = engineV2.TimeoutHandler(blockchain, timeoutMsg)
assert.Nil(t, err) assert.Nil(t, err)
currentRound, _, _, _, _, _ = engineV2.GetPropertiesFaker() currentRound, _, _, _, _, _ = engineV2.GetPropertiesFaker()
assert.Equal(t, utils.Round(1), currentRound) assert.Equal(t, types.Round(1), currentRound)
// Create a timeout message that should trigger timeout pool hook // Create a timeout message that should trigger timeout pool hook
timeoutMsg = &utils.Timeout{ timeoutMsg = &types.Timeout{
Round: utils.Round(1), Round: types.Round(1),
Signature: []byte{4}, Signature: []byte{4},
GapNumber: 450, GapNumber: 450,
} }
@ -139,17 +139,17 @@ func TestTimeoutMessageHandlerSuccessfullyGenerateTCandSyncInfo(t *testing.T) {
assert.NotNil(t, syncInfoMsg) assert.NotNil(t, syncInfoMsg)
// Shouldn't have QC, however, we did not inilise it, hence will show default empty value // Shouldn't have QC, however, we did not inilise it, hence will show default empty value
qc := syncInfoMsg.(*utils.SyncInfo).HighestQuorumCert qc := syncInfoMsg.(*types.SyncInfo).HighestQuorumCert
assert.Equal(t, utils.Round(0), qc.ProposedBlockInfo.Round) assert.Equal(t, types.Round(0), qc.ProposedBlockInfo.Round)
tc := syncInfoMsg.(*utils.SyncInfo).HighestTimeoutCert tc := syncInfoMsg.(*types.SyncInfo).HighestTimeoutCert
assert.NotNil(t, tc) assert.NotNil(t, tc)
assert.Equal(t, tc.Round, utils.Round(1)) assert.Equal(t, tc.Round, types.Round(1))
assert.Equal(t, uint64(450), tc.GapNumber) assert.Equal(t, uint64(450), tc.GapNumber)
// The signatures shall not include the byte{3} from a different gap number // The signatures shall not include the byte{3} from a different gap number
sigatures := []utils.Signature{[]byte{1}, []byte{2}, []byte{4}} sigatures := []types.Signature{[]byte{1}, []byte{2}, []byte{4}}
assert.ElementsMatch(t, tc.Signatures, sigatures) assert.ElementsMatch(t, tc.Signatures, sigatures)
assert.Equal(t, utils.Round(2), currentRound) assert.Equal(t, types.Round(2), currentRound)
} }
func TestThrowErrorIfTimeoutMsgRoundNotEqualToCurrentRound(t *testing.T) { func TestThrowErrorIfTimeoutMsgRoundNotEqualToCurrentRound(t *testing.T) {
@ -157,9 +157,9 @@ func TestThrowErrorIfTimeoutMsgRoundNotEqualToCurrentRound(t *testing.T) {
engineV2 := blockchain.Engine().(*XDPoS.XDPoS).EngineV2 engineV2 := blockchain.Engine().(*XDPoS.XDPoS).EngineV2
// Set round to 3 // Set round to 3
engineV2.SetNewRoundFaker(blockchain, utils.Round(3), false) engineV2.SetNewRoundFaker(blockchain, types.Round(3), false)
timeoutMsg := &utils.Timeout{ timeoutMsg := &types.Timeout{
Round: utils.Round(2), Round: types.Round(2),
Signature: []byte{1}, Signature: []byte{1},
} }
@ -169,7 +169,7 @@ func TestThrowErrorIfTimeoutMsgRoundNotEqualToCurrentRound(t *testing.T) {
assert.Equal(t, "timeout message round number: 2 does not match currentRound: 3", err.Error()) assert.Equal(t, "timeout message round number: 2 does not match currentRound: 3", err.Error())
// Set round to 1 // Set round to 1
engineV2.SetNewRoundFaker(blockchain, utils.Round(1), false) engineV2.SetNewRoundFaker(blockchain, types.Round(1), false)
err = engineV2.TimeoutHandler(blockchain, timeoutMsg) err = engineV2.TimeoutHandler(blockchain, timeoutMsg)
assert.NotNil(t, err) assert.NotNil(t, err)
// Timeout msg round < currentRound // Timeout msg round < currentRound
@ -180,13 +180,13 @@ func TestShouldVerifyTimeoutMessageForFirstV2Block(t *testing.T) {
blockchain, _, _, signer, signFn, _ := PrepareXDCTestBlockChainForV2Engine(t, 901, params.TestXDPoSMockChainConfig, nil) blockchain, _, _, signer, signFn, _ := PrepareXDCTestBlockChainForV2Engine(t, 901, params.TestXDPoSMockChainConfig, nil)
engineV2 := blockchain.Engine().(*XDPoS.XDPoS).EngineV2 engineV2 := blockchain.Engine().(*XDPoS.XDPoS).EngineV2
signedHash, err := signFn(accounts.Account{Address: signer}, utils.TimeoutSigHash(&utils.TimeoutForSign{ signedHash, err := signFn(accounts.Account{Address: signer}, types.TimeoutSigHash(&types.TimeoutForSign{
Round: utils.Round(1), Round: types.Round(1),
GapNumber: 450, GapNumber: 450,
}).Bytes()) }).Bytes())
assert.Nil(t, err) assert.Nil(t, err)
timeoutMsg := &utils.Timeout{ timeoutMsg := &types.Timeout{
Round: utils.Round(1), Round: types.Round(1),
GapNumber: 450, GapNumber: 450,
Signature: signedHash, Signature: signedHash,
} }
@ -195,13 +195,13 @@ func TestShouldVerifyTimeoutMessageForFirstV2Block(t *testing.T) {
assert.Nil(t, err) assert.Nil(t, err)
assert.True(t, verified) assert.True(t, verified)
signedHash, err = signFn(accounts.Account{Address: signer}, utils.TimeoutSigHash(&utils.TimeoutForSign{ signedHash, err = signFn(accounts.Account{Address: signer}, types.TimeoutSigHash(&types.TimeoutForSign{
Round: utils.Round(2), Round: types.Round(2),
GapNumber: 450, GapNumber: 450,
}).Bytes()) }).Bytes())
assert.Nil(t, err) assert.Nil(t, err)
timeoutMsg = &utils.Timeout{ timeoutMsg = &types.Timeout{
Round: utils.Round(2), Round: types.Round(2),
GapNumber: 450, GapNumber: 450,
Signature: signedHash, Signature: signedHash,
} }
@ -215,12 +215,12 @@ func TestShouldVerifyTimeoutMessage(t *testing.T) {
blockchain, _, _, _, _, _ := PrepareXDCTestBlockChainForV2Engine(t, 2251, params.TestXDPoSMockChainConfig, nil) blockchain, _, _, _, _, _ := PrepareXDCTestBlockChainForV2Engine(t, 2251, params.TestXDPoSMockChainConfig, nil)
engineV2 := blockchain.Engine().(*XDPoS.XDPoS).EngineV2 engineV2 := blockchain.Engine().(*XDPoS.XDPoS).EngineV2
signedHash := SignHashByPK(acc1Key, utils.TimeoutSigHash(&utils.TimeoutForSign{ signedHash := SignHashByPK(acc1Key, types.TimeoutSigHash(&types.TimeoutForSign{
Round: utils.Round(5000), Round: types.Round(5000),
GapNumber: 2250, GapNumber: 2250,
}).Bytes()) }).Bytes())
timeoutMsg := &utils.Timeout{ timeoutMsg := &types.Timeout{
Round: utils.Round(5000), Round: types.Round(5000),
GapNumber: 2250, GapNumber: 2250,
Signature: signedHash, Signature: signedHash,
} }
@ -235,46 +235,46 @@ func TestTimeoutPoolKeeyGoodHygiene(t *testing.T) {
engineV2 := blockchain.Engine().(*XDPoS.XDPoS).EngineV2 engineV2 := blockchain.Engine().(*XDPoS.XDPoS).EngineV2
// Set round to 5 // Set round to 5
engineV2.SetNewRoundFaker(blockchain, utils.Round(5), false) engineV2.SetNewRoundFaker(blockchain, types.Round(5), false)
// Inject the first timeout with round 5 // Inject the first timeout with round 5
signedHash, _ := signFn(accounts.Account{Address: signer}, utils.TimeoutSigHash(&utils.TimeoutForSign{ signedHash, _ := signFn(accounts.Account{Address: signer}, types.TimeoutSigHash(&types.TimeoutForSign{
Round: utils.Round(5), Round: types.Round(5),
GapNumber: 450, GapNumber: 450,
}).Bytes()) }).Bytes())
timeoutMsg := &utils.Timeout{ timeoutMsg := &types.Timeout{
Round: utils.Round(5), Round: types.Round(5),
GapNumber: 450, GapNumber: 450,
Signature: signedHash, Signature: signedHash,
} }
engineV2.TimeoutHandler(blockchain, timeoutMsg) engineV2.TimeoutHandler(blockchain, timeoutMsg)
// Inject a second timeout with round 16 // Inject a second timeout with round 16
signedHash, _ = signFn(accounts.Account{Address: signer}, utils.TimeoutSigHash(&utils.TimeoutForSign{ signedHash, _ = signFn(accounts.Account{Address: signer}, types.TimeoutSigHash(&types.TimeoutForSign{
Round: utils.Round(16), Round: types.Round(16),
GapNumber: 450, GapNumber: 450,
}).Bytes()) }).Bytes())
timeoutMsg = &utils.Timeout{ timeoutMsg = &types.Timeout{
Round: utils.Round(16), Round: types.Round(16),
GapNumber: 450, GapNumber: 450,
Signature: signedHash, Signature: signedHash,
} }
// Set round to 16 // Set round to 16
engineV2.SetNewRoundFaker(blockchain, utils.Round(16), false) engineV2.SetNewRoundFaker(blockchain, types.Round(16), false)
engineV2.TimeoutHandler(blockchain, timeoutMsg) engineV2.TimeoutHandler(blockchain, timeoutMsg)
// Inject a third timeout with round 17 // Inject a third timeout with round 17
signedHash, _ = signFn(accounts.Account{Address: signer}, utils.TimeoutSigHash(&utils.TimeoutForSign{ signedHash, _ = signFn(accounts.Account{Address: signer}, types.TimeoutSigHash(&types.TimeoutForSign{
Round: utils.Round(17), Round: types.Round(17),
GapNumber: 450, GapNumber: 450,
}).Bytes()) }).Bytes())
timeoutMsg = &utils.Timeout{ timeoutMsg = &types.Timeout{
Round: utils.Round(17), Round: types.Round(17),
GapNumber: 450, GapNumber: 450,
Signature: signedHash, Signature: signedHash,
} }
// Set round to 16 // Set round to 16
engineV2.SetNewRoundFaker(blockchain, utils.Round(17), false) engineV2.SetNewRoundFaker(blockchain, types.Round(17), false)
engineV2.TimeoutHandler(blockchain, timeoutMsg) engineV2.TimeoutHandler(blockchain, timeoutMsg)
// Let's keep good Hygiene // Let's keep good Hygiene

View file

@ -5,7 +5,7 @@ import (
"testing" "testing"
"github.com/XinFinOrg/XDPoSChain/consensus/XDPoS" "github.com/XinFinOrg/XDPoSChain/consensus/XDPoS"
"github.com/XinFinOrg/XDPoSChain/consensus/XDPoS/utils" "github.com/XinFinOrg/XDPoSChain/core/types"
"github.com/XinFinOrg/XDPoSChain/params" "github.com/XinFinOrg/XDPoSChain/params"
"github.com/stretchr/testify/assert" "github.com/stretchr/testify/assert"
) )
@ -15,9 +15,9 @@ func TestShouldVerifyBlockInfo(t *testing.T) {
blockchain, _, currentBlock, signer, signFn, _ := PrepareXDCTestBlockChainForV2Engine(t, 901, params.TestXDPoSMockChainConfig, nil) blockchain, _, currentBlock, signer, signFn, _ := PrepareXDCTestBlockChainForV2Engine(t, 901, params.TestXDPoSMockChainConfig, nil)
engineV2 := blockchain.Engine().(*XDPoS.XDPoS).EngineV2 engineV2 := blockchain.Engine().(*XDPoS.XDPoS).EngineV2
blockInfo := &utils.BlockInfo{ blockInfo := &types.BlockInfo{
Hash: currentBlock.Hash(), Hash: currentBlock.Hash(),
Round: utils.Round(1), Round: types.Round(1),
Number: currentBlock.Number(), Number: currentBlock.Number(),
} }
err := engineV2.VerifyBlockInfo(blockchain, blockInfo, nil) err := engineV2.VerifyBlockInfo(blockchain, blockInfo, nil)
@ -30,33 +30,33 @@ func TestShouldVerifyBlockInfo(t *testing.T) {
err = blockchain.InsertBlock(block902) err = blockchain.InsertBlock(block902)
assert.Nil(t, err) assert.Nil(t, err)
blockInfo = &utils.BlockInfo{ blockInfo = &types.BlockInfo{
Hash: block902.Hash(), Hash: block902.Hash(),
Round: utils.Round(2), Round: types.Round(2),
Number: block902.Number(), Number: block902.Number(),
} }
err = engineV2.VerifyBlockInfo(blockchain, blockInfo, nil) err = engineV2.VerifyBlockInfo(blockchain, blockInfo, nil)
assert.Nil(t, err) assert.Nil(t, err)
blockInfo = &utils.BlockInfo{ blockInfo = &types.BlockInfo{
Hash: currentBlock.Hash(), Hash: currentBlock.Hash(),
Round: utils.Round(2), Round: types.Round(2),
Number: currentBlock.Number(), Number: currentBlock.Number(),
} }
err = engineV2.VerifyBlockInfo(blockchain, blockInfo, nil) err = engineV2.VerifyBlockInfo(blockchain, blockInfo, nil)
assert.NotNil(t, err) assert.NotNil(t, err)
blockInfo = &utils.BlockInfo{ blockInfo = &types.BlockInfo{
Hash: block902.Hash(), Hash: block902.Hash(),
Round: utils.Round(3), Round: types.Round(3),
Number: block902.Number(), Number: block902.Number(),
} }
err = engineV2.VerifyBlockInfo(blockchain, blockInfo, nil) err = engineV2.VerifyBlockInfo(blockchain, blockInfo, nil)
assert.NotNil(t, err) assert.NotNil(t, err)
blockInfo = &utils.BlockInfo{ blockInfo = &types.BlockInfo{
Hash: block902.Hash(), Hash: block902.Hash(),
Round: utils.Round(2), Round: types.Round(2),
Number: currentBlock.Number(), Number: currentBlock.Number(),
} }
err = engineV2.VerifyBlockInfo(blockchain, blockInfo, nil) err = engineV2.VerifyBlockInfo(blockchain, blockInfo, nil)

View file

@ -108,34 +108,34 @@ func TestShouldVerifyBlock(t *testing.T) {
assert.Equal(t, utils.ErrInvalidDifficulty, err) assert.Equal(t, utils.ErrInvalidDifficulty, err)
// Creat an invalid QC round // Creat an invalid QC round
proposedBlockInfo := &utils.BlockInfo{ proposedBlockInfo := &types.BlockInfo{
Hash: blockchain.GetBlockByNumber(902).Hash(), Hash: blockchain.GetBlockByNumber(902).Hash(),
Round: utils.Round(2), Round: types.Round(2),
Number: blockchain.GetBlockByNumber(902).Number(), Number: blockchain.GetBlockByNumber(902).Number(),
} }
voteForSign := &utils.VoteForSign{ voteForSign := &types.VoteForSign{
ProposedBlockInfo: proposedBlockInfo, ProposedBlockInfo: proposedBlockInfo,
GapNumber: 450, GapNumber: 450,
} }
// Genrate QC // Genrate QC
signedHash, err := signFn(accounts.Account{Address: signer}, utils.VoteSigHash(voteForSign).Bytes()) signedHash, err := signFn(accounts.Account{Address: signer}, types.VoteSigHash(voteForSign).Bytes())
if err != nil { if err != nil {
panic(fmt.Errorf("Error generate QC by creating signedHash: %v", err)) panic(fmt.Errorf("Error generate QC by creating signedHash: %v", err))
} }
// Sign from acc 1, 2, 3 // Sign from acc 1, 2, 3
acc1SignedHash := SignHashByPK(acc1Key, utils.VoteSigHash(voteForSign).Bytes()) acc1SignedHash := SignHashByPK(acc1Key, types.VoteSigHash(voteForSign).Bytes())
acc2SignedHash := SignHashByPK(acc2Key, utils.VoteSigHash(voteForSign).Bytes()) acc2SignedHash := SignHashByPK(acc2Key, types.VoteSigHash(voteForSign).Bytes())
acc3SignedHash := SignHashByPK(acc3Key, utils.VoteSigHash(voteForSign).Bytes()) acc3SignedHash := SignHashByPK(acc3Key, types.VoteSigHash(voteForSign).Bytes())
var signatures []utils.Signature var signatures []types.Signature
signatures = append(signatures, signedHash, acc1SignedHash, acc2SignedHash, acc3SignedHash) signatures = append(signatures, signedHash, acc1SignedHash, acc2SignedHash, acc3SignedHash)
quorumCert := &utils.QuorumCert{ quorumCert := &types.QuorumCert{
ProposedBlockInfo: proposedBlockInfo, ProposedBlockInfo: proposedBlockInfo,
Signatures: signatures, Signatures: signatures,
GapNumber: 450, GapNumber: 450,
} }
extra := utils.ExtraFields_v2{ extra := types.ExtraFields_v2{
Round: utils.Round(2), Round: types.Round(2),
QuorumCert: quorumCert, QuorumCert: quorumCert,
} }
extraInBytes, err := extra.EncodeToBytes() extraInBytes, err := extra.EncodeToBytes()
@ -181,28 +181,28 @@ func TestShouldFailIfNotEnoughQCSignatures(t *testing.T) {
adaptor := blockchain.Engine().(*XDPoS.XDPoS) adaptor := blockchain.Engine().(*XDPoS.XDPoS)
parentBlock := blockchain.GetBlockByNumber(901) parentBlock := blockchain.GetBlockByNumber(901)
proposedBlockInfo := &utils.BlockInfo{ proposedBlockInfo := &types.BlockInfo{
Hash: parentBlock.Hash(), Hash: parentBlock.Hash(),
Round: utils.Round(1), Round: types.Round(1),
Number: parentBlock.Number(), Number: parentBlock.Number(),
} }
voteForSign := &utils.VoteForSign{ voteForSign := &types.VoteForSign{
ProposedBlockInfo: proposedBlockInfo, ProposedBlockInfo: proposedBlockInfo,
GapNumber: 450, GapNumber: 450,
} }
signedHash, err := signFn(accounts.Account{Address: signer}, utils.VoteSigHash(voteForSign).Bytes()) signedHash, err := signFn(accounts.Account{Address: signer}, types.VoteSigHash(voteForSign).Bytes())
assert.Nil(t, err) assert.Nil(t, err)
var signatures []utils.Signature var signatures []types.Signature
// Duplicate the signatures // Duplicate the signatures
signatures = append(signatures, signedHash, signedHash, signedHash, signedHash, signedHash, signedHash) signatures = append(signatures, signedHash, signedHash, signedHash, signedHash, signedHash, signedHash)
quorumCert := &utils.QuorumCert{ quorumCert := &types.QuorumCert{
ProposedBlockInfo: proposedBlockInfo, ProposedBlockInfo: proposedBlockInfo,
Signatures: signatures, Signatures: signatures,
GapNumber: 450, GapNumber: 450,
} }
extra := utils.ExtraFields_v2{ extra := types.ExtraFields_v2{
Round: utils.Round(2), Round: types.Round(2),
QuorumCert: quorumCert, QuorumCert: quorumCert,
} }
extraInBytes, err := extra.EncodeToBytes() extraInBytes, err := extra.EncodeToBytes()

View file

@ -12,7 +12,7 @@ import (
"github.com/XinFinOrg/XDPoSChain/accounts/abi/bind/backends" "github.com/XinFinOrg/XDPoSChain/accounts/abi/bind/backends"
"github.com/XinFinOrg/XDPoSChain/common" "github.com/XinFinOrg/XDPoSChain/common"
"github.com/XinFinOrg/XDPoSChain/consensus/XDPoS" "github.com/XinFinOrg/XDPoSChain/consensus/XDPoS"
"github.com/XinFinOrg/XDPoSChain/consensus/XDPoS/utils" "github.com/XinFinOrg/XDPoSChain/core/types"
"github.com/XinFinOrg/XDPoSChain/params" "github.com/XinFinOrg/XDPoSChain/params"
"github.com/stretchr/testify/assert" "github.com/stretchr/testify/assert"
) )
@ -22,23 +22,23 @@ func TestVoteMessageHandlerSuccessfullyGeneratedAndProcessQCForFistV2Round(t *te
blockchain, _, currentBlock, signer, signFn, _ := PrepareXDCTestBlockChainForV2Engine(t, 901, params.TestXDPoSMockChainConfig, nil) blockchain, _, currentBlock, signer, signFn, _ := PrepareXDCTestBlockChainForV2Engine(t, 901, params.TestXDPoSMockChainConfig, nil)
engineV2 := blockchain.Engine().(*XDPoS.XDPoS).EngineV2 engineV2 := blockchain.Engine().(*XDPoS.XDPoS).EngineV2
blockInfo := &utils.BlockInfo{ blockInfo := &types.BlockInfo{
Hash: currentBlock.Hash(), Hash: currentBlock.Hash(),
Round: utils.Round(1), Round: types.Round(1),
Number: big.NewInt(901), Number: big.NewInt(901),
} }
voteForSign := &utils.VoteForSign{ voteForSign := &types.VoteForSign{
ProposedBlockInfo: blockInfo, ProposedBlockInfo: blockInfo,
GapNumber: 450, GapNumber: 450,
} }
voteSigningHash := utils.VoteSigHash(voteForSign) voteSigningHash := types.VoteSigHash(voteForSign)
// Set round to 5 // Set round to 5
engineV2.SetNewRoundFaker(blockchain, utils.Round(1), false) engineV2.SetNewRoundFaker(blockchain, types.Round(1), false)
// Create two vote messages which will not reach vote pool threshold // Create two vote messages which will not reach vote pool threshold
signedHash, err := signFn(accounts.Account{Address: signer}, voteSigningHash.Bytes()) signedHash, err := signFn(accounts.Account{Address: signer}, voteSigningHash.Bytes())
assert.Nil(t, err) assert.Nil(t, err)
voteMsg := &utils.Vote{ voteMsg := &types.Vote{
ProposedBlockInfo: blockInfo, ProposedBlockInfo: blockInfo,
Signature: signedHash, Signature: signedHash,
GapNumber: 450, GapNumber: 450,
@ -49,12 +49,12 @@ func TestVoteMessageHandlerSuccessfullyGeneratedAndProcessQCForFistV2Round(t *te
currentRound, lockQuorumCert, highestQuorumCert, _, _, _ := engineV2.GetPropertiesFaker() currentRound, lockQuorumCert, highestQuorumCert, _, _, _ := engineV2.GetPropertiesFaker()
// initialised with nil and 0 round // initialised with nil and 0 round
assert.Nil(t, lockQuorumCert) assert.Nil(t, lockQuorumCert)
assert.Equal(t, utils.Round(0), highestQuorumCert.ProposedBlockInfo.Round) assert.Equal(t, types.Round(0), highestQuorumCert.ProposedBlockInfo.Round)
assert.Equal(t, utils.Round(1), currentRound) assert.Equal(t, types.Round(1), currentRound)
signedHash = SignHashByPK(acc2Key, voteSigningHash.Bytes()) signedHash = SignHashByPK(acc2Key, voteSigningHash.Bytes())
voteMsg = &utils.Vote{ voteMsg = &types.Vote{
ProposedBlockInfo: blockInfo, ProposedBlockInfo: blockInfo,
Signature: signedHash, Signature: signedHash,
GapNumber: 450, GapNumber: 450,
@ -64,13 +64,13 @@ func TestVoteMessageHandlerSuccessfullyGeneratedAndProcessQCForFistV2Round(t *te
currentRound, lockQuorumCert, highestQuorumCert, _, _, _ = engineV2.GetPropertiesFaker() currentRound, lockQuorumCert, highestQuorumCert, _, _, _ = engineV2.GetPropertiesFaker()
// Still using the initlised value because we did not yet go to the next round // Still using the initlised value because we did not yet go to the next round
assert.Nil(t, lockQuorumCert) assert.Nil(t, lockQuorumCert)
assert.Equal(t, utils.Round(0), highestQuorumCert.ProposedBlockInfo.Round) assert.Equal(t, types.Round(0), highestQuorumCert.ProposedBlockInfo.Round)
assert.Equal(t, utils.Round(1), currentRound) assert.Equal(t, types.Round(1), currentRound)
// Create a vote message that should trigger vote pool hook and increment the round to 6 // Create a vote message that should trigger vote pool hook and increment the round to 6
signedHash = SignHashByPK(acc3Key, voteSigningHash.Bytes()) signedHash = SignHashByPK(acc3Key, voteSigningHash.Bytes())
voteMsg = &utils.Vote{ voteMsg = &types.Vote{
ProposedBlockInfo: blockInfo, ProposedBlockInfo: blockInfo,
Signature: signedHash, Signature: signedHash,
GapNumber: 450, GapNumber: 450,
@ -80,34 +80,34 @@ func TestVoteMessageHandlerSuccessfullyGeneratedAndProcessQCForFistV2Round(t *te
assert.Nil(t, err) assert.Nil(t, err)
currentRound, lockQuorumCert, highestQuorumCert, _, _, _ = engineV2.GetPropertiesFaker() currentRound, lockQuorumCert, highestQuorumCert, _, _, _ = engineV2.GetPropertiesFaker()
// The lockQC shall be the parent's QC round number // The lockQC shall be the parent's QC round number
assert.Equal(t, utils.Round(0), lockQuorumCert.ProposedBlockInfo.Round) assert.Equal(t, types.Round(0), lockQuorumCert.ProposedBlockInfo.Round)
// The highestQC proposedBlockInfo shall be the same as the one from its votes // The highestQC proposedBlockInfo shall be the same as the one from its votes
assert.Equal(t, highestQuorumCert.ProposedBlockInfo, voteMsg.ProposedBlockInfo) assert.Equal(t, highestQuorumCert.ProposedBlockInfo, voteMsg.ProposedBlockInfo)
// Check round has now changed from 1 to 2 // Check round has now changed from 1 to 2
assert.Equal(t, utils.Round(2), currentRound) assert.Equal(t, types.Round(2), currentRound)
} }
func TestVoteMessageHandlerSuccessfullyGeneratedAndProcessQC(t *testing.T) { func TestVoteMessageHandlerSuccessfullyGeneratedAndProcessQC(t *testing.T) {
blockchain, _, currentBlock, signer, signFn, _ := PrepareXDCTestBlockChainForV2Engine(t, 905, params.TestXDPoSMockChainConfig, nil) blockchain, _, currentBlock, signer, signFn, _ := PrepareXDCTestBlockChainForV2Engine(t, 905, params.TestXDPoSMockChainConfig, nil)
engineV2 := blockchain.Engine().(*XDPoS.XDPoS).EngineV2 engineV2 := blockchain.Engine().(*XDPoS.XDPoS).EngineV2
blockInfo := &utils.BlockInfo{ blockInfo := &types.BlockInfo{
Hash: currentBlock.Hash(), Hash: currentBlock.Hash(),
Round: utils.Round(5), Round: types.Round(5),
Number: big.NewInt(905), Number: big.NewInt(905),
} }
voteForSign := &utils.VoteForSign{ voteForSign := &types.VoteForSign{
ProposedBlockInfo: blockInfo, ProposedBlockInfo: blockInfo,
GapNumber: 450, GapNumber: 450,
} }
voteSigningHash := utils.VoteSigHash(voteForSign) voteSigningHash := types.VoteSigHash(voteForSign)
// Set round to 5 // Set round to 5
engineV2.SetNewRoundFaker(blockchain, utils.Round(5), false) engineV2.SetNewRoundFaker(blockchain, types.Round(5), false)
// Create two vote messages which will not reach vote pool threshold // Create two vote messages which will not reach vote pool threshold
signedHash, err := signFn(accounts.Account{Address: signer}, voteSigningHash.Bytes()) signedHash, err := signFn(accounts.Account{Address: signer}, voteSigningHash.Bytes())
assert.Nil(t, err) assert.Nil(t, err)
voteMsg := &utils.Vote{ voteMsg := &types.Vote{
ProposedBlockInfo: blockInfo, ProposedBlockInfo: blockInfo,
Signature: signedHash, Signature: signedHash,
GapNumber: 450, GapNumber: 450,
@ -118,10 +118,10 @@ func TestVoteMessageHandlerSuccessfullyGeneratedAndProcessQC(t *testing.T) {
currentRound, lockQuorumCert, highestQuorumCert, _, _, _ := engineV2.GetPropertiesFaker() currentRound, lockQuorumCert, highestQuorumCert, _, _, _ := engineV2.GetPropertiesFaker()
// initialised with nil and 0 round // initialised with nil and 0 round
assert.Nil(t, lockQuorumCert) assert.Nil(t, lockQuorumCert)
assert.Equal(t, utils.Round(0), highestQuorumCert.ProposedBlockInfo.Round) assert.Equal(t, types.Round(0), highestQuorumCert.ProposedBlockInfo.Round)
assert.Equal(t, utils.Round(5), currentRound) assert.Equal(t, types.Round(5), currentRound)
signedHash = SignHashByPK(acc1Key, voteSigningHash.Bytes()) signedHash = SignHashByPK(acc1Key, voteSigningHash.Bytes())
voteMsg = &utils.Vote{ voteMsg = &types.Vote{
ProposedBlockInfo: blockInfo, ProposedBlockInfo: blockInfo,
Signature: signedHash, Signature: signedHash,
GapNumber: 450, GapNumber: 450,
@ -131,16 +131,16 @@ func TestVoteMessageHandlerSuccessfullyGeneratedAndProcessQC(t *testing.T) {
currentRound, lockQuorumCert, highestQuorumCert, _, _, _ = engineV2.GetPropertiesFaker() currentRound, lockQuorumCert, highestQuorumCert, _, _, _ = engineV2.GetPropertiesFaker()
// Still using the initlised value because we did not yet go to the next round // Still using the initlised value because we did not yet go to the next round
assert.Nil(t, lockQuorumCert) assert.Nil(t, lockQuorumCert)
assert.Equal(t, utils.Round(0), highestQuorumCert.ProposedBlockInfo.Round) assert.Equal(t, types.Round(0), highestQuorumCert.ProposedBlockInfo.Round)
assert.Equal(t, utils.Round(5), currentRound) assert.Equal(t, types.Round(5), currentRound)
// Create another vote which is signed by someone not from the master node list // Create another vote which is signed by someone not from the master node list
randomSigner, randomSignFn, err := backends.SimulateWalletAddressAndSignFn() randomSigner, randomSignFn, err := backends.SimulateWalletAddressAndSignFn()
assert.Nil(t, err) assert.Nil(t, err)
randomlySignedHash, err := randomSignFn(accounts.Account{Address: randomSigner}, voteSigningHash.Bytes()) randomlySignedHash, err := randomSignFn(accounts.Account{Address: randomSigner}, voteSigningHash.Bytes())
assert.Nil(t, err) assert.Nil(t, err)
voteMsg = &utils.Vote{ voteMsg = &types.Vote{
ProposedBlockInfo: blockInfo, ProposedBlockInfo: blockInfo,
Signature: randomlySignedHash, Signature: randomlySignedHash,
GapNumber: 450, GapNumber: 450,
@ -150,12 +150,12 @@ func TestVoteMessageHandlerSuccessfullyGeneratedAndProcessQC(t *testing.T) {
currentRound, lockQuorumCert, highestQuorumCert, _, _, _ = engineV2.GetPropertiesFaker() currentRound, lockQuorumCert, highestQuorumCert, _, _, _ = engineV2.GetPropertiesFaker()
// Still using the initlised value because we did not yet go to the next round // Still using the initlised value because we did not yet go to the next round
assert.Nil(t, lockQuorumCert) assert.Nil(t, lockQuorumCert)
assert.Equal(t, utils.Round(0), highestQuorumCert.ProposedBlockInfo.Round) assert.Equal(t, types.Round(0), highestQuorumCert.ProposedBlockInfo.Round)
assert.Equal(t, utils.Round(5), currentRound) assert.Equal(t, types.Round(5), currentRound)
// Create a vote message that should trigger vote pool hook and increment the round to 6 // Create a vote message that should trigger vote pool hook and increment the round to 6
signedHash = SignHashByPK(acc3Key, voteSigningHash.Bytes()) signedHash = SignHashByPK(acc3Key, voteSigningHash.Bytes())
voteMsg = &utils.Vote{ voteMsg = &types.Vote{
ProposedBlockInfo: blockInfo, ProposedBlockInfo: blockInfo,
Signature: signedHash, Signature: signedHash,
GapNumber: 450, GapNumber: 450,
@ -165,13 +165,13 @@ func TestVoteMessageHandlerSuccessfullyGeneratedAndProcessQC(t *testing.T) {
assert.Nil(t, err) assert.Nil(t, err)
currentRound, lockQuorumCert, highestQuorumCert, _, _, highestCommitBlock := engineV2.GetPropertiesFaker() currentRound, lockQuorumCert, highestQuorumCert, _, _, highestCommitBlock := engineV2.GetPropertiesFaker()
// The lockQC shall be the parent's QC round number // The lockQC shall be the parent's QC round number
assert.Equal(t, utils.Round(4), lockQuorumCert.ProposedBlockInfo.Round) assert.Equal(t, types.Round(4), lockQuorumCert.ProposedBlockInfo.Round)
// The highestQC proposedBlockInfo shall be the same as the one from its votes // The highestQC proposedBlockInfo shall be the same as the one from its votes
assert.Equal(t, highestQuorumCert.ProposedBlockInfo, voteMsg.ProposedBlockInfo) assert.Equal(t, highestQuorumCert.ProposedBlockInfo, voteMsg.ProposedBlockInfo)
// Check round has now changed from 5 to 6 // Check round has now changed from 5 to 6
assert.Equal(t, utils.Round(6), currentRound) assert.Equal(t, types.Round(6), currentRound)
// Should trigger ProcessQC and trying to commit from blockNum of 16's grandgrandparent which is blockNum 903 with round 3 // Should trigger ProcessQC and trying to commit from blockNum of 16's grandgrandparent which is blockNum 903 with round 3
assert.Equal(t, utils.Round(3), highestCommitBlock.Round) assert.Equal(t, types.Round(3), highestCommitBlock.Round)
assert.Equal(t, big.NewInt(903), highestCommitBlock.Number) assert.Equal(t, big.NewInt(903), highestCommitBlock.Number)
} }
@ -179,15 +179,15 @@ func TestThrowErrorIfVoteMsgRoundIsMoreThanOneRoundAwayFromCurrentRound(t *testi
blockchain, _, _, _, _, _ := PrepareXDCTestBlockChainForV2Engine(t, 905, params.TestXDPoSMockChainConfig, nil) blockchain, _, _, _, _, _ := PrepareXDCTestBlockChainForV2Engine(t, 905, params.TestXDPoSMockChainConfig, nil)
engineV2 := blockchain.Engine().(*XDPoS.XDPoS).EngineV2 engineV2 := blockchain.Engine().(*XDPoS.XDPoS).EngineV2
blockInfo := &utils.BlockInfo{ blockInfo := &types.BlockInfo{
Hash: common.HexToHash("0x1"), Hash: common.HexToHash("0x1"),
Round: utils.Round(6), Round: types.Round(6),
Number: big.NewInt(999), Number: big.NewInt(999),
} }
// Set round to 7 // Set round to 7
engineV2.SetNewRoundFaker(blockchain, utils.Round(7), false) engineV2.SetNewRoundFaker(blockchain, types.Round(7), false)
voteMsg := &utils.Vote{ voteMsg := &types.Vote{
ProposedBlockInfo: blockInfo, ProposedBlockInfo: blockInfo,
Signature: []byte{1}, Signature: []byte{1},
GapNumber: 450, GapNumber: 450,
@ -199,11 +199,11 @@ func TestThrowErrorIfVoteMsgRoundIsMoreThanOneRoundAwayFromCurrentRound(t *testi
assert.Equal(t, "vote message round number: 6 is too far away from currentRound: 7", err.Error()) assert.Equal(t, "vote message round number: 6 is too far away from currentRound: 7", err.Error())
// Set round to 5, it's 1 round away, should not trigger failure // Set round to 5, it's 1 round away, should not trigger failure
engineV2.SetNewRoundFaker(blockchain, utils.Round(5), false) engineV2.SetNewRoundFaker(blockchain, types.Round(5), false)
err = engineV2.VoteHandler(blockchain, voteMsg) err = engineV2.VoteHandler(blockchain, voteMsg)
assert.Nil(t, err) assert.Nil(t, err)
engineV2.SetNewRoundFaker(blockchain, utils.Round(4), false) engineV2.SetNewRoundFaker(blockchain, types.Round(4), false)
err = engineV2.VoteHandler(blockchain, voteMsg) err = engineV2.VoteHandler(blockchain, voteMsg)
assert.NotNil(t, err) assert.NotNil(t, err)
assert.Equal(t, "vote message round number: 6 is too far away from currentRound: 4", err.Error()) assert.Equal(t, "vote message round number: 6 is too far away from currentRound: 4", err.Error())
@ -215,22 +215,22 @@ func TestProcessVoteMsgThenTimeoutMsg(t *testing.T) {
engineV2 := blockchain.Engine().(*XDPoS.XDPoS).EngineV2 engineV2 := blockchain.Engine().(*XDPoS.XDPoS).EngineV2
// Set round to 5 // Set round to 5
engineV2.SetNewRoundFaker(blockchain, utils.Round(5), false) engineV2.SetNewRoundFaker(blockchain, types.Round(5), false)
// Start with vote messages // Start with vote messages
blockInfo := &utils.BlockInfo{ blockInfo := &types.BlockInfo{
Hash: currentBlock.Hash(), Hash: currentBlock.Hash(),
Round: utils.Round(5), Round: types.Round(5),
Number: big.NewInt(905), Number: big.NewInt(905),
} }
voteForSign := &utils.VoteForSign{ voteForSign := &types.VoteForSign{
ProposedBlockInfo: blockInfo, ProposedBlockInfo: blockInfo,
GapNumber: 450, GapNumber: 450,
} }
voteSigningHash := utils.VoteSigHash(voteForSign) voteSigningHash := types.VoteSigHash(voteForSign)
// Create two vote message which will not reach vote pool threshold // Create two vote message which will not reach vote pool threshold
signedHash := SignHashByPK(acc1Key, voteSigningHash.Bytes()) signedHash := SignHashByPK(acc1Key, voteSigningHash.Bytes())
voteMsg := &utils.Vote{ voteMsg := &types.Vote{
ProposedBlockInfo: blockInfo, ProposedBlockInfo: blockInfo,
Signature: signedHash, Signature: signedHash,
GapNumber: 450, GapNumber: 450,
@ -241,10 +241,10 @@ func TestProcessVoteMsgThenTimeoutMsg(t *testing.T) {
currentRound, lockQuorumCert, highestQuorumCert, _, _, _ := engineV2.GetPropertiesFaker() currentRound, lockQuorumCert, highestQuorumCert, _, _, _ := engineV2.GetPropertiesFaker()
// initialised with nil and 0 round // initialised with nil and 0 round
assert.Nil(t, lockQuorumCert) assert.Nil(t, lockQuorumCert)
assert.Equal(t, utils.Round(0), highestQuorumCert.ProposedBlockInfo.Round) assert.Equal(t, types.Round(0), highestQuorumCert.ProposedBlockInfo.Round)
assert.Equal(t, utils.Round(5), currentRound) assert.Equal(t, types.Round(5), currentRound)
voteMsg = &utils.Vote{ voteMsg = &types.Vote{
ProposedBlockInfo: blockInfo, ProposedBlockInfo: blockInfo,
Signature: SignHashByPK(acc2Key, voteSigningHash.Bytes()), Signature: SignHashByPK(acc2Key, voteSigningHash.Bytes()),
GapNumber: 450, GapNumber: 450,
@ -252,10 +252,10 @@ func TestProcessVoteMsgThenTimeoutMsg(t *testing.T) {
err = engineV2.VoteHandler(blockchain, voteMsg) err = engineV2.VoteHandler(blockchain, voteMsg)
assert.Nil(t, err) assert.Nil(t, err)
currentRound, _, _, _, _, _ = engineV2.GetPropertiesFaker() currentRound, _, _, _, _, _ = engineV2.GetPropertiesFaker()
assert.Equal(t, utils.Round(5), currentRound) assert.Equal(t, types.Round(5), currentRound)
// Create a vote message that should trigger vote pool hook // Create a vote message that should trigger vote pool hook
voteMsg = &utils.Vote{ voteMsg = &types.Vote{
ProposedBlockInfo: blockInfo, ProposedBlockInfo: blockInfo,
Signature: SignHashByPK(acc3Key, voteSigningHash.Bytes()), Signature: SignHashByPK(acc3Key, voteSigningHash.Bytes()),
GapNumber: 450, GapNumber: 450,
@ -266,17 +266,17 @@ func TestProcessVoteMsgThenTimeoutMsg(t *testing.T) {
// Check round has now changed from 5 to 6 // Check round has now changed from 5 to 6
currentRound, lockQuorumCert, highestQuorumCert, _, _, _ = engineV2.GetPropertiesFaker() currentRound, lockQuorumCert, highestQuorumCert, _, _, _ = engineV2.GetPropertiesFaker()
// The lockQC shall be the parent's QC round number // The lockQC shall be the parent's QC round number
assert.Equal(t, utils.Round(4), lockQuorumCert.ProposedBlockInfo.Round) assert.Equal(t, types.Round(4), lockQuorumCert.ProposedBlockInfo.Round)
// The highestQC proposedBlockInfo shall be the same as the one from its votes // The highestQC proposedBlockInfo shall be the same as the one from its votes
assert.Equal(t, highestQuorumCert.ProposedBlockInfo, voteMsg.ProposedBlockInfo) assert.Equal(t, highestQuorumCert.ProposedBlockInfo, voteMsg.ProposedBlockInfo)
assert.Equal(t, utils.Round(6), currentRound) assert.Equal(t, types.Round(6), currentRound)
// We shall have highestQuorumCert in engine now, let's do timeout msg to see if we can broadcast SyncInfo which contains both highestQuorumCert and HighestTimeoutCert // We shall have highestQuorumCert in engine now, let's do timeout msg to see if we can broadcast SyncInfo which contains both highestQuorumCert and HighestTimeoutCert
// First, all incoming old timeout msg shall not be processed // First, all incoming old timeout msg shall not be processed
timeoutMsg := &utils.Timeout{ timeoutMsg := &types.Timeout{
Round: utils.Round(5), Round: types.Round(5),
Signature: []byte{1}, Signature: []byte{1},
} }
@ -285,27 +285,27 @@ func TestProcessVoteMsgThenTimeoutMsg(t *testing.T) {
assert.Equal(t, "timeout message round number: 5 does not match currentRound: 6", err.Error()) assert.Equal(t, "timeout message round number: 5 does not match currentRound: 6", err.Error())
// Ok, let's do the timeout msg which is on the same round as the current round by creating two timeout message which will not reach timeout pool threshold // Ok, let's do the timeout msg which is on the same round as the current round by creating two timeout message which will not reach timeout pool threshold
timeoutMsg = &utils.Timeout{ timeoutMsg = &types.Timeout{
Round: utils.Round(6), Round: types.Round(6),
Signature: []byte{1}, Signature: []byte{1},
} }
err = engineV2.TimeoutHandler(blockchain, timeoutMsg) err = engineV2.TimeoutHandler(blockchain, timeoutMsg)
assert.Nil(t, err) assert.Nil(t, err)
currentRound, _, _, _, _, _ = engineV2.GetPropertiesFaker() currentRound, _, _, _, _, _ = engineV2.GetPropertiesFaker()
assert.Equal(t, utils.Round(6), currentRound) assert.Equal(t, types.Round(6), currentRound)
timeoutMsg = &utils.Timeout{ timeoutMsg = &types.Timeout{
Round: utils.Round(6), Round: types.Round(6),
Signature: []byte{2}, Signature: []byte{2},
} }
err = engineV2.TimeoutHandler(blockchain, timeoutMsg) err = engineV2.TimeoutHandler(blockchain, timeoutMsg)
assert.Nil(t, err) assert.Nil(t, err)
currentRound, _, _, _, _, _ = engineV2.GetPropertiesFaker() currentRound, _, _, _, _, _ = engineV2.GetPropertiesFaker()
assert.Equal(t, utils.Round(6), currentRound) assert.Equal(t, types.Round(6), currentRound)
// Create a timeout message that should trigger timeout pool hook // Create a timeout message that should trigger timeout pool hook
timeoutMsg = &utils.Timeout{ timeoutMsg = &types.Timeout{
Round: utils.Round(6), Round: types.Round(6),
Signature: []byte{3}, Signature: []byte{3},
} }
@ -316,18 +316,18 @@ func TestProcessVoteMsgThenTimeoutMsg(t *testing.T) {
assert.NotNil(t, syncInfoMsg) assert.NotNil(t, syncInfoMsg)
// Should have HighestQuorumCert from previous round votes // Should have HighestQuorumCert from previous round votes
qc := syncInfoMsg.(*utils.SyncInfo).HighestQuorumCert qc := syncInfoMsg.(*types.SyncInfo).HighestQuorumCert
assert.NotNil(t, qc) assert.NotNil(t, qc)
assert.Equal(t, utils.Round(5), qc.ProposedBlockInfo.Round) assert.Equal(t, types.Round(5), qc.ProposedBlockInfo.Round)
tc := syncInfoMsg.(*utils.SyncInfo).HighestTimeoutCert tc := syncInfoMsg.(*types.SyncInfo).HighestTimeoutCert
assert.NotNil(t, tc) assert.NotNil(t, tc)
assert.Equal(t, utils.Round(6), tc.Round) assert.Equal(t, types.Round(6), tc.Round)
sigatures := []utils.Signature{[]byte{1}, []byte{2}, []byte{3}} sigatures := []types.Signature{[]byte{1}, []byte{2}, []byte{3}}
assert.ElementsMatch(t, tc.Signatures, sigatures) assert.ElementsMatch(t, tc.Signatures, sigatures)
// Round shall be +1 now // Round shall be +1 now
currentRound, _, _, _, _, _ = engineV2.GetPropertiesFaker() currentRound, _, _, _, _, _ = engineV2.GetPropertiesFaker()
assert.Equal(t, utils.Round(7), currentRound) assert.Equal(t, types.Round(7), currentRound)
} }
func TestVoteMessageShallNotThrowErrorIfBlockNotYetExist(t *testing.T) { func TestVoteMessageShallNotThrowErrorIfBlockNotYetExist(t *testing.T) {
@ -339,21 +339,21 @@ func TestVoteMessageShallNotThrowErrorIfBlockNotYetExist(t *testing.T) {
blockCoinBase := fmt.Sprintf("0x111000000000000000000000000000000%03d", blockNum) blockCoinBase := fmt.Sprintf("0x111000000000000000000000000000000%03d", blockNum)
block := CreateBlock(blockchain, params.TestXDPoSMockChainConfig, currentBlock, blockNum, 6, blockCoinBase, signer, signFn, nil, nil) block := CreateBlock(blockchain, params.TestXDPoSMockChainConfig, currentBlock, blockNum, 6, blockCoinBase, signer, signFn, nil, nil)
blockInfo := &utils.BlockInfo{ blockInfo := &types.BlockInfo{
Hash: block.Header().Hash(), Hash: block.Header().Hash(),
Round: utils.Round(6), Round: types.Round(6),
Number: big.NewInt(906), Number: big.NewInt(906),
} }
voteForSign := &utils.VoteForSign{ voteForSign := &types.VoteForSign{
ProposedBlockInfo: blockInfo, ProposedBlockInfo: blockInfo,
GapNumber: 450, GapNumber: 450,
} }
voteSigningHash := utils.VoteSigHash(voteForSign) voteSigningHash := types.VoteSigHash(voteForSign)
// Set round to 6 // Set round to 6
engineV2.SetNewRoundFaker(blockchain, utils.Round(6), false) engineV2.SetNewRoundFaker(blockchain, types.Round(6), false)
// Create two vote messages which will not reach vote pool threshold // Create two vote messages which will not reach vote pool threshold
voteMsg := &utils.Vote{ voteMsg := &types.Vote{
ProposedBlockInfo: blockInfo, ProposedBlockInfo: blockInfo,
Signature: SignHashByPK(acc1Key, voteSigningHash.Bytes()), Signature: SignHashByPK(acc1Key, voteSigningHash.Bytes()),
GapNumber: 450, GapNumber: 450,
@ -362,7 +362,7 @@ func TestVoteMessageShallNotThrowErrorIfBlockNotYetExist(t *testing.T) {
err := engineV2.VoteHandler(blockchain, voteMsg) err := engineV2.VoteHandler(blockchain, voteMsg)
assert.Nil(t, err) assert.Nil(t, err)
voteMsg = &utils.Vote{ voteMsg = &types.Vote{
ProposedBlockInfo: blockInfo, ProposedBlockInfo: blockInfo,
Signature: SignHashByPK(acc2Key, voteSigningHash.Bytes()), Signature: SignHashByPK(acc2Key, voteSigningHash.Bytes()),
GapNumber: 450, GapNumber: 450,
@ -371,7 +371,7 @@ func TestVoteMessageShallNotThrowErrorIfBlockNotYetExist(t *testing.T) {
assert.Nil(t, err) assert.Nil(t, err)
// Create a vote message that should trigger vote pool hook, but it shall not produce any QC yet // Create a vote message that should trigger vote pool hook, but it shall not produce any QC yet
voteMsg = &utils.Vote{ voteMsg = &types.Vote{
ProposedBlockInfo: blockInfo, ProposedBlockInfo: blockInfo,
Signature: SignHashByPK(acc3Key, voteSigningHash.Bytes()), Signature: SignHashByPK(acc3Key, voteSigningHash.Bytes()),
GapNumber: 450, GapNumber: 450,
@ -382,15 +382,15 @@ func TestVoteMessageShallNotThrowErrorIfBlockNotYetExist(t *testing.T) {
currentRound, lockQuorumCert, highestQuorumCert, _, _, _ := engineV2.GetPropertiesFaker() currentRound, lockQuorumCert, highestQuorumCert, _, _, _ := engineV2.GetPropertiesFaker()
// Still using the initlised value because we did not yet go to the next round // Still using the initlised value because we did not yet go to the next round
assert.Nil(t, lockQuorumCert) assert.Nil(t, lockQuorumCert)
assert.Equal(t, utils.Round(0), highestQuorumCert.ProposedBlockInfo.Round) assert.Equal(t, types.Round(0), highestQuorumCert.ProposedBlockInfo.Round)
assert.Equal(t, utils.Round(6), currentRound) assert.Equal(t, types.Round(6), currentRound)
// Now, inject the block into the chain // Now, inject the block into the chain
err = blockchain.InsertBlock(block) err = blockchain.InsertBlock(block)
assert.Nil(t, err) assert.Nil(t, err)
voteMsg = &utils.Vote{ voteMsg = &types.Vote{
ProposedBlockInfo: blockInfo, ProposedBlockInfo: blockInfo,
Signature: SignHashByPK(voterKey, voteSigningHash.Bytes()), Signature: SignHashByPK(voterKey, voteSigningHash.Bytes()),
GapNumber: 450, GapNumber: 450,
@ -401,12 +401,12 @@ func TestVoteMessageShallNotThrowErrorIfBlockNotYetExist(t *testing.T) {
currentRound, lockQuorumCert, highestQuorumCert, _, _, highestCommitBlock := engineV2.GetPropertiesFaker() currentRound, lockQuorumCert, highestQuorumCert, _, _, highestCommitBlock := engineV2.GetPropertiesFaker()
// The lockQC shall be the parent's QC round number // The lockQC shall be the parent's QC round number
assert.Equal(t, utils.Round(5), lockQuorumCert.ProposedBlockInfo.Round) assert.Equal(t, types.Round(5), lockQuorumCert.ProposedBlockInfo.Round)
// The highestQC proposedBlockInfo shall be the same as the one from its votes // The highestQC proposedBlockInfo shall be the same as the one from its votes
assert.Equal(t, highestQuorumCert.ProposedBlockInfo, voteMsg.ProposedBlockInfo) assert.Equal(t, highestQuorumCert.ProposedBlockInfo, voteMsg.ProposedBlockInfo)
assert.Equal(t, utils.Round(7), currentRound) assert.Equal(t, types.Round(7), currentRound)
// Should trigger ProcessQC and trying to commit from blockNum of 16's grandgrandparent which is blockNum 904 with round 4 // Should trigger ProcessQC and trying to commit from blockNum of 16's grandgrandparent which is blockNum 904 with round 4
assert.Equal(t, utils.Round(4), highestCommitBlock.Round) assert.Equal(t, types.Round(4), highestCommitBlock.Round)
assert.Equal(t, big.NewInt(904), highestCommitBlock.Number) assert.Equal(t, big.NewInt(904), highestCommitBlock.Number)
} }
@ -415,22 +415,22 @@ func TestProcessVoteMsgFailIfVerifyBlockInfoFail(t *testing.T) {
engineV2 := blockchain.Engine().(*XDPoS.XDPoS).EngineV2 engineV2 := blockchain.Engine().(*XDPoS.XDPoS).EngineV2
// Set round to 5 // Set round to 5
engineV2.SetNewRoundFaker(blockchain, utils.Round(5), false) engineV2.SetNewRoundFaker(blockchain, types.Round(5), false)
// Start with vote messages // Start with vote messages
blockInfo := &utils.BlockInfo{ blockInfo := &types.BlockInfo{
Hash: currentBlock.ParentHash(), Hash: currentBlock.ParentHash(),
Round: utils.Round(5), Round: types.Round(5),
Number: big.NewInt(905), Number: big.NewInt(905),
} }
voteForSign := &utils.VoteForSign{ voteForSign := &types.VoteForSign{
ProposedBlockInfo: blockInfo, ProposedBlockInfo: blockInfo,
GapNumber: 450, GapNumber: 450,
} }
voteSigningHash := utils.VoteSigHash(voteForSign) voteSigningHash := types.VoteSigHash(voteForSign)
// Create two vote message which will not reach vote pool threshold // Create two vote message which will not reach vote pool threshold
signedHash := SignHashByPK(acc1Key, voteSigningHash.Bytes()) signedHash := SignHashByPK(acc1Key, voteSigningHash.Bytes())
voteMsg := &utils.Vote{ voteMsg := &types.Vote{
ProposedBlockInfo: blockInfo, ProposedBlockInfo: blockInfo,
Signature: signedHash, Signature: signedHash,
GapNumber: 450, GapNumber: 450,
@ -441,10 +441,10 @@ func TestProcessVoteMsgFailIfVerifyBlockInfoFail(t *testing.T) {
currentRound, lockQuorumCert, highestQuorumCert, _, _, _ := engineV2.GetPropertiesFaker() currentRound, lockQuorumCert, highestQuorumCert, _, _, _ := engineV2.GetPropertiesFaker()
// initialised with nil and 0 round // initialised with nil and 0 round
assert.Nil(t, lockQuorumCert) assert.Nil(t, lockQuorumCert)
assert.Equal(t, utils.Round(0), highestQuorumCert.ProposedBlockInfo.Round) assert.Equal(t, types.Round(0), highestQuorumCert.ProposedBlockInfo.Round)
assert.Equal(t, utils.Round(5), currentRound) assert.Equal(t, types.Round(5), currentRound)
voteMsg = &utils.Vote{ voteMsg = &types.Vote{
ProposedBlockInfo: blockInfo, ProposedBlockInfo: blockInfo,
Signature: SignHashByPK(acc2Key, voteSigningHash.Bytes()), Signature: SignHashByPK(acc2Key, voteSigningHash.Bytes()),
GapNumber: 450, GapNumber: 450,
@ -452,10 +452,10 @@ func TestProcessVoteMsgFailIfVerifyBlockInfoFail(t *testing.T) {
err = engineV2.VoteHandler(blockchain, voteMsg) err = engineV2.VoteHandler(blockchain, voteMsg)
assert.Nil(t, err) assert.Nil(t, err)
currentRound, _, _, _, _, _ = engineV2.GetPropertiesFaker() currentRound, _, _, _, _, _ = engineV2.GetPropertiesFaker()
assert.Equal(t, utils.Round(5), currentRound) assert.Equal(t, types.Round(5), currentRound)
// Create a vote message that should trigger vote pool hook // Create a vote message that should trigger vote pool hook
voteMsg = &utils.Vote{ voteMsg = &types.Vote{
ProposedBlockInfo: blockInfo, ProposedBlockInfo: blockInfo,
Signature: SignHashByPK(acc3Key, voteSigningHash.Bytes()), Signature: SignHashByPK(acc3Key, voteSigningHash.Bytes()),
GapNumber: 450, GapNumber: 450,
@ -470,36 +470,36 @@ func TestVerifyVoteMsg(t *testing.T) {
blockchain, _, currentBlock, signer, signFn, _ := PrepareXDCTestBlockChainForV2Engine(t, 915, params.TestXDPoSMockChainConfig, nil) blockchain, _, currentBlock, signer, signFn, _ := PrepareXDCTestBlockChainForV2Engine(t, 915, params.TestXDPoSMockChainConfig, nil)
engineV2 := blockchain.Engine().(*XDPoS.XDPoS).EngineV2 engineV2 := blockchain.Engine().(*XDPoS.XDPoS).EngineV2
blockInfo := &utils.BlockInfo{ blockInfo := &types.BlockInfo{
Hash: currentBlock.Hash(), Hash: currentBlock.Hash(),
Round: utils.Round(14), Round: types.Round(14),
Number: big.NewInt(915), Number: big.NewInt(915),
} }
voteForSign := &utils.VoteForSign{ voteForSign := &types.VoteForSign{
ProposedBlockInfo: blockInfo, ProposedBlockInfo: blockInfo,
GapNumber: 450, GapNumber: 450,
} }
// Valid message but disqualified as the round does not match // Valid message but disqualified as the round does not match
voteMsg := &utils.Vote{ voteMsg := &types.Vote{
ProposedBlockInfo: blockInfo, ProposedBlockInfo: blockInfo,
Signature: []byte{1}, Signature: []byte{1},
GapNumber: 450, GapNumber: 450,
} }
engineV2.SetNewRoundFaker(blockchain, utils.Round(15), false) engineV2.SetNewRoundFaker(blockchain, types.Round(15), false)
verified, err := engineV2.VerifyVoteMessage(blockchain, voteMsg) verified, err := engineV2.VerifyVoteMessage(blockchain, voteMsg)
assert.False(t, verified) assert.False(t, verified)
assert.Nil(t, err) assert.Nil(t, err)
// Invalid vote message with wrong signature // Invalid vote message with wrong signature
engineV2.SetNewRoundFaker(blockchain, utils.Round(14), false) engineV2.SetNewRoundFaker(blockchain, types.Round(14), false)
verified, err = engineV2.VerifyVoteMessage(blockchain, voteMsg) verified, err = engineV2.VerifyVoteMessage(blockchain, voteMsg)
assert.False(t, verified) assert.False(t, verified)
assert.Equal(t, "Error while verifying message: invalid signature length", err.Error()) assert.Equal(t, "Error while verifying message: invalid signature length", err.Error())
// Valid vote message from a master node // Valid vote message from a master node
signHash, _ := signFn(accounts.Account{Address: signer}, utils.VoteSigHash(voteForSign).Bytes()) signHash, _ := signFn(accounts.Account{Address: signer}, types.VoteSigHash(voteForSign).Bytes())
voteMsg = &utils.Vote{ voteMsg = &types.Vote{
ProposedBlockInfo: blockInfo, ProposedBlockInfo: blockInfo,
Signature: signHash, Signature: signHash,
GapNumber: 450, GapNumber: 450,
@ -514,29 +514,29 @@ func TestVoteMessageHandlerWrongGapNumber(t *testing.T) {
blockchain, _, currentBlock, signer, signFn, _ := PrepareXDCTestBlockChainForV2Engine(t, 905, params.TestXDPoSMockChainConfig, nil) blockchain, _, currentBlock, signer, signFn, _ := PrepareXDCTestBlockChainForV2Engine(t, 905, params.TestXDPoSMockChainConfig, nil)
engineV2 := blockchain.Engine().(*XDPoS.XDPoS).EngineV2 engineV2 := blockchain.Engine().(*XDPoS.XDPoS).EngineV2
blockInfo := &utils.BlockInfo{ blockInfo := &types.BlockInfo{
Hash: currentBlock.Hash(), Hash: currentBlock.Hash(),
Round: utils.Round(5), Round: types.Round(5),
Number: big.NewInt(905), Number: big.NewInt(905),
} }
voteForSign := &utils.VoteForSign{ voteForSign := &types.VoteForSign{
ProposedBlockInfo: blockInfo, ProposedBlockInfo: blockInfo,
GapNumber: 450, GapNumber: 450,
} }
voteSigningHash := utils.VoteSigHash(voteForSign) voteSigningHash := types.VoteSigHash(voteForSign)
// Set round to 5 // Set round to 5
engineV2.SetNewRoundFaker(blockchain, utils.Round(5), false) engineV2.SetNewRoundFaker(blockchain, types.Round(5), false)
// Create two vote messages which will not reach vote pool threshold // Create two vote messages which will not reach vote pool threshold
signedHash, _ := signFn(accounts.Account{Address: signer}, voteSigningHash.Bytes()) signedHash, _ := signFn(accounts.Account{Address: signer}, voteSigningHash.Bytes())
voteMsg := &utils.Vote{ voteMsg := &types.Vote{
ProposedBlockInfo: blockInfo, ProposedBlockInfo: blockInfo,
Signature: signedHash, Signature: signedHash,
GapNumber: 450, GapNumber: 450,
} }
engineV2.VoteHandler(blockchain, voteMsg) engineV2.VoteHandler(blockchain, voteMsg)
signedHash = SignHashByPK(acc1Key, voteSigningHash.Bytes()) signedHash = SignHashByPK(acc1Key, voteSigningHash.Bytes())
voteMsg = &utils.Vote{ voteMsg = &types.Vote{
ProposedBlockInfo: blockInfo, ProposedBlockInfo: blockInfo,
Signature: signedHash, Signature: signedHash,
GapNumber: 450, GapNumber: 450,
@ -544,13 +544,13 @@ func TestVoteMessageHandlerWrongGapNumber(t *testing.T) {
engineV2.VoteHandler(blockchain, voteMsg) engineV2.VoteHandler(blockchain, voteMsg)
// Create a vote message that has wrong gap number // Create a vote message that has wrong gap number
voteForSign = &utils.VoteForSign{ voteForSign = &types.VoteForSign{
ProposedBlockInfo: blockInfo, ProposedBlockInfo: blockInfo,
GapNumber: 451, GapNumber: 451,
} }
voteSigningHash = utils.VoteSigHash(voteForSign) voteSigningHash = types.VoteSigHash(voteForSign)
signedHash = SignHashByPK(acc3Key, voteSigningHash.Bytes()) signedHash = SignHashByPK(acc3Key, voteSigningHash.Bytes())
voteMsg = &utils.Vote{ voteMsg = &types.Vote{
ProposedBlockInfo: blockInfo, ProposedBlockInfo: blockInfo,
Signature: signedHash, Signature: signedHash,
GapNumber: 451, GapNumber: 451,
@ -565,22 +565,22 @@ func TestVotePoolKeepGoodHygiene(t *testing.T) {
blockchain, _, currentBlock, signer, signFn, _ := PrepareXDCTestBlockChainForV2Engine(t, 905, params.TestXDPoSMockChainConfig, nil) blockchain, _, currentBlock, signer, signFn, _ := PrepareXDCTestBlockChainForV2Engine(t, 905, params.TestXDPoSMockChainConfig, nil)
engineV2 := blockchain.Engine().(*XDPoS.XDPoS).EngineV2 engineV2 := blockchain.Engine().(*XDPoS.XDPoS).EngineV2
blockInfo := &utils.BlockInfo{ blockInfo := &types.BlockInfo{
Hash: currentBlock.Hash(), Hash: currentBlock.Hash(),
Round: utils.Round(5), Round: types.Round(5),
Number: big.NewInt(905), Number: big.NewInt(905),
} }
voteForSign := &utils.VoteForSign{ voteForSign := &types.VoteForSign{
ProposedBlockInfo: blockInfo, ProposedBlockInfo: blockInfo,
GapNumber: 450, GapNumber: 450,
} }
voteSigningHash := utils.VoteSigHash(voteForSign) voteSigningHash := types.VoteSigHash(voteForSign)
// Set round to 5 // Set round to 5
engineV2.SetNewRoundFaker(blockchain, utils.Round(5), false) engineV2.SetNewRoundFaker(blockchain, types.Round(5), false)
// Create two vote messages which will not reach vote pool threshold // Create two vote messages which will not reach vote pool threshold
signedHash, _ := signFn(accounts.Account{Address: signer}, voteSigningHash.Bytes()) signedHash, _ := signFn(accounts.Account{Address: signer}, voteSigningHash.Bytes())
voteMsg := &utils.Vote{ voteMsg := &types.Vote{
ProposedBlockInfo: blockInfo, ProposedBlockInfo: blockInfo,
Signature: signedHash, Signature: signedHash,
GapNumber: 450, GapNumber: 450,
@ -588,22 +588,22 @@ func TestVotePoolKeepGoodHygiene(t *testing.T) {
engineV2.VoteHandler(blockchain, voteMsg) engineV2.VoteHandler(blockchain, voteMsg)
// Inject a second vote with round 16 // Inject a second vote with round 16
blockInfo = &utils.BlockInfo{ blockInfo = &types.BlockInfo{
Hash: currentBlock.Hash(), Hash: currentBlock.Hash(),
Round: utils.Round(16), Round: types.Round(16),
Number: big.NewInt(906), Number: big.NewInt(906),
} }
voteForSign = &utils.VoteForSign{ voteForSign = &types.VoteForSign{
ProposedBlockInfo: blockInfo, ProposedBlockInfo: blockInfo,
GapNumber: 450, GapNumber: 450,
} }
voteSigningHash = utils.VoteSigHash(voteForSign) voteSigningHash = types.VoteSigHash(voteForSign)
// Set round to 16 // Set round to 16
engineV2.SetNewRoundFaker(blockchain, utils.Round(16), false) engineV2.SetNewRoundFaker(blockchain, types.Round(16), false)
// Create two vote messages which will not reach vote pool threshold // Create two vote messages which will not reach vote pool threshold
signedHash, _ = signFn(accounts.Account{Address: signer}, voteSigningHash.Bytes()) signedHash, _ = signFn(accounts.Account{Address: signer}, voteSigningHash.Bytes())
voteMsg = &utils.Vote{ voteMsg = &types.Vote{
ProposedBlockInfo: blockInfo, ProposedBlockInfo: blockInfo,
Signature: signedHash, Signature: signedHash,
GapNumber: 450, GapNumber: 450,
@ -611,22 +611,22 @@ func TestVotePoolKeepGoodHygiene(t *testing.T) {
engineV2.VoteHandler(blockchain, voteMsg) engineV2.VoteHandler(blockchain, voteMsg)
// Inject a second vote with round 25, which is less than 10 rounds difference to the last vote round // Inject a second vote with round 25, which is less than 10 rounds difference to the last vote round
blockInfo = &utils.BlockInfo{ blockInfo = &types.BlockInfo{
Hash: currentBlock.Hash(), Hash: currentBlock.Hash(),
Round: utils.Round(25), Round: types.Round(25),
Number: big.NewInt(907), Number: big.NewInt(907),
} }
voteForSign = &utils.VoteForSign{ voteForSign = &types.VoteForSign{
ProposedBlockInfo: blockInfo, ProposedBlockInfo: blockInfo,
GapNumber: 450, GapNumber: 450,
} }
voteSigningHash = utils.VoteSigHash(voteForSign) voteSigningHash = types.VoteSigHash(voteForSign)
// Set round to 25 // Set round to 25
engineV2.SetNewRoundFaker(blockchain, utils.Round(25), false) engineV2.SetNewRoundFaker(blockchain, types.Round(25), false)
// Create two vote messages which will not reach vote pool threshold // Create two vote messages which will not reach vote pool threshold
signedHash, _ = signFn(accounts.Account{Address: signer}, voteSigningHash.Bytes()) signedHash, _ = signFn(accounts.Account{Address: signer}, voteSigningHash.Bytes())
voteMsg = &utils.Vote{ voteMsg = &types.Vote{
ProposedBlockInfo: blockInfo, ProposedBlockInfo: blockInfo,
Signature: signedHash, Signature: signedHash,
GapNumber: 450, GapNumber: 450,

117
core/types/consensus_v2.go Normal file
View file

@ -0,0 +1,117 @@
package types
import (
"fmt"
"math/big"
"github.com/XinFinOrg/XDPoSChain/common"
"github.com/XinFinOrg/XDPoSChain/rlp"
)
// Round number type in XDPoS 2.0
type Round uint64
type Signature []byte
// Block Info struct in XDPoS 2.0, used for vote message, etc.
type BlockInfo struct {
Hash common.Hash
Round Round
Number *big.Int
}
// Vote message in XDPoS 2.0
type Vote struct {
ProposedBlockInfo *BlockInfo
Signature Signature
GapNumber uint64
}
// Timeout message in XDPoS 2.0
type Timeout struct {
Round Round
Signature Signature
GapNumber uint64
}
// BFT Sync Info message in XDPoS 2.0
type SyncInfo struct {
HighestQuorumCert *QuorumCert
HighestTimeoutCert *TimeoutCert
}
// Quorum Certificate struct in XDPoS 2.0
type QuorumCert struct {
ProposedBlockInfo *BlockInfo
Signatures []Signature
GapNumber uint64
}
// Timeout Certificate struct in XDPoS 2.0
type TimeoutCert struct {
Round Round
Signatures []Signature
GapNumber uint64
}
// The parsed extra fields in block header in XDPoS 2.0 (excluding the version byte)
// The version byte (consensus version) is the first byte in header's extra and it's only valid with value >= 2
type ExtraFields_v2 struct {
Round Round
QuorumCert *QuorumCert
}
type EpochSwitchInfo struct {
Masternodes []common.Address
EpochSwitchBlockInfo *BlockInfo
EpochSwitchParentBlockInfo *BlockInfo
}
// Encode XDPoS 2.0 extra fields into bytes
func (e *ExtraFields_v2) EncodeToBytes() ([]byte, error) {
bytes, err := rlp.EncodeToBytes(e)
if err != nil {
return nil, err
}
versionByte := []byte{2}
return append(versionByte, bytes...), nil
}
func (m *Vote) Hash() common.Hash {
return rlpHash(m)
}
func (m *Timeout) Hash() common.Hash {
return rlpHash(m)
}
func (m *SyncInfo) Hash() common.Hash {
return rlpHash(m)
}
type VoteForSign struct {
ProposedBlockInfo *BlockInfo
GapNumber uint64
}
func VoteSigHash(m *VoteForSign) common.Hash {
return rlpHash(m)
}
type TimeoutForSign struct {
Round Round
GapNumber uint64
}
func TimeoutSigHash(m *TimeoutForSign) common.Hash {
return rlpHash(m)
}
func (m *Vote) PoolKey() string {
// return the voted block hash
return fmt.Sprint(m.ProposedBlockInfo.Round, ":", m.GapNumber, ":", m.ProposedBlockInfo.Number, ":", m.ProposedBlockInfo.Hash.Hex())
}
func (m *Timeout) PoolKey() string {
// timeout pool key is round:gapNumber
return fmt.Sprint(m.Round, ":", m.GapNumber)
}

View file

@ -1,15 +1,32 @@
package utils package types
import ( import (
"fmt"
"math/big" "math/big"
"reflect" "reflect"
"strings" "strings"
"testing" "testing"
"github.com/XinFinOrg/XDPoSChain/common" "github.com/XinFinOrg/XDPoSChain/common"
"github.com/XinFinOrg/XDPoSChain/rlp"
"github.com/stretchr/testify/assert" "github.com/stretchr/testify/assert"
) )
// Decode extra fields for consensus version >= 2 (XDPoS 2.0 and future versions)
func DecodeBytesExtraFields(b []byte, val interface{}) error {
if len(b) == 0 {
return fmt.Errorf("extra field is 0 length")
}
switch b[0] {
case 1:
return fmt.Errorf("consensus version 1 is not applicable for decoding extra fields")
case 2:
return rlp.DecodeBytes(b[1:], val)
default:
return fmt.Errorf("consensus version %d is not defined", b[0])
}
}
func toyExtraFields() *ExtraFields_v2 { func toyExtraFields() *ExtraFields_v2 {
round := Round(307) round := Round(307)
blockInfo := &BlockInfo{Hash: common.BigToHash(big.NewInt(2047)), Round: round - 1, Number: big.NewInt(900)} blockInfo := &BlockInfo{Hash: common.BigToHash(big.NewInt(2047)), Round: round - 1, Number: big.NewInt(900)}