serialization helpers for reading and writing Options

(cherry picked from commit 7ab6d3086e4c946ef117ed244bd33c87ff5b9142)
This commit is contained in:
scilio 2022-08-25 17:22:55 -04:00
parent b8dd2e42f7
commit b393222ac8
2 changed files with 32 additions and 34 deletions

View file

@ -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<RangeProof>?
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,

View file

@ -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<O: Writeable, W: Writer>(
writer: &mut W,
o: &Option<O>,
) -> 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<O: Readable, R: Reader>(reader: &mut R) -> Result<Option<O>, 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(())
}
}