Nakamoto Miner[3.0] - Finish signing in-progress block at the end of a tenure or reward cycle
Currently, when a new burn block arrives that kicks off a new reward cycle, both the miner and the signers will cancel the in-progress block. From the miner's perspective this looks like:
- Miner mines block B
- Miner proposes block B
- Miner sees new burn block
- Miner cancels B
From the signer's perspective this looks like:
- Signer sees block B proposal and initiates block validation
- Signer sees new burn block which activates cycle N
- Signer for N-1 is killed
- Block validation response is ignored by signer for cycle N
There are other timing variations of the above scenario (e.g. burn block arrives after signing is initiated, but before signing completes) . I believe with the Nakamoto design, we no longer need to have this race against the burn blocks. Instead, we should allow block B to complete, then the next miner should start its tenure building off of B.
At the end of a tenure which is not the end of a cycle, the miner will cancel block B, but the signer is not killed as it is in the above scenario, so they may complete the signing of the block. I'm not entirely sure exactly what happens in this case at the moment.
I saw this scenario happen in the nakamoto-1 testnet, and it caused a delay in block production:
- 09:10:00.860 - miner assembled block 6028
- 09:10:00.892 - miner proposed block 6028 to signers
- 09:10:02.112 - miner sees new burn block 1236, cancels block assembly
- 09:10:02.455 - miner' (next tenure) assembles block 6028'
- 09:10:02.550 - miner' proposes block 6028' to signers
- 09:10:03.186 - signers complete signing for block 6028
- 09:10:03.365 - miner' receives signature for 6028, ignores it.
This will require changes on the signer's end to not abort signing blocks if their tenure is expired (i.e. a to be signed stacks block could arrive after the burn block that indicates a new reward cycle has started)
I think the simplest policy for this situation would be Option A:
From the miner's perspective:
- If I see a burn block before proposing my block to the signers, don't bother sending it
- If the signers approve a block I proposed before seeing the next burn block, broadcast it
From the signers' perspective:
- If I receive a block proposal after seeing the new burn block, ignore it
- If I am in the middle of signing a proposed block when I see the new burn block, finish signing it
An alternative, Option B, would be to allow the miner to finish building the block it is currently building when it sees the new burn block. This would require the signers to have some grace period where they allow one new block proposal after they have seen the new burn block.
From the miner's perspective:
- If I see a burn block before proposing my block to the signers, immediately finish building the block and send it to the signers
- Wait for the final block to be approved and then broadcast it (or upon rejection, just end)
From the signers' perspective:
- Wait for one final block from the miner for X seconds after seeing the burn block
- If a block arrives before the grace period ends, sign it
- Do not sign blocks from the next miner until after the grace period has ended
- If a block arrives after the grace period ends, ignore it
I have a strong preference for Option A since it is significantly simpler and also potentially helps to encourage the miner to send blocks at a regular pace (i.e. the amount of work thrown away at the end of the tenure is small, since smaller blocks have been regularly built and proposed throughout the tenure).
Yes -- I agree with Option A.
Ok, it seems like Option A is already what is happening on both the miner and signer sides. I don't think we need any changes for that basic case. I have an integration test to verify this in #4919.
The case I was primarily concerned about is no longer an issue. I think we can close this issue, though it's possible other cases are found with further testing.