Skip to content

Instantly share code, notes, and snippets.

@Aboudjem
Last active March 9, 2026 12:00
Show Gist options
  • Select an option

  • Save Aboudjem/7a52313dc83d7fe456a598a936d42ca6 to your computer and use it in GitHub Desktop.

Select an option

Save Aboudjem/7a52313dc83d7fe456a598a936d42ca6 to your computer and use it in GitHub Desktop.
Integra Infrastructure — Server Architecture

Integra Infrastructure — Server Architecture

Complete overview of all Integra servers, the mainnet/testnet coexistence model, and the full state of deployment readiness.

This document represents months of infrastructure work: a custom Cosmos EVM chain fork, 4 servers across 4 cloud providers, a live testnet running in parallel on shared servers, an air-gapped key management architecture where both the treasury AND all four validator operator keys live on a disconnected Windows laptop, a non-zero gas fee model from block 0, non-reproducible Go binaries requiring manual checksum verification across every server, and a genesis ceremony that requires physical USB transfers for every single cryptographic operation.

Last updated: 2026-03-09 (MAINNET LIVE — all 4 validators bonded, blocks producing)


Server Map

# Name IP Provider Specs Cost SSH Status
1 mainnet-gateway 89.167.88.24 Hetzner 16C/32T, 128GB RAM, 2x3.84TB NVMe $21.99/mo ssh -i ~/.ssh/integra root@89.167.88.24 Ready — genesis, systemd, Caddy, Docker, UFW
2 testnet-gateway 46.225.231.81 Hetzner 8 vCPU, 16GB RAM, 320GB + 20GB vol $21.99/mo ssh -i ~/.ssh/integra root@46.225.231.81 Active (testnet + Blockscout + Portal)
3 signer-1 45.77.139.208 Vultr 4 vCPU, 8GB RAM, 160GB $40/mo ssh -i ~/.ssh/integra root@45.77.139.208 Ready — testnet running, mainnet configured
4 signer-2 159.223.206.94 DigitalOcean 4 vCPU, 8GB RAM, 200GB $48/mo ssh -i ~/.ssh/integra root@159.223.206.94 Ready — testnet running, mainnet configured
5 archive 3.208.92.57 AWS us-east-1 4 vCPU, 32GB RAM, 1TB gp3 ~$120/mo ssh -i ~/.ssh/integra-validator-key.pem ubuntu@3.208.92.57 Ready — binary verified, systemd, UFW

Total monthly cost: ~$252/mo (excludes Adam's personal validator on separate AWS EC2)


What's Ready vs. What's Blocked

Done (Adam — server-side)

Every item below required individual SSH sessions across 4 providers with 3 different OS user models, 2 different SSH keys, and careful coordination to avoid disrupting the live testnet running on shared servers.

  • Codebase audit — forked Cosmos EVM SDK, replaced all upstream aatom/262144 defaults with airl/26217, fixed 4 bugs, all 30 tests passing, CI fully green
  • Binary built from commit 0e6a388 (Go 1.23.8, Cosmos SDK v0.53.5) — Go produces non-reproducible builds across environments, so the reference binary was physically copied to ensure identical executables. MD5 9f9c240e0e9f12a04990034410625b84 verified on all 5 servers
  • Nodes initialized on all 4 mainnet servers — consensus keys generated per server
  • Genesis created — 5 accounts, 100B IRL total supply, 5000 gwei base fee, 40+ parameters configured and cross-verified
  • Genesis SHA-256 verified identical on all 4 servers: 4338fc44...14e2a10
  • Persistent peers — full mesh topology, every server peers with every other
  • Port offsets — systematic +10000 on all mainnet ports for shared servers (verified zero collisions across 11 port pairs per server)
  • Config audit — every setting verified line-by-line across all 4 servers (gas prices, chain IDs, API enables, proxy_app ports, pruning modes, client configs)
  • Systemd services created and enabled on all 4 mainnet servers
  • Docker v29.3.0 installed on gateway, signing image built (306MB → 75MB .tar.gz) — this image is how Piyush runs signing commands on his air-gapped Windows laptop
  • Caddy + TLS on gateway with path-routed reverse proxy, HTTPS auto-provisioned
  • UFW hardened on all 4 mainnet servers (found 2 servers with no firewall at all, fixed)
  • Consensus pubkeys collected and packaged as JSON
  • Signing package hosted for download at https://mainnet.integralayer.com/downloads/

Blocked (Piyush — air-gapped signing)

Every step below requires physical interaction with the air-gapped Windows laptop. Files are downloaded from the gateway, transferred via USB stick to the air-gapped machine, processed, and the output makes the return journey via USB → Telegram to Adam.

This architecture — where not just the treasury but all four validator operator keys live on the air-gapped machine — means that every single validator operation (creation, delegation, governance vote) follows this physical transfer ceremony. No remote signing, no automation, no shortcuts.

  • Download signing package from gateway (3 files)
  • Transfer to air-gapped machine via USB
  • Verify all 5 operator keys accessible in Docker keyring
  • Sign 4 gentxs — one per validator, each referencing a different consensus pubkey, each a separate Docker command
  • Transfer 4 signed gentx files back via email to Adam (2026-03-06)
  • (Adam) Collect gentxs, finalize genesis, distribute, verify hash on all 4 — SHA-256: de47657c531fcf81bf830800191539c697edbf16da494334a6d8631fdb6a228d
  • (Adam) Chain start — all 4 nodes started via systemctl, blocks producing (2026-03-09)
  • (Adam) Verification — all 4 validators BONDED, EVM chain ID 0x6669, gas price ~5000 gwei, treasury 99.996B IRL
  • Treasury delegations — same USB round-trip: 4 unsigned txs → sign with incrementing sequence → broadcast in order

Signing Package (Download Links)

Hosted on the mainnet gateway via HTTPS. Piyush downloads these on his internet-connected machine, then transfers to USB for the air-gapped laptop.

File Size Download
Docker signing image 75 MB curl -O https://mainnet.integralayer.com/downloads/integra-signer.tar.gz
Genesis (pre-gentx) 38 KB curl -O https://mainnet.integralayer.com/downloads/genesis-pregentx.json
Consensus pubkeys 850 B curl -O https://mainnet.integralayer.com/downloads/consensus-pubkeys.json

Or download all three at once:

mkdir integra-signing-package && cd integra-signing-package
curl -O https://mainnet.integralayer.com/downloads/integra-signer.tar.gz
curl -O https://mainnet.integralayer.com/downloads/genesis-pregentx.json
curl -O https://mainnet.integralayer.com/downloads/consensus-pubkeys.json

Note

These will be removed from the gateway after genesis is finalized. The download endpoint is temporary.


Infrastructure Hardening (March 6, 2026)

A full audit of all servers revealed gaps that would have caused launch failures. Each server required individual SSH access, verification, and fixes — across 4 different providers, 3 different OS user models, and 2 different SSH keys. Nothing can be scripted when every server is its own snowflake.

Binary Integrity

Warning

Archive node's binary was 59KB larger than the reference despite identical source code and Go version. Different build environments produce non-reproducible binaries. For a Cosmos BFT chain, binary differences can cause consensus divergence — validators disagree on state transitions, the chain halts, and recovery requires coordinated intervention across all operators.

Fixed by physically copying the reference binary from gateway via SCP. The testnet gateway was also running a Feb 26 build while signer-1 and signer-2 (which share a single binary between testnet and mainnet) were already on the new one. Updating required stopping the testnet validator (can't overwrite a running binary on Linux), replacing, and restarting — brief testnet downtime even though the fix was for mainnet.

Server MD5 Status
Gateway 9f9c240e0e9f12a04990034410625b84 Reference
Signer-1 9f9c240e0e9f12a04990034410625b84 Match
Signer-2 9f9c240e0e9f12a04990034410625b84 Match
Archive 9f9c240e0e9f12a04990034410625b84 Fixed (was mismatch)
Testnet GW 9f9c240e0e9f12a04990034410625b84 Fixed (was older build)

Firewall Gaps

Caution

Two servers were running with no firewall at all. On signer-2, which runs both testnet and mainnet with validator keys on it, every port was exposed to the internet.

Server Before After
Gateway Missing EVM/REST/gRPC ports Added 8545, 8546, 1317, 9090
Signer-1 Missing mainnet RPC Added 36657
Signer-2 UFW completely inactive Enabled: SSH, testnet (26656/26657), mainnet (36656/36657)
Archive UFW completely inactive Enabled: SSH, P2P, RPC, EVM, REST, gRPC

Other Fixes

  • Gateway & Archive: No systemd service files existed — nodes were initialized and configured but literally could not start. Created services with appropriate flags.
  • Archive: Pruning was set to "default" instead of "nothing" — an archive node that prunes history defeats the entire purpose. Fixed in both app.toml and systemd.
  • Gateway: No Docker installed — needed to build the signing image for the air-gapped workflow.

Node IDs & Consensus Keys

These are the server-side consensus keys (Ed25519), auto-generated by intgd init. They sign blocks. They are NOT Piyush's operator keys (secp256k1).

Server Node ID Consensus Pubkey
gateway 837a39f482a80b56f491737055fe52199006f1fd O1JktAT8EVm+EEs1TphuwUwsBw+w/grbYeL4cj/cSq0=
signer-1 adeaabdac580df25d3766d6f1950e30c1aba2f1c k95WNbsJQecxhavFluaJje5QMzIQEd9s8WJs/jauB1g=
signer-2 91d0540496a97bf071d7fd44458b1c00a2515af3 TxScDU+iPQkiTnjnsiCaCmUafrOXm2IyhPaR2cTiLes=
archive 9c953486b7e73d0028ef63589605926213471ef3 Lym3RlyQMhhW6PTcTISlmzpE6W39QEosOW2Ynp5qUh4=

Config Audit (2026-03-06)

Every setting verified line-by-line on all 4 servers. Each shared server (signer-1, signer-2) has two complete config sets — one for testnet (default home), one for mainnet (offset home). Every port, path, and flag was individually checked.

Setting Gateway Signer-1 Signer-2 Archive
minimum-gas-prices 5000000000000airl same same same
evm-chain-id 26217 same same same
chain_id (genesis) integra-1 same same same
api.enable true false (OK) false (OK) false (OK)
json-rpc.enable true false (OK) false (OK) false (OK)
proxy_app 26658 36658 36658 26658
P2P port 26656 36656 36656 26656
RPC port 26657 36657 36657 26657
pruning default default default nothing

Note

API and JSON-RPC are disabled in config on signers but the systemd services override this with explicit --api.address and --json-rpc.address flags binding to offset ports.


How Mainnet and Testnet Coexist

Signer-1 and signer-2 run both networks simultaneously on the same physical server. They share a single intgd binary at /usr/local/bin/intgd. Everything else is isolated — but this coupling creates operational complexity:

  • Binary updates affect both networks. You can't overwrite a running executable on Linux (Text file busy), so updating the mainnet binary requires stopping the testnet service too.
  • One wrong --home flag and you're operating on the wrong chain. No warning, no error. Commands silently target testnet instead of mainnet.
  • Firewall rules must cover both. Opening mainnet ports without breaking testnet requires careful per-port UFW configuration.

Port Allocation

Service Testnet (default) Mainnet (+10000 offset)
P2P 26656 36656
RPC 26657 36657
proxy_app 26658 36658
EVM JSON-RPC 8545 18545
WebSocket 8546 18546
REST API 1317 11317
gRPC 9090 19090
pprof 6060 16060
prometheus 26660 36660

Home Directories & Services

Aspect Testnet Mainnet
Chain ID integra-testnet-1 (EVM: 26218) integra-1 (EVM: 26217)
Home directory ~/.intgd (default) /root/.intgd-mainnet
Systemd service intgd.service intgd-mainnet.service

Network Topology

                    MAINNET (integra-1, EVM 26217)
                    ══════════════════════════════

  ┌────────────────┐     ┌────────────────┐     ┌────────────────┐
  │ mainnet-gateway│     │   signer-1     │     │   signer-2     │
  │  89.167.88.24  │◄───►│ 45.77.139.208  │◄───►│159.223.206.94  │
  │  P2P: 26656    │     │  P2P: 36656    │     │  P2P: 36656    │
  └───────┬────────┘     └───────┬────────┘     └───────┬────────┘
          │                      │                      │
          └──────────┬───────────┴──────────────────────┘
                     │
              ┌──────▼─────────┐
              │    archive     │
              │  3.208.92.57   │
              │  P2P: 26656    │
              └────────────────┘

Genesis Parameters

Token Distribution

Account IRL Amount airl Amount
Treasury 99,996,000,000 99996000000000000000000000000
Gateway validator 1,000,000 1000000000000000000000000
Signer-1 validator 1,000,000 1000000000000000000000000
Signer-2 validator 1,000,000 1000000000000000000000000
Archive validator 1,000,000 1000000000000000000000000
Total supply 100,000,000,000 100000000000000000000000000000

Chain Parameters

Parameter Value Notes
Chain ID integra-1
EVM Chain ID 26217 (0x6669)
Base fee 5000000000000 (5000 gwei) ~0.000005 IRL per gas unit
Min gas price 5000000000000 Matches base fee
Inflation 3% fixed min = max = 0.03, rate_change = 0
Unbonding 21 days (1,814,400s)
Max validators 100
Voting period 7 days Expedited: 3 days
Min deposit 100,000,000 IRL Expedited: 500,000,000 IRL
Quorum 33.4%
Community tax 0% Initially zero
Slash (double-sign) 5% Permanent tombstoning
Slash (downtime) 0.01% 10min jail
ERC20 registration Governance only permissionless_registration = false
goal_bonded 0.01 Must be >0 — SDK silently rejects 0.0

Public Endpoints

Mainnet (via Caddy on gateway)

Endpoint URL
RPC https://mainnet.integralayer.com/rpc
REST API https://mainnet.integralayer.com/api
EVM JSON-RPC https://mainnet.integralayer.com/evm
WebSocket wss://mainnet.integralayer.com/ws

Testnet (via Caddy on testnet-gateway)

Endpoint URL
RPC https://testnet.integralayer.com/rpc
REST API https://testnet.integralayer.com/api
EVM JSON-RPC https://testnet.integralayer.com/evm
WebSocket wss://testnet.integralayer.com/ws

SSH Quick Reference

# Mainnet gateway (Hetzner, dedicated)
ssh -i ~/.ssh/integra root@89.167.88.24

# Testnet gateway (Hetzner, dedicated)
ssh -i ~/.ssh/integra root@46.225.231.81

# Signer-1 (Vultr, shared — testnet + mainnet)
ssh -i ~/.ssh/integra root@45.77.139.208

# Signer-2 (DigitalOcean, shared — testnet + mainnet)
ssh -i ~/.ssh/integra root@159.223.206.94

# Archive (AWS — different SSH key, different user)
ssh -i ~/.ssh/integra-validator-key.pem ubuntu@3.208.92.57

Key Info

Item Value
Mainnet Chain ID integra-1
Mainnet EVM Chain ID 26217
Testnet Chain ID integra-testnet-1
Testnet EVM Chain ID 26218
Token IRL / airl (18 decimals)
Bech32 Prefix integra
Binary intgd (commit 0e6a388)
Binary MD5 9f9c240e0e9f12a04990034410625b84
Go version 1.23.8 linux/amd64
Cosmos SDK v0.53.5
Repo github.com/Integra-layer/integra-chain
Genesis SHA-256 4338fc44d971a677d84bc23e6d053d58a9fe7e9bff00136f3027ee18f14e2a10

Gentx Instructions (for Piyush)

Each gentx links one of Piyush's operator keys to the corresponding server's consensus key. Four validators = four separate signing ceremonies on the air-gapped machine, each output file transferred to USB, each verified, each sent back individually.

intgd genesis gentx <key-name> <STAKE_AMOUNT>airl \
  --chain-id integra-1 \
  --moniker "<validator-name>" \
  --commission-rate 0.05 \
  --commission-max-rate 0.20 \
  --commission-max-change-rate 0.01 \
  --gas-prices 5000000000000airl \
  --gas 200000 \
  --pubkey '<consensus-pubkey-json>' \
  --keyring-backend file

Warning

--gas-prices 5000000000000airl is mandatory. The genesis has a non-zero base fee by design — no free transactions from block 0. Without this flag, the gentx silently fails DeliverTx validation.

Note

Each validator has 1,000,000 IRL in genesis. The stake amount should leave some IRL in the account for gas fees. Example: staking 999,000 IRL leaves 1,000 IRL for operations.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment