Skip to main content

cuprate_txpool/ops/
tx_write.rs

1//! Transaction writing ops.
2//!
3//! This module handles writing full transaction data, like removing or adding a transaction.
4use monero_oxide::transaction::{Pruned, Transaction};
5
6use cuprate_helper::time::current_unix_timestamp;
7use cuprate_types::TransactionVerificationData;
8
9use crate::{
10    error::TxPoolError,
11    free::transaction_blob_hash,
12    ops::{
13        key_images::{add_tx_key_images, remove_tx_key_images},
14        TxPoolWriteError,
15    },
16    txpool::TxpoolDatabase,
17    types::{TransactionHash, TransactionInfo, TxStateFlags},
18};
19
20/// Adds a transaction to the tx-pool.
21///
22/// This function fills in all tables necessary to add the transaction to the pool.
23///
24/// # Panics
25/// This function will panic if the transactions inputs are not all of type [`Input::ToKey`](monero_oxide::transaction::Input::ToKey).
26pub fn add_transaction(
27    tx: &TransactionVerificationData,
28    state_stem: bool,
29    w: &mut fjall::OwnedWriteBatch,
30    db: &TxpoolDatabase,
31) -> Result<(), TxPoolWriteError> {
32    add_tx_key_images(&tx.tx.prefix().inputs, &tx.tx_hash, w, db)?;
33
34    // Add the tx blob.
35    w.insert(&db.tx_blobs, tx.tx_hash, &tx.tx_blob);
36
37    let mut flags = TxStateFlags::empty();
38    flags.set(TxStateFlags::STATE_STEM, state_stem);
39
40    // Add the tx info.
41    w.insert(
42        &db.tx_infos,
43        tx.tx_hash,
44        bytemuck::bytes_of(&TransactionInfo {
45            fee: tx.fee,
46            weight: tx.tx_weight,
47            received_at: current_unix_timestamp(),
48            cached_verification_state: tx.cached_verification_state.into(),
49            flags,
50            _padding: [0; 6],
51        }),
52    );
53
54    // Add the blob hash to table 4.
55    let blob_hash = transaction_blob_hash(&tx.tx_blob);
56    w.insert(&db.known_blob_hashes, blob_hash, tx.tx_hash);
57
58    Ok(())
59}
60
61/// Removes a transaction from the transaction pool.
62pub fn remove_transaction(
63    tx_hash: &TransactionHash,
64    w: &mut fjall::OwnedWriteBatch,
65    db: &TxpoolDatabase,
66) -> Result<(), TxPoolError> {
67    // Remove the tx blob.
68    w.remove(&db.tx_blobs, tx_hash);
69
70    w.remove(&db.tx_infos, tx_hash);
71
72    let tx_blob = db
73        .tx_blobs
74        .get(tx_hash.as_ref())?
75        .ok_or(TxPoolError::NotFound)?;
76
77    // Remove the tx key images from table 3.
78    let tx = Transaction::<Pruned>::read(&mut tx_blob.as_ref())
79        .expect("Tx in the tx-pool must be parseable");
80
81    remove_tx_key_images(&tx.prefix().inputs, w, db);
82
83    // Remove the blob hash from table 4.
84    let blob_hash = transaction_blob_hash(&tx_blob);
85    w.remove(&db.known_blob_hashes, blob_hash);
86
87    Ok(())
88}