diff --git a/src/store.rs b/src/store.rs index f04971a..8f7cd2a 100644 --- a/src/store.rs +++ b/src/store.rs @@ -1,5 +1,6 @@ use crate::onion::Onion; use crate::secp::{self, Commitment, RangeProof, SecretKey}; +use crate::types::{read_optional, write_optional}; use grin_core::core::Input; use grin_core::ser::{self, ProtocolVersion, Readable, Reader, Writeable, Writer}; @@ -36,16 +37,7 @@ impl Writeable for SwapData { writer.write_u8(CURRENT_VERSION)?; writer.write_fixed_bytes(&self.excess)?; writer.write_fixed_bytes(&self.output_commit)?; - - // todo: duplicated in payload. Can we impl Writeable for Option? - match &self.rangeproof { - Some(proof) => { - writer.write_u8(1)?; - proof.write(writer)?; - } - None => writer.write_u8(0)?, - }; - + write_optional(writer, &self.rangeproof)?; self.input.write(writer)?; writer.write_u64(self.fee.into())?; self.onion.write(writer)?; @@ -63,15 +55,10 @@ impl Readable for SwapData { let excess = secp::read_secret_key(reader)?; let output_commit = Commitment::read(reader)?; - let rangeproof = if reader.read_u8()? == 0 { - None - } else { - Some(RangeProof::read(reader)?) - }; + let rangeproof = read_optional(reader)?; let input = Input::read(reader)?; let fee = reader.read_u64()?; let onion = Onion::read(reader)?; - Ok(SwapData { excess, output_commit, diff --git a/src/types.rs b/src/types.rs index 3a1d8a5..9fe73b4 100644 --- a/src/types.rs +++ b/src/types.rs @@ -6,6 +6,31 @@ use serde::{Deserialize, Serialize}; const CURRENT_VERSION: u8 = 0; +/// Writes an optional value as '1' + value if Some, or '0' if None +pub fn write_optional( + writer: &mut W, + o: &Option, +) -> Result<(), ser::Error> { + match &o { + Some(o) => { + writer.write_u8(1)?; + o.write(writer)?; + } + None => writer.write_u8(0)?, + }; + Ok(()) +} + +/// Reads an optional value as '1' + value if Some, or '0' if None +pub fn read_optional(reader: &mut R) -> Result, ser::Error> { + let o = if reader.read_u8()? == 0 { + None + } else { + Some(O::read(reader)?) + }; + Ok(o) +} + // todo: Belongs in Onion #[derive(Serialize, Deserialize, Debug, Clone)] pub struct Payload { @@ -37,18 +62,12 @@ impl Readable for Payload { let excess = secp::read_secret_key(reader)?; let fee = FeeFields::try_from(reader.read_u64()?).map_err(|_| ser::Error::CorruptedData)?; - let rangeproof = if reader.read_u8()? == 0 { - None - } else { - Some(RangeProof::read(reader)?) - }; - - let payload = Payload { + let rangeproof = read_optional(reader)?; + Ok(Payload { excess, fee, rangeproof, - }; - Ok(payload) + }) } } @@ -57,15 +76,7 @@ impl Writeable for Payload { writer.write_u8(CURRENT_VERSION)?; writer.write_fixed_bytes(&self.excess)?; writer.write_u64(self.fee.into())?; - - match &self.rangeproof { - Some(proof) => { - writer.write_u8(1)?; - proof.write(writer)?; - } - None => writer.write_u8(0)?, - }; - + write_optional(writer, &self.rangeproof)?; Ok(()) } }