Skip to content

Commit

Permalink
Implemented StateLoockupRobustAddress
Browse files Browse the repository at this point in the history
  • Loading branch information
geoff-vball committed Apr 14, 2022
1 parent aca9496 commit 1960c87
Show file tree
Hide file tree
Showing 9 changed files with 147 additions and 3 deletions.
4 changes: 3 additions & 1 deletion api/api_full.go
Original file line number Diff line number Diff line change
Expand Up @@ -522,8 +522,10 @@ type FullNode interface {
StateMarketStorageDeal(context.Context, abi.DealID, types.TipSetKey) (*MarketDeal, error) //perm:read
// StateLookupID retrieves the ID address of the given address
StateLookupID(context.Context, address.Address, types.TipSetKey) (address.Address, error) //perm:read
// StateAccountKey returns the public key address of the given ID address
// StateAccountKey returns the public key address of the given ID address for secp and bls accounts
StateAccountKey(context.Context, address.Address, types.TipSetKey) (address.Address, error) //perm:read
// StateLookupRobustAddress returns the public key address of the given ID address for non-account addresses (multisig, miners etc)
StateLookupRobustAddress(context.Context, address.Address, types.TipSetKey) (address.Address, error) //perm:read
// StateChangedActors returns all the actors whose states change between the two given state CIDs
// TODO: Should this take tipset keys instead?
StateChangedActors(context.Context, cid.Cid, cid.Cid) (map[string]types.Actor, error) //perm:read
Expand Down
15 changes: 15 additions & 0 deletions api/mocks/mock_full.go

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

13 changes: 13 additions & 0 deletions api/proxy_gen.go

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

45 changes: 45 additions & 0 deletions chain/stmgr/stmgr.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@ import (
"context"
"sync"

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

"github.com/filecoin-project/specs-actors/v7/actors/migration/nv15"

"github.com/filecoin-project/lotus/chain/rand"
Expand All @@ -22,6 +24,7 @@ import (

"github.com/filecoin-project/lotus/api"
"github.com/filecoin-project/lotus/build"
_init "github.com/filecoin-project/lotus/chain/actors/builtin/init"
"github.com/filecoin-project/lotus/chain/actors/builtin/paych"
"github.com/filecoin-project/lotus/chain/actors/policy"
"github.com/filecoin-project/lotus/chain/state"
Expand Down Expand Up @@ -318,6 +321,48 @@ func (sm *StateManager) LookupID(ctx context.Context, addr address.Address, ts *
return state.LookupID(addr)
}

func (sm *StateManager) LookupRobustAddress(ctx context.Context, idAddr address.Address, ts *types.TipSet) (address.Address, error) {
idAddrDecoded, err := address.IDFromAddress(idAddr)
if err != nil {
return address.Undef, xerrors.Errorf("address couldnt decode to id addr: %w", err)
}

cst := cbor.NewCborStore(sm.cs.StateBlockstore())
wrapStore := adt.WrapStore(ctx, cst)

stateTree, err := state.LoadStateTree(cst, sm.parentState(ts))
if err != nil {
return address.Undef, xerrors.Errorf("load state tree: %w", err)
}

initActor, err := stateTree.GetActor(_init.Address)
if err != nil {
return address.Undef, xerrors.Errorf("load init actor: %w", err)
}

initState, err := _init.Load(wrapStore, initActor)
if err != nil {
return address.Undef, xerrors.Errorf("load init state: %w", err)
}
robustAddr := address.Undef

err = initState.ForEachActor(func(id abi.ActorID, addr address.Address) error {
if uint64(id) == idAddrDecoded {
robustAddr = addr
// Hacky way to early return from ForEach
return xerrors.New("robust address found")
}
return nil
})
if err != nil {
if robustAddr == address.Undef {
return address.Undef, xerrors.Errorf("finding address: %w", err)
}
return robustAddr, nil
}
return address.Undef, xerrors.Errorf("address not found")
}

func (sm *StateManager) ValidateChain(ctx context.Context, ts *types.TipSet) error {
tschain := []*types.TipSet{ts}
for ts.Height() != 0 {
Expand Down
26 changes: 25 additions & 1 deletion documentation/en/api-v1-unstable-methods.md
Original file line number Diff line number Diff line change
Expand Up @@ -181,6 +181,7 @@
* [StateListMessages](#StateListMessages)
* [StateListMiners](#StateListMiners)
* [StateLookupID](#StateLookupID)
* [StateLookupRobustAddress](#StateLookupRobustAddress)
* [StateMarketBalance](#StateMarketBalance)
* [StateMarketDeals](#StateMarketDeals)
* [StateMarketParticipants](#StateMarketParticipants)
Expand Down Expand Up @@ -5037,7 +5038,7 @@ A nil TipSetKey can be provided as a param, this will cause the heaviest tipset


### StateAccountKey
StateAccountKey returns the public key address of the given ID address
StateAccountKey returns the public key address of the given ID address for secp and bls accounts


Perms: read
Expand Down Expand Up @@ -5783,6 +5784,29 @@ Response:
StateLookupID retrieves the ID address of the given address


Perms: read

Inputs:
```json
[
"f01234",
[
{
"/": "bafy2bzacea3wsdh6y3a36tb3skempjoxqpuyompjbmfeyf34fi3uy6uue42v4"
},
{
"/": "bafy2bzacebp3shtrn43k7g3unredz7fxn4gj533d3o43tqn2p2ipxxhrvchve"
}
]
]
```

Response: `"f01234"`

### StateLookupRobustAddress
StateLookupRobustAddress returns the public key address of the given ID address for non-account addresses (multisig, miners etc)


Perms: read

Inputs:
Expand Down
9 changes: 9 additions & 0 deletions gateway/node.go
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@ type TargetAPI interface {
StateDealProviderCollateralBounds(ctx context.Context, size abi.PaddedPieceSize, verified bool, tsk types.TipSetKey) (api.DealCollateralBounds, error)
StateGetActor(ctx context.Context, actor address.Address, ts types.TipSetKey) (*types.Actor, error)
StateLookupID(ctx context.Context, addr address.Address, tsk types.TipSetKey) (address.Address, error)
StateLookupRobustAddress(ctx context.Context, addr address.Address, tsk types.TipSetKey) (address.Address, error)
StateListMiners(ctx context.Context, tsk types.TipSetKey) ([]address.Address, error)
StateMarketBalance(ctx context.Context, addr address.Address, tsk types.TipSetKey) (api.MarketBalance, error)
StateMarketStorageDeal(ctx context.Context, dealId abi.DealID, tsk types.TipSetKey) (*api.MarketDeal, error)
Expand Down Expand Up @@ -338,6 +339,14 @@ func (gw *Node) StateLookupID(ctx context.Context, addr address.Address, tsk typ
return gw.target.StateLookupID(ctx, addr, tsk)
}

func (gw *Node) StateLookupRobustAddress(ctx context.Context, addr address.Address, tsk types.TipSetKey) (address.Address, error) {
if err := gw.checkTipsetKey(ctx, tsk); err != nil {
return address.Undef, err
}

return gw.target.StateLookupRobustAddress(ctx, addr, tsk)
}

func (gw *Node) StateMarketBalance(ctx context.Context, addr address.Address, tsk types.TipSetKey) (api.MarketBalance, error) {
if err := gw.checkTipsetKey(ctx, tsk); err != nil {
return api.MarketBalance{}, err
Expand Down
20 changes: 20 additions & 0 deletions itests/self_sent_txn_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -102,3 +102,23 @@ func TestSelfSentTxnV14(t *testing.T) {
require.NoError(t, err)
require.Equal(t, exitcode.Ok, mLookup.Receipt.ExitCode)
}

func TestStateLookupRobustAddress(t *testing.T) {
ctx := context.Background()
kit.QuietMiningLogs()

client15, miner, ens := kit.EnsembleMinimal(t, kit.MockProofs(), kit.GenesisNetworkVersion(network.Version15))
ens.InterconnectAll().BeginMining(10 * time.Millisecond)

addr, err := miner.ActorAddress(ctx)
require.NoError(t, err)

// Look up the robust address
robAddr, err := client15.StateLookupRobustAddress(ctx, addr, types.EmptyTSK)
require.NoError(t, err)

// Check the id address for the given robust address and make sure it matches
idAddr, err := client15.StateLookupID(ctx, robAddr, types.EmptyTSK)
require.NoError(t, err)
require.Equal(t, addr, idAddr)
}
16 changes: 16 additions & 0 deletions node/impl/full/state.go
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ type StateModuleAPI interface {
StateGetActor(ctx context.Context, actor address.Address, tsk types.TipSetKey) (*types.Actor, error)
StateListMiners(ctx context.Context, tsk types.TipSetKey) ([]address.Address, error)
StateLookupID(ctx context.Context, addr address.Address, tsk types.TipSetKey) (address.Address, error)
StateLookupRobustAddress(ctx context.Context, addr address.Address, tsk types.TipSetKey) (address.Address, error)
StateMarketBalance(ctx context.Context, addr address.Address, tsk types.TipSetKey) (api.MarketBalance, error)
StateMarketStorageDeal(ctx context.Context, dealId abi.DealID, tsk types.TipSetKey) (*api.MarketDeal, error)
StateMinerInfo(ctx context.Context, actor address.Address, tsk types.TipSetKey) (miner.MinerInfo, error)
Expand Down Expand Up @@ -449,6 +450,21 @@ func (m *StateModule) StateLookupID(ctx context.Context, addr address.Address, t
return m.StateManager.LookupID(ctx, addr, ts)
}

func (m *StateModule) StateLookupRobustAddress(ctx context.Context, addr address.Address, tsk types.TipSetKey) (address.Address, error) {
ts, err := m.Chain.GetTipSetFromKey(ctx, tsk)
if err != nil {
return address.Undef, xerrors.Errorf("loading tipset %s: %w", tsk, err)
}
if ts.Height() > policy.ChainFinality {
ts, err = m.StateManager.ChainStore().GetTipsetByHeight(ctx, ts.Height()-policy.ChainFinality, ts, true)
if err != nil {
return address.Undef, xerrors.Errorf("failed to load lookback tipset: %w", err)
}
}

return m.StateManager.LookupRobustAddress(ctx, addr, ts)
}

func (m *StateModule) StateAccountKey(ctx context.Context, addr address.Address, tsk types.TipSetKey) (address.Address, error) {
ts, err := m.Chain.GetTipSetFromKey(ctx, tsk)
if err != nil {
Expand Down

0 comments on commit 1960c87

Please sign in to comment.