From 469e5f00a4fa74f058f8aac0e6982cf153d426fa Mon Sep 17 00:00:00 2001 From: Hansie Odendaal Date: Mon, 2 Dec 2024 18:49:15 +0200 Subject: [PATCH] Add addresses to encrypted data Added sender and receiver addresses to encrypted data so a view only wallet will be able to identify the receiver when importing a change output. --- Cargo.lock | 1 + base_layer/core/Cargo.toml | 1 + .../transaction_components/encrypted_data.rs | 418 ++++++++++++++---- .../transaction_protocol/sender.rs | 6 + .../transaction_initializer.rs | 28 +- .../src/output_manager_service/handle.rs | 35 +- .../src/output_manager_service/service.rs | 25 +- .../protocols/transaction_send_protocol.rs | 9 +- .../wallet/src/transaction_service/service.rs | 30 +- .../src/transaction_service/storage/models.rs | 4 + .../transaction_service/storage/sqlite_db.rs | 7 + .../utxo_scanner_service/utxo_scanner_task.rs | 6 +- .../output_manager_service_tests/service.rs | 29 ++ .../transaction_service_tests/service.rs | 12 + .../transaction_service_tests/storage.rs | 3 + .../wallet_ffi/src/callback_handler_tests.rs | 3 +- 16 files changed, 524 insertions(+), 93 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index a295012f50..a494c6e98c 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -6676,6 +6676,7 @@ dependencies = [ "serial_test", "sha2 0.10.8", "sha3", + "static_assertions", "strum", "strum_macros", "tari-tiny-keccak", diff --git a/base_layer/core/Cargo.toml b/base_layer/core/Cargo.toml index 9326422f1f..a01fe9f6e9 100644 --- a/base_layer/core/Cargo.toml +++ b/base_layer/core/Cargo.toml @@ -113,6 +113,7 @@ tempfile = "3.1.0" toml = { version = "0.5" } quickcheck = "1.0" serial_test = "0.5" +static_assertions = "1.1.0" [build-dependencies] tari_common = { path = "../../common", features = [ diff --git a/base_layer/core/src/transactions/transaction_components/encrypted_data.rs b/base_layer/core/src/transactions/transaction_components/encrypted_data.rs index 070d2c45aa..2cd97c8ace 100644 --- a/base_layer/core/src/transactions/transaction_components/encrypted_data.rs +++ b/base_layer/core/src/transactions/transaction_components/encrypted_data.rs @@ -42,6 +42,7 @@ use chacha20poly1305::{ XNonce, }; use digest::{consts::U32, generic_array::GenericArray, FixedOutput}; +use num_traits::ToBytes; use primitive_types::U256; use serde::{Deserialize, Serialize}; use tari_common_types::{ @@ -67,6 +68,7 @@ const SIZE_NONCE: usize = size_of::(); const SIZE_VALUE: usize = size_of::(); const SIZE_MASK: usize = PrivateKey::KEY_LEN; const SIZE_TAG: usize = size_of::(); +const SIZE_U256: usize = size_of::(); pub const STATIC_ENCRYPTED_DATA_SIZE_TOTAL: usize = SIZE_NONCE + SIZE_VALUE + SIZE_MASK + SIZE_TAG; const MAX_ENCRYPTED_DATA_SIZE: usize = 256 + STATIC_ENCRYPTED_DATA_SIZE_TOTAL; @@ -86,26 +88,49 @@ pub enum PaymentId { U256(U256), Address(TariAddress), Open(Vec), - AddressAndData(TariAddress, Vec), + AddressAndData { + sender_address: TariAddress, + id: Vec, + }, + ChangeData { + recipient_address: TariAddress, + amount: MicroMinotari, + msg_and_id: Vec, + }, } impl PaymentId { pub fn get_size(&self) -> usize { match self { PaymentId::Empty => 0, - PaymentId::U64(_) => size_of::(), - PaymentId::U256(_) => size_of::(), + PaymentId::U64(_) => SIZE_VALUE, + PaymentId::U256(_) => SIZE_U256, PaymentId::Address(a) => a.get_size(), PaymentId::Open(v) => v.len(), - PaymentId::AddressAndData(a, v) => a.get_size() + v.len(), + PaymentId::AddressAndData { sender_address, id } => sender_address.get_size() + id.len(), + PaymentId::ChangeData { + recipient_address, + amount: _amount, + msg_and_id, + } => recipient_address.get_size() + SIZE_VALUE + msg_and_id.len(), } } pub fn get_data(&self) -> Vec { match &self { - PaymentId::Empty | PaymentId::U64(_) | PaymentId::U256(_) | PaymentId::Address(_) => Vec::new(), + PaymentId::Empty => { + vec![] + }, + PaymentId::U64(v) => v.to_le_bytes().to_vec(), + PaymentId::U256(v) => { + let bytes: &mut [u8] = &mut [0; SIZE_U256]; + v.to_little_endian(bytes); + bytes.to_vec() + }, + PaymentId::Address(v) => v.to_vec(), PaymentId::Open(v) => v.clone(), - PaymentId::AddressAndData(_v, d) => d.clone(), + PaymentId::AddressAndData { id, .. } => id.clone(), + PaymentId::ChangeData { msg_and_id, .. } => msg_and_id.clone(), } } @@ -120,9 +145,19 @@ impl PaymentId { }, PaymentId::Address(v) => v.to_vec(), PaymentId::Open(v) => v.clone(), - PaymentId::AddressAndData(v, d) => { - let mut bytes = v.to_vec(); - bytes.extend_from_slice(d); + PaymentId::AddressAndData { sender_address, id } => { + let mut bytes = sender_address.to_vec(); + bytes.extend_from_slice(id); + bytes + }, + PaymentId::ChangeData { + recipient_address, + amount, + msg_and_id, + } => { + let mut bytes = amount.as_u64().to_le_bytes().to_vec(); + bytes.extend_from_slice(&recipient_address.to_vec()); + bytes.extend_from_slice(msg_and_id); bytes }, } @@ -131,50 +166,87 @@ impl PaymentId { pub fn from_bytes(bytes: &[u8]) -> Result { match bytes.len() { 0 => Ok(PaymentId::Empty), - 8 => { - let bytes: [u8; 8] = bytes.try_into().expect("Cannot fail, as we already test the length"); + SIZE_VALUE => { + let bytes: [u8; SIZE_VALUE] = bytes.try_into().expect("Cannot fail, as we already test the length"); let v = u64::from_le_bytes(bytes); Ok(PaymentId::U64(v)) }, - 32 => { + SIZE_U256 => { let v = U256::from_little_endian(bytes); Ok(PaymentId::U256(v)) }, - TARI_ADDRESS_INTERNAL_DUAL_SIZE => { - let v = - TariAddress::from_bytes(bytes).map_err(|e| EncryptedDataError::ByteArrayError(e.to_string()))?; - Ok(PaymentId::Address(v)) - }, - TARI_ADDRESS_INTERNAL_SINGLE_SIZE => { - let v = - TariAddress::from_bytes(bytes).map_err(|e| EncryptedDataError::ByteArrayError(e.to_string()))?; - Ok(PaymentId::Address(v)) - }, - len if len < TARI_ADDRESS_INTERNAL_SINGLE_SIZE => Ok(PaymentId::Open(bytes.to_vec())), - len if len < TARI_ADDRESS_INTERNAL_DUAL_SIZE => { - if let Ok(address) = TariAddress::from_bytes(&bytes[0..TARI_ADDRESS_INTERNAL_SINGLE_SIZE]) { - Ok(PaymentId::AddressAndData( - address, - bytes[TARI_ADDRESS_INTERNAL_SINGLE_SIZE..].to_vec(), - )) + len if len <= TARI_ADDRESS_INTERNAL_SINGLE_SIZE => { + if let Ok(v) = TariAddress::from_bytes(bytes) { + // Single + Ok(PaymentId::Address(v)) } else { + // data Ok(PaymentId::Open(bytes.to_vec())) } }, _ => { - if let Ok(address) = TariAddress::from_bytes(&bytes[0..TARI_ADDRESS_INTERNAL_SINGLE_SIZE]) { - Ok(PaymentId::AddressAndData( - address, - bytes[TARI_ADDRESS_INTERNAL_SINGLE_SIZE..].to_vec(), - )) - } else if let Ok(address) = TariAddress::from_bytes(&bytes[0..TARI_ADDRESS_INTERNAL_DUAL_SIZE]) { - Ok(PaymentId::AddressAndData( - address, - bytes[TARI_ADDRESS_INTERNAL_DUAL_SIZE..].to_vec(), - )) - } else { - Ok(PaymentId::Open(bytes.to_vec())) + // PaymentId::Address + if let Ok(v) = TariAddress::from_bytes(bytes) { + // Dual + return Ok(PaymentId::Address(v)); + } + // PaymentId::AddressAndData + if bytes.len() > TARI_ADDRESS_INTERNAL_DUAL_SIZE { + // Dual + data + if let Ok(sender_address) = TariAddress::from_bytes(&bytes[0..TARI_ADDRESS_INTERNAL_DUAL_SIZE]) { + return Ok(PaymentId::AddressAndData { + sender_address, + id: bytes[TARI_ADDRESS_INTERNAL_DUAL_SIZE..].to_vec(), + }); + } } + if bytes.len() > TARI_ADDRESS_INTERNAL_SINGLE_SIZE { + // Single + data + if let Ok(sender_address) = TariAddress::from_bytes(&bytes[0..TARI_ADDRESS_INTERNAL_SINGLE_SIZE]) { + return Ok(PaymentId::AddressAndData { + sender_address, + id: bytes[TARI_ADDRESS_INTERNAL_SINGLE_SIZE..].to_vec(), + }); + } + } + // PaymentId::ChangeData + let mut le_bytes = [0u8; SIZE_VALUE]; + le_bytes.copy_from_slice(&bytes[0..SIZE_VALUE]); + let amount = u64::from_le_bytes(le_bytes); + // Amount + Single/Dual + if let Ok(recipient_address) = TariAddress::from_bytes(&bytes[SIZE_VALUE..]) { + return Ok(PaymentId::ChangeData { + recipient_address, + amount: MicroMinotari::from(amount), + msg_and_id: Vec::new(), + }); + } + if bytes.len() > SIZE_VALUE + TARI_ADDRESS_INTERNAL_DUAL_SIZE { + if let Ok(recipient_address) = + TariAddress::from_bytes(&bytes[SIZE_VALUE..SIZE_VALUE + TARI_ADDRESS_INTERNAL_DUAL_SIZE]) + { + // Amount + Dual + data + return Ok(PaymentId::ChangeData { + recipient_address, + amount: MicroMinotari::from(amount), + msg_and_id: bytes[SIZE_VALUE + TARI_ADDRESS_INTERNAL_DUAL_SIZE..].to_vec(), + }); + } + } + if bytes.len() > SIZE_VALUE + TARI_ADDRESS_INTERNAL_SINGLE_SIZE { + if let Ok(recipient_address) = + TariAddress::from_bytes(&bytes[SIZE_VALUE..SIZE_VALUE + TARI_ADDRESS_INTERNAL_SINGLE_SIZE]) + { + // Amount + Single + data + return Ok(PaymentId::ChangeData { + recipient_address, + amount: MicroMinotari::from(amount), + msg_and_id: bytes[SIZE_VALUE + TARI_ADDRESS_INTERNAL_SINGLE_SIZE..].to_vec(), + }); + } + } + // Single + Ok(PaymentId::Open(bytes.to_vec())) }, } } @@ -188,7 +260,21 @@ impl Display for PaymentId { PaymentId::U256(v) => write!(f, "u256({v})"), PaymentId::Address(v) => write!(f, "address({})", v.to_base58()), PaymentId::Open(v) => write!(f, "data({})", v.to_hex()), - PaymentId::AddressAndData(v, d) => write!(f, "address_and_data({},{})", v.to_base58(), d.to_hex()), + PaymentId::AddressAndData { + sender_address: v, + id: d, + } => write!(f, "address_and_data({},{})", v.to_base58(), d.to_hex()), + PaymentId::ChangeData { + recipient_address, + amount, + msg_and_id, + } => write!( + f, + "change_data({},{},{})", + recipient_address.to_base58(), + amount, + msg_and_id.to_hex() + ), } } } @@ -388,11 +474,118 @@ fn kdf_aead(encryption_key: &PrivateKey, commitment: &Commitment) -> EncryptedDa #[cfg(test)] mod test { + use static_assertions::const_assert; use tari_common_types::types::CommitmentFactory; use tari_crypto::commitment::HomomorphicCommitmentFactory; use super::*; + #[test] + fn address_sizes_increase_as_expected() { + const_assert!(SIZE_VALUE < SIZE_U256); + const_assert!(SIZE_U256 < TARI_ADDRESS_INTERNAL_SINGLE_SIZE); + const_assert!(TARI_ADDRESS_INTERNAL_SINGLE_SIZE < TARI_ADDRESS_INTERNAL_DUAL_SIZE); + } + + fn encrypt_decrypt_payment_id(payment_id: PaymentId) -> PaymentId { + let (value, mask) = (u64::MAX, PrivateKey::random(&mut OsRng)); + let commitment = CommitmentFactory::default().commit(&mask, &PrivateKey::from(value)); + let encryption_key = PrivateKey::random(&mut OsRng); + let amount = MicroMinotari::from(value); + let encrypted_data = + EncryptedData::encrypt_data(&encryption_key, &commitment, amount, &mask, payment_id.clone()).unwrap(); + let (_decrypted_value, _decrypted_mask, decrypted_payment_id) = + EncryptedData::decrypt_data(&encryption_key, &commitment, &encrypted_data).unwrap(); + decrypted_payment_id + } + + #[test] + fn it_encrypts_and_decrypts_equivalent_structures() { + // Address vs. AddressAndData with zero data + + // Single + let payment_id_1 = + PaymentId::Address(TariAddress::from_base58("f3S7XTiyKQauZpDUjdR8NbcQ33MYJigiWiS44ccZCxwAAjk").unwrap()); + let payment_id_2 = PaymentId::AddressAndData { + sender_address: TariAddress::from_base58("f3S7XTiyKQauZpDUjdR8NbcQ33MYJigiWiS44ccZCxwAAjk").unwrap(), + id: vec![], + }; + + let decrypted_payment_id_1 = encrypt_decrypt_payment_id(payment_id_1.clone()); + let decrypted_payment_id_2 = encrypt_decrypt_payment_id(payment_id_2); + // Decrypted bytes are the same + assert_eq!(decrypted_payment_id_1.to_bytes(), decrypted_payment_id_2.to_bytes()); + // But the types are different + assert_eq!(payment_id_1, decrypted_payment_id_1); + assert_eq!(payment_id_1, decrypted_payment_id_2); + + // Dual + let payment_id_1 = PaymentId::Address( + TariAddress::from_base58( + "f425UWsDp714RiN53c1G6ek57rfFnotB5NCMyrn4iDgbR8i2sXVHa4xSsedd66o9KmkRgErQnyDdCaAdNLzcKrj7eUb", + ) + .unwrap(), + ); + let payment_id_2 = PaymentId::AddressAndData { + sender_address: TariAddress::from_base58( + "f425UWsDp714RiN53c1G6ek57rfFnotB5NCMyrn4iDgbR8i2sXVHa4xSsedd66o9KmkRgErQnyDdCaAdNLzcKrj7eUb", + ) + .unwrap(), + id: vec![], + }; + + let decrypted_payment_id_1 = encrypt_decrypt_payment_id(payment_id_1.clone()); + let decrypted_payment_id_2 = encrypt_decrypt_payment_id(payment_id_2); + // Decrypted bytes are the same + assert_eq!(decrypted_payment_id_1.to_bytes(), decrypted_payment_id_2.to_bytes()); + // But the types are different + assert_eq!(payment_id_1, decrypted_payment_id_1); + assert_eq!(payment_id_1, decrypted_payment_id_2); + } + + fn test_edge_case_address(payment_id: PaymentId) { + if let PaymentId::Address(address) = payment_id.clone() { + let payment_id_bytes = payment_id.to_bytes(); + // Manipulate the last byte to invalidate the address + let mut payment_id_2_bytes = payment_id_bytes.clone(); + let payment_id_2_bytes_len = payment_id_2_bytes.len(); + payment_id_2_bytes[payment_id_2_bytes_len - 1] += 1; + + // The original payment_id deserializes to 'PaymentId::Address' + let payment_id_from_bytes = PaymentId::from_bytes(&payment_id_bytes).unwrap(); + assert_eq!(payment_id_from_bytes, payment_id); + + // The manipulated payment_id deserializes to 'PaymentId::Open' + let payment_id_2_from_bytes = PaymentId::from_bytes(&payment_id_2_bytes).unwrap(); + assert_eq!(payment_id_2_from_bytes, PaymentId::Open(payment_id_2_bytes)); + + // All the bytes except for the last byte of the two payment ids should be the same + let address_vec = address.to_vec(); + let payment_id_2_vec = payment_id_2_from_bytes.get_data(); + assert_eq!( + address_vec[..address_vec.len() - 1], + payment_id_2_vec[..payment_id_2_vec.len() - 1] + ); + } else { + panic!("payment_id_1 should be an address"); + } + } + + #[test] + fn it_encrypts_and_decrypts_edge_cases() { + let payment_id = + PaymentId::Address(TariAddress::from_base58("f3S7XTiyKQauZpDUjdR8NbcQ33MYJigiWiS44ccZCxwAAjk").unwrap()); + test_edge_case_address(payment_id); + + let payment_id = PaymentId::Address( + TariAddress::from_base58( + "f425UWsDp714RiN53c1G6ek57rfFnotB5NCMyrn4iDgbR8i2sXVHa4xSsedd66o9KmkRgErQnyDdCaAdNLzcKrj7eUb", + ) + .unwrap(), + ); + test_edge_case_address(payment_id); + } + #[test] fn it_encrypts_and_decrypts_correctly() { for payment_id in [ @@ -411,28 +604,58 @@ mod test { PaymentId::Address(TariAddress::from_base58("f3S7XTiyKQauZpDUjdR8NbcQ33MYJigiWiS44ccZCxwAAjk").unwrap()), PaymentId::Open(vec![1, 2, 3, 4, 5, 6, 7, 8, 9, 10]), PaymentId::Open(vec![1; 256]), - PaymentId::AddressAndData( - TariAddress::from_base58( + PaymentId::AddressAndData { + sender_address: TariAddress::from_base58( "f425UWsDp714RiN53c1G6ek57rfFnotB5NCMyrn4iDgbR8i2sXVHa4xSsedd66o9KmkRgErQnyDdCaAdNLzcKrj7eUb", ) .unwrap(), - vec![1, 2, 3, 4, 5, 6, 7, 8, 9, 10], - ), - PaymentId::AddressAndData( - TariAddress::from_base58( + id: vec![1, 2, 3, 4, 5, 6, 7, 8, 9, 10], + }, + PaymentId::AddressAndData { + sender_address: TariAddress::from_base58( "f425UWsDp714RiN53c1G6ek57rfFnotB5NCMyrn4iDgbR8i2sXVHa4xSsedd66o9KmkRgErQnyDdCaAdNLzcKrj7eUb", ) .unwrap(), - vec![1; 189], - ), - PaymentId::AddressAndData( - TariAddress::from_base58("f3S7XTiyKQauZpDUjdR8NbcQ33MYJigiWiS44ccZCxwAAjk").unwrap(), - vec![1, 2, 3, 4, 5, 6, 7, 8, 9, 10], - ), - PaymentId::AddressAndData( - TariAddress::from_base58("f3S7XTiyKQauZpDUjdR8NbcQ33MYJigiWiS44ccZCxwAAjk").unwrap(), - vec![1; 189], - ), + id: vec![1; 189], + }, + PaymentId::AddressAndData { + sender_address: TariAddress::from_base58("f3S7XTiyKQauZpDUjdR8NbcQ33MYJigiWiS44ccZCxwAAjk").unwrap(), + id: vec![1, 2, 3, 4, 5, 6, 7, 8, 9, 10], + }, + PaymentId::AddressAndData { + sender_address: TariAddress::from_base58("f3S7XTiyKQauZpDUjdR8NbcQ33MYJigiWiS44ccZCxwAAjk").unwrap(), + id: vec![1; 189], + }, + // Single + amount + PaymentId::ChangeData { + recipient_address: TariAddress::from_base58("f3S7XTiyKQauZpDUjdR8NbcQ33MYJigiWiS44ccZCxwAAjk").unwrap(), + amount: MicroMinotari::from(123456), + msg_and_id: vec![], + }, + // Single + amount + data + PaymentId::ChangeData { + recipient_address: TariAddress::from_base58("f3S7XTiyKQauZpDUjdR8NbcQ33MYJigiWiS44ccZCxwAAjk").unwrap(), + amount: MicroMinotari::from(123456), + msg_and_id: vec![1, 2, 3, 4, 5, 6, 7, 8, 9, 10], + }, + // Dual + amount + PaymentId::ChangeData { + recipient_address: TariAddress::from_base58( + "f425UWsDp714RiN53c1G6ek57rfFnotB5NCMyrn4iDgbR8i2sXVHa4xSsedd66o9KmkRgErQnyDdCaAdNLzcKrj7eUb", + ) + .unwrap(), + amount: MicroMinotari::from(123456), + msg_and_id: vec![], + }, + // Dual + amount + data + PaymentId::ChangeData { + recipient_address: TariAddress::from_base58( + "f425UWsDp714RiN53c1G6ek57rfFnotB5NCMyrn4iDgbR8i2sXVHa4xSsedd66o9KmkRgErQnyDdCaAdNLzcKrj7eUb", + ) + .unwrap(), + amount: MicroMinotari::from(123456), + msg_and_id: vec![1, 2, 3, 4, 5, 6, 7, 8, 9, 10], + }, ] { for (value, mask) in [ (0, PrivateKey::default()), @@ -481,28 +704,58 @@ mod test { PaymentId::Address(TariAddress::from_base58("f3S7XTiyKQauZpDUjdR8NbcQ33MYJigiWiS44ccZCxwAAjk").unwrap()), PaymentId::Open(vec![1, 2, 3, 4, 5, 6, 7, 8, 9, 10]), PaymentId::Open(vec![1; 256]), - PaymentId::AddressAndData( - TariAddress::from_base58( + PaymentId::AddressAndData { + sender_address: TariAddress::from_base58( "f425UWsDp714RiN53c1G6ek57rfFnotB5NCMyrn4iDgbR8i2sXVHa4xSsedd66o9KmkRgErQnyDdCaAdNLzcKrj7eUb", ) .unwrap(), - vec![1, 2, 3, 4, 5, 6, 7, 8, 9, 10], - ), - PaymentId::AddressAndData( - TariAddress::from_base58( + id: vec![1, 2, 3, 4, 5, 6, 7, 8, 9, 10], + }, + PaymentId::AddressAndData { + sender_address: TariAddress::from_base58( "f425UWsDp714RiN53c1G6ek57rfFnotB5NCMyrn4iDgbR8i2sXVHa4xSsedd66o9KmkRgErQnyDdCaAdNLzcKrj7eUb", ) .unwrap(), - vec![1; 189], - ), - PaymentId::AddressAndData( - TariAddress::from_base58("f3S7XTiyKQauZpDUjdR8NbcQ33MYJigiWiS44ccZCxwAAjk").unwrap(), - vec![1, 2, 3, 4, 5, 6, 7, 8, 9, 10], - ), - PaymentId::AddressAndData( - TariAddress::from_base58("f3S7XTiyKQauZpDUjdR8NbcQ33MYJigiWiS44ccZCxwAAjk").unwrap(), - vec![1; 189], - ), + id: vec![1; 189], + }, + PaymentId::AddressAndData { + sender_address: TariAddress::from_base58("f3S7XTiyKQauZpDUjdR8NbcQ33MYJigiWiS44ccZCxwAAjk").unwrap(), + id: vec![1, 2, 3, 4, 5, 6, 7, 8, 9, 10], + }, + PaymentId::AddressAndData { + sender_address: TariAddress::from_base58("f3S7XTiyKQauZpDUjdR8NbcQ33MYJigiWiS44ccZCxwAAjk").unwrap(), + id: vec![1; 189], + }, + // Single + amount + PaymentId::ChangeData { + recipient_address: TariAddress::from_base58("f3S7XTiyKQauZpDUjdR8NbcQ33MYJigiWiS44ccZCxwAAjk").unwrap(), + amount: MicroMinotari::from(123456), + msg_and_id: vec![], + }, + // Single + amount + data + PaymentId::ChangeData { + recipient_address: TariAddress::from_base58("f3S7XTiyKQauZpDUjdR8NbcQ33MYJigiWiS44ccZCxwAAjk").unwrap(), + amount: MicroMinotari::from(123456), + msg_and_id: vec![1, 2, 3, 4, 5, 6, 7, 8, 9, 10], + }, + // Dual + amount + PaymentId::ChangeData { + recipient_address: TariAddress::from_base58( + "f425UWsDp714RiN53c1G6ek57rfFnotB5NCMyrn4iDgbR8i2sXVHa4xSsedd66o9KmkRgErQnyDdCaAdNLzcKrj7eUb", + ) + .unwrap(), + amount: MicroMinotari::from(123456), + msg_and_id: vec![], + }, + // Dual + amount + data + PaymentId::ChangeData { + recipient_address: TariAddress::from_base58( + "f425UWsDp714RiN53c1G6ek57rfFnotB5NCMyrn4iDgbR8i2sXVHa4xSsedd66o9KmkRgErQnyDdCaAdNLzcKrj7eUb", + ) + .unwrap(), + amount: MicroMinotari::from(123456), + msg_and_id: vec![1, 2, 3, 4, 5, 6, 7, 8, 9, 10], + }, ] { for (value, mask) in [ (0, PrivateKey::default()), @@ -545,12 +798,21 @@ mod test { "data(0102030405060708090a)" ); assert_eq!( - PaymentId::AddressAndData( - TariAddress::from_base58("f3S7XTiyKQauZpDUjdR8NbcQ33MYJigiWiS44ccZCxwAAjk").unwrap(), - vec![0x48, 0x65, 0x6c, 0x6c, 0x6f, 0x20, 0x57, 0x6f, 0x72, 0x6c, 0x64] - ) + PaymentId::AddressAndData { + sender_address: TariAddress::from_base58("f3S7XTiyKQauZpDUjdR8NbcQ33MYJigiWiS44ccZCxwAAjk").unwrap(), + id: vec![0x48, 0x65, 0x6c, 0x6c, 0x6f, 0x20, 0x57, 0x6f, 0x72, 0x6c, 0x64] + } .to_string(), "address_and_data(f3S7XTiyKQauZpDUjdR8NbcQ33MYJigiWiS44ccZCxwAAjk,48656c6c6f20576f726c64)" ); + assert_eq!( + PaymentId::ChangeData { + recipient_address: TariAddress::from_base58("f3S7XTiyKQauZpDUjdR8NbcQ33MYJigiWiS44ccZCxwAAjk").unwrap(), + amount: MicroMinotari::from(123456), + msg_and_id: vec![0x48, 0x65, 0x6c, 0x6c, 0x6f, 0x20, 0x57, 0x6f, 0x72, 0x6c, 0x64] + } + .to_string(), + "change_data(f3S7XTiyKQauZpDUjdR8NbcQ33MYJigiWiS44ccZCxwAAjk,123456 µT,48656c6c6f20576f726c64)" + ); } } diff --git a/base_layer/core/src/transactions/transaction_protocol/sender.rs b/base_layer/core/src/transactions/transaction_protocol/sender.rs index ef9ef19256..f6f24d700b 100644 --- a/base_layer/core/src/transactions/transaction_protocol/sender.rs +++ b/base_layer/core/src/transactions/transaction_protocol/sender.rs @@ -1130,6 +1130,7 @@ mod test { Covenant::default(), 0.into(), MicroMinotari(1200) - fee - MicroMinotari(10), + TariAddress::default(), ) .await .unwrap() @@ -1255,6 +1256,7 @@ mod test { Covenant::default(), 0.into(), MicroMinotari(5000), + TariAddress::default(), ) .await .unwrap(); @@ -1367,6 +1369,7 @@ mod test { Covenant::default(), 0.into(), MicroMinotari(5000), + TariAddress::default(), ) .await .unwrap(); @@ -1467,6 +1470,7 @@ mod test { Covenant::default(), 0.into(), amount, + TariAddress::default(), ) .await .unwrap(); @@ -1507,6 +1511,7 @@ mod test { Covenant::default(), 0.into(), amount, + TariAddress::default(), ) .await .unwrap(); @@ -1552,6 +1557,7 @@ mod test { Covenant::default(), 0.into(), MicroMinotari(5000), + TariAddress::default(), ) .await .unwrap(); diff --git a/base_layer/core/src/transactions/transaction_protocol/transaction_initializer.rs b/base_layer/core/src/transactions/transaction_protocol/transaction_initializer.rs index ff0a54f002..c814f60b06 100644 --- a/base_layer/core/src/transactions/transaction_protocol/transaction_initializer.rs +++ b/base_layer/core/src/transactions/transaction_protocol/transaction_initializer.rs @@ -79,6 +79,7 @@ pub(super) struct RecipientDetails { pub recipient_covenant: Covenant, pub recipient_minimum_value_promise: MicroMinotari, pub recipient_ephemeral_public_key_nonce: TariKeyId, + pub recipient_address: TariAddress, } /// The SenderTransactionProtocolBuilder is a Builder that helps set up the initial state for the Sender party of a new @@ -98,6 +99,7 @@ pub struct SenderTransactionInitializer { change: Option, recipient: Option, recipient_text_message: Option, + payment_id: Option, prevent_fee_gt_amount: bool, tx_id: Option, kernel_features: KernelFeatures, @@ -130,6 +132,7 @@ where KM: TransactionKeyManagerInterface sender_custom_outputs: Vec::new(), change: None, recipient_text_message: None, + payment_id: None, prevent_fee_gt_amount: true, recipient: None, kernel_features: KernelFeatures::empty(), @@ -162,6 +165,7 @@ where KM: TransactionKeyManagerInterface recipient_covenant: Covenant, recipient_minimum_value_promise: MicroMinotari, amount: MicroMinotari, + recipient_address: TariAddress, ) -> Result<&mut Self, KeyManagerServiceError> { let recipient_ephemeral_public_key_nonce = self .key_manager @@ -179,6 +183,7 @@ where KM: TransactionKeyManagerInterface recipient_minimum_value_promise, recipient_ephemeral_public_key_nonce: recipient_ephemeral_public_key_nonce.key_id, amount, + recipient_address, }; self.recipient = Some(recipient_details); Ok(self) @@ -253,6 +258,12 @@ where KM: TransactionKeyManagerInterface self } + /// Provide a text message for receiver + pub fn with_payment_id(&mut self, payment_id: PaymentId) -> &mut Self { + self.payment_id = Some(payment_id); + self + } + /// This will select the desired kernel features to be signed by the receiver pub fn with_kernel_features(&mut self, features: KernelFeatures) -> &mut Self { self.kernel_features = features; @@ -402,7 +413,19 @@ where KM: TransactionKeyManagerInterface .own_address .clone(); - let payment_id = PaymentId::Address(address); + let payment_id = if let Some(recipient) = self.recipient.clone() { + PaymentId::ChangeData { + recipient_address: recipient.recipient_address, + amount: recipient.amount, + msg_and_id: vec![], + } + } else { + PaymentId::ChangeData { + recipient_address: address, + amount: total_to_self, + msg_and_id: vec![], + } + }; let encrypted_data = self .key_manager @@ -878,6 +901,7 @@ mod test { Default::default(), 0.into(), MicroMinotari(500), + TariAddress::default(), ) .await .unwrap(); @@ -927,6 +951,7 @@ mod test { Default::default(), 0.into(), MicroMinotari::zero(), + TariAddress::default(), ) .await .unwrap(); @@ -994,6 +1019,7 @@ mod test { Default::default(), 0.into(), MicroMinotari(2500), + TariAddress::default(), ) .await .unwrap(); diff --git a/base_layer/wallet/src/output_manager_service/handle.rs b/base_layer/wallet/src/output_manager_service/handle.rs index 7f32a2f147..2b3e71878f 100644 --- a/base_layer/wallet/src/output_manager_service/handle.rs +++ b/base_layer/wallet/src/output_manager_service/handle.rs @@ -31,7 +31,14 @@ use tari_core::{ covenants::Covenant, transactions::{ tari_amount::MicroMinotari, - transaction_components::{OutputFeatures, Transaction, TransactionOutput, WalletOutput, WalletOutputBuilder}, + transaction_components::{ + encrypted_data::PaymentId, + OutputFeatures, + Transaction, + TransactionOutput, + WalletOutput, + WalletOutputBuilder, + }, transaction_protocol::{sender::TransactionSenderMessage, TransactionMetadata}, ReceiverTransactionProtocol, SenderTransactionProtocol, @@ -92,6 +99,8 @@ pub enum OutputManagerRequest { script: TariScript, covenant: Covenant, minimum_value_promise: MicroMinotari, + recipient_address: TariAddress, + payment_id: PaymentId, }, CreatePayToSelfTransaction { tx_id: TxId, @@ -119,6 +128,7 @@ pub enum OutputManagerRequest { ScrapeWallet { tx_id: TxId, fee_per_gram: MicroMinotari, + recipient_address: TariAddress, }, CreateCoinJoin { commitments: Vec, @@ -167,8 +177,16 @@ impl fmt::Display for OutputManagerRequest { v.metadata_signature.u_y().to_hex(), v.metadata_signature.u_a().to_hex(), ), - ScrapeWallet { tx_id, fee_per_gram } => { - write!(f, "ScrapeWallet (tx_id: {}, fee_per_gram: {})", tx_id, fee_per_gram) + ScrapeWallet { + tx_id, + fee_per_gram, + recipient_address, + } => { + write!( + f, + "ScrapeWallet (tx_id: {}, fee_per_gram: {}, recipient_address {})", + tx_id, fee_per_gram, recipient_address + ) }, EncumberAggregateUtxo { tx_id, @@ -509,6 +527,8 @@ impl OutputManagerHandle { script: TariScript, covenant: Covenant, minimum_value_promise: MicroMinotari, + recipient_address: TariAddress, + payment_id: PaymentId, ) -> Result { match self .handle @@ -523,6 +543,8 @@ impl OutputManagerHandle { script, covenant, minimum_value_promise, + recipient_address, + payment_id, }) .await?? { @@ -535,10 +557,15 @@ impl OutputManagerHandle { &mut self, tx_id: TxId, fee_per_gram: MicroMinotari, + recipient_address: TariAddress, ) -> Result { match self .handle - .call(OutputManagerRequest::ScrapeWallet { tx_id, fee_per_gram }) + .call(OutputManagerRequest::ScrapeWallet { + tx_id, + fee_per_gram, + recipient_address, + }) .await?? { OutputManagerResponse::TransactionToSend(stp) => Ok(stp), diff --git a/base_layer/wallet/src/output_manager_service/service.rs b/base_layer/wallet/src/output_manager_service/service.rs index 3b14cb59a1..7ac915a720 100644 --- a/base_layer/wallet/src/output_manager_service/service.rs +++ b/base_layer/wallet/src/output_manager_service/service.rs @@ -327,6 +327,8 @@ where script, covenant, minimum_value_promise, + recipient_address, + payment_id, } => self .prepare_transaction_to_send( tx_id, @@ -339,6 +341,8 @@ where script, covenant, minimum_value_promise, + recipient_address, + payment_id, ) .await .map(OutputManagerResponse::TransactionToSend), @@ -400,8 +404,12 @@ where .await?, )) }, - OutputManagerRequest::ScrapeWallet { tx_id, fee_per_gram } => self - .scrape_wallet(tx_id, fee_per_gram) + OutputManagerRequest::ScrapeWallet { + tx_id, + fee_per_gram, + recipient_address, + } => self + .scrape_wallet(tx_id, fee_per_gram, recipient_address) .await .map(OutputManagerResponse::TransactionToSend), @@ -965,6 +973,8 @@ where recipient_script: TariScript, recipient_covenant: Covenant, recipient_minimum_value_promise: MicroMinotari, + recipient_address: TariAddress, + payment_id: PaymentId, ) -> Result { debug!( target: LOG_TARGET, @@ -1011,10 +1021,12 @@ where recipient_covenant, recipient_minimum_value_promise, amount, + recipient_address, ) .await? .with_sender_address(self.resources.interactive_tari_address.clone()) .with_message(message) + .with_payment_id(payment_id) .with_prevent_fee_gt_amount(self.resources.config.prevent_fee_gt_amount) .with_lock_height(tx_meta.lock_height) .with_kernel_features(tx_meta.kernel_features) @@ -1408,6 +1420,7 @@ where Covenant::default(), minimum_value_promise, amount, + recipient_address.clone(), ) .await? .with_change_data( @@ -1740,6 +1753,7 @@ where Covenant::default(), minimum_value_promise, amount, + recipient_address.clone(), ) .await? .with_change_data( @@ -1818,7 +1832,10 @@ where .await?; let script = push_pubkey_script(&script_spending_key); let payment_id = match payment_id { - PaymentId::Open(v) => PaymentId::AddressAndData(self.resources.interactive_tari_address.clone(), v), + PaymentId::Open(v) => PaymentId::AddressAndData { + sender_address: self.resources.interactive_tari_address.clone(), + id: v, + }, PaymentId::Empty => PaymentId::Address(self.resources.one_sided_tari_address.clone()), _ => payment_id, }; @@ -2831,6 +2848,7 @@ where &mut self, tx_id: TxId, fee_per_gram: MicroMinotari, + recipient_address: TariAddress, ) -> Result { let default_features_and_scripts_size = self .default_features_and_scripts_size() @@ -2862,6 +2880,7 @@ where Default::default(), MicroMinotari::zero(), accumulated_amount, + recipient_address, ) .await? .with_sender_address(self.resources.interactive_tari_address.clone()) diff --git a/base_layer/wallet/src/transaction_service/protocols/transaction_send_protocol.rs b/base_layer/wallet/src/transaction_service/protocols/transaction_send_protocol.rs index e6c0a95f23..0fb85cbb47 100644 --- a/base_layer/wallet/src/transaction_service/protocols/transaction_send_protocol.rs +++ b/base_layer/wallet/src/transaction_service/protocols/transaction_send_protocol.rs @@ -39,7 +39,7 @@ use tari_core::{ transactions::{ key_manager::TransactionKeyManagerInterface, tari_amount::MicroMinotari, - transaction_components::OutputFeatures, + transaction_components::{encrypted_data::PaymentId, OutputFeatures}, transaction_protocol::{ proto::protocol as proto, recipient::RecipientSignedMessage, @@ -93,6 +93,7 @@ pub struct TransactionSendProtocol>>, stage: TransactionSendProtocolStage, resources: TransactionServiceResources, @@ -118,6 +119,7 @@ where amount: MicroMinotari, fee_per_gram: MicroMinotari, message: String, + payment_id: PaymentId, tx_meta: TransactionMetadata, service_request_reply_channel: Option< oneshot::Sender>, @@ -134,6 +136,7 @@ where amount, fee_per_gram, message, + payment_id, service_request_reply_channel, stage, tx_meta, @@ -228,6 +231,8 @@ where TariScript::default(), Covenant::default(), MicroMinotari::zero(), + self.dest_address.clone(), + self.payment_id.clone(), ) .await { @@ -290,6 +295,7 @@ where sender_protocol.clone(), TransactionStatus::Pending, // This does not matter for the check self.message.clone(), + self.payment_id.clone(), Utc::now().naive_utc(), true, // This does not matter for the check ); @@ -344,6 +350,7 @@ where sender_protocol.clone(), initial_send.transaction_status.clone(), self.message.clone(), + self.payment_id.clone(), Utc::now().naive_utc(), initial_send.direct_send_result, ); diff --git a/base_layer/wallet/src/transaction_service/service.rs b/base_layer/wallet/src/transaction_service/service.rs index 9988c774ff..09498212f5 100644 --- a/base_layer/wallet/src/transaction_service/service.rs +++ b/base_layer/wallet/src/transaction_service/service.rs @@ -623,6 +623,7 @@ where *output_features, fee_per_gram, message, + PaymentId::Empty, TransactionMetadata::default(), send_transaction_join_handles, transaction_broadcast_join_handles, @@ -1077,6 +1078,7 @@ where output_features: OutputFeatures, fee_per_gram: MicroMinotari, message: String, + payment_id: PaymentId, tx_meta: TransactionMetadata, join_handles: &mut FuturesUnordered< JoinHandle>>, @@ -1164,6 +1166,7 @@ where amount, fee_per_gram, message, + payment_id, tx_meta, Some(reply_channel), TransactionSendProtocolStage::Initial, @@ -1474,6 +1477,8 @@ where script.clone(), covenant.clone(), minimum_value_promise, + destination.clone(), + PaymentId::Empty, ) .await?; @@ -1672,8 +1677,14 @@ where ) -> Result { let tx_id = TxId::new_random(); let payment_id = match payment_id { - PaymentId::Open(v) => PaymentId::AddressAndData(self.resources.interactive_tari_address.clone(), v), - PaymentId::Empty => PaymentId::Address(self.resources.interactive_tari_address.clone()), + PaymentId::Open(v) => PaymentId::AddressAndData { + sender_address: self.resources.interactive_tari_address.clone(), + id: v, + }, + PaymentId::Empty => PaymentId::AddressAndData { + sender_address: self.resources.interactive_tari_address.clone(), + id: vec![], + }, _ => payment_id, }; self.verify_send(&dest_address, TariAddressFeatures::create_one_sided_only())?; @@ -1700,6 +1711,8 @@ where script.clone(), Covenant::default(), MicroMinotari::zero(), + dest_address.clone(), + payment_id.clone(), ) .await?; @@ -1914,7 +1927,7 @@ where let mut stp = self .resources .output_manager_service - .scrape_wallet(tx_id, fee_per_gram) + .scrape_wallet(tx_id, fee_per_gram, dest_address.clone()) .await?; // This call is needed to advance the state from `SingleRoundMessageReady` to `SingleRoundMessageReady`, @@ -2176,6 +2189,8 @@ where script!(Nop)?, Covenant::default(), MicroMinotari::zero(), + self.resources.interactive_tari_address.clone(), + PaymentId::Empty, ) .await?; @@ -2393,6 +2408,7 @@ where output_features, fee_per_gram, message, + PaymentId::Empty, TransactionMetadata::default(), join_handles, transaction_broadcast_join_handles, @@ -2422,6 +2438,7 @@ where OutputFeatures::for_template_registration(template_registration), fee_per_gram, message, + PaymentId::Empty, TransactionMetadata::default(), join_handles, transaction_broadcast_join_handles, @@ -2790,6 +2807,7 @@ where tx.amount, tx.fee, tx.message, + tx.payment_id, TransactionMetadata::default(), None, stage, @@ -3045,7 +3063,11 @@ where let mut amount = None; for ro in recovered { match &ro.output.payment_id { - PaymentId::AddressAndData(address, _) | PaymentId::Address(address) => { + PaymentId::AddressAndData { + sender_address: address, + id: _, + } | + PaymentId::Address(address) => { if source_address.is_none() { source_address = Some(address.clone()); payment_id = Some(ro.output.payment_id.clone()); diff --git a/base_layer/wallet/src/transaction_service/storage/models.rs b/base_layer/wallet/src/transaction_service/storage/models.rs index fa81435234..fa0c564fda 100644 --- a/base_layer/wallet/src/transaction_service/storage/models.rs +++ b/base_layer/wallet/src/transaction_service/storage/models.rs @@ -91,6 +91,7 @@ pub struct OutboundTransaction { pub sender_protocol: SenderTransactionProtocol, pub status: TransactionStatus, pub message: String, + pub payment_id: PaymentId, pub timestamp: NaiveDateTime, pub cancelled: bool, pub direct_send_success: bool, @@ -107,6 +108,7 @@ impl OutboundTransaction { sender_protocol: SenderTransactionProtocol, status: TransactionStatus, message: String, + payment_id: PaymentId, timestamp: NaiveDateTime, direct_send_success: bool, ) -> Self { @@ -118,6 +120,7 @@ impl OutboundTransaction { sender_protocol, status, message, + payment_id, timestamp, cancelled: false, direct_send_success, @@ -226,6 +229,7 @@ impl From for OutboundTransaction { sender_protocol: SenderTransactionProtocol::new_placeholder(), status: ct.status, message: ct.message, + payment_id: ct.payment_id.unwrap_or(PaymentId::Empty), timestamp: ct.timestamp, cancelled: ct.cancelled.is_some(), direct_send_success: false, diff --git a/base_layer/wallet/src/transaction_service/storage/sqlite_db.rs b/base_layer/wallet/src/transaction_service/storage/sqlite_db.rs index 14cc8ad353..38ec278a97 100644 --- a/base_layer/wallet/src/transaction_service/storage/sqlite_db.rs +++ b/base_layer/wallet/src/transaction_service/storage/sqlite_db.rs @@ -1652,6 +1652,8 @@ impl OutboundTransaction { .map_err(|e| TransactionStorageError::BincodeDeserialize(e.to_string()))?, status: TransactionStatus::Pending, message: o.message, + // TODO: Hansie, fix this in the db + payment_id: PaymentId::Empty, timestamp: o.timestamp, cancelled: o.cancelled != 0, direct_send_success: o.direct_send_success != 0, @@ -2309,6 +2311,7 @@ mod test { Default::default(), MicroMinotari::zero(), amount, + TariAddress::default(), ) .await .unwrap() @@ -2334,6 +2337,7 @@ mod test { sender_protocol: stp.clone(), status: TransactionStatus::Pending, message: "Yo!".to_string(), + payment_id: PaymentId::Empty, timestamp: Utc::now().naive_utc(), cancelled: false, direct_send_success: false, @@ -2353,6 +2357,7 @@ mod test { sender_protocol: stp.clone(), status: TransactionStatus::Pending, message: "Hey!".to_string(), + payment_id: PaymentId::Empty, timestamp: Utc::now().naive_utc(), cancelled: false, direct_send_success: false, @@ -2728,6 +2733,7 @@ mod test { sender_protocol: SenderTransactionProtocol::new_placeholder(), status: TransactionStatus::Pending, message: "Yo!".to_string(), + payment_id: PaymentId::Empty, timestamp: Utc::now().naive_utc(), cancelled: false, direct_send_success: false, @@ -2867,6 +2873,7 @@ mod test { sender_protocol: SenderTransactionProtocol::new_placeholder(), status: TransactionStatus::Pending, message: "Yo!".to_string(), + payment_id: PaymentId::Empty, timestamp: Utc::now().naive_utc(), cancelled: false, direct_send_success: false, diff --git a/base_layer/wallet/src/utxo_scanner_service/utxo_scanner_task.rs b/base_layer/wallet/src/utxo_scanner_service/utxo_scanner_task.rs index 41fb837de3..7101b78ca7 100644 --- a/base_layer/wallet/src/utxo_scanner_service/utxo_scanner_task.rs +++ b/base_layer/wallet/src/utxo_scanner_service/utxo_scanner_task.rs @@ -651,7 +651,11 @@ where self.resources.one_sided_tari_address.clone() } else { match &wo.payment_id { - PaymentId::AddressAndData(address, _) | PaymentId::Address(address) => address.clone(), + PaymentId::AddressAndData { + sender_address: address, + id: _, + } | + PaymentId::Address(address) => address.clone(), _ => TariAddress::default(), } }; diff --git a/base_layer/wallet/tests/output_manager_service_tests/service.rs b/base_layer/wallet/tests/output_manager_service_tests/service.rs index 8d82146257..a3f852a46e 100644 --- a/base_layer/wallet/tests/output_manager_service_tests/service.rs +++ b/base_layer/wallet/tests/output_manager_service_tests/service.rs @@ -269,6 +269,7 @@ async fn generate_sender_transaction_message( Covenant::default(), MicroMinotari::zero(), amount, + TariAddress::default(), ) .await .unwrap(); @@ -404,6 +405,8 @@ async fn test_utxo_selection_no_chain_metadata() { script!(Nop).unwrap(), Covenant::default(), MicroMinotari::zero(), + TariAddress::default(), + PaymentId::Empty, ) .await .unwrap_err(); @@ -440,6 +443,8 @@ async fn test_utxo_selection_no_chain_metadata() { script!(Nop).unwrap(), Covenant::default(), MicroMinotari::zero(), + TariAddress::default(), + PaymentId::Empty, ) .await .unwrap(); @@ -534,6 +539,8 @@ async fn test_utxo_selection_with_chain_metadata() { script!(Nop).unwrap(), Covenant::default(), MicroMinotari::zero(), + TariAddress::default(), + PaymentId::Empty, ) .await .unwrap_err(); @@ -616,6 +623,8 @@ async fn test_utxo_selection_with_chain_metadata() { script!(Nop).unwrap(), Covenant::default(), MicroMinotari::zero(), + TariAddress::default(), + PaymentId::Empty, ) .await .unwrap(); @@ -644,6 +653,8 @@ async fn test_utxo_selection_with_chain_metadata() { script!(Nop).unwrap(), Covenant::default(), MicroMinotari::zero(), + TariAddress::default(), + PaymentId::Empty, ) .await .unwrap(); @@ -739,6 +750,8 @@ async fn test_utxo_selection_with_tx_priority() { script!(Nop).unwrap(), Covenant::default(), MicroMinotari::zero(), + TariAddress::default(), + PaymentId::Empty, ) .await .unwrap(); @@ -785,6 +798,8 @@ async fn send_not_enough_funds() { script!(Nop).unwrap(), Covenant::default(), MicroMinotari::zero(), + TariAddress::default(), + PaymentId::Empty, ) .await { @@ -852,6 +867,8 @@ async fn send_no_change() { TariScript::default(), Covenant::default(), MicroMinotari::zero(), + TariAddress::default(), + PaymentId::Empty, ) .await .unwrap(); @@ -918,6 +935,8 @@ async fn send_not_enough_for_change() { script!(Nop).unwrap(), Covenant::default(), MicroMinotari::zero(), + TariAddress::default(), + PaymentId::Empty, ) .await { @@ -959,6 +978,8 @@ async fn cancel_transaction() { script!(Nop).unwrap(), Covenant::default(), MicroMinotari::zero(), + TariAddress::default(), + PaymentId::Empty, ) .await .unwrap(); @@ -1064,6 +1085,8 @@ async fn test_get_balance() { script!(Nop).unwrap(), Covenant::default(), MicroMinotari::zero(), + TariAddress::default(), + PaymentId::Empty, ) .await .unwrap(); @@ -1135,6 +1158,8 @@ async fn sending_transaction_persisted_while_offline() { script!(Nop).unwrap(), Covenant::default(), MicroMinotari::zero(), + TariAddress::default(), + PaymentId::Empty, ) .await .unwrap(); @@ -1168,6 +1193,8 @@ async fn sending_transaction_persisted_while_offline() { script!(Nop).unwrap(), Covenant::default(), MicroMinotari::zero(), + TariAddress::default(), + PaymentId::Empty, ) .await .unwrap(); @@ -1479,6 +1506,8 @@ async fn test_txo_validation() { TariScript::default(), Covenant::default(), MicroMinotari::zero(), + TariAddress::default(), + PaymentId::Empty, ) .await .unwrap(); diff --git a/base_layer/wallet/tests/transaction_service_tests/service.rs b/base_layer/wallet/tests/transaction_service_tests/service.rs index 15fea49f58..972bdb123c 100644 --- a/base_layer/wallet/tests/transaction_service_tests/service.rs +++ b/base_layer/wallet/tests/transaction_service_tests/service.rs @@ -2556,6 +2556,8 @@ async fn finalize_tx_with_incorrect_pubkey() { script!(Nop).unwrap(), Covenant::default(), MicroMinotari::zero(), + TariAddress::default(), + PaymentId::Empty, ) .await .unwrap(); @@ -2685,6 +2687,8 @@ async fn finalize_tx_with_missing_output() { script!(Nop).unwrap(), Covenant::default(), MicroMinotari::zero(), + TariAddress::default(), + PaymentId::Empty, ) .await .unwrap(); @@ -3353,6 +3357,7 @@ async fn test_transaction_cancellation() { Covenant::default(), MicroMinotari::zero(), amount, + TariAddress::default(), ) .await .unwrap(); @@ -3439,6 +3444,7 @@ async fn test_transaction_cancellation() { Covenant::default(), MicroMinotari::zero(), amount, + TariAddress::default(), ) .await .unwrap(); @@ -4203,6 +4209,7 @@ async fn test_restarting_transaction_protocols() { Covenant::default(), MicroMinotari::zero(), MicroMinotari(2000) - fee - MicroMinotari(10), + TariAddress::default(), ) .await .unwrap() @@ -4278,6 +4285,7 @@ async fn test_restarting_transaction_protocols() { sender_protocol: bob_pre_finalize, status: TransactionStatus::Pending, message: msg.message, + payment_id: PaymentId::Empty, timestamp: Utc::now().naive_utc(), cancelled: false, direct_send_success: false, @@ -4642,6 +4650,7 @@ async fn test_resend_on_startup() { Covenant::default(), MicroMinotari::zero(), amount, + TariAddress::default(), ) .await .unwrap(); @@ -4664,6 +4673,7 @@ async fn test_resend_on_startup() { sender_protocol: stp, status: TransactionStatus::Pending, message: "Yo!".to_string(), + payment_id: PaymentId::Empty, timestamp: Utc::now().naive_utc(), cancelled: false, direct_send_success: false, @@ -5171,6 +5181,7 @@ async fn test_transaction_timeout_cancellation() { Covenant::default(), MicroMinotari::zero(), amount, + TariAddress::default(), ) .await .unwrap(); @@ -5193,6 +5204,7 @@ async fn test_transaction_timeout_cancellation() { sender_protocol: stp, status: TransactionStatus::Pending, message: "Yo!".to_string(), + payment_id: PaymentId::Empty, timestamp: Utc::now() .naive_utc() .checked_sub_signed(ChronoDuration::seconds(20)) diff --git a/base_layer/wallet/tests/transaction_service_tests/storage.rs b/base_layer/wallet/tests/transaction_service_tests/storage.rs index 41e3401691..ddd55e9511 100644 --- a/base_layer/wallet/tests/transaction_service_tests/storage.rs +++ b/base_layer/wallet/tests/transaction_service_tests/storage.rs @@ -102,6 +102,7 @@ pub async fn test_db_backend(backend: T) { Covenant::default(), MicroMinotari::zero(), amount, + TariAddress::default(), ) .await .unwrap(); @@ -141,6 +142,7 @@ pub async fn test_db_backend(backend: T) { sender_protocol: stp.clone(), status: TransactionStatus::Pending, message: messages[i].clone(), + payment_id: PaymentId::Empty, timestamp: Utc::now().naive_utc(), cancelled: false, direct_send_success: false, @@ -499,6 +501,7 @@ pub async fn test_db_backend(backend: T) { stp, TransactionStatus::Pending, "To be cancelled".to_string(), + PaymentId::Empty, Utc::now().naive_utc(), false, ), diff --git a/base_layer/wallet_ffi/src/callback_handler_tests.rs b/base_layer/wallet_ffi/src/callback_handler_tests.rs index c913d985b3..a47919c5cb 100644 --- a/base_layer/wallet_ffi/src/callback_handler_tests.rs +++ b/base_layer/wallet_ffi/src/callback_handler_tests.rs @@ -49,7 +49,7 @@ mod test { }; use tari_core::transactions::{ tari_amount::{uT, MicroMinotari}, - transaction_components::Transaction, + transaction_components::{encrypted_data::PaymentId, Transaction}, ReceiverTransactionProtocol, SenderTransactionProtocol, }; @@ -374,6 +374,7 @@ mod test { stp, TransactionStatus::Pending, "3".to_string(), + PaymentId::Empty, Utc::now().naive_utc(), false, );