Skip to content

Commit

Permalink
Take Params instead of Network in difficulty function
Browse files Browse the repository at this point in the history
What we really want is the maximum target, but since this is a const in
`Params` use an `AsRef<Params>` argument in the `difficulty` functions.

Requires implementation of `AsRef<Params> for Params`.
  • Loading branch information
tcharding committed Apr 2, 2024
1 parent 104dee9 commit f0f6d3f
Show file tree
Hide file tree
Showing 3 changed files with 16 additions and 16 deletions.
17 changes: 10 additions & 7 deletions bitcoin/src/blockdata/block.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,11 +16,11 @@ use io::{BufRead, Write};
use super::Weight;
use crate::blockdata::script;
use crate::blockdata::transaction::{Transaction, Txid, Wtxid};
use crate::consensus::{encode, Decodable, Encodable};
use crate::consensus::{encode, Decodable, Encodable, Params};
use crate::internal_macros::{impl_consensus_encoding, impl_hashencode};
use crate::pow::{CompactTarget, Target, Work};
use crate::prelude::*;
use crate::{merkle_tree, Network, VarInt};
use crate::{merkle_tree, VarInt};

hashes::hash_newtype! {
/// A bitcoin block hash.
Expand Down Expand Up @@ -93,7 +93,9 @@ impl Header {
///
/// Difficulty represents how difficult the current target makes it to find a block, relative to
/// how difficult it would be at the highest possible target (highest target == lowest difficulty).
pub fn difficulty(&self, network: Network) -> u128 { self.target().difficulty(network) }
pub fn difficulty(&self, params: impl AsRef<Params>) -> u128 {
self.target().difficulty(params)
}

/// Computes the popular "difficulty" measure for mining and returns a float value of f64.
pub fn difficulty_float(&self) -> f64 { self.target().difficulty_float() }
Expand Down Expand Up @@ -488,6 +490,7 @@ mod tests {

use super::*;
use crate::consensus::encode::{deserialize, serialize};
use crate::Network;

#[test]
fn test_coinbase_and_bip34() {
Expand All @@ -510,7 +513,7 @@ mod tests {

#[test]
fn block_test() {
let network = Network::Bitcoin;
let params = Params::new(Network::Bitcoin);
// Mainnet block 00000000b0c5a240b2a61d2e75692224efd4cbecdf6eaf4cc2cf477ca7c270e7
let some_block = hex!("010000004ddccd549d28f385ab457e98d1b11ce80bfea2c5ab93015ade4973e400000000bf4473e53794beae34e64fccc471dace6ae544180816f89591894e0f417a914cd74d6e49ffff001d323b3a7b0201000000010000000000000000000000000000000000000000000000000000000000000000ffffffff0804ffff001d026e04ffffffff0100f2052a0100000043410446ef0102d1ec5240f0d061a4246c1bdef63fc3dbab7733052fbbf0ecd8f41fc26bf049ebb4f9527f374280259e7cfa99c48b0e3f39c51347a19a5819651503a5ac00000000010000000321f75f3139a013f50f315b23b0c9a2b6eac31e2bec98e5891c924664889942260000000049483045022100cb2c6b346a978ab8c61b18b5e9397755cbd17d6eb2fe0083ef32e067fa6c785a02206ce44e613f31d9a6b0517e46f3db1576e9812cc98d159bfdaf759a5014081b5c01ffffffff79cda0945903627c3da1f85fc95d0b8ee3e76ae0cfdc9a65d09744b1f8fc85430000000049483045022047957cdd957cfd0becd642f6b84d82f49b6cb4c51a91f49246908af7c3cfdf4a022100e96b46621f1bffcf5ea5982f88cef651e9354f5791602369bf5a82a6cd61a62501fffffffffe09f5fe3ffbf5ee97a54eb5e5069e9da6b4856ee86fc52938c2f979b0f38e82000000004847304402204165be9a4cbab8049e1af9723b96199bfd3e85f44c6b4c0177e3962686b26073022028f638da23fc003760861ad481ead4099312c60030d4cb57820ce4d33812a5ce01ffffffff01009d966b01000000434104ea1feff861b51fe3f5f8a3b12d0f4712db80e919548a80839fc47c6a21e66d957e9c5d8cd108c7a2d2324bad71f9904ac0ae7336507d785b17a2c115e427a32fac00000000");
let cutoff_block = hex!("010000004ddccd549d28f385ab457e98d1b11ce80bfea2c5ab93015ade4973e400000000bf4473e53794beae34e64fccc471dace6ae544180816f89591894e0f417a914cd74d6e49ffff001d323b3a7b0201000000010000000000000000000000000000000000000000000000000000000000000000ffffffff0804ffff001d026e04ffffffff0100f2052a0100000043410446ef0102d1ec5240f0d061a4246c1bdef63fc3dbab7733052fbbf0ecd8f41fc26bf049ebb4f9527f374280259e7cfa99c48b0e3f39c51347a19a5819651503a5ac00000000010000000321f75f3139a013f50f315b23b0c9a2b6eac31e2bec98e5891c924664889942260000000049483045022100cb2c6b346a978ab8c61b18b5e9397755cbd17d6eb2fe0083ef32e067fa6c785a02206ce44e613f31d9a6b0517e46f3db1576e9812cc98d159bfdaf759a5014081b5c01ffffffff79cda0945903627c3da1f85fc95d0b8ee3e76ae0cfdc9a65d09744b1f8fc85430000000049483045022047957cdd957cfd0becd642f6b84d82f49b6cb4c51a91f49246908af7c3cfdf4a022100e96b46621f1bffcf5ea5982f88cef651e9354f5791602369bf5a82a6cd61a62501fffffffffe09f5fe3ffbf5ee97a54eb5e5069e9da6b4856ee86fc52938c2f979b0f38e82000000004847304402204165be9a4cbab8049e1af9723b96199bfd3e85f44c6b4c0177e3962686b26073022028f638da23fc003760861ad481ead4099312c60030d4cb57820ce4d33812a5ce01ffffffff01009d966b01000000434104ea1feff861b51fe3f5f8a3b12d0f4712db80e919548a80839fc47c6a21e66d957e9c5d8cd108c7a2d2324bad71f9904ac0ae7336507d785b17a2c115e427a32fac");
Expand All @@ -537,7 +540,7 @@ mod tests {
real_decode.header.validate_pow(real_decode.header.target()).unwrap(),
real_decode.block_hash()
);
assert_eq!(real_decode.header.difficulty(network), 1);
assert_eq!(real_decode.header.difficulty(&params), 1);
assert_eq!(real_decode.header.difficulty_float(), 1.0);

assert_eq!(real_decode.total_size(), some_block.len());
Expand All @@ -556,7 +559,7 @@ mod tests {
// Check testnet block 000000000000045e0b1660b6445b5e5c5ab63c9a4f956be7e1e69be04fa4497b
#[test]
fn segwit_block_test() {
let network = Network::Testnet;
let params = Params::new(Network::Testnet);
let segwit_block = include_bytes!("../../tests/data/testnet_block_000000000000045e0b1660b6445b5e5c5ab63c9a4f956be7e1e69be04fa4497b.raw").to_vec();

let decode: Result<Block, _> = deserialize(&segwit_block);
Expand All @@ -579,7 +582,7 @@ mod tests {
real_decode.header.validate_pow(real_decode.header.target()).unwrap(),
real_decode.block_hash()
);
assert_eq!(real_decode.header.difficulty(network), 2456598);
assert_eq!(real_decode.header.difficulty(&params), 2456598);
assert_eq!(real_decode.header.difficulty_float(), 2456598.4399242126);

assert_eq!(real_decode.total_size(), segwit_block.len());
Expand Down
4 changes: 4 additions & 0 deletions bitcoin/src/consensus/params.rs
Original file line number Diff line number Diff line change
Expand Up @@ -147,3 +147,7 @@ impl From<Network> for &'static Params {
impl From<&Network> for &'static Params {
fn from(value: &Network) -> Self { value.params() }
}

impl AsRef<Params> for Params {
fn as_ref(&self) -> &Params { self }
}
11 changes: 2 additions & 9 deletions bitcoin/src/pow.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,8 @@ use units::parse;

use crate::blockdata::block::BlockHash;
use crate::consensus::encode::{self, Decodable, Encodable};
#[cfg(doc)]
use crate::consensus::Params;
use crate::error::{ContainsPrefixError, MissingPrefixError, PrefixedHexError, UnprefixedHexError};
use crate::Network;

/// Implement traits and methods shared by `Target` and `Work`.
macro_rules! do_impl {
Expand Down Expand Up @@ -234,16 +232,11 @@ impl Target {
/// [max]: Target::max
/// [target]: crate::blockdata::block::Header::target
#[cfg_attr(all(test, mutate), mutate)]
pub fn difficulty(&self, network: Network) -> u128 {
pub fn difficulty(&self, params: impl AsRef<Params>) -> u128 {
// Panic here may be eaiser to debug than during the actual division.
assert_ne!(self.0, U256::ZERO, "divide by zero");

let max = match network {
Network::Bitcoin => Target::MAX_ATTAINABLE_MAINNET,
Network::Testnet => Target::MAX_ATTAINABLE_TESTNET,
Network::Signet => Target::MAX_ATTAINABLE_SIGNET,
Network::Regtest => Target::MAX_ATTAINABLE_REGTEST,
};
let max = params.as_ref().pow_limit;
let d = max.0 / self.0;
d.saturating_to_u128()
}
Expand Down

0 comments on commit f0f6d3f

Please sign in to comment.