Skip to content

Commit d662466

Browse files
author
Hansie Odendaal
committed
Add coinbase payment_id
Added coinbase payment_id to thre coinbase from the wallet payment address if it exists.
1 parent 0c83469 commit d662466

File tree

6 files changed

+101
-25
lines changed

6 files changed

+101
-25
lines changed

applications/minotari_console_wallet/src/grpc/wallet_grpc_server.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -272,15 +272,15 @@ impl wallet_server::Wallet for WalletGrpcServer {
272272
.await
273273
.map_err(|e| Status::internal(format!("{:?}", e)))?;
274274
let interactive_address = interactive_address
275-
.create_payment_id_address(message.payment_id.clone())
275+
.with_payment_id_user_data(message.payment_id.clone())
276276
.map_err(|e| Status::internal(format!("{:?}", e)))?;
277277
let one_sided_address = self
278278
.wallet
279279
.get_wallet_one_sided_address()
280280
.await
281281
.map_err(|e| Status::internal(format!("{:?}", e)))?;
282282
let one_sided_address = one_sided_address
283-
.create_payment_id_address(message.payment_id)
283+
.with_payment_id_user_data(message.payment_id)
284284
.map_err(|e| Status::internal(format!("{:?}", e)))?;
285285
Ok(Response::new(GetCompleteAddressResponse {
286286
interactive_address: interactive_address.to_vec(),

base_layer/common_types/src/tari_address/dual_address.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -89,7 +89,7 @@ impl DualAddress {
8989
Self::new(view_key, spend_key, network, TariAddressFeatures::default(), None)
9090
}
9191

92-
pub fn add_payment_id(&mut self, data: Vec<u8>) -> Result<(), TariAddressError> {
92+
pub fn add_payment_id_user_data(&mut self, data: Vec<u8>) -> Result<(), TariAddressError> {
9393
if data.len() > MAX_ENCRYPTED_DATA_SIZE {
9494
return Err(TariAddressError::PaymentIdTooLarge);
9595
}
@@ -126,7 +126,7 @@ impl DualAddress {
126126
Self::from_bytes(&bytes)
127127
}
128128

129-
pub fn get_payment_id_bytes(&self) -> Vec<u8> {
129+
pub fn get_payment_id_user_data_bytes(&self) -> Vec<u8> {
130130
self.payment_id_user_data.as_ref().to_vec()
131131
}
132132

base_layer/common_types/src/tari_address/mod.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -239,18 +239,18 @@ impl TariAddress {
239239
}
240240
}
241241

242-
pub fn get_payment_id_bytes(&self) -> Vec<u8> {
242+
pub fn get_payment_id_user_data_bytes(&self) -> Vec<u8> {
243243
match self {
244-
TariAddress::Dual(v) => v.get_payment_id_bytes(),
244+
TariAddress::Dual(v) => v.get_payment_id_user_data_bytes(),
245245
TariAddress::Single(_) => vec![],
246246
}
247247
}
248248

249-
pub fn create_payment_id_address(&self, data: Vec<u8>) -> Result<Self, TariAddressError> {
249+
pub fn with_payment_id_user_data(&self, data: Vec<u8>) -> Result<Self, TariAddressError> {
250250
match self {
251251
TariAddress::Dual(v) => {
252252
let mut address = v.clone();
253-
address.add_payment_id(data)?;
253+
address.add_payment_id_user_data(data)?;
254254
Ok(TariAddress::Dual(address))
255255
},
256256
TariAddress::Single(_) => Err(TariAddressError::PaymentIdNotSupported),

base_layer/core/src/transactions/coinbase_builder.rs

Lines changed: 82 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ use crate::{
4141
transactions::{
4242
tari_amount::{uT, MicroMinotari},
4343
transaction_components::{
44-
encrypted_data::PaymentId,
44+
encrypted_data::{PaymentId, TxType},
4545
CoinBaseExtra,
4646
KernelBuilder,
4747
KernelFeatures,
@@ -449,6 +449,16 @@ pub async fn generate_coinbase_with_wallet_output(
449449
"Invalid address, address must be one-sided enabled".to_string(),
450450
));
451451
}
452+
// Override payment id if the wallet address contains a pyment id
453+
let payment_id = if wallet_payment_address.get_payment_id_user_data_bytes().is_empty() {
454+
payment_id
455+
} else {
456+
PaymentId::Open {
457+
user_data: wallet_payment_address.get_payment_id_user_data_bytes(),
458+
tx_type: TxType::Coinbase,
459+
}
460+
};
461+
452462
let sender_offset = key_manager
453463
.get_next_key(TransactionKeyManagerBranch::SenderOffset.get_branch_key())
454464
.await?;
@@ -509,9 +519,11 @@ mod test {
509519
use tari_common_types::{
510520
key_branches::TransactionKeyManagerBranch,
511521
tari_address::TariAddress,
512-
types::{CompressedCommitment, CompressedPublicKey, Signature},
522+
types::{CompressedCommitment, CompressedPublicKey, PrivateKey, Signature},
513523
};
514524
use tari_comms::types::CompressedSignature;
525+
use tari_crypto::keys::SecretKey;
526+
use tari_utilities::ByteArray;
515527

516528
use crate::{
517529
consensus::{emission::Emission, ConsensusManager, ConsensusManagerBuilder},
@@ -779,15 +791,26 @@ mod test {
779791
}
780792
use tari_script::push_pubkey_script;
781793

782-
use crate::transactions::{
783-
aggregated_body::AggregateBody,
784-
transaction_components::{encrypted_data::PaymentId, KernelBuilder, RangeProofType, TransactionKernelVersion},
785-
transaction_key_manager::{
786-
create_memory_db_key_manager,
787-
MemoryDbKeyManager,
788-
TariKeyId,
789-
TransactionKeyManagerInterface,
790-
TxoStage,
794+
use crate::{
795+
test_helpers::create_consensus_constants,
796+
transactions::{
797+
aggregated_body::AggregateBody,
798+
generate_coinbase_with_wallet_output,
799+
tari_amount::MicroMinotari,
800+
transaction_components::{
801+
encrypted_data::PaymentId,
802+
CoinBaseExtra,
803+
KernelBuilder,
804+
RangeProofType,
805+
TransactionKernelVersion,
806+
},
807+
transaction_key_manager::{
808+
create_memory_db_key_manager,
809+
MemoryDbKeyManager,
810+
TariKeyId,
811+
TransactionKeyManagerInterface,
812+
TxoStage,
813+
},
791814
},
792815
};
793816

@@ -1208,4 +1231,52 @@ mod test {
12081231
)
12091232
.unwrap_err();
12101233
}
1234+
1235+
#[tokio::test]
1236+
async fn test_generate_coinbase_with_payment_id_from_address() {
1237+
let key_manager = create_memory_db_key_manager().unwrap();
1238+
let wallet_private_spend_key = PrivateKey::random(&mut rand::rngs::OsRng);
1239+
let wallet_private_view_key = PrivateKey::random(&mut rand::rngs::OsRng);
1240+
1241+
let script_key_id = key_manager.import_key(wallet_private_spend_key.clone()).await.unwrap();
1242+
let payment_id_user_data = b"This is my payment id";
1243+
let wallet_payment_address =
1244+
tari_common_types::tari_address::TariAddress::new_dual_address_with_default_features(
1245+
tari_common_types::types::CompressedPublicKey::from_secret_key(&wallet_private_view_key),
1246+
tari_common_types::types::CompressedPublicKey::from_secret_key(&wallet_private_spend_key),
1247+
Network::LocalNet,
1248+
)
1249+
.unwrap()
1250+
.with_payment_id_user_data(payment_id_user_data.to_vec())
1251+
.unwrap();
1252+
assert_eq!(
1253+
PaymentId::stringify_bytes(&wallet_payment_address.get_payment_id_user_data_bytes()),
1254+
PaymentId::stringify_bytes(payment_id_user_data)
1255+
);
1256+
1257+
let reward = MicroMinotari::from(1000);
1258+
let header_height = 1;
1259+
let range_proof_type = RangeProofType::RevealedValue;
1260+
1261+
let (_, _, _, coinbase_wallet_output) = generate_coinbase_with_wallet_output(
1262+
MicroMinotari::from(0),
1263+
reward,
1264+
header_height,
1265+
&CoinBaseExtra::default(),
1266+
&key_manager,
1267+
&script_key_id,
1268+
&wallet_payment_address,
1269+
false,
1270+
&create_consensus_constants(header_height),
1271+
range_proof_type,
1272+
PaymentId::Empty,
1273+
)
1274+
.await
1275+
.unwrap();
1276+
1277+
assert_eq!(
1278+
coinbase_wallet_output.payment_id.user_data_as_string(),
1279+
PaymentId::stringify_bytes(payment_id_user_data)
1280+
);
1281+
}
12111282
}

base_layer/core/src/transactions/transaction_components/encrypted_data.rs

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,7 @@ pub enum TxType {
9393
HtlcAtomicSwapRefund = 0b0111,
9494
CodeTemplateRegistration = 0b1000,
9595
ImportedUtxoNoneRewindable = 0b1001,
96+
Coinbase = 0b1011,
9697
}
9798

9899
impl TxType {
@@ -112,6 +113,7 @@ impl TxType {
112113
0b0111 => TxType::HtlcAtomicSwapRefund,
113114
0b1000 => TxType::CodeTemplateRegistration,
114115
0b1001 => TxType::ImportedUtxoNoneRewindable,
116+
0b1011 => TxType::Coinbase,
115117
_ => TxType::default(),
116118
}
117119
}
@@ -128,6 +130,7 @@ impl TxType {
128130
TxType::HtlcAtomicSwapRefund => 0b0111,
129131
TxType::CodeTemplateRegistration => 0b1000,
130132
TxType::ImportedUtxoNoneRewindable => 0b1001,
133+
TxType::Coinbase => 0b1011,
131134
}
132135
}
133136

@@ -149,6 +152,7 @@ impl Display for TxType {
149152
TxType::HtlcAtomicSwapRefund => write!(f, "HtlcAtomicSwapRefund"),
150153
TxType::CodeTemplateRegistration => write!(f, "CodeTemplateRegistration"),
151154
TxType::ImportedUtxoNoneRewindable => write!(f, "ImportedUtxoNoneRewindable"),
155+
TxType::Coinbase => write!(f, "Coinbase"),
152156
}
153157
}
154158
}
@@ -1098,7 +1102,7 @@ mod test {
10981102
),
10991103
PaymentId::Open {
11001104
user_data: vec![1, 2, 3, 4, 5, 6, 7, 8, 9, 10],
1101-
tx_type: TxType::default(),
1105+
tx_type: TxType::Coinbase,
11021106
},
11031107
PaymentId::Open {
11041108
user_data: vec![1; 254],
@@ -1220,6 +1224,7 @@ mod test {
12201224
TxType::HtlcAtomicSwapRefund,
12211225
TxType::CodeTemplateRegistration,
12221226
TxType::ImportedUtxoNoneRewindable,
1227+
TxType::Coinbase,
12231228
] {
12241229
let payment_id = PaymentId::Open {
12251230
tx_type: tx_type.clone(),
@@ -1364,22 +1369,22 @@ mod test {
13641369
sender_one_sided: true,
13651370
amount: MicroMinotari::from(u64::MAX),
13661371
fee: MicroMinotari::from(4_294_967_295 + 100), // 4294.967395 T
1367-
tx_type: TxType::Burn,
1372+
tx_type: TxType::Coinbase,
13681373
user_data: "Hello World!!! 11-22-33".as_bytes().to_vec(),
13691374
};
13701375
// - It can be displayed as is ...
13711376
assert_eq!(
13721377
payment_id_3.to_string(),
13731378
"recipient_address(f425UWsDp714RiN53c1G6ek57rfFnotB5NCMyrn4iDgbR8i2sXVHa4xSsedd66o9KmkRgErQnyDdCaAdNLzcKrj7eUb), \
1374-
sender_one_sided(true), amount(18446744073709.551615 T), fee(4294.967395 T), type(Burn), data(Hello World!!! 11-22-33)"
1379+
sender_one_sided(true), amount(18446744073709.551615 T), fee(4294.967395 T), type(Coinbase), data(Hello World!!! 11-22-33)"
13751380
);
13761381
// ... but it cannot be serialized and deserialized as is - overflowed metadata will be zeroed.
13771382
let payment_id_3_bytes = payment_id_3.to_bytes();
13781383
let payment_id_3_from_bytes = PaymentId::from_bytes(&payment_id_3_bytes);
13791384
assert_eq!(
13801385
payment_id_3_from_bytes.to_string(),
13811386
"recipient_address(f425UWsDp714RiN53c1G6ek57rfFnotB5NCMyrn4iDgbR8i2sXVHa4xSsedd66o9KmkRgErQnyDdCaAdNLzcKrj7eUb), \
1382-
sender_one_sided(true), amount(18446744073709.551615 T), fee(0 µT), type(Burn), data(Hello World!!! 11-22-33)"
1387+
sender_one_sided(true), amount(18446744073709.551615 T), fee(0 µT), type(Coinbase), data(Hello World!!! 11-22-33)"
13831388
);
13841389
}
13851390

base_layer/wallet/src/transaction_service/service.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1206,7 +1206,7 @@ where
12061206
}
12071207
// let override the payment_id if the address says we should
12081208
if destination.features().contains(TariAddressFeatures::PAYMENT_ID) {
1209-
payment_id = PaymentId::open(destination.get_payment_id_bytes(), TxType::PaymentToOther);
1209+
payment_id = PaymentId::open(destination.get_payment_id_user_data_bytes(), TxType::PaymentToOther);
12101210
}
12111211
let (tx_reply_sender, tx_reply_receiver) = mpsc::channel(100);
12121212
let (cancellation_sender, cancellation_receiver) = oneshot::channel();
@@ -1761,7 +1761,7 @@ where
17611761
let tx_id = TxId::new_random();
17621762
// let override the payment_id if the address says we should
17631763
if dest_address.features().contains(TariAddressFeatures::PAYMENT_ID) {
1764-
payment_id = PaymentId::open(dest_address.get_payment_id_bytes(), TxType::PaymentToOther);
1764+
payment_id = PaymentId::open(dest_address.get_payment_id_user_data_bytes(), TxType::PaymentToOther);
17651765
}
17661766
let payment_id = match payment_id.clone() {
17671767
PaymentId::Open { .. } | PaymentId::Empty => PaymentId::add_sender_address(

0 commit comments

Comments
 (0)