From 8fe5f609d18ab68434615a8c7c007a6b56124801 Mon Sep 17 00:00:00 2001 From: moneromooo-monero Date: Fri, 1 Sep 2017 21:22:45 +0100 Subject: [PATCH 1/2] rpc: order transactions in the order they were requested --- src/rpc/core_rpc_server.cpp | 26 +++++++++++++++++++------- 1 file changed, 19 insertions(+), 7 deletions(-) diff --git a/src/rpc/core_rpc_server.cpp b/src/rpc/core_rpc_server.cpp index a6a61705b..76058f8d4 100644 --- a/src/rpc/core_rpc_server.cpp +++ b/src/rpc/core_rpc_server.cpp @@ -478,18 +478,30 @@ namespace cryptonote bool r = m_core.get_pool_transactions(pool_txs); if(r) { - for (std::list::const_iterator i = pool_txs.begin(); i != pool_txs.end(); ++i) + // sort to match original request + std::list sorted_txs; + std::list::const_iterator i; + for (const crypto::hash &h: vh) { - crypto::hash tx_hash = get_transaction_hash(*i); - std::list::iterator mi = std::find(missed_txs.begin(), missed_txs.end(), tx_hash); - if (mi != missed_txs.end()) + if (std::find(missed_txs.begin(), missed_txs.end(), h) == missed_txs.end()) { - pool_tx_hashes.insert(tx_hash); - missed_txs.erase(mi); - txs.push_back(*i); + // core returns the ones it finds in the right order + if (get_transaction_hash(txs.front()) != h) + { + res.status = "Failed: tx hash mismatch"; + return true; + } + sorted_txs.push_back(std::move(txs.front())); + txs.pop_front(); + } + else if ((i = std::find_if(pool_txs.begin(), pool_txs.end(), [h](cryptonote::transaction &tx) { return h == cryptonote::get_transaction_hash(tx); })) != pool_txs.end()) + { + sorted_txs.push_back(*i); + missed_txs.remove(h); ++found_in_pool; } } + txs = sorted_txs; } LOG_PRINT_L2("Found " << found_in_pool << "/" << vh.size() << " transactions in the pool"); } From a15e8583029bcdbc45665b470252a1815e5fe5d1 Mon Sep 17 00:00:00 2001 From: moneromooo-monero Date: Fri, 1 Sep 2017 21:25:12 +0100 Subject: [PATCH 2/2] wallet2: guard against daemon sending txes in the wrong order --- src/wallet/wallet2.cpp | 22 ++++++++++------------ 1 file changed, 10 insertions(+), 12 deletions(-) diff --git a/src/wallet/wallet2.cpp b/src/wallet/wallet2.cpp index 323a3a7fe..cfd0330ef 100644 --- a/src/wallet/wallet2.cpp +++ b/src/wallet/wallet2.cpp @@ -1552,23 +1552,22 @@ void wallet2::update_pool_state(bool refreshed) { if (res.txs.size() == txids.size()) { - size_t n = 0; - for (const auto &txid: txids) + for (const auto &tx_entry: res.txs) { - // might have just been put in a block - if (res.txs[n].in_pool) + if (tx_entry.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[n].as_hex, bd)) + if (epee::string_tools::parse_hexstr_to_binbuff(tx_entry.as_hex, bd)) { if (cryptonote::parse_and_validate_tx_from_blob(bd, tx, tx_hash, tx_prefix_hash)) { - if (tx_hash == txid) + const std::vector::const_iterator i = std::find(txids.begin(), txids.end(), tx_hash); + if (i != txids.end()) { - process_new_transaction(txid, tx, std::vector(), 0, time(NULL), false, true); - m_scanned_pool_txs[0].insert(txid); + process_new_transaction(tx_hash, tx, std::vector(), 0, time(NULL), false, true); + m_scanned_pool_txs[0].insert(tx_hash); if (m_scanned_pool_txs[0].size() > 5000) { std::swap(m_scanned_pool_txs[0], m_scanned_pool_txs[1]); @@ -1577,7 +1576,7 @@ void wallet2::update_pool_state(bool refreshed) } else { - LOG_PRINT_L0("Mismatched txids when processing unconfimed txes from pool"); + MERROR("Got txid " << tx_hash << " which we did not ask for"); } } else @@ -1587,14 +1586,13 @@ void wallet2::update_pool_state(bool refreshed) } else { - LOG_PRINT_L0("Failed to parse tx " << txid); + LOG_PRINT_L0("Failed to parse transaction from daemon"); } } else { - LOG_PRINT_L1("Tx " << txid << " was in pool, but is no more"); + LOG_PRINT_L1("Transaction from daemon was in pool, but is no more"); } - ++n; } } else