Lockouts and why partitions hurt TowerBFT
A 50/50 network partition. Both protocols stall safely; after the heal Alpenglow finalizes in under a second while TowerBFT needs its tower of lockouts to grow past the gap.
At 1.5 s the network splits into two halves of roughly equal stake for 1.2 s. Our transaction is submitted at 1.8 s, in the middle of the partition, to an RPC node on one side.
Two questions matter for a consensus protocol here:
- Safety: can the two halves finalize *different* blocks for the same slot? (They must not.)
- Liveness: how quickly does finality resume after the heal?
TowerBFT answers the first question with lockouts: once a validator votes for a block, it may not vote for a conflicting fork until the lockout (2, 4, 8, … slots) expires. That is what makes TowerBFT slow to recover.
Press Start.
Where it stops
-
The network splits
-
Gulf Stream keeps retrying
The transaction is submitted at 1.8 s to an RPC node on one side of the divider. The current leader is on the other side. Predict what happens.
While the partition lasts, does either protocol finalize anything?
- Both halves finalize their own blocks
- Only Alpenglow finalizes
- Only TowerBFT finalizes
- Neither: both stall until the heal
Both protocols need a supermajority of total stake: 60% (Alpenglow) or ⅔ (TowerBFT). A half cannot reach either, so nothing finalizes and, crucially, nothing *conflicting* finalizes. Stalling is the price of safety.
-
The partition heals
-
Alpenglow skips the stalled window
-
Alpenglow finalizes
-
TowerBFT: a vote reaches depth 8
-
TowerBFT finalizes
What you saw
- A 50/50 partition stalls both protocols; neither finalizes conflicting blocks. Safety held.
- Alpenglow recovers with Skip certificates and a fresh ParentReady: finality resumes about a second after the heal.
- TowerBFT recovers through lockouts and the depth-8 threshold check; finality resumes only when the tower is 31 votes deep again.
- A transaction stuck in a skipped block is re-forwarded by its RPC node; on mainnet your wallet's retry logic does the same.
Try next
- Change the partition to
"stake_split": [0.3, 0.7]in a custom scenario: the 70% side keeps finalizing under both protocols and the 30% side catches up after the heal. - Lesson 20+20 looks at Alpenglow's resilience budget: 20% offline plus 20% adversarial.