Eth JSON-RPC API: Add EAM as contract creator (#9528)

This commit is contained in:
Melanie Riise 2022-10-20 15:10:50 -07:00 committed by vyzo
parent 98e534cc77
commit 7e7fff1dc5

View File

@ -7,14 +7,12 @@ import (
mathbig "math/big"
"golang.org/x/crypto/sha3"
"golang.org/x/xerrors"
"github.com/filecoin-project/go-address"
gocrypto "github.com/filecoin-project/go-crypto"
"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/v8/evm"
init8 "github.com/filecoin-project/go-state-types/builtin/v8/init"
"github.com/filecoin-project/go-state-types/builtin/v8/eam"
typescrypto "github.com/filecoin-project/go-state-types/crypto"
"github.com/filecoin-project/lotus/build"
@ -60,21 +58,16 @@ type EthTxArgs struct {
func NewEthTxArgsFromMessage(msg *types.Message) (EthTxArgs, error) {
var to *EthAddress
params := msg.Params
if msg.To == builtintypes.InitActorAddr {
if msg.To == builtintypes.EthereumAddressManagerActorAddr {
to = nil
var exec init8.ExecParams
var create2 eam.Create2Params
reader := bytes.NewReader(msg.Params)
if err := exec.UnmarshalCBOR(reader); err != nil {
if err := create2.UnmarshalCBOR(reader); err != nil {
return EthTxArgs{}, err
}
var evmParams evm.ConstructorParams
reader1 := bytes.NewReader(exec.ConstructorParams)
if err := evmParams.UnmarshalCBOR(reader1); err != nil {
return EthTxArgs{}, err
}
params = evmParams.Bytecode
params = create2.Initcode
} else {
addr, err := EthAddressFromFilecoinIDAddress(msg.To)
if err != nil {
@ -113,27 +106,19 @@ func (tx *EthTxArgs) ToSignedMessage() (*types.SignedMessage, error) {
// TODO unify with applyEvmMsg
// this is a contract creation
to = builtintypes.InitActorAddr
to = builtintypes.EthereumAddressManagerActorAddr
constructorParams, err := actors.SerializeParams(&evm.ConstructorParams{
Bytecode: tx.Input,
var salt [32]byte
binary.BigEndian.PutUint64(salt[:], uint64(tx.Nonce))
params2, err := actors.SerializeParams(&eam.Create2Params{
Initcode: tx.Input,
Salt: salt,
})
if err != nil {
return nil, fmt.Errorf("failed to serialize constructor params: %w", err)
}
evmActorCid, ok := actors.GetActorCodeID(actors.Version8, "evm")
if !ok {
return nil, fmt.Errorf("failed to lookup evm actor code CID")
}
params, err = actors.SerializeParams(&init8.ExecParams{
CodeCID: evmActorCid,
ConstructorParams: constructorParams,
})
if err != nil {
return nil, fmt.Errorf("failed to serialize init actor exec params: %w", err)
return nil, fmt.Errorf("failed to serialize Create2 params: %w", err)
}
params = params2
} else {
addr, err := tx.To.ToFilecoinAddress()
if err != nil {
@ -276,7 +261,7 @@ func (tx *EthTxArgs) Sender() (address.Address, error) {
func parseEip1559Tx(data []byte) (*EthTxArgs, error) {
if data[0] != 2 {
return nil, xerrors.Errorf("not an EIP-1559 transaction: first byte is not 2")
return nil, fmt.Errorf("not an EIP-1559 transaction: first byte is not 2")
}
d, err := DecodeRLP(data[1:])
@ -285,11 +270,11 @@ func parseEip1559Tx(data []byte) (*EthTxArgs, error) {
}
decoded, ok := d.([]interface{})
if !ok {
return nil, xerrors.Errorf("not an EIP-1559 transaction: decoded data is not a list")
return nil, fmt.Errorf("not an EIP-1559 transaction: decoded data is not a list")
}
if len(decoded) != 9 && len(decoded) != 12 {
return nil, xerrors.Errorf("not an EIP-1559 transaction: should have 6 or 9 elements in the list")
return nil, fmt.Errorf("not an EIP-1559 transaction: should have 6 or 9 elements in the list")
}
chainId, err := parseInt(decoded[0])
@ -375,15 +360,15 @@ func parseEip1559Tx(data []byte) (*EthTxArgs, error) {
func ParseEthTxArgs(data []byte) (*EthTxArgs, error) {
if data[0] > 0x7f {
// legacy transaction
return nil, xerrors.Errorf("legacy transaction is not supported")
return nil, fmt.Errorf("legacy transaction is not supported")
} else if data[0] == 1 {
// EIP-2930
return nil, xerrors.Errorf("EIP-2930 transaction is not supported")
return nil, fmt.Errorf("EIP-2930 transaction is not supported")
} else if data[0] == 2 {
// EIP-1559
return parseEip1559Tx(data)
}
return nil, xerrors.Errorf("unsupported transaction type")
return nil, fmt.Errorf("unsupported transaction type")
}
func padLeadingZeros(data []byte, length int) []byte {
@ -432,18 +417,18 @@ func formatBigInt(val big.Int) ([]byte, error) {
func parseInt(v interface{}) (int, error) {
data, ok := v.([]byte)
if !ok {
return 0, xerrors.Errorf("cannot parse interface to int: input is not a byte array")
return 0, fmt.Errorf("cannot parse interface to int: input is not a byte array")
}
if len(data) == 0 {
return 0, nil
}
if len(data) > 8 {
return 0, xerrors.Errorf("cannot parse interface to int: length is more than 8 bytes")
return 0, fmt.Errorf("cannot parse interface to int: length is more than 8 bytes")
}
var value int64
r := bytes.NewReader(append(make([]byte, 8-len(data)), data...))
if err := binary.Read(r, binary.BigEndian, &value); err != nil {
return 0, xerrors.Errorf("cannot parse interface to EthUint64: %w", err)
return 0, fmt.Errorf("cannot parse interface to EthUint64: %w", err)
}
return int(value), nil
}
@ -451,7 +436,7 @@ func parseInt(v interface{}) (int, error) {
func parseBigInt(v interface{}) (big.Int, error) {
data, ok := v.([]byte)
if !ok {
return big.Zero(), xerrors.Errorf("cannot parse interface to big.Int: input is not a byte array")
return big.Zero(), fmt.Errorf("cannot parse interface to big.Int: input is not a byte array")
}
if len(data) == 0 {
return big.Zero(), nil
@ -464,7 +449,7 @@ func parseBigInt(v interface{}) (big.Int, error) {
func parseBytes(v interface{}) ([]byte, error) {
val, ok := v.([]byte)
if !ok {
return nil, xerrors.Errorf("cannot parse interface into bytes: input is not a byte array")
return nil, fmt.Errorf("cannot parse interface into bytes: input is not a byte array")
}
return val, nil
}