Merge pull request #3271

a7266d6d wallet2+cli+rpc: eliminate redundant m_http_client from cli/rpc and delegate calls to wallet2 (stoffu)
71d18656 replace invoke_http_json("/json_rpc",...) with invoke_http_json_rpc("/json_rpc",methodname,...) to reduce boilerplate (stoffu)
This commit is contained in:
Riccardo Spagni 2018-03-15 17:07:03 +02:00
commit a3f0292c06
No known key found for this signature in database
GPG Key ID: 55432DF31CCD4FCD
7 changed files with 131 additions and 159 deletions

View File

@ -2683,7 +2683,6 @@ bool simple_wallet::init(const boost::program_options::variables_map& vm)
if (!m_trusted_daemon) if (!m_trusted_daemon)
message_writer() << (boost::format(tr("Warning: using an untrusted daemon at %s, privacy will be lessened")) % m_wallet->get_daemon_address()).str(); message_writer() << (boost::format(tr("Warning: using an untrusted daemon at %s, privacy will be lessened")) % m_wallet->get_daemon_address()).str();
m_http_client.set_server(m_wallet->get_daemon_address(), m_wallet->get_daemon_login());
m_wallet->callback(this); m_wallet->callback(this);
return true; return true;
@ -3216,7 +3215,7 @@ bool simple_wallet::start_mining(const std::vector<std::string>& args)
} }
COMMAND_RPC_START_MINING::response res; COMMAND_RPC_START_MINING::response res;
bool r = net_utils::invoke_http_json("/start_mining", req, res, m_http_client); bool r = m_wallet->invoke_http_json("/start_mining", req, res);
std::string err = interpret_rpc_response(r, res.status); std::string err = interpret_rpc_response(r, res.status);
if (err.empty()) if (err.empty())
success_msg_writer() << tr("Mining started in daemon"); success_msg_writer() << tr("Mining started in daemon");
@ -3238,7 +3237,7 @@ bool simple_wallet::stop_mining(const std::vector<std::string>& args)
COMMAND_RPC_STOP_MINING::request req; COMMAND_RPC_STOP_MINING::request req;
COMMAND_RPC_STOP_MINING::response res; COMMAND_RPC_STOP_MINING::response res;
bool r = net_utils::invoke_http_json("/stop_mining", req, res, m_http_client); bool r = m_wallet->invoke_http_json("/stop_mining", req, res);
std::string err = interpret_rpc_response(r, res.status); std::string err = interpret_rpc_response(r, res.status);
if (err.empty()) if (err.empty())
success_msg_writer() << tr("Mining stopped in daemon"); success_msg_writer() << tr("Mining stopped in daemon");
@ -3295,7 +3294,7 @@ bool simple_wallet::save_bc(const std::vector<std::string>& args)
} }
COMMAND_RPC_SAVE_BC::request req; COMMAND_RPC_SAVE_BC::request req;
COMMAND_RPC_SAVE_BC::response res; COMMAND_RPC_SAVE_BC::response res;
bool r = net_utils::invoke_http_json("/save_bc", req, res, m_http_client); bool r = m_wallet->invoke_http_json("/save_bc", req, res);
std::string err = interpret_rpc_response(r, res.status); std::string err = interpret_rpc_response(r, res.status);
if (err.empty()) if (err.empty())
success_msg_writer() << tr("Blockchain saved"); success_msg_writer() << tr("Blockchain saved");
@ -3641,7 +3640,7 @@ uint64_t simple_wallet::get_daemon_blockchain_height(std::string& err)
COMMAND_RPC_GET_HEIGHT::request req; COMMAND_RPC_GET_HEIGHT::request req;
COMMAND_RPC_GET_HEIGHT::response res = boost::value_initialized<COMMAND_RPC_GET_HEIGHT::response>(); COMMAND_RPC_GET_HEIGHT::response res = boost::value_initialized<COMMAND_RPC_GET_HEIGHT::response>();
bool r = net_utils::invoke_http_json("/getheight", req, res, m_http_client); bool r = m_wallet->invoke_http_json("/getheight", req, res);
err = interpret_rpc_response(r, res.status); err = interpret_rpc_response(r, res.status);
return res.height; return res.height;
} }
@ -3763,7 +3762,7 @@ bool simple_wallet::print_ring_members(const std::vector<tools::wallet2::pending
req.outputs[j].index = absolute_offsets[j]; req.outputs[j].index = absolute_offsets[j];
} }
COMMAND_RPC_GET_OUTPUTS_BIN::response res = AUTO_VAL_INIT(res); COMMAND_RPC_GET_OUTPUTS_BIN::response res = AUTO_VAL_INIT(res);
bool r = net_utils::invoke_http_bin("/get_outs.bin", req, res, m_http_client); bool r = m_wallet->invoke_http_bin("/get_outs.bin", req, res);
err = interpret_rpc_response(r, res.status); err = interpret_rpc_response(r, res.status);
if (!err.empty()) if (!err.empty())
{ {

View File

@ -328,7 +328,6 @@ namespace cryptonote
epee::console_handlers_binder m_cmd_binder; epee::console_handlers_binder m_cmd_binder;
std::unique_ptr<tools::wallet2> m_wallet; std::unique_ptr<tools::wallet2> m_wallet;
epee::net_utils::http::http_simple_client m_http_client;
refresh_progress_reporter_t m_refresh_progress_reporter; refresh_progress_reporter_t m_refresh_progress_reporter;
std::atomic<bool> m_idle_run; std::atomic<bool> m_idle_run;

View File

@ -70,18 +70,15 @@ boost::optional<std::string> NodeRPCProxy::get_rpc_version(uint32_t &rpc_version
{ {
if (m_rpc_version == 0) if (m_rpc_version == 0)
{ {
epee::json_rpc::request<cryptonote::COMMAND_RPC_GET_VERSION::request> req_t = AUTO_VAL_INIT(req_t); cryptonote::COMMAND_RPC_GET_VERSION::request req_t = AUTO_VAL_INIT(req_t);
epee::json_rpc::response<cryptonote::COMMAND_RPC_GET_VERSION::response, std::string> resp_t = AUTO_VAL_INIT(resp_t); cryptonote::COMMAND_RPC_GET_VERSION::response resp_t = AUTO_VAL_INIT(resp_t);
req_t.jsonrpc = "2.0";
req_t.id = epee::serialization::storage_entry(0);
req_t.method = "get_version";
m_daemon_rpc_mutex.lock(); m_daemon_rpc_mutex.lock();
bool r = net_utils::invoke_http_json("/json_rpc", req_t, resp_t, m_http_client, rpc_timeout); bool r = net_utils::invoke_http_json_rpc("/json_rpc", "get_version", req_t, resp_t, m_http_client, rpc_timeout);
m_daemon_rpc_mutex.unlock(); m_daemon_rpc_mutex.unlock();
CHECK_AND_ASSERT_MES(r, std::string(), "Failed to connect to daemon"); CHECK_AND_ASSERT_MES(r, std::string(), "Failed to connect to daemon");
CHECK_AND_ASSERT_MES(resp_t.result.status != CORE_RPC_STATUS_BUSY, resp_t.result.status, "Failed to connect to daemon"); CHECK_AND_ASSERT_MES(resp_t.status != CORE_RPC_STATUS_BUSY, resp_t.status, "Failed to connect to daemon");
CHECK_AND_ASSERT_MES(resp_t.result.status == CORE_RPC_STATUS_OK, resp_t.result.status, "Failed to get daemon RPC version"); CHECK_AND_ASSERT_MES(resp_t.status == CORE_RPC_STATUS_OK, resp_t.status, "Failed to get daemon RPC version");
m_rpc_version = resp_t.result.version; m_rpc_version = resp_t.version;
} }
rpc_version = m_rpc_version; rpc_version = m_rpc_version;
return boost::optional<std::string>(); return boost::optional<std::string>();
@ -118,20 +115,17 @@ boost::optional<std::string> NodeRPCProxy::get_target_height(uint64_t &height) c
const time_t now = time(NULL); const time_t now = time(NULL);
if (m_target_height == 0 || now >= m_target_height_time + 30) // re-cache every 30 seconds if (m_target_height == 0 || now >= m_target_height_time + 30) // re-cache every 30 seconds
{ {
epee::json_rpc::request<cryptonote::COMMAND_RPC_GET_INFO::request> req_t = AUTO_VAL_INIT(req_t); cryptonote::COMMAND_RPC_GET_INFO::request req_t = AUTO_VAL_INIT(req_t);
epee::json_rpc::response<cryptonote::COMMAND_RPC_GET_INFO::response, std::string> resp_t = AUTO_VAL_INIT(resp_t); cryptonote::COMMAND_RPC_GET_INFO::response resp_t = AUTO_VAL_INIT(resp_t);
req_t.jsonrpc = "2.0";
req_t.id = epee::serialization::storage_entry(0);
req_t.method = "get_info";
m_daemon_rpc_mutex.lock(); m_daemon_rpc_mutex.lock();
bool r = net_utils::invoke_http_json("/json_rpc", req_t, resp_t, m_http_client, rpc_timeout); bool r = net_utils::invoke_http_json_rpc("/json_rpc", "get_info", req_t, resp_t, m_http_client, rpc_timeout);
m_daemon_rpc_mutex.unlock(); m_daemon_rpc_mutex.unlock();
CHECK_AND_ASSERT_MES(r, std::string(), "Failed to connect to daemon"); CHECK_AND_ASSERT_MES(r, std::string(), "Failed to connect to daemon");
CHECK_AND_ASSERT_MES(resp_t.result.status != CORE_RPC_STATUS_BUSY, resp_t.result.status, "Failed to connect to daemon"); CHECK_AND_ASSERT_MES(resp_t.status != CORE_RPC_STATUS_BUSY, resp_t.status, "Failed to connect to daemon");
CHECK_AND_ASSERT_MES(resp_t.result.status == CORE_RPC_STATUS_OK, resp_t.result.status, "Failed to get target blockchain height"); CHECK_AND_ASSERT_MES(resp_t.status == CORE_RPC_STATUS_OK, resp_t.status, "Failed to get target blockchain height");
m_target_height = resp_t.result.target_height; m_target_height = resp_t.target_height;
m_target_height_time = now; m_target_height_time = now;
} }
height = m_target_height; height = m_target_height;
@ -142,20 +136,17 @@ boost::optional<std::string> NodeRPCProxy::get_earliest_height(uint8_t version,
{ {
if (m_earliest_height[version] == 0) if (m_earliest_height[version] == 0)
{ {
epee::json_rpc::request<cryptonote::COMMAND_RPC_HARD_FORK_INFO::request> req_t = AUTO_VAL_INIT(req_t); cryptonote::COMMAND_RPC_HARD_FORK_INFO::request req_t = AUTO_VAL_INIT(req_t);
epee::json_rpc::response<cryptonote::COMMAND_RPC_HARD_FORK_INFO::response, std::string> resp_t = AUTO_VAL_INIT(resp_t); cryptonote::COMMAND_RPC_HARD_FORK_INFO::response resp_t = AUTO_VAL_INIT(resp_t);
m_daemon_rpc_mutex.lock(); m_daemon_rpc_mutex.lock();
req_t.jsonrpc = "2.0"; req_t.version = version;
req_t.id = epee::serialization::storage_entry(0); bool r = net_utils::invoke_http_json_rpc("/json_rpc", "hard_fork_info", req_t, resp_t, m_http_client, rpc_timeout);
req_t.method = "hard_fork_info";
req_t.params.version = version;
bool r = net_utils::invoke_http_json("/json_rpc", req_t, resp_t, m_http_client, rpc_timeout);
m_daemon_rpc_mutex.unlock(); m_daemon_rpc_mutex.unlock();
CHECK_AND_ASSERT_MES(r, std::string(), "Failed to connect to daemon"); CHECK_AND_ASSERT_MES(r, std::string(), "Failed to connect to daemon");
CHECK_AND_ASSERT_MES(resp_t.result.status != CORE_RPC_STATUS_BUSY, resp_t.result.status, "Failed to connect to daemon"); CHECK_AND_ASSERT_MES(resp_t.status != CORE_RPC_STATUS_BUSY, resp_t.status, "Failed to connect to daemon");
CHECK_AND_ASSERT_MES(resp_t.result.status == CORE_RPC_STATUS_OK, resp_t.result.status, "Failed to get hard fork status"); CHECK_AND_ASSERT_MES(resp_t.status == CORE_RPC_STATUS_OK, resp_t.status, "Failed to get hard fork status");
m_earliest_height[version] = resp_t.result.enabled ? resp_t.result.earliest_height : std::numeric_limits<uint64_t>::max(); m_earliest_height[version] = resp_t.enabled ? resp_t.earliest_height : std::numeric_limits<uint64_t>::max();
} }
earliest_height = m_earliest_height[version]; earliest_height = m_earliest_height[version];
@ -172,20 +163,17 @@ boost::optional<std::string> NodeRPCProxy::get_dynamic_per_kb_fee_estimate(uint6
if (m_dynamic_per_kb_fee_estimate_cached_height != height || m_dynamic_per_kb_fee_estimate_grace_blocks != grace_blocks) if (m_dynamic_per_kb_fee_estimate_cached_height != height || m_dynamic_per_kb_fee_estimate_grace_blocks != grace_blocks)
{ {
epee::json_rpc::request<cryptonote::COMMAND_RPC_GET_PER_KB_FEE_ESTIMATE::request> req_t = AUTO_VAL_INIT(req_t); cryptonote::COMMAND_RPC_GET_PER_KB_FEE_ESTIMATE::request req_t = AUTO_VAL_INIT(req_t);
epee::json_rpc::response<cryptonote::COMMAND_RPC_GET_PER_KB_FEE_ESTIMATE::response, std::string> resp_t = AUTO_VAL_INIT(resp_t); cryptonote::COMMAND_RPC_GET_PER_KB_FEE_ESTIMATE::response resp_t = AUTO_VAL_INIT(resp_t);
m_daemon_rpc_mutex.lock(); m_daemon_rpc_mutex.lock();
req_t.jsonrpc = "2.0"; req_t.grace_blocks = grace_blocks;
req_t.id = epee::serialization::storage_entry(0); bool r = net_utils::invoke_http_json_rpc("/json_rpc", "get_fee_estimate", req_t, resp_t, m_http_client, rpc_timeout);
req_t.method = "get_fee_estimate";
req_t.params.grace_blocks = grace_blocks;
bool r = net_utils::invoke_http_json("/json_rpc", req_t, resp_t, m_http_client, rpc_timeout);
m_daemon_rpc_mutex.unlock(); m_daemon_rpc_mutex.unlock();
CHECK_AND_ASSERT_MES(r, std::string(), "Failed to connect to daemon"); CHECK_AND_ASSERT_MES(r, std::string(), "Failed to connect to daemon");
CHECK_AND_ASSERT_MES(resp_t.result.status != CORE_RPC_STATUS_BUSY, resp_t.result.status, "Failed to connect to daemon"); CHECK_AND_ASSERT_MES(resp_t.status != CORE_RPC_STATUS_BUSY, resp_t.status, "Failed to connect to daemon");
CHECK_AND_ASSERT_MES(resp_t.result.status == CORE_RPC_STATUS_OK, resp_t.result.status, "Failed to get fee estimate"); CHECK_AND_ASSERT_MES(resp_t.status == CORE_RPC_STATUS_OK, resp_t.status, "Failed to get fee estimate");
m_dynamic_per_kb_fee_estimate = resp_t.result.fee; m_dynamic_per_kb_fee_estimate = resp_t.fee;
m_dynamic_per_kb_fee_estimate_cached_height = height; m_dynamic_per_kb_fee_estimate_cached_height = height;
m_dynamic_per_kb_fee_estimate_grace_blocks = grace_blocks; m_dynamic_per_kb_fee_estimate_grace_blocks = grace_blocks;
} }

View File

@ -3540,20 +3540,17 @@ bool wallet2::check_connection(uint32_t *version, uint32_t timeout)
if (version) if (version)
{ {
epee::json_rpc::request<cryptonote::COMMAND_RPC_GET_VERSION::request> req_t = AUTO_VAL_INIT(req_t); cryptonote::COMMAND_RPC_GET_VERSION::request req_t = AUTO_VAL_INIT(req_t);
epee::json_rpc::response<cryptonote::COMMAND_RPC_GET_VERSION::response, std::string> resp_t = AUTO_VAL_INIT(resp_t); cryptonote::COMMAND_RPC_GET_VERSION::response resp_t = AUTO_VAL_INIT(resp_t);
req_t.jsonrpc = "2.0"; bool r = net_utils::invoke_http_json_rpc("/json_rpc", "get_version", req_t, resp_t, m_http_client);
req_t.id = epee::serialization::storage_entry(0);
req_t.method = "get_version";
bool r = net_utils::invoke_http_json("/json_rpc", req_t, resp_t, m_http_client);
if(!r) { if(!r) {
*version = 0; *version = 0;
return false; return false;
} }
if (resp_t.result.status != CORE_RPC_STATUS_OK) if (resp_t.status != CORE_RPC_STATUS_OK)
*version = 0; *version = 0;
else else
*version = resp_t.result.version; *version = resp_t.version;
} }
return true; return true;
@ -3688,19 +3685,16 @@ void wallet2::trim_hashchain()
if (!m_blockchain.empty() && m_blockchain.size() == m_blockchain.offset()) if (!m_blockchain.empty() && m_blockchain.size() == m_blockchain.offset())
{ {
MINFO("Fixing empty hashchain"); MINFO("Fixing empty hashchain");
epee::json_rpc::request<cryptonote::COMMAND_RPC_GET_BLOCK_HEADER_BY_HEIGHT::request> req = AUTO_VAL_INIT(req); cryptonote::COMMAND_RPC_GET_BLOCK_HEADER_BY_HEIGHT::request req = AUTO_VAL_INIT(req);
epee::json_rpc::response<cryptonote::COMMAND_RPC_GET_BLOCK_HEADER_BY_HEIGHT::response, std::string> res = AUTO_VAL_INIT(res); cryptonote::COMMAND_RPC_GET_BLOCK_HEADER_BY_HEIGHT::response res = AUTO_VAL_INIT(res);
m_daemon_rpc_mutex.lock(); m_daemon_rpc_mutex.lock();
req.jsonrpc = "2.0"; req.height = m_blockchain.size() - 1;
req.id = epee::serialization::storage_entry(0); bool r = net_utils::invoke_http_json_rpc("/json_rpc", "getblockheaderbyheight", req, res, m_http_client, rpc_timeout);
req.method = "getblockheaderbyheight";
req.params.height = m_blockchain.size() - 1;
bool r = net_utils::invoke_http_json("/json_rpc", req, res, m_http_client, rpc_timeout);
m_daemon_rpc_mutex.unlock(); m_daemon_rpc_mutex.unlock();
if (r && res.result.status == CORE_RPC_STATUS_OK) if (r && res.status == CORE_RPC_STATUS_OK)
{ {
crypto::hash hash; crypto::hash hash;
epee::string_tools::hex_to_pod(res.result.block_header.hash, hash); epee::string_tools::hex_to_pod(res.block_header.hash, hash);
m_blockchain.refill(hash); m_blockchain.refill(hash);
} }
else else
@ -5160,18 +5154,15 @@ uint32_t wallet2::adjust_priority(uint32_t priority)
} }
// get the current full reward zone // get the current full reward zone
epee::json_rpc::request<cryptonote::COMMAND_RPC_GET_INFO::request> getinfo_req = AUTO_VAL_INIT(getinfo_req); cryptonote::COMMAND_RPC_GET_INFO::request getinfo_req = AUTO_VAL_INIT(getinfo_req);
epee::json_rpc::response<cryptonote::COMMAND_RPC_GET_INFO::response, std::string> getinfo_res = AUTO_VAL_INIT(getinfo_res); cryptonote::COMMAND_RPC_GET_INFO::response getinfo_res = AUTO_VAL_INIT(getinfo_res);
m_daemon_rpc_mutex.lock(); m_daemon_rpc_mutex.lock();
getinfo_req.jsonrpc = "2.0"; bool r = net_utils::invoke_http_json_rpc("/json_rpc", "get_info", getinfo_req, getinfo_res, m_http_client);
getinfo_req.id = epee::serialization::storage_entry(0);
getinfo_req.method = "get_info";
bool r = net_utils::invoke_http_json("/json_rpc", getinfo_req, getinfo_res, m_http_client);
m_daemon_rpc_mutex.unlock(); m_daemon_rpc_mutex.unlock();
THROW_WALLET_EXCEPTION_IF(!r, error::no_connection_to_daemon, "get_info"); THROW_WALLET_EXCEPTION_IF(!r, error::no_connection_to_daemon, "get_info");
THROW_WALLET_EXCEPTION_IF(getinfo_res.result.status == CORE_RPC_STATUS_BUSY, error::daemon_busy, "get_info"); THROW_WALLET_EXCEPTION_IF(getinfo_res.status == CORE_RPC_STATUS_BUSY, error::daemon_busy, "get_info");
THROW_WALLET_EXCEPTION_IF(getinfo_res.result.status != CORE_RPC_STATUS_OK, error::get_tx_pool_error); THROW_WALLET_EXCEPTION_IF(getinfo_res.status != CORE_RPC_STATUS_OK, error::get_tx_pool_error);
const uint64_t full_reward_zone = getinfo_res.result.block_size_limit / 2; const uint64_t full_reward_zone = getinfo_res.block_size_limit / 2;
// get the last N block headers and sum the block sizes // get the last N block headers and sum the block sizes
const size_t N = 10; const size_t N = 10;
@ -5180,26 +5171,23 @@ uint32_t wallet2::adjust_priority(uint32_t priority)
MERROR("The blockchain is too short"); MERROR("The blockchain is too short");
return priority; return priority;
} }
epee::json_rpc::request<cryptonote::COMMAND_RPC_GET_BLOCK_HEADERS_RANGE::request> getbh_req = AUTO_VAL_INIT(getbh_req); cryptonote::COMMAND_RPC_GET_BLOCK_HEADERS_RANGE::request getbh_req = AUTO_VAL_INIT(getbh_req);
epee::json_rpc::response<cryptonote::COMMAND_RPC_GET_BLOCK_HEADERS_RANGE::response, std::string> getbh_res = AUTO_VAL_INIT(getbh_res); cryptonote::COMMAND_RPC_GET_BLOCK_HEADERS_RANGE::response getbh_res = AUTO_VAL_INIT(getbh_res);
m_daemon_rpc_mutex.lock(); m_daemon_rpc_mutex.lock();
getbh_req.jsonrpc = "2.0"; getbh_req.start_height = m_blockchain.size() - N;
getbh_req.id = epee::serialization::storage_entry(0); getbh_req.end_height = m_blockchain.size() - 1;
getbh_req.method = "getblockheadersrange"; r = net_utils::invoke_http_json_rpc("/json_rpc", "getblockheadersrange", getbh_req, getbh_res, m_http_client, rpc_timeout);
getbh_req.params.start_height = m_blockchain.size() - N;
getbh_req.params.end_height = m_blockchain.size() - 1;
r = net_utils::invoke_http_json("/json_rpc", getbh_req, getbh_res, m_http_client, rpc_timeout);
m_daemon_rpc_mutex.unlock(); m_daemon_rpc_mutex.unlock();
THROW_WALLET_EXCEPTION_IF(!r, error::no_connection_to_daemon, "getblockheadersrange"); THROW_WALLET_EXCEPTION_IF(!r, error::no_connection_to_daemon, "getblockheadersrange");
THROW_WALLET_EXCEPTION_IF(getbh_res.result.status == CORE_RPC_STATUS_BUSY, error::daemon_busy, "getblockheadersrange"); THROW_WALLET_EXCEPTION_IF(getbh_res.status == CORE_RPC_STATUS_BUSY, error::daemon_busy, "getblockheadersrange");
THROW_WALLET_EXCEPTION_IF(getbh_res.result.status != CORE_RPC_STATUS_OK, error::get_blocks_error, getbh_res.result.status); THROW_WALLET_EXCEPTION_IF(getbh_res.status != CORE_RPC_STATUS_OK, error::get_blocks_error, getbh_res.status);
if (getbh_res.result.headers.size() != N) if (getbh_res.headers.size() != N)
{ {
MERROR("Bad blockheaders size"); MERROR("Bad blockheaders size");
return priority; return priority;
} }
size_t block_size_sum = 0; size_t block_size_sum = 0;
for (const cryptonote::block_header_response &i : getbh_res.result.headers) for (const cryptonote::block_header_response &i : getbh_res.headers)
{ {
block_size_sum += i.block_size; block_size_sum += i.block_size;
} }
@ -5464,24 +5452,21 @@ void wallet2::get_outs(std::vector<std::vector<tools::wallet2::get_outs_entry>>
if (fake_outputs_count > 0) if (fake_outputs_count > 0)
{ {
// get histogram for the amounts we need // get histogram for the amounts we need
epee::json_rpc::request<cryptonote::COMMAND_RPC_GET_OUTPUT_HISTOGRAM::request> req_t = AUTO_VAL_INIT(req_t); cryptonote::COMMAND_RPC_GET_OUTPUT_HISTOGRAM::request req_t = AUTO_VAL_INIT(req_t);
epee::json_rpc::response<cryptonote::COMMAND_RPC_GET_OUTPUT_HISTOGRAM::response, std::string> resp_t = AUTO_VAL_INIT(resp_t); cryptonote::COMMAND_RPC_GET_OUTPUT_HISTOGRAM::response resp_t = AUTO_VAL_INIT(resp_t);
m_daemon_rpc_mutex.lock(); m_daemon_rpc_mutex.lock();
req_t.jsonrpc = "2.0";
req_t.id = epee::serialization::storage_entry(0);
req_t.method = "get_output_histogram";
for(size_t idx: selected_transfers) for(size_t idx: selected_transfers)
req_t.params.amounts.push_back(m_transfers[idx].is_rct() ? 0 : m_transfers[idx].amount()); req_t.amounts.push_back(m_transfers[idx].is_rct() ? 0 : m_transfers[idx].amount());
std::sort(req_t.params.amounts.begin(), req_t.params.amounts.end()); std::sort(req_t.amounts.begin(), req_t.amounts.end());
auto end = std::unique(req_t.params.amounts.begin(), req_t.params.amounts.end()); auto end = std::unique(req_t.amounts.begin(), req_t.amounts.end());
req_t.params.amounts.resize(std::distance(req_t.params.amounts.begin(), end)); req_t.amounts.resize(std::distance(req_t.amounts.begin(), end));
req_t.params.unlocked = true; req_t.unlocked = true;
req_t.params.recent_cutoff = time(NULL) - RECENT_OUTPUT_ZONE; req_t.recent_cutoff = time(NULL) - RECENT_OUTPUT_ZONE;
bool r = net_utils::invoke_http_json("/json_rpc", req_t, resp_t, m_http_client, rpc_timeout); bool r = net_utils::invoke_http_json_rpc("/json_rpc", "get_output_histogram", req_t, resp_t, m_http_client, rpc_timeout);
m_daemon_rpc_mutex.unlock(); m_daemon_rpc_mutex.unlock();
THROW_WALLET_EXCEPTION_IF(!r, error::no_connection_to_daemon, "transfer_selected"); THROW_WALLET_EXCEPTION_IF(!r, error::no_connection_to_daemon, "transfer_selected");
THROW_WALLET_EXCEPTION_IF(resp_t.result.status == CORE_RPC_STATUS_BUSY, error::daemon_busy, "get_output_histogram"); THROW_WALLET_EXCEPTION_IF(resp_t.status == CORE_RPC_STATUS_BUSY, error::daemon_busy, "get_output_histogram");
THROW_WALLET_EXCEPTION_IF(resp_t.result.status != CORE_RPC_STATUS_OK, error::get_histogram_error, resp_t.result.status); THROW_WALLET_EXCEPTION_IF(resp_t.status != CORE_RPC_STATUS_OK, error::get_histogram_error, resp_t.status);
// we ask for more, to have spares if some outputs are still locked // we ask for more, to have spares if some outputs are still locked
size_t base_requested_outputs_count = (size_t)((fake_outputs_count + 1) * 1.5 + 1); size_t base_requested_outputs_count = (size_t)((fake_outputs_count + 1) * 1.5 + 1);
@ -5505,7 +5490,7 @@ void wallet2::get_outs(std::vector<std::vector<tools::wallet2::get_outs_entry>>
// if there are just enough outputs to mix with, use all of them. // if there are just enough outputs to mix with, use all of them.
// Eventually this should become impossible. // Eventually this should become impossible.
uint64_t num_outs = 0, num_recent_outs = 0; uint64_t num_outs = 0, num_recent_outs = 0;
for (const auto &he: resp_t.result.histogram) for (const auto &he: resp_t.histogram)
{ {
if (he.amount == amount) if (he.amount == amount)
{ {
@ -7502,25 +7487,22 @@ std::vector<uint64_t> wallet2::get_unspent_amounts_vector() const
//---------------------------------------------------------------------------------------------------- //----------------------------------------------------------------------------------------------------
std::vector<size_t> wallet2::select_available_outputs_from_histogram(uint64_t count, bool atleast, bool unlocked, bool allow_rct, bool trusted_daemon) std::vector<size_t> wallet2::select_available_outputs_from_histogram(uint64_t count, bool atleast, bool unlocked, bool allow_rct, bool trusted_daemon)
{ {
epee::json_rpc::request<cryptonote::COMMAND_RPC_GET_OUTPUT_HISTOGRAM::request> req_t = AUTO_VAL_INIT(req_t); cryptonote::COMMAND_RPC_GET_OUTPUT_HISTOGRAM::request req_t = AUTO_VAL_INIT(req_t);
epee::json_rpc::response<cryptonote::COMMAND_RPC_GET_OUTPUT_HISTOGRAM::response, std::string> resp_t = AUTO_VAL_INIT(resp_t); cryptonote::COMMAND_RPC_GET_OUTPUT_HISTOGRAM::response resp_t = AUTO_VAL_INIT(resp_t);
m_daemon_rpc_mutex.lock(); m_daemon_rpc_mutex.lock();
req_t.jsonrpc = "2.0";
req_t.id = epee::serialization::storage_entry(0);
req_t.method = "get_output_histogram";
if (trusted_daemon) if (trusted_daemon)
req_t.params.amounts = get_unspent_amounts_vector(); req_t.amounts = get_unspent_amounts_vector();
req_t.params.min_count = count; req_t.min_count = count;
req_t.params.max_count = 0; req_t.max_count = 0;
req_t.params.unlocked = unlocked; req_t.unlocked = unlocked;
bool r = net_utils::invoke_http_json("/json_rpc", req_t, resp_t, m_http_client, rpc_timeout); bool r = net_utils::invoke_http_json_rpc("/json_rpc", "get_output_histogram", req_t, resp_t, m_http_client, rpc_timeout);
m_daemon_rpc_mutex.unlock(); m_daemon_rpc_mutex.unlock();
THROW_WALLET_EXCEPTION_IF(!r, error::no_connection_to_daemon, "select_available_outputs_from_histogram"); THROW_WALLET_EXCEPTION_IF(!r, error::no_connection_to_daemon, "select_available_outputs_from_histogram");
THROW_WALLET_EXCEPTION_IF(resp_t.result.status == CORE_RPC_STATUS_BUSY, error::daemon_busy, "get_output_histogram"); THROW_WALLET_EXCEPTION_IF(resp_t.status == CORE_RPC_STATUS_BUSY, error::daemon_busy, "get_output_histogram");
THROW_WALLET_EXCEPTION_IF(resp_t.result.status != CORE_RPC_STATUS_OK, error::get_histogram_error, resp_t.result.status); THROW_WALLET_EXCEPTION_IF(resp_t.status != CORE_RPC_STATUS_OK, error::get_histogram_error, resp_t.status);
std::set<uint64_t> mixable; std::set<uint64_t> mixable;
for (const auto &i: resp_t.result.histogram) for (const auto &i: resp_t.histogram)
{ {
mixable.insert(i.amount); mixable.insert(i.amount);
} }
@ -7543,24 +7525,21 @@ std::vector<size_t> wallet2::select_available_outputs_from_histogram(uint64_t co
//---------------------------------------------------------------------------------------------------- //----------------------------------------------------------------------------------------------------
uint64_t wallet2::get_num_rct_outputs() uint64_t wallet2::get_num_rct_outputs()
{ {
epee::json_rpc::request<cryptonote::COMMAND_RPC_GET_OUTPUT_HISTOGRAM::request> req_t = AUTO_VAL_INIT(req_t); cryptonote::COMMAND_RPC_GET_OUTPUT_HISTOGRAM::request req_t = AUTO_VAL_INIT(req_t);
epee::json_rpc::response<cryptonote::COMMAND_RPC_GET_OUTPUT_HISTOGRAM::response, std::string> resp_t = AUTO_VAL_INIT(resp_t); cryptonote::COMMAND_RPC_GET_OUTPUT_HISTOGRAM::response resp_t = AUTO_VAL_INIT(resp_t);
m_daemon_rpc_mutex.lock(); m_daemon_rpc_mutex.lock();
req_t.jsonrpc = "2.0"; req_t.amounts.push_back(0);
req_t.id = epee::serialization::storage_entry(0); req_t.min_count = 0;
req_t.method = "get_output_histogram"; req_t.max_count = 0;
req_t.params.amounts.push_back(0); bool r = net_utils::invoke_http_json_rpc("/json_rpc", "get_output_histogram", req_t, resp_t, m_http_client, rpc_timeout);
req_t.params.min_count = 0;
req_t.params.max_count = 0;
bool r = net_utils::invoke_http_json("/json_rpc", req_t, resp_t, m_http_client, rpc_timeout);
m_daemon_rpc_mutex.unlock(); m_daemon_rpc_mutex.unlock();
THROW_WALLET_EXCEPTION_IF(!r, error::no_connection_to_daemon, "get_num_rct_outputs"); THROW_WALLET_EXCEPTION_IF(!r, error::no_connection_to_daemon, "get_num_rct_outputs");
THROW_WALLET_EXCEPTION_IF(resp_t.result.status == CORE_RPC_STATUS_BUSY, error::daemon_busy, "get_output_histogram"); THROW_WALLET_EXCEPTION_IF(resp_t.status == CORE_RPC_STATUS_BUSY, error::daemon_busy, "get_output_histogram");
THROW_WALLET_EXCEPTION_IF(resp_t.result.status != CORE_RPC_STATUS_OK, error::get_histogram_error, resp_t.result.status); THROW_WALLET_EXCEPTION_IF(resp_t.status != CORE_RPC_STATUS_OK, error::get_histogram_error, resp_t.status);
THROW_WALLET_EXCEPTION_IF(resp_t.result.histogram.size() != 1, error::get_histogram_error, "Expected exactly one response"); THROW_WALLET_EXCEPTION_IF(resp_t.histogram.size() != 1, error::get_histogram_error, "Expected exactly one response");
THROW_WALLET_EXCEPTION_IF(resp_t.result.histogram[0].amount != 0, error::get_histogram_error, "Expected 0 amount"); THROW_WALLET_EXCEPTION_IF(resp_t.histogram[0].amount != 0, error::get_histogram_error, "Expected 0 amount");
return resp_t.result.histogram[0].total_instances; return resp_t.histogram[0].total_instances;
} }
//---------------------------------------------------------------------------------------------------- //----------------------------------------------------------------------------------------------------
const wallet2::transfer_details &wallet2::get_transfer_details(size_t idx) const const wallet2::transfer_details &wallet2::get_transfer_details(size_t idx) const
@ -8476,23 +8455,20 @@ uint64_t wallet2::get_daemon_blockchain_height(string &err) const
uint64_t wallet2::get_daemon_blockchain_target_height(string &err) uint64_t wallet2::get_daemon_blockchain_target_height(string &err)
{ {
epee::json_rpc::request<cryptonote::COMMAND_RPC_GET_INFO::request> req_t = AUTO_VAL_INIT(req_t); cryptonote::COMMAND_RPC_GET_INFO::request req_t = AUTO_VAL_INIT(req_t);
epee::json_rpc::response<cryptonote::COMMAND_RPC_GET_INFO::response, std::string> resp_t = AUTO_VAL_INIT(resp_t); cryptonote::COMMAND_RPC_GET_INFO::response resp_t = AUTO_VAL_INIT(resp_t);
m_daemon_rpc_mutex.lock(); m_daemon_rpc_mutex.lock();
req_t.jsonrpc = "2.0"; bool ok = net_utils::invoke_http_json_rpc("/json_rpc", "get_info", req_t, resp_t, m_http_client);
req_t.id = epee::serialization::storage_entry(0);
req_t.method = "get_info";
bool ok = net_utils::invoke_http_json("/json_rpc", req_t, resp_t, m_http_client);
m_daemon_rpc_mutex.unlock(); m_daemon_rpc_mutex.unlock();
if (ok) if (ok)
{ {
if (resp_t.result.status == CORE_RPC_STATUS_BUSY) if (resp_t.status == CORE_RPC_STATUS_BUSY)
{ {
err = "daemon is busy. Please try again later."; err = "daemon is busy. Please try again later.";
} }
else if (resp_t.result.status != CORE_RPC_STATUS_OK) else if (resp_t.status != CORE_RPC_STATUS_OK)
{ {
err = resp_t.result.status; err = resp_t.status;
} }
else // success, cleaning up error message else // success, cleaning up error message
{ {
@ -8503,7 +8479,7 @@ uint64_t wallet2::get_daemon_blockchain_target_height(string &err)
{ {
err = "possibly lost connection to daemon"; err = "possibly lost connection to daemon";
} }
return resp_t.result.target_height; return resp_t.target_height;
} }
uint64_t wallet2::get_approximate_blockchain_height() const uint64_t wallet2::get_approximate_blockchain_height() const
@ -9739,30 +9715,24 @@ std::vector<std::pair<uint64_t, uint64_t>> wallet2::estimate_backlog(const std::
} }
// get txpool backlog // get txpool backlog
epee::json_rpc::request<cryptonote::COMMAND_RPC_GET_TRANSACTION_POOL_BACKLOG::request> req = AUTO_VAL_INIT(req); cryptonote::COMMAND_RPC_GET_TRANSACTION_POOL_BACKLOG::request req = AUTO_VAL_INIT(req);
epee::json_rpc::response<cryptonote::COMMAND_RPC_GET_TRANSACTION_POOL_BACKLOG::response, std::string> res = AUTO_VAL_INIT(res); cryptonote::COMMAND_RPC_GET_TRANSACTION_POOL_BACKLOG::response res = AUTO_VAL_INIT(res);
m_daemon_rpc_mutex.lock(); m_daemon_rpc_mutex.lock();
req.jsonrpc = "2.0"; bool r = net_utils::invoke_http_json_rpc("/json_rpc", "get_txpool_backlog", req, res, m_http_client, rpc_timeout);
req.id = epee::serialization::storage_entry(0);
req.method = "get_txpool_backlog";
bool r = net_utils::invoke_http_json("/json_rpc", req, res, m_http_client, rpc_timeout);
m_daemon_rpc_mutex.unlock(); m_daemon_rpc_mutex.unlock();
THROW_WALLET_EXCEPTION_IF(!r, error::no_connection_to_daemon, "Failed to connect to daemon"); THROW_WALLET_EXCEPTION_IF(!r, error::no_connection_to_daemon, "Failed to connect to daemon");
THROW_WALLET_EXCEPTION_IF(res.result.status == CORE_RPC_STATUS_BUSY, error::daemon_busy, "get_txpool_backlog"); THROW_WALLET_EXCEPTION_IF(res.status == CORE_RPC_STATUS_BUSY, error::daemon_busy, "get_txpool_backlog");
THROW_WALLET_EXCEPTION_IF(res.result.status != CORE_RPC_STATUS_OK, error::get_tx_pool_error); THROW_WALLET_EXCEPTION_IF(res.status != CORE_RPC_STATUS_OK, error::get_tx_pool_error);
epee::json_rpc::request<cryptonote::COMMAND_RPC_GET_INFO::request> req_t = AUTO_VAL_INIT(req_t); cryptonote::COMMAND_RPC_GET_INFO::request req_t = AUTO_VAL_INIT(req_t);
epee::json_rpc::response<cryptonote::COMMAND_RPC_GET_INFO::response, std::string> resp_t = AUTO_VAL_INIT(resp_t); cryptonote::COMMAND_RPC_GET_INFO::response resp_t = AUTO_VAL_INIT(resp_t);
m_daemon_rpc_mutex.lock(); m_daemon_rpc_mutex.lock();
req_t.jsonrpc = "2.0"; r = net_utils::invoke_http_json_rpc("/json_rpc", "get_info", req_t, resp_t, m_http_client);
req_t.id = epee::serialization::storage_entry(0);
req_t.method = "get_info";
r = net_utils::invoke_http_json("/json_rpc", req_t, resp_t, m_http_client);
m_daemon_rpc_mutex.unlock(); m_daemon_rpc_mutex.unlock();
THROW_WALLET_EXCEPTION_IF(!r, error::no_connection_to_daemon, "get_info"); THROW_WALLET_EXCEPTION_IF(!r, error::no_connection_to_daemon, "get_info");
THROW_WALLET_EXCEPTION_IF(resp_t.result.status == CORE_RPC_STATUS_BUSY, error::daemon_busy, "get_info"); THROW_WALLET_EXCEPTION_IF(resp_t.status == CORE_RPC_STATUS_BUSY, error::daemon_busy, "get_info");
THROW_WALLET_EXCEPTION_IF(resp_t.result.status != CORE_RPC_STATUS_OK, error::get_tx_pool_error); THROW_WALLET_EXCEPTION_IF(resp_t.status != CORE_RPC_STATUS_OK, error::get_tx_pool_error);
uint64_t full_reward_zone = resp_t.result.block_size_limit / 2; uint64_t full_reward_zone = resp_t.block_size_limit / 2;
std::vector<std::pair<uint64_t, uint64_t>> blocks; std::vector<std::pair<uint64_t, uint64_t>> blocks;
for (const auto &fee_level: fee_levels) for (const auto &fee_level: fee_levels)
@ -9770,7 +9740,7 @@ std::vector<std::pair<uint64_t, uint64_t>> wallet2::estimate_backlog(const std::
const double our_fee_byte_min = fee_level.first; const double our_fee_byte_min = fee_level.first;
const double our_fee_byte_max = fee_level.second; const double our_fee_byte_max = fee_level.second;
uint64_t priority_size_min = 0, priority_size_max = 0; uint64_t priority_size_min = 0, priority_size_max = 0;
for (const auto &i: res.result.backlog) for (const auto &i: res.backlog)
{ {
if (i.blob_size == 0) if (i.blob_size == 0)
{ {

View File

@ -1027,6 +1027,25 @@ namespace tools
crypto::public_key get_multisig_signing_public_key(size_t idx) const; crypto::public_key get_multisig_signing_public_key(size_t idx) const;
crypto::public_key get_multisig_signing_public_key(const crypto::secret_key &skey) const; crypto::public_key get_multisig_signing_public_key(const crypto::secret_key &skey) const;
template<class t_request, class t_response>
inline bool invoke_http_json(const boost::string_ref uri, const t_request& req, t_response& res, std::chrono::milliseconds timeout = std::chrono::seconds(15), const boost::string_ref http_method = "GET")
{
boost::lock_guard<boost::mutex> lock(m_daemon_rpc_mutex);
return epee::net_utils::invoke_http_json(uri, req, res, m_http_client, timeout, http_method);
}
template<class t_request, class t_response>
inline bool invoke_http_bin(const boost::string_ref uri, const t_request& req, t_response& res, std::chrono::milliseconds timeout = std::chrono::seconds(15), const boost::string_ref http_method = "GET")
{
boost::lock_guard<boost::mutex> lock(m_daemon_rpc_mutex);
return epee::net_utils::invoke_http_bin(uri, req, res, m_http_client, timeout, http_method);
}
template<class t_request, class t_response>
inline bool invoke_http_json_rpc(const boost::string_ref uri, const std::string& method_name, const t_request& req, t_response& res, std::chrono::milliseconds timeout = std::chrono::seconds(15), const boost::string_ref http_method = "GET", const std::string& req_id = "0")
{
boost::lock_guard<boost::mutex> lock(m_daemon_rpc_mutex);
return epee::net_utils::invoke_http_json_rpc(uri, method_name, req, res, m_http_client, timeout, http_method, req_id);
}
private: private:
/*! /*!
* \brief Stores wallet information to wallet file. * \brief Stores wallet information to wallet file.

View File

@ -229,8 +229,6 @@ namespace tools
assert(bool(http_login)); assert(bool(http_login));
} // end auth enabled } // end auth enabled
m_http_client.set_server(walvars->get_daemon_address(), walvars->get_daemon_login());
m_net_server.set_threads_prefix("RPC"); m_net_server.set_threads_prefix("RPC");
auto rng = [](size_t len, uint8_t *ptr) { return crypto::rand(len, ptr); }; auto rng = [](size_t len, uint8_t *ptr) { return crypto::rand(len, ptr); };
return epee::http_server_impl_base<wallet_rpc_server, connection_context>::init( return epee::http_server_impl_base<wallet_rpc_server, connection_context>::init(
@ -2257,7 +2255,7 @@ namespace tools
daemon_req.ignore_battery = req.ignore_battery; daemon_req.ignore_battery = req.ignore_battery;
cryptonote::COMMAND_RPC_START_MINING::response daemon_res; cryptonote::COMMAND_RPC_START_MINING::response daemon_res;
bool r = net_utils::invoke_http_json("/start_mining", daemon_req, daemon_res, m_http_client); bool r = m_wallet->invoke_http_json("/start_mining", daemon_req, daemon_res);
if (!r || daemon_res.status != CORE_RPC_STATUS_OK) if (!r || daemon_res.status != CORE_RPC_STATUS_OK)
{ {
er.code = WALLET_RPC_ERROR_CODE_UNKNOWN_ERROR; er.code = WALLET_RPC_ERROR_CODE_UNKNOWN_ERROR;
@ -2271,7 +2269,7 @@ namespace tools
{ {
cryptonote::COMMAND_RPC_STOP_MINING::request daemon_req; cryptonote::COMMAND_RPC_STOP_MINING::request daemon_req;
cryptonote::COMMAND_RPC_STOP_MINING::response daemon_res; cryptonote::COMMAND_RPC_STOP_MINING::response daemon_res;
bool r = net_utils::invoke_http_json("/stop_mining", daemon_req, daemon_res, m_http_client); bool r = m_wallet->invoke_http_json("/stop_mining", daemon_req, daemon_res);
if (!r || daemon_res.status != CORE_RPC_STATUS_OK) if (!r || daemon_res.status != CORE_RPC_STATUS_OK)
{ {
er.code = WALLET_RPC_ERROR_CODE_UNKNOWN_ERROR; er.code = WALLET_RPC_ERROR_CODE_UNKNOWN_ERROR;
@ -2351,7 +2349,7 @@ namespace tools
cryptonote::COMMAND_RPC_GET_HEIGHT::request hreq; cryptonote::COMMAND_RPC_GET_HEIGHT::request hreq;
cryptonote::COMMAND_RPC_GET_HEIGHT::response hres; cryptonote::COMMAND_RPC_GET_HEIGHT::response hres;
hres.height = 0; hres.height = 0;
bool r = net_utils::invoke_http_json("/getheight", hreq, hres, m_http_client); bool r = wal->invoke_http_json("/getheight", hreq, hres);
wal->set_refresh_from_block_height(hres.height); wal->set_refresh_from_block_height(hres.height);
crypto::secret_key dummy_key; crypto::secret_key dummy_key;
try { try {

View File

@ -224,7 +224,6 @@ namespace tools
tools::private_file rpc_login_file; tools::private_file rpc_login_file;
std::atomic<bool> m_stop; std::atomic<bool> m_stop;
bool m_trusted_daemon; bool m_trusted_daemon;
epee::net_utils::http::http_simple_client m_http_client;
const boost::program_options::variables_map *m_vm; const boost::program_options::variables_map *m_vm;
}; };
} }