Skip to content

Commit

Permalink
feat!: embed the transaction which spent the inputs within the Dbc st…
Browse files Browse the repository at this point in the history
…ruct
  • Loading branch information
bochaco committed Jun 29, 2022
1 parent 1054224 commit 7db1874
Show file tree
Hide file tree
Showing 7 changed files with 83 additions and 27 deletions.
1 change: 1 addition & 0 deletions examples/mint-repl/mint-repl.rs
Original file line number Diff line number Diff line change
Expand Up @@ -683,6 +683,7 @@ fn write_to_spentbook(mintinfo: &mut MintInfo, mut dbc_builder: DbcBuilder) -> R
dbc_builder =
dbc_builder.add_spent_proof_share(sb_node.log_spent(key_image, tx.clone())?);
}
dbc_builder = dbc_builder.add_spent_transaction(tx);
}
Ok(dbc_builder)
}
Expand Down
26 changes: 21 additions & 5 deletions src/builder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -313,10 +313,8 @@ impl TransactionBuilder {
));
}

// Grand finale! sign the ringct_material to generate a Tx.
let result: Result<(RingCtTransaction, Vec<RevealedCommitment>)> =
ringct_material.sign(rng).map_err(|e| e.into());
let (transaction, revealed_commitments) = result?;
// Grand finale! sign the ringct_material to generate a Tx.
let (transaction, revealed_commitments) = ringct_material.sign(rng)?;

Ok(DbcBuilder::new(
transaction,
Expand All @@ -337,6 +335,7 @@ pub struct DbcBuilder {
pub ringct_material: RingCtMaterial,

pub spent_proof_shares: BTreeMap<KeyImage, HashSet<SpentProofShare>>,
pub spent_transactions: Vec<RingCtTransaction>,
}

impl DbcBuilder {
Expand All @@ -351,8 +350,9 @@ impl DbcBuilder {
transaction,
revealed_commitments,
output_owner_map,
spent_proof_shares: Default::default(),
ringct_material,
spent_proof_shares: Default::default(),
spent_transactions: Vec::default(),
}
}

Expand Down Expand Up @@ -387,6 +387,12 @@ impl DbcBuilder {
self
}

/// Add a transaction which spent one of the inputs
pub fn add_spent_transaction(mut self, spent_tx: RingCtTransaction) -> Self {
self.spent_transactions.push(spent_tx);
self
}

/// Build the output DBCs, verifying the transaction and spentproofs.
///
/// see TransactionVerifier::verify() for a description of
Expand All @@ -401,6 +407,15 @@ impl DbcBuilder {
// note that we do this just once for entire Tx, not once per output Dbc.
TransactionVerifier::verify(verifier, &self.transaction, &spent_proofs)?;

// verify there is a maching spent transaction for each spent_proof
if !spent_proofs.iter().all(|proof| {
self.spent_transactions
.iter()
.any(|tx| Hash::from(tx.hash()) == proof.transaction_hash())
}) {
return Err(Error::MissingSpentTransaction);
}

// build output DBCs
self.build_output_dbcs(spent_proofs)
}
Expand Down Expand Up @@ -456,6 +471,7 @@ impl DbcBuilder {
)),
transaction: self.transaction.clone(),
spent_proofs: spent_proofs.clone(),
spent_transactions: self.spent_transactions.clone(),
};
(dbc, owner_once.clone(), amount_secrets_list[0].clone())
})
Expand Down
47 changes: 35 additions & 12 deletions src/dbc.rs

Large diffs are not rendered by default.

3 changes: 3 additions & 0 deletions src/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,9 @@ pub enum Error {
#[error("OutputProof not found in transaction outputs")]
OutputProofNotFound,

#[error("Missing spent transaction for at least one of the spent proofs")]
MissingSpentTransaction,

#[error("public key is not unique across all transaction outputs")]
PublicKeyNotUniqueAcrossOutputs,

Expand Down
30 changes: 21 additions & 9 deletions src/mint.rs
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,9 @@ mod tests {
Ok(s) => s,
Err(e) => return check_error(e),
};
dbc_builder = dbc_builder.add_spent_proof_share(spent_proof_share);
dbc_builder = dbc_builder
.add_spent_proof_share(spent_proof_share)
.add_spent_transaction(tx);
}
let output_dbcs = dbc_builder.build(&spentbook_node.key_manager)?;

Expand Down Expand Up @@ -200,7 +202,9 @@ mod tests {
Ok(s) => s,
Err(e) => return check_tx_error(e),
};
dbc_builder = dbc_builder.add_spent_proof_share(spent_proof_share);
dbc_builder = dbc_builder
.add_spent_proof_share(spent_proof_share)
.add_spent_transaction(tx);
}

let output_dbcs = dbc_builder.build(&spentbook_node.key_manager)?;
Expand Down Expand Up @@ -320,7 +324,9 @@ mod tests {
}
};

dbc_builder = dbc_builder.add_spent_proof_share(spent_proof_share);
dbc_builder = dbc_builder
.add_spent_proof_share(spent_proof_share)
.add_spent_transaction(tx);
}

let many_to_many_result = dbc_builder.build(&spentbook_node.key_manager);
Expand Down Expand Up @@ -466,8 +472,9 @@ mod tests {
.build(&mut rng)?;

for (key_image, tx) in dbc_builder.inputs() {
dbc_builder =
dbc_builder.add_spent_proof_share(spentbook.log_spent(key_image, tx.clone())?);
dbc_builder = dbc_builder
.add_spent_proof_share(spentbook.log_spent(key_image, tx.clone())?)
.add_spent_transaction(tx);
}

// build output DBCs
Expand Down Expand Up @@ -564,8 +571,11 @@ mod tests {
// normally spentbook verifies the tx, but here we skip it in order to obtain
// a spentproof with an invalid tx.
for (key_image, tx) in dbc_builder_fudged.inputs() {
let spent_proof_share = spentbook.log_spent_and_skip_tx_verification(key_image, tx)?;
dbc_builder_fudged = dbc_builder_fudged.add_spent_proof_share(spent_proof_share);
let spent_proof_share =
spentbook.log_spent_and_skip_tx_verification(key_image, tx.clone())?;
dbc_builder_fudged = dbc_builder_fudged
.add_spent_proof_share(spent_proof_share)
.add_spent_transaction(tx);
}

// The builder should give an error because the sum(inputs) does not equal sum(outputs)
Expand Down Expand Up @@ -643,8 +653,10 @@ mod tests {
)?;

for (key_image, tx) in dbc_builder_true.inputs() {
let spent_proof_share = new_spentbook.log_spent(key_image, tx)?;
dbc_builder_true = dbc_builder_true.add_spent_proof_share(spent_proof_share);
let spent_proof_share = new_spentbook.log_spent(key_image, tx.clone())?;
dbc_builder_true = dbc_builder_true
.add_spent_proof_share(spent_proof_share)
.add_spent_transaction(tx);
}

// Now that the SpentBook is correct, we have a valid spent_proof_share
Expand Down
1 change: 1 addition & 0 deletions src/mock/genesis_builder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,7 @@ impl GenesisBuilder {
dbc_builder = dbc_builder
.add_spent_proof_share(spentbook_node.log_spent(key_image, tx.clone())?);
}
dbc_builder = dbc_builder.add_spent_transaction(tx);
}

// note: for our (mock) purposes, all spentbook nodes are verified to
Expand Down
2 changes: 1 addition & 1 deletion src/spent_proof.rs
Original file line number Diff line number Diff line change
Expand Up @@ -118,7 +118,7 @@ impl SpentProofShare {
&self.spentbook_pks
}

/// represent this SpentProofContent as bytes
/// represent this SpentProofShare as bytes
pub fn to_bytes(&self) -> Vec<u8> {
let mut bytes = self.content.to_bytes();

Expand Down

0 comments on commit 7db1874

Please sign in to comment.