diff options
Diffstat (limited to 'src/rpc')
-rwxr-xr-x | src/rpc/core_rpc_server.cpp | 37 | ||||
-rw-r--r-- | src/rpc/core_rpc_server_commands_defs.h | 8 | ||||
-rw-r--r-- | src/rpc/message_data_structs.h | 1 |
3 files changed, 41 insertions, 5 deletions
diff --git a/src/rpc/core_rpc_server.cpp b/src/rpc/core_rpc_server.cpp index b3ce30d0c..e653b9520 100755 --- a/src/rpc/core_rpc_server.cpp +++ b/src/rpc/core_rpc_server.cpp @@ -478,15 +478,17 @@ namespace cryptonote // try the pool for any missing txes size_t found_in_pool = 0; std::unordered_set<crypto::hash> pool_tx_hashes; + std::unordered_map<crypto::hash, bool> double_spend_seen; if (!missed_txs.empty()) { - std::list<transaction> pool_txs; - bool r = m_core.get_pool_transactions(pool_txs); + std::vector<tx_info> pool_tx_info; + std::vector<spent_key_image_info> pool_key_image_info; + bool r = m_core.get_pool_transactions_and_spent_keys_info(pool_tx_info, pool_key_image_info); if(r) { // sort to match original request std::list<transaction> sorted_txs; - std::list<cryptonote::transaction>::const_iterator i; + std::vector<tx_info>::const_iterator i; for (const crypto::hash &h: vh) { if (std::find(missed_txs.begin(), missed_txs.end(), h) == missed_txs.end()) @@ -500,11 +502,26 @@ namespace cryptonote 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()) + else if ((i = std::find_if(pool_tx_info.begin(), pool_tx_info.end(), [h](const tx_info &txi) { return epee::string_tools::pod_to_hex(h) == txi.id_hash; })) != pool_tx_info.end()) { - sorted_txs.push_back(*i); + cryptonote::transaction tx; + if (!cryptonote::parse_and_validate_tx_from_blob(i->tx_blob, tx)) + { + res.status = "Failed to parse and validate tx from blob"; + return true; + } + sorted_txs.push_back(tx); missed_txs.remove(h); pool_tx_hashes.insert(h); + const std::string hash_string = epee::string_tools::pod_to_hex(h); + for (const auto &ti: pool_tx_info) + { + if (ti.id_hash == hash_string) + { + double_spend_seen.insert(std::make_pair(h, ti.double_spend_seen)); + break; + } + } ++found_in_pool; } } @@ -530,11 +547,21 @@ namespace cryptonote if (e.in_pool) { e.block_height = e.block_timestamp = std::numeric_limits<uint64_t>::max(); + if (double_spend_seen.find(tx_hash) != double_spend_seen.end()) + { + e.double_spend_seen = double_spend_seen[tx_hash]; + } + else + { + MERROR("Failed to determine double spend status for " << tx_hash); + e.double_spend_seen = false; + } } else { e.block_height = m_core.get_blockchain_storage().get_db().get_tx_block_height(tx_hash); e.block_timestamp = m_core.get_blockchain_storage().get_db().get_block_timestamp(e.block_height); + e.double_spend_seen = false; } // fill up old style responses too, in case an old wallet asks diff --git a/src/rpc/core_rpc_server_commands_defs.h b/src/rpc/core_rpc_server_commands_defs.h index ee2a79eb4..57799bb81 100644 --- a/src/rpc/core_rpc_server_commands_defs.h +++ b/src/rpc/core_rpc_server_commands_defs.h @@ -566,6 +566,7 @@ namespace cryptonote std::string as_hex; std::string as_json; bool in_pool; + bool double_spend_seen; uint64_t block_height; uint64_t block_timestamp; std::vector<uint64_t> output_indices; @@ -575,6 +576,7 @@ namespace cryptonote KV_SERIALIZE(as_hex) KV_SERIALIZE(as_json) KV_SERIALIZE(in_pool) + KV_SERIALIZE(double_spend_seen) KV_SERIALIZE(block_height) KV_SERIALIZE(block_timestamp) KV_SERIALIZE(output_indices) @@ -1357,6 +1359,8 @@ namespace cryptonote bool relayed; uint64_t last_relayed_time; bool do_not_relay; + bool double_spend_seen; + std::string tx_blob; BEGIN_KV_SERIALIZE_MAP() KV_SERIALIZE(id_hash) @@ -1372,6 +1376,8 @@ namespace cryptonote KV_SERIALIZE(relayed) KV_SERIALIZE(last_relayed_time) KV_SERIALIZE(do_not_relay) + KV_SERIALIZE(double_spend_seen) + KV_SERIALIZE(tx_blob) END_KV_SERIALIZE_MAP() }; @@ -1480,6 +1486,7 @@ namespace cryptonote uint32_t num_not_relayed; uint64_t histo_98pc; std::vector<txpool_histo> histo; + uint32_t num_double_spends; BEGIN_KV_SERIALIZE_MAP() KV_SERIALIZE(bytes_total) @@ -1494,6 +1501,7 @@ namespace cryptonote KV_SERIALIZE(num_not_relayed) KV_SERIALIZE(histo_98pc) KV_SERIALIZE_CONTAINER_POD_AS_BLOB(histo) + KV_SERIALIZE(num_double_spends) END_KV_SERIALIZE_MAP() }; diff --git a/src/rpc/message_data_structs.h b/src/rpc/message_data_structs.h index 00f1e0caa..581048eaf 100644 --- a/src/rpc/message_data_structs.h +++ b/src/rpc/message_data_structs.h @@ -95,6 +95,7 @@ namespace rpc uint64_t last_relayed_time; bool relayed; bool do_not_relay; + bool double_spend_seen; }; typedef std::unordered_map<crypto::key_image, std::vector<crypto::hash> > key_images_with_tx_hashes; |