github.com/ava-labs/subnet-evm@v0.6.4/internal/ethapi/api_extra.go (about) 1 // (c) 2019-2024, Ava Labs, Inc. All rights reserved. 2 // See the file LICENSE for licensing terms. 3 4 package ethapi 5 6 import ( 7 "context" 8 "fmt" 9 "math/big" 10 11 "github.com/ava-labs/subnet-evm/commontype" 12 "github.com/ava-labs/subnet-evm/core" 13 "github.com/ava-labs/subnet-evm/core/types" 14 "github.com/ava-labs/subnet-evm/params" 15 "github.com/ava-labs/subnet-evm/rpc" 16 "github.com/ethereum/go-ethereum/common" 17 "github.com/ethereum/go-ethereum/common/hexutil" 18 "github.com/ethereum/go-ethereum/rlp" 19 ) 20 21 func (s *BlockChainAPI) GetChainConfig(ctx context.Context) *params.ChainConfigWithUpgradesJSON { 22 return s.b.ChainConfig().ToWithUpgradesJSON() 23 } 24 25 type DetailedExecutionResult struct { 26 UsedGas uint64 `json:"gas"` // Total used gas but include the refunded gas 27 ErrCode int `json:"errCode"` // EVM error code 28 Err string `json:"err"` // Any error encountered during the execution(listed in core/vm/errors.go) 29 ReturnData hexutil.Bytes `json:"returnData"` // Data from evm(function result or data supplied with revert opcode) 30 } 31 32 // CallDetailed performs the same call as Call, but returns the full context 33 func (s *BlockChainAPI) CallDetailed(ctx context.Context, args TransactionArgs, blockNrOrHash rpc.BlockNumberOrHash, overrides *StateOverride) (*DetailedExecutionResult, error) { 34 result, err := DoCall(ctx, s.b, args, blockNrOrHash, overrides, nil, s.b.RPCEVMTimeout(), s.b.RPCGasCap()) 35 if err != nil { 36 return nil, err 37 } 38 39 reply := &DetailedExecutionResult{ 40 UsedGas: result.UsedGas, 41 ReturnData: result.ReturnData, 42 } 43 if result.Err != nil { 44 if err, ok := result.Err.(rpc.Error); ok { 45 reply.ErrCode = err.ErrorCode() 46 } 47 reply.Err = result.Err.Error() 48 } 49 // If the result contains a revert reason, try to unpack and return it. 50 if len(result.Revert()) > 0 { 51 err := newRevertError(result.Revert()) 52 reply.ErrCode = err.ErrorCode() 53 reply.Err = err.Error() 54 } 55 return reply, nil 56 } 57 58 // Note: this API is moved directly from ./eth/api.go to ensure that it is available under an API that is enabled by 59 // default without duplicating the code and serving the same API in the original location as well without creating a 60 // cyclic import. 61 // 62 // BadBlockArgs represents the entries in the list returned when bad blocks are queried. 63 type BadBlockArgs struct { 64 Hash common.Hash `json:"hash"` 65 Block map[string]interface{} `json:"block"` 66 RLP string `json:"rlp"` 67 Reason *core.BadBlockReason `json:"reason"` 68 } 69 70 // GetBadBlocks returns a list of the last 'bad blocks' that the client has seen on the network 71 // and returns them as a JSON list of block hashes. 72 func (s *BlockChainAPI) GetBadBlocks(ctx context.Context) ([]*BadBlockArgs, error) { 73 var ( 74 badBlocks, reasons = s.b.BadBlocks() 75 results = make([]*BadBlockArgs, 0, len(badBlocks)) 76 ) 77 for i, block := range badBlocks { 78 var ( 79 blockRlp string 80 blockJSON map[string]interface{} 81 ) 82 if rlpBytes, err := rlp.EncodeToBytes(block); err != nil { 83 blockRlp = err.Error() // Hacky, but hey, it works 84 } else { 85 blockRlp = fmt.Sprintf("%#x", rlpBytes) 86 } 87 blockJSON = RPCMarshalBlock(block, true, true, s.b.ChainConfig()) 88 results = append(results, &BadBlockArgs{ 89 Hash: block.Hash(), 90 RLP: blockRlp, 91 Block: blockJSON, 92 Reason: reasons[i], 93 }) 94 } 95 return results, nil 96 } 97 98 type FeeConfigResult struct { 99 FeeConfig commontype.FeeConfig `json:"feeConfig"` 100 LastChangedAt *big.Int `json:"lastChangedAt,omitempty"` 101 } 102 103 func (s *BlockChainAPI) FeeConfig(ctx context.Context, blockNrOrHash *rpc.BlockNumberOrHash) (*FeeConfigResult, error) { 104 var ( 105 header *types.Header 106 err error 107 ) 108 if blockNrOrHash == nil { 109 header = s.b.CurrentHeader() 110 } else { 111 header, err = s.b.HeaderByNumberOrHash(ctx, *blockNrOrHash) 112 if err != nil { 113 return nil, err 114 } 115 } 116 117 feeConfig, lastChangedAt, err := s.b.GetFeeConfigAt(header) 118 if err != nil { 119 return nil, err 120 } 121 return &FeeConfigResult{FeeConfig: feeConfig, LastChangedAt: lastChangedAt}, nil 122 } 123 124 // GetActivePrecompilesAt returns the active precompile configs at the given block timestamp. 125 func (s *BlockChainAPI) GetActivePrecompilesAt(ctx context.Context, blockTimestamp *uint64) params.Precompiles { 126 var timestamp uint64 127 if blockTimestamp == nil { 128 timestamp = s.b.CurrentHeader().Time 129 } else { 130 timestamp = *blockTimestamp 131 } 132 133 return s.b.ChainConfig().EnabledStatefulPrecompiles(timestamp) 134 } 135 136 func (s *BlockChainAPI) GetActiveRulesAt(ctx context.Context, blockTimestamp *uint64) params.Rules { 137 var timestamp uint64 138 if blockTimestamp == nil { 139 timestamp = s.b.CurrentHeader().Time 140 } else { 141 timestamp = *blockTimestamp 142 } 143 return s.b.ChainConfig().Rules(common.Big0, timestamp) 144 }