Add a stub ZcashSerialization trait.

There are a few unresolved questions marked in the doc comment for the trait;
we can resolve them later and rework the trait as we map everything out.
This commit is contained in:
Henry de Valence 2019-09-14 08:16:01 -07:00 committed by Deirdre Connolly
parent 73cd06b4dc
commit 00cc1284ae
2 changed files with 76 additions and 14 deletions

View File

@ -2,11 +2,13 @@
use std::io;
use byteorder::{LittleEndian, WriteBytesExt};
use chrono::{DateTime, Utc};
use zebra_chain::types::Sha256dChecksum;
use crate::meta_addr::MetaAddr;
use crate::serialization::{ReadZcashExt, SerializationError, WriteZcashExt, ZcashSerialization};
use crate::types::*;
/// A Bitcoin-like network message for the Zcash protocol.
@ -263,14 +265,39 @@ pub enum RejectReason {
// Maybe just write some functions and refactor later?
impl Message {
/// Serialize `self` into the given writer.
pub fn write<W: io::Write>(&self, mut writer: W, magic: Magic) -> io::Result<()> {
use byteorder::{LittleEndian, WriteBytesExt};
/// Write the body of the message into the given writer. This allows writing
/// the message body prior to writing the header, so that the header can
/// contain a checksum of the message body.
fn write_body<W: io::Write>(
&self,
_writer: W,
_magic: Magic,
_version: Version,
) -> Result<(), SerializationError> {
unimplemented!()
}
/// Try to deserialize a [`Message`] from the given reader.
pub fn try_read_body<R: io::Read>(
_reader: R,
_magic: Magic,
_version: Version,
) -> Result<Self, SerializationError> {
unimplemented!()
}
}
impl ZcashSerialization for Message {
fn write<W: io::Write>(
&self,
mut writer: W,
magic: Magic,
version: Version,
) -> Result<(), SerializationError> {
// Because the header contains a checksum of
// the body data, it must be written first.
let mut body = Vec::new();
self.write_body(&mut body)?;
self.write_body(&mut body, magic, version)?;
use Message::*;
// Note: because all match arms must have
@ -306,18 +333,17 @@ impl Message {
writer.write_all(command)?;
writer.write_u32::<LittleEndian>(body.len() as u32)?;
writer.write_all(&Sha256dChecksum::from(&body[..]).0)?;
writer.write_all(&body)
writer.write_all(&body)?;
Ok(())
}
/// Write the body of the message into the given writer. This allows writing
/// the message body prior to writing the header, so that the header can
/// contain a checksum of the message body.
fn write_body<W: io::Write>(&self, _writer: W) -> io::Result<()> {
unimplemented!()
}
/// Try to deserialize a [`Message`] from the given reader.
pub fn try_read<R: io::Read>(_reader: R) -> Result<Self, String> {
/// Try to read `self` from the given `reader`.
fn try_read<R: io::Read>(
_reader: R,
_magic: Magic,
_version: Version,
) -> Result<Self, SerializationError> {
unimplemented!()
}
}

View File

@ -131,3 +131,39 @@ pub trait ReadZcashExt: io::Read {
/// Mark all types implementing `Read` as implementing the extension.
impl<R: io::Read + ?Sized> ReadZcashExt for R {}
/// Consensus-critical (de)serialization for Zcash.
///
/// This trait provides a generic (de)serialization for consensus-critical
/// formats, such as network messages, transactions, blocks, etc. It is intended
/// for use only in consensus-critical contexts; in other contexts, such as
/// internal storage, it would be preferable to use Serde.
///
/// # Questions
///
/// ## Should this live here in `zebra-network` or in `zebra-chain`?
///
/// This is a proxy question for "is this serialization logic required outside of
/// networking contexts", which requires mapping out the "network context"
/// concept more precisely.
///
/// ## Should the `version` and `magic` parameters always be passed?
///
/// These are required for, e.g., serializing message headers, but possibly not
/// for serializing transactions?
pub trait ZcashSerialization: Sized {
/// Write `self` to the given `writer` using the canonical format.
fn write<W: io::Write>(
&self,
mut writer: W,
magic: Magic,
version: Version,
) -> Result<(), SerializationError>;
/// Try to read `self` from the given `reader`.
fn try_read<R: io::Read>(
reader: R,
magic: Magic,
version: Version,
) -> Result<Self, SerializationError>;
}