diff --git a/applications/minotari_console_wallet/src/automation/commands.rs b/applications/minotari_console_wallet/src/automation/commands.rs index f14225dd51..8b6aba941b 100644 --- a/applications/minotari_console_wallet/src/automation/commands.rs +++ b/applications/minotari_console_wallet/src/automation/commands.rs @@ -42,6 +42,7 @@ use minotari_wallet::{ connectivity_service::WalletConnectivityInterface, output_manager_service::{ handle::{OutputManagerEvent, OutputManagerHandle}, + service::UseOutput, UtxoSelectionCriteria, }, transaction_service::{ @@ -207,6 +208,7 @@ async fn encumber_aggregate_utxo( dh_shared_secret_shares: Vec, recipient_address: TariAddress, original_maturity: u64, + use_output: UseOutput, ) -> Result<(TxId, Transaction, PublicKey, PublicKey, PublicKey), CommandError> { wallet_transaction_service .encumber_aggregate_utxo( @@ -220,6 +222,7 @@ async fn encumber_aggregate_utxo( dh_shared_secret_shares, recipient_address, original_maturity, + use_output, ) .await .map_err(CommandError::TransactionServiceError) @@ -1261,6 +1264,11 @@ pub async fn command_runner( dh_shared_secret_shares, current_recipient_address, original_maturity, + if pre_mine_from_file.is_some() { + UseOutput::AsProvided(embedded_output) + } else { + UseOutput::FromBlockchain + }, ) .await { diff --git a/base_layer/wallet/src/output_manager_service/handle.rs b/base_layer/wallet/src/output_manager_service/handle.rs index 80ec75e3bf..79ab99f6cf 100644 --- a/base_layer/wallet/src/output_manager_service/handle.rs +++ b/base_layer/wallet/src/output_manager_service/handle.rs @@ -46,7 +46,7 @@ use tower::Service; use crate::output_manager_service::{ error::OutputManagerError, - service::{Balance, OutputInfoByTxId}, + service::{Balance, OutputInfoByTxId, UseOutput}, storage::models::{DbWalletOutput, KnownOneSidedPaymentScript, SpendingPriority}, UtxoSelectionCriteria, }; @@ -73,6 +73,7 @@ pub enum OutputManagerRequest { dh_shared_secret_shares: Vec, recipient_address: TariAddress, original_maturity: u64, + use_output: UseOutput, }, SpendBackupPreMineUtxo { tx_id: TxId, @@ -817,6 +818,7 @@ impl OutputManagerHandle { dh_shared_secret_shares: Vec, recipient_address: TariAddress, original_maturity: u64, + use_output: UseOutput, ) -> Result< ( Transaction, @@ -842,6 +844,7 @@ impl OutputManagerHandle { dh_shared_secret_shares, recipient_address, original_maturity, + use_output, }) .await?? { diff --git a/base_layer/wallet/src/output_manager_service/service.rs b/base_layer/wallet/src/output_manager_service/service.rs index b02c2edda6..c62eb50762 100644 --- a/base_layer/wallet/src/output_manager_service/service.rs +++ b/base_layer/wallet/src/output_manager_service/service.rs @@ -258,6 +258,7 @@ where dh_shared_secret_shares, recipient_address, original_maturity, + use_output, } => self .encumber_aggregate_utxo( tx_id, @@ -274,6 +275,7 @@ where original_maturity, RangeProofType::BulletProofPlus, 0.into(), + use_output, ) .await .map(OutputManagerResponse::EncumberAggregateUtxo), @@ -1255,6 +1257,7 @@ where original_maturity: u64, range_proof_type: RangeProofType, minimum_value_promise: MicroMinotari, + use_output: UseOutput, ) -> Result< ( Transaction, @@ -1267,17 +1270,20 @@ where OutputManagerError, > { trace!(target: LOG_TARGET, "encumber_aggregate_utxo: start"); - // Fetch the output from the blockchain - let output = self - .fetch_unspent_outputs_from_node(vec![output_hash]) - .await? - .pop() - .ok_or_else(|| { - OutputManagerError::ServiceError(format!( - "Output with hash {} not found in blockchain (TxId: {})", - output_hash, tx_id - )) - })?; + // Fetch the output from the blockchain or use provided + let output = match use_output { + UseOutput::FromBlockchain => self + .fetch_unspent_outputs_from_node(vec![output_hash]) + .await? + .pop() + .ok_or_else(|| { + OutputManagerError::ServiceError(format!( + "Output with hash {} not found in blockchain (TxId: {})", + output_hash, tx_id + )) + })?, + UseOutput::AsProvided(val) => val, + }; if output.commitment != expected_commitment { return Err(OutputManagerError::ServiceError(format!( "Output commitment does not match expected commitment (TxId: {})", @@ -3299,6 +3305,16 @@ where } } +/// Use the provided output when encumbering an aggregate UTXO or not, for use with +/// `fn encumber_aggregate_utxo` +#[derive(Clone)] +pub enum UseOutput { + /// The transaction output will be fetched from the blockchain + FromBlockchain, + /// The transaction output must be provided + AsProvided(TransactionOutput), +} + fn get_multi_sig_script_components( script: &TariScript, tx_id: TxId, diff --git a/base_layer/wallet/src/transaction_service/handle.rs b/base_layer/wallet/src/transaction_service/handle.rs index 39fa8f6905..ac7b1e3e89 100644 --- a/base_layer/wallet/src/transaction_service/handle.rs +++ b/base_layer/wallet/src/transaction_service/handle.rs @@ -60,7 +60,7 @@ use tokio::sync::broadcast; use tower::Service; use crate::{ - output_manager_service::UtxoSelectionCriteria, + output_manager_service::{service::UseOutput, UtxoSelectionCriteria}, transaction_service::{ error::TransactionServiceError, storage::models::{ @@ -113,6 +113,7 @@ pub enum TransactionServiceRequest { dh_shared_secret_shares: Vec, recipient_address: TariAddress, original_maturity: u64, + use_output: UseOutput, }, SpendBackupPreMineUtxo { fee_per_gram: MicroMinotari, @@ -756,6 +757,7 @@ impl TransactionServiceHandle { dh_shared_secret_shares: Vec, recipient_address: TariAddress, original_maturity: u64, + use_output: UseOutput, ) -> Result<(TxId, Transaction, PublicKey, PublicKey, PublicKey), TransactionServiceError> { match self .handle @@ -770,6 +772,7 @@ impl TransactionServiceHandle { dh_shared_secret_shares, recipient_address, original_maturity, + use_output, }) .await?? { diff --git a/base_layer/wallet/src/transaction_service/service.rs b/base_layer/wallet/src/transaction_service/service.rs index e1ef3ca9c1..4b44d9a3bc 100644 --- a/base_layer/wallet/src/transaction_service/service.rs +++ b/base_layer/wallet/src/transaction_service/service.rs @@ -92,6 +92,7 @@ use crate::{ connectivity_service::WalletConnectivityInterface, output_manager_service::{ handle::{OutputManagerEvent, OutputManagerHandle}, + service::UseOutput, storage::models::SpendingPriority, UtxoSelectionCriteria, }, @@ -711,6 +712,7 @@ where dh_shared_secret_shares, recipient_address, original_maturity, + use_output, } => self .encumber_aggregate_tx( fee_per_gram, @@ -723,6 +725,7 @@ where dh_shared_secret_shares, recipient_address, original_maturity, + use_output, ) .await .map( @@ -1208,6 +1211,7 @@ where dh_shared_secret_shares: Vec, recipient_address: TariAddress, original_maturity: u64, + use_output: UseOutput, ) -> Result<(TxId, Transaction, PublicKey, PublicKey, PublicKey), TransactionServiceError> { let tx_id = TxId::new_random(); @@ -1226,6 +1230,7 @@ where dh_shared_secret_shares, recipient_address.clone(), original_maturity, + use_output, ) .await {