From 717d2a0eebf0e53647b91a83eecf2a8a97b11e41 Mon Sep 17 00:00:00 2001 From: Fridrik Asmundsson Date: Tue, 28 Nov 2023 14:49:06 +0000 Subject: [PATCH 1/4] Add block param to EthEstimateGas --- CHANGELOG.md | 1 + api/api_full.go | 6 +++--- api/api_gateway.go | 2 +- api/mocks/mock_full.go | 8 ++++---- api/proxy_gen.go | 16 ++++++++-------- build/openrpc/full.json.gz | Bin 34831 -> 34835 bytes build/openrpc/gateway.json.gz | Bin 11883 -> 11887 bytes documentation/en/api-v1-unstable-methods.md | 3 ++- gateway/node.go | 2 +- gateway/proxy_eth.go | 4 ++-- itests/eth_account_abstraction_test.go | 2 +- itests/eth_conformance_test.go | 6 +++--- itests/eth_deploy_test.go | 2 +- itests/eth_hash_lookup_test.go | 4 ++-- itests/eth_transactions_test.go | 6 +++--- itests/fevm_test.go | 6 +++--- node/impl/full/dummy.go | 2 +- node/impl/full/eth.go | 10 +++++++--- 18 files changed, 43 insertions(+), 37 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 05caea4f3c1..38b7d2f3885 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,7 @@ - feat: metric: export Mpool message count ([filecoin-project/lotus#11361](https://github.com/filecoin-project/lotus/pull/11361)) - feat: sealing: load SectorsSummary from sealing SectorStats instead of calling API each time ([filecoin-project/lotus#11353](https://github.com/filecoin-project/lotus/pull/11353)) - fix: miner info: Show correct sector state counts ([filecoin-project/lotus#11456](https://github.com/filecoin-project/lotus/pull/11456)) +- feat: add support for specifying block number when calling `eth_estimateGas` RPC number which s ## Improvements - fix: Add time slicing to splitstore purging step during compaction to reduce lock congestion [filecoin-project/lotus#11269](https://github.com/filecoin-project/lotus/pull/11269) diff --git a/api/api_full.go b/api/api_full.go index f919bc13bb4..8a23131af81 100644 --- a/api/api_full.go +++ b/api/api_full.go @@ -823,9 +823,9 @@ type FullNode interface { 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 ethtypes.EthBlockNumberOrHash) (ethtypes.EthBytes, error) //perm:read + EthMaxPriorityFeePerGas(ctx context.Context) (ethtypes.EthBigInt, error) //perm:read + EthEstimateGas(ctx context.Context, tx ethtypes.EthCall, blkParam ethtypes.EthBlockNumberOrHash) (ethtypes.EthUint64, error) //perm:read + EthCall(ctx context.Context, tx ethtypes.EthCall, blkParam ethtypes.EthBlockNumberOrHash) (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 27e7254573c..63489f31b26 100644 --- a/api/api_gateway.go +++ b/api/api_gateway.go @@ -114,7 +114,7 @@ type Gateway interface { EthGasPrice(ctx context.Context) (ethtypes.EthBigInt, error) 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) + EthEstimateGas(ctx context.Context, tx ethtypes.EthCall, blkParam ethtypes.EthBlockNumberOrHash) (ethtypes.EthUint64, error) EthCall(ctx context.Context, tx ethtypes.EthCall, blkParam ethtypes.EthBlockNumberOrHash) (ethtypes.EthBytes, error) EthSendRawTransaction(ctx context.Context, rawTx ethtypes.EthBytes) (ethtypes.EthHash, error) EthGetLogs(ctx context.Context, filter *ethtypes.EthFilterSpec) (*ethtypes.EthFilterResult, error) diff --git a/api/mocks/mock_full.go b/api/mocks/mock_full.go index 856d83813af..f27aa6f791a 100644 --- a/api/mocks/mock_full.go +++ b/api/mocks/mock_full.go @@ -1042,18 +1042,18 @@ func (mr *MockFullNodeMockRecorder) EthChainId(arg0 interface{}) *gomock.Call { } // EthEstimateGas mocks base method. -func (m *MockFullNode) EthEstimateGas(arg0 context.Context, arg1 ethtypes.EthCall) (ethtypes.EthUint64, error) { +func (m *MockFullNode) EthEstimateGas(arg0 context.Context, arg1 ethtypes.EthCall, arg2 ethtypes.EthBlockNumberOrHash) (ethtypes.EthUint64, error) { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "EthEstimateGas", arg0, arg1) + ret := m.ctrl.Call(m, "EthEstimateGas", arg0, arg1, arg2) ret0, _ := ret[0].(ethtypes.EthUint64) ret1, _ := ret[1].(error) return ret0, ret1 } // EthEstimateGas indicates an expected call of EthEstimateGas. -func (mr *MockFullNodeMockRecorder) EthEstimateGas(arg0, arg1 interface{}) *gomock.Call { +func (mr *MockFullNodeMockRecorder) EthEstimateGas(arg0, arg1, arg2 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "EthEstimateGas", reflect.TypeOf((*MockFullNode)(nil).EthEstimateGas), arg0, arg1) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "EthEstimateGas", reflect.TypeOf((*MockFullNode)(nil).EthEstimateGas), arg0, arg1, arg2) } // EthFeeHistory mocks base method. diff --git a/api/proxy_gen.go b/api/proxy_gen.go index 2d1333495b3..3c53ba57b07 100644 --- a/api/proxy_gen.go +++ b/api/proxy_gen.go @@ -255,7 +255,7 @@ type FullNodeMethods struct { EthChainId func(p0 context.Context) (ethtypes.EthUint64, error) `perm:"read"` - EthEstimateGas func(p0 context.Context, p1 ethtypes.EthCall) (ethtypes.EthUint64, error) `perm:"read"` + EthEstimateGas func(p0 context.Context, p1 ethtypes.EthCall, p2 ethtypes.EthBlockNumberOrHash) (ethtypes.EthUint64, error) `perm:"read"` EthFeeHistory func(p0 context.Context, p1 jsonrpc.RawParams) (ethtypes.EthFeeHistory, error) `perm:"read"` @@ -679,7 +679,7 @@ type GatewayMethods struct { EthChainId func(p0 context.Context) (ethtypes.EthUint64, error) `` - EthEstimateGas func(p0 context.Context, p1 ethtypes.EthCall) (ethtypes.EthUint64, error) `` + EthEstimateGas func(p0 context.Context, p1 ethtypes.EthCall, p2 ethtypes.EthBlockNumberOrHash) (ethtypes.EthUint64, error) `` EthFeeHistory func(p0 context.Context, p1 jsonrpc.RawParams) (ethtypes.EthFeeHistory, error) `` @@ -2134,14 +2134,14 @@ func (s *FullNodeStub) EthChainId(p0 context.Context) (ethtypes.EthUint64, error return *new(ethtypes.EthUint64), ErrNotSupported } -func (s *FullNodeStruct) EthEstimateGas(p0 context.Context, p1 ethtypes.EthCall) (ethtypes.EthUint64, error) { +func (s *FullNodeStruct) EthEstimateGas(p0 context.Context, p1 ethtypes.EthCall, p2 ethtypes.EthBlockNumberOrHash) (ethtypes.EthUint64, error) { if s.Internal.EthEstimateGas == nil { return *new(ethtypes.EthUint64), ErrNotSupported } - return s.Internal.EthEstimateGas(p0, p1) + return s.Internal.EthEstimateGas(p0, p1, p2) } -func (s *FullNodeStub) EthEstimateGas(p0 context.Context, p1 ethtypes.EthCall) (ethtypes.EthUint64, error) { +func (s *FullNodeStub) EthEstimateGas(p0 context.Context, p1 ethtypes.EthCall, p2 ethtypes.EthBlockNumberOrHash) (ethtypes.EthUint64, error) { return *new(ethtypes.EthUint64), ErrNotSupported } @@ -4400,14 +4400,14 @@ func (s *GatewayStub) EthChainId(p0 context.Context) (ethtypes.EthUint64, error) return *new(ethtypes.EthUint64), ErrNotSupported } -func (s *GatewayStruct) EthEstimateGas(p0 context.Context, p1 ethtypes.EthCall) (ethtypes.EthUint64, error) { +func (s *GatewayStruct) EthEstimateGas(p0 context.Context, p1 ethtypes.EthCall, p2 ethtypes.EthBlockNumberOrHash) (ethtypes.EthUint64, error) { if s.Internal.EthEstimateGas == nil { return *new(ethtypes.EthUint64), ErrNotSupported } - return s.Internal.EthEstimateGas(p0, p1) + return s.Internal.EthEstimateGas(p0, p1, p2) } -func (s *GatewayStub) EthEstimateGas(p0 context.Context, p1 ethtypes.EthCall) (ethtypes.EthUint64, error) { +func (s *GatewayStub) EthEstimateGas(p0 context.Context, p1 ethtypes.EthCall, p2 ethtypes.EthBlockNumberOrHash) (ethtypes.EthUint64, error) { return *new(ethtypes.EthUint64), ErrNotSupported } diff --git a/build/openrpc/full.json.gz b/build/openrpc/full.json.gz index 29131b824e6cc4c01ab1560c68c27b6e85587201..cbe2471bb5d7ce80a6bb9103c6920aa7e7fbf061 100644 GIT binary patch delta 16837 zcmV)`Kz_fEkOGsC0^(vsG2=A2Yl9Aw+Ew7-FGfk=I~!;4CJvWPf6knSt zP916g!VH;7rv00L|9gE*yhV&%v&<@snP4F5xrlKo++&n7h77$&f9Mni0`n?sSj^NE zvabxeXOLss+xxyb+!#r+Z(!gG)1@I~$#r9TF;7un7a>B5%wmqnYIu{G3^P%$#-8e= zqd{bUKe5aPn_CsfE|2)^LxkH}NYkk9V%Nbwo*t9h>uXcZneG+HHk-=I6wNDl9w-Xy zVO~_k%t`jFc8WK*e=82qh|h@lKJ*}Ixp3p!4Z=~H?~NHP`k0i}F8lO|@7+o8tb<9c z$@ip8J}cCh6Y9Ga5&l|8iKVcAr&oU~!Jf2WBHTqeDcMza-xmdjG?3p(kESwQ)Mz8Z zGh@4VF>WrC2DhW#owoyLf}9;^b3EB{M&q}`H*cI>xb5z~e;J{-Z+1tU=*OE?Pi%IxmS@-hfWP95Du`h($MWw#Z0g zqZHakDcDmi4PjKw;tg^}X);!sHYypZjfXcwBQ_r1#>3k@Ko2kZht+w2 zk|!uSZW}5ePBj=jr79u4&Y3@<0f1m4tM_9Rh^`Ugz@t+J)U6QIal#-#E?}5A2zZcj z;8V}rxFj#)wEL4{CoCW`ld7d%yxpXxq(QFqpTB-I(_E_Y&fKq0%%?aURp*yy?eE`KkSET6ju8TX=GGsDqfb2uFI`q51V&3y};`dBPo5_(?4NTs;Xd)Po- z9FkIMa6i1=pZZ*dOBBWI*S%9;rfhcCWuLk$*=iNi6H-XqHJOPJ|D-lp4zRm_m)e_I zVza-dMI-g4-PtA=C@<`=L-kcZtd*yPD@>7v(Dq(bdw(x#hjMbKHWk)6rvaRzcSUt) zCKcoQOKtn9Z9RXqip{{7!WHibre`AB78GN$TZ8MhHTY<^l#&sS?B=K4{9NOex~7`& zO>O?L6!_i0+mBZCJK`P_7u~j0kM)f<$}+Yv*zV$Xu`;Zu$52CF+_q4U3unUSBztgc z!&r%~bAQm?BEfr6j+}6o9YkrDomG(}Sru(&c3iEOA zHqSZ(cWZrE>%&?f*7~s4hqXSe^ti&iO~aCb#Y@Cv720VOg|(C+(Qyb? z*?≦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 E0J+AkB>(^b delta 16832 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 diff --git a/documentation/en/api-v1-unstable-methods.md b/documentation/en/api-v1-unstable-methods.md index 1dae121018c..377f8b4e62b 100644 --- a/documentation/en/api-v1-unstable-methods.md +++ b/documentation/en/api-v1-unstable-methods.md @@ -2409,7 +2409,8 @@ Inputs: "gasPrice": "0x0", "value": "0x0", "data": "0x07" - } + }, + "string value" ] ``` diff --git a/gateway/node.go b/gateway/node.go index 367e645c1f6..5c686e7744a 100644 --- a/gateway/node.go +++ b/gateway/node.go @@ -131,7 +131,7 @@ type TargetAPI interface { EthGasPrice(ctx context.Context) (ethtypes.EthBigInt, error) 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) + EthEstimateGas(ctx context.Context, tx ethtypes.EthCall, blkParam ethtypes.EthBlockNumberOrHash) (ethtypes.EthUint64, error) EthCall(ctx context.Context, tx ethtypes.EthCall, blkParam ethtypes.EthBlockNumberOrHash) (ethtypes.EthBytes, error) EthSendRawTransaction(ctx context.Context, rawTx ethtypes.EthBytes) (ethtypes.EthHash, error) EthGetLogs(ctx context.Context, filter *ethtypes.EthFilterSpec) (*ethtypes.EthFilterResult, error) diff --git a/gateway/proxy_eth.go b/gateway/proxy_eth.go index e6d433a1744..4fc3b2fd64c 100644 --- a/gateway/proxy_eth.go +++ b/gateway/proxy_eth.go @@ -353,13 +353,13 @@ func (gw *Node) EthMaxPriorityFeePerGas(ctx context.Context) (ethtypes.EthBigInt return gw.target.EthMaxPriorityFeePerGas(ctx) } -func (gw *Node) EthEstimateGas(ctx context.Context, tx ethtypes.EthCall) (ethtypes.EthUint64, error) { +func (gw *Node) EthEstimateGas(ctx context.Context, tx ethtypes.EthCall, blkParam ethtypes.EthBlockNumberOrHash) (ethtypes.EthUint64, error) { if err := gw.limit(ctx, stateRateLimitTokens); err != nil { return 0, err } // todo limit gas? to what? - return gw.target.EthEstimateGas(ctx, tx) + return gw.target.EthEstimateGas(ctx, tx, blkParam) } func (gw *Node) EthCall(ctx context.Context, tx ethtypes.EthCall, blkParam ethtypes.EthBlockNumberOrHash) (ethtypes.EthBytes, error) { diff --git a/itests/eth_account_abstraction_test.go b/itests/eth_account_abstraction_test.go index 8d92d0a049d..62c0083a7f2 100644 --- a/itests/eth_account_abstraction_test.go +++ b/itests/eth_account_abstraction_test.go @@ -275,7 +275,7 @@ func TestEthAccountAbstractionFailsFromEvmActor(t *testing.T) { gaslimit, err := client.EthEstimateGas(ctx, ethtypes.EthCall{ From: ðAddr, Data: contract, - }) + }, ethtypes.NewEthBlockNumberOrHashFromPredefined("latest")) require.NoError(t, err) maxPriorityFeePerGas, err := client.EthMaxPriorityFeePerGas(ctx) diff --git a/itests/eth_conformance_test.go b/itests/eth_conformance_test.go index 15b24997719..c43dd7dfafe 100644 --- a/itests/eth_conformance_test.go +++ b/itests/eth_conformance_test.go @@ -35,7 +35,7 @@ type ethAPIRaw struct { EthBlockNumber func(context.Context) (json.RawMessage, error) EthCall func(context.Context, ethtypes.EthCall, ethtypes.EthBlockNumberOrHash) (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, ethtypes.EthBlockNumberOrHash) (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, ethtypes.EthBlockNumberOrHash) (json.RawMessage, error) @@ -185,7 +185,7 @@ func TestEthOpenRPCConformance(t *testing.T) { return ethapi.EthEstimateGas(context.Background(), ethtypes.EthCall{ From: &senderEthAddr, Data: contractBin, - }) + }, ethtypes.NewEthBlockNumberOrHashFromPredefined("latest")) }, }, @@ -451,7 +451,7 @@ func createRawSignedEthTx(ctx context.Context, t *testing.T, client *kit.TestFul gaslimit, err := client.EthEstimateGas(ctx, ethtypes.EthCall{ From: &senderEthAddr, Data: contractBin, - }) + }, ethtypes.NewEthBlockNumberOrHashFromPredefined("latest")) require.NoError(t, err) maxPriorityFeePerGas, err := client.EthMaxPriorityFeePerGas(ctx) diff --git a/itests/eth_deploy_test.go b/itests/eth_deploy_test.go index ce4c94a28b8..422bc344989 100644 --- a/itests/eth_deploy_test.go +++ b/itests/eth_deploy_test.go @@ -63,7 +63,7 @@ func TestDeployment(t *testing.T) { gaslimit, err := client.EthEstimateGas(ctx, ethtypes.EthCall{ From: ðAddr, Data: contract, - }) + }, ethtypes.NewEthBlockNumberOrHashFromPredefined("latest")) require.NoError(t, err) maxPriorityFeePerGas, err := client.EthMaxPriorityFeePerGas(ctx) diff --git a/itests/eth_hash_lookup_test.go b/itests/eth_hash_lookup_test.go index e1474a90d10..dd3980867c6 100644 --- a/itests/eth_hash_lookup_test.go +++ b/itests/eth_hash_lookup_test.go @@ -50,7 +50,7 @@ func TestTransactionHashLookup(t *testing.T) { gaslimit, err := client.EthEstimateGas(ctx, ethtypes.EthCall{ From: ðAddr, Data: contract, - }) + }, ethtypes.NewEthBlockNumberOrHashFromPredefined("latest")) require.NoError(t, err) maxPriorityFeePerGas, err := client.EthMaxPriorityFeePerGas(ctx) @@ -353,7 +353,7 @@ func TestEthGetMessageCidByTransactionHashEthTx(t *testing.T) { gaslimit, err := client.EthEstimateGas(ctx, ethtypes.EthCall{ From: ðAddr, Data: contract, - }) + }, ethtypes.NewEthBlockNumberOrHashFromPredefined("latest")) require.NoError(t, err) maxPriorityFeePerGas, err := client.EthMaxPriorityFeePerGas(ctx) diff --git a/itests/eth_transactions_test.go b/itests/eth_transactions_test.go index 026ac238790..0039ebde0a4 100644 --- a/itests/eth_transactions_test.go +++ b/itests/eth_transactions_test.go @@ -47,7 +47,7 @@ func TestValueTransferValidSignature(t *testing.T) { gaslimit, err := client.EthEstimateGas(ctx, ethtypes.EthCall{ From: ðAddr, Data: contract, - }) + }, ethtypes.NewEthBlockNumberOrHashFromPredefined("latest")) require.NoError(t, err) maxPriorityFeePerGas, err := client.EthMaxPriorityFeePerGas(ctx) @@ -235,7 +235,7 @@ func TestContractInvocation(t *testing.T) { From: ðAddr, To: &contractAddr, Data: params, - }) + }, ethtypes.NewEthBlockNumberOrHashFromPredefined("latest")) require.NoError(t, err) maxPriorityFeePerGas, err := client.EthMaxPriorityFeePerGas(ctx) @@ -353,7 +353,7 @@ func deployContractTx(ctx context.Context, client *kit.TestFullNode, ethAddr eth gaslimit, err := client.EthEstimateGas(ctx, ethtypes.EthCall{ From: ðAddr, Data: contract, - }) + }, ethtypes.NewEthBlockNumberOrHashFromPredefined("latest")) if err != nil { return nil, err } diff --git a/itests/fevm_test.go b/itests/fevm_test.go index cb69c036cad..7b09ac7f947 100644 --- a/itests/fevm_test.go +++ b/itests/fevm_test.go @@ -661,7 +661,7 @@ func TestFEVMRecursiveActorCallEstimate(t *testing.T) { From: ðAddr, To: &contractAddr, Data: params, - }) + }, ethtypes.NewEthBlockNumberOrHashFromPredefined("latest")) require.NoError(t, err) require.LessOrEqual(t, int64(gaslimit), build.BlockGasLimit) @@ -820,7 +820,7 @@ func TestFEVMBareTransferTriggersSmartContractLogic(t *testing.T) { From: &accntEth, To: &contractEth, Value: ethtypes.EthBigInt(big.NewInt(100)), - }) + }, ethtypes.NewEthBlockNumberOrHashFromPredefined("latest")) require.NoError(t, err) maxPriorityFeePerGas, err := client.EthMaxPriorityFeePerGas(ctx) @@ -1037,7 +1037,7 @@ func TestFEVMErrorParsing(t *testing.T) { _, err := e.EthEstimateGas(ctx, ethtypes.EthCall{ To: &contractAddrEth, Data: entryPoint, - }) + }, ethtypes.NewEthBlockNumberOrHashFromPredefined("latest")) require.ErrorContains(t, err, expected) }) }) diff --git a/node/impl/full/dummy.go b/node/impl/full/dummy.go index 743eadf34dd..857b4c57f5d 100644 --- a/node/impl/full/dummy.go +++ b/node/impl/full/dummy.go @@ -122,7 +122,7 @@ func (e *EthModuleDummy) EthGasPrice(ctx context.Context) (ethtypes.EthBigInt, e return ethtypes.EthBigIntZero, ErrModuleDisabled } -func (e *EthModuleDummy) EthEstimateGas(ctx context.Context, tx ethtypes.EthCall) (ethtypes.EthUint64, error) { +func (e *EthModuleDummy) EthEstimateGas(ctx context.Context, tx ethtypes.EthCall, blkParam ethtypes.EthBlockNumberOrHash) (ethtypes.EthUint64, error) { return 0, ErrModuleDisabled } diff --git a/node/impl/full/eth.go b/node/impl/full/eth.go index 22f78e7232c..12a9d56ea67 100644 --- a/node/impl/full/eth.go +++ b/node/impl/full/eth.go @@ -66,7 +66,7 @@ type EthModuleAPI interface { NetListening(ctx context.Context) (bool, error) EthProtocolVersion(ctx context.Context) (ethtypes.EthUint64, 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, blkParam ethtypes.EthBlockNumberOrHash) (ethtypes.EthUint64, error) EthCall(ctx context.Context, tx ethtypes.EthCall, blkParam ethtypes.EthBlockNumberOrHash) (ethtypes.EthBytes, error) EthMaxPriorityFeePerGas(ctx context.Context) (ethtypes.EthBigInt, error) EthSendRawTransaction(ctx context.Context, rawTx ethtypes.EthBytes) (ethtypes.EthHash, error) @@ -1007,7 +1007,7 @@ func (a *EthModule) applyMessage(ctx context.Context, msg *types.Message, tsk ty return res, nil } -func (a *EthModule) EthEstimateGas(ctx context.Context, tx ethtypes.EthCall) (ethtypes.EthUint64, error) { +func (a *EthModule) EthEstimateGas(ctx context.Context, tx ethtypes.EthCall, blkParam ethtypes.EthBlockNumberOrHash) (ethtypes.EthUint64, error) { msg, err := ethCallToFilecoinMessage(ctx, tx) if err != nil { return ethtypes.EthUint64(0), err @@ -1017,7 +1017,11 @@ func (a *EthModule) EthEstimateGas(ctx context.Context, tx ethtypes.EthCall) (et // gas estimation actually run. msg.GasLimit = 0 - ts := a.Chain.GetHeaviestTipSet() + ts, err := getTipsetByEthBlockNumberOrHash(ctx, a.Chain, blkParam) + if err != nil { + return ethtypes.EthUint64(0), xerrors.Errorf("failed to process block param: %v; %w", blkParam, err) + } + gassedMsg, err := a.GasAPI.GasEstimateMessageGas(ctx, msg, nil, ts.Key()) if err != nil { // On failure, GasEstimateMessageGas doesn't actually return the invocation result, From 6ae91467e6e07de9b6a8185e294cd8b4ac380336 Mon Sep 17 00:00:00 2001 From: Fridrik Asmundsson Date: Tue, 28 Nov 2023 19:39:15 +0000 Subject: [PATCH 2/4] fix spelling --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 38b7d2f3885..2b987a3c2f2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,7 +5,7 @@ - feat: metric: export Mpool message count ([filecoin-project/lotus#11361](https://github.com/filecoin-project/lotus/pull/11361)) - feat: sealing: load SectorsSummary from sealing SectorStats instead of calling API each time ([filecoin-project/lotus#11353](https://github.com/filecoin-project/lotus/pull/11353)) - fix: miner info: Show correct sector state counts ([filecoin-project/lotus#11456](https://github.com/filecoin-project/lotus/pull/11456)) -- feat: add support for specifying block number when calling `eth_estimateGas` RPC number which s +- feat: add support for specifying block number when calling `eth_estimateGas` ([filecoin-project/lotus#11462](https://github.com/filecoin-project/lotus/pull/11462)). ## Improvements - fix: Add time slicing to splitstore purging step during compaction to reduce lock congestion [filecoin-project/lotus#11269](https://github.com/filecoin-project/lotus/pull/11269) From a3417e7488356d97ada733ffa27a7df22b6d1d16 Mon Sep 17 00:00:00 2001 From: Fridrik Asmundsson Date: Wed, 29 Nov 2023 10:17:10 +0000 Subject: [PATCH 3/4] Make block param to EthEstimateGas optional --- api/api_full.go | 6 +-- api/api_gateway.go | 2 +- api/mocks/mock_full.go | 8 ++-- api/proxy_gen.go | 16 ++++---- build/openrpc/full.json.gz | Bin 34835 -> 34820 bytes build/openrpc/gateway.json.gz | Bin 11887 -> 11872 bytes chain/types/ethtypes/eth_types.go | 39 ++++++++++++++++++++ documentation/en/api-v1-unstable-methods.md | 10 +---- gateway/node.go | 2 +- gateway/proxy_eth.go | 10 ++++- itests/eth_account_abstraction_test.go | 8 +++- itests/eth_conformance_test.go | 16 +++++--- itests/eth_deploy_test.go | 7 +++- itests/eth_hash_lookup_test.go | 15 ++++++-- itests/eth_transactions_test.go | 24 +++++++++--- itests/fevm_test.go | 23 +++++++++--- node/impl/full/dummy.go | 2 +- node/impl/full/eth.go | 22 ++++++++--- 18 files changed, 150 insertions(+), 60 deletions(-) diff --git a/api/api_full.go b/api/api_full.go index 8a23131af81..4ae2ea53135 100644 --- a/api/api_full.go +++ b/api/api_full.go @@ -823,9 +823,9 @@ type FullNode interface { 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, blkParam ethtypes.EthBlockNumberOrHash) (ethtypes.EthUint64, error) //perm:read - EthCall(ctx context.Context, tx ethtypes.EthCall, blkParam ethtypes.EthBlockNumberOrHash) (ethtypes.EthBytes, error) //perm:read + EthMaxPriorityFeePerGas(ctx context.Context) (ethtypes.EthBigInt, error) //perm:read + EthEstimateGas(ctx context.Context, p jsonrpc.RawParams) (ethtypes.EthUint64, error) //perm:read + EthCall(ctx context.Context, tx ethtypes.EthCall, blkParam ethtypes.EthBlockNumberOrHash) (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 63489f31b26..238bf43abfe 100644 --- a/api/api_gateway.go +++ b/api/api_gateway.go @@ -114,7 +114,7 @@ type Gateway interface { EthGasPrice(ctx context.Context) (ethtypes.EthBigInt, error) EthFeeHistory(ctx context.Context, p jsonrpc.RawParams) (ethtypes.EthFeeHistory, error) EthMaxPriorityFeePerGas(ctx context.Context) (ethtypes.EthBigInt, error) - EthEstimateGas(ctx context.Context, tx ethtypes.EthCall, blkParam ethtypes.EthBlockNumberOrHash) (ethtypes.EthUint64, error) + EthEstimateGas(ctx context.Context, p jsonrpc.RawParams) (ethtypes.EthUint64, error) EthCall(ctx context.Context, tx ethtypes.EthCall, blkParam ethtypes.EthBlockNumberOrHash) (ethtypes.EthBytes, error) EthSendRawTransaction(ctx context.Context, rawTx ethtypes.EthBytes) (ethtypes.EthHash, error) EthGetLogs(ctx context.Context, filter *ethtypes.EthFilterSpec) (*ethtypes.EthFilterResult, error) diff --git a/api/mocks/mock_full.go b/api/mocks/mock_full.go index f27aa6f791a..92b719550b5 100644 --- a/api/mocks/mock_full.go +++ b/api/mocks/mock_full.go @@ -1042,18 +1042,18 @@ func (mr *MockFullNodeMockRecorder) EthChainId(arg0 interface{}) *gomock.Call { } // EthEstimateGas mocks base method. -func (m *MockFullNode) EthEstimateGas(arg0 context.Context, arg1 ethtypes.EthCall, arg2 ethtypes.EthBlockNumberOrHash) (ethtypes.EthUint64, error) { +func (m *MockFullNode) EthEstimateGas(arg0 context.Context, arg1 jsonrpc.RawParams) (ethtypes.EthUint64, error) { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "EthEstimateGas", arg0, arg1, arg2) + ret := m.ctrl.Call(m, "EthEstimateGas", arg0, arg1) ret0, _ := ret[0].(ethtypes.EthUint64) ret1, _ := ret[1].(error) return ret0, ret1 } // EthEstimateGas indicates an expected call of EthEstimateGas. -func (mr *MockFullNodeMockRecorder) EthEstimateGas(arg0, arg1, arg2 interface{}) *gomock.Call { +func (mr *MockFullNodeMockRecorder) EthEstimateGas(arg0, arg1 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "EthEstimateGas", reflect.TypeOf((*MockFullNode)(nil).EthEstimateGas), arg0, arg1, arg2) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "EthEstimateGas", reflect.TypeOf((*MockFullNode)(nil).EthEstimateGas), arg0, arg1) } // EthFeeHistory mocks base method. diff --git a/api/proxy_gen.go b/api/proxy_gen.go index 3c53ba57b07..8adcbc18986 100644 --- a/api/proxy_gen.go +++ b/api/proxy_gen.go @@ -255,7 +255,7 @@ type FullNodeMethods struct { EthChainId func(p0 context.Context) (ethtypes.EthUint64, error) `perm:"read"` - EthEstimateGas func(p0 context.Context, p1 ethtypes.EthCall, p2 ethtypes.EthBlockNumberOrHash) (ethtypes.EthUint64, error) `perm:"read"` + EthEstimateGas func(p0 context.Context, p1 jsonrpc.RawParams) (ethtypes.EthUint64, error) `perm:"read"` EthFeeHistory func(p0 context.Context, p1 jsonrpc.RawParams) (ethtypes.EthFeeHistory, error) `perm:"read"` @@ -679,7 +679,7 @@ type GatewayMethods struct { EthChainId func(p0 context.Context) (ethtypes.EthUint64, error) `` - EthEstimateGas func(p0 context.Context, p1 ethtypes.EthCall, p2 ethtypes.EthBlockNumberOrHash) (ethtypes.EthUint64, error) `` + EthEstimateGas func(p0 context.Context, p1 jsonrpc.RawParams) (ethtypes.EthUint64, error) `` EthFeeHistory func(p0 context.Context, p1 jsonrpc.RawParams) (ethtypes.EthFeeHistory, error) `` @@ -2134,14 +2134,14 @@ func (s *FullNodeStub) EthChainId(p0 context.Context) (ethtypes.EthUint64, error return *new(ethtypes.EthUint64), ErrNotSupported } -func (s *FullNodeStruct) EthEstimateGas(p0 context.Context, p1 ethtypes.EthCall, p2 ethtypes.EthBlockNumberOrHash) (ethtypes.EthUint64, error) { +func (s *FullNodeStruct) EthEstimateGas(p0 context.Context, p1 jsonrpc.RawParams) (ethtypes.EthUint64, error) { if s.Internal.EthEstimateGas == nil { return *new(ethtypes.EthUint64), ErrNotSupported } - return s.Internal.EthEstimateGas(p0, p1, p2) + return s.Internal.EthEstimateGas(p0, p1) } -func (s *FullNodeStub) EthEstimateGas(p0 context.Context, p1 ethtypes.EthCall, p2 ethtypes.EthBlockNumberOrHash) (ethtypes.EthUint64, error) { +func (s *FullNodeStub) EthEstimateGas(p0 context.Context, p1 jsonrpc.RawParams) (ethtypes.EthUint64, error) { return *new(ethtypes.EthUint64), ErrNotSupported } @@ -4400,14 +4400,14 @@ func (s *GatewayStub) EthChainId(p0 context.Context) (ethtypes.EthUint64, error) return *new(ethtypes.EthUint64), ErrNotSupported } -func (s *GatewayStruct) EthEstimateGas(p0 context.Context, p1 ethtypes.EthCall, p2 ethtypes.EthBlockNumberOrHash) (ethtypes.EthUint64, error) { +func (s *GatewayStruct) EthEstimateGas(p0 context.Context, p1 jsonrpc.RawParams) (ethtypes.EthUint64, error) { if s.Internal.EthEstimateGas == nil { return *new(ethtypes.EthUint64), ErrNotSupported } - return s.Internal.EthEstimateGas(p0, p1, p2) + return s.Internal.EthEstimateGas(p0, p1) } -func (s *GatewayStub) EthEstimateGas(p0 context.Context, p1 ethtypes.EthCall, p2 ethtypes.EthBlockNumberOrHash) (ethtypes.EthUint64, error) { +func (s *GatewayStub) EthEstimateGas(p0 context.Context, p1 jsonrpc.RawParams) (ethtypes.EthUint64, error) { return *new(ethtypes.EthUint64), ErrNotSupported } diff --git a/build/openrpc/full.json.gz b/build/openrpc/full.json.gz index cbe2471bb5d7ce80a6bb9103c6920aa7e7fbf061..99426649275b903af8f200301ae779290cfda9cb 100644 GIT binary patch delta 17048 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 diff --git a/chain/types/ethtypes/eth_types.go b/chain/types/ethtypes/eth_types.go index b796e6f56f2..b933329f495 100644 --- a/chain/types/ethtypes/eth_types.go +++ b/chain/types/ethtypes/eth_types.go @@ -799,6 +799,45 @@ func GetContractEthAddressFromCode(sender EthAddress, salt [32]byte, initcode [] return ethAddr, nil } +// EthEstimateGasParams handles raw jsonrpc params for eth_estimateGas +type EthEstimateGasParams struct { + Tx EthCall + BlkParam *EthBlockNumberOrHash +} + +func (e *EthEstimateGasParams) UnmarshalJSON(b []byte) error { + var params []json.RawMessage + err := json.Unmarshal(b, ¶ms) + if err != nil { + return err + } + + switch len(params) { + case 2: + err = json.Unmarshal(params[1], &e.BlkParam) + if err != nil { + return err + } + fallthrough + case 1: + err = json.Unmarshal(params[0], &e.Tx) + if err != nil { + return err + } + default: + return xerrors.Errorf("expected 1 or 2 params, got %d", len(params)) + } + + return nil +} + +func (e EthEstimateGasParams) MarshalJSON() ([]byte, error) { + if e.BlkParam != nil { + return json.Marshal([]interface{}{e.Tx, e.BlkParam}) + } + return json.Marshal([]interface{}{e.Tx}) +} + // EthFeeHistoryParams handles raw jsonrpc params for eth_feeHistory type EthFeeHistoryParams struct { BlkCount EthUint64 diff --git a/documentation/en/api-v1-unstable-methods.md b/documentation/en/api-v1-unstable-methods.md index 377f8b4e62b..c2929f0f508 100644 --- a/documentation/en/api-v1-unstable-methods.md +++ b/documentation/en/api-v1-unstable-methods.md @@ -2402,15 +2402,7 @@ Perms: read Inputs: ```json [ - { - "from": "0x5cbeecf99d3fdb3f25e309cc264f240bb0664031", - "to": "0x5cbeecf99d3fdb3f25e309cc264f240bb0664031", - "gas": "0x5", - "gasPrice": "0x0", - "value": "0x0", - "data": "0x07" - }, - "string value" + "Bw==" ] ``` diff --git a/gateway/node.go b/gateway/node.go index 5c686e7744a..f2464d27496 100644 --- a/gateway/node.go +++ b/gateway/node.go @@ -131,7 +131,7 @@ type TargetAPI interface { EthGasPrice(ctx context.Context) (ethtypes.EthBigInt, error) EthFeeHistory(ctx context.Context, p jsonrpc.RawParams) (ethtypes.EthFeeHistory, error) EthMaxPriorityFeePerGas(ctx context.Context) (ethtypes.EthBigInt, error) - EthEstimateGas(ctx context.Context, tx ethtypes.EthCall, blkParam ethtypes.EthBlockNumberOrHash) (ethtypes.EthUint64, error) + EthEstimateGas(ctx context.Context, p jsonrpc.RawParams) (ethtypes.EthUint64, error) EthCall(ctx context.Context, tx ethtypes.EthCall, blkParam ethtypes.EthBlockNumberOrHash) (ethtypes.EthBytes, error) EthSendRawTransaction(ctx context.Context, rawTx ethtypes.EthBytes) (ethtypes.EthHash, error) EthGetLogs(ctx context.Context, filter *ethtypes.EthFilterSpec) (*ethtypes.EthFilterResult, error) diff --git a/gateway/proxy_eth.go b/gateway/proxy_eth.go index 4fc3b2fd64c..13a12acfa72 100644 --- a/gateway/proxy_eth.go +++ b/gateway/proxy_eth.go @@ -353,13 +353,19 @@ func (gw *Node) EthMaxPriorityFeePerGas(ctx context.Context) (ethtypes.EthBigInt return gw.target.EthMaxPriorityFeePerGas(ctx) } -func (gw *Node) EthEstimateGas(ctx context.Context, tx ethtypes.EthCall, blkParam ethtypes.EthBlockNumberOrHash) (ethtypes.EthUint64, error) { +func (gw *Node) EthEstimateGas(ctx context.Context, p jsonrpc.RawParams) (ethtypes.EthUint64, error) { + // validate params + _, err := jsonrpc.DecodeParams[ethtypes.EthEstimateGasParams](p) + if err != nil { + return ethtypes.EthUint64(0), xerrors.Errorf("decoding params: %w", err) + } + if err := gw.limit(ctx, stateRateLimitTokens); err != nil { return 0, err } // todo limit gas? to what? - return gw.target.EthEstimateGas(ctx, tx, blkParam) + return gw.target.EthEstimateGas(ctx, p) } func (gw *Node) EthCall(ctx context.Context, tx ethtypes.EthCall, blkParam ethtypes.EthBlockNumberOrHash) (ethtypes.EthBytes, error) { diff --git a/itests/eth_account_abstraction_test.go b/itests/eth_account_abstraction_test.go index 62c0083a7f2..5ca672674a6 100644 --- a/itests/eth_account_abstraction_test.go +++ b/itests/eth_account_abstraction_test.go @@ -3,6 +3,7 @@ package itests import ( "context" "encoding/hex" + "encoding/json" "os" "testing" "time" @@ -272,10 +273,13 @@ func TestEthAccountAbstractionFailsFromEvmActor(t *testing.T) { contract, err := hex.DecodeString(string(contractHex)) require.NoError(t, err) - gaslimit, err := client.EthEstimateGas(ctx, ethtypes.EthCall{ + gasParams, err := json.Marshal(ethtypes.EthEstimateGasParams{Tx: ethtypes.EthCall{ From: ðAddr, Data: contract, - }, ethtypes.NewEthBlockNumberOrHashFromPredefined("latest")) + }}) + require.NoError(t, err) + + gaslimit, err := client.EthEstimateGas(ctx, gasParams) require.NoError(t, err) maxPriorityFeePerGas, err := client.EthMaxPriorityFeePerGas(ctx) diff --git a/itests/eth_conformance_test.go b/itests/eth_conformance_test.go index c43dd7dfafe..9c1b2ae34ef 100644 --- a/itests/eth_conformance_test.go +++ b/itests/eth_conformance_test.go @@ -35,7 +35,7 @@ type ethAPIRaw struct { EthBlockNumber func(context.Context) (json.RawMessage, error) EthCall func(context.Context, ethtypes.EthCall, ethtypes.EthBlockNumberOrHash) (json.RawMessage, error) EthChainId func(context.Context) (json.RawMessage, error) - EthEstimateGas func(context.Context, ethtypes.EthCall, ethtypes.EthBlockNumberOrHash) (json.RawMessage, error) + EthEstimateGas func(context.Context, jsonrpc.RawParams) (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, ethtypes.EthBlockNumberOrHash) (json.RawMessage, error) @@ -182,10 +182,13 @@ func TestEthOpenRPCConformance(t *testing.T) { { method: "eth_estimateGas", call: func(a *ethAPIRaw) (json.RawMessage, error) { - return ethapi.EthEstimateGas(context.Background(), ethtypes.EthCall{ + gasParams, err := json.Marshal(ethtypes.EthEstimateGasParams{Tx: ethtypes.EthCall{ From: &senderEthAddr, Data: contractBin, - }, ethtypes.NewEthBlockNumberOrHashFromPredefined("latest")) + }}) + require.NoError(t, err) + + return ethapi.EthEstimateGas(ctx, gasParams) }, }, @@ -448,10 +451,13 @@ func TestEthOpenRPCConformance(t *testing.T) { } func createRawSignedEthTx(ctx context.Context, t *testing.T, client *kit.TestFullNode, senderEthAddr ethtypes.EthAddress, receiverEthAddr ethtypes.EthAddress, senderKey *key.Key, contractBin []byte) []byte { - gaslimit, err := client.EthEstimateGas(ctx, ethtypes.EthCall{ + gasParams, err := json.Marshal(ethtypes.EthEstimateGasParams{Tx: ethtypes.EthCall{ From: &senderEthAddr, Data: contractBin, - }, ethtypes.NewEthBlockNumberOrHashFromPredefined("latest")) + }}) + require.NoError(t, err) + + gaslimit, err := client.EthEstimateGas(ctx, gasParams) require.NoError(t, err) maxPriorityFeePerGas, err := client.EthMaxPriorityFeePerGas(ctx) diff --git a/itests/eth_deploy_test.go b/itests/eth_deploy_test.go index 422bc344989..68861f98fd8 100644 --- a/itests/eth_deploy_test.go +++ b/itests/eth_deploy_test.go @@ -60,10 +60,13 @@ func TestDeployment(t *testing.T) { // verify the deployer address is an Placeholder. client.AssertActorType(ctx, deployer, manifest.PlaceholderKey) - gaslimit, err := client.EthEstimateGas(ctx, ethtypes.EthCall{ + gasParams, err := json.Marshal(ethtypes.EthEstimateGasParams{Tx: ethtypes.EthCall{ From: ðAddr, Data: contract, - }, ethtypes.NewEthBlockNumberOrHashFromPredefined("latest")) + }}) + require.NoError(t, err) + + gaslimit, err := client.EthEstimateGas(ctx, gasParams) require.NoError(t, err) maxPriorityFeePerGas, err := client.EthMaxPriorityFeePerGas(ctx) diff --git a/itests/eth_hash_lookup_test.go b/itests/eth_hash_lookup_test.go index dd3980867c6..0a2c11d3cf1 100644 --- a/itests/eth_hash_lookup_test.go +++ b/itests/eth_hash_lookup_test.go @@ -3,6 +3,7 @@ package itests import ( "context" "encoding/hex" + "encoding/json" "os" "testing" "time" @@ -47,10 +48,13 @@ func TestTransactionHashLookup(t *testing.T) { // send some funds to the f410 address kit.SendFunds(ctx, t, client, deployer, types.FromFil(10)) - gaslimit, err := client.EthEstimateGas(ctx, ethtypes.EthCall{ + gasParams, err := json.Marshal(ethtypes.EthEstimateGasParams{Tx: ethtypes.EthCall{ From: ðAddr, Data: contract, - }, ethtypes.NewEthBlockNumberOrHashFromPredefined("latest")) + }}) + require.NoError(t, err) + + gaslimit, err := client.EthEstimateGas(ctx, gasParams) require.NoError(t, err) maxPriorityFeePerGas, err := client.EthMaxPriorityFeePerGas(ctx) @@ -350,10 +354,13 @@ func TestEthGetMessageCidByTransactionHashEthTx(t *testing.T) { // send some funds to the f410 address kit.SendFunds(ctx, t, client, deployer, types.FromFil(10)) - gaslimit, err := client.EthEstimateGas(ctx, ethtypes.EthCall{ + gasParams, err := json.Marshal(ethtypes.EthEstimateGasParams{Tx: ethtypes.EthCall{ From: ðAddr, Data: contract, - }, ethtypes.NewEthBlockNumberOrHashFromPredefined("latest")) + }}) + require.NoError(t, err) + + gaslimit, err := client.EthEstimateGas(ctx, gasParams) require.NoError(t, err) maxPriorityFeePerGas, err := client.EthMaxPriorityFeePerGas(ctx) diff --git a/itests/eth_transactions_test.go b/itests/eth_transactions_test.go index 0039ebde0a4..59e5852c9e2 100644 --- a/itests/eth_transactions_test.go +++ b/itests/eth_transactions_test.go @@ -3,6 +3,7 @@ package itests import ( "context" "encoding/hex" + "encoding/json" "os" "testing" "time" @@ -44,10 +45,13 @@ func TestValueTransferValidSignature(t *testing.T) { kit.SendFunds(ctx, t, client, deployer, types.FromFil(1000)) - gaslimit, err := client.EthEstimateGas(ctx, ethtypes.EthCall{ + gasParams, err := json.Marshal(ethtypes.EthEstimateGasParams{Tx: ethtypes.EthCall{ From: ðAddr, Data: contract, - }, ethtypes.NewEthBlockNumberOrHashFromPredefined("latest")) + }}) + require.NoError(t, err) + + gaslimit, err := client.EthEstimateGas(ctx, gasParams) require.NoError(t, err) maxPriorityFeePerGas, err := client.EthMaxPriorityFeePerGas(ctx) @@ -231,11 +235,14 @@ func TestContractInvocation(t *testing.T) { params, err := hex.DecodeString("f8b2cb4f000000000000000000000000ff00000000000000000000000000000000000064") require.NoError(t, err) - gaslimit, err := client.EthEstimateGas(ctx, ethtypes.EthCall{ + gasParams, err := json.Marshal(ethtypes.EthEstimateGasParams{Tx: ethtypes.EthCall{ From: ðAddr, To: &contractAddr, Data: params, - }, ethtypes.NewEthBlockNumberOrHashFromPredefined("latest")) + }}) + require.NoError(t, err) + + gaslimit, err := client.EthEstimateGas(ctx, gasParams) require.NoError(t, err) maxPriorityFeePerGas, err := client.EthMaxPriorityFeePerGas(ctx) @@ -350,10 +357,15 @@ func TestGetBlockByNumber(t *testing.T) { } func deployContractTx(ctx context.Context, client *kit.TestFullNode, ethAddr ethtypes.EthAddress, contract []byte) (*ethtypes.EthTxArgs, error) { - gaslimit, err := client.EthEstimateGas(ctx, ethtypes.EthCall{ + gasParams, err := json.Marshal(ethtypes.EthEstimateGasParams{Tx: ethtypes.EthCall{ From: ðAddr, Data: contract, - }, ethtypes.NewEthBlockNumberOrHashFromPredefined("latest")) + }}) + if err != nil { + return nil, err + } + + gaslimit, err := client.EthEstimateGas(ctx, gasParams) if err != nil { return nil, err } diff --git a/itests/fevm_test.go b/itests/fevm_test.go index 7b09ac7f947..2dcb8ef1dff 100644 --- a/itests/fevm_test.go +++ b/itests/fevm_test.go @@ -6,6 +6,7 @@ import ( "crypto/rand" "encoding/binary" "encoding/hex" + "encoding/json" "fmt" "testing" "time" @@ -657,11 +658,15 @@ func TestFEVMRecursiveActorCallEstimate(t *testing.T) { t.Logf("running with %d recursive calls", r) params := makeParams(r) - gaslimit, err := client.EthEstimateGas(ctx, ethtypes.EthCall{ + + gasParams, err := json.Marshal(ethtypes.EthEstimateGasParams{Tx: ethtypes.EthCall{ From: ðAddr, To: &contractAddr, Data: params, - }, ethtypes.NewEthBlockNumberOrHashFromPredefined("latest")) + }}) + require.NoError(t, err) + + gaslimit, err := client.EthEstimateGas(ctx, gasParams) require.NoError(t, err) require.LessOrEqual(t, int64(gaslimit), build.BlockGasLimit) @@ -816,11 +821,14 @@ func TestFEVMBareTransferTriggersSmartContractLogic(t *testing.T) { contractEth, err := ethtypes.EthAddressFromFilecoinAddress(contractAddr) require.NoError(t, err) - gaslimit, err := client.EthEstimateGas(ctx, ethtypes.EthCall{ + gasParams, err := json.Marshal(ethtypes.EthEstimateGasParams{Tx: ethtypes.EthCall{ From: &accntEth, To: &contractEth, Value: ethtypes.EthBigInt(big.NewInt(100)), - }, ethtypes.NewEthBlockNumberOrHashFromPredefined("latest")) + }}) + require.NoError(t, err) + + gaslimit, err := client.EthEstimateGas(ctx, gasParams) require.NoError(t, err) maxPriorityFeePerGas, err := client.EthMaxPriorityFeePerGas(ctx) @@ -1034,10 +1042,13 @@ func TestFEVMErrorParsing(t *testing.T) { require.ErrorContains(t, err, expected) }) t.Run("EthEstimateGas", func(t *testing.T) { - _, err := e.EthEstimateGas(ctx, ethtypes.EthCall{ + gasParams, err := json.Marshal(ethtypes.EthEstimateGasParams{Tx: ethtypes.EthCall{ To: &contractAddrEth, Data: entryPoint, - }, ethtypes.NewEthBlockNumberOrHashFromPredefined("latest")) + }}) + require.NoError(t, err) + + _, err = e.EthEstimateGas(ctx, gasParams) require.ErrorContains(t, err, expected) }) }) diff --git a/node/impl/full/dummy.go b/node/impl/full/dummy.go index 857b4c57f5d..11ff95a632c 100644 --- a/node/impl/full/dummy.go +++ b/node/impl/full/dummy.go @@ -122,7 +122,7 @@ func (e *EthModuleDummy) EthGasPrice(ctx context.Context) (ethtypes.EthBigInt, e return ethtypes.EthBigIntZero, ErrModuleDisabled } -func (e *EthModuleDummy) EthEstimateGas(ctx context.Context, tx ethtypes.EthCall, blkParam ethtypes.EthBlockNumberOrHash) (ethtypes.EthUint64, error) { +func (e *EthModuleDummy) EthEstimateGas(ctx context.Context, p jsonrpc.RawParams) (ethtypes.EthUint64, error) { return 0, ErrModuleDisabled } diff --git a/node/impl/full/eth.go b/node/impl/full/eth.go index 12a9d56ea67..d4298492f1b 100644 --- a/node/impl/full/eth.go +++ b/node/impl/full/eth.go @@ -66,7 +66,7 @@ type EthModuleAPI interface { NetListening(ctx context.Context) (bool, error) EthProtocolVersion(ctx context.Context) (ethtypes.EthUint64, error) EthGasPrice(ctx context.Context) (ethtypes.EthBigInt, error) - EthEstimateGas(ctx context.Context, tx ethtypes.EthCall, blkParam ethtypes.EthBlockNumberOrHash) (ethtypes.EthUint64, error) + EthEstimateGas(ctx context.Context, p jsonrpc.RawParams) (ethtypes.EthUint64, error) EthCall(ctx context.Context, tx ethtypes.EthCall, blkParam ethtypes.EthBlockNumberOrHash) (ethtypes.EthBytes, error) EthMaxPriorityFeePerGas(ctx context.Context) (ethtypes.EthBigInt, error) EthSendRawTransaction(ctx context.Context, rawTx ethtypes.EthBytes) (ethtypes.EthHash, error) @@ -1007,8 +1007,13 @@ func (a *EthModule) applyMessage(ctx context.Context, msg *types.Message, tsk ty return res, nil } -func (a *EthModule) EthEstimateGas(ctx context.Context, tx ethtypes.EthCall, blkParam ethtypes.EthBlockNumberOrHash) (ethtypes.EthUint64, error) { - msg, err := ethCallToFilecoinMessage(ctx, tx) +func (a *EthModule) EthEstimateGas(ctx context.Context, p jsonrpc.RawParams) (ethtypes.EthUint64, error) { + params, err := jsonrpc.DecodeParams[ethtypes.EthEstimateGasParams](p) + if err != nil { + return ethtypes.EthUint64(0), xerrors.Errorf("decoding params: %w", err) + } + + msg, err := ethCallToFilecoinMessage(ctx, params.Tx) if err != nil { return ethtypes.EthUint64(0), err } @@ -1017,9 +1022,14 @@ func (a *EthModule) EthEstimateGas(ctx context.Context, tx ethtypes.EthCall, blk // gas estimation actually run. msg.GasLimit = 0 - ts, err := getTipsetByEthBlockNumberOrHash(ctx, a.Chain, blkParam) - if err != nil { - return ethtypes.EthUint64(0), xerrors.Errorf("failed to process block param: %v; %w", blkParam, err) + var ts *types.TipSet + if params.BlkParam == nil { + ts = a.Chain.GetHeaviestTipSet() + } else { + ts, err = getTipsetByEthBlockNumberOrHash(ctx, a.Chain, *params.BlkParam) + if err != nil { + return ethtypes.EthUint64(0), xerrors.Errorf("failed to process block param: %v; %w", params.BlkParam, err) + } } gassedMsg, err := a.GasAPI.GasEstimateMessageGas(ctx, msg, nil, ts.Key()) From dd667d28becf20b1cdbdc81487ea79a85ac37550 Mon Sep 17 00:00:00 2001 From: Fridrik Asmundsson Date: Wed, 29 Nov 2023 15:17:05 +0000 Subject: [PATCH 4/4] Update one test to pass optional block param to EthEstimateGas --- itests/eth_transactions_test.go | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/itests/eth_transactions_test.go b/itests/eth_transactions_test.go index 59e5852c9e2..62e21da276c 100644 --- a/itests/eth_transactions_test.go +++ b/itests/eth_transactions_test.go @@ -45,10 +45,14 @@ func TestValueTransferValidSignature(t *testing.T) { kit.SendFunds(ctx, t, client, deployer, types.FromFil(1000)) - gasParams, err := json.Marshal(ethtypes.EthEstimateGasParams{Tx: ethtypes.EthCall{ - From: ðAddr, - Data: contract, - }}) + blkParam := ethtypes.NewEthBlockNumberOrHashFromPredefined("latest") + gasParams, err := json.Marshal(ethtypes.EthEstimateGasParams{ + Tx: ethtypes.EthCall{ + From: ðAddr, + Data: contract, + }, + BlkParam: &blkParam, + }) require.NoError(t, err) gaslimit, err := client.EthEstimateGas(ctx, gasParams)