Skip to content
150 changes: 150 additions & 0 deletions specs/lazy-adr/adr-022-validator-network.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,150 @@
# 022 Validator Network

Date: 2025-05-25
Status: Draft

## Context

When a single sequencer is used there is a limited design space for the token and a limited set of security guarantees. The validator network offers an alternative to using a full consensus protocol, but offers security guarantees with more than one participant verifying the execution and ordering.

The validator network acts as an extra security layer and soft confirmation enabling the rollup to move faster than the underlying DA layer with added security. Secondly a validator network introduces the opportunity to do more with the token of the chain.

The original design and implementation was centered around IBC and adding an extra layer of security for counter party chains, so that the user is not solely trusting the sequencer to act correctly

## Decision

Rollkit will introduce a validator network in which there will be a set of validators verifying execution and construction.

Validators sign **one Attestation per epoch** that covers every block proposed inside that
epoch. The Attestation must be broadcast as a transaction within a configurable
**SubmissionWindow** (measured in blocks and always ≤ `EpochLength`).
Missing the window does **not** incur slashing but the validator forfeits rewards for that
epoch.
If a validator fails to submit an Attestation for **NonParticipationEpochs** consecutive
epochs it is automatically removed from the active validator set (stake remains bonded
unless separate evidence triggers slashing).

The design is centered around the proposer producing blocks as fast as possible and asking
for signatures **after the fact, once per epoch**. This maximises throughput while still
obtaining soft-finality from a multi-party validator set.

### High-level workflow

1. Block broadcast — For every height h the sequencer broadcasts the canonical BlockBundle(h) (header, transactions, state root) to all active attesters over gRPC/WebSocket.
2. Local verification — Each attester independently:
• validates every block header in the epoch and the resulting state transition;
• (optionally) re-executes the blocks using a connected full node;
• after processing the last block of the epoch, what is signs is up to the execution environment.
3. Attestation submission — The attester sends the epoch signature as a transaction
**within SubmissionWindow**.
4. Aggregation & quorum — The attester module / contract collects epoch signatures until
≥ ⅔ of current bonded voting power have signed, providing a soft confirmation of the
whole epoch.
- If quorum is not met by the epoch boundary, the network pauses new proposals until
quorum is reached or **EmergencyMode** governance override is enabled.
5. Final block commit — After the block is included in the DA layer it will be considered to have a hard confirmation.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can you elaborate why the block is gossiped via IBC? Who is receiving them?

### Signing schemes

Different signature schemes can be doused in conjunction with the validator network. To start we will support ED25519 and later one we plan on adding other signature schemes based on how user demand requires.
Comment thread
tac0turtle marked this conversation as resolved.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There appears to be a minor typo in this section. The phrase "later one we plan" should be corrected to "later on we plan" for proper phrasing.

Spotted by Diamond

Is this helpful? React 👍 or 👎 to let us know.

Some potential future additions could be BLS12-381 aggregate and/or a BLS threshold signature.

### Validator set & staking integration

The attester layer can plug into different validator‑set providers. Below we outline the existing Cosmos‑SDK flow and an alternative Reth / EVM flow patterned after UniChain’s staking design. Both share the same quorum rule (≥ ⅔ voting power) and slashing philosophy.

#### Cosmos‑SDK

Introduce a dedicated x/network module that completely owns the CommitHash and ValidatorHash that appear in every block‑header. Rollkit remains untouched; the logic lives entirely in the ABCI application.

Hashes produced in‑app During EndBlock, x/network gathers the attestation bitmap for height h, computes and returns them in ResponseEndBlock.

When a relayer queries /block or /header, the application serves the canonical valset hash and commit hash from its KV‑store, ensuring external clients see the attested header even though rollkit itself never verified the signatures.

Validatorset updates from the staking module (x/staking) remains the single source of truth for bonded power. Every block it emits a ValidatorSetUpdate event. x/network subscribes and mirrors
the active validator bitmap. On a set‑change (say at height 100) the EndBlock hook updates x/network's bitmap before computing the hashes for the next height.
Comment on lines +65 to +66
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

Grammar and sentence break for ValidatorSet updates

  • Change “Validatorset updates … remains” → “Validator set updates … remain.”
  • Merge the broken sentence (“x/network subscribes and mirrors the active validator bitmap.”)
- Validatorset updates from the staking module (x/staking) remains the single source of truth for bonded power. Every block it emits a ValidatorSetUpdate event. x/network subscribes and mirrors
- the active validator bitmap.
+ Validator set updates from the staking module (x/staking) remain the single source of truth for bonded power. Every block emits a ValidatorSetUpdate event, and x/network subscribes to mirror the active validator bitmap.
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
Validatorset updates from the staking module (x/staking) remains the single source of truth for bonded power. Every block it emits a ValidatorSetUpdate event. x/network subscribes and mirrors
the active validator bitmap. On a setchange (say at height 100) the EndBlock hook updates x/network's bitmap before computing the hashes for the next height.
Validator set updates from the staking module (x/staking) remain the single source of truth for bonded power. Every block emits a ValidatorSetUpdate event, and x/network subscribes to mirror the active validator bitmap.
On a set-change (say at height 100) the EndBlock hook updates x/network's bitmap before computing the hashes for the next height.
🧰 Tools
🪛 LanguageTool

[uncategorized] ~50-~50: Possible missing comma found.
Context: ...source of truth for bonded power. Every block it emits a ValidatorSetUpdate event. x/...

(AI_HYDRA_LEO_MISSING_COMMA)

🤖 Prompt for AI Agents
In specs/lazy-adr/adr-022-validator-network.md around lines 50 to 51, correct
the grammar by changing "Validatorset updates ... remains" to "Validator set
updates ... remain" and merge the fragmented sentence "x/network subscribes and
mirrors the active validator bitmap." into the preceding sentence to improve
readability and flow.


##### Flow

```mermaid
sequenceDiagram
participant Val as Validator
participant App as x/network
participant R as Rollkit
Val->>App: MsgAttest{h, sig}
loop within epoch
App->>App: store sig, update bitmap
App->>App:EndBlock{ValidatorHash, CommitHash}
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There's a formatting inconsistency in the Mermaid diagram. The line App->>App:EndBlock{ValidatorHash, CommitHash} is missing a space after the colon, unlike other sequence diagram entries. For consistency with the rest of the diagram, it should be formatted as App->>App: EndBlock{ValidatorHash, CommitHash}.

Suggested change
App->>App:EndBlock{ValidatorHash, CommitHash}
App->>App: EndBlock{ValidatorHash, CommitHash}

Spotted by Diamond

Is this helpful? React 👍 or 👎 to let us know.

end
R->> App: Request for hashes
```

Missing participation at the epoch boundary x/network evaluates participation:

- if validator power‑weighted participation < Quorum (default 2/3) ⇒ return ErrAttestationTimeout and halt new block production;
- validators whose participation < MinParticipation for the entire epoch are auto‑ejected from the attester set via an EditValidator emitted by x/network (their stake remains bonded but they cease to sign until they re‑declare).

#### Reth/EVM Rollup
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ACKed but I am unable to verify the feasibility of this (does it mean a bridge needs to query the contract to verify something before trusting other contracts?).


- Stake manager contract holds the validator stake/weight and maps an address to a key. It will emit `StakeSnapshot(epoch)` events that will be consumed by the consensus client.
- Stake mirror listens for staking snapshot events in order to re build the validtor set. The proposer will always be the same, we do not support rotation at this time. Once the validator set is rebuilt any changes that are witnessed will be applied to the validator network.
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There's a typo in this line: validtor should be spelled validator in the sentence "Stake mirror listens for staking snapshot events in order to re build the validator set."

Suggested change
- Stake mirror listens for staking snapshot events in order to re build the validtor set. The proposer will always be the same, we do not support rotation at this time. Once the validator set is rebuilt any changes that are witnessed will be applied to the validator network.
- Stake mirror listens for staking snapshot events in order to re build the validtor set. The proposer will always be the same, we do not support rotation at this time. Once the validator set is rebuilt any changes that are witnessed will be applied to the validator network.

Spotted by Diamond

Is this helpful? React 👍 or 👎 to let us know.

- The EVM will work in the non blocking way. The validators will be able to join and leave as they please with the requirement that they submit attestations of execution in order to provide a soft confirmation within an epoch if they would like a reward for their work.
Comment on lines +91 to +92
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

Multiple typos in Reth/EVM flow

  • “re build” → “rebuild”
  • “validtor” → “validator”
  • “non blocking” → “non-blocking”
  • Add commas for readability.
- - Stake mirror listens for staking snapshot events in order to re build the validtor set. The proposer will always be the same, we do not support rotation at this time. Once the validator set is rebuilt any changes that are witnessed will be applied to the validator network.
+ - Stake mirror listens for staking snapshot events in order to rebuild the validator set. The proposer will always be the same, as we do not support rotation at this time. Once the validator set is rebuilt, any witnessed changes are applied to the validator network.

- - The EVM will work in the non blocking way. The validators will be able to join and leave as they please with the requirement that they submit attestations of execution in order to provide a soft confirmation within an epoch if they would like a reward for their work.
+ - The EVM will operate in a non-blocking mode. Validators may join or leave freely but must submit attestations of execution to provide a soft confirmation within an epoch if they wish to earn rewards.
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
- Stake mirror listens for staking snapshot events in order to re build the validtor set. The proposer will always be the same, we do not support rotation at this time. Once the validator set is rebuilt any changes that are witnessed will be applied to the validator network.
- The EVM will work in the non blocking way. The validators will be able to join and leave as they please with the requirement that they submit attestations of execution in order to provide a soft confirmation within an epoch if they would like a reward for their work.
- Stake mirror listens for staking snapshot events in order to rebuild the validator set. The proposer will always be the same, as we do not support rotation at this time. Once the validator set is rebuilt, any witnessed changes are applied to the validator network.
- The EVM will operate in a non-blocking mode. Validators may join or leave freely but must submit attestations of execution to provide a soft confirmation within an epoch if they wish to earn rewards.
🧰 Tools
🪛 LanguageTool

[misspelling] ~89-~89: This expression is normally spelled as one or with a hyphen.
Context: ...for staking snapshot events in order to re build the validtor set. The proposer will alw...

(EN_COMPOUNDS_RE_BUILD)


[uncategorized] ~89-~89: A comma might be missing here.
Context: ...at this time. Once the validator set is rebuilt any changes that are witnessed will be ...

(AI_EN_LECTOR_MISSING_PUNCTUATION_COMMA)


[misspelling] ~90-~90: This word is normally spelled with a hyphen.
Context: ...tor network. - The EVM will work in the non blocking way. The validators will be able to joi...

(EN_COMPOUNDS_NON_BLOCKING)


[uncategorized] ~90-~90: Possible missing comma found.
Context: ... will be able to join and leave as they please with the requirement that they submit a...

(AI_HYDRA_LEO_MISSING_COMMA)


[style] ~90-~90: Consider a more concise word here.
Context: ...t they submit attestations of execution in order to provide a soft confirmation within an e...

(IN_ORDER_TO_PREMIUM)

🤖 Prompt for AI Agents
In specs/lazy-adr/adr-022-validator-network.md around lines 89 to 90, fix typos
by changing "re build" to "rebuild", "validtor" to "validator", and "non
blocking" to "non-blocking". Also, add commas where needed to improve
readability in the sentences describing the staking snapshot events and EVM
behavior.


Solidity Contract

```sol
contract StakeManager {
struct Validator { uint96 power; bytes32 edKey; bytes blsKey; }
mapping(address => Validator) public validators;

function stake(uint96 amount, bytes32 edKey, bytes calldata blsKey) external;
function unstake(uint96 amount) external;
function slash(address val, uint96 amt) external /* onlyEvidence */;
function snapshot() external returns (bytes32 root); // called by sequencer each epoch
}
```

### Quorum and liveness

• Quorum rule (per-epoch): `signedVotingPower ≥ 2/3 · totalVotingPower`
• Timers
– `SubmissionWindow` (blocks): max delay after epoch end to include an attestation.
– `AggregationTimeout` (seconds): after window closes; sequencer can advance only if
**EmergencyMode** is enabled, otherwise production halts.
• Safety vs. liveness — Because verification is local and deterministic, equivocation is impossible: the worst failure mode is not reaching quorum (→ halt) which staking incentives should discourage.

## Architecture & Interfaces

```mermaid
Copy link
Copy Markdown
Member

@julienrbrt julienrbrt May 26, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

could you add the commit to DA in this? I suppose it will happens after the attesters have "verifed" the block? Or is it solely for IBC packets?

graph TD
SQ[Sequencer] -- p2p --> A1[Attester 1]
SQ -- p2p --> A2[Attester 2]
SQ -- p2p --> A3[Attester N]
A1 -- SubmitSignature Tx --> SQ
A2 -- SubmitSignature Tx --> SQ
A3 -- SubmitSignature Tx --> SQ
```

### Attester service

• Conn manager — maintains persistent stream to /broadcastBlock and unary client to /SubmitSignature.
• Verifier pipeline:

1. basic header checks;
2. produce signature;
3. async submit transaction with signautres

## Security considerations

• Double-sign protection — Deterministic bytesToSign makes replay impossible; Ed25519 prevents malleability.
• Slashing — Existing Cosmos evidence (MsgEvidence) for missed or duplicate signatures applies unchanged.
• Sybil resistance — validator power is staked; no separate token.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Are there special requirements to the transport channels for block broadcast + signatures response?

## Consequences

- Increased code complexity, more to maintain

## Future work

- Multi-sequencer fail-over — once fast-leader-election is required we can revisit consensus purely for sequencer rotation.
Loading