Got a minimal DATUM “pool” talking to datum_gateway (interop demo)
TL;DR: datum_gateway being open source is enough to build your own pool. EGPOOL is a minimal proof — not production.
Datum_gateway is open source and the protocol is right there in the code. My take: if you can read the protocol, you can build your own pool.
Before arguing, I wanted to try it. So I hacked together a tiny Python prototype called EGPOOL. It speaks the DATUM protocol and can handshake, push CONFIG, and round-trip shares with the gateway — no Ocean pool code involved.
What I proved (all from the public datum gateway code):
• Framing: 4-byte XOR’d header + payload
• Handshake:
- proto=1 HELLO: sealed to pool LT X25519, signed by client LT Ed25519
- proto=2 RESP: sealed to client SESSION X25519, signed by pool LT Ed25519
• Channel (cmd=5):
- Box(serverSessSK, clientSessPK) w/ 24-byte nonce from nk + client session pk
- Nonces increment per message (LE 6×u32)
• CONFIG 0x99: signed by pool SESSION key, applied by gateway
• Share submit 0x27 ↔ response 0x8F: round-trip works
My test setup
EGPOOL pool server <-> DATUM GATEWAY -> Bitcoin node
I connected a bitaxe miner to DATUM Gateway.
I saw gateway handshake with pool server and accepting shares from miner.
Datum Gateway logs from my run:
Handshake response received.
DATUM Server MOTD: Welcome to Python DATUM Prime (prototype)
client configuration cmd received from DATUM server
DATUM Pool Coinbase Tag: "EGPOOL"
DATUM Pool Prime ID: a1b2c3d4
DATUM Pool Min Diff: 65536
Starting Stratum v1 server
---
quick disclaimer — this is a test rig, not a real pool
This is just an interop demo to show the protocol surface is enough.
A production pool still needs all the boring-but-critical stuff: reliable networking & reconnects, user/worker auth, proper vardiff and duplicate detection, real accept/reject plumbing, accounting backed by a DB, coinbaser v2 with real splits, the 0x50 validation path (stxids → by-id → full set), signature discipline (LT vs session), rate limiting/DoS guards, key management/rotation, metrics/alerts, etc
Want to understand more about the protocol?
check my GitHub

GitHub
sv2/doc/Datum_Protocol_Spec.md at main · electricalgrade/sv2
Contribute to electricalgrade/sv2 development by creating an account on GitHub.
#Bitcoin #Mining #DATUM
🚨 Bitcoin blocks are silently accumulating embedded data — not all of it benign.
I built a model that scans OP_RETURNs for suspicious payloads like malware, phishing links, and binary blobs. It works — and that’s the scary part.
📌 Here's why it matters:
- Today, AV/EDR systems don’t scan `.bitcoin/blocks`
- Tomorrow, they will — and when they do, infected chains could get flagged
- Nodes on cloud infrastructure (AWS, GCP) may face bans or throttling
- Centralized miners can bypass mempool policy, embedding malicious data
🧠 This is about more than spam. It's about Bitcoin's long-term health and legitimacy.
We need:
- Sensible datacarrier/mempool policies
- Transparency in block contents
- Decentralized, policy-respecting mining
Bitcoin is permissionless. Let’s not let it become indefensible.
#Bitcoin #OP_RETURN #Malware #AVDetection #Mempool #Mining #ChainSecurity #Nostr
Noise Protocol: A Minimal and Modular Cryptographic Tool
Been working with the Noise protocol recently — here’s a quick breakdown of what it does and how it works under the hood.
Noise is a small framework for building secure handshakes. It’s not a full protocol like TLS, more like a toolkit to define your own. It handles the initial key exchange, identity/auth, and gives you encrypted transport keys after the handshake. That’s it. No certificates, no extensions, no middleboxes.
Each handshake in Noise is built using a "pattern" — I’ve been using XX and NX. These define how the keys are exchanged:
* XX: both sides are anonymous, and exchange keys during handshake.
* NX: responder has a static pubkey, initiator is ephemeral (closer to client-server flows like SV2).
Behind the scenes, these patterns are just sequences of Diffie-Hellman operations between the parties' keys (ephemeral and static), and the handshake hash is updated after each message. Once complete, both sides split the final hash into two symmetric cipherstates, and that’s what’s used to encrypt transport messages.
All operations are constant-time. I’m using the `noise-c` library, which supports `Noise_XX_25519_ChaChaPoly_BLAKE2s` (or SHA256 if you tweak the suite string). Noise defines the handshake state machine, but the crypto primitives are pluggable.
The nice part is that everything’s deterministic and testable. Given the same inputs, the handshake always produces the same shared keys. It’s all pure key material — no ASN.1, no PEMs, no handshake extensions to worry about.
In the next post, I’ll show a tiny C implementation that wraps a Noise handshake (XX or NX), and exchanges Stratum V2 `SetupConnection` messages post-handshake. Useful for testing your own SV2 client/server implementations.
#noiseprotocol #cryptography #infosec #keyexchange #stratumv2 #miningprotocol #cprogramming #protocolengineering #decentralization #bitcoin #nostrdev #datumgateway #DLT #securecommunication #networkprotocols
Continuing on my journey of adding Stratum V2 (SV2) support to Datum Gateway (focused on the mining protocol), the first step is getting the connection setup between the SV2 server and the miner (client) working.
It uses noise protocol.
This weekend, I got this connection setup working (see below).
I’ll be writing two posts on the current progress.
In the first post, I’ll explain how the Noise handshake works, the cryptographic primitives behind it, and why it's a great fit for securing communication. I'll also dive into key concepts like Diffie-Hellman and ephemeral keys.
In the second post, I’ll walk through a simple C implementation where we use the Noise handshake to exchange SV2 SetupConnection messages. This will show how Noise can be integrated into a real-world Stratum V2 mining pool setup.
This will be useful for anyone working with mining infrastructure or interested in the cryptographic side of things. Stay tuned for the full details!
Here is current progress!
[pool] listening on 0.0.0.0:3334 (pattern=NX, prologue="STRATUM/2")
[pool] static pubkey: 39c0a192403e698f375524d21594068c5ac693137898582d054b052cddb7da47
[pool] handshake complete
[pool] SetupConnection: protocol=2 min=2 max=2 vendor="c-noise-client"
[pool] sent SetupConnection.Success (version=2 flags=0x00000000)
[client] handshake complete
[client] SetupConnection.Success used_version=2 flags=0x00000000
#cryptography #mining #stratumv2 #NoiseProtocol #DatumGateway #SV2 #Nostr #miningprotocol #blockchain
working on adding support of sv2 to Datum (only mining protocol)
a small, self-contained C library for SV2 wire handling, with a minimal evented adapter integrated into DATUM. This brings upstream/downstream SV2 compatibility while preserving the SV1 path.
✅ Core library in C (wire framing, message helpers)
✅ Thin evented server: accept SV2 clients, handle Setup/Open/Submit
✅ Python SV1↔SV2 bridge for testing (no miner firmware changes) for my standalone testing.
and some initial results here
SV2 server (dummy)
[sv2-dummy] client ('127.0.0.1', 52379) connected
[sv2-dummy] <- ext=0x0000 msg=0x00 pay=17 bytes hex=0000001100000c646174756d2d62726964676500000000...
[sv2-dummy] -> SetupConnection.Success used_version=2 flags=0
[sv2-dummy] <- ext=0x0001 msg=0x20 pay=8 bytes hex=010020080000010000000000c842...
[sv2-dummy] (noop) ext=0x0001 msg=0x20
SV2-SV1 bridge for my testing
[bridge] SV1 client connected: ('0.0.0.0', 54730)
[sv1] <- ('', 54730) {"id": 1, "method": "mining.subscribe", "params": ["cpuminer/2.5.1", "b10cf00c1"]}
[sv1] -> ('', 54730) {"id":1,"result":[[["mining.notify","b10cf00c1"],["mining.set_difficulty","b10cf00c2"]],"b10cf00c",8],"error":null}
[sv1] -> ('1', 54730) {"id":null,"method":"mining.set_difficulty","params":[1024]}
[sv1] (seed) dummy job_id=e1ad9163 ntime=68a549f7
[sv1] -> ('1', 54730) {"id":null,"method":"mining.notify","params":["e1ad9163","0000000000000000000000000000000000000000000000000000000000000000","01000000010000000000000000000000000000000000000000000000000000000000000000ffffffff1042524447","ffffffff010000000000000000015100000000",[],"20000000","1d00ffff","68a549f7",true]}
and the miner (SV1)..
* Trying .0.0.167:13333...
* Connected to 0.0.167 (0.0.167) port 13333 (#0)
* Connection #0 to host 0.0.167 left intact
[2025-08-20 05:07:19] > {"id": 1, "method": "mining.subscribe", "params": ["cpuminer/2.5.1", "b10cf00c1"]}
[2025-08-20 05:07:19] < {"id":1,"result":[[["mining.notify","b10cf00c1"],["mining.set_difficulty","b10cf00c2"]],"b10cf00c",8],"error":null}
[2025-08-20 05:07:19] Stratum session id: b10cf00c1
[2025-08-20 05:07:19] > {"id": 2, "method": "mining.authorize", "params": ["", ""]}
[2025-08-20 05:07:19] < {"id":null,"method":"mining.set_difficulty","params":[1024]}
[2025-08-20 05:07:19] Stratum difficulty set to 1024
[2025-08-20 05:07:19] < {"id":null,"method":"mining.notify","params":["e1ad9163","0000000000000000000000000000000000000000000000000000000000000000","01000000010000000000000000000000000000000000000000000000000000000000000000ffffffff1042524447","ffffffff010000000000000000015100000000",[],"20000000","1d00ffff","68a549f7",true]}
[2025-08-20 05:07:19] < {"id":2,"result":true,"error":null}
[2025-08-20 05:07:19] DEBUG: job_id='e1ad9163' extranonce2=0000000000000000 ntime=68a549f7
#bitcoin #Datum