diff --git a/substrate/wasm-runtime/polkadot/src/lib.rs b/substrate/wasm-runtime/polkadot/src/lib.rs index 39cab5def1..120c5562cd 100644 --- a/substrate/wasm-runtime/polkadot/src/lib.rs +++ b/substrate/wasm-runtime/polkadot/src/lib.rs @@ -124,11 +124,13 @@ impl Function { } #[derive(Clone)] +#[cfg_attr(test, derive(PartialEq, Debug))] pub struct Digest { pub logs: Vec>, } #[derive(Clone)] +#[cfg_attr(test, derive(PartialEq, Debug))] pub struct Header { pub parent_hash: Hash, pub number: BlockNumber, @@ -145,6 +147,7 @@ pub struct Transaction { pub nonce: TxOrder, } +#[cfg_attr(test, derive(PartialEq, Debug))] pub struct Block { pub header: Header, pub transactions: Vec, @@ -267,6 +270,8 @@ trait Slicable: Sized { fn size_of(_value: &[u8]) -> Option; } +trait NonTrivialSlicable: Slicable {} + impl Slicable for T { fn set_as_slice bool>(fill_slice: F) -> Option { let size = size_of::(); @@ -341,6 +346,72 @@ impl Slicable for Transaction { } } +impl NonTrivialSlicable for Transaction {} + +impl NonTrivialSlicable for Vec where Vec: Slicable {} + +impl Slicable for Vec { + fn from_slice(value: &[u8]) -> Option { + let len = Self::size_of(&value[0..4])?; + let mut off = 4; + let mut r = vec![]; + while off < len { + let element_len = T::size_of(&value[off..])?; + r.push(T::from_slice(&value[off..off + element_len])?); + off += element_len; + } + Some(r) + } + + fn set_as_slice bool>(_fill_slice: F) -> Option { + unimplemented!(); + } + + fn to_vec(&self) -> Vec { + let vecs = self.iter().map(Slicable::to_vec).collect::>(); + let len = vecs.iter().fold(0, |mut a, v| {a += v.len(); a}); + let mut r = vec![].join(&(len as u32)); + vecs.iter().for_each(|v| r.extend_from_slice(v)); + r + } + + fn size_of(data: &[u8]) -> Option { + u32::from_slice(&data[0..4]).map(|i| (i + 4) as usize) + } +} + +impl Slicable for Header { + fn from_slice(value: &[u8]) -> Option { + let mut reader = StreamReader::new(value); + Some(Header { + parent_hash: reader.read()?, + number: reader.read()?, + state_root: reader.read()?, + transaction_root: reader.read()?, + digest: Digest { logs: reader.read()?, }, + }) + } + + fn set_as_slice bool>(_fill_slice: F) -> Option { + unimplemented!(); + } + + fn to_vec(&self) -> Vec { + vec![] + .join(&self.parent_hash) + .join(&self.number) + .join(&self.state_root) + .join(&self.transaction_root) + .join(&self.digest.logs) + } + + fn size_of(data: &[u8]) -> Option { + let first_part = size_of::() + size_of::() + size_of::() + size_of::(); + let second_part = >>::size_of(&data[first_part..])?; + Some(first_part + second_part) + } +} + trait KeyedVec { fn to_keyed_vec(&self, prepend_key: &[u8]) -> Vec; } @@ -717,4 +788,6 @@ mod tests { let deserialised: Transaction = Slicable::from_slice(&data).unwrap(); assert_eq!(deserialised, tx); } + + // TODO: Ser/de Header. }