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

Method computeStateDB

protocols/cpc/api_tracer.go:485–556  ·  view source on GitHub ↗

computeStateDB retrieves the state database associated with a certain block. If no state is locally available for the given block, a number of blocks are attempted to be reexecuted to generate the desired state.

(block *types.Block, reexec uint64)

Source from the content-addressed store, hash-verified

483// If no state is locally available for the given block, a number of blocks are
484// attempted to be reexecuted to generate the desired state.
485func (api *PrivateDebugAPI) computeStateDB(block *types.Block, reexec uint64) (*state.StateDB, error) {
486 // If we have the state fully available, use that
487 pubStateDB, err := api.cpc.blockchain.StateAt(block.StateRoot())
488 if err == nil {
489 return pubStateDB, nil
490 }
491 // Otherwise try to reexec blocks until we find a state or reach our limit
492 origin := block.NumberU64()
493 database := state.NewDatabase(api.cpc.ChainDb())
494
495 for i := uint64(0); i < reexec; i++ {
496 block = api.cpc.blockchain.GetBlock(block.ParentHash(), block.NumberU64()-1)
497 if block == nil {
498 break
499 }
500 if pubStateDB, err = state.New(block.StateRoot(), database); err == nil {
501 break
502 }
503 }
504 if err != nil {
505 switch err.(type) {
506 case *trie.MissingNodeError:
507 return nil, errors.New("required historical state unavailable")
508 default:
509 return nil, err
510 }
511 }
512 // State was available at historical point, regenerate
513 var (
514 start = time.Now()
515 logged time.Time
516 proot common.Hash
517 )
518 for block.NumberU64() < origin {
519 // Print progress logs if long enough time elapsed
520 if time.Since(logged) > 8*time.Second {
521 log.Info("Regenerating historical state", "block", block.NumberU64()+1, "target", origin, "elapsed", time.Since(start))
522 logged = time.Now()
523 }
524 // Retrieve the next block to regenerate and process it
525 if block = api.cpc.blockchain.GetBlockByNumber(block.NumberU64() + 1); block == nil {
526 return nil, fmt.Errorf("block #%d not found", block.NumberU64()+1)
527 }
528
529 // TODO: check if below statement is correct.
530 privStateDB, _ := state.New(core.GetPrivateStateRoot(api.cpc.chainDb, block.StateRoot()), pubStateDB.Database())
531 // TODO: pass real remote database.
532 _, _, _, _, err := api.cpc.blockchain.Processor().Process(block, pubStateDB, privStateDB, nil, vm.Config{})
533 if err != nil {
534 return nil, err
535 }
536 // Finalize the state so any modifications are written to the trie
537 root, err := pubStateDB.Commit(true)
538 if err != nil {
539 return nil, err
540 }
541 if err := pubStateDB.Reset(root); err != nil {
542 return nil, err

Callers 2

traceBlockMethod · 0.95
computeTxEnvMethod · 0.95

Calls 15

TrieDBMethod · 0.95
StateRootMethod · 0.80
NumberU64Method · 0.80
ParentHashMethod · 0.80
ProcessorMethod · 0.80
StateAtMethod · 0.65
ChainDbMethod · 0.65
GetBlockMethod · 0.65
NowMethod · 0.65
InfoMethod · 0.65
GetBlockByNumberMethod · 0.65
DatabaseMethod · 0.65

Tested by

no test coverage detected