Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Murisi/borsh schemas #71

Merged
merged 3 commits into from
Mar 8, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 15 additions & 2 deletions masp_note_encryption/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@
#[cfg(feature = "alloc")]
extern crate alloc;
#[cfg(feature = "alloc")]
use crate::alloc::string::ToString;
#[cfg(feature = "alloc")]
use alloc::vec::Vec;

use core::convert::TryInto;
Expand All @@ -34,7 +36,7 @@ use cipher::KeyIvInit;

//use crate::constants::ASSET_IDENTIFIER_LENGTH;
pub const ASSET_IDENTIFIER_LENGTH: usize = 32;
use borsh::{BorshDeserialize, BorshSerialize};
use borsh::{BorshDeserialize, BorshSchema, BorshSerialize};
use rand_core::RngCore;
use subtle::{Choice, ConstantTimeEq};

Expand Down Expand Up @@ -77,7 +79,18 @@ impl AsRef<[u8]> for OutgoingCipherKey {
/// Newtype representing the byte encoding of an [`EphemeralPublicKey`].
///
/// [`EphemeralPublicKey`]: Domain::EphemeralPublicKey
#[derive(BorshSerialize, BorshDeserialize, Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
#[derive(
BorshSerialize,
BorshDeserialize,
BorshSchema,
Clone,
Debug,
PartialEq,
Eq,
PartialOrd,
Ord,
Hash,
)]
pub struct EphemeralKeyBytes(pub [u8; 32]);

impl AsRef<[u8]> for EphemeralKeyBytes {
Expand Down
3 changes: 2 additions & 1 deletion masp_primitives/src/asset_type.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ use crate::{
sapling::ValueCommitment,
};
use blake2s_simd::Params as Blake2sParams;
use borsh::BorshSchema;
use borsh::{BorshDeserialize, BorshSerialize};
use group::{cofactor::CofactorGroup, Group, GroupEncoding};
use std::{
Expand All @@ -14,7 +15,7 @@ use std::{
hash::{Hash, Hasher},
};

#[derive(Debug, BorshSerialize, BorshDeserialize, Clone, Copy, Eq)]
#[derive(Debug, BorshSerialize, BorshDeserialize, Clone, Copy, Eq, BorshSchema)]
pub struct AssetType {
identifier: [u8; ASSET_IDENTIFIER_LENGTH], //32 byte asset type preimage
#[borsh(skip)]
Expand Down
41 changes: 39 additions & 2 deletions masp_primitives/src/consensus.rs
Original file line number Diff line number Diff line change
@@ -1,16 +1,22 @@
//! Consensus logic and parameters.

use borsh::{BorshDeserialize, BorshSerialize};
use borsh::schema::add_definition;
use borsh::schema::Definition;
use borsh::{BorshDeserialize, BorshSchema, BorshSerialize};
use memuse::DynamicUsage;
use std::cmp::{Ord, Ordering};
use std::collections::BTreeMap;
use std::convert::TryFrom;
use std::fmt;
use std::io::{Error, ErrorKind, Read, Write};
use std::ops::{Add, Bound, RangeBounds, Sub};

/// A wrapper type representing blockchain heights. Safe conversion from
/// various integer types, as well as addition and subtraction, are provided.
#[repr(transparent)]
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, BorshSerialize, BorshDeserialize)]
#[derive(
Clone, Copy, Debug, PartialEq, Eq, Hash, BorshSerialize, BorshDeserialize, BorshSchema,
)]
pub struct BlockHeight(u32);

memuse::impl_no_dynamic_usage!(BlockHeight);
Expand Down Expand Up @@ -265,6 +271,37 @@ impl From<BranchId> for u32 {
}
}

impl BorshSerialize for BranchId {
fn serialize<W: Write>(&self, writer: &mut W) -> std::io::Result<()> {
u32::from(*self).serialize(writer)
}
}

impl BorshDeserialize for BranchId {
fn deserialize_reader<R: Read>(reader: &mut R) -> std::io::Result<Self> {
u32::deserialize_reader(reader)?
.try_into()
.map_err(|x| Error::new(ErrorKind::InvalidInput, x))
}
}

impl BorshSchema for BranchId {
fn add_definitions_recursively(
definitions: &mut BTreeMap<borsh::schema::Declaration, borsh::schema::Definition>,
) {
let definition = Definition::Enum {
tag_width: 4,
variants: vec![(0xe9ff_75a6, "MASP".into(), <()>::declaration())],
};
add_definition(Self::declaration(), definition, definitions);
<()>::add_definitions_recursively(definitions);
}

fn declaration() -> borsh::schema::Declaration {
"BranchId".into()
}
}

impl BranchId {
/// Returns the branch ID corresponding to the consensus rule set that is active at
/// the given height.
Expand Down
24 changes: 24 additions & 0 deletions masp_primitives/src/convert.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,14 @@ use crate::{
},
transaction::components::amount::{I128Sum, ValueSum},
};
use borsh::schema::add_definition;
use borsh::schema::Declaration;
use borsh::schema::Definition;
use borsh::schema::Fields;
use borsh::BorshSchema;
use borsh::{BorshDeserialize, BorshSerialize};
use group::{Curve, GroupEncoding};
use std::collections::BTreeMap;
use std::{
io::{self, Write},
iter::Sum,
Expand Down Expand Up @@ -110,6 +116,24 @@ impl From<I128Sum> for AllowedConversion {
}
}

impl BorshSchema for AllowedConversion {
fn add_definitions_recursively(definitions: &mut BTreeMap<Declaration, Definition>) {
let definition = Definition::Struct {
fields: Fields::NamedFields(vec![
("assets".into(), I128Sum::declaration()),
("generator".into(), <[u8; 32]>::declaration()),
]),
};
add_definition(Self::declaration(), definition, definitions);
I128Sum::add_definitions_recursively(definitions);
<[u8; 32]>::add_definitions_recursively(definitions);
}

fn declaration() -> Declaration {
"AllowedConversion".into()
}
}

impl BorshSerialize for AllowedConversion {
fn serialize<W: Write>(&self, writer: &mut W) -> io::Result<()> {
self.assets.write(writer)?;
Expand Down
4 changes: 2 additions & 2 deletions masp_primitives/src/memo.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
//! Structs for handling encrypted memos.

use borsh::{BorshDeserialize, BorshSerialize};
use borsh::{BorshDeserialize, BorshSchema, BorshSerialize};
use std::cmp::Ordering;
use std::convert::{TryFrom, TryInto};
use std::error;
Expand Down Expand Up @@ -48,7 +48,7 @@ impl fmt::Display for Error {
impl error::Error for Error {}

/// The unencrypted memo bytes received alongside a shielded note in a Zcash transaction.
#[derive(Clone, BorshSerialize, BorshDeserialize)]
#[derive(Clone, BorshSerialize, BorshDeserialize, BorshSchema)]
pub struct MemoBytes(pub(crate) Box<[u8; 512]>);

impl fmt::Debug for MemoBytes {
Expand Down
39 changes: 38 additions & 1 deletion masp_primitives/src/merkle_tree.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,19 @@

use byteorder::{LittleEndian, ReadBytesExt, WriteBytesExt};

use borsh::schema::add_definition;
use borsh::schema::Declaration;
use borsh::schema::Definition;
use borsh::schema::Fields;
use borsh::BorshSchema;
use borsh::{BorshDeserialize, BorshSerialize};
use core::convert::TryFrom;
use incrementalmerkletree::{
self,
bridgetree::{self, Leaf},
Altitude,
};
use std::collections::BTreeMap;
use std::collections::VecDeque;
use std::io::{self, Read, Write};
use std::iter::repeat;
Expand Down Expand Up @@ -711,7 +717,7 @@ impl<Node: Hashable> BorshDeserialize for IncrementalWitness<Node> {

/// A path from a position in a particular commitment tree to the root of that tree.
#[derive(Clone, Debug, PartialEq, Eq)]
pub struct MerklePath<Node: Hashable> {
pub struct MerklePath<Node> {
pub auth_path: Vec<(Node, bool)>,
pub position: u64,
}
Expand Down Expand Up @@ -837,6 +843,37 @@ impl<Node: Hashable> BorshSerialize for MerklePath<Node> {
}
}

impl<Node: BorshSchema> BorshSchema for MerklePath<Node> {
fn add_definitions_recursively(definitions: &mut BTreeMap<Declaration, Definition>) {
let definition = Definition::Sequence {
length_width: 1,
length_range: ((u8::MIN as u64)..=(u8::MAX as u64)),
elements: <(u8, Node)>::declaration(),
};
add_definition(
format!(r#"{}::auth_path"#, Self::declaration()),
definition,
definitions,
);
let definition = Definition::Struct {
fields: Fields::NamedFields(vec![
(
"auth_path".into(),
format!(r#"{}::auth_path"#, Self::declaration()),
),
("position".into(), u64::declaration()),
]),
};
add_definition(Self::declaration(), definition, definitions);
<(u8, Node)>::add_definitions_recursively(definitions);
u64::add_definitions_recursively(definitions);
}

fn declaration() -> Declaration {
format!(r#"MerklePath<{}>"#, Node::declaration())
}
}

#[cfg(test)]
mod tests {

Expand Down
Loading
Loading