Monad Version Agent
Building a verifiable layer around validator upgrades
Beyond Uptime: Designing a Verifiable Operational Layer for Validators
What matters more for a mature blockchain network: a validator that is simply running, or a validator whose operational state can be cryptographically verified?
Historically, in Proof of Stake networks, discussions about validator quality have revolved around basic, binary metrics: is the node online, is it signing blocks, and what is its uptime? But as a network matures, this is no longer sufficient. Capital demands predictability. When institutional delegators allocate millions of dollars, they need more than a green "online" checkmark. A 99.9% uptime metric can easily mask operational chaos: last-minute manual updates, poor infrastructure monitoring, or delayed security patches.
To build true trust, we must move beyond reputation and rely on verifiable on-chain signals. The narrative shifts: Uptime tells you whether a validator is present. Version transparency starts telling you how it operates.
In this post, we examine the architecture behind our Release Code Framework, a system designed to transition validator evaluation from crude uptime metrics to verifiable operational maturity.
The Architecture: A Dual-Layer Approach
When designing a system to track validator updates, the naive approach is to have an off-chain script scrape the node's version and push it to an API. However, this lacks cryptographic proof and is vulnerable to manipulation. We needed a system where the operational reality of the network is inherently observable and verifiable on-chain.
Our solution consists of three core components:
- Validator Version Agent: A one-shot release processing binary written in Rust that runs off-chain on the validator's server.
- Version Registry: An on-chain Solidity smart contract that stores the attestation records.
- Staking Precompile: The absolute on-chain source of truth for a validator's
secpidentity, located at0x0000000000000000000000000000000000001000.
By separating the execution context (Rust binary) from the state context (Solidity contract) and anchoring identity to the protocol's core staking precompile, we create a robust, trustless pipeline.
1. Identity and Cryptographic Proofs
How do we guarantee that an update signal actually came from the validator and wasn't spoofed? We implemented a double-layer security model.
Off-chain Execution:
The Validator Version Agent uses monad-keystore recover to extract the validator's secp private key from their local keystore. The agent then signs a strict 32-byte digest that binds the validator tuple, contract address, chain ID, nonce, deadline, tag hash, and commit hash.
On-chain Verification:
Once the transaction reaches the VersionRegistry contract, the contract does not blindly trust the sender. In fact, the gas-paying sender is not used as the validator authority at all; any account can submit the transaction.
Instead, the contract performs the following steps:
- It queries the staking precompile using
getValidator(uint64)to fetch the authoritative compressedsecp256k1public key for the givenvalidatorId. - It derives the expected EVM address from this compressed pubkey.
- It reconstructs the exact same digest and runs
ecrecoveragainst the provided signature.
If the recovered signer does not match the expected signer, the transaction reverts with an InvalidSigner error. This ensures that only the entity holding the actual validator keystore can attest to a version update.
2. The Policy Engine and State Machine
Operational discipline isn't just about updating; it's about updating according to a predictable schedule based on the severity of the release. To enforce this, the agent is driven by an installer policy defined in update-policy.json.
The binary reads this policy, freezes the release data into a local queue, and publishes it in strict FIFO (First-In-First-Out) order.
We implemented a TTL (Time-To-Live) Policy Engine to handle different release urgencies.
Release eligibility is strictly computed as release_at_unix = detected_at + effective_ttl_hours * 3600. The agent operates as a one-shot execution: if the queue head is not yet releasable, the run exits immediately rather than using blocking wait loops or long-lived polling.
3. Robustness: Queue Integrity and Safe Dequeueing
When dealing with distributed systems, RPC ambiguities and partial failures are inevitable. To prevent out-of-order publication or silent payload mutations, the agent enforces rigid queue processing rules:
- Head-Only Processing: The queue is processed strictly from the head.
- Integrity Quarantines: Before any submission, the agent verifies the queue-head integrity (checking the payload hash, signature validity, and signer identity). If a
payload_hashmismatch occurs and the policyupdated_atdoes not match the head'sdetected_at, the corrupted head is quarantined into arelease-queue-problematic.jsonfile (saving the full snapshot andsecp_pub_key) and dequeued, allowing the loop to continue safely. - Safe Dequeue: A release is only removed from the active queue after on-chain confirmation via
getLatestVersion. This protects the system against false transaction success signals and RPC syncing delays.
Conclusion: The First Building Block
By combining a strict local state machine with cryptographically secure on-chain validation, we have created a system that forces operational transparency.
Version transparency is not the end goal; it is a fundamental building block. Today, it provides transparency into which client version a validator is running. Tomorrow, it becomes the foundation for deep, automated analytics regarding validator quality. When delegators and smart contracts can query a registry to see exactly how quickly a validator responds to critical red patches versus routine green updates, the network can programmatically route capital to the most disciplined operators.
First, the market looked at uptime. Now, it will look at verifiable operational maturity.