diff --git a/pkg/eth/api.go b/pkg/eth/api.go index b7da0051..c00e385e 100644 --- a/pkg/eth/api.go +++ b/pkg/eth/api.go @@ -481,6 +481,28 @@ func (pea *PublicEthAPI) GetRawTransactionByHash(ctx context.Context, hash commo return nil, err } +// accessListResult returns an optional accesslist +// Its the result of the `debug_createAccessList` RPC call. +// It contains an error if the transaction itself failed. +type accessListResult struct { + Accesslist *types.AccessList `json:"accessList"` + Error string `json:"error,omitempty"` + GasUsed hexutil.Uint64 `json:"gasUsed"` +} + +// CreateAccessList creates a EIP-2930 type AccessList for the given transaction. +// Reexec and BlockNrOrHash can be specified to create the accessList on top of a certain state. +func (pea *PublicEthAPI) CreateAccessList(ctx context.Context, args TransactionArgs, blockNrOrHash *rpc.BlockNumberOrHash) (*accessListResult, error) { + if pea.proxyOnError { + var res *accessListResult + if err := pea.rpc.CallContext(ctx, &res, "eth_createAccessList", args, blockNrOrHash); err != nil { + return nil, err + } + return res, nil + } + return nil, RequiresProxyError{method: "eth_createAccessList"} +} + /* Receipts and Logs diff --git a/pkg/eth/errors.go b/pkg/eth/errors.go new file mode 100644 index 00000000..7b6ac0a8 --- /dev/null +++ b/pkg/eth/errors.go @@ -0,0 +1,17 @@ +package eth + +import "fmt" + +type RequiresProxyError struct { + method string +} + +var _ error = RequiresProxyError{} + +func (e RequiresProxyError) SetMethod(method string) { + e.method = method +} + +func (e RequiresProxyError) Error() string { + return fmt.Sprintf("%s requires a configured proxy geth node", e.method) +} diff --git a/pkg/eth/transaction_arguments.go b/pkg/eth/transaction_arguments.go new file mode 100644 index 00000000..f837c500 --- /dev/null +++ b/pkg/eth/transaction_arguments.go @@ -0,0 +1,49 @@ +package eth + +import ( + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/common/hexutil" + "github.com/ethereum/go-ethereum/core/types" +) + +// TransactionArgs represents the arguments to construct a new transaction +// or a message call. +type TransactionArgs struct { + From *common.Address `json:"from"` + To *common.Address `json:"to"` + Gas *hexutil.Uint64 `json:"gas"` + GasPrice *hexutil.Big `json:"gasPrice"` + MaxFeePerGas *hexutil.Big `json:"maxFeePerGas"` + MaxPriorityFeePerGas *hexutil.Big `json:"maxPriorityFeePerGas"` + Value *hexutil.Big `json:"value"` + Nonce *hexutil.Uint64 `json:"nonce"` + + // We accept "data" and "input" for backwards-compatibility reasons. + // "input" is the newer name and should be preferred by clients. + // Issue detail: https://github.com/ethereum/go-ethereum/issues/15628 + Data *hexutil.Bytes `json:"data"` + Input *hexutil.Bytes `json:"input"` + + // Introduced by AccessListTxType transaction. + AccessList *types.AccessList `json:"accessList,omitempty"` + ChainID *hexutil.Big `json:"chainId,omitempty"` +} + +// from retrieves the transaction sender address. +func (args *TransactionArgs) from() common.Address { + if args.From == nil { + return common.Address{} + } + return *args.From +} + +// data retrieves the transaction calldata. Input field is preferred. +func (args *TransactionArgs) data() []byte { + if args.Input != nil { + return *args.Input + } + if args.Data != nil { + return *args.Data + } + return nil +}