Fix/sortition stacks tip burn view#6881
Fix/sortition stacks tip burn view#6881jcnelson merged 18 commits intostacks-network:release/3.3.0.0.6from
Conversation
…ip to the sortition of its burn view. Add unit test coverage to make sure that it works under sortition forks.
Codecov Report❌ Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## release/3.3.0.0.6 #6881 +/- ##
======================================================
+ Coverage 60.93% 77.26% +16.32%
======================================================
Files 412 412
Lines 218665 218959 +294
Branches 338 338
======================================================
+ Hits 133247 169179 +35932
+ Misses 85418 49780 -35638
... and 296 files with indirect coverage changes Continue to review full report in Codecov by Sentry.
🚀 New features to boost your workflow:
|
…tips after the migration to schema 8
|
Putting this in draft until I can find out why all these integration tests failed (ETA tomorrow). |
aaronb-stacks
left a comment
There was a problem hiding this comment.
I think the table needs to track the consensus hash of the stacks blocks (i.e., the consensus hash of their election block). The burn view consensus hash only needs to be used to determine which sortition_id to replace or insert an entry.
Yes, you're right. |
…ion-stacks-tip-burn-view
…ion-stacks-tip-burn-view
brice-stacks
left a comment
There was a problem hiding this comment.
I think this generally looks good, but I believe there is still something wrong. With this fix in place, I'd expect tests::signer::v0::reorg::btc_fork_on_midtenure_accept to fail, since it is asserting on the incorrect memoized block. This test seems to be flaky now, sometimes passing and sometimes failing on the assertion at line 5081. I'm currently not sure whether it is a test problem or an implementation problem.
Yes, I agree. I will try and fix this as soon as I am able. |
…ion-stacks-tip-burn-view
|
@brice-stacks I looked into this. The test will need some expansion. Right now, it passes because the tenure produced in the last common ancestor of the Bitcoin forks has only one block in it in the first place. |
|
The reason this test passes here is because it's racy -- the forked block gets processed before the Bitcoin block. I've locally modified it with a dumb |
…to work out the timing of various things
…ion-stacks-tip-burn-view
* add tracking global for most-recent/currently broadcasting block for test miner
|
Okay -- this should now be ready for re-reviews (though I'm now not a valid reviewer). The scenario the test was trying to trigger was the following:
Then, a bitcoin fork occurs, and with the previous buggy behavior, we assert that: The canonical stacks tip == the tip at the time of the stall. The race condition in the test was between (1) and (2) -- if the next bitcoin block is produced before the miner produces a mid-tenure block, then what happens is as follows:
When the bitcoin fork occurs, the stalled tenure-extend block is correctly not included in the canonical stacks tip. Which means this assertion still passes: The canonical stacks tip == the tip at the time of the stall. I avoided this race-condition by adding a tracking global to the test miner: this variable stores the latest block broadcasted or currently being broadcasted. Then, after we apply the stall to the miner, we wait until the current block being broadcasted is a mid-tenure block. Then, we produce a bitcoin block only after we've confirmed that the miner stalled while producing the mid-tenure block. |
|
I can't approve either |
jacinta-stacks
left a comment
There was a problem hiding this comment.
LGTM, just the one nit and should add a changelog entry.
…om/jcnelson/stacks-core into fix/sortition-stacks-tip-burn-view
|
cc @brice-stacks review please 🙏 |
3719583
into
stacks-network:release/3.3.0.0.6
|
This pull request has been automatically locked since there has not been any recent activity after it was closed. Please open a new issue for related bugs. |
This fixes part of the chain stall from the night of 7/8 Feb 2026. This patch alters the way the sortition DB memoizes the canonical Stacks chain tip by pairing each Stacks chain tip with the sortition of its burn view instead of whatever the canonical sortition tip happened to be.
The reason for this change is because it ensures that the canonical Stacks tip can be found even if a Bitcoin fork is processed before all of the preceding tenure's Stacks blocks can be processed. For example, suppose there are four sortitions: A, B, B', and C'. B and B' both descend from A, and C' descends from B'.
Now, suppose that the Stacks blocks with burn view A -- A1 through A6 -- are processed. Once A4 is processed, the
stacks_chain_tipstable would have assigned sortition A to A4. That is, the canonical Stacks tip at the canonical sortition tip is A4.But now suppose that in-between when A4 and A5 are processed, the Stacks node processes sortition B. In the old code, the
stacks_chain_tipstable would have assigned sortition B to A6. That is, the canonical Stacks tip as of canonical sortition B would be A6. In this patch, there would be no entry instacks_chain_tipsfor B; instead, the row for sortition A would be updated to be A6 (this does not change the behavior of the node, thus far).But now, suppose no Stacks blocks are mined in the B' tenure, and the node processes sortition C'. In the old code, when the node processed B', its
stacks_chain_tipsrow would report A4 as the canonical tip, because that's what its parent sortition A had (the new code does not add a row at all for B'). Now, C' is the canonical sortition history, and as with B', the node would incorrectly report that A4 was the canonical Stacks tip on the canonical sortition tip C' (since that was the tip for B', the parent of C'). In the new code, no row would be added tostacks_chain_tipsfor C'.The old code is what partially led to the chain stall -- despite the node having processed A1 through A6, the node would incorrectly report A4 as being the Stacks chain tip. The miner code used the buggy code paths to deduce what to build atop, but that has been fixed separately. In the new code, the code paths have been updated so that a sortition is not assigned a canonical Stacks tip unless the corresponding Stacks block reported that sortition as its burn view. This way, the code will correctly report A6 as the canonical Stacks tip for sortition tips B, B', and C'