Skip to content

Commit 829eab3

Browse files
committed
f Update fees upon sync, rather than every request
1 parent 74d64ac commit 829eab3

File tree

1 file changed

+45
-36
lines changed

1 file changed

+45
-36
lines changed

src/wallet.rs

+45-36
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ where
3838
// A BDK on-chain wallet.
3939
inner: Mutex<bdk::Wallet<D>>,
4040
// A cache storing the most recently retrieved fee rate estimations.
41-
fee_rate_cache: Mutex<HashMap<ConfirmationTarget, FeeRate>>,
41+
fee_rate_cache: RwLock<HashMap<ConfirmationTarget, FeeRate>>,
4242
tokio_runtime: RwLock<Option<Arc<tokio::runtime::Runtime>>>,
4343
logger: Arc<FilesystemLogger>,
4444
}
@@ -51,18 +51,26 @@ where
5151
blockchain: EsploraBlockchain, wallet: bdk::Wallet<D>, logger: Arc<FilesystemLogger>,
5252
) -> Self {
5353
let inner = Mutex::new(wallet);
54-
let fee_rate_cache = Mutex::new(HashMap::new());
54+
let fee_rate_cache = RwLock::new(HashMap::new());
5555
let tokio_runtime = RwLock::new(None);
5656
Self { blockchain, inner, fee_rate_cache, tokio_runtime, logger }
5757
}
5858

5959
pub(crate) async fn sync(&self) -> Result<(), Error> {
60+
match self.update_fee_estimates().await {
61+
Ok(()) => (),
62+
Err(e) => {
63+
log_error!(self.logger, "Fee estimation error: {}", e);
64+
return Err(e);
65+
}
66+
}
67+
6068
let sync_options = SyncOptions { progress: None };
6169
match self.inner.lock().unwrap().sync(&self.blockchain, sync_options).await {
6270
Ok(()) => Ok(()),
6371
Err(e) => {
6472
log_error!(self.logger, "Wallet sync error: {}", e);
65-
Err(e)?
73+
Err(From::from(e))
6674
}
6775
}
6876
}
@@ -75,6 +83,36 @@ where
7583
*self.tokio_runtime.write().unwrap() = None;
7684
}
7785

86+
pub(crate) async fn update_fee_estimates(&self) -> Result<(), Error> {
87+
let mut locked_fee_rate_cache = self.fee_rate_cache.write().unwrap();
88+
89+
let confirmation_targets = vec![
90+
ConfirmationTarget::Background,
91+
ConfirmationTarget::Normal,
92+
ConfirmationTarget::HighPriority,
93+
];
94+
for target in confirmation_targets {
95+
let num_blocks = num_blocks_from_conf_target(target);
96+
97+
let est_fee_rate = self.blockchain.estimate_fee(num_blocks).await;
98+
99+
match est_fee_rate {
100+
Ok(rate) => {
101+
locked_fee_rate_cache.insert(target, rate);
102+
log_trace!(
103+
self.logger,
104+
"Fee rate estimation updated: {} sats/kwu",
105+
rate.fee_wu(1000)
106+
);
107+
}
108+
Err(e) => {
109+
log_error!(self.logger, "Failed to update fee rate estimation: {}", e);
110+
}
111+
}
112+
}
113+
Ok(())
114+
}
115+
78116
pub(crate) fn create_funding_transaction(
79117
&self, output_script: &Script, value_sats: u64, confirmation_target: ConfirmationTarget,
80118
) -> Result<Transaction, Error> {
@@ -123,41 +161,12 @@ where
123161
}
124162

125163
fn estimate_fee_rate(&self, confirmation_target: ConfirmationTarget) -> FeeRate {
126-
let mut locked_fee_rate_cache = self.fee_rate_cache.lock().unwrap();
127-
let num_blocks = num_blocks_from_conf_target(confirmation_target);
164+
let locked_fee_rate_cache = self.fee_rate_cache.read().unwrap();
128165

129166
// We'll fall back on this, if we really don't have any other information.
130167
let fallback_rate = fallback_fee_from_conf_target(confirmation_target);
131168

132-
let locked_runtime = self.tokio_runtime.read().unwrap();
133-
if locked_runtime.as_ref().is_none() {
134-
log_error!(self.logger, "Failed to update fee rate estimation: No runtime.");
135-
unreachable!("Failed to broadcast transaction: No runtime.");
136-
}
137-
138-
let est_fee_rate = tokio::task::block_in_place(move || {
139-
locked_runtime
140-
.as_ref()
141-
.unwrap()
142-
.handle()
143-
.block_on(async move { self.blockchain.estimate_fee(num_blocks).await })
144-
});
145-
146-
match est_fee_rate {
147-
Ok(rate) => {
148-
locked_fee_rate_cache.insert(confirmation_target, rate);
149-
log_trace!(
150-
self.logger,
151-
"Fee rate estimation updated: {} sats/kwu",
152-
rate.fee_wu(1000)
153-
);
154-
rate
155-
}
156-
Err(e) => {
157-
log_error!(self.logger, "Failed to update fee rate estimation: {}", e);
158-
*locked_fee_rate_cache.get(&confirmation_target).unwrap_or(&fallback_rate)
159-
}
160-
}
169+
*locked_fee_rate_cache.get(&confirmation_target).unwrap_or(&fallback_rate)
161170
}
162171
}
163172

@@ -335,8 +344,8 @@ where
335344
self.wallet.get_new_address().expect("Failed to retrieve new address from wallet.");
336345
match address.payload {
337346
bitcoin::util::address::Payload::WitnessProgram { version, program } => {
338-
return ShutdownScript::new_witness_program(version, &program)
339-
.expect("Invalid shutdown script.");
347+
ShutdownScript::new_witness_program(version, &program)
348+
.expect("Invalid shutdown script.")
340349
}
341350
_ => panic!("Tried to use a non-witness address. This must not ever happen."),
342351
}

0 commit comments

Comments
 (0)