cuprate_consensus/block/
free.rs1use std::collections::HashMap;
3
4use monero_serai::block::Block;
5
6use cuprate_types::TransactionVerificationData;
7
8use crate::ExtendedConsensusError;
9
10pub(crate) fn order_transactions(
12 block: &Block,
13 txs: &mut [TransactionVerificationData],
14) -> Result<(), ExtendedConsensusError> {
15 if block.transactions.len() != txs.len() {
16 return Err(ExtendedConsensusError::TxsIncludedWithBlockIncorrect);
17 }
18
19 for (i, tx_hash) in block.transactions.iter().enumerate() {
20 if tx_hash != &txs[i].tx_hash {
21 let at_index = txs[i..]
22 .iter()
23 .position(|tx| &tx.tx_hash == tx_hash)
24 .ok_or(ExtendedConsensusError::TxsIncludedWithBlockIncorrect)?;
25
26 txs.swap(i, i + at_index);
28 }
29 }
30
31 debug_assert!(block
32 .transactions
33 .iter()
34 .zip(txs.iter())
35 .all(|(tx_hash, tx)| tx_hash == &tx.tx_hash));
36
37 Ok(())
38}
39
40pub(crate) fn pull_ordered_transactions(
44 block: &Block,
45 mut txs: HashMap<[u8; 32], TransactionVerificationData>,
46) -> Result<Vec<TransactionVerificationData>, ExtendedConsensusError> {
47 if block.transactions.len() != txs.len() {
48 return Err(ExtendedConsensusError::TxsIncludedWithBlockIncorrect);
49 }
50
51 let mut ordered_txs = Vec::with_capacity(txs.len());
52
53 if !block.transactions.is_empty() {
54 for tx_hash in &block.transactions {
55 let tx = txs
56 .remove(tx_hash)
57 .ok_or(ExtendedConsensusError::TxsIncludedWithBlockIncorrect)?;
58 ordered_txs.push(tx);
59 }
60 drop(txs);
61 }
62
63 Ok(ordered_txs)
64}