fix: state: rename Actor.Address and only use it for f4 addresses (#12155)

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
This commit is contained in:
Steven Allen 2024-06-27 00:48:28 +00:00 committed by Aarsh Shah
parent b2ba4aaa4b
commit 5ac64aaad8
21 changed files with 123 additions and 116 deletions

View File

@ -15501,7 +15501,7 @@
},
"Nonce": 42,
"Balance": "0",
"Address": "f01234"
"DelegatedAddress": "f01234"
}
},
"GasCharges": [
@ -15541,7 +15541,7 @@
},
"Nonce": 42,
"Balance": "0",
"Address": "f01234"
"DelegatedAddress": "f01234"
}
},
"GasCharges": [
@ -15611,10 +15611,6 @@
"State": {
"additionalProperties": false,
"properties": {
"Address": {
"additionalProperties": false,
"type": "object"
},
"Balance": {
"additionalProperties": false,
"type": "object"
@ -15623,6 +15619,10 @@
"title": "Content Identifier",
"type": "string"
},
"DelegatedAddress": {
"additionalProperties": false,
"type": "object"
},
"Head": {
"title": "Content Identifier",
"type": "string"
@ -15892,7 +15892,7 @@
},
"Nonce": 42,
"Balance": "0",
"Address": "f01234"
"DelegatedAddress": "f01234"
}
}
],
@ -15900,10 +15900,6 @@
".*": {
"additionalProperties": false,
"properties": {
"Address": {
"additionalProperties": false,
"type": "object"
},
"Balance": {
"additionalProperties": false,
"type": "object"
@ -15912,6 +15908,10 @@
"title": "Content Identifier",
"type": "string"
},
"DelegatedAddress": {
"additionalProperties": false,
"type": "object"
},
"Head": {
"title": "Content Identifier",
"type": "string"
@ -16196,7 +16196,7 @@
},
"Nonce": 42,
"Balance": "0",
"Address": "f01234"
"DelegatedAddress": "f01234"
}
},
"GasCharges": [
@ -16236,7 +16236,7 @@
},
"Nonce": 42,
"Balance": "0",
"Address": "f01234"
"DelegatedAddress": "f01234"
}
},
"GasCharges": [
@ -16316,10 +16316,6 @@
"State": {
"additionalProperties": false,
"properties": {
"Address": {
"additionalProperties": false,
"type": "object"
},
"Balance": {
"additionalProperties": false,
"type": "object"
@ -16328,6 +16324,10 @@
"title": "Content Identifier",
"type": "string"
},
"DelegatedAddress": {
"additionalProperties": false,
"type": "object"
},
"Head": {
"title": "Content Identifier",
"type": "string"
@ -17001,15 +17001,11 @@
},
"Nonce": 42,
"Balance": "0",
"Address": "f01234"
"DelegatedAddress": "f01234"
}
],
"additionalProperties": false,
"properties": {
"Address": {
"additionalProperties": false,
"type": "object"
},
"Balance": {
"additionalProperties": false,
"type": "object"
@ -17018,6 +17014,10 @@
"title": "Content Identifier",
"type": "string"
},
"DelegatedAddress": {
"additionalProperties": false,
"type": "object"
},
"Head": {
"title": "Content Identifier",
"type": "string"
@ -21372,7 +21372,7 @@
},
"Nonce": 42,
"Balance": "0",
"Address": "f01234"
"DelegatedAddress": "f01234"
}
},
"GasCharges": [
@ -21412,7 +21412,7 @@
},
"Nonce": 42,
"Balance": "0",
"Address": "f01234"
"DelegatedAddress": "f01234"
}
},
"GasCharges": [
@ -21482,10 +21482,6 @@
"State": {
"additionalProperties": false,
"properties": {
"Address": {
"additionalProperties": false,
"type": "object"
},
"Balance": {
"additionalProperties": false,
"type": "object"
@ -21494,6 +21490,10 @@
"title": "Content Identifier",
"type": "string"
},
"DelegatedAddress": {
"additionalProperties": false,
"type": "object"
},
"Head": {
"title": "Content Identifier",
"type": "string"

View File

@ -6830,7 +6830,7 @@
},
"Nonce": 42,
"Balance": "0",
"Address": "f01234"
"DelegatedAddress": "f01234"
}
},
"GasCharges": [
@ -6870,7 +6870,7 @@
},
"Nonce": 42,
"Balance": "0",
"Address": "f01234"
"DelegatedAddress": "f01234"
}
},
"GasCharges": [
@ -6940,10 +6940,6 @@
"State": {
"additionalProperties": false,
"properties": {
"Address": {
"additionalProperties": false,
"type": "object"
},
"Balance": {
"additionalProperties": false,
"type": "object"
@ -6952,6 +6948,10 @@
"title": "Content Identifier",
"type": "string"
},
"DelegatedAddress": {
"additionalProperties": false,
"type": "object"
},
"Head": {
"title": "Content Identifier",
"type": "string"
@ -7418,15 +7418,11 @@
},
"Nonce": 42,
"Balance": "0",
"Address": "f01234"
"DelegatedAddress": "f01234"
}
],
"additionalProperties": false,
"properties": {
"Address": {
"additionalProperties": false,
"type": "object"
},
"Balance": {
"additionalProperties": false,
"type": "object"
@ -7435,6 +7431,10 @@
"title": "Content Identifier",
"type": "string"
},
"DelegatedAddress": {
"additionalProperties": false,
"type": "object"
},
"Head": {
"title": "Content Identifier",
"type": "string"
@ -9316,7 +9316,7 @@
},
"Nonce": 42,
"Balance": "0",
"Address": "f01234"
"DelegatedAddress": "f01234"
}
},
"GasCharges": [
@ -9356,7 +9356,7 @@
},
"Nonce": 42,
"Balance": "0",
"Address": "f01234"
"DelegatedAddress": "f01234"
}
},
"GasCharges": [
@ -9426,10 +9426,6 @@
"State": {
"additionalProperties": false,
"properties": {
"Address": {
"additionalProperties": false,
"type": "object"
},
"Balance": {
"additionalProperties": false,
"type": "object"
@ -9438,6 +9434,10 @@
"title": "Content Identifier",
"type": "string"
},
"DelegatedAddress": {
"additionalProperties": false,
"type": "object"
},
"Head": {
"title": "Content Identifier",
"type": "string"

View File

@ -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
}

View File

@ -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 {
@ -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 {
@ -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 {
@ -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 {

View File

@ -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

View File

@ -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)
}
@ -60,12 +59,16 @@ func MakeEthNullAddressActor(av actorstypes.Version, addr address.Address) (*typ
return nil, xerrors.Errorf("failed to get EthAccount actor code ID for actors version %d", av)
}
if addr.Protocol() != address.Delegated {
return nil, xerrors.Errorf("eth accounts must have f4 addresses, %s is not an f4 address", addr)
}
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

View File

@ -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

View File

@ -1232,8 +1232,8 @@ func (t *ActorV5) MarshalCBOR(w io.Writer) error {
return err
}
// t.Address (address.Address) (struct)
if err := t.Address.MarshalCBOR(cw); err != nil {
// t.DelegatedAddress (address.Address) (struct)
if err := t.DelegatedAddress.MarshalCBOR(cw); err != nil {
return err
}
return nil
@ -1309,7 +1309,7 @@ func (t *ActorV5) UnmarshalCBOR(r io.Reader) (err error) {
}
}
// t.Address (address.Address) (struct)
// t.DelegatedAddress (address.Address) (struct)
{
@ -1321,9 +1321,9 @@ func (t *ActorV5) UnmarshalCBOR(r io.Reader) (err error) {
if err := cr.UnreadByte(); err != nil {
return err
}
t.Address = new(address.Address)
if err := t.Address.UnmarshalCBOR(cr); err != nil {
return xerrors.Errorf("unmarshaling t.Address pointer: %w", err)
t.DelegatedAddress = new(address.Address)
if err := t.DelegatedAddress.UnmarshalCBOR(cr); err != nil {
return xerrors.Errorf("unmarshaling t.DelegatedAddress pointer: %w", err)
}
}

View File

@ -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:
@ -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 {
@ -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

View File

@ -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
}
}

View File

@ -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

View File

@ -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

View File

@ -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 {

View File

@ -3819,7 +3819,7 @@ Response:
},
"Nonce": 42,
"Balance": "0",
"Address": "f01234"
"DelegatedAddress": "f01234"
}
},
"GasCharges": [
@ -3859,7 +3859,7 @@ Response:
},
"Nonce": 42,
"Balance": "0",
"Address": "f01234"
"DelegatedAddress": "f01234"
}
},
"GasCharges": [
@ -3911,7 +3911,7 @@ Response:
},
"Nonce": 42,
"Balance": "0",
"Address": "f01234"
"DelegatedAddress": "f01234"
}
}
```
@ -4081,7 +4081,7 @@ Response:
},
"Nonce": 42,
"Balance": "0",
"Address": "f01234"
"DelegatedAddress": "f01234"
}
},
"GasCharges": [
@ -4121,7 +4121,7 @@ Response:
},
"Nonce": 42,
"Balance": "0",
"Address": "f01234"
"DelegatedAddress": "f01234"
}
},
"GasCharges": [
@ -4232,7 +4232,7 @@ Response:
},
"Nonce": 42,
"Balance": "0",
"Address": "f01234"
"DelegatedAddress": "f01234"
}
```
@ -5550,7 +5550,7 @@ Response:
},
"Nonce": 42,
"Balance": "0",
"Address": "f01234"
"DelegatedAddress": "f01234"
}
},
"GasCharges": [
@ -5590,7 +5590,7 @@ Response:
},
"Nonce": 42,
"Balance": "0",
"Address": "f01234"
"DelegatedAddress": "f01234"
}
},
"GasCharges": [

View File

@ -5423,7 +5423,7 @@ Response:
},
"Nonce": 42,
"Balance": "0",
"Address": "f01234"
"DelegatedAddress": "f01234"
}
},
"GasCharges": [
@ -5463,7 +5463,7 @@ Response:
},
"Nonce": 42,
"Balance": "0",
"Address": "f01234"
"DelegatedAddress": "f01234"
}
},
"GasCharges": [
@ -5515,7 +5515,7 @@ Response:
},
"Nonce": 42,
"Balance": "0",
"Address": "f01234"
"DelegatedAddress": "f01234"
}
}
```
@ -5685,7 +5685,7 @@ Response:
},
"Nonce": 42,
"Balance": "0",
"Address": "f01234"
"DelegatedAddress": "f01234"
}
},
"GasCharges": [
@ -5725,7 +5725,7 @@ Response:
},
"Nonce": 42,
"Balance": "0",
"Address": "f01234"
"DelegatedAddress": "f01234"
}
},
"GasCharges": [
@ -5887,7 +5887,7 @@ Response:
},
"Nonce": 42,
"Balance": "0",
"Address": "f01234"
"DelegatedAddress": "f01234"
}
```
@ -7306,7 +7306,7 @@ Response:
},
"Nonce": 42,
"Balance": "0",
"Address": "f01234"
"DelegatedAddress": "f01234"
}
},
"GasCharges": [
@ -7346,7 +7346,7 @@ Response:
},
"Nonce": 42,
"Balance": "0",
"Address": "f01234"
"DelegatedAddress": "f01234"
}
},
"GasCharges": [

View File

@ -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
}

View File

@ -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

View File

@ -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
}))

View File

@ -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
}
}

View File

@ -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
}

View File

@ -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,