func(api*DebugAPI)AccountRange(blockNrOrHashrpc.BlockNumberOrHash,starthexutil.Bytes,maxResultsint,nocode,nostorage,incompletesbool)(state.Dump,error){varstateDb*state.StateDBvarerrerrorifnumber,ok:=blockNrOrHash.Number();ok{ifnumber==rpc.PendingBlockNumber{_,stateDb=api.eth.miner.Pending()ifstateDb==nil{returnstate.Dump{},errors.New("pending state is not available")}}else{varheader*types.Headerswitchnumber{caserpc.LatestBlockNumber:header=api.eth.blockchain.CurrentBlock()caserpc.FinalizedBlockNumber:header=api.eth.blockchain.CurrentFinalBlock()caserpc.SafeBlockNumber:header=api.eth.blockchain.CurrentSafeBlock()default:block:=api.eth.blockchain.GetBlockByNumber(uint64(number))ifblock==nil{returnstate.Dump{},fmt.Errorf("block #%d not found",number)}header=block.Header()}ifheader==nil{returnstate.Dump{},fmt.Errorf("block #%d not found",number)}stateDb,err=api.eth.BlockChain().StateAt(header.Root)iferr!=nil{returnstate.Dump{},err}}}elseifhash,ok:=blockNrOrHash.Hash();ok{block:=api.eth.blockchain.GetBlockByHash(hash)ifblock==nil{returnstate.Dump{},fmt.Errorf("block %s not found",hash.Hex())}stateDb,err=api.eth.BlockChain().StateAt(block.Root())iferr!=nil{returnstate.Dump{},err}}else{returnstate.Dump{},errors.New("either block number or block hash must be specified")}opts:=&state.DumpConfig{SkipCode:nocode,SkipStorage:nostorage,OnlyWithAddresses:!incompletes,Start:start,Max:uint64(maxResults)}ifmaxResults>AccountRangeMaxResults||maxResults<=0{opts.Max=AccountRangeMaxResults}returnstateDb.RawDump(opts),nil}// AccountRange enumerates all accounts in the given block and start point in paging request
BlockProfile turns on goroutine profiling for nsec seconds and writes profile data to file. It uses a profile rate of 1 for most accurate information. If a different rate is desired, set the rate and write the profile manually.
func(*HandlerT)BlockProfile(filestring,nsecuint)error{runtime.SetBlockProfileRate(1)time.Sleep(time.Duration(nsec)*time.Second)deferruntime.SetBlockProfileRate(0)returnwriteProfile("block",file)}// BlockProfile turns on goroutine profiling for nsec seconds and writes profile data to// file. It uses a profile rate of 1 for most accurate information. If a different rate is// desired, set the rate and write the profile manually.
func(api*DebugAPI)ChaindbCompact()error{cstart:=time.Now()forb:=0;b<=255;b++{var(start=[// ChaindbCompact flattens the entire key-value database into a single level,// removing all unused slots and merging all keys.]byte{byte(b)}end=[]byte{byte(b+1)})ifb==255{end=nil}log.Info("Compacting database","range",fmt.Sprintf("%#X-%#X",start,end),"elapsed",common.PrettyDuration(time.Since(cstart)))iferr:=api.b.ChainDb().Compact(start,end);err!=nil{log.Error("Database compaction failed","err",err)returnerr}}returnnil}
func(api*DebugAPI)ChaindbProperty(propertystring)(string,error){returnapi.b.ChainDb().Stat(property)}// ChaindbProperty returns leveldb properties of the key-value database.
func(h*HandlerT)CpuProfile(filestring,nsecuint)error{iferr:=h.StartCPUProfile(file);err!=nil{returnerr}time.Sleep(time.Duration(nsec)*time.Second)h.StopCPUProfile()returnnil}// CpuProfile turns on CPU profiling for nsec seconds and writes// profile data to file.
func(api*DebugAPI)DbAncient(kindstring,numberuint64)(hexutil.Bytes,error){returnapi.b.ChainDb().Ancient(kind,number)}// DbAncient retrieves an ancient binary blob from the append-only immutable files.// It is a mapping to the `AncientReaderOp.Ancient` method
func(api*DebugAPI)DbAncients()(uint64,error){returnapi.b.ChainDb().Ancients()}// DbAncients returns the ancient item numbers in the ancient store.// It is a mapping to the `AncientReaderOp.Ancients` method
func(api*DebugAPI)DbGet(keystring)(hexutil.Bytes,error){blob,err:=common.ParseHexOrString(key)iferr!=nil{returnnil,err}returnapi.b.ChainDb().Get(blob)}// DbGet returns the raw value of a key stored in the database.
func(api*DebugAPI)DumpBlock(blockNrrpc.BlockNumber)(state.Dump,error){opts:=&state.DumpConfig{OnlyWithAddresses:true,Max:AccountRangeMaxResults}ifblockNr==rpc.PendingBlockNumber{_,stateDb:=api.eth.miner.Pending()returnstateDb.RawDump(opts),nil}varheader*types.HeaderswitchblockNr{caserpc.LatestBlockNumber:header=api.eth.blockchain.CurrentBlock()caserpc.FinalizedBlockNumber:header=api.eth.blockchain.CurrentFinalBlock()caserpc.SafeBlockNumber:header=api.eth.blockchain.CurrentSafeBlock()default:block:=api.eth.blockchain.GetBlockByNumber(uint64(blockNr))ifblock==nil{returnstate.Dump{},fmt.Errorf("block #%d not found",blockNr)}header=block.Header()}ifheader==nil{returnstate.Dump{},fmt.Errorf("block #%d not found",blockNr)}stateDb,err:=api.eth.BlockChain().StateAt(header.Root)iferr!=nil{returnstate.Dump{},err}returnstateDb.RawDump(opts),nil}// DumpBlock retrieves the entire state of the database at a given block.
GetAccessibleState returns the first number where the node has accessible state on disk. Note this being the post-state of that block and the pre-state of the next block. The (from, to) parameters are the sequence of blocks to search, which can go either forwards or backwards
func(api*DebugAPI)GetAccessibleState(from,torpc.BlockNumber)(uint64,error){ifapi.eth.blockchain.TrieDB().Scheme()==rawdb.PathScheme{return0,errors.New("state history is not yet available in path-based scheme")}db:=api.eth.ChainDb()varpivotuint64ifp:=rawdb.ReadLastPivotNumber(db);p!=nil{pivot=*plog.Info("Found fast-sync pivot marker","number",pivot)}varresolveNum=func(numrpc.BlockNumber)(uint64,error){ifnum.Int64()<0{block:=api.eth.blockchain.CurrentBlock()ifblock==nil{return0,errors.New("current block missing")}returnblock.Number.Uint64(),nil}returnuint64(num.Int64()),nil}var(startuint64enduint64delta=int64(1)lastLogtime.Timeerrerror)ifstart,err=resolveNum(from);err!=nil{return0,err}ifend,err=resolveNum(to);err!=nil{return0,err}ifstart==end{return0,errors.New("from and to needs to be different")}ifstart>end{delta=-1}fori:=int64(start);i!=int64(end);i+=delta{iftime.Since(lastLog)>8*time.Second{log.Info("Finding roots","from",start,"to",end,"at",i)lastLog=time.Now()}ifi<int64(pivot){continue}h:=api.eth.BlockChain().GetHeaderByNumber(uint64(i))ifh==nil{return0,fmt.Errorf("missing header %d",i)}ifok,_:=api.eth.ChainDb().Has(h.Root[// GetAccessibleState returns the first number where the node has accessible// state on disk. Note this being the post-state of that block and the pre-state// of the next block.// The (from, to) parameters are the sequence of blocks to search, which can go// either forwards or backwards:]);ok{returnuint64(i),nil}}return0,errors.New("no state found")}
func(api*DebugAPI)GetBadBlocks(ctxcontext.Context)([// GetBadBlocks returns a list of the last 'bad blocks' that the client has seen on the network// and returns them as a JSON list of block hashes.]*BadBlockArgs,error){var(blocks=rawdb.ReadAllBadBlocks(api.eth.chainDb)results=make([]*BadBlockArgs,0,len(blocks)))for_,block:=rangeblocks{var(blockRlpstringblockJSON*ethapi.RPCMarshalBlockT)ifrlpBytes,err:=rlp.EncodeToBytes(block);err!=nil{blockRlp=err.Error()}else{blockRlp=fmt.Sprintf("%#x",rlpBytes)}blockJSON=ethapi.RPCMarshalBlock(block,true,true,api.eth.APIBackend.ChainConfig())results=append(results,&BadBlockArgs{Hash:block.Hash(),RLP:blockRlp,Block:blockJSON})}returnresults,nil}
GetModifiedAccountsByHash returns all accounts that have changed between the two blocks specified. A change is defined as a difference in nonce, balance, code hash, or storage hash.
With one parameter, returns the list of accounts modified in the specified block.
func(api*DebugAPI)GetModifiedAccountsByHash(startHashcommon.Hash,endHash*common.Hash)([// GetModifiedAccountsByHash returns all accounts that have changed between the// two blocks specified. A change is defined as a difference in nonce, balance,// code hash, or storage hash.//// With one parameter, returns the list of accounts modified in the specified block.]common.Address,error){varstartBlock,endBlock*types.BlockstartBlock=api.eth.blockchain.GetBlockByHash(startHash)ifstartBlock==nil{returnnil,fmt.Errorf("start block %x not found",startHash)}ifendHash==nil{endBlock=startBlockstartBlock=api.eth.blockchain.GetBlockByHash(startBlock.ParentHash())ifstartBlock==nil{returnnil,fmt.Errorf("block %x has no parent",endBlock.Number())}}else{endBlock=api.eth.blockchain.GetBlockByHash(*endHash)ifendBlock==nil{returnnil,fmt.Errorf("end block %x not found",*endHash)}}returnapi.getModifiedAccounts(startBlock,endBlock)}
GetModifiedAccountsByNumber returns all accounts that have changed between the two blocks specified. A change is defined as a difference in nonce, balance, code hash, or storage hash.
With one parameter, returns the list of accounts modified in the specified block.
func(api*DebugAPI)GetModifiedAccountsByNumber(startNumuint64,endNum*uint64)([// GetModifiedAccountsByNumber returns all accounts that have changed between the// two blocks specified. A change is defined as a difference in nonce, balance,// code hash, or storage hash.//// With one parameter, returns the list of accounts modified in the specified block.]common.Address,error){varstartBlock,endBlock*types.BlockstartBlock=api.eth.blockchain.GetBlockByNumber(startNum)ifstartBlock==nil{returnnil,fmt.Errorf("start block %x not found",startNum)}ifendNum==nil{endBlock=startBlockstartBlock=api.eth.blockchain.GetBlockByHash(startBlock.ParentHash())ifstartBlock==nil{returnnil,fmt.Errorf("block %x has no parent",endBlock.Number())}}else{endBlock=api.eth.blockchain.GetBlockByNumber(*endNum)ifendBlock==nil{returnnil,fmt.Errorf("end block %d not found",*endNum)}}returnapi.getModifiedAccounts(startBlock,endBlock)}
func(api*DebugAPI)GetRawBlock(ctxcontext.Context,blockNrOrHashrpc.BlockNumberOrHash)(hexutil.Bytes,error){varhashcommon.Hashifh,ok:=blockNrOrHash.Hash();ok{hash=h}else{block,err:=api.b.BlockByNumberOrHash(ctx,blockNrOrHash)iferr!=nil{returnnil,err}hash=block.Hash()}block,_:=api.b.BlockByHash(ctx,hash)ifblock==nil{returnnil,fmt.Errorf("block #%d not found",hash)}returnrlp.EncodeToBytes(block)}// GetRawBlock retrieves the RLP encoded for a single block.
func(api*DebugAPI)GetRawHeader(ctxcontext.Context,blockNrOrHashrpc.BlockNumberOrHash)(hexutil.Bytes,error){varhashcommon.Hashifh,ok:=blockNrOrHash.Hash();ok{hash=h}else{block,err:=api.b.BlockByNumberOrHash(ctx,blockNrOrHash)iferr!=nil{returnnil,err}hash=block.Hash()}header,_:=api.b.HeaderByHash(ctx,hash)ifheader==nil{returnnil,fmt.Errorf("header #%d not found",hash)}returnrlp.EncodeToBytes(header)}// GetRawHeader retrieves the RLP encoding for a single header.
func(api*DebugAPI)GetRawReceipts(ctxcontext.Context,blockNrOrHashrpc.BlockNumberOrHash)([// GetRawReceipts retrieves the binary-encoded receipts of a single block.]hexutil.Bytes,error){varhashcommon.Hashifh,ok:=blockNrOrHash.Hash();ok{hash=h}else{block,err:=api.b.BlockByNumberOrHash(ctx,blockNrOrHash)iferr!=nil{returnnil,err}hash=block.Hash()}receipts,err:=api.b.GetReceipts(ctx,hash)iferr!=nil{returnnil,err}result:=make([]hexutil.Bytes,len(receipts))fori,receipt:=rangereceipts{b,err:=receipt.MarshalBinary()iferr!=nil{returnnil,err}result[i]=b}returnresult,nil}
func(s*DebugAPI)GetRawTransaction(ctxcontext.Context,hashcommon.Hash)(hexutil.Bytes,error){found,tx,_,_,_,err:=s.b.GetTransaction(ctx,hash)if!found{iftx=s.b.GetPoolTransaction(hash);tx!=nil{returntx.MarshalBinary()}iferr==nil{returnnil,nil}returnnil,NewTxIndexingError()}returntx.MarshalBinary()}// GetRawTransaction returns the bytes of the transaction for the given hash.
func(api*DebugAPI)GetTrieFlushInterval()(string,error){ifapi.eth.blockchain.TrieDB().Scheme()==rawdb.PathScheme{return"",errors.New("trie flush interval is undefined for path-based scheme")}returnapi.eth.blockchain.GetTrieFlushInterval().String(),nil}// GetTrieFlushInterval gets the current value of in-memory trie flush interval
func(h*HandlerT)GoTrace(filestring,nsecuint)error{iferr:=h.StartGoTrace(file);err!=nil{returnerr}time.Sleep(time.Duration(nsec)*time.Second)h.StopGoTrace()returnnil}// GoTrace turns on tracing for nsec seconds and writes// trace data to file.
func(api*API)IntermediateRoots(ctxcontext.Context,hashcommon.Hash,config*TraceConfig)([// IntermediateRoots executes a block (bad- or canon- or side-), and returns a list// of intermediate roots: the stateroot after each transaction.]common.Hash,error){block,_:=api.blockByHash(ctx,hash)ifblock==nil{block=rawdb.ReadBadBlock(api.backend.ChainDb(),hash)}ifblock==nil{returnnil,fmt.Errorf("block %#x not found",hash)}ifblock.NumberU64()==0{returnnil,errors.New("genesis is not traceable")}parent,err:=api.blockByNumberAndHash(ctx,rpc.BlockNumber(block.NumberU64()-1),block.ParentHash())iferr!=nil{returnnil,err}reexec:=defaultTraceReexecifconfig!=nil&&config.Reexec!=nil{reexec=*config.Reexec}statedb,release,err:=api.backend.StateAtBlock(ctx,parent,reexec,nil,true,false)iferr!=nil{returnnil,err}deferrelease()var(roots[]common.Hashsigner=types.MakeSigner(api.backend.ChainConfig(),block.Number(),block.Time())chainConfig=api.backend.ChainConfig()vmctx=core.NewEVMBlockContext(block.Header(),api.chainContext(ctx),nil)deleteEmptyObjects=api.backend.ChainConfig().IsEnabled(api.backend.ChainConfig().GetEIP161dTransition,block.Number()))fori,tx:=rangeblock.Transactions(){iferr:=ctx.Err();err!=nil{returnnil,err}var(msg,_=core.TransactionToMessage(tx,signer,block.BaseFee())txContext=core.NewEVMTxContext(msg)vmenv=vm.NewEVM(vmctx,txContext,statedb,chainConfig,vm.Config{}))statedb.SetTxContext(tx.Hash(),i)if_,err:=core.ApplyMessage(vmenv,msg,new(core.GasPool).AddGas(msg.GasLimit));err!=nil{log.Warn("Tracing intermediate roots did not complete","txindex",i,"txhash",tx.Hash(),"err",err)returnroots,nil}roots=append(roots,statedb.IntermediateRoot(deleteEmptyObjects))}returnroots,nil}
MutexProfile turns on mutex profiling for nsec seconds and writes profile data to file. It uses a profile rate of 1 for most accurate information. If a different rate is desired, set the rate and write the profile manually.
func(*HandlerT)MutexProfile(filestring,nsecuint)error{runtime.SetMutexProfileFraction(1)time.Sleep(time.Duration(nsec)*time.Second)deferruntime.SetMutexProfileFraction(0)returnwriteProfile("mutex",file)}// MutexProfile turns on mutex profiling for nsec seconds and writes profile data to file.// It uses a profile rate of 1 for most accurate information. If a different rate is// desired, set the rate and write the profile manually.
func(api*DebugAPI)Preimage(ctxcontext.Context,hashcommon.Hash)(hexutil.Bytes,error){ifpreimage:=rawdb.ReadPreimage(api.eth.ChainDb(),hash);preimage!=nil{returnpreimage,nil}returnnil,errors.New("unknown preimage")}// Preimage is a debug API function that returns the preimage for a sha3 hash, if known.
func(api*DebugAPI)PrintBlock(ctxcontext.Context,numberuint64)(string,error){block,_:=api.b.BlockByNumber(ctx,rpc.BlockNumber(number))ifblock==nil{return"",fmt.Errorf("block #%d not found",number)}returnspew.Sdump(block),nil}// PrintBlock retrieves a block and returns its pretty printed form.
func(api*DebugAPI)SeedHash(ctxcontext.Context,numberuint64)(string,error){block,_:=api.b.BlockByNumber(ctx,rpc.BlockNumber(number))ifblock==nil{return"",fmt.Errorf("block #%d not found",number)}ecip1099FBlock:=api.b.ChainConfig().GetEthashECIP1099Transition()epochLength:=ethash.CalcEpochLength(number,ecip1099FBlock)epoch:=ethash.CalcEpoch(number,epochLength)returnfmt.Sprintf("%#x",ethash.SeedHash(epoch,epochLength)),nil}// SeedHash retrieves the seed hash of a block.
func(*HandlerT)SetGCPercent(vint)int{returndebug.SetGCPercent(v)}// SetGCPercent sets the garbage collection target percentage. It returns the previous// setting. A negative value disables GC.
SetTrieFlushInterval configures how often in-memory tries are persisted to disk. The value is in terms of block processing time, not wall clock. If the value is shorter than the block generation time, or even 0 or negative, the node will flush trie after processing each block (effectively archive mode).
func(api*DebugAPI)SetTrieFlushInterval(intervalstring)error{ifapi.eth.blockchain.TrieDB().Scheme()==rawdb.PathScheme{returnerrors.New("trie flush interval is undefined for path-based scheme")}t,err:=time.ParseDuration(interval)iferr!=nil{returnerr}api.eth.blockchain.SetTrieFlushInterval(t)returnnil}// SetTrieFlushInterval configures how often in-memory tries are persisted// to disk. The value is in terms of block processing time, not wall clock.// If the value is shorter than the block generation time, or even 0 or negative,// the node will flush trie after processing each block (effectively archive mode).
SnapshotGeneratorStatus returns the current state of the snapshot generator, including whether generation is complete, progress counters, and the current marker position. This is useful for monitoring snapshot readiness without watching logs.
func(api*DebugAPI)SnapshotGeneratorStatus()(map// SnapshotGeneratorStatus returns the current state of the snapshot generator,// including whether generation is complete, progress counters, and the current// marker position. This is useful for monitoring snapshot readiness without// watching logs.[string]interface{},error){snaps:=api.eth.blockchain.Snapshots()ifsnaps==nil{returnnil,errors.New("snapshots not enabled")}done,accounts,slots,storage,marker,err:=snaps.GeneratorProgress()iferr!=nil{returnnil,err}result:=map[string]interface{}{"done":done,"accounts":accounts,"slots":slots,"storage":storage,"diskRoot":snaps.DiskRoot()}iflen(marker)>0{result["marker"]=hexutil.Encode(marker)}returnresult,nil}
Stacks returns a printed representation of the stacks of all goroutines. It also permits the following optional filters to be used: - filter: boolean expression of packages to filter for
func(*HandlerT)Stacks(filter*string)string{buf:=new(bytes.Buffer)pprof.Lookup("goroutine").WriteTo(buf,2)iffilter!=nil&&len(*filter)>0{expanded:=*filterexpanded=regexp.MustCompile(`[:/\.A-Za-z0-9_-]+`).ReplaceAllString(expanded,"`$0` in Value")expanded=regexp.MustCompile("!(`[:/\\.A-Za-z0-9_-]+`)").ReplaceAllString(expanded,"$1 not")expanded=strings.ReplaceAll(expanded,"||","or")expanded=strings.ReplaceAll(expanded,"&&","and")log.Info("Expanded filter expression","filter",*filter,"expanded",expanded)expr,err:=bexpr.CreateEvaluator(expanded)iferr!=nil{log.Error("Failed to parse filter expression","expanded",expanded,"err",err)return""}dump:=buf.String()buf.Reset()for_,trace:=// Stacks returns a printed representation of the stacks of all goroutines. It// also permits the following optional filters to be used:// - filter: boolean expression of packages to filter forrangestrings.Split(dump,"\n\n"){ifok,_:=expr.Evaluate(map[string]string{"Value":trace});ok{buf.WriteString(trace)buf.WriteString("\n\n")}}}returnbuf.String()}
StandardTraceBadBlockToFile dumps the structured logs created during the execution of EVM against a block pulled from the pool of bad ones to the local file system and returns a list of files to the caller.
func(api*API)StandardTraceBadBlockToFile(ctxcontext.Context,hashcommon.Hash,config*StdTraceConfig)([// StandardTraceBadBlockToFile dumps the structured logs created during the// execution of EVM against a block pulled from the pool of bad ones to the// local file system and returns a list of files to the caller.]string,error){block:=rawdb.ReadBadBlock(api.backend.ChainDb(),hash)ifblock==nil{returnnil,fmt.Errorf("bad block %#x not found",hash)}returnapi.standardTraceBlockToFile(ctx,block,config)}
StandardTraceBlockToFile dumps the structured logs created during the execution of EVM to the local file system and returns a list of files to the caller.
func(api*API)StandardTraceBlockToFile(ctxcontext.Context,hashcommon.Hash,config*StdTraceConfig)([// StandardTraceBlockToFile dumps the structured logs created during the// execution of EVM to the local file system and returns a list of files// to the caller.]string,error){block,err:=api.blockByHash(ctx,hash)iferr!=nil{returnnil,err}returnapi.standardTraceBlockToFile(ctx,block,config)}
func(h*HandlerT)StartCPUProfile(filestring)error{h.mu.Lock()deferh.mu.Unlock()ifh.cpuW!=nil{returnerrors.New("CPU profiling already in progress")}f,err:=os.Create(expandHome(file))iferr!=nil{returnerr}iferr:=pprof.StartCPUProfile(f);err!=nil{f.Close()returnerr}h.cpuW=fh.cpuFile=filelog.Info("CPU profiling started","dump",h.cpuFile)returnnil}// StartCPUProfile turns on CPU profiling, writing to the given file.
func(h*HandlerT)StartGoTrace(filestring)error{h.mu.Lock()deferh.mu.Unlock()ifh.traceW!=nil{returnerrors.New("trace already in progress")}f,err:=os.Create(expandHome(file))iferr!=nil{returnerr}iferr:=trace.Start(f);err!=nil{f.Close()returnerr}h.traceW=fh.traceFile=filelog.Info("Go tracing started","dump",h.traceFile)returnnil}// StartGoTrace turns on tracing, writing to the given file.
func(h*HandlerT)StopCPUProfile()error{h.mu.Lock()deferh.mu.Unlock()pprof.StopCPUProfile()ifh.cpuW==nil{returnerrors.New("CPU profiling not in progress")}log.Info("Done writing CPU profile","dump",h.cpuFile)h.cpuW.Close()h.cpuW=nilh.cpuFile=""returnnil}// StopCPUProfile stops an ongoing CPU profile.
func(h*HandlerT)StopGoTrace()error{h.mu.Lock()deferh.mu.Unlock()trace.Stop()ifh.traceW==nil{returnerrors.New("trace not in progress")}log.Info("Done writing Go trace","dump",h.traceFile)h.traceW.Close()h.traceW=nilh.traceFile=""returnnil}// StopGoTrace stops an ongoing trace.
func(api*DebugAPI)StorageRangeAt(ctxcontext.Context,blockNrOrHashrpc.BlockNumberOrHash,txIndexint,contractAddresscommon.Address,keyStarthexutil.Bytes,maxResultint)(StorageRangeResult,error){varblock*types.Blockblock,err:=api.eth.APIBackend.BlockByNumberOrHash(ctx,blockNrOrHash)iferr!=nil{returnStorageRangeResult{},err}ifblock==nil{returnStorageRangeResult{},fmt.Errorf("block %v not found",blockNrOrHash)}_,_,statedb,release,err:=api.eth.stateAtTransaction(ctx,block,txIndex,0)iferr!=nil{returnStorageRangeResult{},err}deferrelease()returnstorageRangeAt(statedb,block.Root(),contractAddress,keyStart,maxResult)}// StorageRangeAt returns the storage at the given block height and transaction index.
Subscribe creates a subscription to an event channel. Subscriptions are not available over HTTP; they are only available over WS, IPC, and Process connections.
func(sub*RPCDebugSubscription)Subscribe(subscriptionNameRPCDebugSubscriptionParamsName,subscriptionOptionsinterface{})(subscriptionIDrpc.ID,errerror){return}// Subscribe creates a subscription to an event channel.// Subscriptions are not available over HTTP; they are only available over WS, IPC, and Process connections.
TraceBadBlock returns the structured logs created during the execution of EVM against a block pulled from the pool of bad ones and returns them as a JSON object.
func(api*API)TraceBadBlock(ctxcontext.Context,hashcommon.Hash,config*TraceConfig)([// TraceBadBlock returns the structured logs created during the execution of// EVM against a block pulled from the pool of bad ones and returns them as a JSON// object.]*txTraceResult,error){block:=rawdb.ReadBadBlock(api.backend.ChainDb(),hash)ifblock==nil{returnnil,fmt.Errorf("bad block %#x not found",hash)}returnapi.traceBlock(ctx,block,config)}
func(api*API)TraceBlock(ctxcontext.Context,blobhexutil.Bytes,config*TraceConfig)([// TraceBlock returns the structured logs created during the execution of EVM// and returns them as a JSON object.]*txTraceResult,error){block:=new(types.Block)iferr:=rlp.DecodeBytes(blob,block);err!=nil{returnnil,fmt.Errorf("could not decode block: %v",err)}returnapi.traceBlock(ctx,block,config)}
func(api*API)TraceBlockByHash(ctxcontext.Context,hashcommon.Hash,config*TraceConfig)([// TraceBlockByHash returns the structured logs created during the execution of// EVM and returns them as a JSON object.]*txTraceResult,error){block,err:=api.blockByHash(ctx,hash)iferr!=nil{returnnil,err}returnapi.traceBlock(ctx,block,config)}
func(api*API)TraceBlockByNumber(ctxcontext.Context,numberrpc.BlockNumber,config*TraceConfig)([// TraceBlockByNumber returns the structured logs created during the execution of// EVM and returns them as a JSON object.]*txTraceResult,error){block,err:=api.blockByNumber(ctx,number)iferr!=nil{returnnil,err}returnapi.traceBlock(ctx,block,config)}
func(api*API)TraceBlockFromFile(ctxcontext.Context,filestring,config*TraceConfig)([// TraceBlockFromFile returns the structured logs created during the execution of// EVM and returns them as a JSON object.]*txTraceResult,error){blob,err:=os.ReadFile(file)iferr!=nil{returnnil,fmt.Errorf("could not read file: %v",err)}returnapi.TraceBlock(ctx,blob,config)}
TraceCall lets you trace a given eth_call. It collects the structured logs created during the execution of EVM if the given transaction was added on top of the provided block and returns them as a JSON object. If no transaction index is specified, the trace will be conducted on the state after executing the specified block. However, if a transaction index is provided, the trace will be conducted on the state after executing the specified transaction within the specified block.
func(api*API)TraceCall(ctxcontext.Context,argsethapi.TransactionArgs,blockNrOrHashrpc.BlockNumberOrHash,config*TraceCallConfig)(interface{},error){var(errerrorblock*types.Blockstatedb*state.StateDBreleaseStateReleaseFunc)ifhash,ok:=blockNrOrHash.Hash();ok{block,err=api.blockByHash(ctx,hash)}elseifnumber,ok:=blockNrOrHash.Number();ok{ifnumber==rpc.PendingBlockNumber{returnnil,errors.New("tracing on top of pending is not supported")}block,err=api.blockByNumber(ctx,number)}else{returnnil,errors.New("invalid arguments; neither block nor hash specified")}iferr!=nil{returnnil,err}reexec:=defaultTraceReexecifconfig!=nil&&config.Reexec!=nil{reexec=*config.Reexec}ifconfig!=nil&&config.TxIndex!=nil{_,_,statedb,release,err=api.backend.StateAtTransaction(ctx,block,int(*config.TxIndex),reexec)}else{statedb,release,err=api.backend.StateAtBlock(ctx,block,reexec,nil,true,false)}iferr!=nil{returnnil,err}deferrelease()vmctx:=core.NewEVMBlockContext(block.Header(),api.chainContext(ctx),nil)ifconfig!=nil{iferr:=config.StateOverrides.Apply(statedb);err!=nil{returnnil,err}config.BlockOverrides.Apply(&vmctx)}msg,err:=args.ToMessage(api.backend.RPCGasCap(),vmctx.BaseFee)iferr!=nil{returnnil,err}traceConfig:=getTraceConfigFromTraceCallConfig(config)returnapi.traceTx(ctx,msg,new(Context),vmctx,statedb,traceConfig)}// TraceCall lets you trace a given eth_call. It collects the structured logs// created during the execution of EVM if the given transaction was added on// top of the provided block and returns them as a JSON object.// If no transaction index is specified, the trace will be conducted on the state// after executing the specified block. However, if a transaction index is provided,// the trace will be conducted on the state after executing the specified transaction// within the specified block.// Try to retrieve the specified block
TraceCallMany lets you trace a given eth_call. It collects the structured logs created during the execution of EVM if the given transaction was added on top of the provided block and returns them as a JSON object. You can provide -2 as a block number to trace on top of the pending block.
func(api*API)TraceCallMany(ctxcontext.Context,txs[// TraceCallMany lets you trace a given eth_call. It collects the structured logs created during the execution of EVM// if the given transaction was added on top of the provided block and returns them as a JSON object.// You can provide -2 as a block number to trace on top of the pending block.]ethapi.TransactionArgs,blockNrOrHashrpc.BlockNumberOrHash,config*TraceCallConfig)(interface{},error){var(errerrorblock*types.Block)ifhash,ok:=blockNrOrHash.Hash();ok{block,err=api.blockByHash(ctx,hash)}elseifnumber,ok:=blockNrOrHash.Number();ok{block,err=api.blockByNumber(ctx,number)}else{returnnil,errors.New("invalid arguments; neither block nor hash specified")}iferr!=nil{returnnil,err}reexec:=defaultTraceReexecifconfig!=nil&&config.Reexec!=nil{reexec=*config.Reexec}statedb,release,err:=api.backend.StateAtBlock(ctx,block,reexec,nil,true,false)iferr!=nil{returnnil,err}deferrelease()ifconfig!=nil{iferr:=config.StateOverrides.Apply(statedb);err!=nil{returnnil,err}}traceConfig:=getTraceConfigFromTraceCallConfig(config)varresults=make([// Try to retrieve the specified block]interface{},len(txs))foridx,args:=rangetxs{msg,err:=args.ToMessage(api.backend.RPCGasCap(),block.BaseFee())iferr!=nil{results[idx]=&txTraceResult{Error:err.Error()}continue}vmctx:=core.NewEVMBlockContext(block.Header(),api.chainContext(ctx),nil)res,err:=api.traceTx(ctx,msg,new(Context),vmctx,statedb,traceConfig)iferr!=nil{results[idx]=&txTraceResult{Error:err.Error()}continue}res,err=decorateResponse(res,traceConfig)iferr!=nil{returnnil,fmt.Errorf("failed to decorate response for transaction at index %d with error %v",idx,err)}results[idx]=res}returnresults,nil}
func(api*API)TraceChain(ctxcontext.Context,start,endrpc.BlockNumber,config*TraceConfig)(*rpc.Subscription,error){from,err:=api.blockByNumber(ctx,start)iferr!=nil{returnnil,err}to,err:=api.blockByNumber(ctx,end)iferr!=nil{returnnil,err}iffrom.Number().Cmp(to.Number())>=0{returnnil,fmt.Errorf("end block (#%d) needs to come after start block (#%d)",end,start)}notifier,supported:=rpc.NotifierFromContext(ctx)if!supported{return&rpc.Subscription{},rpc.ErrNotificationsUnsupported}sub:=notifier.CreateSubscription()resCh:=api.traceChain(from,to,config,notifier.Closed())gofunc(){forresult:=// TraceChain returns the structured logs created during the execution of EVM// between two blocks (excluding start) and returns them as a JSON object.rangeresCh{notifier.Notify(sub.ID,result)}}()returnsub,nil}
func(api*API)TraceTransaction(ctxcontext.Context,hashcommon.Hash,config*TraceConfig)(interface{},error){found,_,blockHash,blockNumber,index,err:=api.backend.GetTransaction(ctx,hash)iferr!=nil{returnnil,ethapi.NewTxIndexingError()}if!found{returnnil,errTxNotFound}ifblockNumber==0{returnnil,errors.New("genesis is not traceable")}reexec:=defaultTraceReexecifconfig!=nil&&config.Reexec!=nil{reexec=*config.Reexec}block,err:=api.blockByNumberAndHash(ctx,rpc.BlockNumber(blockNumber),blockHash)iferr!=nil{returnnil,err}msg,vmctx,statedb,release,err:=api.backend.StateAtTransaction(ctx,block,int(index),reexec)iferr!=nil{returnnil,err}deferrelease()txctx:=&Context{BlockHash:blockHash,BlockNumber:block.Number(),TxIndex:int(index),TxHash:hash}returnapi.traceTx(ctx,msg,txctx,vmctx,statedb,config)}// TraceTransaction returns the structured logs created during the execution of EVM// and returns them as a JSON object.
func(*HandlerT)Verbosity(levelint){glogger.Verbosity(slog.Level(level))}// Verbosity sets the log verbosity ceiling. The verbosity of individual packages// and source files can be raised using Vmodule.
func(*HandlerT)Vmodule(patternstring)error{returnglogger.Vmodule(pattern)}// Vmodule sets the log verbosity pattern. See package log for details on the// pattern syntax.
func(*HandlerT)WriteBlockProfile(filestring)error{returnwriteProfile("block",file)}// WriteBlockProfile writes a goroutine blocking profile to the given file.
WriteMemProfile writes an allocation profile to the given file. Note that the profiling rate cannot be set through the API, it must be set on the command line.
func(*HandlerT)WriteMemProfile(filestring)error{returnwriteProfile("heap",file)}// WriteMemProfile writes an allocation profile to the given file.// Note that the profiling rate cannot be set through the API,// it must be set on the command line.
func(*HandlerT)WriteMutexProfile(filestring)error{returnwriteProfile("mutex",file)}// WriteMutexProfile writes a goroutine blocking profile to the given file.