Skip to content

Commit

Permalink
Merge 3818637 into baeb288
Browse files Browse the repository at this point in the history
  • Loading branch information
davidrusu committed Oct 8, 2021
2 parents baeb288 + 3818637 commit 187bd61
Show file tree
Hide file tree
Showing 11 changed files with 657 additions and 776 deletions.
124 changes: 85 additions & 39 deletions benches/reissue.rs
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
#![allow(clippy::from_iter_instead_of_collect)]

use std::collections::{BTreeMap, BTreeSet};
use std::collections::BTreeMap;
use std::iter::FromIterator;

use sn_dbc::{
bls_dkg_id, Amount, AmountSecrets, Dbc, DbcContent, Error, Mint, ReissueRequestBuilder,
SimpleKeyManager, SimpleSigner, SimpleSpendBook,
bls_dkg_id, Amount, AmountSecrets, Dbc, DbcContent, Error, KeyManager, MintNode,
ReissueRequestBuilder, SimpleKeyManager, SimpleSigner, SpentProof, SpentProofShare,
};

use criterion::{black_box, criterion_group, criterion_main, Criterion};
Expand All @@ -19,13 +19,7 @@ fn decrypt_amount_secrets(
dbcc.amount_secrets_by_secret_key_shares(&owner.public_key_set, &shares)
}

fn genesis(
amount: Amount,
) -> (
Mint<SimpleKeyManager, SimpleSpendBook>,
bls_dkg::outcome::Outcome,
Dbc,
) {
fn genesis(amount: Amount) -> (MintNode<SimpleKeyManager>, bls_dkg::outcome::Outcome, Dbc) {
let genesis_owner = bls_dkg_id();

let key_manager = SimpleKeyManager::new(
Expand All @@ -35,7 +29,7 @@ fn genesis(
),
genesis_owner.public_key_set.public_key(),
);
let mut genesis_node = Mint::new(key_manager, SimpleSpendBook::new());
let mut genesis_node = MintNode::new(key_manager);

let genesis = genesis_node.issue_genesis_dbc(amount).unwrap();

Expand Down Expand Up @@ -77,25 +71,40 @@ fn bench_reissue_1_to_100(c: &mut Criterion) {
.build()
.unwrap();

let spend_sig = genesis_owner
.public_key_set
.combine_signatures([(
genesis_owner.index,
genesis_owner
.secret_key_share
.derive_child(&genesis_dbc.spend_key_index())
.sign(reissue_tx.blinded().hash()),
)])
.unwrap();
let spentbook_pks = genesis.key_manager.public_key_set().unwrap();
let spentbook_sig_share = genesis
.key_manager
.sign(&SpentProof::proof_msg(
&reissue_tx.blinded().hash(),
&spend_sig,
))
.unwrap();

let rr = ReissueRequestBuilder::new(reissue_tx)
.add_dbc_signer(
.add_spent_proof_share(
genesis_dbc.spend_key(),
genesis_owner.public_key_set.clone(),
(genesis_owner.index, genesis_owner.secret_key_share),
SpentProofShare {
spend_sig,
spentbook_pks,
spentbook_sig_share,
},
)
.build()
.unwrap();

let spendbook = genesis.snapshot_spendbook();
c.bench_function(&format!("reissue split 1 to {}", n_outputs), |b| {
b.iter(|| {
genesis.reset_spendbook(spendbook.clone());
genesis
.reissue(
black_box(rr.clone()),
black_box(BTreeSet::from_iter([genesis_dbc.spend_key()])),
)
.unwrap();
genesis.reissue(black_box(rr.clone())).unwrap();
})
});
}
Expand Down Expand Up @@ -126,18 +135,38 @@ fn bench_reissue_100_to_1(c: &mut Criterion) {
(out_dbc.owner, owner)
}));

let spend_sig = genesis_owner
.public_key_set
.combine_signatures([(
genesis_owner.index,
genesis_owner
.secret_key_share
.derive_child(&genesis_dbc.spend_key_index())
.sign(reissue_tx.blinded().hash()),
)])
.unwrap();
let spentbook_pks = genesis.key_manager.public_key_set().unwrap();
let spentbook_sig_share = genesis
.key_manager
.sign(&SpentProof::proof_msg(
&reissue_tx.blinded().hash(),
&spend_sig,
))
.unwrap();

let rr = ReissueRequestBuilder::new(reissue_tx)
.add_dbc_signer(
.add_spent_proof_share(
genesis_dbc.spend_key(),
genesis_owner.public_key_set.clone(),
(genesis_owner.index, genesis_owner.secret_key_share),
SpentProofShare {
spend_sig,
spentbook_pks,
spentbook_sig_share,
},
)
.build()
.unwrap();

let reissue_share = genesis
.reissue(rr.clone(), BTreeSet::from_iter([genesis_dbc.spend_key()]))
.unwrap();
let reissue_share = genesis.reissue(rr.clone()).unwrap();

let (mint_key_set, mint_sig_share) = reissue_share
.mint_node_signatures
Expand Down Expand Up @@ -174,27 +203,44 @@ fn bench_reissue_100_to_1(c: &mut Criterion) {
.build()
.unwrap();

let mut rr_builder = ReissueRequestBuilder::new(merge_tx);
let mut rr_builder = ReissueRequestBuilder::new(merge_tx.clone());

for dbc in dbcs.iter() {
let owner = &dbc_owners[&dbc.owner()];
rr_builder = rr_builder.add_dbc_signer(
let spend_sig = owner
.public_key_set
.combine_signatures([(
owner.index,
owner
.secret_key_share
.derive_child(&dbc.spend_key_index())
.sign(&merge_tx.blinded().hash()),
)])
.unwrap();
let spentbook_pks = genesis.key_manager.public_key_set().unwrap();
let spentbook_sig_share = genesis
.key_manager
.sign(&SpentProof::proof_msg(
&merge_tx.blinded().hash(),
&spend_sig,
))
.unwrap();

rr_builder = rr_builder.add_spent_proof_share(
dbc.spend_key(),
owner.public_key_set.clone(),
(owner.index, owner.secret_key_share.clone()),
);
SpentProofShare {
spend_sig,
spentbook_pks,
spentbook_sig_share,
},
)
}

let merge_rr = rr_builder.build().unwrap();
let inputs = merge_rr.transaction.blinded().inputs;

let spendbook = genesis.snapshot_spendbook();
c.bench_function(&format!("reissue merge {} to 1", n_outputs), |b| {
b.iter(|| {
genesis.reset_spendbook(spendbook.clone());
genesis
.reissue(black_box(merge_rr.clone()), black_box(inputs.clone()))
.unwrap();
genesis.reissue(black_box(merge_rr.clone())).unwrap();
})
});
}
Expand Down
55 changes: 25 additions & 30 deletions examples/mint-repl/mint-repl.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,16 +14,16 @@ use anyhow::{anyhow, Error, Result};
use blsttc::poly::Poly;
use blsttc::serde_impl::SerdeSecret;
use blsttc::{
PublicKey, PublicKeySet, SecretKey, SecretKeySet, SecretKeyShare, Signature, SignatureShare,
Fr, IntoFr, PublicKey, PublicKeySet, SecretKey, SecretKeySet, SecretKeyShare, SignatureShare,
};
use rustyline::config::Configurer;
use rustyline::error::ReadlineError;
use rustyline::Editor;
use serde::{Deserialize, Serialize};
use sn_dbc::{
Amount, Dbc, DbcBuilder, GenesisDbcShare, Mint, Output, ReissueRequest, ReissueRequestBuilder,
ReissueTransaction, SimpleKeyManager as KeyManager, SimpleSigner as Signer,
SimpleSpendBook as SpendBook, SpendKey, TransactionBuilder,
Amount, Dbc, DbcBuilder, GenesisDbcShare, MintNode, Output, ReissueRequest,
ReissueRequestBuilder, ReissueTransaction, SimpleKeyManager as KeyManager,
SimpleSigner as Signer, SpendKey, SpentProof, TransactionBuilder,
};
use std::collections::{BTreeMap, BTreeSet, HashMap};
use std::iter::FromIterator;
Expand All @@ -37,15 +37,16 @@ use termios::{tcsetattr, Termios, ICANON, TCSADRAIN};
/// Holds information about the Mint, which may be comprised
/// of 1 or more nodes.
struct MintInfo {
mintnodes: Vec<Mint<KeyManager, SpendBook>>,
mintnodes: Vec<MintNode<KeyManager>>,
genesis: DbcUnblinded,
secret_key_set: SecretKeySet,
poly: Poly,
spentbook: BTreeMap<SpendKey, ReissueTransaction>,
}

impl MintInfo {
// returns the first mint node.
fn mintnode(&self) -> Result<&Mint<KeyManager, SpendBook>> {
fn mintnode(&self) -> Result<&MintNode<KeyManager>> {
self.mintnodes
.get(0)
.ok_or_else(|| anyhow!("Mint not yet created"))
Expand Down Expand Up @@ -212,7 +213,7 @@ fn mk_new_random_mint(threshold: usize, amount: Amount) -> Result<MintInfo> {
/// creates a new mint from an existing SecretKeySet that was seeded by poly.
fn mk_new_mint(secret_key_set: SecretKeySet, poly: Poly, amount: Amount) -> Result<MintInfo> {
let genesis_pubkey = secret_key_set.public_keys().public_key();
let mut mints: Vec<Mint<KeyManager, SpendBook>> = Default::default();
let mut mints: Vec<MintNode<KeyManager>> = Default::default();

// Generate each Mint node, and corresponding NodeSignature. (Index + SignatureShare)
let mut genesis_set: Vec<GenesisDbcShare> = Default::default();
Expand All @@ -224,7 +225,7 @@ fn mk_new_mint(secret_key_set: SecretKeySet, poly: Poly, amount: Amount) -> Resu
),
genesis_pubkey,
);
let mut mint = Mint::new(key_manager, SpendBook::new());
let mut mint = MintNode::new(key_manager);
genesis_set.push(mint.issue_genesis_dbc(amount)?);
mints.push(mint);
}
Expand Down Expand Up @@ -261,6 +262,7 @@ fn mk_new_mint(secret_key_set: SecretKeySet, poly: Poly, amount: Amount) -> Resu
},
secret_key_set,
poly,
spentbook: Default::default(),
})
}

Expand Down Expand Up @@ -389,8 +391,8 @@ fn print_mintinfo_human(mintinfo: &MintInfo) -> Result<()> {
println!("\n");

println!("-- SpendBook --\n");
for (dbc_owner, _tx) in mintinfo.mintnode()?.spendbook.iter() {
println!(" {}", encode(&dbc_owner.0.to_bytes()));
for (dbc_spend_key, _tx) in mintinfo.spentbook.iter() {
println!(" {}", encode(&dbc_spend_key.0.to_bytes()));
}

println!();
Expand Down Expand Up @@ -569,7 +571,7 @@ fn validate(mintinfo: &MintInfo) -> Result<()> {
};

match dbc.confirm_valid(mintinfo.mintnode()?.key_manager()) {
Ok(_) => match mintinfo.mintnode()?.is_spent(dbc.spend_key())? {
Ok(_) => match mintinfo.spentbook.contains_key(&dbc.spend_key()) {
true => println!("\nThis DBC is unspendable. (valid but has already been spent)\n"),
false => println!("\nThis DBC is spendable. (valid and has not been spent)\n"),
},
Expand Down Expand Up @@ -822,7 +824,7 @@ fn prepare_reissue() -> Result<()> {
}
}

let mut proofs: HashMap<SpendKey, Signature> = Default::default();
let mut proofs: BTreeMap<SpendKey, SpentProof> = Default::default();
for dbc in tx.inner.inputs.iter() {
let shares = match sig_shares_by_input.get(&dbc.owner()) {
Some(s) => s,
Expand All @@ -849,7 +851,7 @@ fn prepare_reissue() -> Result<()> {
let reissue_request = ReissueRequestUnblinded {
inner: ReissueRequest {
transaction: tx.inner.clone(),
input_ownership_proofs: proofs,
spent_proofs: proofs,
},
input_pk_pks: tx.input_pk_pks,
output_pk_pks: tx.output_pk_pks,
Expand Down Expand Up @@ -889,7 +891,8 @@ fn reissue(mintinfo: &mut MintInfo) -> Result<()> {
/// Implements reissue_ez command.
fn reissue_ez(mintinfo: &mut MintInfo) -> Result<()> {
let mut tx_builder: TransactionBuilder = Default::default();
let mut rr_builder: ReissueRequestBuilder = Default::default();
let mut dbc_signers: BTreeMap<SpendKey, (PublicKeySet, BTreeMap<Fr, SecretKeyShare>)> =
Default::default();
let mut pk_pks: HashMap<PublicKey, PublicKeySet> = Default::default();

// Get from user: input DBC(s) and required # of SecretKeyShare+index for each.
Expand Down Expand Up @@ -929,7 +932,9 @@ fn reissue_ez(mintinfo: &mut MintInfo) -> Result<()> {
dbc.owner.threshold() + 1
);

while rr_builder.num_signers_by_dbc(dbc.inner.spend_key()) < dbc.owner.threshold() + 1 {
let mut secret_shares = BTreeMap::new();

while dbc.owner.threshold() + 1 > secret_shares.len() {
let key = readline_prompt_nl("\nSecretKeyShare, or 'cancel': ")?;
let secret: SecretKeyShare = if key == "cancel" {
println!("\nreissue_ez cancelled\n");
Expand All @@ -940,25 +945,16 @@ fn reissue_ez(mintinfo: &mut MintInfo) -> Result<()> {
let idx_input = readline_prompt("\nSecretKeyShare Index: ")?;
let idx: usize = idx_input.parse()?;

rr_builder = rr_builder.add_dbc_signer(
dbc.inner.spend_key(),
dbc.owner.clone(),
(idx, secret.clone()),
);
secret_shares.insert(idx.into_fr(), secret);
}

let secret_shares = rr_builder
.get_signers(dbc.inner.spend_key())
.ok_or(sn_dbc::Error::MissingInputOwnerProof)?
.get(&dbc.owner)
.ok_or(sn_dbc::Error::ReissueRequestPublicKeySetMismatch)?;

let amount_secrets = dbc
.inner
.content
.amount_secrets_by_secret_key_shares(&dbc.owner, secret_shares)?;
.amount_secrets_by_secret_key_shares(&dbc.owner, &secret_shares)?;

tx_builder = tx_builder.add_input(dbc.inner.clone(), amount_secrets);
dbc_signers.insert(dbc.inner.spend_key(), (dbc.owner, secret_shares));
}

let mut i = 0u32;
Expand Down Expand Up @@ -1023,11 +1019,10 @@ fn reissue_ez(mintinfo: &mut MintInfo) -> Result<()> {

let input_owners = tx_builder.input_spend_keys();
let transaction = tx_builder.build()?;
let rr = rr_builder.set_reissue_transaction(transaction).build()?;

println!("Prepared reissue request...");

reissue_exec(mintinfo, &rr, &input_owners, &pk_pks)
reissue_exec(mintinfo, &transaction, &input_owners, &pk_pks)
}

/// Performs reissue
Expand All @@ -1046,7 +1041,7 @@ fn reissue_exec(
// here we pretend the client has made a network request to a single mint node
// so this mint.reissue() execs on the Mint node and returns data to client.
println!("Sending reissue request..");
let reissue_share = mint.reissue(reissue_request.clone(), input_owners.clone())?;
let reissue_share = mint.reissue(reissue_request.clone())?;

// and now we are back to client code.
dbc_builder = dbc_builder.add_reissue_share(reissue_share);
Expand Down

0 comments on commit 187bd61

Please sign in to comment.