use crate::BlockHeader;
const RETARGET_ADJUSTMENT_FACTOR: u64 = 4;
pub fn verify_header_pow(
chain_params: &bitcoin::consensus::Params,
header: &BlockHeader,
) -> Result<(), String> {
let target = header.target();
if target > chain_params.max_attainable_target {
return Err("the header's target should be no larger than pow_limit".to_string());
}
if header.validate_pow(target).is_err() {
return Err("the header's hash should be no larger than its target".to_string());
}
Ok(())
}
pub fn verify_next_header_pow(
chain_params: &bitcoin::consensus::Params,
prev_header: &BlockHeader,
header: &BlockHeader,
) -> Result<(), String> {
if !prev_header.block_hash().eq(&header.prev_blockhash) {
return Err("the header is not consecutive to the previous header".to_string());
}
verify_header_pow(chain_params, header)?;
if !chain_params.allow_min_difficulty_blocks {
let retarget_adjustment_factor_u256 =
cosmwasm_std::Uint256::from(RETARGET_ADJUSTMENT_FACTOR);
let old_target = cosmwasm_std::Uint256::from_be_bytes(prev_header.target().to_be_bytes());
let cur_target = cosmwasm_std::Uint256::from_be_bytes(header.target().to_be_bytes());
let max_cur_target = old_target * retarget_adjustment_factor_u256;
let min_cur_target = old_target / retarget_adjustment_factor_u256;
if cur_target > max_cur_target || cur_target < min_cur_target {
return Err("difficulty not relevant to parent difficulty".to_string());
}
}
Ok(())
}