zmq: Pass lambda to zmq's ZMQPublishRawBlockNotifier

The lambda captures a reference to the chainman unique_ptr to retrieve
block data. An assert is added on the chainman to ensure that the lambda
is not used while the chainman is uninitialized.

This is done in preparation for the following commits where blockstorage
functions are made BlockManager methods.
This commit is contained in:
TheCharlatan
2023-05-03 22:24:21 +02:00
parent 8ed4ff8e05
commit cfbb212493
6 changed files with 21 additions and 9 deletions

View File

@@ -1424,7 +1424,11 @@ bool AppInitMain(NodeContext& node, interfaces::BlockAndHeaderTipInfo* tip_info)
} }
#if ENABLE_ZMQ #if ENABLE_ZMQ
g_zmq_notification_interface = CZMQNotificationInterface::Create(); g_zmq_notification_interface = CZMQNotificationInterface::Create(
[&chainman = node.chainman](CBlock& block, const CBlockIndex& index) {
assert(chainman);
return node::ReadBlockFromDisk(block, &index, chainman->GetConsensus());
});
if (g_zmq_notification_interface) { if (g_zmq_notification_interface) {
RegisterValidationInterface(g_zmq_notification_interface.get()); RegisterValidationInterface(g_zmq_notification_interface.get());

View File

@@ -6,6 +6,7 @@
#define BITCOIN_ZMQ_ZMQABSTRACTNOTIFIER_H #define BITCOIN_ZMQ_ZMQABSTRACTNOTIFIER_H
#include <cstdint> #include <cstdint>
#include <functional>
#include <memory> #include <memory>
#include <string> #include <string>
@@ -13,7 +14,7 @@ class CBlockIndex;
class CTransaction; class CTransaction;
class CZMQAbstractNotifier; class CZMQAbstractNotifier;
using CZMQNotifierFactory = std::unique_ptr<CZMQAbstractNotifier> (*)(); using CZMQNotifierFactory = std::function<std::unique_ptr<CZMQAbstractNotifier>()>;
class CZMQAbstractNotifier class CZMQAbstractNotifier
{ {

View File

@@ -39,12 +39,14 @@ std::list<const CZMQAbstractNotifier*> CZMQNotificationInterface::GetActiveNotif
return result; return result;
} }
std::unique_ptr<CZMQNotificationInterface> CZMQNotificationInterface::Create() std::unique_ptr<CZMQNotificationInterface> CZMQNotificationInterface::Create(std::function<bool(CBlock&, const CBlockIndex&)> get_block_by_index)
{ {
std::map<std::string, CZMQNotifierFactory> factories; std::map<std::string, CZMQNotifierFactory> factories;
factories["pubhashblock"] = CZMQAbstractNotifier::Create<CZMQPublishHashBlockNotifier>; factories["pubhashblock"] = CZMQAbstractNotifier::Create<CZMQPublishHashBlockNotifier>;
factories["pubhashtx"] = CZMQAbstractNotifier::Create<CZMQPublishHashTransactionNotifier>; factories["pubhashtx"] = CZMQAbstractNotifier::Create<CZMQPublishHashTransactionNotifier>;
factories["pubrawblock"] = CZMQAbstractNotifier::Create<CZMQPublishRawBlockNotifier>; factories["pubrawblock"] = [&get_block_by_index]() -> std::unique_ptr<CZMQAbstractNotifier> {
return std::make_unique<CZMQPublishRawBlockNotifier>(get_block_by_index);
};
factories["pubrawtx"] = CZMQAbstractNotifier::Create<CZMQPublishRawTransactionNotifier>; factories["pubrawtx"] = CZMQAbstractNotifier::Create<CZMQPublishRawTransactionNotifier>;
factories["pubsequence"] = CZMQAbstractNotifier::Create<CZMQPublishSequenceNotifier>; factories["pubsequence"] = CZMQAbstractNotifier::Create<CZMQPublishSequenceNotifier>;

View File

@@ -9,6 +9,7 @@
#include <validationinterface.h> #include <validationinterface.h>
#include <cstdint> #include <cstdint>
#include <functional>
#include <list> #include <list>
#include <memory> #include <memory>
@@ -23,7 +24,7 @@ public:
std::list<const CZMQAbstractNotifier*> GetActiveNotifiers() const; std::list<const CZMQAbstractNotifier*> GetActiveNotifiers() const;
static std::unique_ptr<CZMQNotificationInterface> Create(); static std::unique_ptr<CZMQNotificationInterface> Create(std::function<bool(CBlock&, const CBlockIndex&)> get_block_by_index);
protected: protected:
bool Initialize(); bool Initialize();

View File

@@ -39,8 +39,6 @@ namespace Consensus {
struct Params; struct Params;
} }
using node::ReadBlockFromDisk;
static std::multimap<std::string, CZMQAbstractPublishNotifier*> mapPublishNotifiers; static std::multimap<std::string, CZMQAbstractPublishNotifier*> mapPublishNotifiers;
static const char *MSG_HASHBLOCK = "hashblock"; static const char *MSG_HASHBLOCK = "hashblock";
@@ -247,10 +245,9 @@ bool CZMQPublishRawBlockNotifier::NotifyBlock(const CBlockIndex *pindex)
{ {
LogPrint(BCLog::ZMQ, "Publish rawblock %s to %s\n", pindex->GetBlockHash().GetHex(), this->address); LogPrint(BCLog::ZMQ, "Publish rawblock %s to %s\n", pindex->GetBlockHash().GetHex(), this->address);
const Consensus::Params& consensusParams = Params().GetConsensus();
CDataStream ss(SER_NETWORK, PROTOCOL_VERSION | RPCSerializationFlags()); CDataStream ss(SER_NETWORK, PROTOCOL_VERSION | RPCSerializationFlags());
CBlock block; CBlock block;
if (!ReadBlockFromDisk(block, pindex, consensusParams)) { if (!m_get_block_by_index(block, *pindex)) {
zmqError("Can't read block from disk"); zmqError("Can't read block from disk");
return false; return false;
} }

View File

@@ -9,7 +9,9 @@
#include <cstddef> #include <cstddef>
#include <cstdint> #include <cstdint>
#include <functional>
class CBlock;
class CBlockIndex; class CBlockIndex;
class CTransaction; class CTransaction;
@@ -46,7 +48,12 @@ public:
class CZMQPublishRawBlockNotifier : public CZMQAbstractPublishNotifier class CZMQPublishRawBlockNotifier : public CZMQAbstractPublishNotifier
{ {
private:
const std::function<bool(CBlock&, const CBlockIndex&)> m_get_block_by_index;
public: public:
CZMQPublishRawBlockNotifier(std::function<bool(CBlock&, const CBlockIndex&)> get_block_by_index)
: m_get_block_by_index{std::move(get_block_by_index)} {}
bool NotifyBlock(const CBlockIndex *pindex) override; bool NotifyBlock(const CBlockIndex *pindex) override;
}; };