|
|
|
@ -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 |
|
|
|
|
|
|
|
|
|