e133e97f3b
Phase 1 - New RPC commands (no new deps): - getblockheader: header data from memory, zero disk reads - estimatefee: static fee estimation (Bitcoin Core compatible) - getblockchaininfo: chain state, difficulty, moneysupply - getwalletinfo: balance, stake, txcount, keypool, encryption - getnetworkinfo: version, protocol, connections, proxy - gettxoutsetinfo: height, bestblock, total_amount Phase 2 - REST API layer (-rest=1): - /rest/chaininfo.json, /rest/block/<hash>.json|hex - /rest/blockheader/<hash>.json, /rest/tx/<txid>.json|hex - /rest/blockhashbyheight/<n>, /rest/mempool.json - CORS headers for browser-based explorer access Phase 3 - ZMQ pub/sub notifications (optional, USE_ZMQ=1): - Topics: hashblock, hashtx, rawblock, rawtx - Conditional compilation via ENABLE_ZMQ Phase 4 - SSE real-time notifications (-ssenotify=1): - GET /events endpoint (authenticated, long-lived) - Block and transaction event streaming - 15-second keepalive for proxy compatibility Phase 5 - Address index (-addressindex=1): - getaddressbalance, getaddressutxos, getaddresstxids - LevelDB-backed index updated in ConnectBlock/DisconnectBlock - Requires -reindex on first use Also fixes QDesktopServices missing include for Qt5. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
131 lines
3.0 KiB
C++
131 lines
3.0 KiB
C++
// Copyright (c) 2015 The Bitcoin Core developers
|
|
// Copyright (c) 2026 The Triangles developers
|
|
// Distributed under the MIT software license, see the accompanying
|
|
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
|
|
|
#ifdef ENABLE_ZMQ
|
|
|
|
#include "zmqpublishnotifier.h"
|
|
#include "main.h"
|
|
#include "serialize.h"
|
|
#include "util.h"
|
|
|
|
#include <zmq.h>
|
|
#include <string.h>
|
|
|
|
CZMQPublishNotifier* pzmqNotifier = NULL;
|
|
|
|
CZMQPublishNotifier::CZMQPublishNotifier()
|
|
: pcontext(NULL), psocket(NULL), fInitialized(false)
|
|
{
|
|
}
|
|
|
|
CZMQPublishNotifier::~CZMQPublishNotifier()
|
|
{
|
|
Shutdown();
|
|
}
|
|
|
|
bool CZMQPublishNotifier::Initialize(const std::string& addr)
|
|
{
|
|
address = addr;
|
|
pcontext = zmq_ctx_new();
|
|
if (!pcontext)
|
|
{
|
|
printf("ZMQ: Failed to create context\n");
|
|
return false;
|
|
}
|
|
|
|
psocket = zmq_socket(pcontext, ZMQ_PUB);
|
|
if (!psocket)
|
|
{
|
|
printf("ZMQ: Failed to create socket\n");
|
|
zmq_ctx_destroy(pcontext);
|
|
pcontext = NULL;
|
|
return false;
|
|
}
|
|
|
|
int rc = zmq_bind(psocket, address.c_str());
|
|
if (rc != 0)
|
|
{
|
|
printf("ZMQ: Failed to bind to %s: %s\n", address.c_str(), zmq_strerror(errno));
|
|
zmq_close(psocket);
|
|
zmq_ctx_destroy(pcontext);
|
|
psocket = NULL;
|
|
pcontext = NULL;
|
|
return false;
|
|
}
|
|
|
|
printf("ZMQ: Publishing notifications on %s\n", address.c_str());
|
|
fInitialized = true;
|
|
return true;
|
|
}
|
|
|
|
void CZMQPublishNotifier::Shutdown()
|
|
{
|
|
if (psocket)
|
|
{
|
|
zmq_close(psocket);
|
|
psocket = NULL;
|
|
}
|
|
if (pcontext)
|
|
{
|
|
zmq_ctx_destroy(pcontext);
|
|
pcontext = NULL;
|
|
}
|
|
fInitialized = false;
|
|
}
|
|
|
|
bool CZMQPublishNotifier::NotifyBlockHash(const uint256& hash)
|
|
{
|
|
if (!fInitialized) return false;
|
|
|
|
const char* topic = "hashblock";
|
|
zmq_send(psocket, topic, strlen(topic), ZMQ_SNDMORE);
|
|
zmq_send(psocket, hash.begin(), 32, 0);
|
|
return true;
|
|
}
|
|
|
|
bool CZMQPublishNotifier::NotifyBlock(const CBlock& block)
|
|
{
|
|
if (!fInitialized) return false;
|
|
|
|
uint256 hash = block.GetHash();
|
|
NotifyBlockHash(hash);
|
|
|
|
// Also publish raw block
|
|
CDataStream ss(SER_NETWORK, PROTOCOL_VERSION);
|
|
ss << block;
|
|
const char* topic = "rawblock";
|
|
zmq_send(psocket, topic, strlen(topic), ZMQ_SNDMORE);
|
|
zmq_send(psocket, &(*ss.begin()), ss.size(), 0);
|
|
return true;
|
|
}
|
|
|
|
bool CZMQPublishNotifier::NotifyTransactionHash(const uint256& hash)
|
|
{
|
|
if (!fInitialized) return false;
|
|
|
|
const char* topic = "hashtx";
|
|
zmq_send(psocket, topic, strlen(topic), ZMQ_SNDMORE);
|
|
zmq_send(psocket, hash.begin(), 32, 0);
|
|
return true;
|
|
}
|
|
|
|
bool CZMQPublishNotifier::NotifyTransaction(const CTransaction& tx)
|
|
{
|
|
if (!fInitialized) return false;
|
|
|
|
uint256 hash = tx.GetHash();
|
|
NotifyTransactionHash(hash);
|
|
|
|
// Also publish raw tx
|
|
CDataStream ss(SER_NETWORK, PROTOCOL_VERSION);
|
|
ss << tx;
|
|
const char* topic = "rawtx";
|
|
zmq_send(psocket, topic, strlen(topic), ZMQ_SNDMORE);
|
|
zmq_send(psocket, &(*ss.begin()), ss.size(), 0);
|
|
return true;
|
|
}
|
|
|
|
#endif // ENABLE_ZMQ
|