add ability to manipulate stored blocks
Signed-off-by: Uncle Stretch <uncle.stretch@ghostchain.io>
This commit is contained in:
parent
abf2388761
commit
718ae51dee
@ -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.72"
|
version = "0.3.73"
|
||||||
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"
|
||||||
|
|||||||
@ -38,6 +38,7 @@ pub enum Action {
|
|||||||
PayoutValidatorPopup(u32),
|
PayoutValidatorPopup(u32),
|
||||||
PayoutAllValidatorPopup(Vec<u32>),
|
PayoutAllValidatorPopup(Vec<u32>),
|
||||||
WithdrawValidatorPopup,
|
WithdrawValidatorPopup,
|
||||||
|
ChangeBlocksPopup,
|
||||||
|
|
||||||
BalanceRequest([u8; 32], bool),
|
BalanceRequest([u8; 32], bool),
|
||||||
BalanceResponse([u8; 32], Option<SystemAccount>),
|
BalanceResponse([u8; 32], Option<SystemAccount>),
|
||||||
@ -62,6 +63,7 @@ pub enum Action {
|
|||||||
SetSessionKeys([u8; 32], String),
|
SetSessionKeys([u8; 32], String),
|
||||||
ValidateFrom([u8; 32], u32),
|
ValidateFrom([u8; 32], u32),
|
||||||
ChillFrom([u8; 32]),
|
ChillFrom([u8; 32]),
|
||||||
|
ChangeBlocks(u64, u64),
|
||||||
UnbondFrom([u8; 32], u128),
|
UnbondFrom([u8; 32], u128),
|
||||||
RebondFrom([u8; 32], u128),
|
RebondFrom([u8; 32], u128),
|
||||||
WithdrawUnbondedFrom([u8; 32], u32),
|
WithdrawUnbondedFrom([u8; 32], u32),
|
||||||
|
|||||||
157
src/components/validator/change_blocks_popup.rs
Normal file
157
src/components/validator/change_blocks_popup.rs
Normal file
@ -0,0 +1,157 @@
|
|||||||
|
use crossterm::event::{KeyCode, KeyEvent, KeyEventKind};
|
||||||
|
use color_eyre::Result;
|
||||||
|
use ratatui::{
|
||||||
|
layout::{Position, Alignment, Constraint, Flex, Layout, Rect},
|
||||||
|
widgets::{Block, Clear, Paragraph},
|
||||||
|
Frame
|
||||||
|
};
|
||||||
|
use std::sync::mpsc::Sender;
|
||||||
|
use tokio::sync::mpsc::UnboundedSender;
|
||||||
|
|
||||||
|
use super::{Component, PartialComponent, CurrentTab};
|
||||||
|
use crate::{
|
||||||
|
action::Action,
|
||||||
|
config::Config,
|
||||||
|
palette::StylePalette,
|
||||||
|
types::{ActionTarget, ActionLevel},
|
||||||
|
widgets::{Input, InputRequest},
|
||||||
|
};
|
||||||
|
|
||||||
|
#[derive(Debug, Default)]
|
||||||
|
pub struct ChangeBlocksPopup {
|
||||||
|
is_active: bool,
|
||||||
|
action_tx: Option<UnboundedSender<Action>>,
|
||||||
|
network_tx: Option<Sender<Action>>,
|
||||||
|
chain_id: u64,
|
||||||
|
block_number: Input,
|
||||||
|
palette: StylePalette
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ChangeBlocksPopup {
|
||||||
|
fn close_popup(&mut self) {
|
||||||
|
self.is_active = false;
|
||||||
|
if let Some(action_tx) = &self.action_tx {
|
||||||
|
let _ = action_tx.send(Action::ClosePopup);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn submit_new_block(&mut self) {
|
||||||
|
if let Some(network_tx) = &self.network_tx {
|
||||||
|
if let Some(action_tx) = &self.action_tx {
|
||||||
|
let _ = match self.block_number.value().parse::<u64>() {
|
||||||
|
Ok(new_block) => {
|
||||||
|
let _ = network_tx.send(Action::ChangeBlocks(self.chain_id, new_block));
|
||||||
|
action_tx.send(Action::ClosePopup)
|
||||||
|
}
|
||||||
|
Err(_) => action_tx.send(Action::EventLog(
|
||||||
|
"Incorrect block number format".to_string(),
|
||||||
|
ActionLevel::Error,
|
||||||
|
ActionTarget::ValidatorLog,
|
||||||
|
)),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn enter_char(&mut self, new_char: char) {
|
||||||
|
let is_separator_needed = !self.block_number.value().contains('.') && new_char == '.';
|
||||||
|
if new_char.is_digit(10) || is_separator_needed {
|
||||||
|
let _ = self.block_number.handle(InputRequest::InsertChar(new_char));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn delete_char(&mut self) {
|
||||||
|
let _ = self.block_number.handle(InputRequest::DeletePrevChar);
|
||||||
|
}
|
||||||
|
|
||||||
|
fn move_cursor_right(&mut self) {
|
||||||
|
let _ = self.block_number.handle(InputRequest::GoToNextChar);
|
||||||
|
}
|
||||||
|
|
||||||
|
fn move_cursor_left(&mut self) {
|
||||||
|
let _ = self.block_number.handle(InputRequest::GoToPrevChar);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl PartialComponent for ChangeBlocksPopup {
|
||||||
|
fn set_active(&mut self, current_tab: CurrentTab) {
|
||||||
|
match current_tab {
|
||||||
|
CurrentTab::ChangeBlocksPopup => self.is_active = true,
|
||||||
|
_ => {
|
||||||
|
self.is_active = false;
|
||||||
|
self.block_number = Input::new(String::new());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Component for ChangeBlocksPopup {
|
||||||
|
fn register_network_handler(&mut self, tx: Sender<Action>) -> Result<()> {
|
||||||
|
self.network_tx = Some(tx);
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn register_action_handler(&mut self, tx: UnboundedSender<Action>) -> Result<()> {
|
||||||
|
self.action_tx = Some(tx);
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn register_config_handler(&mut self, config: Config) -> Result<()> {
|
||||||
|
if let Some(style) = config.styles.get(&crate::app::Mode::Wallet) {
|
||||||
|
self.palette.with_normal_style(style.get("normal_style").copied());
|
||||||
|
self.palette.with_normal_border_style(style.get("normal_border_style").copied());
|
||||||
|
self.palette.with_normal_title_style(style.get("normal_title_style").copied());
|
||||||
|
self.palette.with_popup_style(style.get("popup_style").copied());
|
||||||
|
self.palette.with_popup_title_style(style.get("popup_title_style").copied());
|
||||||
|
}
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn handle_key_event(&mut self, key: KeyEvent) -> Result<Option<Action>> {
|
||||||
|
if self.is_active && key.kind == KeyEventKind::Press {
|
||||||
|
match key.code {
|
||||||
|
KeyCode::Enter => self.submit_new_block(),
|
||||||
|
KeyCode::Esc => self.close_popup(),
|
||||||
|
KeyCode::Char(to_insert) => self.enter_char(to_insert),
|
||||||
|
KeyCode::Backspace => self.delete_char(),
|
||||||
|
KeyCode::Left => self.move_cursor_left(),
|
||||||
|
KeyCode::Right => self.move_cursor_right(),
|
||||||
|
_ => {},
|
||||||
|
};
|
||||||
|
}
|
||||||
|
Ok(None)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn update(&mut self, action: Action) -> Result<Option<Action>> {
|
||||||
|
match action {
|
||||||
|
Action::SetChoosenGatekeeper(chain_id) => self.chain_id = chain_id,
|
||||||
|
_ => {}
|
||||||
|
};
|
||||||
|
Ok(None)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn draw(&mut self, frame: &mut Frame, area: Rect) -> Result<()> {
|
||||||
|
if self.is_active {
|
||||||
|
let (border_style, border_type) = self.palette.create_popup_style();
|
||||||
|
let input = Paragraph::new(self.block_number.value())
|
||||||
|
.block(Block::bordered()
|
||||||
|
.border_style(border_style)
|
||||||
|
.border_type(border_type)
|
||||||
|
.title_style(self.palette.create_popup_title_style())
|
||||||
|
.title_alignment(Alignment::Right)
|
||||||
|
.title(format!("Bump blocks for #{:?}", self.chain_id)));
|
||||||
|
let v = Layout::vertical([Constraint::Max(3)]).flex(Flex::Center);
|
||||||
|
let h = Layout::horizontal([Constraint::Max(57)]).flex(Flex::Center);
|
||||||
|
let [area] = v.areas(area);
|
||||||
|
let [area] = h.areas(area);
|
||||||
|
|
||||||
|
frame.render_widget(Clear, area);
|
||||||
|
frame.render_widget(input, area);
|
||||||
|
frame.set_cursor_position(Position::new(
|
||||||
|
area.x + self.block_number.cursor() as u16 + 1,
|
||||||
|
area.y + 1
|
||||||
|
));
|
||||||
|
}
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -55,6 +55,12 @@ impl Gatekeepers {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn nullify_evm_blocks(&mut self) {
|
||||||
|
if let Some(action_tx) = &self.action_tx {
|
||||||
|
let _ = action_tx.send(Action::ChangeBlocksPopup);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fn change_choosen_gatekeeper(&mut self) {
|
fn change_choosen_gatekeeper(&mut self) {
|
||||||
if let Some(action_tx) = &self.action_tx {
|
if let Some(action_tx) = &self.action_tx {
|
||||||
if let Some(chain_id) = self.list_state
|
if let Some(chain_id) = self.list_state
|
||||||
@ -191,6 +197,7 @@ impl Component for Gatekeepers {
|
|||||||
KeyCode::Down | KeyCode::Char('j') => self.next_row(),
|
KeyCode::Down | KeyCode::Char('j') => self.next_row(),
|
||||||
KeyCode::Char('g') => self.first_row(),
|
KeyCode::Char('g') => self.first_row(),
|
||||||
KeyCode::Char('G') => self.last_row(),
|
KeyCode::Char('G') => self.last_row(),
|
||||||
|
KeyCode::Char('O') => self.nullify_evm_blocks(),
|
||||||
_ => {},
|
_ => {},
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
@ -33,6 +33,7 @@ mod unbond_popup;
|
|||||||
mod rebond_popup;
|
mod rebond_popup;
|
||||||
mod withdraw_popup;
|
mod withdraw_popup;
|
||||||
mod payee_popup;
|
mod payee_popup;
|
||||||
|
mod change_blocks_popup;
|
||||||
|
|
||||||
use stash_details::StashDetails;
|
use stash_details::StashDetails;
|
||||||
use staking_details::StakingDetails;
|
use staking_details::StakingDetails;
|
||||||
@ -56,6 +57,7 @@ use unbond_popup::UnbondPopup;
|
|||||||
use rebond_popup::RebondPopup;
|
use rebond_popup::RebondPopup;
|
||||||
use withdraw_popup::WithdrawPopup;
|
use withdraw_popup::WithdrawPopup;
|
||||||
use payee_popup::PayeePopup;
|
use payee_popup::PayeePopup;
|
||||||
|
use change_blocks_popup::ChangeBlocksPopup;
|
||||||
|
|
||||||
#[derive(Debug, Copy, Clone, PartialEq)]
|
#[derive(Debug, Copy, Clone, PartialEq)]
|
||||||
pub enum CurrentTab {
|
pub enum CurrentTab {
|
||||||
@ -77,6 +79,7 @@ pub enum CurrentTab {
|
|||||||
RebondPopup,
|
RebondPopup,
|
||||||
WithdrawPopup,
|
WithdrawPopup,
|
||||||
PayeePopup,
|
PayeePopup,
|
||||||
|
ChangeBlocksPopup,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub trait PartialComponent: Component {
|
pub trait PartialComponent: Component {
|
||||||
@ -119,6 +122,7 @@ impl Default for Validator {
|
|||||||
Box::new(RebondPopup::default()),
|
Box::new(RebondPopup::default()),
|
||||||
Box::new(WithdrawPopup::default()),
|
Box::new(WithdrawPopup::default()),
|
||||||
Box::new(PayeePopup::default()),
|
Box::new(PayeePopup::default()),
|
||||||
|
Box::new(ChangeBlocksPopup::default()),
|
||||||
],
|
],
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -185,7 +189,8 @@ impl Component for Validator {
|
|||||||
CurrentTab::RebondPopup |
|
CurrentTab::RebondPopup |
|
||||||
CurrentTab::WithdrawPopup |
|
CurrentTab::WithdrawPopup |
|
||||||
CurrentTab::PayoutPopup |
|
CurrentTab::PayoutPopup |
|
||||||
CurrentTab::PayoutAllPopup => {
|
CurrentTab::PayoutAllPopup |
|
||||||
|
CurrentTab::ChangeBlocksPopup => {
|
||||||
for component in self.components.iter_mut() {
|
for component in self.components.iter_mut() {
|
||||||
component.handle_key_event(key)?;
|
component.handle_key_event(key)?;
|
||||||
}
|
}
|
||||||
@ -266,6 +271,10 @@ impl Component for Validator {
|
|||||||
self.previous_tab = self.current_tab;
|
self.previous_tab = self.current_tab;
|
||||||
self.current_tab = CurrentTab::WithdrawPopup;
|
self.current_tab = CurrentTab::WithdrawPopup;
|
||||||
},
|
},
|
||||||
|
Action::ChangeBlocksPopup => {
|
||||||
|
self.previous_tab = self.current_tab;
|
||||||
|
self.current_tab = CurrentTab::ChangeBlocksPopup;
|
||||||
|
},
|
||||||
Action::ClosePopup => self.current_tab = self.previous_tab,
|
Action::ClosePopup => self.current_tab = self.previous_tab,
|
||||||
_ => {},
|
_ => {},
|
||||||
}
|
}
|
||||||
|
|||||||
@ -3,7 +3,7 @@ use color_eyre::Result;
|
|||||||
use subxt::{backend::{legacy::rpc_methods::SystemHealth, rpc::RpcClient}, rpc_params};
|
use subxt::{backend::{legacy::rpc_methods::SystemHealth, rpc::RpcClient}, rpc_params};
|
||||||
use codec::{Encode, Decode};
|
use codec::{Encode, Decode};
|
||||||
|
|
||||||
use crate::{action::Action, network::miscellaneous::get_slow_clap_storage_key, types::{BlockRange, PeerInformation}};
|
use crate::{action::Action, network::miscellaneous::get_slow_clap_storage_key, types::{ActionLevel, ActionTarget, BlockRange, PeerInformation}};
|
||||||
|
|
||||||
pub async fn get_node_name(
|
pub async fn get_node_name(
|
||||||
action_tx: &UnboundedSender<Action>,
|
action_tx: &UnboundedSender<Action>,
|
||||||
@ -161,3 +161,41 @@ pub async fn get_block_range(
|
|||||||
action_tx.send(Action::SetBlockRange(chain_id, block_range))?;
|
action_tx.send(Action::SetBlockRange(chain_id, block_range))?;
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub async fn nullify_blocks(
|
||||||
|
action_tx: &UnboundedSender<Action>,
|
||||||
|
rpc_client: &RpcClient,
|
||||||
|
chain_id: u64,
|
||||||
|
new_block: u64
|
||||||
|
) -> Result<()> {
|
||||||
|
let chain_id_encoded = chain_id.encode();
|
||||||
|
let block_range_key_raw = get_slow_clap_storage_key(b"block-", &chain_id_encoded);
|
||||||
|
let mut block_range_key = String::from("0x");
|
||||||
|
for byte in block_range_key_raw {
|
||||||
|
block_range_key.push_str(&format!("{:02x}", byte));
|
||||||
|
}
|
||||||
|
|
||||||
|
let zeroes = (new_block, new_block).encode();
|
||||||
|
let mut zeroes_bytes = String::from("0x");
|
||||||
|
for byte in &zeroes {
|
||||||
|
zeroes_bytes.push_str(&format!("{:02x}", byte));
|
||||||
|
}
|
||||||
|
|
||||||
|
match rpc_client
|
||||||
|
.request::<()>("offchain_localStorageSet", rpc_params!["PERSISTENT", block_range_key, zeroes_bytes])
|
||||||
|
.await
|
||||||
|
{
|
||||||
|
Ok(_) => action_tx.send(Action::EventLog(
|
||||||
|
format!("Blocks changed for chain id #{:?}", chain_id),
|
||||||
|
ActionLevel::Info,
|
||||||
|
ActionTarget::ValidatorLog,
|
||||||
|
))?,
|
||||||
|
Err(err) => action_tx.send(Action::EventLog(
|
||||||
|
format!("Block changing failed: {:?}", err),
|
||||||
|
ActionLevel::Error,
|
||||||
|
ActionTarget::ValidatorLog,
|
||||||
|
))?,
|
||||||
|
};
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|||||||
@ -507,6 +507,14 @@ impl Network {
|
|||||||
}
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
Action::ChangeBlocks(chain_id, new_block) => {
|
||||||
|
legacy_rpc_calls::nullify_blocks(
|
||||||
|
&self.action_tx,
|
||||||
|
&self.rpc_client,
|
||||||
|
chain_id,
|
||||||
|
new_block,
|
||||||
|
).await
|
||||||
|
}
|
||||||
_ => Ok(())
|
_ => Ok(())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user