|
|
|
@ -1028,6 +1028,16 @@ void wallet2::check_acc_out_precomp(const tx_out &o, const crypto::key_derivatio
|
|
|
|
|
tx_scan_info.error = false;
|
|
|
|
|
}
|
|
|
|
|
//----------------------------------------------------------------------------------------------------
|
|
|
|
|
void wallet2::check_acc_out_precomp_once(const tx_out &o, const crypto::key_derivation &derivation, const std::vector<crypto::key_derivation> &additional_derivations, size_t i, tx_scan_info_t &tx_scan_info, bool &already_seen) const
|
|
|
|
|
{
|
|
|
|
|
tx_scan_info.received = boost::none;
|
|
|
|
|
if (already_seen)
|
|
|
|
|
return;
|
|
|
|
|
check_acc_out_precomp(o, derivation, additional_derivations, i, tx_scan_info);
|
|
|
|
|
if (tx_scan_info.received)
|
|
|
|
|
already_seen = true;
|
|
|
|
|
}
|
|
|
|
|
//----------------------------------------------------------------------------------------------------
|
|
|
|
|
static uint64_t decodeRct(const rct::rctSig & rv, const crypto::key_derivation &derivation, unsigned int i, rct::key & mask, hw::device &hwdev)
|
|
|
|
|
{
|
|
|
|
|
crypto::secret_key scalar1;
|
|
|
|
@ -1108,7 +1118,7 @@ void wallet2::process_new_transaction(const crypto::hash &txid, const cryptonote
|
|
|
|
|
// Don't try to extract tx public key if tx has no ouputs
|
|
|
|
|
size_t pk_index = 0;
|
|
|
|
|
std::vector<tx_scan_info_t> tx_scan_info(tx.vout.size());
|
|
|
|
|
std::unordered_set<crypto::public_key> public_keys_seen;
|
|
|
|
|
std::deque<bool> output_found(tx.vout.size(), false);
|
|
|
|
|
while (!tx.vout.empty())
|
|
|
|
|
{
|
|
|
|
|
// if tx.vout is not empty, we loop through all tx pubkeys
|
|
|
|
@ -1124,13 +1134,6 @@ void wallet2::process_new_transaction(const crypto::hash &txid, const cryptonote
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (public_keys_seen.find(pub_key_field.pub_key) != public_keys_seen.end())
|
|
|
|
|
{
|
|
|
|
|
MWARNING("The same transaction pubkey is present more than once, ignoring extra instance");
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
public_keys_seen.insert(pub_key_field.pub_key);
|
|
|
|
|
|
|
|
|
|
int num_vouts_received = 0;
|
|
|
|
|
tx_pub_key = pub_key_field.pub_key;
|
|
|
|
|
tools::threadpool& tpool = tools::threadpool::getInstance();
|
|
|
|
@ -1170,7 +1173,7 @@ void wallet2::process_new_transaction(const crypto::hash &txid, const cryptonote
|
|
|
|
|
}
|
|
|
|
|
else if (miner_tx && m_refresh_type == RefreshOptimizeCoinbase)
|
|
|
|
|
{
|
|
|
|
|
check_acc_out_precomp(tx.vout[0], derivation, additional_derivations, 0, tx_scan_info[0]);
|
|
|
|
|
check_acc_out_precomp_once(tx.vout[0], derivation, additional_derivations, 0, tx_scan_info[0], output_found[0]);
|
|
|
|
|
THROW_WALLET_EXCEPTION_IF(tx_scan_info[0].error, error::acc_outs_lookup_error, tx, tx_pub_key, m_account.get_keys());
|
|
|
|
|
|
|
|
|
|
// this assumes that the miner tx pays a single address
|
|
|
|
@ -1180,8 +1183,8 @@ void wallet2::process_new_transaction(const crypto::hash &txid, const cryptonote
|
|
|
|
|
// the first one was already checked
|
|
|
|
|
for (size_t i = 1; i < tx.vout.size(); ++i)
|
|
|
|
|
{
|
|
|
|
|
tpool.submit(&waiter, boost::bind(&wallet2::check_acc_out_precomp, this, std::cref(tx.vout[i]), std::cref(derivation), std::cref(additional_derivations), i,
|
|
|
|
|
std::ref(tx_scan_info[i])));
|
|
|
|
|
tpool.submit(&waiter, boost::bind(&wallet2::check_acc_out_precomp_once, this, std::cref(tx.vout[i]), std::cref(derivation), std::cref(additional_derivations), i,
|
|
|
|
|
std::ref(tx_scan_info[i]), std::ref(output_found[i])));
|
|
|
|
|
}
|
|
|
|
|
waiter.wait();
|
|
|
|
|
// then scan all outputs from 0
|
|
|
|
@ -1203,8 +1206,8 @@ void wallet2::process_new_transaction(const crypto::hash &txid, const cryptonote
|
|
|
|
|
{
|
|
|
|
|
for (size_t i = 0; i < tx.vout.size(); ++i)
|
|
|
|
|
{
|
|
|
|
|
tpool.submit(&waiter, boost::bind(&wallet2::check_acc_out_precomp, this, std::cref(tx.vout[i]), std::cref(derivation), std::cref(additional_derivations), i,
|
|
|
|
|
std::ref(tx_scan_info[i])));
|
|
|
|
|
tpool.submit(&waiter, boost::bind(&wallet2::check_acc_out_precomp_once, this, std::cref(tx.vout[i]), std::cref(derivation), std::cref(additional_derivations), i,
|
|
|
|
|
std::ref(tx_scan_info[i]), std::ref(output_found[i])));
|
|
|
|
|
}
|
|
|
|
|
waiter.wait();
|
|
|
|
|
|
|
|
|
@ -1225,7 +1228,7 @@ void wallet2::process_new_transaction(const crypto::hash &txid, const cryptonote
|
|
|
|
|
{
|
|
|
|
|
for (size_t i = 0; i < tx.vout.size(); ++i)
|
|
|
|
|
{
|
|
|
|
|
check_acc_out_precomp(tx.vout[i], derivation, additional_derivations, i, tx_scan_info[i]);
|
|
|
|
|
check_acc_out_precomp_once(tx.vout[i], derivation, additional_derivations, i, tx_scan_info[i], output_found[i]);
|
|
|
|
|
THROW_WALLET_EXCEPTION_IF(tx_scan_info[i].error, error::acc_outs_lookup_error, tx, tx_pub_key, m_account.get_keys());
|
|
|
|
|
if (tx_scan_info[i].received)
|
|
|
|
|
{
|
|
|
|
@ -5353,15 +5356,10 @@ uint32_t wallet2::adjust_priority(uint32_t priority)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// get the current full reward zone
|
|
|
|
|
cryptonote::COMMAND_RPC_GET_INFO::request getinfo_req = AUTO_VAL_INIT(getinfo_req);
|
|
|
|
|
cryptonote::COMMAND_RPC_GET_INFO::response getinfo_res = AUTO_VAL_INIT(getinfo_res);
|
|
|
|
|
m_daemon_rpc_mutex.lock();
|
|
|
|
|
bool r = net_utils::invoke_http_json_rpc("/json_rpc", "get_info", getinfo_req, getinfo_res, m_http_client);
|
|
|
|
|
m_daemon_rpc_mutex.unlock();
|
|
|
|
|
THROW_WALLET_EXCEPTION_IF(!r, error::no_connection_to_daemon, "get_info");
|
|
|
|
|
THROW_WALLET_EXCEPTION_IF(getinfo_res.status == CORE_RPC_STATUS_BUSY, error::daemon_busy, "get_info");
|
|
|
|
|
THROW_WALLET_EXCEPTION_IF(getinfo_res.status != CORE_RPC_STATUS_OK, error::get_tx_pool_error);
|
|
|
|
|
const uint64_t full_reward_zone = getinfo_res.block_size_limit / 2;
|
|
|
|
|
uint64_t block_size_limit = 0;
|
|
|
|
|
const auto result = m_node_rpc_proxy.get_block_size_limit(block_size_limit);
|
|
|
|
|
throw_on_rpc_response_error(result, "get_info");
|
|
|
|
|
const uint64_t full_reward_zone = block_size_limit / 2;
|
|
|
|
|
|
|
|
|
|
// get the last N block headers and sum the block sizes
|
|
|
|
|
const size_t N = 10;
|
|
|
|
@ -5375,7 +5373,7 @@ uint32_t wallet2::adjust_priority(uint32_t priority)
|
|
|
|
|
m_daemon_rpc_mutex.lock();
|
|
|
|
|
getbh_req.start_height = m_blockchain.size() - N;
|
|
|
|
|
getbh_req.end_height = m_blockchain.size() - 1;
|
|
|
|
|
r = net_utils::invoke_http_json_rpc("/json_rpc", "getblockheadersrange", getbh_req, getbh_res, m_http_client, rpc_timeout);
|
|
|
|
|
bool r = net_utils::invoke_http_json_rpc("/json_rpc", "getblockheadersrange", getbh_req, getbh_res, m_http_client, rpc_timeout);
|
|
|
|
|
m_daemon_rpc_mutex.unlock();
|
|
|
|
|
THROW_WALLET_EXCEPTION_IF(!r, error::no_connection_to_daemon, "getblockheadersrange");
|
|
|
|
|
THROW_WALLET_EXCEPTION_IF(getbh_res.status == CORE_RPC_STATUS_BUSY, error::daemon_busy, "getblockheadersrange");
|
|
|
|
@ -9129,31 +9127,15 @@ uint64_t wallet2::get_daemon_blockchain_height(string &err) const
|
|
|
|
|
|
|
|
|
|
uint64_t wallet2::get_daemon_blockchain_target_height(string &err)
|
|
|
|
|
{
|
|
|
|
|
cryptonote::COMMAND_RPC_GET_INFO::request req_t = AUTO_VAL_INIT(req_t);
|
|
|
|
|
cryptonote::COMMAND_RPC_GET_INFO::response resp_t = AUTO_VAL_INIT(resp_t);
|
|
|
|
|
m_daemon_rpc_mutex.lock();
|
|
|
|
|
bool ok = net_utils::invoke_http_json_rpc("/json_rpc", "get_info", req_t, resp_t, m_http_client);
|
|
|
|
|
m_daemon_rpc_mutex.unlock();
|
|
|
|
|
if (ok)
|
|
|
|
|
{
|
|
|
|
|
if (resp_t.status == CORE_RPC_STATUS_BUSY)
|
|
|
|
|
{
|
|
|
|
|
err = "daemon is busy. Please try again later.";
|
|
|
|
|
}
|
|
|
|
|
else if (resp_t.status != CORE_RPC_STATUS_OK)
|
|
|
|
|
{
|
|
|
|
|
err = resp_t.status;
|
|
|
|
|
}
|
|
|
|
|
else // success, cleaning up error message
|
|
|
|
|
{
|
|
|
|
|
err = "";
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
err = "";
|
|
|
|
|
uint64_t target_height = 0;
|
|
|
|
|
const auto result = m_node_rpc_proxy.get_target_height(target_height);
|
|
|
|
|
if (result && *result != CORE_RPC_STATUS_OK)
|
|
|
|
|
{
|
|
|
|
|
err = "possibly lost connection to daemon";
|
|
|
|
|
err= *result;
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
return resp_t.target_height;
|
|
|
|
|
return target_height;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
uint64_t wallet2::get_approximate_blockchain_height() const
|
|
|
|
@ -10395,15 +10377,10 @@ std::vector<std::pair<uint64_t, uint64_t>> wallet2::estimate_backlog(const std::
|
|
|
|
|
THROW_WALLET_EXCEPTION_IF(res.status == CORE_RPC_STATUS_BUSY, error::daemon_busy, "get_txpool_backlog");
|
|
|
|
|
THROW_WALLET_EXCEPTION_IF(res.status != CORE_RPC_STATUS_OK, error::get_tx_pool_error);
|
|
|
|
|
|
|
|
|
|
cryptonote::COMMAND_RPC_GET_INFO::request req_t = AUTO_VAL_INIT(req_t);
|
|
|
|
|
cryptonote::COMMAND_RPC_GET_INFO::response resp_t = AUTO_VAL_INIT(resp_t);
|
|
|
|
|
m_daemon_rpc_mutex.lock();
|
|
|
|
|
r = net_utils::invoke_http_json_rpc("/json_rpc", "get_info", req_t, resp_t, m_http_client);
|
|
|
|
|
m_daemon_rpc_mutex.unlock();
|
|
|
|
|
THROW_WALLET_EXCEPTION_IF(!r, error::no_connection_to_daemon, "get_info");
|
|
|
|
|
THROW_WALLET_EXCEPTION_IF(resp_t.status == CORE_RPC_STATUS_BUSY, error::daemon_busy, "get_info");
|
|
|
|
|
THROW_WALLET_EXCEPTION_IF(resp_t.status != CORE_RPC_STATUS_OK, error::get_tx_pool_error);
|
|
|
|
|
uint64_t full_reward_zone = resp_t.block_size_limit / 2;
|
|
|
|
|
uint64_t block_size_limit = 0;
|
|
|
|
|
const auto result = m_node_rpc_proxy.get_block_size_limit(block_size_limit);
|
|
|
|
|
throw_on_rpc_response_error(result, "get_info");
|
|
|
|
|
uint64_t full_reward_zone = block_size_limit / 2;
|
|
|
|
|
|
|
|
|
|
std::vector<std::pair<uint64_t, uint64_t>> blocks;
|
|
|
|
|
for (const auto &fee_level: fee_levels)
|
|
|
|
|