Skip to content

Commit

Permalink
Xin 138 (ethereum#49)
Browse files Browse the repository at this point in the history
* check block header after vote pool reached

* refactor test_helper to fix issues with tests randomly failing
  • Loading branch information
wjrjerome authored Jan 30, 2022
1 parent dc15891 commit 328d555
Show file tree
Hide file tree
Showing 12 changed files with 258 additions and 233 deletions.
12 changes: 12 additions & 0 deletions consensus/XDPoS/engines/engine_v2/engine.go
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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
}
Expand Down
7 changes: 6 additions & 1 deletion consensus/XDPoS/utils/pool.go
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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)
}
Expand Down
10 changes: 9 additions & 1 deletion consensus/XDPoS/utils/pool_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand All @@ -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)
Expand Down
40 changes: 13 additions & 27 deletions consensus/tests/adaptor_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down Expand Up @@ -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())
Expand All @@ -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)
Expand Down
55 changes: 18 additions & 37 deletions consensus/tests/authorised_masternode_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -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)
}
Expand All @@ -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)
Expand All @@ -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"))
Expand All @@ -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)

}
Loading

0 comments on commit 328d555

Please sign in to comment.