Skip to content

Commit

Permalink
feat: add tx_id_to export (#5126)
Browse files Browse the repository at this point in the history
Description
---
Adds the tx_id to export unspent utxo request. 

Motivation and Context
---
This allows a callee to ask the TMS service using the tx_id for more details about how the output was received

How Has This Been Tested?
---
Unit tests. 

Fixes: #5117
  • Loading branch information
SWvheerden authored Jan 18, 2023
1 parent a568e04 commit 7eeeff4
Show file tree
Hide file tree
Showing 13 changed files with 333 additions and 48 deletions.
2 changes: 2 additions & 0 deletions applications/tari_console_wallet/src/automation/commands.rs
Original file line number Diff line number Diff line change
Expand Up @@ -765,6 +765,7 @@ pub async fn command_runner(
},
ExportUtxos(args) => match output_service.get_unspent_outputs().await {
Ok(utxos) => {
let utxos: Vec<UnblindedOutput> = utxos.into_iter().map(|v| v.unblinded_output).collect();
let count = utxos.len();
let sum: MicroTari = utxos.iter().map(|utxo| utxo.value).sum();
if let Some(file) = args.output_file {
Expand Down Expand Up @@ -801,6 +802,7 @@ pub async fn command_runner(
},
CountUtxos => match output_service.get_unspent_outputs().await {
Ok(utxos) => {
let utxos: Vec<UnblindedOutput> = utxos.into_iter().map(|v| v.unblinded_output).collect();
let count = utxos.len();
let values: Vec<MicroTari> = utxos.iter().map(|utxo| utxo.value).collect();
let sum: MicroTari = values.iter().sum();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -274,7 +274,7 @@ impl wallet_server::Wallet for WalletGrpcServer {
Ok(Response::new(GetUnspentAmountsResponse {
amount: unspent_amounts
.into_iter()
.map(|o| o.value.as_u64())
.map(|o| o.unblinded_output.value.as_u64())
.filter(|&a| a > 0)
.collect(),
}))
Expand Down
6 changes: 3 additions & 3 deletions base_layer/wallet/src/output_manager_service/handle.rs
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ use crate::output_manager_service::{
service::{Balance, OutputStatusesByTxId},
storage::{
database::OutputBackendQuery,
models::{KnownOneSidedPaymentScript, SpendingPriority},
models::{DbUnblindedOutput, KnownOneSidedPaymentScript, SpendingPriority},
},
UtxoSelectionCriteria,
};
Expand Down Expand Up @@ -252,7 +252,7 @@ pub enum OutputManagerResponse {
TransactionToSend(SenderTransactionProtocol),
TransactionCancelled,
SpentOutputs(Vec<UnblindedOutput>),
UnspentOutputs(Vec<UnblindedOutput>),
UnspentOutputs(Vec<DbUnblindedOutput>),
Outputs(Vec<UnblindedOutput>),
InvalidOutputs(Vec<UnblindedOutput>),
BaseNodePublicKeySet,
Expand Down Expand Up @@ -625,7 +625,7 @@ impl OutputManagerHandle {
}

/// Sorted from lowest value to highest
pub async fn get_unspent_outputs(&mut self) -> Result<Vec<UnblindedOutput>, OutputManagerError> {
pub async fn get_unspent_outputs(&mut self) -> Result<Vec<DbUnblindedOutput>, OutputManagerError> {
match self.handle.call(OutputManagerRequest::GetUnspentOutputs).await?? {
OutputManagerResponse::UnspentOutputs(s) => Ok(s),
_ => Err(OutputManagerError::UnexpectedApiResponse),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -161,6 +161,8 @@ where
None,
Some(proof),
output_source,
None,
None,
)?;
let tx_id = TxId::new_random();
let output_hex = db_output.commitment.to_hex();
Expand Down
41 changes: 37 additions & 4 deletions base_layer/wallet/src/output_manager_service/service.rs
Original file line number Diff line number Diff line change
Expand Up @@ -351,7 +351,7 @@ where
Ok(OutputManagerResponse::SpentOutputs(outputs))
},
OutputManagerRequest::GetUnspentOutputs => {
let outputs = self.fetch_unspent_outputs()?.into_iter().map(|v| v.into()).collect();
let outputs = self.fetch_unspent_outputs()?;
Ok(OutputManagerResponse::UnspentOutputs(outputs))
},
OutputManagerRequest::GetOutputsBy(q) => {
Expand Down Expand Up @@ -650,6 +650,8 @@ where
&self.resources.factories,
spend_priority,
OutputSource::default(),
tx_id,
None,
)?;
debug!(
target: LOG_TARGET,
Expand Down Expand Up @@ -688,6 +690,8 @@ where
spend_priority,
None,
OutputSource::default(),
tx_id,
None,
)?;
debug!(
target: LOG_TARGET,
Expand Down Expand Up @@ -728,6 +732,8 @@ where
&self.resources.factories,
spend_priority,
OutputSource::default(),
Some(tx_id),
None,
)?;
self.resources.db.add_unvalidated_output(tx_id, output)?;

Expand Down Expand Up @@ -844,6 +850,8 @@ where
None,
None,
OutputSource::default(),
Some(single_round_sender_data.tx_id),
None,
)?;

self.resources
Expand Down Expand Up @@ -1046,6 +1054,8 @@ where
None,
None,
OutputSource::default(),
Some(tx_id),
None,
)?);
}

Expand Down Expand Up @@ -1110,6 +1120,8 @@ where
None,
None,
OutputSource::Coinbase,
Some(tx_id),
None,
)?;

// If there is no existing output available, we store the one we produced.
Expand Down Expand Up @@ -1203,13 +1215,15 @@ where
None,
None,
OutputSource::default(),
None,
None,
)?)
}

let mut stp = builder
.build(&self.resources.factories, None, u64::MAX)
.map_err(|e| OutputManagerError::BuildError(e.message))?;

let tx_id = stp.get_tx_id()?;
if let Some(unblinded_output) = stp.get_change_unblinded_output()? {
db_outputs.push(DbUnblindedOutput::rewindable_from_unblinded_output(
unblinded_output,
Expand All @@ -1218,9 +1232,10 @@ where
None,
None,
OutputSource::default(),
Some(tx_id),
None,
)?);
}
let tx_id = stp.get_tx_id()?;

self.resources
.db
Expand Down Expand Up @@ -1325,6 +1340,8 @@ where
None,
None,
OutputSource::default(),
Some(tx_id),
None,
)?;
builder
.with_output(utxo.unblinded_output.clone(), sender_offset_private_key.clone())
Expand Down Expand Up @@ -1365,6 +1382,8 @@ where
None,
None,
OutputSource::default(),
Some(tx_id),
None,
)?;
outputs.push(change_output);
}
Expand Down Expand Up @@ -1820,6 +1839,8 @@ where
None,
None,
OutputSource::default(),
None,
None,
)?;

tx_builder
Expand Down Expand Up @@ -2039,6 +2060,8 @@ where
None,
None,
OutputSource::default(),
None,
None,
)?;

tx_builder
Expand Down Expand Up @@ -2097,6 +2120,8 @@ where
None,
None,
OutputSource::default(),
Some(tx_id),
None,
)?);
}

Expand Down Expand Up @@ -2246,6 +2271,8 @@ where
None,
None,
OutputSource::default(),
None,
None,
)?;

tx_builder
Expand Down Expand Up @@ -2408,6 +2435,8 @@ where
None,
None,
OutputSource::AtomicSwap,
Some(tx_id),
None,
)?;
outputs.push(change_output);

Expand Down Expand Up @@ -2495,6 +2524,8 @@ where
None,
None,
OutputSource::Refund,
Some(tx_id),
None,
)?;
outputs.push(change_output);

Expand Down Expand Up @@ -2645,6 +2676,7 @@ where
output.minimum_value_promise,
);

let tx_id = TxId::new_random();
let db_output = DbUnblindedOutput::rewindable_from_unblinded_output(
rewound_output.clone(),
&self.resources.factories,
Expand All @@ -2655,10 +2687,11 @@ where
None,
Some(&output.proof),
output_source,
Some(tx_id),
None,
)?;

let output_hex = output.commitment.to_hex();
let tx_id = TxId::new_random();

match self.resources.db.add_unspent_output_with_tx_id(tx_id, db_output) {
Ok(_) => {
Expand Down
15 changes: 14 additions & 1 deletion base_layer/wallet/src/output_manager_service/storage/models.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,10 @@ use std::cmp::Ordering;

use chrono::NaiveDateTime;
use derivative::Derivative;
use tari_common_types::types::{BlockHash, BulletRangeProof, Commitment, HashOutput, PrivateKey};
use tari_common_types::{
transaction::TxId,
types::{BlockHash, BulletRangeProof, Commitment, HashOutput, PrivateKey},
};
use tari_core::transactions::{
transaction_components::UnblindedOutput,
transaction_protocol::RewindData,
Expand All @@ -51,6 +54,8 @@ pub struct DbUnblindedOutput {
pub marked_deleted_in_block: Option<BlockHash>,
pub spending_priority: SpendingPriority,
pub source: OutputSource,
pub received_in_tx_id: Option<TxId>,
pub spent_in_tx_id: Option<TxId>,
}

impl DbUnblindedOutput {
Expand All @@ -59,6 +64,8 @@ impl DbUnblindedOutput {
factory: &CryptoFactories,
spend_priority: Option<SpendingPriority>,
source: OutputSource,
received_in_tx_id: Option<TxId>,
spent_in_tx_id: Option<TxId>,
) -> Result<DbUnblindedOutput, OutputManagerStorageError> {
let tx_out = output.as_transaction_output(factory)?;
Ok(DbUnblindedOutput {
Expand All @@ -74,6 +81,8 @@ impl DbUnblindedOutput {
marked_deleted_in_block: None,
spending_priority: spend_priority.unwrap_or(SpendingPriority::Normal),
source,
received_in_tx_id,
spent_in_tx_id,
})
}

Expand All @@ -84,6 +93,8 @@ impl DbUnblindedOutput {
spending_priority: Option<SpendingPriority>,
proof: Option<&BulletRangeProof>,
source: OutputSource,
received_in_tx_id: Option<TxId>,
spent_in_tx_id: Option<TxId>,
) -> Result<DbUnblindedOutput, OutputManagerStorageError> {
let tx_out = output.as_rewindable_transaction_output(factory, rewind_data, proof)?;
Ok(DbUnblindedOutput {
Expand All @@ -99,6 +110,8 @@ impl DbUnblindedOutput {
marked_deleted_in_block: None,
spending_priority: spending_priority.unwrap_or(SpendingPriority::Normal),
source,
received_in_tx_id,
spent_in_tx_id,
})
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1412,6 +1412,7 @@ mod test {
(input, unblinded_output)
}

#[allow(clippy::too_many_lines)]
#[test]
fn test_crud() {
let db_name = format!("{}.sqlite3", random::string(8).as_str());
Expand Down Expand Up @@ -1439,7 +1440,8 @@ mod test {

for _i in 0..2 {
let (_, uo) = make_input(MicroTari::from(100 + OsRng.next_u64() % 1000));
let uo = DbUnblindedOutput::from_unblinded_output(uo, &factories, None, OutputSource::Unknown).unwrap();
let uo = DbUnblindedOutput::from_unblinded_output(uo, &factories, None, OutputSource::Unknown, None, None)
.unwrap();
let o = NewOutputSql::new(uo, OutputStatus::Unspent, None, None, &cipher).unwrap();
outputs.push(o.clone());
outputs_unspent.push(o.clone());
Expand All @@ -1448,7 +1450,8 @@ mod test {

for _i in 0..3 {
let (_, uo) = make_input(MicroTari::from(100 + OsRng.next_u64() % 1000));
let uo = DbUnblindedOutput::from_unblinded_output(uo, &factories, None, OutputSource::Unknown).unwrap();
let uo = DbUnblindedOutput::from_unblinded_output(uo, &factories, None, OutputSource::Unknown, None, None)
.unwrap();
let o = NewOutputSql::new(uo, OutputStatus::Spent, None, None, &cipher).unwrap();
outputs.push(o.clone());
outputs_spent.push(o.clone());
Expand Down Expand Up @@ -1556,7 +1559,8 @@ mod test {
let (_, uo) = make_input(MicroTari::from(100 + OsRng.next_u64() % 1000));
let decrypted_spending_key = uo.spending_key.to_vec();

let uo = DbUnblindedOutput::from_unblinded_output(uo, &factories, None, OutputSource::Unknown).unwrap();
let uo =
DbUnblindedOutput::from_unblinded_output(uo, &factories, None, OutputSource::Unknown, None, None).unwrap();

let output = NewOutputSql::new(uo, OutputStatus::Unspent, None, None, &cipher).unwrap();

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -795,6 +795,8 @@ impl OutputSql {
marked_deleted_in_block,
spending_priority,
source: o.source.try_into()?,
received_in_tx_id: o.received_in_tx_id.map(|d| (d as u64).into()),
spent_in_tx_id: o.spent_in_tx_id.map(|d| (d as u64).into()),
})
}
}
Expand Down
Loading

0 comments on commit 7eeeff4

Please sign in to comment.