Executando um nó OpenFiat
Os operadores de nós mantêm o mercado descentralizado que fica acima da blockchain. Os validadores da Solana protegem a cadeia e executam os programas do OpenFiat; os nós carregam as listagens, a reputação, as mensagens e a descoberta.
Os comandos abaixo usam a implantação de referência: o serviço openfiat-node, /etc/openfiat para configuração e /var/lib/openfiat para dados.
Hardware
Mínimo
4 núcleos de CPU · 16 GB de RAM · SSD NVMe de 250 GB · Conexão de banda larga estável
Recomendado para produção
8–16 núcleos de CPU · 32 GB de RAM ou mais · SSD NVMe de 1 TB · Rede de alta largura de banda e baixa latência · Proteção de energia por no-break (UPS) · Conectividade de internet redundante
O nó é um único binário Rust. libp2p (QUIC, Noise, Yamux) e RocksDB são compilados dentro — não há nada para instalar separadamente.
Onde executá-lo
A AllenHark lidera o desenvolvimento inicial do protocolo e vende as duas coisas de que um nó precisa: um servidor e acesso RPC à Solana. Os operadores de nós recebem 50% de desconto em ambos, como parte do programa OpenFiat.
Hospedagem de servidores
Armazenamento NVMe em links de 10 Gbps, em Frankfurt, Amsterdã e Chicago. Dimensione contra o hardware acima — o armazenamento é o que um nó completo vai exigindo, então diga o que você está executando e ele pode ser especificado para você.
Ver preçosRPC e gRPC da Solana
Conexões com stake, para que as transações que seu nó envia não fiquem em fila atrás das de todos os outros. O acesso é concedido por lista de IPs permitidos em vez de uma chave de API. O Yellowstone gRPC está disponível para transmitir atualizações de contas e slots.
Ver preçosReivindicando o desconto
Não há código a inserir. Pergunte no Discord ou no chat em allenhark.com, diga que está executando um nó OpenFiat, e o desconto é aplicado ao seu pedido.
Sirva a rede, não só a si mesmo
Um nó que só lê é um convidado. Um nó que o público pode alcançar é infraestrutura — carteiras, exploradores e apps web precisam falar com *alguém*, e hoje existem poucos desses alguéns. Cada operador que põe seu nó atrás de TLS e define --public-rpc-url amplia esse conjunto, que é a diferença entre uma rede com várias portas de entrada independentes e uma com um único ponto de falha do qual todos dependem em silêncio. Custa um certificado e um proxy reverso. Também é remunerado: um nó alcançável é um que os pares podem desafiar e recompensar, e os próprios aplicativos do OpenFiat usarão o seu junto com todos os outros.
Duas coisas que vale saber antes. Servir o público significa tráfego real, então dimensione a máquina para isso e vigie o endpoint de métricas. E um nó público é um compromisso público — as pessoas vão construir contra a URL que você publica, então retire-a deliberadamente em vez de silenciosamente.
Instalação
Compilar a partir do código-fonte — para produção, hoje
Nenhuma versão foi marcada ainda, então esta é atualmente a única forma de obter o binário do nó. Precisa do toolchain do Rust e de um toolchain de C para o RocksDB. Compile, coloque em /usr/local/bin e execute sob systemd — esta é a implantação que esta página documenta, e a que se deve usar para um nó do qual outros dependem.
# Rust toolchain, then build the node binary
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y
source "$HOME/.cargo/env"
apt install -y build-essential pkg-config libssl-dev clang cmake
git clone https://github.com/OpenFiat-org/openfiat-core.git
cd openfiat-core
cargo build --release --bin openfiat-node
install -m 0755 target/release/openfiat-node /usr/local/bin/Binário pré-compilado — assim que uma versão for marcada
Empurrar uma tag v* executa o workflow de release, que compila o openfiat-node em runners nativos e publica arquivos linux-x86_64 e windows-x86_64 nos GitHub Releases. Nada foi marcado ainda, então essa página está vazia no momento. Note que são builds de release comuns, não estáticos nem assinados — verifique o que você baixa contra o workflow que o produziu.
Releases do GitHubuseradd --system --create-home --home-dir /var/lib/openfiat --shell /usr/sbin/nologin openfiat
install -m 755 openfiat-node /usr/local/bin/openfiat-node
mkdir -p /etc/openfiat
chown -R openfiat:openfiat /var/lib/openfiat
systemctl daemon-reload
systemctl enable --now openfiat-node
journalctl -u openfiat-node -fDocker — apenas para testes
Use a imagem para experimentar um nó localmente ou para subir um cluster multinó descartável — não para executar um nó do qual a rede depende. Existe para testes locais reproduzíveis; a produção executa o binário sob systemd.
# /opt/openfiat/compose.yaml
# TESTING ONLY. Use this to try a node locally or to bring up a throwaway
# cluster — run a production node from the binary under systemd instead
# (see the unit file further down this page).
services:
node:
image: ghcr.io/openfiat-org/openfiat-node:latest
restart: unless-stopped
# QUIC needs UDP; the same TCP port serves JSON-RPC, WebSocket, REST,
# health, and metrics together — there is no separate metrics port.
ports:
- "4001:4001/udp"
- "7080:7080/tcp"
volumes:
- /var/lib/openfiat:/data
- /etc/openfiat/wallet.json:/data/wallet.json:ro
command:
- --ledger=/data
- --identity=/data/wallet.json
- --rpc-bind-address=0.0.0.0:7080
- --gossip-bind-address=/ip4/0.0.0.0/udp/4001/quic-v1
# Static multiaddr — DNS bootstrap does not resolve (see this
# file's own top comment). Repeat the flag for several.
- --entrypoint=/ip4/84.32.223.111/udp/4001/quic-v1/p2p/12D3KooWK9hQ7TwbfvFiaAxUbRFCkdhS7iEpAJDnewNL1anyREQ1
# Omit to stay GossipOnly, the safe default. Any value opts into
# real Solana devnet connectivity (OFS-4300 §4).
- --solana-rpc-url=https://api.devnet.solana.com
stop_grace_period: 60s
ulimits:
nofile: 65536install -d -m 0750 /var/lib/openfiat
docker compose -f /opt/openfiat/compose.yaml up -d
docker compose -f /opt/openfiat/compose.yaml logs -f nodePortas
- 4001/UDPTráfego entre pares. O QUIC é o transporte principal, então esta porta UDP deve ser alcançável — a que as pessoas mais esquecem de abrir.Deve ser alcançável
- 7080/TCPJSON-RPC, WebSocket, REST, saúde e métricas — uma porta real serve tudo, não há porta separada por superfície.Deve ser alcançável
- 7080/TCPA mesma porta da API acima (GET /metrics). Restrinja com firewall para loopback/uma rede privada se você não quiser que seja pública.Mantenha privada
Colocando um nó online
Trabalhe nestes passos em ordem. Cada passo abaixo traz o comando de que precisa.
- 01
Prepare a máquina
Um servidor Debian ou Ubuntu atual, um firewall e um relógio preciso. O relógio importa mais do que parece: os registros carregam timestamps e horários de expiração, e um relógio desviado faz um nó rejeitar dados válidos.
shell# Debian 12 / Ubuntu 24.04, as root apt update && apt install -y ca-certificates curl gnupg ufw chrony # Clock drift breaks signature and expiry checks — keep NTP running. systemctl enable --now chrony - 02
Instale o nó
Compile a partir do código-fonte e execute o resultado sob systemd — nenhuma versão foi marcada ainda, então essa é a única forma de obter um binário hoje, e o resto deste manual assume isso. Recorra ao Docker só ao testar localmente ou subir um cluster descartável.
- 03
Gere a carteira do nó
Não há um formato de "identidade de nó" separado — a identidade de um nó é um wallet.json real da CLI da Solana, o mesmo arquivo que o solana-keygen produz. Sua seed é reutilizada tanto para a identidade de gossip/par do nó quanto para a chave de assinatura da Solana. Guarde o arquivo — se você o perder, o nó reingressa como um estranho e começa a construir reputação do zero.
shell# The node's identity IS a Solana CLI-format wallet.json — the same # file "solana-keygen new" produces (its own seed is reused for the # node's gossip/P2P keypair too, see crates/cli's load_or_generate_wallet). # There is no separate "node identity" format or command. solana-keygen new --outfile /etc/openfiat/wallet.json chmod 600 /etc/openfiat/wallet.json solana-keygen pubkey /etc/openfiat/wallet.json - 04
Defina o ambiente
O openfiat-node não tem arquivo de configuração próprio — cada ajuste é uma variável de ambiente, lida uma vez na inicialização: onde os dados ficam, em qual endereço escutar, quais pares discar na partida e (opcionalmente) qual endpoint RPC da Solana usar. Os pares de bootstrap devem ser um multiaddr/IP estático, não um nome de host — o bootstrap por DNS não resolve.
shell# There is no config file and no environment variables. Every # setting is a flag on the systemd unit's ExecStart below, so # "systemctl cat openfiat-node" shows exactly what a running node was # given, and "openfiat-node --help" is the whole surface. # # Try it in the foreground first — the node prints the addresses it is # reachable at and whether it reached Solana: openfiat-node \ --ledger /var/lib/openfiat \ --identity /etc/openfiat/wallet.json \ --rpc-bind-address 0.0.0.0:7080 \ --gossip-bind-address /ip4/0.0.0.0/udp/4001/quic-v1 \ --entrypoint /ip4/84.32.223.111/udp/4001/quic-v1/p2p/12D3KooWK9hQ7TwbfvFiaAxUbRFCkdhS7iEpAJDnewNL1anyREQ1 \ --solana-rpc-url https://api.devnet.solana.com # Omit --solana-rpc-url to stay GossipOnly, the safe default: the node # still serves the marketplace, but its on-chain answers come # second-hand from peers. Never put a real endpoint or API key anywhere # version controlled — it belongs in the unit file on the server. # # Add --ipfs-api-url http://127.0.0.1:5001 to pin protocol content and # earn the full reward share, and --retention archival to keep the whole # history instead of a rolling 30 days. - 05
Abra as portas certas
Os pares alcançam o nó por UDP porque o QUIC é o transporte principal — essa é a porta que as pessoas mais esquecem. Uma porta TCP serve JSON-RPC, WebSocket, REST, saúde e métricas juntos; mantenha-a privada se você não quiser servir clientes publicamente.
shellufw default deny incoming ufw allow 22/tcp # keep your own access ufw allow 4001/udp # libp2p, QUIC — the port people most often forget ufw allow 443/tcp # once nginx terminates TLS in front (see below) ufw allow 7080/tcp # only if the node is exposed directly, without a proxy ufw enable && ufw status verbose - 06
Sirva a rede: torne seu nó alcançável
Este é o passo que transforma um nó de algo que observa a rede em algo que a carrega. Coloque o nginx na frente e obtenha um certificado, então informe ao nó sua URL pública com --public-rpc-url e ele se anuncia para que carteiras, exploradores e o próprio app web do OpenFiat possam usá-lo. A ordem importa: nginx sobre HTTP simples primeiro, depois o certbot adiciona TLS — uma configuração que já nomeia um certificado não consegue iniciar, então o certbot falha antes de poder emitir aquele que teria resolvido. Um certificado não é enfeite opcional: uma página servida por HTTPS não consegue abrir uma conexão HTTP simples, então um nó sem um é invisível para todo navegador por mais saudável que esteja.
/etc/nginx/sites-available/openfiat-node# /etc/nginx/sites-available/openfiat-node # # HTTP only at this stage, with NO TLS directives. certbot --nginx works # by running "nginx -t" and editing this file, so a config that already # points at a certificate cannot load, nginx will not start, and certbot # fails before it can issue the certificate that would have fixed it. server { listen 80; listen [::]:80; server_name openfiat.example.com; location / { proxy_pass http://127.0.0.1:7080; proxy_http_version 1.1; # The node serves its WebSocket event stream on the same port; # without these the stream downgrades to a plain request and # subscriptions silently never deliver. proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection "upgrade"; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto $scheme; # Do NOT add CORS headers here — the node already sets them, and # two Access-Control-Allow-Origin headers on one response make # browsers reject it while curl sees a clean 200. proxy_read_timeout 300s; } }shell# The A record must already resolve for the world — certbot proves # control of the name over port 80. Check a public resolver, not your # own machine, whose cache can be stale: dig +short @8.8.8.8 openfiat.example.com ln -s /etc/nginx/sites-available/openfiat-node /etc/nginx/sites-enabled/ nginx -t && systemctl reload nginx curl -s http://openfiat.example.com/health # ok, before any certificate apt install -y certbot python3-certbot-nginx certbot --nginx -d openfiat.example.com # certbot edits the server block in place: it adds listen 443 ssl, the # certificate paths, and a redirect from :80. The location block and its # proxy headers carry over. Renewal installs itself as a systemd timer. # Do not hand-write a 443 block afterwards — certbot manages that one. # Then tell the network this node can be reached directly: # openfiat-node --public-rpc-url https://openfiat.example.com - 07
Execute-o como serviço
Sob systemd o nó reinicia após uma queda ou reboot, e ganha um período de encerramento longo o suficiente para o banco de dados esvaziar de forma limpa em vez de ser morto no meio de uma escrita.
openfiat-node.service# /etc/systemd/system/openfiat-node.service [Unit] Description=OpenFiat node Documentation=https://docs.openfiat.network After=network-online.target Wants=network-online.target [Service] Type=simple User=openfiat Group=openfiat ExecStart=/usr/local/bin/openfiat-node \ --ledger /var/lib/openfiat \ --identity /etc/openfiat/wallet.json \ --rpc-bind-address 0.0.0.0:7080 \ --gossip-bind-address /ip4/0.0.0.0/udp/4001/quic-v1 \ --entrypoint /ip4/84.32.223.111/udp/4001/quic-v1/p2p/12D3KooWK9hQ7TwbfvFiaAxUbRFCkdhS7iEpAJDnewNL1anyREQ1 \ --solana-rpc-url https://api.devnet.solana.com WorkingDirectory=/var/lib/openfiat Restart=on-failure RestartSec=5s # openfiat-node handles SIGTERM itself (graceful shutdown) rather than # needing systemd to force-kill it; this gives that shutdown path a # reasonable window before systemd escalates to SIGKILL. TimeoutStopSec=30s NoNewPrivileges=true ProtectSystem=strict ProtectHome=true ReadWritePaths=/var/lib/openfiat PrivateTmp=true # AF_NETLINK is required, not optional: binding a wildcard address makes # libp2p enumerate this host's interfaces, and that goes over a netlink # socket. Without it the QUIC listener fails and the gossip actor panics # while the HTTP thread survives — so systemd reports the unit active # and the node looks healthy while serving nothing. RestrictAddressFamilies=AF_INET AF_INET6 AF_UNIX AF_NETLINK [Install] WantedBy=multi-user.targetshelluseradd --system --create-home --home-dir /var/lib/openfiat --shell /usr/sbin/nologin openfiat install -m 755 openfiat-node /usr/local/bin/openfiat-node mkdir -p /etc/openfiat chown -R openfiat:openfiat /var/lib/openfiat systemctl daemon-reload systemctl enable --now openfiat-node journalctl -u openfiat-node -f - 08
Deixe-o alcançar
Em vez de reproduzir todo o histórico, um nó novo pode descobrir e importar um snapshot anunciado por um par do estado atual do mercado (OFS-1300) — métodos JSON-RPC reais, não uma ferramenta separada: getLatestSnapshot, getCheckpointHeight. Assinatura, versão do protocolo e raiz de estado, todos têm de corresponder antes de se confiar.
shell# Snapshot sync (OFS-1300) is real JSON-RPC, not a separate CLI — # a new node discovers and imports a peer-announced snapshot instead of # replaying all history: curl -s -X POST http://localhost:7080/rpc -H 'content-type: application/json' \ -d '{"jsonrpc":"2.0","id":1,"method":"getLatestSnapshot","params":{}}' curl -s -X POST http://localhost:7080/rpc -H 'content-type: application/json' \ -d '{"jsonrpc":"2.0","id":1,"method":"getCheckpointHeight","params":{}}' - 09
Verifique que está saudável
GET /health confirma que o processo está no ar; getChainStatus por JSON-RPC diz se é GossipOnly ou RpcConnected, e seu blockhash atual se for o último.
shell# Is it up, and which mode is it in? curl -s http://localhost:7080/health # ok curl -s -X POST http://localhost:7080/rpc -H 'content-type: application/json' \ -d '{"jsonrpc":"2.0","id":1,"method":"getChainStatus","params":{}}' # {"jsonrpc":"2.0","id":1,"result":{"mode":"GossipOnly","blockhash":null,"slot":null,"age_ms":null}} # ("RpcConnected" with a real blockhash once --solana-rpc-url is set) # The addresses your node is reachable at are in its own log — give one # of these to another operator as their --entrypoint: journalctl -u openfiat-node | grep "reachable at a new address" - 10
Já faz parte da rede
Não há um passo de "anunciar" separado — assim que um nó tem pares de bootstrap, ele propaga por gossip e é propagado automaticamente; ninguém o aprova. Fazer stake, publicar metadados no registro de serviços, ingressar em disputas e emitir votos de governança são ações separadas, guiadas por carteira, que um cliente realiza contra o nó em execução — veja o guia de participação relevante para cada uma.
Um nó faz stake de OPEN para se tornar um participante ativo. Mas o stake não compra reputação: um operador com desempenho ruim não pode compensar fazendo mais stake. A prioridade efetiva combina reputação, stake e o desempenho de rede medido.
- 11
Vigie-o
Os sinais que de fato predizem problema são os pares conectados, o modo da cadeia (GossipOnly vs RpcConnected) e a idade do blockhash. Alerte sobre esses e você saberá antes dos seus usuários.
prometheus.yml# /etc/prometheus/prometheus.yml — same port as everything else, # no separate metrics listener to configure on the node's own side. scrape_configs: - job_name: openfiat-node static_configs: - targets: ["127.0.0.1:7080"] - 12
Mantenha-o atual
Pare, troque o binário, inicie. Os nós atualizam um de cada vez, então a rede nunca precisa de uma parada coordenada, e os eventos de gossip perdidos são reproduzidos na inicialização.
shellsystemctl stop openfiat-node # SIGTERM, lets RocksDB flush # docker: docker compose pull node && docker compose up -d node install -m 0755 ./openfiat-node /usr/local/bin/ systemctl start openfiat-node # Missed gossip events replay automatically on start. journalctl -u openfiat-node -f - 13
Faça backup do que não pode ser regenerado
O estado do mercado sempre pode ser ressincronizado a partir de um snapshot. A carteira não pode ser regenerada. Os saldos e a custódia vivem na Solana, não no seu disco.
shell# Back up what cannot be re-derived. Marketplace state can always be # re-synced from a snapshot; the wallet cannot be regenerated. tar czf openfiat-wallet-$(date +%F).tar.gz /etc/openfiat/wallet.json # Authoritative financial state lives on Solana, not on the node's own # RocksDB volume.
Quando algo está errado
Nenhum par se conecta
A UDP 4001 está bloqueada, ou o --entrypoint aponta para um endereço que os pares não conseguem realmente alcançar — deve ser um multiaddr/IP estático, não um nome de host (o bootstrap por DNS não resolve). Seu próprio nó registra os endereços em que é alcançável assim que está escutando.
ss -lunp | grep 4001 && journalctl -u openfiat-node -n 100A sincronização nunca conclui
A importação do snapshot (OFS-1300) não terminou, ou nenhum par anunciou um snapshot recente o suficiente ainda — verifique getLatestSnapshot/getCheckpointHeight.
journalctl -u openfiat-node -n 200 --no-pager | grep -i snapshotO uso de disco continua crescendo
O RocksDB não compactou.
du -sh /var/lib/openfiat/*Assinaturas ou expirações rejeitadas
Desvio do relógio. Os registros carregam timestamps e expiração, então o relógio do host precisa estar correto.
chronyc trackingO que um nó deve expor
Isso é tudo o que o nó exporta hoje — contagem de pares, modo da cadeia e progresso de sincronização ainda não são métricas do Prometheus, apenas valores que você pode consultar por JSON-RPC (getChainStatus, getLatestSnapshot, getCheckpointHeight).
Infraestrutura
CPU · Memória · Disco · Throughput de rede
Protocolo (GET /metrics)
rpc_requests_total · rpc_errors_total
Hospedando a interface de usuário
O OpenFiat separa o protocolo de suas interfaces. Qualquer um pode hospedar uma interface web, um gateway móvel, um portal corporativo ou um mercado regional, e cada um deles alcança o mesmo mercado.
Independentemente da interface usada, cada participante interage com o mesmo mercado descentralizado.
Interface web oficial · Interfaces da comunidade · Interfaces de comerciante · Mercados regionais · Portais corporativos
A que uma interface se conecta
As interfaces não falam diretamente com a cadeia. Elas se conectam a um ou mais nós OpenFiat próximos, e trocam para outro nó se um ficar indisponível.
Superfície de API do nó
- MercadoBuscar anúncios · Criar anúncios · Atualizar anúncios · Remover anúncios
- NegociaçãoReservar anúncios · Sincronizar sessões de negociação · Enviar confirmações de pagamento
- InfraestruturaDescoberta de pares · Descoberta de gateways · Informações de snapshot · Inteligência de risco
- GovernançaDescoberta de propostas · Envio de votos · Informações de tesouraria
Todo nó compatível expõe a mesma superfície de API, então uma interface escrita contra um nó funciona contra todos.