Skip to content

Commit

Permalink
RGB network serialization completed
Browse files Browse the repository at this point in the history
  • Loading branch information
dr-orlovsky committed Jan 22, 2020
1 parent 532f590 commit ab27b02
Show file tree
Hide file tree
Showing 4 changed files with 143 additions and 11 deletions.
2 changes: 1 addition & 1 deletion src/csv/serialize/commitment/collections.rs
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ impl<T> Commitment for Option<T> where T: Commitment {


/// In terms of commitment serialization, `Vec` is stored in form of usize-serialized length
/// (see `Commitemtn` implementation for `usize` type for serialization platform-independent
/// (see `Commitment` implementation for `usize` type for serialization platform-independent
/// constant-length serialization rules) followed by a consequently-serialized vec items,
/// according to their type.
///
Expand Down
86 changes: 86 additions & 0 deletions src/csv/serialize/network.rs
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,92 @@ macro_rules! network_serialize_from_commitment {
};
}

macro_rules! network_serialize_list {
( $encoder:ident; $($item:expr),+ ) => {
{
let mut len = 0usize;
$(
len += $item.network_serialize(&mut $encoder)?;
)+
len
}
}
}

impl<T> Network for T where T: super::commitment::FromConsensus {
#[inline]
fn network_serialize<E: io::Write>(&self, mut e: E) -> Result<usize, Error> {
Ok(self.consensus_encode(&mut e)?)
}

#[inline]
fn network_deserialize<D: io::Read>(d: D) -> Result<Self, Error> {
Ok(Self::consensus_decode(d)?)
}
}

network_serialize_from_commitment!(usize);
network_serialize_from_commitment!(f32);
network_serialize_from_commitment!(f64);
network_serialize_from_commitment!(&[u8]);
network_serialize_from_commitment!(Box<[u8]>);
network_serialize_from_commitment!(&str);


/// In terms of network serialization, we interpret `Option` as a zero-length `Vec`
/// (for `Optional::None`) or single-item `Vec` (for `Optional::Some`). For deserialization
/// an attempt to read `Option` from a serialized non-0 or non-1 length Vec will result in
/// `Error::WrongOptionalEncoding`.
impl<T> Network for Option<T> where T: Network {
fn network_serialize<E: io::Write>(&self, mut e: E) -> Result<usize, Error> {
Ok(match self {
None => network_serialize_list!(e; 0usize),
Some(val) => network_serialize_list!(e; 1usize, val),
})
}

fn network_deserialize<D: io::Read>(mut d: D) -> Result<Self, Error> {
let mut vec = Vec::<T>::network_deserialize(&mut d)?;
match vec.len() {
0 => Ok(None),
1 => Ok(Some(
vec.pop().expect("We are sure that there is a single item in the vec")
)),
_ => Err(Error::WrongOptionalEncoding),
}
}
}


/// In terms of network serialization, `Vec` is stored in form of usize-serialized length
/// (see `Commitment` implementation for `usize` type for serialization platform-independent
/// constant-length serialization rules) followed by a consequently-serialized vec items,
/// according to their type.
///
/// An attempt to serialize `Vec` with more items than can fit in `usize` serialization rules
/// will result in `Error::OversizedVectorAllocation`.
impl<T> Network for Vec<T> where T: Network {
fn network_serialize<E: io::Write>(&self, mut e: E) -> Result<usize, Error> {
let len = self.len() as usize;
let mut serialized = len.network_serialize(&mut e)?;
for item in self {
serialized += item.network_serialize(&mut e)?;
}

Ok(serialized)
}

fn network_deserialize<D: io::Read>(mut d: D) -> Result<Self, Error> {
let len = usize::network_deserialize(&mut d)?;
let mut data = Vec::<T>::with_capacity(len as usize);
for _ in 0..len {
data.push(T::network_deserialize(&mut d)?);
}
Ok(data)
}
}


#[inline]
pub fn network_serialize<T: Network>(data: &T) -> Result<Vec<u8>, Error> {
let mut encoder = io::Cursor::new(vec![]);
Expand Down
2 changes: 2 additions & 0 deletions src/rgb/schema/schema.rs
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,8 @@ impl serialize::Commitment for Schema {
}
}

network_serialize_from_commitment!(Schema);

static MIDSTATE_SHEMAID: [u8; 32] = [
25, 205, 224, 91, 171, 217, 131, 31, 140, 104, 5, 155, 127, 82, 14, 81, 58, 245, 79, 165, 114,
243, 110, 60, 133, 174, 103, 187, 103, 230, 9, 106
Expand Down
64 changes: 54 additions & 10 deletions src/rgb/serialize.rs
Original file line number Diff line number Diff line change
Expand Up @@ -148,7 +148,15 @@ impl csv::serialize::Commitment for rgb::Metadata {
}
}

// TODO: Implement network serialization
impl csv::serialize::Network for rgb::Metadata {
fn network_serialize<E: io::Write>(&self, mut e: E) -> Result<usize, csv::serialize::Error> {
self.as_ref().network_serialize(&mut e)
}

fn network_deserialize<D: io::Read>(mut d: D) -> Result<Self, csv::serialize::Error> {
Vec::<rgb::metadata::Field>::network_deserialize(&mut d).map(Self::from_inner)
}
}


/// ## Seal commitment serialization
Expand Down Expand Up @@ -231,7 +239,25 @@ impl csv::serialize::Commitment for rgb::state::Partial {
}
}

// TODO: Implement network serialization for rgb::state::Partial
const TAG_COMMITMENT: u8 = 0x00u8;
const TAG_STATE: u8 = 0x01u8;

impl csv::serialize::Network for rgb::state::Partial {
fn network_serialize<E: io::Write>(&self, mut e: E) -> Result<usize, csv::serialize::Error> {
Ok(match self {
Self::Commitment (cmt) => TAG_COMMITMENT.network_serialize(&mut e)? + cmt.network_serialize(&mut e)?,
Self::State(state) => TAG_STATE.network_serialize(&mut e)? + state.network_serialize(&mut e)?,
})
}

fn network_deserialize<D: io::Read>(mut d: D) -> Result<Self, csv::serialize::Error> {
Ok(match u8::network_deserialize(&mut d)? {
TAG_COMMITMENT => Self::Commitment(rgb::commit::StateCommitment::network_deserialize(&mut d)?),
TAG_STATE => Self::State(rgb::state::Bound::network_deserialize(&mut d)?),
_ => Err(csv::serialize::Error::ValueOutOfRange)?,
})
}
}


impl csv::serialize::Commitment for rgb::state::Bound {
Expand Down Expand Up @@ -273,7 +299,15 @@ impl csv::serialize::Commitment for rgb::State {
}
}

// TODO: Implement network serialization
impl csv::serialize::Network for rgb::State {
fn network_serialize<E: io::Write>(&self, mut e: E) -> Result<usize, csv::serialize::Error> {
self.clone().into_inner().network_serialize(&mut e)
}

fn network_deserialize<D: io::Read>(mut d: D) -> Result<Self, csv::serialize::Error> {
Vec::<rgb::state::Partial>::network_deserialize(&mut d).map(Self::from_inner)
}
}


/// ## Script commitment serialization
Expand Down Expand Up @@ -314,10 +348,20 @@ impl csv::serialize::Commitment for rgb::Transition {
}
}

// TODO: Implement network serialization
/* Draft:
Ok(Self {
meta: Meta::commitment_deserialize(&mut d)?,
state: State::commitment_deserialize(&mut d)?,
script: Option::<Script>::commitment_deserialize(&mut d)?
})*/
impl csv::serialize::Network for rgb::Transition {
fn network_serialize<E: io::Write>(&self, mut e: E) -> Result<usize, csv::serialize::Error> {
Ok(
self.meta.network_serialize(&mut e)? +
self.state.network_serialize(&mut e)? +
self.script.network_serialize(&mut e)?
)
}

fn network_deserialize<D: io::Read>(mut d: D) -> Result<Self, csv::serialize::Error> {
Ok(Self {
meta: rgb::Metadata::network_deserialize(&mut d)?,
state: rgb::State::network_deserialize(&mut d)?,
script: Option::<rgb::Script>::network_deserialize(&mut d)?
})
}
}

0 comments on commit ab27b02

Please sign in to comment.