Skip to content

LocalDevAccountCreator should reject non-canonical validator IDs in overridePublicKeys #322

Description

@Kewe63

Summary

LocalDevAccountCreator accepts non-canonical validator IDs in overridePublicKeys because it parses the validator ID with Number(...) and only checks Number.isNaN(...).

As a result, values such as 1.5, 1e0, and 01 are accepted as validator IDs even though they are not canonical integer validator IDs.


Affected File

scripts/genesis/AccountCreator.ts


Observed Behavior

overridePublicKeys entries are parsed from strings in this format:

<validator_id>:<public_key>

The validator ID is currently converted with Number(...). This accepts multiple forms that should likely be rejected for an integer identifier.

Examples observed on current code:

1 ACCEPTED [[1,"0x1111...1111"]]
1.5 ACCEPTED [[1.5,"0x1111...1111"]]
1e0 ACCEPTED [[1,"0x1111...1111"]]
01 ACCEPTED [[1,"0x1111...1111"]]

The parser accepts:

  • fractional values, such as 1.5
  • scientific notation, such as 1e0
  • non-canonical leading-zero values, such as 01

Expected Behavior

overridePublicKeys validator IDs should be canonical non-negative decimal integers.

For example, these should be accepted:

  • 0
  • 1
  • 42

These should be rejected:

  • 1.5
  • 1e0
  • 01
  • -1
  • NaN
  • Infinity
  • empty strings

Reproduction

I verified this with a focused repro against the current parser.

Current behavior:

1 ACCEPTED [[1,"0x1111...1111"]]
1.5 ACCEPTED [[1.5,"0x1111...1111"]]
1e0 ACCEPTED [[1,"0x1111...1111"]]
01 ACCEPTED [[1,"0x1111...1111"]]

A negative regression test also fails on current code:

assert.throws(
  () => new LocalDevAccountCreator({ overridePublicKeys: `1.5:${key}` }),
  /Invalid validator ID/
)

The constructor currently does not throw for 1.5.


Why This Matters

validator_id is used as an identifier, so accepting fractional or alternate numeric encodings can cause ambiguous or unintended mappings.

For example:

  • 1e0 and 1 both resolve to the same numeric ID.
  • 01 and 1 both resolve to the same numeric ID.
  • 1.5 remains a non-integer key, which is unexpected for a validator ID.

Strict parsing also makes genesis/dev configuration errors fail early instead of producing confusing account/public-key mappings.


Suggested Fix

Validate the validator ID string before converting it to Number.

For example:

  • require canonical decimal integer syntax:

/^(0|[1-9][0-9]*)$/

  • then convert with Number(...)
  • then verify:

Number.isSafeInteger(id)
id >= 0


Potential Regression Tests

Add tests for overridePublicKeys parsing that verify:

Accepted:

  • 0:<key>
  • 1:<key>
  • 42:<key>

Rejected:

  • 1.5:<key>
  • 1e0:<key>
  • 01:<key>
  • -1:<key>
  • NaN:<key>
  • Infinity:<key>
  • :<key>

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