Merge rust-bitcoin/rust-bitcoin#2878: Implement constants for `ChildNumber` enum

39df0a9fbe update api (Divyansh Gupta)
3a5f2932a4 create constants for ChildNumber enum (Divyansh Gupta)

Pull request description:

  this aims to fix #2750

ACKs for top commit:
  tcharding:
    ACK 39df0a9fbe

Tree-SHA512: e1c38568facd2b9aa55b1b1ec0d5d5f68ff38ca3fe68962bc316c060a062299935aa51bcfc1c255a7f5c9ad97435cab22e2c160d3fd3f52a46f6b5cbb7d5743f
This commit is contained in:
Andrew Poelstra 2024-06-22 18:10:34 +00:00
commit 0554c2825f
No known key found for this signature in database
GPG Key ID: C588D63CE41B97C1
10 changed files with 49 additions and 36 deletions

View File

@ -5711,6 +5711,10 @@ pub const bitcoin::bip158::FilterHash::N: usize
pub const bitcoin::bip158::FilterHeader::DISPLAY_BACKWARD: bool
pub const bitcoin::bip158::FilterHeader::LEN: usize
pub const bitcoin::bip158::FilterHeader::N: usize
pub const bitcoin::bip32::ChildNumber::ONE_HARDENED: Self
pub const bitcoin::bip32::ChildNumber::ONE_NORMAL: Self
pub const bitcoin::bip32::ChildNumber::ZERO_HARDENED: Self
pub const bitcoin::bip32::ChildNumber::ZERO_NORMAL: Self
pub const bitcoin::bip32::XKeyIdentifier::DISPLAY_BACKWARD: bool
pub const bitcoin::bip32::XKeyIdentifier::LEN: usize
pub const bitcoin::bip32::XKeyIdentifier::N: usize

View File

@ -5422,6 +5422,10 @@ pub const bitcoin::bip158::FilterHash::DISPLAY_BACKWARD: bool
pub const bitcoin::bip158::FilterHash::LEN: usize
pub const bitcoin::bip158::FilterHeader::DISPLAY_BACKWARD: bool
pub const bitcoin::bip158::FilterHeader::LEN: usize
pub const bitcoin::bip32::ChildNumber::ONE_HARDENED: Self
pub const bitcoin::bip32::ChildNumber::ONE_NORMAL: Self
pub const bitcoin::bip32::ChildNumber::ZERO_HARDENED: Self
pub const bitcoin::bip32::ChildNumber::ZERO_NORMAL: Self
pub const bitcoin::bip32::XKeyIdentifier::DISPLAY_BACKWARD: bool
pub const bitcoin::bip32::XKeyIdentifier::LEN: usize
pub const bitcoin::blockdata::block::BlockHash::DISPLAY_BACKWARD: bool

View File

@ -4805,6 +4805,10 @@ pub const bitcoin::bip158::FilterHash::DISPLAY_BACKWARD: bool
pub const bitcoin::bip158::FilterHash::LEN: usize
pub const bitcoin::bip158::FilterHeader::DISPLAY_BACKWARD: bool
pub const bitcoin::bip158::FilterHeader::LEN: usize
pub const bitcoin::bip32::ChildNumber::ONE_HARDENED: Self
pub const bitcoin::bip32::ChildNumber::ONE_NORMAL: Self
pub const bitcoin::bip32::ChildNumber::ZERO_HARDENED: Self
pub const bitcoin::bip32::ChildNumber::ZERO_NORMAL: Self
pub const bitcoin::bip32::XKeyIdentifier::DISPLAY_BACKWARD: bool
pub const bitcoin::bip32::XKeyIdentifier::LEN: usize
pub const bitcoin::blockdata::block::BlockHash::DISPLAY_BACKWARD: bool

View File

@ -48,7 +48,7 @@ fn main() {
// generate first receiving address at m/0/0
// manually creating indexes this time
let zero = ChildNumber::from_normal_idx(0).unwrap();
let zero = ChildNumber::ZERO_NORMAL;
let public_key = xpub.derive_pub(&secp, &[zero, zero]).unwrap().public_key;
let address = Address::p2wpkh(CompressedPublicKey(public_key), KnownHrp::Mainnet);
println!("First receiving address: {}", address);

View File

@ -61,7 +61,7 @@ fn get_external_address_xpriv<C: Signing>(
let derivation_path =
BIP84_DERIVATION_PATH.into_derivation_path().expect("valid derivation path");
let child_xpriv = master_xpriv.derive_priv(secp, &derivation_path);
let external_index = ChildNumber::from_normal_idx(0).unwrap();
let external_index = ChildNumber::ZERO_NORMAL;
let idx = ChildNumber::from_normal_idx(index).expect("valid index number");
child_xpriv.derive_priv(secp, &[external_index, idx])
@ -76,7 +76,7 @@ fn get_internal_address_xpriv<C: Signing>(
let derivation_path =
BIP84_DERIVATION_PATH.into_derivation_path().expect("valid derivation path");
let child_xpriv = master_xpriv.derive_priv(secp, &derivation_path);
let internal_index = ChildNumber::from_normal_idx(1).unwrap();
let internal_index = ChildNumber::ONE_NORMAL;
let idx = ChildNumber::from_normal_idx(index).expect("valid index number");
child_xpriv.derive_priv(secp, &[internal_index, idx])

View File

@ -255,7 +255,7 @@ impl WatchOnly {
&self,
secp: &Secp256k1<C>,
) -> Result<(CompressedPublicKey, Address, DerivationPath)> {
let path = [ChildNumber::from_normal_idx(1)?, ChildNumber::from_normal_idx(0)?];
let path = [ChildNumber::ONE_NORMAL, ChildNumber::ZERO_NORMAL];
let derived = self.account_0_xpub.derive_pub(secp, &path)?;
let pk = derived.to_pub();

View File

@ -60,7 +60,7 @@ fn get_external_address_xpriv<C: Signing>(
let derivation_path =
BIP86_DERIVATION_PATH.into_derivation_path().expect("valid derivation path");
let child_xpriv = master_xpriv.derive_priv(secp, &derivation_path);
let external_index = ChildNumber::from_normal_idx(0).unwrap();
let external_index = ChildNumber::ZERO_NORMAL;
let idx = ChildNumber::from_normal_idx(index).expect("valid index number");
child_xpriv.derive_priv(secp, &[external_index, idx])
@ -75,7 +75,7 @@ fn get_internal_address_xpriv<C: Signing>(
let derivation_path =
BIP86_DERIVATION_PATH.into_derivation_path().expect("valid derivation path");
let child_xpriv = master_xpriv.derive_priv(secp, &derivation_path);
let internal_index = ChildNumber::from_normal_idx(1).unwrap();
let internal_index = ChildNumber::ONE_NORMAL;
let idx = ChildNumber::from_normal_idx(index).expect("valid index number");
child_xpriv.derive_priv(secp, &[internal_index, idx])

View File

@ -360,7 +360,7 @@ impl BenefactorWallet {
current_spend_info: None,
next_psbt: None,
secp: Secp256k1::new(),
next: ChildNumber::from_normal_idx(0).expect("Zero is a valid child number"),
next: ChildNumber::ZERO_NORMAL,
})
}

View File

@ -126,8 +126,19 @@ pub enum ChildNumber {
index: u32,
},
}
impl ChildNumber {
/// Normal child number with index 0.
pub const ZERO_NORMAL: Self = ChildNumber::Normal { index: 0 };
/// Normal child number with index 1.
pub const ONE_NORMAL: Self = ChildNumber::Normal { index: 1 };
/// Hardened child number with index 0.
pub const ZERO_HARDENED: Self = ChildNumber::Hardened { index: 0 };
/// Hardened child number with index 1.
pub const ONE_HARDENED: Self = ChildNumber::Hardened { index: 1 };
/// Create a [`Normal`] from an index, returns an error if the index is not within
/// [0, 2^31 - 1].
///
@ -417,8 +428,8 @@ impl DerivationPath {
///
/// let deriv_1 = base.extend(DerivationPath::from_str("0/1").unwrap());
/// let deriv_2 = base.extend(&[
/// ChildNumber::from_normal_idx(0).unwrap(),
/// ChildNumber::from_normal_idx(1).unwrap()
/// ChildNumber::ZERO_NORMAL,
/// ChildNumber::ONE_NORMAL
/// ]);
///
/// assert_eq!(deriv_1, deriv_2);
@ -564,7 +575,7 @@ impl Xpriv {
network: network.into(),
depth: 0,
parent_fingerprint: Default::default(),
child_number: ChildNumber::from_normal_idx(0)?,
child_number: ChildNumber::ZERO_NORMAL,
private_key: secp256k1::SecretKey::from_slice(&hmac_result.as_ref()[..32])?,
chain_code: ChainCode::from_hmac(hmac_result),
})
@ -919,23 +930,16 @@ mod tests {
assert_eq!(DerivationPath::from_str("m/").unwrap(), DerivationPath(vec![]));
assert_eq!(DerivationPath::from_str("").unwrap(), DerivationPath(vec![]));
assert_eq!(
DerivationPath::from_str("0'"),
Ok(vec![ChildNumber::from_hardened_idx(0).unwrap()].into())
);
assert_eq!(DerivationPath::from_str("0'"), Ok(vec![ChildNumber::ZERO_HARDENED].into()));
assert_eq!(
DerivationPath::from_str("0'/1"),
Ok(vec![
ChildNumber::from_hardened_idx(0).unwrap(),
ChildNumber::from_normal_idx(1).unwrap()
]
.into())
Ok(vec![ChildNumber::ZERO_HARDENED, ChildNumber::ONE_NORMAL].into())
);
assert_eq!(
DerivationPath::from_str("0h/1/2'"),
Ok(vec![
ChildNumber::from_hardened_idx(0).unwrap(),
ChildNumber::from_normal_idx(1).unwrap(),
ChildNumber::ZERO_HARDENED,
ChildNumber::ONE_NORMAL,
ChildNumber::from_hardened_idx(2).unwrap(),
]
.into())
@ -943,16 +947,16 @@ mod tests {
assert_eq!(
DerivationPath::from_str("0'/1/2h/2"),
Ok(vec![
ChildNumber::from_hardened_idx(0).unwrap(),
ChildNumber::from_normal_idx(1).unwrap(),
ChildNumber::ZERO_HARDENED,
ChildNumber::ONE_NORMAL,
ChildNumber::from_hardened_idx(2).unwrap(),
ChildNumber::from_normal_idx(2).unwrap(),
]
.into())
);
let want = DerivationPath::from(vec![
ChildNumber::from_hardened_idx(0).unwrap(),
ChildNumber::from_normal_idx(1).unwrap(),
ChildNumber::ZERO_HARDENED,
ChildNumber::ONE_NORMAL,
ChildNumber::from_hardened_idx(2).unwrap(),
ChildNumber::from_normal_idx(2).unwrap(),
ChildNumber::from_normal_idx(1000000000).unwrap(),
@ -975,10 +979,7 @@ mod tests {
let numbers: Vec<ChildNumber> = path.clone().into();
let path2: DerivationPath = numbers.into();
assert_eq!(path, path2);
assert_eq!(
&path[..2],
&[ChildNumber::from_hardened_idx(0).unwrap(), ChildNumber::from_normal_idx(1).unwrap()]
);
assert_eq!(&path[..2], &[ChildNumber::ZERO_HARDENED, ChildNumber::ONE_NORMAL]);
let indexed: DerivationPath = path[..2].into();
assert_eq!(indexed, DerivationPath::from_str("0h/1").unwrap());
assert_eq!(indexed.child(ChildNumber::from_hardened_idx(2).unwrap()), path);
@ -1166,11 +1167,11 @@ mod tests {
#[test]
#[cfg(feature = "serde")]
pub fn encode_decode_childnumber() {
serde_round_trip!(ChildNumber::from_normal_idx(0).unwrap());
serde_round_trip!(ChildNumber::from_normal_idx(1).unwrap());
serde_round_trip!(ChildNumber::ZERO_NORMAL);
serde_round_trip!(ChildNumber::ONE_NORMAL);
serde_round_trip!(ChildNumber::from_normal_idx((1 << 31) - 1).unwrap());
serde_round_trip!(ChildNumber::from_hardened_idx(0).unwrap());
serde_round_trip!(ChildNumber::from_hardened_idx(1).unwrap());
serde_round_trip!(ChildNumber::ZERO_HARDENED);
serde_round_trip!(ChildNumber::ONE_HARDENED);
serde_round_trip!(ChildNumber::from_hardened_idx((1 << 31) - 1).unwrap());
}

View File

@ -1356,8 +1356,8 @@ mod tests {
let fprint = sk.fingerprint(secp);
let dpath: Vec<ChildNumber> = vec![
ChildNumber::from_normal_idx(0).unwrap(),
ChildNumber::from_normal_idx(1).unwrap(),
ChildNumber::ZERO_NORMAL,
ChildNumber::ONE_NORMAL,
ChildNumber::from_normal_idx(2).unwrap(),
ChildNumber::from_normal_idx(4).unwrap(),
ChildNumber::from_normal_idx(42).unwrap(),