Skip to content

Commit

Permalink
Fix difficulty bits check
Browse files Browse the repository at this point in the history
  • Loading branch information
liuchengxu committed Jul 19, 2024
1 parent e62a3f3 commit e913182
Show file tree
Hide file tree
Showing 2 changed files with 49 additions and 9 deletions.
10 changes: 6 additions & 4 deletions crates/sc-consensus-nakamoto/src/verification.rs
Original file line number Diff line number Diff line change
Expand Up @@ -77,8 +77,8 @@ pub enum Error {
Header(#[from] HeaderError),
#[error("Script verification: {0}")]
Script(#[from] bitcoinconsensus::Error),
#[error(transparent)]
BitcoinCodec(#[from] bitcoin::io::Error),
#[error("Bitcoin codec: {0:?}")]
BitcoinCodec(bitcoin::io::Error),
/// An error occurred in the client.
#[error(transparent)]
Client(#[from] sp_blockchain::Error),
Expand Down Expand Up @@ -263,7 +263,8 @@ where
}

tx_data.clear();
tx.consensus_encode(&mut tx_data)?;
tx.consensus_encode(&mut tx_data)
.map_err(Error::BitcoinCodec)?;
let spending_transaction = tx_data.as_slice();

let mut total_input_value = 0;
Expand Down Expand Up @@ -418,7 +419,8 @@ mod tests {
find_utxo_in_current_block(&block, out_point, 36, |index| txids
.get(&index)
.copied()
.unwrap()),
.unwrap())
.map(|txout| txout.value.to_sat()),
Some(295600000)
);
}
Expand Down
48 changes: 43 additions & 5 deletions crates/sc-consensus-nakamoto/src/verification/header_verify.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,8 @@ const MAX_FUTURE_BLOCK_TIME: u32 = 2 * 60 * 60;
#[derive(Debug, thiserror::Error)]
pub enum Error {
/// Block's difficulty is invalid.
#[error("Incorrect proof-of-work")]
BadDifficultyBits,
#[error("Incorrect proof-of-work: {{ got: {got:?}, expected: {expected:?} }}")]
BadDifficultyBits { got: Target, expected: Target },
/// Block's proof-of-work is invalid.
#[error("proof-of-work validation failed: {0:?}")]
InvalidProofOfWork(ValidationError),
Expand Down Expand Up @@ -85,11 +85,15 @@ where
&self.consensus_params,
&self.client,
);
let expected_bits = expected_target.to_compact_lossy().to_consensus();

let actual_target = header.target();

if actual_target != expected_target {
return Err(Error::BadDifficultyBits);
if actual_target.to_compact_lossy().to_consensus() != expected_bits {
return Err(Error::BadDifficultyBits {
got: actual_target,
expected: expected_target,
});
}

header
Expand Down Expand Up @@ -200,7 +204,7 @@ where
let last_block_time = last_block.time;

calculate_next_work_required(
retarget_header.target().0,
last_block.target().0,
first_block_time.into(),
last_block_time.into(),
consensus_params,
Expand Down Expand Up @@ -242,3 +246,37 @@ fn calculate_next_work_required(
target
}
}

#[cfg(test)]
mod tests {
use super::*;
use bitcoin::consensus::encode::deserialize_hex;

#[test]
fn test_calculate_next_work_required() {
// block_354816
let block_354816: BitcoinHeader = deserialize_hex
("020000003f99814a36d2a2043b1d4bf61a410f71828eca1decbf56000000000000000000b3762ed278ac44bb953e24262cfeb952d0abe6d3b7f8b74fd24e009b96b6cb965d674655dd1317186436e79d").unwrap();

let expected_target = block_354816.target();

// block_352800, first block in this period.
let first_block: BitcoinHeader = deserialize_hex("0200000074c51c1cc53aaf478c643bb612da6bd17b268cd9bdccc4000000000000000000ccc0a2618a1f973dfac37827435b463abd18cbfd0f280a90432d3d78497a36cc02f33355f0171718b72a1dc7").unwrap();

// block_354815, last block in this period.
let last_block: BitcoinHeader = deserialize_hex("030000004c9c1b59250f30b8d360886a5433501120b056a000bdc0160000000000000000caca1bf0c55a5ba2299f9e60d10c01c679bb266c7df815ff776a1b97fd3a199ac1644655f01717182707bd59").unwrap();

let new_target = calculate_next_work_required(
last_block.target().0,
first_block.time as u64,
last_block.time as u64,
&Params::new(bitcoin::Network::Bitcoin),
);

assert_eq!(
new_target.to_compact_lossy().to_consensus(),
expected_target.to_compact_lossy().to_consensus(),
"Difficulty bits must match"
);
}
}

0 comments on commit e913182

Please sign in to comment.