Skip to content

feat(sv2): add braidpool-common and braidpool-template-provider crates [Part 1] - #1

Open
nkatha23 wants to merge 5 commits into
braidpool:sv2-integration-braidpoolfrom
nkatha23:braidpool/template-provider
Open

nkatha23 wants to merge 5 commits into
braidpool:sv2-integration-braidpoolfrom
nkatha23:braidpool/template-provider

Conversation

@nkatha23

@nkatha23 nkatha23 commented Sep 3, 2026 •

Copy link
Copy Markdown

Part of braidpool/braidpool#313. Architecture documented in the SV2 integration workflow.

This PR Adds two new crates to the pool-apps workspace:

braidpool-common defines BraidpoolTemplate, a shared type the Braidpool node sends to the SV2 pool. This keeps sv2-apps independent of node internals by providing a clean boundary between the two repositories.

braidpool-template-provider receives BraidpoolTemplate via a tokio::sync::mpsc channel and converts to SV2 TemplateDistribution messages (NewTemplate + SetNewPrevHash). Runs as a sibling task to ipc_template_consumer in the node.

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🟡 Changes recommended

There are confirmed protocol/behavior correctness issues (coinbase value/outputs semantics, header_timestamp=0, and incoming channel close handling) that can lead to invalid SV2 behavior or runaway loops.

Once you've addressed the issues Copilot identified, you can request another Copilot review.

Pull request overview

Adds initial scaffolding for Braidpool SV2 integration by introducing a shared template boundary type (braidpool-common) and a template-provider crate that converts those templates into SV2 TemplateDistribution messages.

Changes:

  • Extend pool-apps workspace to include braidpool-common and braidpool-template-provider.
  • Add braidpool-common::BraidpoolTemplate and initial SV2 message builders / consumer loop.
  • Update CI workflow to run on the sv2-integration-braidpool branch.
File summaries
File Description
pool-apps/Cargo.toml Adds the two new crates to the pool-apps workspace.
pool-apps/Cargo.lock Locks new workspace crates and dependency graph changes (e.g. serde/rand features).
pool-apps/braidpool-template-provider/src/sv2_messages.rs Builds NewTemplate / SetNewPrevHash from BraidpoolTemplate.
pool-apps/braidpool-template-provider/src/lib.rs Async consumer loop bridging templates to SV2 TemplateDistribution messages.
pool-apps/braidpool-template-provider/src/error.rs Defines error types used by the provider and message builders.
pool-apps/braidpool-template-provider/Cargo.toml Declares the new provider crate and dependencies.
pool-apps/braidpool-common/src/template.rs Defines the shared BraidpoolTemplate boundary type.
pool-apps/braidpool-common/src/lib.rs Exposes the template module.
pool-apps/braidpool-common/Cargo.toml Declares the new common crate.
.github/workflows/ci.yaml Expands CI triggers to include sv2-integration-braidpool branch.
Review details

Suppressed comments (2)

pool-apps/braidpool-template-provider/src/sv2_messages.rs:59

  • coinbase_tx_value_remaining is currently set to the sum of all coinbase outputs, while coinbase_tx_outputs serializes all outputs including non-zero payout outputs. In this workspace, SV2 consumers treat coinbase_tx_value_remaining as the value for the payout output they construct (e.g. pool-apps/pool/.../template_distribution_message_handler.rs:50 and miner-apps/jd-client/.../template_message_handler.rs:59), and the reference TP implementation serializes only the required zero-valued outputs (bitcoin-core-sv2/.../v30x/template_data.rs:333-363). Sending full-valued outputs here is likely to produce an invalid coinbase (double-paying) for those consumers.
    let coinbase_tx_value_remaining: u64 = coinbase_tx
        .output
        .iter()
        .map(|o| o.value.to_sat())
        .sum();

pool-apps/braidpool-template-provider/src/lib.rs:123

  • The tokio::select! arm pattern-matches only Ok(message) = sv2_incoming_rx.recv(). If the incoming channel closes, recv() resolves to Err immediately and this arm will never match, which can lead to a hot loop and a stuck task. Also, RequestTransactionDataError is sent with let _ = ..., so a closed outgoing channel would silently drop the response.
            Ok(message) = sv2_incoming_rx.recv() => {
                match message {
                    TemplateDistributionOwned::SubmitSolution(_solution) => {
                        debug!("Received SubmitSolution — forwarding to node via bridge");
                        // TODO(sv2-integration): forward to node's block submission channel
                        // This will be wired in PR 4 when the node bridge is added
  • Files reviewed: 9/10 changed files
  • Comments generated: 4
  • Review effort level: Lite

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment thread pool-apps/braidpool-template-provider/src/lib.rs
Comment thread pool-apps/braidpool-template-provider/src/sv2_messages.rs
Comment thread pool-apps/braidpool-common/src/template.rs
Comment thread pool-apps/braidpool-template-provider/src/sv2_messages.rs

@Sansh2356 Sansh2356 left a comment

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.

Code ACK c5b29a6 .

@Sansh2356 Sansh2356 left a comment

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.

Code ACK c5b29a6, following the flow as discussed .

@Sansh2356

Copy link
Copy Markdown
Collaborator

Resolving conflicts, and lgtm .

braidpool-common: introduces BraidpoolTemplate — a shared type boundary
between the Braidpool node and sv2-apps. Carries the coinbase_tx (already
built by template_creator with OP_RETURN commitment), merkle_path,
prev_hash, nbits, version, height, and template_id.

braidpool-template-provider: sv2_template_consumer receives BraidpoolTemplate
via mpsc channel and converts to SV2 TemplateDistribution messages
(NewTemplate + SetNewPrevHash). Uses braidpool_mode=true to include all
coinbase outputs (reward + segwit + OP_RETURN) as required by Braidpool's
coinbase structure.

Key design decisions:
- BraidpoolTemplate replaces direct node::ipc imports, keeping sv2-apps
  independent of node internals
- height field explicitly required from ipc_template.components since
  BlockTemplate.height = Height::ZERO in ipc_template_consumer
- RequestTransactionData returns error — Braidpool does not use TDP
- Add header_timestamp to BraidpoolTemplate (fixes invalid min_ntime=0)
- Guard coinbase_tx.input[0] access against empty input vec
- Handle closed channel in select! loops to prevent hot loop on Err
- Fix clippy uninlined_format_args and iter_cloned_collect warnings
- Scope CI clippy/fmt/machete to braidpool-common and braidpool-template-provider only
- Pin machete install to avoid rustc 1.91 requirement on 1.88 toolchain
stratum-apps features=[pool] transitively enables bitcoin_core_sv2,
which currently fails to compile against stratum-core. Depend
on stratum-core directly to sidestep the transitive dependency.
@nkatha23
nkatha23 force-pushed the braidpool/template-provider branch from c5b29a6 to 9c9db33 Compare October 23, 2026 18:30
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.

3 participants