Umotu Explorer
Home/docs/operators/validator-node

Validator Onboarding — Umotu (CometBFT)

Run a validator with CometBFT for consensus and Umotu’s ABCI app for execution (embedded EVM). This guide explains identities, registration, setup, and verification.

Identity Model

  • Consensus identity: CometBFT validator key (Ed25519, 32 bytes).
  • Operator identity: Ethereum address (EOA) for on‑chain ops and rewards.
  • Mapping: ValidatorRegistry maps consensusKeyoperator.

Register your CometBFT consensus key on‑chain, pointing to the operator EOA.

Quick Start (single node)

Install CometBFT v0.38.12 and the Umotu native bundle, then start the launcher in dev mode (no QC/PBS enforcement) for initial testing.

# Linux (amd64)
# CometBFT
curl -LO https://github.com/cometbft/cometbft/releases/download/v0.38.12/cometbft_0.38.12_linux_amd64.tar.gz
tar xzf cometbft_*.tar.gz && sudo mv cometbft*/cometbft /usr/local/bin/
cometbft init --home ~/.umotu/cometbft

# Umotu bundle
curl -LO https://downloads.umotu.com/releases/umotu-node-v0.3.1-linux_amd64.tar.gz
tar xzf umotu-node-v0.3.1-linux_amd64.tar.gz
./bin/umotu-node --dev start
  • ABCI JSON‑RPC: http://localhost:8080/rpc
  • CometBFT RPC: http://localhost:26657

For production, set QC/PBS activation (either absolute heights via UMOTU_*_ACTIVATE_AT or relative windows via UMOTU_*_ACTIVATE_WITHIN) across validators and remove --dev.

Register Your Consensus Key

  1. Get your consensus public key
    # ABCI helper
    curl -fsS http://localhost:8080/consensus-key | jq
    # { type, base64, hex, address }
    
    # Or direct from CometBFT
    curl -fsS http://localhost:26657/status | jq -r .result.validator_info.pub_key.value   | base64 -d | xxd -p -c 256 | sed 's/^/0x/'
  2. Register on‑chain
    # Foundry cast (example)
    REG=0x<ValidatorRegistry>
    CONS=0x<consensusKeyHex>
    POWER=1
    cast send $REG 'register(bytes32,uint32)' $CONS $POWER   --rpc-url http://localhost:8080/rpc   --private-key $PK
  3. Verify mapping
    cast call $REG 'operatorOf(bytes32)(address)' $CONS --rpc-url http://localhost:8080/rpc

Tip: set UMOTU_VALIDATOR_REGISTRY in your environment for services that need it. To schedule QC/PBS enforcement without hunting for the current height, set UMOTU_QC_ACTIVATE_WITHIN / UMOTU_PBS_ACTIVATE_WITHIN (the ABCI starts enforcing that many blocks after it reaches live head).

PBS-lite Automation

The ABCI proposer now handles relay interactions for you—configure a token once and restart.

  1. Configure the env
    UMOTU_BUILDER_AUTOMATION=true
    # Comma-separated builder relays; the proposer will try each until one responds
    UMOTU_BUILDER_RELAY_URL=https://builder-relay1.testnet.umotu.com,https://builder-relay2.testnet.umotu.com
    UMOTU_BUILDER_TOKEN=<your proposer token>
    UMOTU_BUILDER_ASSIGN_TIMEOUT_MS=1500
    UMOTU_BUILDER_SLASH_INTERVAL_SEC=5
    UMOTU_BUILDER_SLASH_TIMEOUT_MS=8000

    Add these to abci/.env (or your systemd env file), then restart the node.

  2. Mint a token via POST /register
    VALCONS=$(curl -s http://localhost:26657/status | jq -r '.result.validator_info.address' | tr '[:upper:]' '[:lower:]')
    OPERATOR=0xYourOperatorAddress
    NONCE=$(date +%s)
    MESSAGE="UMOTU_RELAY_REGISTER:proposer:${OPERATOR}:${VALCONS}:${NONCE}"
    SIG=$(cast wallet sign --private-key $OPERATOR_PRIV "$MESSAGE")
    
    curl -X POST http://builder-relay:8387/register   -H "Content-Type: application/json"   -d "{\"role\":\"proposer\",\"address\":\"$OPERATOR\",\"proposerId\":\"$VALCONS\",\"nonce\":\"$NONCE\",\"signature\":\"$SIG\"}"

    Copy the returned token into UMOTU_BUILDER_TOKEN. Ensure the relay persists ./builder-relay-data so tokens survive restarts.

  3. Let automation run
    • During PrepareProposal it calls GET /bids, picks the best valid bid, and instantly posts /assign.
    • FinalizeBlock validates tx #1 against the receipt hash so QC/phones can verify it.
    • A watchdog waits for expiresAt; if the builder never delivers, it automatically POSTs /slash so you still capture the proposer share.
    • If no bids arrive or the relay is unreachable, it silently falls back to the local mempool (respecting UMOTU_ALLOW_BUILDER_FALLBACK).

Need to troubleshoot? You can still `curl` `GET /bids`, `POST /assign`, or `POST /slash`; automation coexists with manual calls.

Stake & Register

Once your node is healthy, stake UMT in ValidatorRegistry so the operator EOA enters the validator set. Addresses live in system-addresses.json.

Env snippet
export RPC_URL=https://rpc.testnet.umotu.com
export REGISTRY=0xValidatorRegistry
export REWARDS=0xValidatorRewards
export PK=0xYourOperatorPrivateKey
Register consensus key & stake
# CONS from /consensus-key or umotu_getConsensusKey
CONS=0x<ed25519 hex>
cast send $REGISTRY 'register(bytes32,uint32)' $CONS 1 --rpc-url $RPC_URL --private-key $PK
# Stake 50k UMT (native)
cast send $REGISTRY 'stake(uint256)' 50000e18 --rpc-url $RPC_URL --private-key $PK
  • stake() uses native UMT; no ERC‑20 approve is needed.
  • Use cast call $REGISTRY 'operatorOf(bytes32)(address)' to confirm the mapping.
  • On testnet, target stake is 50k UMT; governance can adjust for mainnet.

Rewards & Unbonding

Claim rewards
# Pending reward balance
cast call $REWARDS 'pending(address)(uint256)' $(cast wallet address --private-key $PK) --rpc-url $RPC_URL
# Claim
cast send $REWARDS 'claim()' --rpc-url $RPC_URL --private-key $PK
Unbond flow
# Request unbond (example: 10k)
cast send $REGISTRY 'requestUnbond(uint256)' 10000e18 --rpc-url $RPC_URL --private-key $PK
# Inspect pending amount + unlock
cast call $REGISTRY 'pending(address)(uint256,uint256)' $(cast wallet address --private-key $PK) --rpc-url $RPC_URL
# After unlock, withdraw
cast send $REGISTRY 'withdrawUnbond()' --rpc-url $RPC_URL --private-key $PK

Validator rewards come from protocol fees (base fee share, PBS payments). There is no new emission; APR depends on network usage and policy.

CometBFT Configuration

  • Home: ~/.umotu/cometbft (created by cometbft init or on first launcher run).
  • Set persistent_peers in config.toml or use a seeds list for discovery.
  • Expose P2P 26656 and (optionally) RPC 26657; keep RPC behind a firewall if public.
  • Prometheus metrics can be enabled in config.
# Helpers
cometbft show-node-id --home ~/.umotu/cometbft
cometbft version

systemd (Linux)

Use the provided unit to run the launcher as a service.

# Install binaries from bundle
sudo install -m 755 bin/umotu-node /usr/local/bin/umotu-node
sudo install -m 755 bin/umotu-abci /usr/local/bin/umotu-abci

# Env file
sudo tee /etc/default/umotu-node >/dev/null <<'EOF'
UMOTU_GENESIS=/var/lib/umotu/genesis.json
UMOTU_VALIDATOR_REGISTRY=0x0000000000000000000000000000000000000000
UMOTU_QC_ENFORCE=false
UMOTU_PBS_REQUIRED=false
UMOTU_ALLOW_BUILDER_FALLBACK=true
EOF

# Service
sudo cp ops/systemd/umotu-node.service /etc/systemd/system/
sudo systemctl daemon-reload
sudo systemctl enable --now umotu-node
sudo systemctl status umotu-node

See ops/systemd/README.md in the repo for more.

Verify Health

# ABCI
curl -fsS http://localhost:8080/healthz
# CometBFT
curl -fsS http://localhost:26657/health
# JSON-RPC
curl -s -X POST http://localhost:8080/rpc -H 'content-type: application/json' --data '{"jsonrpc":"2.0","id":1,"method":"eth_chainId","params":[]}'