TESTNET TESTNET SIM BLOCK EPOCH VALIDATORS TESTNET-1 // OPERATIONAL
Run a validatorLancer un validateur

Run a CURS3D validator. Faire tourner un validateur CURS3D.

Join the BFT-PoS testnet, produce blocks, earn epoch rewards. Quantum-resistant signatures (Dilithium L5), 10s block time, 32-block epochs. Rejoignez le testnet BFT-PoS, produisez des blocs, gagnez des récompenses d'époque. Signatures post-quantiques (Dilithium L5), bloc toutes les 10s, époques de 32 blocs.

Testnet only.Testnet uniquement. No mainnet yet. Stake has no real-world value but slashing/jailing rules are enforced.Pas encore de mainnet. Le stake n'a pas de valeur réelle mais les règles de slashing/jail s'appliquent.

CPU

1 OCPU / 2 vCPU

RAM

6 GB

DISK

40 GB SSD

OS

Ubuntu 22.04+

01

RequirementsPrérequis

Tested on Oracle Cloud ARM Free Tier (Ampere A1, 1 OCPU / 6 GB). Hetzner CAX11, AWS t4g.medium, GCP e2-medium also work. ARM64 and x86_64 both supported. Minimum stake: 1 000 CUR.Testé sur Oracle Cloud ARM Free Tier (Ampere A1, 1 OCPU / 6 Go). Hetzner CAX11, AWS t4g.medium, GCP e2-medium fonctionnent aussi. ARM64 et x86_64 supportés. Stake minimum : 1 000 CUR.

02

Open portsPorts à ouvrir

ports
4337/tcp   # P2P (libp2p, Gossipsub)
8080/tcp   # HTTP API (optional, only if you want to expose your node)
9545/tcp   # TCP RPC (CLI, keep on localhost only)
03

Install dependenciesInstaller les dépendances

install.sh
$ sudo apt-get update
$ sudo apt-get install -y build-essential pkg-config libssl-dev curl jq nginx
$ curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y
$ source ~/.cargo/env
04

Build CURS3DCompiler CURS3D

build.sh
$ git clone https://github.com/Pazificateur69/curs3d.git
$ cd curs3d
$ cargo build --release
# ~10 min on a 1 OCPU ARM box
05

Generate validator keys (ON the server)Générer les clés validateur (SUR le serveur)

Important:Important : Argon2id parameters are hardware-tuned. Keys MUST be generated directly on the server that will run the node — never cross-compile or transfer encrypted wallets between hosts.Les paramètres Argon2id sont calibrés pour le hardware. Les clés DOIVENT être générées directement sur le serveur qui fera tourner le node — jamais de cross-compilation ni de transfert de wallets chiffrés entre machines.

keygen.sh
# Create wallet from the server that will run the validator
$ printf '%s\n' 'change-this-validator-password' > /etc/curs3d/validator.password
$ chmod 600 /etc/curs3d/validator.password
$ ./target/release/curs3d wallet --output /etc/curs3d/validator.json --password-file /etc/curs3d/validator.password

# Save the address shown — that's your validator address
# Keep /etc/curs3d/validator.json and /etc/curs3d/validator.password together
06

Get the genesis fileRécupérer le genesis

genesis.sh
# Copy the exact genesis config used by the existing network
$ scp existing-validator:/etc/curs3d/genesis.public-testnet.json /etc/curs3d/genesis.public-testnet.json
# /api/genesis is only a light-client anchor, not a reusable validator config

Note: if you join an existing testnet, you start from the genesis and let your node sync all blocks via P2P. State sync via snapshots is also supported.Note : si vous rejoignez un testnet existant, vous démarrez du genesis et laissez votre node sync tous les blocs via P2P. Le state sync par snapshot est aussi supporté.

07

Start the nodeDémarrer le node

start-node.sh
# Bootnode info (current testnet bootstrap)
$ BOOTNODE=/ip4/144.24.192.222/tcp/4337/p2p/12D3KooWGy9BLopUe6CmnxuFgk5pCou8Kj5R1DXa9XLga9MD63va

$ ./target/release/curs3d node \
    --data-dir /var/lib/curs3d \
    --validator-wallet /etc/curs3d/validator.json \
    --validator-password-file /etc/curs3d/validator.password \
    --genesis-config /etc/curs3d/genesis.public-testnet.json \
    --bootnode $BOOTNODE \
    --public-addr /ip4/YOUR_PUBLIC_IP/tcp/4337 \
    --rpc-addr 127.0.0.1:9545 \
    --http-addr 127.0.0.1:8080
08

Stake to activateStaker pour activer

A node is observer-only until it stakes. Use the CLI to bond at least 1000 CUR (testnet faucet: faucet endpoint):Un node est en mode observateur tant qu'il n'a pas staké. Utilisez la CLI pour bonder au moins 1000 CUR (faucet testnet : endpoint faucet) :

stake.sh
# Request faucet (100 CUR per hour, request ~10 times to get 1000+)
$ curl -X POST https://api.curs3d.fr/api/faucet/request \
    -H "Content-Type: application/json" \
    -d '{"address":"YOUR_VALIDATOR_ADDRESS"}'

# Stake 1000 CUR (in microtokens: 1_000_000_000)
$ ./target/release/curs3d stake \
    --wallet /etc/curs3d/validator.json \
    --amount 1000000000 \
    --rpc-addr 127.0.0.1:9545
09

Run as a systemd serviceService systemd

curs3d.service
$ sudo tee /etc/systemd/system/curs3d.service > /dev/null <<'EOF'
[Unit]
Description=CURS3D validator node
After=network.target

[Service]
Type=simple
User=ubuntu
WorkingDirectory=/home/ubuntu/curs3d
Environment=RUST_LOG=info
ExecStart=/home/ubuntu/curs3d/target/release/curs3d node \
    --data-dir /var/lib/curs3d \
    --validator-wallet /etc/curs3d/validator.json \
    --validator-password-file /etc/curs3d/validator.password \
    --genesis-config /etc/curs3d/genesis.public-testnet.json \
    --bootnode /ip4/144.24.192.222/tcp/4337/p2p/12D3KooWGy9BLopUe6CmnxuFgk5pCou8Kj5R1DXa9XLga9MD63va \
    --public-addr /ip4/YOUR_PUBLIC_IP/tcp/4337 \
    --rpc-addr 127.0.0.1:9545 \
    --http-addr 127.0.0.1:8080
Restart=always
RestartSec=5
StartLimitIntervalSec=300
StartLimitBurst=10

[Install]
WantedBy=multi-user.target
EOF

$ sudo systemctl daemon-reload
$ sudo systemctl enable curs3d
$ sudo systemctl start curs3d
$ journalctl -u curs3d -f
10

Verify you're producing blocksVérifier que vous produisez des blocs

verify.sh
# Local status
$ curl -s http://localhost:8080/api/status | jq

# Are you in the active validator set?
$ curl -s https://api.curs3d.fr/api/validators | jq '.data[] | select(.address=="YOUR_ADDR")'

# Watch on the public explorer
# https://explorer.curs3d.fr — search your validator address

Rewards & slashingRécompenses & slashing

  • Block reward: 50 CUR per block produced.Récompense bloc : 50 CUR par bloc produit.
  • Epoch rewards: 100 microtokens per CUR staked, per block produced in the epoch.Récompenses d'époque : 100 microtokens par CUR staké, par bloc produit dans l'époque.
  • Inactivity penalty: 2 epochs grace period, then escalating stake penalty.Pénalité d'inactivité : 2 époques de grâce, puis pénalité progressive sur le stake.
  • Equivocation slashing: 33% of staked balance + 64-block jail. Don't run two nodes with the same key.Slashing par équivocation : 33% du stake + jail de 64 blocs. Ne jamais faire tourner deux nodes avec la même clé.

Operational checklistChecklist opérationnelle

  • Set up a healthcheck cron (every 2 min) that pings /api/healthz and restarts the service if it fails.Mettre en place un healthcheck cron (toutes les 2 min) qui ping /api/healthz et redémarre le service en cas d'échec.
  • Back up /etc/curs3d/validator.json AND /etc/curs3d/validator.password together — without both, your stake is lost.Sauvegarder /etc/curs3d/validator.json ET /etc/curs3d/validator.password ensemble — sans les deux, le stake est perdu.
  • Monitor with Prometheus: /api/metrics exposes block height, peer count, finalized height.Monitorer avec Prometheus : /api/metrics expose la hauteur, le nombre de peers, la hauteur finalisée.
  • Use TLS for the public API (nginx + certbot). See deploy/nginx/curs3d.conf in the repo.Utiliser TLS pour l'API publique (nginx + certbot). Voir deploy/nginx/curs3d.conf dans le repo.

Automated deploy scriptScript de déploiement automatisé

If you have OCI CLI configured for Oracle Cloud, the repo includes deploy/scripts/add-node.sh to provision a node from prepared validator artifacts (instance creation, SSH provisioning, build, systemd setup, join to the bootnode).Si vous avez OCI CLI configuré pour Oracle Cloud, le repo inclut deploy/scripts/add-node.sh pour provisionner un node à partir d'artefacts validateurs préparés (création d'instance, provisioning SSH, build, setup systemd, connexion au bootnode).

add-node.sh
$ ./deploy/scripts/add-node.sh 3 144.24.192.222 12D3KooWGy9BLopUe6CmnxuFgk5pCou8Kj5R1DXa9XLga9MD63va

Need help?Besoin d'aide ?

Open an issue on GitHub or check the full documentation.Ouvrez un ticket sur GitHub ou consultez la documentation complète.