Add EIP-1898 support needed for The Graph compatibility

Fixes: #10814

This PR updates the following RPC methods according to EIP-1898
specs.

The following RPC methods are affected:

- eth_getBalance
- eth_getStorageAt
- eth_getTransactionCount
- eth_getCode
- eth_call

Note that eth_getBlockByNumber was not included in this list in
the spec although it seems it should be affected also?

Currently these methods all accept a blkParam string which can be
one of "latest", "earliest", "pending", or a block number (decimal
or hex). The spec enables caller to additionally specify a json
hash which can include the following fields:

- blockNumber EthUint64: A block number (decimal or hex) which is
  similar to the original use of the blkParam string
- blockHash EthHash: The block hash
- requireCanonical bool) If true we should make sure the block is
  in the canonical chain

Since the blkParam needs to support both being a number/string and
a json hash then this to properly work we need to introduce a new
struct with pointer fields to check if they exist. This is done
in the EthBlockParamByNumberOrHash struct which first tries to
unmarshal as a json hash (according to eip-1898) and then fallback
to unmarshal as string/number.
This commit is contained in:
Fridrik Asmundsson 2023-05-03 17:24:36 +00:00
parent 517c0a53b1
commit f358160cd5
20 changed files with 355 additions and 141 deletions

View File

@ -796,32 +796,32 @@ type FullNode interface {
// EthGetBlockTransactionCountByHash returns the number of messages in the TipSet // EthGetBlockTransactionCountByHash returns the number of messages in the TipSet
EthGetBlockTransactionCountByHash(ctx context.Context, blkHash ethtypes.EthHash) (ethtypes.EthUint64, error) //perm:read EthGetBlockTransactionCountByHash(ctx context.Context, blkHash ethtypes.EthHash) (ethtypes.EthUint64, error) //perm:read
EthGetBlockByHash(ctx context.Context, blkHash ethtypes.EthHash, fullTxInfo bool) (ethtypes.EthBlock, error) //perm:read EthGetBlockByHash(ctx context.Context, blkHash ethtypes.EthHash, fullTxInfo bool) (ethtypes.EthBlock, error) //perm:read
EthGetBlockByNumber(ctx context.Context, blkNum string, fullTxInfo bool) (ethtypes.EthBlock, error) //perm:read EthGetBlockByNumber(ctx context.Context, blkNum string, fullTxInfo bool) (ethtypes.EthBlock, error) //perm:read
EthGetTransactionByHash(ctx context.Context, txHash *ethtypes.EthHash) (*ethtypes.EthTx, error) //perm:read EthGetTransactionByHash(ctx context.Context, txHash *ethtypes.EthHash) (*ethtypes.EthTx, error) //perm:read
EthGetTransactionByHashLimited(ctx context.Context, txHash *ethtypes.EthHash, limit abi.ChainEpoch) (*ethtypes.EthTx, error) //perm:read EthGetTransactionByHashLimited(ctx context.Context, txHash *ethtypes.EthHash, limit abi.ChainEpoch) (*ethtypes.EthTx, error) //perm:read
EthGetTransactionHashByCid(ctx context.Context, cid cid.Cid) (*ethtypes.EthHash, error) //perm:read EthGetTransactionHashByCid(ctx context.Context, cid cid.Cid) (*ethtypes.EthHash, error) //perm:read
EthGetMessageCidByTransactionHash(ctx context.Context, txHash *ethtypes.EthHash) (*cid.Cid, error) //perm:read EthGetMessageCidByTransactionHash(ctx context.Context, txHash *ethtypes.EthHash) (*cid.Cid, error) //perm:read
EthGetTransactionCount(ctx context.Context, sender ethtypes.EthAddress, blkOpt string) (ethtypes.EthUint64, error) //perm:read EthGetTransactionCount(ctx context.Context, sender ethtypes.EthAddress, blkParam ethtypes.EthBlockParamByNumberOrHash) (ethtypes.EthUint64, error) //perm:read
EthGetTransactionReceipt(ctx context.Context, txHash ethtypes.EthHash) (*EthTxReceipt, error) //perm:read EthGetTransactionReceipt(ctx context.Context, txHash ethtypes.EthHash) (*EthTxReceipt, error) //perm:read
EthGetTransactionReceiptLimited(ctx context.Context, txHash ethtypes.EthHash, limit abi.ChainEpoch) (*EthTxReceipt, error) //perm:read EthGetTransactionReceiptLimited(ctx context.Context, txHash ethtypes.EthHash, limit abi.ChainEpoch) (*EthTxReceipt, error) //perm:read
EthGetTransactionByBlockHashAndIndex(ctx context.Context, blkHash ethtypes.EthHash, txIndex ethtypes.EthUint64) (ethtypes.EthTx, error) //perm:read EthGetTransactionByBlockHashAndIndex(ctx context.Context, blkHash ethtypes.EthHash, txIndex ethtypes.EthUint64) (ethtypes.EthTx, error) //perm:read
EthGetTransactionByBlockNumberAndIndex(ctx context.Context, blkNum ethtypes.EthUint64, txIndex ethtypes.EthUint64) (ethtypes.EthTx, error) //perm:read EthGetTransactionByBlockNumberAndIndex(ctx context.Context, blkNum ethtypes.EthUint64, txIndex ethtypes.EthUint64) (ethtypes.EthTx, error) //perm:read
EthGetCode(ctx context.Context, address ethtypes.EthAddress, blkOpt string) (ethtypes.EthBytes, error) //perm:read EthGetCode(ctx context.Context, address ethtypes.EthAddress, blkParam ethtypes.EthBlockParamByNumberOrHash) (ethtypes.EthBytes, error) //perm:read
EthGetStorageAt(ctx context.Context, address ethtypes.EthAddress, position ethtypes.EthBytes, blkParam string) (ethtypes.EthBytes, error) //perm:read EthGetStorageAt(ctx context.Context, address ethtypes.EthAddress, position ethtypes.EthBytes, blkParam ethtypes.EthBlockParamByNumberOrHash) (ethtypes.EthBytes, error) //perm:read
EthGetBalance(ctx context.Context, address ethtypes.EthAddress, blkParam string) (ethtypes.EthBigInt, error) //perm:read EthGetBalance(ctx context.Context, address ethtypes.EthAddress, blkParam ethtypes.EthBlockParamByNumberOrHash) (ethtypes.EthBigInt, error) //perm:read
EthChainId(ctx context.Context) (ethtypes.EthUint64, error) //perm:read EthChainId(ctx context.Context) (ethtypes.EthUint64, error) //perm:read
EthSyncing(ctx context.Context) (ethtypes.EthSyncingResult, error) //perm:read EthSyncing(ctx context.Context) (ethtypes.EthSyncingResult, error) //perm:read
NetVersion(ctx context.Context) (string, error) //perm:read NetVersion(ctx context.Context) (string, error) //perm:read
NetListening(ctx context.Context) (bool, error) //perm:read NetListening(ctx context.Context) (bool, error) //perm:read
EthProtocolVersion(ctx context.Context) (ethtypes.EthUint64, error) //perm:read EthProtocolVersion(ctx context.Context) (ethtypes.EthUint64, error) //perm:read
EthGasPrice(ctx context.Context) (ethtypes.EthBigInt, error) //perm:read EthGasPrice(ctx context.Context) (ethtypes.EthBigInt, error) //perm:read
EthFeeHistory(ctx context.Context, p jsonrpc.RawParams) (ethtypes.EthFeeHistory, error) //perm:read EthFeeHistory(ctx context.Context, p jsonrpc.RawParams) (ethtypes.EthFeeHistory, error) //perm:read
EthMaxPriorityFeePerGas(ctx context.Context) (ethtypes.EthBigInt, error) //perm:read EthMaxPriorityFeePerGas(ctx context.Context) (ethtypes.EthBigInt, error) //perm:read
EthEstimateGas(ctx context.Context, tx ethtypes.EthCall) (ethtypes.EthUint64, error) //perm:read EthEstimateGas(ctx context.Context, tx ethtypes.EthCall) (ethtypes.EthUint64, error) //perm:read
EthCall(ctx context.Context, tx ethtypes.EthCall, blkParam string) (ethtypes.EthBytes, error) //perm:read EthCall(ctx context.Context, tx ethtypes.EthCall, blkParam ethtypes.EthBlockParamByNumberOrHash) (ethtypes.EthBytes, error) //perm:read
EthSendRawTransaction(ctx context.Context, rawTx ethtypes.EthBytes) (ethtypes.EthHash, error) //perm:read EthSendRawTransaction(ctx context.Context, rawTx ethtypes.EthBytes) (ethtypes.EthHash, error) //perm:read

View File

@ -94,12 +94,12 @@ type Gateway interface {
EthGetTransactionByHashLimited(ctx context.Context, txHash *ethtypes.EthHash, limit abi.ChainEpoch) (*ethtypes.EthTx, error) EthGetTransactionByHashLimited(ctx context.Context, txHash *ethtypes.EthHash, limit abi.ChainEpoch) (*ethtypes.EthTx, error)
EthGetTransactionHashByCid(ctx context.Context, cid cid.Cid) (*ethtypes.EthHash, error) EthGetTransactionHashByCid(ctx context.Context, cid cid.Cid) (*ethtypes.EthHash, error)
EthGetMessageCidByTransactionHash(ctx context.Context, txHash *ethtypes.EthHash) (*cid.Cid, error) EthGetMessageCidByTransactionHash(ctx context.Context, txHash *ethtypes.EthHash) (*cid.Cid, error)
EthGetTransactionCount(ctx context.Context, sender ethtypes.EthAddress, blkOpt string) (ethtypes.EthUint64, error) EthGetTransactionCount(ctx context.Context, sender ethtypes.EthAddress, blkParam ethtypes.EthBlockParamByNumberOrHash) (ethtypes.EthUint64, error)
EthGetTransactionReceipt(ctx context.Context, txHash ethtypes.EthHash) (*EthTxReceipt, error) EthGetTransactionReceipt(ctx context.Context, txHash ethtypes.EthHash) (*EthTxReceipt, error)
EthGetTransactionReceiptLimited(ctx context.Context, txHash ethtypes.EthHash, limit abi.ChainEpoch) (*EthTxReceipt, error) EthGetTransactionReceiptLimited(ctx context.Context, txHash ethtypes.EthHash, limit abi.ChainEpoch) (*EthTxReceipt, error)
EthGetCode(ctx context.Context, address ethtypes.EthAddress, blkOpt string) (ethtypes.EthBytes, error) EthGetCode(ctx context.Context, address ethtypes.EthAddress, blkParam ethtypes.EthBlockParamByNumberOrHash) (ethtypes.EthBytes, error)
EthGetStorageAt(ctx context.Context, address ethtypes.EthAddress, position ethtypes.EthBytes, blkParam string) (ethtypes.EthBytes, error) EthGetStorageAt(ctx context.Context, address ethtypes.EthAddress, position ethtypes.EthBytes, blkParam ethtypes.EthBlockParamByNumberOrHash) (ethtypes.EthBytes, error)
EthGetBalance(ctx context.Context, address ethtypes.EthAddress, blkParam string) (ethtypes.EthBigInt, error) EthGetBalance(ctx context.Context, address ethtypes.EthAddress, blkParam ethtypes.EthBlockParamByNumberOrHash) (ethtypes.EthBigInt, error)
EthChainId(ctx context.Context) (ethtypes.EthUint64, error) EthChainId(ctx context.Context) (ethtypes.EthUint64, error)
EthSyncing(ctx context.Context) (ethtypes.EthSyncingResult, error) EthSyncing(ctx context.Context) (ethtypes.EthSyncingResult, error)
NetVersion(ctx context.Context) (string, error) NetVersion(ctx context.Context) (string, error)
@ -109,7 +109,7 @@ type Gateway interface {
EthFeeHistory(ctx context.Context, p jsonrpc.RawParams) (ethtypes.EthFeeHistory, error) EthFeeHistory(ctx context.Context, p jsonrpc.RawParams) (ethtypes.EthFeeHistory, error)
EthMaxPriorityFeePerGas(ctx context.Context) (ethtypes.EthBigInt, error) EthMaxPriorityFeePerGas(ctx context.Context) (ethtypes.EthBigInt, error)
EthEstimateGas(ctx context.Context, tx ethtypes.EthCall) (ethtypes.EthUint64, error) EthEstimateGas(ctx context.Context, tx ethtypes.EthCall) (ethtypes.EthUint64, error)
EthCall(ctx context.Context, tx ethtypes.EthCall, blkParam string) (ethtypes.EthBytes, error) EthCall(ctx context.Context, tx ethtypes.EthCall, blkParam ethtypes.EthBlockParamByNumberOrHash) (ethtypes.EthBytes, error)
EthSendRawTransaction(ctx context.Context, rawTx ethtypes.EthBytes) (ethtypes.EthHash, error) EthSendRawTransaction(ctx context.Context, rawTx ethtypes.EthBytes) (ethtypes.EthHash, error)
EthGetLogs(ctx context.Context, filter *ethtypes.EthFilterSpec) (*ethtypes.EthFilterResult, error) EthGetLogs(ctx context.Context, filter *ethtypes.EthFilterSpec) (*ethtypes.EthFilterResult, error)
EthGetFilterChanges(ctx context.Context, id ethtypes.EthFilterID) (*ethtypes.EthFilterResult, error) EthGetFilterChanges(ctx context.Context, id ethtypes.EthFilterID) (*ethtypes.EthFilterResult, error)

View File

@ -480,6 +480,9 @@ func ExampleValue(method string, t, parent reflect.Type) interface{} {
es := exampleStruct(method, t.Elem(), t) es := exampleStruct(method, t.Elem(), t)
ExampleValues[t] = es ExampleValues[t] = es
return es return es
} else if t.Elem().Kind() == reflect.String {
str := "string value"
return &str
} }
case reflect.Interface: case reflect.Interface:
return struct{}{} return struct{}{}

View File

@ -1012,7 +1012,7 @@ func (mr *MockFullNodeMockRecorder) EthBlockNumber(arg0 interface{}) *gomock.Cal
} }
// EthCall mocks base method. // EthCall mocks base method.
func (m *MockFullNode) EthCall(arg0 context.Context, arg1 ethtypes.EthCall, arg2 string) (ethtypes.EthBytes, error) { func (m *MockFullNode) EthCall(arg0 context.Context, arg1 ethtypes.EthCall, arg2 ethtypes.EthBlockParamByNumberOrHash) (ethtypes.EthBytes, error) {
m.ctrl.T.Helper() m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "EthCall", arg0, arg1, arg2) ret := m.ctrl.Call(m, "EthCall", arg0, arg1, arg2)
ret0, _ := ret[0].(ethtypes.EthBytes) ret0, _ := ret[0].(ethtypes.EthBytes)
@ -1087,7 +1087,7 @@ func (mr *MockFullNodeMockRecorder) EthGasPrice(arg0 interface{}) *gomock.Call {
} }
// EthGetBalance mocks base method. // EthGetBalance mocks base method.
func (m *MockFullNode) EthGetBalance(arg0 context.Context, arg1 ethtypes.EthAddress, arg2 string) (ethtypes.EthBigInt, error) { func (m *MockFullNode) EthGetBalance(arg0 context.Context, arg1 ethtypes.EthAddress, arg2 ethtypes.EthBlockParamByNumberOrHash) (ethtypes.EthBigInt, error) {
m.ctrl.T.Helper() m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "EthGetBalance", arg0, arg1, arg2) ret := m.ctrl.Call(m, "EthGetBalance", arg0, arg1, arg2)
ret0, _ := ret[0].(ethtypes.EthBigInt) ret0, _ := ret[0].(ethtypes.EthBigInt)
@ -1162,7 +1162,7 @@ func (mr *MockFullNodeMockRecorder) EthGetBlockTransactionCountByNumber(arg0, ar
} }
// EthGetCode mocks base method. // EthGetCode mocks base method.
func (m *MockFullNode) EthGetCode(arg0 context.Context, arg1 ethtypes.EthAddress, arg2 string) (ethtypes.EthBytes, error) { func (m *MockFullNode) EthGetCode(arg0 context.Context, arg1 ethtypes.EthAddress, arg2 ethtypes.EthBlockParamByNumberOrHash) (ethtypes.EthBytes, error) {
m.ctrl.T.Helper() m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "EthGetCode", arg0, arg1, arg2) ret := m.ctrl.Call(m, "EthGetCode", arg0, arg1, arg2)
ret0, _ := ret[0].(ethtypes.EthBytes) ret0, _ := ret[0].(ethtypes.EthBytes)
@ -1237,7 +1237,7 @@ func (mr *MockFullNodeMockRecorder) EthGetMessageCidByTransactionHash(arg0, arg1
} }
// EthGetStorageAt mocks base method. // EthGetStorageAt mocks base method.
func (m *MockFullNode) EthGetStorageAt(arg0 context.Context, arg1 ethtypes.EthAddress, arg2 ethtypes.EthBytes, arg3 string) (ethtypes.EthBytes, error) { func (m *MockFullNode) EthGetStorageAt(arg0 context.Context, arg1 ethtypes.EthAddress, arg2 ethtypes.EthBytes, arg3 ethtypes.EthBlockParamByNumberOrHash) (ethtypes.EthBytes, error) {
m.ctrl.T.Helper() m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "EthGetStorageAt", arg0, arg1, arg2, arg3) ret := m.ctrl.Call(m, "EthGetStorageAt", arg0, arg1, arg2, arg3)
ret0, _ := ret[0].(ethtypes.EthBytes) ret0, _ := ret[0].(ethtypes.EthBytes)
@ -1312,7 +1312,7 @@ func (mr *MockFullNodeMockRecorder) EthGetTransactionByHashLimited(arg0, arg1, a
} }
// EthGetTransactionCount mocks base method. // EthGetTransactionCount mocks base method.
func (m *MockFullNode) EthGetTransactionCount(arg0 context.Context, arg1 ethtypes.EthAddress, arg2 string) (ethtypes.EthUint64, error) { func (m *MockFullNode) EthGetTransactionCount(arg0 context.Context, arg1 ethtypes.EthAddress, arg2 ethtypes.EthBlockParamByNumberOrHash) (ethtypes.EthUint64, error) {
m.ctrl.T.Helper() m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "EthGetTransactionCount", arg0, arg1, arg2) ret := m.ctrl.Call(m, "EthGetTransactionCount", arg0, arg1, arg2)
ret0, _ := ret[0].(ethtypes.EthUint64) ret0, _ := ret[0].(ethtypes.EthUint64)

View File

@ -252,7 +252,7 @@ type FullNodeMethods struct {
EthBlockNumber func(p0 context.Context) (ethtypes.EthUint64, error) `perm:"read"` EthBlockNumber func(p0 context.Context) (ethtypes.EthUint64, error) `perm:"read"`
EthCall func(p0 context.Context, p1 ethtypes.EthCall, p2 string) (ethtypes.EthBytes, error) `perm:"read"` EthCall func(p0 context.Context, p1 ethtypes.EthCall, p2 ethtypes.EthBlockParamByNumberOrHash) (ethtypes.EthBytes, error) `perm:"read"`
EthChainId func(p0 context.Context) (ethtypes.EthUint64, error) `perm:"read"` EthChainId func(p0 context.Context) (ethtypes.EthUint64, error) `perm:"read"`
@ -262,7 +262,7 @@ type FullNodeMethods struct {
EthGasPrice func(p0 context.Context) (ethtypes.EthBigInt, error) `perm:"read"` EthGasPrice func(p0 context.Context) (ethtypes.EthBigInt, error) `perm:"read"`
EthGetBalance func(p0 context.Context, p1 ethtypes.EthAddress, p2 string) (ethtypes.EthBigInt, error) `perm:"read"` EthGetBalance func(p0 context.Context, p1 ethtypes.EthAddress, p2 ethtypes.EthBlockParamByNumberOrHash) (ethtypes.EthBigInt, error) `perm:"read"`
EthGetBlockByHash func(p0 context.Context, p1 ethtypes.EthHash, p2 bool) (ethtypes.EthBlock, error) `perm:"read"` EthGetBlockByHash func(p0 context.Context, p1 ethtypes.EthHash, p2 bool) (ethtypes.EthBlock, error) `perm:"read"`
@ -272,7 +272,7 @@ type FullNodeMethods struct {
EthGetBlockTransactionCountByNumber func(p0 context.Context, p1 ethtypes.EthUint64) (ethtypes.EthUint64, error) `perm:"read"` EthGetBlockTransactionCountByNumber func(p0 context.Context, p1 ethtypes.EthUint64) (ethtypes.EthUint64, error) `perm:"read"`
EthGetCode func(p0 context.Context, p1 ethtypes.EthAddress, p2 string) (ethtypes.EthBytes, error) `perm:"read"` EthGetCode func(p0 context.Context, p1 ethtypes.EthAddress, p2 ethtypes.EthBlockParamByNumberOrHash) (ethtypes.EthBytes, error) `perm:"read"`
EthGetFilterChanges func(p0 context.Context, p1 ethtypes.EthFilterID) (*ethtypes.EthFilterResult, error) `perm:"read"` EthGetFilterChanges func(p0 context.Context, p1 ethtypes.EthFilterID) (*ethtypes.EthFilterResult, error) `perm:"read"`
@ -282,7 +282,7 @@ type FullNodeMethods struct {
EthGetMessageCidByTransactionHash func(p0 context.Context, p1 *ethtypes.EthHash) (*cid.Cid, error) `perm:"read"` EthGetMessageCidByTransactionHash func(p0 context.Context, p1 *ethtypes.EthHash) (*cid.Cid, error) `perm:"read"`
EthGetStorageAt func(p0 context.Context, p1 ethtypes.EthAddress, p2 ethtypes.EthBytes, p3 string) (ethtypes.EthBytes, error) `perm:"read"` EthGetStorageAt func(p0 context.Context, p1 ethtypes.EthAddress, p2 ethtypes.EthBytes, p3 ethtypes.EthBlockParamByNumberOrHash) (ethtypes.EthBytes, error) `perm:"read"`
EthGetTransactionByBlockHashAndIndex func(p0 context.Context, p1 ethtypes.EthHash, p2 ethtypes.EthUint64) (ethtypes.EthTx, error) `perm:"read"` EthGetTransactionByBlockHashAndIndex func(p0 context.Context, p1 ethtypes.EthHash, p2 ethtypes.EthUint64) (ethtypes.EthTx, error) `perm:"read"`
@ -292,7 +292,7 @@ type FullNodeMethods struct {
EthGetTransactionByHashLimited func(p0 context.Context, p1 *ethtypes.EthHash, p2 abi.ChainEpoch) (*ethtypes.EthTx, error) `perm:"read"` EthGetTransactionByHashLimited func(p0 context.Context, p1 *ethtypes.EthHash, p2 abi.ChainEpoch) (*ethtypes.EthTx, error) `perm:"read"`
EthGetTransactionCount func(p0 context.Context, p1 ethtypes.EthAddress, p2 string) (ethtypes.EthUint64, error) `perm:"read"` EthGetTransactionCount func(p0 context.Context, p1 ethtypes.EthAddress, p2 ethtypes.EthBlockParamByNumberOrHash) (ethtypes.EthUint64, error) `perm:"read"`
EthGetTransactionHashByCid func(p0 context.Context, p1 cid.Cid) (*ethtypes.EthHash, error) `perm:"read"` EthGetTransactionHashByCid func(p0 context.Context, p1 cid.Cid) (*ethtypes.EthHash, error) `perm:"read"`
@ -668,7 +668,7 @@ type GatewayMethods struct {
EthBlockNumber func(p0 context.Context) (ethtypes.EthUint64, error) `` EthBlockNumber func(p0 context.Context) (ethtypes.EthUint64, error) ``
EthCall func(p0 context.Context, p1 ethtypes.EthCall, p2 string) (ethtypes.EthBytes, error) `` EthCall func(p0 context.Context, p1 ethtypes.EthCall, p2 ethtypes.EthBlockParamByNumberOrHash) (ethtypes.EthBytes, error) ``
EthChainId func(p0 context.Context) (ethtypes.EthUint64, error) `` EthChainId func(p0 context.Context) (ethtypes.EthUint64, error) ``
@ -678,7 +678,7 @@ type GatewayMethods struct {
EthGasPrice func(p0 context.Context) (ethtypes.EthBigInt, error) `` EthGasPrice func(p0 context.Context) (ethtypes.EthBigInt, error) ``
EthGetBalance func(p0 context.Context, p1 ethtypes.EthAddress, p2 string) (ethtypes.EthBigInt, error) `` EthGetBalance func(p0 context.Context, p1 ethtypes.EthAddress, p2 ethtypes.EthBlockParamByNumberOrHash) (ethtypes.EthBigInt, error) ``
EthGetBlockByHash func(p0 context.Context, p1 ethtypes.EthHash, p2 bool) (ethtypes.EthBlock, error) `` EthGetBlockByHash func(p0 context.Context, p1 ethtypes.EthHash, p2 bool) (ethtypes.EthBlock, error) ``
@ -688,7 +688,7 @@ type GatewayMethods struct {
EthGetBlockTransactionCountByNumber func(p0 context.Context, p1 ethtypes.EthUint64) (ethtypes.EthUint64, error) `` EthGetBlockTransactionCountByNumber func(p0 context.Context, p1 ethtypes.EthUint64) (ethtypes.EthUint64, error) ``
EthGetCode func(p0 context.Context, p1 ethtypes.EthAddress, p2 string) (ethtypes.EthBytes, error) `` EthGetCode func(p0 context.Context, p1 ethtypes.EthAddress, p2 ethtypes.EthBlockParamByNumberOrHash) (ethtypes.EthBytes, error) ``
EthGetFilterChanges func(p0 context.Context, p1 ethtypes.EthFilterID) (*ethtypes.EthFilterResult, error) `` EthGetFilterChanges func(p0 context.Context, p1 ethtypes.EthFilterID) (*ethtypes.EthFilterResult, error) ``
@ -698,13 +698,13 @@ type GatewayMethods struct {
EthGetMessageCidByTransactionHash func(p0 context.Context, p1 *ethtypes.EthHash) (*cid.Cid, error) `` EthGetMessageCidByTransactionHash func(p0 context.Context, p1 *ethtypes.EthHash) (*cid.Cid, error) ``
EthGetStorageAt func(p0 context.Context, p1 ethtypes.EthAddress, p2 ethtypes.EthBytes, p3 string) (ethtypes.EthBytes, error) `` EthGetStorageAt func(p0 context.Context, p1 ethtypes.EthAddress, p2 ethtypes.EthBytes, p3 ethtypes.EthBlockParamByNumberOrHash) (ethtypes.EthBytes, error) ``
EthGetTransactionByHash func(p0 context.Context, p1 *ethtypes.EthHash) (*ethtypes.EthTx, error) `` EthGetTransactionByHash func(p0 context.Context, p1 *ethtypes.EthHash) (*ethtypes.EthTx, error) ``
EthGetTransactionByHashLimited func(p0 context.Context, p1 *ethtypes.EthHash, p2 abi.ChainEpoch) (*ethtypes.EthTx, error) `` EthGetTransactionByHashLimited func(p0 context.Context, p1 *ethtypes.EthHash, p2 abi.ChainEpoch) (*ethtypes.EthTx, error) ``
EthGetTransactionCount func(p0 context.Context, p1 ethtypes.EthAddress, p2 string) (ethtypes.EthUint64, error) `` EthGetTransactionCount func(p0 context.Context, p1 ethtypes.EthAddress, p2 ethtypes.EthBlockParamByNumberOrHash) (ethtypes.EthUint64, error) ``
EthGetTransactionHashByCid func(p0 context.Context, p1 cid.Cid) (*ethtypes.EthHash, error) `` EthGetTransactionHashByCid func(p0 context.Context, p1 cid.Cid) (*ethtypes.EthHash, error) ``
@ -2091,14 +2091,14 @@ func (s *FullNodeStub) EthBlockNumber(p0 context.Context) (ethtypes.EthUint64, e
return *new(ethtypes.EthUint64), ErrNotSupported return *new(ethtypes.EthUint64), ErrNotSupported
} }
func (s *FullNodeStruct) EthCall(p0 context.Context, p1 ethtypes.EthCall, p2 string) (ethtypes.EthBytes, error) { func (s *FullNodeStruct) EthCall(p0 context.Context, p1 ethtypes.EthCall, p2 ethtypes.EthBlockParamByNumberOrHash) (ethtypes.EthBytes, error) {
if s.Internal.EthCall == nil { if s.Internal.EthCall == nil {
return *new(ethtypes.EthBytes), ErrNotSupported return *new(ethtypes.EthBytes), ErrNotSupported
} }
return s.Internal.EthCall(p0, p1, p2) return s.Internal.EthCall(p0, p1, p2)
} }
func (s *FullNodeStub) EthCall(p0 context.Context, p1 ethtypes.EthCall, p2 string) (ethtypes.EthBytes, error) { func (s *FullNodeStub) EthCall(p0 context.Context, p1 ethtypes.EthCall, p2 ethtypes.EthBlockParamByNumberOrHash) (ethtypes.EthBytes, error) {
return *new(ethtypes.EthBytes), ErrNotSupported return *new(ethtypes.EthBytes), ErrNotSupported
} }
@ -2146,14 +2146,14 @@ func (s *FullNodeStub) EthGasPrice(p0 context.Context) (ethtypes.EthBigInt, erro
return *new(ethtypes.EthBigInt), ErrNotSupported return *new(ethtypes.EthBigInt), ErrNotSupported
} }
func (s *FullNodeStruct) EthGetBalance(p0 context.Context, p1 ethtypes.EthAddress, p2 string) (ethtypes.EthBigInt, error) { func (s *FullNodeStruct) EthGetBalance(p0 context.Context, p1 ethtypes.EthAddress, p2 ethtypes.EthBlockParamByNumberOrHash) (ethtypes.EthBigInt, error) {
if s.Internal.EthGetBalance == nil { if s.Internal.EthGetBalance == nil {
return *new(ethtypes.EthBigInt), ErrNotSupported return *new(ethtypes.EthBigInt), ErrNotSupported
} }
return s.Internal.EthGetBalance(p0, p1, p2) return s.Internal.EthGetBalance(p0, p1, p2)
} }
func (s *FullNodeStub) EthGetBalance(p0 context.Context, p1 ethtypes.EthAddress, p2 string) (ethtypes.EthBigInt, error) { func (s *FullNodeStub) EthGetBalance(p0 context.Context, p1 ethtypes.EthAddress, p2 ethtypes.EthBlockParamByNumberOrHash) (ethtypes.EthBigInt, error) {
return *new(ethtypes.EthBigInt), ErrNotSupported return *new(ethtypes.EthBigInt), ErrNotSupported
} }
@ -2201,14 +2201,14 @@ func (s *FullNodeStub) EthGetBlockTransactionCountByNumber(p0 context.Context, p
return *new(ethtypes.EthUint64), ErrNotSupported return *new(ethtypes.EthUint64), ErrNotSupported
} }
func (s *FullNodeStruct) EthGetCode(p0 context.Context, p1 ethtypes.EthAddress, p2 string) (ethtypes.EthBytes, error) { func (s *FullNodeStruct) EthGetCode(p0 context.Context, p1 ethtypes.EthAddress, p2 ethtypes.EthBlockParamByNumberOrHash) (ethtypes.EthBytes, error) {
if s.Internal.EthGetCode == nil { if s.Internal.EthGetCode == nil {
return *new(ethtypes.EthBytes), ErrNotSupported return *new(ethtypes.EthBytes), ErrNotSupported
} }
return s.Internal.EthGetCode(p0, p1, p2) return s.Internal.EthGetCode(p0, p1, p2)
} }
func (s *FullNodeStub) EthGetCode(p0 context.Context, p1 ethtypes.EthAddress, p2 string) (ethtypes.EthBytes, error) { func (s *FullNodeStub) EthGetCode(p0 context.Context, p1 ethtypes.EthAddress, p2 ethtypes.EthBlockParamByNumberOrHash) (ethtypes.EthBytes, error) {
return *new(ethtypes.EthBytes), ErrNotSupported return *new(ethtypes.EthBytes), ErrNotSupported
} }
@ -2256,14 +2256,14 @@ func (s *FullNodeStub) EthGetMessageCidByTransactionHash(p0 context.Context, p1
return nil, ErrNotSupported return nil, ErrNotSupported
} }
func (s *FullNodeStruct) EthGetStorageAt(p0 context.Context, p1 ethtypes.EthAddress, p2 ethtypes.EthBytes, p3 string) (ethtypes.EthBytes, error) { func (s *FullNodeStruct) EthGetStorageAt(p0 context.Context, p1 ethtypes.EthAddress, p2 ethtypes.EthBytes, p3 ethtypes.EthBlockParamByNumberOrHash) (ethtypes.EthBytes, error) {
if s.Internal.EthGetStorageAt == nil { if s.Internal.EthGetStorageAt == nil {
return *new(ethtypes.EthBytes), ErrNotSupported return *new(ethtypes.EthBytes), ErrNotSupported
} }
return s.Internal.EthGetStorageAt(p0, p1, p2, p3) return s.Internal.EthGetStorageAt(p0, p1, p2, p3)
} }
func (s *FullNodeStub) EthGetStorageAt(p0 context.Context, p1 ethtypes.EthAddress, p2 ethtypes.EthBytes, p3 string) (ethtypes.EthBytes, error) { func (s *FullNodeStub) EthGetStorageAt(p0 context.Context, p1 ethtypes.EthAddress, p2 ethtypes.EthBytes, p3 ethtypes.EthBlockParamByNumberOrHash) (ethtypes.EthBytes, error) {
return *new(ethtypes.EthBytes), ErrNotSupported return *new(ethtypes.EthBytes), ErrNotSupported
} }
@ -2311,14 +2311,14 @@ func (s *FullNodeStub) EthGetTransactionByHashLimited(p0 context.Context, p1 *et
return nil, ErrNotSupported return nil, ErrNotSupported
} }
func (s *FullNodeStruct) EthGetTransactionCount(p0 context.Context, p1 ethtypes.EthAddress, p2 string) (ethtypes.EthUint64, error) { func (s *FullNodeStruct) EthGetTransactionCount(p0 context.Context, p1 ethtypes.EthAddress, p2 ethtypes.EthBlockParamByNumberOrHash) (ethtypes.EthUint64, error) {
if s.Internal.EthGetTransactionCount == nil { if s.Internal.EthGetTransactionCount == nil {
return *new(ethtypes.EthUint64), ErrNotSupported return *new(ethtypes.EthUint64), ErrNotSupported
} }
return s.Internal.EthGetTransactionCount(p0, p1, p2) return s.Internal.EthGetTransactionCount(p0, p1, p2)
} }
func (s *FullNodeStub) EthGetTransactionCount(p0 context.Context, p1 ethtypes.EthAddress, p2 string) (ethtypes.EthUint64, error) { func (s *FullNodeStub) EthGetTransactionCount(p0 context.Context, p1 ethtypes.EthAddress, p2 ethtypes.EthBlockParamByNumberOrHash) (ethtypes.EthUint64, error) {
return *new(ethtypes.EthUint64), ErrNotSupported return *new(ethtypes.EthUint64), ErrNotSupported
} }
@ -4313,14 +4313,14 @@ func (s *GatewayStub) EthBlockNumber(p0 context.Context) (ethtypes.EthUint64, er
return *new(ethtypes.EthUint64), ErrNotSupported return *new(ethtypes.EthUint64), ErrNotSupported
} }
func (s *GatewayStruct) EthCall(p0 context.Context, p1 ethtypes.EthCall, p2 string) (ethtypes.EthBytes, error) { func (s *GatewayStruct) EthCall(p0 context.Context, p1 ethtypes.EthCall, p2 ethtypes.EthBlockParamByNumberOrHash) (ethtypes.EthBytes, error) {
if s.Internal.EthCall == nil { if s.Internal.EthCall == nil {
return *new(ethtypes.EthBytes), ErrNotSupported return *new(ethtypes.EthBytes), ErrNotSupported
} }
return s.Internal.EthCall(p0, p1, p2) return s.Internal.EthCall(p0, p1, p2)
} }
func (s *GatewayStub) EthCall(p0 context.Context, p1 ethtypes.EthCall, p2 string) (ethtypes.EthBytes, error) { func (s *GatewayStub) EthCall(p0 context.Context, p1 ethtypes.EthCall, p2 ethtypes.EthBlockParamByNumberOrHash) (ethtypes.EthBytes, error) {
return *new(ethtypes.EthBytes), ErrNotSupported return *new(ethtypes.EthBytes), ErrNotSupported
} }
@ -4368,14 +4368,14 @@ func (s *GatewayStub) EthGasPrice(p0 context.Context) (ethtypes.EthBigInt, error
return *new(ethtypes.EthBigInt), ErrNotSupported return *new(ethtypes.EthBigInt), ErrNotSupported
} }
func (s *GatewayStruct) EthGetBalance(p0 context.Context, p1 ethtypes.EthAddress, p2 string) (ethtypes.EthBigInt, error) { func (s *GatewayStruct) EthGetBalance(p0 context.Context, p1 ethtypes.EthAddress, p2 ethtypes.EthBlockParamByNumberOrHash) (ethtypes.EthBigInt, error) {
if s.Internal.EthGetBalance == nil { if s.Internal.EthGetBalance == nil {
return *new(ethtypes.EthBigInt), ErrNotSupported return *new(ethtypes.EthBigInt), ErrNotSupported
} }
return s.Internal.EthGetBalance(p0, p1, p2) return s.Internal.EthGetBalance(p0, p1, p2)
} }
func (s *GatewayStub) EthGetBalance(p0 context.Context, p1 ethtypes.EthAddress, p2 string) (ethtypes.EthBigInt, error) { func (s *GatewayStub) EthGetBalance(p0 context.Context, p1 ethtypes.EthAddress, p2 ethtypes.EthBlockParamByNumberOrHash) (ethtypes.EthBigInt, error) {
return *new(ethtypes.EthBigInt), ErrNotSupported return *new(ethtypes.EthBigInt), ErrNotSupported
} }
@ -4423,14 +4423,14 @@ func (s *GatewayStub) EthGetBlockTransactionCountByNumber(p0 context.Context, p1
return *new(ethtypes.EthUint64), ErrNotSupported return *new(ethtypes.EthUint64), ErrNotSupported
} }
func (s *GatewayStruct) EthGetCode(p0 context.Context, p1 ethtypes.EthAddress, p2 string) (ethtypes.EthBytes, error) { func (s *GatewayStruct) EthGetCode(p0 context.Context, p1 ethtypes.EthAddress, p2 ethtypes.EthBlockParamByNumberOrHash) (ethtypes.EthBytes, error) {
if s.Internal.EthGetCode == nil { if s.Internal.EthGetCode == nil {
return *new(ethtypes.EthBytes), ErrNotSupported return *new(ethtypes.EthBytes), ErrNotSupported
} }
return s.Internal.EthGetCode(p0, p1, p2) return s.Internal.EthGetCode(p0, p1, p2)
} }
func (s *GatewayStub) EthGetCode(p0 context.Context, p1 ethtypes.EthAddress, p2 string) (ethtypes.EthBytes, error) { func (s *GatewayStub) EthGetCode(p0 context.Context, p1 ethtypes.EthAddress, p2 ethtypes.EthBlockParamByNumberOrHash) (ethtypes.EthBytes, error) {
return *new(ethtypes.EthBytes), ErrNotSupported return *new(ethtypes.EthBytes), ErrNotSupported
} }
@ -4478,14 +4478,14 @@ func (s *GatewayStub) EthGetMessageCidByTransactionHash(p0 context.Context, p1 *
return nil, ErrNotSupported return nil, ErrNotSupported
} }
func (s *GatewayStruct) EthGetStorageAt(p0 context.Context, p1 ethtypes.EthAddress, p2 ethtypes.EthBytes, p3 string) (ethtypes.EthBytes, error) { func (s *GatewayStruct) EthGetStorageAt(p0 context.Context, p1 ethtypes.EthAddress, p2 ethtypes.EthBytes, p3 ethtypes.EthBlockParamByNumberOrHash) (ethtypes.EthBytes, error) {
if s.Internal.EthGetStorageAt == nil { if s.Internal.EthGetStorageAt == nil {
return *new(ethtypes.EthBytes), ErrNotSupported return *new(ethtypes.EthBytes), ErrNotSupported
} }
return s.Internal.EthGetStorageAt(p0, p1, p2, p3) return s.Internal.EthGetStorageAt(p0, p1, p2, p3)
} }
func (s *GatewayStub) EthGetStorageAt(p0 context.Context, p1 ethtypes.EthAddress, p2 ethtypes.EthBytes, p3 string) (ethtypes.EthBytes, error) { func (s *GatewayStub) EthGetStorageAt(p0 context.Context, p1 ethtypes.EthAddress, p2 ethtypes.EthBytes, p3 ethtypes.EthBlockParamByNumberOrHash) (ethtypes.EthBytes, error) {
return *new(ethtypes.EthBytes), ErrNotSupported return *new(ethtypes.EthBytes), ErrNotSupported
} }
@ -4511,14 +4511,14 @@ func (s *GatewayStub) EthGetTransactionByHashLimited(p0 context.Context, p1 *eth
return nil, ErrNotSupported return nil, ErrNotSupported
} }
func (s *GatewayStruct) EthGetTransactionCount(p0 context.Context, p1 ethtypes.EthAddress, p2 string) (ethtypes.EthUint64, error) { func (s *GatewayStruct) EthGetTransactionCount(p0 context.Context, p1 ethtypes.EthAddress, p2 ethtypes.EthBlockParamByNumberOrHash) (ethtypes.EthUint64, error) {
if s.Internal.EthGetTransactionCount == nil { if s.Internal.EthGetTransactionCount == nil {
return *new(ethtypes.EthUint64), ErrNotSupported return *new(ethtypes.EthUint64), ErrNotSupported
} }
return s.Internal.EthGetTransactionCount(p0, p1, p2) return s.Internal.EthGetTransactionCount(p0, p1, p2)
} }
func (s *GatewayStub) EthGetTransactionCount(p0 context.Context, p1 ethtypes.EthAddress, p2 string) (ethtypes.EthUint64, error) { func (s *GatewayStub) EthGetTransactionCount(p0 context.Context, p1 ethtypes.EthAddress, p2 ethtypes.EthBlockParamByNumberOrHash) (ethtypes.EthUint64, error) {
return *new(ethtypes.EthUint64), ErrNotSupported return *new(ethtypes.EthUint64), ErrNotSupported
} }

Binary file not shown.

Binary file not shown.

View File

@ -839,3 +839,82 @@ func (e EthFeeHistoryParams) MarshalJSON() ([]byte, error) {
} }
return json.Marshal([]interface{}{e.BlkCount, e.NewestBlkNum}) return json.Marshal([]interface{}{e.BlkCount, e.NewestBlkNum})
} }
type EthBlockParamByNumberOrHash struct {
PredefinedBlock *string
Number *EthUint64
BlockNumber *EthUint64 `json:"blockNumber,omitempty"`
BlockHash *EthHash `json:"blockHash,omitempty"`
RequireCanonical bool `json:"requireCanonical,omitempty"`
}
func NewEthBlockParamFromPredefined(predefined string) EthBlockParamByNumberOrHash {
return EthBlockParamByNumberOrHash{
PredefinedBlock: &predefined,
Number: nil,
BlockHash: nil,
RequireCanonical: false,
}
}
func NewEthBlockParamFromNumber(number EthUint64) EthBlockParamByNumberOrHash {
return EthBlockParamByNumberOrHash{
PredefinedBlock: nil,
Number: &number,
BlockHash: nil,
RequireCanonical: false,
}
}
func NewEthBlockParamFromHexString(str string) (EthBlockParamByNumberOrHash, error) {
// check if block param is a number (decimal or hex)
var num EthUint64 = 0
err := num.UnmarshalJSON([]byte(str))
if err != nil {
return NewEthBlockParamFromNumber(0), err
}
return EthBlockParamByNumberOrHash{
PredefinedBlock: nil,
Number: &num,
BlockHash: nil,
RequireCanonical: false,
}, nil
}
func (e *EthBlockParamByNumberOrHash) UnmarshalJSON(b []byte) error {
// we first try to unmarshal into a EthBlockParamByNumberOrHash struct to check
// if the block param is a block hash or block number (see EIP-1898). We use
// a temporary struct to avoid infinite recursion.
type tmpStruct EthBlockParamByNumberOrHash
var tmp tmpStruct
if err := json.Unmarshal(b, &tmp); err == nil {
if tmp.BlockNumber != nil && tmp.BlockHash != nil {
return errors.New("cannot specify both blockNumber and blockHash")
}
*e = EthBlockParamByNumberOrHash(tmp)
return nil
}
// check if block param is once of the special strings
var str string
err := json.Unmarshal(b, &str)
if err != nil {
return err
}
if str == "earliest" || str == "pending" || str == "latest" {
e.PredefinedBlock = &str
return nil
}
// check if block param is a number (decimal or hex)
var num EthUint64
if err := num.UnmarshalJSON(b); err == nil {
e.Number = &num
return nil
}
return errors.New("invalid block param")
}

View File

@ -130,7 +130,7 @@ var EvmCallSimulateCmd = &cli.Command{
From: &fromEthAddr, From: &fromEthAddr,
To: &toEthAddr, To: &toEthAddr,
Data: params, Data: params,
}, "") }, ethtypes.NewEthBlockParamFromPredefined("latest"))
if err != nil { if err != nil {
fmt.Println("Eth call fails, return val: ", res) fmt.Println("Eth call fails, return val: ", res)
return err return err
@ -518,7 +518,7 @@ var EvmGetBytecode = &cli.Command{
defer closer() defer closer()
ctx := ReqContext(cctx) ctx := ReqContext(cctx)
code, err := api.EthGetCode(ctx, contractAddr, "latest") code, err := api.EthGetCode(ctx, contractAddr, ethtypes.NewEthBlockParamFromPredefined("latest"))
if err != nil { if err != nil {
return err return err
} }

View File

@ -2375,7 +2375,13 @@ Inputs:
"value": "0x0", "value": "0x0",
"data": "0x07" "data": "0x07"
}, },
"string value" {
"PredefinedBlock": "string value",
"Number": "0x5",
"blockNumber": "0x5",
"blockHash": "0x37690cfec6c1bf4c3b9288c7a5d783e98731e90b0a4c177c2a374c7a9427355e",
"requireCanonical": true
}
] ]
``` ```
@ -2455,7 +2461,13 @@ Inputs:
```json ```json
[ [
"0x5cbeecf99d3fdb3f25e309cc264f240bb0664031", "0x5cbeecf99d3fdb3f25e309cc264f240bb0664031",
"string value" {
"PredefinedBlock": "string value",
"Number": "0x5",
"blockNumber": "0x5",
"blockHash": "0x37690cfec6c1bf4c3b9288c7a5d783e98731e90b0a4c177c2a374c7a9427355e",
"requireCanonical": true
}
] ]
``` ```
@ -2588,7 +2600,13 @@ Inputs:
```json ```json
[ [
"0x5cbeecf99d3fdb3f25e309cc264f240bb0664031", "0x5cbeecf99d3fdb3f25e309cc264f240bb0664031",
"string value" {
"PredefinedBlock": "string value",
"Number": "0x5",
"blockNumber": "0x5",
"blockHash": "0x37690cfec6c1bf4c3b9288c7a5d783e98731e90b0a4c177c2a374c7a9427355e",
"requireCanonical": true
}
] ]
``` ```
@ -2691,7 +2709,13 @@ Inputs:
[ [
"0x5cbeecf99d3fdb3f25e309cc264f240bb0664031", "0x5cbeecf99d3fdb3f25e309cc264f240bb0664031",
"0x07", "0x07",
"string value" {
"PredefinedBlock": "string value",
"Number": "0x5",
"blockNumber": "0x5",
"blockHash": "0x37690cfec6c1bf4c3b9288c7a5d783e98731e90b0a4c177c2a374c7a9427355e",
"requireCanonical": true
}
] ]
``` ```
@ -2861,7 +2885,13 @@ Inputs:
```json ```json
[ [
"0x5cbeecf99d3fdb3f25e309cc264f240bb0664031", "0x5cbeecf99d3fdb3f25e309cc264f240bb0664031",
"string value" {
"PredefinedBlock": "string value",
"Number": "0x5",
"blockNumber": "0x5",
"blockHash": "0x37690cfec6c1bf4c3b9288c7a5d783e98731e90b0a4c177c2a374c7a9427355e",
"requireCanonical": true
}
] ]
``` ```

View File

@ -110,13 +110,13 @@ type TargetAPI interface {
EthGetTransactionByHashLimited(ctx context.Context, txHash *ethtypes.EthHash, limit abi.ChainEpoch) (*ethtypes.EthTx, error) EthGetTransactionByHashLimited(ctx context.Context, txHash *ethtypes.EthHash, limit abi.ChainEpoch) (*ethtypes.EthTx, error)
EthGetTransactionHashByCid(ctx context.Context, cid cid.Cid) (*ethtypes.EthHash, error) EthGetTransactionHashByCid(ctx context.Context, cid cid.Cid) (*ethtypes.EthHash, error)
EthGetMessageCidByTransactionHash(ctx context.Context, txHash *ethtypes.EthHash) (*cid.Cid, error) EthGetMessageCidByTransactionHash(ctx context.Context, txHash *ethtypes.EthHash) (*cid.Cid, error)
EthGetTransactionCount(ctx context.Context, sender ethtypes.EthAddress, blkOpt string) (ethtypes.EthUint64, error) EthGetTransactionCount(ctx context.Context, sender ethtypes.EthAddress, blkParam ethtypes.EthBlockParamByNumberOrHash) (ethtypes.EthUint64, error)
EthGetTransactionReceiptLimited(ctx context.Context, txHash ethtypes.EthHash, limit abi.ChainEpoch) (*api.EthTxReceipt, error) EthGetTransactionReceiptLimited(ctx context.Context, txHash ethtypes.EthHash, limit abi.ChainEpoch) (*api.EthTxReceipt, error)
EthGetTransactionByBlockHashAndIndex(ctx context.Context, blkHash ethtypes.EthHash, txIndex ethtypes.EthUint64) (ethtypes.EthTx, error) EthGetTransactionByBlockHashAndIndex(ctx context.Context, blkHash ethtypes.EthHash, txIndex ethtypes.EthUint64) (ethtypes.EthTx, error)
EthGetTransactionByBlockNumberAndIndex(ctx context.Context, blkNum ethtypes.EthUint64, txIndex ethtypes.EthUint64) (ethtypes.EthTx, error) EthGetTransactionByBlockNumberAndIndex(ctx context.Context, blkNum ethtypes.EthUint64, txIndex ethtypes.EthUint64) (ethtypes.EthTx, error)
EthGetCode(ctx context.Context, address ethtypes.EthAddress, blkOpt string) (ethtypes.EthBytes, error) EthGetCode(ctx context.Context, address ethtypes.EthAddress, blkParam ethtypes.EthBlockParamByNumberOrHash) (ethtypes.EthBytes, error)
EthGetStorageAt(ctx context.Context, address ethtypes.EthAddress, position ethtypes.EthBytes, blkParam string) (ethtypes.EthBytes, error) EthGetStorageAt(ctx context.Context, address ethtypes.EthAddress, position ethtypes.EthBytes, blkParam ethtypes.EthBlockParamByNumberOrHash) (ethtypes.EthBytes, error)
EthGetBalance(ctx context.Context, address ethtypes.EthAddress, blkParam string) (ethtypes.EthBigInt, error) EthGetBalance(ctx context.Context, address ethtypes.EthAddress, blkParam ethtypes.EthBlockParamByNumberOrHash) (ethtypes.EthBigInt, error)
EthChainId(ctx context.Context) (ethtypes.EthUint64, error) EthChainId(ctx context.Context) (ethtypes.EthUint64, error)
EthSyncing(ctx context.Context) (ethtypes.EthSyncingResult, error) EthSyncing(ctx context.Context) (ethtypes.EthSyncingResult, error)
NetVersion(ctx context.Context) (string, error) NetVersion(ctx context.Context) (string, error)
@ -126,7 +126,7 @@ type TargetAPI interface {
EthFeeHistory(ctx context.Context, p jsonrpc.RawParams) (ethtypes.EthFeeHistory, error) EthFeeHistory(ctx context.Context, p jsonrpc.RawParams) (ethtypes.EthFeeHistory, error)
EthMaxPriorityFeePerGas(ctx context.Context) (ethtypes.EthBigInt, error) EthMaxPriorityFeePerGas(ctx context.Context) (ethtypes.EthBigInt, error)
EthEstimateGas(ctx context.Context, tx ethtypes.EthCall) (ethtypes.EthUint64, error) EthEstimateGas(ctx context.Context, tx ethtypes.EthCall) (ethtypes.EthUint64, error)
EthCall(ctx context.Context, tx ethtypes.EthCall, blkParam string) (ethtypes.EthBytes, error) EthCall(ctx context.Context, tx ethtypes.EthCall, blkParam ethtypes.EthBlockParamByNumberOrHash) (ethtypes.EthBytes, error)
EthSendRawTransaction(ctx context.Context, rawTx ethtypes.EthBytes) (ethtypes.EthHash, error) EthSendRawTransaction(ctx context.Context, rawTx ethtypes.EthBytes) (ethtypes.EthHash, error)
EthGetLogs(ctx context.Context, filter *ethtypes.EthFilterSpec) (*ethtypes.EthFilterResult, error) EthGetLogs(ctx context.Context, filter *ethtypes.EthFilterSpec) (*ethtypes.EthFilterResult, error)
EthGetFilterChanges(ctx context.Context, id ethtypes.EthFilterID) (*ethtypes.EthFilterResult, error) EthGetFilterChanges(ctx context.Context, id ethtypes.EthFilterID) (*ethtypes.EthFilterResult, error)

View File

@ -80,6 +80,38 @@ func (gw *Node) checkBlkHash(ctx context.Context, blkHash ethtypes.EthHash) erro
return gw.checkTipsetKey(ctx, tsk) return gw.checkTipsetKey(ctx, tsk)
} }
func (gw *Node) checkEthBlockParamByNumberOrHash(ctx context.Context, blkParam ethtypes.EthBlockParamByNumberOrHash, lookback ethtypes.EthUint64) error {
head, err := gw.target.ChainHead(ctx)
if err != nil {
return err
}
var num ethtypes.EthUint64 = 0
if blkParam.PredefinedBlock != nil {
if *blkParam.PredefinedBlock == "earliest" {
return fmt.Errorf("block param \"earliest\" is not supported")
} else if *blkParam.PredefinedBlock == "pending" || *blkParam.PredefinedBlock == "latest" {
// Head is always ok.
if lookback == 0 {
return nil
}
if lookback <= ethtypes.EthUint64(head.Height()) {
num = ethtypes.EthUint64(head.Height()) - lookback
}
}
} else if blkParam.Number != nil {
num = *blkParam.Number
} else if blkParam.BlockHash != nil || blkParam.BlockNumber != nil {
return fmt.Errorf("block hash and block number are not supported")
} else {
return fmt.Errorf("invalid block param")
}
return gw.checkTipsetHeight(head, abi.ChainEpoch(num))
}
func (gw *Node) checkBlkParam(ctx context.Context, blkParam string, lookback ethtypes.EthUint64) error { func (gw *Node) checkBlkParam(ctx context.Context, blkParam string, lookback ethtypes.EthUint64) error {
if blkParam == "earliest" { if blkParam == "earliest" {
// also not supported in node impl // also not supported in node impl
@ -178,16 +210,16 @@ func (gw *Node) EthGetMessageCidByTransactionHash(ctx context.Context, txHash *e
return gw.target.EthGetMessageCidByTransactionHash(ctx, txHash) return gw.target.EthGetMessageCidByTransactionHash(ctx, txHash)
} }
func (gw *Node) EthGetTransactionCount(ctx context.Context, sender ethtypes.EthAddress, blkOpt string) (ethtypes.EthUint64, error) { func (gw *Node) EthGetTransactionCount(ctx context.Context, sender ethtypes.EthAddress, blkParam ethtypes.EthBlockParamByNumberOrHash) (ethtypes.EthUint64, error) {
if err := gw.limit(ctx, stateRateLimitTokens); err != nil { if err := gw.limit(ctx, stateRateLimitTokens); err != nil {
return 0, err return 0, err
} }
if err := gw.checkBlkParam(ctx, blkOpt, 0); err != nil { if err := gw.checkEthBlockParamByNumberOrHash(ctx, blkParam, 0); err != nil {
return 0, err return 0, err
} }
return gw.target.EthGetTransactionCount(ctx, sender, blkOpt) return gw.target.EthGetTransactionCount(ctx, sender, blkParam)
} }
func (gw *Node) EthGetTransactionReceipt(ctx context.Context, txHash ethtypes.EthHash) (*api.EthTxReceipt, error) { func (gw *Node) EthGetTransactionReceipt(ctx context.Context, txHash ethtypes.EthHash) (*api.EthTxReceipt, error) {
@ -208,36 +240,36 @@ func (gw *Node) EthGetTransactionReceiptLimited(ctx context.Context, txHash etht
return gw.target.EthGetTransactionReceiptLimited(ctx, txHash, limit) return gw.target.EthGetTransactionReceiptLimited(ctx, txHash, limit)
} }
func (gw *Node) EthGetCode(ctx context.Context, address ethtypes.EthAddress, blkOpt string) (ethtypes.EthBytes, error) { func (gw *Node) EthGetCode(ctx context.Context, address ethtypes.EthAddress, blkParam ethtypes.EthBlockParamByNumberOrHash) (ethtypes.EthBytes, error) {
if err := gw.limit(ctx, stateRateLimitTokens); err != nil { if err := gw.limit(ctx, stateRateLimitTokens); err != nil {
return nil, err return nil, err
} }
if err := gw.checkBlkParam(ctx, blkOpt, 0); err != nil { if err := gw.checkEthBlockParamByNumberOrHash(ctx, blkParam, 0); err != nil {
return nil, err return nil, err
} }
return gw.target.EthGetCode(ctx, address, blkOpt) return gw.target.EthGetCode(ctx, address, blkParam)
} }
func (gw *Node) EthGetStorageAt(ctx context.Context, address ethtypes.EthAddress, position ethtypes.EthBytes, blkParam string) (ethtypes.EthBytes, error) { func (gw *Node) EthGetStorageAt(ctx context.Context, address ethtypes.EthAddress, position ethtypes.EthBytes, blkParam ethtypes.EthBlockParamByNumberOrHash) (ethtypes.EthBytes, error) {
if err := gw.limit(ctx, stateRateLimitTokens); err != nil { if err := gw.limit(ctx, stateRateLimitTokens); err != nil {
return nil, err return nil, err
} }
if err := gw.checkBlkParam(ctx, blkParam, 0); err != nil { if err := gw.checkEthBlockParamByNumberOrHash(ctx, blkParam, 0); err != nil {
return nil, err return nil, err
} }
return gw.target.EthGetStorageAt(ctx, address, position, blkParam) return gw.target.EthGetStorageAt(ctx, address, position, blkParam)
} }
func (gw *Node) EthGetBalance(ctx context.Context, address ethtypes.EthAddress, blkParam string) (ethtypes.EthBigInt, error) { func (gw *Node) EthGetBalance(ctx context.Context, address ethtypes.EthAddress, blkParam ethtypes.EthBlockParamByNumberOrHash) (ethtypes.EthBigInt, error) {
if err := gw.limit(ctx, stateRateLimitTokens); err != nil { if err := gw.limit(ctx, stateRateLimitTokens); err != nil {
return ethtypes.EthBigInt(big.Zero()), err return ethtypes.EthBigInt(big.Zero()), err
} }
if err := gw.checkBlkParam(ctx, blkParam, 0); err != nil { if err := gw.checkEthBlockParamByNumberOrHash(ctx, blkParam, 0); err != nil {
return ethtypes.EthBigInt(big.Zero()), err return ethtypes.EthBigInt(big.Zero()), err
} }
@ -332,12 +364,12 @@ func (gw *Node) EthEstimateGas(ctx context.Context, tx ethtypes.EthCall) (ethtyp
return gw.target.EthEstimateGas(ctx, tx) return gw.target.EthEstimateGas(ctx, tx)
} }
func (gw *Node) EthCall(ctx context.Context, tx ethtypes.EthCall, blkParam string) (ethtypes.EthBytes, error) { func (gw *Node) EthCall(ctx context.Context, tx ethtypes.EthCall, blkParam ethtypes.EthBlockParamByNumberOrHash) (ethtypes.EthBytes, error) {
if err := gw.limit(ctx, stateRateLimitTokens); err != nil { if err := gw.limit(ctx, stateRateLimitTokens); err != nil {
return nil, err return nil, err
} }
if err := gw.checkBlkParam(ctx, blkParam, 0); err != nil { if err := gw.checkEthBlockParamByNumberOrHash(ctx, blkParam, 0); err != nil {
return nil, err return nil, err
} }

View File

@ -2,7 +2,6 @@ package itests
import ( import (
"context" "context"
"strconv"
"testing" "testing"
"time" "time"
@ -32,7 +31,7 @@ func TestEthGetBalanceExistingF4address(t *testing.T) {
// send some funds to the f410 address // send some funds to the f410 address
kit.SendFunds(ctx, t, client, deployer, fundAmount) kit.SendFunds(ctx, t, client, deployer, fundAmount)
balance, err := client.EthGetBalance(ctx, ethAddr, "latest") balance, err := client.EthGetBalance(ctx, ethAddr, ethtypes.NewEthBlockParamFromPredefined("latest"))
require.NoError(t, err) require.NoError(t, err)
require.Equal(t, balance, ethtypes.EthBigInt{Int: fundAmount.Int}) require.Equal(t, balance, ethtypes.EthBigInt{Int: fundAmount.Int})
} }
@ -47,7 +46,7 @@ func TestEthGetBalanceNonExistentF4address(t *testing.T) {
_, ethAddr, _ := client.EVM().NewAccount() _, ethAddr, _ := client.EVM().NewAccount()
balance, err := client.EthGetBalance(ctx, ethAddr, "latest") balance, err := client.EthGetBalance(ctx, ethAddr, ethtypes.NewEthBlockParamFromPredefined("latest"))
require.NoError(t, err) require.NoError(t, err)
require.Equal(t, balance, ethtypes.EthBigIntZero) require.Equal(t, balance, ethtypes.EthBigIntZero)
} }
@ -71,7 +70,7 @@ func TestEthGetBalanceExistentIDMaskedAddr(t *testing.T) {
balance, err := client.WalletBalance(ctx, fid) balance, err := client.WalletBalance(ctx, fid)
require.NoError(t, err) require.NoError(t, err)
ebal, err := client.EthGetBalance(ctx, ethAddr, "latest") ebal, err := client.EthGetBalance(ctx, ethAddr, ethtypes.NewEthBlockParamFromPredefined("latest"))
require.NoError(t, err) require.NoError(t, err)
require.Equal(t, ebal, ethtypes.EthBigInt{Int: balance.Int}) require.Equal(t, ebal, ethtypes.EthBigInt{Int: balance.Int})
} }
@ -93,7 +92,7 @@ func TestEthGetBalanceBuiltinActor(t *testing.T) {
ethAddr, err := ethtypes.EthAddressFromFilecoinAddress(fid) ethAddr, err := ethtypes.EthAddressFromFilecoinAddress(fid)
require.NoError(t, err) require.NoError(t, err)
ebal, err := client.EthGetBalance(ctx, ethAddr, "latest") ebal, err := client.EthGetBalance(ctx, ethAddr, ethtypes.NewEthBlockParamFromPredefined("latest"))
require.NoError(t, err) require.NoError(t, err)
require.Equal(t, ethtypes.EthBigInt{Int: big.NewInt(10).Int}, ebal) require.Equal(t, ethtypes.EthBigInt{Int: big.NewInt(10).Int}, ebal)
} }
@ -130,15 +129,15 @@ func TestEthBalanceCorrectLookup(t *testing.T) {
inclTsParents, err := client.ChainGetTipSet(ctx, inclTs.Parents()) inclTsParents, err := client.ChainGetTipSet(ctx, inclTs.Parents())
require.NoError(t, err) require.NoError(t, err)
bal, err := client.EVM().EthGetBalance(ctx, ethAddr, strconv.FormatInt(int64(inclTsParents.Height()), 10)) bal, err := client.EVM().EthGetBalance(ctx, ethAddr, ethtypes.NewEthBlockParamFromNumber(inclTsParents.Height()))
require.NoError(t, err) require.NoError(t, err)
require.Equal(t, int64(0), bal.Int64()) require.Equal(t, int64(0), bal.Int64())
bal, err = client.EVM().EthGetBalance(ctx, ethAddr, strconv.FormatInt(int64(inclTs.Height()), 10)) bal, err = client.EVM().EthGetBalance(ctx, ethAddr, ethtypes.NewEthBlockParamFromNumber(inclTs.Height()))
require.NoError(t, err) require.NoError(t, err)
require.Equal(t, val, bal.Int64()) require.Equal(t, val, bal.Int64())
bal, err = client.EVM().EthGetBalance(ctx, ethAddr, strconv.FormatInt(int64(execTs.Height()), 10)) bal, err = client.EVM().EthGetBalance(ctx, ethAddr, ethtypes.NewEthBlockParamFromNumber(execTs.Height()))
require.NoError(t, err) require.NoError(t, err)
require.Equal(t, val, bal.Int64()) require.Equal(t, val, bal.Int64())
} }

View File

@ -33,12 +33,12 @@ func TestGetCodeAndNonce(t *testing.T) {
{ {
// A random eth address should have no code. // A random eth address should have no code.
_, ethAddr, filAddr := client.EVM().NewAccount() _, ethAddr, filAddr := client.EVM().NewAccount()
bytecode, err := client.EVM().EthGetCode(ctx, ethAddr, "latest") bytecode, err := client.EVM().EthGetCode(ctx, ethAddr, ethtypes.NewEthBlockParamFromPredefined("latest"))
require.NoError(t, err) require.NoError(t, err)
require.Empty(t, bytecode) require.Empty(t, bytecode)
// Nonce should also be zero // Nonce should also be zero
nonce, err := client.EVM().EthGetTransactionCount(ctx, ethAddr, "latest") nonce, err := client.EVM().EthGetTransactionCount(ctx, ethAddr, ethtypes.NewEthBlockParamFromPredefined("latest"))
require.NoError(t, err) require.NoError(t, err)
require.Zero(t, nonce) require.Zero(t, nonce)
@ -46,12 +46,12 @@ func TestGetCodeAndNonce(t *testing.T) {
kit.SendFunds(ctx, t, client, filAddr, types.FromFil(10)) kit.SendFunds(ctx, t, client, filAddr, types.FromFil(10))
// The code should still be empty, target is now a placeholder. // The code should still be empty, target is now a placeholder.
bytecode, err = client.EVM().EthGetCode(ctx, ethAddr, "latest") bytecode, err = client.EVM().EthGetCode(ctx, ethAddr, ethtypes.NewEthBlockParamFromPredefined("latest"))
require.NoError(t, err) require.NoError(t, err)
require.Empty(t, bytecode) require.Empty(t, bytecode)
// Nonce should still be zero. // Nonce should still be zero.
nonce, err = client.EVM().EthGetTransactionCount(ctx, ethAddr, "latest") nonce, err = client.EVM().EthGetTransactionCount(ctx, ethAddr, ethtypes.NewEthBlockParamFromPredefined("latest"))
require.NoError(t, err) require.NoError(t, err)
require.Zero(t, nonce) require.Zero(t, nonce)
} }
@ -68,12 +68,12 @@ func TestGetCodeAndNonce(t *testing.T) {
contractFilAddr := *createReturn.RobustAddress contractFilAddr := *createReturn.RobustAddress
// The newly deployed contract should not be empty. // The newly deployed contract should not be empty.
bytecode, err := client.EVM().EthGetCode(ctx, contractAddr, "latest") bytecode, err := client.EVM().EthGetCode(ctx, contractAddr, ethtypes.NewEthBlockParamFromPredefined("latest"))
require.NoError(t, err) require.NoError(t, err)
require.NotEmpty(t, bytecode) require.NotEmpty(t, bytecode)
// Nonce should be one. // Nonce should be one.
nonce, err := client.EVM().EthGetTransactionCount(ctx, contractAddr, "latest") nonce, err := client.EVM().EthGetTransactionCount(ctx, contractAddr, ethtypes.NewEthBlockParamFromPredefined("latest"))
require.NoError(t, err) require.NoError(t, err)
require.Equal(t, ethtypes.EthUint64(1), nonce) require.Equal(t, ethtypes.EthUint64(1), nonce)
@ -82,12 +82,12 @@ func TestGetCodeAndNonce(t *testing.T) {
require.NoError(t, err) require.NoError(t, err)
// The code should be empty again. // The code should be empty again.
bytecode, err = client.EVM().EthGetCode(ctx, contractAddr, "latest") bytecode, err = client.EVM().EthGetCode(ctx, contractAddr, ethtypes.NewEthBlockParamFromPredefined("latest"))
require.NoError(t, err) require.NoError(t, err)
require.Empty(t, bytecode) require.Empty(t, bytecode)
// Nonce should go back to zero // Nonce should go back to zero
nonce, err = client.EVM().EthGetTransactionCount(ctx, contractAddr, "latest") nonce, err = client.EVM().EthGetTransactionCount(ctx, contractAddr, ethtypes.NewEthBlockParamFromPredefined("latest"))
require.NoError(t, err) require.NoError(t, err)
require.Zero(t, nonce) require.Zero(t, nonce)
} }

View File

@ -33,25 +33,25 @@ import (
type ethAPIRaw struct { type ethAPIRaw struct {
EthAccounts func(context.Context) (json.RawMessage, error) EthAccounts func(context.Context) (json.RawMessage, error)
EthBlockNumber func(context.Context) (json.RawMessage, error) EthBlockNumber func(context.Context) (json.RawMessage, error)
EthCall func(context.Context, ethtypes.EthCall, string) (json.RawMessage, error) EthCall func(context.Context, ethtypes.EthCall, ethtypes.EthBlockParamByNumberOrHash) (json.RawMessage, error)
EthChainId func(context.Context) (json.RawMessage, error) EthChainId func(context.Context) (json.RawMessage, error)
EthEstimateGas func(context.Context, ethtypes.EthCall) (json.RawMessage, error) EthEstimateGas func(context.Context, ethtypes.EthCall) (json.RawMessage, error)
EthFeeHistory func(context.Context, ethtypes.EthUint64, string, []float64) (json.RawMessage, error) EthFeeHistory func(context.Context, ethtypes.EthUint64, string, []float64) (json.RawMessage, error)
EthGasPrice func(context.Context) (json.RawMessage, error) EthGasPrice func(context.Context) (json.RawMessage, error)
EthGetBalance func(context.Context, ethtypes.EthAddress, string) (json.RawMessage, error) EthGetBalance func(context.Context, ethtypes.EthAddress, ethtypes.EthBlockParamByNumberOrHash) (json.RawMessage, error)
EthGetBlockByHash func(context.Context, ethtypes.EthHash, bool) (json.RawMessage, error) EthGetBlockByHash func(context.Context, ethtypes.EthHash, bool) (json.RawMessage, error)
EthGetBlockByNumber func(context.Context, string, bool) (json.RawMessage, error) EthGetBlockByNumber func(context.Context, string, bool) (json.RawMessage, error)
EthGetBlockTransactionCountByHash func(context.Context, ethtypes.EthHash) (json.RawMessage, error) EthGetBlockTransactionCountByHash func(context.Context, ethtypes.EthHash) (json.RawMessage, error)
EthGetBlockTransactionCountByNumber func(context.Context, ethtypes.EthUint64) (json.RawMessage, error) EthGetBlockTransactionCountByNumber func(context.Context, ethtypes.EthUint64) (json.RawMessage, error)
EthGetCode func(context.Context, ethtypes.EthAddress, string) (json.RawMessage, error) EthGetCode func(context.Context, ethtypes.EthAddress, ethtypes.EthBlockParamByNumberOrHash) (json.RawMessage, error)
EthGetFilterChanges func(context.Context, ethtypes.EthFilterID) (json.RawMessage, error) EthGetFilterChanges func(context.Context, ethtypes.EthFilterID) (json.RawMessage, error)
EthGetFilterLogs func(context.Context, ethtypes.EthFilterID) (json.RawMessage, error) EthGetFilterLogs func(context.Context, ethtypes.EthFilterID) (json.RawMessage, error)
EthGetLogs func(context.Context, *ethtypes.EthFilterSpec) (json.RawMessage, error) EthGetLogs func(context.Context, *ethtypes.EthFilterSpec) (json.RawMessage, error)
EthGetStorageAt func(context.Context, ethtypes.EthAddress, ethtypes.EthBytes, string) (json.RawMessage, error) EthGetStorageAt func(context.Context, ethtypes.EthAddress, ethtypes.EthBytes, ethtypes.EthBlockParamByNumberOrHash) (json.RawMessage, error)
EthGetTransactionByBlockHashAndIndex func(context.Context, ethtypes.EthHash, ethtypes.EthUint64) (json.RawMessage, error) EthGetTransactionByBlockHashAndIndex func(context.Context, ethtypes.EthHash, ethtypes.EthUint64) (json.RawMessage, error)
EthGetTransactionByBlockNumberAndIndex func(context.Context, ethtypes.EthUint64, ethtypes.EthUint64) (json.RawMessage, error) EthGetTransactionByBlockNumberAndIndex func(context.Context, ethtypes.EthUint64, ethtypes.EthUint64) (json.RawMessage, error)
EthGetTransactionByHash func(context.Context, *ethtypes.EthHash) (json.RawMessage, error) EthGetTransactionByHash func(context.Context, *ethtypes.EthHash) (json.RawMessage, error)
EthGetTransactionCount func(context.Context, ethtypes.EthAddress, string) (json.RawMessage, error) EthGetTransactionCount func(context.Context, ethtypes.EthAddress, ethtypes.EthBlockParamByNumberOrHash) (json.RawMessage, error)
EthGetTransactionReceipt func(context.Context, ethtypes.EthHash) (json.RawMessage, error) EthGetTransactionReceipt func(context.Context, ethtypes.EthHash) (json.RawMessage, error)
EthMaxPriorityFeePerGas func(context.Context) (json.RawMessage, error) EthMaxPriorityFeePerGas func(context.Context) (json.RawMessage, error)
EthNewBlockFilter func(context.Context) (json.RawMessage, error) EthNewBlockFilter func(context.Context) (json.RawMessage, error)
@ -168,7 +168,7 @@ func TestEthOpenRPCConformance(t *testing.T) {
return ethapi.EthCall(context.Background(), ethtypes.EthCall{ return ethapi.EthCall(context.Background(), ethtypes.EthCall{
From: &senderEthAddr, From: &senderEthAddr,
Data: contractBin, Data: contractBin,
}, "latest") }, ethtypes.NewEthBlockParamFromPredefined("latest"))
}, },
}, },
@ -207,7 +207,8 @@ func TestEthOpenRPCConformance(t *testing.T) {
method: "eth_getBalance", method: "eth_getBalance",
variant: "blocknumber", variant: "blocknumber",
call: func(a *ethAPIRaw) (json.RawMessage, error) { call: func(a *ethAPIRaw) (json.RawMessage, error) {
return ethapi.EthGetBalance(context.Background(), contractEthAddr, "0x0") blockParam, _ := ethtypes.NewEthBlockParamFromHexString("0x0")
return ethapi.EthGetBalance(context.Background(), contractEthAddr, blockParam)
}, },
}, },
@ -261,7 +262,7 @@ func TestEthOpenRPCConformance(t *testing.T) {
method: "eth_getCode", method: "eth_getCode",
variant: "blocknumber", variant: "blocknumber",
call: func(a *ethAPIRaw) (json.RawMessage, error) { call: func(a *ethAPIRaw) (json.RawMessage, error) {
return ethapi.EthGetCode(context.Background(), contractEthAddr, blockNumberWithMessage.Hex()) return ethapi.EthGetCode(context.Background(), contractEthAddr, ethtypes.NewEthBlockParamFromNumber(blockNumberWithMessage))
}, },
}, },
@ -307,7 +308,8 @@ func TestEthOpenRPCConformance(t *testing.T) {
method: "eth_getStorageAt", method: "eth_getStorageAt",
variant: "blocknumber", variant: "blocknumber",
call: func(a *ethAPIRaw) (json.RawMessage, error) { call: func(a *ethAPIRaw) (json.RawMessage, error) {
return ethapi.EthGetStorageAt(context.Background(), contractEthAddr, ethtypes.EthBytes{0}, "0x0") blockParam, _ := ethtypes.NewEthBlockParamFromHexString("0x0")
return ethapi.EthGetStorageAt(context.Background(), contractEthAddr, ethtypes.EthBytes{0}, blockParam)
}, },
}, },
@ -338,7 +340,7 @@ func TestEthOpenRPCConformance(t *testing.T) {
method: "eth_getTransactionCount", method: "eth_getTransactionCount",
variant: "blocknumber", variant: "blocknumber",
call: func(a *ethAPIRaw) (json.RawMessage, error) { call: func(a *ethAPIRaw) (json.RawMessage, error) {
return ethapi.EthGetTransactionCount(context.Background(), senderEthAddr, blockNumberWithMessage.Hex()) return ethapi.EthGetTransactionCount(context.Background(), senderEthAddr, ethtypes.NewEthBlockParamFromNumber(blockNumberWithMessage))
}, },
}, },

View File

@ -316,7 +316,7 @@ func TestGetBlockByNumber(t *testing.T) {
// Fetch balance on a null round; should not fail and should return previous balance. // Fetch balance on a null round; should not fail and should return previous balance.
// Should be lower than original balance. // Should be lower than original balance.
bal, err := client.EthGetBalance(ctx, ethAddr, (ethtypes.EthUint64(afterNullHeight - 1)).Hex()) bal, err := client.EthGetBalance(ctx, ethAddr, ethtypes.NewEthBlockParamFromNumber(ethtypes.EthUint64(afterNullHeight-1)))
require.NoError(t, err) require.NoError(t, err)
require.NotEqual(t, big.Zero(), bal) require.NotEqual(t, big.Zero(), bal)
require.Equal(t, types.FromFil(10).Int, bal.Int) require.Equal(t, types.FromFil(10).Int, bal.Int)

View File

@ -268,14 +268,14 @@ func TestFEVMDelegateCall(t *testing.T) {
// The implementation's storage should not have been updated. // The implementation's storage should not have been updated.
actorAddrEth, err := ethtypes.EthAddressFromFilecoinAddress(actorAddr) actorAddrEth, err := ethtypes.EthAddressFromFilecoinAddress(actorAddr)
require.NoError(t, err) require.NoError(t, err)
value, err := client.EVM().EthGetStorageAt(ctx, actorAddrEth, nil, "latest") value, err := client.EVM().EthGetStorageAt(ctx, actorAddrEth, nil, ethtypes.NewEthBlockParamFromPredefined("latest"))
require.NoError(t, err) require.NoError(t, err)
require.Equal(t, ethtypes.EthBytes(make([]byte, 32)), value) require.Equal(t, ethtypes.EthBytes(make([]byte, 32)), value)
// The storage actor's storage _should_ have been updated // The storage actor's storage _should_ have been updated
storageAddrEth, err := ethtypes.EthAddressFromFilecoinAddress(storageAddr) storageAddrEth, err := ethtypes.EthAddressFromFilecoinAddress(storageAddr)
require.NoError(t, err) require.NoError(t, err)
value, err = client.EVM().EthGetStorageAt(ctx, storageAddrEth, nil, "latest") value, err = client.EVM().EthGetStorageAt(ctx, storageAddrEth, nil, ethtypes.NewEthBlockParamFromPredefined("latest"))
require.NoError(t, err) require.NoError(t, err)
require.Equal(t, ethtypes.EthBytes(expectedResult), value) require.Equal(t, ethtypes.EthBytes(expectedResult), value)
} }
@ -881,7 +881,7 @@ func TestFEVMTestDeployOnTransfer(t *testing.T) {
require.NoError(t, err) require.NoError(t, err)
require.True(t, ret.Receipt.ExitCode.IsSuccess()) require.True(t, ret.Receipt.ExitCode.IsSuccess())
balance, err := client.EVM().EthGetBalance(ctx, randomAddr, "latest") balance, err := client.EVM().EthGetBalance(ctx, randomAddr, ethtypes.NewEthBlockParamFromPredefined("latest"))
require.NoError(t, err) require.NoError(t, err)
require.Equal(t, value.Int, balance.Int) require.Equal(t, value.Int, balance.Int)
@ -1030,7 +1030,7 @@ func TestFEVMErrorParsing(t *testing.T) {
_, err := e.EthCall(ctx, ethtypes.EthCall{ _, err := e.EthCall(ctx, ethtypes.EthCall{
To: &contractAddrEth, To: &contractAddrEth,
Data: entryPoint, Data: entryPoint,
}, "latest") }, ethtypes.NewEthBlockParamFromPredefined("latest"))
require.ErrorContains(t, err, expected) require.ErrorContains(t, err, expected)
}) })
t.Run("EthEstimateGas", func(t *testing.T) { t.Run("EthEstimateGas", func(t *testing.T) {

View File

@ -199,7 +199,7 @@ func (e *EVM) AssertAddressBalanceConsistent(ctx context.Context, addr address.A
ethAddr, err := ethtypes.EthAddressFromFilecoinAddress(addr) ethAddr, err := ethtypes.EthAddressFromFilecoinAddress(addr)
require.NoError(e.t, err) require.NoError(e.t, err)
ebal, err := e.EthGetBalance(ctx, ethAddr, "latest") ebal, err := e.EthGetBalance(ctx, ethAddr, ethtypes.NewEthBlockParamFromPredefined("latest"))
require.NoError(e.t, err) require.NoError(e.t, err)
require.Equal(e.t, fbal, types.BigInt(ebal)) require.Equal(e.t, fbal, types.BigInt(ebal))

View File

@ -62,7 +62,7 @@ func (e *EthModuleDummy) EthGetTransactionByHashLimited(ctx context.Context, txH
return nil, ErrModuleDisabled return nil, ErrModuleDisabled
} }
func (e *EthModuleDummy) EthGetTransactionCount(ctx context.Context, sender ethtypes.EthAddress, blkOpt string) (ethtypes.EthUint64, error) { func (e *EthModuleDummy) EthGetTransactionCount(ctx context.Context, sender ethtypes.EthAddress, blkParam ethtypes.EthBlockParamByNumberOrHash) (ethtypes.EthUint64, error) {
return 0, ErrModuleDisabled return 0, ErrModuleDisabled
} }
@ -82,15 +82,15 @@ func (e *EthModuleDummy) EthGetTransactionByBlockNumberAndIndex(ctx context.Cont
return ethtypes.EthTx{}, ErrModuleDisabled return ethtypes.EthTx{}, ErrModuleDisabled
} }
func (e *EthModuleDummy) EthGetCode(ctx context.Context, address ethtypes.EthAddress, blkOpt string) (ethtypes.EthBytes, error) { func (e *EthModuleDummy) EthGetCode(ctx context.Context, address ethtypes.EthAddress, blkParam ethtypes.EthBlockParamByNumberOrHash) (ethtypes.EthBytes, error) {
return nil, ErrModuleDisabled return nil, ErrModuleDisabled
} }
func (e *EthModuleDummy) EthGetStorageAt(ctx context.Context, address ethtypes.EthAddress, position ethtypes.EthBytes, blkParam string) (ethtypes.EthBytes, error) { func (e *EthModuleDummy) EthGetStorageAt(ctx context.Context, address ethtypes.EthAddress, position ethtypes.EthBytes, blkParam ethtypes.EthBlockParamByNumberOrHash) (ethtypes.EthBytes, error) {
return nil, ErrModuleDisabled return nil, ErrModuleDisabled
} }
func (e *EthModuleDummy) EthGetBalance(ctx context.Context, address ethtypes.EthAddress, blkParam string) (ethtypes.EthBigInt, error) { func (e *EthModuleDummy) EthGetBalance(ctx context.Context, address ethtypes.EthAddress, blkParam ethtypes.EthBlockParamByNumberOrHash) (ethtypes.EthBigInt, error) {
return ethtypes.EthBigIntZero, ErrModuleDisabled return ethtypes.EthBigIntZero, ErrModuleDisabled
} }
@ -126,7 +126,7 @@ func (e *EthModuleDummy) EthEstimateGas(ctx context.Context, tx ethtypes.EthCall
return 0, ErrModuleDisabled return 0, ErrModuleDisabled
} }
func (e *EthModuleDummy) EthCall(ctx context.Context, tx ethtypes.EthCall, blkParam string) (ethtypes.EthBytes, error) { func (e *EthModuleDummy) EthCall(ctx context.Context, tx ethtypes.EthCall, blkParam ethtypes.EthBlockParamByNumberOrHash) (ethtypes.EthBytes, error) {
return nil, ErrModuleDisabled return nil, ErrModuleDisabled
} }

View File

@ -59,12 +59,12 @@ type EthModuleAPI interface {
EthGetTransactionByHashLimited(ctx context.Context, txHash *ethtypes.EthHash, limit abi.ChainEpoch) (*ethtypes.EthTx, error) EthGetTransactionByHashLimited(ctx context.Context, txHash *ethtypes.EthHash, limit abi.ChainEpoch) (*ethtypes.EthTx, error)
EthGetMessageCidByTransactionHash(ctx context.Context, txHash *ethtypes.EthHash) (*cid.Cid, error) EthGetMessageCidByTransactionHash(ctx context.Context, txHash *ethtypes.EthHash) (*cid.Cid, error)
EthGetTransactionHashByCid(ctx context.Context, cid cid.Cid) (*ethtypes.EthHash, error) EthGetTransactionHashByCid(ctx context.Context, cid cid.Cid) (*ethtypes.EthHash, error)
EthGetTransactionCount(ctx context.Context, sender ethtypes.EthAddress, blkOpt string) (ethtypes.EthUint64, error) EthGetTransactionCount(ctx context.Context, sender ethtypes.EthAddress, blkParam ethtypes.EthBlockParamByNumberOrHash) (ethtypes.EthUint64, error)
EthGetTransactionReceipt(ctx context.Context, txHash ethtypes.EthHash) (*api.EthTxReceipt, error) EthGetTransactionReceipt(ctx context.Context, txHash ethtypes.EthHash) (*api.EthTxReceipt, error)
EthGetTransactionReceiptLimited(ctx context.Context, txHash ethtypes.EthHash, limit abi.ChainEpoch) (*api.EthTxReceipt, error) EthGetTransactionReceiptLimited(ctx context.Context, txHash ethtypes.EthHash, limit abi.ChainEpoch) (*api.EthTxReceipt, error)
EthGetCode(ctx context.Context, address ethtypes.EthAddress, blkOpt string) (ethtypes.EthBytes, error) EthGetCode(ctx context.Context, address ethtypes.EthAddress, blkParam ethtypes.EthBlockParamByNumberOrHash) (ethtypes.EthBytes, error)
EthGetStorageAt(ctx context.Context, address ethtypes.EthAddress, position ethtypes.EthBytes, blkParam string) (ethtypes.EthBytes, error) EthGetStorageAt(ctx context.Context, address ethtypes.EthAddress, position ethtypes.EthBytes, blkParam ethtypes.EthBlockParamByNumberOrHash) (ethtypes.EthBytes, error)
EthGetBalance(ctx context.Context, address ethtypes.EthAddress, blkParam string) (ethtypes.EthBigInt, error) EthGetBalance(ctx context.Context, address ethtypes.EthAddress, blkParam ethtypes.EthBlockParamByNumberOrHash) (ethtypes.EthBigInt, error)
EthFeeHistory(ctx context.Context, p jsonrpc.RawParams) (ethtypes.EthFeeHistory, error) EthFeeHistory(ctx context.Context, p jsonrpc.RawParams) (ethtypes.EthFeeHistory, error)
EthChainId(ctx context.Context) (ethtypes.EthUint64, error) EthChainId(ctx context.Context) (ethtypes.EthUint64, error)
EthSyncing(ctx context.Context) (ethtypes.EthSyncingResult, error) EthSyncing(ctx context.Context) (ethtypes.EthSyncingResult, error)
@ -73,7 +73,7 @@ type EthModuleAPI interface {
EthProtocolVersion(ctx context.Context) (ethtypes.EthUint64, error) EthProtocolVersion(ctx context.Context) (ethtypes.EthUint64, error)
EthGasPrice(ctx context.Context) (ethtypes.EthBigInt, error) EthGasPrice(ctx context.Context) (ethtypes.EthBigInt, error)
EthEstimateGas(ctx context.Context, tx ethtypes.EthCall) (ethtypes.EthUint64, error) EthEstimateGas(ctx context.Context, tx ethtypes.EthCall) (ethtypes.EthUint64, error)
EthCall(ctx context.Context, tx ethtypes.EthCall, blkParam string) (ethtypes.EthBytes, error) EthCall(ctx context.Context, tx ethtypes.EthCall, blkParam ethtypes.EthBlockParamByNumberOrHash) (ethtypes.EthBytes, error)
EthMaxPriorityFeePerGas(ctx context.Context) (ethtypes.EthBigInt, error) EthMaxPriorityFeePerGas(ctx context.Context) (ethtypes.EthBigInt, error)
EthSendRawTransaction(ctx context.Context, rawTx ethtypes.EthBytes) (ethtypes.EthHash, error) EthSendRawTransaction(ctx context.Context, rawTx ethtypes.EthBytes) (ethtypes.EthHash, error)
Web3ClientVersion(ctx context.Context) (string, error) Web3ClientVersion(ctx context.Context) (string, error)
@ -241,7 +241,76 @@ func (a *EthModule) EthGetBlockByHash(ctx context.Context, blkHash ethtypes.EthH
return newEthBlockFromFilecoinTipSet(ctx, ts, fullTxInfo, a.Chain, a.StateAPI) return newEthBlockFromFilecoinTipSet(ctx, ts, fullTxInfo, a.Chain, a.StateAPI)
} }
func (a *EthModule) parseBlkParam(ctx context.Context, blkParam string, strict bool) (tipset *types.TipSet, err error) { func (a *EthModule) getTipsetByEthBlockNumberOrHash(ctx context.Context, blkParam ethtypes.EthBlockParamByNumberOrHash) (*types.TipSet, error) {
head := a.Chain.GetHeaviestTipSet()
predefined := blkParam.PredefinedBlock
if predefined != nil {
if *predefined == "earliest" {
return nil, fmt.Errorf("block param \"earliest\" is not supported")
} else if *predefined == "pending" {
return head, nil
} else if *predefined == "latest" {
parent, err := a.Chain.GetTipSetFromKey(ctx, head.Parents())
if err != nil {
return nil, fmt.Errorf("cannot get parent tipset")
}
return parent, nil
} else {
return nil, fmt.Errorf("unknown predefined block %s", *predefined)
}
}
// utility function to validate a tipset by height and return it
returnAndValidateTipsetFunc := func(height abi.ChainEpoch) (*types.TipSet, error) {
if height > head.Height()-1 {
return nil, fmt.Errorf("requested a future epoch (beyond 'latest')")
}
ts, err := a.ChainAPI.ChainGetTipSetByHeight(ctx, height, head.Key())
if err != nil {
return nil, fmt.Errorf("cannot get tipset at height: %v", height)
}
return ts, nil
}
if blkParam.Number != nil {
return returnAndValidateTipsetFunc(abi.ChainEpoch(*blkParam.Number))
}
if blkParam.BlockNumber != nil {
return returnAndValidateTipsetFunc(abi.ChainEpoch(*blkParam.BlockNumber))
}
if blkParam.BlockHash != nil {
ts, err := a.Chain.GetTipSetByCid(ctx, blkParam.BlockHash.ToCid())
if err != nil {
return nil, fmt.Errorf("cannot get tipset by hash: %v", err)
}
if blkParam.RequireCanonical {
// walk back the current chain (our head) until we reach targetHeight and validate the block hash
currTs := head
for {
if currTs.Equals(ts) {
return ts, nil
} else if currTs.Height() < ts.Height() {
return nil, fmt.Errorf("could not find block hash %s in canonical chain", blkParam.BlockHash.ToCid())
}
currTs, err = a.Chain.LoadTipSet(ctx, currTs.Parents())
if err != nil {
return nil, fmt.Errorf("failed to load tipset: %v", err)
}
}
}
return ts, nil
}
return nil, errors.New("invalid block param")
}
func (a *EthModule) parseBlkParam(ctx context.Context, blkParam string, strict bool) (*types.TipSet, error) {
if blkParam == "earliest" { if blkParam == "earliest" {
return nil, fmt.Errorf("block param \"earliest\" is not supported") return nil, fmt.Errorf("block param \"earliest\" is not supported")
} }
@ -382,13 +451,13 @@ func (a *EthModule) EthGetTransactionHashByCid(ctx context.Context, cid cid.Cid)
return &hash, err return &hash, err
} }
func (a *EthModule) EthGetTransactionCount(ctx context.Context, sender ethtypes.EthAddress, blkParam string) (ethtypes.EthUint64, error) { func (a *EthModule) EthGetTransactionCount(ctx context.Context, sender ethtypes.EthAddress, blkParam ethtypes.EthBlockParamByNumberOrHash) (ethtypes.EthUint64, error) {
addr, err := sender.ToFilecoinAddress() addr, err := sender.ToFilecoinAddress()
if err != nil { if err != nil {
return ethtypes.EthUint64(0), nil return ethtypes.EthUint64(0), nil
} }
ts, err := a.parseBlkParam(ctx, blkParam, false) ts, err := a.getTipsetByEthBlockNumberOrHash(ctx, blkParam)
if err != nil { if err != nil {
return ethtypes.EthUint64(0), xerrors.Errorf("failed to process block param: %s; %w", blkParam, err) return ethtypes.EthUint64(0), xerrors.Errorf("failed to process block param: %s; %w", blkParam, err)
} }
@ -470,13 +539,13 @@ func (a *EthAPI) EthGetTransactionByBlockNumberAndIndex(context.Context, ethtype
} }
// EthGetCode returns string value of the compiled bytecode // EthGetCode returns string value of the compiled bytecode
func (a *EthModule) EthGetCode(ctx context.Context, ethAddr ethtypes.EthAddress, blkParam string) (ethtypes.EthBytes, error) { func (a *EthModule) EthGetCode(ctx context.Context, ethAddr ethtypes.EthAddress, blkParam ethtypes.EthBlockParamByNumberOrHash) (ethtypes.EthBytes, error) {
to, err := ethAddr.ToFilecoinAddress() to, err := ethAddr.ToFilecoinAddress()
if err != nil { if err != nil {
return nil, xerrors.Errorf("cannot get Filecoin address: %w", err) return nil, xerrors.Errorf("cannot get Filecoin address: %w", err)
} }
ts, err := a.parseBlkParam(ctx, blkParam, false) ts, err := a.getTipsetByEthBlockNumberOrHash(ctx, blkParam)
if err != nil { if err != nil {
return nil, xerrors.Errorf("failed to process block param: %s; %w", blkParam, err) return nil, xerrors.Errorf("failed to process block param: %s; %w", blkParam, err)
} }
@ -554,8 +623,8 @@ func (a *EthModule) EthGetCode(ctx context.Context, ethAddr ethtypes.EthAddress,
return blk.RawData(), nil return blk.RawData(), nil
} }
func (a *EthModule) EthGetStorageAt(ctx context.Context, ethAddr ethtypes.EthAddress, position ethtypes.EthBytes, blkParam string) (ethtypes.EthBytes, error) { func (a *EthModule) EthGetStorageAt(ctx context.Context, ethAddr ethtypes.EthAddress, position ethtypes.EthBytes, blkParam ethtypes.EthBlockParamByNumberOrHash) (ethtypes.EthBytes, error) {
ts, err := a.parseBlkParam(ctx, blkParam, false) ts, err := a.getTipsetByEthBlockNumberOrHash(ctx, blkParam)
if err != nil { if err != nil {
return nil, xerrors.Errorf("failed to process block param: %s; %w", blkParam, err) return nil, xerrors.Errorf("failed to process block param: %s; %w", blkParam, err)
} }
@ -645,13 +714,13 @@ func (a *EthModule) EthGetStorageAt(ctx context.Context, ethAddr ethtypes.EthAdd
return ethtypes.EthBytes(ret), nil return ethtypes.EthBytes(ret), nil
} }
func (a *EthModule) EthGetBalance(ctx context.Context, address ethtypes.EthAddress, blkParam string) (ethtypes.EthBigInt, error) { func (a *EthModule) EthGetBalance(ctx context.Context, address ethtypes.EthAddress, blkParam ethtypes.EthBlockParamByNumberOrHash) (ethtypes.EthBigInt, error) {
filAddr, err := address.ToFilecoinAddress() filAddr, err := address.ToFilecoinAddress()
if err != nil { if err != nil {
return ethtypes.EthBigInt{}, err return ethtypes.EthBigInt{}, err
} }
ts, err := a.parseBlkParam(ctx, blkParam, false) ts, err := a.getTipsetByEthBlockNumberOrHash(ctx, blkParam)
if err != nil { if err != nil {
return ethtypes.EthBigInt{}, xerrors.Errorf("failed to process block param: %s; %w", blkParam, err) return ethtypes.EthBigInt{}, xerrors.Errorf("failed to process block param: %s; %w", blkParam, err)
} }
@ -1112,13 +1181,13 @@ func ethGasSearch(
return -1, xerrors.Errorf("message execution failed: exit %s, reason: %s", res.MsgRct.ExitCode, res.Error) return -1, xerrors.Errorf("message execution failed: exit %s, reason: %s", res.MsgRct.ExitCode, res.Error)
} }
func (a *EthModule) EthCall(ctx context.Context, tx ethtypes.EthCall, blkParam string) (ethtypes.EthBytes, error) { func (a *EthModule) EthCall(ctx context.Context, tx ethtypes.EthCall, blkParam ethtypes.EthBlockParamByNumberOrHash) (ethtypes.EthBytes, error) {
msg, err := a.ethCallToFilecoinMessage(ctx, tx) msg, err := a.ethCallToFilecoinMessage(ctx, tx)
if err != nil { if err != nil {
return nil, xerrors.Errorf("failed to convert ethcall to filecoin message: %w", err) return nil, xerrors.Errorf("failed to convert ethcall to filecoin message: %w", err)
} }
ts, err := a.parseBlkParam(ctx, blkParam, false) ts, err := a.getTipsetByEthBlockNumberOrHash(ctx, blkParam)
if err != nil { if err != nil {
return nil, xerrors.Errorf("failed to process block param: %s; %w", blkParam, err) return nil, xerrors.Errorf("failed to process block param: %s; %w", blkParam, err)
} }