diff --git a/chain/store/store.go b/chain/store/store.go index 807188c85..3bbdaa0f7 100644 --- a/chain/store/store.go +++ b/chain/store/store.go @@ -17,6 +17,7 @@ import ( amt "github.com/filecoin-project/go-amt-ipld" "github.com/filecoin-project/lotus/chain/types" + lru "github.com/hashicorp/golang-lru" block "github.com/ipfs/go-block-format" "github.com/ipfs/go-cid" dstore "github.com/ipfs/go-datastore" @@ -49,14 +50,18 @@ type ChainStore struct { reorgCh chan<- reorg headChangeNotifs []func(rev, app []*types.TipSet) error + + mmCache *lru.ARCCache } func NewChainStore(bs bstore.Blockstore, ds dstore.Batching) *ChainStore { + c, _ := lru.NewARC(2048) cs := &ChainStore{ bs: bs, ds: ds, bestTips: pubsub.New(64), tipsets: make(map[uint64][]cid.Cid), + mmCache: c, } cs.reorgCh = cs.reorgWorker(context.TODO()) @@ -627,10 +632,21 @@ func (cs *ChainStore) MessagesForTipset(ts *types.TipSet) ([]ChainMsg, error) { return out, nil } -func (cs *ChainStore) MessagesForBlock(b *types.BlockHeader) ([]*types.Message, []*types.SignedMessage, error) { +type mmCids struct { + bls []cid.Cid + secpk []cid.Cid +} + +func (cs *ChainStore) readMsgMetaCids(mmc cid.Cid) ([]cid.Cid, []cid.Cid, error) { + o, ok := cs.mmCache.Get(mmc) + if ok { + mmcids := o.(*mmCids) + return mmcids.bls, mmcids.secpk, nil + } + cst := hamt.CSTFromBstore(cs.bs) var msgmeta types.MsgMeta - if err := cst.Get(context.TODO(), b.Messages, &msgmeta); err != nil { + if err := cst.Get(context.TODO(), mmc, &msgmeta); err != nil { return nil, nil, xerrors.Errorf("failed to load msgmeta: %w", err) } @@ -644,6 +660,20 @@ func (cs *ChainStore) MessagesForBlock(b *types.BlockHeader) ([]*types.Message, return nil, nil, errors.Wrap(err, "loading secpk message cids for block") } + cs.mmCache.Add(mmc, &mmCids{ + bls: blscids, + secpk: secpkcids, + }) + + return blscids, secpkcids, nil +} + +func (cs *ChainStore) MessagesForBlock(b *types.BlockHeader) ([]*types.Message, []*types.SignedMessage, error) { + blscids, secpkcids, err := cs.readMsgMetaCids(b.Messages) + if err != nil { + return nil, nil, err + } + blsmsgs, err := cs.LoadMessagesFromCids(blscids) if err != nil { return nil, nil, errors.Wrap(err, "loading bls messages for block")