---
title: Async Channel Map — Data Flow Between Components
---
flowchart LR
subgraph NODE["braidpool/braidpool — Node Process"]
CONSUMER["ipc_template_consumer"]
BRAID["Braid Engine<br/>+ P2P"]
end
subgraph SV2["braidpool/sv2-apps — Pool Process"]
direction TB
TP["sv2_template_consumer<br/>(braidpool-template-provider)"]
POOL["Pool Channel Manager"]
end
MINERS["SV1 / SV2 Miners"]
CONSUMER -- "① tokio::sync::mpsc<br/>Sender<BraidpoolTemplate><br/>(one-way, node → sv2-apps)" --> TP
TP -- "② async_channel<br/>Sender<TemplateDistributionOwned><br/>• NewTemplate<br/>• SetNewPrevHash<br/>• RequestTransactionDataError" --> POOL
POOL -- "③ async_channel<br/>Receiver<TemplateDistributionOwned><br/>• CoinbaseOutputConstraints (startup)<br/>• SubmitSolution<br/>• RequestTransactionData" --> TP
POOL -- "④ tokio::sync::mpsc<br/>Sender<ValidatedShare><br/>share-bead bridge" --> BRAID
POOL <-- "⑤ Noise-encrypted TCP<br/>SV2 binary frames<br/>Extended Mining Channel" --> MINERS
-
-
Save nkatha23/d24dd086221d7067908297d97006c11f to your computer and use it in GitHub Desktop.
SV2 integration workflow
---
title: Braidpool Coinbase Transaction Structure
---
flowchart TB
subgraph INPUT["Coinbase Input v2 locktime 0"]
SIG["scriptSig<br/>BIP-34 block height<br/>EXTRANONCE_SEP 16 x 0x01<br/>pool_identifier"]
WIT["witness 32 zero bytes"]
end
PAY["Payout Outputs<br/>subsidy + fees<br/>EDCA under research"]
SEG["SegWit Commitment BIP-141<br/>OP_RETURN aa21a9ed<br/>witness_root via IPC"]
OPR["Braidpool Commitment<br/>OP_RETURN + hash<br/>+ extranonce max 80B"]
subgraph META["BraidpoolMetadata"]
M1["parent BeadHashes"]
M2["payout_address P2TR"]
M3["comm_pubkey secp256k1"]
M4["miner_ip"]
M5["timestamp ms epoch"]
M6["committed transactions"]
end
INPUT --> PAY --> SEG --> OPR -->|"hash"| META
---
title: Braidpool SV2 — Detailed Architecture
---
flowchart TB
subgraph NODE["braidpool/braidpool — Node"]
direction TB
BTC_IPC["Bitcoin Core IPC<br/>Cap'n Proto socket"]
IPC_CONSUMER["ipc_template_consumer<br/>builds BraidpoolTemplate<br/>from processed_block_hex<br/>embeds OP_RETURN commitment"]
BRAID_ENGINE["Braid Consensus Engine<br/>braid::extend"]
PROPAGATE["propagate_valid_bead<br/>node/src/lib.rs"]
P2P_LOOP["P2P Event Loop<br/>libp2p floodsub"]
SQLITE[("SQLite<br/>braidpool.db")]
BTC_IPC --> IPC_CONSUMER
PROPAGATE --> BRAID_ENGINE
BRAID_ENGINE --> P2P_LOOP
BRAID_ENGINE --> SQLITE
end
subgraph SV2_APPS["braidpool/sv2-apps — Pool + Translator"]
direction TB
subgraph TEMPLATE_PROVIDER["pool-apps/braidpool-template-provider"]
TP_CONSUMER["sv2_template_consumer<br/>receives BraidpoolTemplate<br/>waits for CoinbaseOutputConstraints first"]
BUILD_TEMPLATE["build_new_template<br/>braidpool_mode = true<br/>all outputs included<br/>coinbase_prefix from scriptSig"]
BUILD_PREVHASH["build_set_new_prev_hash<br/>header_timestamp from template<br/>→ min_ntime downstream"]
TP_CONSUMER --> BUILD_TEMPLATE
TP_CONSUMER --> BUILD_PREVHASH
end
subgraph POOL_CHANNEL_MGR["pool-apps/pool — Downstream Channel Manager"]
SETUP["SetupConnection<br/>Noise NX-handshake"]
OPEN_EXT["OpenExtendedMiningChannel<br/>extranonce_size = 12 normal<br/>extranonce_size = 5 audit"]
SEND_JOB["NewExtendedMiningJob<br/>coinbase_tx_prefix<br/>coinbase_tx_suffix<br/>merkle_path"]
SET_PREVHASH["SetNewPrevHash<br/>activates Future Job<br/>header_timestamp = min_ntime"]
SHARE_HANDLER["SubmitSharesExtended<br/>PoW via U256 target<br/>no f64 precision loss"]
SHARE_BRIDGE["ShareBridgeSender<br/>ValidatedShare<br/>extranonce1: Vec<u8>"]
COB_CONSTRAINTS["CoinbaseOutputConstraints<br/>sent on startup to template-provider"]
end
subgraph TPROXY["miner-apps/translator-proxy"]
SV2_UP["SV2 Upstream Client<br/>Extended Channel<br/>Noise handshake"]
JOB_XLAT["job_translator<br/>NewExtendedMiningJob<br/>per-miner merkle root"]
SV1_DOWN["SV1 Server Socket<br/>mining.subscribe<br/>mining.authorize<br/>mining.submit"]
end
COB_CONSTRAINTS -->|"async_channel<br/>TemplateDistributionOwned"| TP_CONSUMER
BUILD_TEMPLATE -->|"NewExtendedMiningJob"| SEND_JOB
BUILD_PREVHASH -->|"SetNewPrevHash"| SET_PREVHASH
SET_PREVHASH --> SV2_UP
SEND_JOB --> SV2_UP
SV2_UP --> JOB_XLAT
JOB_XLAT -->|"mining.notify"| SV1_DOWN
SV1_DOWN -->|"mining.submit"| SV2_UP
SV2_UP -->|"SubmitSharesExtended"| SHARE_HANDLER
SHARE_HANDLER --> SHARE_BRIDGE
end
SV1_MINERS["SV1 Miners<br/>Stratum V1 TCP"]
SV2_MINERS["SV2 Miners<br/>Stratum V2 Encrypted"]
PEERS["Braidpool P2P<br/>Network Peers"]
IPC_CONSUMER -->|"tokio::sync::mpsc<br/>BraidpoolTemplate<br/>height from ipc_template.components"| TP_CONSUMER
SHARE_BRIDGE -->|"ValidatedShare"| PROPAGATE
P2P_LOOP <-->|"floodsub beads"| PEERS
SV1_MINERS --> SV1_DOWN
SV2_MINERS --> SETUP
SETUP --> OPEN_EXT
---
title: Extranonce Space — How 10,000 Miners Search Without Colliding
---
flowchart TB
subgraph NORMAL["Normal Mode — OpenExtendedMiningChannel(extranonce_size = 12)"]
direction LR
NP["Pool prefix<br/>4 bytes<br/>assigned by pool<br/>same for all miners<br/>on this channel"]
NT["Miner slot<br/>2 bytes<br/>assigned by tproxy<br/>unique per miner<br/>up to 65,536 miners"]
NM["Miner rolls<br/>10 bytes<br/>4,294,967,296 × 65,536<br/>≈ 281 trillion combinations<br/>per nonce roll"]
NP --> NT --> NM
NL["Total: 4 + 2 + 10 = 16 bytes"]
end
subgraph AUDIT["Audit Mode — OpenExtendedMiningChannel(extranonce_size = 5)"]
direction LR
AP["Pool prefix<br/>4 bytes<br/>assigned by pool"]
AT["Miner slot<br/>2 bytes<br/>assigned by tproxy"]
AM["Miner rolls<br/>3 bytes<br/>16,777,216 combinations<br/>smaller space — all shares<br/>are auditable"]
AP --> AT --> AM
AL["Total: 4 + 2 + 3 = 9 bytes"]
end
subgraph HOW["How tproxy assigns miner slots"]
direction TB
S1["Miner connects → tproxy increments counter"]
S2["Counter value becomes the 2-byte miner slot"]
S3["extranonce sent in SubmitSharesExtended<br/>= miner_slot (2B) + miner_rolled (10B or 3B)"]
S4["Pool reconstructs full coinbase:<br/>pool_prefix (4B) + extranonce (12B or 5B)<br/>to verify PoW"]
S1 --> S2 --> S3 --> S4
end
subgraph WIRE["Where each piece appears in SV2 messages"]
direction TB
W1["SetupConnection → OpenExtendedMiningChannel<br/>tproxy requests extranonce_size from pool"]
W2["OpenExtendedMiningChannelSuccess<br/>pool responds with extranonce_prefix (4B)"]
W3["SubmitSharesExtended<br/>miner sends back the extranonce it used"]
W4["ValidatedShare → propagate_valid_bead<br/>extranonce1: Vec<u8> stored in bead<br/>enables UHPO payout attribution"]
W1 --> W2 --> W3 --> W4
end
---
title: Braidpool SV2 — General Flow
---
flowchart LR
BTC["Bitcoin Core<br/>mempool · block index"]
subgraph NODE["braidpool/braidpool — Node"]
IPC["ipc_template_consumer<br/>Cap'n Proto IPC<br/>builds coinbase + OP_RETURN"]
BRAID["Braid Engine<br/>braid::extend + P2P"]
end
subgraph SV2["braidpool/sv2-apps"]
ADAPTER["braidpool-template-provider<br/>SV2 adapter"]
POOL["Pool<br/>channel manager"]
TPROXY["Translator Proxy<br/>SV1 ↔ SV2"]
end
SV1["SV1 Miners<br/>Stratum V1"]
SV2M["SV2 Miners<br/>Stratum V2"]
PEERS["Braidpool<br/>P2P Network"]
BTC -->|"Cap'n Proto IPC\nnew block template"| IPC
IPC -->|"mpsc BraidpoolTemplate\n(braidpool-common)"| ADAPTER
ADAPTER -->|"NewTemplate\nSetNewPrevHash"| POOL
POOL -->|"NewExtendedMiningJob\nSetNewPrevHash"| TPROXY
TPROXY -->|"mining.notify"| SV1
POOL <-->|"Noise-encrypted SV2"| SV2M
SV1 -->|"mining.submit"| TPROXY
TPROXY -->|"SubmitSharesExtended"| POOL
POOL -->|"ValidatedShare"| BRAID
BRAID -->|"submitblock"| BTC
BRAID <-->|"floodsub beads"| PEERS
---
title: Overall Braidpool Mining Lifecycle
---
sequenceDiagram
participant BITCOIN as Bitcoin Core
participant IPC as Cap'n Proto IPC Client<br/>(braidpool/braidpool)
participant CONSUMER as ipc_template_consumer<br/>(braidpool/braidpool)
participant PROVIDER as braidpool-template-provider<br/>(sv2-apps)
participant POOL as Pool Channel Manager<br/>(sv2-apps)
participant TPROXY as Translator Proxy<br/>(sv2-apps)
participant MINER as SV1 Miner
participant BRAID as Braid Node Core<br/>(braidpool/braidpool)
participant PEERS as Other Braidpool Nodes
Note over BITCOIN,PEERS: ── Startup ──
POOL->>PROVIDER: CoinbaseOutputConstraints<br/>pool sends on startup
MINER->>TPROXY: mining.subscribe
MINER->>TPROXY: mining.authorize
TPROXY->>POOL: SetupConnection<br/>Noise NX handshake
POOL-->>TPROXY: SetupConnection.Success
TPROXY->>POOL: OpenExtendedMiningChannel
POOL-->>TPROXY: OpenExtendedMiningChannelSuccess
Note over BITCOIN,PEERS: ── Template Update ──
BITCOIN->>IPC: publish new block template
IPC->>CONSUMER: forward Cap'n Proto event
CONSUMER->>CONSUMER: rebuild coinbase<br/>insert OP_RETURN commitment<br/>finalize BraidpoolTemplate
CONSUMER->>PROVIDER: BraidpoolTemplate via mpsc
PROVIDER->>POOL: NewExtendedMiningJob (future job)
POOL->>TPROXY: NewExtendedMiningJob
TPROXY->>MINER: mining.notify (prepare work)
PROVIDER->>POOL: SetNewPrevHash (activates job)
POOL->>TPROXY: SetNewPrevHash
TPROXY->>MINER: mining.notify (clean_jobs=true)
Note over BITCOIN,PEERS: ── Mining Loop ──
loop Each share submitted
MINER->>TPROXY: mining.submit<br/>(job_id, extranonce2, ntime, nonce)
TPROXY->>POOL: SubmitSharesExtended
POOL->>POOL: validate PoW<br/>U256 target
POOL->>BRAID: ValidatedShare → propagate_valid_bead
BRAID->>BRAID: braid::extend<br/>add bead to DAG
POOL->>TPROXY: SubmitSharesSuccess
TPROXY->>MINER: submit result OK
BRAID->>PEERS: floodsub announce new bead
end
Note over BITCOIN,PEERS: ── Block Found ──
alt block found
BRAID->>IPC: submitblock via Cap'n Proto
IPC->>BITCOIN: submit to network
BITCOIN-->>IPC: block accepted
BRAID->>PEERS: notify new block
end
---
title: P2P Communication Flow
---
sequenceDiagram
participant NODE as Braidpool Node<br/>(braidpool/braidpool)
participant NETWORK as Braidpool P2P Network<br/>libp2p floodsub + Kademlia
participant PEER as Remote Braidpool Node
NODE->>NETWORK: 1. Startup<br/>Kademlia find_node bootstrap
NETWORK-->>NODE: 2. Bootstrap response<br/>nearest peers
NODE->>PEER: 3. BeadRequest GetTips
PEER-->>NODE: 4. BeadResponse Tips<br/>(DAG tips from peer)
NODE->>PEER: 5. BeadRequest GetBeadsAfter(tips)
PEER-->>NODE: 6. BeadResponse Beads<br/>(sync missing beads)
NODE->>NODE: 7. Validate each bead<br/>braid::extend
NODE->>NODE: 8. Persist to SQLite<br/>braidpool.db
Note over NODE: Valid share arrives<br/>from SV2 Share Bridge<br/>(ValidatedShare → bead)
NODE->>NODE: 9. propagate_valid_bead<br/>create bead from ValidatedShare<br/>braid::extend
NODE->>NETWORK: 10. Floodsub announce<br/>new local bead
NETWORK->>PEER: 11. Propagate to all peers
---
title: Repository Boundary — braidpool-common as Shared Type Boundary
---
flowchart TB
subgraph REPO1["github.com/braidpool/braidpool"]
direction TB
subgraph NODE_CRATE["node/ — main binary"]
IPC_C["ipc_template_consumer<br/>node/src/ipc_template_consumer.rs<br/>• reads Cap'n Proto IPC from Bitcoin Core<br/>• runs template_creator.rs<br/>• embeds OP_RETURN commitment<br/>• sends BraidpoolTemplate over mpsc"]
BRAID_C["braid::{extend, dag}<br/>node/src/braid/<br/>• validates shares<br/>• extends DAG<br/>• propagates beads via P2P"]
end
subgraph WIRING["node wiring"]
WIRE["spawn sv2_template_consumer task<br/>wire mpsc::Sender<BraidpoolTemplate><br/>start Pool + tproxy processes"]
end
IPC_C -.-> WIRE
end
subgraph COMMON["pool-apps/braidpool-common<br/>(lives in braidpool/sv2-apps)"]
BPT_TYPE["pub struct BraidpoolTemplate {<br/> coinbase_tx: Vec<u8>,<br/> merkle_path: Vec<[u8; 32]>,<br/> prev_hash: [u8; 32],<br/> nbits: u32,<br/> header_timestamp: u32,<br/> version: i32,<br/> height: u32,<br/> template_id: u64,<br/>}"]
NOTE["Only cross-repo type.<br/>Node depends on this crate.<br/>sv2-apps depends on this crate.<br/>Neither depends on the other."]
end
subgraph REPO2["github.com/braidpool/sv2-apps"]
direction TB
subgraph TMPL["pool-apps/braidpool-template-provider"]
TP_FN["pub async fn sv2_template_consumer<br/>• receives BraidpoolTemplate via mpsc<br/>• build_new_template → NewExtendedMiningJob<br/>• build_set_new_prev_hash → SetNewPrevHash<br/>• handles SubmitSolution<br/>• handles RequestTransactionData"]
end
subgraph POOL_CRATE["pool-apps/pool"]
POOL_IMPL["Downstream Channel Manager<br/>• Noise NX handshake<br/>• Extended mining channel<br/>• PoW validation — U256 target<br/>• braidpool_mode = true"]
end
subgraph TPROXY_CRATE["miner-apps/translator-proxy"]
TPROXY_IMPL["Translator Proxy<br/>• SV1 server socket<br/>• SV2 upstream extended client<br/>• per-miner merkle root computation"]
end
TP_FN -->|"async_channel<br/>TemplateDistributionOwned"| POOL_IMPL
POOL_IMPL --> TPROXY_IMPL
end
REPO1 -->|"Cargo.toml dependency<br/>braidpool-common = { git = ... }"| COMMON
REPO2 -->|"Cargo.toml dependency<br/>braidpool-common = { path = ... }"| COMMON
IPC_C -->|"tokio::sync::mpsc<br/>Sender<BraidpoolTemplate>"| TP_FN
POOL_IMPL -->|"ValidatedShare"| BRAID_C
BTC["Bitcoin Core<br/>Cap'n Proto IPC"]
BTC --> IPC_C
---
title: SV2 Simplification Braidpool vs Standard SRI
---
flowchart LR
subgraph SRI["Standard SRI"]
direction TB
BTC_SRI["Bitcoin Core"]
TP["Template Provider<br/>REMOVED"]
JD_S["Job Distributor Server<br/>REMOVED"]
JD_C["Job Distributor Client<br/>REMOVED"]
POOL_SRI["Pool binary KEPT"]
TPROXY_SRI["Translator Proxy KEPT"]
BTC_SRI --> TP --> JD_S --> JD_C --> POOL_SRI --> TPROXY_SRI
end
subgraph BP["Braidpool Architecture"]
direction TB
BTC_BP["Bitcoin Core"]
NODE_BP["braidpool Node NEW<br/>builds coinbase + OP_RETURN<br/>sends BraidpoolTemplate"]
COMMON_BP["braidpool-common NEW<br/>BraidpoolTemplate type"]
BTP_BP["template-provider NEW<br/>SV2 adapter"]
POOL_BP["Pool binary MODIFIED<br/>braidpool_mode = true"]
TPROXY_BP["Translator Proxy KEPT"]
BTC_BP --> NODE_BP --> COMMON_BP --> BTP_BP --> POOL_BP --> TPROXY_BP
end
SRI -->|"Braidpool replaces"| BP
---
title: New Template Flow
---
sequenceDiagram
participant BITCOIN as Bitcoin Core
participant IPC as ipc_block_listener<br/>(braidpool/braidpool)
participant CONSUMER as ipc_template_consumer<br/>(braidpool/braidpool)
participant PROVIDER as sv2_template_consumer<br/>braidpool-template-provider<br/>(sv2-apps)
participant POOL as Pool Channel Manager<br/>(sv2-apps)
participant TPROXY as Translator Proxy<br/>(sv2-apps)
participant MINER as SV1 Miner
BITCOIN->>IPC: new block template<br/>Cap'n Proto IPC
IPC->>CONSUMER: Arc<BlockTemplate><br/>ipc_template.components<br/>(height lives here, not BlockTemplate.height)
CONSUMER->>CONSUMER: template_creator builds coinbase<br/>OP_RETURN commitment embedded<br/>stored as processed_block_hex
CONSUMER->>PROVIDER: BraidpoolTemplate<br/>(coinbase_tx, merkle_path,<br/>prev_hash, nbits, version,<br/>height, header_timestamp,<br/>template_id)
Note over PROVIDER: Startup handshake —<br/>must receive CoinbaseOutputConstraints<br/>from pool before processing templates
POOL->>PROVIDER: CoinbaseOutputConstraints<br/>coinbase_output_max_additional_size
Note over PROVIDER: Future Job path<br/>(latency optimisation)
PROVIDER->>POOL: NewExtendedMiningJob<br/>future_template = true<br/>braidpool_mode = true — all outputs included<br/>(reward + segwit + OP_RETURN)
POOL->>TPROXY: NewExtendedMiningJob
TPROXY->>TPROXY: compute merkle_root<br/>per miner extranonce_prefix
TPROXY->>MINER: mining.notify<br/>(miners prepare work in advance)
PROVIDER->>POOL: SetNewPrevHash<br/>activates the Future Job<br/>header_timestamp from template → min_ntime
POOL->>TPROXY: SetNewPrevHash
TPROXY->>MINER: mining.notify<br/>clean_jobs = true<br/>(miners activate instantly)
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment