Nomad Docs
  • Nomad 101
    • Funds Recovery
    • Introduction
    • Our Mission
    • Getting Started
  • The Nomad Protocol
    • Overview
    • Cross-chain Messaging
      • Lifecycle of a Message
    • Verification Mechanisms
      • Background on Verification
      • Native Verification
      • External Verification
      • Optimistic Verification
      • Comparing Mechanisms
    • Security
      • Root of Trust
        • Fraud
          • Optimistic Timeout Period
          • Fraud Recovery
        • App-Governed Root of Trust
        • Liveness Assumptions
      • Attack Vectors
        • Key Compromise
        • Economic Attacks
        • Smart Contract Bugs
      • Long-Term Security
        • Permissionless Watchers
        • Financial Controls
        • Cross-Domain MEV
    • Smart Contracts
      • Home
      • Replica
      • XAppConnectionManager
    • Off-chain Agents
      • Updater
      • Watchers
      • Relayer
      • Processor
  • Token Bridge
    • Overview
    • How to Bridge
      • Using Etherscan
      • Nomad Bridge App
      • Testnet Bridge App
    • Asset Issuers
      • Custom Representations
    • Deployed Tokens
      • Mainnet
      • Testnet
    • Smart Contracts
      • BridgeRouter
      • TokenRegistry
      • BridgeToken
      • BridgeMessage
    • Architecture
    • FAQ
  • Governance Bridge
    • Overview
    • Zodiac: Nomad Module
    • Smart Contracts
      • NomadModule
    • Architecture
  • Developers
    • Quickstart
      • Send Messages
      • Receive Messages
    • Environments
      • Domain (Chain) IDs
    • Application Developers
      • Building xApps
      • SDK
        • Contracts SDK
        • Typescript SDK
      • Examples
        • Ping Pong
        • Example Bridge GUI
        • xApp Example
      • Advanced
        • Router Pattern
    • Node Operators
      • Running Agents Guide
        • Troubleshooting
      • Running a Watcher
      • Agent Operations
      • Agent Gas Values
      • The Keymaster
    • Core Developers
      • Upgrade Setup
      • Deploying Contracts
        • Development
        • Production
  • Operational Security
    • Audits
    • Bug Bounty
    • Governance
    • Contracts
    • Agent Operations
  • Resources
    • Awesome Interoperability
    • Brand Kit
    • FAQ
    • Glossary
    • GitHub
    • Discord
    • Twitter
    • Website
Powered by GitBook
On this page
  • Performing Updates
  • Updater Selection
  • Updater Slashing
  1. The Nomad Protocol
  2. Off-chain Agents

Updater

PreviousOff-chain AgentsNextWatchers

Last updated 2 years ago

Updater Code:

The Updater is an off-chain agent that does the following:

  • Observe on the origin chain

  • Sign attestations to new roots

  • Publish the signed attestation to the Home

The Home contract permissions an "updater" that must attest to the state of the message tree. The updater places a bond on the home chain and is required to periodically sign attestations (updates or U). Each attestation contains the root from the previous attestation (U_prev), and a new root (U_new).

Performing Updates

The Updater maps logically to a single Home contract. Its entire job is to observe the Home to ensure that new messages (and hence new roots) are notarized such that they can be relayed to any number of Replicas.

The Updater listens for events on the Home, and calls functions to perform its job.

Listening for New Roots

Cross-chain applications enqueue messages to be sent by calling on the Home contract. Once the message is enqueued in the Home's message tree, the Home emits the following event:

emit Dispatch(
    _messageHash,
    count() - 1,
    _destinationAndNonce(_destinationDomain, _nonce),
    committedRoot,
    _message
);

Updaters listen for these events, and after batching some number of messages (per their SLA), will sign an update over the old root and new root.

Publishing an Update

function update(
    bytes32 _committedRoot,
    bytes32 _newRoot,
    bytes memory _signature
) external notFailed {
    // check that the update is not fraudulent;
    // if fraud is detected, Updater is slashed & Home is set to FAILED state
    if (improperUpdate(_committedRoot, _newRoot, _signature)) return;
    // clear all of the intermediate roots contained in this update from the queue
    while (true) {
        bytes32 _next = queue.dequeue();
        if (_next == _newRoot) break;
    }
    // update the Home state with the latest signed root & emit event
    committedRoot = _newRoot;
    emit Update(localDomain, _committedRoot, _newRoot, _signature);
}

Updater Selection

At a given time, there is only one Updater enrolled per Home contract. This helps reduce overhead of verification, relative to externally verified systems that require many validators or guardians.

Updater Slashing

If an Updater ever attempts to commit fraud (by attesting to an invalid root), the Home contract will be set to a failed state, at which point the Updater will be slashed:

function _fail() internal {
    // set contract to FAILED
    state = States.Failed;
    // slash Updater
    updaterManager.slashUpdater(msg.sender);
    emit UpdaterSlashed(updater, msg.sender);
}

Updaters sign attestations off-chain and publish them by calling on the Home contract:

Once the update has been performed, a may relay the new update to on destination chains.

Updaters are selected and enrolled on the Home contract by the , which is established at initialization time.

The UpdaterManager can be changed by calling . This function can only be called by the owner role, which belongs to .

The function in the UpdaterManager will be implemented when updater bonding and rotation are also implemented in the future.

https://github.com/nomad-xyz/rust/tree/main/agents/updater
the Home contract
dispatch
update
Relayer
Replica contracts
UpdaterManager contract
_setUpdaterManager
Nomad governance
slashUpdater