bor module is responsible for managing span intervals and coordinating interactions with the Bor chain. Specifically, it determines when a new span is created and which producer it assigns, based on the current block number and the current span.
Since the Rio hardfork, each span has exactly one selected producer, and spans are created in-consensus during Heimdall’s block processing (
AddNewVeBlopSpan) rather than through the MsgProposeSpan side-transaction flow described below. The MsgProposeSpan path is pre-Rio: its side-handler now votes NO for any span at or after the Rio height, so it no longer produces spans in production. The data structures and query commands on this page remain current; the proposal/voting mechanics describe the legacy flow.Preliminary terminology
- A
side-transactionis a normal heimdall transaction but the data with which the message is composed needs to be voted on by the validators since the data is obscure to the consensus protocol itself, and it has no way of validating the data’s correctness. - A
sprintcomprises of 16 bor blocks (configured in bor). - A
spancomprises 400 sprints in bor (check heimdall’s bor params endpoint).
Overview
The validators on the bor chain produce blocks within spans. Hence, it is imperative for the protocol to formalize the producer for a range of blocks (span). The bor module in heimdall facilitates this by selecting the producer for each span from the producer pool, which is determined on-chain from stake-weighted validator producer votes. The bor chain fetches and persists this information before the next span begins. The bor module is a crucial component in heimdall since the PoS chain “liveness” depends on it.
How it works
ASpan is defined by the data structure:
idmeans the id of the span, calculated by monotonically incrementing the id of the previous span.start_blockcorresponds to the block in bor from which the given span would begin.end_blockcorresponds to the block in bor at which the given span would conclude.validator_setdefines the set of active validators.selected_producersare the validators selected to produce blocks in bor from the validator set.bor_chain_idcorresponds to bor chain ID.
ProposeSpan handler for basic sanity (verify whether the proposed span is in continuity, appropriate span duration, correct chain ID, etc.). Since this is a side-transaction, the validators then vote on the data present in MsgProposeSpan on the basis of its correctness. All these checks are done in SideHandleMsgSpan (verifying seed, span continuity, etc.) and if correct, the validator would vote YES.
Finally, if there are 2/3+ YES votes, the PostHandleMsgSpan persists the proposed span in the state via the keeper :
FreezeSet internally invokes SelectNextProducers, which pseudo-randomly picks producers from the validator set, leaning more towards validators with higher voting power based on stake:
Proposing a span manually
A validator can use the CLI to propose a span:Query commands
One can run the following query commands from the bor module:span- Query the span corresponding to the given span id.span-list- Fetch span list.latest-span- Query the latest span.next-span-seed- Query the seed for the next span.next-span- Query the next span.params- Fetch the parameters associated with the bor module.