diff options
-rw-r--r-- | contrib/epee/include/misc_log_ex.h | 1 | ||||
-rw-r--r-- | contrib/epee/include/misc_os_dependent.h | 12 | ||||
-rw-r--r-- | src/cryptonote_core/tx_pool.h | 2 | ||||
-rw-r--r-- | src/daemon/rpc_command_executor.cpp | 16 | ||||
-rw-r--r-- | src/rpc/core_rpc_server.cpp | 32 | ||||
-rw-r--r-- | src/rpc/core_rpc_server_commands_defs.h | 29 | ||||
-rw-r--r-- | src/simplewallet/simplewallet.cpp | 9 | ||||
-rw-r--r-- | tests/core_tests/chaingen.h | 6 |
8 files changed, 88 insertions, 19 deletions
diff --git a/contrib/epee/include/misc_log_ex.h b/contrib/epee/include/misc_log_ex.h index d1451ff12..7cb1e61aa 100644 --- a/contrib/epee/include/misc_log_ex.h +++ b/contrib/epee/include/misc_log_ex.h @@ -424,6 +424,7 @@ namespace log_space } std::cout << buf; + std::cout << std::flush; #endif reset_console_color(); return true; diff --git a/contrib/epee/include/misc_os_dependent.h b/contrib/epee/include/misc_os_dependent.h index 2abca0446..806d3e83e 100644 --- a/contrib/epee/include/misc_os_dependent.h +++ b/contrib/epee/include/misc_os_dependent.h @@ -53,11 +53,13 @@ namespace misc_utils #if defined(_MSC_VER) return ::GetTickCount64(); #elif defined(WIN32) -# if defined(WIN64) - return GetTickCount64(); -# else - return GetTickCount(); -# endif + static LARGE_INTEGER pcfreq = {0}; + LARGE_INTEGER ticks; + if (!pcfreq.QuadPart) + QueryPerformanceFrequency(&pcfreq); + QueryPerformanceCounter(&ticks); + ticks.QuadPart *= 1000; /* we want msec */ + return ticks.QuadPart / pcfreq.QuadPart; #elif defined(__MACH__) clock_serv_t cclock; mach_timespec_t mts; diff --git a/src/cryptonote_core/tx_pool.h b/src/cryptonote_core/tx_pool.h index 84e11eeff..c7aab7f08 100644 --- a/src/cryptonote_core/tx_pool.h +++ b/src/cryptonote_core/tx_pool.h @@ -310,6 +310,7 @@ namespace cryptonote #define CURRENT_MEMPOOL_ARCHIVE_VER 11 +#define CURRENT_MEMPOOL_TX_DETAILS_ARCHIVE_VER 11 /** * @brief serialize the transaction pool to/from disk @@ -530,6 +531,7 @@ namespace boost } } BOOST_CLASS_VERSION(cryptonote::tx_memory_pool, CURRENT_MEMPOOL_ARCHIVE_VER) +BOOST_CLASS_VERSION(cryptonote::tx_memory_pool::tx_details, CURRENT_MEMPOOL_TX_DETAILS_ARCHIVE_VER) diff --git a/src/daemon/rpc_command_executor.cpp b/src/daemon/rpc_command_executor.cpp index 933c93ed7..ced24330d 100644 --- a/src/daemon/rpc_command_executor.cpp +++ b/src/daemon/rpc_command_executor.cpp @@ -575,16 +575,26 @@ bool t_rpc_command_executor::print_transaction(crypto::hash transaction_hash) { } } - if (1 == res.txs_as_hex.size()) + if (1 == res.txs.size() || 1 == res.txs_as_hex.size()) { + if (1 == res.txs.size()) + { + // only available for new style answers + if (res.txs.front().in_pool) + tools::success_msg_writer() << "Found in pool"; + else + tools::success_msg_writer() << "Found in blockchain at height " << res.txs.front().block_height; + } + // first as hex - tools::success_msg_writer() << res.txs_as_hex.front(); + const std::string &as_hex = (1 == res.txs.size()) ? res.txs.front().as_hex : res.txs_as_hex.front(); + tools::success_msg_writer() << as_hex; // then as json crypto::hash tx_hash, tx_prefix_hash; cryptonote::transaction tx; cryptonote::blobdata blob; - if (!string_tools::parse_hexstr_to_binbuff(res.txs_as_hex.front(), blob)) + if (!string_tools::parse_hexstr_to_binbuff(as_hex, blob)) { tools::fail_msg_writer() << "Failed to parse tx"; } diff --git a/src/rpc/core_rpc_server.cpp b/src/rpc/core_rpc_server.cpp index 165a24c22..f3745e627 100644 --- a/src/rpc/core_rpc_server.cpp +++ b/src/rpc/core_rpc_server.cpp @@ -240,6 +240,7 @@ namespace cryptonote // try the pool for any missing txes size_t found_in_pool = 0; + std::unordered_set<crypto::hash> pool_tx_hashes; if (!missed_txs.empty()) { std::list<transaction> pool_txs; @@ -248,9 +249,11 @@ namespace cryptonote { for (std::list<transaction>::const_iterator i = pool_txs.begin(); i != pool_txs.end(); ++i) { - std::list<crypto::hash>::iterator mi = std::find(missed_txs.begin(), missed_txs.end(), get_transaction_hash(*i)); + crypto::hash tx_hash = get_transaction_hash(*i); + std::list<crypto::hash>::iterator mi = std::find(missed_txs.begin(), missed_txs.end(), tx_hash); if (mi != missed_txs.end()) { + pool_tx_hashes.insert(tx_hash); missed_txs.erase(mi); txs.push_back(*i); ++found_in_pool; @@ -260,12 +263,33 @@ namespace cryptonote LOG_PRINT_L2("Found " << found_in_pool << "/" << vh.size() << " transactions in the pool"); } + std::list<std::string>::const_iterator txhi = req.txs_hashes.begin(); + std::vector<crypto::hash>::const_iterator vhi = vh.begin(); BOOST_FOREACH(auto& tx, txs) { + res.txs.push_back(COMMAND_RPC_GET_TRANSACTIONS::entry()); + COMMAND_RPC_GET_TRANSACTIONS::entry &e = res.txs.back(); + + crypto::hash tx_hash = *vhi++; + e.tx_hash = *txhi++; blobdata blob = t_serializable_object_to_blob(tx); - res.txs_as_hex.push_back(string_tools::buff_to_hex_nodelimer(blob)); + e.as_hex = string_tools::buff_to_hex_nodelimer(blob); + if (req.decode_as_json) + e.as_json = obj_to_json_str(tx); + e.in_pool = pool_tx_hashes.find(tx_hash) != pool_tx_hashes.end(); + if (e.in_pool) + { + e.block_height = std::numeric_limits<uint64_t>::max(); + } + else + { + e.block_height = m_core.get_blockchain_storage().get_db().get_tx_block_height(tx_hash); + } + + // fill up old style responses too, in case an old wallet asks + res.txs_as_hex.push_back(e.as_hex); if (req.decode_as_json) - res.txs_as_json.push_back(obj_to_json_str(tx)); + res.txs_as_json.push_back(e.as_json); } BOOST_FOREACH(const auto& miss_tx, missed_txs) @@ -273,7 +297,7 @@ namespace cryptonote res.missed_tx.push_back(string_tools::pod_to_hex(miss_tx)); } - LOG_PRINT_L2(res.txs_as_hex.size() << " transactions found, " << res.missed_tx.size() << " not found"); + LOG_PRINT_L2(res.txs.size() << " transactions found, " << res.missed_tx.size() << " not found"); res.status = CORE_RPC_STATUS_OK; return true; } diff --git a/src/rpc/core_rpc_server_commands_defs.h b/src/rpc/core_rpc_server_commands_defs.h index 91f5e2c90..e712c27c2 100644 --- a/src/rpc/core_rpc_server_commands_defs.h +++ b/src/rpc/core_rpc_server_commands_defs.h @@ -103,18 +103,41 @@ namespace cryptonote END_KV_SERIALIZE_MAP() }; + struct entry + { + std::string tx_hash; + std::string as_hex; + std::string as_json; + bool in_pool; + uint64_t block_height; + + BEGIN_KV_SERIALIZE_MAP() + KV_SERIALIZE(tx_hash) + KV_SERIALIZE(as_hex) + KV_SERIALIZE(as_json) + KV_SERIALIZE(in_pool) + KV_SERIALIZE(block_height) + END_KV_SERIALIZE_MAP() + }; struct response { - std::list<std::string> txs_as_hex; //transactions blobs as hex + // older compatibility stuff + std::list<std::string> txs_as_hex; //transactions blobs as hex (old compat) + std::list<std::string> txs_as_json; //transactions decoded as json (old compat) + + // in both old and new std::list<std::string> missed_tx; //not found transactions - std::list<std::string> txs_as_json; //transactions decoded as json + + // new style + std::vector<entry> txs; std::string status; BEGIN_KV_SERIALIZE_MAP() KV_SERIALIZE(txs_as_hex) - KV_SERIALIZE(missed_tx) KV_SERIALIZE(txs_as_json) + KV_SERIALIZE(txs) + KV_SERIALIZE(missed_tx) KV_SERIALIZE(status) END_KV_SERIALIZE_MAP() }; diff --git a/src/simplewallet/simplewallet.cpp b/src/simplewallet/simplewallet.cpp index aa571755f..30c958381 100644 --- a/src/simplewallet/simplewallet.cpp +++ b/src/simplewallet/simplewallet.cpp @@ -2497,13 +2497,18 @@ bool simple_wallet::check_tx_key(const std::vector<std::string> &args_) COMMAND_RPC_GET_TRANSACTIONS::response res; req.txs_hashes.push_back(epee::string_tools::pod_to_hex(txid)); if (!net_utils::invoke_http_json_remote_command2(m_daemon_address + "/gettransactions", req, res, m_http_client) || - res.txs_as_hex.empty()) + (res.txs.empty() && res.txs_as_hex.empty())) { fail_msg_writer() << tr("failed to get transaction from daemon"); return true; } cryptonote::blobdata tx_data; - if (!string_tools::parse_hexstr_to_binbuff(res.txs_as_hex.front(), tx_data)) + bool ok; + if (!res.txs.empty()) + ok = string_tools::parse_hexstr_to_binbuff(res.txs.front().as_hex, tx_data); + else + ok = string_tools::parse_hexstr_to_binbuff(res.txs_as_hex.front(), tx_data); + if (!ok) { fail_msg_writer() << tr("failed to parse transaction from daemon"); return true; diff --git a/tests/core_tests/chaingen.h b/tests/core_tests/chaingen.h index 44170d116..652413b8a 100644 --- a/tests/core_tests/chaingen.h +++ b/tests/core_tests/chaingen.h @@ -470,13 +470,15 @@ inline bool replay_events_through_core(cryptonote::core& cr, const std::vector<t CATCH_ENTRY_L0("replay_events_through_core", false); } //-------------------------------------------------------------------------- -template<class t_test_class> +template<typename t_test_class> struct get_test_options { - const std::pair<uint8_t, uint64_t> hard_forks[1] = {std::make_pair((uint8_t)1, (uint64_t)0)}; + const std::pair<uint8_t, uint64_t> hard_forks[1]; const cryptonote::test_options test_options = { hard_forks }; + get_test_options():hard_forks{std::make_pair((uint8_t)1, (uint64_t)0)}{} }; + //-------------------------------------------------------------------------- template<class t_test_class> inline bool do_replay_events(std::vector<test_event_entry>& events) |