(&mut self)
| 116 | } |
| 117 | |
| 118 | pub(crate) async fn process_transactions(&mut self) -> Result<()> { |
| 119 | // Bulk drain the current queue to fit into the new block |
| 120 | // This is not safe as we lose transactions if a panic occurs |
| 121 | // or if the program is halted |
| 122 | let transactions = self |
| 123 | .transactions |
| 124 | .lock() |
| 125 | .await |
| 126 | .mempool |
| 127 | .drain(0..) |
| 128 | .collect::<VecDeque<_>>(); |
| 129 | |
| 130 | if !transactions.is_empty() { |
| 131 | let mut receipts: Vec<TransactionReceipt> = vec![]; |
| 132 | let mut processed: Vec<Transaction> = vec![]; |
| 133 | |
| 134 | tracing::info!("Processing {} transactions", transactions.len()); |
| 135 | |
| 136 | for mut transaction in transactions.into_iter() { |
| 137 | match self.process_transaction(&mut transaction) { |
| 138 | Ok((transaction, transaction_receipt)) => { |
| 139 | receipts.push(transaction_receipt); |
| 140 | processed.push(transaction.to_owned()); |
| 141 | } |
| 142 | Err(error) => { |
| 143 | match error { |
| 144 | // The nonce is too high, add back to the mempool |
| 145 | ChainError::NonceTooHigh(_, _) => { |
| 146 | tracing::warn!( |
| 147 | "Could not process transaction {:?}: {}", |
| 148 | transaction, |
| 149 | error |
| 150 | ); |
| 151 | self.transactions |
| 152 | .lock() |
| 153 | .await |
| 154 | .mempool |
| 155 | .push_back(transaction); |
| 156 | } |
| 157 | _ => tracing::error!( |
| 158 | "Could not process transaction {:?}: {}", |
| 159 | transaction, |
| 160 | error |
| 161 | ), |
| 162 | } |
| 163 | } |
| 164 | } |
| 165 | } |
| 166 | |
| 167 | // update world state |
| 168 | let state_trie = self.accounts.root_hash()?; |
| 169 | self.world_state.update_state_trie(state_trie); |
| 170 | |
| 171 | tracing::info!("World State: state_trie {:?}", state_trie); |
| 172 | |
| 173 | let num_processed = processed.len(); |
| 174 | let block = self.new_block(processed, state_trie)?; |
| 175 |
no test coverage detected