Skip to content

Commit

Permalink
fix wallet validation
Browse files Browse the repository at this point in the history
  • Loading branch information
SWvheerden committed Feb 28, 2024
1 parent c6f2b8d commit da27952
Show file tree
Hide file tree
Showing 8 changed files with 78 additions and 68 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ pub trait OutputManagerBackend: Send + Sync + Clone {
confirmed: bool,
) -> Result<(), OutputManagerStorageError>;

fn mark_output_as_unspent(&self, hash: FixedHash) -> 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 @@ -423,9 +423,9 @@ where T: OutputManagerBackend + 'static
Ok(())
}

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

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -586,17 +586,22 @@ impl OutputManagerBackend for OutputManagerSqliteDatabase {
Ok(())
}

fn mark_output_as_unspent(&self, hash: FixedHash) -> Result<(), OutputManagerStorageError> {
fn mark_output_as_unspent(&self, hash: FixedHash, confirmed: bool) -> Result<(), OutputManagerStorageError> {
let start = Instant::now();
let mut conn = self.database_connection.get_pooled_connection()?;
let acquire_lock = start.elapsed();
let hash = hash.to_vec();
let status = if confirmed {
OutputStatus::Unspent
} else {
OutputStatus::UnspentMinedUnconfirmed
};
debug!(target: LOG_TARGET, "mark_output_as_unspent({})", hash.to_hex());
diesel::update(outputs::table.filter(outputs::hash.eq(hash)))
.set((
outputs::marked_deleted_at_height.eq::<Option<i64>>(None),
outputs::marked_deleted_in_block.eq::<Option<Vec<u8>>>(None),
outputs::status.eq(OutputStatus::Unspent as i32),
outputs::status.eq(status as i32),
))
.execute(&mut conn)
.num_rows_affected_or_not_found(1)?;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -236,7 +236,7 @@ where
if data.height_deleted_at == 0 && output.marked_deleted_at_height.is_some() {
// this is mined but not yet spent
self.db
.mark_output_as_unspent(output.hash)
.mark_output_as_unspent(output.hash, true)
.for_protocol(self.operation_id)?;
info!(
target: LOG_TARGET,
Expand Down Expand Up @@ -395,8 +395,10 @@ where
last_spent_output.commitment.to_hex(),
self.operation_id
);
// we mark the output as UnspentMinedUnconfirmed so it wont get picked it by the OMS to be spendable
// immediately as we first need to find out if this output is unspent, in a mempool, or spent.
self.db
.mark_output_as_unspent(last_spent_output.hash)
.mark_output_as_unspent(last_spent_output.hash, false)
.for_protocol(self.operation_id)?;
} else {
debug!(
Expand Down
50 changes: 25 additions & 25 deletions base_layer/wallet/tests/output_manager_service_tests/service.rs
Original file line number Diff line number Diff line change
Expand Up @@ -311,7 +311,7 @@ async fn fee_estimate() {
.await;
oms.output_manager_handle.add_output(uo.clone(), None).await.unwrap();
backend
.mark_output_as_unspent(uo.hash(&oms.key_manager_handle).await.unwrap())
.mark_output_as_unspent(uo.hash(&oms.key_manager_handle).await.unwrap(), true)
.unwrap();

let fee_calc = Fee::new(*create_consensus_constants(0).transaction_weight_params());
Expand Down Expand Up @@ -430,7 +430,7 @@ async fn test_utxo_selection_no_chain_metadata() {
.await;
oms.add_output(uo.clone(), None).await.unwrap();
backend
.mark_output_as_unspent(uo.hash(&key_manager).await.unwrap())
.mark_output_as_unspent(uo.hash(&key_manager).await.unwrap(), true)
.unwrap();
}

Expand Down Expand Up @@ -562,7 +562,7 @@ async fn test_utxo_selection_with_chain_metadata() {
.await;
oms.add_output(uo.clone(), None).await.unwrap();
backend
.mark_output_as_unspent(uo.hash(&key_manager).await.unwrap())
.mark_output_as_unspent(uo.hash(&key_manager).await.unwrap(), true)
.unwrap();
}

Expand Down Expand Up @@ -710,7 +710,7 @@ async fn test_utxo_selection_with_tx_priority() {
.await
.unwrap();
backend
.mark_output_as_unspent(uo_high.hash(&key_manager).await.unwrap())
.mark_output_as_unspent(uo_high.hash(&key_manager).await.unwrap(), true)
.unwrap();
// Low priority
let uo_low_2 = make_input_with_features(
Expand All @@ -725,7 +725,7 @@ async fn test_utxo_selection_with_tx_priority() {
.await;
oms.add_output(uo_low_2.clone(), None).await.unwrap();
backend
.mark_output_as_unspent(uo_low_2.hash(&key_manager).await.unwrap())
.mark_output_as_unspent(uo_low_2.hash(&key_manager).await.unwrap(), true)
.unwrap();

let utxos = oms.get_unspent_outputs().await.unwrap();
Expand Down Expand Up @@ -780,7 +780,7 @@ async fn send_not_enough_funds() {
.await;
oms.output_manager_handle.add_output(uo.clone(), None).await.unwrap();
backend
.mark_output_as_unspent(uo.hash(&oms.key_manager_handle).await.unwrap())
.mark_output_as_unspent(uo.hash(&oms.key_manager_handle).await.unwrap(), true)
.unwrap();
}

Expand Down Expand Up @@ -834,7 +834,7 @@ async fn send_no_change() {
oms.output_manager_handle.add_output(uo_1.clone(), None).await.unwrap();

backend
.mark_output_as_unspent(uo_1.hash(&oms.key_manager_handle).await.unwrap())
.mark_output_as_unspent(uo_1.hash(&oms.key_manager_handle).await.unwrap(), true)
.unwrap();
let value2 = 8000;
let uo_2 = create_wallet_output_with_data(
Expand All @@ -848,7 +848,7 @@ async fn send_no_change() {
.unwrap();
oms.output_manager_handle.add_output(uo_2.clone(), None).await.unwrap();
backend
.mark_output_as_unspent(uo_2.hash(&oms.key_manager_handle).await.unwrap())
.mark_output_as_unspent(uo_2.hash(&oms.key_manager_handle).await.unwrap(), true)
.unwrap();

let stp = oms
Expand Down Expand Up @@ -900,7 +900,7 @@ async fn send_not_enough_for_change() {
.unwrap();
oms.output_manager_handle.add_output(uo_1.clone(), None).await.unwrap();
backend
.mark_output_as_unspent(uo_1.hash(&oms.key_manager_handle).await.unwrap())
.mark_output_as_unspent(uo_1.hash(&oms.key_manager_handle).await.unwrap(), true)
.unwrap();
let value2 = MicroMinotari(800);
let uo_2 = create_wallet_output_with_data(
Expand All @@ -914,7 +914,7 @@ async fn send_not_enough_for_change() {
.unwrap();
oms.output_manager_handle.add_output(uo_2.clone(), None).await.unwrap();
backend
.mark_output_as_unspent(uo_2.hash(&oms.key_manager_handle).await.unwrap())
.mark_output_as_unspent(uo_2.hash(&oms.key_manager_handle).await.unwrap(), true)
.unwrap();

match oms
Expand Down Expand Up @@ -955,7 +955,7 @@ async fn cancel_transaction() {
.await;
oms.output_manager_handle.add_output(uo.clone(), None).await.unwrap();
backend
.mark_output_as_unspent(uo.hash(&oms.key_manager_handle).await.unwrap())
.mark_output_as_unspent(uo.hash(&oms.key_manager_handle).await.unwrap(), true)
.unwrap();
}
let stp = oms
Expand Down Expand Up @@ -1046,7 +1046,7 @@ async fn test_get_balance() {
total += uo.value;
oms.output_manager_handle.add_output(uo.clone(), None).await.unwrap();
backend
.mark_output_as_unspent(uo.hash(&oms.key_manager_handle).await.unwrap())
.mark_output_as_unspent(uo.hash(&oms.key_manager_handle).await.unwrap(), true)
.unwrap();

let uo = make_input(
Expand All @@ -1059,7 +1059,7 @@ async fn test_get_balance() {
total += uo.value;
oms.output_manager_handle.add_output(uo.clone(), None).await.unwrap();
backend
.mark_output_as_unspent(uo.hash(&oms.key_manager_handle).await.unwrap())
.mark_output_as_unspent(uo.hash(&oms.key_manager_handle).await.unwrap(), true)
.unwrap();

let send_value = MicroMinotari::from(1000);
Expand Down Expand Up @@ -1114,7 +1114,7 @@ async fn sending_transaction_persisted_while_offline() {
.await;
oms.output_manager_handle.add_output(uo.clone(), None).await.unwrap();
backend
.mark_output_as_unspent(uo.hash(&oms.key_manager_handle).await.unwrap())
.mark_output_as_unspent(uo.hash(&oms.key_manager_handle).await.unwrap(), true)
.unwrap();
let uo = make_input(
&mut OsRng.clone(),
Expand All @@ -1125,7 +1125,7 @@ async fn sending_transaction_persisted_while_offline() {
.await;
oms.output_manager_handle.add_output(uo.clone(), None).await.unwrap();
backend
.mark_output_as_unspent(uo.hash(&oms.key_manager_handle).await.unwrap())
.mark_output_as_unspent(uo.hash(&oms.key_manager_handle).await.unwrap(), true)
.unwrap();

let balance = oms.output_manager_handle.get_balance().await.unwrap();
Expand Down Expand Up @@ -1215,13 +1215,13 @@ async fn coin_split_with_change() {
assert!(oms.output_manager_handle.add_output(uo3.clone(), None).await.is_ok());
// lets mark them as unspent so we can use them
backend
.mark_output_as_unspent(uo1.hash(&oms.key_manager_handle).await.unwrap())
.mark_output_as_unspent(uo1.hash(&oms.key_manager_handle).await.unwrap(), true)
.unwrap();
backend
.mark_output_as_unspent(uo2.hash(&oms.key_manager_handle).await.unwrap())
.mark_output_as_unspent(uo2.hash(&oms.key_manager_handle).await.unwrap(), true)
.unwrap();
backend
.mark_output_as_unspent(uo3.hash(&oms.key_manager_handle).await.unwrap())
.mark_output_as_unspent(uo3.hash(&oms.key_manager_handle).await.unwrap(), true)
.unwrap();

let fee_per_gram = MicroMinotari::from(5);
Expand Down Expand Up @@ -1279,13 +1279,13 @@ async fn coin_split_no_change() {
assert!(oms.output_manager_handle.add_output(uo3.clone(), None).await.is_ok());
// lets mark then as unspent so we can use them
backend
.mark_output_as_unspent(uo1.hash(&oms.key_manager_handle).await.unwrap())
.mark_output_as_unspent(uo1.hash(&oms.key_manager_handle).await.unwrap(), true)
.unwrap();
backend
.mark_output_as_unspent(uo2.hash(&oms.key_manager_handle).await.unwrap())
.mark_output_as_unspent(uo2.hash(&oms.key_manager_handle).await.unwrap(), true)
.unwrap();
backend
.mark_output_as_unspent(uo3.hash(&oms.key_manager_handle).await.unwrap())
.mark_output_as_unspent(uo3.hash(&oms.key_manager_handle).await.unwrap(), true)
.unwrap();
let (_tx_id, coin_split_tx, amount) = oms
.output_manager_handle
Expand All @@ -1309,7 +1309,7 @@ async fn it_handles_large_coin_splits() {
assert!(oms.output_manager_handle.add_output(uo.clone(), None).await.is_ok());
// lets mark them as unspent so we can use them
backend
.mark_output_as_unspent(uo.hash(&oms.key_manager_handle).await.unwrap())
.mark_output_as_unspent(uo.hash(&oms.key_manager_handle).await.unwrap(), true)
.unwrap();

let fee_per_gram = MicroMinotari::from(1);
Expand Down Expand Up @@ -1355,7 +1355,7 @@ async fn test_txo_validation() {
.await
.unwrap();
oms_db
.mark_output_as_unspent(output1.hash(&oms.key_manager_handle).await.unwrap())
.mark_output_as_unspent(output1.hash(&oms.key_manager_handle).await.unwrap(), true)
.unwrap();

let output2_value = 2_000_000;
Expand All @@ -1373,7 +1373,7 @@ async fn test_txo_validation() {
.await
.unwrap();
oms_db
.mark_output_as_unspent(output2.hash(&oms.key_manager_handle).await.unwrap())
.mark_output_as_unspent(output2.hash(&oms.key_manager_handle).await.unwrap(), true)
.unwrap();

let output3_value = 4_000_000;
Expand All @@ -1391,7 +1391,7 @@ async fn test_txo_validation() {
.unwrap();

oms_db
.mark_output_as_unspent(output3.hash(&oms.key_manager_handle).await.unwrap())
.mark_output_as_unspent(output3.hash(&oms.key_manager_handle).await.unwrap(), true)
.unwrap();

let mut block1_header = BlockHeader::new(1);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ pub async fn test_db_backend<T: OutputManagerBackend + 'static>(backend: T) {
.unwrap();
kmo.wallet_output.features.maturity = i;
db.add_unspent_output(kmo.clone()).unwrap();
db.mark_output_as_unspent(kmo.hash).unwrap();
db.mark_output_as_unspent(kmo.hash, true).unwrap();
unspent_outputs.push(kmo);
}

Expand Down Expand Up @@ -111,7 +111,7 @@ pub async fn test_db_backend<T: OutputManagerBackend + 'static>(backend: T) {
.await
.unwrap();
db.add_unspent_output(kmo.clone()).unwrap();
db.mark_output_as_unspent(kmo.hash).unwrap();
db.mark_output_as_unspent(kmo.hash, true).unwrap();
pending_tx.outputs_to_be_spent.push(kmo);
}
for _ in 0..2 {
Expand Down Expand Up @@ -356,7 +356,7 @@ pub async fn test_short_term_encumberance() {
.unwrap();
kmo.wallet_output.features.maturity = i;
db.add_unspent_output(kmo.clone()).unwrap();
db.mark_output_as_unspent(kmo.hash).unwrap();
db.mark_output_as_unspent(kmo.hash, true).unwrap();
unspent_outputs.push(kmo);
}

Expand Down
Loading

0 comments on commit da27952

Please sign in to comment.