last update and rate limits are visible now
Signed-off-by: Uncle Stretch <uncle.stretch@ghostchain.io>
This commit is contained in:
parent
bae21bb505
commit
7f246d9a4e
@ -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.76"
|
version = "0.3.77"
|
||||||
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"
|
||||||
|
|||||||
@ -133,7 +133,10 @@ pub enum Action {
|
|||||||
SetChoosenGatekeeper(u64),
|
SetChoosenGatekeeper(u64),
|
||||||
SetSlashingSpansLength(usize, [u8; 32]),
|
SetSlashingSpansLength(usize, [u8; 32]),
|
||||||
SetStoredRpcEndpoints(Vec<String>),
|
SetStoredRpcEndpoints(Vec<String>),
|
||||||
|
SetLastUpdated(u64, u64),
|
||||||
|
SetRateLimitDelay(u64, u64),
|
||||||
UpdateStoredRpcEndpoints(u64, Vec<String>),
|
UpdateStoredRpcEndpoints(u64, Vec<String>),
|
||||||
|
NullifyLastTimestamp(u64),
|
||||||
|
|
||||||
BestBlockInformation(H256, u32),
|
BestBlockInformation(H256, u32),
|
||||||
FinalizedBlockInformation(H256, u32),
|
FinalizedBlockInformation(H256, u32),
|
||||||
|
|||||||
@ -1,14 +1,10 @@
|
|||||||
use color_eyre::Result;
|
use color_eyre::Result;
|
||||||
use crossterm::event::{KeyCode, KeyEvent, KeyEventKind};
|
use crossterm::event::{KeyCode, KeyEvent, KeyEventKind};
|
||||||
use ratatui::{
|
use ratatui::{
|
||||||
layout::{Alignment, Constraint, Flex, Layout, Position, Rect},
|
layout::{Alignment, Constraint, Flex, Layout, Position, Rect}, prelude::Margin, style::{Color, Style}, text::Line, widgets::{
|
||||||
prelude::Margin,
|
|
||||||
style::{Color, Style},
|
|
||||||
widgets::{
|
|
||||||
Block, BorderType, Cell, Clear, Paragraph, Row, Scrollbar, ScrollbarOrientation,
|
Block, BorderType, Cell, Clear, Paragraph, Row, Scrollbar, ScrollbarOrientation,
|
||||||
ScrollbarState, Table, TableState,
|
ScrollbarState, Table, TableState,
|
||||||
},
|
}, Frame
|
||||||
Frame,
|
|
||||||
};
|
};
|
||||||
use std::sync::mpsc::Sender;
|
use std::sync::mpsc::Sender;
|
||||||
use tokio::sync::mpsc::UnboundedSender;
|
use tokio::sync::mpsc::UnboundedSender;
|
||||||
@ -33,6 +29,8 @@ enum Selected {
|
|||||||
pub struct GatekeeperEndpoints {
|
pub struct GatekeeperEndpoints {
|
||||||
is_active: bool,
|
is_active: bool,
|
||||||
selected: Selected,
|
selected: Selected,
|
||||||
|
rate_limit_delay: u64,
|
||||||
|
last_updated: u64,
|
||||||
chain_id: u64,
|
chain_id: u64,
|
||||||
rpc_input: Input,
|
rpc_input: Input,
|
||||||
action_tx: Option<UnboundedSender<Action>>,
|
action_tx: Option<UnboundedSender<Action>>,
|
||||||
@ -92,6 +90,11 @@ impl GatekeeperEndpoints {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Selected::StoredRpcs if new_char == 'T' => {
|
||||||
|
if let Some(network_tx) = &self.network_tx {
|
||||||
|
let _ = network_tx.send(Action::NullifyLastTimestamp(self.chain_id));
|
||||||
|
}
|
||||||
|
}
|
||||||
_ => match new_char {
|
_ => match new_char {
|
||||||
'j' => self.move_cursor_down(),
|
'j' => self.move_cursor_down(),
|
||||||
'k' => self.move_cursor_up(),
|
'k' => self.move_cursor_up(),
|
||||||
@ -233,6 +236,34 @@ impl GatekeeperEndpoints {
|
|||||||
|
|
||||||
(table, scrollbar)
|
(table, scrollbar)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn prepare_rate_limits(&self) -> String {
|
||||||
|
format!("Rate limit: {}", self.rate_limit_delay / 1_000)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn prepare_datetime_string(&self) -> String {
|
||||||
|
let now = std::time::SystemTime::now()
|
||||||
|
.duration_since(std::time::UNIX_EPOCH)
|
||||||
|
.expect("Time went backwards")
|
||||||
|
.as_millis();
|
||||||
|
|
||||||
|
let diff = now as i64 - self.last_updated as i64;
|
||||||
|
let abs_diff = diff.abs();
|
||||||
|
|
||||||
|
if abs_diff < 60_000 {
|
||||||
|
let secs = abs_diff / 1_000;
|
||||||
|
format!("{}secs {}", secs, if diff >= 0 { "ago" } else { "left" })
|
||||||
|
} else if abs_diff < 3_600_000 {
|
||||||
|
let mins = abs_diff / 60_000;
|
||||||
|
format!("{}mins {}", mins, if diff >= 0 { "ago" } else { "left" })
|
||||||
|
} else if abs_diff < 86_400_000 {
|
||||||
|
let hours = abs_diff / 3_600_000;
|
||||||
|
format!("{}hour {}", hours, if diff >= 0 { "ago" } else { "left" })
|
||||||
|
} else {
|
||||||
|
let days = abs_diff / 86_400_000;
|
||||||
|
format!("{}days {}", days, if diff >= 0 { "ago" } else { "left" })
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl PartialComponent for GatekeeperEndpoints {
|
impl PartialComponent for GatekeeperEndpoints {
|
||||||
@ -304,6 +335,16 @@ impl Component for GatekeeperEndpoints {
|
|||||||
fn update(&mut self, action: Action) -> Result<Option<Action>> {
|
fn update(&mut self, action: Action) -> Result<Option<Action>> {
|
||||||
match action {
|
match action {
|
||||||
Action::SetChoosenGatekeeper(chain_id) => self.set_chain_id(chain_id),
|
Action::SetChoosenGatekeeper(chain_id) => self.set_chain_id(chain_id),
|
||||||
|
Action::SetLastUpdated(chain_id, last_updated) => {
|
||||||
|
if chain_id == self.chain_id {
|
||||||
|
self.last_updated = last_updated;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Action::SetRateLimitDelay(chain_id, rate_limit_delay) => {
|
||||||
|
if chain_id == self.chain_id {
|
||||||
|
self.rate_limit_delay = rate_limit_delay;
|
||||||
|
}
|
||||||
|
}
|
||||||
Action::SetGatekeepedNetwork(network) => {
|
Action::SetGatekeepedNetwork(network) => {
|
||||||
self.default_endpoints = network.default_endpoints
|
self.default_endpoints = network.default_endpoints
|
||||||
}
|
}
|
||||||
@ -358,7 +399,9 @@ impl Component for GatekeeperEndpoints {
|
|||||||
.border_type(input_border_type)
|
.border_type(input_border_type)
|
||||||
.title_style(self.palette.create_popup_title_style())
|
.title_style(self.palette.create_popup_title_style())
|
||||||
.title_alignment(Alignment::Right)
|
.title_alignment(Alignment::Right)
|
||||||
.title("Input new RPC"),
|
.title("Input new RPC")
|
||||||
|
.title_bottom(Line::from(self.prepare_datetime_string()).left_aligned())
|
||||||
|
.title_bottom(Line::from(self.prepare_rate_limits()).right_aligned()),
|
||||||
);
|
);
|
||||||
|
|
||||||
let v = Layout::vertical([Constraint::Max(14)]).flex(Flex::Center);
|
let v = Layout::vertical([Constraint::Max(14)]).flex(Flex::Center);
|
||||||
|
|||||||
@ -191,6 +191,7 @@ impl Component for Validator {
|
|||||||
| CurrentTab::RotatePopup
|
| CurrentTab::RotatePopup
|
||||||
| CurrentTab::ValidatePopup
|
| CurrentTab::ValidatePopup
|
||||||
| CurrentTab::ChillPopup
|
| CurrentTab::ChillPopup
|
||||||
|
| CurrentTab::PayeePopup
|
||||||
| CurrentTab::UnbondPopup
|
| CurrentTab::UnbondPopup
|
||||||
| CurrentTab::RebondPopup
|
| CurrentTab::RebondPopup
|
||||||
| CurrentTab::WithdrawPopup
|
| CurrentTab::WithdrawPopup
|
||||||
|
|||||||
@ -169,6 +169,66 @@ pub async fn get_block_range(
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub async fn get_last_updated(
|
||||||
|
action_tx: &UnboundedSender<Action>,
|
||||||
|
rpc_client: &RpcClient,
|
||||||
|
chain_id: u64,
|
||||||
|
) -> Result<()> {
|
||||||
|
let chain_id_encoded = chain_id.encode();
|
||||||
|
let block_range_key_raw = get_slow_clap_storage_key(b"last-timestamp-", &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 last_timestamp: u64 = rpc_client
|
||||||
|
.request(
|
||||||
|
"offchain_localStorageGet",
|
||||||
|
rpc_params!["PERSISTENT", block_range_key],
|
||||||
|
)
|
||||||
|
.await
|
||||||
|
.ok()
|
||||||
|
.map(|hex_string: String| {
|
||||||
|
let bytes = hex::decode(&hex_string[2..]).expect("Invalid hex string");
|
||||||
|
u64::decode(&mut bytes.as_slice())
|
||||||
|
.ok()
|
||||||
|
.unwrap_or_default()
|
||||||
|
})
|
||||||
|
.unwrap_or_default();
|
||||||
|
|
||||||
|
action_tx.send(Action::SetLastUpdated(chain_id, last_timestamp))?;
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
pub async fn get_rate_limit_delay(
|
||||||
|
action_tx: &UnboundedSender<Action>,
|
||||||
|
rpc_client: &RpcClient,
|
||||||
|
chain_id: u64,
|
||||||
|
) -> Result<()> {
|
||||||
|
let chain_id_encoded = chain_id.encode();
|
||||||
|
let block_range_key_raw = get_slow_clap_storage_key(b"rate-limit-", &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 last_timestamp: u64 = rpc_client
|
||||||
|
.request(
|
||||||
|
"offchain_localStorageGet",
|
||||||
|
rpc_params!["PERSISTENT", block_range_key],
|
||||||
|
)
|
||||||
|
.await
|
||||||
|
.ok()
|
||||||
|
.map(|hex_string: String| {
|
||||||
|
let bytes = hex::decode(&hex_string[2..]).expect("Invalid hex string");
|
||||||
|
u64::decode(&mut bytes.as_slice())
|
||||||
|
.ok()
|
||||||
|
.unwrap_or(5_000u64)
|
||||||
|
})
|
||||||
|
.unwrap_or(5_000u64);
|
||||||
|
|
||||||
|
action_tx.send(Action::SetRateLimitDelay(chain_id, last_timestamp))?;
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
pub async fn nullify_blocks(
|
pub async fn nullify_blocks(
|
||||||
action_tx: &UnboundedSender<Action>,
|
action_tx: &UnboundedSender<Action>,
|
||||||
rpc_client: &RpcClient,
|
rpc_client: &RpcClient,
|
||||||
@ -286,3 +346,40 @@ pub async fn set_stored_rpc_endpoints(
|
|||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub async fn set_last_timestamp(
|
||||||
|
action_tx: &UnboundedSender<Action>,
|
||||||
|
rpc_client: &RpcClient,
|
||||||
|
chain_id: u64,
|
||||||
|
) -> Result<()> {
|
||||||
|
let chain_id_encoded = chain_id.encode();
|
||||||
|
let endpoint_key_raw = get_slow_clap_storage_key(b"last-timestamp-", &chain_id_encoded);
|
||||||
|
let mut endpoint_key = String::from("0x");
|
||||||
|
for byte in endpoint_key_raw {
|
||||||
|
endpoint_key.push_str(&format!("{:02x}", byte));
|
||||||
|
}
|
||||||
|
|
||||||
|
let encoded_zero = String::from("0x0000000000000000");
|
||||||
|
match rpc_client
|
||||||
|
.request::<()>(
|
||||||
|
"offchain_localStorageSet",
|
||||||
|
rpc_params!["PERSISTENT", endpoint_key, encoded_zero],
|
||||||
|
)
|
||||||
|
.await
|
||||||
|
{
|
||||||
|
Ok(_) => {
|
||||||
|
action_tx.send(Action::EventLog(
|
||||||
|
format!("Last timestamp nullified for network #{:?}", chain_id),
|
||||||
|
ActionLevel::Info,
|
||||||
|
ActionTarget::ValidatorLog,
|
||||||
|
))?;
|
||||||
|
get_stored_rpc_endpoints(action_tx, rpc_client, chain_id).await?;
|
||||||
|
}
|
||||||
|
Err(err) => action_tx.send(Action::EventLog(
|
||||||
|
format!("Last timestamp nullification failed: {:?}", err),
|
||||||
|
ActionLevel::Error,
|
||||||
|
ActionTarget::ValidatorLog,
|
||||||
|
))?,
|
||||||
|
};
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|||||||
@ -378,6 +378,10 @@ impl Network {
|
|||||||
for chain_id in GATEKEEPED_CHAIN_IDS {
|
for chain_id in GATEKEEPED_CHAIN_IDS {
|
||||||
legacy_rpc_calls::get_block_range(&self.action_tx, &self.rpc_client, chain_id)
|
legacy_rpc_calls::get_block_range(&self.action_tx, &self.rpc_client, chain_id)
|
||||||
.await?;
|
.await?;
|
||||||
|
legacy_rpc_calls::get_last_updated(&self.action_tx, &self.rpc_client, chain_id)
|
||||||
|
.await?;
|
||||||
|
legacy_rpc_calls::get_rate_limit_delay(&self.action_tx, &self.rpc_client, chain_id)
|
||||||
|
.await?;
|
||||||
}
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
@ -846,6 +850,14 @@ impl Network {
|
|||||||
)
|
)
|
||||||
.await
|
.await
|
||||||
}
|
}
|
||||||
|
Action::NullifyLastTimestamp(chain_id) => {
|
||||||
|
legacy_rpc_calls::set_last_timestamp(
|
||||||
|
&self.action_tx,
|
||||||
|
&self.rpc_client,
|
||||||
|
chain_id,
|
||||||
|
)
|
||||||
|
.await
|
||||||
|
}
|
||||||
_ => Ok(()),
|
_ => Ok(()),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user