Block Assembly - Algorand Specifications
Keyboard shortcuts
Press ← or → to navigate between chapters
Press S or / to search in the book
Press ? to show this help
Press Esc to hide this help
- Auto
- Light
- Dark
Algorand Specifications
The TxPool is responsible for populating the payset of a block, a process referred to as BlockAssembly.
The BlockAssembly is a time-bound algorithm that manages the flow of transactions into the pending BlockEvaluator and stops ingestion once timing constraints are reached.
It also handles possible desynchronizations between the TxPool.round (the current round as perceived by the TxPool) and the actual round being assembled by the pending BlockEvaluator. This discrepancy arises based on how often the Update function has been invoked.
The following pseudocode outlines a high-level view of how BlockAssembly operates:
Algorithm 5: Block Assembly
1: function AssembleBlock(r)
2: if TxPool.round < r−2 then
3: return AssembleBlock.emptyBlock(r)
4: endif
5: if r < TxPool.round then
6: return nil
7: endif
8: assemblyDeadline ← round.startTime() + δassemblyDeadline
9: Wait until assemblyDeadline ∨ (TxPool.round = r ∧ BlockEvaluator is done)
10: if ¬BlockEvaluator.done() then
11: if TxPool.round > r then
12: return nil (r is behind TxPool.round)
13: endif
14: assemblyDeadline ← assemblyDeadline + ϵassemblyWait
15: Wait until assemblyDeadline ∨ (TxPool.round = r ∧ BlockEvaluator is done)
16: if ¬BlockEvaluator.done() then
17: return AssembleBlock.emptyBlock(r) (Ran out of time)
18: endif
19: if TxPool.round > r then
20: return nil (Requested round is behind transaction pool round)
21: elseif TxPool.round = r−1 then
22: return AssembleBlock.emptyBlock(r)
23: elseif TxPool.round < r then
24: return nil
25: endif
26: endif
27: return BlockEvaluator.block
28: end function
Important
IMPLEMENTATION:
Block assembly reference implementation.
This algorithm begins by taking a target round r, for which a new block is to be assembled.
It first checks the round currently perceived by the TxPool, which matches the round being handled by the pending BlockEvaluator.
If the TxPool.round is significantly behind
r: an empty block is immediately assembled and returned, as there’s no time to catch up.If the TxPool is already ahead of
r: no action is needed, as TxPool is simply ahead of the network’s current state.
Next, the algorithm waits for the assembly deadline δassemblyDeadline. During this time, the pending BlockEvaluator is expected to notify the completed block assembly in the background via the Ingestion function, and that it is caught up to the round r.
If this doesn’t happen by the deadline, the algorithm performs another round of checks:
If the TxPool.round is now ahead of
r: the process is aborted, waiting for the network to catch up. This should rarely happen.Otherwise, if the TxPool is still behind: an additional wait period
ϵassemblyWaitis introduced.
After this extra wait, similar checks are repeated:
If the TxPool is still too far behind: there is no more time to wait, and the algorithm exits.
Otherwise: the algorithm proceeds.
If all checks pass and timing constraints are met without returning early (an empty block or a nil value), the pending BlockEvaluator finally provides the fully assembled block for round r.