Skip to content

Commit

Permalink
chore: Eth TX Encoding
Browse files Browse the repository at this point in the history
  • Loading branch information
simlecode committed Dec 15, 2022
1 parent 361f145 commit a10fd3b
Show file tree
Hide file tree
Showing 2 changed files with 46 additions and 31 deletions.
48 changes: 37 additions & 11 deletions app/submodule/eth/eth_api.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import (
actorstypes "github.com/filecoin-project/go-state-types/actors"
"github.com/filecoin-project/go-state-types/big"
builtintypes "github.com/filecoin-project/go-state-types/builtin"
"github.com/filecoin-project/go-state-types/builtin/v10/eam"
"github.com/filecoin-project/go-state-types/builtin/v10/evm"
init10 "github.com/filecoin-project/go-state-types/builtin/v10/init"
"github.com/filecoin-project/specs-actors/actors/builtin"
Expand Down Expand Up @@ -181,7 +182,7 @@ func (a *ethAPI) EthGetCode(ctx context.Context, ethAddr types.EthAddress) (type
From: from,
To: to,
Value: big.Zero(),
Method: abi.MethodNum(3), // GetBytecode
Method: builtintypes.MethodsEVM.GetBytecode,
Params: nil,
GasLimit: constants.BlockGasLimit,
GasFeeCap: big.Zero(),
Expand Down Expand Up @@ -268,7 +269,7 @@ func (a *ethAPI) EthGetStorageAt(ctx context.Context, ethAddr types.EthAddress,
From: from,
To: to,
Value: big.Zero(),
Method: abi.MethodNum(4), // GetStorageAt
Method: builtintypes.MethodsEVM.GetStorageAt,
Params: params,
GasLimit: constants.BlockGasLimit,
GasFeeCap: big.Zero(),
Expand Down Expand Up @@ -420,8 +421,7 @@ func (a *ethAPI) applyEvmMsg(ctx context.Context, tx types.EthCall) (*types.Invo
if tx.To == nil {
to = builtintypes.InitActorAddr
constructorParams, err := actors.SerializeParams(&evm.ConstructorParams{
Creator: tx.Data,
Initcode: []byte{},
Initcode: tx.Data,
})
if err != nil {
return nil, fmt.Errorf("failed to serialize constructor params: %w", err)
Expand All @@ -445,14 +445,18 @@ func (a *ethAPI) applyEvmMsg(ctx context.Context, tx types.EthCall) (*types.Invo
return nil, fmt.Errorf("cannot get Filecoin address: %w", err)
}
to = addr
params = tx.Data
var buf bytes.Buffer
if err := cbg.WriteByteArray(&buf, tx.Data); err != nil {
return nil, fmt.Errorf("failed to encode tx input into a cbor byte-string %v", err)
}
params = buf.Bytes()
}

msg := &types.Message{
From: from,
To: to,
Value: big.Int(tx.Value),
Method: abi.MethodNum(2),
Method: builtintypes.MethodsEVM.InvokeContract,
Params: params,
GasLimit: constants.BlockGasLimit,
GasFeeCap: big.Zero(),
Expand Down Expand Up @@ -510,7 +514,7 @@ func (a *ethAPI) EthCall(ctx context.Context, tx types.EthCall, blkParam string)
return nil, err
}
if len(invokeResult.MsgRct.Return) > 0 {
return types.EthBytes(invokeResult.MsgRct.Return), nil
return cbg.ReadByteArray(bytes.NewReader(invokeResult.MsgRct.Return), uint64(len(invokeResult.MsgRct.Return)))
}
return types.EthBytes{}, nil
}
Expand Down Expand Up @@ -618,9 +622,31 @@ func (a *ethAPI) ethTxFromFilecoinMessageLookup(ctx context.Context, msgLookup *
}

toAddr := &toEthAddr
_, err = types.CheckContractCreation(msgLookup)
if err == nil {
toAddr = nil
input := msg.Params
// Check to see if we need to decode as contract deployment.
if toFilAddr == builtintypes.EthereumAddressManagerActorAddr {
switch msg.Method {
case builtintypes.MethodsEAM.Create:
toAddr = nil
var params eam.CreateParams
err = params.UnmarshalCBOR(bytes.NewReader(msg.Params))
input = params.Initcode
case builtintypes.MethodsEAM.Create2:
toAddr = nil
var params eam.Create2Params
err = params.UnmarshalCBOR(bytes.NewReader(msg.Params))
input = params.Initcode
}
if err != nil {
return types.EthTx{}, err
}
}
// Otherwise, try to decode as a cbor byte array.
// TODO: Actually check if this is an ethereum call. This code will work for demo purposes, but is not correct.
if toAddr != nil {
if decodedParams, err := cbg.ReadByteArray(bytes.NewReader(msg.Params), uint64(len(msg.Params))); err == nil {
input = decodedParams
}
}

tx := types.EthTx{
Expand All @@ -638,7 +664,7 @@ func (a *ethAPI) ethTxFromFilecoinMessageLookup(ctx context.Context, msgLookup *
V: types.EthBytes{},
R: types.EthBytes{},
S: types.EthBytes{},
Input: msg.Params,
Input: input,
}
return tx, nil
}
Expand Down
29 changes: 9 additions & 20 deletions venus-shared/types/eth.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import (
"strings"

builtintypes "github.com/filecoin-project/go-state-types/builtin"
init8 "github.com/filecoin-project/go-state-types/builtin/v8/init"
"github.com/filecoin-project/go-state-types/builtin/v10/eam"
"github.com/ipfs/go-cid"
"github.com/multiformats/go-multihash"
"github.com/multiformats/go-varint"
Expand Down Expand Up @@ -212,10 +212,14 @@ func NewEthTxReceipt(tx EthTx, lookup *MsgLookup, replay *InvocResult) (EthTxRec
Logs: []string{},
}

contractAddr, err := CheckContractCreation(lookup)
if err == nil {
receipt.To = nil
receipt.ContractAddress = contractAddr
if receipt.To == nil && lookup.Receipt.ExitCode.IsSuccess() {
// Create and Create2 return the same things.
var ret eam.CreateReturn
if err := ret.UnmarshalCBOR(bytes.NewReader(lookup.Receipt.Return)); err != nil {
return EthTxReceipt{}, fmt.Errorf("failed to parse contract creation result: %w", err)
}
addr := EthAddress(ret.EthAddress)
receipt.ContractAddress = &addr
}

if lookup.Receipt.ExitCode.IsSuccess() {
Expand All @@ -235,21 +239,6 @@ func NewEthTxReceipt(tx EthTx, lookup *MsgLookup, replay *InvocResult) (EthTxRec
return receipt, nil
}

func CheckContractCreation(lookup *MsgLookup) (*EthAddress, error) {
if lookup.Receipt.ExitCode.IsError() {
return nil, fmt.Errorf("message execution was not successful")
}
var result init8.ExecReturn
ret := bytes.NewReader(lookup.Receipt.Return)
if err := result.UnmarshalCBOR(ret); err == nil {
contractAddr, err := EthAddressFromFilecoinIDAddress(result.IDAddress)
if err == nil {
return &contractAddr, nil
}
}
return nil, fmt.Errorf("not a contract creation tx")
}

const (
ETH_ADDRESS_LENGTH = 20 // nolint
ETH_HASH_LENGTH = 32 // nolint
Expand Down

0 comments on commit a10fd3b

Please sign in to comment.