func(api*DebugAPI)AccountRange(blockNrOrHashrpc.BlockNumberOrHash,starthexutil.Bytes,maxResultsint,nocode,nostorage,incompletesbool)(state.IteratorDump,error){varstateDb*state.StateDBvarerrerrorifnumber,ok:=blockNrOrHash.Number();ok{ifnumber==rpc.PendingBlockNumber{_,stateDb=api.eth.miner.Pending()}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.IteratorDump{},fmt.Errorf("block #%d not found",number)}header=block.Header()}ifheader==nil{returnstate.IteratorDump{},fmt.Errorf("block #%d not found",number)}stateDb,err=api.eth.BlockChain().StateAt(header.Root)iferr!=nil{returnstate.IteratorDump{},err}}}elseifhash,ok:=blockNrOrHash.Hash();ok{block:=api.eth.blockchain.GetBlockByHash(hash)ifblock==nil{returnstate.IteratorDump{},fmt.Errorf("block %s not found",hash.Hex())}stateDb,err=api.eth.BlockChain().StateAt(block.Root())iferr!=nil{returnstate.IteratorDump{},err}}else{returnstate.IteratorDump{},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.IteratorDump(opts),nil}// AccountRange enumerates all accounts in the given block and start point in paging request
func(*HandlerT)BacktraceAt(locationstring)error{returnglogger.BacktraceAt(location)}// BacktraceAt sets the log backtrace location. See package log for details on// the pattern syntax.
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{forb:=byte(0);b<255;b++{log.Info("Compacting chain database","range",fmt.Sprintf("0x%0.2X-0x%0.2X",b,b+1))iferr:=api.b.ChainDb().Compact([// ChaindbCompact flattens the entire key-value database into a single level,// removing all unused slots and merging all keys.]byte{b},[]byte{b+1});err!=nil{log.Error("Database compaction failed","err",err)returnerr}}returnnil}
func(api*DebugAPI)ChaindbProperty(propertystring)(string,error){ifproperty==""{property="leveldb.stats"}elseif!strings.HasPrefix(property,"leveldb."){property="leveldb."+property}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){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){tx,_,_,_,err:=s.b.GetTransaction(ctx,hash)iferr!=nil{returnnil,err}iftx==nil{iftx=s.b.GetPoolTransaction(hash);tx==nil{returnnil,nil}}returntx.MarshalBinary()}// GetRawTransaction returns the bytes of the transaction for the given hash.
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.
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()st,err:=statedb.StorageTrie(contractAddress)iferr!=nil{returnStorageRangeResult{},err}ifst==nil{returnStorageRangeResult{},fmt.Errorf("account %x doesn't exist",contractAddress)}returnstorageRangeAt(st,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.Decode(bytes.NewReader(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.
func(api*API)TraceCall(ctxcontext.Context,argsethapi.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{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}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(),block.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.// 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){tx,blockHash,blockNumber,index,err:=api.backend.GetTransaction(ctx,hash)iferr!=nil{returnnil,err}iftx==nil{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(log.Lvl(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.