use crate::utils::encoding::serde_byte_array;
use byteorder::{BigEndian, ByteOrder as _};
use fvm_ipld_encoding::tuple::*;
use get_size2::GetSize;
use sha2::digest::Digest as _;
#[cfg_attr(test, derive(derive_quickcheck_arbitrary::Arbitrary))]
#[derive(
Clone,
Debug,
Default,
Eq,
PartialEq,
Hash,
Ord,
PartialOrd,
Serialize_tuple,
Deserialize_tuple,
GetSize,
)]
pub struct BeaconEntry {
round: u64,
#[serde(with = "serde_byte_array")]
signature: Vec<u8>,
}
impl BeaconEntry {
pub fn new(round: u64, signature: Vec<u8>) -> Self {
let signature = signature.into_boxed_slice().into_vec();
debug_assert_eq!(
signature.len(),
signature.capacity(),
"BeaconEntry::signature should be right-sized"
);
Self { round, signature }
}
pub fn round(&self) -> u64 {
self.round
}
pub fn signature(&self) -> &[u8] {
&self.signature
}
pub fn into_parts(self) -> (u64, Vec<u8>) {
let Self { round, signature } = self;
(round, signature)
}
pub fn message_unchained(round: u64) -> impl AsRef<[u8]> {
let mut round_bytes = [0; std::mem::size_of::<u64>()];
BigEndian::write_u64(&mut round_bytes, round);
sha2::Sha256::digest(round_bytes)
}
pub fn message_chained(round: u64, prev_signature: impl AsRef<[u8]>) -> impl AsRef<[u8]> {
let mut round_bytes = [0; std::mem::size_of::<u64>()];
BigEndian::write_u64(&mut round_bytes, round);
let mut hasher = sha2::Sha256::default();
hasher.update(prev_signature);
hasher.update(round_bytes);
hasher.finalize()
}
}