CheckMempool() Checks each transaction in the mempool and caches a block proposal
()
| 212 | |
| 213 | // CheckMempool() Checks each transaction in the mempool and caches a block proposal |
| 214 | func (m *Mempool) CheckMempool() { |
| 215 | m.log.Info("Validating mempool and caching a new proposal block") |
| 216 | var err lib.ErrorI |
| 217 | // check if a validator |
| 218 | // create the actual block structure with the maximum amount of transactions allowed or available in the mempool |
| 219 | block := &lib.Block{ |
| 220 | BlockHeader: &lib.BlockHeader{Time: uint64(time.Now().UnixMicro()), ProposerAddress: m.address.Bytes()}, |
| 221 | Transactions: m.GetTransactions(math.MaxUint64), // get all transactions in mempool - but apply block will only keep 'max-block' amount |
| 222 | } |
| 223 | // capture the tentative block result using a new object reference |
| 224 | blockResult, result := new(lib.BlockResult), new(lib.ApplyBlockResults) |
| 225 | // setup a context with cancel |
| 226 | ctx, stop := context.WithCancel(context.Background()) |
| 227 | // set the cancel function |
| 228 | m.stop = stop |
| 229 | block.BlockHeader, result, err = m.FSM.ApplyBlock(ctx, block, true) |
| 230 | if err != nil { |
| 231 | m.log.Warnf("Check Mempool error: %s", err.Error()) |
| 232 | return |
| 233 | } |
| 234 | // set the block result block header |
| 235 | blockResult = &lib.BlockResult{BlockHeader: block.BlockHeader, Transactions: result.Results, Events: result.Events} |
| 236 | // get RC build height |
| 237 | rcBuildHeight := m.controller.RootChainHeight() |
| 238 | // calculate rc build height |
| 239 | ownRoot, err := m.FSM.LoadIsOwnRoot() |
| 240 | if err != nil { |
| 241 | m.log.Error(err.Error()) |
| 242 | } |
| 243 | // if ownRoot |
| 244 | if ownRoot { |
| 245 | rcBuildHeight = m.FSM.Height() |
| 246 | } |
| 247 | // cache the proposal |
| 248 | m.cachedProposal.Store(&CachedProposal{ |
| 249 | Block: block, |
| 250 | BlockResult: blockResult, |
| 251 | CertResults: m.controller.NewCertificateResults(m.FSM, block, blockResult, &bft.ByzantineEvidence{DSE: bft.DoubleSignEvidences{}}, rcBuildHeight), |
| 252 | rcBuildHeight: rcBuildHeight, |
| 253 | }) |
| 254 | // create a cache of failed tx bytes to evict from the mempool |
| 255 | var failedTxBz [][]byte |
| 256 | // mark as failed in the cache |
| 257 | for _, tx := range result.Failed { |
| 258 | // cache failed txs for RPC display |
| 259 | m.cachedFailedTxs.Add(tx) |
| 260 | // save the bytes |
| 261 | failedTxBz = append(failedTxBz, tx.GetBytes()) |
| 262 | } |
| 263 | // evict all invalid transactions from the mempool |
| 264 | m.DeleteTransaction(failedTxBz...) |
| 265 | // log a warning |
| 266 | if len(result.Failed) != 0 { |
| 267 | m.log.Warnf("Removed failed %d txs from mempool", len(result.Failed)) |
| 268 | for _, f := range result.Failed { |
| 269 | m.log.Warnf("%s", f.Error) |
| 270 | } |
| 271 | } |
no test coverage detected