Skip to content

Commit

Permalink
Merge pull request #4875 from filecoin-project/frrist/fix-init-pred
Browse files Browse the repository at this point in the history
Fix init actor address map diffing
  • Loading branch information
magik6k authored Nov 16, 2020
2 parents 49d3bb9 + d25e5d1 commit a152d98
Show file tree
Hide file tree
Showing 5 changed files with 164 additions and 166 deletions.
152 changes: 152 additions & 0 deletions chain/actors/builtin/init/diff.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,152 @@
package init

import (
"bytes"

"github.com/filecoin-project/go-address"
"github.com/filecoin-project/go-state-types/abi"
typegen "github.com/whyrusleeping/cbor-gen"

"github.com/filecoin-project/lotus/chain/actors/adt"
)

func DiffAddressMap(pre, cur State) (*AddressMapChanges, error) {
prem, err := pre.addressMap()
if err != nil {
return nil, err
}

curm, err := cur.addressMap()
if err != nil {
return nil, err
}

preRoot, err := prem.Root()
if err != nil {
return nil, err
}

curRoot, err := curm.Root()
if err != nil {
return nil, err
}

results := new(AddressMapChanges)
// no change.
if curRoot.Equals(preRoot) {
return results, nil
}

err = adt.DiffAdtMap(prem, curm, &addressMapDiffer{results, pre, cur})
if err != nil {
return nil, err
}

return results, nil
}

type addressMapDiffer struct {
Results *AddressMapChanges
pre, adter State
}

type AddressMapChanges struct {
Added []AddressPair
Modified []AddressChange
Removed []AddressPair
}

func (i *addressMapDiffer) AsKey(key string) (abi.Keyer, error) {
addr, err := address.NewFromBytes([]byte(key))
if err != nil {
return nil, err
}
return abi.AddrKey(addr), nil
}

func (i *addressMapDiffer) Add(key string, val *typegen.Deferred) error {
pkAddr, err := address.NewFromBytes([]byte(key))
if err != nil {
return err
}
id := new(typegen.CborInt)
if err := id.UnmarshalCBOR(bytes.NewReader(val.Raw)); err != nil {
return err
}
idAddr, err := address.NewIDAddress(uint64(*id))
if err != nil {
return err
}
i.Results.Added = append(i.Results.Added, AddressPair{
ID: idAddr,
PK: pkAddr,
})
return nil
}

func (i *addressMapDiffer) Modify(key string, from, to *typegen.Deferred) error {
pkAddr, err := address.NewFromBytes([]byte(key))
if err != nil {
return err
}

fromID := new(typegen.CborInt)
if err := fromID.UnmarshalCBOR(bytes.NewReader(from.Raw)); err != nil {
return err
}
fromIDAddr, err := address.NewIDAddress(uint64(*fromID))
if err != nil {
return err
}

toID := new(typegen.CborInt)
if err := toID.UnmarshalCBOR(bytes.NewReader(to.Raw)); err != nil {
return err
}
toIDAddr, err := address.NewIDAddress(uint64(*toID))
if err != nil {
return err
}

i.Results.Modified = append(i.Results.Modified, AddressChange{
From: AddressPair{
ID: fromIDAddr,
PK: pkAddr,
},
To: AddressPair{
ID: toIDAddr,
PK: pkAddr,
},
})
return nil
}

func (i *addressMapDiffer) Remove(key string, val *typegen.Deferred) error {
pkAddr, err := address.NewFromBytes([]byte(key))
if err != nil {
return err
}
id := new(typegen.CborInt)
if err := id.UnmarshalCBOR(bytes.NewReader(val.Raw)); err != nil {
return err
}
idAddr, err := address.NewIDAddress(uint64(*id))
if err != nil {
return err
}
i.Results.Removed = append(i.Results.Removed, AddressPair{
ID: idAddr,
PK: pkAddr,
})
return nil
}

type AddressChange struct {
From AddressPair
To AddressPair
}

type AddressPair struct {
ID address.Address
PK address.Address
}
2 changes: 2 additions & 0 deletions chain/actors/builtin/init/init.go
Original file line number Diff line number Diff line change
Expand Up @@ -57,4 +57,6 @@ type State interface {

// Sets the network's name. This should only be used on upgrade/fork.
SetNetworkName(name string) error

addressMap() (adt.Map, error)
}
4 changes: 4 additions & 0 deletions chain/actors/builtin/init/v0.go
Original file line number Diff line number Diff line change
Expand Up @@ -79,3 +79,7 @@ func (s *state0) Remove(addrs ...address.Address) (err error) {
s.State.AddressMap = amr
return nil
}

func (s *state0) addressMap() (adt.Map, error) {
return adt0.AsMap(s.store, s.AddressMap)
}
4 changes: 4 additions & 0 deletions chain/actors/builtin/init/v2.go
Original file line number Diff line number Diff line change
Expand Up @@ -79,3 +79,7 @@ func (s *state2) Remove(addrs ...address.Address) (err error) {
s.State.AddressMap = amr
return nil
}

func (s *state2) addressMap() (adt.Map, error) {
return adt2.AsMap(s.store, s.AddressMap)
}
168 changes: 2 additions & 166 deletions chain/events/state/predicates.go
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
package state

import (
"bytes"
"context"

"github.com/filecoin-project/lotus/chain/actors/builtin/miner"
Expand All @@ -10,7 +9,6 @@ import (
"github.com/filecoin-project/go-state-types/abi"
"github.com/filecoin-project/go-state-types/big"
cbor "github.com/ipfs/go-ipld-cbor"
typegen "github.com/whyrusleeping/cbor-gen"

"github.com/filecoin-project/lotus/api/apibstore"
"github.com/filecoin-project/lotus/chain/actors/adt"
Expand Down Expand Up @@ -419,179 +417,17 @@ type AddressPair struct {
PK address.Address
}

type InitActorAddressChanges struct {
Added []AddressPair
Modified []AddressChange
Removed []AddressPair
}

type AddressChange struct {
From AddressPair
To AddressPair
}

type DiffInitActorStateFunc func(ctx context.Context, oldState init_.State, newState init_.State) (changed bool, user UserData, err error)

func (i *InitActorAddressChanges) AsKey(key string) (abi.Keyer, error) {
addr, err := address.NewFromBytes([]byte(key))
if err != nil {
return nil, err
}
return abi.AddrKey(addr), nil
}

func (i *InitActorAddressChanges) Add(key string, val *typegen.Deferred) error {
pkAddr, err := address.NewFromBytes([]byte(key))
if err != nil {
return err
}
id := new(typegen.CborInt)
if err := id.UnmarshalCBOR(bytes.NewReader(val.Raw)); err != nil {
return err
}
idAddr, err := address.NewIDAddress(uint64(*id))
if err != nil {
return err
}
i.Added = append(i.Added, AddressPair{
ID: idAddr,
PK: pkAddr,
})
return nil
}

func (i *InitActorAddressChanges) Modify(key string, from, to *typegen.Deferred) error {
pkAddr, err := address.NewFromBytes([]byte(key))
if err != nil {
return err
}

fromID := new(typegen.CborInt)
if err := fromID.UnmarshalCBOR(bytes.NewReader(from.Raw)); err != nil {
return err
}
fromIDAddr, err := address.NewIDAddress(uint64(*fromID))
if err != nil {
return err
}

toID := new(typegen.CborInt)
if err := toID.UnmarshalCBOR(bytes.NewReader(to.Raw)); err != nil {
return err
}
toIDAddr, err := address.NewIDAddress(uint64(*toID))
if err != nil {
return err
}

i.Modified = append(i.Modified, AddressChange{
From: AddressPair{
ID: fromIDAddr,
PK: pkAddr,
},
To: AddressPair{
ID: toIDAddr,
PK: pkAddr,
},
})
return nil
}

func (i *InitActorAddressChanges) Remove(key string, val *typegen.Deferred) error {
pkAddr, err := address.NewFromBytes([]byte(key))
if err != nil {
return err
}
id := new(typegen.CborInt)
if err := id.UnmarshalCBOR(bytes.NewReader(val.Raw)); err != nil {
return err
}
idAddr, err := address.NewIDAddress(uint64(*id))
if err != nil {
return err
}
i.Removed = append(i.Removed, AddressPair{
ID: idAddr,
PK: pkAddr,
})
return nil
}

func (sp *StatePredicates) OnAddressMapChange() DiffInitActorStateFunc {
return func(ctx context.Context, oldState, newState init_.State) (changed bool, user UserData, err error) {
addressChanges := &InitActorAddressChanges{
Added: []AddressPair{},
Modified: []AddressChange{},
Removed: []AddressPair{},
}

err = oldState.ForEachActor(func(oldId abi.ActorID, oldAddress address.Address) error {
oldIdAddress, err := address.NewIDAddress(uint64(oldId))
if err != nil {
return err
}

newIdAddress, found, err := newState.ResolveAddress(oldAddress)
if err != nil {
return err
}

if !found {
addressChanges.Removed = append(addressChanges.Removed, AddressPair{
ID: oldIdAddress,
PK: oldAddress,
})
}

if oldIdAddress != newIdAddress {
addressChanges.Modified = append(addressChanges.Modified, AddressChange{
From: AddressPair{
ID: oldIdAddress,
PK: oldAddress,
},
To: AddressPair{
ID: newIdAddress,
PK: oldAddress,
},
})
}

return nil
})

addressChanges, err := init_.DiffAddressMap(oldState, newState)
if err != nil {
return false, nil, err
}

err = newState.ForEachActor(func(newId abi.ActorID, newAddress address.Address) error {
newIdAddress, err := address.NewIDAddress(uint64(newId))
if err != nil {
return err
}

_, found, err := newState.ResolveAddress(newAddress)
if err != nil {
return err
}

if !found {
addressChanges.Added = append(addressChanges.Added, AddressPair{
ID: newIdAddress,
PK: newAddress,
})
}

return nil
})

if err != nil {
return false, nil, err
}

if len(addressChanges.Added)+len(addressChanges.Removed)+len(addressChanges.Modified) == 0 {
if len(addressChanges.Added)+len(addressChanges.Modified)+len(addressChanges.Removed) == 0 {
return false, nil, nil
}

return true, addressChanges, nil
}
}

0 comments on commit a152d98

Please sign in to comment.