Proposal: On-chain Validator Client Version Attestations (Signed by `id-secp`)

Summary

This is a proposal for the Monad Foundation to consider introducing an official on-chain mechanism for validators to publish authenticated client version updates.

Under this approach, validators run a lightweight local agent that detects monad-bft restarts and version changes, signs a small attestation using the validator’s consensus SECP identity (id-secp), and submits it to a smart contract. The contract verifies the signature against the validator’s registered key (via the Staking precompile) and records the update as immutable on-chain state/events.

The result is a public, verifiable dataset of validator client versions and upgrade timelines that any frontend can read directly from the blockchain.


Motivation

A small on-chain registry of validator-signed version updates is a cleaner source of truth for this specific telemetry:

  • Authenticity: each update is signed by the validator’s consensus identity (id-secp), so the network can verify “this validator reported it”.
  • Immutability: a permanent history of version transitions is preserved on-chain.
  • Permissionless access: any dashboard or monitoring tool can read the same dataset from chain without special infrastructure.

Proposed Design

1) Validator Version Agent (off-chain, run by validators)

Validators run a small service that:

  • monitors monad-bft for restarts and maintains the last known client version locally,
  • when a restart occurs and the version differs from the last known value:
    • builds a version attestation payload,
    • signs it using the validator’s consensus SECP key (id-secp),
    • submits the attestation to the on-chain registry contract.

2) Transaction Sender EVM Address (validator-managed)

On-chain submissions require a transaction, so each validator sets up a separate dedicated EVM sender address used only for this reporting flow. The validator keeps the private key locally (it is not shared with anyone) and funds the address with a small amount to cover transaction fees.

This sender key is only used to broadcast the transaction, while the attestation itself is signed by the validator’s consensus SECP identity (id-secp).

3) On-chain Version Registry Contract

A smart contract accepts version submissions and records them only if:

  • the attestation signature is valid,
  • the signer corresponds to the validator’s registered identity (retrieved by validatorId from the Staking precompile),
  • the update is not a replay (per-validator nonce).

The contract stores the current version and emits an event for each accepted update, enabling both:

  • fast “latest state” reads, and
  • complete historical tracking via events.

How the Contract Verifies the Signature (Simple Flow)

  1. The contract receives validatorId, versionHash, timestamp, nonce, and the signature.
  2. The contract rebuilds the same message hash (digest) from these fields (plus a domain like chainId + contract address).
  3. The contract uses ecrecover to recover the signer address from the digest and the signature.
  4. The contract calls the Staking precompile and fetches the validator record by validatorId to get the validator’s secpPubkey.
  5. The contract derives the expected signer address from that secpPubkey and compares it with the recovered signer address.
  6. If they match (and the nonce is valid), the contract accepts the update, stores the new version data, and emits an event.

Attestation Payload (Concept)

Each update includes at minimum:

  • validatorId
  • version (versionHash = keccak256(versionString)?)
  • timestamp
  • nonce
  • signature (produced with id-secp)

What This Enables

  • Network-wide version statistics with strong authenticity guarantees
    • Accurate distribution of client versions across validators
    • Upgrade adoption curves and timelines
  • Public, permissionless data access
    • Any frontend can read the latest versions and historical transitions directly from chain
  • Standardized and transparent upgrade visibility
    • A canonical dataset for the ecosystem, independent of centralized polling infrastructure
2 Likes

Solid idea! This can be extended further by also pushing the validator metadata onchain.

Doing this might draw attention to security bug fix updates, if any.

I’m also concerned about a second program having access to the private key.

Perhaps instead validators could push a version into a block they create? This would allow security updates to not notify of changes, would not involve adding another piece of software, and would take single digit minutes on average for changes to be able to be seen on chain for active validators.

The extra_data field is already in blocks, and could be used for this.

Thanks, makes sense to think about security.

  • Releases are public on GitHub already, and the “Latest” tag is the recommended version signal. This just makes adoption measurable;

  • Attestations can be signed with the existing validator id-secp using monad-sign-name-record, which is already part of the node tooling;

  • The agent should be Foundation-shipped;

  • No new attack vector: the key stays local, and the contract accepts only signatures that match the validator identity in staking state.