diff --git a/src/action.rs b/src/action.rs index 052d389..6c4eeaa 100644 --- a/src/action.rs +++ b/src/action.rs @@ -35,7 +35,7 @@ pub enum Action { ClosePopup, RotateSessionKeys, - PayoutValidatorPopup(u32, bool), + PayoutValidatorPopup(u32), WithdrawValidatorPopup, BalanceRequest([u8; 32], bool), diff --git a/src/components/validator/history.rs b/src/components/validator/history.rs index 9d6e2ad..ab51c9f 100644 --- a/src/components/validator/history.rs +++ b/src/components/validator/history.rs @@ -1,4 +1,4 @@ -use std::collections::BTreeMap; +use std::collections::{HashSet, BTreeMap}; use std::sync::mpsc::Sender; use color_eyre::Result; @@ -18,6 +18,7 @@ use ratatui::{ use tokio::sync::mpsc::UnboundedSender; use super::{PartialComponent, Component, CurrentTab}; +use crate::types::{ActionLevel, ActionTarget}; use crate::{ action::Action, config::Config, @@ -38,6 +39,7 @@ pub struct History { scroll_state: ScrollbarState, table_state: TableState, rewards: BTreeMap, + pending_payout: HashSet, } impl Default for History { @@ -57,7 +59,8 @@ impl History { action_tx: None, scroll_state: ScrollbarState::new(0), table_state: TableState::new(), - rewards: BTreeMap::new(), + rewards: Default::default(), + pending_payout: Default::default(), palette: StylePalette::default(), } } @@ -73,8 +76,22 @@ impl History { .get(&era_index) .map(|x| x.is_claimed) .expect("BTreeMap of rewards is indexed; qed"); + if let Some(action_tx) = &self.action_tx { - let _ = action_tx.send(Action::PayoutValidatorPopup(*era_index, is_claimed)); + let _ = match (is_claimed, self.pending_payout.contains(era_index)) { + (false, false) => { + self.pending_payout.insert(*era_index); + action_tx.send(Action::PayoutValidatorPopup(*era_index)) + } + (false, true) => action_tx.send(Action::EventLog( + format!("payout for era #{} is in-flight already", era_index), + ActionLevel::Warn, + ActionTarget::ValidatorLog)), + (true, _) => action_tx.send(Action::EventLog( + format!("staking rewards for era index #{} already claimed", era_index), + ActionLevel::Warn, + ActionTarget::ValidatorLog)), + }; } } } @@ -143,6 +160,7 @@ impl History { match self.rewards.get_mut(&era_index) { Some(reward_item) => { if reward_item.is_claimed == false && is_claimed == true { + self.pending_payout.remove(&era_index); if let Some(network_tx) = &self.network_tx { let _ = network_tx.send(Action::RemoveEraToWatch(era_index)); } @@ -183,10 +201,7 @@ impl PartialComponent for History { fn set_active(&mut self, current_tab: CurrentTab) { match current_tab { CurrentTab::History => self.is_active = true, - _ => { - self.table_state.select(None); - self.is_active = false; - } + _ => self.is_active = false, } } } @@ -263,6 +278,12 @@ impl Component for History { Cell::from(reward_text), ]).style(self.palette.create_highlight_style()) } else { + if self.pending_payout.contains(key) { + era_index_text = era_index_text.add_modifier(Modifier::SLOW_BLINK); + slash_text = slash_text.add_modifier(Modifier::SLOW_BLINK); + reward_text = reward_text.add_modifier(Modifier::SLOW_BLINK); + } + Row::new(vec![ Cell::from(era_index_text), Cell::from(slash_text), diff --git a/src/components/validator/mod.rs b/src/components/validator/mod.rs index 1fd055e..1cafd43 100644 --- a/src/components/validator/mod.rs +++ b/src/components/validator/mod.rs @@ -240,7 +240,7 @@ impl Component for Validator { self.previous_tab = CurrentTab::NominatorsByValidator; self.current_tab = CurrentTab::NominatorsByValidator; } - Action::PayoutValidatorPopup(_, _) => { + Action::PayoutValidatorPopup(_) => { self.previous_tab = self.current_tab; self.current_tab = CurrentTab::PayoutPopup; } diff --git a/src/components/validator/payout_popup.rs b/src/components/validator/payout_popup.rs index 5d1d561..4ff301e 100644 --- a/src/components/validator/payout_popup.rs +++ b/src/components/validator/payout_popup.rs @@ -13,7 +13,6 @@ use crate::{ action::Action, config::Config, palette::StylePalette, - types::{ActionLevel, ActionTarget}, }; #[derive(Debug)] @@ -24,7 +23,6 @@ pub struct PayoutPopup { secret_seed: [u8; 32], stash_account_id: [u8; 32], era_index: u32, - is_claimed: bool, palette: StylePalette } @@ -41,18 +39,12 @@ impl PayoutPopup { secret_seed: [0u8; 32], stash_account_id: [0u8; 32], era_index: 0u32, - is_claimed: false, action_tx: None, network_tx: None, palette: StylePalette::default(), } } - fn store_era_to_claim(&mut self, era_index: u32, is_claimed: bool) { - self.is_claimed = is_claimed; - self.era_index = era_index; - } - fn close_popup(&mut self) { self.is_active = false; if let Some(action_tx) = &self.action_tx { @@ -61,20 +53,11 @@ impl PayoutPopup { } fn start_payout(&mut self) { - if self.is_claimed { - if let Some(action_tx) = &self.action_tx { - let _ = action_tx.send(Action::EventLog( - format!("staking rewards for era index #{} already claimed", self.era_index), - ActionLevel::Warn, - ActionTarget::ValidatorLog)); - } - } else { - if let Some(network_tx) = &self.network_tx { - let _ = network_tx.send(Action::PayoutStakers( - self.secret_seed, - self.stash_account_id, - self.era_index)); - } + if let Some(network_tx) = &self.network_tx { + let _ = network_tx.send(Action::PayoutStakers( + self.secret_seed, + self.stash_account_id, + self.era_index)); } if let Some(action_tx) = &self.action_tx { let _ = action_tx.send(Action::ClosePopup); @@ -126,8 +109,7 @@ impl Component for PayoutPopup { fn update(&mut self, action: Action) -> Result> { match action { - Action::PayoutValidatorPopup(era_index, is_claimed) => - self.store_era_to_claim(era_index, is_claimed), + Action::PayoutValidatorPopup(era_index) => self.era_index = era_index, Action::SetStashSecret(secret_seed) => self.secret_seed = secret_seed, Action::SetStashAccount(account_id) => self.stash_account_id = account_id, _ => {}