Fix get outputs call in wallet (#1319)

* Fix get outputs call in wallet. It generates an invalid url if there are 1000+ outputs.
* Also switched to async http client for performance reasons
* Couple unrelated cleanups
* fixup! Fix get outputs call in wallet
This commit is contained in:
hashmap 2018-08-06 21:48:05 +02:00 committed by Ignotus Peverell
parent 498ea9718e
commit 414a30224e
3 changed files with 22 additions and 13 deletions

View file

@ -5,7 +5,6 @@ use hyper::{Body, Method, Request, Response, StatusCode};
use std::collections::hash_map::DefaultHasher; use std::collections::hash_map::DefaultHasher;
use std::hash::{Hash, Hasher}; use std::hash::{Hash, Hasher};
use std::sync::Arc; use std::sync::Arc;
use util::LOGGER;
lazy_static! { lazy_static! {
static ref WILDCARD_HASH: u64 = calculate_hash(&"*"); static ref WILDCARD_HASH: u64 = calculate_hash(&"*");
@ -141,7 +140,6 @@ impl Router {
for key in keys { for key in keys {
node_id = self.find(node_id, key).ok_or(RouterError::RouteNotFound)?; node_id = self.find(node_id, key).ok_or(RouterError::RouteNotFound)?;
if self.node(node_id).key == *WILDCARD_STOP_HASH { if self.node(node_id).key == *WILDCARD_STOP_HASH {
debug!(LOGGER, "ROUTER stop card");
break; break;
} }
} }

View file

@ -16,8 +16,11 @@
//! specific to the FileWallet //! specific to the FileWallet
use failure::ResultExt; use failure::ResultExt;
use futures::{stream, Stream};
use libwallet::types::*; use libwallet::types::*;
use std::collections::HashMap; use std::collections::HashMap;
use tokio::runtime::Runtime;
use api; use api;
use error::{Error, ErrorKind}; use error::{Error, ErrorKind};
@ -129,19 +132,27 @@ impl WalletClient for HTTPWalletClient {
// build a map of api outputs by commit so we can look them up efficiently // build a map of api outputs by commit so we can look them up efficiently
let mut api_outputs: HashMap<pedersen::Commitment, String> = HashMap::new(); let mut api_outputs: HashMap<pedersen::Commitment, String> = HashMap::new();
let mut tasks = Vec::new();
for query_chunk in query_params.chunks(1000) { for query_chunk in query_params.chunks(500) {
let url = format!("{}/v1/chain/outputs/byids?{}", addr, query_chunk.join("&"),); let url = format!("{}/v1/chain/outputs/byids?{}", addr, query_chunk.join("&"),);
tasks.push(api::client::get_async::<Vec<api::Output>>(url.as_str()));
}
match api::client::get::<Vec<api::Output>>(url.as_str()) { let task = stream::futures_unordered(tasks).collect();
Ok(outputs) => for out in outputs {
api_outputs.insert(out.commit.commit(), util::to_hex(out.commit.to_vec())); let mut rt = Runtime::new().unwrap();
}, let results = match rt.block_on(task) {
Err(_) => { Ok(outputs) => outputs,
// if we got anything other than 200 back from server, don't attempt to refresh Err(e) => {
// the wallet data after error!(LOGGER, "Outputs by id failed: {}", e);
return Err(libwallet::ErrorKind::ClientCallback("Error from server"))?; return Err(libwallet::ErrorKind::ClientCallback("Error from server"))?;
} }
};
for res in results {
for out in res {
api_outputs.insert(out.commit.commit(), util::to_hex(out.commit.to_vec()));
} }
} }
Ok(api_outputs) Ok(api_outputs)

View file

@ -32,7 +32,7 @@ use keychain::Keychain;
use libtx::slate::Slate; use libtx::slate::Slate;
use libwallet::api::{APIForeign, APIOwner}; use libwallet::api::{APIForeign, APIOwner};
use libwallet::types::{ use libwallet::types::{
BlockFees, CbData, OutputData, SendTXArgs, TxLogEntry, WalletBackend, WalletClient, WalletInfo, CbData, OutputData, SendTXArgs, TxLogEntry, WalletBackend, WalletClient, WalletInfo,
}; };
use libwallet::{Error, ErrorKind}; use libwallet::{Error, ErrorKind};
use url::form_urlencoded; use url::form_urlencoded;