internal/ethapi: support block number or hash on state-related methods (#19491)
This change adds support for EIP-1898.
This commit is contained in:
committed by
Felix Lange
parent
62391ddbeb
commit
ad03d9801c
93
rpc/types.go
93
rpc/types.go
@ -18,10 +18,12 @@ package rpc
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"math"
|
||||
"strings"
|
||||
|
||||
"github.com/ethereum/go-ethereum/common"
|
||||
"github.com/ethereum/go-ethereum/common/hexutil"
|
||||
)
|
||||
|
||||
@ -105,3 +107,94 @@ func (bn *BlockNumber) UnmarshalJSON(data []byte) error {
|
||||
func (bn BlockNumber) Int64() int64 {
|
||||
return (int64)(bn)
|
||||
}
|
||||
|
||||
type BlockNumberOrHash struct {
|
||||
BlockNumber *BlockNumber `json:"blockNumber,omitempty"`
|
||||
BlockHash *common.Hash `json:"blockHash,omitempty"`
|
||||
RequireCanonical bool `json:"requireCanonical,omitempty"`
|
||||
}
|
||||
|
||||
func (bnh *BlockNumberOrHash) UnmarshalJSON(data []byte) error {
|
||||
type erased BlockNumberOrHash
|
||||
e := erased{}
|
||||
err := json.Unmarshal(data, &e)
|
||||
if err == nil {
|
||||
if e.BlockNumber != nil && e.BlockHash != nil {
|
||||
return fmt.Errorf("cannot specify both BlockHash and BlockNumber, choose one or the other")
|
||||
}
|
||||
bnh.BlockNumber = e.BlockNumber
|
||||
bnh.BlockHash = e.BlockHash
|
||||
bnh.RequireCanonical = e.RequireCanonical
|
||||
return nil
|
||||
}
|
||||
var input string
|
||||
err = json.Unmarshal(data, &input)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
switch input {
|
||||
case "earliest":
|
||||
bn := EarliestBlockNumber
|
||||
bnh.BlockNumber = &bn
|
||||
return nil
|
||||
case "latest":
|
||||
bn := LatestBlockNumber
|
||||
bnh.BlockNumber = &bn
|
||||
return nil
|
||||
case "pending":
|
||||
bn := PendingBlockNumber
|
||||
bnh.BlockNumber = &bn
|
||||
return nil
|
||||
default:
|
||||
if len(input) == 66 {
|
||||
hash := common.Hash{}
|
||||
err := hash.UnmarshalText([]byte(input))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
bnh.BlockHash = &hash
|
||||
return nil
|
||||
} else {
|
||||
blckNum, err := hexutil.DecodeUint64(input)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if blckNum > math.MaxInt64 {
|
||||
return fmt.Errorf("blocknumber too high")
|
||||
}
|
||||
bn := BlockNumber(blckNum)
|
||||
bnh.BlockNumber = &bn
|
||||
return nil
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (bnh *BlockNumberOrHash) Number() (BlockNumber, bool) {
|
||||
if bnh.BlockNumber != nil {
|
||||
return *bnh.BlockNumber, true
|
||||
}
|
||||
return BlockNumber(0), false
|
||||
}
|
||||
|
||||
func (bnh *BlockNumberOrHash) Hash() (common.Hash, bool) {
|
||||
if bnh.BlockHash != nil {
|
||||
return *bnh.BlockHash, true
|
||||
}
|
||||
return common.Hash{}, false
|
||||
}
|
||||
|
||||
func BlockNumberOrHashWithNumber(blockNr BlockNumber) BlockNumberOrHash {
|
||||
return BlockNumberOrHash{
|
||||
BlockNumber: &blockNr,
|
||||
BlockHash: nil,
|
||||
RequireCanonical: false,
|
||||
}
|
||||
}
|
||||
|
||||
func BlockNumberOrHashWithHash(hash common.Hash, canonical bool) BlockNumberOrHash {
|
||||
return BlockNumberOrHash{
|
||||
BlockNumber: nil,
|
||||
BlockHash: &hash,
|
||||
RequireCanonical: canonical,
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user