cuprate_txpool/ops/
tx_write.rs1use bytemuck::TransparentWrapper;
5use monero_serai::transaction::{NotPruned, Transaction};
6
7use cuprate_database::{DatabaseRw, DbResult, StorableVec};
8use cuprate_helper::time::current_unix_timestamp;
9use cuprate_types::TransactionVerificationData;
10
11use crate::{
12 free::transaction_blob_hash,
13 ops::{
14 key_images::{add_tx_key_images, remove_tx_key_images},
15 TxPoolWriteError,
16 },
17 tables::TablesMut,
18 types::{TransactionHash, TransactionInfo, TxStateFlags},
19};
20
21pub fn add_transaction(
28 tx: &TransactionVerificationData,
29 state_stem: bool,
30 tables: &mut impl TablesMut,
31) -> Result<(), TxPoolWriteError> {
32 tables
34 .transaction_blobs_mut()
35 .put(&tx.tx_hash, StorableVec::wrap_ref(&tx.tx_blob))?;
36
37 let mut flags = TxStateFlags::empty();
38 flags.set(TxStateFlags::STATE_STEM, state_stem);
39
40 tables.transaction_infos_mut().put(
42 &tx.tx_hash,
43 &TransactionInfo {
44 fee: tx.fee,
45 weight: tx.tx_weight,
46 received_at: current_unix_timestamp(),
47 flags,
48 _padding: [0; 7],
49 },
50 )?;
51
52 let cached_verification_state = tx.cached_verification_state.into();
54 tables
55 .cached_verification_state_mut()
56 .put(&tx.tx_hash, &cached_verification_state)?;
57
58 let kis_table = tables.spent_key_images_mut();
60 add_tx_key_images(&tx.tx.prefix().inputs, &tx.tx_hash, kis_table)?;
61
62 let blob_hash = transaction_blob_hash(&tx.tx_blob);
64 tables
65 .known_blob_hashes_mut()
66 .put(&blob_hash, &tx.tx_hash)?;
67
68 Ok(())
69}
70
71pub fn remove_transaction(tx_hash: &TransactionHash, tables: &mut impl TablesMut) -> DbResult<()> {
73 let tx_blob = tables.transaction_blobs_mut().take(tx_hash)?.0;
75
76 tables.transaction_infos_mut().delete(tx_hash)?;
78
79 tables.cached_verification_state_mut().delete(tx_hash)?;
81
82 let tx = Transaction::<NotPruned>::read(&mut tx_blob.as_slice())
84 .expect("Tx in the tx-pool must be parseable");
85 let kis_table = tables.spent_key_images_mut();
86 remove_tx_key_images(&tx.prefix().inputs, kis_table)?;
87
88 let blob_hash = transaction_blob_hash(&tx_blob);
90 tables.known_blob_hashes_mut().delete(&blob_hash)?;
91
92 Ok(())
93}