From 120cc70a6d980a57a190953300b5a29ceaeae737 Mon Sep 17 00:00:00 2001 From: Kris Nuttycombe Date: Mon, 11 Oct 2021 13:42:01 -0600 Subject: [PATCH] Fix type of default_address --- zcash_client_backend/src/data_api/wallet.rs | 2 +- zcash_client_backend/src/welding_rig.rs | 2 +- zcash_client_sqlite/src/chain.rs | 2 +- zcash_client_sqlite/src/lib.rs | 6 +- zcash_client_sqlite/src/wallet/init.rs | 2 +- zcash_client_sqlite/src/wallet/transact.rs | 12 ++-- zcash_extensions/src/transparent/demo.rs | 2 +- zcash_primitives/src/sapling.rs | 5 +- zcash_primitives/src/sapling/keys.rs | 2 +- zcash_primitives/src/transaction/builder.rs | 6 +- zcash_primitives/src/zip32.rs | 62 ++++++++++----------- 11 files changed, 50 insertions(+), 53 deletions(-) diff --git a/zcash_client_backend/src/data_api/wallet.rs b/zcash_client_backend/src/data_api/wallet.rs index ea3c05f13..40552fa49 100644 --- a/zcash_client_backend/src/data_api/wallet.rs +++ b/zcash_client_backend/src/data_api/wallet.rs @@ -124,7 +124,7 @@ where /// /// let account = AccountId(0); /// let extsk = spending_key(&[0; 32][..], COIN_TYPE, account.0); -/// let to = extsk.default_address().unwrap().1.into(); +/// let to = extsk.default_address().1.into(); /// /// let data_file = NamedTempFile::new().unwrap(); /// let db_read = WalletDb::for_path(data_file, Network::TestNetwork).unwrap(); diff --git a/zcash_client_backend/src/welding_rig.rs b/zcash_client_backend/src/welding_rig.rs index 572e31ba6..c4b682b59 100644 --- a/zcash_client_backend/src/welding_rig.rs +++ b/zcash_client_backend/src/welding_rig.rs @@ -357,7 +357,7 @@ mod tests { value: Amount, tx_after: bool, ) -> CompactBlock { - let to = extfvk.default_address().unwrap().1; + let to = extfvk.default_address().1; // Create a fake Note for the account let mut rng = OsRng; diff --git a/zcash_client_sqlite/src/chain.rs b/zcash_client_sqlite/src/chain.rs index 1b3692239..55a8198b7 100644 --- a/zcash_client_sqlite/src/chain.rs +++ b/zcash_client_sqlite/src/chain.rs @@ -537,7 +537,7 @@ mod tests { // Create a second fake CompactBlock spending value from the address let extsk2 = ExtendedSpendingKey::master(&[0]); - let to2 = extsk2.default_address().unwrap().1; + let to2 = extsk2.default_address().1; let value2 = Amount::from_u64(2).unwrap(); insert_into_cache( &db_cache, diff --git a/zcash_client_sqlite/src/lib.rs b/zcash_client_sqlite/src/lib.rs index e7fdafc63..69673d1d7 100644 --- a/zcash_client_sqlite/src/lib.rs +++ b/zcash_client_sqlite/src/lib.rs @@ -545,7 +545,7 @@ fn address_from_extfvk( params: &P, extfvk: &ExtendedFullViewingKey, ) -> String { - let addr = extfvk.default_address().unwrap().1; + let addr = extfvk.default_address().1; encode_payment_address(params.hrp_sapling_payment_address(), &addr) } @@ -607,7 +607,7 @@ mod tests { extfvk: ExtendedFullViewingKey, value: Amount, ) -> (CompactBlock, Nullifier) { - let to = extfvk.default_address().unwrap().1; + let to = extfvk.default_address().1; // Create a fake Note for the account let mut rng = OsRng; @@ -698,7 +698,7 @@ mod tests { // Create a fake Note for the change ctx.outputs.push({ - let change_addr = extfvk.default_address().unwrap().1; + let change_addr = extfvk.default_address().1; let rseed = generate_random_rseed(&network(), height, &mut rng); let note = Note { g_d: change_addr.diversifier().g_d().unwrap(), diff --git a/zcash_client_sqlite/src/wallet/init.rs b/zcash_client_sqlite/src/wallet/init.rs index f21f53182..7e8587fbf 100644 --- a/zcash_client_sqlite/src/wallet/init.rs +++ b/zcash_client_sqlite/src/wallet/init.rs @@ -310,6 +310,6 @@ mod tests { // The account's address should be in the data DB let pa = get_address(&db_data, AccountId(0)).unwrap(); - assert_eq!(pa.unwrap(), extsk.default_address().unwrap().1); + assert_eq!(pa.unwrap(), extsk.default_address().1); } } diff --git a/zcash_client_sqlite/src/wallet/transact.rs b/zcash_client_sqlite/src/wallet/transact.rs index 361696ba9..e468d8aa7 100644 --- a/zcash_client_sqlite/src/wallet/transact.rs +++ b/zcash_client_sqlite/src/wallet/transact.rs @@ -200,7 +200,7 @@ mod tests { ExtendedFullViewingKey::from(&extsk1), ]; init_accounts_table(&db_data, &extfvks).unwrap(); - let to = extsk0.default_address().unwrap().1.into(); + let to = extsk0.default_address().1.into(); // Invalid extsk for the given account should cause an error let mut db_write = db_data.get_update_ops().unwrap(); @@ -245,7 +245,7 @@ mod tests { let extsk = ExtendedSpendingKey::master(&[]); let extfvks = [ExtendedFullViewingKey::from(&extsk)]; init_accounts_table(&db_data, &extfvks).unwrap(); - let to = extsk.default_address().unwrap().1.into(); + let to = extsk.default_address().1.into(); // We cannot do anything if we aren't synchronised let mut db_write = db_data.get_update_ops().unwrap(); @@ -283,7 +283,7 @@ mod tests { let extsk = ExtendedSpendingKey::master(&[]); let extfvks = [ExtendedFullViewingKey::from(&extsk)]; init_accounts_table(&db_data, &extfvks).unwrap(); - let to = extsk.default_address().unwrap().1.into(); + let to = extsk.default_address().1.into(); // Account balance should be zero assert_eq!(get_balance(&db_data, AccountId(0)).unwrap(), Amount::zero()); @@ -367,7 +367,7 @@ mod tests { // Spend fails because there are insufficient verified notes let extsk2 = ExtendedSpendingKey::master(&[]); - let to = extsk2.default_address().unwrap().1.into(); + let to = extsk2.default_address().1.into(); match create_spend_to_address( &mut db_write, &tests::network(), @@ -469,7 +469,7 @@ mod tests { // Send some of the funds to another address let extsk2 = ExtendedSpendingKey::master(&[]); - let to = extsk2.default_address().unwrap().1.into(); + let to = extsk2.default_address().1.into(); create_spend_to_address( &mut db_write, &tests::network(), @@ -589,7 +589,7 @@ mod tests { assert_eq!(get_balance(&db_data, AccountId(0)).unwrap(), value); let extsk2 = ExtendedSpendingKey::master(&[]); - let addr2 = extsk2.default_address().unwrap().1; + let addr2 = extsk2.default_address().1; let to = addr2.clone().into(); let send_and_recover_with_policy = |db_write: &mut DataConnStmtCache<'_, _>, ovk_policy| { diff --git a/zcash_extensions/src/transparent/demo.rs b/zcash_extensions/src/transparent/demo.rs index 18f2b3a17..274e7b5d5 100644 --- a/zcash_extensions/src/transparent/demo.rs +++ b/zcash_extensions/src/transparent/demo.rs @@ -809,7 +809,7 @@ mod tests { // create some inputs to spend let extsk = ExtendedSpendingKey::master(&[]); - let to = extsk.default_address().unwrap().1; + let to = extsk.default_address().1; let note1 = to .create_note(110000, Rseed::BeforeZip212(jubjub::Fr::random(&mut rng))) .unwrap(); diff --git a/zcash_primitives/src/sapling.rs b/zcash_primitives/src/sapling.rs index 99b06e703..8fa0187c0 100644 --- a/zcash_primitives/src/sapling.rs +++ b/zcash_primitives/src/sapling.rs @@ -546,10 +546,7 @@ pub mod testing { } pub fn arb_payment_address() -> impl Strategy { - arb_extended_spending_key() - .prop_map(|sk| sk.default_address().map(|(_, a)| a)) - .prop_filter("A valid payment address is required.", |r| r.is_ok()) - .prop_map(|r| r.unwrap()) + arb_extended_spending_key().prop_map(|sk| sk.default_address().1) } prop_compose! { diff --git a/zcash_primitives/src/sapling/keys.rs b/zcash_primitives/src/sapling/keys.rs index 4ab313bd6..eec54a32b 100644 --- a/zcash_primitives/src/sapling/keys.rs +++ b/zcash_primitives/src/sapling/keys.rs @@ -199,7 +199,7 @@ pub mod testing { prop_compose! { pub fn arb_shielded_addr()(extsk in arb_extended_spending_key()) -> PaymentAddress { let extfvk = ExtendedFullViewingKey::from(&extsk); - extfvk.default_address().unwrap().1 + extfvk.default_address().1 } } } diff --git a/zcash_primitives/src/transaction/builder.rs b/zcash_primitives/src/transaction/builder.rs index b3f251763..74eaa921e 100644 --- a/zcash_primitives/src/transaction/builder.rs +++ b/zcash_primitives/src/transaction/builder.rs @@ -496,7 +496,7 @@ mod tests { let extsk = ExtendedSpendingKey::master(&[]); let extfvk = ExtendedFullViewingKey::from(&extsk); let ovk = extfvk.fvk.ovk; - let to = extfvk.default_address().unwrap().1; + let to = extfvk.default_address().1; let sapling_activation_height = TEST_NETWORK .activation_height(NetworkUpgrade::Sapling) @@ -549,7 +549,7 @@ mod tests { fn binding_sig_present_if_shielded_spend() { let extsk = ExtendedSpendingKey::master(&[]); let extfvk = ExtendedFullViewingKey::from(&extsk); - let to = extfvk.default_address().unwrap().1; + let to = extfvk.default_address().1; let mut rng = OsRng; @@ -622,7 +622,7 @@ mod tests { let extfvk = ExtendedFullViewingKey::from(&extsk); let ovk = Some(extfvk.fvk.ovk); - let to = extfvk.default_address().unwrap().1; + let to = extfvk.default_address().1; // Fail if there is only a Sapling output // 0.0005 z-ZEC out, 0.00001 t-ZEC fee diff --git a/zcash_primitives/src/zip32.rs b/zcash_primitives/src/zip32.rs index 3d8ef4398..9e7b71b17 100644 --- a/zcash_primitives/src/zip32.rs +++ b/zcash_primitives/src/zip32.rs @@ -161,18 +161,19 @@ impl DiversifierKey { /// Returns the first index starting from j that generates a valid /// diversifier, along with the corresponding diversifier. Returns - /// an error if the diversifier space is exhausted. + /// `None` if the diversifier space contains no valid diversifiers + /// at or above the specified diversifier index. pub fn find_diversifier( &self, mut j: DiversifierIndex, - ) -> Result<(DiversifierIndex, Diversifier), ()> { + ) -> Option<(DiversifierIndex, Diversifier)> { let ff = FF1::::new(&self.0, 2).unwrap(); loop { match Self::try_diversifier_internal(&ff, j) { - Some(d_j) => return Ok((j, d_j)), + Some(d_j) => return Some((j, d_j)), None => { if j.increment().is_err() { - return Err(()); + return None; } } } @@ -351,7 +352,11 @@ impl ExtendedSpendingKey { } } - pub fn default_address(&self) -> Result<(DiversifierIndex, PaymentAddress), ()> { + /// Returns the address with the lowest valid diversifier index, along with + /// the diversifier index that generated that address. Returns `None` with + /// negligible frequency; a `None` result here indicates that no valid + /// addresses could be generated. + pub fn default_address(&self) -> (DiversifierIndex, PaymentAddress) { ExtendedFullViewingKey::from(self).default_address() } } @@ -451,19 +456,17 @@ impl ExtendedFullViewingKey { /// one which will produce a valid diversifier, and return the payment address /// constructed using that diversifier along with the index at which the /// valid diversifier was found. - pub fn find_address( - &self, - j: DiversifierIndex, - ) -> Result<(DiversifierIndex, PaymentAddress), ()> { + pub fn find_address(&self, j: DiversifierIndex) -> Option<(DiversifierIndex, PaymentAddress)> { let (j, d_j) = self.dk.find_diversifier(j)?; - match self.fvk.vk.to_payment_address(d_j) { - Some(addr) => Ok((j, addr)), - None => Err(()), - } + self.fvk.vk.to_payment_address(d_j).map(|addr| (j, addr)) } - pub fn default_address(&self) -> Result<(DiversifierIndex, PaymentAddress), ()> { - self.find_address(DiversifierIndex::new()) + /// Returns the payment address corresponding to the smallest valid diversifier + /// index, along with that index. + pub fn default_address(&self) -> (DiversifierIndex, PaymentAddress) { + // This unwrap is safe, if you have to search the 2^88 space of + // diversifiers it'll never return anyway. + self.find_address(DiversifierIndex::new()).unwrap() } } @@ -568,7 +571,7 @@ mod tests { fn default_address() { let seed = [0; 32]; let xsk_m = ExtendedSpendingKey::master(&seed); - let (j_m, addr_m) = xsk_m.default_address().unwrap(); + let (j_m, addr_m) = xsk_m.default_address(); assert_eq!(j_m.0, [0; 11]); assert_eq!( addr_m.diversifier().0, @@ -1065,34 +1068,31 @@ mod tests { // d0 let mut di = DiversifierIndex::new(); - match xfvk.dk.find_diversifier(di) { - Ok((l, d)) if l == di => assert_eq!(d.0, tv.d0.unwrap()), - Ok((_, _)) => assert!(tv.d0.is_none()), - Err(()) => panic!(), + match xfvk.dk.find_diversifier(di).unwrap() { + (l, d) if l == di => assert_eq!(d.0, tv.d0.unwrap()), + (_, _) => assert!(tv.d0.is_none()), } // d1 di.increment().unwrap(); - match xfvk.dk.find_diversifier(di) { - Ok((l, d)) if l == di => assert_eq!(d.0, tv.d1.unwrap()), - Ok((_, _)) => assert!(tv.d1.is_none()), - Err(()) => panic!(), + match xfvk.dk.find_diversifier(di).unwrap() { + (l, d) if l == di => assert_eq!(d.0, tv.d1.unwrap()), + (_, _) => assert!(tv.d1.is_none()), } // d2 di.increment().unwrap(); - match xfvk.dk.find_diversifier(di) { - Ok((l, d)) if l == di => assert_eq!(d.0, tv.d2.unwrap()), - Ok((_, _)) => assert!(tv.d2.is_none()), - Err(()) => panic!(), + match xfvk.dk.find_diversifier(di).unwrap() { + (l, d) if l == di => assert_eq!(d.0, tv.d2.unwrap()), + (_, _) => assert!(tv.d2.is_none()), } // dmax let dmax = DiversifierIndex([0xff; 11]); match xfvk.dk.find_diversifier(dmax) { - Ok((l, d)) if l == dmax => assert_eq!(d.0, tv.dmax.unwrap()), - Ok((_, _)) => panic!(), - Err(_) => assert!(tv.dmax.is_none()), + Some((l, d)) if l == dmax => assert_eq!(d.0, tv.dmax.unwrap()), + Some((_, _)) => panic!(), + None => assert!(tv.dmax.is_none()), } } }