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::{
parameters::Network,
primitives::Script,
serialization::{SerializationError, ZcashDeserialize, ZcashSerialize},
types::Script,
};
/// Magic numbers used to identify what networks Transparent Addresses
@ -247,8 +247,6 @@ mod tests {
use secp256k1::PublicKey;
use crate::types::Script;
use super::*;
#[test]

View File

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

View File

@ -20,12 +20,9 @@ pub mod commitments;
pub mod keys;
pub mod notes;
pub mod parameters;
pub mod proofs;
pub mod primitives;
pub mod serialization;
pub mod transaction;
pub mod treestate;
pub mod types;
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::block::BlockHeight;
use crate::proofs::{Bctv14Proof, Groth16Proof};
use crate::primitives::{Bctv14Proof, Groth16Proof};
/// A Zcash transaction.
///

View File

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

View File

@ -10,7 +10,7 @@ use std::{
use crate::{
commitments, keys, notes,
proofs::ZkSnarkProof,
primitives::{Script, ZkSnarkProof},
serialization::{
ReadZcashExt, SerializationError, WriteZcashExt, ZcashDeserialize, ZcashSerialize,
},
@ -227,7 +227,7 @@ impl ZcashDeserialize for TransparentInput {
hash: TransactionHash(bytes),
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>()?,
})
}
@ -246,7 +246,7 @@ impl ZcashDeserialize for TransparentOutput {
fn zcash_deserialize<R: io::Read>(mut reader: R) -> Result<Self, SerializationError> {
Ok(TransparentOutput {
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::{
commitments, keys, notes,
proofs::Groth16Proof,
redjubjub::{self, Binding, SpendAuth},
primitives::{
redjubjub::{self, Binding, SpendAuth},
Groth16Proof,
},
serialization::serde_helpers,
treestate::note_commitment_tree::SaplingNoteTreeRootHash,
};

View File

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

View File

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

View File

@ -1,12 +1,7 @@
//! Newtype wrappers for primitive data types with semantic meaning.
#![allow(clippy::unit_arg)]
use crate::serialization::{
ReadZcashExt, SerializationError, WriteZcashExt, ZcashDeserialize, ZcashSerialize,
};
use std::{
fmt,
io::{self, Read},
};
use crate::serialization::{ReadZcashExt, SerializationError, ZcashDeserialize, ZcashSerialize};
use std::io::{self, Read};
/// A sequence of message authentication tags ...
///
@ -29,56 +24,3 @@ impl ZcashSerialize for MAC {
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];
}
}
}