diff options
Diffstat (limited to 'src/wallet')
-rw-r--r-- | src/wallet/api/wallet.cpp | 44 | ||||
-rw-r--r-- | src/wallet/api/wallet.h | 1 | ||||
-rw-r--r-- | src/wallet/api/wallet2_api.h | 7 | ||||
-rw-r--r-- | src/wallet/wallet2.cpp | 92 | ||||
-rw-r--r-- | src/wallet/wallet2.h | 2 |
5 files changed, 68 insertions, 78 deletions
diff --git a/src/wallet/api/wallet.cpp b/src/wallet/api/wallet.cpp index 7cd8656e1..1ee2e20b6 100644 --- a/src/wallet/api/wallet.cpp +++ b/src/wallet/api/wallet.cpp @@ -154,18 +154,20 @@ struct Wallet2CallbackImpl : public tools::i_wallet2_callback } } - virtual void on_money_received(uint64_t height, const crypto::hash &txid, const cryptonote::transaction& tx, uint64_t amount, const cryptonote::subaddress_index& subaddr_index, bool is_change, uint64_t unlock_time) + virtual void on_money_received(uint64_t height, const crypto::hash &txid, const cryptonote::transaction& tx, uint64_t amount, uint64_t burnt, const cryptonote::subaddress_index& subaddr_index, bool is_change, uint64_t unlock_time) { std::string tx_hash = epee::string_tools::pod_to_hex(txid); LOG_PRINT_L3(__FUNCTION__ << ": money received. height: " << height << ", tx: " << tx_hash - << ", amount: " << print_money(amount) + << ", amount: " << print_money(amount - burnt) + << ", burnt: " << print_money(burnt) + << ", raw_output_value: " << print_money(amount) << ", idx: " << subaddr_index); // do not signal on received tx if wallet is not syncronized completely if (m_listener && m_wallet->synchronized()) { - m_listener->moneyReceived(tx_hash, amount); + m_listener->moneyReceived(tx_hash, amount - burnt); m_listener->updated(); } } @@ -1280,6 +1282,42 @@ bool WalletImpl::importOutputs(const string &filename) return true; } +bool WalletImpl::scanTransactions(const std::vector<std::string> &txids) +{ + if (txids.empty()) + { + setStatusError(string(tr("Failed to scan transactions: no transaction ids provided."))); + return false; + } + + // Parse and dedup args + std::unordered_set<crypto::hash> txids_u; + for (const auto &s : txids) + { + crypto::hash txid; + if (!epee::string_tools::hex_to_pod(s, txid)) + { + setStatusError(string(tr("Invalid txid specified: ")) + s); + return false; + } + txids_u.insert(txid); + } + std::vector<crypto::hash> txids_v(txids_u.begin(), txids_u.end()); + + try + { + m_wallet->scan_tx(txids_v); + } + catch (const std::exception &e) + { + LOG_ERROR("Failed to scan transaction: " << e.what()); + setStatusError(string(tr("Failed to scan transaction: ")) + e.what()); + return false; + } + + return true; +} + void WalletImpl::addSubaddressAccount(const std::string& label) { m_wallet->add_subaddress_account(label); diff --git a/src/wallet/api/wallet.h b/src/wallet/api/wallet.h index 0e61ee330..018b2a0ed 100644 --- a/src/wallet/api/wallet.h +++ b/src/wallet/api/wallet.h @@ -169,6 +169,7 @@ public: bool importKeyImages(const std::string &filename) override; bool exportOutputs(const std::string &filename, bool all = false) override; bool importOutputs(const std::string &filename) override; + bool scanTransactions(const std::vector<std::string> &txids) override; virtual void disposeTransaction(PendingTransaction * t) override; virtual uint64_t estimateTransactionFee(const std::vector<std::pair<std::string, uint64_t>> &destinations, diff --git a/src/wallet/api/wallet2_api.h b/src/wallet/api/wallet2_api.h index c6f81f0e4..b67bce60c 100644 --- a/src/wallet/api/wallet2_api.h +++ b/src/wallet/api/wallet2_api.h @@ -927,6 +927,13 @@ struct Wallet */ virtual bool importOutputs(const std::string &filename) = 0; + /*! + * \brief scanTransactions - scan a list of transaction ids, this operation may reveal the txids to the remote node and affect your privacy + * \param txids - list of transaction ids + * \return - true on success + */ + virtual bool scanTransactions(const std::vector<std::string> &txids) = 0; + virtual TransactionHistory * history() = 0; virtual AddressBook * addressBook() = 0; virtual Subaddress * subaddress() = 0; diff --git a/src/wallet/wallet2.cpp b/src/wallet/wallet2.cpp index 0b2a6c0f5..5b4bbd5b7 100644 --- a/src/wallet/wallet2.cpp +++ b/src/wallet/wallet2.cpp @@ -2208,7 +2208,7 @@ void wallet2::process_new_transaction(const crypto::hash &txid, const cryptonote } LOG_PRINT_L0("Received money: " << print_money(td.amount()) << ", with tx: " << txid); 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, 0, td.m_subaddr_index, spends_one_of_ours(tx), td.m_tx.unlock_time); } total_received_1 += amount; notify = true; @@ -2242,7 +2242,8 @@ void wallet2::process_new_transaction(const crypto::hash &txid, const cryptonote tx_money_got_in_outs[tx_scan_info[o].received->index] -= m_transfers[kit->second].amount(); uint64_t amount = tx.vout[o].amount ? tx.vout[o].amount : tx_scan_info[o].amount; - uint64_t extra_amount = amount - m_transfers[kit->second].amount(); + uint64_t burnt = m_transfers[kit->second].amount(); + uint64_t extra_amount = amount - burnt; if (!pool) { transfer_details &td = m_transfers[kit->second]; @@ -2285,7 +2286,7 @@ void wallet2::process_new_transaction(const crypto::hash &txid, const cryptonote LOG_PRINT_L0("Received money: " << print_money(td.amount()) << ", with tx: " << txid); 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, burnt, td.m_subaddr_index, spends_one_of_ours(tx), td.m_tx.unlock_time); } total_received_1 += extra_amount; notify = true; @@ -3159,14 +3160,18 @@ void wallet2::update_pool_state(std::vector<std::tuple<cryptonote::transaction, } } - // get those txes - if (!txids.empty()) + // get_transaction_pool_hashes.bin may return more transactions than we're allowed to request in restricted mode + const size_t SLICE_SIZE = 100; // RESTRICTED_TRANSACTIONS_COUNT as defined in rpc/core_rpc_server.cpp + for (size_t offset = 0; offset < txids.size(); offset += SLICE_SIZE) { cryptonote::COMMAND_RPC_GET_TRANSACTIONS::request req; cryptonote::COMMAND_RPC_GET_TRANSACTIONS::response res; - for (const auto &p: txids) - req.txs_hashes.push_back(epee::string_tools::pod_to_hex(p.first)); - MDEBUG("asking for " << txids.size() << " transactions"); + + const size_t n_txids = std::min<size_t>(SLICE_SIZE, txids.size() - offset); + for (size_t n = offset; n < (offset + n_txids); ++n) { + req.txs_hashes.push_back(epee::string_tools::pod_to_hex(txids.at(n).first)); + } + MDEBUG("asking for " << req.txs_hashes.size() << " transactions"); req.decode_as_json = false; req.prune = true; @@ -3183,7 +3188,7 @@ void wallet2::update_pool_state(std::vector<std::tuple<cryptonote::transaction, MDEBUG("Got " << r << " and " << res.status); if (r && res.status == CORE_RPC_STATUS_OK) { - if (res.txs.size() == txids.size()) + if (res.txs.size() == req.txs_hashes.size()) { for (const auto &tx_entry: res.txs) { @@ -3219,7 +3224,7 @@ void wallet2::update_pool_state(std::vector<std::tuple<cryptonote::transaction, } else { - LOG_PRINT_L0("Expected " << txids.size() << " tx(es), got " << res.txs.size()); + LOG_PRINT_L0("Expected " << n_txids << " out of " << txids.size() << " tx(es), got " << res.txs.size()); } } else @@ -3622,32 +3627,7 @@ bool wallet2::refresh(bool trusted_daemon, uint64_t & blocks_fetched, bool& rece //---------------------------------------------------------------------------------------------------- bool wallet2::get_rct_distribution(uint64_t &start_height, std::vector<uint64_t> &distribution) { - uint32_t rpc_version; - boost::optional<std::string> result = m_node_rpc_proxy.get_rpc_version(rpc_version); - // no error - if (!!result) - { - // empty string -> not connection - THROW_WALLET_EXCEPTION_IF(result->empty(), tools::error::no_connection_to_daemon, "getversion"); - THROW_WALLET_EXCEPTION_IF(*result == CORE_RPC_STATUS_BUSY, tools::error::daemon_busy, "getversion"); - if (*result != CORE_RPC_STATUS_OK) - { - MDEBUG("Cannot determine daemon RPC version, not requesting rct distribution"); - return false; - } - } - else - { - if (rpc_version >= MAKE_CORE_RPC_VERSION(1, 19)) - { - MDEBUG("Daemon is recent enough, requesting rct distribution"); - } - else - { - MDEBUG("Daemon is too old, not requesting rct distribution"); - return false; - } - } + MDEBUG("Requesting rct distribution"); cryptonote::COMMAND_RPC_GET_OUTPUT_DISTRIBUTION::request req = AUTO_VAL_INIT(req); cryptonote::COMMAND_RPC_GET_OUTPUT_DISTRIBUTION::response res = AUTO_VAL_INIT(res); @@ -12090,7 +12070,8 @@ bool wallet2::check_reserve_proof(const cryptonote::account_public_address &addr crypto::key_derivation derivation; THROW_WALLET_EXCEPTION_IF(!crypto::generate_key_derivation(proof.shared_secret, rct::rct2sk(rct::I), derivation), error::wallet_internal_error, "Failed to generate key derivation"); crypto::public_key subaddr_spendkey; - crypto::derive_subaddress_public_key(output_public_key, derivation, proof.index_in_tx, subaddr_spendkey); + THROW_WALLET_EXCEPTION_IF(!crypto::derive_subaddress_public_key(output_public_key, derivation, proof.index_in_tx, subaddr_spendkey), + error::wallet_internal_error, "Failed to derive subaddress public key"); THROW_WALLET_EXCEPTION_IF(subaddr_spendkeys.count(subaddr_spendkey) == 0, error::wallet_internal_error, "The address doesn't seem to have received the fund"); @@ -14022,43 +14003,6 @@ uint64_t wallet2::get_segregation_fork_height() const if (m_segregation_height > 0) return m_segregation_height; - if (m_use_dns && !m_offline) - { - // All four MoneroPulse domains have DNSSEC on and valid - static const std::vector<std::string> dns_urls = { - "segheights.moneropulse.org", - "segheights.moneropulse.net", - "segheights.moneropulse.co", - "segheights.moneropulse.se" - }; - - const uint64_t current_height = get_blockchain_current_height(); - uint64_t best_diff = std::numeric_limits<uint64_t>::max(), best_height = 0; - std::vector<std::string> records; - if (tools::dns_utils::load_txt_records_from_dns(records, dns_urls)) - { - for (const auto& record : records) - { - std::vector<std::string> fields; - boost::split(fields, record, boost::is_any_of(":")); - if (fields.size() != 2) - continue; - uint64_t height; - if (!string_tools::get_xtype_from_string(height, fields[1])) - continue; - - MINFO("Found segregation height via DNS: " << fields[0] << " fork height at " << height); - uint64_t diff = height > current_height ? height - current_height : current_height - height; - if (diff < best_diff) - { - best_diff = diff; - best_height = height; - } - } - if (best_height) - return best_height; - } - } return SEGREGATION_FORK_HEIGHT; } //---------------------------------------------------------------------------------------------------- diff --git a/src/wallet/wallet2.h b/src/wallet/wallet2.h index e051946ad..fbea1b46f 100644 --- a/src/wallet/wallet2.h +++ b/src/wallet/wallet2.h @@ -137,7 +137,7 @@ private: public: // Full wallet callbacks virtual void on_new_block(uint64_t height, const cryptonote::block& block) {} - virtual void on_money_received(uint64_t height, const crypto::hash &txid, const cryptonote::transaction& tx, uint64_t amount, const cryptonote::subaddress_index& subaddr_index, bool is_change, uint64_t unlock_time) {} + virtual void on_money_received(uint64_t height, const crypto::hash &txid, const cryptonote::transaction& tx, uint64_t amount, uint64_t burnt, const cryptonote::subaddress_index& subaddr_index, bool is_change, uint64_t unlock_time) {} virtual void on_unconfirmed_money_received(uint64_t height, const crypto::hash &txid, const cryptonote::transaction& tx, uint64_t amount, const cryptonote::subaddress_index& subaddr_index) {} virtual void on_money_spent(uint64_t height, const crypto::hash &txid, const cryptonote::transaction& in_tx, uint64_t amount, const cryptonote::transaction& spend_tx, const cryptonote::subaddress_index& subaddr_index) {} virtual void on_skip_transaction(uint64_t height, const crypto::hash &txid, const cryptonote::transaction& tx) {} |