Skip to content

Commit

Permalink
fix: state: rename Actor.Address and only use it for f4 addresses
Browse files Browse the repository at this point in the history
Per the FIP [1], the top-level actor address field should only be used
for delegated addresses. Unfortunately, the FIP's design was changed [2]
but neither lotus genesis code nor the field name were updated to
reflect this. Fortunately, all the migration code (on mainnet, at
least), has correctly left this field unset/unchanged (except for actors
with f4 addresses).

[1]: https://github.com/filecoin-project/FIPs/blob/master/FIPS/fip-0048.md#new-lookup_delegated_address-syscall-and-state-changes
[2]: https://github.com/filecoin-project/FIPs/blob/master/FIPS/fip-0048.md#recording-other-addresses-in-the-actorstate-root
  • Loading branch information
Stebalien committed Jun 27, 2024
1 parent 653210b commit 4da459f
Show file tree
Hide file tree
Showing 17 changed files with 55 additions and 52 deletions.
4 changes: 2 additions & 2 deletions chain/consensus/common.go
Original file line number Diff line number Diff line change
Expand Up @@ -168,12 +168,12 @@ func IsValidForSending(nv network.Version, act *types.Actor) bool {

// Allow placeholder actors with a delegated address and nonce 0 to send a message.
// These will be converted to an EthAccount actor on first send.
if !builtin.IsPlaceholderActor(act.Code) || act.Nonce != 0 || act.Address == nil || act.Address.Protocol() != address.Delegated {
if !builtin.IsPlaceholderActor(act.Code) || act.Nonce != 0 || act.DelegatedAddress == nil || act.DelegatedAddress.Protocol() != address.Delegated {
return false
}

// Only allow such actors to send if their delegated address is in the EAM's namespace.
id, _, err := varint.FromUvarint(act.Address.Payload())
id, _, err := varint.FromUvarint(act.DelegatedAddress.Payload())
return err == nil && id == builtintypes.EthereumAddressManagerActorID
}

Expand Down
28 changes: 14 additions & 14 deletions chain/consensus/filcns/upgrades.go
Original file line number Diff line number Diff line change
Expand Up @@ -2115,11 +2115,11 @@ func buildUpgradeActorsV12MinerFix(oldBuggyMinerCID, newManifestCID cid.Cid) fun
}

return actorsOut.SetActor(a, &types.ActorV5{
Code: newCid,
Head: actor.Head,
Nonce: actor.Nonce,
Balance: actor.Balance,
Address: actor.Address,
Code: newCid,
Head: actor.Head,
Nonce: actor.Nonce,
Balance: actor.Balance,
DelegatedAddress: actor.DelegatedAddress,
})
})
if err != nil {
Expand Down Expand Up @@ -2153,8 +2153,8 @@ func buildUpgradeActorsV12MinerFix(oldBuggyMinerCID, newManifestCID cid.Cid) fun
return xerrors.Errorf("mismatched balance for actor %s: %d != %d", a, inActor.Balance, outActor.Balance)
}

if inActor.Address != outActor.Address && inActor.Address.String() != outActor.Address.String() {
return xerrors.Errorf("mismatched address for actor %s: %s != %s", a, inActor.Address, outActor.Address)
if inActor.DelegatedAddress != outActor.DelegatedAddress && inActor.DelegatedAddress.String() != outActor.DelegatedAddress.String() {
return xerrors.Errorf("mismatched address for actor %s: %s != %s", a, inActor.DelegatedAddress, outActor.DelegatedAddress)
}

if inActor.Head != outActor.Head && a != builtin.SystemActorAddr {
Expand Down Expand Up @@ -2413,11 +2413,11 @@ func upgradeActorsV13VerifregFix(oldBuggyVerifregCID, newManifestCID cid.Cid) fu
}

return actorsOut.SetActor(a, &types.ActorV5{
Code: newCid,
Head: actor.Head,
Nonce: actor.Nonce,
Balance: actor.Balance,
Address: actor.Address,
Code: newCid,
Head: actor.Head,
Nonce: actor.Nonce,
Balance: actor.Balance,
DelegatedAddress: actor.DelegatedAddress,
})
})
if err != nil {
Expand Down Expand Up @@ -2451,8 +2451,8 @@ func upgradeActorsV13VerifregFix(oldBuggyVerifregCID, newManifestCID cid.Cid) fu
return xerrors.Errorf("mismatched balance for actor %s: %d != %d", a, inActor.Balance, outActor.Balance)
}

if inActor.Address != outActor.Address && inActor.Address.String() != outActor.Address.String() {
return xerrors.Errorf("mismatched address for actor %s: %s != %s", a, inActor.Address, outActor.Address)
if inActor.DelegatedAddress != outActor.DelegatedAddress && inActor.DelegatedAddress.String() != outActor.DelegatedAddress.String() {
return xerrors.Errorf("mismatched address for actor %s: %s != %s", a, inActor.DelegatedAddress, outActor.DelegatedAddress)
}

if inActor.Head != outActor.Head && a != builtin.SystemActorAddr {
Expand Down
13 changes: 9 additions & 4 deletions chain/gen/genesis/genesis.go
Original file line number Diff line number Diff line change
Expand Up @@ -378,11 +378,16 @@ func MakeAccountActor(ctx context.Context, cst cbor.IpldStore, av actorstypes.Ve
return nil, xerrors.Errorf("failed to get account actor code ID for actors version %d", av)
}

var delegatedAddr *address.Address
if addr.Protocol() == address.Delegated {
delegatedAddr = &addr
}

act := &types.Actor{
Code: actcid,
Head: statecid,
Balance: bal,
Address: &addr,
Code: actcid,
Head: statecid,
Balance: bal,
DelegatedAddress: delegatedAddr,
}

return act, nil
Expand Down
11 changes: 5 additions & 6 deletions chain/gen/genesis/genesis_eth.go
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,6 @@ func SetupEAM(_ context.Context, nst *state.StateTree, nv network.Version) error
Code: codecid,
Head: vm.EmptyObjectCid,
Balance: big.Zero(),
Address: &builtin.EthereumAddressManagerActorAddr, // so that it can create ETH0
}
return nst.SetActor(builtin.EthereumAddressManagerActorAddr, header)
}
Expand All @@ -61,11 +60,11 @@ func MakeEthNullAddressActor(av actorstypes.Version, addr address.Address) (*typ
}

act := &types.Actor{
Code: actcid,
Head: vm.EmptyObjectCid,
Nonce: 0,
Balance: big.Zero(),
Address: &addr,
Code: actcid,
Head: vm.EmptyObjectCid,
Nonce: 0,
Balance: big.Zero(),
DelegatedAddress: &addr,
}

return act, nil
Expand Down
4 changes: 2 additions & 2 deletions chain/types/actor.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,8 @@ type ActorV5 struct {
Head cid.Cid
Nonce uint64
Balance BigInt
// Deterministic Address.
Address *address.Address
// The f4 address of the actor, if any.
DelegatedAddress *address.Address
}

type Actor = ActorV5
Expand Down
6 changes: 3 additions & 3 deletions chain/types/cbor_gen.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

5 changes: 2 additions & 3 deletions chain/vm/mkactor.go
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,7 @@ func TryCreateAccountActor(rt *Runtime, addr address.Address) (*types.Actor, add
func makeAccountActor(ver actorstypes.Version, addr address.Address) (*types.Actor, aerrors.ActorError) {
switch addr.Protocol() {
case address.BLS, address.SECP256K1:
return newAccountActor(ver, addr), nil
return newAccountActor(ver), nil
case address.ID:
return nil, aerrors.Newf(exitcode.SysErrInvalidReceiver, "no actor with given ID: %s", addr)
case address.Actor:
Expand All @@ -99,7 +99,7 @@ func makeAccountActor(ver actorstypes.Version, addr address.Address) (*types.Act
}
}

func newAccountActor(ver actorstypes.Version, addr address.Address) *types.Actor {
func newAccountActor(ver actorstypes.Version) *types.Actor {
// TODO: ActorsUpgrade use a global actor registry?
var code cid.Cid
switch ver {
Expand All @@ -124,7 +124,6 @@ func newAccountActor(ver actorstypes.Version, addr address.Address) *types.Actor
Code: code,
Balance: types.NewInt(0),
Head: EmptyObjectCid,
Address: &addr,
}

return nact
Expand Down
4 changes: 2 additions & 2 deletions chain/vm/vm.go
Original file line number Diff line number Diff line change
Expand Up @@ -59,9 +59,9 @@ func ResolveToDeterministicAddr(state types.StateTree, cst cbor.IpldStore, addr
}

if state.Version() >= types.StateTreeVersion5 {
if act.Address != nil {
if act.DelegatedAddress != nil {
// If there _is_ an f4 address, return it as "key" address
return *act.Address, nil
return *act.DelegatedAddress, nil
}
}

Expand Down
4 changes: 2 additions & 2 deletions cli/evm.go
Original file line number Diff line number Diff line change
Expand Up @@ -471,8 +471,8 @@ func ethAddrFromFilecoinAddress(ctx context.Context, addr address.Address, fnapi
if err != nil {
return ethtypes.EthAddress{}, addr, err
}
if fAct.Address != nil && (*fAct.Address).Protocol() == address.Delegated {
faddr = *fAct.Address
if fAct.DelegatedAddress != nil && (*fAct.DelegatedAddress).Protocol() == address.Delegated {
faddr = *fAct.DelegatedAddress
}
case address.Delegated:
faddr = addr
Expand Down
4 changes: 2 additions & 2 deletions cli/state.go
Original file line number Diff line number Diff line change
Expand Up @@ -633,8 +633,8 @@ var StateGetActorCmd = &cli.Command{
fmt.Printf("Nonce:\t\t%d\n", a.Nonce)
fmt.Printf("Code:\t\t%s (%s)\n", a.Code, strtype)
fmt.Printf("Head:\t\t%s\n", a.Head)
if a.Address != nil {
fmt.Printf("Delegated address:\t\t%s\n", a.Address)
if a.DelegatedAddress != nil {
fmt.Printf("Delegated address:\t\t%s\n", a.DelegatedAddress)
}

return nil
Expand Down
4 changes: 2 additions & 2 deletions cmd/lotus-shed/indexes.go
Original file line number Diff line number Diff line change
Expand Up @@ -146,11 +146,11 @@ var backfillEventsCmd = &cli.Command{
}

actor, err := api.StateGetActor(ctx, idAddr, ts.Key())
if err != nil || actor.Address == nil {
if err != nil || actor.DelegatedAddress == nil {
return idAddr, true
}

return *actor.Address, true
return *actor.DelegatedAddress, true
}

isIndexedValue := func(b uint8) bool {
Expand Down
4 changes: 2 additions & 2 deletions itests/eth_filter_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -1154,8 +1154,8 @@ func getEthAddress(ctx context.Context, t *testing.T, client *kit.TestFullNode,

actor, err := client.StateGetActor(ctx, addr, head.Key())
require.NoError(t, err)
require.NotNil(t, actor.Address)
ethContractAddr, err := ethtypes.EthAddressFromFilecoinAddress(*actor.Address)
require.NotNil(t, actor.DelegatedAddress)
ethContractAddr, err := ethtypes.EthAddressFromFilecoinAddress(*actor.DelegatedAddress)
require.NoError(t, err)
return ethContractAddr
}
Expand Down
2 changes: 1 addition & 1 deletion itests/fevm_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -215,7 +215,7 @@ func TestFEVMETH0(t *testing.T) {

eth0Addr, err := address.NewDelegatedAddress(builtintypes.EthereumAddressManagerActorID, make([]byte, 20))
require.NoError(t, err)
require.Equal(t, *act.Address, eth0Addr)
require.Equal(t, *act.DelegatedAddress, eth0Addr)
}

// TestFEVMDelegateCall deploys two contracts and makes a delegate call transaction
Expand Down
2 changes: 1 addition & 1 deletion itests/migration_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -596,7 +596,7 @@ func TestMigrationNV18(t *testing.T) {
// check all actor's Address fields
require.NoError(t, newStateTree.ForEach(func(address address.Address, actor *types.Actor) error {
if address != ethZeroAddrID {
require.Nil(t, actor.Address)
require.Nil(t, actor.DelegatedAddress)
}
return nil
}))
Expand Down
4 changes: 2 additions & 2 deletions node/impl/full/eth_trace.go
Original file line number Diff line number Diff line change
Expand Up @@ -103,8 +103,8 @@ func baseEnvironment(st *state.StateTree, from address.Address) (*environment, e
}

func traceToAddress(act *types.ActorTrace) ethtypes.EthAddress {
if act.State.Address != nil {
if addr, err := ethtypes.EthAddressFromFilecoinAddress(*act.State.Address); err == nil {
if act.State.DelegatedAddress != nil {
if addr, err := ethtypes.EthAddressFromFilecoinAddress(*act.State.DelegatedAddress); err == nil {
return addr
}
}
Expand Down
4 changes: 2 additions & 2 deletions node/impl/full/eth_utils.go
Original file line number Diff line number Diff line change
Expand Up @@ -419,9 +419,9 @@ func lookupEthAddress(addr address.Address, st *state.StateTree) (ethtypes.EthAd
} else if err != nil {
// Any other error -> fail.
return ethtypes.EthAddress{}, err
} else if actor.Address == nil {
} else if actor.DelegatedAddress == nil {
// No delegated address -> use masked ID address.
} else if ethAddr, err := ethtypes.EthAddressFromFilecoinAddress(*actor.Address); err == nil && !ethAddr.IsMaskedID() {
} else if ethAddr, err := ethtypes.EthAddressFromFilecoinAddress(*actor.DelegatedAddress); err == nil && !ethAddr.IsMaskedID() {
// Conversable into an eth address, use it.
return ethAddr, nil
}
Expand Down
4 changes: 2 additions & 2 deletions node/modules/actorevent.go
Original file line number Diff line number Diff line change
Expand Up @@ -138,11 +138,11 @@ func EventFilterManager(cfg config.EventsConfig) func(helpers.MetricsCtx, repo.L
}

actor, err := sm.LoadActor(ctx, idAddr, ts)
if err != nil || actor.Address == nil {
if err != nil || actor.DelegatedAddress == nil {
return idAddr, true
}

return *actor.Address, true
return *actor.DelegatedAddress, true
},

MaxFilterResults: cfg.MaxFilterResults,
Expand Down

0 comments on commit 4da459f

Please sign in to comment.