chain: create primitives module.

This contains definitions of primitive types used in other structures
and re-exports of component libraries.
This commit is contained in:
Henry de Valence 2020-08-15 16:33:46 -07:00
parent 196e841cd9
commit c5a8cb0c91
15 changed files with 98 additions and 84 deletions

View File

@ -11,8 +11,8 @@ use proptest::{arbitrary::Arbitrary, collection::vec, prelude::*};
use crate::{ use crate::{
parameters::Network, parameters::Network,
primitives::Script,
serialization::{SerializationError, ZcashDeserialize, ZcashSerialize}, serialization::{SerializationError, ZcashDeserialize, ZcashSerialize},
types::Script,
}; };
/// Magic numbers used to identify what networks Transparent Addresses /// Magic numbers used to identify what networks Transparent Addresses
@ -247,8 +247,6 @@ mod tests {
use secp256k1::PublicKey; use secp256k1::PublicKey;
use crate::types::Script;
use super::*; use super::*;
#[test] #[test]

View File

@ -31,7 +31,7 @@ use proptest_derive::Arbitrary;
use crate::{ use crate::{
parameters::Network, parameters::Network,
redjubjub::{self, SpendAuth}, primitives::redjubjub::{self, SpendAuth},
serialization::{ serialization::{
serde_helpers, ReadZcashExt, SerializationError, ZcashDeserialize, ZcashSerialize, serde_helpers, ReadZcashExt, SerializationError, ZcashDeserialize, ZcashSerialize,
}, },

View File

@ -20,12 +20,9 @@ pub mod commitments;
pub mod keys; pub mod keys;
pub mod notes; pub mod notes;
pub mod parameters; pub mod parameters;
pub mod proofs; pub mod primitives;
pub mod serialization; pub mod serialization;
pub mod transaction; pub mod transaction;
pub mod treestate; pub mod treestate;
pub mod types; pub mod types;
pub mod work; pub mod work;
pub use ed25519_zebra;
pub use redjubjub;

View File

@ -0,0 +1,15 @@
//! Primitives used in Zcash structures.
//!
//! This contains re-exports of libraries used in the public API, as well as stub
//! definitions of primitive types which must be represented in this library but
//! whose functionality is implemented elsewhere.
mod proofs;
mod script;
pub use ed25519_zebra as ed25519;
pub use redjubjub;
pub use x25519_dalek as x25519;
pub use proofs::{Bctv14Proof, Groth16Proof, ZkSnarkProof};
pub use script::Script;

View File

@ -0,0 +1,62 @@
#![allow(clippy::unit_arg)]
use crate::serialization::{
ReadZcashExt, SerializationError, WriteZcashExt, ZcashDeserialize, ZcashSerialize,
};
use std::{
fmt,
io::{self, Read},
};
/// An encoding of a Bitcoin script.
#[derive(Clone, Eq, PartialEq, Serialize, Deserialize)]
#[cfg_attr(test, derive(proptest_derive::Arbitrary))]
pub struct Script(pub Vec<u8>);
impl fmt::Debug for Script {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
f.debug_tuple("Script")
.field(&hex::encode(&self.0))
.finish()
}
}
impl ZcashSerialize for Script {
fn zcash_serialize<W: io::Write>(&self, mut writer: W) -> Result<(), io::Error> {
writer.write_compactsize(self.0.len() as u64)?;
writer.write_all(&self.0[..])?;
Ok(())
}
}
impl ZcashDeserialize for Script {
fn zcash_deserialize<R: io::Read>(mut reader: R) -> Result<Self, SerializationError> {
// XXX what is the max length of a script?
let len = reader.read_compactsize()?;
let mut bytes = Vec::new();
reader.take(len).read_to_end(&mut bytes)?;
Ok(Script(bytes))
}
}
#[cfg(test)]
mod proptests {
use std::io::Cursor;
use proptest::prelude::*;
use super::*;
use crate::serialization::{ZcashDeserialize, ZcashSerialize};
proptest! {
#[test]
fn script_roundtrip(script in any::<Script>()) {
let mut bytes = Cursor::new(Vec::new());
script.zcash_serialize(&mut bytes)?;
bytes.set_position(0);
let other_script = Script::zcash_deserialize(&mut bytes)?;
prop_assert_eq![script, other_script];
}
}
}

View File

@ -20,7 +20,7 @@ pub use transparent::{CoinbaseData, OutPoint, TransparentInput, TransparentOutpu
use crate::amount::Amount; use crate::amount::Amount;
use crate::block::BlockHeight; use crate::block::BlockHeight;
use crate::proofs::{Bctv14Proof, Groth16Proof}; use crate::primitives::{Bctv14Proof, Groth16Proof};
/// A Zcash transaction. /// A Zcash transaction.
/// ///

View File

@ -2,9 +2,8 @@ use serde::{Deserialize, Serialize};
use crate::{ use crate::{
amount::{Amount, NonNegative}, amount::{Amount, NonNegative},
ed25519_zebra,
notes::sprout, notes::sprout,
proofs::ZkSnarkProof, primitives::{ed25519, x25519, ZkSnarkProof},
treestate, treestate,
}; };
@ -29,15 +28,15 @@ pub struct JoinSplit<P: ZkSnarkProof> {
/// A note commitment for this output note. /// A note commitment for this output note.
pub commitments: [crate::commitments::sprout::NoteCommitment; 2], pub commitments: [crate::commitments::sprout::NoteCommitment; 2],
/// An X25519 public key. /// An X25519 public key.
pub ephemeral_key: x25519_dalek::PublicKey, pub ephemeral_key: x25519::PublicKey,
/// A 256-bit seed that must be chosen independently at random for each /// A 256-bit seed that must be chosen independently at random for each
/// JoinSplit description. /// JoinSplit description.
pub random_seed: [u8; 32], pub random_seed: [u8; 32],
/// A message authentication tag. /// A message authentication tag.
pub vmacs: [crate::types::MAC; 2], pub vmacs: [crate::types::MAC; 2],
/// A ZK JoinSplit proof, either a /// A ZK JoinSplit proof, either a
/// [`Groth16Proof`](crate::proofs::Groth16Proof) or a /// [`Groth16Proof`](crate::primitives::Groth16Proof) or a
/// [`Bctv14Proof`](crate::proofs::Bctv14Proof). /// [`Bctv14Proof`](crate::primitives::Bctv14Proof).
#[serde(bound(serialize = "P: ZkSnarkProof", deserialize = "P: ZkSnarkProof"))] #[serde(bound(serialize = "P: ZkSnarkProof", deserialize = "P: ZkSnarkProof"))]
pub zkproof: P, pub zkproof: P,
/// A ciphertext component for this output note. /// A ciphertext component for this output note.
@ -89,9 +88,9 @@ pub struct JoinSplitData<P: ZkSnarkProof> {
))] ))]
pub rest: Vec<JoinSplit<P>>, pub rest: Vec<JoinSplit<P>>,
/// The public key for the JoinSplit signature. /// The public key for the JoinSplit signature.
pub pub_key: ed25519_zebra::VerificationKeyBytes, pub pub_key: ed25519::VerificationKeyBytes,
/// The JoinSplit signature. /// The JoinSplit signature.
pub sig: ed25519_zebra::Signature, pub sig: ed25519::Signature,
} }
impl<P: ZkSnarkProof> JoinSplitData<P> { impl<P: ZkSnarkProof> JoinSplitData<P> {

View File

@ -10,7 +10,7 @@ use std::{
use crate::{ use crate::{
commitments, keys, notes, commitments, keys, notes,
proofs::ZkSnarkProof, primitives::{Script, ZkSnarkProof},
serialization::{ serialization::{
ReadZcashExt, SerializationError, WriteZcashExt, ZcashDeserialize, ZcashSerialize, ReadZcashExt, SerializationError, WriteZcashExt, ZcashDeserialize, ZcashSerialize,
}, },
@ -227,7 +227,7 @@ impl ZcashDeserialize for TransparentInput {
hash: TransactionHash(bytes), hash: TransactionHash(bytes),
index: reader.read_u32::<LittleEndian>()?, index: reader.read_u32::<LittleEndian>()?,
}, },
unlock_script: types::Script::zcash_deserialize(&mut reader)?, unlock_script: Script::zcash_deserialize(&mut reader)?,
sequence: reader.read_u32::<LittleEndian>()?, sequence: reader.read_u32::<LittleEndian>()?,
}) })
} }
@ -246,7 +246,7 @@ impl ZcashDeserialize for TransparentOutput {
fn zcash_deserialize<R: io::Read>(mut reader: R) -> Result<Self, SerializationError> { fn zcash_deserialize<R: io::Read>(mut reader: R) -> Result<Self, SerializationError> {
Ok(TransparentOutput { Ok(TransparentOutput {
value: reader.read_u64::<LittleEndian>()?.try_into()?, value: reader.read_u64::<LittleEndian>()?.try_into()?,
lock_script: types::Script::zcash_deserialize(&mut reader)?, lock_script: Script::zcash_deserialize(&mut reader)?,
}) })
} }
} }

View File

@ -1,7 +1,9 @@
use crate::{ use crate::{
commitments, keys, notes, commitments, keys, notes,
proofs::Groth16Proof, primitives::{
redjubjub::{self, Binding, SpendAuth}, redjubjub::{self, Binding, SpendAuth},
Groth16Proof,
},
serialization::serde_helpers, serialization::serde_helpers,
treestate::note_commitment_tree::SaplingNoteTreeRootHash, treestate::note_commitment_tree::SaplingNoteTreeRootHash,
}; };

View File

@ -7,13 +7,12 @@ use crate::{
block::BlockHeight, block::BlockHeight,
commitments, keys, commitments, keys,
notes::{sapling, sprout}, notes::{sapling, sprout},
proofs::{Bctv14Proof, Groth16Proof, ZkSnarkProof}, primitives::{Bctv14Proof, Groth16Proof, Script, ZkSnarkProof},
transaction::{ transaction::{
CoinbaseData, JoinSplit, JoinSplitData, LockTime, OutPoint, Output, ShieldedData, Spend, CoinbaseData, JoinSplit, JoinSplitData, LockTime, OutPoint, Output, ShieldedData, Spend,
Transaction, TransparentInput, TransparentOutput, Transaction, TransparentInput, TransparentOutput,
}, },
treestate::{self, note_commitment_tree::SaplingNoteTreeRootHash}, treestate::{self, note_commitment_tree::SaplingNoteTreeRootHash},
types::Script,
}; };
impl Transaction { impl Transaction {

View File

@ -7,7 +7,7 @@ use proptest_derive::Arbitrary;
use crate::{ use crate::{
amount::{Amount, NonNegative}, amount::{Amount, NonNegative},
block::BlockHeight, block::BlockHeight,
types::Script, primitives::Script,
}; };
use super::TransactionHash; use super::TransactionHash;

View File

@ -1,12 +1,7 @@
//! Newtype wrappers for primitive data types with semantic meaning. //! Newtype wrappers for primitive data types with semantic meaning.
#![allow(clippy::unit_arg)] #![allow(clippy::unit_arg)]
use crate::serialization::{ use crate::serialization::{ReadZcashExt, SerializationError, ZcashDeserialize, ZcashSerialize};
ReadZcashExt, SerializationError, WriteZcashExt, ZcashDeserialize, ZcashSerialize, use std::io::{self, Read};
};
use std::{
fmt,
io::{self, Read},
};
/// A sequence of message authentication tags ... /// A sequence of message authentication tags ...
/// ///
@ -29,56 +24,3 @@ impl ZcashSerialize for MAC {
writer.write_all(&self.0[..]) writer.write_all(&self.0[..])
} }
} }
/// An encoding of a Bitcoin script.
#[derive(Clone, Eq, PartialEq, Serialize, Deserialize)]
#[cfg_attr(test, derive(proptest_derive::Arbitrary))]
pub struct Script(pub Vec<u8>);
impl fmt::Debug for Script {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
f.debug_tuple("Script")
.field(&hex::encode(&self.0))
.finish()
}
}
impl ZcashSerialize for Script {
fn zcash_serialize<W: io::Write>(&self, mut writer: W) -> Result<(), io::Error> {
writer.write_compactsize(self.0.len() as u64)?;
writer.write_all(&self.0[..])?;
Ok(())
}
}
impl ZcashDeserialize for Script {
fn zcash_deserialize<R: io::Read>(mut reader: R) -> Result<Self, SerializationError> {
// XXX what is the max length of a script?
let len = reader.read_compactsize()?;
let mut bytes = Vec::new();
reader.take(len).read_to_end(&mut bytes)?;
Ok(Script(bytes))
}
}
#[cfg(test)]
mod proptests {
use std::io::Cursor;
use proptest::prelude::*;
use super::*;
use crate::serialization::{ZcashDeserialize, ZcashSerialize};
proptest! {
#[test]
fn script_roundtrip(script in any::<Script>()) {
let mut bytes = Cursor::new(Vec::new());
script.zcash_serialize(&mut bytes)?;
bytes.set_position(0);
let other_script = Script::zcash_deserialize(&mut bytes)?;
prop_assert_eq![script, other_script];
}
}
}