Add comprehensive RPC API upgrade: REST, ZMQ, SSE, address index

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>
This commit is contained in:
2026-03-12 00:50:34 -07:00
parent 0f34c7d26f
commit e133e97f3b
16 changed files with 1429 additions and 5 deletions
+54 -1
View File
@@ -11,6 +11,11 @@
#include "ui_interface.h"
#include "checkpoints.h"
#include "smessage.h"
#ifdef ENABLE_ZMQ
#include "zmqpublishnotifier.h"
#endif
#include "notificationqueue.h"
#include "addressindex.h"
#include <boost/filesystem.hpp>
#include <boost/filesystem/fstream.hpp>
// boost/filesystem/convenience.hpp removed in modern Boost; functionality is in filesystem.hpp
@@ -147,7 +152,22 @@ void Shutdown(void* parg)
}
SecureMsgShutdown();
#ifdef ENABLE_ZMQ
if (pzmqNotifier)
{
pzmqNotifier->Shutdown();
delete pzmqNotifier;
pzmqNotifier = NULL;
}
#endif
if (pNotificationQueue)
{
delete pNotificationQueue;
pNotificationQueue = NULL;
}
nTransactionsUpdated++;
// CTxDB().Close();
bitdb.Flush(false);
@@ -1006,6 +1026,39 @@ bool AppInit2()
ThreadDeferredStartup(NULL);
}
// ********************************************************* Step 11.5: ZMQ notifications
#ifdef ENABLE_ZMQ
{
std::string zmqAddr = GetArg("-zmqpubhashblock", "");
if (zmqAddr.empty())
zmqAddr = GetArg("-zmqpubhashtx", "");
if (zmqAddr.empty())
zmqAddr = GetArg("-zmqpub", "");
if (!zmqAddr.empty())
{
pzmqNotifier = new CZMQPublishNotifier();
if (!pzmqNotifier->Initialize(zmqAddr))
{
printf("ZMQ: Failed to initialize publisher on %s\n", zmqAddr.c_str());
delete pzmqNotifier;
pzmqNotifier = NULL;
}
}
}
#endif
// ********************************************************* Step 11.6: Address index
fAddressIndex = GetBoolArg("-addressindex", false);
if (fAddressIndex)
printf("Address index enabled\n");
// ********************************************************* Step 11.7: SSE notification queue
if (GetBoolArg("-ssenotify", false))
{
pNotificationQueue = new CNotificationQueue();
printf("SSE: Notification queue initialized (connect to /events on RPC port)\n");
}
// ********************************************************* Step 12: finished
uiInterface.InitMessage(_("Done loading"));