Skip to content

Commit

Permalink
Fix API wallets calls (#1597)
Browse files Browse the repository at this point in the history
* Add API Secret in wallet calls

* File node api secret default to same api secret and directly in http parameter
  • Loading branch information
quentinlesceller authored and hashmap committed Sep 27, 2018
1 parent 5a83989 commit a13c20c
Show file tree
Hide file tree
Showing 18 changed files with 91 additions and 90 deletions.
7 changes: 6 additions & 1 deletion config/src/comments.rs
Original file line number Diff line number Diff line change
Expand Up @@ -326,7 +326,12 @@ fn comments() -> HashMap<String, String> {
#where the wallet should find a running node
".to_string(),
);

retval.insert(
"node_api_secret_path".to_string(),
"
#location of the node api secret for basic auth on the Grin API
".to_string(),
);
retval.insert(
"data_file_dir".to_string(),
"
Expand Down
4 changes: 4 additions & 0 deletions config/src/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -371,6 +371,10 @@ impl GlobalWalletConfig {
secret_path.push(API_SECRET_FILE_NAME);
self.members.as_mut().unwrap().wallet.api_secret_path =
Some(secret_path.to_str().unwrap().to_owned());
let mut node_secret_path = wallet_home.clone();
node_secret_path.push(API_SECRET_FILE_NAME);
self.members.as_mut().unwrap().wallet.node_api_secret_path =
Some(node_secret_path.to_str().unwrap().to_owned());
let mut log_path = wallet_home.clone();
log_path.push(WALLET_LOG_FILE_NAME);
self.members
Expand Down
6 changes: 3 additions & 3 deletions servers/tests/framework/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -263,7 +263,7 @@ impl LocalServerContainer {
let _ = fs::create_dir_all(self.wallet_config.clone().data_file_dir);
let r = wallet::WalletSeed::init_file(&self.wallet_config);

let client = HTTPWalletClient::new(&self.wallet_config.check_node_api_http_addr);
let client = HTTPWalletClient::new(&self.wallet_config.check_node_api_http_addr, None);

if let Err(e) = r {
//panic!("Error initializing wallet seed: {}", e);
Expand Down Expand Up @@ -305,7 +305,7 @@ impl LocalServerContainer {
let keychain: keychain::ExtKeychain = wallet_seed
.derive_keychain("")
.expect("Failed to derive keychain from seed file and passphrase.");
let client = HTTPWalletClient::new(&config.check_node_api_http_addr);
let client = HTTPWalletClient::new(&config.check_node_api_http_addr, None);
let mut wallet = FileWallet::new(config.clone(), "", client)
.unwrap_or_else(|e| panic!("Error creating wallet: {:?} Config: {:?}", e, config));
wallet.keychain = Some(keychain);
Expand All @@ -331,7 +331,7 @@ impl LocalServerContainer {
.derive_keychain("")
.expect("Failed to derive keychain from seed file and passphrase.");

let client = HTTPWalletClient::new(&config.check_node_api_http_addr);
let client = HTTPWalletClient::new(&config.check_node_api_http_addr, None);

let max_outputs = 500;
let change_outputs = 1;
Expand Down
4 changes: 2 additions & 2 deletions servers/tests/simulnet.rs
Original file line number Diff line number Diff line change
Expand Up @@ -423,15 +423,15 @@ fn replicate_tx_fluff_failure() {

// Create Wallet 1 (Mining Input) and start it listening
// Wallet 1 post to another node, just for fun
let client1 = HTTPWalletClient::new("http://127.0.0.1:23003");
let client1 = HTTPWalletClient::new("http://127.0.0.1:23003", None);
let wallet1 = create_wallet("target/tmp/tx_fluff/wallet1", client1.clone());
let wallet1_handle = thread::spawn(move || {
controller::foreign_listener(wallet1, "127.0.0.1:33000")
.unwrap_or_else(|e| panic!("Error creating wallet1 listener: {:?}", e,));
});

// Create Wallet 2 (Recipient) and launch
let client2 = HTTPWalletClient::new("http://127.0.0.1:23001");
let client2 = HTTPWalletClient::new("http://127.0.0.1:23001", None);
let wallet2 = create_wallet("target/tmp/tx_fluff/wallet2", client2.clone());
let wallet2_handle = thread::spawn(move || {
controller::foreign_listener(wallet2, "127.0.0.1:33001")
Expand Down
12 changes: 8 additions & 4 deletions src/bin/cmd/wallet.rs
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ pub fn seed_exists(wallet_config: WalletConfig) -> bool {
pub fn instantiate_wallet(
wallet_config: WalletConfig,
passphrase: &str,
node_api_secret: Option<String>,
) -> Box<WalletInst<HTTPWalletClient, keychain::ExtKeychain>> {
if grin_wallet::needs_migrate(&wallet_config.data_file_dir) {
// Migrate wallet automatically
Expand All @@ -67,7 +68,7 @@ pub fn instantiate_wallet(
warn!(LOGGER, "If anything went wrong, you can try again by deleting the `db` directory and running a wallet command");
warn!(LOGGER, "If all is okay, you can move/backup/delete all files in the wallet directory EXCEPT FOR wallet.seed");
}
let client = HTTPWalletClient::new(&wallet_config.check_node_api_http_addr);
let client = HTTPWalletClient::new(&wallet_config.check_node_api_http_addr, node_api_secret);
let db_wallet = LMDBBackend::new(wallet_config.clone(), "", client).unwrap_or_else(|e| {
panic!(
"Error creating DB wallet: {} Config: {:?}",
Expand Down Expand Up @@ -102,13 +103,15 @@ pub fn wallet_command(wallet_args: &ArgMatches, config: GlobalWalletConfig) {
if wallet_args.is_present("show_spent") {
show_spent = true;
}
let node_api_secret = get_first_line(wallet_config.node_api_secret_path.clone());

// Derive the keychain based on seed from seed file and specified passphrase.
// Generate the initial wallet seed if we are running "wallet init".
if let ("init", Some(_)) = wallet_args.subcommand() {
WalletSeed::init_file(&wallet_config).expect("Failed to init wallet seed file.");
info!(LOGGER, "Wallet seed file created");
let client = HTTPWalletClient::new(&wallet_config.check_node_api_http_addr);
let client =
HTTPWalletClient::new(&wallet_config.check_node_api_http_addr, node_api_secret);
let _: LMDBBackend<HTTPWalletClient, keychain::ExtKeychain> =
LMDBBackend::new(wallet_config.clone(), "", client).unwrap_or_else(|e| {
panic!(
Expand All @@ -126,11 +129,11 @@ pub fn wallet_command(wallet_args: &ArgMatches, config: GlobalWalletConfig) {
let passphrase = wallet_args
.value_of("pass")
.expect("Failed to read passphrase.");

// Handle listener startup commands
{
let wallet = instantiate_wallet(wallet_config.clone(), passphrase);
let wallet = instantiate_wallet(wallet_config.clone(), passphrase, node_api_secret.clone());
let api_secret = get_first_line(wallet_config.api_secret_path.clone());

match wallet_args.subcommand() {
("listen", Some(listen_args)) => {
if let Some(port) = listen_args.value_of("port") {
Expand Down Expand Up @@ -174,6 +177,7 @@ pub fn wallet_command(wallet_args: &ArgMatches, config: GlobalWalletConfig) {
let wallet = Arc::new(Mutex::new(instantiate_wallet(
wallet_config.clone(),
passphrase,
node_api_secret,
)));
let res = controller::owner_single_use(wallet.clone(), |api| {
match wallet_args.subcommand() {
Expand Down
6 changes: 2 additions & 4 deletions src/bin/tui/menu.rs
Original file line number Diff line number Diff line change
Expand Up @@ -63,13 +63,11 @@ pub fn create() -> Box<View> {
let mut s: ViewRef<SelectView<&str>> = c.find_id(MAIN_MENU).unwrap();
s.select_down(1)(c);
Some(EventResult::Consumed(None));
})
.on_pre_event('k', move |c| {
}).on_pre_event('k', move |c| {
let mut s: ViewRef<SelectView<&str>> = c.find_id(MAIN_MENU).unwrap();
s.select_up(1)(c);
Some(EventResult::Consumed(None));
})
.on_pre_event(Key::Tab, move |c| {
}).on_pre_event(Key::Tab, move |c| {
let mut s: ViewRef<SelectView<&str>> = c.find_id(MAIN_MENU).unwrap();
if s.selected_id().unwrap() == s.len() - 1 {
s.set_selection(0)(c);
Expand Down
57 changes: 19 additions & 38 deletions src/bin/tui/mining.rs
Original file line number Diff line number Diff line change
Expand Up @@ -170,52 +170,40 @@ impl TUIStatusListener for TUIMiningView {
let table_view = TableView::<WorkerStats, StratumWorkerColumn>::new()
.column(StratumWorkerColumn::Id, "Worker ID", |c| {
c.width_percent(10)
})
.column(StratumWorkerColumn::IsConnected, "Connected", |c| {
}).column(StratumWorkerColumn::IsConnected, "Connected", |c| {
c.width_percent(10)
})
.column(StratumWorkerColumn::LastSeen, "Last Seen", |c| {
}).column(StratumWorkerColumn::LastSeen, "Last Seen", |c| {
c.width_percent(20)
})
.column(StratumWorkerColumn::PowDifficulty, "Pow Difficulty", |c| {
}).column(StratumWorkerColumn::PowDifficulty, "Pow Difficulty", |c| {
c.width_percent(10)
})
.column(StratumWorkerColumn::NumAccepted, "Num Accepted", |c| {
}).column(StratumWorkerColumn::NumAccepted, "Num Accepted", |c| {
c.width_percent(10)
})
.column(StratumWorkerColumn::NumRejected, "Num Rejected", |c| {
}).column(StratumWorkerColumn::NumRejected, "Num Rejected", |c| {
c.width_percent(10)
})
.column(StratumWorkerColumn::NumStale, "Num Stale", |c| {
}).column(StratumWorkerColumn::NumStale, "Num Stale", |c| {
c.width_percent(10)
});

let status_view = LinearLayout::new(Orientation::Vertical)
.child(
LinearLayout::new(Orientation::Horizontal)
.child(TextView::new(" ").with_id("stratum_config_status")),
)
.child(
).child(
LinearLayout::new(Orientation::Horizontal)
.child(TextView::new(" ").with_id("stratum_is_running_status")),
)
.child(
).child(
LinearLayout::new(Orientation::Horizontal)
.child(TextView::new(" ").with_id("stratum_num_workers_status")),
)
.child(
).child(
LinearLayout::new(Orientation::Horizontal)
.child(TextView::new(" ").with_id("stratum_block_height_status")),
)
.child(
).child(
LinearLayout::new(Orientation::Horizontal)
.child(TextView::new(" ").with_id("stratum_network_difficulty_status")),
)
.child(
).child(
LinearLayout::new(Orientation::Horizontal)
.child(TextView::new(" ").with_id("stratum_network_hashrate")),
)
.child(
).child(
LinearLayout::new(Orientation::Horizontal)
.child(TextView::new(" ").with_id("stratum_cuckoo_size_status")),
);
Expand All @@ -225,26 +213,22 @@ impl TUIStatusListener for TUIMiningView {
.child(BoxView::with_full_screen(
Dialog::around(table_view.with_id(TABLE_MINING_STATUS).min_size((50, 20)))
.title("Mining Workers"),
))
.with_id("mining_device_view");
)).with_id("mining_device_view");

let diff_status_view = LinearLayout::new(Orientation::Vertical)
.child(
LinearLayout::new(Orientation::Horizontal)
.child(TextView::new("Tip Height: "))
.child(TextView::new("").with_id("diff_cur_height")),
)
.child(
).child(
LinearLayout::new(Orientation::Horizontal)
.child(TextView::new("Difficulty Adjustment Window: "))
.child(TextView::new("").with_id("diff_adjust_window")),
)
.child(
).child(
LinearLayout::new(Orientation::Horizontal)
.child(TextView::new("Average Block Time: "))
.child(TextView::new("").with_id("diff_avg_block_time")),
)
.child(
).child(
LinearLayout::new(Orientation::Horizontal)
.child(TextView::new("Average Difficulty: "))
.child(TextView::new("").with_id("diff_avg_difficulty")),
Expand All @@ -253,11 +237,9 @@ impl TUIStatusListener for TUIMiningView {
let diff_table_view = TableView::<DiffBlock, DiffColumn>::new()
.column(DiffColumn::BlockNumber, "Block Number", |c| {
c.width_percent(25)
})
.column(DiffColumn::Difficulty, "Network Difficulty", |c| {
}).column(DiffColumn::Difficulty, "Network Difficulty", |c| {
c.width_percent(25)
})
.column(DiffColumn::Time, "Block Time", |c| c.width_percent(25))
}).column(DiffColumn::Time, "Block Time", |c| c.width_percent(25))
.column(DiffColumn::Duration, "Duration", |c| c.width_percent(25));

let mining_difficulty_view = LinearLayout::new(Orientation::Vertical)
Expand All @@ -268,8 +250,7 @@ impl TUIStatusListener for TUIMiningView {
.with_id(TABLE_MINING_DIFF_STATUS)
.min_size((50, 20)),
).title("Mining Difficulty Data"),
))
.with_id("mining_difficulty_view");
)).with_id("mining_difficulty_view");

let view_stack = StackView::new()
.layer(mining_difficulty_view)
Expand Down
9 changes: 3 additions & 6 deletions src/bin/tui/peers.rs
Original file line number Diff line number Diff line change
Expand Up @@ -86,21 +86,18 @@ impl TUIStatusListener for TUIPeerView {
.column(PeerColumn::Direction, "Direction", |c| c.width_percent(20))
.column(PeerColumn::TotalDifficulty, "Total Difficulty", |c| {
c.width_percent(20)
})
.column(PeerColumn::Version, "Version", |c| c.width_percent(20));
}).column(PeerColumn::Version, "Version", |c| c.width_percent(20));
let peer_status_view = BoxView::with_full_screen(
LinearLayout::new(Orientation::Vertical)
.child(
LinearLayout::new(Orientation::Horizontal)
.child(TextView::new("Total Peers: "))
.child(TextView::new(" ").with_id("peers_total")),
)
.child(
).child(
LinearLayout::new(Orientation::Horizontal)
.child(TextView::new("Longest Chain: "))
.child(TextView::new(" ").with_id("longest_work_peer")),
)
.child(TextView::new(" "))
).child(TextView::new(" "))
.child(
Dialog::around(table_view.with_id(TABLE_PEER_STATUS).min_size((50, 20)))
.title("Connected Peers"),
Expand Down
21 changes: 7 additions & 14 deletions src/bin/tui/status.rs
Original file line number Diff line number Diff line change
Expand Up @@ -37,35 +37,28 @@ impl TUIStatusListener for TUIStatusView {
LinearLayout::new(Orientation::Horizontal)
.child(TextView::new("Current Status: "))
.child(TextView::new("Starting").with_id("basic_current_status")),
)
.child(
).child(
LinearLayout::new(Orientation::Horizontal)
.child(TextView::new("Connected Peers: "))
.child(TextView::new("0").with_id("connected_peers")),
)
.child(
).child(
LinearLayout::new(Orientation::Horizontal)
.child(TextView::new("Chain Height: "))
.child(TextView::new(" ").with_id("chain_height")),
)
.child(
).child(
LinearLayout::new(Orientation::Horizontal)
.child(TextView::new("Total Difficulty: "))
.child(TextView::new(" ").with_id("basic_total_difficulty")),
)
.child(
).child(
LinearLayout::new(Orientation::Horizontal)
.child(TextView::new("------------------------")),
)
.child(
).child(
LinearLayout::new(Orientation::Horizontal)
.child(TextView::new(" ").with_id("basic_mining_config_status")),
)
.child(
).child(
LinearLayout::new(Orientation::Horizontal)
.child(TextView::new(" ").with_id("basic_mining_status")),
)
.child(
).child(
LinearLayout::new(Orientation::Horizontal)
.child(TextView::new(" ").with_id("basic_network_info")),
), //.child(logo_view)
Expand Down
15 changes: 10 additions & 5 deletions wallet/src/client.rs
Original file line number Diff line number Diff line change
Expand Up @@ -32,13 +32,15 @@ use util::{self, LOGGER};
#[derive(Clone)]
pub struct HTTPWalletClient {
node_url: String,
node_api_secret: Option<String>,
}

impl HTTPWalletClient {
/// Create a new client that will communicate with the given grin node
pub fn new(node_url: &str) -> HTTPWalletClient {
pub fn new(node_url: &str, node_api_secret: Option<String>) -> HTTPWalletClient {
HTTPWalletClient {
node_url: node_url.to_owned(),
node_api_secret: node_api_secret,
}
}
}
Expand All @@ -47,6 +49,9 @@ impl WalletClient for HTTPWalletClient {
fn node_url(&self) -> &str {
&self.node_url
}
fn node_api_secret(&self) -> Option<String> {
self.node_api_secret.clone()
}

/// Call the wallet API to create a coinbase output for the given
/// block_fees. Will retry based on default "retry forever with backoff"
Expand Down Expand Up @@ -101,7 +106,7 @@ impl WalletClient for HTTPWalletClient {
} else {
url = format!("{}/v1/pool/push", dest);
}
api::client::post_no_ret(url.as_str(), None, tx).context(
api::client::post_no_ret(url.as_str(), self.node_api_secret(), tx).context(
libwallet::ErrorKind::ClientCallback("Posting transaction to node"),
)?;
Ok(())
Expand All @@ -111,7 +116,7 @@ impl WalletClient for HTTPWalletClient {
fn get_chain_height(&self) -> Result<u64, libwallet::Error> {
let addr = self.node_url();
let url = format!("{}/v1/chain", addr);
let res = api::client::get::<api::Tip>(url.as_str(), None).context(
let res = api::client::get::<api::Tip>(url.as_str(), self.node_api_secret()).context(
libwallet::ErrorKind::ClientCallback("Getting chain height from node"),
)?;
Ok(res.height)
Expand All @@ -138,7 +143,7 @@ impl WalletClient for HTTPWalletClient {
let url = format!("{}/v1/chain/outputs/byids?{}", addr, query_chunk.join("&"),);
tasks.push(api::client::get_async::<Vec<api::Output>>(
url.as_str(),
None,
self.node_api_secret(),
));
}

Expand Down Expand Up @@ -184,7 +189,7 @@ impl WalletClient for HTTPWalletClient {
let mut api_outputs: Vec<(pedersen::Commitment, pedersen::RangeProof, bool, u64)> =
Vec::new();

match api::client::get::<api::OutputListing>(url.as_str(), None) {
match api::client::get::<api::OutputListing>(url.as_str(), self.node_api_secret()) {
Ok(o) => {
for out in o.outputs {
let is_coinbase = match out.output_type {
Expand Down
Loading

0 comments on commit a13c20c

Please sign in to comment.