BEDROCK-V1-1-BLOCK-CONSTRUCTION
| Field | Value |
|---|---|
| Name | Bedrock v1.1 Block Construction, Validation and Execution Specification |
| Slug | 93 |
| Status | raw |
| Category | Standards Track |
| Editor | Marcin Pawlowski [email protected] |
| Contributors | Thomas Lavaur [email protected], Daniel Sanchez Quiros [email protected], David Rusu [email protected], Álvaro Castro-Castilla [email protected], Mehmet Gonen [email protected], Filip Dimitrijevic [email protected] |
Timeline
- 2026-01-19 —
f24e567— Chore/updates mdbook (#262) - 2026-01-16 —
89f2ea8— Chore/mdbook updates (#258)
Abstract
This specification defines the construction, validation, and execution of block proposals in the Nomos blockchain. It describes how block proposals contain references to transactions rather than complete transactions, compressing the proposal size from up to 1 MB down to 33 kB to save bandwidth necessary to broadcast new blocks.
Keywords: Bedrock, block construction, validation, execution, leader, transaction, Proof of Leadership
Semantics
The keywords "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this document are to be interpreted as described in RFC 2119.
Definitions
| Terminology | Description |
|---|---|
| Leader | A node elected through the leader lottery to construct a new block. |
| Block Builder | The leader node that constructs a new block proposal. |
| Block Proposer | The leader node that shares the constructed block with other network members. |
| Block Proposal | A message structure containing a header and references to transactions. |
| Proof of Leadership (PoL) | A proof confirming that a node is indeed the elected leader. |
| Transaction Maturity | The assumption that transactions have had enough time to spread across the network. |
| Validator | A node that validates and executes block proposals. |
High-level Flow
This section presents a high-level description of the block lifecycle. The main focus of this section is to build an intuition on the block construction, validation, and execution.
-
A leader is selected. The leader becomes a block builder.
-
The block builder constructs a block proposal.
-
The block builder selects the latest block (parent) as the reference point for the chain state update.
-
The block builder constructs references to the deterministically generated Mantle Transactions that execute the Service Reward Distribution Protocol, if such transactions can be constructed. For example, there is no need to distribute rewards when all rewards have already been distributed.
-
The block builder selects valid Mantle Transactions (as defined in Mantle Specification) from its mempool and includes references to them in the proposal.
-
The block builder populates the block header of the block proposal.
-
-
The block proposer sends the block proposal to the Blend network.
-
The validators receive the block proposal.
-
The validators validate the block proposal.
-
They validate the block header.
-
They verify distribution of service rewards through Mantle Transactions as specified in Service Reward Distribution Protocol. This is done by independently deriving the distribution transaction and confirming that it matches the first reference, if there are rewards to be distributed.
-
They retrieve complete transactions from their mempool that are referred in the block.
-
They validate each transaction included in the block.
-
-
The validators execute the block proposal.
-
They derive the new blockchain state from the previous one by executing transactions as defined in Mantle Specification.
-
They update the different variables that need to be maintained over time.
-
Constructions
Hash
This specification uses two hashing algorithms that have the same output length of 256 bits (32 bytes) that are Poseidon2 and Blake2b.
Block Proposal
A block proposal, instead of containing complete Mantle Transactions of an unlimited size, contains references of fixed size to the transactions. Therefore, the size of the proposal is constant and it is 33129 bytes.
The following message structure is defined:
class Proposal: # 33129 bytes
header: Header # 297 bytes
references: References # 32768 bytes
signature: Ed25519Signature # 64 bytes
Where:
headeris the header of the proposal; defined below: Header.referencesis a set of 1024 references to transactions of ahashtype; the size of thehashtype is 32 bytes and is the transaction hash as defined in Mantle Specification - Mantle Transaction.signatureis the signature of the completeheaderusing theleader_keyfrom theProofOfLeadership; the size of theEd25519Signaturetype is 64 bytes.
Note: The length of the
referenceslist must be preserved to maintain the message's indistinguishability in the Blend protocol. Therefore, the list must be padded with zeros when necessary.
Header
class Header: # 297 bytes
bedrock_version: byte # 1 bytes
parent_block: hash # 32 bytes
slot: SlotNumber # 8 bytes
block_root: hash # 32 bytes
proof_of_leadership: ProofOfLeadership # 224 bytes
Where:
bedrock_versionis the version of the proposal message structure that supports other protocols defined in Bedrock Specification; the size of it is 1 byte and is fixed to0x01.parent_blockis the block ID (Cryptarchia v1 Protocol Specification) of the parent block, validated and accepted by the block builder. It is used for the derivation of theAgedLedgerandLatestLedgervalues necessary for validating the PoL; the size of thehashis 32 bytes.slotis the consensus slot number; the size of theSlotNumbertype is 8 bytes.block_rootis the root of the Merkle tree constructed from transaction hashes (defined in Mantle Specification - Mantle Transaction) used for constructing thereferenceslist in thetransactions; the size of thehashis 32 bytes.proof_of_leadershipis the proof confirming that the sender is the leader; defined below: Proof of Leadership.
Block References
class References: # 32768 bytes
service_reward: list[zkhash] # 1*32 bytes
mempool_transactions: list[zkhash] # 1024-len(service_reward)*32 bytes
Where:
service_rewardis a set of up to 1 reference to a reward transaction of azkhashtype; the size of thezkhashtype is 32 bytes and is the transaction hash as defined in Mantle Specification - Mantle Transaction.mempool_transactionsis a set of up to 1024 references to transactions of azkhashtype; the size of thezkhashtype is 32 bytes and is the transaction hash as defined in Mantle Specification - Mantle Transaction.
The service_reward transaction is created deterministically by the leader
and is not obtained from the mempool.
If this transaction were obtained from the mempool,
it could expose the leader's identity as the transaction creator.
To protect the leader's identity,
only the service_reward reference is included in the proposal,
and it is derived again by the nodes verifying the block.
The service_reward transaction is a Service Rewards Distribution Transaction
that distributes service rewards.
It is a Mantle Transaction with no input
and up to service_count x 4 outputs,
service_count being the number of services (global parameter).
The outputs represent the validators rewarded (up to 4 per service).
If the service_reward transaction cannot be created,
then nothing is added to the list.
Therefore, the service_reward list is allowed to have a length of 0.
Proof of Leadership
class ProofOfLeadership: # 224 bytes
leader_voucher: RewardVoucher # 32 bytes
entropy_contribution: zkhash # 32 bytes
proof: ProofOfLeadership # 128 bytes
leader_key: Ed25519PublicKey # 32 bytes
Where:
leader_voucheris the voucher value used for retrieving the reward by the leader for proposal; the size of theRewardVoucheris 32 bytes.entropy_contributionis the output of the PoL contribution for Cryptarchia entropy; the size of thezkhashtype is 32 bytes.proofis the proof confirming that the proposal is constructed by the leader; the size of theProofOfLeadershiptype is 128 bytes (2 compressed G1 and 1 compressed G2 BN256 elements).leader_keyis the one-timeEd25519PublicKeyused for signing theProposal. This binds the content of the proposal with theProofOfLeadership; the size of theEd25519PublicKeytype is 32 bytes.
Proposal Construction
This section explains how the block proposal structure presented above is populated by the consensus leader.
The block proposal is constructed by the leader of the current slot.
The node becomes a leader only after successfully generating a valid PoL
for a given (Epoch, Slot).
Prerequisites
Before constructing the proposal, the block builder must:
-
Select a valid parent block referenced by
ParentBlockon which they will extend the chain. -
Derive the required Ledger state snapshots
AgedLedgerandLatestLedgerfrom the state of the chain including the last block. -
Select a valid unspent note winning the PoL.
-
Generate a valid PoL proving leadership eligibility for
(Epoch, Slot)based on the selected note. Attach the PoL to a one-time Ed25519 public key used to sign the block proposal.
Only after the PoL is generated can the block proposal be constructed (see Proof of Leadership Specification).
Construction Procedure
-
Initialize proposal metadata with the last known state of the blockchain. Set the:
header:bedrock_versionparent_blockslotblock_rootproof_of_leadership:leader_voucherentropy_contributionproofleader_key
-
Construct the
service_rewardobject:- If there are service rewards to be distributed,
construct the transaction that distributes
the service rewards from previous session
and add its reference to the
service_rewardlist. This transaction must be computed locally, do not disseminate this transaction.
- If there are service rewards to be distributed,
construct the transaction that distributes
the service rewards from previous session
and add its reference to the
-
Construct the
mempool_transactionsobject:-
Select Mantle transactions:
-
Choose up to
1024-len(service_reward)validSignedMantleTxfrom the local mempool. -
Ensure each transaction:
-
Is valid according to Mantle Specification.
-
Has no conflicts with others (e.g., two transactions trying to spend the same note).
-
-
-
-
Derive references values:
references: list[zkhash] = [mantle_txhash(tx) for tx in service_reward + mempool_transactions] -
Compute the
header.block_rootas the root of the Merkle tree constructed from thelist(service_reward) + mempool_transactionstransactions used to buildreferences. -
Sign the block proposal header.
signature = Ed25519.sign(leader_secret_key, header) -
Assemble the block proposal.
proposal = Proposal( header, references, signature )
The PoL must have been generated beforehand and bound to the same Ledger view as mentioned in the Prerequisites.
The constructed proposal can now be broadcast to the network for validation.
Block Proposal Reconstruction
Given a block proposal, this specification assumes transaction maturity. This means that the block proposal must include transactions from the mempool that have had enough time to spread across the network to reach all nodes. This ensures that transactions are widely known and recognized before block reconstruction.
This transaction maturity assumption holds true because the block proposal must be sent through the Blend Network before it reaches validators and can be reconstructed. The Blend Network introduces significant delay, ensuring that transactions referenced in the proposal have reached all network participants.
This approach is crucial for maintaining smooth network operation and reducing the risk that proposals get rejected due to transactions being unavailable to some validators. Moreover, by increasing the number of nodes that have seen the transaction, anonymity is also enhanced as the set of nodes with the same view is larger. This may result in increased difficulty—or even practical prevention—of executing deanonymization attacks such as tagging attacks.
Upon receipt of a block proposal, validators must confirm the presence of all referenced transactions within their local mempool. This verification is an absolute requirement—if even a single referenced transaction is missing from the validator's mempool, the entire proposal must be rejected. This stringent validation protocol ensures only widely-distributed transactions are included in the blockchain, safeguarding against potential network state fragmentation.
The process works as follows:
-
Transaction is added to the node mempool.
-
Node sends the transaction to all its neighbors.
-
Neighbors add the transaction to their own mempools and propagate it to their neighbors—transaction is gossiped throughout the network.
-
Block builder selects a transaction from its local mempool, which is guaranteed to be propagated through the network due to steps 1-3.
-
Block builder constructs a block proposal with references to selected transactions.
-
Block proposal is sent through the Blend Network, which requires multiple rounds of gossiping. This introduces a delay that ensures the transaction has reached most of the network participants' mempools.
-
Block proposal is received by validators.
-
Validators check their local mempools for all referenced transactions from the proposal.
-
If any transaction is missing, the entire proposal is rejected.
-
If all transactions are present, the block proposal is reconstructed and proceeds to further validation steps.
Block Proposal Validation
This section defines the procedure followed by a Nomos node to validate a received block proposal.
Given a Proposal, a proposed block consisting of a header and references.
This block proposal is considered valid if the following conditions are met:
Block Validation
The Proposal must satisfy the rules defined in
Cryptarchia v1 Protocol Specification - Block Header Validation.
Block Proposal Reconstruction Validation
The references must refer to either a service_reward transaction
that is locally derivable
or to existing mempool_transaction entries
that are retrievable from the node's local mempool.
Mempool Transactions Validation
mempool_transactions must refer to a valid sequence
of Mantle Transactions from the mempool.
Each transaction must be valid according to the rules
defined in the Mantle Specification.
In order to verify ZK proofs,
they are batched for verification as explained in
Batch verification of ZK proofs
to get better performances.
Rewards Validation
-
Check if the first reference matches a deterministically derived Service Rewards Distribution Transaction that distributes previous session service fees as defined in Service Reward Distribution Protocol. It should take no input and output up to
service_count * 4reward notes distributed to the correct validators. -
If the above rewarding transactions cannot be derived, then the first reference must refer to a
mempool_transaction.
If any of the above checks fail, the block proposal must be rejected.
Block Execution
This section specifies how a Nomos node executes a valid block proposal to update its local state.
Given a ValidBlock that has successfully passed proposal validation,
the node must:
-
Append the
leader_vouchercontained in the block to the set of reward vouchers when the following epoch starts. -
Execute the Mantle Transactions included in the block sequentially, using the execution rules defined in the Mantle Specification.
Annex
Batch verification of ZK proofs
Blob Samples
-
For each sample the verifier follows the classic cryptographic verification procedure as described in NomosDA Cryptographic Protocol - Verification except the last step, once the verifier has a single commitment C^(i), an aggregated element v^(i) at position u^(i) and one proof π^(i) for each sample.
-
The verifier draws a random value for each sample r_i ← $F_p.
-
The verifier computes:
-
C' := Σ(i=1 to k) r_i · C^(i)
-
v' := Σ(i=1 to k) r_i · v^(i)
-
π' := Σ(i=1 to k) r_i · π^(i)
-
u' := Σ(i=1 to k) r_i · u^(i) · π^(i)
-
-
They test if e(C' - v' · G1 + u', G2) = e(π', τ · G2).
Proofs of Claim
-
For each proof of Claim the verifier collects the classic Groth16 elements required for verification. It includes the proof π^(i), and the public values x_j^(i) for each proof of claim.
-
The verifier draws one random value for each proof r_i ← $F_p.
-
The verifier computes:
-
π'_j := Σ(i=1 to k) r_i · π_j^(i) for j ∈ {A, B, C}.
-
r' := Σ(i=1 to k) r_i
-
IC := r' · Ψ_0 + Σ(j=1 to l) (Σ(i=1 to k) r_i · x_j^(i)) · Ψ_j
-
-
They test if Σ(i=1 to k) e(r_1 · π'_A, π'_B) = e(r' · [α]_1, [β]_2) + e(IC, [γ]_2) + e(π'_C, [δ]_2).
Note: This batch verification of Groth16 proofs is the same as what is described in the Zcash paper, Appendix B.2.
ZkSignatures
The verifier follows the same procedure as in Proofs of Claim but with the Groth16 proofs of ZkSignatures.
References
Normative
- Mantle Specification - Mantle transaction specification
- Cryptarchia v1 Protocol Specification - Cryptarchia consensus protocol
- Bedrock Specification - Bedrock protocol specification
- Proof of Leadership Specification - Proof of Leadership specification
- Service Reward Distribution Protocol - Service reward distribution protocol
- NomosDA Cryptographic Protocol - NomosDA cryptographic verification
Informative
- v1.1 Block Construction, Validation and Execution Specification - Original specification document
- Poseidon2 - Hash function
- Blake2b - Hash function
- Zcash paper, Appendix B.2 - Batch verification of Groth16 proofs
Copyright
Copyright and related rights waived via CC0.