mirror of
https://github.com/sonr-io/sonr.git
synced 2026-08-02 17:31:39 +00:00
Feat/add networks (#1303)
* No commit suggestions generated * No commit suggestions generated * No commit suggestions generated
This commit is contained in:
@@ -0,0 +1,17 @@
|
||||
CHAIN_ID=sonrtest_1-1
|
||||
DENOM=usnr
|
||||
KEYRING=test
|
||||
KEYALGO=eth_secp256k1
|
||||
BLOCK_TIME=5s
|
||||
VOTING_PERIOD=30s
|
||||
EXPEDITED_VOTING_PERIOD=15s
|
||||
MAX_GAS=100000000
|
||||
MIN_COMMISSION_RATE=0.050000000000000000
|
||||
NARUTO_MNEMONIC="decorate bright ozone fork gallery riot bus exhaust worth way bone indoor calm squirrel merry zero scheme cotton until shop any excess stage laundry"
|
||||
SENKU_MNEMONIC="wealth flavor believe regret funny network recall kiss grape useless pepper cram hint member few certain unveil rather brick bargain curious require crowd raise"
|
||||
YAEGER_MNEMONIC="quality vacuum heart guard buzz spike sight swarm shove special gym robust assume sudden deposit grid alcohol choice devote leader tilt noodle tide penalty"
|
||||
FAUCET_MNEMONIC="notice oak worry limit wrap speak medal online prefer cluster roof addict wrist behave treat actual wasp year salad speed social layer crew genius"
|
||||
BASE_ALLOCATION=100000000000000000000000000usnr
|
||||
STAKE_AMOUNT=30000000000000000000000usnr
|
||||
FAUCET_ALLOCATION=250000000000000000000000000000usnr
|
||||
DOCKER_IMAGE=onsonr/snrd:latest
|
||||
@@ -0,0 +1,106 @@
|
||||
name: sonr-core
|
||||
|
||||
services:
|
||||
ipfs:
|
||||
container_name: ipfs
|
||||
image: ipfs/kubo:release
|
||||
ports:
|
||||
- "127.0.0.1:5001:5001"
|
||||
- "127.0.0.1:8080:8080"
|
||||
- "127.0.0.1:4001:4001"
|
||||
volumes:
|
||||
- ${HOME}/.ipfs:/data/ipfs
|
||||
networks:
|
||||
- sonr-network
|
||||
|
||||
cluster:
|
||||
container_name: cluster
|
||||
image: ipfs/ipfs-cluster:latest
|
||||
depends_on:
|
||||
- ipfs
|
||||
environment:
|
||||
CLUSTER_PEERNAME: cluster
|
||||
CLUSTER_SECRET: 0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef
|
||||
CLUSTER_IPFSHTTP_NODEMULTIADDRESS: /dns4/ipfs/tcp/5001
|
||||
CLUSTER_CRDT_TRUSTEDPEERS: "*"
|
||||
CLUSTER_MONITORPINGINTERVAL: 2s
|
||||
ports:
|
||||
- "127.0.0.1:9094:9094"
|
||||
- "127.0.0.1:9095:9095"
|
||||
volumes:
|
||||
- ${HOME}/.ipfs-cluster:/data/ipfs-cluster
|
||||
networks:
|
||||
- sonr-network
|
||||
|
||||
caddy:
|
||||
container_name: caddy
|
||||
image: caddy:2-alpine
|
||||
restart: unless-stopped
|
||||
depends_on:
|
||||
snrd:
|
||||
condition: service_healthy
|
||||
ports:
|
||||
- "80:80"
|
||||
- "443:443"
|
||||
- "443:443/udp"
|
||||
volumes:
|
||||
- ./caddy/Caddyfile:/etc/caddy/Caddyfile:ro
|
||||
- caddy-data:/data
|
||||
- caddy-config:/config
|
||||
environment:
|
||||
CADDY_DOMAIN: ${CADDY_DOMAIN:-localhost}
|
||||
networks:
|
||||
- sonr-network
|
||||
|
||||
snrd:
|
||||
container_name: snrd
|
||||
image: onsonr/snrd:latest
|
||||
build:
|
||||
context: .
|
||||
dockerfile: cmd/snrd/Dockerfile
|
||||
restart: unless-stopped
|
||||
depends_on:
|
||||
- ipfs
|
||||
command: ["/usr/bin/devnet"]
|
||||
environment:
|
||||
CHAIN_ID: ${CHAIN_ID:-sonrtest_1-1}
|
||||
MONIKER: ${MONIKER:-sonr-dev-node}
|
||||
DENOM: ${DENOM:-usnr}
|
||||
BLOCK_TIME: ${BLOCK_TIME:-1s}
|
||||
CLEAN: ${CLEAN:-true}
|
||||
KEYRING: ${KEYRING:-test}
|
||||
HOME_DIR: /home/snrd/.snrd
|
||||
KEY: acc0
|
||||
KEY2: acc1
|
||||
KEYALGO: eth_secp256k1
|
||||
LOG_LEVEL: ${LOG_LEVEL:-debug}
|
||||
TRACE: ${TRACE:-true}
|
||||
SKIP_INSTALL: "true"
|
||||
ports:
|
||||
- "26657:26657"
|
||||
- "1317:1317"
|
||||
- "9090:9090"
|
||||
- "9091:9091"
|
||||
- "8545:8545"
|
||||
- "8546:8546"
|
||||
- "26656:26656"
|
||||
- "6060:6060"
|
||||
volumes:
|
||||
- ${HOME}/.sonr:/root/.sonr
|
||||
healthcheck:
|
||||
test: ["CMD", "snrd", "status", "--home", "/home/snrd/.snrd"]
|
||||
interval: 10s
|
||||
timeout: 5s
|
||||
retries: 5
|
||||
start_period: 60s
|
||||
networks:
|
||||
- sonr-network
|
||||
|
||||
networks:
|
||||
sonr-network:
|
||||
driver: bridge
|
||||
name: sonr-network
|
||||
|
||||
volumes:
|
||||
caddy-config:
|
||||
caddy-data:
|
||||
@@ -0,0 +1,17 @@
|
||||
CHAIN_ID=sonrtest_1-1
|
||||
DENOM=usnr
|
||||
KEYRING=test
|
||||
KEYALGO=eth_secp256k1
|
||||
BLOCK_TIME=5s
|
||||
VOTING_PERIOD=30s
|
||||
EXPEDITED_VOTING_PERIOD=15s
|
||||
MAX_GAS=100000000
|
||||
MIN_COMMISSION_RATE=0.050000000000000000
|
||||
NARUTO_MNEMONIC="decorate bright ozone fork gallery riot bus exhaust worth way bone indoor calm squirrel merry zero scheme cotton until shop any excess stage laundry"
|
||||
SENKU_MNEMONIC="wealth flavor believe regret funny network recall kiss grape useless pepper cram hint member few certain unveil rather brick bargain curious require crowd raise"
|
||||
YAEGER_MNEMONIC="quality vacuum heart guard buzz spike sight swarm shove special gym robust assume sudden deposit grid alcohol choice devote leader tilt noodle tide penalty"
|
||||
FAUCET_MNEMONIC="notice oak worry limit wrap speak medal online prefer cluster roof addict wrist behave treat actual wasp year salad speed social layer crew genius"
|
||||
BASE_ALLOCATION=100000000000000000000000000usnr
|
||||
STAKE_AMOUNT=30000000000000000000000usnr
|
||||
FAUCET_ALLOCATION=250000000000000000000000000000usnr
|
||||
DOCKER_IMAGE=onsonr/snrd:latest
|
||||
@@ -0,0 +1,591 @@
|
||||
# Docker Containers
|
||||
|
||||
This document describes all Docker containers used in the Sonr testnet architecture.
|
||||
|
||||
## Overview
|
||||
|
||||
The testnet consists of 7 containers organized in a validator-sentry architecture:
|
||||
- **3 Validators** (private, isolated networks)
|
||||
- **3 Sentry Nodes** (public-facing, Cloudflare tunnel integration)
|
||||
- **1 IPFS Node** (distributed storage)
|
||||
|
||||
All containers use the `unless-stopped` restart policy for resilience.
|
||||
|
||||
---
|
||||
|
||||
## Container Architecture
|
||||
|
||||
```
|
||||
┌─────────────────────────────────────────────────────────┐
|
||||
│ Cloudflare Tunnel (DockFlare) │
|
||||
└────────────────────┬────────────────────────────────────┘
|
||||
│
|
||||
┌────────────────┴────────────────────┐
|
||||
│ net-public + cloudflare-net │
|
||||
│ │
|
||||
│ ┌──────────┐ ┌──────────┐ ┌──────────┐ ┌──────┐
|
||||
│ │ sentry- │ │ sentry- │ │ sentry- │ │ IPFS │
|
||||
│ │ alice │◄─► bob │◄─► carol │ │ │
|
||||
│ └────┬─────┘ └────┬─────┘ └────┬─────┘ └──────┘
|
||||
└───────┼─────────────┼─────────────┼─────────────────┘
|
||||
│ │ │
|
||||
│ private │ private │ private
|
||||
│ │ │
|
||||
┌───────▼──────┐ ┌────▼──────┐ ┌────▼──────┐
|
||||
│ val-alice │ │ val-bob │ │ val-carol │
|
||||
│ (net-alice) │ │ (net-bob) │ │(net-carol)│
|
||||
└──────────────┘ └───────────┘ └───────────┘
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Validator Containers
|
||||
|
||||
Validators are the core consensus nodes that produce blocks and maintain blockchain state. They are isolated on private networks for security.
|
||||
|
||||
### val-alice
|
||||
|
||||
**Purpose:** Alice's validator node
|
||||
**Image:** `onsonr/snrd:latest`
|
||||
**Network:** `net-alice` (private)
|
||||
**Volume:** `./val-alice:/root/.sonr`
|
||||
|
||||
**Configuration:**
|
||||
- **Chain ID:** `sonrtest_1-1`
|
||||
- **Moniker:** `val-alice`
|
||||
- **Pruning:** Disabled (`--pruning=nothing`)
|
||||
- **Min Gas Prices:** `0usnr` (free for testnet)
|
||||
|
||||
**Security Features:**
|
||||
- Runs on isolated private network
|
||||
- Only connects to its own sentry (`sentry-alice`)
|
||||
- No direct public access
|
||||
- Protected by sentry's `private_peer_ids` configuration
|
||||
|
||||
**Data Directory:**
|
||||
```
|
||||
./val-alice/
|
||||
├── config/
|
||||
│ ├── genesis.json # Genesis state
|
||||
│ ├── config.toml # Tendermint config
|
||||
│ ├── app.toml # Application config
|
||||
│ └── priv_validator_key.json # Validator signing key (CRITICAL!)
|
||||
└── data/ # Blockchain data
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### val-bob
|
||||
|
||||
**Purpose:** Bob's validator node
|
||||
**Image:** `onsonr/snrd:latest`
|
||||
**Network:** `net-bob` (private)
|
||||
**Volume:** `./val-bob:/root/.sonr`
|
||||
|
||||
**Configuration:**
|
||||
- **Chain ID:** `sonrtest_1-1`
|
||||
- **Moniker:** `val-bob`
|
||||
- **Pruning:** Disabled
|
||||
- **Min Gas Prices:** `0usnr`
|
||||
|
||||
**Security:** Same as val-alice, isolated on `net-bob`
|
||||
|
||||
---
|
||||
|
||||
### val-carol
|
||||
|
||||
**Purpose:** Carol's validator node
|
||||
**Image:** `onsonr/snrd:latest`
|
||||
**Network:** `net-carol` (private)
|
||||
**Volume:** `./val-carol:/root/.sonr`
|
||||
|
||||
**Configuration:**
|
||||
- **Chain ID:** `sonrtest_1-1`
|
||||
- **Moniker:** `val-carol`
|
||||
- **Pruning:** Disabled
|
||||
- **Min Gas Prices:** `0usnr`
|
||||
|
||||
**Security:** Same as val-alice, isolated on `net-carol`
|
||||
|
||||
---
|
||||
|
||||
## Sentry Containers
|
||||
|
||||
Sentry nodes act as a protective layer between validators and the public internet. They handle all public RPC, REST, gRPC, and EVM requests while shielding validator identities.
|
||||
|
||||
### sentry-alice
|
||||
|
||||
**Purpose:** Alice's public-facing sentry node
|
||||
**Image:** `onsonr/snrd:latest`
|
||||
**Networks:**
|
||||
- `net-alice` (connects to val-alice)
|
||||
- `net-public` (connects to other sentries)
|
||||
- `cloudflare-net` (for DockFlare tunnels)
|
||||
|
||||
**Volume:** `./sentry-alice:/root/.sonr`
|
||||
**Depends On:** `val-alice`
|
||||
|
||||
**Configuration:**
|
||||
- **Chain ID:** `sonrtest_1-1`
|
||||
- **Moniker:** `sentry-alice`
|
||||
- **Pruning:** Disabled
|
||||
- **Min Gas Prices:** `0usnr`
|
||||
|
||||
**Exposed Services:**
|
||||
- **RPC:** Port 26657 (Tendermint RPC)
|
||||
- **REST:** Port 1317 (Cosmos REST API)
|
||||
- **gRPC:** Port 9090 (gRPC endpoint)
|
||||
- **EVM JSON-RPC:** Port 8545 (Ethereum-compatible)
|
||||
- **EVM WebSocket:** Port 8546 (WebSocket subscriptions)
|
||||
|
||||
**JSON-RPC APIs Enabled:**
|
||||
- `eth` - Ethereum JSON-RPC
|
||||
- `txpool` - Transaction pool inspection
|
||||
- `personal` - Account management
|
||||
- `net` - Network info
|
||||
- `debug` - Debugging APIs
|
||||
- `web3` - Web3 utilities
|
||||
|
||||
**Cloudflare Tunnel Endpoints:**
|
||||
|
||||
| Endpoint | Hostname | Internal Service | Description |
|
||||
|----------|----------|------------------|-------------|
|
||||
| RPC | `alice-rpc.sonr.land` | `http://sentry-alice:26657` | Tendermint RPC for queries and transactions |
|
||||
| REST | `alice-rest.sonr.land` | `http://sentry-alice:1317` | Cosmos REST API (LCD) |
|
||||
| gRPC | `alice-grpc.sonr.land` | `http://sentry-alice:9090` | gRPC for efficient binary communication |
|
||||
| EVM | `alice-evm.sonr.land` | `http://sentry-alice:8545` | EVM JSON-RPC (MetaMask compatible) |
|
||||
|
||||
**Peer Connections:**
|
||||
- **Persistent Peer:** `val-alice` (private connection)
|
||||
- **Seeds:** `sentry-bob`, `sentry-carol` (public P2P)
|
||||
- **Private Peer IDs:** Marks `val-alice` as private to hide from network
|
||||
|
||||
**Security Features:**
|
||||
- Shields validator from direct exposure
|
||||
- Handles all public-facing traffic
|
||||
- Rate limiting and DDoS protection via Cloudflare
|
||||
- TLS encryption via Cloudflare tunnels
|
||||
|
||||
---
|
||||
|
||||
### sentry-bob
|
||||
|
||||
**Purpose:** Bob's public-facing sentry node
|
||||
**Image:** `onsonr/snrd:latest`
|
||||
**Networks:** `net-bob`, `net-public`, `cloudflare-net`
|
||||
**Volume:** `./sentry-bob:/root/.sonr`
|
||||
**Depends On:** `val-bob`
|
||||
|
||||
**Configuration:** Same as sentry-alice, with moniker `sentry-bob`
|
||||
|
||||
**Cloudflare Tunnel Endpoints:**
|
||||
- `bob-rpc.sonr.land` → RPC (26657)
|
||||
- `bob-rest.sonr.land` → REST (1317)
|
||||
- `bob-grpc.sonr.land` → gRPC (9090)
|
||||
- `bob-evm.sonr.land` → EVM JSON-RPC (8545)
|
||||
|
||||
**Peer Connections:**
|
||||
- **Persistent Peer:** `val-bob`
|
||||
- **Seeds:** `sentry-alice`, `sentry-carol`
|
||||
|
||||
---
|
||||
|
||||
### sentry-carol
|
||||
|
||||
**Purpose:** Carol's public-facing sentry node
|
||||
**Image:** `onsonr/snrd:latest`
|
||||
**Networks:** `net-carol`, `net-public`, `cloudflare-net`
|
||||
**Volume:** `./sentry-carol:/root/.sonr`
|
||||
**Depends On:** `val-carol`
|
||||
|
||||
**Configuration:** Same as sentry-alice, with moniker `sentry-carol`
|
||||
|
||||
**Cloudflare Tunnel Endpoints:**
|
||||
- `carol-rpc.sonr.land` → RPC (26657)
|
||||
- `carol-rest.sonr.land` → REST (1317)
|
||||
- `carol-grpc.sonr.land` → gRPC (9090)
|
||||
- `carol-evm.sonr.land` → EVM JSON-RPC (8545)
|
||||
|
||||
**Peer Connections:**
|
||||
- **Persistent Peer:** `val-carol`
|
||||
- **Seeds:** `sentry-alice`, `sentry-bob`
|
||||
|
||||
---
|
||||
|
||||
## IPFS Container
|
||||
|
||||
### ipfsctl
|
||||
|
||||
**Purpose:** Distributed file storage and content addressing
|
||||
**Image:** `ipfs/kubo:latest` (official IPFS implementation)
|
||||
**Networks:**
|
||||
- `net-public` (connects to sentry nodes)
|
||||
- `cloudflare-net` (for DockFlare tunnels)
|
||||
|
||||
**Volume:** `ipfs-data:/data/ipfs` (named volume)
|
||||
|
||||
**Configuration:**
|
||||
- **IPFS Profile:** `server` (optimized for server deployment)
|
||||
|
||||
**Exposed Services:**
|
||||
- **API:** Port 5001 (IPFS HTTP API)
|
||||
- **Gateway:** Port 8080 (IPFS Gateway for content retrieval)
|
||||
- **Swarm:** Port 4001 (P2P networking)
|
||||
|
||||
**Cloudflare Tunnel Endpoints:**
|
||||
|
||||
| Endpoint | Hostname | Internal Service | Description |
|
||||
|----------|----------|------------------|-------------|
|
||||
| API | `ipfs-api.sonr.land` | `http://ipfsctl:5001` | IPFS API for adding/pinning content |
|
||||
| Gateway | `ipfs-gateway.sonr.land` | `http://ipfsctl:8080` | HTTP gateway for retrieving content |
|
||||
|
||||
**Features:**
|
||||
- **Content-Addressed Storage:** Files identified by cryptographic hash (CID)
|
||||
- **Distributed Network:** Connects to global IPFS network
|
||||
- **Persistent Storage:** Data stored in named volume
|
||||
- **HTTP API:** RESTful API for programmatic access
|
||||
- **Gateway Access:** Retrieve content via HTTP using CID
|
||||
|
||||
**Common Operations:**
|
||||
|
||||
```bash
|
||||
# Add file to IPFS
|
||||
curl -X POST -F file=@myfile.txt https://ipfs-api.sonr.land/api/v0/add
|
||||
|
||||
# Retrieve file by CID
|
||||
curl https://ipfs-gateway.sonr.land/ipfs/QmYwAPJzv5CZsnA625s3Xf2nemtYgPpHdWEz79ojWnPbdG/readme
|
||||
|
||||
# Check version
|
||||
curl -X POST https://ipfs-api.sonr.land/api/v0/version | jq
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Network Topology
|
||||
|
||||
### Private Networks
|
||||
|
||||
Each validator has its own isolated network:
|
||||
|
||||
| Network | Purpose | Containers |
|
||||
|---------|---------|------------|
|
||||
| `net-alice` | Alice validator isolation | `val-alice`, `sentry-alice` |
|
||||
| `net-bob` | Bob validator isolation | `val-bob`, `sentry-bob` |
|
||||
| `net-carol` | Carol validator isolation | `val-carol`, `sentry-carol` |
|
||||
|
||||
**Security Benefits:**
|
||||
- Validators cannot directly communicate with each other
|
||||
- Prevents Byzantine attacks at network layer
|
||||
- Forces all communication through sentries
|
||||
|
||||
### Public Network
|
||||
|
||||
| Network | Purpose | Containers |
|
||||
|---------|---------|------------|
|
||||
| `net-public` | Sentry interconnection | `sentry-alice`, `sentry-bob`, `sentry-carol`, `ipfsctl` |
|
||||
|
||||
**Purpose:**
|
||||
- Sentries discover and connect to each other
|
||||
- IPFS accessible to all sentries
|
||||
- Public P2P gossip network
|
||||
|
||||
### Cloudflare Network
|
||||
|
||||
| Network | Purpose | Containers |
|
||||
|---------|---------|------------|
|
||||
| `cloudflare-net` | DockFlare tunnel access | `sentry-alice`, `sentry-bob`, `sentry-carol`, `ipfsctl` |
|
||||
|
||||
**Type:** External (must be created before starting stack)
|
||||
**Purpose:** Allows DockFlare to discover and tunnel traffic to containers
|
||||
|
||||
**Setup:**
|
||||
```bash
|
||||
docker network create cloudflare-net
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Volume Management
|
||||
|
||||
### Bind Mounts (Validators & Sentries)
|
||||
|
||||
```
|
||||
./val-alice:/root/.sonr
|
||||
./val-bob:/root/.sonr
|
||||
./val-carol:/root/.sonr
|
||||
./sentry-alice:/root/.sonr
|
||||
./sentry-bob:/root/.sonr
|
||||
./sentry-carol:/root/.sonr
|
||||
```
|
||||
|
||||
**Advantages:**
|
||||
- Direct file system access from host
|
||||
- Easy backup and inspection
|
||||
- No permission issues (files owned by host user)
|
||||
|
||||
**Backup:**
|
||||
```bash
|
||||
tar -czf testnet-backup.tar.gz val-* sentry-*
|
||||
```
|
||||
|
||||
### Named Volume (IPFS)
|
||||
|
||||
```
|
||||
ipfs-data:/data/ipfs
|
||||
```
|
||||
|
||||
**Advantages:**
|
||||
- Managed by Docker
|
||||
- Better performance on some systems
|
||||
- Automatic cleanup with `docker compose down -v`
|
||||
|
||||
**Backup:**
|
||||
```bash
|
||||
docker run --rm -v ipfs-data:/data -v $(pwd):/backup alpine tar czf /backup/ipfs-backup.tar.gz /data
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Container Management
|
||||
|
||||
### Start All Containers
|
||||
```bash
|
||||
make start
|
||||
# or
|
||||
docker compose up -d
|
||||
```
|
||||
|
||||
### Stop All Containers
|
||||
```bash
|
||||
make stop
|
||||
# or
|
||||
docker compose down
|
||||
```
|
||||
|
||||
### View Container Logs
|
||||
```bash
|
||||
# All containers
|
||||
docker compose logs -f
|
||||
|
||||
# Specific container
|
||||
docker compose logs -f sentry-alice
|
||||
|
||||
# Last 100 lines
|
||||
docker compose logs --tail=100 val-alice
|
||||
```
|
||||
|
||||
### Execute Commands in Containers
|
||||
```bash
|
||||
# Via bootstrap script
|
||||
devbox run exec sentry-alice status
|
||||
|
||||
# Via docker compose
|
||||
docker compose exec sentry-alice snrd status --home /root/.sonr
|
||||
|
||||
# Via docker
|
||||
docker exec -it sentry-alice snrd keys list --keyring-backend test
|
||||
```
|
||||
|
||||
### Inspect Container Configuration
|
||||
```bash
|
||||
# View environment variables
|
||||
docker inspect sentry-alice -f '{{json .Config.Env}}' | jq
|
||||
|
||||
# View networks
|
||||
docker inspect sentry-alice -f '{{json .NetworkSettings.Networks}}' | jq
|
||||
|
||||
# View mounts
|
||||
docker inspect sentry-alice -f '{{json .Mounts}}' | jq
|
||||
```
|
||||
|
||||
### Resource Usage
|
||||
```bash
|
||||
# Real-time stats
|
||||
docker stats
|
||||
|
||||
# Container resource limits (if set)
|
||||
docker inspect sentry-alice -f '{{json .HostConfig.Memory}}' | jq
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Health Checks
|
||||
|
||||
### Container Status
|
||||
```bash
|
||||
docker ps --filter "name=val-" --filter "name=sentry-" --filter "name=ipfs"
|
||||
```
|
||||
|
||||
### Node Sync Status
|
||||
```bash
|
||||
# Check if nodes are syncing
|
||||
for container in sentry-alice sentry-bob sentry-carol; do
|
||||
echo "=== $container ==="
|
||||
docker exec $container sh -c 'curl -s http://localhost:26657/status | jq -r ".result.sync_info.catching_up"'
|
||||
done
|
||||
```
|
||||
|
||||
### Block Height
|
||||
```bash
|
||||
# Current block height
|
||||
docker exec sentry-alice sh -c 'curl -s http://localhost:26657/status | jq -r ".result.sync_info.latest_block_height"'
|
||||
```
|
||||
|
||||
### IPFS Health
|
||||
```bash
|
||||
# Check IPFS daemon
|
||||
curl -X POST https://ipfs-api.sonr.land/api/v0/version | jq
|
||||
|
||||
# Check connected peers
|
||||
curl -X POST https://ipfs-api.sonr.land/api/v0/swarm/peers | jq
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Security Considerations
|
||||
|
||||
### Validator Security
|
||||
1. **Never expose validators directly** - Always use sentries
|
||||
2. **Backup `priv_validator_key.json`** - Cannot be recovered if lost
|
||||
3. **Monitor validator uptime** - Downtime results in slashing
|
||||
4. **Use KMS in production** - Hardware security modules for key management
|
||||
|
||||
### Sentry Security
|
||||
1. **Rate limiting via Cloudflare** - Protects against DDoS
|
||||
2. **TLS encryption** - All traffic encrypted via Cloudflare tunnels
|
||||
3. **No exposed ports** - All access via tunnels only
|
||||
4. **Regular updates** - Keep `onsonr/snrd` image updated
|
||||
|
||||
### IPFS Security
|
||||
1. **Content verification** - All content verified by CID
|
||||
2. **No private data** - IPFS is a public network
|
||||
3. **Pin important content** - Prevent garbage collection
|
||||
4. **Monitor storage** - IPFS can grow large over time
|
||||
|
||||
---
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
### Container Won't Start
|
||||
```bash
|
||||
# Check logs
|
||||
docker compose logs <container-name>
|
||||
|
||||
# Check resource usage
|
||||
docker stats
|
||||
|
||||
# Verify networks exist
|
||||
docker network ls | grep -E "net-|cloudflare"
|
||||
|
||||
# Recreate container
|
||||
docker compose up -d --force-recreate <container-name>
|
||||
```
|
||||
|
||||
### Permission Issues
|
||||
```bash
|
||||
# Fix ownership (if needed)
|
||||
sudo chown -R $USER:$USER val-* sentry-*
|
||||
|
||||
# Check bind mount permissions
|
||||
ls -la val-alice/
|
||||
```
|
||||
|
||||
### Network Connectivity Issues
|
||||
```bash
|
||||
# Test connectivity between containers
|
||||
docker exec sentry-alice ping -c 3 val-alice
|
||||
docker exec sentry-alice ping -c 3 sentry-bob
|
||||
|
||||
# Check network configuration
|
||||
docker network inspect net-public
|
||||
```
|
||||
|
||||
### IPFS Issues
|
||||
```bash
|
||||
# Check IPFS daemon status
|
||||
docker compose logs ipfsctl
|
||||
|
||||
# Restart IPFS
|
||||
docker compose restart ipfsctl
|
||||
|
||||
# Clear IPFS cache (WARNING: destructive)
|
||||
docker compose down
|
||||
docker volume rm testnet_ipfs-data
|
||||
docker compose up -d
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Performance Tuning
|
||||
|
||||
### Resource Limits (Optional)
|
||||
|
||||
Add to `docker-compose.yml`:
|
||||
|
||||
```yaml
|
||||
services:
|
||||
val-alice:
|
||||
deploy:
|
||||
resources:
|
||||
limits:
|
||||
cpus: '2.0'
|
||||
memory: 4G
|
||||
reservations:
|
||||
cpus: '1.0'
|
||||
memory: 2G
|
||||
```
|
||||
|
||||
### Logging Configuration
|
||||
|
||||
Prevent log bloat:
|
||||
|
||||
```yaml
|
||||
services:
|
||||
val-alice:
|
||||
logging:
|
||||
driver: "json-file"
|
||||
options:
|
||||
max-size: "100m"
|
||||
max-file: "3"
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Maintenance
|
||||
|
||||
### Update Containers
|
||||
```bash
|
||||
# Pull latest images
|
||||
docker compose pull
|
||||
|
||||
# Restart with new images
|
||||
docker compose up -d
|
||||
```
|
||||
|
||||
### Clean Up
|
||||
```bash
|
||||
# Remove stopped containers
|
||||
docker compose down
|
||||
|
||||
# Remove all data (WARNING: destructive)
|
||||
docker compose down -v
|
||||
|
||||
# Clean Docker system
|
||||
docker system prune -a
|
||||
```
|
||||
|
||||
### Backup Procedure
|
||||
```bash
|
||||
# Stop containers
|
||||
make stop
|
||||
|
||||
# Backup data
|
||||
tar -czf testnet-backup-$(date +%Y%m%d).tar.gz val-* sentry-* .env
|
||||
|
||||
# Backup IPFS volume
|
||||
docker run --rm -v testnet_ipfs-data:/data -v $(pwd):/backup \
|
||||
alpine tar czf /backup/ipfs-backup-$(date +%Y%m%d).tar.gz /data
|
||||
|
||||
# Restart containers
|
||||
make start
|
||||
```
|
||||
@@ -0,0 +1,247 @@
|
||||
# Environment Variables
|
||||
|
||||
This document describes all environment variables that can be configured for the Sonr testnet.
|
||||
|
||||
## Configuration File
|
||||
|
||||
All variables are defined in `.env` file in the repository root. Copy `.env.example` to `.env` and customize:
|
||||
|
||||
```bash
|
||||
cp .env.example .env
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Global Configuration
|
||||
|
||||
These variables are used during initialization and apply to all services.
|
||||
|
||||
### Chain Configuration
|
||||
|
||||
| Variable | Default | Description |
|
||||
|----------|---------|-------------|
|
||||
| `CHAIN_ID` | `sonrtest_1-1` | Blockchain chain identifier |
|
||||
| `DENOM` | `usnr` | Base denomination for the native token |
|
||||
| `KEYRING` | `test` | Keyring backend (test, file, os) |
|
||||
| `KEYALGO` | `eth_secp256k1` | Key algorithm for validator keys |
|
||||
|
||||
### Network Parameters
|
||||
|
||||
| Variable | Default | Description |
|
||||
|----------|---------|-------------|
|
||||
| `BLOCK_TIME` | `5s` | Target block time |
|
||||
| `VOTING_PERIOD` | `30s` | Governance proposal voting period |
|
||||
| `EXPEDITED_VOTING_PERIOD` | `15s` | Expedited proposal voting period |
|
||||
| `MAX_GAS` | `100000000` | Maximum gas per block |
|
||||
| `MIN_COMMISSION_RATE` | `0.050000000000000000` | Minimum validator commission rate (5%) |
|
||||
|
||||
### Validator Mnemonics
|
||||
|
||||
**⚠️ WARNING**: Change these for production! Default mnemonics are public.
|
||||
|
||||
| Variable | Description |
|
||||
|----------|-------------|
|
||||
| `ALICE_MNEMONIC` | 24-word mnemonic for Alice validator |
|
||||
| `BOB_MNEMONIC` | 24-word mnemonic for Bob validator |
|
||||
| `CAROL_MNEMONIC` | 24-word mnemonic for Carol validator |
|
||||
| `FAUCET_MNEMONIC` | 24-word mnemonic for faucet account |
|
||||
|
||||
### Initial Balances
|
||||
|
||||
| Variable | Default | Description |
|
||||
|----------|---------|-------------|
|
||||
| `BASE_ALLOCATION` | `100000000000000000000000000usnr` | Base allocation per validator (100M SNR) |
|
||||
| `STAKE_AMOUNT` | `30000000000000000000000usnr` | Initial stake per validator (30M SNR) |
|
||||
| `FAUCET_ALLOCATION` | `250000000000000000000000000000usnr` | Faucet account balance (250M SNR) |
|
||||
|
||||
### Docker Configuration
|
||||
|
||||
| Variable | Default | Description |
|
||||
|----------|---------|-------------|
|
||||
| `DOCKER_IMAGE` | `onsonr/snrd:latest` | Docker image for validator and sentry nodes |
|
||||
|
||||
---
|
||||
|
||||
## Container-Specific Variables
|
||||
|
||||
These variables are set in `docker-compose.yml` for each container.
|
||||
|
||||
### Validators (val-alice, val-bob, val-carol)
|
||||
|
||||
All validators share the same environment variables but with different values:
|
||||
|
||||
| Variable | Value | Description |
|
||||
|----------|-------|-------------|
|
||||
| `CHAIN_ID` | `sonrtest_1-1` | Chain identifier (same for all) |
|
||||
| `MONIKER` | `val-{name}` | Validator node name (val-alice, val-bob, val-carol) |
|
||||
|
||||
**Command-line flags:**
|
||||
- `--home /root/.sonr` - Node home directory
|
||||
- `--pruning=nothing` - Disable state pruning
|
||||
- `--minimum-gas-prices=0usnr` - Minimum gas price (0 for testnet)
|
||||
- `--chain-id=sonrtest_1-1` - Chain identifier
|
||||
|
||||
**Networks:**
|
||||
- Private network: `net-{name}` (net-alice, net-bob, net-carol)
|
||||
|
||||
**Volumes:**
|
||||
- `./val-{name}:/root/.sonr` - Bind mount for node data
|
||||
|
||||
---
|
||||
|
||||
### Sentries (sentry-alice, sentry-bob, sentry-carol)
|
||||
|
||||
All sentries share the same environment variables but with different values:
|
||||
|
||||
| Variable | Value | Description |
|
||||
|----------|-------|-------------|
|
||||
| `CHAIN_ID` | `sonrtest_1-1` | Chain identifier (same for all) |
|
||||
| `MONIKER` | `sentry-{name}` | Sentry node name (sentry-alice, sentry-bob, sentry-carol) |
|
||||
|
||||
**Command-line flags:**
|
||||
- `--home /root/.sonr` - Node home directory
|
||||
- `--pruning=nothing` - Disable state pruning
|
||||
- `--minimum-gas-prices=0usnr` - Minimum gas price (0 for testnet)
|
||||
- `--rpc.laddr=tcp://0.0.0.0:26657` - RPC listen address
|
||||
- `--json-rpc.api=eth,txpool,personal,net,debug,web3` - Enabled JSON-RPC APIs
|
||||
- `--json-rpc.address=0.0.0.0:8545` - EVM JSON-RPC address
|
||||
- `--json-rpc.ws-address=0.0.0.0:8546` - EVM WebSocket address
|
||||
- `--chain-id=sonrtest_1-1` - Chain identifier
|
||||
|
||||
**Networks:**
|
||||
- Private network: `net-{name}` (connects to validator)
|
||||
- `net-public` (connects to other sentries)
|
||||
- `cloudflare-net` (for DockFlare tunnels)
|
||||
|
||||
**Volumes:**
|
||||
- `./sentry-{name}:/root/.sonr` - Bind mount for node data
|
||||
|
||||
**DockFlare Labels (indexed):**
|
||||
|
||||
Each sentry exposes 4 endpoints via Cloudflare tunnels:
|
||||
|
||||
| Index | Hostname Pattern | Service | Description |
|
||||
|-------|------------------|---------|-------------|
|
||||
| `0` | `{name}-rpc.sonr.land` | `http://sentry-{name}:26657` | Tendermint RPC |
|
||||
| `1` | `{name}-rest.sonr.land` | `http://sentry-{name}:1317` | Cosmos REST API |
|
||||
| `2` | `{name}-grpc.sonr.land` | `http://sentry-{name}:9090` | gRPC endpoint |
|
||||
| `3` | `{name}-evm.sonr.land` | `http://sentry-{name}:8545` | EVM JSON-RPC |
|
||||
|
||||
**Example for sentry-alice:**
|
||||
```yaml
|
||||
labels:
|
||||
- "dockflare.enable=true"
|
||||
- "dockflare.0.hostname=alice-rpc.sonr.land"
|
||||
- "dockflare.0.service=http://sentry-alice:26657"
|
||||
- "dockflare.1.hostname=alice-rest.sonr.land"
|
||||
- "dockflare.1.service=http://sentry-alice:1317"
|
||||
- "dockflare.2.hostname=alice-grpc.sonr.land"
|
||||
- "dockflare.2.service=http://sentry-alice:9090"
|
||||
- "dockflare.3.hostname=alice-evm.sonr.land"
|
||||
- "dockflare.3.service=http://sentry-alice:8545"
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### IPFS (ipfsctl)
|
||||
|
||||
| Variable | Value | Description |
|
||||
|----------|-------|-------------|
|
||||
| `IPFS_PROFILE` | `server` | IPFS configuration profile for server mode |
|
||||
|
||||
**Networks:**
|
||||
- `net-public` (connects to sentries)
|
||||
- `cloudflare-net` (for DockFlare tunnels)
|
||||
|
||||
**Volumes:**
|
||||
- `ipfs-data:/data/ipfs` - Named volume for IPFS data
|
||||
|
||||
**DockFlare Labels:**
|
||||
|
||||
| Index | Hostname | Service | Description |
|
||||
|-------|----------|---------|-------------|
|
||||
| `0` | `ipfs-api.sonr.land` | `http://ipfsctl:5001` | IPFS API endpoint |
|
||||
| `1` | `ipfs-gateway.sonr.land` | `http://ipfsctl:8080` | IPFS Gateway |
|
||||
|
||||
---
|
||||
|
||||
## DockFlare Configuration
|
||||
|
||||
DockFlare requires the following environment variables (not in `.env`, set when running DockFlare container):
|
||||
|
||||
| Variable | Required | Description |
|
||||
|----------|----------|-------------|
|
||||
| `CLOUDFLARE_API_TOKEN` | ✅ Yes | Cloudflare API token with Tunnel:Edit, DNS:Edit, Zone:Read permissions |
|
||||
| `CLOUDFLARE_ACCOUNT_ID` | ⚠️ Recommended | Cloudflare account ID (found in dashboard) |
|
||||
| `CLOUDFLARE_ZONE_ID` | ⚠️ Recommended | Cloudflare zone ID for domain (found in dashboard) |
|
||||
|
||||
**Example DockFlare Setup:**
|
||||
```bash
|
||||
docker run -d \
|
||||
--name dockflare \
|
||||
--restart unless-stopped \
|
||||
--network cloudflare-net \
|
||||
-v /var/run/docker.sock:/var/run/docker.sock \
|
||||
-e CLOUDFLARE_API_TOKEN=your_token_here \
|
||||
-e CLOUDFLARE_ACCOUNT_ID=your_account_id \
|
||||
-e CLOUDFLARE_ZONE_ID=your_zone_id \
|
||||
ghcr.io/sonr-io/dockflare:latest
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Runtime Overrides
|
||||
|
||||
You can override specific values at runtime by modifying `docker-compose.yml` or passing environment variables:
|
||||
|
||||
### Override Docker Image
|
||||
```bash
|
||||
export DOCKER_IMAGE=onsonr/snrd:v1.2.3
|
||||
make start
|
||||
```
|
||||
|
||||
### Override Chain ID
|
||||
Edit `docker-compose.yml` and change all instances of:
|
||||
```yaml
|
||||
environment:
|
||||
- CHAIN_ID=your-custom-chain-id
|
||||
```
|
||||
|
||||
And update command flags:
|
||||
```yaml
|
||||
command: >
|
||||
snrd start
|
||||
...
|
||||
--chain-id=your-custom-chain-id
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Security Best Practices
|
||||
|
||||
1. **Never commit `.env` to version control** - It's already in `.gitignore`
|
||||
2. **Generate new mnemonics for production**:
|
||||
```bash
|
||||
snrd keys add test --keyring-backend test --output json | jq -r .mnemonic
|
||||
```
|
||||
3. **Use KMS for production validator keys** (e.g., tmkms)
|
||||
4. **Rotate Cloudflare API tokens** regularly
|
||||
5. **Use strong passwords** if switching from `test` keyring to `file` or `os`
|
||||
6. **Backup mnemonics securely** - They cannot be recovered if lost
|
||||
|
||||
---
|
||||
|
||||
## Verification
|
||||
|
||||
After configuration, verify your setup:
|
||||
|
||||
```bash
|
||||
# Check .env is loaded
|
||||
make status
|
||||
|
||||
# Test endpoints
|
||||
make test
|
||||
|
||||
# View container environment
|
||||
docker inspect sentry-alice -f '{{json .Config.Env}}' | jq
|
||||
```
|
||||
@@ -0,0 +1,66 @@
|
||||
# Sonr Testnet Makefile
|
||||
.PHONY: help all init start stop restart clean status logs test setup
|
||||
|
||||
# Default target
|
||||
.DEFAULT_GOAL := help
|
||||
|
||||
# Help target
|
||||
help:
|
||||
@echo "Sonr Testnet Management (via Devbox)"
|
||||
@echo ""
|
||||
@echo "Setup:"
|
||||
@echo " make all - Check/install devbox"
|
||||
@echo ""
|
||||
@echo "Testnet Operations:"
|
||||
@echo " make setup - Create .env from template"
|
||||
@echo " make init - Initialize validators and sentries"
|
||||
@echo " make start - Start testnet"
|
||||
@echo " make stop - Stop testnet"
|
||||
@echo " make restart - Restart testnet"
|
||||
@echo " make clean - Clean all data"
|
||||
@echo " make status - Show status"
|
||||
@echo " make logs - View logs"
|
||||
@echo ""
|
||||
@echo "Testing:"
|
||||
@echo " make test - Run basic tests"
|
||||
|
||||
# Check/install devbox
|
||||
all:
|
||||
@command -v devbox >/dev/null 2>&1 || (echo "Installing devbox..." && curl -fsSL https://get.jetpack.io/devbox | bash)
|
||||
@echo "✅ devbox is ready"
|
||||
|
||||
# Setup .env file
|
||||
setup:
|
||||
@devbox run setup
|
||||
|
||||
# Initialize validators
|
||||
init:
|
||||
@devbox run init
|
||||
|
||||
# Start testnet
|
||||
start:
|
||||
@devbox run start
|
||||
|
||||
# Stop testnet
|
||||
stop:
|
||||
@devbox run stop
|
||||
|
||||
# Restart testnet
|
||||
restart:
|
||||
@devbox run restart
|
||||
|
||||
# Clean all data
|
||||
clean:
|
||||
@devbox run clean
|
||||
|
||||
# Show status
|
||||
status:
|
||||
@devbox run status
|
||||
|
||||
# View logs
|
||||
logs:
|
||||
@devbox run logs
|
||||
|
||||
# Run tests
|
||||
test:
|
||||
@devbox run test
|
||||
@@ -0,0 +1,407 @@
|
||||
# Sonr Testnet
|
||||
|
||||
Production-ready 3-validator testnet with validator-sentry architecture and Cloudflare tunnel integration via DockFlare.
|
||||
|
||||
## Overview
|
||||
|
||||
This testnet provides:
|
||||
- **3 Validators** with isolated private networks
|
||||
- **3 Sentry Nodes** for public access and DDoS protection
|
||||
- **IPFS Node** for distributed storage
|
||||
- **Cloudflare Tunnels** for secure, zero-configuration public endpoints
|
||||
- **14 Public Endpoints** via `*.sonr.land` domains
|
||||
|
||||
## Quick Start
|
||||
|
||||
### Prerequisites
|
||||
|
||||
1. **Docker & Docker Compose**
|
||||
```bash
|
||||
docker --version
|
||||
docker compose version
|
||||
```
|
||||
|
||||
2. **Devbox** (provides snrd binary via Nix)
|
||||
```bash
|
||||
# Auto-install via Makefile
|
||||
make all
|
||||
|
||||
# Or install manually
|
||||
curl -fsSL https://get.jetpack.io/devbox | bash
|
||||
```
|
||||
|
||||
3. **DockFlare** (for Cloudflare tunnels)
|
||||
```bash
|
||||
docker network create cloudflare-net
|
||||
docker run -d \
|
||||
--name dockflare \
|
||||
--restart unless-stopped \
|
||||
--network cloudflare-net \
|
||||
-v /var/run/docker.sock:/var/run/docker.sock \
|
||||
-e CLOUDFLARE_API_TOKEN=your_token_here \
|
||||
-e CLOUDFLARE_ACCOUNT_ID=your_account_id \
|
||||
-e CLOUDFLARE_ZONE_ID=your_zone_id \
|
||||
ghcr.io/sonr-io/dockflare:latest
|
||||
```
|
||||
|
||||
> Get credentials from: https://dash.cloudflare.com
|
||||
|
||||
### Setup
|
||||
|
||||
```bash
|
||||
# 1. Clone repository
|
||||
git clone https://github.com/sonr-io/testnet
|
||||
cd testnet
|
||||
|
||||
# 2. Install devbox (if not already installed)
|
||||
make all
|
||||
|
||||
# 3. Create environment configuration
|
||||
make setup
|
||||
# Optional: Edit .env to customize
|
||||
|
||||
# 4. Initialize testnet
|
||||
make init
|
||||
|
||||
# 5. Start testnet
|
||||
make start
|
||||
|
||||
# 6. Verify endpoints
|
||||
make test
|
||||
```
|
||||
|
||||
**That's it!** Your testnet is running with Cloudflare tunnels.
|
||||
|
||||
---
|
||||
|
||||
## Commands
|
||||
|
||||
All testnet operations are managed via `make`:
|
||||
|
||||
```bash
|
||||
make all # Check/install devbox
|
||||
make setup # Create .env from template
|
||||
make init # Initialize validators and sentries
|
||||
make start # Start testnet
|
||||
make stop # Stop testnet
|
||||
make restart # Restart testnet
|
||||
make clean # Clean all data (WARNING: destructive)
|
||||
make status # Show status and endpoints
|
||||
make logs # View logs
|
||||
make test # Run basic tests
|
||||
make help # Show available commands
|
||||
```
|
||||
|
||||
> **Note:** All commands use devbox under the hood, which provides the `snrd` binary via Nix.
|
||||
|
||||
---
|
||||
|
||||
## Public Endpoints
|
||||
|
||||
All services are accessible via Cloudflare tunnels (no port conflicts):
|
||||
|
||||
### Sentry Endpoints
|
||||
|
||||
**Alice:**
|
||||
- RPC: `https://alice-rpc.sonr.land`
|
||||
- REST: `https://alice-rest.sonr.land`
|
||||
- gRPC: `https://alice-grpc.sonr.land`
|
||||
- EVM: `https://alice-evm.sonr.land`
|
||||
|
||||
**Bob:**
|
||||
- RPC: `https://bob-rpc.sonr.land`
|
||||
- REST: `https://bob-rest.sonr.land`
|
||||
- gRPC: `https://bob-grpc.sonr.land`
|
||||
- EVM: `https://bob-evm.sonr.land`
|
||||
|
||||
**Carol:**
|
||||
- RPC: `https://carol-rpc.sonr.land`
|
||||
- REST: `https://carol-rest.sonr.land`
|
||||
- gRPC: `https://carol-grpc.sonr.land`
|
||||
- EVM: `https://carol-evm.sonr.land`
|
||||
|
||||
### IPFS Endpoints
|
||||
|
||||
- API: `https://ipfs-api.sonr.land`
|
||||
- Gateway: `https://ipfs-gateway.sonr.land`
|
||||
|
||||
### Example Usage
|
||||
|
||||
```bash
|
||||
# Query blockchain status
|
||||
curl https://alice-rpc.sonr.land/status | jq
|
||||
|
||||
# Query account balance
|
||||
curl https://alice-rest.sonr.land/cosmos/bank/v1beta1/balances/idx16wx7ye3ce060tjvmmpu8lm0ak5xr7gm2vjyh4k | jq
|
||||
|
||||
# Send transaction
|
||||
snrd tx bank send alice idx1... 1000000usnr \
|
||||
--node https://alice-rpc.sonr.land \
|
||||
--chain-id sonrtest_1-1 \
|
||||
--keyring-backend test \
|
||||
--yes
|
||||
|
||||
# IPFS operations
|
||||
curl -X POST https://ipfs-api.sonr.land/api/v0/version | jq
|
||||
curl https://ipfs-gateway.sonr.land/ipfs/<CID>
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Architecture
|
||||
|
||||
```
|
||||
Cloudflare Tunnel (DockFlare)
|
||||
│
|
||||
▼
|
||||
┌──────────────────────────────────────────────┐
|
||||
│ net-public + cloudflare-net │
|
||||
│ │
|
||||
│ ┌──────────────┐ ┌──────────────┐ ┌──────────────┐ ┌──────────┐
|
||||
│ │sentry-alice │◄─►sentry-bob │◄─►sentry-carol │ │ IPFS │
|
||||
│ └──────┬───────┘ └──────┬───────┘ └──────┬───────┘ └──────────┘
|
||||
└─────────┼──────────────────┼──────────────────┼──────────────────────┘
|
||||
│ │ │
|
||||
│ Private │ Private │ Private
|
||||
│ │ │
|
||||
┌─────────▼────────┐ ┌──────▼────────┐ ┌─────▼─────────┐
|
||||
│ val-alice │ │ val-bob │ │ val-carol │
|
||||
│ (net-alice) │ │ (net-bob) │ │ (net-carol) │
|
||||
└──────────────────┘ └───────────────┘ └───────────────┘
|
||||
```
|
||||
|
||||
### Key Features
|
||||
|
||||
- **Validator Isolation**: Each validator on private network
|
||||
- **Sentry Protection**: Public traffic filtered through sentries
|
||||
- **No Port Conflicts**: All services via Cloudflare tunnels
|
||||
- **Auto-Discovery**: DockFlare automatically creates tunnels
|
||||
- **TLS Encryption**: All traffic encrypted via Cloudflare
|
||||
|
||||
---
|
||||
|
||||
## Genesis Accounts
|
||||
|
||||
| Name | Address | Balance | Purpose |
|
||||
|------|---------|---------|---------|
|
||||
| Alice | `idx140fehngcrxvhdt84x729p3f0qmkmea8n570lrg` | 100M SNR | Validator |
|
||||
| Bob | `idx1r6yue0vuyj9m7xw78npspt9drq2tmtvgcrf7sr` | 100M SNR | Validator |
|
||||
| Carol | `idx1pe9mc2q72u94sn2gg52ramrt26x5efw6kslflg` | 100M SNR | Validator |
|
||||
| Faucet | `idx16wx7ye3ce060tjvmmpu8lm0ak5xr7gm2vjyh4k` | 250M SNR | Faucet |
|
||||
|
||||
**Total Genesis Supply:** 550M SNR (300M staked + 250M faucet)
|
||||
|
||||
---
|
||||
|
||||
## Configuration
|
||||
|
||||
Configuration is managed via `.env` file:
|
||||
|
||||
```bash
|
||||
cp .env.example .env
|
||||
```
|
||||
|
||||
Quick setup:
|
||||
```bash
|
||||
make setup # Creates .env from .env.example
|
||||
```
|
||||
|
||||
**Key Variables:**
|
||||
- `CHAIN_ID=sonrtest_1-1` - Chain identifier
|
||||
- `DENOM=usnr` - Native token denomination
|
||||
- `BLOCK_TIME=5s` - Target block time
|
||||
- `VOTING_PERIOD=30s` - Governance voting period
|
||||
- `ALICE_MNEMONIC`, `BOB_MNEMONIC`, `CAROL_MNEMONIC` - Validator keys
|
||||
- `FAUCET_MNEMONIC` - Faucet account key
|
||||
- `DOCKER_IMAGE=onsonr/snrd:latest` - Container image
|
||||
|
||||
**⚠️ WARNING:** Default mnemonics in `.env.example` are public. Generate new ones for production!
|
||||
|
||||
For complete configuration details, see [docs/Environment.md](docs/Environment.md)
|
||||
|
||||
---
|
||||
|
||||
## Documentation
|
||||
|
||||
### Detailed Guides
|
||||
|
||||
- **[Docker.md](docs/Docker.md)** - Complete container documentation
|
||||
- All 7 containers explained
|
||||
- Network topology and security
|
||||
- Volume management
|
||||
- Health checks and troubleshooting
|
||||
- Performance tuning
|
||||
- Backup procedures
|
||||
|
||||
- **[Cloudflare.md](docs/Cloudflare.md)** - DockFlare integration guide
|
||||
- Complete domain mapping (14 endpoints)
|
||||
- DockFlare setup and configuration
|
||||
- DNS management
|
||||
- Testing all endpoint types
|
||||
- Access policies
|
||||
- Troubleshooting tunnels
|
||||
|
||||
- **[Environment.md](docs/Environment.md)** - Environment variable reference
|
||||
- Global configuration variables
|
||||
- Container-specific variables
|
||||
- DockFlare environment variables
|
||||
- Runtime overrides
|
||||
- Security best practices
|
||||
|
||||
- **[Architecture.md](docs/Architecture.md)** - Architecture deep dive
|
||||
- **[CLAUDE.md](CLAUDE.md)** - Quick reference for AI assistants
|
||||
|
||||
---
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
### Initialization Takes 1-2 Minutes
|
||||
|
||||
This is normal. The script initializes 6 nodes, creates genesis, and configures peer connections.
|
||||
|
||||
**Expected output:**
|
||||
- 📋 Initializing validators
|
||||
- 🛡️ Initializing sentries
|
||||
- 💰 Adding genesis accounts
|
||||
- 🔗 Setting up peer connections
|
||||
- ✅ Completion with validator addresses
|
||||
|
||||
**If init fails:**
|
||||
```bash
|
||||
make clean
|
||||
make init
|
||||
```
|
||||
|
||||
### Validators Not Syncing
|
||||
|
||||
```bash
|
||||
# Check logs
|
||||
docker compose logs val-alice
|
||||
|
||||
# Verify peer connections
|
||||
docker exec val-alice snrd tendermint show-node-id --home /root/.sonr
|
||||
```
|
||||
|
||||
### Cloudflare Tunnels Not Working
|
||||
|
||||
Check DockFlare logs:
|
||||
```bash
|
||||
docker logs dockflare
|
||||
```
|
||||
|
||||
Common issues:
|
||||
- Missing `cloudflare-net` network
|
||||
- Invalid API token
|
||||
- Container not on `cloudflare-net`
|
||||
|
||||
See [docs/Cloudflare.md#troubleshooting](docs/Cloudflare.md#troubleshooting) for detailed help.
|
||||
|
||||
### IPFS Port Conflict
|
||||
|
||||
If IPFS fails with "port 8080 already allocated":
|
||||
1. Stop the conflicting service
|
||||
2. Or modify `docker-compose.yml` to use different port
|
||||
|
||||
---
|
||||
|
||||
## Production Deployment
|
||||
|
||||
**Before deploying to production:**
|
||||
|
||||
1. ✅ **Generate new mnemonics** - Never use defaults
|
||||
```bash
|
||||
snrd keys add test --keyring-backend test --output json | jq -r .mnemonic
|
||||
```
|
||||
|
||||
2. ✅ **Use KMS** for validator key management (e.g., tmkms)
|
||||
|
||||
3. ✅ **Configure firewall rules** to restrict validator access
|
||||
|
||||
4. ✅ **Enable monitoring** (Prometheus, Grafana)
|
||||
|
||||
5. ✅ **Set up backups** of validator keys and state
|
||||
```bash
|
||||
tar -czf backup.tar.gz val-* sentry-* .env
|
||||
```
|
||||
|
||||
6. ✅ **Rotate Cloudflare API tokens** regularly (every 90 days)
|
||||
|
||||
7. ✅ **Enable rate limiting** in Cloudflare dashboard
|
||||
|
||||
8. ✅ **Use persistent volumes** instead of bind mounts (optional)
|
||||
|
||||
---
|
||||
|
||||
## Development
|
||||
|
||||
### View Logs
|
||||
|
||||
```bash
|
||||
# All services
|
||||
make logs
|
||||
|
||||
# Specific service
|
||||
docker compose logs -f sentry-alice
|
||||
|
||||
# Search logs
|
||||
docker compose logs val-alice | grep -i error
|
||||
```
|
||||
|
||||
### Execute Commands
|
||||
|
||||
```bash
|
||||
# Via docker compose (recommended)
|
||||
docker compose exec sentry-alice snrd query bank total
|
||||
|
||||
# Direct docker exec
|
||||
docker exec -it sentry-alice snrd keys list --keyring-backend test
|
||||
```
|
||||
|
||||
### Clean Restart
|
||||
|
||||
```bash
|
||||
make clean # Remove all data (destructive!)
|
||||
make init # Reinitialize
|
||||
make start # Start fresh
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Testing
|
||||
|
||||
```bash
|
||||
# Run basic tests
|
||||
make test
|
||||
```
|
||||
|
||||
### Manual Testing
|
||||
|
||||
```bash
|
||||
# RPC
|
||||
curl https://alice-rpc.sonr.land/status | jq
|
||||
|
||||
# REST
|
||||
curl https://alice-rest.sonr.land/cosmos/base/tendermint/v1beta1/node_info | jq
|
||||
|
||||
# EVM JSON-RPC
|
||||
curl -X POST https://alice-evm.sonr.land \
|
||||
-H "Content-Type: application/json" \
|
||||
-d '{"jsonrpc":"2.0","method":"eth_chainId","params":[],"id":1}' | jq
|
||||
|
||||
# IPFS
|
||||
curl -X POST https://ipfs-api.sonr.land/api/v0/version | jq
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Support
|
||||
|
||||
- **Documentation**: See [docs/](docs/) directory
|
||||
- **Issues**: https://github.com/sonr-io/testnet/issues
|
||||
- **Discord**: https://discord.gg/sonr
|
||||
|
||||
---
|
||||
|
||||
## License
|
||||
|
||||
Apache 2.0
|
||||
@@ -0,0 +1,200 @@
|
||||
name: sonr-testnet
|
||||
networks:
|
||||
net-naruto:
|
||||
net-senku:
|
||||
net-yaeger:
|
||||
net-public:
|
||||
dokploy-network:
|
||||
external: true
|
||||
|
||||
services:
|
||||
val-naruto:
|
||||
image: onsonr/snrd:latest
|
||||
container_name: val-naruto
|
||||
command: sh -c "mkdir -p /root/.sonr && /usr/bin/testnet-setup.sh && snrd start --home /root/.sonr --pruning=nothing --minimum-gas-prices=0usnr --chain-id=sonrtest_1-1"
|
||||
environment:
|
||||
- CHAIN_ID=sonrtest_1-1
|
||||
- MONIKER=val-naruto
|
||||
- NODE_TYPE=validator
|
||||
- VALIDATOR_NAME=val-naruto
|
||||
- WAIT_FOR_SYNC=false
|
||||
volumes:
|
||||
- ../val-naruto:/root/.sonr
|
||||
networks:
|
||||
- net-naruto
|
||||
restart: unless-stopped
|
||||
|
||||
sentry-naruto:
|
||||
image: onsonr/snrd:latest
|
||||
container_name: sentry-naruto
|
||||
command: sh -c "/usr/bin/testnet-setup.sh && snrd start --home /root/.sonr --pruning=nothing --minimum-gas-prices=0usnr --rpc.laddr=tcp://0.0.0.0:26657 --json-rpc.api=eth,txpool,personal,net,debug,web3 --json-rpc.address=0.0.0.0:8545 --json-rpc.ws-address=0.0.0.0:8546 --chain-id=sonrtest_1-1"
|
||||
environment:
|
||||
- CHAIN_ID=sonrtest_1-1
|
||||
- MONIKER=sentry-naruto
|
||||
- NODE_TYPE=sentry
|
||||
- VALIDATOR_NAME=sentry-naruto
|
||||
- WAIT_FOR_SYNC=true
|
||||
volumes:
|
||||
- ../sentry-naruto:/root/.sonr
|
||||
networks:
|
||||
- net-naruto
|
||||
- net-public
|
||||
- dokploy-network
|
||||
labels:
|
||||
- traefik.enable=true
|
||||
- traefik.http.routers.naruto-rpc.rule=Host(`${naruto_rpc_domain}`)
|
||||
- traefik.http.routers.naruto-rpc.entrypoints=websecure
|
||||
- traefik.http.routers.naruto-rpc.tls.certResolver=letsencrypt
|
||||
- traefik.http.services.naruto-rpc.loadbalancer.server.port=26657
|
||||
- traefik.http.routers.naruto-rest.rule=Host(`${naruto_rest_domain}`)
|
||||
- traefik.http.routers.naruto-rest.entrypoints=websecure
|
||||
- traefik.http.routers.naruto-rest.tls.certResolver=letsencrypt
|
||||
- traefik.http.services.naruto-rest.loadbalancer.server.port=1317
|
||||
- traefik.http.routers.naruto-grpc.rule=Host(`${naruto_grpc_domain}`)
|
||||
- traefik.http.routers.naruto-grpc.entrypoints=websecure
|
||||
- traefik.http.routers.naruto-grpc.tls.certResolver=letsencrypt
|
||||
- traefik.http.services.naruto-grpc.loadbalancer.server.port=9090
|
||||
- traefik.http.routers.naruto-evm.rule=Host(`${naruto_evm_domain}`)
|
||||
- traefik.http.routers.naruto-evm.entrypoints=websecure
|
||||
- traefik.http.routers.naruto-evm.tls.certResolver=letsencrypt
|
||||
- traefik.http.services.naruto-evm.loadbalancer.server.port=8545
|
||||
depends_on:
|
||||
- val-naruto
|
||||
restart: unless-stopped
|
||||
|
||||
# Senku's Validator
|
||||
val-senku:
|
||||
image: onsonr/snrd:latest
|
||||
container_name: val-senku
|
||||
command: sh -c "/usr/bin/testnet-setup.sh && snrd start --home /root/.sonr --pruning=nothing --minimum-gas-prices=0usnr --chain-id=sonrtest_1-1"
|
||||
environment:
|
||||
- CHAIN_ID=sonrtest_1-1
|
||||
- MONIKER=val-senku
|
||||
- NODE_TYPE=validator
|
||||
- VALIDATOR_NAME=val-senku
|
||||
- WAIT_FOR_SYNC=false
|
||||
volumes:
|
||||
- ../val-senku:/root/.sonr
|
||||
networks:
|
||||
- net-senku
|
||||
restart: unless-stopped
|
||||
|
||||
# Senku's Sentry
|
||||
sentry-senku:
|
||||
image: onsonr/snrd:latest
|
||||
container_name: sentry-senku
|
||||
command: sh -c "/usr/bin/testnet-setup.sh && snrd start --home /root/.sonr --pruning=nothing --minimum-gas-prices=0usnr --rpc.laddr=tcp://0.0.0.0:26657 --json-rpc.api=eth,txpool,personal,net,debug,web3 --json-rpc.address=0.0.0.0:8545 --json-rpc.ws-address=0.0.0.0:8546 --chain-id=sonrtest_1-1"
|
||||
environment:
|
||||
- CHAIN_ID=sonrtest_1-1
|
||||
- MONIKER=sentry-senku
|
||||
- NODE_TYPE=sentry
|
||||
- VALIDATOR_NAME=sentry-senku
|
||||
- WAIT_FOR_SYNC=true
|
||||
volumes:
|
||||
- ../sentry-senku:/root/.sonr
|
||||
networks:
|
||||
- net-senku
|
||||
- net-public
|
||||
- dokploy-network
|
||||
labels:
|
||||
- traefik.enable=true
|
||||
- traefik.http.routers.senku-rpc.rule=Host(`${senku_rpc_domain}`)
|
||||
- traefik.http.routers.senku-rpc.entrypoints=websecure
|
||||
- traefik.http.routers.senku-rpc.tls.certResolver=letsencrypt
|
||||
- traefik.http.services.senku-rpc.loadbalancer.server.port=26657
|
||||
- traefik.http.routers.senku-rest.rule=Host(`${senku_rest_domain}`)
|
||||
- traefik.http.routers.senku-rest.entrypoints=websecure
|
||||
- traefik.http.routers.senku-rest.tls.certResolver=letsencrypt
|
||||
- traefik.http.services.senku-rest.loadbalancer.server.port=1317
|
||||
- traefik.http.routers.senku-grpc.rule=Host(`${senku_grpc_domain}`)
|
||||
- traefik.http.routers.senku-grpc.entrypoints=websecure
|
||||
- traefik.http.routers.senku-grpc.tls.certResolver=letsencrypt
|
||||
- traefik.http.services.senku-grpc.loadbalancer.server.port=9090
|
||||
- traefik.http.routers.senku-evm.rule=Host(`${senku_evm_domain}`)
|
||||
- traefik.http.routers.senku-evm.entrypoints=websecure
|
||||
- traefik.http.routers.senku-evm.tls.certResolver=letsencrypt
|
||||
- traefik.http.services.senku-evm.loadbalancer.server.port=8545
|
||||
depends_on:
|
||||
- val-senku
|
||||
restart: unless-stopped
|
||||
|
||||
# Yaeger's Validator
|
||||
val-yaeger:
|
||||
image: onsonr/snrd:latest
|
||||
container_name: val-yaeger
|
||||
command: sh -c "/usr/bin/testnet-setup.sh && snrd start --home /root/.sonr --pruning=nothing --minimum-gas-prices=0usnr --chain-id=sonrtest_1-1"
|
||||
environment:
|
||||
- CHAIN_ID=sonrtest_1-1
|
||||
- MONIKER=val-yaeger
|
||||
- NODE_TYPE=validator
|
||||
- VALIDATOR_NAME=val-yaeger
|
||||
- WAIT_FOR_SYNC=false
|
||||
volumes:
|
||||
- ../val-yaeger:/root/.sonr
|
||||
networks:
|
||||
- net-yaeger
|
||||
restart: unless-stopped
|
||||
|
||||
# Yaeger's Sentry (Public Node)
|
||||
sentry-yaeger:
|
||||
image: onsonr/snrd:latest
|
||||
container_name: sentry-yaeger
|
||||
command: sh -c "/usr/bin/testnet-setup.sh && snrd start --home /root/.sonr --pruning=nothing --minimum-gas-prices=0usnr --rpc.laddr=tcp://0.0.0.0:26657 --json-rpc.api=eth,txpool,personal,net,debug,web3 --json-rpc.address=0.0.0.0:8545 --json-rpc.ws-address=0.0.0.0:8546 --chain-id=sonrtest_1-1"
|
||||
environment:
|
||||
- CHAIN_ID=sonrtest_1-1
|
||||
- MONIKER=sentry-yaeger
|
||||
- NODE_TYPE=sentry
|
||||
- VALIDATOR_NAME=sentry-yaeger
|
||||
- WAIT_FOR_SYNC=true
|
||||
volumes:
|
||||
- ../sentry-yaeger:/root/.sonr
|
||||
networks:
|
||||
- net-yaeger
|
||||
- net-public
|
||||
- dokploy-network
|
||||
labels:
|
||||
- traefik.enable=true
|
||||
- traefik.http.routers.yaeger-rpc.rule=Host(`${yaeger_rpc_domain}`)
|
||||
- traefik.http.routers.yaeger-rpc.entrypoints=websecure
|
||||
- traefik.http.routers.yaeger-rpc.tls.certResolver=letsencrypt
|
||||
- traefik.http.services.yaeger-rpc.loadbalancer.server.port=26657
|
||||
- traefik.http.routers.yaeger-rest.rule=Host(`${yaeger_rest_domain}`)
|
||||
- traefik.http.routers.yaeger-rest.entrypoints=websecure
|
||||
- traefik.http.routers.yaeger-rest.tls.certResolver=letsencrypt
|
||||
- traefik.http.services.yaeger-rest.loadbalancer.server.port=1317
|
||||
- traefik.http.routers.yaeger-grpc.rule=Host(`${yaeger_grpc_domain}`)
|
||||
- traefik.http.routers.yaeger-grpc.entrypoints=websecure
|
||||
- traefik.http.routers.yaeger-grpc.tls.certResolver=letsencrypt
|
||||
- traefik.http.services.yaeger-grpc.loadbalancer.server.port=9090
|
||||
- traefik.http.routers.yaeger-evm.rule=Host(`${yaeger_evm_domain}`)
|
||||
- traefik.http.routers.yaeger-evm.entrypoints=websecure
|
||||
- traefik.http.routers.yaeger-evm.tls.certResolver=letsencrypt
|
||||
- traefik.http.services.yaeger-evm.loadbalancer.server.port=8545
|
||||
depends_on:
|
||||
- val-yaeger
|
||||
restart: unless-stopped
|
||||
|
||||
ipfsctl:
|
||||
image: ipfs/kubo:latest
|
||||
container_name: ipfsctl
|
||||
environment:
|
||||
- IPFS_PROFILE=server
|
||||
volumes:
|
||||
- ipfs-data:/data/ipfs
|
||||
networks:
|
||||
- net-public
|
||||
- dokploy-network
|
||||
labels:
|
||||
- traefik.enable=true
|
||||
- traefik.http.routers.ipfs-api.rule=Host(`${ipfs_api_domain}`)
|
||||
- traefik.http.routers.ipfs-api.entrypoints=websecure
|
||||
- traefik.http.routers.ipfs-api.tls.certResolver=letsencrypt
|
||||
- traefik.http.services.ipfs-api.loadbalancer.server.port=5001
|
||||
- traefik.http.routers.ipfs-gateway.rule=Host(`${ipfs_gateway_domain}`)
|
||||
- traefik.http.routers.ipfs-gateway.entrypoints=websecure
|
||||
- traefik.http.routers.ipfs-gateway.tls.certResolver=letsencrypt
|
||||
- traefik.http.services.ipfs-gateway.loadbalancer.server.port=8080
|
||||
restart: unless-stopped
|
||||
|
||||
volumes:
|
||||
ipfs-data:
|
||||
@@ -0,0 +1,107 @@
|
||||
[variables]
|
||||
# Naruto Sentry Domains
|
||||
naruto_rpc_domain = "${domain}"
|
||||
naruto_rest_domain = "${domain}"
|
||||
naruto_grpc_domain = "${domain}"
|
||||
naruto_evm_domain = "${domain}"
|
||||
|
||||
# Senku Sentry Domains
|
||||
senku_rpc_domain = "${domain}"
|
||||
senku_rest_domain = "${domain}"
|
||||
senku_grpc_domain = "${domain}"
|
||||
senku_evm_domain = "${domain}"
|
||||
|
||||
# Yaeger Sentry Domains
|
||||
yaeger_rpc_domain = "${domain}"
|
||||
yaeger_rest_domain = "${domain}"
|
||||
yaeger_grpc_domain = "${domain}"
|
||||
yaeger_evm_domain = "${domain}"
|
||||
|
||||
# IPFS Domains
|
||||
ipfs_api_domain = "${domain}"
|
||||
ipfs_gateway_domain = "${domain}"
|
||||
|
||||
[config]
|
||||
# Naruto Sentry RPC
|
||||
[[config.domains]]
|
||||
serviceName = "sentry-naruto"
|
||||
port = 26657
|
||||
host = "${naruto_rpc_domain}"
|
||||
|
||||
# Naruto Sentry REST
|
||||
[[config.domains]]
|
||||
serviceName = "sentry-naruto"
|
||||
port = 1317
|
||||
host = "${naruto_rest_domain}"
|
||||
|
||||
# Naruto Sentry gRPC
|
||||
[[config.domains]]
|
||||
serviceName = "sentry-naruto"
|
||||
port = 9090
|
||||
host = "${naruto_grpc_domain}"
|
||||
|
||||
# Naruto Sentry EVM
|
||||
[[config.domains]]
|
||||
serviceName = "sentry-naruto"
|
||||
port = 8545
|
||||
host = "${naruto_evm_domain}"
|
||||
|
||||
# Senku Sentry RPC
|
||||
[[config.domains]]
|
||||
serviceName = "sentry-senku"
|
||||
port = 26657
|
||||
host = "${senku_rpc_domain}"
|
||||
|
||||
# Senku Sentry REST
|
||||
[[config.domains]]
|
||||
serviceName = "sentry-senku"
|
||||
port = 1317
|
||||
host = "${senku_rest_domain}"
|
||||
|
||||
# Senku Sentry gRPC
|
||||
[[config.domains]]
|
||||
serviceName = "sentry-senku"
|
||||
port = 9090
|
||||
host = "${senku_grpc_domain}"
|
||||
|
||||
# Senku Sentry EVM
|
||||
[[config.domains]]
|
||||
serviceName = "sentry-senku"
|
||||
port = 8545
|
||||
host = "${senku_evm_domain}"
|
||||
|
||||
# Yaeger Sentry RPC
|
||||
[[config.domains]]
|
||||
serviceName = "sentry-yaeger"
|
||||
port = 26657
|
||||
host = "${yaeger_rpc_domain}"
|
||||
|
||||
# Yaeger Sentry REST
|
||||
[[config.domains]]
|
||||
serviceName = "sentry-yaeger"
|
||||
port = 1317
|
||||
host = "${yaeger_rest_domain}"
|
||||
|
||||
# Yaeger Sentry gRPC
|
||||
[[config.domains]]
|
||||
serviceName = "sentry-yaeger"
|
||||
port = 9090
|
||||
host = "${yaeger_grpc_domain}"
|
||||
|
||||
# Yaeger Sentry EVM
|
||||
[[config.domains]]
|
||||
serviceName = "sentry-yaeger"
|
||||
port = 8545
|
||||
host = "${yaeger_evm_domain}"
|
||||
|
||||
# IPFS API
|
||||
[[config.domains]]
|
||||
serviceName = "ipfsctl"
|
||||
port = 5001
|
||||
host = "${ipfs_api_domain}"
|
||||
|
||||
# IPFS Gateway
|
||||
[[config.domains]]
|
||||
serviceName = "ipfsctl"
|
||||
port = 8080
|
||||
host = "${ipfs_gateway_domain}"
|
||||
Reference in New Issue
Block a user