Compare commits
	
		
			2 Commits
		
	
	
		
			7e9e6ac329
			...
			8555ddceec
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| 8555ddceec | |||
| 5b0ef1c4b7 | 
@ -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.18"
 | 
					version = "0.3.19"
 | 
				
			||||||
edition = "2021"
 | 
					edition = "2021"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
[dependencies]
 | 
					[dependencies]
 | 
				
			||||||
 | 
				
			|||||||
@ -49,11 +49,13 @@ pub enum Action {
 | 
				
			|||||||
    UpdateKnownValidator(String),
 | 
					    UpdateKnownValidator(String),
 | 
				
			||||||
    TransferTo(String),
 | 
					    TransferTo(String),
 | 
				
			||||||
    AccountDetailsOf(String, Option<SystemAccount>),
 | 
					    AccountDetailsOf(String, Option<SystemAccount>),
 | 
				
			||||||
 | 
					    StoreRotatedKeys(String),
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    TransferBalance(String, [u8; 32], u128),
 | 
					    TransferBalance(String, [u8; 32], u128),
 | 
				
			||||||
    BondValidatorExtraFrom([u8; 32], u128),
 | 
					    BondValidatorExtraFrom([u8; 32], u128),
 | 
				
			||||||
    BondValidatorFrom([u8; 32], u128),
 | 
					    BondValidatorFrom([u8; 32], u128),
 | 
				
			||||||
    PayoutStakers([u8; 32], [u8; 32], u32),
 | 
					    PayoutStakers([u8; 32], [u8; 32], u32),
 | 
				
			||||||
 | 
					    SetSessionKeys([u8; 32], String),
 | 
				
			||||||
    EventLog(String, ActionLevel, ActionTarget),
 | 
					    EventLog(String, ActionLevel, ActionTarget),
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    NewBestBlock(u32),
 | 
					    NewBestBlock(u32),
 | 
				
			||||||
 | 
				
			|||||||
@ -10,7 +10,11 @@ use std::sync::mpsc::Sender;
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
use super::{Component, PartialComponent, CurrentTab};
 | 
					use super::{Component, PartialComponent, CurrentTab};
 | 
				
			||||||
use crate::{
 | 
					use crate::{
 | 
				
			||||||
    action::Action, config::Config, palette::StylePalette, types::{ActionLevel, ActionTarget}, widgets::{Input, InputRequest} 
 | 
					    action::Action, 
 | 
				
			||||||
 | 
					    config::Config, 
 | 
				
			||||||
 | 
					    palette::StylePalette, 
 | 
				
			||||||
 | 
					    types::{ActionLevel, ActionTarget}, 
 | 
				
			||||||
 | 
					    widgets::{Input, InputRequest},
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#[derive(Debug)]
 | 
					#[derive(Debug)]
 | 
				
			||||||
 | 
				
			|||||||
@ -2,10 +2,11 @@ use crossterm::event::{KeyCode, KeyEvent, KeyEventKind};
 | 
				
			|||||||
use color_eyre::Result;
 | 
					use color_eyre::Result;
 | 
				
			||||||
use ratatui::{
 | 
					use ratatui::{
 | 
				
			||||||
    layout::{Alignment, Constraint, Flex, Layout, Rect}, 
 | 
					    layout::{Alignment, Constraint, Flex, Layout, Rect}, 
 | 
				
			||||||
    widgets::{Block, Clear, Paragraph}, 
 | 
					    text::Text, 
 | 
				
			||||||
    Frame
 | 
					    widgets::{Block, Cell, Clear, Row, Table}, 
 | 
				
			||||||
 | 
					    Frame,
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
//use tokio::sync::mpsc::UnboundedSender;
 | 
					use tokio::sync::mpsc::UnboundedSender;
 | 
				
			||||||
use std::sync::mpsc::Sender;
 | 
					use std::sync::mpsc::Sender;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
use super::{Component, PartialComponent, CurrentTab};
 | 
					use super::{Component, PartialComponent, CurrentTab};
 | 
				
			||||||
@ -13,14 +14,15 @@ use crate::{
 | 
				
			|||||||
    action::Action, 
 | 
					    action::Action, 
 | 
				
			||||||
    config::Config, 
 | 
					    config::Config, 
 | 
				
			||||||
    palette::StylePalette, 
 | 
					    palette::StylePalette, 
 | 
				
			||||||
    //types::{ActionLevel, ActionTarget}, 
 | 
					 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#[derive(Debug)]
 | 
					#[derive(Debug)]
 | 
				
			||||||
pub struct RotatePopup {
 | 
					pub struct RotatePopup {
 | 
				
			||||||
    is_active: bool,
 | 
					    is_active: bool,
 | 
				
			||||||
    //action_tx: Option<UnboundedSender<Action>>,
 | 
					    action_tx: Option<UnboundedSender<Action>>,
 | 
				
			||||||
    network_tx: Option<Sender<Action>>,
 | 
					    network_tx: Option<Sender<Action>>,
 | 
				
			||||||
 | 
					    cached_keys: String,
 | 
				
			||||||
 | 
					    secret_seed: [u8; 32],
 | 
				
			||||||
    palette: StylePalette
 | 
					    palette: StylePalette
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -34,17 +36,46 @@ impl RotatePopup {
 | 
				
			|||||||
    pub fn new() -> Self {
 | 
					    pub fn new() -> Self {
 | 
				
			||||||
        Self {
 | 
					        Self {
 | 
				
			||||||
            is_active: false,
 | 
					            is_active: false,
 | 
				
			||||||
            //action_tx: None,
 | 
					            action_tx: None,
 | 
				
			||||||
            network_tx: None,
 | 
					            network_tx: None,
 | 
				
			||||||
 | 
					            cached_keys: String::new(),
 | 
				
			||||||
 | 
					            secret_seed: [0u8; 32],
 | 
				
			||||||
            palette: StylePalette::default(),
 | 
					            palette: StylePalette::default(),
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    fn rotate_keys(&mut self) {
 | 
					    fn rotate_keys(&mut self) {
 | 
				
			||||||
        todo!();
 | 
					        if !self.cached_keys.is_empty() && self.cached_keys.len() == 258 {
 | 
				
			||||||
        //if let Some(network_tx) = &self.network_tx {
 | 
					            if let Some(network_tx) = &self.network_tx {
 | 
				
			||||||
        //    let _ = network_tx.send(Action::RotateSessionKeys);
 | 
					                let _ = network_tx.send(Action::SetSessionKeys(
 | 
				
			||||||
        //}
 | 
					                        self.secret_seed, self.cached_keys.clone()));
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            if let Some(action_tx) = &self.action_tx {
 | 
				
			||||||
 | 
					                let _ = action_tx.send(Action::ClosePopup);
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        } else {
 | 
				
			||||||
 | 
					            if let Some(network_tx) = &self.network_tx {
 | 
				
			||||||
 | 
					                let _ = network_tx.send(Action::RotateSessionKeys);
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    fn parse_session_keys(&self) -> (String, String, String, String) {
 | 
				
			||||||
 | 
					        if !self.cached_keys.is_empty() && self.cached_keys.len() == 258 {
 | 
				
			||||||
 | 
					            let gran_key = format!("0x{}", &self.cached_keys[2..66]);
 | 
				
			||||||
 | 
					            let babe_key = format!("0x{}", &self.cached_keys[66..130]);
 | 
				
			||||||
 | 
					            let audi_key = format!("0x{}", &self.cached_keys[130..194]);
 | 
				
			||||||
 | 
					            let slow_key = format!("0x{}", &self.cached_keys[194..258]);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            (gran_key, babe_key, audi_key, slow_key)
 | 
				
			||||||
 | 
					        } else {
 | 
				
			||||||
 | 
					            (
 | 
				
			||||||
 | 
					                String::from("not prepared"),
 | 
				
			||||||
 | 
					                String::from("not prepared"),
 | 
				
			||||||
 | 
					                String::from("not prepared"),
 | 
				
			||||||
 | 
					                String::from("not prepared"),
 | 
				
			||||||
 | 
					            )
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -73,6 +104,16 @@ impl Component for RotatePopup {
 | 
				
			|||||||
        }
 | 
					        }
 | 
				
			||||||
        Ok(())
 | 
					        Ok(())
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    fn update(&mut self, action: Action) -> Result<Option<Action>> {
 | 
				
			||||||
 | 
					        match action {
 | 
				
			||||||
 | 
					            Action::StoreRotatedKeys(cached_keys) => self.cached_keys = cached_keys,
 | 
				
			||||||
 | 
					            Action::SetStashSecret(secret_seed) => self.secret_seed = secret_seed,
 | 
				
			||||||
 | 
					            _ => {}
 | 
				
			||||||
 | 
					        };
 | 
				
			||||||
 | 
					        Ok(None)
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    fn handle_key_event(&mut self, key: KeyEvent) -> Result<Option<Action>> {
 | 
					    fn handle_key_event(&mut self, key: KeyEvent) -> Result<Option<Action>> {
 | 
				
			||||||
        if self.is_active && key.kind == KeyEventKind::Press {
 | 
					        if self.is_active && key.kind == KeyEventKind::Press {
 | 
				
			||||||
            match key.code {
 | 
					            match key.code {
 | 
				
			||||||
@ -87,20 +128,48 @@ impl Component for RotatePopup {
 | 
				
			|||||||
    fn draw(&mut self, frame: &mut Frame, area: Rect) -> Result<()> {
 | 
					    fn draw(&mut self, frame: &mut Frame, area: Rect) -> Result<()> {
 | 
				
			||||||
        if self.is_active {
 | 
					        if self.is_active {
 | 
				
			||||||
            let (border_style, border_type) = self.palette.create_popup_style();
 | 
					            let (border_style, border_type) = self.palette.create_popup_style();
 | 
				
			||||||
            let popup = Paragraph::new(" Do you want to proceed key rotation?")
 | 
					
 | 
				
			||||||
 | 
					            let (gran_key, babe_key, audi_key, slow_key) = self.parse_session_keys();
 | 
				
			||||||
 | 
					            let table = Table::new(
 | 
				
			||||||
 | 
					                vec![
 | 
				
			||||||
 | 
					                    Row::new(vec![
 | 
				
			||||||
 | 
					                        Cell::from(Text::from("gran".to_string()).alignment(Alignment::Left)),
 | 
				
			||||||
 | 
					                        Cell::from(Text::from(gran_key).alignment(Alignment::Right)), 
 | 
				
			||||||
 | 
					                    ]),
 | 
				
			||||||
 | 
					                    Row::new(vec![
 | 
				
			||||||
 | 
					                        Cell::from(Text::from("babe".to_string()).alignment(Alignment::Left)),
 | 
				
			||||||
 | 
					                        Cell::from(Text::from(babe_key).alignment(Alignment::Right)), 
 | 
				
			||||||
 | 
					                    ]),
 | 
				
			||||||
 | 
					                    Row::new(vec![
 | 
				
			||||||
 | 
					                        Cell::from(Text::from("audi".to_string()).alignment(Alignment::Left)),
 | 
				
			||||||
 | 
					                        Cell::from(Text::from(audi_key).alignment(Alignment::Right)), 
 | 
				
			||||||
 | 
					                    ]),
 | 
				
			||||||
 | 
					                    Row::new(vec![
 | 
				
			||||||
 | 
					                        Cell::from(Text::from("slow".to_string()).alignment(Alignment::Left)),
 | 
				
			||||||
 | 
					                        Cell::from(Text::from(slow_key).alignment(Alignment::Right)), 
 | 
				
			||||||
 | 
					                    ]),
 | 
				
			||||||
 | 
					                    ],
 | 
				
			||||||
 | 
					                [
 | 
				
			||||||
 | 
					                    Constraint::Min(4),
 | 
				
			||||||
 | 
					                    Constraint::Min(0),
 | 
				
			||||||
 | 
					                ],
 | 
				
			||||||
 | 
					            )
 | 
				
			||||||
 | 
					            .highlight_style(self.palette.create_highlight_style())
 | 
				
			||||||
 | 
					            .column_spacing(1)
 | 
				
			||||||
            .block(Block::bordered()
 | 
					            .block(Block::bordered()
 | 
				
			||||||
                .border_style(border_style)
 | 
					                .border_style(border_style)
 | 
				
			||||||
                .border_type(border_type)
 | 
					                .border_type(border_type)
 | 
				
			||||||
                    .title_style(self.palette.create_popup_title_style())
 | 
					 | 
				
			||||||
                .title_alignment(Alignment::Right)
 | 
					                .title_alignment(Alignment::Right)
 | 
				
			||||||
                    .title("Enter to proceed / Esc to close"));
 | 
					                .title_style(self.palette.create_title_style(false))
 | 
				
			||||||
            let v = Layout::vertical([Constraint::Max(3)]).flex(Flex::Center);
 | 
					                .title("Rotate session keys (Enter to proceed / Esc to close)"));
 | 
				
			||||||
            let h = Layout::horizontal([Constraint::Max(50)]).flex(Flex::Center);
 | 
					
 | 
				
			||||||
 | 
					            let v = Layout::vertical([Constraint::Max(6)]).flex(Flex::Center);
 | 
				
			||||||
 | 
					            let h = Layout::horizontal([Constraint::Max(73)]).flex(Flex::Center);
 | 
				
			||||||
            let [area] = v.areas(area);
 | 
					            let [area] = v.areas(area);
 | 
				
			||||||
            let [area] = h.areas(area);
 | 
					            let [area] = h.areas(area);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            frame.render_widget(Clear, area);
 | 
					            frame.render_widget(Clear, area);
 | 
				
			||||||
            frame.render_widget(popup, area);
 | 
					            frame.render_widget(table, area);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        Ok(())
 | 
					        Ok(())
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
				
			|||||||
@ -120,3 +120,15 @@ pub async fn get_local_identity(
 | 
				
			|||||||
    action_tx.send(Action::SetLocalIdentity(local_peer_id))?;
 | 
					    action_tx.send(Action::SetLocalIdentity(local_peer_id))?;
 | 
				
			||||||
    Ok(())
 | 
					    Ok(())
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					pub async fn rotate_keys(
 | 
				
			||||||
 | 
					    action_tx: &UnboundedSender<Action>,
 | 
				
			||||||
 | 
					    rpc_client: &RpcClient,
 | 
				
			||||||
 | 
					) -> Result<()> {
 | 
				
			||||||
 | 
					    let rotated_keys: String = rpc_client
 | 
				
			||||||
 | 
					        .request("author_rotateKeys", rpc_params![])
 | 
				
			||||||
 | 
					        .await
 | 
				
			||||||
 | 
					        .unwrap_or_default();
 | 
				
			||||||
 | 
					    action_tx.send(Action::StoreRotatedKeys(rotated_keys))?;
 | 
				
			||||||
 | 
					    Ok(())
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
@ -166,6 +166,7 @@ impl Network {
 | 
				
			|||||||
            Action::GetConnectedPeers => legacy_rpc_calls::get_connected_peers(&self.action_tx, &self.rpc_client).await,
 | 
					            Action::GetConnectedPeers => legacy_rpc_calls::get_connected_peers(&self.action_tx, &self.rpc_client).await,
 | 
				
			||||||
            Action::GetListenAddresses => legacy_rpc_calls::get_listen_addresses(&self.action_tx, &self.rpc_client).await,
 | 
					            Action::GetListenAddresses => legacy_rpc_calls::get_listen_addresses(&self.action_tx, &self.rpc_client).await,
 | 
				
			||||||
            Action::GetLocalIdentity => legacy_rpc_calls::get_local_identity(&self.action_tx, &self.rpc_client).await,
 | 
					            Action::GetLocalIdentity => legacy_rpc_calls::get_local_identity(&self.action_tx, &self.rpc_client).await,
 | 
				
			||||||
 | 
					            Action::RotateSessionKeys => legacy_rpc_calls::rotate_keys(&self.action_tx, &self.rpc_client).await,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            Action::GetBlockAuthor(hash, logs) => predefined_calls::get_block_author(&self.action_tx, &self.online_client_api, &logs, &hash).await,
 | 
					            Action::GetBlockAuthor(hash, logs) => predefined_calls::get_block_author(&self.action_tx, &self.online_client_api, &logs, &hash).await,
 | 
				
			||||||
            Action::GetActiveEra => predefined_calls::get_active_era(&self.action_tx, &self.online_client_api).await,
 | 
					            Action::GetActiveEra => predefined_calls::get_active_era(&self.action_tx, &self.online_client_api).await,
 | 
				
			||||||
@ -312,6 +313,24 @@ impl Network {
 | 
				
			|||||||
                }
 | 
					                }
 | 
				
			||||||
                Ok(())
 | 
					                Ok(())
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
 | 
					            Action::SetSessionKeys(sender, hashed_keys) => {
 | 
				
			||||||
 | 
					                let sender_str = hex::encode(sender);
 | 
				
			||||||
 | 
					                let maybe_nonce = self.senders.get_mut(&sender_str);
 | 
				
			||||||
 | 
					                if let Ok(tx_progress) = predefined_txs::set_keys(
 | 
				
			||||||
 | 
					                    &self.action_tx,
 | 
				
			||||||
 | 
					                    &self.online_client_api,
 | 
				
			||||||
 | 
					                    &sender,
 | 
				
			||||||
 | 
					                    &hashed_keys,
 | 
				
			||||||
 | 
					                    maybe_nonce,
 | 
				
			||||||
 | 
					                ).await {
 | 
				
			||||||
 | 
					                    self.transactions_to_watch.push(TxToWatch {
 | 
				
			||||||
 | 
					                        tx_progress,
 | 
				
			||||||
 | 
					                        sender: sender_str,
 | 
				
			||||||
 | 
					                        target: ActionTarget::ValidatorLog,
 | 
				
			||||||
 | 
					                    });
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					                Ok(())
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
            _ => Ok(())
 | 
					            _ => Ok(())
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
				
			|||||||
@ -7,10 +7,7 @@ use subxt::{
 | 
				
			|||||||
use tokio::sync::mpsc::UnboundedSender;
 | 
					use tokio::sync::mpsc::UnboundedSender;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
use crate::{
 | 
					use crate::{
 | 
				
			||||||
    action::Action, 
 | 
					    action::Action, casper::{CasperConfig, CasperExtrinsicParamsBuilder}, casper_network::{self, runtime_types}, types::{ActionLevel, ActionTarget} 
 | 
				
			||||||
    types::{ActionLevel, ActionTarget},
 | 
					 | 
				
			||||||
    casper::{CasperExtrinsicParamsBuilder, CasperConfig}, 
 | 
					 | 
				
			||||||
    casper_network, 
 | 
					 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
pub async fn transfer_balance(
 | 
					pub async fn transfer_balance(
 | 
				
			||||||
@ -203,3 +200,68 @@ pub async fn payout_stakers(
 | 
				
			|||||||
            }
 | 
					            }
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					pub async fn set_keys(
 | 
				
			||||||
 | 
					    action_tx: &UnboundedSender<Action>,
 | 
				
			||||||
 | 
					    api: &OnlineClient<CasperConfig>,
 | 
				
			||||||
 | 
					    sender: &[u8; 32],
 | 
				
			||||||
 | 
					    hashed_keys_str: &String,
 | 
				
			||||||
 | 
					    mut maybe_nonce: Option<&mut u32>,
 | 
				
			||||||
 | 
					) -> Result<TxProgress<CasperConfig, OnlineClient<CasperConfig>>> {
 | 
				
			||||||
 | 
					    let (gran_key, babe_key, audi_key, slow_key) = {
 | 
				
			||||||
 | 
					        let s = hashed_keys_str.trim_start_matches("0x");
 | 
				
			||||||
 | 
					        (
 | 
				
			||||||
 | 
					            hex::decode(&s[0..64]).unwrap().as_slice().try_into().unwrap(),
 | 
				
			||||||
 | 
					            hex::decode(&s[64..128]).unwrap().as_slice().try_into().unwrap(),
 | 
				
			||||||
 | 
					            hex::decode(&s[128..192]).unwrap().as_slice().try_into().unwrap(),
 | 
				
			||||||
 | 
					            hex::decode(&s[192..256]).unwrap().as_slice().try_into().unwrap(),
 | 
				
			||||||
 | 
					        )
 | 
				
			||||||
 | 
					    };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    let session_keys = runtime_types::casper_runtime::opaque::SessionKeys {
 | 
				
			||||||
 | 
					        grandpa: runtime_types::sp_consensus_grandpa::app::Public(gran_key),
 | 
				
			||||||
 | 
					        babe: runtime_types::sp_consensus_babe::app::Public(babe_key),
 | 
				
			||||||
 | 
					        authority_discovery: runtime_types::sp_authority_discovery::app::Public(audi_key),
 | 
				
			||||||
 | 
					        slow_clap: runtime_types::ghost_slow_clap::sr25519::app_sr25519::Public(slow_key),
 | 
				
			||||||
 | 
					    };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // it seems like there is no check for the second paramter, that's why
 | 
				
			||||||
 | 
					    // we it can be anything.
 | 
				
			||||||
 | 
					    // Not sure TBH
 | 
				
			||||||
 | 
					    let transfer_tx = casper_network::tx()
 | 
				
			||||||
 | 
					        .session()
 | 
				
			||||||
 | 
					        .set_keys(session_keys, Vec::new());
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    let tx_params = match maybe_nonce {
 | 
				
			||||||
 | 
					        Some(ref mut nonce) => {
 | 
				
			||||||
 | 
					            **nonce = nonce.saturating_add(1);
 | 
				
			||||||
 | 
					            CasperExtrinsicParamsBuilder::new()
 | 
				
			||||||
 | 
					                .nonce(nonce.saturating_sub(1) as u64)
 | 
				
			||||||
 | 
					                .build()
 | 
				
			||||||
 | 
					        },
 | 
				
			||||||
 | 
					        None => CasperExtrinsicParamsBuilder::new().build(),
 | 
				
			||||||
 | 
					    };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    let pair = Pair::from_seed(sender);
 | 
				
			||||||
 | 
					    let signer = PairSigner::<CasperConfig, Pair>::new(pair);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    match api
 | 
				
			||||||
 | 
					        .tx()
 | 
				
			||||||
 | 
					        .sign_and_submit_then_watch(&transfer_tx, &signer, tx_params)
 | 
				
			||||||
 | 
					        .await {
 | 
				
			||||||
 | 
					            Ok(tx_progress) => {
 | 
				
			||||||
 | 
					                action_tx.send(Action::EventLog(
 | 
				
			||||||
 | 
					                        format!("set keys {} sent", tx_progress.extrinsic_hash()),
 | 
				
			||||||
 | 
					                        ActionLevel::Info,
 | 
				
			||||||
 | 
					                        ActionTarget::ValidatorLog))?;
 | 
				
			||||||
 | 
					                Ok(tx_progress)
 | 
				
			||||||
 | 
					            },
 | 
				
			||||||
 | 
					            Err(err) => {
 | 
				
			||||||
 | 
					                action_tx.send(Action::EventLog(
 | 
				
			||||||
 | 
					                        format!("error during set keys: {err}"), 
 | 
				
			||||||
 | 
					                        ActionLevel::Error,
 | 
				
			||||||
 | 
					                        ActionTarget::ValidatorLog))?;
 | 
				
			||||||
 | 
					                Err(err.into())
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
		Reference in New Issue
	
	Block a user