Skip to content

Commit

Permalink
refactor(eth): attach ToFilecoinMessage converter to EthCall. (#12844)
Browse files Browse the repository at this point in the history
  • Loading branch information
rjan90 authored Jan 24, 2025
1 parent 4c9687a commit a90ee17
Show file tree
Hide file tree
Showing 4 changed files with 64 additions and 61 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
# UNRELEASED

- refactor(eth): attach ToFilecoinMessage converter to EthCall method for improved package/module import structure. This change also exports the converter as a public method, enhancing usability for developers utilizing Lotus as a library. ([filecoin-project/lotus#12844](https://github.com/filecoin-project/lotus/pull/12844))
- Add json output of tipsets to `lotus chain list`. ([filecoin-project/lotus#12691](https://github.com/filecoin-project/lotus/pull/12691))
- Remove IPNI advertisement relay over pubsub via Lotus node as it now has been deprecated. ([filecoin-project/lotus#12768](https://github.com/filecoin-project/lotus/pull/12768)
- During a network upgrade, log migration progress every 2 seconds so they are more helpful and informative. The `LOTUS_MIGRATE_PROGRESS_LOG_SECONDS` environment variable can be used to change this if needed. ([filecoin-project/lotus#12732](https://github.com/filecoin-project/lotus/pull/12732))
Expand Down
61 changes: 61 additions & 0 deletions chain/types/ethtypes/eth_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,10 @@ import (
"github.com/filecoin-project/go-state-types/big"
builtintypes "github.com/filecoin-project/go-state-types/builtin"

"github.com/filecoin-project/lotus/build"
"github.com/filecoin-project/lotus/build/buildconstants"
"github.com/filecoin-project/lotus/chain/actors"
"github.com/filecoin-project/lotus/chain/types"
"github.com/filecoin-project/lotus/lib/must"
)

Expand Down Expand Up @@ -247,6 +250,64 @@ type EthCall struct {
Data EthBytes `json:"data"`
}

func (c *EthCall) ToFilecoinMessage() (*types.Message, error) {
var from address.Address
if c.From == nil || *c.From == (EthAddress{}) {
// Send from the filecoin "system" address.
var err error
from, err = (EthAddress{}).ToFilecoinAddress()
if err != nil {
return nil, fmt.Errorf("failed to construct the ethereum system address: %w", err)
}
} else {
// The from address must be translatable to an f4 address.
var err error
from, err = c.From.ToFilecoinAddress()
if err != nil {
return nil, fmt.Errorf("failed to translate sender address (%s): %w", c.From.String(), err)
}
if p := from.Protocol(); p != address.Delegated {
return nil, fmt.Errorf("expected a class 4 address, got: %d: %w", p, err)
}
}

var params []byte
if len(c.Data) > 0 {
initcode := abi.CborBytes(c.Data)
params2, err := actors.SerializeParams(&initcode)
if err != nil {
return nil, fmt.Errorf("failed to serialize params: %w", err)
}
params = params2
}

var to address.Address
var method abi.MethodNum
if c.To == nil {
// this is a contract creation
to = builtintypes.EthereumAddressManagerActorAddr
method = builtintypes.MethodsEAM.CreateExternal
} else {
addr, err := c.To.ToFilecoinAddress()
if err != nil {
return nil, xerrors.Errorf("cannot get Filecoin address: %w", err)
}
to = addr
method = builtintypes.MethodsEVM.InvokeContract
}

return &types.Message{
From: from,
To: to,
Value: big.Int(c.Value),
Method: method,
Params: params,
GasLimit: build.BlockGasLimit,
GasFeeCap: big.Zero(),
GasPremium: big.Zero(),
}, nil
}

func (c *EthCall) UnmarshalJSON(b []byte) error {
type EthCallRaw EthCall // Avoid a recursive call.
type EthCallDecode struct {
Expand Down
4 changes: 2 additions & 2 deletions node/impl/eth/gas.go
Original file line number Diff line number Diff line change
Expand Up @@ -186,7 +186,7 @@ func (e *ethGas) EthEstimateGas(ctx context.Context, p jsonrpc.RawParams) (ethty
return ethtypes.EthUint64(0), xerrors.Errorf("decoding params: %w", err)
}

msg, err := ethCallToFilecoinMessage(ctx, params.Tx)
msg, err := params.Tx.ToFilecoinMessage()
if err != nil {
return ethtypes.EthUint64(0), err
}
Expand Down Expand Up @@ -237,7 +237,7 @@ func (e *ethGas) EthEstimateGas(ctx context.Context, p jsonrpc.RawParams) (ethty
}

func (e *ethGas) EthCall(ctx context.Context, tx ethtypes.EthCall, blkParam ethtypes.EthBlockNumberOrHash) (ethtypes.EthBytes, error) {
msg, err := ethCallToFilecoinMessage(ctx, tx)
msg, err := tx.ToFilecoinMessage()
if err != nil {
return nil, xerrors.Errorf("failed to convert ethcall to filecoin message: %w", err)
}
Expand Down
59 changes: 0 additions & 59 deletions node/impl/eth/utils.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,6 @@ import (

"github.com/filecoin-project/lotus/api"
"github.com/filecoin-project/lotus/build/buildconstants"
"github.com/filecoin-project/lotus/chain/actors"
"github.com/filecoin-project/lotus/chain/actors/builtin"
"github.com/filecoin-project/lotus/chain/actors/policy"
"github.com/filecoin-project/lotus/chain/state"
Expand Down Expand Up @@ -99,64 +98,6 @@ func getTipsetByEthBlockNumberOrHash(ctx context.Context, cp ChainStore, blkPara
return nil, xerrors.New("invalid block param")
}

func ethCallToFilecoinMessage(ctx context.Context, tx ethtypes.EthCall) (*types.Message, error) {
var from address.Address
if tx.From == nil || *tx.From == (ethtypes.EthAddress{}) {
// Send from the filecoin "system" address.
var err error
from, err = (ethtypes.EthAddress{}).ToFilecoinAddress()
if err != nil {
return nil, xerrors.Errorf("failed to construct the ethereum system address: %w", err)
}
} else {
// The from address must be translatable to an f4 address.
var err error
from, err = tx.From.ToFilecoinAddress()
if err != nil {
return nil, xerrors.Errorf("failed to translate sender address (%s): %w", tx.From.String(), err)
}
if p := from.Protocol(); p != address.Delegated {
return nil, xerrors.Errorf("expected a class 4 address, got: %d: %w", p, err)
}
}

var params []byte
if len(tx.Data) > 0 {
initcode := abi.CborBytes(tx.Data)
params2, err := actors.SerializeParams(&initcode)
if err != nil {
return nil, xerrors.Errorf("failed to serialize params: %w", err)
}
params = params2
}

var to address.Address
var method abi.MethodNum
if tx.To == nil {
// this is a contract creation
to = builtintypes.EthereumAddressManagerActorAddr
method = builtintypes.MethodsEAM.CreateExternal
} else {
addr, err := tx.To.ToFilecoinAddress()
if err != nil {
return nil, xerrors.Errorf("cannot get Filecoin address: %w", err)
}
to = addr
method = builtintypes.MethodsEVM.InvokeContract
}

return &types.Message{
From: from,
To: to,
Value: big.Int(tx.Value),
Method: method,
Params: params,
GasLimit: buildconstants.BlockGasLimit,
GasFeeCap: big.Zero(),
GasPremium: big.Zero(),
}, nil
}

func newEthBlockFromFilecoinTipSet(ctx context.Context, ts *types.TipSet, fullTxInfo bool, cp ChainStore, sp StateManager) (ethtypes.EthBlock, error) {
parentKeyCid, err := ts.Parents().Cid()
if err != nil {
Expand Down

0 comments on commit a90ee17

Please sign in to comment.