mirror of
https://github.com/monero-project/monero.git
synced 2024-12-28 21:06:14 -05:00
Merge pull request #916
b89b963
wallet: add unconfirmed incoming txes from the txpool (moneromooo-monero)
This commit is contained in:
commit
07f974a499
@ -3082,6 +3082,7 @@ bool simple_wallet::show_transfers(const std::vector<std::string> &args_)
|
|||||||
bool out = true;
|
bool out = true;
|
||||||
bool pending = true;
|
bool pending = true;
|
||||||
bool failed = true;
|
bool failed = true;
|
||||||
|
bool pool = true;
|
||||||
uint64_t min_height = 0;
|
uint64_t min_height = 0;
|
||||||
uint64_t max_height = (uint64_t)-1;
|
uint64_t max_height = (uint64_t)-1;
|
||||||
|
|
||||||
@ -3099,7 +3100,7 @@ bool simple_wallet::show_transfers(const std::vector<std::string> &args_)
|
|||||||
local_args.erase(local_args.begin());
|
local_args.erase(local_args.begin());
|
||||||
}
|
}
|
||||||
else if (local_args[0] == "out" || local_args[0] == "outgoing") {
|
else if (local_args[0] == "out" || local_args[0] == "outgoing") {
|
||||||
in = false;
|
in = pool = false;
|
||||||
local_args.erase(local_args.begin());
|
local_args.erase(local_args.begin());
|
||||||
}
|
}
|
||||||
else if (local_args[0] == "pending") {
|
else if (local_args[0] == "pending") {
|
||||||
@ -3107,7 +3108,11 @@ bool simple_wallet::show_transfers(const std::vector<std::string> &args_)
|
|||||||
local_args.erase(local_args.begin());
|
local_args.erase(local_args.begin());
|
||||||
}
|
}
|
||||||
else if (local_args[0] == "failed") {
|
else if (local_args[0] == "failed") {
|
||||||
in = out = pending = false;
|
in = out = pending = pool = false;
|
||||||
|
local_args.erase(local_args.begin());
|
||||||
|
}
|
||||||
|
else if (local_args[0] == "pool") {
|
||||||
|
in = out = pending = failed = false;
|
||||||
local_args.erase(local_args.begin());
|
local_args.erase(local_args.begin());
|
||||||
}
|
}
|
||||||
else if (local_args[0] == "all" || local_args[0] == "both") {
|
else if (local_args[0] == "all" || local_args[0] == "both") {
|
||||||
@ -3182,6 +3187,27 @@ bool simple_wallet::show_transfers(const std::vector<std::string> &args_)
|
|||||||
((unsigned long long)i->first) % (i->second.first ? tr("in") : tr("out")) % i->second.second;
|
((unsigned long long)i->first) % (i->second.first ? tr("in") : tr("out")) % i->second.second;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (pool) {
|
||||||
|
try
|
||||||
|
{
|
||||||
|
m_wallet->update_pool_state();
|
||||||
|
std::list<std::pair<crypto::hash, tools::wallet2::payment_details>> payments;
|
||||||
|
m_wallet->get_unconfirmed_payments(payments);
|
||||||
|
for (std::list<std::pair<crypto::hash, tools::wallet2::payment_details>>::const_iterator i = payments.begin(); i != payments.end(); ++i) {
|
||||||
|
const tools::wallet2::payment_details &pd = i->second;
|
||||||
|
std::string payment_id = string_tools::pod_to_hex(i->first);
|
||||||
|
if (payment_id.substr(16).find_first_not_of('0') == std::string::npos)
|
||||||
|
payment_id = payment_id.substr(0,16);
|
||||||
|
std::string note = m_wallet->get_tx_note(pd.m_tx_hash);
|
||||||
|
message_writer() << (boost::format("%8.8s %6.6s %16.16s %20.20s %s %s %s %s") % "pool" % "in" % get_human_readable_timestamp(pd.m_timestamp) % print_money(pd.m_amount) % string_tools::pod_to_hex(pd.m_tx_hash) % payment_id % "-" % note).str();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (...)
|
||||||
|
{
|
||||||
|
fail_msg_writer() << "Failed to get pool state";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// print unconfirmed last
|
// print unconfirmed last
|
||||||
if (pending || failed) {
|
if (pending || failed) {
|
||||||
std::list<std::pair<crypto::hash, tools::wallet2::unconfirmed_transfer_details>> upayments;
|
std::list<std::pair<crypto::hash, tools::wallet2::unconfirmed_transfer_details>> upayments;
|
||||||
|
@ -186,7 +186,7 @@ void wallet2::check_acc_out(const account_keys &acc, const tx_out &o, const cryp
|
|||||||
error = false;
|
error = false;
|
||||||
}
|
}
|
||||||
//----------------------------------------------------------------------------------------------------
|
//----------------------------------------------------------------------------------------------------
|
||||||
void wallet2::process_new_transaction(const cryptonote::transaction& tx, uint64_t height, uint64_t ts, bool miner_tx)
|
void wallet2::process_new_transaction(const cryptonote::transaction& tx, uint64_t height, uint64_t ts, bool miner_tx, bool pool)
|
||||||
{
|
{
|
||||||
if (!miner_tx)
|
if (!miner_tx)
|
||||||
process_unconfirmed(tx, height);
|
process_unconfirmed(tx, height);
|
||||||
@ -318,16 +318,19 @@ void wallet2::process_new_transaction(const cryptonote::transaction& tx, uint64_
|
|||||||
//usually we have only one transfer for user in transaction
|
//usually we have only one transfer for user in transaction
|
||||||
cryptonote::COMMAND_RPC_GET_TX_GLOBAL_OUTPUTS_INDEXES::request req = AUTO_VAL_INIT(req);
|
cryptonote::COMMAND_RPC_GET_TX_GLOBAL_OUTPUTS_INDEXES::request req = AUTO_VAL_INIT(req);
|
||||||
cryptonote::COMMAND_RPC_GET_TX_GLOBAL_OUTPUTS_INDEXES::response res = AUTO_VAL_INIT(res);
|
cryptonote::COMMAND_RPC_GET_TX_GLOBAL_OUTPUTS_INDEXES::response res = AUTO_VAL_INIT(res);
|
||||||
req.txid = get_transaction_hash(tx);
|
if (!pool)
|
||||||
m_daemon_rpc_mutex.lock();
|
{
|
||||||
bool r = net_utils::invoke_http_bin_remote_command2(m_daemon_address + "/get_o_indexes.bin", req, res, m_http_client, WALLET_RCP_CONNECTION_TIMEOUT);
|
req.txid = get_transaction_hash(tx);
|
||||||
m_daemon_rpc_mutex.unlock();
|
m_daemon_rpc_mutex.lock();
|
||||||
THROW_WALLET_EXCEPTION_IF(!r, error::no_connection_to_daemon, "get_o_indexes.bin");
|
bool r = net_utils::invoke_http_bin_remote_command2(m_daemon_address + "/get_o_indexes.bin", req, res, m_http_client, WALLET_RCP_CONNECTION_TIMEOUT);
|
||||||
THROW_WALLET_EXCEPTION_IF(res.status == CORE_RPC_STATUS_BUSY, error::daemon_busy, "get_o_indexes.bin");
|
m_daemon_rpc_mutex.unlock();
|
||||||
THROW_WALLET_EXCEPTION_IF(res.status != CORE_RPC_STATUS_OK, error::get_out_indices_error, res.status);
|
THROW_WALLET_EXCEPTION_IF(!r, error::no_connection_to_daemon, "get_o_indexes.bin");
|
||||||
THROW_WALLET_EXCEPTION_IF(res.o_indexes.size() != tx.vout.size(), error::wallet_internal_error,
|
THROW_WALLET_EXCEPTION_IF(res.status == CORE_RPC_STATUS_BUSY, error::daemon_busy, "get_o_indexes.bin");
|
||||||
"transactions outputs size=" + std::to_string(tx.vout.size()) +
|
THROW_WALLET_EXCEPTION_IF(res.status != CORE_RPC_STATUS_OK, error::get_out_indices_error, res.status);
|
||||||
" not match with COMMAND_RPC_GET_TX_GLOBAL_OUTPUTS_INDEXES response size=" + std::to_string(res.o_indexes.size()));
|
THROW_WALLET_EXCEPTION_IF(res.o_indexes.size() != tx.vout.size(), error::wallet_internal_error,
|
||||||
|
"transactions outputs size=" + std::to_string(tx.vout.size()) +
|
||||||
|
" not match with COMMAND_RPC_GET_TX_GLOBAL_OUTPUTS_INDEXES response size=" + std::to_string(res.o_indexes.size()));
|
||||||
|
}
|
||||||
|
|
||||||
BOOST_FOREACH(size_t o, outs)
|
BOOST_FOREACH(size_t o, outs)
|
||||||
{
|
{
|
||||||
@ -347,18 +350,21 @@ void wallet2::process_new_transaction(const cryptonote::transaction& tx, uint64_
|
|||||||
+ ", m_transfers.size() is " + boost::lexical_cast<std::string>(m_transfers.size()));
|
+ ", m_transfers.size() is " + boost::lexical_cast<std::string>(m_transfers.size()));
|
||||||
if (kit == m_key_images.end())
|
if (kit == m_key_images.end())
|
||||||
{
|
{
|
||||||
m_transfers.push_back(boost::value_initialized<transfer_details>());
|
if (!pool)
|
||||||
transfer_details& td = m_transfers.back();
|
{
|
||||||
td.m_block_height = height;
|
m_transfers.push_back(boost::value_initialized<transfer_details>());
|
||||||
td.m_internal_output_index = o;
|
transfer_details& td = m_transfers.back();
|
||||||
td.m_global_output_index = res.o_indexes[o];
|
td.m_block_height = height;
|
||||||
td.m_tx = tx;
|
td.m_internal_output_index = o;
|
||||||
td.m_key_image = ki;
|
td.m_global_output_index = res.o_indexes[o];
|
||||||
td.m_spent = false;
|
td.m_tx = tx;
|
||||||
m_key_images[td.m_key_image] = m_transfers.size()-1;
|
td.m_key_image = ki;
|
||||||
LOG_PRINT_L0("Received money: " << print_money(td.amount()) << ", with tx: " << get_transaction_hash(tx));
|
td.m_spent = false;
|
||||||
if (0 != m_callback)
|
m_key_images[td.m_key_image] = m_transfers.size()-1;
|
||||||
m_callback->on_money_received(height, td.m_tx, td.m_internal_output_index);
|
LOG_PRINT_L0("Received money: " << print_money(td.amount()) << ", with tx: " << get_transaction_hash(tx));
|
||||||
|
if (0 != m_callback)
|
||||||
|
m_callback->on_money_received(height, td.m_tx, td.m_internal_output_index);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else if (m_transfers[kit->second].m_spent || m_transfers[kit->second].amount() >= tx.vout[o].amount)
|
else if (m_transfers[kit->second].m_spent || m_transfers[kit->second].amount() >= tx.vout[o].amount)
|
||||||
{
|
{
|
||||||
@ -375,17 +381,20 @@ void wallet2::process_new_transaction(const cryptonote::transaction& tx, uint64_
|
|||||||
// The new larger output replaced a previous smaller one
|
// The new larger output replaced a previous smaller one
|
||||||
tx_money_got_in_outs -= tx.vout[o].amount;
|
tx_money_got_in_outs -= tx.vout[o].amount;
|
||||||
|
|
||||||
transfer_details &td = m_transfers[kit->second];
|
if (!pool)
|
||||||
td.m_block_height = height;
|
{
|
||||||
td.m_internal_output_index = o;
|
transfer_details &td = m_transfers[kit->second];
|
||||||
td.m_global_output_index = res.o_indexes[o];
|
td.m_block_height = height;
|
||||||
td.m_tx = tx;
|
td.m_internal_output_index = o;
|
||||||
THROW_WALLET_EXCEPTION_IF(td.m_key_image != ki, error::wallet_internal_error, "Inconsistent key images");
|
td.m_global_output_index = res.o_indexes[o];
|
||||||
THROW_WALLET_EXCEPTION_IF(td.m_spent, error::wallet_internal_error, "Inconsistent spent status");
|
td.m_tx = tx;
|
||||||
|
THROW_WALLET_EXCEPTION_IF(td.m_key_image != ki, error::wallet_internal_error, "Inconsistent key images");
|
||||||
|
THROW_WALLET_EXCEPTION_IF(td.m_spent, error::wallet_internal_error, "Inconsistent spent status");
|
||||||
|
|
||||||
LOG_PRINT_L0("Received money: " << print_money(td.amount()) << ", with tx: " << get_transaction_hash(tx));
|
LOG_PRINT_L0("Received money: " << print_money(td.amount()) << ", with tx: " << get_transaction_hash(tx));
|
||||||
if (0 != m_callback)
|
if (0 != m_callback)
|
||||||
m_callback->on_money_received(height, td.m_tx, td.m_internal_output_index);
|
m_callback->on_money_received(height, td.m_tx, td.m_internal_output_index);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -462,8 +471,11 @@ void wallet2::process_new_transaction(const cryptonote::transaction& tx, uint64_
|
|||||||
payment.m_block_height = height;
|
payment.m_block_height = height;
|
||||||
payment.m_unlock_time = tx.unlock_time;
|
payment.m_unlock_time = tx.unlock_time;
|
||||||
payment.m_timestamp = ts;
|
payment.m_timestamp = ts;
|
||||||
m_payments.emplace(payment_id, payment);
|
if (pool)
|
||||||
LOG_PRINT_L2("Payment found: " << payment_id << " / " << payment.m_tx_hash << " / " << payment.m_amount);
|
m_unconfirmed_payments.emplace(payment_id, payment);
|
||||||
|
else
|
||||||
|
m_payments.emplace(payment_id, payment);
|
||||||
|
LOG_PRINT_L2("Payment found in " << (pool ? "pool" : "block") << ": " << payment_id << " / " << payment.m_tx_hash << " / " << payment.m_amount);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
//----------------------------------------------------------------------------------------------------
|
//----------------------------------------------------------------------------------------------------
|
||||||
@ -506,7 +518,7 @@ void wallet2::process_new_blockchain_entry(const cryptonote::block& b, const cry
|
|||||||
if(b.timestamp + 60*60*24 > m_account.get_createtime() && height >= m_refresh_from_block_height)
|
if(b.timestamp + 60*60*24 > m_account.get_createtime() && height >= m_refresh_from_block_height)
|
||||||
{
|
{
|
||||||
TIME_MEASURE_START(miner_tx_handle_time);
|
TIME_MEASURE_START(miner_tx_handle_time);
|
||||||
process_new_transaction(b.miner_tx, height, b.timestamp, true);
|
process_new_transaction(b.miner_tx, height, b.timestamp, true, false);
|
||||||
TIME_MEASURE_FINISH(miner_tx_handle_time);
|
TIME_MEASURE_FINISH(miner_tx_handle_time);
|
||||||
|
|
||||||
TIME_MEASURE_START(txs_handle_time);
|
TIME_MEASURE_START(txs_handle_time);
|
||||||
@ -515,7 +527,7 @@ void wallet2::process_new_blockchain_entry(const cryptonote::block& b, const cry
|
|||||||
cryptonote::transaction tx;
|
cryptonote::transaction tx;
|
||||||
bool r = parse_and_validate_tx_from_blob(txblob, tx);
|
bool r = parse_and_validate_tx_from_blob(txblob, tx);
|
||||||
THROW_WALLET_EXCEPTION_IF(!r, error::tx_parse_error, txblob);
|
THROW_WALLET_EXCEPTION_IF(!r, error::tx_parse_error, txblob);
|
||||||
process_new_transaction(tx, height, b.timestamp, false);
|
process_new_transaction(tx, height, b.timestamp, false, false);
|
||||||
}
|
}
|
||||||
TIME_MEASURE_FINISH(txs_handle_time);
|
TIME_MEASURE_FINISH(txs_handle_time);
|
||||||
LOG_PRINT_L2("Processed block: " << bl_id << ", height " << height << ", " << miner_tx_handle_time + txs_handle_time << "(" << miner_tx_handle_time << "/" << txs_handle_time <<")ms");
|
LOG_PRINT_L2("Processed block: " << bl_id << ", height " << height << ", " << miner_tx_handle_time + txs_handle_time << "(" << miner_tx_handle_time << "/" << txs_handle_time <<")ms");
|
||||||
@ -743,20 +755,16 @@ void wallet2::pull_next_blocks(uint64_t start_height, uint64_t &blocks_start_hei
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
//----------------------------------------------------------------------------------------------------
|
//----------------------------------------------------------------------------------------------------
|
||||||
void wallet2::check_pending_txes()
|
void wallet2::update_pool_state()
|
||||||
{
|
{
|
||||||
// if we don't have any pending txes, we don't need to check anything
|
// get the pool state
|
||||||
if (m_unconfirmed_txs.empty())
|
|
||||||
return;
|
|
||||||
|
|
||||||
// we have at least one pending tx, so get the pool state
|
|
||||||
cryptonote::COMMAND_RPC_GET_TRANSACTION_POOL::request req;
|
cryptonote::COMMAND_RPC_GET_TRANSACTION_POOL::request req;
|
||||||
cryptonote::COMMAND_RPC_GET_TRANSACTION_POOL::response res;
|
cryptonote::COMMAND_RPC_GET_TRANSACTION_POOL::response res;
|
||||||
m_daemon_rpc_mutex.lock();
|
m_daemon_rpc_mutex.lock();
|
||||||
bool r = epee::net_utils::invoke_http_json_remote_command2(m_daemon_address + "/get_transaction_pool", req, res, m_http_client, 200000);
|
bool r = epee::net_utils::invoke_http_json_remote_command2(m_daemon_address + "/get_transaction_pool", req, res, m_http_client, 200000);
|
||||||
m_daemon_rpc_mutex.unlock();
|
m_daemon_rpc_mutex.unlock();
|
||||||
THROW_WALLET_EXCEPTION_IF(!r, error::no_connection_to_daemon, "check_pending_txes");
|
THROW_WALLET_EXCEPTION_IF(!r, error::no_connection_to_daemon, "get_transaction_pool");
|
||||||
THROW_WALLET_EXCEPTION_IF(res.status == CORE_RPC_STATUS_BUSY, error::daemon_busy, "is_key_image_spent");
|
THROW_WALLET_EXCEPTION_IF(res.status == CORE_RPC_STATUS_BUSY, error::daemon_busy, "get_transaction_pool");
|
||||||
THROW_WALLET_EXCEPTION_IF(res.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);
|
||||||
|
|
||||||
// remove any pending tx that's not in the pool
|
// remove any pending tx that's not in the pool
|
||||||
@ -793,6 +801,120 @@ void wallet2::check_pending_txes()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// remove pool txes to us that aren't in the pool anymore
|
||||||
|
std::unordered_map<crypto::hash, wallet2::payment_details>::iterator uit = m_unconfirmed_payments.begin();
|
||||||
|
while (uit != m_unconfirmed_payments.end())
|
||||||
|
{
|
||||||
|
const std::string txid = string_tools::pod_to_hex(uit->first);
|
||||||
|
bool found = false;
|
||||||
|
for (auto it2: res.transactions)
|
||||||
|
{
|
||||||
|
if (it2.id_hash == txid)
|
||||||
|
{
|
||||||
|
found = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
auto pit = uit++;
|
||||||
|
if (!found)
|
||||||
|
{
|
||||||
|
m_unconfirmed_payments.erase(pit);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// add new pool txes to us
|
||||||
|
for (auto it: res.transactions)
|
||||||
|
{
|
||||||
|
cryptonote::blobdata txid_data;
|
||||||
|
if(epee::string_tools::parse_hexstr_to_binbuff(it.id_hash, txid_data))
|
||||||
|
{
|
||||||
|
const crypto::hash txid = *reinterpret_cast<const crypto::hash*>(txid_data.data());
|
||||||
|
if (m_unconfirmed_payments.find(txid) == m_unconfirmed_payments.end())
|
||||||
|
{
|
||||||
|
LOG_PRINT_L1("Found new pool tx: " << txid);
|
||||||
|
bool found = false;
|
||||||
|
for (const auto &i: m_unconfirmed_txs)
|
||||||
|
{
|
||||||
|
if (i.first == txid)
|
||||||
|
{
|
||||||
|
found = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!found)
|
||||||
|
{
|
||||||
|
// not one of those we sent ourselves
|
||||||
|
cryptonote::COMMAND_RPC_GET_TRANSACTIONS::request req;
|
||||||
|
cryptonote::COMMAND_RPC_GET_TRANSACTIONS::response res;
|
||||||
|
req.txs_hashes.push_back(it.id_hash);
|
||||||
|
req.decode_as_json = false;
|
||||||
|
m_daemon_rpc_mutex.lock();
|
||||||
|
bool r = epee::net_utils::invoke_http_json_remote_command2(m_daemon_address + "/gettransactions", req, res, m_http_client, 200000);
|
||||||
|
m_daemon_rpc_mutex.unlock();
|
||||||
|
if (r && res.status == CORE_RPC_STATUS_OK)
|
||||||
|
{
|
||||||
|
if (res.txs.size() == 1)
|
||||||
|
{
|
||||||
|
// might have just been put in a block
|
||||||
|
if (res.txs[0].in_pool)
|
||||||
|
{
|
||||||
|
cryptonote::transaction tx;
|
||||||
|
cryptonote::blobdata bd;
|
||||||
|
crypto::hash tx_hash, tx_prefix_hash;
|
||||||
|
if (epee::string_tools::parse_hexstr_to_binbuff(res.txs[0].as_hex, bd))
|
||||||
|
{
|
||||||
|
if (cryptonote::parse_and_validate_tx_from_blob(bd, tx, tx_hash, tx_prefix_hash))
|
||||||
|
{
|
||||||
|
if (tx_hash == txid)
|
||||||
|
{
|
||||||
|
process_new_transaction(tx, 0, time(NULL), false, true);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
LOG_PRINT_L0("Mismatched txids when processing unconfimed txes from pool");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
LOG_PRINT_L0("failed to validate transaction from daemon");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
LOG_PRINT_L0("Failed to parse tx " << txid);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
LOG_PRINT_L1("Tx " << txid << " was in pool, but is no more");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
LOG_PRINT_L0("Expected 1 tx, got " << res.txs.size());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
LOG_PRINT_L0("Error calling gettransactions daemon RPC: r " << r << ", status " << res.status);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
LOG_PRINT_L1("We sent that one");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
LOG_PRINT_L1("Already saw that one");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
LOG_PRINT_L0("Failed to parse txid");
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
//----------------------------------------------------------------------------------------------------
|
//----------------------------------------------------------------------------------------------------
|
||||||
void wallet2::fast_refresh(uint64_t stop_height, uint64_t &blocks_start_height, std::list<crypto::hash> &short_chain_history)
|
void wallet2::fast_refresh(uint64_t stop_height, uint64_t &blocks_start_height, std::list<crypto::hash> &short_chain_history)
|
||||||
@ -931,7 +1053,7 @@ void wallet2::refresh(uint64_t start_height, uint64_t & blocks_fetched, bool& re
|
|||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
check_pending_txes();
|
update_pool_state();
|
||||||
}
|
}
|
||||||
catch (...)
|
catch (...)
|
||||||
{
|
{
|
||||||
@ -1733,6 +1855,13 @@ void wallet2::get_unconfirmed_payments_out(std::list<std::pair<crypto::hash,wall
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
//----------------------------------------------------------------------------------------------------
|
//----------------------------------------------------------------------------------------------------
|
||||||
|
void wallet2::get_unconfirmed_payments(std::list<std::pair<crypto::hash,wallet2::payment_details>>& unconfirmed_payments) const
|
||||||
|
{
|
||||||
|
for (auto i = m_unconfirmed_payments.begin(); i != m_unconfirmed_payments.end(); ++i) {
|
||||||
|
unconfirmed_payments.push_back(*i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//----------------------------------------------------------------------------------------------------
|
||||||
void wallet2::rescan_spent()
|
void wallet2::rescan_spent()
|
||||||
{
|
{
|
||||||
std::vector<std::string> key_images;
|
std::vector<std::string> key_images;
|
||||||
|
@ -303,6 +303,8 @@ namespace tools
|
|||||||
void get_payments_out(std::list<std::pair<crypto::hash,wallet2::confirmed_transfer_details>>& confirmed_payments,
|
void get_payments_out(std::list<std::pair<crypto::hash,wallet2::confirmed_transfer_details>>& confirmed_payments,
|
||||||
uint64_t min_height, uint64_t max_height = (uint64_t)-1) const;
|
uint64_t min_height, uint64_t max_height = (uint64_t)-1) const;
|
||||||
void get_unconfirmed_payments_out(std::list<std::pair<crypto::hash,wallet2::unconfirmed_transfer_details>>& unconfirmed_payments) const;
|
void get_unconfirmed_payments_out(std::list<std::pair<crypto::hash,wallet2::unconfirmed_transfer_details>>& unconfirmed_payments) const;
|
||||||
|
void get_unconfirmed_payments(std::list<std::pair<crypto::hash,wallet2::payment_details>>& unconfirmed_payments) const;
|
||||||
|
|
||||||
uint64_t get_blockchain_current_height() const { return m_local_bc_height; }
|
uint64_t get_blockchain_current_height() const { return m_local_bc_height; }
|
||||||
void rescan_spent();
|
void rescan_spent();
|
||||||
void rescan_blockchain(bool refresh = true);
|
void rescan_blockchain(bool refresh = true);
|
||||||
@ -334,6 +336,9 @@ namespace tools
|
|||||||
if(ver < 12)
|
if(ver < 12)
|
||||||
return;
|
return;
|
||||||
a & m_tx_notes;
|
a & m_tx_notes;
|
||||||
|
if(ver < 13)
|
||||||
|
return;
|
||||||
|
a & m_unconfirmed_payments;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
@ -389,6 +394,8 @@ namespace tools
|
|||||||
std::string sign(const std::string &data) const;
|
std::string sign(const std::string &data) const;
|
||||||
bool verify(const std::string &data, const cryptonote::account_public_address &address, const std::string &signature) const;
|
bool verify(const std::string &data, const cryptonote::account_public_address &address, const std::string &signature) const;
|
||||||
|
|
||||||
|
void update_pool_state();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
/*!
|
/*!
|
||||||
* \brief Stores wallet information to wallet file.
|
* \brief Stores wallet information to wallet file.
|
||||||
@ -404,7 +411,7 @@ namespace tools
|
|||||||
* \param password Password of wallet file
|
* \param password Password of wallet file
|
||||||
*/
|
*/
|
||||||
bool load_keys(const std::string& keys_file_name, const std::string& password);
|
bool load_keys(const std::string& keys_file_name, const std::string& password);
|
||||||
void process_new_transaction(const cryptonote::transaction& tx, uint64_t height, uint64_t ts, bool miner_tx);
|
void process_new_transaction(const cryptonote::transaction& tx, uint64_t height, uint64_t ts, bool miner_tx, bool pool);
|
||||||
void process_new_blockchain_entry(const cryptonote::block& b, const cryptonote::block_complete_entry& bche, const crypto::hash& bl_id, uint64_t height);
|
void process_new_blockchain_entry(const cryptonote::block& b, const cryptonote::block_complete_entry& bche, const crypto::hash& bl_id, uint64_t height);
|
||||||
void detach_blockchain(uint64_t height);
|
void detach_blockchain(uint64_t height);
|
||||||
void get_short_chain_history(std::list<crypto::hash>& ids) const;
|
void get_short_chain_history(std::list<crypto::hash>& ids) const;
|
||||||
@ -428,7 +435,6 @@ namespace tools
|
|||||||
void check_acc_out(const cryptonote::account_keys &acc, const cryptonote::tx_out &o, const crypto::public_key &tx_pub_key, size_t i, uint64_t &money_transfered, bool &error) const;
|
void check_acc_out(const cryptonote::account_keys &acc, const cryptonote::tx_out &o, const crypto::public_key &tx_pub_key, size_t i, uint64_t &money_transfered, bool &error) const;
|
||||||
void parse_block_round(const cryptonote::blobdata &blob, cryptonote::block &bl, crypto::hash &bl_id, bool &error) const;
|
void parse_block_round(const cryptonote::blobdata &blob, cryptonote::block &bl, crypto::hash &bl_id, bool &error) const;
|
||||||
uint64_t get_upper_tranaction_size_limit();
|
uint64_t get_upper_tranaction_size_limit();
|
||||||
void check_pending_txes();
|
|
||||||
std::vector<uint64_t> get_unspent_amounts_vector();
|
std::vector<uint64_t> get_unspent_amounts_vector();
|
||||||
uint64_t sanitize_fee_multiplier(uint64_t fee_multiplier) const;
|
uint64_t sanitize_fee_multiplier(uint64_t fee_multiplier) const;
|
||||||
|
|
||||||
@ -441,6 +447,7 @@ namespace tools
|
|||||||
std::atomic<uint64_t> m_local_bc_height; //temporary workaround
|
std::atomic<uint64_t> m_local_bc_height; //temporary workaround
|
||||||
std::unordered_map<crypto::hash, unconfirmed_transfer_details> m_unconfirmed_txs;
|
std::unordered_map<crypto::hash, unconfirmed_transfer_details> m_unconfirmed_txs;
|
||||||
std::unordered_map<crypto::hash, confirmed_transfer_details> m_confirmed_txs;
|
std::unordered_map<crypto::hash, confirmed_transfer_details> m_confirmed_txs;
|
||||||
|
std::unordered_map<crypto::hash, payment_details> m_unconfirmed_payments;
|
||||||
std::unordered_map<crypto::hash, crypto::secret_key> m_tx_keys;
|
std::unordered_map<crypto::hash, crypto::secret_key> m_tx_keys;
|
||||||
|
|
||||||
transfer_container m_transfers;
|
transfer_container m_transfers;
|
||||||
@ -469,7 +476,7 @@ namespace tools
|
|||||||
uint64_t m_refresh_from_block_height;
|
uint64_t m_refresh_from_block_height;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
BOOST_CLASS_VERSION(tools::wallet2, 12)
|
BOOST_CLASS_VERSION(tools::wallet2, 13)
|
||||||
BOOST_CLASS_VERSION(tools::wallet2::payment_details, 1)
|
BOOST_CLASS_VERSION(tools::wallet2::payment_details, 1)
|
||||||
BOOST_CLASS_VERSION(tools::wallet2::unconfirmed_transfer_details, 3)
|
BOOST_CLASS_VERSION(tools::wallet2::unconfirmed_transfer_details, 3)
|
||||||
BOOST_CLASS_VERSION(tools::wallet2::confirmed_transfer_details, 2)
|
BOOST_CLASS_VERSION(tools::wallet2::confirmed_transfer_details, 2)
|
||||||
|
@ -918,8 +918,8 @@ namespace tools
|
|||||||
std::list<std::pair<crypto::hash, tools::wallet2::confirmed_transfer_details>> payments;
|
std::list<std::pair<crypto::hash, tools::wallet2::confirmed_transfer_details>> payments;
|
||||||
m_wallet.get_payments_out(payments, min_height, max_height);
|
m_wallet.get_payments_out(payments, min_height, max_height);
|
||||||
for (std::list<std::pair<crypto::hash, tools::wallet2::confirmed_transfer_details>>::const_iterator i = payments.begin(); i != payments.end(); ++i) {
|
for (std::list<std::pair<crypto::hash, tools::wallet2::confirmed_transfer_details>>::const_iterator i = payments.begin(); i != payments.end(); ++i) {
|
||||||
res.in.push_back(wallet_rpc::COMMAND_RPC_GET_TRANSFERS::entry());
|
res.out.push_back(wallet_rpc::COMMAND_RPC_GET_TRANSFERS::entry());
|
||||||
wallet_rpc::COMMAND_RPC_GET_TRANSFERS::entry &entry = res.in.back();
|
wallet_rpc::COMMAND_RPC_GET_TRANSFERS::entry &entry = res.out.back();
|
||||||
const tools::wallet2::confirmed_transfer_details &pd = i->second;
|
const tools::wallet2::confirmed_transfer_details &pd = i->second;
|
||||||
|
|
||||||
entry.txid = string_tools::pod_to_hex(i->first);
|
entry.txid = string_tools::pod_to_hex(i->first);
|
||||||
@ -969,6 +969,29 @@ namespace tools
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (req.pool)
|
||||||
|
{
|
||||||
|
m_wallet.update_pool_state();
|
||||||
|
|
||||||
|
std::list<std::pair<crypto::hash, tools::wallet2::payment_details>> payments;
|
||||||
|
m_wallet.get_unconfirmed_payments(payments);
|
||||||
|
for (std::list<std::pair<crypto::hash, tools::wallet2::payment_details>>::const_iterator i = payments.begin(); i != payments.end(); ++i) {
|
||||||
|
res.pool.push_back(wallet_rpc::COMMAND_RPC_GET_TRANSFERS::entry());
|
||||||
|
wallet_rpc::COMMAND_RPC_GET_TRANSFERS::entry &entry = res.pool.back();
|
||||||
|
const tools::wallet2::payment_details &pd = i->second;
|
||||||
|
|
||||||
|
entry.txid = string_tools::pod_to_hex(pd.m_tx_hash);
|
||||||
|
entry.payment_id = string_tools::pod_to_hex(i->first);
|
||||||
|
if (entry.payment_id.substr(16).find_first_not_of('0') == std::string::npos)
|
||||||
|
entry.payment_id = entry.payment_id.substr(0,16);
|
||||||
|
entry.height = 0;
|
||||||
|
entry.timestamp = pd.m_timestamp;
|
||||||
|
entry.amount = pd.m_amount;
|
||||||
|
entry.fee = 0; // TODO
|
||||||
|
entry.note = m_wallet.get_tx_note(pd.m_tx_hash);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
//------------------------------------------------------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------------------------------------------------------
|
||||||
|
@ -496,6 +496,7 @@ namespace wallet_rpc
|
|||||||
bool out;
|
bool out;
|
||||||
bool pending;
|
bool pending;
|
||||||
bool failed;
|
bool failed;
|
||||||
|
bool pool;
|
||||||
|
|
||||||
bool filter_by_height;
|
bool filter_by_height;
|
||||||
uint64_t min_height;
|
uint64_t min_height;
|
||||||
@ -506,6 +507,7 @@ namespace wallet_rpc
|
|||||||
KV_SERIALIZE(out);
|
KV_SERIALIZE(out);
|
||||||
KV_SERIALIZE(pending);
|
KV_SERIALIZE(pending);
|
||||||
KV_SERIALIZE(failed);
|
KV_SERIALIZE(failed);
|
||||||
|
KV_SERIALIZE(pool);
|
||||||
KV_SERIALIZE(filter_by_height);
|
KV_SERIALIZE(filter_by_height);
|
||||||
KV_SERIALIZE(min_height);
|
KV_SERIALIZE(min_height);
|
||||||
KV_SERIALIZE(max_height);
|
KV_SERIALIZE(max_height);
|
||||||
@ -541,12 +543,14 @@ namespace wallet_rpc
|
|||||||
std::list<entry> out;
|
std::list<entry> out;
|
||||||
std::list<entry> pending;
|
std::list<entry> pending;
|
||||||
std::list<entry> failed;
|
std::list<entry> failed;
|
||||||
|
std::list<entry> pool;
|
||||||
|
|
||||||
BEGIN_KV_SERIALIZE_MAP()
|
BEGIN_KV_SERIALIZE_MAP()
|
||||||
KV_SERIALIZE(in);
|
KV_SERIALIZE(in);
|
||||||
KV_SERIALIZE(out);
|
KV_SERIALIZE(out);
|
||||||
KV_SERIALIZE(pending);
|
KV_SERIALIZE(pending);
|
||||||
KV_SERIALIZE(failed);
|
KV_SERIALIZE(failed);
|
||||||
|
KV_SERIALIZE(pool);
|
||||||
END_KV_SERIALIZE_MAP()
|
END_KV_SERIALIZE_MAP()
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
Loading…
Reference in New Issue
Block a user