From 455cacc1b7ab75fc2bbf1d25c508d363c2d89593 Mon Sep 17 00:00:00 2001 From: Jerome Date: Sun, 22 May 2022 11:43:25 +1000 Subject: [PATCH] move XDC consensus types into core (#93) --- consensus/XDPoS/engines/engine_v2/engine.go | 82 +++--- .../XDPoS/engines/engine_v2/epochSwitch.go | 17 +- .../XDPoS/engines/engine_v2/forensics.go | 42 +-- .../XDPoS/engines/engine_v2/forensics_test.go | 44 +-- consensus/XDPoS/engines/engine_v2/mining.go | 2 +- .../XDPoS/engines/engine_v2/testing_utils.go | 16 +- consensus/XDPoS/engines/engine_v2/timeout.go | 23 +- consensus/XDPoS/engines/engine_v2/utils.go | 18 +- consensus/XDPoS/engines/engine_v2/vote.go | 28 +- consensus/XDPoS/utils/errors.go | 10 +- consensus/XDPoS/utils/pool_test.go | 9 +- consensus/XDPoS/utils/types.go | 122 --------- consensus/XDPoS/utils/utils.go | 11 + .../tests/engine_v2_tests/adaptor_test.go | 37 ++- .../tests/engine_v2_tests/forensics_test.go | 32 +-- consensus/tests/engine_v2_tests/helper.go | 24 +- .../tests/engine_v2_tests/initial_test.go | 25 +- consensus/tests/engine_v2_tests/mine_test.go | 12 +- .../tests/engine_v2_tests/penalty_test.go | 10 +- .../engine_v2_tests/proposed_block_test.go | 97 +++---- .../tests/engine_v2_tests/sync_info_test.go | 37 +-- .../tests/engine_v2_tests/timeout_test.go | 114 ++++---- .../engine_v2_tests/verify_blockinfo_test.go | 22 +- .../engine_v2_tests/verify_header_test.go | 38 +-- consensus/tests/engine_v2_tests/vote_test.go | 258 +++++++++--------- core/types/consensus_v2.go | 117 ++++++++ .../types/consensus_v2_test.go | 19 +- 27 files changed, 646 insertions(+), 620 deletions(-) create mode 100644 core/types/consensus_v2.go rename consensus/XDPoS/utils/types_test.go => core/types/consensus_v2_test.go (86%) diff --git a/consensus/XDPoS/engines/engine_v2/engine.go b/consensus/XDPoS/engines/engine_v2/engine.go index d3d944db2e..eaa4c8b704 100644 --- a/consensus/XDPoS/engines/engine_v2/engine.go +++ b/consensus/XDPoS/engines/engine_v2/engine.go @@ -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, diff --git a/consensus/XDPoS/engines/engine_v2/epochSwitch.go b/consensus/XDPoS/engines/engine_v2/epochSwitch.go index 45dc074324..e3787c42ff 100644 --- a/consensus/XDPoS/engines/engine_v2/epochSwitch.go +++ b/consensus/XDPoS/engines/engine_v2/epochSwitch.go @@ -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 { diff --git a/consensus/XDPoS/engines/engine_v2/forensics.go b/consensus/XDPoS/engines/engine_v2/forensics.go index ea7c577846..4f0750a7d3 100644 --- a/consensus/XDPoS/engines/engine_v2/forensics.go +++ b/consensus/XDPoS/engines/engine_v2/forensics.go @@ -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 diff --git a/consensus/XDPoS/engines/engine_v2/forensics_test.go b/consensus/XDPoS/engines/engine_v2/forensics_test.go index 358beda50e..85206587c6 100644 --- a/consensus/XDPoS/engines/engine_v2/forensics_test.go +++ b/consensus/XDPoS/engines/engine_v2/forensics_test.go @@ -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) diff --git a/consensus/XDPoS/engines/engine_v2/mining.go b/consensus/XDPoS/engines/engine_v2/mining.go index 5d3805e32d..fdc1325f4a 100644 --- a/consensus/XDPoS/engines/engine_v2/mining.go +++ b/consensus/XDPoS/engines/engine_v2/mining.go @@ -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 diff --git a/consensus/XDPoS/engines/engine_v2/testing_utils.go b/consensus/XDPoS/engines/engine_v2/testing_utils.go index 8a6f94c6b3..033cd7fb31 100644 --- a/consensus/XDPoS/engines/engine_v2/testing_utils.go +++ b/consensus/XDPoS/engines/engine_v2/testing_utils.go @@ -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 } diff --git a/consensus/XDPoS/engines/engine_v2/timeout.go b/consensus/XDPoS/engines/engine_v2/timeout.go index 1327400b29..ece20cfe23 100644 --- a/consensus/XDPoS/engines/engine_v2/timeout.go +++ b/consensus/XDPoS/engines/engine_v2/timeout.go @@ -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, diff --git a/consensus/XDPoS/engines/engine_v2/utils.go b/consensus/XDPoS/engines/engine_v2/utils.go index 1efbf66c67..8830bfa21d 100644 --- a/consensus/XDPoS/engines/engine_v2/utils.go +++ b/consensus/XDPoS/engines/engine_v2/utils.go @@ -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 } diff --git a/consensus/XDPoS/engines/engine_v2/vote.go b/consensus/XDPoS/engines/engine_v2/vote.go index dc6f3c94ad..eaf3034567 100644 --- a/consensus/XDPoS/engines/engine_v2/vote.go +++ b/consensus/XDPoS/engines/engine_v2/vote.go @@ -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 diff --git a/consensus/XDPoS/utils/errors.go b/consensus/XDPoS/utils/errors.go index 2dfbb6d538..275cf6ce49 100644 --- a/consensus/XDPoS/utils/errors.go +++ b/consensus/XDPoS/utils/errors.go @@ -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 { diff --git a/consensus/XDPoS/utils/pool_test.go b/consensus/XDPoS/utils/pool_test.go index e4b6ab63b3..6a94afa3e8 100644 --- a/consensus/XDPoS/utils/pool_test.go +++ b/consensus/XDPoS/utils/pool_test.go @@ -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) diff --git a/consensus/XDPoS/utils/types.go b/consensus/XDPoS/utils/types.go index 13a21d1246..4f55973cfd 100644 --- a/consensus/XDPoS/utils/types.go +++ b/consensus/XDPoS/utils/types.go @@ -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) -} diff --git a/consensus/XDPoS/utils/utils.go b/consensus/XDPoS/utils/utils.go index 4c3d5a90a1..0bf8924fe9 100644 --- a/consensus/XDPoS/utils/utils.go +++ b/consensus/XDPoS/utils/utils.go @@ -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 +} diff --git a/consensus/tests/engine_v2_tests/adaptor_test.go b/consensus/tests/engine_v2_tests/adaptor_test.go index d097147857..1c1649ccca 100644 --- a/consensus/tests/engine_v2_tests/adaptor_test.go +++ b/consensus/tests/engine_v2_tests/adaptor_test.go @@ -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() diff --git a/consensus/tests/engine_v2_tests/forensics_test.go b/consensus/tests/engine_v2_tests/forensics_test.go index 9bfddd00d6..cc5c2ae9dd 100644 --- a/consensus/tests/engine_v2_tests/forensics_test.go +++ b/consensus/tests/engine_v2_tests/forensics_test.go @@ -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) diff --git a/consensus/tests/engine_v2_tests/helper.go b/consensus/tests/engine_v2_tests/helper.go index 89939b716b..0fd2014e20 100644 --- a/consensus/tests/engine_v2_tests/helper.go +++ b/consensus/tests/engine_v2_tests/helper.go @@ -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() diff --git a/consensus/tests/engine_v2_tests/initial_test.go b/consensus/tests/engine_v2_tests/initial_test.go index 5693762c24..9d9a7d9b21 100644 --- a/consensus/tests/engine_v2_tests/initial_test.go +++ b/consensus/tests/engine_v2_tests/initial_test.go @@ -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 diff --git a/consensus/tests/engine_v2_tests/mine_test.go b/consensus/tests/engine_v2_tests/mine_test.go index e4879c2cb7..61cec63647 100644 --- a/consensus/tests/engine_v2_tests/mine_test.go +++ b/consensus/tests/engine_v2_tests/mine_test.go @@ -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) } diff --git a/consensus/tests/engine_v2_tests/penalty_test.go b/consensus/tests/engine_v2_tests/penalty_test.go index 7b766ace61..cadab500b3 100644 --- a/consensus/tests/engine_v2_tests/penalty_test.go +++ b/consensus/tests/engine_v2_tests/penalty_test.go @@ -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) diff --git a/consensus/tests/engine_v2_tests/proposed_block_test.go b/consensus/tests/engine_v2_tests/proposed_block_test.go index 265a1a302c..28742b3f49 100644 --- a/consensus/tests/engine_v2_tests/proposed_block_test.go +++ b/consensus/tests/engine_v2_tests/proposed_block_test.go @@ -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) diff --git a/consensus/tests/engine_v2_tests/sync_info_test.go b/consensus/tests/engine_v2_tests/sync_info_test.go index 3e1b095d84..8219b37a4e 100644 --- a/consensus/tests/engine_v2_tests/sync_info_test.go +++ b/consensus/tests/engine_v2_tests/sync_info_test.go @@ -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, } diff --git a/consensus/tests/engine_v2_tests/timeout_test.go b/consensus/tests/engine_v2_tests/timeout_test.go index 5497b3b2ea..54a571eba9 100644 --- a/consensus/tests/engine_v2_tests/timeout_test.go +++ b/consensus/tests/engine_v2_tests/timeout_test.go @@ -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 diff --git a/consensus/tests/engine_v2_tests/verify_blockinfo_test.go b/consensus/tests/engine_v2_tests/verify_blockinfo_test.go index 36bf0d7dec..68778d899d 100644 --- a/consensus/tests/engine_v2_tests/verify_blockinfo_test.go +++ b/consensus/tests/engine_v2_tests/verify_blockinfo_test.go @@ -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) diff --git a/consensus/tests/engine_v2_tests/verify_header_test.go b/consensus/tests/engine_v2_tests/verify_header_test.go index e8bec43968..d2ddb32965 100644 --- a/consensus/tests/engine_v2_tests/verify_header_test.go +++ b/consensus/tests/engine_v2_tests/verify_header_test.go @@ -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() diff --git a/consensus/tests/engine_v2_tests/vote_test.go b/consensus/tests/engine_v2_tests/vote_test.go index 59f047c9f2..71d92c405c 100644 --- a/consensus/tests/engine_v2_tests/vote_test.go +++ b/consensus/tests/engine_v2_tests/vote_test.go @@ -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, diff --git a/core/types/consensus_v2.go b/core/types/consensus_v2.go new file mode 100644 index 0000000000..78a20e787b --- /dev/null +++ b/core/types/consensus_v2.go @@ -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) +} diff --git a/consensus/XDPoS/utils/types_test.go b/core/types/consensus_v2_test.go similarity index 86% rename from consensus/XDPoS/utils/types_test.go rename to core/types/consensus_v2_test.go index 549fe7c179..55687f150b 100644 --- a/consensus/XDPoS/utils/types_test.go +++ b/core/types/consensus_v2_test.go @@ -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)}