From 5db96fa8f197c6cf0da2d12b29e495259e516753 Mon Sep 17 00:00:00 2001 From: Uncle Stretch Date: Mon, 29 Sep 2025 17:27:01 +0300 Subject: [PATCH] fix for the slashing spans calculation during withdrawals Signed-off-by: Uncle Stretch --- Cargo.toml | 2 +- src/network/predefined_calls.rs | 18 ++++++++++++++++-- src/types/mod.rs | 1 + src/types/staking.rs | 7 +++++++ 4 files changed, 25 insertions(+), 3 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 67b989d..3b4630f 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.68" +version = "0.3.69" edition = "2021" homepage = "https://git.ghostchain.io/ghostchain" repository = "https://git.ghostchain.io/ghostchain/ghost-eye" diff --git a/src/network/predefined_calls.rs b/src/network/predefined_calls.rs index 532b0b9..67348c6 100644 --- a/src/network/predefined_calls.rs +++ b/src/network/predefined_calls.rs @@ -4,6 +4,7 @@ use subxt::{ backend::rpc::RpcClient, client::OnlineClient, config::substrate::DigestItem, + ext::sp_runtime::Saturating, ext::sp_core::crypto::{ AccountId32, Ss58AddressFormat, Ss58Codec, }, @@ -14,7 +15,7 @@ use subxt::{ use crate::{ action::Action, casper_network::runtime_types::{ghost_networks::NetworkType, pallet_staking::RewardDestination, sp_consensus_slots}, - types::{EraInfo, EraRewardPoints, Gatekeeper, Nominations, Nominator, SessionKeyInfo, SystemAccount, UnlockChunk}, + types::{EraInfo, EraRewardPoints, Gatekeeper, Nominations, Nominator, SlashingSpan, SessionKeyInfo, SystemAccount, UnlockChunk}, CasperAccountId, CasperConfig }; @@ -592,7 +593,20 @@ pub async fn get_slashing_spans( ) -> Result<()> { let slashing_spans_length = super::raw_calls::staking::slashing_spans(api, None, account_id) .await? - .map(|spans| spans.prior.len()) + .map(|spans| { + let mut last_start = spans.last_start; + let mut index = spans.span_index; + let last = SlashingSpan { index, start: last_start, length: None }; + let prior = spans.prior.iter().cloned().map(move |length| { + let start = last_start.saturating_sub(length); + last_start = start; + index.saturating_reduce(1); + + SlashingSpan { index, start, length: Some(length) } + }); + + std::iter::once(last).chain(prior).count() + }) .unwrap_or_default(); action_tx.send(Action::SetSlashingSpansLength(slashing_spans_length, *account_id))?; Ok(()) diff --git a/src/types/mod.rs b/src/types/mod.rs index ad46334..98b5728 100644 --- a/src/types/mod.rs +++ b/src/types/mod.rs @@ -19,5 +19,6 @@ pub use nominator::Nominator; pub use nominator::Nominations; pub use staking::UnlockChunk; pub use staking::RewardDestination; +pub use staking::SlashingSpan; pub use networks::Gatekeeper; pub use networks::BlockRange; diff --git a/src/types/staking.rs b/src/types/staking.rs index 00b5c4b..9551c23 100644 --- a/src/types/staking.rs +++ b/src/types/staking.rs @@ -8,6 +8,13 @@ pub struct UnlockChunk { pub era: u32, } +#[derive(Debug, Default, Clone, PartialEq, Eq, Serialize, Deserialize, Decode)] +pub struct SlashingSpan { + pub index: u32, + pub start: u32, + pub length: Option +} + #[derive(Default, Debug, Clone, PartialEq, Eq, Display, Serialize, Deserialize)] pub enum RewardDestination { #[default]