Skip to content

Commit

Permalink
Optimize txo validation sqlite queries
Browse files Browse the repository at this point in the history
Optimized transaction validation sqlite queries to run in batch mode where ever
possible to minimise db operations.
  • Loading branch information
hansieodendaal committed Mar 11, 2024
1 parent 9aeed79 commit 3f239f7
Show file tree
Hide file tree
Showing 7 changed files with 596 additions and 295 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ use crate::output_manager_service::{
storage::{
database::{DbKey, DbValue, OutputBackendQuery, WriteOperation},
models::DbWalletOutput,
sqlite_db::{ReceivedOutputInfoForBatch, SpentOutputInfoForBatch},
},
};

Expand All @@ -37,29 +38,32 @@ pub trait OutputManagerBackend: Send + Sync + Clone {
/// Modify the state the of the backend with a write operation
fn write(&self, op: WriteOperation) -> Result<Option<DbValue>, OutputManagerStorageError>;
fn fetch_pending_incoming_outputs(&self) -> Result<Vec<DbWalletOutput>, OutputManagerStorageError>;

fn set_received_output_mined_height_and_status(
/// Perform a batch update of the received outputs' mined height and status
fn set_received_outputs_mined_height_and_status_batch_mode(
&self,
hash: FixedHash,
mined_height: u64,
mined_in_block: FixedHash,
confirmed: bool,
mined_timestamp: u64,
updates: Vec<ReceivedOutputInfoForBatch>,
) -> Result<(), OutputManagerStorageError>;
/// Perform a batch update of the outputs' unmined and invalid state
fn set_output_to_unmined_and_invalid_batch_mode(
&self,
hashes: Vec<FixedHash>,
) -> Result<(), OutputManagerStorageError>;
/// Perform a batch update of the outputs' last validation timestamp
fn update_last_validation_timestamp_batch_mode(
&self,
hashes: Vec<FixedHash>,
) -> Result<(), OutputManagerStorageError>;

fn set_output_to_unmined_and_invalid(&self, hash: FixedHash) -> Result<(), OutputManagerStorageError>;
fn update_last_validation_timestamp(&self, hash: FixedHash) -> Result<(), OutputManagerStorageError>;
fn set_outputs_to_be_revalidated(&self) -> Result<(), OutputManagerStorageError>;

fn mark_output_as_spent(
/// Perform a batch update of the outputs' spent status
fn mark_output_as_spent_batch_mode(
&self,
hash: FixedHash,
mark_deleted_at_height: u64,
mark_deleted_in_block: FixedHash,
confirmed: bool,
updates: Vec<SpentOutputInfoForBatch>,
) -> Result<(), OutputManagerStorageError>;
/// Perform a batch update of the outputs' unspent status
fn mark_output_as_unspent_batch_mode(
&self,
hashes: Vec<(FixedHash, bool)>,
) -> Result<(), OutputManagerStorageError>;

fn mark_output_as_unspent(&self, hash: FixedHash, confirmed: bool) -> Result<(), OutputManagerStorageError>;
/// This method encumbers the specified outputs into a `PendingTransactionOutputs` record. This is a short term
/// encumberance in case the app is closed or crashes before transaction neogtiation is complete. These will be
/// cleared on startup of the service.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ pub use backend::OutputManagerBackend;
use log::*;
use tari_common_types::{
transaction::TxId,
types::{Commitment, HashOutput},
types::{Commitment, FixedHash, HashOutput},
};
use tari_core::transactions::{
tari_amount::MicroMinotari,
Expand All @@ -44,6 +44,7 @@ use crate::output_manager_service::{
service::Balance,
storage::{
models::{DbWalletOutput, KnownOneSidedPaymentScript},
sqlite_db::{ReceivedOutputInfoForBatch, SpentOutputInfoForBatch},
OutputStatus,
},
};
Expand Down Expand Up @@ -387,15 +388,35 @@ where T: OutputManagerBackend + 'static
mined_in_block: HashOutput,
confirmed: bool,
mined_timestamp: u64,
) -> Result<(), OutputManagerStorageError> {
self.set_received_outputs_mined_height_and_status_batch_mode(vec![ReceivedOutputInfoForBatch {
hash,
mined_height,
mined_in_block,
confirmed,
mined_timestamp,
}])
}

pub fn set_received_outputs_mined_height_and_status_batch_mode(
&self,
updates: Vec<ReceivedOutputInfoForBatch>,
) -> Result<(), OutputManagerStorageError> {
let db = self.db.clone();
db.set_received_output_mined_height_and_status(hash, mined_height, mined_in_block, confirmed, mined_timestamp)?;
db.set_received_outputs_mined_height_and_status_batch_mode(updates)?;
Ok(())
}

pub fn set_output_to_unmined_and_invalid(&self, hash: HashOutput) -> Result<(), OutputManagerStorageError> {
self.set_output_to_unmined_and_invalid_batch_mode(vec![hash])
}

pub fn set_output_to_unmined_and_invalid_batch_mode(
&self,
hashes: Vec<FixedHash>,
) -> Result<(), OutputManagerStorageError> {
let db = self.db.clone();
db.set_output_to_unmined_and_invalid(hash)?;
db.set_output_to_unmined_and_invalid_batch_mode(hashes)?;
Ok(())
}

Expand All @@ -406,8 +427,15 @@ where T: OutputManagerBackend + 'static
}

pub fn update_last_validation_timestamp(&self, hash: HashOutput) -> Result<(), OutputManagerStorageError> {
self.update_last_validation_timestamp_batch_mode(vec![hash])
}

pub fn update_last_validation_timestamp_batch_mode(
&self,
hashes: Vec<FixedHash>,
) -> Result<(), OutputManagerStorageError> {
let db = self.db.clone();
db.update_last_validation_timestamp(hash)?;
db.update_last_validation_timestamp_batch_mode(hashes)?;
Ok(())
}

Expand All @@ -417,15 +445,34 @@ where T: OutputManagerBackend + 'static
deleted_height: u64,
deleted_in_block: HashOutput,
confirmed: bool,
) -> Result<(), OutputManagerStorageError> {
self.mark_output_as_spent_batch_mode(vec![SpentOutputInfoForBatch {
hash,
confirmed,
mark_deleted_at_height: deleted_height,
mark_deleted_in_block: deleted_in_block,
}])
}

pub fn mark_output_as_spent_batch_mode(
&self,
updates: Vec<SpentOutputInfoForBatch>,
) -> Result<(), OutputManagerStorageError> {
let db = self.db.clone();
db.mark_output_as_spent(hash, deleted_height, deleted_in_block, confirmed)?;
db.mark_output_as_spent_batch_mode(updates)?;
Ok(())
}

pub fn mark_output_as_unspent(&self, hash: HashOutput, confirmed: bool) -> Result<(), OutputManagerStorageError> {
self.mark_output_as_unspent_batch_mode(vec![(hash, confirmed)])
}

pub fn mark_output_as_unspent_batch_mode(
&self,
hashes: Vec<(FixedHash, bool)>,
) -> Result<(), OutputManagerStorageError> {
let db = self.db.clone();
db.mark_output_as_unspent(hash, confirmed)?;
db.mark_output_as_unspent_batch_mode(hashes)?;
Ok(())
}

Expand Down
Loading

0 comments on commit 3f239f7

Please sign in to comment.