use super::*;
impl<N: Network> FromBytes for Ratify<N> {
fn read_le<R: Read>(mut reader: R) -> IoResult<Self> {
let version = u8::read_le(&mut reader)?;
if version != 1 {
return Err(error("Invalid ratify version"));
}
let variant = Variant::read_le(&mut reader)?;
let ratify = match variant {
0 => {
let committee: Committee<N> = FromBytes::read_le(&mut reader)?;
let num_public_balances: u16 = FromBytes::read_le(&mut reader)?;
let mut public_balances = PublicBalances::with_capacity(num_public_balances as usize);
for _ in 0..num_public_balances {
let address: Address<N> = FromBytes::read_le(&mut reader)?;
let amount: u64 = FromBytes::read_le(&mut reader)?;
public_balances.insert(address, amount);
}
let num_bonded_balances: u16 = FromBytes::read_le(&mut reader)?;
let mut bonded_balances = BondedBalances::with_capacity(num_bonded_balances as usize);
for _ in 0..num_bonded_balances {
let address: Address<N> = FromBytes::read_le(&mut reader)?;
let validator_address: Address<N> = FromBytes::read_le(&mut reader)?;
let withdrawal_address: Address<N> = FromBytes::read_le(&mut reader)?;
let amount: u64 = FromBytes::read_le(&mut reader)?;
bonded_balances.insert(address, (validator_address, withdrawal_address, amount));
}
Self::Genesis(Box::new(committee), Box::new(public_balances), Box::new(bonded_balances))
}
1 => {
let amount: u64 = FromBytes::read_le(&mut reader)?;
Self::BlockReward(amount)
}
2 => {
let amount: u64 = FromBytes::read_le(&mut reader)?;
Self::PuzzleReward(amount)
}
3.. => return Err(error(format!("Failed to decode ratify object variant {variant}"))),
};
Ok(ratify)
}
}
impl<N: Network> ToBytes for Ratify<N> {
fn write_le<W: Write>(&self, mut writer: W) -> IoResult<()> {
1u8.write_le(&mut writer)?;
match self {
Self::Genesis(committee, public_balances, bonded_balances) => {
(0 as Variant).write_le(&mut writer)?;
committee.write_le(&mut writer)?;
u16::try_from(public_balances.len()).map_err(|e| error(e.to_string()))?.write_le(&mut writer)?;
for (address, amount) in public_balances.iter() {
address.write_le(&mut writer)?;
amount.write_le(&mut writer)?;
}
u16::try_from(bonded_balances.len()).map_err(|e| error(e.to_string()))?.write_le(&mut writer)?;
for (address, (validator_address, withdrawal_address, amount)) in bonded_balances.iter() {
address.write_le(&mut writer)?;
validator_address.write_le(&mut writer)?;
withdrawal_address.write_le(&mut writer)?;
amount.write_le(&mut writer)?;
}
Ok(())
}
Self::BlockReward(amount) => {
(1 as Variant).write_le(&mut writer)?;
amount.write_le(&mut writer)
}
Self::PuzzleReward(amount) => {
(2 as Variant).write_le(&mut writer)?;
amount.write_le(&mut writer)
}
}
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_bytes() {
let rng = &mut TestRng::default();
for expected in crate::ratify::test_helpers::sample_ratifications(rng) {
let expected_bytes = expected.to_bytes_le().unwrap();
assert_eq!(expected, Ratify::read_le(&expected_bytes[..]).unwrap());
}
}
}