use std::fmt::Display;
#[cfg(any(test, feature = "arbitrary-impls"))]
use arbitrary::Arbitrary;
use get_size2::GetSize;
use serde::Deserialize;
use serde::Serialize;
use tasm_lib::prelude::TasmObject;
use tasm_lib::twenty_first::math::bfield_codec::BFieldCodec;
use tasm_lib::twenty_first::tip5::digest::Digest;
#[derive(
Clone,
Copy,
Debug,
Serialize,
Deserialize,
PartialEq,
Eq,
Hash,
GetSize,
BFieldCodec,
TasmObject,
)]
#[cfg_attr(any(test, feature = "arbitrary-impls"), derive(Arbitrary))]
pub struct AdditionRecord {
pub canonical_commitment: Digest,
}
impl AdditionRecord {
pub fn new(canonical_commitment: Digest) -> Self {
Self {
canonical_commitment,
}
}
}
impl Display for AdditionRecord {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "{}", self.canonical_commitment)
}
}
#[cfg(any(test, feature = "test-helpers"))]
impl rand::distr::Distribution<AdditionRecord> for rand::distr::StandardUniform {
fn sample<R: rand::Rng + ?Sized>(&self, rng: &mut R) -> AdditionRecord {
AdditionRecord {
canonical_commitment: rng.random(),
}
}
}
#[cfg(test)]
#[cfg_attr(coverage_nightly, coverage(off))]
mod tests {
use rand::random;
use tasm_lib::prelude::Tip5;
use super::*;
use crate::commit;
#[test]
fn get_size_test() {
let addition_record_0: AdditionRecord = commit(
Tip5::hash(&1492u128),
Tip5::hash(&1522u128),
Tip5::hash(&1521u128),
);
assert_eq!(std::mem::size_of::<Digest>(), addition_record_0.get_size());
}
#[test]
fn hash_identity_test() {
let addition_record_0: AdditionRecord = commit(
Tip5::hash(&1492u128),
Tip5::hash(&1522u128),
Tip5::hash(&1521u128),
);
let addition_record_1: AdditionRecord = commit(
Tip5::hash(&1492u128),
Tip5::hash(&1522u128),
Tip5::hash(&1521u128),
);
assert_eq!(
Tip5::hash(&addition_record_0),
Tip5::hash(&addition_record_1),
"Two addition records with same commitments and same MMR AOCLs must agree."
);
let addition_record_2: AdditionRecord = commit(
Tip5::hash(&1451u128),
Tip5::hash(&1480u128),
Tip5::hash(&1481u128),
);
assert_ne!(
Tip5::hash(&addition_record_0),
Tip5::hash(&addition_record_2),
"Two addition records with differing commitments but same MMR AOCLs must differ."
);
}
#[test]
fn serialization_test() {
let item = Tip5::hash(&1492u128);
let sender_randomness = Tip5::hash(&1522u128);
let receiver_digest = Tip5::hash(&1583u128);
let addition_record: AdditionRecord = commit(item, sender_randomness, receiver_digest);
let json = serde_json::to_string(&addition_record).unwrap();
let s_back = serde_json::from_str::<AdditionRecord>(&json).unwrap();
assert_eq!(
addition_record.canonical_commitment,
s_back.canonical_commitment
);
}
#[test]
fn bfieldcodec_test() {
let addition_record = AdditionRecord {
canonical_commitment: random(),
};
let encoded = addition_record.encode();
let decoded = *AdditionRecord::decode(&encoded).unwrap();
assert_eq!(addition_record, decoded);
}
#[test]
fn bfieldcodec_test_on_vecs() {
for i in 0..5 {
let addition_records = vec![
AdditionRecord {
canonical_commitment: random(),
};
i
];
let encoded = addition_records.encode();
let decoded = *Vec::<AdditionRecord>::decode(&encoded).unwrap();
assert_eq!(addition_records, decoded);
}
}
}