2020-07-16 22:28:35 +00:00
|
|
|
package messagepool
|
|
|
|
|
|
|
|
import (
|
2020-08-01 22:54:21 +00:00
|
|
|
"context"
|
2020-08-01 21:56:43 +00:00
|
|
|
"sort"
|
2020-07-16 22:28:35 +00:00
|
|
|
"time"
|
|
|
|
|
2020-08-01 21:56:43 +00:00
|
|
|
"github.com/filecoin-project/lotus/chain/types"
|
2020-08-01 22:54:21 +00:00
|
|
|
"github.com/ipfs/go-cid"
|
2020-08-06 22:40:25 +00:00
|
|
|
"golang.org/x/xerrors"
|
2020-07-16 22:28:35 +00:00
|
|
|
)
|
|
|
|
|
|
|
|
func (mp *MessagePool) pruneExcessMessages() error {
|
2020-08-01 23:25:13 +00:00
|
|
|
mp.curTsLk.Lock()
|
|
|
|
ts := mp.curTs
|
|
|
|
mp.curTsLk.Unlock()
|
|
|
|
|
2020-07-16 22:28:35 +00:00
|
|
|
mp.lk.Lock()
|
|
|
|
defer mp.lk.Unlock()
|
|
|
|
|
|
|
|
if mp.currentSize < mp.maxTxPoolSizeHi {
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
2020-08-01 23:25:13 +00:00
|
|
|
return mp.pruneMessages(context.TODO(), ts)
|
2020-08-01 21:56:43 +00:00
|
|
|
}
|
|
|
|
|
2020-08-01 23:25:13 +00:00
|
|
|
func (mp *MessagePool) pruneMessages(ctx context.Context, ts *types.TipSet) error {
|
2020-08-05 10:28:14 +00:00
|
|
|
start := time.Now()
|
|
|
|
defer func() {
|
|
|
|
log.Infof("message pruning took %s", time.Since(start))
|
|
|
|
}()
|
2020-08-01 22:54:21 +00:00
|
|
|
|
2020-08-06 22:40:25 +00:00
|
|
|
baseFee, err := mp.api.ChainComputeBaseFee(ctx, ts)
|
|
|
|
if err != nil {
|
|
|
|
return xerrors.Errorf("computing basefee: %w", err)
|
|
|
|
}
|
|
|
|
|
2020-08-05 20:16:09 +00:00
|
|
|
pending, _ := mp.getPendingMessages(ts, ts)
|
|
|
|
|
2020-08-05 10:28:14 +00:00
|
|
|
// Collect all messages to track which ones to remove and create chains for block inclusion
|
|
|
|
pruneMsgs := make(map[cid.Cid]*types.SignedMessage, mp.currentSize)
|
|
|
|
var chains []*msgChain
|
2020-08-05 20:16:09 +00:00
|
|
|
for actor, mset := range pending {
|
|
|
|
for _, m := range mset {
|
2020-08-05 10:28:14 +00:00
|
|
|
pruneMsgs[m.Message.Cid()] = m
|
2020-08-01 22:54:21 +00:00
|
|
|
}
|
2020-08-06 22:40:25 +00:00
|
|
|
actorChains := mp.createMessageChains(actor, mset, baseFee, ts)
|
2020-08-05 10:28:14 +00:00
|
|
|
chains = append(chains, actorChains...)
|
2020-08-01 22:54:21 +00:00
|
|
|
}
|
|
|
|
|
2020-08-05 10:28:14 +00:00
|
|
|
// Sort the chains
|
2020-08-06 15:37:28 +00:00
|
|
|
sort.Slice(chains, func(i, j int) bool {
|
2020-08-05 10:28:14 +00:00
|
|
|
return chains[i].Before(chains[j])
|
2020-08-01 22:54:21 +00:00
|
|
|
})
|
|
|
|
|
2020-08-05 10:28:14 +00:00
|
|
|
// Keep messages (remove them from pruneMsgs) from chains while we are under the low water mark
|
|
|
|
keepCount := 0
|
|
|
|
keepLoop:
|
|
|
|
for _, chain := range chains {
|
|
|
|
for _, m := range chain.msgs {
|
|
|
|
if keepCount < MemPoolSizeLimitLoDefault {
|
|
|
|
delete(pruneMsgs, m.Message.Cid())
|
|
|
|
keepCount++
|
|
|
|
} else {
|
|
|
|
break keepLoop
|
2020-08-01 22:54:21 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-08-05 10:28:14 +00:00
|
|
|
// and remove all messages that are still in pruneMsgs after processing the chains
|
|
|
|
log.Infof("Pruning %d messages", len(pruneMsgs))
|
|
|
|
for _, m := range pruneMsgs {
|
|
|
|
mp.remove(m.Message.From, m.Message.Nonce)
|
2020-08-01 22:54:21 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
return nil
|
|
|
|
}
|