Description
This is a WIP/draft pull request seeking concept/approach ACK. The goal is to initiate discussion and gather feedback on the proposed changes to see if there is sufficient support for an ACK before finalizing an implementation.
This PR initially proposes the addition of a new thread and server to enable Bitcoin Core to run as a Sv2 TP (Stratum V2 Template Provider). This approach is the most direct and naive approach in regards to integrating into the Bitcoin architecture. It builds on #23049 but no longer uses the Rust library and implements the server and message de/serialization in C++.
This PR branch has been used for testing with the SRI (Stratum V2 Reference Implementation), but it has been limited to regtest and some tests on testnet. This branch is considered far from complete.
Context
Stratum V2 is a proposed evolution of the stratum mining protocol, it has several benefits over its predecessor:
-
By default, it uses secure communication, which can protect against man-in-the-middle-attacks, e.g. hashrate hijacking
-
It uses a binary protocol instead of JSON, optimizing data transfer between all parties
-
It allows miners/downstream connections to propose their own transaction sets to mining pools
-
It can reduce occurrence of empty mined blocks
Links below for further reference:
- Stratum V2 specification: https://github.com/stratum-mining/sv2-spec
- SRI (Stratum V2 Reference Implementation): https://github.com/stratum-mining/stratum
- Stratum V2 overview: https://stratumprotocol.org/
Motivation
The motivation for this PR and potential future work is to allow Bitcoin Core to run as a Sv2 TP. This will enable downstream Sv2 connections to be able to connect and receive/submit valid work over the Sv2 protocol.
Below is an outline of a few pros/cons regarding the Sv2 TP in Bitcoin Core.
Pros:
-
Running Bitcoin Core with a config flag to enable the Sv2 TP could be arguably easier for adoption. A user would only need to be able to compile and run Bitcoin Core and its dependencies to be able to extract valid work and broadcast legitimate work over the Sv2 protocol
-
The Sv2 TP being as close as possible to the mempool and p2p network benefits downstream connections so that they can start new work quickly. The time between a node learning of a new best block and then sending new work downstream should be as minimal as possible
-
Implementing the Sv2 TP in C++ means it should be (hopefully) easier for a wider range of contributors/reviewers to be able to maintain and build. The Sv2 TP only uses a small subset of messages from the entire Sv2 Rust library. Therefore, we realized that re-implementing a subset of the messages in C++ and implementing a server carries less external dependency risk and less architectural complexity
-
No additional external dependencies are required
Cons:
-
The Sv2 TP in core will need to be kept up to date with changes in the SRI, coordination would be required to prevent any potential versioning issues
-
Adds another thread/sub-module that will need to access the mempool to build candidate blocks, so there would be another area of the code attempting to acquire
cs_main
viaBlockAssembler
-
Another architectural approach other than a new thread and server for the Sv2 TP might be preferred such as the current work in the multiprocess project
Build
To run the Sv2 TP on this branch, Bitcoin needs to be configured with ./configure --enable-template-provider
.
Future work
If there is sufficient approach/concept ACK or support in general. Then the below points are outstanding future work and existing nits.
Future work:
-
A noise implementation from the noise protocol framework needs to be introduced for secure communication between the Sv2 TP and downstream connections. The noise spec for Sv2 has been reworked to accommodate resources currently available in core e.g.
secp256k1
andBIP 340 schnorrsig
-
There are current working changes proposed to the Sv2 TP spec, to allow downstream connections to send shorttxid sets, allowing miners/downstream connections to present their own tx sets
-
Perhaps the Sv2 TP should be adapted to current work in the Bitcoin Core architecture. The new thread has been helpful for testing against the current SRI stack, it seems like the server implementation can adapt easily to different architectural needs
Existing/known nits:
-
The server implementation has no limit on the number of downstream connections, it needs to be added
-
There could be potential conflict with functional tests. The Sv2 TP responds to the best new block change by reaching into the mempool and building a new block for downstream. My guess is that it would be acceptable to disable the Sv2 TP when running functional tests that asserts mempool state and then enable the Sv2 TP when it needs to specifically run its functional tests
-
Getting the full merkle path is required in the NewTemplate message. I noticed that this was previously possible with the old implementation that was moved to merkle_test.cpp , the current implementation does an in-place calculation to just return the root. I was wondering if anyone has any suggestions or insight to a preferred solution? e.g. Move back the old functions from merkle_tests or write a new implementation?
Thank you to all who helped contribute to the process of building this branch including working on the SRI, using this branch for testing and refining the Sv2 specs.
Any feedback or reviews from nits to overall approach would be very much appreciated.