github.com/filecoin-project/specs-actors/v4@v4.0.2/actors/builtin/init/init_actor_state.go (about) 1 package init 2 3 import ( 4 addr "github.com/filecoin-project/go-address" 5 "github.com/filecoin-project/go-state-types/abi" 6 cid "github.com/ipfs/go-cid" 7 cbg "github.com/whyrusleeping/cbor-gen" 8 xerrors "golang.org/x/xerrors" 9 10 "github.com/filecoin-project/specs-actors/v4/actors/builtin" 11 "github.com/filecoin-project/specs-actors/v4/actors/util/adt" 12 ) 13 14 type State struct { 15 AddressMap cid.Cid // HAMT[addr.Address]abi.ActorID 16 NextID abi.ActorID 17 NetworkName string 18 } 19 20 func ConstructState(store adt.Store, networkName string) (*State, error) { 21 emptyAddressMapCid, err := adt.StoreEmptyMap(store, builtin.DefaultHamtBitwidth) 22 if err != nil { 23 return nil, xerrors.Errorf("failed to create empty map: %w", err) 24 } 25 26 return &State{ 27 AddressMap: emptyAddressMapCid, 28 NextID: abi.ActorID(builtin.FirstNonSingletonActorId), 29 NetworkName: networkName, 30 }, nil 31 } 32 33 // ResolveAddress resolves an address to an ID-address, if possible. 34 // If the provided address is an ID address, it is returned as-is. 35 // This means that mapped ID-addresses (which should only appear as values, not keys) and 36 // singleton actor addresses (which are not in the map) pass through unchanged. 37 // 38 // Returns an ID-address and `true` if the address was already an ID-address or was resolved in the mapping. 39 // Returns an undefined address and `false` if the address was not an ID-address and not found in the mapping. 40 // Returns an error only if state was inconsistent. 41 func (s *State) ResolveAddress(store adt.Store, address addr.Address) (addr.Address, bool, error) { 42 // Short-circuit ID address resolution. 43 if address.Protocol() == addr.ID { 44 return address, true, nil 45 } 46 47 // Lookup address. 48 m, err := adt.AsMap(store, s.AddressMap, builtin.DefaultHamtBitwidth) 49 if err != nil { 50 return addr.Undef, false, xerrors.Errorf("failed to load address map: %w", err) 51 } 52 53 var actorID cbg.CborInt 54 if found, err := m.Get(abi.AddrKey(address), &actorID); err != nil { 55 return addr.Undef, false, xerrors.Errorf("failed to get from address map: %w", err) 56 } else if found { 57 // Reconstruct address from the ActorID. 58 idAddr, err := addr.NewIDAddress(uint64(actorID)) 59 return idAddr, true, err 60 } else { 61 return addr.Undef, false, nil 62 } 63 } 64 65 // Allocates a new ID address and stores a mapping of the argument address to it. 66 // Returns the newly-allocated address. 67 func (s *State) MapAddressToNewID(store adt.Store, address addr.Address) (addr.Address, error) { 68 actorID := cbg.CborInt(s.NextID) 69 s.NextID++ 70 71 m, err := adt.AsMap(store, s.AddressMap, builtin.DefaultHamtBitwidth) 72 if err != nil { 73 return addr.Undef, xerrors.Errorf("failed to load address map: %w", err) 74 } 75 err = m.Put(abi.AddrKey(address), &actorID) 76 if err != nil { 77 return addr.Undef, xerrors.Errorf("map address failed to store entry: %w", err) 78 } 79 amr, err := m.Root() 80 if err != nil { 81 return addr.Undef, xerrors.Errorf("failed to get address map root: %w", err) 82 } 83 s.AddressMap = amr 84 85 idAddr, err := addr.NewIDAddress(uint64(actorID)) 86 return idAddr, err 87 }