Operar un nodo

xrs-node 0.1.1Rustpuertos 4000 · 56001 · 50008

Un binario, tres puertos, un archivo de claves.

Compilar

git clone https://github.com/ZZachWWins/xeriscointestnet && cd xeriscointestnet cargo build --release
xrs-nodeel nodo
keypair_genescribe keypair.json
walletconstruye transacciones, imprime el curl para enviarlas
rustc1.94.1 en el último informe de remediación de Xeris; sin fijar
cc, perl, makeOpenSSL vendored, SQLite bundled

Claves

# keypair.json; --mainnet escribe keypair_mainnet.json RUST_LOG=info ./target/release/keypair_gen
ArchivoContenidoModo
keypair.jsonarray JSON de 64 bytes, la clave secreta Ed255190600
dilithium3_sk.binclave secreta ML-DSA-65, 4,032 bytes; escrita en el primer arranque en el directorio de trabajo; autoverificada en cada arranque0600
dilithium3_pk.binclave pública, 1,952 bytesumask

keypair.json se carga con XerisKeypair.fromJsonFile.

Arrancar

FlagPor defectoSignificado
--validator <seed-ip> <keypair.json> <data-dir>—unirse por un seed; si falta el keypair se genera
--bootstrap <keypair.json> <data-dir>—primer nodo de una cadena; necesita la clave del tesoro
--mainnetoffchain id xeris-mainnet-v1; roster obligatorio; <seed-ip> ignorado
--genesisoffescribe un descriptor de génesis y sale
--p2p-port4000P2P
--rpc-port56001RPC
--explorer-port50008API del explorador
--genesis-pre-stake—obsoleto, ignorado
RUST_LOG=info ./target/release/xrs-node \ --validator 138.197.116.81 keypair.json ./data # mainnet: tres direcciones P2P export XRS_FEDERATED_PRODUCERS='<pk1>@<ip1>:4000,<pk2>@<ip2>:4000,<pk3>@<ip3>:4000' RUST_LOG=info ./target/release/xrs-node --mainnet \ --validator 138.197.116.81 keypair_mainnet.json ./data

Entorno

XRS_FEDERATED_PRODUCERS3 entradas pubkey@ipv4:port, las direcciones P2P; obligatoria con --mainnet
XRS_LOCAL_ONLY=1P2P y RPC escuchan en 127.0.0.1, sin seeds DNS; el explorador sigue en 0.0.0.0
XRS_SEED_PEERSip[:port] separados por comas, ≤ 200, de confianza; solo testnet
XRS_MAX_DEEP_SYNC_BYTESpresupuesto de disco del deep-sync; por defecto 512 GiB, mínimo 1 GiB
RUST_LOGinfo muestra el banner y el log de bloques; sin definir solo imprime errores

Puertos

PuertoServicioProtocoloEscucha
4000P2PTCP, desafío-respuesta Ed255190.0.0.0, o 127.0.0.1 en modo local
56001RPCHTTP/1.1, sin TLS0.0.0.0, o 127.0.0.1 en modo local
50008API del exploradorHTTP/1.1, sin TLS0.0.0.0 siempre

Termina TLS en un proxy inverso. El limitador de escritura usa el peer TCP: un proxy, un presupuesto de 30 por minuto.

Archivos

<data-dir>/ledger.datbloques, una línea JSON cada uno, fsync antes de aplicar
<data-dir>/tx_receipts.sqlitehistorial del explorador, esquema 2; reconstruido por replay si la versión difiere; obligatorio en toda red
<data-dir>/ledger.dat.recovered-txs.sqlitediario de recuperación; creado en cada arranque
<data-dir>/price_history_<pool>.json≤ 10,080 instantáneas por pool, una cada 100 bloques
<data-dir>/ledger_snapshot.json, contract_state.jsonse escriben, nunca se cargan
<cwd>/dilithium3_*.binlas claves PQ
Dos nodos arrancados desde un mismo directorio de trabajo comparten una clave PQ.

Pares

--validator <seed-ip>se marca primero; puerto 4000 si no se indica
XRS_SEED_PEERSde confianza
lista de seeds DNSuna URL HTTPS leída al arrancar, 5 s de espera, salvo en modo local
lista integradavacía
mainnetel roster sustituye a todas las fuentes anteriores
direcciónIPv4, puerto opcional; hostnames rechazados

Stake y producción

1generar keypair.json
2arrancar con --validator; el log dice needs 1000 to mine
3fondear la dirección: ≥ 1,000 XRS más tarifas; sin faucet
4wallet stake → POST /stake
5wallet pq-register → POST /pq-register, antes del primer bloque
# cada uno imprime el curl de envío; ejecútalo ./target/release/wallet stake keypair.json 1000 ./target/release/wallet pq-register keypair.json
import { readFileSync } from 'node:fs'; import { XerisClient, XerisKeypair } from 'xeris-sdk'; const client = new XerisClient('http://127.0.0.1', { rpcPort: 56001, explorerPort: 50008 }); const kp = XerisKeypair.fromJsonFile('keypair.json'); const pk = readFileSync('dilithium3_pk.bin'); await client.stakeXrs(kp, 1000); // POST /stake await client.pqKeyRegister(kp, pk, 'dilithium3', 3); // POST /pq-register
producir bloquesstake ≥ 1,000 XRS; cuenta desde el bloque siguiente
primer Stakestake resultante ≥ 1,000 XRS; /stake no lo comprueba antes
recompensas de stakingstake ≥ 100 XRS; 7 % anual, cada 900 bloques, al saldo líquido
unstaketodo, o conservar ≥ 1,000 XRS; parcial ≥ 1 XRS, POST /unstake
unbonding151,200 slots (7 días); slasheable; se libera sin reclamar, GET /account/{address}/unstaking
atestacionesstake ≥ 100 XRS; 0.01 XRS, una cada 10 bloques, dentro de 200 slots, hash de 32 bytes, ValidatorAttestation
slashing10 % del stake por doble firma probada; 5 % de eso al reportero, el resto se quema, SlashReport
clave PQuna por nodo; los bloques la exigen desde el slot 2
mainnet Stakesolo claves del roster; el resto: Public self-staking is closed during federated beta
Mainnet: la clave del nodo debe estar en el roster de 3 entradas XRS_FEDERATED_PRODUCERS o el arranque falla.

Estado

curl -s http://127.0.0.1:56001/health curl -s http://127.0.0.1:50008/v2/stats curl -s http://127.0.0.1:56001/stake/<address>
SeñalRutaSDK
activoGET /healthgetHealth()
altura, TPS estimadoGET /v2/statsgetStats()
stake, isValidator, blocksProposedGET /stake/{address}getStakeInfo(address)
clave PQGET /pq/keys/{address}getPqKey(address)
recompensa por bloque, tarifas, halvingGET /network/economicsgetNetworkEconomics()
paresel log del nodo—
métricasninguna—