Skip to content

BFT consensus threshold is validator-count-weighted, not stake-weighted (Sybil risk) #496

Description

@RUKAYAT-CODER

Background

bft_consensus.rs::update_consensus_state computes the Byzantine threshold purely from the count of active validators (n = 3f+12f+1 votes required), even though the same function already tracks each validator's stake (total_stake, VALIDATOR_STAKES):

/// # TODO
/// - Weight the threshold by stake rather than validator count to make
///   Sybil attacks more expensive (stake-weighted BFT).
fn update_consensus_state(env: &Env) -> Result<(), BridgeError> {
    ...
    // Byzantine threshold: 2f+1 where n = 3f+1
    // For n validators, we need ceil(2n/3) + 1 for BFT
    ...
}

Because the threshold only depends on the number of active validators and not their stake, an attacker can cheapen a Sybil attack by registering many low-stake validators rather than needing to acquire a proportional share of total stake — undermining the economic security assumption typical BFT-with-stake systems rely on.

Implementation Plan

  • Change update_consensus_state (and the vote-counting logic in vote_on_proposal) to weight votes/threshold by validator stake rather than raw validator count, while preserving the 2f+1-equivalent safety margin expressed in stake terms.
  • Ensure property_based_tests.rs's existing BFT safety/liveness properties (quorum intersection, threshold monotonicity) are updated to validate the stake-weighted formula rather than the count-based one.
  • Add a test/property demonstrating that registering many low-stake validators no longer reduces the effective attack cost below the equivalent honest-majority stake threshold.

Acceptance Criteria

  • Consensus threshold and vote counting are computed from validator stake, not validator count
  • Existing BFT property tests are updated and still pass under the stake-weighted model
  • A new test demonstrates Sybil resistance (many low-stake validators can't cheaply reach threshold)

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions