Move Sprout components to a bundle within TransactionData
This commit is contained in:
parent
84e8952ec3
commit
670d03e74f
|
@ -79,7 +79,7 @@ impl<'a> demo::Context for Context<'a> {
|
|||
self.tx.vin.is_empty()
|
||||
&& self.tx.vout.is_empty()
|
||||
&& self.tx.sapling_bundle.is_none()
|
||||
&& self.tx.joinsplits.is_empty()
|
||||
&& self.tx.sprout_bundle.is_none()
|
||||
&& self.tx.orchard_bundle.is_none()
|
||||
}
|
||||
|
||||
|
|
|
@ -605,8 +605,8 @@ mod tests {
|
|||
fn is_tze_only(&self) -> bool {
|
||||
self.tx.vin.is_empty()
|
||||
&& self.tx.vout.is_empty()
|
||||
&& self.tx.sprout_bundle.is_none()
|
||||
&& self.tx.sapling_bundle.is_none()
|
||||
&& self.tx.joinsplits.is_empty()
|
||||
&& self.tx.orchard_bundle.is_none()
|
||||
}
|
||||
|
||||
|
|
|
@ -351,9 +351,7 @@ impl<'a, P: consensus::Parameters, R: RngCore> Builder<'a, P, R> {
|
|||
tze_outputs,
|
||||
lock_time: 0,
|
||||
expiry_height: self.expiry_height,
|
||||
joinsplits: vec![],
|
||||
joinsplit_pubkey: None,
|
||||
joinsplit_sig: None,
|
||||
sprout_bundle: None,
|
||||
sapling_bundle,
|
||||
orchard_bundle: None,
|
||||
};
|
||||
|
@ -435,9 +433,7 @@ impl<'a, P: consensus::Parameters, R: RngCore> Builder<'a, P, R> {
|
|||
tze_outputs: unauthed_tx.tze_outputs,
|
||||
lock_time: unauthed_tx.lock_time,
|
||||
expiry_height: unauthed_tx.expiry_height,
|
||||
joinsplits: unauthed_tx.joinsplits,
|
||||
joinsplit_pubkey: unauthed_tx.joinsplit_pubkey,
|
||||
joinsplit_sig: unauthed_tx.joinsplit_sig,
|
||||
sprout_bundle: unauthed_tx.sprout_bundle,
|
||||
sapling_bundle: signed_sapling_bundle,
|
||||
orchard_bundle: None,
|
||||
};
|
||||
|
|
|
@ -10,6 +10,13 @@ const PHGR_PROOF_SIZE: usize = 33 + 33 + 65 + 33 + 33 + 33 + 33 + 33;
|
|||
const ZC_NUM_JS_INPUTS: usize = 2;
|
||||
const ZC_NUM_JS_OUTPUTS: usize = 2;
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct Bundle {
|
||||
pub joinsplits: Vec<JsDescription>,
|
||||
pub joinsplit_pubkey: [u8; 32],
|
||||
pub joinsplit_sig: [u8; 64],
|
||||
}
|
||||
|
||||
#[derive(Clone)]
|
||||
pub(crate) enum SproutProof {
|
||||
Groth([u8; GROTH_PROOF_SIZE]),
|
||||
|
|
|
@ -15,7 +15,10 @@ use crate::{
|
|||
|
||||
use self::{
|
||||
components::{
|
||||
sapling, Amount, JsDescription, OutputDescription, SpendDescription, TxIn, TxOut,
|
||||
amount::Amount,
|
||||
sapling::{self, OutputDescription, SpendDescription},
|
||||
sprout::{self, JsDescription},
|
||||
transparent::{TxIn, TxOut},
|
||||
},
|
||||
sighash::{signature_hash_data, SignableInput, SIGHASH_ALL},
|
||||
util::sha256d::{HashReader, HashWriter},
|
||||
|
@ -243,9 +246,7 @@ pub struct TransactionData<A: Authorization> {
|
|||
pub tze_outputs: Vec<TzeOut>,
|
||||
pub lock_time: u32,
|
||||
pub expiry_height: BlockHeight,
|
||||
pub joinsplits: Vec<JsDescription>,
|
||||
pub joinsplit_pubkey: Option<[u8; 32]>,
|
||||
pub joinsplit_sig: Option<[u8; 64]>,
|
||||
pub sprout_bundle: Option<sprout::Bundle>,
|
||||
pub sapling_bundle: Option<sapling::Bundle<A::SaplingAuth>>,
|
||||
pub orchard_bundle: Option<orchard::Bundle<A::OrchardAuth, Amount>>,
|
||||
}
|
||||
|
@ -293,8 +294,10 @@ impl<A: Authorization> std::fmt::Debug for TransactionData<A> {
|
|||
self.sapling_bundle
|
||||
.as_ref()
|
||||
.map_or(&vec![], |b| &b.shielded_outputs),
|
||||
self.joinsplits,
|
||||
self.joinsplit_pubkey,
|
||||
self.sprout_bundle
|
||||
.as_ref()
|
||||
.map_or(&vec![], |b| &b.joinsplits),
|
||||
self.sprout_bundle.as_ref().map(|b| &b.joinsplit_pubkey),
|
||||
self.sapling_bundle.as_ref().map(|b| &b.authorization)
|
||||
)
|
||||
}
|
||||
|
@ -326,9 +329,7 @@ impl TransactionData<Unauthorized> {
|
|||
tze_outputs: vec![],
|
||||
lock_time: 0,
|
||||
expiry_height: 0u32.into(),
|
||||
joinsplits: vec![],
|
||||
joinsplit_pubkey: None,
|
||||
joinsplit_sig: None,
|
||||
sprout_bundle: None,
|
||||
sapling_bundle: None,
|
||||
orchard_bundle: None,
|
||||
}
|
||||
|
@ -344,9 +345,7 @@ impl TransactionData<Unauthorized> {
|
|||
tze_outputs: vec![],
|
||||
lock_time: 0,
|
||||
expiry_height: 0u32.into(),
|
||||
joinsplits: vec![],
|
||||
joinsplit_pubkey: None,
|
||||
joinsplit_sig: None,
|
||||
sprout_bundle: None,
|
||||
sapling_bundle: None,
|
||||
orchard_bundle: None,
|
||||
}
|
||||
|
@ -426,22 +425,25 @@ impl Transaction {
|
|||
(Amount::zero(), vec![], vec![])
|
||||
};
|
||||
|
||||
let (joinsplits, joinsplit_pubkey, joinsplit_sig) = if version.has_sprout() {
|
||||
let jss = Vector::read(&mut reader, |r| {
|
||||
let sprout_bundle = if version.has_sprout() {
|
||||
let joinsplits = Vector::read(&mut reader, |r| {
|
||||
JsDescription::read(r, version.has_sapling())
|
||||
})?;
|
||||
let (pubkey, sig) = if !jss.is_empty() {
|
||||
let mut joinsplit_pubkey = [0; 32];
|
||||
let mut joinsplit_sig = [0; 64];
|
||||
reader.read_exact(&mut joinsplit_pubkey)?;
|
||||
reader.read_exact(&mut joinsplit_sig)?;
|
||||
(Some(joinsplit_pubkey), Some(joinsplit_sig))
|
||||
|
||||
if !joinsplits.is_empty() {
|
||||
let mut bundle = sprout::Bundle {
|
||||
joinsplits,
|
||||
joinsplit_pubkey: [0; 32],
|
||||
joinsplit_sig: [0; 64],
|
||||
};
|
||||
reader.read_exact(&mut bundle.joinsplit_pubkey)?;
|
||||
reader.read_exact(&mut bundle.joinsplit_sig)?;
|
||||
Some(bundle)
|
||||
} else {
|
||||
(None, None)
|
||||
};
|
||||
(jss, pubkey, sig)
|
||||
None
|
||||
}
|
||||
} else {
|
||||
(vec![], None, None)
|
||||
None
|
||||
};
|
||||
|
||||
let binding_sig = if (is_sapling_v4 || has_tze)
|
||||
|
@ -467,9 +469,7 @@ impl Transaction {
|
|||
tze_outputs,
|
||||
lock_time,
|
||||
expiry_height,
|
||||
joinsplits,
|
||||
joinsplit_pubkey,
|
||||
joinsplit_sig,
|
||||
sprout_bundle,
|
||||
sapling_bundle: binding_sig.map(|binding_sig| sapling::Bundle {
|
||||
value_balance,
|
||||
shielded_spends,
|
||||
|
@ -529,41 +529,16 @@ impl Transaction {
|
|||
}
|
||||
|
||||
if self.version.has_sprout() {
|
||||
Vector::write(&mut writer, &self.joinsplits, |w, e| e.write(w))?;
|
||||
if !self.joinsplits.is_empty() {
|
||||
match self.joinsplit_pubkey {
|
||||
Some(pubkey) => writer.write_all(&pubkey)?,
|
||||
None => {
|
||||
return Err(io::Error::new(
|
||||
io::ErrorKind::InvalidInput,
|
||||
"Missing JoinSplit pubkey",
|
||||
));
|
||||
}
|
||||
}
|
||||
match self.joinsplit_sig {
|
||||
Some(sig) => writer.write_all(&sig)?,
|
||||
None => {
|
||||
return Err(io::Error::new(
|
||||
io::ErrorKind::InvalidInput,
|
||||
"Missing JoinSplit signature",
|
||||
));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if !self.version.has_sprout() || self.joinsplits.is_empty() {
|
||||
if self.joinsplit_pubkey.is_some() {
|
||||
return Err(io::Error::new(
|
||||
io::ErrorKind::InvalidInput,
|
||||
"JoinSplit pubkey should not be present",
|
||||
));
|
||||
}
|
||||
if self.joinsplit_sig.is_some() {
|
||||
return Err(io::Error::new(
|
||||
io::ErrorKind::InvalidInput,
|
||||
"JoinSplit signature should not be present",
|
||||
));
|
||||
Vector::write(
|
||||
&mut writer,
|
||||
self.sprout_bundle
|
||||
.as_ref()
|
||||
.map_or(&vec![], |b| &b.joinsplits),
|
||||
|w, e| e.write(w),
|
||||
)?;
|
||||
for bundle in &self.sprout_bundle {
|
||||
writer.write_all(&bundle.joinsplit_pubkey)?;
|
||||
writer.write_all(&bundle.joinsplit_sig)?;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -577,10 +552,12 @@ impl Transaction {
|
|||
));
|
||||
}
|
||||
} else {
|
||||
return Err(io::Error::new(
|
||||
io::ErrorKind::InvalidInput,
|
||||
"Binding signature should not be present",
|
||||
));
|
||||
if self.sapling_bundle.is_some() {
|
||||
return Err(io::Error::new(
|
||||
io::ErrorKind::InvalidInput,
|
||||
"Binding signature should not be present",
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
Ok(())
|
||||
|
@ -727,9 +704,7 @@ pub mod testing {
|
|||
tze_outputs: if branch_id == BranchId::ZFuture { tze_outputs } else { vec![] },
|
||||
lock_time,
|
||||
expiry_height: expiry_height.into(),
|
||||
joinsplits: vec![], //FIXME
|
||||
joinsplit_pubkey: None, //FIXME
|
||||
joinsplit_sig: None, //FIXME
|
||||
sprout_bundle: None,
|
||||
sapling_bundle: None, //FIXME
|
||||
orchard_bundle: None, //FIXME
|
||||
}
|
||||
|
@ -750,9 +725,7 @@ pub mod testing {
|
|||
vin, vout,
|
||||
lock_time,
|
||||
expiry_height: expiry_height.into(),
|
||||
joinsplits: vec![], //FIXME
|
||||
joinsplit_pubkey: None, //FIXME
|
||||
joinsplit_sig: None, //FIXME
|
||||
sprout_bundle: None,
|
||||
sapling_bundle: None, //FIXME
|
||||
orchard_bundle: None, //FIXME
|
||||
}
|
||||
|
|
|
@ -299,12 +299,17 @@ pub fn signature_hash_data<
|
|||
}
|
||||
update_hash!(
|
||||
h,
|
||||
!tx.joinsplits.is_empty(),
|
||||
joinsplits_hash(
|
||||
consensus_branch_id,
|
||||
&tx.joinsplits,
|
||||
&tx.joinsplit_pubkey.unwrap()
|
||||
)
|
||||
!tx.sprout_bundle
|
||||
.as_ref()
|
||||
.map_or(true, |b| b.joinsplits.is_empty()),
|
||||
{
|
||||
let bundle = tx.sprout_bundle.as_ref().unwrap();
|
||||
joinsplits_hash(
|
||||
consensus_branch_id,
|
||||
&bundle.joinsplits,
|
||||
&bundle.joinsplit_pubkey,
|
||||
)
|
||||
}
|
||||
);
|
||||
if tx.version.has_sapling() {
|
||||
update_hash!(
|
||||
|
|
Loading…
Reference in New Issue