JointSplit -> JoinSplit

This commit is contained in:
Svyatoslav Nikolsky 2018-11-19 10:08:41 +03:00
parent afb52268bb
commit 106a93fb2e
5 changed files with 46 additions and 62 deletions

View File

@ -4,20 +4,20 @@ use hex::ToHex;
use ser::{Error, Stream, Reader, CompactInteger};
#[derive(Clone)]
pub enum JointSplitProof {
pub enum JoinSplitProof {
PHGR([u8; 296]),
Groth([u8; 192]),
}
#[derive(Debug, PartialEq, Default, Clone)]
pub struct JointSplit {
pub descriptions: Vec<JointSplitDescription>,
pub struct JoinSplit {
pub descriptions: Vec<JoinSplitDescription>,
pub pubkey: H256,
pub sig: H512,
}
#[derive(Clone)]
pub struct JointSplitDescription {
pub struct JoinSplitDescription {
pub value_pub_old: u64,
pub value_pub_new: u64,
pub anchor: [u8; 32],
@ -26,13 +26,13 @@ pub struct JointSplitDescription {
pub ephemeral_key: [u8; 32],
pub random_seed: [u8; 32],
pub macs: [[u8; 32]; 2],
pub zkproof: JointSplitProof,
pub zkproof: JoinSplitProof,
pub ciphertexts: [[u8; 601]; 2],
}
impl Default for JointSplitDescription {
impl Default for JoinSplitDescription {
fn default() -> Self {
JointSplitDescription {
JoinSplitDescription {
value_pub_old: Default::default(),
value_pub_new: Default::default(),
anchor: Default::default(),
@ -47,9 +47,9 @@ impl Default for JointSplitDescription {
}
}
impl fmt::Debug for JointSplitDescription {
impl fmt::Debug for JoinSplitDescription {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
f.debug_struct("JointSplitDescription")
f.debug_struct("JoinSplitDescription")
.field("value_pub_old", &self.value_pub_old)
.field("value_pub_new", &self.value_pub_new)
.field("anchor", &self.anchor.to_hex::<String>())
@ -68,8 +68,8 @@ impl fmt::Debug for JointSplitDescription {
}
}
impl PartialEq<JointSplitDescription> for JointSplitDescription {
fn eq(&self, other: &JointSplitDescription) -> bool {
impl PartialEq<JoinSplitDescription> for JoinSplitDescription {
fn eq(&self, other: &JoinSplitDescription) -> bool {
self.value_pub_old == other.value_pub_old
&& self.value_pub_new == other.value_pub_new
&& self.anchor == other.anchor
@ -84,32 +84,32 @@ impl PartialEq<JointSplitDescription> for JointSplitDescription {
}
}
impl Default for JointSplitProof {
impl Default for JoinSplitProof {
fn default() -> Self {
JointSplitProof::Groth([0; 192])
JoinSplitProof::Groth([0; 192])
}
}
impl fmt::Debug for JointSplitProof {
impl fmt::Debug for JoinSplitProof {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match *self {
JointSplitProof::PHGR(ref proof) => f.write_fmt(format_args!("PHGR({:?})", &proof.to_hex::<String>())),
JointSplitProof::Groth(ref proof) => f.write_fmt(format_args!("Groth({:?})", &proof.to_hex::<String>())),
JoinSplitProof::PHGR(ref proof) => f.write_fmt(format_args!("PHGR({:?})", &proof.to_hex::<String>())),
JoinSplitProof::Groth(ref proof) => f.write_fmt(format_args!("Groth({:?})", &proof.to_hex::<String>())),
}
}
}
impl PartialEq<JointSplitProof> for JointSplitProof {
fn eq(&self, other: &JointSplitProof) -> bool {
impl PartialEq<JoinSplitProof> for JoinSplitProof {
fn eq(&self, other: &JoinSplitProof) -> bool {
match (self, other) {
(&JointSplitProof::Groth(v1), &JointSplitProof::Groth(v2)) => v1.as_ref() == v2.as_ref(),
(&JointSplitProof::PHGR(v1), &JointSplitProof::PHGR(v2)) => v1.as_ref() == v2.as_ref(),
(&JoinSplitProof::Groth(v1), &JoinSplitProof::Groth(v2)) => v1.as_ref() == v2.as_ref(),
(&JoinSplitProof::PHGR(v1), &JoinSplitProof::PHGR(v2)) => v1.as_ref() == v2.as_ref(),
_ => false,
}
}
}
pub fn serialize_joint_split(stream: &mut Stream, joint_split: &Option<JointSplit>) {
pub fn serialize_joint_split(stream: &mut Stream, joint_split: &Option<JoinSplit>) {
if let &Some(ref joint_split) = joint_split {
let len: CompactInteger = joint_split.descriptions.len().into();
stream.append(&len);
@ -124,8 +124,8 @@ pub fn serialize_joint_split(stream: &mut Stream, joint_split: &Option<JointSpli
.append(&d.random_seed)
.append(&d.macs);
match d.zkproof {
JointSplitProof::PHGR(ref proof) => stream.append(proof),
JointSplitProof::Groth(ref proof) => stream.append(proof),
JoinSplitProof::PHGR(ref proof) => stream.append(proof),
JoinSplitProof::Groth(ref proof) => stream.append(proof),
};
stream.append(&d.ciphertexts);
}
@ -135,11 +135,11 @@ pub fn serialize_joint_split(stream: &mut Stream, joint_split: &Option<JointSpli
}
}
pub fn deserialize_joint_split<T>(reader: &mut Reader<T>, use_groth: bool) -> Result<Option<JointSplit>, Error> where T: io::Read {
pub fn deserialize_joint_split<T>(reader: &mut Reader<T>, use_groth: bool) -> Result<Option<JoinSplit>, Error> where T: io::Read {
let len: usize = reader.read::<CompactInteger>()?.into();
let mut descriptions = Vec::with_capacity(len);
for _ in 0..len {
descriptions.push(JointSplitDescription {
descriptions.push(JoinSplitDescription {
value_pub_old: reader.read()?,
value_pub_new: reader.read()?,
anchor: reader.read()?,
@ -149,9 +149,9 @@ pub fn deserialize_joint_split<T>(reader: &mut Reader<T>, use_groth: bool) -> Re
random_seed: reader.read()?,
macs: reader.read()?,
zkproof: if use_groth {
JointSplitProof::Groth(reader.read()?)
JoinSplitProof::Groth(reader.read()?)
} else {
JointSplitProof::PHGR(reader.read()?)
JoinSplitProof::PHGR(reader.read()?)
},
ciphertexts: reader.read()?,
});
@ -160,7 +160,7 @@ pub fn deserialize_joint_split<T>(reader: &mut Reader<T>, use_groth: bool) -> Re
let pubkey = reader.read()?;
let sig = reader.read()?;
Ok(Some(JointSplit {
Ok(Some(JoinSplit {
descriptions,
pubkey,
sig,

View File

@ -34,7 +34,7 @@ pub use transaction::{OVERWINTER_TX_VERSION_GROUP_ID, SAPLING_TX_VERSION_GROUP_I
pub use block::Block;
pub use block_header::BlockHeader;
pub use solution::EquihashSolution;
pub use join_split::{JointSplit, JointSplitDescription};
pub use join_split::{JoinSplit, JoinSplitDescription};
pub use merkle_root::{merkle_root, merkle_node_hash};
pub use sapling::{Sapling, SaplingSpendDescription, SaplingOutputDescription};
pub use transaction::{Transaction, TransactionInput, TransactionOutput, OutPoint};

View File

@ -9,7 +9,7 @@ use ser::{deserialize, serialize};
use crypto::dhash256;
use hash::H256;
use constants::{SEQUENCE_FINAL, LOCKTIME_THRESHOLD};
use join_split::{JointSplit, deserialize_joint_split, serialize_joint_split};
use join_split::{JoinSplit, deserialize_joint_split, serialize_joint_split};
use sapling::Sapling;
use ser::{Error, Serializable, Deserializable, Stream, Reader};
@ -103,7 +103,7 @@ pub struct Transaction {
pub outputs: Vec<TransactionOutput>,
pub lock_time: u32,
pub expiry_height: u32,
pub joint_split: Option<JointSplit>,
pub joint_split: Option<JoinSplit>,
pub sapling: Option<Sapling>,
}

View File

@ -107,7 +107,7 @@ pub enum TransactionError {
/// Using output that is surely spent
UsingSpentOutput(H256, u32),
/// A coinbase transaction MUST NOT have any joint split descriptions
CoinbaseWithJointSplit,
CoinbaseWithJoinSplit,
/// Invalid transaction version.
InvalidVersion,
/// Invalid transaction version group.

View File

@ -13,7 +13,7 @@ pub struct TransactionVerifier<'a> {
pub empty: TransactionEmpty<'a>,
pub null_non_coinbase: TransactionNullNonCoinbase<'a>,
pub oversized_coinbase: TransactionOversizedCoinbase<'a>,
pub joint_split_in_coinbase: TransactionJointSplitInCoinbase<'a>,
pub joint_split_in_coinbase: TransactionJoinSplitInCoinbase<'a>,
pub size: TransactionAbsoluteSize<'a>,
pub value_overflow: TransactionValueOverflow<'a>,
}
@ -26,7 +26,7 @@ impl<'a> TransactionVerifier<'a> {
empty: TransactionEmpty::new(transaction),
null_non_coinbase: TransactionNullNonCoinbase::new(transaction),
oversized_coinbase: TransactionOversizedCoinbase::new(transaction, MIN_COINBASE_SIZE..MAX_COINBASE_SIZE),
joint_split_in_coinbase: TransactionJointSplitInCoinbase::new(transaction),
joint_split_in_coinbase: TransactionJoinSplitInCoinbase::new(transaction),
size: TransactionAbsoluteSize::new(transaction, consensus),
value_overflow: TransactionValueOverflow::new(transaction, consensus),
}
@ -77,7 +77,7 @@ impl<'a> MemoryPoolTransactionVerifier<'a> {
}
}
/// If version == 1 or nJointSplit == 0, then tx_in_count MUST NOT be 0.
/// If version == 1 or nJoinSplit == 0, then tx_in_count MUST NOT be 0.
/// Transactions containing empty `vin` must have either non-empty `vjoinsplit` or non-empty `vShieldedSpend`.
/// Transactions containing empty `vout` must have either non-empty `vjoinsplit` or non-empty `vShieldedOutput`.
pub struct TransactionEmpty<'a> {
@ -92,7 +92,7 @@ impl<'a> TransactionEmpty<'a> {
}
fn check(&self) -> Result<(), TransactionError> {
// If version == 1 or nJointSplit == 0, then tx_in_count MUST NOT be 0.
// If version == 1 or nJoinSplit == 0, then tx_in_count MUST NOT be 0.
if self.transaction.raw.version == 1 || self.transaction.raw.joint_split.is_none() {
if self.transaction.raw.inputs.is_empty() {
return Err(TransactionError::Empty);
@ -266,20 +266,20 @@ impl<'a> TransactionVersion<'a> {
}
/// A coinbase transaction MUST NOT have any JoinSplit descriptions.
pub struct TransactionJointSplitInCoinbase<'a> {
pub struct TransactionJoinSplitInCoinbase<'a> {
transaction: &'a IndexedTransaction,
}
impl<'a> TransactionJointSplitInCoinbase<'a> {
impl<'a> TransactionJoinSplitInCoinbase<'a> {
fn new(transaction: &'a IndexedTransaction) -> Self {
TransactionJointSplitInCoinbase {
TransactionJoinSplitInCoinbase {
transaction,
}
}
fn check(&self) -> Result<(), TransactionError> {
if self.transaction.raw.is_coinbase() && self.transaction.raw.joint_split.is_some() {
return Err(TransactionError::CoinbaseWithJointSplit);
return Err(TransactionError::CoinbaseWithJoinSplit);
}
Ok(())
@ -325,7 +325,7 @@ mod tests {
SAPLING_TX_VERSION_GROUP_ID};
use network::{Network, ConsensusParams};
use error::TransactionError;
use super::{TransactionEmpty, TransactionVersion, TransactionJointSplitInCoinbase, TransactionValueOverflow};
use super::{TransactionEmpty, TransactionVersion, TransactionJoinSplitInCoinbase, TransactionValueOverflow};
#[test]
fn transaction_empty_works() {
@ -349,22 +349,6 @@ mod tests {
#[test]
fn transaction_version_works() {
/*
if self.transaction.raw.version < OVERWINTER_TX_VERSION {
return Err(TransactionError::InvalidVersion);
}
let is_overwinter_group = self.transaction.raw.version_group_id == OVERWINTER_TX_VERSION_GROUP_ID;
let is_sapling_group = self.transaction.raw.version_group_id == SAPLING_TX_VERSION_GROUP_ID;
if !is_overwinter_group && !is_sapling_group {
return Err(TransactionError::InvalidVersionGroup);
}
Ok(())
*/
assert_eq!(TransactionVersion::new(&test_data::TransactionBuilder::with_version(0)
.into()).check(), Err(TransactionError::InvalidVersion));
@ -388,16 +372,16 @@ mod tests {
#[test]
fn transaction_joint_split_in_coinbase_works() {
assert_eq!(TransactionJointSplitInCoinbase::new(&test_data::TransactionBuilder::coinbase()
.add_default_joint_split().into()).check(), Err(TransactionError::CoinbaseWithJointSplit));
assert_eq!(TransactionJoinSplitInCoinbase::new(&test_data::TransactionBuilder::coinbase()
.add_default_joint_split().into()).check(), Err(TransactionError::CoinbaseWithJoinSplit));
assert_eq!(TransactionJointSplitInCoinbase::new(&test_data::TransactionBuilder::coinbase()
assert_eq!(TransactionJoinSplitInCoinbase::new(&test_data::TransactionBuilder::coinbase()
.into()).check(), Ok(()));
assert_eq!(TransactionJointSplitInCoinbase::new(&test_data::TransactionBuilder::default()
assert_eq!(TransactionJoinSplitInCoinbase::new(&test_data::TransactionBuilder::default()
.add_default_joint_split().into()).check(), Ok(()));
assert_eq!(TransactionJointSplitInCoinbase::new(&test_data::TransactionBuilder::default()
assert_eq!(TransactionJoinSplitInCoinbase::new(&test_data::TransactionBuilder::default()
.into()).check(), Ok(()));
}