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

Method SetHead

core/blockchain.go:394–445  ·  view source on GitHub ↗

SetHead rewinds the local chain to a new head. In the case of headers, everything above the new head will be deleted and the new one set. In the case of blocks though, the head may be further rewound if block bodies are missing (non-archive nodes after a fast sync).

(head uint64)

Source from the content-addressed store, hash-verified

392// though, the head may be further rewound if block bodies are missing (non-archive
393// nodes after a fast sync).
394func (bc *BlockChain) SetHead(head uint64) error {
395 log.Warn("Rewinding blockchain", "target", head)
396
397 bc.mu.Lock()
398 defer bc.mu.Unlock()
399
400 // Rewind the header chain, deleting all block bodies until then
401 delFn := func(db rawdb.DatabaseDeleter, hash common.Hash, num uint64) {
402 rawdb.DeleteBody(db, hash, num)
403 }
404 bc.hc.SetHead(head, delFn)
405 currentHeader := bc.hc.CurrentHeader()
406
407 // Clear out any stale content from the caches
408 bc.bodyCache.Purge()
409 bc.bodyRLPCache.Purge()
410 bc.blockCache.Purge()
411 bc.futureBlocks.Purge()
412
413 // Rewind the block chain, ensuring we don't end up with a stateless head block
414 if currentBlock := bc.CurrentBlock(); currentBlock != nil && currentHeader.Number.Uint64() < currentBlock.NumberU64() {
415 bc.currentBlock.Store(bc.GetBlock(currentHeader.Hash(), currentHeader.Number.Uint64()))
416 }
417 if currentBlock := bc.CurrentBlock(); currentBlock != nil {
418 if _, err := state.New(currentBlock.StateRoot(), bc.stateCache); err != nil {
419 // Rewound state missing, rolled back to before pivot, reset to genesis
420 bc.currentBlock.Store(bc.genesisBlock)
421 }
422 if _, err := state.New(GetPrivateStateRoot(bc.db, currentBlock.StateRoot()), bc.privateStateCache); err != nil {
423 // Rewound state missing, rolled back to before pivot, reset to genesis
424 bc.currentBlock.Store(bc.genesisBlock)
425 }
426 }
427 // Rewind the fast block in a simpleton way to the target head
428 if currentFastBlock := bc.CurrentFastBlock(); currentFastBlock != nil && currentHeader.Number.Uint64() < currentFastBlock.NumberU64() {
429 bc.currentFastBlock.Store(bc.GetBlock(currentHeader.Hash(), currentHeader.Number.Uint64()))
430 }
431 // If either blocks reached nil, reset to the genesis state
432 if currentBlock := bc.CurrentBlock(); currentBlock == nil {
433 bc.currentBlock.Store(bc.genesisBlock)
434 }
435 if currentFastBlock := bc.CurrentFastBlock(); currentFastBlock == nil {
436 bc.currentFastBlock.Store(bc.genesisBlock)
437 }
438 currentBlock := bc.CurrentBlock()
439 currentFastBlock := bc.CurrentFastBlock()
440
441 rawdb.WriteHeadBlockHash(bc.db, currentBlock.Hash())
442 rawdb.WriteHeadFastBlockHash(bc.db, currentFastBlock.Hash())
443
444 return bc.loadLastState()
445}
446
447// FastSyncCommitHead sets the current head block to the one defined by the hash
448// irrelevant what the chain contents were prior.

Callers 2

NewBlockChainFunction · 0.95
ResetWithGenesisBlockMethod · 0.95

Calls 14

CurrentBlockMethod · 0.95
GetBlockMethod · 0.95
CurrentFastBlockMethod · 0.95
loadLastStateMethod · 0.95
GetPrivateStateRootFunction · 0.85
LockMethod · 0.80
UnlockMethod · 0.80
Uint64Method · 0.80
NumberU64Method · 0.80
StateRootMethod · 0.80
WarnMethod · 0.65
SetHeadMethod · 0.65

Tested by

no test coverage detected