Commit b19c872
fix: v21 — close macroblock-boundary timeout-cert circular deadlock
Three surgical changes to the BFT vote-pool semantics. Closes the
deadlock observed at the first macroblock boundary with a failed
primary producer (mb_idx=4 on 5-node testnet, h=360 stuck for 12.7 h).
A1. Forward-looking TimeoutVote target (node.rs:17749)
Vote mb_idx now derives from next_height / 90, not
microblock_height / 90. At a macroblock boundary the old
expression resolved to the PREVIOUS macroblock (already
finalised); voters could never converge 2f+1 on the new one.
Receiver-side already accepts forward votes within local_mb + 50
(unified_p2p.rs::handle_timeout_vote), so emitter-only change.
A2. Vote-pool fallback in pipeline cert check
(block_pipeline.rs:1761, +2 helpers in unified_p2p.rs)
When AggregatedTimeoutCert for (mb_idx, round) is missing,
consult the live TIMEOUT_VOTES pool. If 2f+1 distinct-voter
Dilithium3-signed votes are present, admit (cert is just an
aggregated view of those same signed messages — same trust
source, same threshold). Otherwise fall back to the original
defer-and-request-backfill path.
New SimplifiedP2P helpers:
count_timeout_votes_in_pool(mb_idx, round) -> usize
has_two_f_plus_one_timeout_votes(mb_idx, round, threshold) -> bool
Logged at INFO with a boundary flag indicating whether the
bypass fired at h % 90 == 0 (legitimate cert-aggregation race)
or mid-macroblock (operator-attention worthy).
B1. Heartbeat-driven forward TimeoutVote emit (node.rs +95 lines)
Existing heartbeat_fast_path detector (3 s silent threshold)
only triggered empty-slot attestation. Now also emits a signed
TimeoutVote at certified_round + 1 — gated on
proposed_timeout_round == 0, is_synced_enough, and
(microblock_height > 0 || genesis_era_dead_producer) so the new
path never double-fires with the legacy stall-driven emit.
broadcast_timeout_vote dedupes via TIMEOUT_VOTED_HEIGHTS, so
cross-tick or cross-path redundancy collapses to one effective
vote per (mb_idx, round, voter).
Safety
------
A1: same Dilithium3 signature, same (mb_idx, round, voter_id)
anti-replay tracker, same 2f+1 threshold for cert generation.
A2: pool entries are the same Dilithium3-signed messages the cert
aggregator consumes (verified at gossip ingest). No new gate, just
direct access.
B1: same signing path, same broadcast path, same per-voter dedup.
The cryptographic floor (signature math + 2f+1) is unchanged across
all three fixes.
Scalability
-----------
Per-node steady-state cost: zero added bandwidth, zero added
storage, O(1) hot-path for A2 lookup. Identical profile from 5-node
genesis to 1M super-nodes.
Tests
-----
* 6 new regression tests in tests_v21_a2_vote_pool covering pool
helpers (zero/exact/below/at/above threshold, independent
per-round buckets).
* Full suite: qnet-consensus 73 passed, qnet-integration 149 passed
(was 143, +6 new), 12 ignored hardware bench, 0 failed across
both crates.
* cargo build --release: clean, 0 warnings.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>1 parent d9c7a89 commit b19c872
3 files changed
Lines changed: 450 additions & 23 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
1769 | 1769 | | |
1770 | 1770 | | |
1771 | 1771 | | |
1772 | | - | |
1773 | | - | |
1774 | | - | |
1775 | | - | |
1776 | | - | |
1777 | | - | |
1778 | | - | |
1779 | | - | |
1780 | | - | |
1781 | | - | |
1782 | | - | |
1783 | | - | |
1784 | | - | |
1785 | | - | |
| 1772 | + | |
| 1773 | + | |
| 1774 | + | |
| 1775 | + | |
| 1776 | + | |
| 1777 | + | |
| 1778 | + | |
| 1779 | + | |
| 1780 | + | |
| 1781 | + | |
| 1782 | + | |
| 1783 | + | |
| 1784 | + | |
| 1785 | + | |
| 1786 | + | |
| 1787 | + | |
| 1788 | + | |
| 1789 | + | |
| 1790 | + | |
| 1791 | + | |
| 1792 | + | |
| 1793 | + | |
| 1794 | + | |
| 1795 | + | |
| 1796 | + | |
| 1797 | + | |
| 1798 | + | |
| 1799 | + | |
| 1800 | + | |
| 1801 | + | |
| 1802 | + | |
| 1803 | + | |
| 1804 | + | |
| 1805 | + | |
| 1806 | + | |
| 1807 | + | |
| 1808 | + | |
| 1809 | + | |
| 1810 | + | |
| 1811 | + | |
| 1812 | + | |
| 1813 | + | |
| 1814 | + | |
| 1815 | + | |
| 1816 | + | |
| 1817 | + | |
| 1818 | + | |
| 1819 | + | |
| 1820 | + | |
| 1821 | + | |
| 1822 | + | |
| 1823 | + | |
| 1824 | + | |
| 1825 | + | |
| 1826 | + | |
| 1827 | + | |
1786 | 1828 | | |
| 1829 | + | |
| 1830 | + | |
| 1831 | + | |
| 1832 | + | |
| 1833 | + | |
| 1834 | + | |
| 1835 | + | |
| 1836 | + | |
| 1837 | + | |
| 1838 | + | |
1787 | 1839 | | |
1788 | 1840 | | |
1789 | | - | |
1790 | | - | |
| 1841 | + | |
| 1842 | + | |
| 1843 | + | |
1791 | 1844 | | |
1792 | 1845 | | |
1793 | | - | |
| 1846 | + | |
| 1847 | + | |
| 1848 | + | |
| 1849 | + | |
| 1850 | + | |
| 1851 | + | |
| 1852 | + | |
| 1853 | + | |
| 1854 | + | |
| 1855 | + | |
| 1856 | + | |
| 1857 | + | |
| 1858 | + | |
| 1859 | + | |
| 1860 | + | |
| 1861 | + | |
| 1862 | + | |
| 1863 | + | |
| 1864 | + | |
| 1865 | + | |
| 1866 | + | |
| 1867 | + | |
| 1868 | + | |
| 1869 | + | |
| 1870 | + | |
1794 | 1871 | | |
1795 | | - | |
1796 | 1872 | | |
1797 | 1873 | | |
1798 | 1874 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
17694 | 17694 | | |
17695 | 17695 | | |
17696 | 17696 | | |
17697 | | - | |
17698 | | - | |
17699 | | - | |
17700 | | - | |
17701 | | - | |
| 17697 | + | |
| 17698 | + | |
| 17699 | + | |
| 17700 | + | |
| 17701 | + | |
| 17702 | + | |
| 17703 | + | |
| 17704 | + | |
| 17705 | + | |
| 17706 | + | |
| 17707 | + | |
| 17708 | + | |
| 17709 | + | |
| 17710 | + | |
| 17711 | + | |
| 17712 | + | |
| 17713 | + | |
| 17714 | + | |
| 17715 | + | |
| 17716 | + | |
| 17717 | + | |
| 17718 | + | |
| 17719 | + | |
| 17720 | + | |
| 17721 | + | |
| 17722 | + | |
| 17723 | + | |
| 17724 | + | |
| 17725 | + | |
| 17726 | + | |
| 17727 | + | |
| 17728 | + | |
| 17729 | + | |
| 17730 | + | |
| 17731 | + | |
| 17732 | + | |
| 17733 | + | |
| 17734 | + | |
| 17735 | + | |
| 17736 | + | |
| 17737 | + | |
| 17738 | + | |
| 17739 | + | |
| 17740 | + | |
| 17741 | + | |
| 17742 | + | |
| 17743 | + | |
| 17744 | + | |
| 17745 | + | |
| 17746 | + | |
| 17747 | + | |
| 17748 | + | |
| 17749 | + | |
17702 | 17750 | | |
17703 | 17751 | | |
17704 | 17752 | | |
| |||
18154 | 18202 | | |
18155 | 18203 | | |
18156 | 18204 | | |
| 18205 | + | |
| 18206 | + | |
| 18207 | + | |
| 18208 | + | |
| 18209 | + | |
| 18210 | + | |
| 18211 | + | |
| 18212 | + | |
| 18213 | + | |
| 18214 | + | |
| 18215 | + | |
| 18216 | + | |
| 18217 | + | |
| 18218 | + | |
| 18219 | + | |
| 18220 | + | |
| 18221 | + | |
| 18222 | + | |
| 18223 | + | |
| 18224 | + | |
| 18225 | + | |
| 18226 | + | |
| 18227 | + | |
| 18228 | + | |
| 18229 | + | |
| 18230 | + | |
| 18231 | + | |
| 18232 | + | |
| 18233 | + | |
| 18234 | + | |
| 18235 | + | |
| 18236 | + | |
| 18237 | + | |
| 18238 | + | |
| 18239 | + | |
| 18240 | + | |
| 18241 | + | |
| 18242 | + | |
| 18243 | + | |
| 18244 | + | |
| 18245 | + | |
| 18246 | + | |
| 18247 | + | |
| 18248 | + | |
| 18249 | + | |
| 18250 | + | |
| 18251 | + | |
| 18252 | + | |
| 18253 | + | |
| 18254 | + | |
| 18255 | + | |
| 18256 | + | |
| 18257 | + | |
| 18258 | + | |
| 18259 | + | |
| 18260 | + | |
| 18261 | + | |
| 18262 | + | |
| 18263 | + | |
| 18264 | + | |
| 18265 | + | |
| 18266 | + | |
| 18267 | + | |
| 18268 | + | |
| 18269 | + | |
| 18270 | + | |
| 18271 | + | |
| 18272 | + | |
| 18273 | + | |
| 18274 | + | |
| 18275 | + | |
| 18276 | + | |
| 18277 | + | |
| 18278 | + | |
| 18279 | + | |
| 18280 | + | |
| 18281 | + | |
| 18282 | + | |
| 18283 | + | |
| 18284 | + | |
| 18285 | + | |
| 18286 | + | |
| 18287 | + | |
| 18288 | + | |
| 18289 | + | |
| 18290 | + | |
| 18291 | + | |
| 18292 | + | |
| 18293 | + | |
| 18294 | + | |
| 18295 | + | |
| 18296 | + | |
18157 | 18297 | | |
18158 | 18298 | | |
18159 | 18299 | | |
| |||
0 commit comments