Overview

YouthChain uses a pipelined BFT protocol on top of PoE leader election. Every block goes through a single round of voting; every commit is a single aggregated BLS12-381 signature over the validator set.

Validator set (testnet)

4 nodes, each with its own BLS12-381 signing key (used for both the block proposal signature and the aggregated commit) and an ed25519 key used as the node’s transaction-signing identity. The registry is seeded from genesis.json and maintained on-chain by the ValidatorRegistry contract.

Slot timing

  • Slot length: 2 seconds × (view + 1). View starts at 0 and increments on every failed leader.
  • Leader: deterministically selected by PoeEngine::select_validator_index_for(beacon, slot, view). Selection is weighted by stake × (1 + β·ES) with β=0.10, seeded by a BLS randomness beacon derived from the parent’s aggregated commit signature. Higher-stake validators get more slots; on the 4-node testnet the ES term is inert, so stake is the differentiator. Every registered validator keeps a guaranteed minimum share.

Measured timing (testnet)

  • BFT commit latency — from the leader logging LEADING to the aggregated ⌊2N/3⌋+1 commit is ~20–40 ms on the current single-host testnet (LAN, no WAN round-trips).
  • Block cadence — production ticks every ~200 ms; with a non-empty mempool the leader produces immediately, so under load blocks land ~200 ms apart. When idle the chain emits a heartbeat block roughly every 1 s to stay visibly live. (The 2 s × (view+1) figure above is the view-change window, not the steady-state block time.)

Vote round

1

Leader proposes

The leader assembles a block from its mempool, runs it through revm, hashes the header, signs it with its BLS12-381 key, and POSTs the proposal to every peer’s /internal/bft/proposal endpoint.
2

Peers validate

Each peer independently re-hashes the header, re-runs the txs, checks the leader’s BLS12-381 signature and that block.validator is a registered validator. Replays are rejected (view + timestamp rule).
3

Peers sign with BLS

On success, each peer returns (signer_index, bls_signature) over block.hash. The signature is aggregable.
4

Leader aggregates quorum

Once the leader holds ⌊2N/3⌋ + 1 valid signatures (including its own), it aggregates them into a single BlsBlockSignature via aggregate_signatures() and writes commit_signers + commit_signature into the block.
5

Commit & gossip

The sealed block is stored in sled, applied to WorldState, and broadcast to peers. Peers verify the aggregate against the union of the public keys listed in commit_signers and accept the block.

Authenticated, consensus-safe P2P

The mutating internal endpoints — /internal/bft/proposal, /internal/gossip/block, /internal/gossip/tx, and /internal/peers (POST) — require a shared node token (x-yc-p2p-token); read-only sync endpoints stay open. Crucially, BFT votes are collected only from the fixed startup validator set, never from dynamically-discovered peers. A container that reaches a node’s internal port can therefore neither inject votes/peers nor stall consensus — and a sync source that serves bad or no data is skipped for the next candidate, with every block BLS + commit verified before it is applied.

View change

If the leader fails to gather a quorum within the slot window, the view counter is incremented and a new leader is chosen for the same slot:
Any registered validator can produce at view > 0 if:
  1. The previous attempt at the same height failed to collect ⌊2N/3⌋+1 votes.
  2. The new block’s timestamp is after new_min_timestamp.
  3. The new leader is a registered validator.
This gives the chain liveness even if a leader is offline, slow, or Byzantine.

Equivocation protection

The PoeEngine tracks (slot, producer, block_hash) tuples. A producer retrying the same slot with a different timestamp/view is allowed (legitimate retry). A producer signing two distinct blocks at the same (slot, producer) is detected by the fork choice rule and the conflicting blocks are dropped; the Byzantine validator can be slashed by the DAO.

Fork choice

The canonical tip is the block with the most commit signatures at the highest finalized height (ties broken by lowest hash). Under single-leader production with per-slot finality there are effectively no competing forks, so in practice there is always exactly one tip. Full path-weight DAG fork-choice — summing BLS quorum weight along each path back to genesis — ships alongside parallel production.

Guarantees

  • Safety: no two conflicting blocks can both be BFT-finalized, assuming < N/3 Byzantine validators.
  • Liveness: if ≥ 2N/3 + 1 validators are online and synchronous within the slot window, a block is produced every slot.
  • Finality: a block with commit_signers.len() ≥ ⌊2N/3⌋+1 is final. There are no reorgs past finality.