mirror of
https://github.com/Qortal/pirate-librustzcash.git
synced 2025-02-01 08:12:14 +00:00
Add binding signature only if needed
This commit is contained in:
parent
188537ea02
commit
98f9bda329
@ -494,6 +494,9 @@ impl<R: RngCore + CryptoRng> Builder<R> {
|
||||
tx_metadata.spend_indices.resize(spends.len(), 0);
|
||||
tx_metadata.output_indices.resize(orig_outputs_len, 0);
|
||||
|
||||
// Record if we'll need a binding signature
|
||||
let binding_sig_needed = !spends.is_empty() || !outputs.is_empty();
|
||||
|
||||
// Create Sapling SpendDescriptions
|
||||
if spends.len() > 0 {
|
||||
let anchor = self.anchor.expect("anchor was set if spends were added");
|
||||
@ -627,11 +630,17 @@ impl<R: RngCore + CryptoRng> Builder<R> {
|
||||
&JUBJUB,
|
||||
));
|
||||
}
|
||||
self.mtx.binding_sig = Some(
|
||||
prover
|
||||
.binding_sig(&mut ctx, self.mtx.value_balance, &sighash)
|
||||
.map_err(|()| Error::BindingSig)?,
|
||||
);
|
||||
|
||||
// Add a binding signature if needed
|
||||
if binding_sig_needed {
|
||||
self.mtx.binding_sig = Some(
|
||||
prover
|
||||
.binding_sig(&mut ctx, self.mtx.value_balance, &sighash)
|
||||
.map_err(|()| Error::BindingSig)?,
|
||||
);
|
||||
} else {
|
||||
self.mtx.binding_sig = None;
|
||||
}
|
||||
|
||||
// Transparent signatures
|
||||
#[cfg(feature = "transparent-inputs")]
|
||||
@ -696,6 +705,78 @@ mod tests {
|
||||
);
|
||||
}
|
||||
|
||||
#[cfg(feature = "transparent-inputs")]
|
||||
#[test]
|
||||
fn binding_sig_absent_if_no_shielded_spend_or_output() {
|
||||
use crate::transaction::{
|
||||
builder::{self, TransparentInputs},
|
||||
TransactionData,
|
||||
};
|
||||
|
||||
// Create a builder with 0 fee, so we can construct t outputs
|
||||
let mut builder = builder::Builder {
|
||||
rng: OsRng,
|
||||
mtx: TransactionData::new(),
|
||||
fee: Amount::zero(),
|
||||
anchor: None,
|
||||
spends: vec![],
|
||||
outputs: vec![],
|
||||
transparent_inputs: TransparentInputs::default(),
|
||||
change_address: None,
|
||||
};
|
||||
|
||||
// Create a tx with only t output. No binding_sig should be present
|
||||
builder
|
||||
.add_transparent_output(&TransparentAddress::PublicKey([0; 20]), Amount::zero())
|
||||
.unwrap();
|
||||
|
||||
let (tx, _) = builder
|
||||
.build(consensus::BranchId::Sapling, &MockTxProver)
|
||||
.unwrap();
|
||||
// No binding signature, because only t input and outputs
|
||||
assert!(tx.binding_sig.is_none());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn binding_sig_present_if_shielded_spend() {
|
||||
let extsk = ExtendedSpendingKey::master(&[]);
|
||||
let extfvk = ExtendedFullViewingKey::from(&extsk);
|
||||
let to = extfvk.default_address().unwrap().1;
|
||||
|
||||
let mut rng = OsRng;
|
||||
|
||||
let note1 = to
|
||||
.create_note(50000, Fs::random(&mut rng), &JUBJUB)
|
||||
.unwrap();
|
||||
let cm1 = Node::new(note1.cm(&JUBJUB).into_repr());
|
||||
let mut tree = CommitmentTree::new();
|
||||
tree.append(cm1).unwrap();
|
||||
let witness1 = IncrementalWitness::from_tree(&tree);
|
||||
|
||||
let mut builder = Builder::new(0);
|
||||
|
||||
// Create a tx with a sapling spend. binding_sig should be present
|
||||
builder
|
||||
.add_sapling_spend(
|
||||
extsk.clone(),
|
||||
*to.diversifier(),
|
||||
note1.clone(),
|
||||
witness1.path().unwrap(),
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
builder
|
||||
.add_transparent_output(&TransparentAddress::PublicKey([0; 20]), Amount::zero())
|
||||
.unwrap();
|
||||
|
||||
// Expect a binding signature error, because our inputs aren't valid, but this shows
|
||||
// that a binding signature was attempted
|
||||
assert_eq!(
|
||||
builder.build(consensus::BranchId::Sapling, &MockTxProver),
|
||||
Err(Error::BindingSig)
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn fails_on_negative_transparent_output() {
|
||||
let mut builder = Builder::new(0);
|
||||
|
Loading…
Reference in New Issue
Block a user