mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-06-21 22:24:32 +00:00
verify headers shall use parent block if not present in the chain (#77)
This commit is contained in:
parent
cb67e8e26a
commit
0241d40699
4 changed files with 88 additions and 19 deletions
|
|
@ -689,16 +689,25 @@ func (x *XDPoS_v2) ProposedBlockHandler(chain consensus.ChainReader, blockHeader
|
|||
*/
|
||||
|
||||
// To be used by different message verification. Verify local DB block info against the received block information(i.e hash, blockNum, round)
|
||||
func (x *XDPoS_v2) VerifyBlockInfo(blockChainReader consensus.ChainReader, blockInfo *utils.BlockInfo) error {
|
||||
func (x *XDPoS_v2) VerifyBlockInfo(blockChainReader consensus.ChainReader, blockInfo *utils.BlockInfo, blockHeader *types.Header) error {
|
||||
/*
|
||||
1. Check if is able to get header by hash from the chain
|
||||
2. Check the header from step 1 matches what's in the blockInfo. This includes the block number and the round
|
||||
*/
|
||||
blockHeader := blockChainReader.GetHeaderByHash(blockInfo.Hash)
|
||||
if blockHeader == nil {
|
||||
log.Warn("[VerifyBlockInfo] No such header in the chain", "BlockInfoHash", blockInfo.Hash.Hex(), "BlockInfoNum", blockInfo.Number, "BlockInfoRound", blockInfo.Round, "currentHeaderNum", blockChainReader.CurrentHeader().Number)
|
||||
return fmt.Errorf("[VerifyBlockInfo] header doesn't exist for the received blockInfo at hash: %v", blockInfo.Hash.Hex())
|
||||
blockHeader = blockChainReader.GetHeaderByHash(blockInfo.Hash)
|
||||
if blockHeader == nil {
|
||||
log.Warn("[VerifyBlockInfo] No such header in the chain", "BlockInfoHash", blockInfo.Hash.Hex(), "BlockInfoNum", blockInfo.Number, "BlockInfoRound", blockInfo.Round, "currentHeaderNum", blockChainReader.CurrentHeader().Number)
|
||||
return fmt.Errorf("[VerifyBlockInfo] header doesn't exist for the received blockInfo at hash: %v", blockInfo.Hash.Hex())
|
||||
}
|
||||
} else {
|
||||
// If blockHeader present, then its value shall consistent with what's provided in the blockInfo
|
||||
if blockHeader.Hash() != blockInfo.Hash {
|
||||
log.Warn("[VerifyBlockInfo] BlockHeader and blockInfo mismatch", "BlockInfoHash", blockInfo.Hash.Hex(), "BlockHeaderHash", blockHeader.Hash())
|
||||
return fmt.Errorf("[VerifyBlockInfo] Provided blockheader does not match what's in the blockInfo")
|
||||
}
|
||||
}
|
||||
|
||||
if blockHeader.Number.Cmp(blockInfo.Number) != 0 {
|
||||
log.Warn("[VerifyBlockInfo] Block Number mismatch", "BlockInfoHash", blockInfo.Hash.Hex(), "BlockInfoNum", blockInfo.Number, "BlockInfoRound", blockInfo.Round, "blockHeaderNum", blockHeader.Number)
|
||||
return fmt.Errorf("[VerifyBlockInfo] chain header number does not match for the received blockInfo at hash: %v", blockInfo.Hash.Hex())
|
||||
|
|
@ -792,7 +801,8 @@ func (x *XDPoS_v2) verifyQC(blockChainReader consensus.ChainReader, quorumCert *
|
|||
log.Error("[verifyQC] gap number mismatch", "BlockInfoHash", quorumCert.ProposedBlockInfo.Hash, "Gap", quorumCert.GapNumber, "GapShouldBe", gapNumber)
|
||||
return fmt.Errorf("gap number mismatch %v", quorumCert)
|
||||
}
|
||||
return x.VerifyBlockInfo(blockChainReader, quorumCert.ProposedBlockInfo)
|
||||
|
||||
return x.VerifyBlockInfo(blockChainReader, quorumCert.ProposedBlockInfo, parentHeader)
|
||||
}
|
||||
|
||||
// Update local QC variables including highestQC & lockQuorumCert, as well as commit the blocks that satisfy the algorithm requirements
|
||||
|
|
|
|||
|
|
@ -77,7 +77,7 @@ func (x *XDPoS_v2) voteHandler(chain consensus.ChainReader, voteMsg *utils.Vote)
|
|||
return nil
|
||||
}
|
||||
|
||||
err := x.VerifyBlockInfo(chain, voteMsg.ProposedBlockInfo)
|
||||
err := x.VerifyBlockInfo(chain, voteMsg.ProposedBlockInfo, nil)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
|
|
|||
|
|
@ -20,7 +20,7 @@ func TestShouldVerifyBlockInfo(t *testing.T) {
|
|||
Round: utils.Round(1),
|
||||
Number: currentBlock.Number(),
|
||||
}
|
||||
err := engineV2.VerifyBlockInfo(blockchain, blockInfo)
|
||||
err := engineV2.VerifyBlockInfo(blockchain, blockInfo, nil)
|
||||
assert.Nil(t, err)
|
||||
|
||||
// Insert another Block, but it won't trigger commit
|
||||
|
|
@ -35,7 +35,7 @@ func TestShouldVerifyBlockInfo(t *testing.T) {
|
|||
Round: utils.Round(2),
|
||||
Number: block902.Number(),
|
||||
}
|
||||
err = engineV2.VerifyBlockInfo(blockchain, blockInfo)
|
||||
err = engineV2.VerifyBlockInfo(blockchain, blockInfo, nil)
|
||||
assert.Nil(t, err)
|
||||
|
||||
blockInfo = &utils.BlockInfo{
|
||||
|
|
@ -43,7 +43,7 @@ func TestShouldVerifyBlockInfo(t *testing.T) {
|
|||
Round: utils.Round(2),
|
||||
Number: currentBlock.Number(),
|
||||
}
|
||||
err = engineV2.VerifyBlockInfo(blockchain, blockInfo)
|
||||
err = engineV2.VerifyBlockInfo(blockchain, blockInfo, nil)
|
||||
assert.NotNil(t, err)
|
||||
|
||||
blockInfo = &utils.BlockInfo{
|
||||
|
|
@ -51,7 +51,7 @@ func TestShouldVerifyBlockInfo(t *testing.T) {
|
|||
Round: utils.Round(3),
|
||||
Number: block902.Number(),
|
||||
}
|
||||
err = engineV2.VerifyBlockInfo(blockchain, blockInfo)
|
||||
err = engineV2.VerifyBlockInfo(blockchain, blockInfo, nil)
|
||||
assert.NotNil(t, err)
|
||||
|
||||
blockInfo = &utils.BlockInfo{
|
||||
|
|
@ -59,6 +59,6 @@ func TestShouldVerifyBlockInfo(t *testing.T) {
|
|||
Round: utils.Round(2),
|
||||
Number: currentBlock.Number(),
|
||||
}
|
||||
err = engineV2.VerifyBlockInfo(blockchain, blockInfo)
|
||||
err = engineV2.VerifyBlockInfo(blockchain, blockInfo, nil)
|
||||
assert.NotNil(t, err)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -235,9 +235,6 @@ func TestShouldVerifyHeaders(t *testing.T) {
|
|||
blockchain, _, _, _, _, _ := PrepareXDCTestBlockChainForV2Engine(t, 910, &config, 0)
|
||||
adaptor := blockchain.Engine().(*XDPoS.XDPoS)
|
||||
|
||||
// var results <-chan error
|
||||
// var abort <-chan struct{}
|
||||
|
||||
// Happy path
|
||||
var happyPathHeaders []*types.Header
|
||||
happyPathHeaders = append(happyPathHeaders, blockchain.GetBlockByNumber(899).Header(), blockchain.GetBlockByNumber(900).Header(), blockchain.GetBlockByNumber(901).Header(), blockchain.GetBlockByNumber(902).Header())
|
||||
|
|
@ -245,10 +242,72 @@ func TestShouldVerifyHeaders(t *testing.T) {
|
|||
var fullVerifies []bool
|
||||
fullVerifies = append(fullVerifies, false, true, true, false)
|
||||
_, results := adaptor.VerifyHeaders(blockchain, happyPathHeaders, fullVerifies)
|
||||
select {
|
||||
case result := <-results:
|
||||
assert.Nil(t, result)
|
||||
case <-time.After(time.Duration(2) * time.Second): // It should be very fast to verify headers
|
||||
t.Fatalf("Taking too long to verify headers")
|
||||
var verified []bool
|
||||
for {
|
||||
select {
|
||||
case result := <-results:
|
||||
if result != nil {
|
||||
panic("Error received while verifying headers")
|
||||
}
|
||||
verified = append(verified, true)
|
||||
case <-time.After(time.Duration(5) * time.Second): // It should be very fast to verify headers
|
||||
if len(verified) == len(happyPathHeaders) {
|
||||
return
|
||||
} else {
|
||||
panic("Suppose to have verified 3 block headers")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestShouldVerifyHeadersEvenIfParentsNotYetWrittenIntoDB(t *testing.T) {
|
||||
b, err := json.Marshal(params.TestXDPoSMockChainConfig)
|
||||
assert.Nil(t, err)
|
||||
configString := string(b)
|
||||
|
||||
var config params.ChainConfig
|
||||
err = json.Unmarshal([]byte(configString), &config)
|
||||
assert.Nil(t, err)
|
||||
// Enable verify
|
||||
config.XDPoS.V2.SkipV2Validation = false
|
||||
// Skip the mining time validation by set mine time to 0
|
||||
config.XDPoS.V2.MinePeriod = 0
|
||||
// Block 901 is the first v2 block with round of 1
|
||||
blockchain, _, block910, signer, signFn, _ := PrepareXDCTestBlockChainForV2Engine(t, 910, &config, 0)
|
||||
adaptor := blockchain.Engine().(*XDPoS.XDPoS)
|
||||
|
||||
var headersTobeVerified []*types.Header
|
||||
|
||||
// Create block 911 but don't write into DB
|
||||
blockNumber := 911
|
||||
roundNumber := int64(blockNumber) - config.XDPoS.V2.SwitchBlock.Int64()
|
||||
block911 := CreateBlock(blockchain, &config, block910, blockNumber, roundNumber, signer.Hex(), signer, signFn, nil)
|
||||
|
||||
// Create block 912 and not write into DB as well
|
||||
blockNumber = 912
|
||||
roundNumber = int64(blockNumber) - config.XDPoS.V2.SwitchBlock.Int64()
|
||||
block912 := CreateBlock(blockchain, &config, block911, blockNumber, roundNumber, signer.Hex(), signer, signFn, nil)
|
||||
|
||||
headersTobeVerified = append(headersTobeVerified, block910.Header(), block911.Header(), block912.Header())
|
||||
// Randomly set full verify
|
||||
var fullVerifies []bool
|
||||
fullVerifies = append(fullVerifies, true, true, true)
|
||||
_, results := adaptor.VerifyHeaders(blockchain, headersTobeVerified, fullVerifies)
|
||||
|
||||
var verified []bool
|
||||
for {
|
||||
select {
|
||||
case result := <-results:
|
||||
if result != nil {
|
||||
panic("Error received while verifying headers")
|
||||
}
|
||||
verified = append(verified, true)
|
||||
case <-time.After(time.Duration(5) * time.Second): // It should be very fast to verify headers
|
||||
if len(verified) == len(headersTobeVerified) {
|
||||
return
|
||||
} else {
|
||||
panic("Suppose to have verified 3 block headers")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue