diff --git a/internal/ethapi/api.go b/internal/ethapi/api.go index 30f6dd06ab..06a0dcf8eb 100644 --- a/internal/ethapi/api.go +++ b/internal/ethapi/api.go @@ -87,7 +87,7 @@ type feeHistoryResult struct { GasUsedRatio []float64 `json:"gasUsedRatio"` } -func (s *PublicEthereumAPI) FeeHistory(ctx context.Context, blockCount hexutil.Uint, lastBlock rpc.BlockNumber, rewardPercentiles []float64) (*feeHistoryResult, error) { +func (s *PublicEthereumAPI) FeeHistory(ctx context.Context, blockCount rpc.DecimalOrHex, lastBlock rpc.BlockNumber, rewardPercentiles []float64) (*feeHistoryResult, error) { oldest, reward, baseFee, gasUsed, err := s.b.FeeHistory(ctx, int(blockCount), lastBlock, rewardPercentiles) if err != nil { return nil, err diff --git a/rpc/types.go b/rpc/types.go index d1b878c785..ad068defa8 100644 --- a/rpc/types.go +++ b/rpc/types.go @@ -21,6 +21,7 @@ import ( "encoding/json" "fmt" "math" + "strconv" "strings" "github.com/ethereum/go-ethereum/common" @@ -191,3 +192,24 @@ func BlockNumberOrHashWithHash(hash common.Hash, canonical bool) BlockNumberOrHa RequireCanonical: canonical, } } + +// DecimalOrHex unmarshals a non-negative decimal or hex parameter into a uint64. +type DecimalOrHex uint64 + +// UnmarshalJSON implements json.Unmarshaler. +func (dh *DecimalOrHex) UnmarshalJSON(data []byte) error { + input := strings.TrimSpace(string(data)) + if len(input) >= 2 && input[0] == '"' && input[len(input)-1] == '"' { + input = input[1 : len(input)-1] + } + + value, err := strconv.ParseUint(input, 10, 64) + if err != nil { + value, err = hexutil.DecodeUint64(input) + } + if err != nil { + return err + } + *dh = DecimalOrHex(value) + return nil +}