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
No known key found for this signature in database
GPG Key ID: 9B79B45691DB4173
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
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) {
RegisterValidationInterface(g_zmq_notification_interface.get());

View File

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

View File

@ -39,12 +39,14 @@ std::list<const CZMQAbstractNotifier*> CZMQNotificationInterface::GetActiveNotif
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;
factories["pubhashblock"] = CZMQAbstractNotifier::Create<CZMQPublishHashBlockNotifier>;
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["pubsequence"] = CZMQAbstractNotifier::Create<CZMQPublishSequenceNotifier>;

View File

@ -9,6 +9,7 @@
#include <validationinterface.h>
#include <cstdint>
#include <functional>
#include <list>
#include <memory>
@ -23,7 +24,7 @@ public:
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:
bool Initialize();

View File

@ -39,8 +39,6 @@ namespace Consensus {
struct Params;
}
using node::ReadBlockFromDisk;
static std::multimap<std::string, CZMQAbstractPublishNotifier*> mapPublishNotifiers;
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);
const Consensus::Params& consensusParams = Params().GetConsensus();
CDataStream ss(SER_NETWORK, PROTOCOL_VERSION | RPCSerializationFlags());
CBlock block;
if (!ReadBlockFromDisk(block, pindex, consensusParams)) {
if (!m_get_block_by_index(block, *pindex)) {
zmqError("Can't read block from disk");
return false;
}

View File

@ -9,7 +9,9 @@
#include <cstddef>
#include <cstdint>
#include <functional>
class CBlock;
class CBlockIndex;
class CTransaction;
@ -46,7 +48,12 @@ public:
class CZMQPublishRawBlockNotifier : public CZMQAbstractPublishNotifier
{
private:
const std::function<bool(CBlock&, const CBlockIndex&)> m_get_block_by_index;
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;
};