1use crate::{BlockHeader, Transaction};
7use serde::{Deserialize, Serialize};
8
9pub type ShortTxId = [u8; 6];
11
12#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
14pub struct CompactBlock {
15 pub header: BlockHeader,
17 pub nonce: u64,
19 pub short_ids: Vec<ShortTxId>,
21 pub prefilled_txs: Vec<(usize, Transaction, Option<Vec<crate::segwit::Witness>>)>,
24}
25
26pub fn siphash24(k0: u64, k1: u64, data: &[u8]) -> u64 {
28 use siphasher::sip::SipHasher24;
29 use std::hash::Hasher;
30 let mut hasher = SipHasher24::new_with_keys(k0, k1);
31 hasher.write(data);
32 hasher.finish()
33}
34
35pub fn short_tx_id(header: &BlockHeader, wtxid: &crate::Hash, nonce: u64) -> ShortTxId {
37 use sha2::{Digest, Sha256};
38 let mut data = crate::serialization::serialize_block_header(header);
39 data.extend_from_slice(&nonce.to_le_bytes());
40 let hash = Sha256::digest(&data);
41 let k0 = u64::from_le_bytes(hash[0..8].try_into().expect("8"));
42 let k1 = u64::from_le_bytes(hash[8..16].try_into().expect("8"));
43 let digest = siphash24(k0, k1, wtxid);
44 let bytes = digest.to_le_bytes();
45 let mut short = [0u8; 6];
46 short.copy_from_slice(&bytes[..6]);
47 short
48}
49
50#[cfg(test)]
51mod siphash_vector {
52 use super::siphash24;
53
54 #[test]
55 fn siphash24_matches_the_reference_vector() {
56 let mut key = [0u8; 16];
57 for (i, byte) in key.iter_mut().enumerate() {
58 *byte = i as u8;
59 }
60 let k0 = u64::from_le_bytes(key[0..8].try_into().unwrap());
61 let k1 = u64::from_le_bytes(key[8..16].try_into().unwrap());
62 let msg: Vec<u8> = (0..15).collect();
63 assert_eq!(siphash24(k0, k1, &msg), 0xa129_ca61_49be_45e5);
64 }
65}