Skip to content

Commit

Permalink
feat: impl add_output(s)_by_amount() methods
Browse files Browse the repository at this point in the history
Adds two TransactionBuilder methods:
 ::add_output_by_amount() and ::add_outputs_by_amount().

With these a caller does not need to construct an Output and the
calling code is shorter and nicer.

This commit also changes all the tests, example, bench to use the new
methods.
  • Loading branch information
dan-da committed Mar 22, 2022
1 parent dee5555 commit 2f5b01d
Show file tree
Hide file tree
Showing 5 changed files with 53 additions and 99 deletions.
31 changes: 7 additions & 24 deletions benches/reissue.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,6 @@ use sn_dbc::{
SpentBookNodeMock,
};

use blst_ringct::Output;

use criterion::{black_box, criterion_group, criterion_main, Criterion};
use rand8::SeedableRng as SeedableRng8;

Expand All @@ -37,13 +35,10 @@ fn bench_reissue_1_to_100(c: &mut Criterion) {
vec![], // never any decoys for genesis
&mut rng8,
)
.add_outputs((0..N_OUTPUTS).into_iter().map(|_| {
.add_outputs_by_amount((0..N_OUTPUTS).into_iter().map(|_| {
let owner_once =
OwnerOnce::from_owner_base(Owner::from_random_secret_key(&mut rng8), &mut rng8);
(
Output::new(owner_once.as_owner().public_key(), 1),
owner_once,
)
(1, owner_once)
}))
.build(&mut rng8)
.unwrap();
Expand Down Expand Up @@ -79,13 +74,10 @@ fn bench_reissue_100_to_1(c: &mut Criterion) {
vec![], // never any decoy inputs for genesis
&mut rng8,
)
.add_outputs((0..N_OUTPUTS).into_iter().map(|_| {
.add_outputs_by_amount((0..N_OUTPUTS).into_iter().map(|_| {
let owner_once =
OwnerOnce::from_owner_base(Owner::from_random_secret_key(&mut rng8), &mut rng8);
(
Output::new(owner_once.as_owner().public_key(), 1),
owner_once,
)
(1, owner_once)
}))
.build(&mut rng8)
.unwrap();
Expand Down Expand Up @@ -117,13 +109,7 @@ fn bench_reissue_100_to_1(c: &mut Criterion) {
.collect(),
&mut rng8,
)
.add_output(
Output::new(
output_owner_once.as_owner().public_key(),
N_OUTPUTS as Amount,
),
output_owner_once,
)
.add_output_by_amount(N_OUTPUTS as Amount, output_owner_once)
.build(&mut rng8)
.unwrap();

Expand Down Expand Up @@ -156,12 +142,9 @@ fn generate_dbc_of_value(
vec![], // never any decoys for genesis
rng8,
)
.add_outputs(output_amounts.into_iter().map(|amount| {
.add_outputs_by_amount(output_amounts.into_iter().map(|amount| {
let owner_once = OwnerOnce::from_owner_base(Owner::from_random_secret_key(rng8), rng8);
(
Output::new(owner_once.as_owner().public_key(), amount),
owner_once,
)
(amount, owner_once)
}))
.build(rng8)?;

Expand Down
15 changes: 4 additions & 11 deletions examples/mint-repl/mint-repl.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,9 +24,8 @@ use rustyline::error::ReadlineError;
use rustyline::Editor;
use serde::{Deserialize, Serialize};
use sn_dbc::{
Amount, Dbc, DbcBuilder, GenesisBuilderMock, MintNode, Output, OutputOwnerMap, Owner,
OwnerOnce, ReissueRequest, ReissueRequestBuilder, SimpleKeyManager, SpentBookNodeMock,
TransactionBuilder,
Amount, Dbc, DbcBuilder, GenesisBuilderMock, MintNode, OutputOwnerMap, Owner, OwnerOnce,
ReissueRequest, ReissueRequestBuilder, SimpleKeyManager, SpentBookNodeMock, TransactionBuilder,
};
use std::collections::{BTreeMap, HashMap};
use std::iter::FromIterator;
Expand Down Expand Up @@ -678,10 +677,7 @@ fn prepare_tx(mintinfo: &MintInfo) -> Result<RingCtTransactionRevealed> {

let owner_once = OwnerOnce::from_owner_base(owner_base, &mut rng8);

tx_builder = tx_builder.add_output(
Output::new(owner_once.as_owner().public_key(), amount),
owner_once,
);
tx_builder = tx_builder.add_output_by_amount(amount, owner_once);

i += 1;
}
Expand Down Expand Up @@ -817,10 +813,7 @@ fn reissue_auto_cli(mintinfo: &mut MintInfo) -> Result<()> {
let owner_once =
OwnerOnce::from_owner_base(Owner::from_random_secret_key(&mut rng8), &mut rng8);

tx_builder = tx_builder.add_output(
Output::new(owner_once.as_owner().public_key(), amount),
owner_once,
);
tx_builder = tx_builder.add_output_by_amount(amount, owner_once);
}

let (mut rr_builder, mut dbc_builder, _material) = tx_builder.build(&mut rng8)?;
Expand Down
20 changes: 20 additions & 0 deletions src/builder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -163,6 +163,26 @@ impl TransactionBuilder {
self
}

/// add an output by providing Amount and OwnerOnce
pub fn add_output_by_amount(mut self, amount: Amount, owner: OwnerOnce) -> Self {
let pk = owner.as_owner().public_key();
let output = Output::new(pk, amount);
self.output_owner_map.insert(pk, owner);
self.ringct_material.outputs.push(output);
self
}

/// add an output by providing iter of (Amount, OwnerOnce)
pub fn add_outputs_by_amount(
mut self,
outputs: impl IntoIterator<Item = (Amount, OwnerOnce)>,
) -> Self {
for (amount, owner) in outputs.into_iter() {
self = self.add_output_by_amount(amount, owner);
}
self
}

/// get a list of input owners
pub fn input_owners(&self) -> Vec<PublicKey> {
self.ringct_material
Expand Down
22 changes: 5 additions & 17 deletions src/dbc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -305,14 +305,7 @@ pub(crate) mod tests {

let (mut rr_builder, dbc_builder, _material) = crate::TransactionBuilder::default()
.add_input_by_secrets(dbc_owner, amount_secrets, decoy_inputs, rng8)
.add_outputs(divide(amount, n_ways).zip(output_owners.into_iter()).map(
|(amount, owner_once)| {
(
Output::new(owner_once.as_owner().public_key(), amount),
owner_once,
)
},
))
.add_outputs_by_amount(divide(amount, n_ways).zip(output_owners.into_iter()))
.build(rng8)?;

for (key_image, tx) in rr_builder.inputs() {
Expand Down Expand Up @@ -433,10 +426,7 @@ pub(crate) mod tests {

let (mut rr_builder, dbc_builder, _material) = crate::TransactionBuilder::default()
.add_inputs_dbc(inputs, &mut rng8)?
.add_output(
Output::new(owner_once.as_owner().public_key(), amount),
owner_once.clone(),
)
.add_output_by_amount(amount, owner_once.clone())
.build(&mut rng8)?;

let reissue_tx = rr_builder.transaction.clone();
Expand Down Expand Up @@ -650,12 +640,10 @@ pub(crate) mod tests {
vec![], // never any decoys for genesis
rng8,
)
.add_outputs(output_amounts.into_iter().map(|amount| {
let owner_once =
OwnerOnce::from_owner_base(Owner::from_random_secret_key(rng8), rng8);
.add_outputs_by_amount(output_amounts.into_iter().map(|amount| {
(
Output::new(owner_once.as_owner().public_key(), amount),
owner_once,
amount,
OwnerOnce::from_owner_base(Owner::from_random_secret_key(rng8), rng8),
)
}))
.build(rng8)?;
Expand Down
64 changes: 17 additions & 47 deletions src/mint.rs
Original file line number Diff line number Diff line change
Expand Up @@ -167,7 +167,7 @@ impl<K: KeyManager> MintNode<K> {
#[cfg(test)]
mod tests {
use super::*;
use blst_ringct::{DecoyInput, Output};
use blst_ringct::DecoyInput;
use blsttc::{SecretKey, SecretKeySet};
use quickcheck_macros::quickcheck;
use rand_core::SeedableRng as SeedableRngCore;
Expand Down Expand Up @@ -225,12 +225,12 @@ mod tests {
vec![], // genesis is only input, so no decoys.
&mut rng8,
)?
.add_outputs(output_amounts.iter().enumerate().map(|(idx, a)| {
(
crate::Output::new(owners[idx].as_owner().public_key(), *a),
owners[idx].clone(),
)
}))
.add_outputs_by_amount(
output_amounts
.iter()
.enumerate()
.map(|(idx, a)| (*a, owners[idx].clone())),
)
.build(&mut rng8)?;

// We make this a closure because it is used for checking both spentbook
Expand Down Expand Up @@ -347,13 +347,10 @@ mod tests {
vec![], // genesis is only input, so no decoys.
&mut rng8,
)?
.add_outputs(input_amounts.iter().copied().map(|amount| {
.add_outputs_by_amount(input_amounts.iter().copied().map(|amount| {
let owner_once =
OwnerOnce::from_owner_base(Owner::from_random_secret_key(&mut rng8), &mut rng8);
(
crate::Output::new(owner_once.as_owner().public_key(), amount),
owner_once,
)
(amount, owner_once)
}))
.build(&mut rng8)?;

Expand Down Expand Up @@ -414,23 +411,14 @@ mod tests {
})
.collect();

let outputs: Vec<(Output, OwnerOnce)> = output_amounts
.iter()
.zip(owners)
.map(|(amount, owner_once)| {
(
crate::Output::new(owner_once.as_owner().public_key(), *amount),
owner_once,
)
})
.collect();
let outputs = output_amounts.clone().into_iter().zip(owners);

let (mut rr2_builder, mut dbc_builder, _material) = crate::TransactionBuilder::default()
.add_inputs_dbc(inputs_dbcs.clone(), &mut rng8)?
.add_outputs(outputs.clone())
.add_outputs_by_amount(outputs.clone())
.build(&mut rng8)?;

let dbc_output_amounts: Vec<Amount> = outputs.iter().map(|(o, _)| o.amount).collect();
let dbc_output_amounts: Vec<Amount> = outputs.map(|(amt, _)| amt).collect();
let output_total_amount: Amount = dbc_output_amounts.iter().sum();

assert_eq!(inputs_dbcs.len(), rr2_builder.transaction.mlsags.len());
Expand Down Expand Up @@ -588,10 +576,7 @@ mod tests {
OwnerOnce::from_owner_base(Owner::from_random_secret_key(&mut rng8), &mut rng8);

let (_rr_builder, dbc_builder, ..) = crate::TransactionBuilder::default()
.add_output(
Output::new(output1_owner.as_owner().public_key(), 100),
output1_owner.clone(),
)
.add_output_by_amount(100, output1_owner.clone())
.build(&mut rng8)?;

let amount_secrets = AmountSecrets::from(dbc_builder.revealed_commitments[0]);
Expand All @@ -603,10 +588,7 @@ mod tests {

let (fraud_rr_builder, ..) = crate::TransactionBuilder::default()
.add_input_by_secrets(secret_key, amount_secrets, decoy_inputs, &mut rng8)
.add_output(
Output::new(output2_owner.as_owner().public_key(), 100),
output2_owner,
)
.add_output_by_amount(100, output2_owner)
.build(&mut rng8)?;

let fraud_rr = fraud_rr_builder.build()?;
Expand Down Expand Up @@ -682,10 +664,7 @@ mod tests {
vec![], // genesis is only input, so no decoys.
&mut rng8,
)?
.add_output(
Output::new(output_owner.as_owner().public_key(), output_amount),
output_owner.clone(),
)
.add_output_by_amount(output_amount, output_owner.clone())
.build(&mut rng8)?;

for (key_image, tx) in rr_builder.inputs() {
Expand Down Expand Up @@ -771,13 +750,7 @@ mod tests {
decoy_inputs.clone(),
&mut rng8,
)?
.add_output(
Output::new(
output_owner.as_owner().public_key(),
fudged_secrets.amount(),
),
output_owner.clone(),
)
.add_output_by_amount(fudged_secrets.amount(), output_owner.clone())
.build(&mut rng8)?;

// ----------
Expand Down Expand Up @@ -842,10 +815,7 @@ mod tests {
decoy_inputs,
&mut rng8,
)
.add_output(
Output::new(output_owner.as_owner().public_key(), true_secrets.amount()),
output_owner,
)
.add_output_by_amount(true_secrets.amount(), output_owner)
.build(&mut rng8)?;

let tx_true = rr_builder_true.transaction.clone();
Expand Down

0 comments on commit 2f5b01d

Please sign in to comment.