Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[console-wallet] Update app state after setting base node via command. Allow amount field to parse Tari. #3019

Merged
merged 3 commits into from
Jun 24, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions applications/tari_console_wallet/src/automation/commands.rs
Original file line number Diff line number Diff line change
Expand Up @@ -577,7 +577,6 @@ pub async fn command_runner(
},
SetCustomBaseNode => {
let (public_key, net_address) = set_base_node_peer(wallet.clone(), &parsed.args).await?;
println!("Saving custom base node peer in wallet database.");
wallet
.db
.set_client_key_value(CUSTOM_BASE_NODE_PUBLIC_KEY_KEY.to_string(), public_key.to_string())
Expand All @@ -586,9 +585,9 @@ pub async fn command_runner(
.db
.set_client_key_value(CUSTOM_BASE_NODE_ADDRESS_KEY.to_string(), net_address.to_string())
.await?;
println!("Custom base node peer saved in wallet database.");
},
ClearCustomBaseNode => {
println!("Clearing custom base node peer in wallet database.");
wallet
.db
.clear_client_value(CUSTOM_BASE_NODE_PUBLIC_KEY_KEY.to_string())
Expand All @@ -597,6 +596,7 @@ pub async fn command_runner(
.db
.clear_client_value(CUSTOM_BASE_NODE_ADDRESS_KEY.to_string())
.await?;
println!("Custom base node peer cleared from wallet database.");
},
}
}
Expand Down
2 changes: 1 addition & 1 deletion applications/tari_console_wallet/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -135,7 +135,7 @@ fn main_inner() -> Result<(), ExitCodes> {
let config = WalletModeConfig {
base_node_config,
base_node_selected,
daemon_mode: bootstrap.daemon_mode,
bootstrap,
global_config,
handle,
notify_script,
Expand Down
2 changes: 0 additions & 2 deletions applications/tari_console_wallet/src/ui/app.rs
Original file line number Diff line number Diff line change
Expand Up @@ -49,8 +49,6 @@ use tui::{
};

pub const LOG_TARGET: &str = "wallet::ui::app";
pub const CUSTOM_BASE_NODE_PUBLIC_KEY_KEY: &str = "console_wallet_custom_base_node_public_key";
pub const CUSTOM_BASE_NODE_ADDRESS_KEY: &str = "console_wallet_custom_base_node_address";

pub struct App<B: Backend> {
pub title: String,
Expand Down
24 changes: 24 additions & 0 deletions applications/tari_console_wallet/src/ui/components/network_tab.rs
Original file line number Diff line number Diff line change
Expand Up @@ -426,6 +426,30 @@ impl<B: Backend> Component<B> for NetworkTab {
self.detailed_base_node = app_state.get_base_node_list().get(0).map(|(_, peer)| peer.clone());
}
},
's' => {
// set the currently selected base node as a custom base node
let base_node = app_state.get_selected_base_node();
let public_key = base_node.public_key.to_hex();
let address = base_node
.addresses
.first()
.map(|a| a.to_string())
.unwrap_or_else(|| "".to_string());

match Handle::current().block_on(app_state.set_custom_base_node(public_key, address)) {
Ok(peer) => {
self.previous_address_field = self.address_field.clone();
self.previous_public_key_field = self.public_key_field.clone();
self.detailed_base_node = Some(peer);
},
Err(e) => {
warn!(target: LOG_TARGET, "Could not set custom base node peer: {}", e);
self.error_message = Some(format!("Error setting new Base Node Address:\n{}", e.to_string()));
self.address_field = self.previous_address_field.clone();
self.public_key_field = self.previous_public_key_field.clone();
},
}
},
_ => {},
}
}
Expand Down
19 changes: 11 additions & 8 deletions applications/tari_console_wallet/src/ui/components/send_tab.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ use crate::{
},
utils::formatting::display_compressed_string,
};
use tari_core::transactions::tari_amount::MicroTari;
use tari_wallet::types::DEFAULT_FEE_PER_GRAM;
use tokio::{runtime::Handle, sync::watch};
use tui::{
Expand Down Expand Up @@ -131,7 +132,7 @@ impl SendTab {
SendInputMode::Amount => Style::default().fg(Color::Magenta),
_ => Style::default(),
})
.block(Block::default().borders(Borders::ALL).title("(A)mount (uT):"));
.block(Block::default().borders(Borders::ALL).title("(A)mount (uT or T):"));
f.render_widget(amount_input, amount_fee_layout[0]);

let fee_input = Paragraph::new(self.fee_field.as_ref())
Expand Down Expand Up @@ -315,7 +316,7 @@ impl SendTab {
Some(ConfirmationDialogType::ConfirmNormalSend) |
Some(ConfirmationDialogType::ConfirmOneSidedSend) => {
if 'y' == c {
let amount = if let Ok(v) = self.amount_field.parse::<u64>() {
let amount = if let Ok(v) = self.amount_field.parse::<MicroTari>() {
v
} else {
self.error_message =
Expand All @@ -337,7 +338,7 @@ impl SendTab {
if one_sided_transaction {
match Handle::current().block_on(app_state.send_one_sided_transaction(
self.to_field.clone(),
amount,
amount.into(),
fee_per_gram,
self.message_field.clone(),
tx,
Expand All @@ -353,7 +354,7 @@ impl SendTab {
} else {
match Handle::current().block_on(app_state.send_transaction(
self.to_field.clone(),
amount,
amount.into(),
fee_per_gram,
self.message_field.clone(),
tx,
Expand Down Expand Up @@ -408,7 +409,7 @@ impl SendTab {
match self.send_input_mode {
SendInputMode::None => (),
SendInputMode::To => match c {
'\n' | '\t' => {
'\n' => {
self.send_input_mode = SendInputMode::Amount;
},
c => {
Expand All @@ -419,7 +420,8 @@ impl SendTab {
SendInputMode::Amount => match c {
'\n' => self.send_input_mode = SendInputMode::Message,
c => {
if c.is_numeric() {
let symbols = &['t', 'T', 'u', 'U'];
if c.is_numeric() || symbols.contains(&c) {
self.amount_field.push(c);
}
return KeyHandled::Handled;
Expand Down Expand Up @@ -692,8 +694,9 @@ impl<B: Backend> Component<B> for SendTab {
);
return;
}
if self.amount_field.parse::<u64>().is_err() {
self.error_message = Some("Amount should be an integer\nPress Enter to continue.".to_string());
if self.amount_field.parse::<MicroTari>().is_err() {
self.error_message =
Some("Amount should be a valid amount of Tari\nPress Enter to continue.".to_string());
return;
};

Expand Down
1 change: 1 addition & 0 deletions applications/tari_console_wallet/src/ui/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@ pub fn run(app: App<CrosstermBackend<Stdout>>) -> Result<(), ExitCodes> {
app.app_state.refresh_contacts_state().await?;
trace!(target: LOG_TARGET, "Refreshing connected peers state");
app.app_state.refresh_connected_peers_state().await?;
trace!(target: LOG_TARGET, "Starting app state event monitor");
app.app_state.start_event_monitor(app.notifier.clone()).await;
Result::<_, UiError>::Ok(())
})
Expand Down
3 changes: 1 addition & 2 deletions applications/tari_console_wallet/src/ui/state/app_state.rs
Original file line number Diff line number Diff line change
Expand Up @@ -29,9 +29,8 @@ use crate::{
},
UiContact,
UiError,
CUSTOM_BASE_NODE_ADDRESS_KEY,
CUSTOM_BASE_NODE_PUBLIC_KEY_KEY,
},
utils::db::{CUSTOM_BASE_NODE_ADDRESS_KEY, CUSTOM_BASE_NODE_PUBLIC_KEY_KEY},
wallet_modes::PeerConfig,
};
use futures::{stream::Fuse, StreamExt};
Expand Down
4 changes: 2 additions & 2 deletions applications/tari_console_wallet/src/utils/db.rs
Original file line number Diff line number Diff line change
Expand Up @@ -33,8 +33,8 @@ pub const LOG_TARGET: &str = "wallet::utils::db";
pub const CUSTOM_BASE_NODE_PUBLIC_KEY_KEY: &str = "console_wallet_custom_base_node_public_key";
pub const CUSTOM_BASE_NODE_ADDRESS_KEY: &str = "console_wallet_custom_base_node_address";

/// This helper function will attempt to read a stored base node public key and address from the wallet database if
/// possible. If both are found they are used to construct and return a Peer.
/// This helper function will attempt to read a stored base node public key and address from the wallet database.
/// If both are found they are used to construct and return a Peer.
pub async fn get_custom_base_node_peer_from_db(wallet: &mut WalletSqlite) -> Option<Peer> {
let custom_base_node_peer_pubkey = match wallet
.db
Expand Down
34 changes: 26 additions & 8 deletions applications/tari_console_wallet/src/wallet_modes.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,12 +26,13 @@ use crate::{
recovery::wallet_recovery,
ui,
ui::App,
utils::db::get_custom_base_node_peer_from_db,
};
use log::*;
use rand::{rngs::OsRng, seq::SliceRandom};
use std::{fs, io::Stdout, net::SocketAddr, path::PathBuf};
use tari_app_utilities::utilities::ExitCodes;
use tari_common::GlobalConfig;
use tari_common::{ConfigBootstrap, GlobalConfig};
use tari_comms::peer_manager::Peer;
use tari_wallet::WalletSqlite;
use tokio::runtime::Handle;
Expand All @@ -55,7 +56,7 @@ pub enum WalletMode {
pub struct WalletModeConfig {
pub base_node_config: PeerConfig,
pub base_node_selected: Peer,
pub daemon_mode: bool,
pub bootstrap: ConfigBootstrap,
pub global_config: GlobalConfig,
pub handle: Handle,
pub notify_script: Option<PathBuf>,
Expand Down Expand Up @@ -106,6 +107,8 @@ impl PeerConfig {
}
}

/// Returns all the peers from the PeerConfig.
/// In order: Custom base node, service peers, peer seeds.
pub fn get_all_peers(&self) -> Vec<Peer> {
let num_peers = self.base_node_peers.len();
let num_seeds = self.peer_seeds.len();
Expand Down Expand Up @@ -170,10 +173,16 @@ pub fn script_mode(config: WalletModeConfig, wallet: WalletSqlite, path: PathBuf
wallet_or_exit(config, wallet)
}

/// Prompts the user to continue to the wallet, or exit.
fn wallet_or_exit(config: WalletModeConfig, wallet: WalletSqlite) -> Result<(), ExitCodes> {
if config.daemon_mode {
info!(target: LOG_TARGET, "Daemon mode detected - auto exiting.");
Ok(())
if config.bootstrap.command_mode_auto_exit {
info!(target: LOG_TARGET, "Auto exit argument supplied - exiting.");
return Ok(());
}

if config.bootstrap.daemon_mode {
info!(target: LOG_TARGET, "Starting GRPC server.");
grpc_mode(config, wallet)
} else {
debug!(target: LOG_TARGET, "Prompting for run or exit key.");
println!("\nPress Enter to continue to the wallet, or type q (or quit) followed by Enter.");
Expand All @@ -195,10 +204,10 @@ fn wallet_or_exit(config: WalletModeConfig, wallet: WalletSqlite) -> Result<(),
}
}

pub fn tui_mode(config: WalletModeConfig, wallet: WalletSqlite) -> Result<(), ExitCodes> {
pub fn tui_mode(config: WalletModeConfig, mut wallet: WalletSqlite) -> Result<(), ExitCodes> {
let WalletModeConfig {
base_node_config,
base_node_selected,
mut base_node_config,
mut base_node_selected,
global_config,
handle,
notify_script,
Expand All @@ -209,6 +218,15 @@ pub fn tui_mode(config: WalletModeConfig, wallet: WalletSqlite) -> Result<(), Ex

let notifier = Notifier::new(notify_script, handle.clone(), wallet.clone());

// update the selected/custom base node since it may have been changed by script/command mode
let base_node_custom = handle.block_on(get_custom_base_node_peer_from_db(&mut wallet));
base_node_config.base_node_custom = base_node_custom.clone();
if let Some(peer) = base_node_custom {
base_node_selected = peer;
} else if let Some(peer) = handle.block_on(wallet.get_base_node_peer())? {
base_node_selected = peer;
}

let app = App::<CrosstermBackend<Stdout>>::new(
"Tari Console Wallet".into(),
wallet,
Expand Down
9 changes: 9 additions & 0 deletions base_layer/wallet/src/base_node_service/handle.rs
Original file line number Diff line number Diff line change
Expand Up @@ -37,12 +37,14 @@ pub type BaseNodeEventReceiver = broadcast::Receiver<Arc<BaseNodeEvent>>;
pub enum BaseNodeServiceRequest {
GetChainMetadata,
SetBaseNodePeer(Box<Peer>),
GetBaseNodePeer,
}
/// API Response enum
#[derive(Debug)]
pub enum BaseNodeServiceResponse {
ChainMetadata(Option<ChainMetadata>),
BaseNodePeerSet,
BaseNodePeer(Option<Box<Peer>>),
}
#[derive(Clone, Debug, Hash, PartialEq, Eq)]
pub enum BaseNodeEvent {
Expand Down Expand Up @@ -90,4 +92,11 @@ impl BaseNodeServiceHandle {
_ => Err(BaseNodeServiceError::UnexpectedApiResponse),
}
}

pub async fn get_base_node_peer(&mut self) -> Result<Option<Peer>, BaseNodeServiceError> {
match self.handle.call(BaseNodeServiceRequest::GetBaseNodePeer).await?? {
BaseNodeServiceResponse::BaseNodePeer(peer) => Ok(peer.map(|p| *p)),
_ => Err(BaseNodeServiceError::UnexpectedApiResponse),
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -121,6 +121,10 @@ impl MockBaseNodeService {
self.set_base_node_peer(*peer);
Ok(BaseNodeServiceResponse::BaseNodePeerSet)
},
BaseNodeServiceRequest::GetBaseNodePeer => {
let peer = self.state.base_node_peer.clone();
Ok(BaseNodeServiceResponse::BaseNodePeer(peer.map(Box::new)))
},
BaseNodeServiceRequest::GetChainMetadata => Ok(BaseNodeServiceResponse::ChainMetadata(
self.state.chain_metadata.clone(),
)),
Expand Down
4 changes: 4 additions & 0 deletions base_layer/wallet/src/base_node_service/service.rs
Original file line number Diff line number Diff line change
Expand Up @@ -187,6 +187,10 @@ where T: WalletBackend + 'static
self.set_base_node_peer(*peer).await;
Ok(BaseNodeServiceResponse::BaseNodePeerSet)
},
BaseNodeServiceRequest::GetBaseNodePeer => {
let peer = self.get_state().await.base_node_peer.map(Box::new);
Ok(BaseNodeServiceResponse::BaseNodePeer(peer))
},
BaseNodeServiceRequest::GetChainMetadata => match self.get_state().await.chain_metadata.clone() {
Some(metadata) => Ok(BaseNodeServiceResponse::ChainMetadata(Some(metadata))),
None => {
Expand Down
9 changes: 8 additions & 1 deletion base_layer/wallet/src/wallet.rs
Original file line number Diff line number Diff line change
Expand Up @@ -250,7 +250,7 @@ where
self.comms.clone().wait_until_shutdown().await;
}

/// This function will set the base_node that the wallet uses to broadcast transactions, monitor outputs, and
/// This function will set the base node that the wallet uses to broadcast transactions, monitor outputs, and
/// monitor the base node state.
pub async fn set_base_node_peer(
&mut self,
Expand Down Expand Up @@ -296,6 +296,13 @@ where
Ok(())
}

pub async fn get_base_node_peer(&mut self) -> Result<Option<Peer>, WalletError> {
self.base_node_service
.get_base_node_peer()
.await
.map_err(WalletError::BaseNodeServiceError)
}

/// Import an external spendable UTXO into the wallet. The output will be added to the Output Manager and made
/// spendable. A faux incoming transaction will be created to provide a record of the event. The TxId of the
/// generated transaction is returned.
Expand Down
Loading