use super::*;
impl<N: Network> FromBytes for Plaintext<N> {
fn read_le<R: Read>(mut reader: R) -> IoResult<Self> {
let index = u8::read_le(&mut reader)?;
let plaintext = match index {
0 => Self::Literal(Literal::read_le(&mut reader)?, Default::default()),
1 => {
let num_members = u8::read_le(&mut reader)?;
let mut members = IndexMap::with_capacity(num_members as usize);
for _ in 0..num_members {
let identifier = Identifier::<N>::read_le(&mut reader)?;
let num_bytes = u16::read_le(&mut reader)?;
let bytes = (0..num_bytes).map(|_| u8::read_le(&mut reader)).collect::<Result<Vec<_>, _>>()?;
let plaintext = Plaintext::read_le(&mut bytes.as_slice())?;
members.insert(identifier, plaintext);
}
Self::Struct(members, Default::default())
}
2.. => return Err(error(format!("Failed to decode plaintext variant {index}"))),
};
Ok(plaintext)
}
}
impl<N: Network> ToBytes for Plaintext<N> {
fn write_le<W: Write>(&self, mut writer: W) -> IoResult<()> {
match self {
Self::Literal(literal, ..) => {
0u8.write_le(&mut writer)?;
literal.write_le(&mut writer)
}
Self::Struct(struct_, ..) => {
1u8.write_le(&mut writer)?;
u8::try_from(struct_.len())
.or_halt_with::<N>("Plaintext struct length exceeds u8::MAX.")
.write_le(&mut writer)?;
for (member_name, member_value) in struct_ {
member_name.write_le(&mut writer)?;
let bytes = member_value.to_bytes_le().map_err(|e| error(e.to_string()))?;
u16::try_from(bytes.len())
.or_halt_with::<N>("Plaintext member exceeds u16::MAX bytes.")
.write_le(&mut writer)?;
bytes.write_le(&mut writer)?;
}
Ok(())
}
}
}
}
#[cfg(test)]
mod tests {
use super::*;
use snarkvm_console_network::Testnet3;
type CurrentNetwork = Testnet3;
const ITERATIONS: u32 = 1000;
fn check_bytes(expected: Plaintext<CurrentNetwork>) -> Result<()> {
let expected_bytes = expected.to_bytes_le()?;
assert_eq!(expected, Plaintext::read_le(&expected_bytes[..])?);
Ok(())
}
#[test]
fn test_bytes() -> Result<()> {
let rng = &mut TestRng::default();
for _ in 0..ITERATIONS {
let private_key = snarkvm_console_account::PrivateKey::<CurrentNetwork>::new(rng)?;
check_bytes(Plaintext::Literal(
Literal::<CurrentNetwork>::Address(Address::try_from(private_key)?),
Default::default(),
))?;
check_bytes(Plaintext::Literal(
Literal::<CurrentNetwork>::Boolean(Boolean::new(Uniform::rand(rng))),
Default::default(),
))?;
check_bytes(Plaintext::Literal(Literal::<CurrentNetwork>::Field(Uniform::rand(rng)), Default::default()))?;
check_bytes(Plaintext::Literal(Literal::<CurrentNetwork>::Group(Uniform::rand(rng)), Default::default()))?;
check_bytes(Plaintext::Literal(
Literal::<CurrentNetwork>::I8(I8::new(Uniform::rand(rng))),
Default::default(),
))?;
check_bytes(Plaintext::Literal(
Literal::<CurrentNetwork>::I16(I16::new(Uniform::rand(rng))),
Default::default(),
))?;
check_bytes(Plaintext::Literal(
Literal::<CurrentNetwork>::I32(I32::new(Uniform::rand(rng))),
Default::default(),
))?;
check_bytes(Plaintext::Literal(
Literal::<CurrentNetwork>::I64(I64::new(Uniform::rand(rng))),
Default::default(),
))?;
check_bytes(Plaintext::Literal(
Literal::<CurrentNetwork>::I128(I128::new(Uniform::rand(rng))),
Default::default(),
))?;
check_bytes(Plaintext::Literal(
Literal::<CurrentNetwork>::U8(U8::new(Uniform::rand(rng))),
Default::default(),
))?;
check_bytes(Plaintext::Literal(
Literal::<CurrentNetwork>::U16(U16::new(Uniform::rand(rng))),
Default::default(),
))?;
check_bytes(Plaintext::Literal(
Literal::<CurrentNetwork>::U32(U32::new(Uniform::rand(rng))),
Default::default(),
))?;
check_bytes(Plaintext::Literal(
Literal::<CurrentNetwork>::U64(U64::new(Uniform::rand(rng))),
Default::default(),
))?;
check_bytes(Plaintext::Literal(
Literal::<CurrentNetwork>::U128(U128::new(Uniform::rand(rng))),
Default::default(),
))?;
check_bytes(Plaintext::Literal(Literal::<CurrentNetwork>::Scalar(Uniform::rand(rng)), Default::default()))?;
check_bytes(Plaintext::Literal(
Literal::<CurrentNetwork>::String(StringType::rand(rng)),
Default::default(),
))?;
}
let expected = Plaintext::<CurrentNetwork>::from_str(
"{ owner: aleo1d5hg2z3ma00382pngntdp68e74zv54jdxy249qhaujhks9c72yrs33ddah, gates: 5u64, token_amount: 100u64 }",
)?;
let expected_bytes = expected.to_bytes_le()?;
assert_eq!(expected, Plaintext::read_le(&expected_bytes[..])?);
assert!(Plaintext::<CurrentNetwork>::read_le(&expected_bytes[1..]).is_err());
Ok(())
}
}