mirror of
https://github.com/Qortal/pirate-librustzcash.git
synced 2025-02-15 19:25:47 +00:00
Use Option<[u8; N]> for JoinSplit pubkey and signature in a transaction
This commit is contained in:
parent
9b06205ed6
commit
d707ebd321
@ -43,8 +43,8 @@ pub struct TransactionData {
|
|||||||
pub shielded_spends: Vec<SpendDescription>,
|
pub shielded_spends: Vec<SpendDescription>,
|
||||||
pub shielded_outputs: Vec<OutputDescription>,
|
pub shielded_outputs: Vec<OutputDescription>,
|
||||||
pub joinsplits: Vec<JSDescription>,
|
pub joinsplits: Vec<JSDescription>,
|
||||||
pub joinsplit_pubkey: [u8; 32],
|
pub joinsplit_pubkey: Option<[u8; 32]>,
|
||||||
pub joinsplit_sig: [u8; 64],
|
pub joinsplit_sig: Option<[u8; 64]>,
|
||||||
pub binding_sig: Option<Signature>,
|
pub binding_sig: Option<Signature>,
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -62,8 +62,8 @@ impl TransactionData {
|
|||||||
shielded_spends: vec![],
|
shielded_spends: vec![],
|
||||||
shielded_outputs: vec![],
|
shielded_outputs: vec![],
|
||||||
joinsplits: vec![],
|
joinsplits: vec![],
|
||||||
joinsplit_pubkey: [0u8; 32],
|
joinsplit_pubkey: None,
|
||||||
joinsplit_sig: [0u8; 64],
|
joinsplit_sig: None,
|
||||||
binding_sig: None,
|
binding_sig: None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -122,19 +122,22 @@ impl Transaction {
|
|||||||
(Amount(0), vec![], vec![])
|
(Amount(0), vec![], vec![])
|
||||||
};
|
};
|
||||||
|
|
||||||
let mut joinsplit_pubkey = [0; 32];
|
let (joinsplits, joinsplit_pubkey, joinsplit_sig) = if version >= 2 {
|
||||||
let mut joinsplit_sig = [0; 64];
|
|
||||||
let joinsplits = if version >= 2 {
|
|
||||||
let jss = Vector::read(&mut reader, |r| {
|
let jss = Vector::read(&mut reader, |r| {
|
||||||
JSDescription::read(r, overwintered && version >= SAPLING_TX_VERSION)
|
JSDescription::read(r, overwintered && version >= SAPLING_TX_VERSION)
|
||||||
})?;
|
})?;
|
||||||
if !jss.is_empty() {
|
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_pubkey)?;
|
||||||
reader.read_exact(&mut joinsplit_sig)?;
|
reader.read_exact(&mut joinsplit_sig)?;
|
||||||
}
|
(Some(joinsplit_pubkey), Some(joinsplit_sig))
|
||||||
jss
|
} else {
|
||||||
|
(None, None)
|
||||||
|
};
|
||||||
|
(jss, pubkey, sig)
|
||||||
} else {
|
} else {
|
||||||
vec![]
|
(vec![], None, None)
|
||||||
};
|
};
|
||||||
|
|
||||||
let binding_sig =
|
let binding_sig =
|
||||||
@ -196,8 +199,39 @@ impl Transaction {
|
|||||||
if self.version >= 2 {
|
if self.version >= 2 {
|
||||||
Vector::write(&mut writer, &self.joinsplits, |w, e| e.write(w))?;
|
Vector::write(&mut writer, &self.joinsplits, |w, e| e.write(w))?;
|
||||||
if !self.joinsplits.is_empty() {
|
if !self.joinsplits.is_empty() {
|
||||||
writer.write_all(&self.joinsplit_pubkey)?;
|
match self.joinsplit_pubkey {
|
||||||
writer.write_all(&self.joinsplit_sig)?;
|
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 < 2 || 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",
|
||||||
|
));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -110,7 +110,7 @@ fn joinsplits_hash(tx: &TransactionData) -> Vec<u8> {
|
|||||||
for js in &tx.joinsplits {
|
for js in &tx.joinsplits {
|
||||||
js.write(&mut data).unwrap();
|
js.write(&mut data).unwrap();
|
||||||
}
|
}
|
||||||
data.extend_from_slice(&tx.joinsplit_pubkey);
|
data.extend_from_slice(&tx.joinsplit_pubkey.unwrap());
|
||||||
let mut h = Blake2b::with_params(32, &[], &[], ZCASH_JOINSPLITS_HASH_PERSONALIZATION);
|
let mut h = Blake2b::with_params(32, &[], &[], ZCASH_JOINSPLITS_HASH_PERSONALIZATION);
|
||||||
h.update(&data);
|
h.update(&data);
|
||||||
h.finalize().as_ref().to_vec()
|
h.finalize().as_ref().to_vec()
|
||||||
|
@ -156,6 +156,46 @@ fn tx_read_write() {
|
|||||||
assert_eq!(&data[..], &encoded[..]);
|
assert_eq!(&data[..], &encoded[..]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn tx_write_rejects_unexpected_joinsplit_pubkey() {
|
||||||
|
// Succeeds without a JoinSplit pubkey
|
||||||
|
{
|
||||||
|
let tx = TransactionData::new().freeze();
|
||||||
|
let mut encoded = Vec::new();
|
||||||
|
assert!(tx.write(&mut encoded).is_ok());
|
||||||
|
}
|
||||||
|
|
||||||
|
// Fails with an unexpected JoinSplit pubkey
|
||||||
|
{
|
||||||
|
let mut tx = TransactionData::new();
|
||||||
|
tx.joinsplit_pubkey = Some([0; 32]);
|
||||||
|
let tx = tx.freeze();
|
||||||
|
|
||||||
|
let mut encoded = Vec::new();
|
||||||
|
assert!(tx.write(&mut encoded).is_err());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn tx_write_rejects_unexpected_joinsplit_sig() {
|
||||||
|
// Succeeds without a JoinSplit signature
|
||||||
|
{
|
||||||
|
let tx = TransactionData::new().freeze();
|
||||||
|
let mut encoded = Vec::new();
|
||||||
|
assert!(tx.write(&mut encoded).is_ok());
|
||||||
|
}
|
||||||
|
|
||||||
|
// Fails with an unexpected JoinSplit signature
|
||||||
|
{
|
||||||
|
let mut tx = TransactionData::new();
|
||||||
|
tx.joinsplit_sig = Some([0; 64]);
|
||||||
|
let tx = tx.freeze();
|
||||||
|
|
||||||
|
let mut encoded = Vec::new();
|
||||||
|
assert!(tx.write(&mut encoded).is_err());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn tx_write_rejects_unexpected_binding_sig() {
|
fn tx_write_rejects_unexpected_binding_sig() {
|
||||||
// Succeeds without a binding signature
|
// Succeeds without a binding signature
|
||||||
|
Loading…
x
Reference in New Issue
Block a user