fix for withdrawals table, many thanks to @neptune

Signed-off-by: Uncle Stretch <uncle.stretch@ghostchain.io>
This commit is contained in:
Uncle Stretch 2025-02-26 15:43:03 +03:00
parent de1732372e
commit 48eb85efa3
Signed by: str3tch
GPG Key ID: 84F3190747EE79AA
7 changed files with 52 additions and 36 deletions

View File

@ -2,7 +2,7 @@
name = "ghost-eye" name = "ghost-eye"
authors = ["str3tch <stretch@ghostchain.io>"] authors = ["str3tch <stretch@ghostchain.io>"]
description = "Application for interacting with Casper/Ghost nodes that are exposing RPC only to the localhost" 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" edition = "2021"
homepage = "https://git.ghostchain.io/ghostchain" homepage = "https://git.ghostchain.io/ghostchain"
repository = "https://git.ghostchain.io/ghostchain/ghost-eye" repository = "https://git.ghostchain.io/ghostchain/ghost-eye"

View File

@ -5,8 +5,7 @@ use subxt::utils::H256;
use subxt::config::substrate::DigestItem; use subxt::config::substrate::DigestItem;
use crate::types::{ use crate::types::{
ActionLevel, ActionTarget, CasperExtrinsicDetails, EraInfo, EraRewardPoints, ActionLevel, ActionTarget, CasperExtrinsicDetails, EraInfo, EraRewardPoints, Nominator, PeerInformation, SessionKeyInfo, UnlockChunk, SystemAccount
Nominator, PeerInformation, SessionKeyInfo, SystemAccount,
}; };
#[derive(Debug, Clone, PartialEq, Eq, Display, Serialize, Deserialize)] #[derive(Debug, Clone, PartialEq, Eq, Display, Serialize, Deserialize)]
@ -118,7 +117,6 @@ pub enum Action {
SetStashSecret([u8; 32]), SetStashSecret([u8; 32]),
SetChoosenValidator([u8; 32], u32, u32), SetChoosenValidator([u8; 32], u32, u32),
SetSlashingSpansLength(usize, [u8; 32]), SetSlashingSpansLength(usize, [u8; 32]),
SetUnlockingIsEmpty(bool, [u8; 32]),
BestBlockInformation(H256, u32), BestBlockInformation(H256, u32),
FinalizedBlockInformation(H256, u32), FinalizedBlockInformation(H256, u32),
@ -135,7 +133,7 @@ pub enum Action {
SetValidatorEraReward(u32, u128), SetValidatorEraReward(u32, u128),
SetValidatorEraClaimed(u32, bool), SetValidatorEraClaimed(u32, bool),
SetValidatorEraSlash(u32, u128), SetValidatorEraSlash(u32, u128),
SetValidatorEraUnlocking(u32, u128, [u8; 32]), SetValidatorEraUnlocking(Vec<UnlockChunk>, [u8; 32]),
SetValidatorLatestClaim(u32, [u8; 32]), SetValidatorLatestClaim(u32, [u8; 32]),
SetValidatorInSession(bool, [u8; 32]), SetValidatorInSession(bool, [u8; 32]),
SetIsBonded(bool, [u8; 32]), SetIsBonded(bool, [u8; 32]),

View File

@ -59,17 +59,18 @@ impl WithdrawPopup {
fn proceed(&mut self) { fn proceed(&mut self) {
if let Some(network_tx) = &self.network_tx { if let Some(network_tx) = &self.network_tx {
let spans_needed = if self.stash_should_be_killed() { let spans_needed = if self.stash_should_be_killed() {
self.slashing_spans_length
} else {
0
};
let _ = network_tx.send(Action::WithdrawUnbondedFrom(
self.secret_seed, spans_needed));
if let Some(action_tx) = &self.action_tx { if let Some(action_tx) = &self.action_tx {
let _ = action_tx.send(Action::EventLog( let _ = action_tx.send(Action::EventLog(
"Current stash account will be killed during this transaction".to_string(), "Current stash account will be killed during this transaction".to_string(),
ActionLevel::Warn, ActionLevel::Warn,
ActionTarget::ValidatorLog)); ActionTarget::ValidatorLog));
}
self.slashing_spans_length
} else {
0
};
let _ = network_tx.send(Action::WithdrawUnbondedFrom(self.secret_seed, spans_needed));
if let Some(action_tx) = &self.action_tx {
let _ = action_tx.send(Action::ClosePopup); let _ = action_tx.send(Action::ClosePopup);
} }
} }
@ -127,8 +128,8 @@ impl Component for WithdrawPopup {
self.slashing_spans_length = length as u32, self.slashing_spans_length = length as u32,
Action::SetStakedAmountRatio(_, active_balance, account_id) if self.stash_account == account_id => Action::SetStakedAmountRatio(_, active_balance, account_id) if self.stash_account == account_id =>
self.active_balance = active_balance.unwrap_or_default(), self.active_balance = active_balance.unwrap_or_default(),
Action::SetUnlockingIsEmpty(is_empty, account_id) if self.stash_account == account_id => Action::SetValidatorEraUnlocking(unlockings, account_id) if self.stash_account == account_id =>
self.unlocking_is_empty = is_empty, self.unlocking_is_empty = unlockings.is_empty(),
_ => {} _ => {}
}; };
Ok(None) Ok(None)

View File

@ -1,5 +1,3 @@
use std::collections::BTreeMap;
use color_eyre::Result; use color_eyre::Result;
use crossterm::event::{KeyCode, KeyEvent}; use crossterm::event::{KeyCode, KeyEvent};
use ratatui::layout::{Constraint, Margin}; use ratatui::layout::{Constraint, Margin};
@ -15,6 +13,7 @@ use ratatui::{
}; };
use super::{PartialComponent, Component, CurrentTab}; use super::{PartialComponent, Component, CurrentTab};
use crate::types::UnlockChunk;
use crate::{ use crate::{
action::Action, action::Action,
config::Config, config::Config,
@ -26,7 +25,7 @@ pub struct Withdrawals {
palette: StylePalette, palette: StylePalette,
scroll_state: ScrollbarState, scroll_state: ScrollbarState,
table_state: TableState, table_state: TableState,
unlockings: BTreeMap<u32, u128>, unlockings: Vec<UnlockChunk>,
stash_account: [u8; 32], stash_account: [u8; 32],
current_era: u32, current_era: u32,
} }
@ -47,7 +46,7 @@ impl Withdrawals {
scroll_state: ScrollbarState::new(0), scroll_state: ScrollbarState::new(0),
table_state: TableState::new(), table_state: TableState::new(),
palette: StylePalette::default(), palette: StylePalette::default(),
unlockings: BTreeMap::new(), unlockings: Vec::new(),
stash_account: [0u8; 32], stash_account: [0u8; 32],
current_era: 0, current_era: 0,
} }
@ -98,14 +97,21 @@ impl Withdrawals {
self.scroll_state = self.scroll_state.position(i); self.scroll_state = self.scroll_state.position(i);
} }
fn add_new_unlocking(&mut self, era_index: u32, unlocking: u128) { fn add_new_unlocking(&mut self, unlockings: Vec<UnlockChunk>) {
match self.unlockings.get_mut(&era_index) { let mut updated_unlockings = Vec::new();
Some(unlck) => *unlck = unlocking, for chunk in unlockings {
None => { if chunk.era > self.current_era {
let _ = self.unlockings.insert(era_index, unlocking); 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 { fn prepare_u128(&self, value: u128) -> String {
@ -155,8 +161,8 @@ impl Component for Withdrawals {
match action { match action {
Action::SetStashAccount(account_id) => self.stash_account = account_id, Action::SetStashAccount(account_id) => self.stash_account = account_id,
Action::SetActiveEra(era_info) => self.current_era = era_info.index, Action::SetActiveEra(era_info) => self.current_era = era_info.index,
Action::SetValidatorEraUnlocking(era_index, unlocking, account_id) if self.stash_account == account_id => Action::SetValidatorEraUnlocking(unlockings, account_id) if self.stash_account == account_id =>
self.add_new_unlocking(era_index, unlocking), self.add_new_unlocking(unlockings),
_ => {} _ => {}
}; };
Ok(None) Ok(None)
@ -181,11 +187,11 @@ impl Component for Withdrawals {
let table = Table::new( let table = Table::new(
self.unlockings self.unlockings
.iter() .iter()
.map(|(key, value)| { .map(|unlock| {
let mut est_era_text = Text::from(self.estimate_time(*key)).alignment(Alignment::Center); let mut est_era_text = Text::from(self.estimate_time(unlock.era)).alignment(Alignment::Center);
let mut value_text = Text::from(self.prepare_u128(*value)).alignment(Alignment::Right); 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); est_era_text = est_era_text.add_modifier(Modifier::CROSSED_OUT);
value_text = value_text.add_modifier(Modifier::CROSSED_OUT); value_text = value_text.add_modifier(Modifier::CROSSED_OUT);
} }

View File

@ -14,7 +14,7 @@ use subxt::{
use crate::{ use crate::{
action::Action, action::Action,
casper_network::runtime_types::sp_consensus_slots, casper_network::runtime_types::sp_consensus_slots,
types::{EraInfo, EraRewardPoints, Nominator, SessionKeyInfo, SystemAccount}, types::{EraInfo, EraRewardPoints, Nominator, SessionKeyInfo, UnlockChunk, SystemAccount},
CasperAccountId, CasperConfig CasperAccountId, CasperConfig
}; };
@ -432,15 +432,16 @@ pub async fn get_validators_ledger(
match maybe_ledger { match maybe_ledger {
Some(ledger) => { Some(ledger) => {
let chunks = ledger.unlocking.0
.iter()
.map(|chunk| UnlockChunk { value: chunk.value, era: chunk.era })
.collect::<Vec<_>>();
action_tx.send(Action::SetStakedAmountRatio(Some(ledger.total), Some(ledger.active), *account_id))?; 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))?; action_tx.send(Action::SetValidatorEraUnlocking(chunks, *account_id))?;
for chunk in ledger.unlocking.0.iter() {
action_tx.send(Action::SetValidatorEraUnlocking(chunk.era, chunk.value, *account_id))?;
}
}, },
None => { None => {
action_tx.send(Action::SetStakedAmountRatio(None, None, *account_id))?; 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))?;
} }
} }

View File

@ -5,6 +5,7 @@ mod account;
mod peer; mod peer;
mod session; mod session;
mod nominator; mod nominator;
mod staking;
pub use extrinsics::CasperExtrinsicDetails; pub use extrinsics::CasperExtrinsicDetails;
pub use era::{EraRewardPoints, EraInfo}; pub use era::{EraRewardPoints, EraInfo};
@ -14,3 +15,4 @@ pub use account::SystemAccount;
pub use peer::PeerInformation; pub use peer::PeerInformation;
pub use session::SessionKeyInfo; pub use session::SessionKeyInfo;
pub use nominator::Nominator; pub use nominator::Nominator;
pub use staking::UnlockChunk;

8
src/types/staking.rs Normal file
View File

@ -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,
}