diff options
author | Lee Clagett <code@leeclagett.com> | 2020-03-16 23:59:26 +0000 |
---|---|---|
committer | Lee Clagett <code@leeclagett.com> | 2020-05-04 02:06:35 +0000 |
commit | e5214a2ca22cecf123bcff1ab441ed0415d08a6f (patch) | |
tree | 75a052bb95f6087421c8fedde549d6930c5af847 /src/cryptonote_core | |
parent | Merge pull request #6586 (diff) | |
download | monero-e5214a2ca22cecf123bcff1ab441ed0415d08a6f.tar.xz |
Adding ZMQ/Pub support for txpool_add and chain_main events
Diffstat (limited to 'src/cryptonote_core')
-rw-r--r-- | src/cryptonote_core/blockchain.cpp | 31 | ||||
-rw-r--r-- | src/cryptonote_core/blockchain.h | 9 | ||||
-rw-r--r-- | src/cryptonote_core/cryptonote_core.cpp | 38 | ||||
-rw-r--r-- | src/cryptonote_core/cryptonote_core.h | 15 |
4 files changed, 77 insertions, 16 deletions
diff --git a/src/cryptonote_core/blockchain.cpp b/src/cryptonote_core/blockchain.cpp index 7851b0f6a..b0726981c 100644 --- a/src/cryptonote_core/blockchain.cpp +++ b/src/cryptonote_core/blockchain.cpp @@ -1234,10 +1234,15 @@ bool Blockchain::switch_to_alternative_blockchain(std::list<block_extended_info> reorg_notify->notify("%s", std::to_string(split_height).c_str(), "%h", std::to_string(m_db->height()).c_str(), "%n", std::to_string(m_db->height() - split_height).c_str(), "%d", std::to_string(discarded_blocks).c_str(), NULL); - std::shared_ptr<tools::Notify> block_notify = m_block_notify; - if (block_notify) - for (const auto &bei: alt_chain) - block_notify->notify("%s", epee::string_tools::pod_to_hex(get_block_hash(bei.bl)).c_str(), NULL); + for (const auto& notifier : m_block_notifiers) + { + std::size_t notify_height = split_height; + for (const auto& bei: alt_chain) + { + notifier(notify_height, {std::addressof(bei.bl), 1}); + ++notify_height; + } + } MGINFO_GREEN("REORGANIZE SUCCESS! on height: " << split_height << ", new blockchain size: " << m_db->height()); return true; @@ -4236,12 +4241,9 @@ leave: get_difficulty_for_next_block(); // just to cache it invalidate_block_template_cache(); - if (notify) - { - std::shared_ptr<tools::Notify> block_notify = m_block_notify; - if (block_notify) - block_notify->notify("%s", epee::string_tools::pod_to_hex(id).c_str(), NULL); - } + + for (const auto& notifier: m_block_notifiers) + notifier(new_height - 1, {std::addressof(bl), 1}); return true; } @@ -5132,6 +5134,15 @@ void Blockchain::set_user_options(uint64_t maxthreads, bool sync_on_blocks, uint m_max_prepare_blocks_threads = maxthreads; } +void Blockchain::add_block_notify(boost::function<void(std::uint64_t, epee::span<const block>)>&& notify) +{ + if (notify) + { + CRITICAL_REGION_LOCAL(m_blockchain_lock); + m_block_notifiers.push_back(std::move(notify)); + } +} + void Blockchain::safesyncmode(const bool onoff) { /* all of this is no-op'd if the user set a specific diff --git a/src/cryptonote_core/blockchain.h b/src/cryptonote_core/blockchain.h index fb7e5c4f8..703dd6400 100644 --- a/src/cryptonote_core/blockchain.h +++ b/src/cryptonote_core/blockchain.h @@ -30,6 +30,7 @@ #pragma once #include <boost/asio/io_service.hpp> +#include <boost/function/function_fwd.hpp> #include <boost/serialization/serialization.hpp> #include <boost/serialization/version.hpp> #include <boost/serialization/list.hpp> @@ -764,7 +765,7 @@ namespace cryptonote * * @param notify the notify object to call at every new block */ - void set_block_notify(const std::shared_ptr<tools::Notify> ¬ify) { m_block_notify = notify; } + void add_block_notify(boost::function<void(std::uint64_t, epee::span<const block>)> &¬ify); /** * @brief sets a reorg notify object to call for every reorg @@ -1125,7 +1126,11 @@ namespace cryptonote bool m_batch_success; - std::shared_ptr<tools::Notify> m_block_notify; + /* `boost::function` is used because the implementation never allocates if + the callable object has a single `std::shared_ptr` or `std::weap_ptr` + internally. Whereas, the libstdc++ `std::function` will allocate. */ + + std::vector<boost::function<void(std::uint64_t, epee::span<const block>)>> m_block_notifiers; std::shared_ptr<tools::Notify> m_reorg_notify; // for prepare_handle_incoming_blocks diff --git a/src/cryptonote_core/cryptonote_core.cpp b/src/cryptonote_core/cryptonote_core.cpp index 141e54459..ce9c8878d 100644 --- a/src/cryptonote_core/cryptonote_core.cpp +++ b/src/cryptonote_core/cryptonote_core.cpp @@ -41,6 +41,7 @@ using namespace epee; #include "common/download.h" #include "common/threadpool.h" #include "common/command_line.h" +#include "cryptonote_basic/events.h" #include "warnings.h" #include "crypto/crypto.h" #include "cryptonote_config.h" @@ -51,6 +52,7 @@ using namespace epee; #include "ringct/rctTypes.h" #include "blockchain_db/blockchain_db.h" #include "ringct/rctSigs.h" +#include "rpc/zmq_pub.h" #include "common/notify.h" #include "hardforks/hardforks.h" #include "version.h" @@ -262,6 +264,13 @@ namespace cryptonote { m_blockchain_storage.set_enforce_dns_checkpoints(enforce_dns); } + //----------------------------------------------------------------------------------- + void core::set_txpool_listener(boost::function<void(std::vector<txpool_event>)> zmq_pub) + { + CRITICAL_REGION_LOCAL(m_incoming_tx_lock); + m_zmq_pub = std::move(zmq_pub); + } + //----------------------------------------------------------------------------------------------- bool core::update_checkpoints(const bool skip_dns /* = false */) { @@ -614,7 +623,20 @@ namespace cryptonote try { if (!command_line::is_arg_defaulted(vm, arg_block_notify)) - m_blockchain_storage.set_block_notify(std::shared_ptr<tools::Notify>(new tools::Notify(command_line::get_arg(vm, arg_block_notify).c_str()))); + { + struct hash_notify + { + tools::Notify cmdline; + + void operator()(std::uint64_t, epee::span<const block> blocks) const + { + for (const block bl : blocks) + cmdline.notify("%s", epee::string_tools::pod_to_hex(get_block_hash(bl)).c_str(), NULL); + } + }; + + m_blockchain_storage.add_block_notify(hash_notify{{command_line::get_arg(vm, arg_block_notify).c_str()}}); + } } catch (const std::exception &e) { @@ -957,8 +979,7 @@ namespace cryptonote return false; } - struct result { bool res; cryptonote::transaction tx; crypto::hash hash; }; - std::vector<result> results(tx_blobs.size()); + std::vector<txpool_event> results(tx_blobs.size()); CRITICAL_REGION_LOCAL(m_incoming_tx_lock); @@ -1023,6 +1044,7 @@ namespace cryptonote if (!tx_info.empty()) handle_incoming_tx_accumulated_batch(tx_info, tx_relay == relay_method::block); + bool valid_events = false; bool ok = true; it = tx_blobs.begin(); for (size_t i = 0; i < tx_blobs.size(); i++, ++it) { @@ -1045,10 +1067,18 @@ namespace cryptonote {MERROR_VER("Transaction verification impossible: " << results[i].hash);} if(tvc[i].m_added_to_pool) + { MDEBUG("tx added: " << results[i].hash); + valid_events = true; + } + else + results[i].res = false; } - return ok; + if (valid_events && m_zmq_pub && matches_category(tx_relay, relay_category::legacy)) + m_zmq_pub(std::move(results)); + + return ok; CATCH_ENTRY_L0("core::handle_incoming_txs()", false); } //----------------------------------------------------------------------------------------------- diff --git a/src/cryptonote_core/cryptonote_core.h b/src/cryptonote_core/cryptonote_core.h index 6a9ffda92..a53596c2c 100644 --- a/src/cryptonote_core/cryptonote_core.h +++ b/src/cryptonote_core/cryptonote_core.h @@ -32,9 +32,11 @@ #include <ctime> +#include <boost/function.hpp> #include <boost/program_options/options_description.hpp> #include <boost/program_options/variables_map.hpp> +#include "cryptonote_basic/fwd.h" #include "cryptonote_core/i_core_events.h" #include "cryptonote_protocol/cryptonote_protocol_handler_common.h" #include "cryptonote_protocol/enums.h" @@ -48,6 +50,7 @@ #include "warnings.h" #include "crypto/hash.h" #include "span.h" +#include "rpc/fwd.h" PUSH_WARNINGS DISABLE_VS_WARNINGS(4355) @@ -446,6 +449,13 @@ namespace cryptonote void set_enforce_dns_checkpoints(bool enforce_dns); /** + * @brief set a listener for txes being added to the txpool + * + * @param callable to notify, or empty function to disable. + */ + void set_txpool_listener(boost::function<void(std::vector<txpool_event>)> zmq_pub); + + /** * @brief set whether or not to enable or disable DNS checkpoints * * @param disble whether to disable DNS checkpoints @@ -1098,7 +1108,12 @@ namespace cryptonote bool m_fluffy_blocks_enabled; bool m_offline; + /* `boost::function` is used because the implementation never allocates if + the callable object has a single `std::shared_ptr` or `std::weap_ptr` + internally. Whereas, the libstdc++ `std::function` will allocate. */ + std::shared_ptr<tools::Notify> m_block_rate_notify; + boost::function<void(std::vector<txpool_event>)> m_zmq_pub; }; } |