add verifyHeaders option to blockchain.insertChain()

pull/1751/head
Dennis Won 5 years ago
parent 6d37cdb053
commit 7d68c7cc01
  1. 3
      api/service/syncing/syncing.go
  2. 40
      core/blockchain.go
  3. 2
      node/node_handler.go
  4. 10
      test/chain/main.go

@ -545,7 +545,6 @@ func (ss *StateSync) updateBlockAndStatus(block *types.Block, bc *core.BlockChai
utils.Logger().Info().Str("blockHex", bc.CurrentBlock().Hash().Hex()).Msg("[SYNC] Current Block")
// Verify block signatures
// TODO chao: only when block is verified against last commit sigs, we can update the block and status
if block.NumberU64() > 1 {
// Verify signature every 100 blocks
verifySig := block.NumberU64()%100 == 0
@ -560,7 +559,7 @@ func (ss *StateSync) updateBlockAndStatus(block *types.Block, bc *core.BlockChai
}
}
_, err := bc.InsertChain([]*types.Block{block})
_, err := bc.InsertChain([]*types.Block{block}, false /* verifyHeaders */)
if err != nil {
utils.Logger().Error().Err(err).Msgf("[SYNC] Error adding new block to blockchain %d %d", block.NumberU64(), block.ShardID())

@ -814,7 +814,7 @@ func (bc *BlockChain) procFutureBlocks() {
// Insert one by one as chain insertion needs contiguous ancestry between blocks
for i := range blocks {
bc.InsertChain(blocks[i : i+1])
bc.InsertChain(blocks[i:i+1], true /* verifyHeaders */)
}
}
}
@ -1140,8 +1140,8 @@ func (bc *BlockChain) WriteBlockWithState(block *types.Block, receipts []*types.
// wrong.
//
// After insertion is done, all accumulated events will be fired.
func (bc *BlockChain) InsertChain(chain types.Blocks) (int, error) {
n, events, logs, err := bc.insertChain(chain)
func (bc *BlockChain) InsertChain(chain types.Blocks, verifyHeaders bool) (int, error) {
n, events, logs, err := bc.insertChain(chain, verifyHeaders)
bc.PostChainEvents(events, logs)
if err == nil {
for idx, block := range chain {
@ -1190,7 +1190,7 @@ func (bc *BlockChain) InsertChain(chain types.Blocks) (int, error) {
// insertChain will execute the actual chain insertion and event aggregation. The
// only reason this method exists as a separate one is to make locking cleaner
// with deferred statements.
func (bc *BlockChain) insertChain(chain types.Blocks) (int, []interface{}, []*types.Log, error) {
func (bc *BlockChain) insertChain(chain types.Blocks, verifyHeaders bool) (int, []interface{}, []*types.Log, error) {
// Sanity check that we have something meaningful to import
if len(chain) == 0 {
return 0, nil, nil, nil
@ -1205,7 +1205,7 @@ func (bc *BlockChain) insertChain(chain types.Blocks) (int, []interface{}, []*ty
Str("parent", chain[i].ParentHash().Hex()).
Str("prevnumber", chain[i-1].Number().String()).
Str("prevhash", chain[i-1].Hash().Hex()).
Msg("Non contiguous block insert")
Msg("insertChain: non contiguous block insert")
return 0, nil, nil, fmt.Errorf("non contiguous insert: item %d is #%d [%x…], item %d is #%d [%x…] (parent [%x…])", i-1, chain[i-1].NumberU64(),
chain[i-1].Hash().Bytes()[:4], i, chain[i].NumberU64(), chain[i].Hash().Bytes()[:4], chain[i].ParentHash().Bytes()[:4])
@ -1227,16 +1227,23 @@ func (bc *BlockChain) insertChain(chain types.Blocks) (int, []interface{}, []*ty
lastCanon *types.Block
coalescedLogs []*types.Log
)
// Start the parallel header verifier
headers := make([]*block.Header, len(chain))
seals := make([]bool, len(chain))
for i, block := range chain {
headers[i] = block.Header()
seals[i] = true
var verifyHeadersResults <-chan error
// If the block header chain has not been verified, conduct header verification here.
if verifyHeaders {
headers := make([]*block.Header, len(chain))
seals := make([]bool, len(chain))
for i, block := range chain {
headers[i] = block.Header()
seals[i] = true
}
// Note that VerifyHeaders verifies headers in the chain in parallel
abort, results := bc.Engine().VerifyHeaders(bc, headers, seals)
verifyHeadersResults = results
defer close(abort)
}
abort, results := bc.Engine().VerifyHeaders(bc, headers, seals)
defer close(abort)
// Start a parallel signature recovery (signer will fluke on fork transition, minimal perf loss)
//senderCacher.recoverFromBlocks(types.MakeSigner(bc.chainConfig, chain[0].Number()), chain)
@ -1251,7 +1258,10 @@ func (bc *BlockChain) insertChain(chain types.Blocks) (int, []interface{}, []*ty
// Wait for the block's verification to complete
bstart := time.Now()
err := <-results
var err error
if verifyHeaders {
err = <-verifyHeadersResults
}
if err == nil {
err = bc.Validator().ValidateBody(block)
}
@ -1308,7 +1318,7 @@ func (bc *BlockChain) insertChain(chain types.Blocks) (int, []interface{}, []*ty
if len(winner) > 0 {
// Import all the pruned blocks to make the state available
bc.chainmu.Unlock()
_, evs, logs, err := bc.insertChain(winner)
_, evs, logs, err := bc.insertChain(winner, true /* verifyHeaders */)
bc.chainmu.Lock()
events, coalescedLogs = evs, logs

@ -409,7 +409,7 @@ func (node *Node) PostConsensusProcessing(newBlock *types.Block, commitSigAndBit
// AddNewBlock is usedd to add new block into the blockchain.
func (node *Node) AddNewBlock(newBlock *types.Block) error {
_, err := node.Blockchain().InsertChain([]*types.Block{newBlock})
_, err := node.Blockchain().InsertChain([]*types.Block{newBlock}, true /* verifyHeaders */)
if err != nil {
utils.Logger().Error().
Err(err).

@ -130,7 +130,7 @@ func fundFaucetContract(chain *core.BlockChain) {
fmt.Println(err)
}
block, _ := contractworker.FinalizeNewBlock([]byte{}, []byte{}, 0, common.Address{}, nil, nil)
_, err = chain.InsertChain(types.Blocks{block})
_, err = chain.InsertChain(types.Blocks{block}, true /* verifyHeaders */)
if err != nil {
fmt.Println(err)
}
@ -171,7 +171,7 @@ func callFaucetContractToFundAnAddress(chain *core.BlockChain) {
fmt.Println(err)
}
block, _ := contractworker.FinalizeNewBlock([]byte{}, []byte{}, 0, common.Address{}, nil, nil)
_, err = chain.InsertChain(types.Blocks{block})
_, err = chain.InsertChain(types.Blocks{block}, true /* verifyHeaders */)
if err != nil {
fmt.Println(err)
}
@ -247,7 +247,7 @@ func playStaking(chain *core.BlockChain) {
fmt.Println(err)
}
block, _ := contractworker.FinalizeNewBlock([]byte{}, []byte{}, 0, common.Address{}, nil, nil)
_, err = chain.InsertChain(types.Blocks{block})
_, err = chain.InsertChain(types.Blocks{block}, true /* verifyHeaders */)
if err != nil {
fmt.Println(err)
}
@ -306,7 +306,7 @@ func playWithdrawStaking(chain *core.BlockChain) {
}
block, _ := contractworker.FinalizeNewBlock([]byte{}, []byte{}, 0, common.Address{}, nil, nil)
_, err = chain.InsertChain(types.Blocks{block})
_, err = chain.InsertChain(types.Blocks{block}, true /* verifyHeaders */)
if err != nil {
fmt.Println(err)
}
@ -350,7 +350,7 @@ func main() {
gen.SetShardID(0)
gen.AddTx(pendingTxs[i])
})
if _, err := chain.InsertChain(blocks); err != nil {
if _, err := chain.InsertChain(blocks, true /* verifyHeaders */); err != nil {
log.Fatal(err)
}
}

Loading…
Cancel
Save