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.spend_indices.resize(spends.len(), 0);
|
||||||
tx_metadata.output_indices.resize(orig_outputs_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
|
// Create Sapling SpendDescriptions
|
||||||
if spends.len() > 0 {
|
if spends.len() > 0 {
|
||||||
let anchor = self.anchor.expect("anchor was set if spends were added");
|
let anchor = self.anchor.expect("anchor was set if spends were added");
|
||||||
@ -627,11 +630,17 @@ impl<R: RngCore + CryptoRng> Builder<R> {
|
|||||||
&JUBJUB,
|
&JUBJUB,
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
self.mtx.binding_sig = Some(
|
|
||||||
prover
|
// Add a binding signature if needed
|
||||||
.binding_sig(&mut ctx, self.mtx.value_balance, &sighash)
|
if binding_sig_needed {
|
||||||
.map_err(|()| Error::BindingSig)?,
|
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
|
// Transparent signatures
|
||||||
#[cfg(feature = "transparent-inputs")]
|
#[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]
|
#[test]
|
||||||
fn fails_on_negative_transparent_output() {
|
fn fails_on_negative_transparent_output() {
|
||||||
let mut builder = Builder::new(0);
|
let mut builder = Builder::new(0);
|
||||||
|
Loading…
Reference in New Issue
Block a user