1717package eth
1818
1919import (
20+ "context"
2021 "errors"
2122 "fmt"
2223 "time"
@@ -56,7 +57,7 @@ var noopReleaser = tracers.StateReleaseFunc(func() {})
5657// - preferDisk: this arg can be used by the caller to signal that even though the 'base' is
5758// provided, it would be preferable to start from a fresh state, if we have it
5859// on disk.
59- func (eth * Ethereum ) StateAtBlock (block * types.Block , reexec uint64 , base * state.StateDB , readOnly bool , preferDisk bool ) (statedb * state.StateDB , release tracers.StateReleaseFunc , err error ) {
60+ func (eth * Ethereum ) StateAtBlock (ctx context. Context , block * types.Block , reexec uint64 , base * state.StateDB , readOnly bool , preferDisk bool ) (statedb * state.StateDB , release tracers.StateReleaseFunc , err error ) {
6061 var (
6162 current * types.Block
6263 database state.Database
@@ -111,6 +112,9 @@ func (eth *Ethereum) StateAtBlock(block *types.Block, reexec uint64, base *state
111112 }
112113 // Database does not have the state for the given block, try to regenerate
113114 for i := uint64 (0 ); i < reexec ; i ++ {
115+ if err := ctx .Err (); err != nil {
116+ return nil , nil , err
117+ }
114118 if current .NumberU64 () == 0 {
115119 return nil , nil , errors .New ("genesis state is missing" )
116120 }
@@ -142,6 +146,9 @@ func (eth *Ethereum) StateAtBlock(block *types.Block, reexec uint64, base *state
142146 parent common.Hash
143147 )
144148 for current .NumberU64 () < origin {
149+ if err := ctx .Err (); err != nil {
150+ return nil , nil , err
151+ }
145152 // Print progress logs if long enough time elapsed
146153 if time .Since (logged ) > 8 * time .Second && report {
147154 log .Info ("Regenerating historical state" , "block" , current .NumberU64 ()+ 1 , "target" , origin , "remaining" , origin - current .NumberU64 ()- 1 , "elapsed" , time .Since (start ))
@@ -182,7 +189,7 @@ func (eth *Ethereum) StateAtBlock(block *types.Block, reexec uint64, base *state
182189}
183190
184191// stateAtTransaction returns the execution environment of a certain transaction.
185- func (eth * Ethereum ) stateAtTransaction (block * types.Block , txIndex int , reexec uint64 ) (core.Message , vm.BlockContext , * state.StateDB , tracers.StateReleaseFunc , error ) {
192+ func (eth * Ethereum ) stateAtTransaction (ctx context. Context , block * types.Block , txIndex int , reexec uint64 ) (core.Message , vm.BlockContext , * state.StateDB , tracers.StateReleaseFunc , error ) {
186193 // Short circuit if it's genesis block.
187194 if block .NumberU64 () == 0 {
188195 return nil , vm.BlockContext {}, nil , nil , errors .New ("no transaction in genesis" )
@@ -194,7 +201,7 @@ func (eth *Ethereum) stateAtTransaction(block *types.Block, txIndex int, reexec
194201 }
195202 // Lookup the statedb of parent block from the live database,
196203 // otherwise regenerate it on the flight.
197- statedb , release , err := eth .StateAtBlock (parent , reexec , nil , true , false )
204+ statedb , release , err := eth .StateAtBlock (ctx , parent , reexec , nil , true , false )
198205 if err != nil {
199206 return nil , vm.BlockContext {}, nil , nil , err
200207 }
0 commit comments