diff --git a/Cargo.toml b/Cargo.toml index b4ed0c7..c4feea7 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -2,7 +2,7 @@ name = "ghost-eye" authors = ["str3tch "] description = "Application for interacting with Casper/Ghost nodes that are exposing RPC only to the localhost" -version = "0.3.44" +version = "0.3.45" edition = "2021" homepage = "https://git.ghostchain.io/ghostchain" repository = "https://git.ghostchain.io/ghostchain/ghost-eye" diff --git a/src/action.rs b/src/action.rs index 7d886f3..80e29e6 100644 --- a/src/action.rs +++ b/src/action.rs @@ -5,8 +5,7 @@ use subxt::utils::H256; use subxt::config::substrate::DigestItem; use crate::types::{ - ActionLevel, ActionTarget, CasperExtrinsicDetails, EraInfo, EraRewardPoints, - Nominator, PeerInformation, SessionKeyInfo, SystemAccount, + ActionLevel, ActionTarget, CasperExtrinsicDetails, EraInfo, EraRewardPoints, Nominator, PeerInformation, SessionKeyInfo, UnlockChunk, SystemAccount }; #[derive(Debug, Clone, PartialEq, Eq, Display, Serialize, Deserialize)] @@ -118,7 +117,6 @@ pub enum Action { SetStashSecret([u8; 32]), SetChoosenValidator([u8; 32], u32, u32), SetSlashingSpansLength(usize, [u8; 32]), - SetUnlockingIsEmpty(bool, [u8; 32]), BestBlockInformation(H256, u32), FinalizedBlockInformation(H256, u32), @@ -135,7 +133,7 @@ pub enum Action { SetValidatorEraReward(u32, u128), SetValidatorEraClaimed(u32, bool), SetValidatorEraSlash(u32, u128), - SetValidatorEraUnlocking(u32, u128, [u8; 32]), + SetValidatorEraUnlocking(Vec, [u8; 32]), SetValidatorLatestClaim(u32, [u8; 32]), SetValidatorInSession(bool, [u8; 32]), SetIsBonded(bool, [u8; 32]), diff --git a/src/components/validator/withdraw_popup.rs b/src/components/validator/withdraw_popup.rs index 40dab5c..cc34e4b 100644 --- a/src/components/validator/withdraw_popup.rs +++ b/src/components/validator/withdraw_popup.rs @@ -59,17 +59,18 @@ impl WithdrawPopup { fn proceed(&mut self) { if let Some(network_tx) = &self.network_tx { let spans_needed = if self.stash_should_be_killed() { + if let Some(action_tx) = &self.action_tx { + let _ = action_tx.send(Action::EventLog( + "Current stash account will be killed during this transaction".to_string(), + ActionLevel::Warn, + ActionTarget::ValidatorLog)); + } self.slashing_spans_length } else { 0 }; - let _ = network_tx.send(Action::WithdrawUnbondedFrom( - self.secret_seed, spans_needed)); + let _ = network_tx.send(Action::WithdrawUnbondedFrom(self.secret_seed, spans_needed)); if let Some(action_tx) = &self.action_tx { - let _ = action_tx.send(Action::EventLog( - "Current stash account will be killed during this transaction".to_string(), - ActionLevel::Warn, - ActionTarget::ValidatorLog)); let _ = action_tx.send(Action::ClosePopup); } } @@ -127,8 +128,8 @@ impl Component for WithdrawPopup { self.slashing_spans_length = length as u32, Action::SetStakedAmountRatio(_, active_balance, account_id) if self.stash_account == account_id => self.active_balance = active_balance.unwrap_or_default(), - Action::SetUnlockingIsEmpty(is_empty, account_id) if self.stash_account == account_id => - self.unlocking_is_empty = is_empty, + Action::SetValidatorEraUnlocking(unlockings, account_id) if self.stash_account == account_id => + self.unlocking_is_empty = unlockings.is_empty(), _ => {} }; Ok(None) diff --git a/src/components/validator/withdrawals.rs b/src/components/validator/withdrawals.rs index 95ef457..b719ff3 100644 --- a/src/components/validator/withdrawals.rs +++ b/src/components/validator/withdrawals.rs @@ -1,5 +1,3 @@ -use std::collections::BTreeMap; - use color_eyre::Result; use crossterm::event::{KeyCode, KeyEvent}; use ratatui::layout::{Constraint, Margin}; @@ -15,6 +13,7 @@ use ratatui::{ }; use super::{PartialComponent, Component, CurrentTab}; +use crate::types::UnlockChunk; use crate::{ action::Action, config::Config, @@ -26,7 +25,7 @@ pub struct Withdrawals { palette: StylePalette, scroll_state: ScrollbarState, table_state: TableState, - unlockings: BTreeMap, + unlockings: Vec, stash_account: [u8; 32], current_era: u32, } @@ -47,7 +46,7 @@ impl Withdrawals { scroll_state: ScrollbarState::new(0), table_state: TableState::new(), palette: StylePalette::default(), - unlockings: BTreeMap::new(), + unlockings: Vec::new(), stash_account: [0u8; 32], current_era: 0, } @@ -98,14 +97,21 @@ impl Withdrawals { self.scroll_state = self.scroll_state.position(i); } - fn add_new_unlocking(&mut self, era_index: u32, unlocking: u128) { - match self.unlockings.get_mut(&era_index) { - Some(unlck) => *unlck = unlocking, - None => { - let _ = self.unlockings.insert(era_index, unlocking); - }, + fn add_new_unlocking(&mut self, unlockings: Vec) { + let mut updated_unlockings = Vec::new(); + for chunk in unlockings { + if chunk.era > self.current_era { + updated_unlockings.push(chunk); + } else { + match updated_unlockings.get_mut(0) { + Some(stored_chunk) => (*stored_chunk).value += chunk.value, + None => updated_unlockings.push(chunk), + } + } } - self.scroll_state = self.scroll_state.content_length(self.unlockings.len()); + self.unlockings = updated_unlockings; + self.scroll_state = self.scroll_state + .content_length(self.unlockings.len()); } fn prepare_u128(&self, value: u128) -> String { @@ -155,8 +161,8 @@ impl Component for Withdrawals { match action { Action::SetStashAccount(account_id) => self.stash_account = account_id, Action::SetActiveEra(era_info) => self.current_era = era_info.index, - Action::SetValidatorEraUnlocking(era_index, unlocking, account_id) if self.stash_account == account_id => - self.add_new_unlocking(era_index, unlocking), + Action::SetValidatorEraUnlocking(unlockings, account_id) if self.stash_account == account_id => + self.add_new_unlocking(unlockings), _ => {} }; Ok(None) @@ -181,11 +187,11 @@ impl Component for Withdrawals { let table = Table::new( self.unlockings .iter() - .map(|(key, value)| { - let mut est_era_text = Text::from(self.estimate_time(*key)).alignment(Alignment::Center); - let mut value_text = Text::from(self.prepare_u128(*value)).alignment(Alignment::Right); + .map(|unlock| { + let mut est_era_text = Text::from(self.estimate_time(unlock.era)).alignment(Alignment::Center); + let mut value_text = Text::from(self.prepare_u128(unlock.value)).alignment(Alignment::Right); - if *key > self.current_era { + if unlock.era > self.current_era { est_era_text = est_era_text.add_modifier(Modifier::CROSSED_OUT); value_text = value_text.add_modifier(Modifier::CROSSED_OUT); } diff --git a/src/network/predefined_calls.rs b/src/network/predefined_calls.rs index b5f11b4..895e50b 100644 --- a/src/network/predefined_calls.rs +++ b/src/network/predefined_calls.rs @@ -14,7 +14,7 @@ use subxt::{ use crate::{ action::Action, casper_network::runtime_types::sp_consensus_slots, - types::{EraInfo, EraRewardPoints, Nominator, SessionKeyInfo, SystemAccount}, + types::{EraInfo, EraRewardPoints, Nominator, SessionKeyInfo, UnlockChunk, SystemAccount}, CasperAccountId, CasperConfig }; @@ -432,15 +432,16 @@ pub async fn get_validators_ledger( match maybe_ledger { Some(ledger) => { + let chunks = ledger.unlocking.0 + .iter() + .map(|chunk| UnlockChunk { value: chunk.value, era: chunk.era }) + .collect::>(); action_tx.send(Action::SetStakedAmountRatio(Some(ledger.total), Some(ledger.active), *account_id))?; - action_tx.send(Action::SetUnlockingIsEmpty(ledger.unlocking.0.is_empty(), *account_id))?; - for chunk in ledger.unlocking.0.iter() { - action_tx.send(Action::SetValidatorEraUnlocking(chunk.era, chunk.value, *account_id))?; - } + action_tx.send(Action::SetValidatorEraUnlocking(chunks, *account_id))?; }, None => { action_tx.send(Action::SetStakedAmountRatio(None, None, *account_id))?; - action_tx.send(Action::SetUnlockingIsEmpty(true, *account_id))?; + action_tx.send(Action::SetValidatorEraUnlocking(Vec::new(), *account_id))?; } } diff --git a/src/types/mod.rs b/src/types/mod.rs index bc65171..64fc7ad 100644 --- a/src/types/mod.rs +++ b/src/types/mod.rs @@ -5,6 +5,7 @@ mod account; mod peer; mod session; mod nominator; +mod staking; pub use extrinsics::CasperExtrinsicDetails; pub use era::{EraRewardPoints, EraInfo}; @@ -14,3 +15,4 @@ pub use account::SystemAccount; pub use peer::PeerInformation; pub use session::SessionKeyInfo; pub use nominator::Nominator; +pub use staking::UnlockChunk; diff --git a/src/types/staking.rs b/src/types/staking.rs new file mode 100644 index 0000000..5ab423e --- /dev/null +++ b/src/types/staking.rs @@ -0,0 +1,8 @@ +use codec::Decode; +use serde::{Serialize, Deserialize}; + +#[derive(Debug, Default, Clone, PartialEq, Eq, Serialize, Deserialize, Decode)] +pub struct UnlockChunk { + pub value: u128, + pub era: u32, +}