Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(lens): Optimize StateGetActor calls. #214

Merged
merged 5 commits into from
Jan 12, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -1346,6 +1346,7 @@ github.com/onsi/gomega v1.9.0/go.mod h1:Ho0h+IUsWyvy1OpqCwxlQ/21gkhVunqlU8fDGcoT
github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo=
github.com/onsi/gomega v1.10.2 h1:aY/nuoWlKJud2J6U0E3NWsjlg+0GtwXxgEqthRdzlcs=
github.com/onsi/gomega v1.10.2/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo=
github.com/op/go-logging v0.0.0-20160315200505-970db520ece7 h1:lDH9UUVJtmYCjyT0CI4q8xvlXPxeZ0gYCVvWbmPlp88=
github.com/op/go-logging v0.0.0-20160315200505-970db520ece7/go.mod h1:HzydrMdWErDVzsI23lYNej1Htcns9BCg93Dk0bBINWk=
github.com/opentracing-contrib/go-grpc v0.0.0-20180928155321-4b5a12d3ff02/go.mod h1:JNdpVEzCpXBgIiv4ds+TzhN1hrtxq6ClLrTlT9OQRSc=
github.com/opentracing-contrib/go-grpc v0.0.0-20191001143057-db30781987df h1:vdYtBU6zvL7v+Tr+0xFM/qhahw/EvY8DMMunZHKH6eE=
Expand Down
1 change: 1 addition & 0 deletions lens/carrepo/carrepo.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,5 +32,6 @@ func NewAPIOpener(c *cli.Context) (lens.APIOpener, lens.APICloser, error) {
tsk := types.NewTipSetKey(c...)
return &tsk, nil
}

return util.NewAPIOpener(c, cacheDB, h)
}
5 changes: 4 additions & 1 deletion lens/lotus/api.go
Original file line number Diff line number Diff line change
Expand Up @@ -132,7 +132,10 @@ func (aw *APIWrapper) StateGetActor(ctx context.Context, actor address.Address,
ctx, _ = tag.New(ctx, tag.Upsert(metrics.API, "StateGetActor"))
stop := metrics.Timer(ctx, metrics.LensRequestDuration)
defer stop()
return aw.FullNode.StateGetActor(ctx, actor, tsk)

//return aw.FullNode.StateGetActor(ctx, actor, tsk)
// TODO idk how to get a store.ChainStore here
return lens.OptimizedStateGetActorWithFallback(ctx, aw.Store(), aw.FullNode, aw.FullNode, actor, tsk)
}

func (aw *APIWrapper) StateListActors(ctx context.Context, tsk types.TipSetKey) ([]address.Address, error) {
Expand Down
5 changes: 5 additions & 0 deletions lens/lotusrepo/repo.go
Original file line number Diff line number Diff line change
Expand Up @@ -126,6 +126,11 @@ func (ra *RepoAPI) Store() adt.Store {
return adtStore
}

// TODO: Remove. See https://github.com/filecoin-project/sentinel-visor/issues/196
func (ra *RepoAPI) StateGetActor(ctx context.Context, actor address.Address, tsk types.TipSetKey) (*types.Actor, error) {
return lens.OptimizedStateGetActorWithFallback(ctx, ra.ChainAPI.Chain.Store(ctx), ra.ChainAPI, ra.StateAPI, actor, tsk)
}

func (ra *RepoAPI) ClientStartDeal(ctx context.Context, params *api.StartDealParams) (*cid.Cid, error) {
return nil, fmt.Errorf("unsupported")
}
Expand Down
58 changes: 58 additions & 0 deletions lens/util.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
package lens

import (
"context"
"errors"

"github.com/filecoin-project/go-address"
"github.com/filecoin-project/lotus/chain/state"
"github.com/filecoin-project/lotus/chain/types"
"github.com/filecoin-project/lotus/node/impl/full"
cbor "github.com/ipfs/go-ipld-cbor"
logging "github.com/ipfs/go-log/v2"
"golang.org/x/xerrors"
)

var logger = logging.Logger("visor/lens/lotus")

// OptimizedStateGetActorWithFallback is a helper to obtain an actor in the
// state of the current tipset without recomputing the full tipset. It does
// this by obtaining the child tipset (current height+1) and using the
// pre-computed ParentState().
//
// TODO: Remove. See: https://github.com/filecoin-project/sentinel-visor/issues/196
func OptimizedStateGetActorWithFallback(ctx context.Context, store cbor.IpldStore, chainAPI full.ChainModuleAPI, fallback full.StateModuleAPI, actor address.Address, tsk types.TipSetKey) (*types.Actor, error) {
Copy link
Contributor Author

@hsanjuan hsanjuan Jan 12, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This could be simpler if FullNodeAPI actually implemented FullNode but it doesn't:

lens/util/repo.go:109:74: cannot use ra.FullNodeAPI (type impl.FullNodeAPI) as type api.FullNode in argument to lens.OptimizedStateGetActorWithFallback:
	impl.FullNodeAPI does not implement api.FullNode (AuthNew method has pointer receiver)

act, err := efficientStateGetActorFromChainStore(ctx, store, chainAPI, actor, tsk)
if err != nil {
logger.Warnf("Optimized StateGetActorError: %s. Falling back to default StateGetActor().", err)
return fallback.StateGetActor(ctx, actor, tsk)
}
return act, nil
}

func efficientStateGetActorFromChainStore(ctx context.Context, store cbor.IpldStore, chainAPI full.ChainModuleAPI, actor address.Address, tsk types.TipSetKey) (*types.Actor, error) {
ts, err := chainAPI.ChainGetTipSet(ctx, tsk)
if err != nil {
return nil, xerrors.Errorf("Failed to load tipset: %w", err)
}

// heaviest tipset means look on the main chain and false means return tipset following null round.
head, err := chainAPI.ChainHead(ctx)
if err != nil {
return nil, xerrors.Errorf("Failed to get chain head: %w", err)
}
child, err := chainAPI.ChainGetTipSetByHeight(ctx, ts.Height()+1, head.Key())
if err != nil {
return nil, xerrors.Errorf("load child tipset: %w", err)
}

if !types.CidArrsEqual(child.Parents().Cids(), ts.Cids()) {
return nil, errors.New("child is not on the same chain")
}

st, err := state.LoadStateTree(store, child.ParentState())
if err != nil {
return nil, xerrors.Errorf("load state tree: %w", err)
}
return st.GetActor(actor)
}
5 changes: 5 additions & 0 deletions lens/util/repo.go
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,11 @@ type LensAPI struct {
cs *store.ChainStore
}

// TODO: Remove. See https://github.com/filecoin-project/sentinel-visor/issues/196
func (ra *LensAPI) StateGetActor(ctx context.Context, actor address.Address, tsk types.TipSetKey) (*types.Actor, error) {
return lens.OptimizedStateGetActorWithFallback(ctx, ra.cs.Store(ctx), ra.FullNodeAPI.ChainAPI, ra.FullNodeAPI.StateAPI, actor, tsk)
}

func (ra *LensAPI) ComputeGasOutputs(gasUsed, gasLimit int64, baseFee, feeCap, gasPremium abi.TokenAmount) vm.GasOutputs {
return vm.ComputeGasOutputs(gasUsed, gasLimit, baseFee, feeCap, gasPremium)
}
Expand Down