From 2b10ac5385354754e8c68c16a37c42ce01bbdce7 Mon Sep 17 00:00:00 2001 From: i-norden Date: Wed, 4 Jan 2023 15:43:24 -0600 Subject: [PATCH 1/5] eth_createAccessList fall-through endpoint --- pkg/eth/api.go | 22 ++++++++++++++ pkg/eth/errors.go | 17 +++++++++++ pkg/eth/transaction_arguments.go | 49 ++++++++++++++++++++++++++++++++ 3 files changed, 88 insertions(+) create mode 100644 pkg/eth/errors.go create mode 100644 pkg/eth/transaction_arguments.go 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 +} From ed088cdf21552ae18072f9f45aa985b7550e4f84 Mon Sep 17 00:00:00 2001 From: i-norden Date: Wed, 4 Jan 2023 15:48:17 -0600 Subject: [PATCH 2/5] eth_feeHistory fallthrough endpoint --- pkg/eth/api.go | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/pkg/eth/api.go b/pkg/eth/api.go index c00e385e..44a9763b 100644 --- a/pkg/eth/api.go +++ b/pkg/eth/api.go @@ -503,6 +503,25 @@ func (pea *PublicEthAPI) CreateAccessList(ctx context.Context, args TransactionA return nil, RequiresProxyError{method: "eth_createAccessList"} } +type feeHistoryResult struct { + OldestBlock *hexutil.Big `json:"oldestBlock"` + Reward [][]*hexutil.Big `json:"reward,omitempty"` + BaseFee []*hexutil.Big `json:"baseFeePerGas,omitempty"` + GasUsedRatio []float64 `json:"gasUsedRatio"` +} + +// FeeHistory returns the fee market history. +func (pea *PublicEthAPI) FeeHistory(ctx context.Context, blockCount rpc.DecimalOrHex, lastBlock rpc.BlockNumber, rewardPercentiles []float64) (*feeHistoryResult, error) { + if pea.proxyOnError { + var res *feeHistoryResult + if err := pea.rpc.CallContext(ctx, &res, "eth_feeHistory", blockCount, lastBlock, rewardPercentiles); err != nil { + return nil, err + } + return res, nil + } + return nil, RequiresProxyError{method: "eth_feeHistory"} +} + /* Receipts and Logs From 7b19973f916718e98455570280da693a0ddc9490 Mon Sep 17 00:00:00 2001 From: i-norden Date: Wed, 4 Jan 2023 15:48:40 -0600 Subject: [PATCH 3/5] eth_estimateGas fallthrough --- pkg/eth/api.go | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/pkg/eth/api.go b/pkg/eth/api.go index 44a9763b..991936fd 100644 --- a/pkg/eth/api.go +++ b/pkg/eth/api.go @@ -522,6 +522,19 @@ func (pea *PublicEthAPI) FeeHistory(ctx context.Context, blockCount rpc.DecimalO return nil, RequiresProxyError{method: "eth_feeHistory"} } +// EstimateGas returns an estimate of the amount of gas needed to execute the +// given transaction against the current pending block. +func (pea *PublicEthAPI) EstimateGas(ctx context.Context, args TransactionArgs, blockNrOrHash *rpc.BlockNumberOrHash) (hexutil.Uint64, error) { + if pea.proxyOnError { + var res hexutil.Uint64 + if err := pea.rpc.CallContext(ctx, &res, "eth_estimateGas", args, blockNrOrHash); err != nil { + return hexutil.Uint64(0), err + } + return res, nil + } + return hexutil.Uint64(0), RequiresProxyError{method: "eth_estimateGas"} +} + /* Receipts and Logs From 74071ecdf9589945112e1a8639ecbf6968ff7675 Mon Sep 17 00:00:00 2001 From: i-norden Date: Wed, 4 Jan 2023 16:02:25 -0600 Subject: [PATCH 4/5] eth_gasPrice fall-through --- pkg/eth/api.go | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/pkg/eth/api.go b/pkg/eth/api.go index 991936fd..65a4413a 100644 --- a/pkg/eth/api.go +++ b/pkg/eth/api.go @@ -535,6 +535,18 @@ func (pea *PublicEthAPI) EstimateGas(ctx context.Context, args TransactionArgs, return hexutil.Uint64(0), RequiresProxyError{method: "eth_estimateGas"} } +// GasPrice returns a suggestion for a gas price for legacy transactions. +func (pea *PublicEthAPI) GasPrice(ctx context.Context) (*hexutil.Big, error) { + if pea.proxyOnError { + var res *hexutil.Big + if err := pea.rpc.CallContext(ctx, &res, "eth_gasPrice"); err != nil { + return nil, err + } + return res, nil + } + return nil, RequiresProxyError{method: "eth_gasPrice"} +} + /* Receipts and Logs From 1b5dbc33d7fd7c3cd860b0d0e11bda5b66707a47 Mon Sep 17 00:00:00 2001 From: i-norden Date: Wed, 4 Jan 2023 16:04:19 -0600 Subject: [PATCH 5/5] eth_maxPriorityFeePerGas fall-through --- pkg/eth/api.go | 20 ++++++++++++++++---- 1 file changed, 16 insertions(+), 4 deletions(-) diff --git a/pkg/eth/api.go b/pkg/eth/api.go index 65a4413a..c178301b 100644 --- a/pkg/eth/api.go +++ b/pkg/eth/api.go @@ -493,7 +493,7 @@ type accessListResult struct { // 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 { + if pea.rpc != nil { var res *accessListResult if err := pea.rpc.CallContext(ctx, &res, "eth_createAccessList", args, blockNrOrHash); err != nil { return nil, err @@ -512,7 +512,7 @@ type feeHistoryResult struct { // FeeHistory returns the fee market history. func (pea *PublicEthAPI) FeeHistory(ctx context.Context, blockCount rpc.DecimalOrHex, lastBlock rpc.BlockNumber, rewardPercentiles []float64) (*feeHistoryResult, error) { - if pea.proxyOnError { + if pea.rpc != nil { var res *feeHistoryResult if err := pea.rpc.CallContext(ctx, &res, "eth_feeHistory", blockCount, lastBlock, rewardPercentiles); err != nil { return nil, err @@ -525,7 +525,7 @@ func (pea *PublicEthAPI) FeeHistory(ctx context.Context, blockCount rpc.DecimalO // EstimateGas returns an estimate of the amount of gas needed to execute the // given transaction against the current pending block. func (pea *PublicEthAPI) EstimateGas(ctx context.Context, args TransactionArgs, blockNrOrHash *rpc.BlockNumberOrHash) (hexutil.Uint64, error) { - if pea.proxyOnError { + if pea.rpc != nil { var res hexutil.Uint64 if err := pea.rpc.CallContext(ctx, &res, "eth_estimateGas", args, blockNrOrHash); err != nil { return hexutil.Uint64(0), err @@ -537,7 +537,7 @@ func (pea *PublicEthAPI) EstimateGas(ctx context.Context, args TransactionArgs, // GasPrice returns a suggestion for a gas price for legacy transactions. func (pea *PublicEthAPI) GasPrice(ctx context.Context) (*hexutil.Big, error) { - if pea.proxyOnError { + if pea.rpc != nil { var res *hexutil.Big if err := pea.rpc.CallContext(ctx, &res, "eth_gasPrice"); err != nil { return nil, err @@ -547,6 +547,18 @@ func (pea *PublicEthAPI) GasPrice(ctx context.Context) (*hexutil.Big, error) { return nil, RequiresProxyError{method: "eth_gasPrice"} } +// MaxPriorityFeePerGas returns a suggestion for a gas tip cap for dynamic fee transactions. +func (pea *PublicEthAPI) MaxPriorityFeePerGas(ctx context.Context) (*hexutil.Big, error) { + if pea.rpc != nil { + var res *hexutil.Big + if err := pea.rpc.CallContext(ctx, &res, "eth_maxPriorityFeePerGas"); err != nil { + return nil, err + } + return res, nil + } + return nil, RequiresProxyError{method: "eth_maxPriorityFeePerGas"} +} + /* Receipts and Logs