feat: use f4 eth addresses wherever possible (#9532)
Co-authored-by: Raúl Kripalani <raul@protocol.ai>
This commit is contained in:
parent
aa0e6c17b9
commit
56b238980b
@ -81,7 +81,7 @@ func NewEthTxArgsFromMessage(msg *types.Message) (EthTxArgs, error) {
|
||||
}
|
||||
}
|
||||
if isCreate {
|
||||
addr, err := EthAddressFromFilecoinIDAddress(msg.To)
|
||||
addr, err := EthAddressFromFilecoinAddress(msg.To)
|
||||
if err != nil {
|
||||
return EthTxArgs{}, nil
|
||||
}
|
||||
|
@ -13,6 +13,7 @@ import (
|
||||
"github.com/filecoin-project/go-state-types/builtin"
|
||||
"github.com/ipfs/go-cid"
|
||||
"github.com/multiformats/go-multihash"
|
||||
"github.com/multiformats/go-varint"
|
||||
"golang.org/x/xerrors"
|
||||
|
||||
"github.com/filecoin-project/go-address"
|
||||
@ -292,15 +293,41 @@ func (ea EthAddress) ToFilecoinAddress() (address.Address, error) {
|
||||
return addr, nil
|
||||
}
|
||||
|
||||
func EthAddressFromFilecoinIDAddress(addr address.Address) (EthAddress, error) {
|
||||
id, err := address.IDFromAddress(addr)
|
||||
if err != nil {
|
||||
return EthAddress{}, err
|
||||
func TryEthAddressFromFilecoinAddress(addr address.Address, allowId bool) (EthAddress, bool, error) {
|
||||
switch addr.Protocol() {
|
||||
case address.ID:
|
||||
if !allowId {
|
||||
return EthAddress{}, false, nil
|
||||
}
|
||||
id, err := address.IDFromAddress(addr)
|
||||
if err != nil {
|
||||
return EthAddress{}, false, err
|
||||
}
|
||||
var ethaddr EthAddress
|
||||
ethaddr[0] = 0xff
|
||||
binary.BigEndian.PutUint64(ethaddr[12:], id)
|
||||
return ethaddr, true, nil
|
||||
case address.Delegated:
|
||||
payload := addr.Payload()
|
||||
namespace, n, err := varint.FromUvarint(payload)
|
||||
if err != nil {
|
||||
return EthAddress{}, false, xerrors.Errorf("invalid delegated address namespace in: %s", addr)
|
||||
}
|
||||
payload = payload[n:]
|
||||
if namespace == builtin.EthereumAddressManagerActorID {
|
||||
addr, err := EthAddressFromBytes(payload)
|
||||
return addr, err == nil, err
|
||||
}
|
||||
}
|
||||
var ethaddr EthAddress
|
||||
ethaddr[0] = 0xff
|
||||
binary.BigEndian.PutUint64(ethaddr[12:], id)
|
||||
return ethaddr, nil
|
||||
return EthAddress{}, false, nil
|
||||
}
|
||||
|
||||
func EthAddressFromFilecoinAddress(addr address.Address) (EthAddress, error) {
|
||||
ethAddr, ok, err := TryEthAddressFromFilecoinAddress(addr, true)
|
||||
if !ok && err == nil {
|
||||
err = xerrors.Errorf("failed to convert filecoin address %s to an equivalent eth address", addr)
|
||||
}
|
||||
return ethAddr, err
|
||||
}
|
||||
|
||||
func EthAddressFromHex(s string) (EthAddress, error) {
|
||||
|
@ -119,7 +119,7 @@ func TestParseEthAddr(t *testing.T) {
|
||||
addr, err := address.NewIDAddress(id)
|
||||
require.Nil(t, err)
|
||||
|
||||
eaddr, err := EthAddressFromFilecoinIDAddress(addr)
|
||||
eaddr, err := EthAddressFromFilecoinAddress(addr)
|
||||
require.Nil(t, err)
|
||||
|
||||
faddr, err := eaddr.ToFilecoinAddress()
|
||||
|
@ -588,6 +588,50 @@ func (a *EthModule) ethBlockFromFilecoinTipSet(ctx context.Context, ts *types.Ti
|
||||
return block, nil
|
||||
}
|
||||
|
||||
// lookupEthAddress makes its best effort at finding the Ethereum address for a
|
||||
// Filecoin address. It does the following:
|
||||
//
|
||||
// 1. If the supplied address is an f410 address, we return its payload as the EthAddress.
|
||||
// 2. Otherwise (f0, f1, f2, f3), we look up the actor on the state tree. If it has a predictable address, we return it if it's f410 address.
|
||||
// 3. Otherwise, we fall back to returning a masked ID Ethereum address. If the supplied address is an f0 address, we
|
||||
// use that ID to form the masked ID address.
|
||||
// 4. Otherwise, we fetch the actor's ID from the state tree and form the masked ID with it.
|
||||
func (a *EthModule) lookupEthAddress(ctx context.Context, addr address.Address) (api.EthAddress, error) {
|
||||
// Attempt to convert directly.
|
||||
if ethAddr, ok, err := api.TryEthAddressFromFilecoinAddress(addr, false); err != nil {
|
||||
return api.EthAddress{}, err
|
||||
} else if ok {
|
||||
return ethAddr, nil
|
||||
}
|
||||
|
||||
// Lookup on the target actor.
|
||||
actor, err := a.StateAPI.StateGetActor(ctx, addr, types.EmptyTSK)
|
||||
if err != nil {
|
||||
return api.EthAddress{}, err
|
||||
}
|
||||
if actor.Address != nil {
|
||||
if ethAddr, ok, err := api.TryEthAddressFromFilecoinAddress(*actor.Address, false); err != nil {
|
||||
return api.EthAddress{}, err
|
||||
} else if ok {
|
||||
return ethAddr, nil
|
||||
}
|
||||
}
|
||||
|
||||
// Check if we already have an ID addr, and use it if possible.
|
||||
if ethAddr, ok, err := api.TryEthAddressFromFilecoinAddress(addr, true); err != nil {
|
||||
return api.EthAddress{}, err
|
||||
} else if ok {
|
||||
return ethAddr, nil
|
||||
}
|
||||
|
||||
// Otherwise, resolve the ID addr.
|
||||
idAddr, err := a.StateAPI.StateLookupID(ctx, addr, types.EmptyTSK)
|
||||
if err != nil {
|
||||
return api.EthAddress{}, err
|
||||
}
|
||||
return api.EthAddressFromFilecoinAddress(idAddr)
|
||||
}
|
||||
|
||||
func (a *EthModule) ethTxFromFilecoinMessageLookup(ctx context.Context, msgLookup *api.MsgLookup) (api.EthTx, error) {
|
||||
if msgLookup == nil {
|
||||
return api.EthTx{}, fmt.Errorf("msg does not exist")
|
||||
@ -613,22 +657,12 @@ func (a *EthModule) ethTxFromFilecoinMessageLookup(ctx context.Context, msgLooku
|
||||
return api.EthTx{}, err
|
||||
}
|
||||
|
||||
fromFilIdAddr, err := a.StateAPI.StateLookupID(ctx, msg.From, types.EmptyTSK)
|
||||
fromEthAddr, err := a.lookupEthAddress(ctx, msg.From)
|
||||
if err != nil {
|
||||
return api.EthTx{}, err
|
||||
}
|
||||
|
||||
fromEthAddr, err := api.EthAddressFromFilecoinIDAddress(fromFilIdAddr)
|
||||
if err != nil {
|
||||
return api.EthTx{}, err
|
||||
}
|
||||
|
||||
toFilAddr, err := a.StateAPI.StateLookupID(ctx, msg.To, types.EmptyTSK)
|
||||
if err != nil {
|
||||
return api.EthTx{}, err
|
||||
}
|
||||
|
||||
toEthAddr, err := api.EthAddressFromFilecoinIDAddress(toFilAddr)
|
||||
toEthAddr, err := a.lookupEthAddress(ctx, msg.To)
|
||||
if err != nil {
|
||||
return api.EthTx{}, err
|
||||
}
|
||||
@ -636,7 +670,8 @@ func (a *EthModule) ethTxFromFilecoinMessageLookup(ctx context.Context, msgLooku
|
||||
toAddr := &toEthAddr
|
||||
input := msg.Params
|
||||
// Check to see if we need to decode as contract deployment.
|
||||
if toFilAddr == builtintypes.EthereumAddressManagerActorAddr {
|
||||
// We don't need to resolve the to address, because there's only one form (an ID).
|
||||
if msg.To == builtintypes.EthereumAddressManagerActorAddr {
|
||||
switch msg.Method {
|
||||
case builtintypes.MethodsEAM.Create:
|
||||
toAddr = nil
|
||||
|
Loading…
Reference in New Issue
Block a user