diff --git a/api/api_full.go b/api/api_full.go index af62c3b0c..cbf2b7435 100644 --- a/api/api_full.go +++ b/api/api_full.go @@ -796,32 +796,32 @@ type FullNode interface { // EthGetBlockTransactionCountByHash returns the number of messages in the TipSet 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 - 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 - 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 - 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 - 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 - 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 + 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 + 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 + EthGetTransactionHashByCid(ctx context.Context, cid cid.Cid) (*ethtypes.EthHash, error) //perm:read + EthGetMessageCidByTransactionHash(ctx context.Context, txHash *ethtypes.EthHash) (*cid.Cid, 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 + 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 + 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 - EthGetStorageAt(ctx context.Context, address ethtypes.EthAddress, position ethtypes.EthBytes, blkParam string) (ethtypes.EthBytes, error) //perm:read - EthGetBalance(ctx context.Context, address ethtypes.EthAddress, blkParam string) (ethtypes.EthBigInt, error) //perm:read - EthChainId(ctx context.Context) (ethtypes.EthUint64, error) //perm:read - EthSyncing(ctx context.Context) (ethtypes.EthSyncingResult, error) //perm:read - NetVersion(ctx context.Context) (string, error) //perm:read - NetListening(ctx context.Context) (bool, error) //perm:read - EthProtocolVersion(ctx context.Context) (ethtypes.EthUint64, error) //perm:read - EthGasPrice(ctx context.Context) (ethtypes.EthBigInt, error) //perm:read - EthFeeHistory(ctx context.Context, p jsonrpc.RawParams) (ethtypes.EthFeeHistory, 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 ethtypes.EthBlockParamByNumberOrHash) (ethtypes.EthBytes, 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 + EthSyncing(ctx context.Context) (ethtypes.EthSyncingResult, error) //perm:read + NetVersion(ctx context.Context) (string, error) //perm:read + NetListening(ctx context.Context) (bool, error) //perm:read + EthProtocolVersion(ctx context.Context) (ethtypes.EthUint64, error) //perm:read + EthGasPrice(ctx context.Context) (ethtypes.EthBigInt, error) //perm:read + EthFeeHistory(ctx context.Context, p jsonrpc.RawParams) (ethtypes.EthFeeHistory, error) //perm:read - EthMaxPriorityFeePerGas(ctx context.Context) (ethtypes.EthBigInt, 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 + EthMaxPriorityFeePerGas(ctx context.Context) (ethtypes.EthBigInt, error) //perm:read + EthEstimateGas(ctx context.Context, tx ethtypes.EthCall) (ethtypes.EthUint64, 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 diff --git a/api/api_gateway.go b/api/api_gateway.go index 97116d345..767918b10 100644 --- a/api/api_gateway.go +++ b/api/api_gateway.go @@ -94,12 +94,12 @@ type Gateway interface { EthGetTransactionByHashLimited(ctx context.Context, txHash *ethtypes.EthHash, limit abi.ChainEpoch) (*ethtypes.EthTx, error) EthGetTransactionHashByCid(ctx context.Context, cid cid.Cid) (*ethtypes.EthHash, 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) EthGetTransactionReceiptLimited(ctx context.Context, txHash ethtypes.EthHash, limit abi.ChainEpoch) (*EthTxReceipt, error) - EthGetCode(ctx context.Context, address ethtypes.EthAddress, blkOpt string) (ethtypes.EthBytes, error) - EthGetStorageAt(ctx context.Context, address ethtypes.EthAddress, position ethtypes.EthBytes, blkParam string) (ethtypes.EthBytes, error) - EthGetBalance(ctx context.Context, address ethtypes.EthAddress, blkParam string) (ethtypes.EthBigInt, 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 ethtypes.EthBlockParamByNumberOrHash) (ethtypes.EthBytes, error) + EthGetBalance(ctx context.Context, address ethtypes.EthAddress, blkParam ethtypes.EthBlockParamByNumberOrHash) (ethtypes.EthBigInt, error) EthChainId(ctx context.Context) (ethtypes.EthUint64, error) EthSyncing(ctx context.Context) (ethtypes.EthSyncingResult, error) NetVersion(ctx context.Context) (string, error) @@ -109,7 +109,7 @@ type Gateway interface { EthFeeHistory(ctx context.Context, p jsonrpc.RawParams) (ethtypes.EthFeeHistory, error) EthMaxPriorityFeePerGas(ctx context.Context) (ethtypes.EthBigInt, 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) EthGetLogs(ctx context.Context, filter *ethtypes.EthFilterSpec) (*ethtypes.EthFilterResult, error) EthGetFilterChanges(ctx context.Context, id ethtypes.EthFilterID) (*ethtypes.EthFilterResult, error) diff --git a/api/docgen/docgen.go b/api/docgen/docgen.go index 5c1d43129..018629600 100644 --- a/api/docgen/docgen.go +++ b/api/docgen/docgen.go @@ -480,6 +480,9 @@ func ExampleValue(method string, t, parent reflect.Type) interface{} { es := exampleStruct(method, t.Elem(), t) ExampleValues[t] = es return es + } else if t.Elem().Kind() == reflect.String { + str := "string value" + return &str } case reflect.Interface: return struct{}{} diff --git a/api/mocks/mock_full.go b/api/mocks/mock_full.go index 0b0e3ca4c..62ba66ccf 100644 --- a/api/mocks/mock_full.go +++ b/api/mocks/mock_full.go @@ -1012,7 +1012,7 @@ func (mr *MockFullNodeMockRecorder) EthBlockNumber(arg0 interface{}) *gomock.Cal } // 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() ret := m.ctrl.Call(m, "EthCall", arg0, arg1, arg2) ret0, _ := ret[0].(ethtypes.EthBytes) @@ -1087,7 +1087,7 @@ func (mr *MockFullNodeMockRecorder) EthGasPrice(arg0 interface{}) *gomock.Call { } // 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() ret := m.ctrl.Call(m, "EthGetBalance", arg0, arg1, arg2) ret0, _ := ret[0].(ethtypes.EthBigInt) @@ -1162,7 +1162,7 @@ func (mr *MockFullNodeMockRecorder) EthGetBlockTransactionCountByNumber(arg0, ar } // 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() ret := m.ctrl.Call(m, "EthGetCode", arg0, arg1, arg2) ret0, _ := ret[0].(ethtypes.EthBytes) @@ -1237,7 +1237,7 @@ func (mr *MockFullNodeMockRecorder) EthGetMessageCidByTransactionHash(arg0, arg1 } // 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() ret := m.ctrl.Call(m, "EthGetStorageAt", arg0, arg1, arg2, arg3) ret0, _ := ret[0].(ethtypes.EthBytes) @@ -1312,7 +1312,7 @@ func (mr *MockFullNodeMockRecorder) EthGetTransactionByHashLimited(arg0, arg1, a } // 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() ret := m.ctrl.Call(m, "EthGetTransactionCount", arg0, arg1, arg2) ret0, _ := ret[0].(ethtypes.EthUint64) diff --git a/api/proxy_gen.go b/api/proxy_gen.go index f2caab266..0f6c38b56 100644 --- a/api/proxy_gen.go +++ b/api/proxy_gen.go @@ -252,7 +252,7 @@ type FullNodeMethods struct { 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"` @@ -262,7 +262,7 @@ type FullNodeMethods struct { 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"` @@ -272,7 +272,7 @@ type FullNodeMethods struct { 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"` @@ -282,7 +282,7 @@ type FullNodeMethods struct { 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"` @@ -292,7 +292,7 @@ type FullNodeMethods struct { 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"` @@ -668,7 +668,7 @@ type GatewayMethods struct { 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) `` @@ -678,7 +678,7 @@ type GatewayMethods struct { 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) `` @@ -688,7 +688,7 @@ type GatewayMethods struct { 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) `` @@ -698,13 +698,13 @@ type GatewayMethods struct { 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) `` 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) `` @@ -2091,14 +2091,14 @@ func (s *FullNodeStub) EthBlockNumber(p0 context.Context) (ethtypes.EthUint64, e 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 { return *new(ethtypes.EthBytes), ErrNotSupported } 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 } @@ -2146,14 +2146,14 @@ func (s *FullNodeStub) EthGasPrice(p0 context.Context) (ethtypes.EthBigInt, erro 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 { return *new(ethtypes.EthBigInt), ErrNotSupported } 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 } @@ -2201,14 +2201,14 @@ func (s *FullNodeStub) EthGetBlockTransactionCountByNumber(p0 context.Context, p 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 { return *new(ethtypes.EthBytes), ErrNotSupported } 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 } @@ -2256,14 +2256,14 @@ func (s *FullNodeStub) EthGetMessageCidByTransactionHash(p0 context.Context, p1 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 { return *new(ethtypes.EthBytes), ErrNotSupported } 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 } @@ -2311,14 +2311,14 @@ func (s *FullNodeStub) EthGetTransactionByHashLimited(p0 context.Context, p1 *et 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 { return *new(ethtypes.EthUint64), ErrNotSupported } 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 } @@ -4313,14 +4313,14 @@ func (s *GatewayStub) EthBlockNumber(p0 context.Context) (ethtypes.EthUint64, er 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 { return *new(ethtypes.EthBytes), ErrNotSupported } 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 } @@ -4368,14 +4368,14 @@ func (s *GatewayStub) EthGasPrice(p0 context.Context) (ethtypes.EthBigInt, error 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 { return *new(ethtypes.EthBigInt), ErrNotSupported } 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 } @@ -4423,14 +4423,14 @@ func (s *GatewayStub) EthGetBlockTransactionCountByNumber(p0 context.Context, p1 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 { return *new(ethtypes.EthBytes), ErrNotSupported } 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 } @@ -4478,14 +4478,14 @@ func (s *GatewayStub) EthGetMessageCidByTransactionHash(p0 context.Context, p1 * 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 { return *new(ethtypes.EthBytes), ErrNotSupported } 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 } @@ -4511,14 +4511,14 @@ func (s *GatewayStub) EthGetTransactionByHashLimited(p0 context.Context, p1 *eth 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 { return *new(ethtypes.EthUint64), ErrNotSupported } 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 } diff --git a/build/openrpc/full.json.gz b/build/openrpc/full.json.gz index 57f88c609..a3891144b 100644 Binary files a/build/openrpc/full.json.gz and b/build/openrpc/full.json.gz differ diff --git a/build/openrpc/gateway.json.gz b/build/openrpc/gateway.json.gz index abf3dc973..34e27f110 100644 Binary files a/build/openrpc/gateway.json.gz and b/build/openrpc/gateway.json.gz differ diff --git a/chain/types/ethtypes/eth_types.go b/chain/types/ethtypes/eth_types.go index 64f67f662..dcb85fffe 100644 --- a/chain/types/ethtypes/eth_types.go +++ b/chain/types/ethtypes/eth_types.go @@ -839,3 +839,82 @@ func (e EthFeeHistoryParams) MarshalJSON() ([]byte, error) { } 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") +} diff --git a/cli/evm.go b/cli/evm.go index 84cbf8c61..e3dda8647 100644 --- a/cli/evm.go +++ b/cli/evm.go @@ -130,7 +130,7 @@ var EvmCallSimulateCmd = &cli.Command{ From: &fromEthAddr, To: &toEthAddr, Data: params, - }, "") + }, ethtypes.NewEthBlockParamFromPredefined("latest")) if err != nil { fmt.Println("Eth call fails, return val: ", res) return err @@ -518,7 +518,7 @@ var EvmGetBytecode = &cli.Command{ defer closer() ctx := ReqContext(cctx) - code, err := api.EthGetCode(ctx, contractAddr, "latest") + code, err := api.EthGetCode(ctx, contractAddr, ethtypes.NewEthBlockParamFromPredefined("latest")) if err != nil { return err } diff --git a/documentation/en/api-v1-unstable-methods.md b/documentation/en/api-v1-unstable-methods.md index e3c97eecf..a72c57d61 100644 --- a/documentation/en/api-v1-unstable-methods.md +++ b/documentation/en/api-v1-unstable-methods.md @@ -2375,7 +2375,13 @@ Inputs: "value": "0x0", "data": "0x07" }, - "string value" + { + "PredefinedBlock": "string value", + "Number": "0x5", + "blockNumber": "0x5", + "blockHash": "0x37690cfec6c1bf4c3b9288c7a5d783e98731e90b0a4c177c2a374c7a9427355e", + "requireCanonical": true + } ] ``` @@ -2455,7 +2461,13 @@ Inputs: ```json [ "0x5cbeecf99d3fdb3f25e309cc264f240bb0664031", - "string value" + { + "PredefinedBlock": "string value", + "Number": "0x5", + "blockNumber": "0x5", + "blockHash": "0x37690cfec6c1bf4c3b9288c7a5d783e98731e90b0a4c177c2a374c7a9427355e", + "requireCanonical": true + } ] ``` @@ -2588,7 +2600,13 @@ Inputs: ```json [ "0x5cbeecf99d3fdb3f25e309cc264f240bb0664031", - "string value" + { + "PredefinedBlock": "string value", + "Number": "0x5", + "blockNumber": "0x5", + "blockHash": "0x37690cfec6c1bf4c3b9288c7a5d783e98731e90b0a4c177c2a374c7a9427355e", + "requireCanonical": true + } ] ``` @@ -2691,7 +2709,13 @@ Inputs: [ "0x5cbeecf99d3fdb3f25e309cc264f240bb0664031", "0x07", - "string value" + { + "PredefinedBlock": "string value", + "Number": "0x5", + "blockNumber": "0x5", + "blockHash": "0x37690cfec6c1bf4c3b9288c7a5d783e98731e90b0a4c177c2a374c7a9427355e", + "requireCanonical": true + } ] ``` @@ -2861,7 +2885,13 @@ Inputs: ```json [ "0x5cbeecf99d3fdb3f25e309cc264f240bb0664031", - "string value" + { + "PredefinedBlock": "string value", + "Number": "0x5", + "blockNumber": "0x5", + "blockHash": "0x37690cfec6c1bf4c3b9288c7a5d783e98731e90b0a4c177c2a374c7a9427355e", + "requireCanonical": true + } ] ``` diff --git a/gateway/node.go b/gateway/node.go index 6f1dac73a..b8eac8d72 100644 --- a/gateway/node.go +++ b/gateway/node.go @@ -110,13 +110,13 @@ type TargetAPI interface { EthGetTransactionByHashLimited(ctx context.Context, txHash *ethtypes.EthHash, limit abi.ChainEpoch) (*ethtypes.EthTx, error) EthGetTransactionHashByCid(ctx context.Context, cid cid.Cid) (*ethtypes.EthHash, 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) 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) - EthGetCode(ctx context.Context, address ethtypes.EthAddress, blkOpt string) (ethtypes.EthBytes, error) - EthGetStorageAt(ctx context.Context, address ethtypes.EthAddress, position ethtypes.EthBytes, blkParam string) (ethtypes.EthBytes, error) - EthGetBalance(ctx context.Context, address ethtypes.EthAddress, blkParam string) (ethtypes.EthBigInt, 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 ethtypes.EthBlockParamByNumberOrHash) (ethtypes.EthBytes, error) + EthGetBalance(ctx context.Context, address ethtypes.EthAddress, blkParam ethtypes.EthBlockParamByNumberOrHash) (ethtypes.EthBigInt, error) EthChainId(ctx context.Context) (ethtypes.EthUint64, error) EthSyncing(ctx context.Context) (ethtypes.EthSyncingResult, error) NetVersion(ctx context.Context) (string, error) @@ -126,7 +126,7 @@ type TargetAPI interface { EthFeeHistory(ctx context.Context, p jsonrpc.RawParams) (ethtypes.EthFeeHistory, error) EthMaxPriorityFeePerGas(ctx context.Context) (ethtypes.EthBigInt, 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) EthGetLogs(ctx context.Context, filter *ethtypes.EthFilterSpec) (*ethtypes.EthFilterResult, error) EthGetFilterChanges(ctx context.Context, id ethtypes.EthFilterID) (*ethtypes.EthFilterResult, error) diff --git a/gateway/proxy_eth.go b/gateway/proxy_eth.go index b992c9ea9..275baa935 100644 --- a/gateway/proxy_eth.go +++ b/gateway/proxy_eth.go @@ -80,6 +80,38 @@ func (gw *Node) checkBlkHash(ctx context.Context, blkHash ethtypes.EthHash) erro 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 { if blkParam == "earliest" { // 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) } -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 { 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 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) { @@ -208,36 +240,36 @@ func (gw *Node) EthGetTransactionReceiptLimited(ctx context.Context, txHash etht 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 { 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 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 { 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 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 { 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 } @@ -332,12 +364,12 @@ func (gw *Node) EthEstimateGas(ctx context.Context, tx ethtypes.EthCall) (ethtyp 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 { return nil, err } - if err := gw.checkBlkParam(ctx, blkParam, 0); err != nil { + if err := gw.checkEthBlockParamByNumberOrHash(ctx, blkParam, 0); err != nil { return nil, err } diff --git a/itests/eth_balance_test.go b/itests/eth_balance_test.go index 116587902..cd6d1558b 100644 --- a/itests/eth_balance_test.go +++ b/itests/eth_balance_test.go @@ -2,7 +2,6 @@ package itests import ( "context" - "strconv" "testing" "time" @@ -32,7 +31,7 @@ func TestEthGetBalanceExistingF4address(t *testing.T) { // send some funds to the f410 address 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.Equal(t, balance, ethtypes.EthBigInt{Int: fundAmount.Int}) } @@ -47,7 +46,7 @@ func TestEthGetBalanceNonExistentF4address(t *testing.T) { _, 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.Equal(t, balance, ethtypes.EthBigIntZero) } @@ -71,7 +70,7 @@ func TestEthGetBalanceExistentIDMaskedAddr(t *testing.T) { balance, err := client.WalletBalance(ctx, fid) 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.Equal(t, ebal, ethtypes.EthBigInt{Int: balance.Int}) } @@ -93,7 +92,7 @@ func TestEthGetBalanceBuiltinActor(t *testing.T) { ethAddr, err := ethtypes.EthAddressFromFilecoinAddress(fid) 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.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()) 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.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.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.Equal(t, val, bal.Int64()) } diff --git a/itests/eth_bytecode_test.go b/itests/eth_bytecode_test.go index a8a75e83f..86048ff91 100644 --- a/itests/eth_bytecode_test.go +++ b/itests/eth_bytecode_test.go @@ -33,12 +33,12 @@ func TestGetCodeAndNonce(t *testing.T) { { // A random eth address should have no code. _, 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.Empty(t, bytecode) // 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.Zero(t, nonce) @@ -46,12 +46,12 @@ func TestGetCodeAndNonce(t *testing.T) { kit.SendFunds(ctx, t, client, filAddr, types.FromFil(10)) // 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.Empty(t, bytecode) // 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.Zero(t, nonce) } @@ -68,12 +68,12 @@ func TestGetCodeAndNonce(t *testing.T) { contractFilAddr := *createReturn.RobustAddress // 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.NotEmpty(t, bytecode) // 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.Equal(t, ethtypes.EthUint64(1), nonce) @@ -82,12 +82,12 @@ func TestGetCodeAndNonce(t *testing.T) { require.NoError(t, err) // 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.Empty(t, bytecode) // 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.Zero(t, nonce) } diff --git a/itests/eth_conformance_test.go b/itests/eth_conformance_test.go index 4d8f5c3dd..2a899e968 100644 --- a/itests/eth_conformance_test.go +++ b/itests/eth_conformance_test.go @@ -33,25 +33,25 @@ import ( type ethAPIRaw struct { EthAccounts 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) EthEstimateGas func(context.Context, ethtypes.EthCall) (json.RawMessage, error) EthFeeHistory func(context.Context, ethtypes.EthUint64, string, []float64) (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) EthGetBlockByNumber func(context.Context, string, bool) (json.RawMessage, error) EthGetBlockTransactionCountByHash func(context.Context, ethtypes.EthHash) (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) EthGetFilterLogs func(context.Context, ethtypes.EthFilterID) (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) EthGetTransactionByBlockNumberAndIndex func(context.Context, ethtypes.EthUint64, ethtypes.EthUint64) (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) EthMaxPriorityFeePerGas 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{ From: &senderEthAddr, Data: contractBin, - }, "latest") + }, ethtypes.NewEthBlockParamFromPredefined("latest")) }, }, @@ -207,7 +207,8 @@ func TestEthOpenRPCConformance(t *testing.T) { method: "eth_getBalance", variant: "blocknumber", 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", variant: "blocknumber", 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", variant: "blocknumber", 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", variant: "blocknumber", call: func(a *ethAPIRaw) (json.RawMessage, error) { - return ethapi.EthGetTransactionCount(context.Background(), senderEthAddr, blockNumberWithMessage.Hex()) + return ethapi.EthGetTransactionCount(context.Background(), senderEthAddr, ethtypes.NewEthBlockParamFromNumber(blockNumberWithMessage)) }, }, diff --git a/itests/eth_transactions_test.go b/itests/eth_transactions_test.go index 8d0df0433..eb900c7fb 100644 --- a/itests/eth_transactions_test.go +++ b/itests/eth_transactions_test.go @@ -316,7 +316,7 @@ func TestGetBlockByNumber(t *testing.T) { // Fetch balance on a null round; should not fail and should return previous 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.NotEqual(t, big.Zero(), bal) require.Equal(t, types.FromFil(10).Int, bal.Int) diff --git a/itests/fevm_test.go b/itests/fevm_test.go index 9b6dba92c..7051bb0df 100644 --- a/itests/fevm_test.go +++ b/itests/fevm_test.go @@ -268,14 +268,14 @@ func TestFEVMDelegateCall(t *testing.T) { // The implementation's storage should not have been updated. actorAddrEth, err := ethtypes.EthAddressFromFilecoinAddress(actorAddr) 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.Equal(t, ethtypes.EthBytes(make([]byte, 32)), value) // The storage actor's storage _should_ have been updated storageAddrEth, err := ethtypes.EthAddressFromFilecoinAddress(storageAddr) 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.Equal(t, ethtypes.EthBytes(expectedResult), value) } @@ -881,7 +881,7 @@ func TestFEVMTestDeployOnTransfer(t *testing.T) { require.NoError(t, err) 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.Equal(t, value.Int, balance.Int) @@ -1030,7 +1030,7 @@ func TestFEVMErrorParsing(t *testing.T) { _, err := e.EthCall(ctx, ethtypes.EthCall{ To: &contractAddrEth, Data: entryPoint, - }, "latest") + }, ethtypes.NewEthBlockParamFromPredefined("latest")) require.ErrorContains(t, err, expected) }) t.Run("EthEstimateGas", func(t *testing.T) { diff --git a/itests/kit/evm.go b/itests/kit/evm.go index c8904ab15..9b9299980 100644 --- a/itests/kit/evm.go +++ b/itests/kit/evm.go @@ -199,7 +199,7 @@ func (e *EVM) AssertAddressBalanceConsistent(ctx context.Context, addr address.A ethAddr, err := ethtypes.EthAddressFromFilecoinAddress(addr) 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.Equal(e.t, fbal, types.BigInt(ebal)) diff --git a/node/impl/full/dummy.go b/node/impl/full/dummy.go index 918e84d10..636732416 100644 --- a/node/impl/full/dummy.go +++ b/node/impl/full/dummy.go @@ -62,7 +62,7 @@ func (e *EthModuleDummy) EthGetTransactionByHashLimited(ctx context.Context, txH 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 } @@ -82,15 +82,15 @@ func (e *EthModuleDummy) EthGetTransactionByBlockNumberAndIndex(ctx context.Cont 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 } -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 } -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 } @@ -126,7 +126,7 @@ func (e *EthModuleDummy) EthEstimateGas(ctx context.Context, tx ethtypes.EthCall 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 } diff --git a/node/impl/full/eth.go b/node/impl/full/eth.go index 38c3a88d1..cee222683 100644 --- a/node/impl/full/eth.go +++ b/node/impl/full/eth.go @@ -59,12 +59,12 @@ type EthModuleAPI interface { EthGetTransactionByHashLimited(ctx context.Context, txHash *ethtypes.EthHash, limit abi.ChainEpoch) (*ethtypes.EthTx, error) EthGetMessageCidByTransactionHash(ctx context.Context, txHash *ethtypes.EthHash) (*cid.Cid, 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) 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) - EthGetStorageAt(ctx context.Context, address ethtypes.EthAddress, position ethtypes.EthBytes, blkParam string) (ethtypes.EthBytes, error) - EthGetBalance(ctx context.Context, address ethtypes.EthAddress, blkParam string) (ethtypes.EthBigInt, 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 ethtypes.EthBlockParamByNumberOrHash) (ethtypes.EthBytes, error) + EthGetBalance(ctx context.Context, address ethtypes.EthAddress, blkParam ethtypes.EthBlockParamByNumberOrHash) (ethtypes.EthBigInt, error) EthFeeHistory(ctx context.Context, p jsonrpc.RawParams) (ethtypes.EthFeeHistory, error) EthChainId(ctx context.Context) (ethtypes.EthUint64, error) EthSyncing(ctx context.Context) (ethtypes.EthSyncingResult, error) @@ -73,7 +73,7 @@ type EthModuleAPI interface { EthProtocolVersion(ctx context.Context) (ethtypes.EthUint64, error) EthGasPrice(ctx context.Context) (ethtypes.EthBigInt, 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) EthSendRawTransaction(ctx context.Context, rawTx ethtypes.EthBytes) (ethtypes.EthHash, 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) } -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" { 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 } -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() if err != nil { return ethtypes.EthUint64(0), nil } - ts, err := a.parseBlkParam(ctx, blkParam, false) + ts, err := a.getTipsetByEthBlockNumberOrHash(ctx, blkParam) if err != nil { 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 -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() if err != nil { 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 { 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 } -func (a *EthModule) EthGetStorageAt(ctx context.Context, ethAddr ethtypes.EthAddress, position ethtypes.EthBytes, blkParam string) (ethtypes.EthBytes, error) { - ts, err := a.parseBlkParam(ctx, blkParam, false) +func (a *EthModule) EthGetStorageAt(ctx context.Context, ethAddr ethtypes.EthAddress, position ethtypes.EthBytes, blkParam ethtypes.EthBlockParamByNumberOrHash) (ethtypes.EthBytes, error) { + ts, err := a.getTipsetByEthBlockNumberOrHash(ctx, blkParam) if err != nil { 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 } -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() if err != nil { return ethtypes.EthBigInt{}, err } - ts, err := a.parseBlkParam(ctx, blkParam, false) + ts, err := a.getTipsetByEthBlockNumberOrHash(ctx, blkParam) if err != nil { 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) } -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) if err != nil { 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 { return nil, xerrors.Errorf("failed to process block param: %s; %w", blkParam, err) }