primitives: Implement Arbitrary for CompactTarget
What changed, and why it matters
This commit adds a test-only feature implementation that lets the fuzzing framework generate random CompactTarget values. It does not change any production logic, consensus rules, or security behavior.
No security action required. This is a routine test/fuzzing infrastructure change.
Security signals we found
No strong security signals were identified.
Evidence from the diff
The patch adds an arbitrary::Arbitrary trait implementation for bitcoin_primitives::pow::CompactTarget behind the arbitrary feature gate. It also updates an API test to use this new implementation instead of a hard-coded value. The implementation simply calls Self::from_consensus(u.arbitrary()?), which is the existing public constructor. No cryptographic, consensus, or parsing code is modified.
Changed components
primitives/src/pow.rsprimitives/tests/api.rsapi/primitives/all-features.txtInspect captured patch +12 / −1
diff --git a/api/primitives/all-features.txt b/api/primitives/all-features.txt
index a1a34331..04add9ce 100644
--- a/api/primitives/all-features.txt
+++ b/api/primitives/all-features.txt
@@ -943,6 +943,7 @@ impl<'a> arbitrary::Arbitrary<'a> for bitcoin_primitives::Wtxid
impl<'a> arbitrary::Arbitrary<'a> for bitcoin_primitives::block::Block
impl<'a> arbitrary::Arbitrary<'a> for bitcoin_primitives::block::Header
impl<'a> arbitrary::Arbitrary<'a> for bitcoin_primitives::block::Version
+impl<'a> arbitrary::Arbitrary<'a> for bitcoin_primitives::pow::CompactTarget
impl<'a> arbitrary::Arbitrary<'a> for bitcoin_primitives::script::ScriptHash
impl<'a> arbitrary::Arbitrary<'a> for bitcoin_primitives::script::WScriptHash
impl<'a> arbitrary::Arbitrary<'a> for bitcoin_primitives::transaction::OutPoint
@@ -1598,6 +1599,7 @@ pub fn bitcoin_primitives::merkle_tree::TxMerkleNodeEncoder<'e>::advance(&mut se
pub fn bitcoin_primitives::merkle_tree::TxMerkleNodeEncoder<'e>::current_chunk(&self) -> &[u8]
pub fn bitcoin_primitives::merkle_tree::TxMerkleNodeEncoder<'e>::len(&self) -> usize
pub fn bitcoin_primitives::merkle_tree::TxMerkleNodeEncoder<'e>::new(encoder: bitcoin_consensus_encoding::encode::encoders::ArrayEncoder<32>) -> bitcoin_primitives::merkle_tree::TxMerkleNodeEncoder<'e>
+pub fn bitcoin_primitives::pow::CompactTarget::arbitrary(u: &mut arbitrary::unstructured::Unstructured<'a>) -> arbitrary::error::Result<Self>
pub fn bitcoin_primitives::pow::CompactTarget::clone(&self) -> bitcoin_primitives::pow::CompactTarget
pub fn bitcoin_primitives::pow::CompactTarget::cmp(&self, other: &bitcoin_primitives::pow::CompactTarget) -> core::cmp::Ordering
pub fn bitcoin_primitives::pow::CompactTarget::decoder() -> Self::Decoder
diff --git a/primitives/src/pow.rs b/primitives/src/pow.rs
index a26d44e0..41e552fb 100644
--- a/primitives/src/pow.rs
+++ b/primitives/src/pow.rs
@@ -5,6 +5,8 @@
use core::convert::Infallible;
use core::fmt;
+#[cfg(feature = "arbitrary")]
+use arbitrary::{Arbitrary, Unstructured};
use internals::write_err;
/// Encoding of 256-bit target as 32-bit float.
@@ -135,6 +137,13 @@ impl std::error::Error for CompactTargetDecoderError {
fn source(&self) -> Option<&(dyn std::error::Error + 'static)> { Some(&self.0) }
}
+#[cfg(feature = "arbitrary")]
+impl<'a> Arbitrary<'a> for CompactTarget {
+ fn arbitrary(u: &mut Unstructured<'a>) -> arbitrary::Result<Self> {
+ Ok(Self::from_consensus(u.arbitrary()?))
+ }
+}
+
#[cfg(test)]
mod tests {
#[cfg(feature = "alloc")]
diff --git a/primitives/tests/api.rs b/primitives/tests/api.rs
index a3879e8a..b996b615 100644
--- a/primitives/tests/api.rs
+++ b/primitives/tests/api.rs
@@ -300,7 +300,7 @@ fn api_all_non_error_types_have_non_empty_debug() {
block::WitnessCommitment::from_byte_array(BYTES);
merkle_tree::TxMerkleNode::from_byte_array(BYTES);
merkle_tree::WitnessMerkleNode::from_byte_array(BYTES);
- pow::CompactTarget::from_consensus(0x1d00_ffff);
+ pow::CompactTarget::arbitrary(&mut u).unwrap();
REDEEM_SCRIPT.as_script();
SCRIPT_SIG.as_script();
SCRIPT_PUB_KEY.as_script();
Why this scored 15/100
Community notes
Notes can correct, qualify, or add evidence to the AI analysis. Every note shown here has been validated by a human moderator.
The AI analysis stands alone for now. Submit a note if you can add evidence or important context.