mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-06-19 13:21:37 +00:00
move XDC consensus types into core (#93)
This commit is contained in:
parent
727202cac9
commit
455cacc1b7
27 changed files with 646 additions and 620 deletions
|
|
@ -46,14 +46,14 @@ type XDPoS_v2 struct {
|
|||
|
||||
timeoutPool *utils.Pool
|
||||
votePool *utils.Pool
|
||||
currentRound utils.Round
|
||||
highestSelfMinedRound utils.Round
|
||||
highestVotedRound utils.Round
|
||||
highestQuorumCert *utils.QuorumCert
|
||||
currentRound types.Round
|
||||
highestSelfMinedRound types.Round
|
||||
highestVotedRound types.Round
|
||||
highestQuorumCert *types.QuorumCert
|
||||
// lockQuorumCert in XDPoS Consensus 2.0, used in voting rule
|
||||
lockQuorumCert *utils.QuorumCert
|
||||
highestTimeoutCert *utils.TimeoutCert
|
||||
highestCommitBlock *utils.BlockInfo
|
||||
lockQuorumCert *types.QuorumCert
|
||||
highestTimeoutCert *types.TimeoutCert
|
||||
highestCommitBlock *types.BlockInfo
|
||||
|
||||
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)
|
||||
|
|
@ -90,22 +90,22 @@ func New(config *params.XDPoSConfig, db ethdb.Database, waitPeriodCh chan int) *
|
|||
timeoutPool: timeoutPool,
|
||||
votePool: votePool,
|
||||
|
||||
highestSelfMinedRound: utils.Round(0),
|
||||
highestSelfMinedRound: types.Round(0),
|
||||
|
||||
highestTimeoutCert: &utils.TimeoutCert{
|
||||
Round: utils.Round(0),
|
||||
Signatures: []utils.Signature{},
|
||||
highestTimeoutCert: &types.TimeoutCert{
|
||||
Round: types.Round(0),
|
||||
Signatures: []types.Signature{},
|
||||
},
|
||||
highestQuorumCert: &utils.QuorumCert{
|
||||
ProposedBlockInfo: &utils.BlockInfo{
|
||||
highestQuorumCert: &types.QuorumCert{
|
||||
ProposedBlockInfo: &types.BlockInfo{
|
||||
Hash: common.Hash{},
|
||||
Round: utils.Round(0),
|
||||
Round: types.Round(0),
|
||||
Number: big.NewInt(0),
|
||||
},
|
||||
Signatures: []utils.Signature{},
|
||||
Signatures: []types.Signature{},
|
||||
GapNumber: 0,
|
||||
},
|
||||
highestVotedRound: utils.Round(0),
|
||||
highestVotedRound: types.Round(0),
|
||||
highestCommitBlock: nil,
|
||||
forensics: NewForensics(),
|
||||
}
|
||||
|
|
@ -138,17 +138,17 @@ func (x *XDPoS_v2) Initial(chain consensus.ChainReader, header *types.Header) er
|
|||
return nil
|
||||
}
|
||||
|
||||
var quorumCert *utils.QuorumCert
|
||||
var quorumCert *types.QuorumCert
|
||||
var err error
|
||||
|
||||
if header.Number.Int64() == x.config.V2.SwitchBlock.Int64() {
|
||||
log.Info("[Initial] highest QC for consensus v2 first block")
|
||||
blockInfo := &utils.BlockInfo{
|
||||
blockInfo := &types.BlockInfo{
|
||||
Hash: header.Hash(),
|
||||
Round: utils.Round(0),
|
||||
Round: types.Round(0),
|
||||
Number: header.Number,
|
||||
}
|
||||
quorumCert = &utils.QuorumCert{
|
||||
quorumCert = &types.QuorumCert{
|
||||
ProposedBlockInfo: blockInfo,
|
||||
Signatures: nil,
|
||||
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
|
||||
}
|
||||
|
||||
extra := utils.ExtraFields_v2{
|
||||
extra := types.ExtraFields_v2{
|
||||
Round: currentRound,
|
||||
QuorumCert: highestQC,
|
||||
}
|
||||
|
|
@ -403,7 +403,7 @@ func (x *XDPoS_v2) Seal(chain consensus.ChainReader, block *types.Block, stop <-
|
|||
header.Validator = signature
|
||||
|
||||
// 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)
|
||||
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)
|
||||
|
|
@ -520,7 +520,7 @@ func (x *XDPoS_v2) VerifyHeaders(chain consensus.ChainReader, headers []*types.H
|
|||
SyncInfo workflow
|
||||
*/
|
||||
// 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
|
||||
2. Verify items including:
|
||||
|
|
@ -547,7 +547,7 @@ func (x *XDPoS_v2) VerifySyncInfoMessage(chain consensus.ChainReader, syncInfo *
|
|||
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()
|
||||
defer x.lock.Unlock()
|
||||
/*
|
||||
|
|
@ -564,7 +564,7 @@ func (x *XDPoS_v2) SyncInfoHandler(chain consensus.ChainReader, syncInfo *utils.
|
|||
/*
|
||||
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)
|
||||
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 {
|
||||
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,
|
||||
GapNumber: vote.GapNumber,
|
||||
}), 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
|
||||
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()
|
||||
defer x.lock.Unlock()
|
||||
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)
|
||||
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)
|
||||
if err != nil {
|
||||
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")
|
||||
}
|
||||
|
||||
verified, _, err := x.verifyMsgSignature(utils.TimeoutSigHash(&utils.TimeoutForSign{
|
||||
verified, _, err := x.verifyMsgSignature(types.TimeoutSigHash(&types.TimeoutForSign{
|
||||
Round: timeoutMsg.Round,
|
||||
GapNumber: timeoutMsg.GapNumber,
|
||||
}), timeoutMsg.Signature, snap.NextEpochMasterNodes)
|
||||
|
|
@ -638,7 +638,7 @@ func (x *XDPoS_v2) VerifyTimeoutMessage(chain consensus.ChainReader, timeoutMsg
|
|||
2. Collect timeout
|
||||
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()
|
||||
defer x.lock.Unlock()
|
||||
return x.timeoutHandler(blockChainReader, timeout)
|
||||
|
|
@ -665,7 +665,7 @@ func (x *XDPoS_v2) ProposedBlockHandler(chain consensus.ChainReader, blockHeader
|
|||
}
|
||||
|
||||
// Generate blockInfo
|
||||
blockInfo := &utils.BlockInfo{
|
||||
blockInfo := &types.BlockInfo{
|
||||
Hash: blockHeader.Hash(),
|
||||
Round: round,
|
||||
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)
|
||||
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
|
||||
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
|
||||
}
|
||||
|
||||
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
|
||||
2. Get epoch master node list by hash
|
||||
|
|
@ -783,9 +783,9 @@ func (x *XDPoS_v2) verifyQC(blockChainReader consensus.ChainReader, quorumCert *
|
|||
var haveError error
|
||||
|
||||
for _, signature := range signatures {
|
||||
go func(sig utils.Signature) {
|
||||
go func(sig types.Signature) {
|
||||
defer wg.Done()
|
||||
verified, _, err := x.verifyMsgSignature(utils.VoteSigHash(&utils.VoteForSign{
|
||||
verified, _, err := x.verifyMsgSignature(types.VoteSigHash(&types.VoteForSign{
|
||||
ProposedBlockInfo: quorumCert.ProposedBlockInfo,
|
||||
GapNumber: quorumCert.GapNumber,
|
||||
}), 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
|
||||
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)
|
||||
// 1. Update HighestQC
|
||||
if incomingQuorumCert.ProposedBlockInfo.Round > x.highestQuorumCert.ProposedBlockInfo.Round {
|
||||
|
|
@ -863,7 +863,7 @@ func (x *XDPoS_v2) processQC(blockChainReader consensus.ChainReader, incomingQuo
|
|||
2. Reset timer
|
||||
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.timeoutCount = 0
|
||||
//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 {
|
||||
return &utils.SyncInfo{
|
||||
func (x *XDPoS_v2) getSyncInfo() *types.SyncInfo {
|
||||
return &types.SyncInfo{
|
||||
HighestQuorumCert: x.highestQuorumCert,
|
||||
HighestTimeoutCert: x.highestTimeoutCert,
|
||||
}
|
||||
}
|
||||
|
||||
//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
|
||||
if big.NewInt(0).Sub(proposedBlockHeader.Number, big.NewInt(2)).Cmp(x.config.V2.SwitchBlock) <= 0 {
|
||||
return false, nil
|
||||
|
|
@ -918,7 +918,7 @@ func (x *XDPoS_v2) commitBlocks(blockChainReader consensus.ChainReader, proposed
|
|||
}
|
||||
// Commit the grandParent block
|
||||
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,
|
||||
Hash: grandParentBlock.Hash(),
|
||||
Round: round,
|
||||
|
|
|
|||
|
|
@ -6,13 +6,12 @@ import (
|
|||
|
||||
"github.com/XinFinOrg/XDPoSChain/common"
|
||||
"github.com/XinFinOrg/XDPoSChain/consensus"
|
||||
"github.com/XinFinOrg/XDPoSChain/consensus/XDPoS/utils"
|
||||
"github.com/XinFinOrg/XDPoSChain/core/types"
|
||||
"github.com/XinFinOrg/XDPoSChain/log"
|
||||
)
|
||||
|
||||
// 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)
|
||||
if err != nil {
|
||||
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,
|
||||
// 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)
|
||||
if ok {
|
||||
log.Debug("[getEpochSwitchInfo] cache hit", "hash", hash.Hex())
|
||||
epochSwitchInfo := e.(*utils.EpochSwitchInfo)
|
||||
epochSwitchInfo := e.(*types.EpochSwitchInfo)
|
||||
return epochSwitchInfo, nil
|
||||
}
|
||||
h := header
|
||||
|
|
@ -56,9 +55,9 @@ func (x *XDPoS_v2) getEpochSwitchInfo(chain consensus.ChainReader, header *types
|
|||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
epochSwitchInfo := &utils.EpochSwitchInfo{
|
||||
epochSwitchInfo := &types.EpochSwitchInfo{
|
||||
Masternodes: masternodes,
|
||||
EpochSwitchBlockInfo: &utils.BlockInfo{
|
||||
EpochSwitchBlockInfo: &types.BlockInfo{
|
||||
Hash: hash,
|
||||
Number: h.Number,
|
||||
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
|
||||
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
|
||||
// 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 {
|
||||
|
|
@ -99,7 +98,7 @@ func (x *XDPoS_v2) isEpochSwitchAtRound(round utils.Round, parentHeader *types.H
|
|||
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
|
||||
}
|
||||
|
||||
|
|
@ -129,7 +128,7 @@ func (x *XDPoS_v2) IsEpochSwitch(header *types.Header) (bool, uint64, error) {
|
|||
return false, 0, err
|
||||
}
|
||||
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
|
||||
// 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 {
|
||||
|
|
|
|||
|
|
@ -19,7 +19,7 @@ const (
|
|||
|
||||
type ForensicsInfo struct {
|
||||
HashPath []string // HashesTillSmallerRoundQc or HashesTillLargerRoundQc
|
||||
QuorumCert utils.QuorumCert
|
||||
QuorumCert types.QuorumCert
|
||||
SignerAddresses []string
|
||||
}
|
||||
|
||||
|
|
@ -32,7 +32,7 @@ type ForensicProof struct {
|
|||
|
||||
// Forensics instance. Placeholder for future properties to be added
|
||||
type Forensics struct {
|
||||
HighestCommittedQCs []utils.QuorumCert
|
||||
HighestCommittedQCs []types.QuorumCert
|
||||
}
|
||||
|
||||
// Initiate a forensics process
|
||||
|
|
@ -40,22 +40,22 @@ func NewForensics() *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)
|
||||
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]
|
||||
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.
|
||||
if len(headers) != NUM_OF_FORENSICS_QC-1 {
|
||||
log.Error("[SetCommittedQcs] Received input length not equal to 2", len(headers))
|
||||
return fmt.Errorf("Received headers length not equal to 2 ")
|
||||
}
|
||||
|
||||
var committedQCs []utils.QuorumCert
|
||||
var committedQCs []types.QuorumCert
|
||||
for i, h := range headers {
|
||||
var decodedExtraField utils.ExtraFields_v2
|
||||
var decodedExtraField types.ExtraFields_v2
|
||||
// Decode the qc1 and qc2
|
||||
err := utils.DecodeBytesExtraFields(h.Extra, &decodedExtraField)
|
||||
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
|
||||
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)
|
||||
// Clone the values to a temporary variable
|
||||
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.
|
||||
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.
|
||||
lowerRoundQC := firstQc
|
||||
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
|
||||
func (f *Forensics) findAncestorQCs(chain consensus.ChainReader, currentQc utils.QuorumCert, distanceFromCurrrentQc int) ([]utils.QuorumCert, error) {
|
||||
var quorumCerts []utils.QuorumCert
|
||||
func (f *Forensics) findAncestorQCs(chain consensus.ChainReader, currentQc types.QuorumCert, distanceFromCurrrentQc int) ([]types.QuorumCert, error) {
|
||||
var quorumCerts []types.QuorumCert
|
||||
quorumCertificate := currentQc
|
||||
// Append the initial value
|
||||
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())
|
||||
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)
|
||||
if err != nil {
|
||||
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)
|
||||
}
|
||||
// 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-- {
|
||||
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
|
||||
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
|
||||
lowerBlockNumQCs := highestCommittedQCs
|
||||
higherBlockNumQCs := incomingQCandItsParents
|
||||
|
|
@ -214,7 +214,7 @@ func (f *Forensics) checkQCsOnTheSameChain(chain consensus.ChainReader, highestC
|
|||
proposedBlockInfo := higherBlockNumQCs[0].ProposedBlockInfo
|
||||
for i := 0; i < int((big.NewInt(0).Sub(higherBlockNumQCs[0].ProposedBlockInfo.Number, lowerBlockNumQCs[0].ProposedBlockInfo.Number)).Int64()); i++ {
|
||||
parentHeader := chain.GetHeaderByHash(proposedBlockInfo.Hash)
|
||||
var decodedExtraField utils.ExtraFields_v2
|
||||
var decodedExtraField types.ExtraFields_v2
|
||||
err := utils.DecodeBytesExtraFields(parentHeader.Extra, &decodedExtraField)
|
||||
if err != nil {
|
||||
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
|
||||
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 _, quorumCert2 := range quorumCerts2 {
|
||||
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
|
||||
func (f *Forensics) getQcSignerAddresses(quorumCert utils.QuorumCert) []string {
|
||||
func (f *Forensics) getQcSignerAddresses(quorumCert types.QuorumCert) []string {
|
||||
var signerList []string
|
||||
|
||||
// The QC signatures are signed by votes special struct VoteForSign
|
||||
quorumCertSignedHash := utils.VoteSigHash(&utils.VoteForSign{
|
||||
quorumCertSignedHash := types.VoteSigHash(&types.VoteForSign{
|
||||
ProposedBlockInfo: quorumCert.ProposedBlockInfo,
|
||||
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
|
||||
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
|
||||
*/
|
||||
|
|
@ -280,7 +280,7 @@ func (f *Forensics) findAncestorQcThroughRound(chain consensus.ChainReader, high
|
|||
ancestorQC := higherRoundQCs[0]
|
||||
for ancestorQC.ProposedBlockInfo.Round >= lowerRoundQCs[NUM_OF_FORENSICS_QC-1].ProposedBlockInfo.Round {
|
||||
proposedBlock := chain.GetHeaderByHash(ancestorQC.ProposedBlockInfo.Hash)
|
||||
var decodedExtraField utils.ExtraFields_v2
|
||||
var decodedExtraField types.ExtraFields_v2
|
||||
err := utils.DecodeBytesExtraFields(proposedBlock.Extra, &decodedExtraField)
|
||||
if err != nil {
|
||||
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")
|
||||
}
|
||||
|
||||
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
|
||||
lowerBlockNumHash := firstBlockInfo.Hash
|
||||
higherBlockNumberHash := secondBlockInfo.Hash
|
||||
|
|
|
|||
|
|
@ -12,7 +12,7 @@ import (
|
|||
"github.com/XinFinOrg/XDPoSChain/accounts"
|
||||
"github.com/XinFinOrg/XDPoSChain/accounts/keystore"
|
||||
"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/stretchr/testify/assert"
|
||||
)
|
||||
|
|
@ -72,69 +72,69 @@ func TestFindQCsInSameRound(t *testing.T) {
|
|||
gapNumber := 450
|
||||
|
||||
// If ONE in common
|
||||
var sig []utils.Signature
|
||||
qc1 := &utils.QuorumCert{
|
||||
ProposedBlockInfo: &utils.BlockInfo{
|
||||
var sig []types.Signature
|
||||
qc1 := &types.QuorumCert{
|
||||
ProposedBlockInfo: &types.BlockInfo{
|
||||
Hash: common.StringToHash("qc1"),
|
||||
Round: utils.Round(10),
|
||||
Round: types.Round(10),
|
||||
Number: big.NewInt(910),
|
||||
},
|
||||
Signatures: sig,
|
||||
GapNumber: uint64(gapNumber),
|
||||
}
|
||||
|
||||
qc2 := &utils.QuorumCert{
|
||||
ProposedBlockInfo: &utils.BlockInfo{
|
||||
qc2 := &types.QuorumCert{
|
||||
ProposedBlockInfo: &types.BlockInfo{
|
||||
Hash: common.StringToHash("qc2"),
|
||||
Round: utils.Round(12),
|
||||
Round: types.Round(12),
|
||||
Number: big.NewInt(910),
|
||||
},
|
||||
Signatures: sig,
|
||||
GapNumber: uint64(gapNumber),
|
||||
}
|
||||
|
||||
qc3 := &utils.QuorumCert{
|
||||
ProposedBlockInfo: &utils.BlockInfo{
|
||||
qc3 := &types.QuorumCert{
|
||||
ProposedBlockInfo: &types.BlockInfo{
|
||||
Hash: common.StringToHash("qc3"),
|
||||
Round: utils.Round(13),
|
||||
Round: types.Round(13),
|
||||
Number: big.NewInt(910),
|
||||
},
|
||||
Signatures: sig,
|
||||
GapNumber: uint64(gapNumber),
|
||||
}
|
||||
|
||||
qc4 := &utils.QuorumCert{
|
||||
ProposedBlockInfo: &utils.BlockInfo{
|
||||
qc4 := &types.QuorumCert{
|
||||
ProposedBlockInfo: &types.BlockInfo{
|
||||
Hash: common.StringToHash("qc4"),
|
||||
Round: utils.Round(12),
|
||||
Round: types.Round(12),
|
||||
Number: big.NewInt(910),
|
||||
},
|
||||
Signatures: sig,
|
||||
GapNumber: uint64(gapNumber),
|
||||
}
|
||||
|
||||
qc5 := &utils.QuorumCert{
|
||||
ProposedBlockInfo: &utils.BlockInfo{
|
||||
qc5 := &types.QuorumCert{
|
||||
ProposedBlockInfo: &types.BlockInfo{
|
||||
Hash: common.StringToHash("qc5"),
|
||||
Round: utils.Round(13),
|
||||
Round: types.Round(13),
|
||||
Number: big.NewInt(910),
|
||||
},
|
||||
Signatures: sig,
|
||||
GapNumber: uint64(gapNumber),
|
||||
}
|
||||
|
||||
qc6 := &utils.QuorumCert{
|
||||
ProposedBlockInfo: &utils.BlockInfo{
|
||||
qc6 := &types.QuorumCert{
|
||||
ProposedBlockInfo: &types.BlockInfo{
|
||||
Hash: common.StringToHash("qc6"),
|
||||
Round: utils.Round(15),
|
||||
Round: types.Round(15),
|
||||
Number: big.NewInt(910),
|
||||
},
|
||||
Signatures: sig,
|
||||
GapNumber: uint64(gapNumber),
|
||||
}
|
||||
|
||||
var qcSet1 []utils.QuorumCert
|
||||
var qcSet2 []utils.QuorumCert
|
||||
var qcSet1 []types.QuorumCert
|
||||
var qcSet2 []types.QuorumCert
|
||||
|
||||
found, first, second := forensics.findQCsInSameRound(append(qcSet1, *qc1, *qc2, *qc3), append(qcSet2, *qc4, *qc5, *qc6))
|
||||
assert.True(t, found)
|
||||
|
|
|
|||
|
|
@ -12,7 +12,7 @@ import (
|
|||
)
|
||||
|
||||
// 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 {
|
||||
log.Warn("[yourturn] Already mined on this round", "Round", round, "highestSelfMinedRound", x.highestSelfMinedRound, "ParentHash", parent.Hash().Hex(), "ParentNumber", parent.Number)
|
||||
return false, utils.ErrAlreadyMined
|
||||
|
|
|
|||
|
|
@ -3,14 +3,14 @@ package engine_v2
|
|||
import (
|
||||
"github.com/XinFinOrg/XDPoSChain/common"
|
||||
"github.com/XinFinOrg/XDPoSChain/consensus"
|
||||
"github.com/XinFinOrg/XDPoSChain/consensus/XDPoS/utils"
|
||||
"github.com/XinFinOrg/XDPoSChain/core/types"
|
||||
)
|
||||
|
||||
/*
|
||||
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()
|
||||
defer x.lock.Unlock()
|
||||
// Reset a bunch of things
|
||||
|
|
@ -21,32 +21,32 @@ func (x *XDPoS_v2) SetNewRoundFaker(blockChainReader consensus.ChainReader, newR
|
|||
}
|
||||
|
||||
// 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()
|
||||
defer x.lock.Unlock()
|
||||
return x.processQC(chain, qc)
|
||||
}
|
||||
|
||||
// Utils for test to check currentRound value
|
||||
func (x *XDPoS_v2) GetCurrentRoundFaker() utils.Round {
|
||||
func (x *XDPoS_v2) GetCurrentRoundFaker() types.Round {
|
||||
x.lock.RLock()
|
||||
defer x.lock.RUnlock()
|
||||
return x.currentRound
|
||||
}
|
||||
|
||||
// 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)
|
||||
}
|
||||
|
||||
// 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)
|
||||
}
|
||||
|
||||
// WARN: This function is designed for testing purpose only!
|
||||
// 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()
|
||||
defer x.lock.RUnlock()
|
||||
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!
|
||||
// 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.highestTimeoutCert = highestTC
|
||||
}
|
||||
|
|
|
|||
|
|
@ -10,10 +10,11 @@ import (
|
|||
"github.com/XinFinOrg/XDPoSChain/common"
|
||||
"github.com/XinFinOrg/XDPoSChain/consensus"
|
||||
"github.com/XinFinOrg/XDPoSChain/consensus/XDPoS/utils"
|
||||
"github.com/XinFinOrg/XDPoSChain/core/types"
|
||||
"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
|
||||
if timeout.Round != x.currentRound {
|
||||
return &utils.ErrIncomingMessageRoundNotEqualCurrentRound{
|
||||
|
|
@ -47,13 +48,13 @@ func (x *XDPoS_v2) timeoutHandler(blockChainReader consensus.ChainReader, timeou
|
|||
3. generateSyncInfo()
|
||||
*/
|
||||
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 {
|
||||
signatures = append(signatures, v.(*utils.Timeout).Signature)
|
||||
signatures = append(signatures, v.(*types.Timeout).Signature)
|
||||
}
|
||||
// Genrate TC
|
||||
timeoutCert := &utils.TimeoutCert{
|
||||
Round: currentTimeoutMsg.(*utils.Timeout).Round,
|
||||
timeoutCert := &types.TimeoutCert{
|
||||
Round: currentTimeoutMsg.(*types.Timeout).Round,
|
||||
Signatures: signatures,
|
||||
GapNumber: gapNumber,
|
||||
}
|
||||
|
|
@ -71,7 +72,7 @@ func (x *XDPoS_v2) onTimeoutPoolThresholdReached(blockChainReader consensus.Chai
|
|||
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
|
||||
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))
|
||||
var haveError error
|
||||
|
||||
signedTimeoutObj := utils.TimeoutSigHash(&utils.TimeoutForSign{
|
||||
signedTimeoutObj := types.TimeoutSigHash(&types.TimeoutForSign{
|
||||
Round: timeoutCert.Round,
|
||||
GapNumber: timeoutCert.GapNumber,
|
||||
})
|
||||
|
||||
for _, signature := range timeoutCert.Signatures {
|
||||
go func(sig utils.Signature) {
|
||||
go func(sig types.Signature) {
|
||||
defer wg.Done()
|
||||
verified, _, err := x.verifyMsgSignature(signedTimeoutObj, sig, snap.NextEpochMasterNodes)
|
||||
if err != nil {
|
||||
|
|
@ -134,7 +135,7 @@ func (x *XDPoS_v2) verifyTC(chain consensus.ChainReader, timeoutCert *utils.Time
|
|||
1. Update highestTC
|
||||
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 {
|
||||
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)
|
||||
}
|
||||
|
||||
signedHash, err := x.signSignature(utils.TimeoutSigHash(&utils.TimeoutForSign{
|
||||
signedHash, err := x.signSignature(types.TimeoutSigHash(&types.TimeoutForSign{
|
||||
Round: x.currentRound,
|
||||
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)
|
||||
return err
|
||||
}
|
||||
timeoutMsg := &utils.Timeout{
|
||||
timeoutMsg := &types.Timeout{
|
||||
Round: x.currentRound,
|
||||
Signature: signedHash,
|
||||
GapNumber: gapNumber,
|
||||
|
|
|
|||
|
|
@ -72,10 +72,10 @@ func decodeMasternodesFromHeaderExtra(checkpointHeader *types.Header) []common.A
|
|||
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)
|
||||
list := []utils.Signature{}
|
||||
duplicates := []utils.Signature{}
|
||||
list := []types.Signature{}
|
||||
duplicates := []types.Signature{}
|
||||
for _, signature := range signatureSlice {
|
||||
hexOfSig := common.Bytes2Hex(signature)
|
||||
if _, value := keys[hexOfSig]; !value {
|
||||
|
|
@ -88,7 +88,7 @@ func UniqueSignatures(signatureSlice []utils.Signature) ([]utils.Signature, []ut
|
|||
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
|
||||
x.signLock.RLock()
|
||||
signer, signFn := x.signer, x.signFn
|
||||
|
|
@ -101,7 +101,7 @@ func (x *XDPoS_v2) signSignature(signingHash common.Hash) (utils.Signature, erro
|
|||
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
|
||||
if len(masternodes) == 0 {
|
||||
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())
|
||||
}
|
||||
|
||||
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
|
||||
|
||||
// last v1 block
|
||||
if header.Number.Cmp(x.config.V2.SwitchBlock) == 0 {
|
||||
masternodes = decodeMasternodesFromHeaderExtra(header)
|
||||
return nil, utils.Round(0), masternodes, nil
|
||||
return nil, types.Round(0), masternodes, nil
|
||||
}
|
||||
|
||||
// v2 block
|
||||
masternodes = x.GetMasternodesFromEpochSwitchHeader(header)
|
||||
var decodedExtraField utils.ExtraFields_v2
|
||||
var decodedExtraField types.ExtraFields_v2
|
||||
err := utils.DecodeBytesExtraFields(header.Extra, &decodedExtraField)
|
||||
if err != nil {
|
||||
return nil, utils.Round(0), masternodes, err
|
||||
return nil, types.Round(0), masternodes, err
|
||||
}
|
||||
return decodedExtraField.QuorumCert, decodedExtraField.Round, masternodes, nil
|
||||
}
|
||||
|
|
|
|||
|
|
@ -15,7 +15,7 @@ import (
|
|||
)
|
||||
|
||||
// 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
|
||||
// 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
|
||||
|
|
@ -28,7 +28,7 @@ func (x *XDPoS_v2) sendVote(chainReader consensus.ChainReader, blockInfo *utils.
|
|||
}
|
||||
epochSwitchNumber := epochSwitchInfo.EpochSwitchBlockInfo.Number.Uint64()
|
||||
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,
|
||||
GapNumber: gapNumber,
|
||||
}))
|
||||
|
|
@ -38,7 +38,7 @@ func (x *XDPoS_v2) sendVote(chainReader consensus.ChainReader, blockInfo *utils.
|
|||
}
|
||||
|
||||
x.highestVotedRound = x.currentRound
|
||||
voteMsg := &utils.Vote{
|
||||
voteMsg := &types.Vote{
|
||||
ProposedBlockInfo: blockInfo,
|
||||
Signature: signedHash,
|
||||
GapNumber: gapNumber,
|
||||
|
|
@ -53,7 +53,7 @@ func (x *XDPoS_v2) sendVote(chainReader consensus.ChainReader, blockInfo *utils.
|
|||
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
|
||||
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
|
||||
var wg sync.WaitGroup
|
||||
wg.Add(len(pooledVotes))
|
||||
signatureSlice := make([]utils.Signature, len(pooledVotes))
|
||||
signatureSlice := make([]types.Signature, len(pooledVotes))
|
||||
counter := 0
|
||||
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()
|
||||
verified, _, err := x.verifyMsgSignature(utils.VoteSigHash(&utils.VoteForSign{
|
||||
verified, _, err := x.verifyMsgSignature(types.VoteSigHash(&types.VoteForSign{
|
||||
ProposedBlockInfo: v.ProposedBlockInfo,
|
||||
GapNumber: v.GapNumber,
|
||||
}), v.Signature, masternodes)
|
||||
|
|
@ -115,13 +115,13 @@ func (x *XDPoS_v2) onVotePoolThresholdReached(chain consensus.ChainReader, poole
|
|||
} else {
|
||||
signatureSlice[i] = v.Signature
|
||||
}
|
||||
}(h, vote.(*utils.Vote), counter)
|
||||
}(h, vote.(*types.Vote), counter)
|
||||
counter++
|
||||
}
|
||||
wg.Wait()
|
||||
|
||||
// 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 {
|
||||
if len(v) != 0 {
|
||||
validSignatureSlice = append(validSignatureSlice, v)
|
||||
|
|
@ -134,10 +134,10 @@ func (x *XDPoS_v2) onVotePoolThresholdReached(chain consensus.ChainReader, poole
|
|||
return nil
|
||||
}
|
||||
// Genrate QC
|
||||
quorumCert := &utils.QuorumCert{
|
||||
ProposedBlockInfo: currentVoteMsg.(*utils.Vote).ProposedBlockInfo,
|
||||
quorumCert := &types.QuorumCert{
|
||||
ProposedBlockInfo: currentVoteMsg.(*types.Vote).ProposedBlockInfo,
|
||||
Signatures: validSignatureSlice,
|
||||
GapNumber: currentVoteMsg.(*utils.Vote).GapNumber,
|
||||
GapNumber: currentVoteMsg.(*types.Vote).GapNumber,
|
||||
}
|
||||
err := x.processQC(chain, quorumCert)
|
||||
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
|
||||
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.
|
||||
if x.currentRound <= x.highestVotedRound {
|
||||
return false, nil
|
||||
|
|
@ -183,7 +183,7 @@ func (x *XDPoS_v2) verifyVotingRule(blockChainReader consensus.ChainReader, bloc
|
|||
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())
|
||||
|
||||
nextBlockHash := currentBlock.Hash
|
||||
|
|
|
|||
|
|
@ -3,6 +3,8 @@ package utils
|
|||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
|
||||
"github.com/XinFinOrg/XDPoSChain/core/types"
|
||||
)
|
||||
|
||||
// Various error messages to mark blocks invalid. These should be private to
|
||||
|
|
@ -98,8 +100,8 @@ var (
|
|||
|
||||
type ErrIncomingMessageRoundNotEqualCurrentRound struct {
|
||||
Type string
|
||||
IncomingRound Round
|
||||
CurrentRound Round
|
||||
IncomingRound types.Round
|
||||
CurrentRound types.Round
|
||||
}
|
||||
|
||||
func (e *ErrIncomingMessageRoundNotEqualCurrentRound) Error() string {
|
||||
|
|
@ -108,8 +110,8 @@ func (e *ErrIncomingMessageRoundNotEqualCurrentRound) Error() string {
|
|||
|
||||
type ErrIncomingMessageRoundTooFarFromCurrentRound struct {
|
||||
Type string
|
||||
IncomingRound Round
|
||||
CurrentRound Round
|
||||
IncomingRound types.Round
|
||||
CurrentRound types.Round
|
||||
}
|
||||
|
||||
func (e *ErrIncomingMessageRoundTooFarFromCurrentRound) Error() string {
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@ package utils
|
|||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/XinFinOrg/XDPoSChain/core/types"
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
|
|
@ -10,10 +11,10 @@ func TestPoolAdd(t *testing.T) {
|
|||
assert := assert.New(t)
|
||||
|
||||
pool := NewPool(2) // 2 is the cert threshold
|
||||
timeout1 := Timeout{Round: 1, Signature: []byte{1}}
|
||||
timeout2 := Timeout{Round: 1, Signature: []byte{2}}
|
||||
timeout3 := Timeout{Round: 1, Signature: []byte{3}}
|
||||
timeout4 := Timeout{Round: 1, Signature: []byte{4}}
|
||||
timeout1 := types.Timeout{Round: 1, Signature: []byte{1}}
|
||||
timeout2 := types.Timeout{Round: 1, Signature: []byte{2}}
|
||||
timeout3 := types.Timeout{Round: 1, Signature: []byte{3}}
|
||||
timeout4 := types.Timeout{Round: 1, Signature: []byte{4}}
|
||||
thresholdReached, numOfItems, pooledTimeouts := pool.Add(&timeout1)
|
||||
assert.NotNil(pooledTimeouts)
|
||||
assert.Equal(1, numOfItems)
|
||||
|
|
|
|||
|
|
@ -1,7 +1,6 @@
|
|||
package utils
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"math/big"
|
||||
"time"
|
||||
|
||||
|
|
@ -12,9 +11,6 @@ import (
|
|||
"github.com/XinFinOrg/XDPoSChain/consensus/clique"
|
||||
"github.com/XinFinOrg/XDPoSChain/core/state"
|
||||
"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"
|
||||
)
|
||||
|
||||
|
|
@ -61,121 +57,3 @@ type PublicApiSnapshot struct {
|
|||
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
|
||||
}
|
||||
|
||||
// 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)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -8,6 +8,7 @@ import (
|
|||
"strconv"
|
||||
|
||||
"github.com/XinFinOrg/XDPoSChain/common"
|
||||
"github.com/XinFinOrg/XDPoSChain/crypto/sha3"
|
||||
"github.com/XinFinOrg/XDPoSChain/log"
|
||||
"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])
|
||||
}
|
||||
}
|
||||
|
||||
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
|
||||
}
|
||||
|
|
|
|||
|
|
@ -7,7 +7,6 @@ import (
|
|||
|
||||
"github.com/XinFinOrg/XDPoSChain/common"
|
||||
"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/stretchr/testify/assert"
|
||||
|
|
@ -88,17 +87,17 @@ func TestAdaptorIsEpochSwitch(t *testing.T) {
|
|||
assert.Nil(t, err)
|
||||
assert.False(t, isEpochSwitchBlock, "header should not be epoch switch", header)
|
||||
// v2
|
||||
parentBlockInfo := &utils.BlockInfo{
|
||||
parentBlockInfo := &types.BlockInfo{
|
||||
Hash: header.ParentHash,
|
||||
Round: utils.Round(0),
|
||||
Round: types.Round(0),
|
||||
Number: big.NewInt(0).Set(blockchain.Config().XDPoS.V2.SwitchBlock),
|
||||
}
|
||||
quorumCert := &utils.QuorumCert{
|
||||
quorumCert := &types.QuorumCert{
|
||||
ProposedBlockInfo: parentBlockInfo,
|
||||
Signatures: nil,
|
||||
GapNumber: blockchain.Config().XDPoS.V2.SwitchBlock.Uint64() - blockchain.Config().XDPoS.Gap,
|
||||
}
|
||||
extra := utils.ExtraFields_v2{
|
||||
extra := types.ExtraFields_v2{
|
||||
Round: 1,
|
||||
QuorumCert: quorumCert,
|
||||
}
|
||||
|
|
@ -109,17 +108,17 @@ func TestAdaptorIsEpochSwitch(t *testing.T) {
|
|||
isEpochSwitchBlock, _, err = adaptor.IsEpochSwitch(header)
|
||||
assert.Nil(t, err)
|
||||
assert.True(t, isEpochSwitchBlock, "header should be epoch switch", header)
|
||||
parentBlockInfo = &utils.BlockInfo{
|
||||
parentBlockInfo = &types.BlockInfo{
|
||||
Hash: header.ParentHash,
|
||||
Round: utils.Round(1),
|
||||
Round: types.Round(1),
|
||||
Number: big.NewInt(0).Add(blockchain.Config().XDPoS.V2.SwitchBlock, big.NewInt(1)),
|
||||
}
|
||||
quorumCert = &utils.QuorumCert{
|
||||
quorumCert = &types.QuorumCert{
|
||||
ProposedBlockInfo: parentBlockInfo,
|
||||
Signatures: nil,
|
||||
GapNumber: blockchain.Config().XDPoS.V2.SwitchBlock.Uint64() - blockchain.Config().XDPoS.Gap,
|
||||
}
|
||||
extra = utils.ExtraFields_v2{
|
||||
extra = types.ExtraFields_v2{
|
||||
Round: 2,
|
||||
QuorumCert: quorumCert,
|
||||
}
|
||||
|
|
@ -130,18 +129,18 @@ func TestAdaptorIsEpochSwitch(t *testing.T) {
|
|||
isEpochSwitchBlock, _, err = adaptor.IsEpochSwitch(header)
|
||||
assert.Nil(t, err)
|
||||
assert.False(t, isEpochSwitchBlock, "header should not be epoch switch", header)
|
||||
parentBlockInfo = &utils.BlockInfo{
|
||||
parentBlockInfo = &types.BlockInfo{
|
||||
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)),
|
||||
}
|
||||
quorumCert = &utils.QuorumCert{
|
||||
quorumCert = &types.QuorumCert{
|
||||
ProposedBlockInfo: parentBlockInfo,
|
||||
Signatures: nil,
|
||||
GapNumber: blockchain.Config().XDPoS.V2.SwitchBlock.Uint64() - blockchain.Config().XDPoS.Gap,
|
||||
}
|
||||
extra = utils.ExtraFields_v2{
|
||||
Round: utils.Round(blockchain.Config().XDPoS.Epoch) + 1,
|
||||
extra = types.ExtraFields_v2{
|
||||
Round: types.Round(blockchain.Config().XDPoS.Epoch) + 1,
|
||||
QuorumCert: quorumCert,
|
||||
}
|
||||
extraBytes, err = extra.EncodeToBytes()
|
||||
|
|
@ -151,18 +150,18 @@ func TestAdaptorIsEpochSwitch(t *testing.T) {
|
|||
isEpochSwitchBlock, _, err = adaptor.IsEpochSwitch(header)
|
||||
assert.Nil(t, err)
|
||||
assert.True(t, isEpochSwitchBlock, "header should be epoch switch", header)
|
||||
parentBlockInfo = &utils.BlockInfo{
|
||||
parentBlockInfo = &types.BlockInfo{
|
||||
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)),
|
||||
}
|
||||
quorumCert = &utils.QuorumCert{
|
||||
quorumCert = &types.QuorumCert{
|
||||
ProposedBlockInfo: parentBlockInfo,
|
||||
Signatures: nil,
|
||||
GapNumber: blockchain.Config().XDPoS.V2.SwitchBlock.Uint64() - blockchain.Config().XDPoS.Gap,
|
||||
}
|
||||
extra = utils.ExtraFields_v2{
|
||||
Round: utils.Round(blockchain.Config().XDPoS.Epoch) + 2,
|
||||
extra = types.ExtraFields_v2{
|
||||
Round: types.Round(blockchain.Config().XDPoS.Epoch) + 2,
|
||||
QuorumCert: quorumCert,
|
||||
}
|
||||
extraBytes, err = extra.EncodeToBytes()
|
||||
|
|
|
|||
|
|
@ -20,23 +20,23 @@ func TestProcessQcShallSetForensicsCommittedQc(t *testing.T) {
|
|||
engineV2 := blockchain.Engine().(*XDPoS.XDPoS).EngineV2
|
||||
|
||||
// Assuming we are getting block 906 which have QC pointing at block 905
|
||||
blockInfo := &utils.BlockInfo{
|
||||
blockInfo := &types.BlockInfo{
|
||||
Hash: currentBlock.Hash(),
|
||||
Round: utils.Round(5),
|
||||
Round: types.Round(5),
|
||||
Number: big.NewInt(905),
|
||||
}
|
||||
voteForSign := &utils.VoteForSign{
|
||||
voteForSign := &types.VoteForSign{
|
||||
ProposedBlockInfo: blockInfo,
|
||||
GapNumber: 450,
|
||||
}
|
||||
voteSigningHash := utils.VoteSigHash(voteForSign)
|
||||
voteSigningHash := types.VoteSigHash(voteForSign)
|
||||
|
||||
// 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
|
||||
signedHash, err := signFn(accounts.Account{Address: signer}, voteSigningHash.Bytes())
|
||||
assert.Nil(t, err)
|
||||
voteMsg := &utils.Vote{
|
||||
voteMsg := &types.Vote{
|
||||
ProposedBlockInfo: blockInfo,
|
||||
Signature: signedHash,
|
||||
GapNumber: 450,
|
||||
|
|
@ -45,7 +45,7 @@ func TestProcessQcShallSetForensicsCommittedQc(t *testing.T) {
|
|||
err = engineV2.VoteHandler(blockchain, voteMsg)
|
||||
assert.Nil(t, err)
|
||||
signedHash = SignHashByPK(acc1Key, voteSigningHash.Bytes())
|
||||
voteMsg = &utils.Vote{
|
||||
voteMsg = &types.Vote{
|
||||
ProposedBlockInfo: blockInfo,
|
||||
Signature: signedHash,
|
||||
GapNumber: 450,
|
||||
|
|
@ -58,7 +58,7 @@ func TestProcessQcShallSetForensicsCommittedQc(t *testing.T) {
|
|||
assert.Nil(t, err)
|
||||
randomlySignedHash, err := randomSignFn(accounts.Account{Address: randomSigner}, voteSigningHash.Bytes())
|
||||
assert.Nil(t, err)
|
||||
voteMsg = &utils.Vote{
|
||||
voteMsg = &types.Vote{
|
||||
ProposedBlockInfo: blockInfo,
|
||||
Signature: randomlySignedHash,
|
||||
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
|
||||
signedHash = SignHashByPK(acc3Key, voteSigningHash.Bytes())
|
||||
voteMsg = &utils.Vote{
|
||||
voteMsg = &types.Vote{
|
||||
ProposedBlockInfo: blockInfo,
|
||||
Signature: signedHash,
|
||||
GapNumber: 450,
|
||||
|
|
@ -86,7 +86,7 @@ func TestSetCommittedQCsInOrder(t *testing.T) {
|
|||
forensics := blockchain.Engine().(*XDPoS.XDPoS).EngineV2.GetForensicsFaker()
|
||||
|
||||
var headers []types.Header
|
||||
var decodedExtraField utils.ExtraFields_v2
|
||||
var decodedExtraField types.ExtraFields_v2
|
||||
// Decode the qc1 and qc2
|
||||
err := utils.DecodeBytesExtraFields(currentBlock.Header().Extra, &decodedExtraField)
|
||||
assert.Nil(t, err)
|
||||
|
|
@ -110,14 +110,14 @@ func TestSetCommittedQCsInOrder(t *testing.T) {
|
|||
func TestForensicsMonitoring(t *testing.T) {
|
||||
blockchain, _, currentBlock, _, _, _ := PrepareXDCTestBlockChainForV2Engine(t, 915, params.TestXDPoSMockChainConfig, nil)
|
||||
forensics := blockchain.Engine().(*XDPoS.XDPoS).EngineV2.GetForensicsFaker()
|
||||
var decodedCurrentblockExtraField utils.ExtraFields_v2
|
||||
var decodedCurrentblockExtraField types.ExtraFields_v2
|
||||
// Decode the QC from latest block
|
||||
err := utils.DecodeBytesExtraFields(currentBlock.Header().Extra, &decodedCurrentblockExtraField)
|
||||
assert.Nil(t, err)
|
||||
incomingQC := decodedCurrentblockExtraField.QuorumCert
|
||||
// Now, let's try set committed blocks, where the highestedCommitted blocks are 905, 906 and 907
|
||||
var headers []types.Header
|
||||
var decodedBlock905ExtraField utils.ExtraFields_v2
|
||||
var decodedBlock905ExtraField types.ExtraFields_v2
|
||||
err = utils.DecodeBytesExtraFields(blockchain.GetHeaderByNumber(905).Extra, &decodedBlock905ExtraField)
|
||||
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
|
||||
var headers []types.Header
|
||||
var decodedBlock915ExtraField utils.ExtraFields_v2
|
||||
var decodedBlock915ExtraField types.ExtraFields_v2
|
||||
err := utils.DecodeBytesExtraFields(blockchain.GetHeaderByNumber(915).Extra, &decodedBlock915ExtraField)
|
||||
assert.Nil(t, err)
|
||||
err = forensics.SetCommittedQCs(append(headers, *blockchain.GetHeaderByNumber(913), *blockchain.GetHeaderByNumber(914)), *decodedBlock915ExtraField.QuorumCert)
|
||||
assert.Nil(t, err)
|
||||
|
||||
var decodedExtraField utils.ExtraFields_v2
|
||||
var decodedExtraField types.ExtraFields_v2
|
||||
// Decode the QC from forking chain
|
||||
err = utils.DecodeBytesExtraFields(currentForkBlock.Header().Extra, &decodedExtraField)
|
||||
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
|
||||
var headers []types.Header
|
||||
var decodedBlock915ExtraField utils.ExtraFields_v2
|
||||
var decodedBlock915ExtraField types.ExtraFields_v2
|
||||
err := utils.DecodeBytesExtraFields(blockchain.GetHeaderByNumber(915).Extra, &decodedBlock915ExtraField)
|
||||
assert.Nil(t, err)
|
||||
err = forensics.SetCommittedQCs(append(headers, *blockchain.GetHeaderByNumber(913), *blockchain.GetHeaderByNumber(914)), *decodedBlock915ExtraField.QuorumCert)
|
||||
assert.Nil(t, err)
|
||||
|
||||
var decodedExtraField utils.ExtraFields_v2
|
||||
var decodedExtraField types.ExtraFields_v2
|
||||
// Decode the QC from forking chain
|
||||
err = utils.DecodeBytesExtraFields(currentForkBlock.Header().Extra, &decodedExtraField)
|
||||
assert.Nil(t, err)
|
||||
|
|
|
|||
|
|
@ -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 header.Number.Cmp(config.XDPoS.V2.SwitchBlock) > 0 {
|
||||
var decodedExtraField utils.ExtraFields_v2
|
||||
var decodedExtraField types.ExtraFields_v2
|
||||
err := utils.DecodeBytesExtraFields(header.Extra, &decodedExtraField)
|
||||
if err != nil {
|
||||
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 {
|
||||
var extraField utils.ExtraFields_v2
|
||||
var round utils.Round
|
||||
var extraField types.ExtraFields_v2
|
||||
var round types.Round
|
||||
err := utils.DecodeBytesExtraFields(currentBlock.Extra(), &extraField)
|
||||
if err != nil {
|
||||
round = utils.Round(0)
|
||||
round = types.Round(0)
|
||||
} else {
|
||||
round = extraField.Round
|
||||
}
|
||||
|
||||
proposedBlockInfo := &utils.BlockInfo{
|
||||
proposedBlockInfo := &types.BlockInfo{
|
||||
Hash: currentBlock.Hash(),
|
||||
Round: round,
|
||||
Number: currentBlock.Number(),
|
||||
}
|
||||
gapNumber := currentBlock.Number().Uint64() - currentBlock.Number().Uint64()%params.TestXDPoSMockChainConfig.XDPoS.Epoch - params.TestXDPoSMockChainConfig.XDPoS.Gap
|
||||
voteForSign := &utils.VoteForSign{
|
||||
voteForSign := &types.VoteForSign{
|
||||
ProposedBlockInfo: proposedBlockInfo,
|
||||
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 {
|
||||
panic(fmt.Errorf("Error generate QC by creating signedHash: %v", err))
|
||||
}
|
||||
var signatures []utils.Signature
|
||||
var signatures []types.Signature
|
||||
if len(accKeys) == 0 {
|
||||
// Sign from acc 1, 2, 3 by default
|
||||
accKeys = append(accKeys, acc1Key, acc2Key, acc3Key)
|
||||
}
|
||||
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, signedHash)
|
||||
|
||||
quorumCert := &utils.QuorumCert{
|
||||
quorumCert := &types.QuorumCert{
|
||||
ProposedBlockInfo: proposedBlockInfo,
|
||||
Signatures: signatures,
|
||||
GapNumber: gapNumber,
|
||||
}
|
||||
|
||||
extra := utils.ExtraFields_v2{
|
||||
Round: utils.Round(roundNumber),
|
||||
extra := types.ExtraFields_v2{
|
||||
Round: types.Round(roundNumber),
|
||||
QuorumCert: quorumCert,
|
||||
}
|
||||
extraInBytes, err := extra.EncodeToBytes()
|
||||
|
|
|
|||
|
|
@ -6,7 +6,6 @@ import (
|
|||
|
||||
"github.com/XinFinOrg/XDPoSChain/common"
|
||||
"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/stretchr/testify/assert"
|
||||
|
|
@ -25,17 +24,17 @@ func TestInitialFirstV2Blcok(t *testing.T) {
|
|||
assert.Nil(t, err)
|
||||
|
||||
round, _, highQC, _, _, _ := adaptor.EngineV2.GetPropertiesFaker()
|
||||
blockInfo := &utils.BlockInfo{
|
||||
blockInfo := &types.BlockInfo{
|
||||
Hash: header.Hash(),
|
||||
Round: utils.Round(0),
|
||||
Round: types.Round(0),
|
||||
Number: header.Number,
|
||||
}
|
||||
expectedQuorumCert := &utils.QuorumCert{
|
||||
expectedQuorumCert := &types.QuorumCert{
|
||||
ProposedBlockInfo: blockInfo,
|
||||
Signatures: nil,
|
||||
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)
|
||||
|
||||
// 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)
|
||||
timeoutMsg := <-adaptor.EngineV2.BroadcastCh
|
||||
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) {
|
||||
|
|
@ -66,17 +65,17 @@ func TestInitialOtherV2Block(t *testing.T) {
|
|||
}
|
||||
|
||||
// v2
|
||||
blockInfo := &utils.BlockInfo{
|
||||
blockInfo := &types.BlockInfo{
|
||||
Hash: currentBlock.Header().Hash(),
|
||||
Round: utils.Round(10),
|
||||
Round: types.Round(10),
|
||||
Number: big.NewInt(910),
|
||||
}
|
||||
quorumCert := &utils.QuorumCert{
|
||||
quorumCert := &types.QuorumCert{
|
||||
ProposedBlockInfo: blockInfo,
|
||||
Signatures: nil, // after decode it got default value []utils.Signature{}
|
||||
GapNumber: 450,
|
||||
}
|
||||
extra := utils.ExtraFields_v2{
|
||||
extra := types.ExtraFields_v2{
|
||||
Round: 11,
|
||||
QuorumCert: quorumCert,
|
||||
}
|
||||
|
|
@ -102,12 +101,12 @@ func TestInitialOtherV2Block(t *testing.T) {
|
|||
assert.Nil(t, err)
|
||||
|
||||
round, _, highQC, _, _, _ := adaptor.EngineV2.GetPropertiesFaker()
|
||||
expectedQuorumCert := &utils.QuorumCert{
|
||||
expectedQuorumCert := &types.QuorumCert{
|
||||
ProposedBlockInfo: blockInfo,
|
||||
Signatures: []utils.Signature{},
|
||||
Signatures: []types.Signature{},
|
||||
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)
|
||||
|
||||
// Test snapshot
|
||||
|
|
|
|||
|
|
@ -49,7 +49,7 @@ func TestYourTurnInitialV2(t *testing.T) {
|
|||
assert.Nil(t, err)
|
||||
// round=1, so masternode[1] has YourTurn = True
|
||||
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())
|
||||
assert.Nil(t, err)
|
||||
|
|
@ -171,7 +171,7 @@ func TestPrepareFail(t *testing.T) {
|
|||
err = adaptor.Prepare(blockchain, notReadyToMine)
|
||||
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{
|
||||
ParentHash: currentBlock.Hash(),
|
||||
Number: big.NewInt(int64(901)),
|
||||
|
|
@ -201,7 +201,7 @@ func TestPrepareHappyPath(t *testing.T) {
|
|||
Coinbase: signer,
|
||||
}
|
||||
|
||||
adaptor.EngineV2.SetNewRoundFaker(blockchain, utils.Round(4), false)
|
||||
adaptor.EngineV2.SetNewRoundFaker(blockchain, types.Round(4), false)
|
||||
err = adaptor.Prepare(blockchain, header901)
|
||||
assert.Nil(t, err)
|
||||
|
||||
|
|
@ -216,9 +216,9 @@ func TestPrepareHappyPath(t *testing.T) {
|
|||
}
|
||||
assert.Equal(t, validators, header901.Validators)
|
||||
|
||||
var decodedExtraField utils.ExtraFields_v2
|
||||
var decodedExtraField types.ExtraFields_v2
|
||||
err = utils.DecodeBytesExtraFields(header901.Extra, &decodedExtraField)
|
||||
assert.Nil(t, err)
|
||||
assert.Equal(t, utils.Round(4), decodedExtraField.Round)
|
||||
assert.Equal(t, utils.Round(0), decodedExtraField.QuorumCert.ProposedBlockInfo.Round)
|
||||
assert.Equal(t, types.Round(4), decodedExtraField.Round)
|
||||
assert.Equal(t, types.Round(0), decodedExtraField.QuorumCert.ProposedBlockInfo.Round)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -19,7 +19,7 @@ func TestHookPenaltyV2Mining(t *testing.T) {
|
|||
adaptor := blockchain.Engine().(*XDPoS.XDPoS)
|
||||
hooks.AttachConsensusV2Hooks(adaptor, blockchain, config)
|
||||
assert.NotNil(t, adaptor.EngineV2.HookPenalty)
|
||||
var extraField utils.ExtraFields_v2
|
||||
var extraField types.ExtraFields_v2
|
||||
// 901 is the first v2 block
|
||||
header901 := blockchain.GetHeaderByNumber(config.XDPoS.Epoch + 1)
|
||||
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
|
||||
// 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
|
||||
adaptor.EngineV2.AuthorizeFaker(acc1Addr)
|
||||
err = adaptor.Prepare(blockchain, headerMining)
|
||||
|
|
@ -70,7 +70,7 @@ func TestHookPenaltyV2Comeback(t *testing.T) {
|
|||
adaptor := blockchain.Engine().(*XDPoS.XDPoS)
|
||||
hooks.AttachConsensusV2Hooks(adaptor, blockchain, config)
|
||||
assert.NotNil(t, adaptor.EngineV2.HookPenalty)
|
||||
var extraField utils.ExtraFields_v2
|
||||
var extraField types.ExtraFields_v2
|
||||
// 901 is the first v2 block
|
||||
header901 := blockchain.GetHeaderByNumber(config.XDPoS.Epoch + 1)
|
||||
err := utils.DecodeBytesExtraFields(header901.Extra, &extraField)
|
||||
|
|
@ -99,7 +99,7 @@ func TestHookPenaltyV2Jump(t *testing.T) {
|
|||
adaptor := blockchain.Engine().(*XDPoS.XDPoS)
|
||||
hooks.AttachConsensusV2Hooks(adaptor, blockchain, config)
|
||||
assert.NotNil(t, adaptor.EngineV2.HookPenalty)
|
||||
var extraField utils.ExtraFields_v2
|
||||
var extraField types.ExtraFields_v2
|
||||
// 901 is the first v2 block
|
||||
header901 := blockchain.GetHeaderByNumber(config.XDPoS.Epoch + 1)
|
||||
err := utils.DecodeBytesExtraFields(header901.Extra, &extraField)
|
||||
|
|
@ -107,7 +107,7 @@ func TestHookPenaltyV2Jump(t *testing.T) {
|
|||
masternodes := adaptor.GetMasternodesFromCheckpointHeader(header901)
|
||||
assert.Equal(t, 5, len(masternodes))
|
||||
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
|
||||
penalty, err := adaptor.EngineV2.HookPenalty(blockchain, header2085.Number, header2085.ParentHash, masternodes)
|
||||
assert.Nil(t, err)
|
||||
|
|
|
|||
|
|
@ -8,6 +8,7 @@ import (
|
|||
"github.com/XinFinOrg/XDPoSChain/accounts/abi/bind/backends"
|
||||
"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/stretchr/testify/assert"
|
||||
)
|
||||
|
|
@ -17,7 +18,7 @@ func TestShouldSendVoteMsgAndCommitGrandGrandParentBlock(t *testing.T) {
|
|||
blockchain, _, currentBlock, signer, signFn, _ := PrepareXDCTestBlockChainForV2Engine(t, 901, params.TestXDPoSMockChainConfig, nil)
|
||||
engineV2 := blockchain.Engine().(*XDPoS.XDPoS).EngineV2
|
||||
|
||||
var extraField utils.ExtraFields_v2
|
||||
var extraField types.ExtraFields_v2
|
||||
err := utils.DecodeBytesExtraFields(currentBlock.Extra(), &extraField)
|
||||
if err != nil {
|
||||
t.Fatal("Fail to decode extra data", err)
|
||||
|
|
@ -29,17 +30,17 @@ func TestShouldSendVoteMsgAndCommitGrandGrandParentBlock(t *testing.T) {
|
|||
}
|
||||
|
||||
voteMsg := <-engineV2.BroadcastCh
|
||||
poolSize := engineV2.GetVotePoolSizeFaker(voteMsg.(*utils.Vote))
|
||||
poolSize := engineV2.GetVotePoolSizeFaker(voteMsg.(*types.Vote))
|
||||
|
||||
assert.Equal(t, poolSize, 1)
|
||||
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()
|
||||
// Shoud trigger setNewRound
|
||||
assert.Equal(t, utils.Round(1), round)
|
||||
assert.Equal(t, types.Round(1), round)
|
||||
// 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
|
||||
blockNum := 902
|
||||
|
|
@ -56,8 +57,8 @@ func TestShouldSendVoteMsgAndCommitGrandGrandParentBlock(t *testing.T) {
|
|||
assert.NotNil(t, voteMsg)
|
||||
round, _, highestQC, _, _, _ = engineV2.GetPropertiesFaker()
|
||||
// Shoud trigger setNewRound
|
||||
assert.Equal(t, utils.Round(2), round)
|
||||
assert.Equal(t, utils.Round(1), highestQC.ProposedBlockInfo.Round)
|
||||
assert.Equal(t, types.Round(2), round)
|
||||
assert.Equal(t, types.Round(1), highestQC.ProposedBlockInfo.Round)
|
||||
|
||||
// Insert one more Block, but still won't trigger commit
|
||||
blockNum = 903
|
||||
|
|
@ -74,8 +75,8 @@ func TestShouldSendVoteMsgAndCommitGrandGrandParentBlock(t *testing.T) {
|
|||
assert.NotNil(t, voteMsg)
|
||||
round, _, highestQC, _, _, highestCommitBlock := engineV2.GetPropertiesFaker()
|
||||
// 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, utils.Round(2), highestQC.ProposedBlockInfo.Round)
|
||||
assert.Equal(t, types.Round(3), round)
|
||||
assert.Equal(t, types.Round(2), highestQC.ProposedBlockInfo.Round)
|
||||
assert.Nil(t, highestCommitBlock)
|
||||
|
||||
// Insert one more Block, this time will trigger commit
|
||||
|
|
@ -93,11 +94,11 @@ func TestShouldSendVoteMsgAndCommitGrandGrandParentBlock(t *testing.T) {
|
|||
assert.NotNil(t, voteMsg)
|
||||
round, _, highestQC, _, _, highestCommitBlock = engineV2.GetPropertiesFaker()
|
||||
|
||||
assert.Equal(t, utils.Round(4), round)
|
||||
assert.Equal(t, utils.Round(3), highestQC.ProposedBlockInfo.Round)
|
||||
assert.Equal(t, types.Round(4), round)
|
||||
assert.Equal(t, types.Round(3), highestQC.ProposedBlockInfo.Round)
|
||||
assert.Equal(t, currentBlock.Hash(), highestCommitBlock.Hash)
|
||||
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) {
|
||||
|
|
@ -105,7 +106,7 @@ func TestShouldNotCommitIfRoundsNotContinousFor3Rounds(t *testing.T) {
|
|||
blockchain, _, currentBlock, signer, signFn, _ := PrepareXDCTestBlockChainForV2Engine(t, 905, params.TestXDPoSMockChainConfig, nil)
|
||||
engineV2 := blockchain.Engine().(*XDPoS.XDPoS).EngineV2
|
||||
|
||||
var extraField utils.ExtraFields_v2
|
||||
var extraField types.ExtraFields_v2
|
||||
err := utils.DecodeBytesExtraFields(currentBlock.Extra(), &extraField)
|
||||
if err != nil {
|
||||
t.Fatal("Fail to decode extra data", err)
|
||||
|
|
@ -118,17 +119,17 @@ func TestShouldNotCommitIfRoundsNotContinousFor3Rounds(t *testing.T) {
|
|||
|
||||
voteMsg := <-engineV2.BroadcastCh
|
||||
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()
|
||||
|
||||
grandGrandParentBlock := blockchain.GetBlockByNumber(902)
|
||||
// Shoud trigger setNewRound
|
||||
assert.Equal(t, utils.Round(5), round)
|
||||
assert.Equal(t, utils.Round(4), highestQC.ProposedBlockInfo.Round)
|
||||
assert.Equal(t, types.Round(5), round)
|
||||
assert.Equal(t, types.Round(4), highestQC.ProposedBlockInfo.Round)
|
||||
assert.Equal(t, grandGrandParentBlock.Hash(), highestCommitBlock.Hash)
|
||||
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)
|
||||
blockNum := 906
|
||||
|
|
@ -146,12 +147,12 @@ func TestShouldNotCommitIfRoundsNotContinousFor3Rounds(t *testing.T) {
|
|||
round, _, highestQC, _, _, highestCommitBlock = engineV2.GetPropertiesFaker()
|
||||
grandGrandParentBlock = blockchain.GetBlockByNumber(903)
|
||||
|
||||
assert.Equal(t, utils.Round(6), round)
|
||||
assert.Equal(t, utils.Round(5), highestQC.ProposedBlockInfo.Round)
|
||||
assert.Equal(t, types.Round(6), round)
|
||||
assert.Equal(t, types.Round(5), highestQC.ProposedBlockInfo.Round)
|
||||
// It commit its grandgrandparent block
|
||||
assert.Equal(t, grandGrandParentBlock.Hash(), highestCommitBlock.Hash)
|
||||
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
|
||||
blockCoinBase = fmt.Sprintf("0x111000000000000000000000000000000%03d", blockNum)
|
||||
|
|
@ -167,12 +168,12 @@ func TestShouldNotCommitIfRoundsNotContinousFor3Rounds(t *testing.T) {
|
|||
assert.NotNil(t, voteMsg)
|
||||
round, _, highestQC, _, _, highestCommitBlock = engineV2.GetPropertiesFaker()
|
||||
|
||||
assert.Equal(t, utils.Round(8), round)
|
||||
assert.Equal(t, utils.Round(7), highestQC.ProposedBlockInfo.Round)
|
||||
assert.Equal(t, types.Round(8), round)
|
||||
assert.Equal(t, types.Round(7), highestQC.ProposedBlockInfo.Round)
|
||||
// Should NOT commit, the `grandGrandParentBlock` is still on blockNum 903
|
||||
assert.Equal(t, grandGrandParentBlock.Hash(), highestCommitBlock.Hash)
|
||||
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
|
||||
|
||||
// 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)
|
||||
if err != nil {
|
||||
t.Fatal("Fail to decode extra data", err)
|
||||
|
|
@ -196,11 +197,11 @@ func TestProposedBlockMessageHandlerSuccessfullyGenerateVote(t *testing.T) {
|
|||
|
||||
voteMsg := <-engineV2.BroadcastCh
|
||||
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()
|
||||
// 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)
|
||||
}
|
||||
|
||||
|
|
@ -211,9 +212,9 @@ func TestShouldNotSetNewRound(t *testing.T) {
|
|||
engineV2 := blockchain.Engine().(*XDPoS.XDPoS).EngineV2
|
||||
|
||||
// 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)
|
||||
if err != nil {
|
||||
t.Fatal("Fail to decode extra data", err)
|
||||
|
|
@ -226,7 +227,7 @@ func TestShouldNotSetNewRound(t *testing.T) {
|
|||
|
||||
round, _, highestQC, _, _, _ := engineV2.GetPropertiesFaker()
|
||||
// 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)
|
||||
}
|
||||
|
||||
|
|
@ -235,7 +236,7 @@ func TestShouldNotSendVoteMessageIfAlreadyVoteForThisRound(t *testing.T) {
|
|||
engineV2 := blockchain.Engine().(*XDPoS.XDPoS).EngineV2
|
||||
|
||||
// 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())
|
||||
if err != nil {
|
||||
|
|
@ -244,12 +245,12 @@ func TestShouldNotSendVoteMessageIfAlreadyVoteForThisRound(t *testing.T) {
|
|||
|
||||
voteMsg := <-engineV2.BroadcastCh
|
||||
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()
|
||||
// Shoud trigger setNewRound
|
||||
assert.Equal(t, utils.Round(6), round)
|
||||
assert.Equal(t, utils.Round(6), highestVotedRound)
|
||||
assert.Equal(t, types.Round(6), round)
|
||||
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
|
||||
err = engineV2.ProposedBlockHandler(blockchain, currentBlock.Header())
|
||||
|
|
@ -263,8 +264,8 @@ func TestShouldNotSendVoteMessageIfAlreadyVoteForThisRound(t *testing.T) {
|
|||
case <-time.After(5 * time.Second):
|
||||
// Shoud not trigger setNewRound
|
||||
round, _, _, _, highestVotedRound, _ = engineV2.GetPropertiesFaker()
|
||||
assert.Equal(t, utils.Round(6), round)
|
||||
assert.Equal(t, utils.Round(6), highestVotedRound)
|
||||
assert.Equal(t, types.Round(6), round)
|
||||
assert.Equal(t, types.Round(6), highestVotedRound)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -273,9 +274,9 @@ func TestShouldNotSendVoteMsgIfBlockInfoRoundNotEqualCurrentRound(t *testing.T)
|
|||
engineV2 := blockchain.Engine().(*XDPoS.XDPoS).EngineV2
|
||||
|
||||
// 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)
|
||||
if err != nil {
|
||||
t.Fatal("Fail to decode extra data", err)
|
||||
|
|
@ -292,7 +293,7 @@ func TestShouldNotSendVoteMsgIfBlockInfoRoundNotEqualCurrentRound(t *testing.T)
|
|||
case <-time.After(5 * time.Second):
|
||||
// Shoud not trigger setNewRound
|
||||
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})
|
||||
engineV2 := blockchain.Engine().(*XDPoS.XDPoS).EngineV2
|
||||
|
||||
var extraField utils.ExtraFields_v2
|
||||
var extraField types.ExtraFields_v2
|
||||
err := utils.DecodeBytesExtraFields(forkedBlock.Extra(), &extraField)
|
||||
if err != nil {
|
||||
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
|
||||
err = engineV2.ProposedBlockHandler(blockchain, currentBlock.Header())
|
||||
if err != nil {
|
||||
t.Fatal("Error while handling block 16", err)
|
||||
}
|
||||
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
|
||||
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())
|
||||
if err != nil {
|
||||
t.Fatal("Fail propose proposedBlock handler", err)
|
||||
|
|
@ -336,7 +337,7 @@ func TestShouldNotSendVoteMsgIfBlockNotExtendedFromAncestor(t *testing.T) {
|
|||
case <-time.After(5 * time.Second):
|
||||
// Shoud not trigger setNewRound
|
||||
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)
|
||||
}
|
||||
round, _, _, _, _, _ := engineV2.GetPropertiesFaker()
|
||||
assert.Equal(t, utils.Round(i-900), round)
|
||||
assert.Equal(t, types.Round(i-900), round)
|
||||
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)
|
||||
|
||||
// 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)
|
||||
if err != nil {
|
||||
t.Fatal("Fail to decode extra data", err)
|
||||
|
|
|
|||
|
|
@ -6,6 +6,7 @@ import (
|
|||
|
||||
"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/stretchr/testify/assert"
|
||||
)
|
||||
|
|
@ -15,17 +16,17 @@ func TestSyncInfoShouldSuccessfullyUpdateByQC(t *testing.T) {
|
|||
blockchain, _, currentBlock, _, _, _ := PrepareXDCTestBlockChainForV2Engine(t, 905, params.TestXDPoSMockChainConfig, nil)
|
||||
engineV2 := blockchain.Engine().(*XDPoS.XDPoS).EngineV2
|
||||
|
||||
var extraField utils.ExtraFields_v2
|
||||
var extraField types.ExtraFields_v2
|
||||
err := utils.DecodeBytesExtraFields(currentBlock.Extra(), &extraField)
|
||||
if err != nil {
|
||||
t.Fatal("Fail to decode extra data", err)
|
||||
}
|
||||
|
||||
syncInfoMsg := &utils.SyncInfo{
|
||||
syncInfoMsg := &types.SyncInfo{
|
||||
HighestQuorumCert: extraField.QuorumCert,
|
||||
HighestTimeoutCert: &utils.TimeoutCert{
|
||||
Round: utils.Round(2),
|
||||
Signatures: []utils.Signature{},
|
||||
HighestTimeoutCert: &types.TimeoutCert{
|
||||
Round: types.Round(2),
|
||||
Signatures: []types.Signature{},
|
||||
},
|
||||
}
|
||||
|
||||
|
|
@ -35,9 +36,9 @@ func TestSyncInfoShouldSuccessfullyUpdateByQC(t *testing.T) {
|
|||
}
|
||||
round, _, highestQuorumCert, _, _, highestCommitBlock := engineV2.GetPropertiesFaker()
|
||||
// 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, utils.Round(2), highestCommitBlock.Round)
|
||||
assert.Equal(t, types.Round(2), highestCommitBlock.Round)
|
||||
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)
|
||||
engineV2 := blockchain.Engine().(*XDPoS.XDPoS).EngineV2
|
||||
|
||||
var extraField utils.ExtraFields_v2
|
||||
var extraField types.ExtraFields_v2
|
||||
err := utils.DecodeBytesExtraFields(currentBlock.Extra(), &extraField)
|
||||
if err != nil {
|
||||
t.Fatal("Fail to decode extra data", err)
|
||||
}
|
||||
|
||||
highestTC := &utils.TimeoutCert{
|
||||
Round: utils.Round(6),
|
||||
Signatures: []utils.Signature{},
|
||||
highestTC := &types.TimeoutCert{
|
||||
Round: types.Round(6),
|
||||
Signatures: []types.Signature{},
|
||||
}
|
||||
|
||||
syncInfoMsg := &utils.SyncInfo{
|
||||
syncInfoMsg := &types.SyncInfo{
|
||||
HighestQuorumCert: extraField.QuorumCert,
|
||||
HighestTimeoutCert: highestTC,
|
||||
}
|
||||
|
|
@ -67,7 +68,7 @@ func TestSyncInfoShouldSuccessfullyUpdateByTC(t *testing.T) {
|
|||
t.Fatal(err)
|
||||
}
|
||||
round, _, highestQuorumCert, _, _, _ := engineV2.GetPropertiesFaker()
|
||||
assert.Equal(t, utils.Round(7), round)
|
||||
assert.Equal(t, types.Round(7), round)
|
||||
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
|
||||
parentBlock := blockchain.GetBlockByNumber(903)
|
||||
var extraField utils.ExtraFields_v2
|
||||
var extraField types.ExtraFields_v2
|
||||
err := utils.DecodeBytesExtraFields(parentBlock.Extra(), &extraField)
|
||||
if err != nil {
|
||||
t.Fatal("Fail to decode extra data", err)
|
||||
}
|
||||
|
||||
highestTC := &utils.TimeoutCert{
|
||||
Round: utils.Round(5),
|
||||
Signatures: []utils.Signature{},
|
||||
highestTC := &types.TimeoutCert{
|
||||
Round: types.Round(5),
|
||||
Signatures: []types.Signature{},
|
||||
}
|
||||
|
||||
syncInfoMsg := &utils.SyncInfo{
|
||||
syncInfoMsg := &types.SyncInfo{
|
||||
HighestQuorumCert: extraField.QuorumCert,
|
||||
HighestTimeoutCert: highestTC,
|
||||
}
|
||||
|
|
|
|||
|
|
@ -9,7 +9,7 @@ import (
|
|||
"github.com/XinFinOrg/XDPoSChain/accounts"
|
||||
"github.com/XinFinOrg/XDPoSChain/accounts/abi/bind/backends"
|
||||
"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/params"
|
||||
"github.com/stretchr/testify/assert"
|
||||
|
|
@ -20,11 +20,11 @@ func TestCountdownTimeoutToSendTimeoutMessage(t *testing.T) {
|
|||
engineV2 := blockchain.Engine().(*XDPoS.XDPoS).EngineV2
|
||||
|
||||
timeoutMsg := <-engineV2.BroadcastCh
|
||||
poolSize := engineV2.GetTimeoutPoolSizeFaker(timeoutMsg.(*utils.Timeout))
|
||||
poolSize := engineV2.GetTimeoutPoolSizeFaker(timeoutMsg.(*types.Timeout))
|
||||
assert.Equal(t, poolSize, 1)
|
||||
assert.NotNil(t, timeoutMsg)
|
||||
assert.Equal(t, uint64(450), timeoutMsg.(*utils.Timeout).GapNumber)
|
||||
assert.Equal(t, utils.Round(1), timeoutMsg.(*utils.Timeout).Round)
|
||||
assert.Equal(t, uint64(450), timeoutMsg.(*types.Timeout).GapNumber)
|
||||
assert.Equal(t, types.Round(1), timeoutMsg.(*types.Timeout).Round)
|
||||
}
|
||||
|
||||
func TestCountdownTimeoutNotToSendTimeoutMessageIfNotInMasternodeList(t *testing.T) {
|
||||
|
|
@ -55,9 +55,9 @@ func TestSyncInfoAfterReachTimeoutSnycThreadhold(t *testing.T) {
|
|||
for i := 0; i < 3; i++ {
|
||||
obj := <-engineV2.BroadcastCh
|
||||
switch v := obj.(type) {
|
||||
case *utils.Timeout:
|
||||
case *types.Timeout:
|
||||
timeoutCounter++
|
||||
case *utils.SyncInfo:
|
||||
case *types.SyncInfo:
|
||||
syncInfoCounter++
|
||||
default:
|
||||
log.Error("Unknown message type received", "value", v)
|
||||
|
|
@ -71,9 +71,9 @@ func TestSyncInfoAfterReachTimeoutSnycThreadhold(t *testing.T) {
|
|||
for i := 0; i < 3; i++ {
|
||||
obj := <-engineV2.BroadcastCh
|
||||
switch v := obj.(type) {
|
||||
case *utils.Timeout:
|
||||
case *types.Timeout:
|
||||
timeoutCounter++
|
||||
case *utils.SyncInfo:
|
||||
case *types.SyncInfo:
|
||||
syncInfoCounter++
|
||||
default:
|
||||
log.Error("Unknown message type received", "value", v)
|
||||
|
|
@ -89,10 +89,10 @@ func TestTimeoutMessageHandlerSuccessfullyGenerateTCandSyncInfo(t *testing.T) {
|
|||
engineV2 := blockchain.Engine().(*XDPoS.XDPoS).EngineV2
|
||||
|
||||
// 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
|
||||
timeoutMsg := &utils.Timeout{
|
||||
Round: utils.Round(1),
|
||||
timeoutMsg := &types.Timeout{
|
||||
Round: types.Round(1),
|
||||
Signature: []byte{1},
|
||||
GapNumber: 450,
|
||||
}
|
||||
|
|
@ -100,31 +100,31 @@ func TestTimeoutMessageHandlerSuccessfullyGenerateTCandSyncInfo(t *testing.T) {
|
|||
err := engineV2.TimeoutHandler(blockchain, timeoutMsg)
|
||||
assert.Nil(t, err)
|
||||
currentRound, _, _, _, _, _ := engineV2.GetPropertiesFaker()
|
||||
assert.Equal(t, utils.Round(1), currentRound)
|
||||
timeoutMsg = &utils.Timeout{
|
||||
Round: utils.Round(1),
|
||||
assert.Equal(t, types.Round(1), currentRound)
|
||||
timeoutMsg = &types.Timeout{
|
||||
Round: types.Round(1),
|
||||
Signature: []byte{2},
|
||||
GapNumber: 450,
|
||||
}
|
||||
err = engineV2.TimeoutHandler(blockchain, timeoutMsg)
|
||||
assert.Nil(t, err)
|
||||
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
|
||||
timeoutMsg = &utils.Timeout{
|
||||
Round: utils.Round(1),
|
||||
timeoutMsg = &types.Timeout{
|
||||
Round: types.Round(1),
|
||||
Signature: []byte{3},
|
||||
GapNumber: 1350,
|
||||
}
|
||||
err = engineV2.TimeoutHandler(blockchain, timeoutMsg)
|
||||
assert.Nil(t, err)
|
||||
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
|
||||
timeoutMsg = &utils.Timeout{
|
||||
Round: utils.Round(1),
|
||||
timeoutMsg = &types.Timeout{
|
||||
Round: types.Round(1),
|
||||
Signature: []byte{4},
|
||||
GapNumber: 450,
|
||||
}
|
||||
|
|
@ -139,17 +139,17 @@ func TestTimeoutMessageHandlerSuccessfullyGenerateTCandSyncInfo(t *testing.T) {
|
|||
assert.NotNil(t, syncInfoMsg)
|
||||
|
||||
// Shouldn't have QC, however, we did not inilise it, hence will show default empty value
|
||||
qc := syncInfoMsg.(*utils.SyncInfo).HighestQuorumCert
|
||||
assert.Equal(t, utils.Round(0), qc.ProposedBlockInfo.Round)
|
||||
qc := syncInfoMsg.(*types.SyncInfo).HighestQuorumCert
|
||||
assert.Equal(t, types.Round(0), qc.ProposedBlockInfo.Round)
|
||||
|
||||
tc := syncInfoMsg.(*utils.SyncInfo).HighestTimeoutCert
|
||||
tc := syncInfoMsg.(*types.SyncInfo).HighestTimeoutCert
|
||||
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)
|
||||
// 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.Equal(t, utils.Round(2), currentRound)
|
||||
assert.Equal(t, types.Round(2), currentRound)
|
||||
}
|
||||
|
||||
func TestThrowErrorIfTimeoutMsgRoundNotEqualToCurrentRound(t *testing.T) {
|
||||
|
|
@ -157,9 +157,9 @@ func TestThrowErrorIfTimeoutMsgRoundNotEqualToCurrentRound(t *testing.T) {
|
|||
engineV2 := blockchain.Engine().(*XDPoS.XDPoS).EngineV2
|
||||
|
||||
// Set round to 3
|
||||
engineV2.SetNewRoundFaker(blockchain, utils.Round(3), false)
|
||||
timeoutMsg := &utils.Timeout{
|
||||
Round: utils.Round(2),
|
||||
engineV2.SetNewRoundFaker(blockchain, types.Round(3), false)
|
||||
timeoutMsg := &types.Timeout{
|
||||
Round: types.Round(2),
|
||||
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())
|
||||
|
||||
// Set round to 1
|
||||
engineV2.SetNewRoundFaker(blockchain, utils.Round(1), false)
|
||||
engineV2.SetNewRoundFaker(blockchain, types.Round(1), false)
|
||||
err = engineV2.TimeoutHandler(blockchain, timeoutMsg)
|
||||
assert.NotNil(t, err)
|
||||
// Timeout msg round < currentRound
|
||||
|
|
@ -180,13 +180,13 @@ func TestShouldVerifyTimeoutMessageForFirstV2Block(t *testing.T) {
|
|||
blockchain, _, _, signer, signFn, _ := PrepareXDCTestBlockChainForV2Engine(t, 901, params.TestXDPoSMockChainConfig, nil)
|
||||
engineV2 := blockchain.Engine().(*XDPoS.XDPoS).EngineV2
|
||||
|
||||
signedHash, err := signFn(accounts.Account{Address: signer}, utils.TimeoutSigHash(&utils.TimeoutForSign{
|
||||
Round: utils.Round(1),
|
||||
signedHash, err := signFn(accounts.Account{Address: signer}, types.TimeoutSigHash(&types.TimeoutForSign{
|
||||
Round: types.Round(1),
|
||||
GapNumber: 450,
|
||||
}).Bytes())
|
||||
assert.Nil(t, err)
|
||||
timeoutMsg := &utils.Timeout{
|
||||
Round: utils.Round(1),
|
||||
timeoutMsg := &types.Timeout{
|
||||
Round: types.Round(1),
|
||||
GapNumber: 450,
|
||||
Signature: signedHash,
|
||||
}
|
||||
|
|
@ -195,13 +195,13 @@ func TestShouldVerifyTimeoutMessageForFirstV2Block(t *testing.T) {
|
|||
assert.Nil(t, err)
|
||||
assert.True(t, verified)
|
||||
|
||||
signedHash, err = signFn(accounts.Account{Address: signer}, utils.TimeoutSigHash(&utils.TimeoutForSign{
|
||||
Round: utils.Round(2),
|
||||
signedHash, err = signFn(accounts.Account{Address: signer}, types.TimeoutSigHash(&types.TimeoutForSign{
|
||||
Round: types.Round(2),
|
||||
GapNumber: 450,
|
||||
}).Bytes())
|
||||
assert.Nil(t, err)
|
||||
timeoutMsg = &utils.Timeout{
|
||||
Round: utils.Round(2),
|
||||
timeoutMsg = &types.Timeout{
|
||||
Round: types.Round(2),
|
||||
GapNumber: 450,
|
||||
Signature: signedHash,
|
||||
}
|
||||
|
|
@ -215,12 +215,12 @@ func TestShouldVerifyTimeoutMessage(t *testing.T) {
|
|||
blockchain, _, _, _, _, _ := PrepareXDCTestBlockChainForV2Engine(t, 2251, params.TestXDPoSMockChainConfig, nil)
|
||||
engineV2 := blockchain.Engine().(*XDPoS.XDPoS).EngineV2
|
||||
|
||||
signedHash := SignHashByPK(acc1Key, utils.TimeoutSigHash(&utils.TimeoutForSign{
|
||||
Round: utils.Round(5000),
|
||||
signedHash := SignHashByPK(acc1Key, types.TimeoutSigHash(&types.TimeoutForSign{
|
||||
Round: types.Round(5000),
|
||||
GapNumber: 2250,
|
||||
}).Bytes())
|
||||
timeoutMsg := &utils.Timeout{
|
||||
Round: utils.Round(5000),
|
||||
timeoutMsg := &types.Timeout{
|
||||
Round: types.Round(5000),
|
||||
GapNumber: 2250,
|
||||
Signature: signedHash,
|
||||
}
|
||||
|
|
@ -235,46 +235,46 @@ func TestTimeoutPoolKeeyGoodHygiene(t *testing.T) {
|
|||
engineV2 := blockchain.Engine().(*XDPoS.XDPoS).EngineV2
|
||||
|
||||
// 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
|
||||
|
||||
signedHash, _ := signFn(accounts.Account{Address: signer}, utils.TimeoutSigHash(&utils.TimeoutForSign{
|
||||
Round: utils.Round(5),
|
||||
signedHash, _ := signFn(accounts.Account{Address: signer}, types.TimeoutSigHash(&types.TimeoutForSign{
|
||||
Round: types.Round(5),
|
||||
GapNumber: 450,
|
||||
}).Bytes())
|
||||
timeoutMsg := &utils.Timeout{
|
||||
Round: utils.Round(5),
|
||||
timeoutMsg := &types.Timeout{
|
||||
Round: types.Round(5),
|
||||
GapNumber: 450,
|
||||
Signature: signedHash,
|
||||
}
|
||||
engineV2.TimeoutHandler(blockchain, timeoutMsg)
|
||||
|
||||
// Inject a second timeout with round 16
|
||||
signedHash, _ = signFn(accounts.Account{Address: signer}, utils.TimeoutSigHash(&utils.TimeoutForSign{
|
||||
Round: utils.Round(16),
|
||||
signedHash, _ = signFn(accounts.Account{Address: signer}, types.TimeoutSigHash(&types.TimeoutForSign{
|
||||
Round: types.Round(16),
|
||||
GapNumber: 450,
|
||||
}).Bytes())
|
||||
timeoutMsg = &utils.Timeout{
|
||||
Round: utils.Round(16),
|
||||
timeoutMsg = &types.Timeout{
|
||||
Round: types.Round(16),
|
||||
GapNumber: 450,
|
||||
Signature: signedHash,
|
||||
}
|
||||
// Set round to 16
|
||||
engineV2.SetNewRoundFaker(blockchain, utils.Round(16), false)
|
||||
engineV2.SetNewRoundFaker(blockchain, types.Round(16), false)
|
||||
engineV2.TimeoutHandler(blockchain, timeoutMsg)
|
||||
|
||||
// Inject a third timeout with round 17
|
||||
signedHash, _ = signFn(accounts.Account{Address: signer}, utils.TimeoutSigHash(&utils.TimeoutForSign{
|
||||
Round: utils.Round(17),
|
||||
signedHash, _ = signFn(accounts.Account{Address: signer}, types.TimeoutSigHash(&types.TimeoutForSign{
|
||||
Round: types.Round(17),
|
||||
GapNumber: 450,
|
||||
}).Bytes())
|
||||
timeoutMsg = &utils.Timeout{
|
||||
Round: utils.Round(17),
|
||||
timeoutMsg = &types.Timeout{
|
||||
Round: types.Round(17),
|
||||
GapNumber: 450,
|
||||
Signature: signedHash,
|
||||
}
|
||||
// Set round to 16
|
||||
engineV2.SetNewRoundFaker(blockchain, utils.Round(17), false)
|
||||
engineV2.SetNewRoundFaker(blockchain, types.Round(17), false)
|
||||
engineV2.TimeoutHandler(blockchain, timeoutMsg)
|
||||
|
||||
// Let's keep good Hygiene
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@ import (
|
|||
"testing"
|
||||
|
||||
"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/stretchr/testify/assert"
|
||||
)
|
||||
|
|
@ -15,9 +15,9 @@ func TestShouldVerifyBlockInfo(t *testing.T) {
|
|||
blockchain, _, currentBlock, signer, signFn, _ := PrepareXDCTestBlockChainForV2Engine(t, 901, params.TestXDPoSMockChainConfig, nil)
|
||||
engineV2 := blockchain.Engine().(*XDPoS.XDPoS).EngineV2
|
||||
|
||||
blockInfo := &utils.BlockInfo{
|
||||
blockInfo := &types.BlockInfo{
|
||||
Hash: currentBlock.Hash(),
|
||||
Round: utils.Round(1),
|
||||
Round: types.Round(1),
|
||||
Number: currentBlock.Number(),
|
||||
}
|
||||
err := engineV2.VerifyBlockInfo(blockchain, blockInfo, nil)
|
||||
|
|
@ -30,33 +30,33 @@ func TestShouldVerifyBlockInfo(t *testing.T) {
|
|||
err = blockchain.InsertBlock(block902)
|
||||
assert.Nil(t, err)
|
||||
|
||||
blockInfo = &utils.BlockInfo{
|
||||
blockInfo = &types.BlockInfo{
|
||||
Hash: block902.Hash(),
|
||||
Round: utils.Round(2),
|
||||
Round: types.Round(2),
|
||||
Number: block902.Number(),
|
||||
}
|
||||
err = engineV2.VerifyBlockInfo(blockchain, blockInfo, nil)
|
||||
assert.Nil(t, err)
|
||||
|
||||
blockInfo = &utils.BlockInfo{
|
||||
blockInfo = &types.BlockInfo{
|
||||
Hash: currentBlock.Hash(),
|
||||
Round: utils.Round(2),
|
||||
Round: types.Round(2),
|
||||
Number: currentBlock.Number(),
|
||||
}
|
||||
err = engineV2.VerifyBlockInfo(blockchain, blockInfo, nil)
|
||||
assert.NotNil(t, err)
|
||||
|
||||
blockInfo = &utils.BlockInfo{
|
||||
blockInfo = &types.BlockInfo{
|
||||
Hash: block902.Hash(),
|
||||
Round: utils.Round(3),
|
||||
Round: types.Round(3),
|
||||
Number: block902.Number(),
|
||||
}
|
||||
err = engineV2.VerifyBlockInfo(blockchain, blockInfo, nil)
|
||||
assert.NotNil(t, err)
|
||||
|
||||
blockInfo = &utils.BlockInfo{
|
||||
blockInfo = &types.BlockInfo{
|
||||
Hash: block902.Hash(),
|
||||
Round: utils.Round(2),
|
||||
Round: types.Round(2),
|
||||
Number: currentBlock.Number(),
|
||||
}
|
||||
err = engineV2.VerifyBlockInfo(blockchain, blockInfo, nil)
|
||||
|
|
|
|||
|
|
@ -108,34 +108,34 @@ func TestShouldVerifyBlock(t *testing.T) {
|
|||
assert.Equal(t, utils.ErrInvalidDifficulty, err)
|
||||
|
||||
// Creat an invalid QC round
|
||||
proposedBlockInfo := &utils.BlockInfo{
|
||||
proposedBlockInfo := &types.BlockInfo{
|
||||
Hash: blockchain.GetBlockByNumber(902).Hash(),
|
||||
Round: utils.Round(2),
|
||||
Round: types.Round(2),
|
||||
Number: blockchain.GetBlockByNumber(902).Number(),
|
||||
}
|
||||
voteForSign := &utils.VoteForSign{
|
||||
voteForSign := &types.VoteForSign{
|
||||
ProposedBlockInfo: proposedBlockInfo,
|
||||
GapNumber: 450,
|
||||
}
|
||||
// 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 {
|
||||
panic(fmt.Errorf("Error generate QC by creating signedHash: %v", err))
|
||||
}
|
||||
// Sign from acc 1, 2, 3
|
||||
acc1SignedHash := SignHashByPK(acc1Key, utils.VoteSigHash(voteForSign).Bytes())
|
||||
acc2SignedHash := SignHashByPK(acc2Key, utils.VoteSigHash(voteForSign).Bytes())
|
||||
acc3SignedHash := SignHashByPK(acc3Key, utils.VoteSigHash(voteForSign).Bytes())
|
||||
var signatures []utils.Signature
|
||||
acc1SignedHash := SignHashByPK(acc1Key, types.VoteSigHash(voteForSign).Bytes())
|
||||
acc2SignedHash := SignHashByPK(acc2Key, types.VoteSigHash(voteForSign).Bytes())
|
||||
acc3SignedHash := SignHashByPK(acc3Key, types.VoteSigHash(voteForSign).Bytes())
|
||||
var signatures []types.Signature
|
||||
signatures = append(signatures, signedHash, acc1SignedHash, acc2SignedHash, acc3SignedHash)
|
||||
quorumCert := &utils.QuorumCert{
|
||||
quorumCert := &types.QuorumCert{
|
||||
ProposedBlockInfo: proposedBlockInfo,
|
||||
Signatures: signatures,
|
||||
GapNumber: 450,
|
||||
}
|
||||
|
||||
extra := utils.ExtraFields_v2{
|
||||
Round: utils.Round(2),
|
||||
extra := types.ExtraFields_v2{
|
||||
Round: types.Round(2),
|
||||
QuorumCert: quorumCert,
|
||||
}
|
||||
extraInBytes, err := extra.EncodeToBytes()
|
||||
|
|
@ -181,28 +181,28 @@ func TestShouldFailIfNotEnoughQCSignatures(t *testing.T) {
|
|||
adaptor := blockchain.Engine().(*XDPoS.XDPoS)
|
||||
|
||||
parentBlock := blockchain.GetBlockByNumber(901)
|
||||
proposedBlockInfo := &utils.BlockInfo{
|
||||
proposedBlockInfo := &types.BlockInfo{
|
||||
Hash: parentBlock.Hash(),
|
||||
Round: utils.Round(1),
|
||||
Round: types.Round(1),
|
||||
Number: parentBlock.Number(),
|
||||
}
|
||||
voteForSign := &utils.VoteForSign{
|
||||
voteForSign := &types.VoteForSign{
|
||||
ProposedBlockInfo: proposedBlockInfo,
|
||||
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)
|
||||
var signatures []utils.Signature
|
||||
var signatures []types.Signature
|
||||
// Duplicate the signatures
|
||||
signatures = append(signatures, signedHash, signedHash, signedHash, signedHash, signedHash, signedHash)
|
||||
quorumCert := &utils.QuorumCert{
|
||||
quorumCert := &types.QuorumCert{
|
||||
ProposedBlockInfo: proposedBlockInfo,
|
||||
Signatures: signatures,
|
||||
GapNumber: 450,
|
||||
}
|
||||
|
||||
extra := utils.ExtraFields_v2{
|
||||
Round: utils.Round(2),
|
||||
extra := types.ExtraFields_v2{
|
||||
Round: types.Round(2),
|
||||
QuorumCert: quorumCert,
|
||||
}
|
||||
extraInBytes, err := extra.EncodeToBytes()
|
||||
|
|
|
|||
|
|
@ -12,7 +12,7 @@ import (
|
|||
"github.com/XinFinOrg/XDPoSChain/accounts/abi/bind/backends"
|
||||
"github.com/XinFinOrg/XDPoSChain/common"
|
||||
"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/stretchr/testify/assert"
|
||||
)
|
||||
|
|
@ -22,23 +22,23 @@ func TestVoteMessageHandlerSuccessfullyGeneratedAndProcessQCForFistV2Round(t *te
|
|||
blockchain, _, currentBlock, signer, signFn, _ := PrepareXDCTestBlockChainForV2Engine(t, 901, params.TestXDPoSMockChainConfig, nil)
|
||||
engineV2 := blockchain.Engine().(*XDPoS.XDPoS).EngineV2
|
||||
|
||||
blockInfo := &utils.BlockInfo{
|
||||
blockInfo := &types.BlockInfo{
|
||||
Hash: currentBlock.Hash(),
|
||||
Round: utils.Round(1),
|
||||
Round: types.Round(1),
|
||||
Number: big.NewInt(901),
|
||||
}
|
||||
voteForSign := &utils.VoteForSign{
|
||||
voteForSign := &types.VoteForSign{
|
||||
ProposedBlockInfo: blockInfo,
|
||||
GapNumber: 450,
|
||||
}
|
||||
voteSigningHash := utils.VoteSigHash(voteForSign)
|
||||
voteSigningHash := types.VoteSigHash(voteForSign)
|
||||
|
||||
// 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
|
||||
signedHash, err := signFn(accounts.Account{Address: signer}, voteSigningHash.Bytes())
|
||||
assert.Nil(t, err)
|
||||
voteMsg := &utils.Vote{
|
||||
voteMsg := &types.Vote{
|
||||
ProposedBlockInfo: blockInfo,
|
||||
Signature: signedHash,
|
||||
GapNumber: 450,
|
||||
|
|
@ -49,12 +49,12 @@ func TestVoteMessageHandlerSuccessfullyGeneratedAndProcessQCForFistV2Round(t *te
|
|||
currentRound, lockQuorumCert, highestQuorumCert, _, _, _ := engineV2.GetPropertiesFaker()
|
||||
// initialised with nil and 0 round
|
||||
assert.Nil(t, lockQuorumCert)
|
||||
assert.Equal(t, utils.Round(0), highestQuorumCert.ProposedBlockInfo.Round)
|
||||
assert.Equal(t, utils.Round(1), currentRound)
|
||||
assert.Equal(t, types.Round(0), highestQuorumCert.ProposedBlockInfo.Round)
|
||||
assert.Equal(t, types.Round(1), currentRound)
|
||||
|
||||
signedHash = SignHashByPK(acc2Key, voteSigningHash.Bytes())
|
||||
|
||||
voteMsg = &utils.Vote{
|
||||
voteMsg = &types.Vote{
|
||||
ProposedBlockInfo: blockInfo,
|
||||
Signature: signedHash,
|
||||
GapNumber: 450,
|
||||
|
|
@ -64,13 +64,13 @@ func TestVoteMessageHandlerSuccessfullyGeneratedAndProcessQCForFistV2Round(t *te
|
|||
currentRound, lockQuorumCert, highestQuorumCert, _, _, _ = engineV2.GetPropertiesFaker()
|
||||
// Still using the initlised value because we did not yet go to the next round
|
||||
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
|
||||
signedHash = SignHashByPK(acc3Key, voteSigningHash.Bytes())
|
||||
voteMsg = &utils.Vote{
|
||||
voteMsg = &types.Vote{
|
||||
ProposedBlockInfo: blockInfo,
|
||||
Signature: signedHash,
|
||||
GapNumber: 450,
|
||||
|
|
@ -80,34 +80,34 @@ func TestVoteMessageHandlerSuccessfullyGeneratedAndProcessQCForFistV2Round(t *te
|
|||
assert.Nil(t, err)
|
||||
currentRound, lockQuorumCert, highestQuorumCert, _, _, _ = engineV2.GetPropertiesFaker()
|
||||
// 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
|
||||
assert.Equal(t, highestQuorumCert.ProposedBlockInfo, voteMsg.ProposedBlockInfo)
|
||||
// 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) {
|
||||
blockchain, _, currentBlock, signer, signFn, _ := PrepareXDCTestBlockChainForV2Engine(t, 905, params.TestXDPoSMockChainConfig, nil)
|
||||
engineV2 := blockchain.Engine().(*XDPoS.XDPoS).EngineV2
|
||||
|
||||
blockInfo := &utils.BlockInfo{
|
||||
blockInfo := &types.BlockInfo{
|
||||
Hash: currentBlock.Hash(),
|
||||
Round: utils.Round(5),
|
||||
Round: types.Round(5),
|
||||
Number: big.NewInt(905),
|
||||
}
|
||||
voteForSign := &utils.VoteForSign{
|
||||
voteForSign := &types.VoteForSign{
|
||||
ProposedBlockInfo: blockInfo,
|
||||
GapNumber: 450,
|
||||
}
|
||||
voteSigningHash := utils.VoteSigHash(voteForSign)
|
||||
voteSigningHash := types.VoteSigHash(voteForSign)
|
||||
|
||||
// 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
|
||||
signedHash, err := signFn(accounts.Account{Address: signer}, voteSigningHash.Bytes())
|
||||
assert.Nil(t, err)
|
||||
voteMsg := &utils.Vote{
|
||||
voteMsg := &types.Vote{
|
||||
ProposedBlockInfo: blockInfo,
|
||||
Signature: signedHash,
|
||||
GapNumber: 450,
|
||||
|
|
@ -118,10 +118,10 @@ func TestVoteMessageHandlerSuccessfullyGeneratedAndProcessQC(t *testing.T) {
|
|||
currentRound, lockQuorumCert, highestQuorumCert, _, _, _ := engineV2.GetPropertiesFaker()
|
||||
// initialised with nil and 0 round
|
||||
assert.Nil(t, lockQuorumCert)
|
||||
assert.Equal(t, utils.Round(0), highestQuorumCert.ProposedBlockInfo.Round)
|
||||
assert.Equal(t, utils.Round(5), currentRound)
|
||||
assert.Equal(t, types.Round(0), highestQuorumCert.ProposedBlockInfo.Round)
|
||||
assert.Equal(t, types.Round(5), currentRound)
|
||||
signedHash = SignHashByPK(acc1Key, voteSigningHash.Bytes())
|
||||
voteMsg = &utils.Vote{
|
||||
voteMsg = &types.Vote{
|
||||
ProposedBlockInfo: blockInfo,
|
||||
Signature: signedHash,
|
||||
GapNumber: 450,
|
||||
|
|
@ -131,16 +131,16 @@ func TestVoteMessageHandlerSuccessfullyGeneratedAndProcessQC(t *testing.T) {
|
|||
currentRound, lockQuorumCert, highestQuorumCert, _, _, _ = engineV2.GetPropertiesFaker()
|
||||
// Still using the initlised value because we did not yet go to the next round
|
||||
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
|
||||
randomSigner, randomSignFn, err := backends.SimulateWalletAddressAndSignFn()
|
||||
assert.Nil(t, err)
|
||||
randomlySignedHash, err := randomSignFn(accounts.Account{Address: randomSigner}, voteSigningHash.Bytes())
|
||||
assert.Nil(t, err)
|
||||
voteMsg = &utils.Vote{
|
||||
voteMsg = &types.Vote{
|
||||
ProposedBlockInfo: blockInfo,
|
||||
Signature: randomlySignedHash,
|
||||
GapNumber: 450,
|
||||
|
|
@ -150,12 +150,12 @@ func TestVoteMessageHandlerSuccessfullyGeneratedAndProcessQC(t *testing.T) {
|
|||
currentRound, lockQuorumCert, highestQuorumCert, _, _, _ = engineV2.GetPropertiesFaker()
|
||||
// Still using the initlised value because we did not yet go to the next round
|
||||
assert.Nil(t, lockQuorumCert)
|
||||
assert.Equal(t, utils.Round(0), highestQuorumCert.ProposedBlockInfo.Round)
|
||||
assert.Equal(t, utils.Round(5), currentRound)
|
||||
assert.Equal(t, types.Round(0), highestQuorumCert.ProposedBlockInfo.Round)
|
||||
assert.Equal(t, types.Round(5), currentRound)
|
||||
|
||||
// Create a vote message that should trigger vote pool hook and increment the round to 6
|
||||
signedHash = SignHashByPK(acc3Key, voteSigningHash.Bytes())
|
||||
voteMsg = &utils.Vote{
|
||||
voteMsg = &types.Vote{
|
||||
ProposedBlockInfo: blockInfo,
|
||||
Signature: signedHash,
|
||||
GapNumber: 450,
|
||||
|
|
@ -165,13 +165,13 @@ func TestVoteMessageHandlerSuccessfullyGeneratedAndProcessQC(t *testing.T) {
|
|||
assert.Nil(t, err)
|
||||
currentRound, lockQuorumCert, highestQuorumCert, _, _, highestCommitBlock := engineV2.GetPropertiesFaker()
|
||||
// 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
|
||||
assert.Equal(t, highestQuorumCert.ProposedBlockInfo, voteMsg.ProposedBlockInfo)
|
||||
// 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
|
||||
assert.Equal(t, utils.Round(3), highestCommitBlock.Round)
|
||||
assert.Equal(t, types.Round(3), highestCommitBlock.Round)
|
||||
assert.Equal(t, big.NewInt(903), highestCommitBlock.Number)
|
||||
}
|
||||
|
||||
|
|
@ -179,15 +179,15 @@ func TestThrowErrorIfVoteMsgRoundIsMoreThanOneRoundAwayFromCurrentRound(t *testi
|
|||
blockchain, _, _, _, _, _ := PrepareXDCTestBlockChainForV2Engine(t, 905, params.TestXDPoSMockChainConfig, nil)
|
||||
engineV2 := blockchain.Engine().(*XDPoS.XDPoS).EngineV2
|
||||
|
||||
blockInfo := &utils.BlockInfo{
|
||||
blockInfo := &types.BlockInfo{
|
||||
Hash: common.HexToHash("0x1"),
|
||||
Round: utils.Round(6),
|
||||
Round: types.Round(6),
|
||||
Number: big.NewInt(999),
|
||||
}
|
||||
|
||||
// Set round to 7
|
||||
engineV2.SetNewRoundFaker(blockchain, utils.Round(7), false)
|
||||
voteMsg := &utils.Vote{
|
||||
engineV2.SetNewRoundFaker(blockchain, types.Round(7), false)
|
||||
voteMsg := &types.Vote{
|
||||
ProposedBlockInfo: blockInfo,
|
||||
Signature: []byte{1},
|
||||
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())
|
||||
|
||||
// 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)
|
||||
assert.Nil(t, err)
|
||||
|
||||
engineV2.SetNewRoundFaker(blockchain, utils.Round(4), false)
|
||||
engineV2.SetNewRoundFaker(blockchain, types.Round(4), false)
|
||||
err = engineV2.VoteHandler(blockchain, voteMsg)
|
||||
assert.NotNil(t, err)
|
||||
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
|
||||
|
||||
// Set round to 5
|
||||
engineV2.SetNewRoundFaker(blockchain, utils.Round(5), false)
|
||||
engineV2.SetNewRoundFaker(blockchain, types.Round(5), false)
|
||||
|
||||
// Start with vote messages
|
||||
blockInfo := &utils.BlockInfo{
|
||||
blockInfo := &types.BlockInfo{
|
||||
Hash: currentBlock.Hash(),
|
||||
Round: utils.Round(5),
|
||||
Round: types.Round(5),
|
||||
Number: big.NewInt(905),
|
||||
}
|
||||
voteForSign := &utils.VoteForSign{
|
||||
voteForSign := &types.VoteForSign{
|
||||
ProposedBlockInfo: blockInfo,
|
||||
GapNumber: 450,
|
||||
}
|
||||
voteSigningHash := utils.VoteSigHash(voteForSign)
|
||||
voteSigningHash := types.VoteSigHash(voteForSign)
|
||||
// Create two vote message which will not reach vote pool threshold
|
||||
signedHash := SignHashByPK(acc1Key, voteSigningHash.Bytes())
|
||||
voteMsg := &utils.Vote{
|
||||
voteMsg := &types.Vote{
|
||||
ProposedBlockInfo: blockInfo,
|
||||
Signature: signedHash,
|
||||
GapNumber: 450,
|
||||
|
|
@ -241,10 +241,10 @@ func TestProcessVoteMsgThenTimeoutMsg(t *testing.T) {
|
|||
currentRound, lockQuorumCert, highestQuorumCert, _, _, _ := engineV2.GetPropertiesFaker()
|
||||
// initialised with nil and 0 round
|
||||
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)
|
||||
voteMsg = &utils.Vote{
|
||||
assert.Equal(t, types.Round(5), currentRound)
|
||||
voteMsg = &types.Vote{
|
||||
ProposedBlockInfo: blockInfo,
|
||||
Signature: SignHashByPK(acc2Key, voteSigningHash.Bytes()),
|
||||
GapNumber: 450,
|
||||
|
|
@ -252,10 +252,10 @@ func TestProcessVoteMsgThenTimeoutMsg(t *testing.T) {
|
|||
err = engineV2.VoteHandler(blockchain, voteMsg)
|
||||
assert.Nil(t, err)
|
||||
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
|
||||
voteMsg = &utils.Vote{
|
||||
voteMsg = &types.Vote{
|
||||
ProposedBlockInfo: blockInfo,
|
||||
Signature: SignHashByPK(acc3Key, voteSigningHash.Bytes()),
|
||||
GapNumber: 450,
|
||||
|
|
@ -266,17 +266,17 @@ func TestProcessVoteMsgThenTimeoutMsg(t *testing.T) {
|
|||
// Check round has now changed from 5 to 6
|
||||
currentRound, lockQuorumCert, highestQuorumCert, _, _, _ = engineV2.GetPropertiesFaker()
|
||||
// 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
|
||||
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
|
||||
|
||||
// First, all incoming old timeout msg shall not be processed
|
||||
timeoutMsg := &utils.Timeout{
|
||||
Round: utils.Round(5),
|
||||
timeoutMsg := &types.Timeout{
|
||||
Round: types.Round(5),
|
||||
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())
|
||||
|
||||
// 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{
|
||||
Round: utils.Round(6),
|
||||
timeoutMsg = &types.Timeout{
|
||||
Round: types.Round(6),
|
||||
Signature: []byte{1},
|
||||
}
|
||||
|
||||
err = engineV2.TimeoutHandler(blockchain, timeoutMsg)
|
||||
assert.Nil(t, err)
|
||||
currentRound, _, _, _, _, _ = engineV2.GetPropertiesFaker()
|
||||
assert.Equal(t, utils.Round(6), currentRound)
|
||||
timeoutMsg = &utils.Timeout{
|
||||
Round: utils.Round(6),
|
||||
assert.Equal(t, types.Round(6), currentRound)
|
||||
timeoutMsg = &types.Timeout{
|
||||
Round: types.Round(6),
|
||||
Signature: []byte{2},
|
||||
}
|
||||
err = engineV2.TimeoutHandler(blockchain, timeoutMsg)
|
||||
assert.Nil(t, err)
|
||||
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
|
||||
timeoutMsg = &utils.Timeout{
|
||||
Round: utils.Round(6),
|
||||
timeoutMsg = &types.Timeout{
|
||||
Round: types.Round(6),
|
||||
Signature: []byte{3},
|
||||
}
|
||||
|
||||
|
|
@ -316,18 +316,18 @@ func TestProcessVoteMsgThenTimeoutMsg(t *testing.T) {
|
|||
assert.NotNil(t, syncInfoMsg)
|
||||
|
||||
// Should have HighestQuorumCert from previous round votes
|
||||
qc := syncInfoMsg.(*utils.SyncInfo).HighestQuorumCert
|
||||
qc := syncInfoMsg.(*types.SyncInfo).HighestQuorumCert
|
||||
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.Equal(t, utils.Round(6), tc.Round)
|
||||
sigatures := []utils.Signature{[]byte{1}, []byte{2}, []byte{3}}
|
||||
assert.Equal(t, types.Round(6), tc.Round)
|
||||
sigatures := []types.Signature{[]byte{1}, []byte{2}, []byte{3}}
|
||||
assert.ElementsMatch(t, tc.Signatures, sigatures)
|
||||
// Round shall be +1 now
|
||||
currentRound, _, _, _, _, _ = engineV2.GetPropertiesFaker()
|
||||
assert.Equal(t, utils.Round(7), currentRound)
|
||||
assert.Equal(t, types.Round(7), currentRound)
|
||||
}
|
||||
|
||||
func TestVoteMessageShallNotThrowErrorIfBlockNotYetExist(t *testing.T) {
|
||||
|
|
@ -339,21 +339,21 @@ func TestVoteMessageShallNotThrowErrorIfBlockNotYetExist(t *testing.T) {
|
|||
blockCoinBase := fmt.Sprintf("0x111000000000000000000000000000000%03d", blockNum)
|
||||
block := CreateBlock(blockchain, params.TestXDPoSMockChainConfig, currentBlock, blockNum, 6, blockCoinBase, signer, signFn, nil, nil)
|
||||
|
||||
blockInfo := &utils.BlockInfo{
|
||||
blockInfo := &types.BlockInfo{
|
||||
Hash: block.Header().Hash(),
|
||||
Round: utils.Round(6),
|
||||
Round: types.Round(6),
|
||||
Number: big.NewInt(906),
|
||||
}
|
||||
voteForSign := &utils.VoteForSign{
|
||||
voteForSign := &types.VoteForSign{
|
||||
ProposedBlockInfo: blockInfo,
|
||||
GapNumber: 450,
|
||||
}
|
||||
voteSigningHash := utils.VoteSigHash(voteForSign)
|
||||
voteSigningHash := types.VoteSigHash(voteForSign)
|
||||
|
||||
// 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
|
||||
voteMsg := &utils.Vote{
|
||||
voteMsg := &types.Vote{
|
||||
ProposedBlockInfo: blockInfo,
|
||||
Signature: SignHashByPK(acc1Key, voteSigningHash.Bytes()),
|
||||
GapNumber: 450,
|
||||
|
|
@ -362,7 +362,7 @@ func TestVoteMessageShallNotThrowErrorIfBlockNotYetExist(t *testing.T) {
|
|||
err := engineV2.VoteHandler(blockchain, voteMsg)
|
||||
assert.Nil(t, err)
|
||||
|
||||
voteMsg = &utils.Vote{
|
||||
voteMsg = &types.Vote{
|
||||
ProposedBlockInfo: blockInfo,
|
||||
Signature: SignHashByPK(acc2Key, voteSigningHash.Bytes()),
|
||||
GapNumber: 450,
|
||||
|
|
@ -371,7 +371,7 @@ func TestVoteMessageShallNotThrowErrorIfBlockNotYetExist(t *testing.T) {
|
|||
assert.Nil(t, err)
|
||||
|
||||
// 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,
|
||||
Signature: SignHashByPK(acc3Key, voteSigningHash.Bytes()),
|
||||
GapNumber: 450,
|
||||
|
|
@ -382,15 +382,15 @@ func TestVoteMessageShallNotThrowErrorIfBlockNotYetExist(t *testing.T) {
|
|||
currentRound, lockQuorumCert, highestQuorumCert, _, _, _ := engineV2.GetPropertiesFaker()
|
||||
// Still using the initlised value because we did not yet go to the next round
|
||||
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
|
||||
err = blockchain.InsertBlock(block)
|
||||
assert.Nil(t, err)
|
||||
|
||||
voteMsg = &utils.Vote{
|
||||
voteMsg = &types.Vote{
|
||||
ProposedBlockInfo: blockInfo,
|
||||
Signature: SignHashByPK(voterKey, voteSigningHash.Bytes()),
|
||||
GapNumber: 450,
|
||||
|
|
@ -401,12 +401,12 @@ func TestVoteMessageShallNotThrowErrorIfBlockNotYetExist(t *testing.T) {
|
|||
|
||||
currentRound, lockQuorumCert, highestQuorumCert, _, _, highestCommitBlock := engineV2.GetPropertiesFaker()
|
||||
// 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
|
||||
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
|
||||
assert.Equal(t, utils.Round(4), highestCommitBlock.Round)
|
||||
assert.Equal(t, types.Round(4), highestCommitBlock.Round)
|
||||
assert.Equal(t, big.NewInt(904), highestCommitBlock.Number)
|
||||
}
|
||||
|
||||
|
|
@ -415,22 +415,22 @@ func TestProcessVoteMsgFailIfVerifyBlockInfoFail(t *testing.T) {
|
|||
engineV2 := blockchain.Engine().(*XDPoS.XDPoS).EngineV2
|
||||
|
||||
// Set round to 5
|
||||
engineV2.SetNewRoundFaker(blockchain, utils.Round(5), false)
|
||||
engineV2.SetNewRoundFaker(blockchain, types.Round(5), false)
|
||||
|
||||
// Start with vote messages
|
||||
blockInfo := &utils.BlockInfo{
|
||||
blockInfo := &types.BlockInfo{
|
||||
Hash: currentBlock.ParentHash(),
|
||||
Round: utils.Round(5),
|
||||
Round: types.Round(5),
|
||||
Number: big.NewInt(905),
|
||||
}
|
||||
voteForSign := &utils.VoteForSign{
|
||||
voteForSign := &types.VoteForSign{
|
||||
ProposedBlockInfo: blockInfo,
|
||||
GapNumber: 450,
|
||||
}
|
||||
voteSigningHash := utils.VoteSigHash(voteForSign)
|
||||
voteSigningHash := types.VoteSigHash(voteForSign)
|
||||
// Create two vote message which will not reach vote pool threshold
|
||||
signedHash := SignHashByPK(acc1Key, voteSigningHash.Bytes())
|
||||
voteMsg := &utils.Vote{
|
||||
voteMsg := &types.Vote{
|
||||
ProposedBlockInfo: blockInfo,
|
||||
Signature: signedHash,
|
||||
GapNumber: 450,
|
||||
|
|
@ -441,10 +441,10 @@ func TestProcessVoteMsgFailIfVerifyBlockInfoFail(t *testing.T) {
|
|||
currentRound, lockQuorumCert, highestQuorumCert, _, _, _ := engineV2.GetPropertiesFaker()
|
||||
// initialised with nil and 0 round
|
||||
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)
|
||||
voteMsg = &utils.Vote{
|
||||
assert.Equal(t, types.Round(5), currentRound)
|
||||
voteMsg = &types.Vote{
|
||||
ProposedBlockInfo: blockInfo,
|
||||
Signature: SignHashByPK(acc2Key, voteSigningHash.Bytes()),
|
||||
GapNumber: 450,
|
||||
|
|
@ -452,10 +452,10 @@ func TestProcessVoteMsgFailIfVerifyBlockInfoFail(t *testing.T) {
|
|||
err = engineV2.VoteHandler(blockchain, voteMsg)
|
||||
assert.Nil(t, err)
|
||||
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
|
||||
voteMsg = &utils.Vote{
|
||||
voteMsg = &types.Vote{
|
||||
ProposedBlockInfo: blockInfo,
|
||||
Signature: SignHashByPK(acc3Key, voteSigningHash.Bytes()),
|
||||
GapNumber: 450,
|
||||
|
|
@ -470,36 +470,36 @@ func TestVerifyVoteMsg(t *testing.T) {
|
|||
blockchain, _, currentBlock, signer, signFn, _ := PrepareXDCTestBlockChainForV2Engine(t, 915, params.TestXDPoSMockChainConfig, nil)
|
||||
engineV2 := blockchain.Engine().(*XDPoS.XDPoS).EngineV2
|
||||
|
||||
blockInfo := &utils.BlockInfo{
|
||||
blockInfo := &types.BlockInfo{
|
||||
Hash: currentBlock.Hash(),
|
||||
Round: utils.Round(14),
|
||||
Round: types.Round(14),
|
||||
Number: big.NewInt(915),
|
||||
}
|
||||
voteForSign := &utils.VoteForSign{
|
||||
voteForSign := &types.VoteForSign{
|
||||
ProposedBlockInfo: blockInfo,
|
||||
GapNumber: 450,
|
||||
}
|
||||
|
||||
// Valid message but disqualified as the round does not match
|
||||
voteMsg := &utils.Vote{
|
||||
voteMsg := &types.Vote{
|
||||
ProposedBlockInfo: blockInfo,
|
||||
Signature: []byte{1},
|
||||
GapNumber: 450,
|
||||
}
|
||||
engineV2.SetNewRoundFaker(blockchain, utils.Round(15), false)
|
||||
engineV2.SetNewRoundFaker(blockchain, types.Round(15), false)
|
||||
verified, err := engineV2.VerifyVoteMessage(blockchain, voteMsg)
|
||||
assert.False(t, verified)
|
||||
assert.Nil(t, err)
|
||||
|
||||
// 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)
|
||||
assert.False(t, verified)
|
||||
assert.Equal(t, "Error while verifying message: invalid signature length", err.Error())
|
||||
|
||||
// Valid vote message from a master node
|
||||
signHash, _ := signFn(accounts.Account{Address: signer}, utils.VoteSigHash(voteForSign).Bytes())
|
||||
voteMsg = &utils.Vote{
|
||||
signHash, _ := signFn(accounts.Account{Address: signer}, types.VoteSigHash(voteForSign).Bytes())
|
||||
voteMsg = &types.Vote{
|
||||
ProposedBlockInfo: blockInfo,
|
||||
Signature: signHash,
|
||||
GapNumber: 450,
|
||||
|
|
@ -514,29 +514,29 @@ func TestVoteMessageHandlerWrongGapNumber(t *testing.T) {
|
|||
blockchain, _, currentBlock, signer, signFn, _ := PrepareXDCTestBlockChainForV2Engine(t, 905, params.TestXDPoSMockChainConfig, nil)
|
||||
engineV2 := blockchain.Engine().(*XDPoS.XDPoS).EngineV2
|
||||
|
||||
blockInfo := &utils.BlockInfo{
|
||||
blockInfo := &types.BlockInfo{
|
||||
Hash: currentBlock.Hash(),
|
||||
Round: utils.Round(5),
|
||||
Round: types.Round(5),
|
||||
Number: big.NewInt(905),
|
||||
}
|
||||
voteForSign := &utils.VoteForSign{
|
||||
voteForSign := &types.VoteForSign{
|
||||
ProposedBlockInfo: blockInfo,
|
||||
GapNumber: 450,
|
||||
}
|
||||
voteSigningHash := utils.VoteSigHash(voteForSign)
|
||||
voteSigningHash := types.VoteSigHash(voteForSign)
|
||||
|
||||
// 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
|
||||
signedHash, _ := signFn(accounts.Account{Address: signer}, voteSigningHash.Bytes())
|
||||
voteMsg := &utils.Vote{
|
||||
voteMsg := &types.Vote{
|
||||
ProposedBlockInfo: blockInfo,
|
||||
Signature: signedHash,
|
||||
GapNumber: 450,
|
||||
}
|
||||
engineV2.VoteHandler(blockchain, voteMsg)
|
||||
signedHash = SignHashByPK(acc1Key, voteSigningHash.Bytes())
|
||||
voteMsg = &utils.Vote{
|
||||
voteMsg = &types.Vote{
|
||||
ProposedBlockInfo: blockInfo,
|
||||
Signature: signedHash,
|
||||
GapNumber: 450,
|
||||
|
|
@ -544,13 +544,13 @@ func TestVoteMessageHandlerWrongGapNumber(t *testing.T) {
|
|||
engineV2.VoteHandler(blockchain, voteMsg)
|
||||
|
||||
// Create a vote message that has wrong gap number
|
||||
voteForSign = &utils.VoteForSign{
|
||||
voteForSign = &types.VoteForSign{
|
||||
ProposedBlockInfo: blockInfo,
|
||||
GapNumber: 451,
|
||||
}
|
||||
voteSigningHash = utils.VoteSigHash(voteForSign)
|
||||
voteSigningHash = types.VoteSigHash(voteForSign)
|
||||
signedHash = SignHashByPK(acc3Key, voteSigningHash.Bytes())
|
||||
voteMsg = &utils.Vote{
|
||||
voteMsg = &types.Vote{
|
||||
ProposedBlockInfo: blockInfo,
|
||||
Signature: signedHash,
|
||||
GapNumber: 451,
|
||||
|
|
@ -565,22 +565,22 @@ func TestVotePoolKeepGoodHygiene(t *testing.T) {
|
|||
blockchain, _, currentBlock, signer, signFn, _ := PrepareXDCTestBlockChainForV2Engine(t, 905, params.TestXDPoSMockChainConfig, nil)
|
||||
engineV2 := blockchain.Engine().(*XDPoS.XDPoS).EngineV2
|
||||
|
||||
blockInfo := &utils.BlockInfo{
|
||||
blockInfo := &types.BlockInfo{
|
||||
Hash: currentBlock.Hash(),
|
||||
Round: utils.Round(5),
|
||||
Round: types.Round(5),
|
||||
Number: big.NewInt(905),
|
||||
}
|
||||
voteForSign := &utils.VoteForSign{
|
||||
voteForSign := &types.VoteForSign{
|
||||
ProposedBlockInfo: blockInfo,
|
||||
GapNumber: 450,
|
||||
}
|
||||
voteSigningHash := utils.VoteSigHash(voteForSign)
|
||||
voteSigningHash := types.VoteSigHash(voteForSign)
|
||||
|
||||
// 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
|
||||
signedHash, _ := signFn(accounts.Account{Address: signer}, voteSigningHash.Bytes())
|
||||
voteMsg := &utils.Vote{
|
||||
voteMsg := &types.Vote{
|
||||
ProposedBlockInfo: blockInfo,
|
||||
Signature: signedHash,
|
||||
GapNumber: 450,
|
||||
|
|
@ -588,22 +588,22 @@ func TestVotePoolKeepGoodHygiene(t *testing.T) {
|
|||
engineV2.VoteHandler(blockchain, voteMsg)
|
||||
|
||||
// Inject a second vote with round 16
|
||||
blockInfo = &utils.BlockInfo{
|
||||
blockInfo = &types.BlockInfo{
|
||||
Hash: currentBlock.Hash(),
|
||||
Round: utils.Round(16),
|
||||
Round: types.Round(16),
|
||||
Number: big.NewInt(906),
|
||||
}
|
||||
voteForSign = &utils.VoteForSign{
|
||||
voteForSign = &types.VoteForSign{
|
||||
ProposedBlockInfo: blockInfo,
|
||||
GapNumber: 450,
|
||||
}
|
||||
voteSigningHash = utils.VoteSigHash(voteForSign)
|
||||
voteSigningHash = types.VoteSigHash(voteForSign)
|
||||
|
||||
// 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
|
||||
signedHash, _ = signFn(accounts.Account{Address: signer}, voteSigningHash.Bytes())
|
||||
voteMsg = &utils.Vote{
|
||||
voteMsg = &types.Vote{
|
||||
ProposedBlockInfo: blockInfo,
|
||||
Signature: signedHash,
|
||||
GapNumber: 450,
|
||||
|
|
@ -611,22 +611,22 @@ func TestVotePoolKeepGoodHygiene(t *testing.T) {
|
|||
engineV2.VoteHandler(blockchain, voteMsg)
|
||||
|
||||
// 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(),
|
||||
Round: utils.Round(25),
|
||||
Round: types.Round(25),
|
||||
Number: big.NewInt(907),
|
||||
}
|
||||
voteForSign = &utils.VoteForSign{
|
||||
voteForSign = &types.VoteForSign{
|
||||
ProposedBlockInfo: blockInfo,
|
||||
GapNumber: 450,
|
||||
}
|
||||
voteSigningHash = utils.VoteSigHash(voteForSign)
|
||||
voteSigningHash = types.VoteSigHash(voteForSign)
|
||||
|
||||
// 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
|
||||
signedHash, _ = signFn(accounts.Account{Address: signer}, voteSigningHash.Bytes())
|
||||
voteMsg = &utils.Vote{
|
||||
voteMsg = &types.Vote{
|
||||
ProposedBlockInfo: blockInfo,
|
||||
Signature: signedHash,
|
||||
GapNumber: 450,
|
||||
|
|
|
|||
117
core/types/consensus_v2.go
Normal file
117
core/types/consensus_v2.go
Normal 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)
|
||||
}
|
||||
|
|
@ -1,15 +1,32 @@
|
|||
package utils
|
||||
package types
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"math/big"
|
||||
"reflect"
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
"github.com/XinFinOrg/XDPoSChain/common"
|
||||
"github.com/XinFinOrg/XDPoSChain/rlp"
|
||||
"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 {
|
||||
round := Round(307)
|
||||
blockInfo := &BlockInfo{Hash: common.BigToHash(big.NewInt(2047)), Round: round - 1, Number: big.NewInt(900)}
|
||||
Loading…
Reference in a new issue