From 2f491fa98722394b69d0a6b608207fcca2b75e35 Mon Sep 17 00:00:00 2001 From: SW van Heerden Date: Thu, 1 Aug 2024 07:33:01 +0200 Subject: [PATCH] feat: check address features on send (#6433) Description --- Add checking of addresses on send Motivation and Context --- We should not send a transaction to an address not accepting that feature. This will check the network and if the address accepts interactive/one-sided --- .../wallet/src/transaction_service/service.rs | 32 +++++++++++++------ 1 file changed, 22 insertions(+), 10 deletions(-) diff --git a/base_layer/wallet/src/transaction_service/service.rs b/base_layer/wallet/src/transaction_service/service.rs index 3203d91c97..f55825672f 100644 --- a/base_layer/wallet/src/transaction_service/service.rs +++ b/base_layer/wallet/src/transaction_service/service.rs @@ -1064,13 +1064,13 @@ where reply_channel: oneshot::Sender>, ) -> Result<(), TransactionServiceError> { let tx_id = TxId::new_random(); - if destination.network() != self.resources.interactive_tari_address.network() { + if let Err(e) = self.verify_send(&destination, TariAddressFeatures::create_interactive_only()) { let _result = reply_channel .send(Err(TransactionServiceError::InvalidNetwork)) .inspect_err(|_| { warn!(target: LOG_TARGET, "Failed to send service reply"); }); - return Err(TransactionServiceError::InvalidNetwork); + return Err(e); } // If we're paying ourselves, let's complete and submit the transaction immediately if &self @@ -1408,6 +1408,7 @@ where >, ) -> Result, TransactionServiceError> { let tx_id = TxId::new_random(); + self.verify_send(&destination, TariAddressFeatures::create_one_sided_only())?; // this can be anything, so lets generate a random private key let pre_image = PublicKey::from_secret_key(&PrivateKey::random(&mut OsRng)); let hash: [u8; 32] = Sha256::digest(pre_image.as_bytes()).into(); @@ -1421,7 +1422,7 @@ where HashSha256 PushHash(Box::new(hash)) Equal IfThen PushPubKey(Box::new(destination.public_spend_key().clone())) Else - CheckHeightVerify(height) PushPubKey(Box::new(self.resources.node_identity.public_key().clone())) + CheckHeightVerify(height) PushPubKey(Box::new(self.resources.one_sided_tari_address.public_spend_key().clone())) EndIf ); @@ -1643,6 +1644,7 @@ where payment_id: PaymentId, ) -> Result { let tx_id = TxId::new_random(); + self.verify_send(&dest_address, TariAddressFeatures::create_one_sided_only())?; // For a stealth transaction, the script is not provided because the public key that should be included // is not known at this stage. This will only be known later. For now, @@ -1871,9 +1873,6 @@ where JoinHandle>>, >, ) -> Result { - if destination.network() != self.resources.one_sided_tari_address.network() { - return Err(TransactionServiceError::InvalidNetwork); - } let dest_pubkey = destination.public_spend_key().clone(); self.send_one_sided_or_stealth( destination, @@ -2202,10 +2201,6 @@ where JoinHandle>>, >, ) -> Result { - if destination.network() != self.resources.one_sided_tari_address.network() { - return Err(TransactionServiceError::InvalidNetwork); - } - self.send_one_sided_or_stealth( destination, amount, @@ -3342,6 +3337,23 @@ where fn connectivity(&self) -> &TWalletConnectivity { &self.resources.connectivity } + + fn verify_send( + &self, + address: &TariAddress, + sending_method: TariAddressFeatures, + ) -> Result<(), TransactionServiceError> { + if address.network() != self.resources.interactive_tari_address.network() { + return Err(TransactionServiceError::InvalidNetwork); + } + if !address.features().contains(sending_method) { + return Err(TransactionServiceError::InvalidAddress(format!( + "Address does not support feature {} ", + sending_method + ))); + } + Ok(()) + } } /// This struct is a collection of the common resources that a protocol in the service requires.