feat: mpool: Cache actors in lite mode (#11668)

This commit is contained in:
Łukasz Magiera 2024-03-12 10:44:56 +01:00 committed by GitHub
parent 6f7498b622
commit c1c5deb458
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194

View File

@ -5,6 +5,7 @@ import (
"errors" "errors"
"time" "time"
lru "github.com/hashicorp/golang-lru/v2"
"github.com/ipfs/go-cid" "github.com/ipfs/go-cid"
pubsub "github.com/libp2p/go-libp2p-pubsub" pubsub "github.com/libp2p/go-libp2p-pubsub"
"golang.org/x/xerrors" "golang.org/x/xerrors"
@ -16,6 +17,8 @@ import (
"github.com/filecoin-project/lotus/chain/stmgr" "github.com/filecoin-project/lotus/chain/stmgr"
"github.com/filecoin-project/lotus/chain/store" "github.com/filecoin-project/lotus/chain/store"
"github.com/filecoin-project/lotus/chain/types" "github.com/filecoin-project/lotus/chain/types"
"github.com/filecoin-project/lotus/lib/must"
"github.com/filecoin-project/lotus/lib/result"
) )
var ( var (
@ -39,10 +42,19 @@ type Provider interface {
IsLite() bool IsLite() bool
} }
type actorCacheKey struct {
types.TipSetKey
address.Address
}
var nonceCacheSize = 128
type mpoolProvider struct { type mpoolProvider struct {
sm *stmgr.StateManager sm *stmgr.StateManager
ps *pubsub.PubSub ps *pubsub.PubSub
liteActorCache *lru.Cache[actorCacheKey, result.Result[*types.Actor]]
lite MpoolNonceAPI lite MpoolNonceAPI
} }
@ -53,18 +65,31 @@ func NewProvider(sm *stmgr.StateManager, ps *pubsub.PubSub) Provider {
} }
func NewProviderLite(sm *stmgr.StateManager, ps *pubsub.PubSub, noncer MpoolNonceAPI) Provider { func NewProviderLite(sm *stmgr.StateManager, ps *pubsub.PubSub, noncer MpoolNonceAPI) Provider {
return &mpoolProvider{sm: sm, ps: ps, lite: noncer} return &mpoolProvider{
sm: sm,
ps: ps,
lite: noncer,
liteActorCache: must.One(lru.New[actorCacheKey, result.Result[*types.Actor]](nonceCacheSize)),
}
} }
func (mpp *mpoolProvider) IsLite() bool { func (mpp *mpoolProvider) IsLite() bool {
return mpp.lite != nil return mpp.lite != nil
} }
func (mpp *mpoolProvider) getActorLite(addr address.Address, ts *types.TipSet) (*types.Actor, error) { func (mpp *mpoolProvider) getActorLite(addr address.Address, ts *types.TipSet) (act *types.Actor, err error) {
if !mpp.IsLite() { if !mpp.IsLite() {
return nil, errors.New("should not use getActorLite on non lite Provider") return nil, errors.New("should not use getActorLite on non lite Provider")
} }
if c, ok := mpp.liteActorCache.Get(actorCacheKey{ts.Key(), addr}); ok {
return c.Unwrap()
}
defer func() {
mpp.liteActorCache.Add(actorCacheKey{ts.Key(), addr}, result.Wrap(act, err))
}()
n, err := mpp.lite.GetNonce(context.TODO(), addr, ts.Key()) n, err := mpp.lite.GetNonce(context.TODO(), addr, ts.Key())
if err != nil { if err != nil {
return nil, xerrors.Errorf("getting nonce over lite: %w", err) return nil, xerrors.Errorf("getting nonce over lite: %w", err)