Skip to content

bug(genesis): ValidatorManager accepts validator sets with no positive voting power #344

Description

@sanjeebdas1979

Summary

The genesis ValidatorManager schema currently accepts validator configurations that cannot produce a usable consensus validator set.

Two invalid configurations are accepted:

  1. An empty validators array.
  2. A validator set where every validator has votingPower: 0.

Zero-power validators are valid individually, but the validator set as a whole should contain at least one validator with positive voting power.

Why this matters

The genesis configuration currently marks configured validators as active, but the consensus-side validator decoding ignores validators with zero voting power.

As a result, an empty validator list or an all-zero voting-power validator set can leave consensus with no usable validators and cause startup to fail later.

This would be better rejected during genesis configuration validation.

Reproduction

Using schemaValidatorManager.safeParse():

// Currently accepted, but should be rejected.
configWithValidators([])

// Currently accepted, but should be rejected.
configWithValidators([
  validator(PUBLIC_KEY_A, CONTROLLER_A, 0n),
  validator(PUBLIC_KEY_B, CONTROLLER_B, 0n),
])

Before adding validation, the regression test produced:

ValidatorManager genesis validator-set validation
  1) rejects an empty validator set
  2) rejects a validator set with no positive voting power
  ✔ accepts a validator set with positive voting power
  ✔ accepts zero-power validators when another validator has positive power

2 passing
2 failing

Both failing cases returned success: true from the schema.

Expected behavior

Genesis validation should require the validator set to contain at least one validator with positive voting power.

The following should remain valid:

[20]     -> valid
[0, 20]  -> valid

The following should be rejected:

[]       -> invalid
[0, 0]   -> invalid

This preserves support for zero-power validators while preventing a validator set with no effective voting power.

Proposed fix

Add a set-level validation to schemaValidatorManager:

if (!data.validators.some((validator) => validator.votingPower > 0n)) {
  ctx.addIssue({
    code: z.ZodIssueCode.custom,
    path: ['validators'],
    message: 'At least one validator must have positive voting power',
  })
}

A regression test covering empty, all-zero, positive-only, and mixed zero/positive validator sets can be included with the fix.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions