* check block header after vote pool reached

* refactor test_helper to fix issues with tests randomly failing
This commit is contained in:
Jerome 2022-01-30 13:00:24 +11:00 committed by GitHub
parent dc15891d1f
commit 328d555b9b
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
12 changed files with 258 additions and 233 deletions

View file

@ -568,10 +568,20 @@ func (x *XDPoS_v2) voteHandler(chain consensus.ChainReader, voteMsg *utils.Vote)
thresholdReached, numberOfVotesInPool, pooledVotes := x.votePool.Add(voteMsg)
if thresholdReached {
log.Info(fmt.Sprintf("Vote pool threashold reached: %v, number of items in the pool: %v", thresholdReached, numberOfVotesInPool))
// Check if the block already exist, otherwise we try luck with the next vote
proposedBlock := chain.GetHeaderByHash(voteMsg.ProposedBlockInfo.Hash)
if proposedBlock == nil {
log.Warn("[voteHandler] The proposed block from vote message does not exist yet, wait for the next vote to try again", "Hash", voteMsg.ProposedBlockInfo.Hash, "Round", voteMsg.ProposedBlockInfo.Round)
return nil
}
err := x.onVotePoolThresholdReached(chain, pooledVotes, voteMsg)
if err != nil {
return err
}
// clean up vote at the same poolKey. and pookKey is proposed block hash
x.votePool.ClearPoolKeyByObj(voteMsg)
}
return nil
@ -648,6 +658,8 @@ func (x *XDPoS_v2) timeoutHandler(timeout *utils.Timeout) error {
if err != nil {
return err
}
// clean up timeout message at the same poolKey. and pookKey is proposed block hash
x.timeoutPool.ClearPoolKeyByObj(timeout)
}
return nil
}

View file

@ -31,7 +31,6 @@ func (p *Pool) Add(obj PoolObj) (bool, int, map[common.Hash]PoolObj) {
objListKeyed[obj.Hash()] = obj
numOfItems := len(objListKeyed)
if numOfItems >= p.threshold {
delete(p.objList, poolKey)
return true, numOfItems, objListKeyed
}
return false, numOfItems, objListKeyed
@ -45,6 +44,12 @@ func (p *Pool) Size(obj PoolObj) int {
return len(objListKeyed)
}
// Given the pool object, clear all object under the same pool key
func (p *Pool) ClearPoolKeyByObj(obj PoolObj) {
poolKey := obj.PoolKey()
delete(p.objList, poolKey)
}
func (p *Pool) Clear() {
p.objList = make(map[string]map[common.Hash]PoolObj)
}

View file

@ -13,6 +13,7 @@ func TestPoolAdd(t *testing.T) {
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}}
thresholdReached, numOfItems, pooledTimeouts := pool.Add(&timeout1)
assert.NotNil(pooledTimeouts)
assert.Equal(1, numOfItems)
@ -29,8 +30,15 @@ func TestPoolAdd(t *testing.T) {
assert.NotNil(pooledTimeouts)
assert.Equal(2, numOfItems)
// Try to add one more to the same round, but that round threshold has already been reached, hence deleted
// Try to add one more to the same round, it should also trigger threshold
thresholdReached, numOfItems, pooledTimeouts = pool.Add(&timeout3)
assert.True(thresholdReached)
assert.NotNil(pooledTimeouts)
assert.Equal(3, numOfItems)
// Only after manually clearned the pool at its objKey, we shall not have any value for this particular key
pool.ClearPoolKeyByObj(&timeout3)
thresholdReached, numOfItems, pooledTimeouts = pool.Add(&timeout4)
assert.False(thresholdReached)
assert.NotNil(pooledTimeouts)
assert.Equal(1, numOfItems)

View file

@ -44,10 +44,11 @@ func TestAdaptorShouldGetAuthorForDifferentConsensusVersion(t *testing.T) {
if err != nil {
t.Fatal(err)
}
block11, err := insertBlock(blockchain, header)
block11, err := createBlockFromHeader(blockchain, header, nil)
if err != nil {
t.Fatal(err)
}
blockchain.InsertBlock(block11)
addressFromAdaptor, errorAdaptor = adaptor.Author(block11.Header())
if errorAdaptor != nil {
@ -177,24 +178,17 @@ func TestAdaptorGetMasternodesV2(t *testing.T) {
adaptor := blockchain.Engine().(*XDPoS.XDPoS)
blockNum := 11
blockCoinBase := "0x111000000000000000000000000000000123"
blockHeader := createBlock(params.TestXDPoSMockChainConfigWithV2Engine, currentBlock, blockNum, 1, blockCoinBase, signer, signFn)
// it contains 3 master nodes
blockHeader.Validators = common.Hex2Bytes("0278c350152e15fa6ffc712a5a73d704ce73e2e103d9e17ae3ff2c6712e44e25b09ac5ee91f6c9ff065551f0dcac6f00cae11192d462db709be3758c")
currentBlock = CreateBlock(blockchain, params.TestXDPoSMockChainConfigWithV2Engine, currentBlock, blockNum, 1, blockCoinBase, signer, signFn)
// block 11 is the first v2 block, and is treated as epoch switch block
currentBlock, err := insertBlock(blockchain, blockHeader)
if err != nil {
t.Fatal(err)
}
blockchain.InsertBlock(currentBlock)
masternodes1 := adaptor.GetMasternodes(blockchain, currentBlock.Header())
assert.Equal(t, 3, len(masternodes1))
assert.Equal(t, 4, len(masternodes1))
masternodes1ByNumber := adaptor.GetMasternodesByNumber(blockchain, currentBlock.NumberU64())
assert.True(t, reflect.DeepEqual(masternodes1, masternodes1ByNumber), "at block number", blockNum)
for blockNum = 12; blockNum < 15; blockNum++ {
blockHeader = createBlock(params.TestXDPoSMockChainConfigWithV2Engine, currentBlock, blockNum, int64(blockNum-10), blockCoinBase, signer, signFn)
currentBlock, err = insertBlock(blockchain, blockHeader)
if err != nil {
t.Fatal(err)
}
currentBlock = CreateBlock(blockchain, params.TestXDPoSMockChainConfigWithV2Engine, currentBlock, blockNum, int64(blockNum-10), blockCoinBase, signer, signFn)
blockchain.InsertBlock(currentBlock)
masternodes2 := adaptor.GetMasternodes(blockchain, currentBlock.Header())
assert.True(t, reflect.DeepEqual(masternodes1, masternodes2), "at block number", blockNum)
masternodes2ByNumber := adaptor.GetMasternodesByNumber(blockchain, currentBlock.NumberU64())
@ -215,25 +209,17 @@ func TestGetCurrentEpochSwitchBlock(t *testing.T) {
// V2
blockNum := 11
blockCoinBase := "0x111000000000000000000000000000000123"
blockHeader := createBlock(params.TestXDPoSMockChainConfigWithV2Engine, currentBlock, blockNum, 1, blockCoinBase, signer, signFn)
// it contains 3 master nodes
blockHeader.Validators = common.Hex2Bytes("0278c350152e15fa6ffc712a5a73d704ce73e2e103d9e17ae3ff2c6712e44e25b09ac5ee91f6c9ff065551f0dcac6f00cae11192d462db709be3758c")
// block 11 is the first v2 block, and is treated as epoch switch block
currentBlock, err = insertBlock(blockchain, blockHeader)
if err != nil {
t.Fatal(err)
}
currentBlock = CreateBlock(blockchain, params.TestXDPoSMockChainConfigWithV2Engine, currentBlock, blockNum, 1, blockCoinBase, signer, signFn)
blockchain.InsertBlock(currentBlock)
currentCheckpointNumber, epochNum, err = adaptor.GetCurrentEpochSwitchBlock(blockchain, currentBlock.Number())
assert.Nil(t, err)
assert.Equal(t, uint64(11), currentCheckpointNumber)
assert.Equal(t, uint64(0), epochNum)
for blockNum = 12; blockNum < 15; blockNum++ {
blockHeader = createBlock(params.TestXDPoSMockChainConfigWithV2Engine, currentBlock, blockNum, int64(blockNum-10), blockCoinBase, signer, signFn)
currentBlock, err = insertBlock(blockchain, blockHeader)
if err != nil {
t.Fatal(err)
}
currentBlock = CreateBlock(blockchain, params.TestXDPoSMockChainConfigWithV2Engine, currentBlock, blockNum, int64(blockNum-10), blockCoinBase, signer, signFn)
blockchain.InsertBlock(currentBlock)
currentCheckpointNumber, epochNum, err := adaptor.GetCurrentEpochSwitchBlock(blockchain, currentBlock.Number())
assert.Nil(t, err)
assert.Equal(t, uint64(11), currentCheckpointNumber)

View file

@ -32,7 +32,8 @@ func TestIsAuthorisedMNForConsensusV1(t *testing.T) {
ParentHash: parentBlock.Hash(),
Coinbase: common.HexToAddress(blockCoinbaseA),
}
block449, err := insertBlockTxs(blockchain, header, []*types.Transaction{tx})
block449, err := createBlockFromHeader(blockchain, header, []*types.Transaction{tx})
blockchain.InsertBlock(block449)
if err != nil {
t.Fatal(err)
}
@ -57,10 +58,11 @@ func TestIsAuthorisedMNForConsensusV1(t *testing.T) {
ParentHash: parentBlock.Hash(),
Coinbase: common.HexToAddress(block450CoinbaseAddress),
}
block450, err := insertBlock(blockchain, header)
block450, err := createBlockFromHeader(blockchain, header, nil)
if err != nil {
t.Fatal(err)
}
blockchain.InsertBlock(block450)
isAuthorisedMN = engine.IsAuthorisedAddress(blockchain, block450.Header(), acc3Addr)
assert.False(t, isAuthorisedMN)
@ -75,23 +77,14 @@ func TestIsAuthorisedMNForConsensusV2(t *testing.T) {
adaptor := blockchain.Engine().(*XDPoS.XDPoS)
blockNum := 11
blockCoinBase := "0x111000000000000000000000000000000123"
blockHeader := createBlock(params.TestXDPoSMockChainConfigWithV2Engine, currentBlock, blockNum, 1, blockCoinBase, signer, signFn)
// it contains 3 master nodes
// xdc0278C350152e15fa6FFC712a5A73D704Ce73E2E1
// xdc03d9e17Ae3fF2c6712E44e25B09Ac5ee91f6c9ff
// xdc065551F0dcAC6f00CAe11192D462db709bE3758c
blockHeader.Validators = common.Hex2Bytes("0278c350152e15fa6ffc712a5a73d704ce73e2e103d9e17ae3ff2c6712e44e25b09ac5ee91f6c9ff065551f0dcac6f00cae11192d462db709be3758c")
// block 11 is the first v2 block, and is treated as epoch switch block
currentBlock, err := insertBlock(blockchain, blockHeader)
if err != nil {
t.Fatal(err)
}
currentBlock = CreateBlock(blockchain, params.TestXDPoSMockChainConfigWithV2Engine, currentBlock, blockNum, 1, blockCoinBase, signer, signFn)
blockchain.InsertBlock(currentBlock)
// As long as the address is in the master node list, they are all valid
isAuthorisedMN := adaptor.IsAuthorisedAddress(blockchain, currentBlock.Header(), common.HexToAddress("xdc03d9e17Ae3fF2c6712E44e25B09Ac5ee91f6c9ff"))
isAuthorisedMN := adaptor.IsAuthorisedAddress(blockchain, currentBlock.Header(), common.HexToAddress("xdc0D3ab14BBaD3D99F4203bd7a11aCB94882050E7e"))
assert.True(t, isAuthorisedMN)
isAuthorisedMN = adaptor.IsAuthorisedAddress(blockchain, currentBlock.Header(), common.HexToAddress("xdc065551F0dcAC6f00CAe11192D462db709bE3758c"))
isAuthorisedMN = adaptor.IsAuthorisedAddress(blockchain, currentBlock.Header(), common.HexToAddress("xdc71562b71999873DB5b286dF957af199Ec94617F7"))
assert.True(t, isAuthorisedMN)
isAuthorisedMN = adaptor.IsAuthorisedAddress(blockchain, currentBlock.Header(), common.HexToAddress("xdcbanana"))
@ -105,47 +98,35 @@ func TestIsYourTurnConsensusV2(t *testing.T) {
adaptor := blockchain.Engine().(*XDPoS.XDPoS)
blockNum := 11
blockCoinBase := "0x111000000000000000000000000000000123"
blockHeader := createBlock(params.TestXDPoSMockChainConfigWithV2Engine, currentBlock, blockNum, 1, blockCoinBase, signer, signFn)
// it contains 3 master nodes
// xdc0278C350152e15fa6FFC712a5A73D704Ce73E2E1
// xdc03d9e17Ae3fF2c6712E44e25B09Ac5ee91f6c9ff
// xdc065551F0dcAC6f00CAe11192D462db709bE3758c
blockHeader.Validators = common.Hex2Bytes("0278c350152e15fa6ffc712a5a73d704ce73e2e103d9e17ae3ff2c6712e44e25b09ac5ee91f6c9ff065551f0dcac6f00cae11192d462db709be3758c")
// block 11 is the first v2 block, and is treated as epoch switch block
currentBlock, err := insertBlock(blockchain, blockHeader)
if err != nil {
t.Fatal(err)
}
currentBlock = CreateBlock(blockchain, params.TestXDPoSMockChainConfigWithV2Engine, currentBlock, blockNum, 1, blockCoinBase, signer, signFn)
blockchain.InsertBlock(currentBlock)
// The first address is valid
isYourTurn, err := adaptor.YourTurn(blockchain, currentBlock.Header(), common.HexToAddress("xdc0278C350152e15fa6FFC712a5A73D704Ce73E2E1"))
isYourTurn, err := adaptor.YourTurn(blockchain, currentBlock.Header(), common.HexToAddress("xdc703c4b2bD70c169f5717101CaeE543299Fc946C7"))
assert.Nil(t, err)
assert.True(t, isYourTurn)
// The second and third address are not valid
isYourTurn, err = adaptor.YourTurn(blockchain, currentBlock.Header(), common.HexToAddress("xdc03d9e17Ae3fF2c6712E44e25B09Ac5ee91f6c9ff"))
isYourTurn, err = adaptor.YourTurn(blockchain, currentBlock.Header(), common.HexToAddress("xdc0D3ab14BBaD3D99F4203bd7a11aCB94882050E7e"))
assert.Nil(t, err)
assert.False(t, isYourTurn)
isYourTurn, err = adaptor.YourTurn(blockchain, currentBlock.Header(), common.HexToAddress("xdc065551F0dcAC6f00CAe11192D462db709bE3758c"))
isYourTurn, err = adaptor.YourTurn(blockchain, currentBlock.Header(), common.HexToAddress("xdc71562b71999873DB5b286dF957af199Ec94617F7"))
assert.Nil(t, err)
assert.False(t, isYourTurn)
// We continue to grow the chain which will increase the round number
blockNum = 12
blockHeader = createBlock(params.TestXDPoSMockChainConfigWithV2Engine, currentBlock, blockNum, int64(blockNum-10), blockCoinBase, signer, signFn)
currentBlock, err = insertBlock(blockchain, blockHeader)
if err != nil {
t.Fatal(err)
}
currentBlock = CreateBlock(blockchain, params.TestXDPoSMockChainConfigWithV2Engine, currentBlock, blockNum, int64(blockNum-10), blockCoinBase, signer, signFn)
blockchain.InsertBlock(currentBlock)
adaptor.EngineV2.SetNewRoundFaker(1, false)
isYourTurn, _ = adaptor.YourTurn(blockchain, currentBlock.Header(), common.HexToAddress("xdc0278C350152e15fa6FFC712a5A73D704Ce73E2E1"))
isYourTurn, _ = adaptor.YourTurn(blockchain, currentBlock.Header(), common.HexToAddress("xdc703c4b2bD70c169f5717101CaeE543299Fc946C7"))
assert.False(t, isYourTurn)
isYourTurn, _ = adaptor.YourTurn(blockchain, currentBlock.Header(), common.HexToAddress("xdc03d9e17Ae3fF2c6712E44e25B09Ac5ee91f6c9ff"))
isYourTurn, _ = adaptor.YourTurn(blockchain, currentBlock.Header(), common.HexToAddress("xdc0D3ab14BBaD3D99F4203bd7a11aCB94882050E7e"))
assert.True(t, isYourTurn)
isYourTurn, _ = adaptor.YourTurn(blockchain, currentBlock.Header(), common.HexToAddress("xdc065551F0dcAC6f00CAe11192D462db709bE3758c"))
isYourTurn, _ = adaptor.YourTurn(blockchain, currentBlock.Header(), common.HexToAddress("xdc71562b71999873DB5b286dF957af199Ec94617F7"))
assert.False(t, isYourTurn)
}

View file

@ -33,10 +33,11 @@ func TestNotUpdateSignerListIfNotOnGapBlock(t *testing.T) {
ParentHash: parentBlock.Hash(),
Coinbase: common.HexToAddress(blockCoinbaseA),
}
blockA, err := insertBlockTxs(blockchain, header, []*types.Transaction{tx})
blockA, err := createBlockFromHeader(blockchain, header, []*types.Transaction{tx})
if err != nil {
t.Fatal(err)
}
blockchain.InsertBlock(blockA)
signers, err := GetSnapshotSigner(blockchain, blockA.Header())
if err != nil {
@ -67,10 +68,11 @@ func TestNotChangeSingerListIfNothingProposedOrVoted(t *testing.T) {
ParentHash: parentBlock.Hash(),
Coinbase: common.HexToAddress(blockCoinBase),
}
block, err := insertBlock(blockchain, header)
block, err := createBlockFromHeader(blockchain, header, nil)
if err != nil {
t.Fatal(err)
}
blockchain.InsertBlock(block)
parentSigners, err := GetSnapshotSigner(blockchain, parentBlock.Header())
if err != nil {
t.Fatal(err)
@ -108,10 +110,12 @@ func TestUpdateSignerListIfVotedBeforeGap(t *testing.T) {
ParentHash: parentBlock.Hash(),
Coinbase: common.HexToAddress(blockCoinbaseA),
}
block449, err := insertBlockTxs(blockchain, header, []*types.Transaction{tx})
block449, err := createBlockFromHeader(blockchain, header, []*types.Transaction{tx})
if err != nil {
t.Fatal(err)
}
blockchain.InsertBlock(block449)
parentBlock = block449
signers, err := GetSnapshotSigner(blockchain, block449.Header())
@ -138,10 +142,11 @@ func TestUpdateSignerListIfVotedBeforeGap(t *testing.T) {
ParentHash: parentBlock.Hash(),
Coinbase: common.HexToAddress(block450CoinbaseAddress),
}
block450, err := insertBlock(blockchain, header)
block450, err := createBlockFromHeader(blockchain, header, nil)
if err != nil {
t.Fatal(err)
}
blockchain.InsertBlock(block450)
signers, err = GetSnapshotSigner(blockchain, block450.Header())
if err != nil {
@ -178,10 +183,11 @@ func TestCallUpdateM1WithSmartContractTranscation(t *testing.T) {
ParentHash: currentBlock.Hash(),
Coinbase: common.HexToAddress(blockCoinbaseA),
}
blockA, err := insertBlockTxs(blockchain, header, []*types.Transaction{tx})
blockA, err := createBlockFromHeader(blockchain, header, []*types.Transaction{tx})
if err != nil {
t.Fatal(err)
}
blockchain.InsertBlock(blockA)
signers, err := GetSnapshotSigner(blockchain, blockA.Header())
if err != nil {
@ -226,10 +232,11 @@ func TestCallUpdateM1WhenForkedBlockBackToMainChain(t *testing.T) {
ParentHash: currentBlock.Hash(),
Coinbase: common.HexToAddress(blockCoinbaseA),
}
blockA, err := insertBlockTxs(blockchain, header, []*types.Transaction{tx})
blockA, err := createBlockFromHeader(blockchain, header, []*types.Transaction{tx})
if err != nil {
t.Fatal(err)
}
blockchain.InsertBlock(blockA)
signers, err = GetSnapshotSigner(blockchain, blockA.Header())
if err != nil {
@ -260,10 +267,11 @@ func TestCallUpdateM1WhenForkedBlockBackToMainChain(t *testing.T) {
ParentHash: currentBlock.Hash(),
Coinbase: common.HexToAddress(blockCoinBase450B),
}
block450B, err := insertBlockTxs(blockchain, header, []*types.Transaction{tx})
block450B, err := createBlockFromHeader(blockchain, header, []*types.Transaction{tx})
if err != nil {
t.Fatal(err)
}
blockchain.InsertBlock(block450B)
signers, err = GetSnapshotSigner(blockchain, block450B.Header())
if err != nil {
t.Fatal(err)
@ -289,7 +297,8 @@ func TestCallUpdateM1WhenForkedBlockBackToMainChain(t *testing.T) {
ParentHash: block450B.Hash(),
Coinbase: common.HexToAddress(blockCoinBase451B),
}
block451B, err := insertBlock(blockchain, header)
block451B, err := createBlockFromHeader(blockchain, header, nil)
blockchain.InsertBlock(block451B)
if err != nil {
t.Fatal(err)
@ -371,10 +380,11 @@ func TestStatesShouldBeUpdatedWhenForkedBlockBecameMainChainAtGapBlock(t *testin
ParentHash: parentBlock.Hash(),
Coinbase: common.HexToAddress(blockCoinbaseA),
}
blockA, err := insertBlockTxs(blockchain, header, []*types.Transaction{tx, transferTransaction})
blockA, err := createBlockFromHeader(blockchain, header, []*types.Transaction{tx, transferTransaction})
if err != nil {
t.Fatal(err)
}
blockchain.InsertBlock(blockA)
state, err = blockchain.State()
if err != nil {
t.Fatalf("Failed while trying to get blockchain state")
@ -412,10 +422,11 @@ func TestStatesShouldBeUpdatedWhenForkedBlockBecameMainChainAtGapBlock(t *testin
ParentHash: parentBlock.Hash(),
Coinbase: common.HexToAddress(blockCoinBase450B),
}
block450B, err := insertBlockTxs(blockchain, header, []*types.Transaction{tx, transferTransaction})
block450B, err := createBlockFromHeader(blockchain, header, []*types.Transaction{tx, transferTransaction})
if err != nil {
t.Fatal(err)
}
blockchain.InsertBlock(block450B)
state, err = blockchain.State()
if err != nil {
t.Fatalf("Failed while trying to get blockchain state")
@ -445,11 +456,11 @@ func TestStatesShouldBeUpdatedWhenForkedBlockBecameMainChainAtGapBlock(t *testin
ParentHash: block450B.Hash(),
Coinbase: common.HexToAddress(blockCoinBase451B),
}
block451B, err := insertBlock(blockchain, header)
block451B, err := createBlockFromHeader(blockchain, header, nil)
if err != nil {
t.Fatal(err)
}
blockchain.InsertBlock(block451B)
signers, err = GetSnapshotSigner(blockchain, block450B.Header())
if err != nil {
@ -513,10 +524,11 @@ func TestVoteShouldNotBeAffectedByFork(t *testing.T) {
ParentHash: parentBlock.Hash(),
Coinbase: common.HexToAddress(blockCoinBase450A),
}
block450A, err := insertBlock(blockchain, header)
block450A, err := createBlockFromHeader(blockchain, header, nil)
if err != nil {
t.Fatal(err)
}
blockchain.InsertBlock(block450A)
// Insert 451 A with vote
blockCoinbase451A := "0xaaa0000000000000000000000000000000000451"
@ -532,10 +544,11 @@ func TestVoteShouldNotBeAffectedByFork(t *testing.T) {
ParentHash: block450A.Hash(),
Coinbase: common.HexToAddress(blockCoinbase451A),
}
block451A, err := insertBlockTxs(blockchain, header, []*types.Transaction{tx})
block451A, err := createBlockFromHeader(blockchain, header, []*types.Transaction{tx})
if err != nil {
t.Fatal(err)
}
blockchain.InsertBlock(block451A)
// SignerList should be unchanged as the vote happen after GAP block
signers, err = GetSnapshotSigner(blockchain, block451A.Header())
@ -561,10 +574,11 @@ func TestVoteShouldNotBeAffectedByFork(t *testing.T) {
ParentHash: parentBlock.Hash(),
Coinbase: common.HexToAddress(blockCoinBase450B),
}
block450B, err := insertBlock(blockchain, header)
block450B, err := createBlockFromHeader(blockchain, header, nil)
if err != nil {
t.Fatal(err)
}
blockchain.InsertBlock(block450B)
blockCoinBase451B := "0xbbb0000000000000000000000000000000000451"
merkleRoot = "35999dded35e8db12de7e6c1471eb9670c162eec616ecebbaf4fddd4676fb930"
@ -574,10 +588,11 @@ func TestVoteShouldNotBeAffectedByFork(t *testing.T) {
ParentHash: block450B.Hash(),
Coinbase: common.HexToAddress(blockCoinBase451B),
}
block451B, err := insertBlock(blockchain, header)
block451B, err := createBlockFromHeader(blockchain, header, nil)
if err != nil {
t.Fatal(err)
}
blockchain.InsertBlock(block451B)
blockCoinBase452B := "0xbbb0000000000000000000000000000000000452"
merkleRoot = "35999dded35e8db12de7e6c1471eb9670c162eec616ecebbaf4fddd4676fb930"
@ -587,10 +602,11 @@ func TestVoteShouldNotBeAffectedByFork(t *testing.T) {
ParentHash: block451B.Hash(),
Coinbase: common.HexToAddress(blockCoinBase452B),
}
block452B, err := insertBlock(blockchain, header)
block452B, err := createBlockFromHeader(blockchain, header, nil)
if err != nil {
t.Fatal(err)
}
blockchain.InsertBlock(block452B)
signers, err = GetSnapshotSigner(blockchain, block452B.Header())
if err != nil {
t.Fatal(err)

View file

@ -48,10 +48,11 @@ func TestRaceConditionOnBlockchainReadAndWrite(t *testing.T) {
Coinbase: common.HexToAddress(blockCoinbaseA),
}
blockA, err := insertBlockTxs(blockchain, header, []*types.Transaction{tx, transferTransaction})
blockA, err := createBlockFromHeader(blockchain, header, []*types.Transaction{tx, transferTransaction})
if err != nil {
t.Fatal(err)
}
blockchain.InsertBlock(blockA)
state, err = blockchain.State()
if err != nil {
t.Fatalf("Failed while trying to get blockchain state")
@ -92,10 +93,11 @@ func TestRaceConditionOnBlockchainReadAndWrite(t *testing.T) {
Difficulty: big.NewInt(2),
}
block450B, err := insertBlockTxs(blockchain, header, []*types.Transaction{tx, transferTransaction})
block450B, err := createBlockFromHeader(blockchain, header, []*types.Transaction{tx, transferTransaction})
if err != nil {
t.Fatal(err)
}
blockchain.InsertBlock(block450B)
if blockchain.CurrentHeader().Hash() != block450B.Hash() {
t.Fatalf("the block with higher difficulty should be current header")
}
@ -129,11 +131,11 @@ func TestRaceConditionOnBlockchainReadAndWrite(t *testing.T) {
Coinbase: common.HexToAddress(blockCoinBase451B),
Difficulty: big.NewInt(3),
}
block451B, err := insertBlock(blockchain, header)
block451B, err := createBlockFromHeader(blockchain, header, nil)
if err != nil {
t.Fatal(err)
}
blockchain.InsertBlock(block451B)
signers, err = GetSnapshotSigner(blockchain, block450B.Header())
if err != nil {

View file

@ -31,10 +31,11 @@ func TestYourTurnInitialV2(t *testing.T) {
Coinbase: common.HexToAddress(blockCoinbaseA),
Extra: common.Hex2Bytes("d7830100018358444388676f312e31352e38856c696e757800000000000000000278c350152e15fa6ffc712a5a73d704ce73e2e103d9e17ae3ff2c6712e44e25b09ac5ee91f6c9ff065551f0dcac6f00cae11192d462db709be3758ccef312ee5eea8d7bad5374c6a652150515d744508b61c1a4deb4e4e7bf057e4e3824c11fd2569bcb77a52905cda63b5a58507910bed335e4c9d87ae0ecdfafd400"),
}
block900, err := insertBlock(blockchain, header)
block900, err := createBlockFromHeader(blockchain, header, nil)
if err != nil {
t.Fatal(err)
}
blockchain.InsertBlock(block900)
// YourTurn is called before mine first v2 block
b, err := adaptor.YourTurn(blockchain, block900.Header(), common.HexToAddress("xdc0278C350152e15fa6FFC712a5A73D704Ce73E2E1"))
@ -85,9 +86,9 @@ func TestUpdateMasterNodes(t *testing.T) {
if err != nil {
t.Fatal(err)
}
parentBlock, err := insertBlockTxs(blockchain, header, []*types.Transaction{tx})
parentBlock, err := createBlockFromHeader(blockchain, header, []*types.Transaction{tx})
assert.Nil(t, err)
blockchain.InsertBlock(parentBlock)
t.Logf("Inserting block from 1351 to 1800...")
for i := 1351; i <= 1800; i++ {
blockCoinbase := fmt.Sprintf("0xaaa000000000000000000000000000000000%4d", i)
@ -103,10 +104,11 @@ func TestUpdateMasterNodes(t *testing.T) {
if err != nil {
t.Fatal(err)
}
block, err := insertBlock(blockchain, header)
block, err := createBlockFromHeader(blockchain, header, nil)
if err != nil {
t.Fatal(err)
}
blockchain.InsertBlock(block)
parentBlock = block
}

View file

@ -43,11 +43,8 @@ func TestShouldSendVoteMsgAndCommitGrandGrandParentBlock(t *testing.T) {
// Insert another Block, but it won't trigger commit
blockNum := 12
blockCoinBase := fmt.Sprintf("0x111000000000000000000000000000000%03d", blockNum)
blockHeader := createBlock(params.TestXDPoSMockChainConfigWithV2Engine, currentBlock, blockNum, 2, blockCoinBase, signer, signFn)
block12, err := insertBlock(blockchain, blockHeader)
if err != nil {
t.Fatal(err)
}
block12 := CreateBlock(blockchain, params.TestXDPoSMockChainConfigWithV2Engine, currentBlock, blockNum, 2, blockCoinBase, signer, signFn)
blockchain.InsertBlock(block12)
err = engineV2.ProposedBlockHandler(blockchain, block12.Header())
if err != nil {
t.Fatal("Fail propose proposedBlock handler", err)
@ -63,11 +60,8 @@ func TestShouldSendVoteMsgAndCommitGrandGrandParentBlock(t *testing.T) {
// Insert one more Block, but still won't trigger commit
blockNum = 13
blockCoinBase = fmt.Sprintf("0x111000000000000000000000000000000%03d", blockNum)
blockHeader = createBlock(params.TestXDPoSMockChainConfigWithV2Engine, block12, blockNum, 3, blockCoinBase, signer, signFn)
block13, err := insertBlock(blockchain, blockHeader)
if err != nil {
t.Fatal(err)
}
block13 := CreateBlock(blockchain, params.TestXDPoSMockChainConfigWithV2Engine, block12, blockNum, 3, blockCoinBase, signer, signFn)
blockchain.InsertBlock(block13)
err = engineV2.ProposedBlockHandler(blockchain, block13.Header())
if err != nil {
t.Fatal("Fail propose proposedBlock handler", err)
@ -84,11 +78,8 @@ func TestShouldSendVoteMsgAndCommitGrandGrandParentBlock(t *testing.T) {
// Insert one more Block, this time will trigger commit
blockNum = 14
blockCoinBase = fmt.Sprintf("0x111000000000000000000000000000000%03d", blockNum)
blockHeader = createBlock(params.TestXDPoSMockChainConfigWithV2Engine, block13, blockNum, 4, blockCoinBase, signer, signFn)
block14, err := insertBlock(blockchain, blockHeader)
if err != nil {
t.Fatal(err)
}
block14 := CreateBlock(blockchain, params.TestXDPoSMockChainConfigWithV2Engine, block13, blockNum, 4, blockCoinBase, signer, signFn)
blockchain.InsertBlock(block14)
err = engineV2.ProposedBlockHandler(blockchain, block14.Header())
if err != nil {
t.Fatal("Fail propose proposedBlock handler", err)
@ -138,11 +129,8 @@ func TestShouldNotCommitIfRoundsNotContinousFor3Rounds(t *testing.T) {
// Injecting new block which have gaps in the round number (Round 7 instead of 6)
blockNum := 16
blockCoinBase := fmt.Sprintf("0x111000000000000000000000000000000%03d", blockNum)
blockHeader := createBlock(params.TestXDPoSMockChainConfigWithV2Engine, currentBlock, blockNum, 7, blockCoinBase, signer, signFn)
block16, err := insertBlock(blockchain, blockHeader)
if err != nil {
t.Fatal(err)
}
block16 := CreateBlock(blockchain, params.TestXDPoSMockChainConfigWithV2Engine, currentBlock, blockNum, 7, blockCoinBase, signer, signFn)
blockchain.InsertBlock(block16)
err = engineV2.ProposedBlockHandler(blockchain, block16.Header())
if err != nil {
t.Fatal("Fail propose proposedBlock handler", err)
@ -162,11 +150,8 @@ func TestShouldNotCommitIfRoundsNotContinousFor3Rounds(t *testing.T) {
blockNum = 17
blockCoinBase = fmt.Sprintf("0x111000000000000000000000000000000%03d", blockNum)
blockHeader = createBlock(params.TestXDPoSMockChainConfigWithV2Engine, block16, blockNum, 8, blockCoinBase, signer, signFn)
block17, err := insertBlock(blockchain, blockHeader)
if err != nil {
t.Fatal(err)
}
block17 := CreateBlock(blockchain, params.TestXDPoSMockChainConfigWithV2Engine, block16, blockNum, 8, blockCoinBase, signer, signFn)
blockchain.InsertBlock(block17)
err = engineV2.ProposedBlockHandler(blockchain, block17.Header())
if err != nil {
t.Fatal("Fail propose proposedBlock handler", err)

View file

@ -225,6 +225,7 @@ func GetCandidateFromCurrentSmartContract(backend bind.ContractBackend, t *testi
return ms
}
// V1 consensus engine
func PrepareXDCTestBlockChain(t *testing.T, numOfBlocks int, chainConfig *params.ChainConfig) (*BlockChain, *backends.SimulatedBackend, *types.Block, common.Address) {
// Preparation
var err error
@ -258,10 +259,11 @@ func PrepareXDCTestBlockChain(t *testing.T, numOfBlocks int, chainConfig *params
ParentHash: currentBlock.Hash(),
Coinbase: common.HexToAddress(blockCoinBase),
}
block, err := insertBlock(blockchain, header)
block, err := createBlockFromHeader(blockchain, header, nil)
if err != nil {
t.Fatal(err)
}
blockchain.InsertBlock(block)
currentBlock = block
}
// Update Signer as there is no previous signer assigned
@ -273,6 +275,7 @@ func PrepareXDCTestBlockChain(t *testing.T, numOfBlocks int, chainConfig *params
return blockchain, backend, currentBlock, signer
}
// V2 concensus engine
func PrepareXDCTestBlockChainForV2Engine(t *testing.T, numOfBlocks int, chainConfig *params.ChainConfig, numOfForkedBlocks int) (*BlockChain, *backends.SimulatedBackend, *types.Block, common.Address, func(account accounts.Account, hash []byte) ([]byte, error), *types.Block) {
// Preparation
var err error
@ -298,46 +301,16 @@ func PrepareXDCTestBlockChainForV2Engine(t *testing.T, numOfBlocks int, chainCon
}
}()
var masternodesFromV1LastEpoch []common.Address
// Insert initial blocks
for i := 1; i <= numOfBlocks; i++ {
blockCoinBase := fmt.Sprintf("0x111000000000000000000000000000000%03d", i)
roundNumber := int64(i) - chainConfig.XDPoS.XDPoSV2Block.Int64()
header := createBlock(chainConfig, currentBlock, i, roundNumber, blockCoinBase, signer, signFn)
// Inject the hardcoded master node list for the last v1 epoch block
if int64(i) == chainConfig.XDPoS.XDPoSV2Block.Int64() {
// reset extra
header.Extra = []byte{}
if len(header.Extra) < utils.ExtraVanity {
header.Extra = append(header.Extra, bytes.Repeat([]byte{0x00}, utils.ExtraVanity-len(header.Extra))...)
}
header.Extra = header.Extra[:utils.ExtraVanity]
var masternodes []common.Address
masternodes = append(masternodes, acc1Addr, acc2Addr, acc3Addr, signer)
masternodesFromV1LastEpoch = masternodes
for _, masternode := range masternodes {
header.Extra = append(header.Extra, masternode[:]...)
}
header.Extra = append(header.Extra, make([]byte, utils.ExtraSeal)...)
block := CreateBlock(blockchain, chainConfig, currentBlock, i, roundNumber, blockCoinBase, signer, signFn)
// Sign all the things for v1 block use v1 sigHash function
sighash, err := signFn(accounts.Account{Address: signer}, blockchain.Engine().(*XDPoS.XDPoS).SigHash(header).Bytes())
if err != nil {
t.Fatal(err)
}
copy(header.Extra[len(header.Extra)-utils.ExtraSeal:], sighash)
} else if (int64(i) == (chainConfig.XDPoS.XDPoSV2Block.Int64() + 1)) && masternodesFromV1LastEpoch != nil { // This is the first v2 block, we need to copy the last v1 epoch master node list and inject into v2 validators
for _, v := range masternodesFromV1LastEpoch {
header.Validators = append(header.Validators, v[:]...)
}
}
block, err := insertBlock(blockchain, header)
err = blockchain.InsertBlock(block)
if err != nil {
t.Fatal(err)
}
// Produce forked block for the last numOfForkedBlocks'th blocks
if numOfForkedBlocks != 0 && i > numOfBlocks-numOfForkedBlocks {
if currentForkBlock == nil {
@ -347,12 +320,9 @@ func PrepareXDCTestBlockChainForV2Engine(t *testing.T, numOfBlocks int, chainCon
forkedBlockRoundNumber := roundNumber + int64(numOfForkedBlocks)
forkedBlockHeader := createBlock(chainConfig, currentForkBlock, i, forkedBlockRoundNumber, forkedBlockCoinBase, signer, signFn)
forkedBlock := CreateBlock(blockchain, chainConfig, currentForkBlock, i, forkedBlockRoundNumber, forkedBlockCoinBase, signer, signFn)
forkedBlock, err := insertBlock(blockchain, forkedBlockHeader)
if err != nil {
t.Fatal(err)
}
blockchain.InsertBlock(forkedBlock)
currentForkBlock = forkedBlock
}
currentBlock = block
@ -367,13 +337,12 @@ func PrepareXDCTestBlockChainForV2Engine(t *testing.T, numOfBlocks int, chainCon
return blockchain, backend, currentBlock, signer, signFn, currentForkBlock
}
func createBlock(chainConfig *params.ChainConfig, startingBlock *types.Block, blockNumIteration int, roundNumber int64, blockCoinBase string, signer common.Address, signFn func(account accounts.Account, hash []byte) ([]byte, error)) *types.Header {
func CreateBlock(blockchain *BlockChain, chainConfig *params.ChainConfig, startingBlock *types.Block, blockNumber int, roundNumber int64, blockCoinBase string, signer common.Address, signFn func(account accounts.Account, hash []byte) ([]byte, error)) *types.Block {
currentBlock := startingBlock
merkleRoot := "35999dded35e8db12de7e6c1471eb9670c162eec616ecebbaf4fddd4676fb930"
var header *types.Header
// Build engine v2 compatible extra data field
if big.NewInt(int64(blockNumIteration)).Cmp(chainConfig.XDPoS.XDPoSV2Block) == 1 {
if big.NewInt(int64(blockNumber)).Cmp(chainConfig.XDPoS.XDPoSV2Block) == 1 { // Build engine v2 compatible extra data field
var extraField utils.ExtraFields_v2
var round utils.Round
err := utils.DecodeBytesExtraFields(currentBlock.Extra(), &extraField)
@ -410,22 +379,59 @@ func createBlock(chainConfig *params.ChainConfig, startingBlock *types.Block, bl
}
header = &types.Header{
Root: common.HexToHash(merkleRoot),
Number: big.NewInt(int64(blockNumIteration)),
Number: big.NewInt(int64(blockNumber)),
ParentHash: currentBlock.Hash(),
Coinbase: common.HexToAddress(blockCoinBase),
Extra: extraInBytes,
Validator: signedHash,
}
if int64(blockNumber) == (chainConfig.XDPoS.XDPoSV2Block.Int64() + 1) { // This is the first v2 block, we need to copy the last v1 epoch master node list and inject into v2 validators
// Get last master node list from last v1 block
lastv1Block := blockchain.GetBlockByNumber(chainConfig.XDPoS.XDPoSV2Block.Uint64())
masternodesFromV1LastEpoch := decodeMasternodesFromHeaderExtra(lastv1Block.Header())
for _, v := range masternodesFromV1LastEpoch {
header.Validators = append(header.Validators, v[:]...)
}
}
} else {
// V1 block
header = &types.Header{
Root: common.HexToHash(merkleRoot),
Number: big.NewInt(int64(blockNumIteration)),
Number: big.NewInt(int64(blockNumber)),
ParentHash: currentBlock.Hash(),
Coinbase: common.HexToAddress(blockCoinBase),
}
// Inject the hardcoded master node list for the last v1 epoch block
if big.NewInt(int64(blockNumber)).Cmp(chainConfig.XDPoS.XDPoSV2Block) == 0 {
// reset extra
header.Extra = []byte{}
if len(header.Extra) < utils.ExtraVanity {
header.Extra = append(header.Extra, bytes.Repeat([]byte{0x00}, utils.ExtraVanity-len(header.Extra))...)
}
header.Extra = header.Extra[:utils.ExtraVanity]
var masternodes []common.Address
masternodes = append(masternodes, acc1Addr, acc2Addr, acc3Addr, signer)
// masternodesFromV1LastEpoch = masternodes
for _, masternode := range masternodes {
header.Extra = append(header.Extra, masternode[:]...)
}
header.Extra = append(header.Extra, make([]byte, utils.ExtraSeal)...)
// Sign all the things for v1 block use v1 sigHash function
sighash, err := signFn(accounts.Account{Address: signer}, blockchain.Engine().(*XDPoS.XDPoS).SigHash(header).Bytes())
if err != nil {
panic(fmt.Errorf("Error when sign last v1 block hash during test block creation"))
}
copy(header.Extra[len(header.Extra)-utils.ExtraSeal:], sighash)
}
}
return header
block, err := createBlockFromHeader(blockchain, header, nil)
if err != nil {
panic(fmt.Errorf("Fail to create block in test helper, %v", err))
}
return block
}
func generateSignature(backend *backends.SimulatedBackend, adaptor *XDPoS.XDPoS, header *types.Header) error {
@ -442,54 +448,7 @@ func generateSignature(backend *backends.SimulatedBackend, adaptor *XDPoS.XDPoS,
return nil
}
// insert Block without transcation attached
func insertBlock(blockchain *BlockChain, header *types.Header) (*types.Block, error) {
header.ReceiptHash = common.HexToHash("0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421")
block, err := createXDPoSTestBlock(
blockchain,
header,
nil,
)
if err != nil {
return nil, err
}
err = blockchain.InsertBlock(block)
if err != nil {
return nil, err
}
return block, nil
}
// insert Block with transcation attached
func insertBlockTxs(blockchain *BlockChain, header *types.Header, txs []*types.Transaction) (*types.Block, error) {
/*
header := types.Header{
Root: common.HexToHash(root),
Number: big.NewInt(int64(blockNum)),
ParentHash: parentBlock.Hash(),
Coinbase: common.HexToAddress(blockCoinBase),
}
*/
header.ReceiptHash = common.HexToHash("0x9319777b782ba2c83a33c995481ff894ac96d9a92a1963091346a3e1e386705c")
block, err := createXDPoSTestBlock(
blockchain,
header,
txs,
)
if err != nil {
return nil, err
}
err = blockchain.InsertBlock(block)
if err != nil {
return nil, err
}
return block, nil
}
//func createXDPoSTestBlock(bc *BlockChain, parentHash, coinbase string, number int, txs []*types.Transaction, receiptHash string, root common.Hash, customExtra []byte, signer common.Address) (*types.Block, error) {
func createXDPoSTestBlock(bc *BlockChain, customHeader *types.Header, txs []*types.Transaction) (*types.Block, error) {
func createBlockFromHeader(bc *BlockChain, customHeader *types.Header, txs []*types.Transaction) (*types.Block, error) {
if customHeader.Extra == nil {
extraSubstring := "d7830100018358444388676f312e31342e31856c696e75780000000000000000b185dc0d0e917d18e5dbf0746be6597d3331dd27ea0554e6db433feb2e81730b20b2807d33a1527bf43cd3bc057aa7f641609c2551ebe2fd575f4db704fbf38101" // Grabbed from existing mainnet block, it does not have any meaning except for the length validation
customHeader.Extra, _ = hex.DecodeString(extraSubstring)
@ -500,28 +459,18 @@ func createXDPoSTestBlock(bc *BlockChain, customHeader *types.Header, txs []*typ
} else {
difficulty = customHeader.Difficulty
}
/*
header := types.Header{
ParentHash: common.HexToHash(parentHash),
UncleHash: types.EmptyUncleHash,
TxHash: types.EmptyRootHash,
// ReceiptHash: types.EmptyRootHash,
ReceiptHash: common.HexToHash(receiptHash),
Root: root,
Coinbase: common.HexToAddress(coinbase),
Difficulty: big.NewInt(int64(1)),
Number: big.NewInt(int64(number)),
GasLimit: 1200000000,
Time: big.NewInt(int64(number * 10)),
Extra: customExtra,
Validator: signer[:],
}
*/
// TODO: check if this is needed
if len(txs) != 0 {
customHeader.ReceiptHash = common.HexToHash("0x9319777b782ba2c83a33c995481ff894ac96d9a92a1963091346a3e1e386705c")
} else {
customHeader.ReceiptHash = common.HexToHash("0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421")
}
header := types.Header{
ParentHash: customHeader.ParentHash,
UncleHash: types.EmptyUncleHash,
TxHash: types.EmptyRootHash,
// ReceiptHash: types.EmptyRootHash,
ParentHash: customHeader.ParentHash,
UncleHash: types.EmptyUncleHash,
TxHash: types.EmptyRootHash,
ReceiptHash: customHeader.ReceiptHash,
Root: customHeader.Root,
Coinbase: customHeader.Coinbase,
@ -543,7 +492,6 @@ func createXDPoSTestBlock(bc *BlockChain, customHeader *types.Header, txs []*typ
return nil, fmt.Errorf("%v when get state", err)
}
gp := new(GasPool).AddGas(header.GasLimit)
// usedGas := uint64(0)
var gasUsed = new(uint64)
var receipts types.Receipts
@ -586,3 +534,12 @@ func createXDPoSTestBlock(bc *BlockChain, customHeader *types.Header, txs []*typ
// return signedTX
// }
// */
// Get masternodes address from checkpoint Header. Only used for v1 last block
func decodeMasternodesFromHeaderExtra(checkpointHeader *types.Header) []common.Address {
masternodes := make([]common.Address, (len(checkpointHeader.Extra)-utils.ExtraVanity-utils.ExtraSeal)/common.AddressLength)
for i := 0; i < len(masternodes); i++ {
copy(masternodes[i][:], checkpointHeader.Extra[utils.ExtraVanity+i*common.AddressLength:])
}
return masternodes
}

View file

@ -1,6 +1,7 @@
package tests
import (
"fmt"
"math/big"
"testing"
@ -24,7 +25,7 @@ func TestVoteMessageHandlerSuccessfullyGeneratedAndProcessQCForFistV2Round(t *te
// Set round to 5
engineV2.SetNewRoundFaker(utils.Round(1), false)
// Create two timeout message which will not reach vote pool threshold
// Create two vote messages which will not reach vote pool threshold
voteMsg := &utils.Vote{
ProposedBlockInfo: blockInfo,
Signature: []byte{1},
@ -79,7 +80,7 @@ func TestVoteMessageHandlerSuccessfullyGeneratedAndProcessQC(t *testing.T) {
// Set round to 5
engineV2.SetNewRoundFaker(utils.Round(5), false)
// Create two timeout message which will not reach vote pool threshold
// Create two vote messages which will not reach vote pool threshold
voteMsg := &utils.Vote{
ProposedBlockInfo: blockInfo,
Signature: []byte{1},
@ -265,3 +266,73 @@ func TestProcessVoteMsgThenTimeoutMsg(t *testing.T) {
currentRound, _, _, _, _ = engineV2.GetProperties()
assert.Equal(t, utils.Round(7), currentRound)
}
func TestVoteMessageShallNotThrowErrorIfBlockNotYetExist(t *testing.T) {
blockchain, _, currentBlock, signer, signFn, _ := PrepareXDCTestBlockChainForV2Engine(t, 15, params.TestXDPoSMockChainConfigWithV2Engine, 0)
engineV2 := blockchain.Engine().(*XDPoS.XDPoS).EngineV2
// Create a new block but don't inject it into the chain yet
blockNum := 16
blockCoinBase := fmt.Sprintf("0x111000000000000000000000000000000%03d", blockNum)
block := CreateBlock(blockchain, params.TestXDPoSMockChainConfigWithV2Engine, currentBlock, blockNum, 6, blockCoinBase, signer, signFn)
blockInfo := &utils.BlockInfo{
Hash: block.Header().Hash(),
Round: utils.Round(6),
Number: big.NewInt(16),
}
// Set round to 6
engineV2.SetNewRoundFaker(utils.Round(6), false)
// Create two vote messages which will not reach vote pool threshold
voteMsg := &utils.Vote{
ProposedBlockInfo: blockInfo,
Signature: []byte{1},
}
err := engineV2.VoteHandler(blockchain, voteMsg)
assert.Nil(t, err)
voteMsg = &utils.Vote{
ProposedBlockInfo: blockInfo,
Signature: []byte{2},
}
err = engineV2.VoteHandler(blockchain, voteMsg)
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{
ProposedBlockInfo: blockInfo,
Signature: []byte{3},
}
err = engineV2.VoteHandler(blockchain, voteMsg)
assert.Nil(t, err)
currentRound, lockQuorumCert, highestQuorumCert, _, _ := engineV2.GetProperties()
// 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(6), currentRound)
// Now, inject the block into the chain
blockchain.InsertBlock(block)
voteMsg = &utils.Vote{
ProposedBlockInfo: blockInfo,
Signature: []byte{4},
}
err = engineV2.VoteHandler(blockchain, voteMsg)
assert.Nil(t, err)
currentRound, lockQuorumCert, highestQuorumCert, _, highestCommitBlock := engineV2.GetProperties()
// The lockQC shall be the parent's QC round number
assert.Equal(t, utils.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)
// Should trigger ProcessQC and trying to commit from blockNum of 16's grandgrandparent which is blockNum 14 with round 4
assert.Equal(t, utils.Round(4), highestCommitBlock.Round)
assert.Equal(t, big.NewInt(14), highestCommitBlock.Number)
}

View file

@ -40,7 +40,7 @@ var (
CertThreshold: common.MaxMasternodesV2*2/3 + 1,
}
TestXDPoSV2Config = &V2{
TimeoutWorkerDuration: 5,
TimeoutWorkerDuration: 10,
CertThreshold: 3,
}