mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-06-23 23:24:30 +00:00
Xin 138 (#49)
* check block header after vote pool reached * refactor test_helper to fix issues with tests randomly failing
This commit is contained in:
parent
dc15891d1f
commit
328d555b9b
12 changed files with 258 additions and 233 deletions
|
|
@ -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
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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 {
|
||||
|
|
|
|||
|
|
@ -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
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -40,7 +40,7 @@ var (
|
|||
CertThreshold: common.MaxMasternodesV2*2/3 + 1,
|
||||
}
|
||||
TestXDPoSV2Config = &V2{
|
||||
TimeoutWorkerDuration: 5,
|
||||
TimeoutWorkerDuration: 10,
|
||||
CertThreshold: 3,
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue