From 8ac65cde803d753ffc270c7da851f4478b67cbde Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Magiera?= Date: Fri, 15 Nov 2019 17:39:43 +0100 Subject: [PATCH] api.StateLookupID --- api/api_full.go | 1 + api/struct.go | 5 +++++ chain/state/statetree.go | 32 ++++++++++++++++---------------- cli/state.go | 33 +++++++++++++++++++++++++++++++++ node/impl/full/state.go | 9 +++++++++ 5 files changed, 64 insertions(+), 16 deletions(-) diff --git a/api/api_full.go b/api/api_full.go index dba59ad31..b50f0282a 100644 --- a/api/api_full.go +++ b/api/api_full.go @@ -110,6 +110,7 @@ type FullNode interface { StateMarketParticipants(context.Context, *types.TipSet) (map[string]actors.StorageParticipantBalance, error) StateMarketDeals(context.Context, *types.TipSet) (map[string]actors.OnChainDeal, error) StateMarketStorageDeal(context.Context, uint64, *types.TipSet) (*actors.OnChainDeal, error) + StateLookupID(context.Context, address.Address, *types.TipSet) (address.Address, error) MarketEnsureAvailable(context.Context, address.Address, types.BigInt) error // MarketFreeBalance diff --git a/api/struct.go b/api/struct.go index d94cc031f..c26ff9c36 100644 --- a/api/struct.go +++ b/api/struct.go @@ -105,6 +105,7 @@ type FullNodeStruct struct { StateMarketParticipants func(context.Context, *types.TipSet) (map[string]actors.StorageParticipantBalance, error) `perm:"read"` StateMarketDeals func(context.Context, *types.TipSet) (map[string]actors.OnChainDeal, error) `perm:"read"` StateMarketStorageDeal func(context.Context, uint64, *types.TipSet) (*actors.OnChainDeal, error) `perm:"read"` + StateLookupID func(ctx context.Context, addr address.Address, ts *types.TipSet) (address.Address, error) `perm:"read"` MarketEnsureAvailable func(context.Context, address.Address, types.BigInt) error `perm:"sign"` @@ -420,6 +421,10 @@ func (c *FullNodeStruct) StateMarketStorageDeal(ctx context.Context, dealid uint return c.Internal.StateMarketStorageDeal(ctx, dealid, ts) } +func (c *FullNodeStruct) StateLookupID(ctx context.Context, addr address.Address, ts *types.TipSet) (address.Address, error) { + return c.Internal.StateLookupID(ctx, addr, ts) +} + func (c *FullNodeStruct) MarketEnsureAvailable(ctx context.Context, addr address.Address, amt types.BigInt) error { return c.Internal.MarketEnsureAvailable(ctx, addr, amt) } diff --git a/chain/state/statetree.go b/chain/state/statetree.go index 55a812275..1237007a5 100644 --- a/chain/state/statetree.go +++ b/chain/state/statetree.go @@ -47,13 +47,11 @@ func LoadStateTree(cst *hamt.CborIpldStore, c cid.Cid) (*StateTree, error) { } func (st *StateTree) SetActor(addr address.Address, act *types.Actor) error { - if addr.Protocol() != address.ID { - iaddr, err := st.lookupID(addr) - if err != nil { - return xerrors.Errorf("ID lookup failed: %w", err) - } - addr = iaddr + iaddr, err := st.LookupID(addr) + if err != nil { + return xerrors.Errorf("ID lookup failed: %w", err) } + addr = iaddr cact, ok := st.actorcache[addr] if ok { @@ -67,7 +65,11 @@ func (st *StateTree) SetActor(addr address.Address, act *types.Actor) error { return st.root.Set(context.TODO(), string(addr.Bytes()), act) } -func (st *StateTree) lookupID(addr address.Address) (address.Address, error) { +func (st *StateTree) LookupID(addr address.Address) (address.Address, error) { + if addr.Protocol() == address.ID { + return addr, nil + } + act, err := st.GetActor(actors.InitAddress) if err != nil { return address.Undef, xerrors.Errorf("getting init actor: %w", err) @@ -86,16 +88,14 @@ func (st *StateTree) GetActor(addr address.Address) (*types.Actor, error) { return nil, fmt.Errorf("GetActor called on undefined address") } - if addr.Protocol() != address.ID { - iaddr, err := st.lookupID(addr) - if err != nil { - if xerrors.Is(err, hamt.ErrNotFound) { - return nil, xerrors.Errorf("resolution lookup failed (%s): %w", addr, types.ErrActorNotFound) - } - return nil, xerrors.Errorf("address resolution: %w", err) + iaddr, err := st.LookupID(addr) + if err != nil { + if xerrors.Is(err, hamt.ErrNotFound) { + return nil, xerrors.Errorf("resolution lookup failed (%s): %w", addr, types.ErrActorNotFound) } - addr = iaddr + return nil, xerrors.Errorf("address resolution: %w", err) } + addr = iaddr cact, ok := st.actorcache[addr] if ok { @@ -103,7 +103,7 @@ func (st *StateTree) GetActor(addr address.Address) (*types.Actor, error) { } var act types.Actor - err := st.root.Find(context.TODO(), string(addr.Bytes()), &act) + err = st.root.Find(context.TODO(), string(addr.Bytes()), &act) if err != nil { if err == hamt.ErrNotFound { return nil, types.ErrActorNotFound diff --git a/cli/state.go b/cli/state.go index 91a7f9fa1..24809f982 100644 --- a/cli/state.go +++ b/cli/state.go @@ -21,6 +21,7 @@ var stateCmd = &cli.Command{ stateListActorsCmd, stateListMinersCmd, stateGetActorCmd, + stateLookupIDCmd, }, } @@ -288,3 +289,35 @@ var stateGetActorCmd = &cli.Command{ return nil }, } + +var stateLookupIDCmd = &cli.Command{ + Name: "lookup", + Usage: "Find corresponding ID address", + Action: func(cctx *cli.Context) error { + api, closer, err := GetFullNodeAPI(cctx) + if err != nil { + return err + } + defer closer() + + ctx := ReqContext(cctx) + + if !cctx.Args().Present() { + return fmt.Errorf("must pass address of actor to get") + } + + addr, err := address.NewFromString(cctx.Args().First()) + if err != nil { + return err + } + + a, err := api.StateLookupID(ctx, addr, nil) + if err != nil { + return err + } + + fmt.Printf("%s\n", a) + + return nil + }, +} diff --git a/node/impl/full/state.go b/node/impl/full/state.go index 75e68f337..4d3d3cd1f 100644 --- a/node/impl/full/state.go +++ b/node/impl/full/state.go @@ -154,6 +154,15 @@ func (a *StateAPI) StateGetActor(ctx context.Context, actor address.Address, ts return state.GetActor(actor) } +func (a *StateAPI) StateLookupID(ctx context.Context, addr address.Address, ts *types.TipSet) (address.Address, error) { + state, err := a.stateForTs(ctx, ts) + if err != nil { + return address.Undef, err + } + + return state.LookupID(addr) +} + func (a *StateAPI) StateReadState(ctx context.Context, act *types.Actor, ts *types.TipSet) (*api.ActorState, error) { state, err := a.stateForTs(ctx, ts) if err != nil {