What changed, and why it matters
This commit only fixes code style and documentation warnings (lint errors) in the addresses crate. It changes how some Rust patterns are written, adds missing documentation comments, and adjusts test code formatting. There is no change to program behavior or security.
No security action needed. Treat as routine code-quality maintenance.
Security signals we found
No strong security signals were identified.
Evidence from the diff
The commit resolves Clippy/rustdoc lint warnings in addresses/src/lib.rs. Changes include replacing wildcard use Enum::* imports with fully-qualified enum paths, adding # Errors documentation sections to public functions, adding #[allow(clippy::missing_panics_doc)] annotations, and minor formatting fixes in tests (semicolons, removing unnecessary .iter()). No logic, validation, or cryptographic behavior is altered.
Changed components
addresses/src/lib.rsInspect captured patch +69 / −48
diff --git a/addresses/src/lib.rs b/addresses/src/lib.rs
index cffc5bb5..eaf18e8a 100644
--- a/addresses/src/lib.rs
+++ b/addresses/src/lib.rs
@@ -287,9 +287,8 @@ enum AddressInner {
/// Formats bech32 as upper case if alternate formatting is chosen (`{:#}`).
impl fmt::Display for AddressInner {
fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
- use AddressInner::*;
match self {
- P2pkh { hash, network } => {
+ &Self::P2pkh { hash, network } => {
let mut prefixed = [0; 21];
prefixed[0] = match network {
NetworkKind::Main => PUBKEY_ADDRESS_PREFIX_MAIN,
@@ -298,7 +297,7 @@ impl fmt::Display for AddressInner {
prefixed[1..].copy_from_slice(hash.as_byte_array());
base58::Base58CkString::encode_unbounded(&prefixed[..]).fmt(fmt)
}
- P2sh { hash, network } => {
+ Self::P2sh { hash, network } => {
let mut prefixed = [0; 21];
prefixed[0] = match network {
NetworkKind::Main => SCRIPT_ADDRESS_PREFIX_MAIN,
@@ -307,7 +306,7 @@ impl fmt::Display for AddressInner {
prefixed[1..].copy_from_slice(hash.as_byte_array());
base58::Base58CkString::encode_unbounded(&prefixed[..]).fmt(fmt)
}
- Segwit { program, hrp } => {
+ Self::Segwit { program, hrp } => {
let hrp = hrp.to_hrp();
let version = Fe32::try_from(program.version().to_num())
.expect("version nums 0-16 are valid fe32 values");
@@ -341,12 +340,10 @@ pub enum KnownHrp {
impl KnownHrp {
/// Constructs a new [`KnownHrp`] from [`Network`].
fn from_network(network: Network) -> Self {
- use Network::*;
-
match network {
- Bitcoin => Self::Mainnet,
- Testnet(_) | Signet => Self::Testnets,
- Regtest => Self::Regtest,
+ Network::Bitcoin => Self::Mainnet,
+ Network::Testnet(_) | Network::Signet => Self::Testnets,
+ Network::Regtest => Self::Regtest,
}
}
@@ -587,11 +584,10 @@ impl<V: NetworkValidation> Address<V> {
/// Returns the [`NetworkKind`] of this address.
pub fn network_kind(&self) -> NetworkKind {
- use AddressInner::*;
match *self.inner() {
- P2pkh { hash: _, ref network } => *network,
- P2sh { hash: _, ref network } => *network,
- Segwit { program: _, ref hrp } => NetworkKind::from(*hrp),
+ AddressInner::P2pkh { hash: _, ref network } => *network,
+ AddressInner::P2sh { hash: _, ref network } => *network,
+ AddressInner::Segwit { program: _, ref hrp } => NetworkKind::from(*hrp),
}
}
}
@@ -611,6 +607,10 @@ impl Address {
///
/// This address type was introduced with BIP-0016 and is the popular type to implement multi-sig
/// these days.
+ ///
+ /// # Errors
+ ///
+ /// Returns an error if the script exceeds 520 bytes.
#[inline]
pub fn p2sh<T: ScriptHashableTag>(
redeem_script: &Script<T>,
@@ -642,6 +642,7 @@ impl Address {
/// pay-to-witness-public-key-hash (P2WPKH).
///
/// This is a SegWit address type that looks familiar (as p2sh) to legacy clients.
+ #[allow(clippy::missing_panics_doc)] // script cannot cause hash failure due to size
pub fn p2shwpkh(pk: FullPublicKey, network: impl Into<NetworkKind>) -> Self {
let builder =
ScriptPubKey::builder().push_opcode(OP_PUSHBYTES_0).push_slice(pk.wpubkey_hash());
@@ -650,6 +651,10 @@ impl Address {
}
/// Constructs a new pay-to-witness-script-hash (P2WSH) [`Address`] from a witness script.
+ ///
+ /// # Errors
+ ///
+ /// Returns an error if the script exceeds 10,000 bytes.
pub fn p2wsh(
witness_script: &WitnessScript,
hrp: impl Into<KnownHrp>,
@@ -668,6 +673,11 @@ impl Address {
/// pay-to-witness-script-hash (P2WSH).
///
/// This is a SegWit address type that looks familiar (as p2sh) to legacy clients.
+ ///
+ /// # Errors
+ ///
+ /// Returns an error if the script exceeds 10,000 bytes.
+ #[allow(clippy::missing_panics_doc)] // script cannot cause hash failure due to size
pub fn p2shwsh(
witness_script: &WitnessScript,
network: impl Into<NetworkKind>,
@@ -736,41 +746,34 @@ impl Address {
/// Gets the address data from this address.
pub fn to_address_data(self) -> AddressData {
- use AddressData::*;
-
match *self.inner() {
- AddressInner::P2pkh { hash, network: _ } => P2pkh { pubkey_hash: hash },
- AddressInner::P2sh { hash, network: _ } => P2sh { script_hash: hash },
- AddressInner::Segwit { program, hrp: _ } => Segwit { witness_program: program },
+ AddressInner::P2pkh { hash, network: _ } => AddressData::P2pkh { pubkey_hash: hash },
+ AddressInner::P2sh { hash, network: _ } => AddressData::P2sh { script_hash: hash },
+ AddressInner::Segwit { program, hrp: _ } =>
+ AddressData::Segwit { witness_program: program },
}
}
/// Gets the pubkey hash for this address if this is a P2PKH address.
pub fn pubkey_hash(&self) -> Option<PubkeyHash> {
- use AddressInner::*;
-
match *self.inner() {
- P2pkh { ref hash, network: _ } => Some(*hash),
+ AddressInner::P2pkh { ref hash, network: _ } => Some(*hash),
_ => None,
}
}
/// Gets the script hash for this address if this is a P2SH address.
pub fn script_hash(&self) -> Option<ScriptHash> {
- use AddressInner::*;
-
match *self.inner() {
- P2sh { ref hash, network: _ } => Some(*hash),
+ AddressInner::P2sh { ref hash, network: _ } => Some(*hash),
_ => None,
}
}
/// Gets the witness program for this address if this is a SegWit address.
pub fn witness_program(&self) -> Option<WitnessProgram> {
- use AddressInner::*;
-
match *self.inner() {
- Segwit { ref program, hrp: _ } => Some(*program),
+ AddressInner::Segwit { ref program, hrp: _ } => Some(*program),
_ => None,
}
}
@@ -792,7 +795,8 @@ impl Address {
/// Generates a script pubkey spending to this address.
pub fn script_pubkey(&self) -> ScriptPubKeyBuf {
- use AddressInner::*;
+ use AddressInner::{P2pkh, P2sh, Segwit};
+
match *self.inner() {
P2pkh { hash, network: _ } => ScriptPubKeyBuf::new_p2pkh(hash),
P2sh { hash, network: _ } => ScriptPubKeyBuf::new_p2sh(hash),
@@ -859,7 +863,8 @@ impl Address {
/// Returns true if the address creates a particular script
/// This function doesn't make any allocations.
pub fn matches_script_pubkey(&self, script: &ScriptPubKey) -> bool {
- use AddressInner::*;
+ use AddressInner::{P2pkh, P2sh, Segwit};
+
match *self.inner() {
P2pkh { ref hash, network: _ } if script.is_p2pkh() =>
&script.as_bytes()[3..23] == <PubkeyHash as AsRef<[u8; 20]>>::as_ref(hash),
@@ -880,11 +885,10 @@ impl Address {
/// - For p2pkh, the payload is the pubkey hash.
/// - For SegWit addresses, the payload is the witness program.
fn payload_as_bytes(&self) -> &[u8] {
- use AddressInner::*;
match *self.inner() {
- P2sh { ref hash, network: _ } => hash.as_ref(),
- P2pkh { ref hash, network: _ } => hash.as_ref(),
- Segwit { ref program, hrp: _ } => program.program().as_bytes(),
+ AddressInner::P2sh { ref hash, network: _ } => hash.as_ref(),
+ AddressInner::P2pkh { ref hash, network: _ } => hash.as_ref(),
+ AddressInner::Segwit { ref program, hrp: _ } => program.program().as_bytes(),
}
}
}
@@ -918,11 +922,10 @@ impl Address<NetworkUnchecked> {
/// assert_eq!(address.is_valid_for_network(Network::Testnet(TestnetVersion::V4)), false);
/// ```
pub fn is_valid_for_network(&self, n: Network) -> bool {
- use AddressInner::*;
match *self.inner() {
- P2pkh { hash: _, ref network } => *network == NetworkKind::from(n),
- P2sh { hash: _, ref network } => *network == NetworkKind::from(n),
- Segwit { program: _, ref hrp } => *hrp == KnownHrp::from_network(n),
+ AddressInner::P2pkh { hash: _, ref network } => *network == NetworkKind::from(n),
+ AddressInner::P2sh { hash: _, ref network } => *network == NetworkKind::from(n),
+ AddressInner::Segwit { program: _, ref hrp } => *hrp == KnownHrp::from_network(n),
}
}
@@ -987,6 +990,15 @@ impl Address<NetworkUnchecked> {
pub fn assume_checked(self) -> Address { Address::from_inner(self.to_inner()) }
/// Parses a bech32 Address string
+ ///
+ /// # Errors
+ ///
+ /// - [`Bech32Error::ParseBech32`] if the string is not valid bech32 or does not encode a valid
+ /// SegWit address.
+ /// - [`Bech32Error::WitnessVersion`] if the witness version byte is not a valid witness version.
+ /// - [`Bech32Error::UnknownHrp`] if the human-readable part is not one of the known Bitcoin
+ /// HRPs (`bc`, `tb`, or `bcrt`).
+ #[allow(clippy::missing_panics_doc)]
pub fn from_bech32_str(s: &str) -> Result<Self, Bech32Error> {
let (hrp, witness_version, data) =
bech32::segwit::decode(s).map_err(|e| Bech32Error::ParseBech32(ParseBech32Error(e)))?;
@@ -1000,6 +1012,19 @@ impl Address<NetworkUnchecked> {
}
/// Parses a base58 Address string
+ ///
+ /// # Errors
+ ///
+ /// - [`Base58Error::LegacyAddressTooLong`] if the input string is longer than 50 characters.
+ /// - [`Base58Error::ParseBase58`] if the input string is invalid base58, less than 4 bytes or
+ /// the checksum does not match the expected value.
+ /// - [`Base58Error::InvalidBase58PayloadLength`] if the resulting decoded slice is not 21
+ /// bytes.
+ /// - [`Base58Error::InvalidLegacyPrefix`] if the address prefix is not one of:
+ /// - [`PUBKEY_ADDRESS_PREFIX_MAIN`]
+ /// - [`PUBKEY_ADDRESS_PREFIX_TEST`]
+ /// - [`SCRIPT_ADDRESS_PREFIX_MAIN`]
+ /// - [`SCRIPT_ADDRESS_PREFIX_TEST`]
pub fn from_base58_str(s: &str) -> Result<Self, Base58Error> {
if s.len() > 50 {
return Err(LegacyAddressTooLongError { length: s.len() }.into());
@@ -1133,7 +1158,7 @@ mod tests {
fn p2sh_parse_for_large_script() {
let script = RedeemScriptBuf::from_hex_no_length_prefix("552103a765fc35b3f210b95223846b36ef62a4e53e34e2925270c2c7906b92c9f718eb2103c327511374246759ec8d0b89fa6c6b23b33e11f92c5bc155409d86de0c79180121038cae7406af1f12f4786d820a1466eec7bc5785a1b5e4a387eca6d797753ef6db2103252bfb9dcaab0cd00353f2ac328954d791270203d66c2be8b430f115f451b8a12103e79412d42372c55dd336f2eb6eb639ef9d74a22041ba79382c74da2338fe58ad21035049459a4ebc00e876a9eef02e72a3e70202d3d1f591fc0dd542f93f642021f82102016f682920d9723c61b27f562eb530c926c00106004798b6471e8c52c60ee02057ae12123122313123123ac1231231231231313123131231231231313212313213123123552103a765fc35b3f210b95223846b36ef62a4e53e34e2925270c2c7906b92c9f718eb2103c327511374246759ec8d0b89fa6c6b23b33e11f92c5bc155409d86de0c79180121038cae7406af1f12f4786d820a1466eec7bc5785a1b5e4a387eca6d797753ef6db2103252bfb9dcaab0cd00353f2ac328954d791270203d66c2be8b430f115f451b8a12103e79412d42372c55dd336f2eb6eb639ef9d74a22041ba79382c74da2338fe58ad21035049459a4ebc00e876a9eef02e72a3e70202d3d1f591fc0dd542f93f642021f82102016f682920d9723c61b27f562eb530c926c00106004798b6471e8c52c60ee02057ae12123122313123123ac1231231231231313123131231231231313212313213123123552103a765fc35b3f210b95223846b36ef62a4e53e34e2925270c2c7906b92c9f718eb2103c327511374246759ec8d0b89fa6c6b23b33e11f92c5bc155409d86de0c79180121038cae7406af1f12f4786d820a1466eec7bc5785a1b5e4a387eca6d797753ef6db2103252bfb9dcaab0cd00353f2ac328954d791270203d66c2be8b430f115f451b8a12103e79412d42372c55dd336f2eb6eb639ef9d74a22041ba79382c74da2338fe58ad21035049459a4ebc00e876a9eef02e72a3e70202d3d1f591fc0dd542f93f642021f82102016f682920d9723c61b27f562eb530c926c00106004798b6471e8c52c60ee02057ae12123122313123123ac1231231231231313123131231231231313212313213123123").unwrap();
let res = Address::p2sh(&script, NetworkKind::Test);
- assert_eq!(res.unwrap_err().invalid_size(), script.len())
+ assert_eq!(res.unwrap_err().invalid_size(), script.len());
}
#[test]
@@ -1192,9 +1217,7 @@ mod tests {
#[test]
fn qr_string() {
- for el in
- ["132F25rTsvBdp9JzLLBHP5mvGY66i1xdiM", "33iFwdLuRpW1uK1RTRqsoi8rR4NpDzk66k"].iter()
- {
+ for el in ["132F25rTsvBdp9JzLLBHP5mvGY66i1xdiM", "33iFwdLuRpW1uK1RTRqsoi8rR4NpDzk66k"] {
let addr = el
.parse::<Address<_>>()
.unwrap()
@@ -1206,9 +1229,7 @@ mod tests {
for el in [
"bcrt1q2nfxmhd4n3c8834pj72xagvyr9gl57n5r94fsl",
"bc1qwqdg6squsna38e46795at95yu9atm8azzmyvckulcc7kytlcckxswvvzej",
- ]
- .iter()
- {
+ ] {
let addr = el.parse::<Address<_>>().unwrap().assume_checked();
assert_eq!(addr.to_qr_uri(), format!("bitcoin:{}", el.to_ascii_uppercase()));
}
@@ -1232,7 +1253,7 @@ mod tests {
let unused_pubkey = "02ba604e6ad9d3864eda8dc41c62668514ef7d5417d3b6db46e45cc4533bff001c"
.parse::<LegacyPublicKey>()
.expect("pubkey");
- assert!(!address.is_related_to_pubkey(unused_pubkey))
+ assert!(!address.is_related_to_pubkey(unused_pubkey));
}
#[test]
@@ -1253,7 +1274,7 @@ mod tests {
let unused_pubkey = "02ba604e6ad9d3864eda8dc41c62668514ef7d5417d3b6db46e45cc4533bff001c"
.parse::<LegacyPublicKey>()
.expect("pubkey");
- assert!(!address.is_related_to_pubkey(unused_pubkey))
+ assert!(!address.is_related_to_pubkey(unused_pubkey));
}
#[test]
@@ -1274,7 +1295,7 @@ mod tests {
let unused_pubkey = "02ba604e6ad9d3864eda8dc41c62668514ef7d5417d3b6db46e45cc4533bff001c"
.parse::<LegacyPublicKey>()
.expect("pubkey");
- assert!(!address.is_related_to_pubkey(unused_pubkey))
+ assert!(!address.is_related_to_pubkey(unused_pubkey));
}
#[test]
@@ -1295,7 +1316,7 @@ mod tests {
let unused_pubkey = "02ba604e6ad9d3864eda8dc41c62668514ef7d5417d3b6db46e45cc4533bff001c"
.parse::<LegacyPublicKey>()
.expect("pubkey");
- assert!(!address.is_related_to_pubkey(unused_pubkey))
+ assert!(!address.is_related_to_pubkey(unused_pubkey));
}
#[test]
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.