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:
parent
73cd06b4dc
commit
00cc1284ae
|
@ -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!()
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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>;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue