CheckMempool() periodically checks the mempool: - Validates all transactions in the mempool - Caches a proposal block based on the current state and the mempool transactions - P2P Gossip out any transactions that weren't previously gossiped
()
| 90 | // - Caches a proposal block based on the current state and the mempool transactions |
| 91 | // - P2P Gossip out any transactions that weren't previously gossiped |
| 92 | func (c *Controller) CheckMempool() { |
| 93 | deDupe, _ := lru.New[string, struct{}](100_000) |
| 94 | // if configured to not check mempool besides right after CommitBlock |
| 95 | if c.Config.LazyMempoolCheckFrequencyS == 0 { |
| 96 | return |
| 97 | } |
| 98 | for { |
| 99 | // keep a list of transaction needing to be gossipped |
| 100 | var toGossip [][]byte |
| 101 | // if recheck is necessary |
| 102 | if c.Mempool.recheck.Load() { |
| 103 | // execute in a function call to allow defer |
| 104 | func() { |
| 105 | c.Mempool.L.Lock() |
| 106 | defer c.Mempool.L.Unlock() |
| 107 | // be mempool strict on proposals |
| 108 | resetProposalConfig := c.SetFSMInConsensusModeForProposals() |
| 109 | // once done proposing, 'reset' the proposal mode back to default to 'accept all' |
| 110 | defer func() { resetProposalConfig() }() |
| 111 | // reset the mempool |
| 112 | c.Mempool.FSM.Reset() |
| 113 | // check the mempool to cache a proposal block and validate the mempool itself |
| 114 | c.Mempool.CheckMempool() |
| 115 | // get the transactions to gossip |
| 116 | toGossip = c.Mempool.GetTransactions(math.MaxUint64) |
| 117 | // set recheck to false |
| 118 | c.Mempool.recheck.Store(false) |
| 119 | }() |
| 120 | } |
| 121 | // for each transaction to gossip |
| 122 | var dedupedTxs [][]byte |
| 123 | for _, tx := range toGossip { |
| 124 | // get the key for the transaction |
| 125 | key := crypto.HashString(tx) |
| 126 | // if not already gossiped |
| 127 | if _, found := deDupe.Get(key); !found { |
| 128 | // add to the de-dupe list |
| 129 | deDupe.Add(key, struct{}{}) |
| 130 | dedupedTxs = append(dedupedTxs, tx) |
| 131 | } |
| 132 | } |
| 133 | if len(dedupedTxs) != 0 { |
| 134 | // gossip the transactions to peers |
| 135 | if err := c.P2P.SendToPeers(Tx, &lib.TxMessage{ChainId: c.Config.ChainId, Txs: dedupedTxs}); err != nil { |
| 136 | // log the gossip error |
| 137 | c.log.Error(fmt.Sprintf("unable to gossip tx with err: %s", err.Error())) |
| 138 | } |
| 139 | } |
| 140 | // sleep for the recheck time |
| 141 | time.Sleep(time.Duration(c.Config.LazyMempoolCheckFrequencyS) * time.Second) |
| 142 | } |
| 143 | } |
| 144 | |
| 145 | // Mempool accepts or rejects incoming txs based on the mempool (ephemeral copy) state |
| 146 | // - recheck when |
no test coverage detected