use super::super::hash::{Blake2b256, HashFunction};
pub trait Signable<W> {
fn write(&self, writer: &mut W);
}
mod bcs_signable {
pub trait BcsSignable: serde::Serialize + serde::de::DeserializeOwned {}
impl BcsSignable for super::super::TransactionData {}
}
impl<T, W> Signable<W> for T
where
T: bcs_signable::BcsSignable,
W: std::io::Write,
{
#[allow(clippy::expect_used, reason = "invariant guaranteed by the sealed trait above")]
fn write(&self, writer: &mut W) {
let name = serde_name::trace_name::<Self>().expect("Self must be a struct or an enum");
write!(writer, "{}::", name).expect("Hasher should not fail");
bcs::serialize_into(writer, &self).expect("Message serialization should not fail");
}
}
fn hash<S: Signable<H>, H: HashFunction<DIGEST_SIZE>, const DIGEST_SIZE: usize>(signable: &S) -> [u8; DIGEST_SIZE] {
let mut digest = H::default();
signable.write(&mut digest);
let hash = digest.finalize();
hash.into()
}
pub fn default_hash<S: Signable<Blake2b256>>(signable: &S) -> [u8; 32] {
hash::<S, Blake2b256, 32>(signable)
}