StratumV2 (Sv2) protocol defines various roles, one of which is the Template Provider (TP), explained in the template distribution section of the spec. The TP pushes block template updates to miners whenever the chain tip is updated or when mempool fees have increased sufficiently.
Rather than implementing the TP role in Bitcoin Core, the work done in #31098 allows third-party processes to interface with bitcoind through interprocess communication (IPC). The IPC interface, introduced as part of the multiprocess project, is work-in-progress too.
Bitcoin Core now exposes a mining interface through two classes BlockTemplate and Mining which provide key methods needed by the Sv2 TP client, enabling projects like Sjors’ TP client to receive block template updates via the interface.
PR Overview
PR #31981 adds a new method to the mining interface called checkBlock that checks the validity of a block template. This check is equivalent to the one done in getblocktemplate RPC in proposal mode.
The method responsible for checking whether a block template is valid in Bitcoin core is TestBlockValidity.
Motivation
Using the IPC interface to check block validity is more performant than the getblocktemplate RPC, as it avoids serializing up to 4 MB of transaction data as JSON.
Does an Sv2 TP client have to implement the new checkBlock method in the mining interface (yes/no)?
Can you list some checks performed on the block in getblocktemplate proposal mode? Does that include checking for a valid proof of work for the block template?
Apart from performance reasons mentioned in the PR description, are there any reasons an Sv2 TP client would want to use IPC instead of RPC?
What is the key difference between contextual and context-free checks in the block template validity checks?
Is there a change in behavior for TestBlockValidity after this PR, or is it a pure refactor? If yes, what’s the change?
One of the reasons for locking cs_main in TestBlockValidity is to prevent CheckBlock race conditions. Can you describe a scenario when that might happen?
In commit 1d029c23, why do we assert that fChecked should return false? Is this a potential issue?
In this CheckBlock size check, which size rule are we checking? Is it an overestimate check? Which size check is missing there?
In commit cca5993b, can you clarify the note that serialization of BlockValidationState is “fragile”?
<stringintech> I'm a bit confused by the terminology here. The PR description mentions “pools” may want to verify templates using checkBlock IPC (or getblocktemplate proposal mode). The question asks if “Sv2 TP clients” need to implement this method. Are “pools” and “Sv2 TP clients” the same thing here? I haven't gone through the Sv2 documentation
<abubakarsadiq> Question 2: Can you list some checks performed on the block in getblocktemplate proposal mode? Does that include checking for a valid proof of work for the block template?
<stringintech> And no valid PoW is checked cause the goal would be start solving the block once the checkBlock passes in getblocktemplate proposal mode.
<abubakarsadiq> 4. Apart from performance reasons mentioned in the PR description, are there any reasons an Sv2 TP client would want to use IPC instead of RPC?
<stringintech> Not sure but if clients are already using IPC for mining related functions implementing block verification this way too would be easier.
<abubakarsadiq> I think another reason apart from performance I read is that RPC is poll-based. An Sv2 TP client prefers push-based communication or long-polling, as seen in the waitNext implementation.
<sjors47> So the way they could do that currently is to use the getblocktemplate RPC in "proposal" mode, and basically just give it a serialized hex block.
<santos> monlovesmango: Local IPC channels often have lower overhead than TCP and are easy to secure via OS‐provided permissions, but they don’t give you the same out-of-the-box, cryptographic authentication (or optional TLS encryption) that you get if you run over TCP.
<stringintech> i noticed two main changes; the error handling and the CheckBlock (a context-free check) which is called before the contextual header check.
<abubakarsadiq> @sjors this brings us to another question In commit cca5993b, can you clarify the note that serialization of BlockValidationState is “fragile”?
<abubakarsadiq> One of the reasons for locking `cs_main` in `TestBlockValidity` is to prevent `CheckBlock` race conditions. Can you describe a scenario when that might happen?
<abubakarsadiq> @sjors is it possible we receive the same block from the P2P network and are trying to validate and update its state, while simultaneously calling getblocktemplate in proposal mode with same block. that would cause a race no?
<abubakarsadiq> monlovesmango: I don't think that will cause a race since they are not identical blocks, even if they are identical correct me if I am wrong @sjors. `TestBlockValidity` does not save the block so a race will not happen no?
<stringintech> abubakarsadiq: I thought so (regarding your explaination race condition for identical blocks) but i noticed in the code that may be worried about a race condition on fChecked flag; which i could not understand why.
<abubakarsadiq> yeah @sjors to answer the question myself I was a bit confused by the assertion. I believe it is an issue we should return instead. We might attempt to check a block that we already received via P2P and stored it's state.
<stringintech> abubakarsadiq: yes i understand that. which is why i didnt get why we are worried about the fChecked race condition (not sure if i read this in the code comments or commit description or ...)
<dzxzg> It seems like avoiding BlockValidationState is a nice win for the IPC interface, but it would be nice for internal users of `TestBlockValidity` to have the enum... I wonder the refactor would be simpler if testblockvalidity remained mostly as is and you placed a little wrapper around TestBlockValidity, that returns a bool and modifies the passed
<stringintech> abubakarsadiq: Witness data is excluded when performing the check, but later in ContextualCheckBlock we consider it (block weight check).
<dzxzg> abubakarsadiq: Every caller of TestBlockValidity cares about two things: Was it valid? If not, what was the reason? That is solved in a precise and reusable way with an enum. It seems to me that only the ipc interface suffers from the awkardness of packing and serializing all of this over the wire.
<stringintech> abubakarsadiq: if you mean why CheckBlock size check is not enough because we are not considering witness data and until we are sure the witness data is not tempered with in ContextualCheckBlock we can not check it?
<abubakarsadiq> Yeah I think it is an overestimate check for the weight that enable us to fail fast when the non-witness block weight exceed the maximum block weight.
<monlovesmango> I can understand not using teh enum if we are actually getting rid of the enum altogether. but if the enum is going to continue to exists it seems better to use the enum for consistency