Import transaction

This commit is contained in:
thotbot 2021-07-03 23:05:40 +02:00 committed by wowario
parent 3ea6587022
commit 4edba5301a
5 changed files with 70 additions and 0 deletions

View file

@ -1348,6 +1348,22 @@ bool WalletImpl::importOutputs(const string &filename)
return true; return true;
} }
bool WalletImpl::importTransaction(const std::string &txid, std::vector<uint64_t> &o_indices, uint64_t height, uint8_t block_version, uint64_t ts, bool miner_tx, bool pool, bool double_spend_seen)
{
try
{
m_wallet->import_tx(txid, o_indices, height, block_version, ts, miner_tx, pool, double_spend_seen);
}
catch (const std::exception &e)
{
LOG_ERROR("Failed to import transaction: " << e.what());
setStatusError(string(tr("Failed to import transaction: ")) + e.what());
return false;
}
return true;
}
void WalletImpl::addSubaddressAccount(const std::string& label) void WalletImpl::addSubaddressAccount(const std::string& label)
{ {
m_wallet->add_subaddress_account(label); m_wallet->add_subaddress_account(label);

View file

@ -184,6 +184,7 @@ public:
bool importKeyImages(const std::string &filename) override; bool importKeyImages(const std::string &filename) override;
bool exportOutputs(const std::string &filename, bool all = false) override; bool exportOutputs(const std::string &filename, bool all = false) override;
bool importOutputs(const std::string &filename) override; bool importOutputs(const std::string &filename) override;
bool importTransaction(const std::string &txid, std::vector<uint64_t> &o_indices, uint64_t height, uint8_t block_version, uint64_t ts, bool miner_tx, bool pool, bool double_spend_seen) override;
virtual void disposeTransaction(PendingTransaction * t) override; virtual void disposeTransaction(PendingTransaction * t) override;
virtual uint64_t estimateTransactionFee(const std::vector<std::pair<std::string, uint64_t>> &destinations, virtual uint64_t estimateTransactionFee(const std::vector<std::pair<std::string, uint64_t>> &destinations,

View file

@ -1062,6 +1062,8 @@ struct Wallet
*/ */
virtual bool importOutputs(const std::string &filename) = 0; virtual bool importOutputs(const std::string &filename) = 0;
virtual bool importTransaction(const std::string &txid, std::vector<uint64_t> &o_indices, uint64_t height, uint8_t block_version, uint64_t ts, bool miner_tx, bool pool, bool double_spend_seen) = 0;
virtual TransactionHistory * history() = 0; virtual TransactionHistory * history() = 0;
virtual AddressBook * addressBook() = 0; virtual AddressBook * addressBook() = 0;
virtual Coins * coins() = 0; virtual Coins * coins() = 0;

View file

@ -2241,6 +2241,8 @@ void wallet2::process_new_transaction(const crypto::hash &txid, const cryptonote
update_multisig_rescan_info(*m_multisig_rescan_k, *m_multisig_rescan_info, m_transfers.size() - 1); update_multisig_rescan_info(*m_multisig_rescan_k, *m_multisig_rescan_info, m_transfers.size() - 1);
} }
LOG_PRINT_L0("Received money: " << print_money(td.amount()) << ", with tx: " << txid); LOG_PRINT_L0("Received money: " << print_money(td.amount()) << ", with tx: " << txid);
lock.unlock();
if (0 != m_callback) if (0 != m_callback)
m_callback->on_money_received(height, txid, tx, td.m_amount, td.m_subaddr_index, spends_one_of_ours(tx), td.m_tx.unlock_time); m_callback->on_money_received(height, txid, tx, td.m_amount, td.m_subaddr_index, spends_one_of_ours(tx), td.m_tx.unlock_time);
} }
@ -3221,6 +3223,54 @@ void wallet2::update_pool_state(std::vector<std::tuple<cryptonote::transaction,
} }
MTRACE("update_pool_state end"); MTRACE("update_pool_state end");
} }
//----------------------------------------------------------------------------------------------------
void wallet2::import_tx(const std::string &txid, std::vector<uint64_t> &o_indices, uint64_t height, uint8_t block_version, uint64_t ts, bool miner_tx, bool pool, bool double_spend_seen)
{
crypto::hash hash;
epee::string_tools::hex_to_pod(txid, hash);
cryptonote::COMMAND_RPC_GET_TRANSACTIONS::request req;
cryptonote::COMMAND_RPC_GET_TRANSACTIONS::response res;
req.txs_hashes.push_back(epee::string_tools::pod_to_hex(hash));
req.decode_as_json = false;
req.prune = true;
bool r;
{
const boost::lock_guard<boost::recursive_mutex> lock{m_daemon_rpc_mutex};
uint64_t pre_call_credits = m_rpc_payment_state.credits;
req.client = get_client_signature();
r = epee::net_utils::invoke_http_json("/gettransactions", req, res, *m_http_client, rpc_timeout);
if (r && res.status == CORE_RPC_STATUS_OK)
check_rpc_cost("/gettransactions", res.credits, pre_call_credits, res.txs.size() * COST_PER_TX);
}
MDEBUG("Got " << r << " and " << res.status);
if (!(r && res.status == CORE_RPC_STATUS_OK)) {
THROW_WALLET_EXCEPTION(error::wallet_internal_error, "Error calling gettransactions daemon RPC: r " + std::to_string(r) + ", status " + get_rpc_status(res.status));
}
if (res.txs.size() != 1) {
THROW_WALLET_EXCEPTION(error::wallet_internal_error, "Expected 1 tx, got " + std::to_string(res.txs.size()));
}
const auto &tx_entry = res.txs[0];
cryptonote::transaction tx;
cryptonote::blobdata bd;
crypto::hash tx_hash;
if (!get_pruned_tx(tx_entry, tx, tx_hash)) {
THROW_WALLET_EXCEPTION(error::wallet_internal_error, "Failed to parse transaction from daemon");
}
if (tx_hash != hash) {
THROW_WALLET_EXCEPTION(error::wallet_internal_error, "Got txid " + epee::string_tools::pod_to_hex(tx_hash) + " which we did not ask for");
}
process_new_transaction(tx_hash, tx, o_indices, height, block_version, ts, miner_tx, pool, double_spend_seen, {});
}
//---------------------------------------------------------------------------------------------------- //----------------------------------------------------------------------------------------------------
void wallet2::process_pool_state(const std::vector<std::tuple<cryptonote::transaction, crypto::hash, bool>> &txs) void wallet2::process_pool_state(const std::vector<std::tuple<cryptonote::transaction, crypto::hash, bool>> &txs)
{ {

View file

@ -1384,6 +1384,7 @@ private:
bool import_key_images(std::vector<crypto::key_image> key_images, size_t offset=0, boost::optional<std::unordered_set<size_t>> selected_transfers=boost::none); bool import_key_images(std::vector<crypto::key_image> key_images, size_t offset=0, boost::optional<std::unordered_set<size_t>> selected_transfers=boost::none);
bool import_key_images(signed_tx_set & signed_tx, size_t offset=0, bool only_selected_transfers=false); bool import_key_images(signed_tx_set & signed_tx, size_t offset=0, bool only_selected_transfers=false);
crypto::public_key get_tx_pub_key_from_received_outs(const tools::wallet2::transfer_details &td) const; crypto::public_key get_tx_pub_key_from_received_outs(const tools::wallet2::transfer_details &td) const;
void import_tx(const std::string &txid, std::vector<uint64_t> &o_indices, uint64_t height, uint8_t block_version, uint64_t ts, bool miner_tx, bool pool, bool double_spend_seen);
void update_pool_state(std::vector<std::tuple<cryptonote::transaction, crypto::hash, bool>> &process_txs, bool refreshed = false); void update_pool_state(std::vector<std::tuple<cryptonote::transaction, crypto::hash, bool>> &process_txs, bool refreshed = false);
void process_pool_state(const std::vector<std::tuple<cryptonote::transaction, crypto::hash, bool>> &txs); void process_pool_state(const std::vector<std::tuple<cryptonote::transaction, crypto::hash, bool>> &txs);