Skip to content

Dashboard/Backend/transactions: added mempool API/WS to fetch transactions from bitcoin node#72

Open
sethdivyansh wants to merge 19 commits into
dmnd-pool:masterfrom
sethdivyansh:backend/transaction
Open

Dashboard/Backend/transactions: added mempool API/WS to fetch transactions from bitcoin node#72
sethdivyansh wants to merge 19 commits into
dmnd-pool:masterfrom
sethdivyansh:backend/transaction

Conversation

@sethdivyansh
Copy link
Copy Markdown

@sethdivyansh sethdivyansh commented Jun 8, 2025

Overview

This PR introduces a Rust-based backend service for streaming real-time Bitcoin blockchain data. Built with Axum, the service connects to a Bitcoin Core node via RPC and ZeroMQ to deliver blockchain events through WebSocket and REST API endpoints.

Add these lines to your config.toml:

# Bitcoin Core Configuration (all fields optional)
zmq_pub_sequence = "tcp://127.0.0.1:28334"  # Defaults to tcp://127.0.0.1:28334 if not set
rpc_allow_ip = "127.0.0.1"                  # Defaults to 127.0.0.1
rpc_port = 8332                             # Defaults to 8332
bitcoin_datadir = "path/to/your/bitcoin"    # Defaults to OS-specific Bitcoin data directory

Prerequisite::

To use ZMQ with Rust, the native ZeroMQ library (libzmq) must be installed on the system. The zmq crate depends on it during compilation.

Installation

  • Linux (Ubuntu/Debian):
    sudo apt install libzmq3-dev
  • macOS (with Homebrew):
    brew install zeromq
  • Windows (using vcpkg):**
    vcpkg install zeromq
    Or download prebuilt binaries from https://zeromq.org/download/

API Endpoints

REST Endpoints

GET /api/mempool - Current mempool transactions with full details

WebSocket Endpoints

/ws/bitcoin/stream Real-time Bitcoin events (mempool + blocks)
/ws/jd/stream Real-time NewTemplate event notifications

Event Types

About zmq
The WebSocket stream provides four types of events:
A: New transactions added to mempool with full transaction details
R: Transactions removed from mempool (includes txid and sequence number)
C: New blocks mined with block hash and complete transaction list
D: Block reorganizations with affected transactions

Architecture

Bitcoin Core Node
       ↓
    ZMQ Sequence
       ↓
   Rust Backend ←→ RPC Calls
       ↓
   WebSocket/REST
       ↓
   Frontend Client
  1. ZMQ Listener: Receives sequence events from Bitcoin Core
  2. Event Processor: Enriches events with RPC data (transaction details, block info)
  3. Broadcaster: Distributes events to connected WebSocket clients
  4. REST API: Provides current state endpoints

Error Handling

  • Automatic Reconnection: ZMQ connection automatically reconnects on failure
  • Backlog Management: Failed broadcasts are queued and retried

@sethdivyansh sethdivyansh changed the title Dashboard/Backend/transactions: added mempool API/WS Dashboard/Backend/transactions: added mempool API/WS to fetch transactions from bitcoin node Jun 8, 2025
@sethdivyansh sethdivyansh marked this pull request as ready for review June 12, 2025 15:41
@sethdivyansh sethdivyansh force-pushed the backend/transaction branch from 97ce92d to b785a7e Compare June 13, 2025 17:34
@sethdivyansh
Copy link
Copy Markdown
Author

@Priceless-P Please review this when you get a chance.

@Priceless-P
Copy link
Copy Markdown
Collaborator

I noticed that it is missing

  • POST /api/job-declaration - Submit selected transactions for inclusion in the next block
  • GET /api/job-declarations - Get history of submitted job declarations

The rest of the endpoint seems okay. Let me know when you have them available so I can test them together.

@sethdivyansh sethdivyansh force-pushed the backend/transaction branch 2 times, most recently from 01decc0 to 71e6e88 Compare June 21, 2025 13:38
Comment thread src/jd_client/job_declarator/mod.rs Outdated
template: NewTemplate<'static>,
token: Vec<u8>,
tx_list_: Seq064K<'static, B016M<'static>>,
tx_list_receiver: Arc<tokio::sync::Mutex<TReceiver<Seq064K<'static, B016M<'static>>>>>,
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Use roles_logic_sv2 Mutex not tokio Mutex

Comment thread src/jd_client/job_declarator/mod.rs Outdated
}
super::IS_CUSTOM_JOB_SET.store(false, std::sync::atomic::Ordering::Release);

let tx_list_ = {
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There should be a configurable duration (default of 30secs) to wait for a transactions to arrive. If no transaction arrives within that time, fall back to using the transaction from TemplateRx.

@sethdivyansh
Copy link
Copy Markdown
Author

sethdivyansh commented Jun 27, 2025

@Priceless-P I have made significant refactors in the transaction logic by switching from separate rawtx and rawblock ZMQ topics to the unified sequence topic. This change improves handling of edge cases such as:

  • Transaction updates via Replace-by-Fee (RBF)
  • Transaction removal due to abandonment or eviction
  • Blockchain reorganizations (reorgs)

It also reduced overall complexity.
About zmq: https://github.com/Sjors/bitcoin/blob/sv2/doc/zmq.md#message-format

@sethdivyansh sethdivyansh force-pushed the backend/transaction branch 4 times, most recently from 7e1b8ed to a7b2fd4 Compare July 2, 2025 22:37
Comment thread src/jd_client/job_declarator/mod.rs Outdated
);

if jd_event_broadcaster.send(template_notification).is_err() {
error!("Failed to send template notification: no receivers available");
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This will always fail because you are not using the receiver anywhere

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It will fail until a client is connected to the websocket.
Since this is a Tokio broadcast channel, receivers must explicitly subscribe to the sender in order to receive messages. That subscription happens inside the ws_event_handler() fn in jd_event_ws.rs.

Until at least one receiver is subscribed, any .send() call on the broadcaster will return an error which is expected behavior in this case.

}));

// Set up the connection with the upstream for job response notifications
if let Err(e) = Upstream::set_job_declarator(&up, &self_) {
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why do we need this?

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This connection setup is essential for enabling bidirectional communication between JobDeclarator and Upstream. Without it, Upstream can't notify JobDeclarator about job declaration responses, causing the API to wait indefinitely. By injecting a reference to JobDeclarator into Upstream, it enables a complete async response flow, ensuring the API receives timely feedback from the pool via Upstream.

@Priceless-P
Copy link
Copy Markdown
Collaborator

  • Rename dashboard_build to dashboard, move its contents into a build/ subfolder.
  • Move jd_event_ws.rs, assets.rs, and dashboard.rs from api/ into dashboard/.
  • Disable bitcoincore_rpc logs by default.
  • Add doc comments explaining each function’s purpose and behavior.

@sethdivyansh
Copy link
Copy Markdown
Author

  • Rename dashboard_build to dashboard, move its contents into a build/ subfolder.
  • Move jd_event_ws.rs, assets.rs, and dashboard.rs from api/ into dashboard/.
  • Disable bitcoincore_rpc logs by default.
  • Add doc comments explaining each function’s purpose and behavior.

Done with the changes.

@sethdivyansh sethdivyansh force-pushed the backend/transaction branch 2 times, most recently from 448d6ac to 739ec91 Compare July 7, 2025 20:19
@sethdivyansh sethdivyansh force-pushed the backend/transaction branch from 739ec91 to 894ac52 Compare July 23, 2025 13:10
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants