use crate::{BlockHeader, Transaction};
use serde::{Deserialize, Serialize};
pub type ShortTxId = [u8; 6];
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub struct CompactBlock {
pub header: BlockHeader,
pub nonce: u64,
pub short_ids: Vec<ShortTxId>,
pub prefilled_txs: Vec<(usize, Transaction, Option<Vec<crate::segwit::Witness>>)>,
}
pub fn siphash24(k0: u64, k1: u64, data: &[u8]) -> u64 {
use siphasher::sip::SipHasher24;
use std::hash::Hasher;
let mut hasher = SipHasher24::new_with_keys(k0, k1);
hasher.write(data);
hasher.finish()
}
pub fn short_tx_id(header: &BlockHeader, wtxid: &crate::Hash, nonce: u64) -> ShortTxId {
use sha2::{Digest, Sha256};
let mut data = crate::serialization::serialize_block_header(header);
data.extend_from_slice(&nonce.to_le_bytes());
let hash = Sha256::digest(&data);
let k0 = u64::from_le_bytes(hash[0..8].try_into().expect("8"));
let k1 = u64::from_le_bytes(hash[8..16].try_into().expect("8"));
let digest = siphash24(k0, k1, wtxid);
let bytes = digest.to_le_bytes();
let mut short = [0u8; 6];
short.copy_from_slice(&bytes[..6]);
short
}
#[cfg(test)]
mod siphash_vector {
use super::siphash24;
#[test]
fn siphash24_matches_the_reference_vector() {
let mut key = [0u8; 16];
for (i, byte) in key.iter_mut().enumerate() {
*byte = i as u8;
}
let k0 = u64::from_le_bytes(key[0..8].try_into().unwrap());
let k1 = u64::from_le_bytes(key[8..16].try_into().unwrap());
let msg: Vec<u8> = (0..15).collect();
assert_eq!(siphash24(k0, k1, &msg), 0xa129_ca61_49be_45e5);
}
}