Compare commits

...

4 Commits

Author SHA1 Message Date
Fridrik Asmundsson
825b514c8b Update one test to pass optional block param to EthEstimateGas 2023-12-14 11:31:10 -06:00
Fridrik Asmundsson
0db343a164 Make block param to EthEstimateGas optional 2023-12-14 11:30:49 -06:00
Fridrik Asmundsson
9a1004301a fix spelling 2023-12-14 11:30:16 -06:00
Fridrik Asmundsson
1f5f6ae0f2 Add block param to EthEstimateGas 2023-12-14 11:29:32 -06:00
17 changed files with 160 additions and 55 deletions

View File

@ -1,15 +1,21 @@
# Lotus changelog # Lotus changelog
# UNRELEASED
- chore: Auto remove local chain data when importing chain file or snapshot ([filecoin-project/lotus#11277](https://github.com/filecoin-project/lotus/pull/11277))
- 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` ([filecoin-project/lotus#11462](https://github.com/filecoin-project/lotus/pull/11462)).
## Improvements
- fix: exchange: allow up to 10k messages per block ([filecoin-project/lotus#11506](https://github.com/filecoin-project/lotus/pull/11506))
# v1.25.1 / 2023-12-09 # v1.25.1 / 2023-12-09
This is a **highly recommended PATCH RELEASE.** The patch release fixes the issue were node operators trying to catch up sync were unable to sync large message blocks/epochs due to an increased number of messages on the network. This is a **highly recommended PATCH RELEASE.** The patch release fixes the issue were node operators trying to catch up sync were unable to sync large message blocks/epochs due to an increased number of messages on the network.
This patch release allows for up to 10k messages per block. Additionally, it introduces a limit on the amount of data that can be read at once, ensuring the system can handle worst-case scenarios. This patch release allows for up to 10k messages per block. Additionally, it introduces a limit on the amount of data that can be read at once, ensuring the system can handle worst-case scenarios.
## Improvements
- fix: exchange: allow up to 10k messages per block ([filecoin-project/lotus#11506](https://github.com/filecoin-project/lotus/pull/11506))
# v 1.25.0 / 2023-11-22 # v 1.25.0 / 2023-11-22
This is a highly recommended feature release of Lotus. This optional release supports the Filecoin network version 21 upgrade, codenamed Watermelon 🍉, in addition to the numerous improvements and enhancements for node operators, ETH RPC-providers and storage providers. This is a highly recommended feature release of Lotus. This optional release supports the Filecoin network version 21 upgrade, codenamed Watermelon 🍉, in addition to the numerous improvements and enhancements for node operators, ETH RPC-providers and storage providers.

View File

@ -824,7 +824,7 @@ type FullNode interface {
EthFeeHistory(ctx context.Context, p jsonrpc.RawParams) (ethtypes.EthFeeHistory, error) //perm:read EthFeeHistory(ctx context.Context, p jsonrpc.RawParams) (ethtypes.EthFeeHistory, error) //perm:read
EthMaxPriorityFeePerGas(ctx context.Context) (ethtypes.EthBigInt, error) //perm:read EthMaxPriorityFeePerGas(ctx context.Context) (ethtypes.EthBigInt, error) //perm:read
EthEstimateGas(ctx context.Context, tx ethtypes.EthCall) (ethtypes.EthUint64, error) //perm:read EthEstimateGas(ctx context.Context, p jsonrpc.RawParams) (ethtypes.EthUint64, error) //perm:read
EthCall(ctx context.Context, tx ethtypes.EthCall, blkParam ethtypes.EthBlockNumberOrHash) (ethtypes.EthBytes, 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 EthSendRawTransaction(ctx context.Context, rawTx ethtypes.EthBytes) (ethtypes.EthHash, error) //perm:read

View File

@ -114,7 +114,7 @@ type Gateway interface {
EthGasPrice(ctx context.Context) (ethtypes.EthBigInt, error) EthGasPrice(ctx context.Context) (ethtypes.EthBigInt, error)
EthFeeHistory(ctx context.Context, p jsonrpc.RawParams) (ethtypes.EthFeeHistory, error) EthFeeHistory(ctx context.Context, p jsonrpc.RawParams) (ethtypes.EthFeeHistory, error)
EthMaxPriorityFeePerGas(ctx context.Context) (ethtypes.EthBigInt, error) EthMaxPriorityFeePerGas(ctx context.Context) (ethtypes.EthBigInt, error)
EthEstimateGas(ctx context.Context, tx ethtypes.EthCall) (ethtypes.EthUint64, error) EthEstimateGas(ctx context.Context, p jsonrpc.RawParams) (ethtypes.EthUint64, error)
EthCall(ctx context.Context, tx ethtypes.EthCall, blkParam ethtypes.EthBlockNumberOrHash) (ethtypes.EthBytes, error) EthCall(ctx context.Context, tx ethtypes.EthCall, blkParam ethtypes.EthBlockNumberOrHash) (ethtypes.EthBytes, error)
EthSendRawTransaction(ctx context.Context, rawTx ethtypes.EthBytes) (ethtypes.EthHash, error) EthSendRawTransaction(ctx context.Context, rawTx ethtypes.EthBytes) (ethtypes.EthHash, error)
EthGetLogs(ctx context.Context, filter *ethtypes.EthFilterSpec) (*ethtypes.EthFilterResult, error) EthGetLogs(ctx context.Context, filter *ethtypes.EthFilterSpec) (*ethtypes.EthFilterResult, error)

View File

@ -1042,7 +1042,7 @@ func (mr *MockFullNodeMockRecorder) EthChainId(arg0 interface{}) *gomock.Call {
} }
// EthEstimateGas mocks base method. // 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 jsonrpc.RawParams) (ethtypes.EthUint64, error) {
m.ctrl.T.Helper() m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "EthEstimateGas", arg0, arg1) ret := m.ctrl.Call(m, "EthEstimateGas", arg0, arg1)
ret0, _ := ret[0].(ethtypes.EthUint64) ret0, _ := ret[0].(ethtypes.EthUint64)

View File

@ -255,7 +255,7 @@ type FullNodeMethods struct {
EthChainId func(p0 context.Context) (ethtypes.EthUint64, error) `perm:"read"` 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 jsonrpc.RawParams) (ethtypes.EthUint64, error) `perm:"read"`
EthFeeHistory func(p0 context.Context, p1 jsonrpc.RawParams) (ethtypes.EthFeeHistory, 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) `` 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 jsonrpc.RawParams) (ethtypes.EthUint64, error) ``
EthFeeHistory func(p0 context.Context, p1 jsonrpc.RawParams) (ethtypes.EthFeeHistory, 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 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 jsonrpc.RawParams) (ethtypes.EthUint64, error) {
if s.Internal.EthEstimateGas == nil { if s.Internal.EthEstimateGas == nil {
return *new(ethtypes.EthUint64), ErrNotSupported return *new(ethtypes.EthUint64), ErrNotSupported
} }
return s.Internal.EthEstimateGas(p0, p1) return s.Internal.EthEstimateGas(p0, p1)
} }
func (s *FullNodeStub) EthEstimateGas(p0 context.Context, p1 ethtypes.EthCall) (ethtypes.EthUint64, error) { func (s *FullNodeStub) EthEstimateGas(p0 context.Context, p1 jsonrpc.RawParams) (ethtypes.EthUint64, error) {
return *new(ethtypes.EthUint64), ErrNotSupported return *new(ethtypes.EthUint64), ErrNotSupported
} }
@ -4400,14 +4400,14 @@ func (s *GatewayStub) EthChainId(p0 context.Context) (ethtypes.EthUint64, error)
return *new(ethtypes.EthUint64), ErrNotSupported 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 jsonrpc.RawParams) (ethtypes.EthUint64, error) {
if s.Internal.EthEstimateGas == nil { if s.Internal.EthEstimateGas == nil {
return *new(ethtypes.EthUint64), ErrNotSupported return *new(ethtypes.EthUint64), ErrNotSupported
} }
return s.Internal.EthEstimateGas(p0, p1) return s.Internal.EthEstimateGas(p0, p1)
} }
func (s *GatewayStub) EthEstimateGas(p0 context.Context, p1 ethtypes.EthCall) (ethtypes.EthUint64, error) { func (s *GatewayStub) EthEstimateGas(p0 context.Context, p1 jsonrpc.RawParams) (ethtypes.EthUint64, error) {
return *new(ethtypes.EthUint64), ErrNotSupported return *new(ethtypes.EthUint64), ErrNotSupported
} }

View File

@ -799,6 +799,45 @@ func GetContractEthAddressFromCode(sender EthAddress, salt [32]byte, initcode []
return ethAddr, nil 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, &params)
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 // EthFeeHistoryParams handles raw jsonrpc params for eth_feeHistory
type EthFeeHistoryParams struct { type EthFeeHistoryParams struct {
BlkCount EthUint64 BlkCount EthUint64

View File

@ -2402,14 +2402,7 @@ Perms: read
Inputs: Inputs:
```json ```json
[ [
{ "Bw=="
"from": "0x5cbeecf99d3fdb3f25e309cc264f240bb0664031",
"to": "0x5cbeecf99d3fdb3f25e309cc264f240bb0664031",
"gas": "0x5",
"gasPrice": "0x0",
"value": "0x0",
"data": "0x07"
}
] ]
``` ```

View File

@ -131,7 +131,7 @@ type TargetAPI interface {
EthGasPrice(ctx context.Context) (ethtypes.EthBigInt, error) EthGasPrice(ctx context.Context) (ethtypes.EthBigInt, error)
EthFeeHistory(ctx context.Context, p jsonrpc.RawParams) (ethtypes.EthFeeHistory, error) EthFeeHistory(ctx context.Context, p jsonrpc.RawParams) (ethtypes.EthFeeHistory, error)
EthMaxPriorityFeePerGas(ctx context.Context) (ethtypes.EthBigInt, error) EthMaxPriorityFeePerGas(ctx context.Context) (ethtypes.EthBigInt, error)
EthEstimateGas(ctx context.Context, tx ethtypes.EthCall) (ethtypes.EthUint64, error) EthEstimateGas(ctx context.Context, p jsonrpc.RawParams) (ethtypes.EthUint64, error)
EthCall(ctx context.Context, tx ethtypes.EthCall, blkParam ethtypes.EthBlockNumberOrHash) (ethtypes.EthBytes, error) EthCall(ctx context.Context, tx ethtypes.EthCall, blkParam ethtypes.EthBlockNumberOrHash) (ethtypes.EthBytes, error)
EthSendRawTransaction(ctx context.Context, rawTx ethtypes.EthBytes) (ethtypes.EthHash, error) EthSendRawTransaction(ctx context.Context, rawTx ethtypes.EthBytes) (ethtypes.EthHash, error)
EthGetLogs(ctx context.Context, filter *ethtypes.EthFilterSpec) (*ethtypes.EthFilterResult, error) EthGetLogs(ctx context.Context, filter *ethtypes.EthFilterSpec) (*ethtypes.EthFilterResult, error)

View File

@ -353,13 +353,19 @@ func (gw *Node) EthMaxPriorityFeePerGas(ctx context.Context) (ethtypes.EthBigInt
return gw.target.EthMaxPriorityFeePerGas(ctx) 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, 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 { if err := gw.limit(ctx, stateRateLimitTokens); err != nil {
return 0, err return 0, err
} }
// todo limit gas? to what? // todo limit gas? to what?
return gw.target.EthEstimateGas(ctx, tx) return gw.target.EthEstimateGas(ctx, p)
} }
func (gw *Node) EthCall(ctx context.Context, tx ethtypes.EthCall, blkParam ethtypes.EthBlockNumberOrHash) (ethtypes.EthBytes, error) { func (gw *Node) EthCall(ctx context.Context, tx ethtypes.EthCall, blkParam ethtypes.EthBlockNumberOrHash) (ethtypes.EthBytes, error) {

View File

@ -3,6 +3,7 @@ package itests
import ( import (
"context" "context"
"encoding/hex" "encoding/hex"
"encoding/json"
"os" "os"
"testing" "testing"
"time" "time"
@ -272,10 +273,13 @@ func TestEthAccountAbstractionFailsFromEvmActor(t *testing.T) {
contract, err := hex.DecodeString(string(contractHex)) contract, err := hex.DecodeString(string(contractHex))
require.NoError(t, err) require.NoError(t, err)
gaslimit, err := client.EthEstimateGas(ctx, ethtypes.EthCall{ gasParams, err := json.Marshal(ethtypes.EthEstimateGasParams{Tx: ethtypes.EthCall{
From: &ethAddr, From: &ethAddr,
Data: contract, Data: contract,
}) }})
require.NoError(t, err)
gaslimit, err := client.EthEstimateGas(ctx, gasParams)
require.NoError(t, err) require.NoError(t, err)
maxPriorityFeePerGas, err := client.EthMaxPriorityFeePerGas(ctx) maxPriorityFeePerGas, err := client.EthMaxPriorityFeePerGas(ctx)

View File

@ -35,7 +35,7 @@ type ethAPIRaw struct {
EthBlockNumber func(context.Context) (json.RawMessage, error) EthBlockNumber func(context.Context) (json.RawMessage, error)
EthCall func(context.Context, ethtypes.EthCall, ethtypes.EthBlockNumberOrHash) (json.RawMessage, error) EthCall func(context.Context, ethtypes.EthCall, ethtypes.EthBlockNumberOrHash) (json.RawMessage, error)
EthChainId func(context.Context) (json.RawMessage, error) EthChainId func(context.Context) (json.RawMessage, error)
EthEstimateGas func(context.Context, ethtypes.EthCall) (json.RawMessage, error) EthEstimateGas func(context.Context, jsonrpc.RawParams) (json.RawMessage, error)
EthFeeHistory func(context.Context, ethtypes.EthUint64, string, []float64) (json.RawMessage, error) EthFeeHistory func(context.Context, ethtypes.EthUint64, string, []float64) (json.RawMessage, error)
EthGasPrice func(context.Context) (json.RawMessage, error) EthGasPrice func(context.Context) (json.RawMessage, error)
EthGetBalance func(context.Context, ethtypes.EthAddress, ethtypes.EthBlockNumberOrHash) (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", method: "eth_estimateGas",
call: func(a *ethAPIRaw) (json.RawMessage, error) { 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, From: &senderEthAddr,
Data: contractBin, Data: contractBin,
}) }})
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 { 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, From: &senderEthAddr,
Data: contractBin, Data: contractBin,
}) }})
require.NoError(t, err)
gaslimit, err := client.EthEstimateGas(ctx, gasParams)
require.NoError(t, err) require.NoError(t, err)
maxPriorityFeePerGas, err := client.EthMaxPriorityFeePerGas(ctx) maxPriorityFeePerGas, err := client.EthMaxPriorityFeePerGas(ctx)

View File

@ -60,10 +60,13 @@ func TestDeployment(t *testing.T) {
// verify the deployer address is an Placeholder. // verify the deployer address is an Placeholder.
client.AssertActorType(ctx, deployer, manifest.PlaceholderKey) client.AssertActorType(ctx, deployer, manifest.PlaceholderKey)
gaslimit, err := client.EthEstimateGas(ctx, ethtypes.EthCall{ gasParams, err := json.Marshal(ethtypes.EthEstimateGasParams{Tx: ethtypes.EthCall{
From: &ethAddr, From: &ethAddr,
Data: contract, Data: contract,
}) }})
require.NoError(t, err)
gaslimit, err := client.EthEstimateGas(ctx, gasParams)
require.NoError(t, err) require.NoError(t, err)
maxPriorityFeePerGas, err := client.EthMaxPriorityFeePerGas(ctx) maxPriorityFeePerGas, err := client.EthMaxPriorityFeePerGas(ctx)

View File

@ -3,6 +3,7 @@ package itests
import ( import (
"context" "context"
"encoding/hex" "encoding/hex"
"encoding/json"
"os" "os"
"testing" "testing"
"time" "time"
@ -47,10 +48,13 @@ func TestTransactionHashLookup(t *testing.T) {
// send some funds to the f410 address // send some funds to the f410 address
kit.SendFunds(ctx, t, client, deployer, types.FromFil(10)) 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: &ethAddr, From: &ethAddr,
Data: contract, Data: contract,
}) }})
require.NoError(t, err)
gaslimit, err := client.EthEstimateGas(ctx, gasParams)
require.NoError(t, err) require.NoError(t, err)
maxPriorityFeePerGas, err := client.EthMaxPriorityFeePerGas(ctx) maxPriorityFeePerGas, err := client.EthMaxPriorityFeePerGas(ctx)
@ -313,10 +317,13 @@ func TestEthGetMessageCidByTransactionHashEthTx(t *testing.T) {
// send some funds to the f410 address // send some funds to the f410 address
kit.SendFunds(ctx, t, client, deployer, types.FromFil(10)) 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: &ethAddr, From: &ethAddr,
Data: contract, Data: contract,
}) }})
require.NoError(t, err)
gaslimit, err := client.EthEstimateGas(ctx, gasParams)
require.NoError(t, err) require.NoError(t, err)
maxPriorityFeePerGas, err := client.EthMaxPriorityFeePerGas(ctx) maxPriorityFeePerGas, err := client.EthMaxPriorityFeePerGas(ctx)

View File

@ -3,6 +3,7 @@ package itests
import ( import (
"context" "context"
"encoding/hex" "encoding/hex"
"encoding/json"
"os" "os"
"testing" "testing"
"time" "time"
@ -42,12 +43,19 @@ func TestValueTransferValidSignature(t *testing.T) {
kit.SendFunds(ctx, t, client, deployer, types.FromFil(1000)) kit.SendFunds(ctx, t, client, deployer, types.FromFil(1000))
gaslimit, err := client.EthEstimateGas(ctx, ethtypes.EthCall{ blkParam := ethtypes.NewEthBlockNumberOrHashFromPredefined("latest")
From: &ethAddr, gasParams, err := json.Marshal(ethtypes.EthEstimateGasParams{
Data: contract, Tx: ethtypes.EthCall{
From: &ethAddr,
Data: contract,
},
BlkParam: &blkParam,
}) })
require.NoError(t, err) require.NoError(t, err)
gaslimit, err := client.EthEstimateGas(ctx, gasParams)
require.NoError(t, err)
maxPriorityFeePerGas, err := client.EthMaxPriorityFeePerGas(ctx) maxPriorityFeePerGas, err := client.EthMaxPriorityFeePerGas(ctx)
require.NoError(t, err) require.NoError(t, err)
@ -229,11 +237,14 @@ func TestContractInvocation(t *testing.T) {
params, err := hex.DecodeString("f8b2cb4f000000000000000000000000ff00000000000000000000000000000000000064") params, err := hex.DecodeString("f8b2cb4f000000000000000000000000ff00000000000000000000000000000000000064")
require.NoError(t, err) require.NoError(t, err)
gaslimit, err := client.EthEstimateGas(ctx, ethtypes.EthCall{ gasParams, err := json.Marshal(ethtypes.EthEstimateGasParams{Tx: ethtypes.EthCall{
From: &ethAddr, From: &ethAddr,
To: &contractAddr, To: &contractAddr,
Data: params, Data: params,
}) }})
require.NoError(t, err)
gaslimit, err := client.EthEstimateGas(ctx, gasParams)
require.NoError(t, err) require.NoError(t, err)
maxPriorityFeePerGas, err := client.EthMaxPriorityFeePerGas(ctx) maxPriorityFeePerGas, err := client.EthMaxPriorityFeePerGas(ctx)
@ -348,10 +359,15 @@ func TestGetBlockByNumber(t *testing.T) {
} }
func deployContractTx(ctx context.Context, client *kit.TestFullNode, ethAddr ethtypes.EthAddress, contract []byte) (*ethtypes.EthTxArgs, error) { 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: &ethAddr, From: &ethAddr,
Data: contract, Data: contract,
}) }})
if err != nil {
return nil, err
}
gaslimit, err := client.EthEstimateGas(ctx, gasParams)
if err != nil { if err != nil {
return nil, err return nil, err
} }

View File

@ -6,6 +6,7 @@ import (
"crypto/rand" "crypto/rand"
"encoding/binary" "encoding/binary"
"encoding/hex" "encoding/hex"
"encoding/json"
"fmt" "fmt"
"testing" "testing"
"time" "time"
@ -657,11 +658,15 @@ func TestFEVMRecursiveActorCallEstimate(t *testing.T) {
t.Logf("running with %d recursive calls", r) t.Logf("running with %d recursive calls", r)
params := makeParams(r) params := makeParams(r)
gaslimit, err := client.EthEstimateGas(ctx, ethtypes.EthCall{
gasParams, err := json.Marshal(ethtypes.EthEstimateGasParams{Tx: ethtypes.EthCall{
From: &ethAddr, From: &ethAddr,
To: &contractAddr, To: &contractAddr,
Data: params, Data: params,
}) }})
require.NoError(t, err)
gaslimit, err := client.EthEstimateGas(ctx, gasParams)
require.NoError(t, err) require.NoError(t, err)
require.LessOrEqual(t, int64(gaslimit), build.BlockGasLimit) require.LessOrEqual(t, int64(gaslimit), build.BlockGasLimit)
@ -816,11 +821,14 @@ func TestFEVMBareTransferTriggersSmartContractLogic(t *testing.T) {
contractEth, err := ethtypes.EthAddressFromFilecoinAddress(contractAddr) contractEth, err := ethtypes.EthAddressFromFilecoinAddress(contractAddr)
require.NoError(t, err) require.NoError(t, err)
gaslimit, err := client.EthEstimateGas(ctx, ethtypes.EthCall{ gasParams, err := json.Marshal(ethtypes.EthEstimateGasParams{Tx: ethtypes.EthCall{
From: &accntEth, From: &accntEth,
To: &contractEth, To: &contractEth,
Value: ethtypes.EthBigInt(big.NewInt(100)), Value: ethtypes.EthBigInt(big.NewInt(100)),
}) }})
require.NoError(t, err)
gaslimit, err := client.EthEstimateGas(ctx, gasParams)
require.NoError(t, err) require.NoError(t, err)
maxPriorityFeePerGas, err := client.EthMaxPriorityFeePerGas(ctx) maxPriorityFeePerGas, err := client.EthMaxPriorityFeePerGas(ctx)
@ -1034,10 +1042,13 @@ func TestFEVMErrorParsing(t *testing.T) {
require.ErrorContains(t, err, expected) require.ErrorContains(t, err, expected)
}) })
t.Run("EthEstimateGas", func(t *testing.T) { t.Run("EthEstimateGas", func(t *testing.T) {
_, err := e.EthEstimateGas(ctx, ethtypes.EthCall{ gasParams, err := json.Marshal(ethtypes.EthEstimateGasParams{Tx: ethtypes.EthCall{
To: &contractAddrEth, To: &contractAddrEth,
Data: entryPoint, Data: entryPoint,
}) }})
require.NoError(t, err)
_, err = e.EthEstimateGas(ctx, gasParams)
require.ErrorContains(t, err, expected) require.ErrorContains(t, err, expected)
}) })
}) })

View File

@ -122,7 +122,7 @@ func (e *EthModuleDummy) EthGasPrice(ctx context.Context) (ethtypes.EthBigInt, e
return ethtypes.EthBigIntZero, ErrModuleDisabled return ethtypes.EthBigIntZero, ErrModuleDisabled
} }
func (e *EthModuleDummy) EthEstimateGas(ctx context.Context, tx ethtypes.EthCall) (ethtypes.EthUint64, error) { func (e *EthModuleDummy) EthEstimateGas(ctx context.Context, p jsonrpc.RawParams) (ethtypes.EthUint64, error) {
return 0, ErrModuleDisabled return 0, ErrModuleDisabled
} }

View File

@ -66,7 +66,7 @@ type EthModuleAPI interface {
NetListening(ctx context.Context) (bool, error) NetListening(ctx context.Context) (bool, error)
EthProtocolVersion(ctx context.Context) (ethtypes.EthUint64, error) EthProtocolVersion(ctx context.Context) (ethtypes.EthUint64, error)
EthGasPrice(ctx context.Context) (ethtypes.EthBigInt, error) EthGasPrice(ctx context.Context) (ethtypes.EthBigInt, error)
EthEstimateGas(ctx context.Context, tx ethtypes.EthCall) (ethtypes.EthUint64, error) EthEstimateGas(ctx context.Context, p jsonrpc.RawParams) (ethtypes.EthUint64, error)
EthCall(ctx context.Context, tx ethtypes.EthCall, blkParam ethtypes.EthBlockNumberOrHash) (ethtypes.EthBytes, error) EthCall(ctx context.Context, tx ethtypes.EthCall, blkParam ethtypes.EthBlockNumberOrHash) (ethtypes.EthBytes, error)
EthMaxPriorityFeePerGas(ctx context.Context) (ethtypes.EthBigInt, error) EthMaxPriorityFeePerGas(ctx context.Context) (ethtypes.EthBigInt, error)
EthSendRawTransaction(ctx context.Context, rawTx ethtypes.EthBytes) (ethtypes.EthHash, error) EthSendRawTransaction(ctx context.Context, rawTx ethtypes.EthBytes) (ethtypes.EthHash, error)
@ -999,8 +999,13 @@ func (a *EthModule) applyMessage(ctx context.Context, msg *types.Message, tsk ty
return res, nil return res, nil
} }
func (a *EthModule) EthEstimateGas(ctx context.Context, tx ethtypes.EthCall) (ethtypes.EthUint64, error) { func (a *EthModule) EthEstimateGas(ctx context.Context, p jsonrpc.RawParams) (ethtypes.EthUint64, error) {
msg, err := ethCallToFilecoinMessage(ctx, tx) 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 { if err != nil {
return ethtypes.EthUint64(0), err return ethtypes.EthUint64(0), err
} }
@ -1009,7 +1014,16 @@ func (a *EthModule) EthEstimateGas(ctx context.Context, tx ethtypes.EthCall) (et
// gas estimation actually run. // gas estimation actually run.
msg.GasLimit = 0 msg.GasLimit = 0
ts := a.Chain.GetHeaviestTipSet() 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()) gassedMsg, err := a.GasAPI.GasEstimateMessageGas(ctx, msg, nil, ts.Key())
if err != nil { if err != nil {
// On failure, GasEstimateMessageGas doesn't actually return the invocation result, // On failure, GasEstimateMessageGas doesn't actually return the invocation result,