Skip to content

Commit

Permalink
cleanup ethtypes.{Try=>}EthAddressFromFilecoinAddress.
Browse files Browse the repository at this point in the history
  • Loading branch information
raulk committed Jan 12, 2023
1 parent b4b1241 commit 8e6bead
Show file tree
Hide file tree
Showing 2 changed files with 38 additions and 57 deletions.
72 changes: 30 additions & 42 deletions chain/types/ethtypes/eth_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import (
"encoding/binary"
"encoding/hex"
"encoding/json"
"errors"
"fmt"
mathbig "math/big"
"strconv"
Expand All @@ -30,6 +31,8 @@ var (
EthTopic4 = "topic4"
)

var ErrInvalidAddress = errors.New("invalid Filecoin Eth address")

type EthUint64 uint64

func (e EthUint64) MarshalJSON() ([]byte, error) {
Expand Down Expand Up @@ -249,16 +252,28 @@ func EthAddressFromPubKey(pubk []byte) ([]byte, error) {
}

func EthAddressFromFilecoinAddress(addr address.Address) (EthAddress, error) {
ethAddr, ok, err := TryEthAddressFromFilecoinAddress(addr, true)
if err != nil {
return EthAddress{}, xerrors.Errorf("failed to try converting filecoin to eth addr: %w", err)
}

if !ok {
return EthAddress{}, xerrors.Errorf("failed to convert filecoin address %s to an equivalent eth address", addr)
switch addr.Protocol() {
case address.ID:
id, err := address.IDFromAddress(addr)
if err != nil {
return EthAddress{}, err
}
var ethaddr EthAddress
ethaddr[0] = 0xff
binary.BigEndian.PutUint64(ethaddr[12:], id)
return ethaddr, nil
case address.Delegated:
payload := addr.Payload()
namespace, n, err := varint.FromUvarint(payload)
if err != nil {
return EthAddress{}, xerrors.Errorf("invalid delegated address namespace in: %s", addr)
}
payload = payload[n:]
if namespace == builtintypes.EthereumAddressManagerActorID {
return CastEthAddress(payload)
}
}

return ethAddr, nil
return EthAddress{}, ErrInvalidAddress
}

// ParseEthAddress parses an Ethereum address from a hex string.
Expand Down Expand Up @@ -303,9 +318,13 @@ func (ea *EthAddress) UnmarshalJSON(b []byte) error {
return nil
}

func (ea EthAddress) ToFilecoinAddress() (address.Address, error) {
func (ea EthAddress) IsMaskedID() bool {
idmask := [12]byte{0xff}
if bytes.Equal(ea[:12], idmask[:]) {
return bytes.Equal(ea[:12], idmask[:])
}

func (ea EthAddress) ToFilecoinAddress() (address.Address, error) {
if ea.IsMaskedID() {
// This is a masked ID address.
id := binary.BigEndian.Uint64(ea[12:])
return address.NewIDAddress(id)
Expand All @@ -321,37 +340,6 @@ func (ea EthAddress) ToFilecoinAddress() (address.Address, error) {
return addr, nil
}

// This API assumes that if an ID address is passed in, it doesn't have an equivalent
// delegated address
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 == builtintypes.EthereumAddressManagerActorID {
addr, err := CastEthAddress(payload)
return addr, err == nil, err
}
}
return EthAddress{}, false, nil
}

type EthHash [EthHashLength]byte

func (h EthHash) MarshalJSON() ([]byte, error) {
Expand Down
23 changes: 8 additions & 15 deletions node/impl/full/eth.go
Original file line number Diff line number Diff line change
Expand Up @@ -1431,30 +1431,23 @@ func newEthBlockFromFilecoinTipSet(ctx context.Context, ts *types.TipSet, fullTx
// 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 lookupEthAddress(ctx context.Context, addr address.Address, sa StateAPI) (ethtypes.EthAddress, error) {
// Attempt to convert directly.
if ethAddr, ok, err := ethtypes.TryEthAddressFromFilecoinAddress(addr, false); err != nil {
return ethtypes.EthAddress{}, err
} else if ok {
// Attempt to convert directly, if it's an f4 address.
ethAddr, err := ethtypes.EthAddressFromFilecoinAddress(addr)
if err == nil && !ethAddr.IsMaskedID() {
return ethAddr, nil
}

// Lookup on the target actor.
actor, err := sa.StateGetActor(ctx, addr, types.EmptyTSK)
if err != nil {
// Lookup on the target actor and try to get an f410 address.
if actor, err := sa.StateGetActor(ctx, addr, types.EmptyTSK); err != nil {
return ethtypes.EthAddress{}, err
}
if actor.Address != nil {
if ethAddr, ok, err := ethtypes.TryEthAddressFromFilecoinAddress(*actor.Address, false); err != nil {
return ethtypes.EthAddress{}, err
} else if ok {
} else if actor.Address != nil {
if ethAddr, err := ethtypes.EthAddressFromFilecoinAddress(*actor.Address); err == nil && !ethAddr.IsMaskedID() {
return ethAddr, nil
}
}

// Check if we already have an ID addr, and use it if possible.
if ethAddr, ok, err := ethtypes.TryEthAddressFromFilecoinAddress(addr, true); err != nil {
return ethtypes.EthAddress{}, err
} else if ok {
if err == nil && ethAddr.IsMaskedID() {
return ethAddr, nil
}

Expand Down

0 comments on commit 8e6bead

Please sign in to comment.