Change wallet to not try to extract tx public key when tx has no outputs (fixes 202612 tx format messages and is otherwise correct)
This commit is contained in:
parent
08205f01d9
commit
6b77e8358c
1 changed files with 49 additions and 45 deletions
|
@ -109,55 +109,59 @@ void wallet2::process_new_transaction(const cryptonote::transaction& tx, uint64_
|
||||||
LOG_PRINT_L0("Transaction extra has unsupported format: " << get_transaction_hash(tx));
|
LOG_PRINT_L0("Transaction extra has unsupported format: " << get_transaction_hash(tx));
|
||||||
}
|
}
|
||||||
|
|
||||||
tx_extra_pub_key pub_key_field;
|
// Don't try to extract tx public key if tx has no ouputs
|
||||||
if(!find_tx_extra_field_by_type(tx_extra_fields, pub_key_field))
|
if (!tx.vout.empty())
|
||||||
{
|
{
|
||||||
LOG_PRINT_L0("Public key wasn't found in the transaction extra. Skipping transaction " << get_transaction_hash(tx));
|
tx_extra_pub_key pub_key_field;
|
||||||
if(0 != m_callback)
|
if(!find_tx_extra_field_by_type(tx_extra_fields, pub_key_field))
|
||||||
m_callback->on_skip_transaction(height, tx);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
crypto::public_key tx_pub_key = pub_key_field.pub_key;
|
|
||||||
bool r = lookup_acc_outs(m_account.get_keys(), tx, tx_pub_key, outs, tx_money_got_in_outs);
|
|
||||||
THROW_WALLET_EXCEPTION_IF(!r, error::acc_outs_lookup_error, tx, tx_pub_key, m_account.get_keys());
|
|
||||||
|
|
||||||
if(!outs.empty() && tx_money_got_in_outs)
|
|
||||||
{
|
|
||||||
//good news - got money! take care about it
|
|
||||||
//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::response res = AUTO_VAL_INIT(res);
|
|
||||||
req.txid = get_transaction_hash(tx);
|
|
||||||
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(!r, error::no_connection_to_daemon, "get_o_indexes.bin");
|
|
||||||
THROW_WALLET_EXCEPTION_IF(res.status == CORE_RPC_STATUS_BUSY, error::daemon_busy, "get_o_indexes.bin");
|
|
||||||
THROW_WALLET_EXCEPTION_IF(res.status != CORE_RPC_STATUS_OK, error::get_out_indices_error, res.status);
|
|
||||||
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)
|
|
||||||
{
|
{
|
||||||
THROW_WALLET_EXCEPTION_IF(tx.vout.size() <= o, error::wallet_internal_error, "wrong out in transaction: internal index=" +
|
LOG_PRINT_L0("Public key wasn't found in the transaction extra. Skipping transaction " << get_transaction_hash(tx));
|
||||||
std::to_string(o) + ", total_outs=" + std::to_string(tx.vout.size()));
|
if(0 != m_callback)
|
||||||
|
m_callback->on_skip_transaction(height, tx);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
m_transfers.push_back(boost::value_initialized<transfer_details>());
|
crypto::public_key tx_pub_key = pub_key_field.pub_key;
|
||||||
transfer_details& td = m_transfers.back();
|
bool r = lookup_acc_outs(m_account.get_keys(), tx, tx_pub_key, outs, tx_money_got_in_outs);
|
||||||
td.m_block_height = height;
|
THROW_WALLET_EXCEPTION_IF(!r, error::acc_outs_lookup_error, tx, tx_pub_key, m_account.get_keys());
|
||||||
td.m_internal_output_index = o;
|
|
||||||
td.m_global_output_index = res.o_indexes[o];
|
|
||||||
td.m_tx = tx;
|
|
||||||
td.m_spent = false;
|
|
||||||
cryptonote::keypair in_ephemeral;
|
|
||||||
cryptonote::generate_key_image_helper(m_account.get_keys(), tx_pub_key, o, in_ephemeral, td.m_key_image);
|
|
||||||
THROW_WALLET_EXCEPTION_IF(in_ephemeral.pub != boost::get<cryptonote::txout_to_key>(tx.vout[o].target).key,
|
|
||||||
error::wallet_internal_error, "key_image generated ephemeral public key not matched with output_key");
|
|
||||||
|
|
||||||
m_key_images[td.m_key_image] = m_transfers.size()-1;
|
if(!outs.empty() && tx_money_got_in_outs)
|
||||||
LOG_PRINT_L0("Received money: " << print_money(td.amount()) << ", with tx: " << get_transaction_hash(tx));
|
{
|
||||||
if (0 != m_callback)
|
//good news - got money! take care about it
|
||||||
m_callback->on_money_received(height, td.m_tx, td.m_internal_output_index);
|
//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::response res = AUTO_VAL_INIT(res);
|
||||||
|
req.txid = get_transaction_hash(tx);
|
||||||
|
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(!r, error::no_connection_to_daemon, "get_o_indexes.bin");
|
||||||
|
THROW_WALLET_EXCEPTION_IF(res.status == CORE_RPC_STATUS_BUSY, error::daemon_busy, "get_o_indexes.bin");
|
||||||
|
THROW_WALLET_EXCEPTION_IF(res.status != CORE_RPC_STATUS_OK, error::get_out_indices_error, res.status);
|
||||||
|
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)
|
||||||
|
{
|
||||||
|
THROW_WALLET_EXCEPTION_IF(tx.vout.size() <= o, error::wallet_internal_error, "wrong out in transaction: internal index=" +
|
||||||
|
std::to_string(o) + ", total_outs=" + std::to_string(tx.vout.size()));
|
||||||
|
|
||||||
|
m_transfers.push_back(boost::value_initialized<transfer_details>());
|
||||||
|
transfer_details& td = m_transfers.back();
|
||||||
|
td.m_block_height = height;
|
||||||
|
td.m_internal_output_index = o;
|
||||||
|
td.m_global_output_index = res.o_indexes[o];
|
||||||
|
td.m_tx = tx;
|
||||||
|
td.m_spent = false;
|
||||||
|
cryptonote::keypair in_ephemeral;
|
||||||
|
cryptonote::generate_key_image_helper(m_account.get_keys(), tx_pub_key, o, in_ephemeral, td.m_key_image);
|
||||||
|
THROW_WALLET_EXCEPTION_IF(in_ephemeral.pub != boost::get<cryptonote::txout_to_key>(tx.vout[o].target).key,
|
||||||
|
error::wallet_internal_error, "key_image generated ephemeral public key not matched with output_key");
|
||||||
|
|
||||||
|
m_key_images[td.m_key_image] = m_transfers.size()-1;
|
||||||
|
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);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue