Skip to content

Adding Support For Non-Validators#393

Open
samliok wants to merge 3 commits into
mainfrom
non-validator
Open

Adding Support For Non-Validators#393
samliok wants to merge 3 commits into
mainfrom
non-validator

Conversation

@samliok

@samliok samliok commented Jun 2, 2026

Copy link
Copy Markdown
Collaborator

Non-Validator Node

Adds a nonvalidator package implementing a node that follows a Simplex chain,
verifying and indexing finalized blocks, without participating in consensus (it never
votes, proposes, or signs). It tracks the chain by collecting blocks + finalizations from
validators and replicating any sequences it's missing.

NonValidator (non_validator.go)

Similarly to the epoch we have a HandleMessage function. However we only listen to these message types:

  • Block messages (handleBlock) — accepts a block only if it's from the round's
    leader, in a known epoch, and within the sequence window. Blocks are buffered in
    incompleteSequences until the matching finalization arrives.
  • Finalizations (handleFinalization) — verifies the QC against the epoch's validator
    set. Matches against any buffered block; finalizations too far ahead or for unknown
    epochs are forwarded to the replicator / trigger a sealing-block request.
  • Replication responses (handleReplicationResponse) — validates each fetched quorum
    round, stores it in the replication state, then schedules the next in-order finalized
    block for verification and indexing.

Once a block and a verified finalization are held for a sequence, a verification task is
scheduled (scheduleNewFinalizedBlockTask) through a BlockDependencyManager, which
enforces that sequences are verified/indexed in order.

Epoch validation (epochs.go, epoch_replicator.go)

A non-validator must know each epoch's validator set to verify finalizations. Validator
sets are carried in sealing blocks (new SealingBlockInfo, see below) which form a
backward-linked hash chain across epochs.

  • epochs map holds only epochs whose validator set has been validated. Bootstrapped from
    storage in newEpochs (handles genesis / pre-Simplex Epoch 0).
  • A new epoch is validated when (maybeValidateNextEpoch):
    1. we receive/verify the sealing block normally, or
    2. canValidate — we already trust the next epoch and this block matches its
      prevSealingBlockHash (validate backward down the chain), or
    3. epochReplicator.collectedQuorumRound — we've collected F+1 matching sealing-block
      responses from distinct nodes for an epoch we can't otherwise verify


switch {
case msg.BlockDigestRequest != nil:
// TODO: it seems reasonable for our non-validator to be able to process these messages and send out responses.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

for another pr

return nil
}

// TODO: add a re-broadcast timeout task until we have validated an epoch.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

for another pr

func (n *NonValidator) sendRequest(seq uint64, to simplex.NodeID) {
digestRequest := simplex.BlockDigestRequest{
Seq: seq,
Digest: simplex.Digest{}, // TODO: In the epoch code, update how we process digests to not drop the request given an empty digest.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

for another pr

@samliok samliok marked this pull request as ready for review June 11, 2026 18:18
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant