fix: load tip height directly rather than from cache

This ensures the coins are sorted according to the latest
tip height in case the cache has not been recently refreshed.
This commit is contained in:
Michael Mallan 2025-04-22 14:53:26 +01:00
parent 0d9cf43bf9
commit c2f964d5b3
No known key found for this signature in database
GPG Key ID: 5177CDCEDB0EABEB
3 changed files with 20 additions and 10 deletions

View File

@ -27,6 +27,8 @@ pub enum Message {
Info(Result<GetInfoResult, Error>),
ReceiveAddress(Result<(Address, ChildNumber), Error>),
Coins(Result<Vec<Coin>, Error>),
/// When we want both coins and tip height together.
CoinsTipHeight(Result<Vec<Coin>, Error>, Result<i32, Error>),
Labels(Result<HashMap<String, String>, Error>),
SpendTxs(Result<Vec<SpendTx>, Error>),
Psbt(Result<(Psbt, Vec<String>), Error>),

View File

@ -126,13 +126,21 @@ impl State for CreateSpendPanel {
Task::batch(vec![
Task::perform(
async move {
daemon1
.list_coins(&[CoinStatus::Unconfirmed, CoinStatus::Confirmed], &[])
.await
.map(|res| res.coins)
.map_err(|e| e.into())
(
daemon1
.clone()
.list_coins(&[CoinStatus::Unconfirmed, CoinStatus::Confirmed], &[])
.await
.map(|res| res.coins)
.map_err(|e| e.into()),
daemon1
.get_info()
.await
.map(|res| res.block_height)
.map_err(|e| e.into()),
)
},
Message::Coins,
|(res_coins, res_tip)| Message::CoinsTipHeight(res_coins, res_tip),
),
Task::perform(
async move {

View File

@ -566,8 +566,8 @@ impl Step for DefineSpend {
}
Err(e) => self.warning = Some(e),
},
Message::Coins(res) => match res {
Ok(coins) => {
Message::CoinsTipHeight(res_coins, res_tip) => match (res_coins, res_tip) {
(Ok(coins), Ok(tip)) => {
let selected: HashSet<OutPoint> =
HashSet::from_iter(self.coins.iter().filter_map(|(c, selected)| {
if *selected {
@ -577,14 +577,14 @@ impl Step for DefineSpend {
}
}));
self.coins = filter_coins(&coins, Some(selected));
self.sort_coins(cache.blockheight as u32);
self.sort_coins(tip as u32);
// In case some selected coins are not spendable anymore and
// new coins make more sense to be selected. A redraft is triggered
// if all forms are valid (checked in the redraft method)
self.redraft(daemon);
self.check_valid();
}
Err(e) => self.warning = Some(e),
(Err(e), _) | (Ok(_), Err(e)) => self.warning = Some(e),
},
_ => {}
};