From 91120a9a4a8594f9272e5c6378d7ef6ce9765f7b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ege=20Okan=20=C3=9Cnald=C4=B1?= <35339130+exeokan@users.noreply.github.com> Date: Fri, 7 Feb 2025 17:21:15 +0300 Subject: [PATCH] Use sha2 for block hash calculation (#1823) --- crates/bitcoin-da/src/spec/header.rs | 38 ++++++++++++++++++++++++++-- 1 file changed, 36 insertions(+), 2 deletions(-) diff --git a/crates/bitcoin-da/src/spec/header.rs b/crates/bitcoin-da/src/spec/header.rs index ec2ab2359e..8170aa0c52 100644 --- a/crates/bitcoin-da/src/spec/header.rs +++ b/crates/bitcoin-da/src/spec/header.rs @@ -1,6 +1,7 @@ use core::ops::Deref; use bitcoin::block::{Header as BitcoinHeader, Version}; +use bitcoin::consensus::Encodable; use bitcoin::hashes::Hash; use bitcoin::{BlockHash, CompactTarget, TxMerkleNode}; use borsh::{BorshDeserialize, BorshSerialize}; @@ -8,6 +9,7 @@ use serde::{Deserialize, Serialize}; use sov_rollup_interface::da::BlockHeaderTrait; use super::block_hash::BlockHashWrapper; +use crate::helpers::calculate_double_sha256; // HeaderWrapper is a wrapper around BlockHash to implement BlockHeaderTrait #[derive( @@ -33,7 +35,7 @@ impl BlockHeaderTrait for HeaderWrapper { } fn verify_hash(&self) -> bool { - self.hash() == BlockHashWrapper::from(self.header.block_hash().to_byte_array()) + self.hash() == BlockHashWrapper(self.block_hash()) } fn txs_commitment(&self) -> Self::Hash { @@ -70,7 +72,11 @@ impl HeaderWrapper { } pub fn block_hash(&self) -> BlockHash { - self.header.block_hash() + let mut enc = vec![]; + self.header + .consensus_encode(&mut enc) + .expect("engines don't error"); + BlockHash::from_raw_hash(Hash::from_byte_array(calculate_double_sha256(&enc))) } pub fn merkle_root(&self) -> [u8; 32] { @@ -135,3 +141,31 @@ impl From for BitcoinHeaderWrapper { Self(header) } } + +#[cfg(test)] +mod tests { + use std::fs::File; + use std::io::{BufRead, BufReader}; + use std::ops::Deref; + + use borsh::BorshDeserialize; + + use super::BitcoinHeaderWrapper; + use crate::spec::header::HeaderWrapper; + + #[test] + fn calculate_block_hash() { + let file = File::open("test_data/testnet4/headers-40310-42346.txt").unwrap(); + let reader = BufReader::new(file); + for (line, height) in reader.lines().zip(40310..=42346) { + let header_hex = line.unwrap(); + let header_bytes = hex::decode(&header_hex).unwrap(); + + let inner_header = + BitcoinHeaderWrapper::deserialize(&mut header_bytes.as_ref()).unwrap(); + let header = HeaderWrapper::new(*inner_header.deref(), 0, height, [0; 32]); + + assert_eq!(inner_header.block_hash(), header.block_hash()) + } + } +}