MCPcopy Create free account
hub / github.com/CPChain/chain / insertChain

Method insertChain

core/blockchain.go:1304–1573  ·  view source on GitHub ↗

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.

(chain types.Blocks)

Source from the content-addressed store, hash-verified

1302// only reason this method exists as a separate one is to make locking cleaner
1303// with deferred statements.
1304func (bc *BlockChain) insertChain(chain types.Blocks) (int, []interface{}, []*types.Log, error) {
1305 // Sanity check that we have something meaningful to import
1306 if len(chain) == 0 {
1307 return 0, nil, nil, nil
1308 }
1309 // Do a sanity check that the provided chain is actually ordered and linked
1310 for i := 1; i < len(chain); i++ {
1311 if chain[i].NumberU64() != chain[i-1].NumberU64()+1 || chain[i].ParentHash() != chain[i-1].Hash() {
1312 // Chain broke ancestry, log a messge (programming error) and skip insertion
1313 log.Error("Non contiguous block insert", "number", chain[i].Number(), "hash", chain[i].Hash().Hex(),
1314 "parent", chain[i].ParentHash().Hex(), "prevnumber", chain[i-1].Number(), "prevhash", chain[i-1].Hash().Hex())
1315 return 0, nil, nil, ErrInvalidChain
1316 }
1317 }
1318
1319 bc.chainmu.Lock()
1320 defer bc.chainmu.Unlock()
1321
1322 // A queued approach to delivering events. This is generally
1323 // faster than direct delivery and requires much less mutex
1324 // acquiring.
1325 var (
1326 stats = insertStats{startTime: mclock.Now()}
1327 events = make([]interface{}, 0, len(chain))
1328 lastCanon *types.Block
1329 coalescedLogs []*types.Log
1330 )
1331 // Start the parallel header verifier
1332 headers := make([]*types.Header, len(chain))
1333 refHeaders := make([]*types.Header, len(chain))
1334 verifySigs := make([]bool, len(chain))
1335
1336 for i, block := range chain {
1337 headers[i] = block.Header()
1338 refHeaders[i] = block.RefHeader()
1339 verifySigs[i] = true
1340 }
1341 abort, results := bc.engine.VerifyHeaders(bc, headers, verifySigs, refHeaders)
1342 defer close(abort)
1343
1344 // Start a parallel signature recovery (signer will fluke on fork transition, minimal perf loss)
1345 senderCacher.recoverFromBlocks(types.MakeSigner(bc.chainConfig), chain)
1346
1347 // Iterate over the blocks and insert when the verifier permits
1348 for i, block := range chain {
1349 // update known head if it is necessary
1350 _, headN := bc.KnownHead()
1351
1352 if bc.CurrentBlock() != nil && bc.CurrentBlock().NumberU64() > headN {
1353 bc.SetKnownHead(bc.CurrentBlock().Hash(), bc.CurrentBlock().NumberU64())
1354 }
1355
1356 // If the chain is terminating, stop processing blocks
1357 if atomic.LoadInt32(&bc.procInterrupt) == 1 {
1358 log.Debug("Premature abort during blocks processing")
1359 break
1360 }
1361 // If the header is a banned one, straight out abort

Callers 1

InsertChainMethod · 0.95

Calls 15

NumberU64Method · 0.95
ParentHashMethod · 0.95
KnownHeadMethod · 0.95
CurrentBlockMethod · 0.95
SetKnownHeadMethod · 0.95
reportBlockMethod · 0.95
GetBlockByNumberMethod · 0.95
ValidatorMethod · 0.95
GetBlockMethod · 0.95
HasStateMethod · 0.95
StateRootMethod · 0.95

Tested by

no test coverage detected