Skip to content

Commit 0b810a4

Browse files
Merge remote-tracking branch 'origin/v0.42-dev' into merge/v0.42-dev-into-per-wallet-filter-scan-v2
2 parents a8e381a + da28aca commit 0b810a4

1 file changed

Lines changed: 68 additions & 0 deletions

File tree

key-wallet-manager/src/accessors.rs

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,44 @@ impl<T: WalletInfoInterface + Send + Sync + 'static> WalletManager<T> {
3333
}
3434
}
3535

36+
/// Immutable wallet + mutable info — split borrow on two maps.
37+
pub fn get_wallet_and_info_mut(&mut self, wallet_id: &WalletId) -> Option<(&Wallet, &mut T)> {
38+
match (self.wallets.get(wallet_id), self.wallet_infos.get_mut(wallet_id)) {
39+
(Some(wallet), Some(info)) => Some((wallet, info)),
40+
_ => None,
41+
}
42+
}
43+
44+
/// Mutable wallet + mutable info — split borrow on two maps.
45+
///
46+
/// Used when the caller needs to mutate both the `Wallet` (e.g. to
47+
/// idempotently re-derive HD accounts via `Wallet::add_account` during
48+
/// changeset replay) and the associated info in the same scope.
49+
pub fn get_wallet_mut_and_info_mut(
50+
&mut self,
51+
wallet_id: &WalletId,
52+
) -> Option<(&mut Wallet, &mut T)> {
53+
match (self.wallets.get_mut(wallet_id), self.wallet_infos.get_mut(wallet_id)) {
54+
(Some(wallet), Some(info)) => Some((wallet, info)),
55+
_ => None,
56+
}
57+
}
58+
59+
/// Insert a pre-built wallet and info pair.
60+
///
61+
/// Errors with [`WalletError::WalletExists`] if a wallet with the same ID is
62+
/// already registered. On success bumps the structural revision.
63+
pub fn insert_wallet(&mut self, wallet: Wallet, info: T) -> Result<WalletId, WalletError> {
64+
let wallet_id = wallet.compute_wallet_id();
65+
if self.wallets.contains_key(&wallet_id) {
66+
return Err(WalletError::WalletExists(wallet_id));
67+
}
68+
self.wallets.insert(wallet_id, wallet);
69+
self.wallet_infos.insert(wallet_id, info);
70+
self.bump_structural_revision();
71+
Ok(wallet_id)
72+
}
73+
3674
/// Remove a wallet
3775
pub fn remove_wallet(&mut self, wallet_id: &WalletId) -> Result<(Wallet, T), WalletError> {
3876
let wallet =
@@ -192,3 +230,33 @@ impl<T: WalletInfoInterface + Send + Sync + 'static> WalletManager<T> {
192230
outpoints
193231
}
194232
}
233+
234+
#[cfg(test)]
235+
mod tests {
236+
use super::*;
237+
use crate::test_helpers::TEST_MNEMONIC;
238+
use key_wallet::mnemonic::{Language, Mnemonic};
239+
use key_wallet::wallet::initialization::WalletAccountCreationOptions;
240+
use key_wallet::wallet::managed_wallet_info::ManagedWalletInfo;
241+
242+
fn build_wallet() -> Wallet {
243+
let mnemonic = Mnemonic::from_phrase(TEST_MNEMONIC, Language::English).unwrap();
244+
Wallet::from_mnemonic(mnemonic, Network::Testnet, WalletAccountCreationOptions::Default)
245+
.expect("wallet from mnemonic")
246+
}
247+
248+
#[test]
249+
fn insert_wallet_rejects_duplicate() {
250+
let mut manager: WalletManager<ManagedWalletInfo> = WalletManager::new(Network::Testnet);
251+
let wallet = build_wallet();
252+
let info = ManagedWalletInfo::from_wallet(&wallet);
253+
254+
let id =
255+
manager.insert_wallet(wallet.clone(), info.clone()).expect("first insert succeeds");
256+
257+
match manager.insert_wallet(wallet, info) {
258+
Err(WalletError::WalletExists(dup_id)) => assert_eq!(dup_id, id),
259+
other => panic!("expected WalletExists, got {:?}", other),
260+
}
261+
}
262+
}

0 commit comments

Comments
 (0)