Desenvolvimento Local em Detalhe
Desenvolvimento local em Solana não é "pular a rede e torcer". É uma escolha deliberada de fidelidade: quanto do estado da mainnet, da superfície RPC e do realismo multiparte você precisa para a pergunta que está respondendo hoje.
Esta página é o mapa conceitual da seção. Use-a para posicionar solana-test-validator, Surfpool, cloning, fixtures, logs locais, testes unitários LiteSVM e devnet em um continuum antes de seguir as páginas de receita.
Resumo
A maior parte do trabalho de programa e cliente deve começar em um cluster local na máquina. Você controla gênesis, airdrops, IDs de programa e reset do ledger. Nada compete com você por slots, e o CI pode reexecutar o mesmo gênesis a cada PR.
solana-test-validator (incluído no Agave / Solana CLI) é o cluster local padrão de nó único. Expõe JSON-RPC (padrão http://127.0.0.1:8899), faucet generoso e execução completa de programas BPF/SBF para que Anchor, CLI e clientes @solana/kit se comportem como clientes RPC remotos.
Quando precisar de layouts de produção, clone contas selecionadas no test validator ou use um workspace de fork da mainnet com Surfpool 0.12.0. Clones são snapshots estáticos na inicialização. Ferramentas de fork mantêm um overlay estilo ao vivo para que grafos DeFi continuem úteis sem listas infinitas de --clone.
Abaixo de RPC local completo está LiteSVM 0.6.x para testes unitários Rust em subsegundos sem cluster HTTP. Acima da localnet estão devnet e sondas na mainnet para demos compartilhadas, IDs de programa entre laptops e sinais fracos sobre efeitos de rede reais.
O trade-off é fixo. Mais rápido e determinístico significa menos realismo compartilhado. Mais realista significa mais custo de setup e estado externo instável. Escolha a menor fidelidade que ainda responda à pergunta.
Fundamentos
O que "local" significa em Solana
Um ambiente local é qualquer superfície de execução que não depende de um cluster público para inclusão. Isso inclui um validador local completo, um simulador de fork com RPC e um harness SVM em memória dentro de um binário de teste Rust.
Clientes ainda falam Solana: recent blockhashes, account metas, assinaturas, orçamentos de compute e logs de programa. Você não inventa uma API falsa. Você encolhe ou substitui o cluster atrás dos mesmos contratos de cliente.
Por que o local existe como loop de primeira classe
Clusters públicos punem iteração apertada. Faucets limitam taxa, programas compartilhados mudam sob você e cotas de RPC quebram o CI. O local mantém o loop interno compilar, carregar, enviar, fazer assert, resetar e preserva experimentos de autoridade de upgrade ou mint privados sem gastar SOL real.
As peças de uma stack local
| Peça | Papel |
|---|---|
| Agave / Solana CLI | Instala solana-test-validator, helpers de faucet, ferramentas de deploy e conta |
| Ledger local | Estado em disco em algo como test-ledger/ a menos que você resete |
| RPC + WebSocket | Como CLI, Anchor, carteiras e @solana/kit falam com o cluster |
| Faucet | SOL de teste ilimitado para aluguel e taxas |
| Caminho de carga de programa | Deploy, --bpf-program ou dump/load de binários .so |
| Caminho de seed de estado | Fixtures (--account), clones (--clone) ou hidratação de fork |
| Caminho de log | Stdout do validador, solana logs, meta de transação, contadores de CU |
| Runners de teste | anchor test, clientes TS/JS customizados, testes Rust LiteSVM |
Pins da toolchain para este guia
Trate versões como contrato da equipe. Este guia assume Agave 4.1.1, Solana CLI 3.0.10, Surfpool 0.12.0, LiteSVM 0.6.x, Anchor 0.32.1, Rust 1.91.1 e @solana/kit 7.0.0. Fixe CLI e Anchor como você fixa dependências em Cargo.toml.
Localnet vs "apenas testes unitários"
LiteSVM executa lógica de programa in-process para correção de instrução, layout de conta e matemática de PDA sem RPC. Não substitui wallet adapters, assinaturas WebSocket, UX de confirmação ou scripts multi-cliente que precisam de endpoint JSON-RPC real.
Mecânica
Pense no desenvolvimento local como um loop fechado: semear estado, apontar clientes para localhost, exercitar programas, observar logs, resetar ou mutar, repetir.
Loop de desenvolvimento local em ASCII
[ Origem ]
programa Rust (Anchor / nativo)
cliente TS/JS (@solana/kit, Anchor TS)
fixtures / listas de clone / config de fork
|
| build .so + gerar clientes / IDLs
v
+------------------+ opcional: testes unitários LiteSVM
| cargo / anchor |----> asserts SVM in-process (sem RPC)
| build |
+------------------+
|
| iniciar backend de cluster
v
+------------------------------------------+
| A) solana-test-validator |
| --reset, --bpf-program, --clone, |
| fixtures --account |
| B) Surfpool (workspace fork mainnet) |
+------------------------------------------+
|
| RPC http://127.0.0.1:8899 (típico)
| faucet para SOL local
v
+------------------+
| solana config |
| Anchor.toml |
| cliente RPC app |
+------------------+
|
| deploy / airdrop / enviar txs / rodar testes
v
+------------------+
| execução prog. |
| CPI em clones |
| mutações estado |
+------------------+
|
| logs, meta, CU, dumps de conta
v
+------------------+
| solana logs |
| confirm -v |
| asserts |
+------------------+
|
| pass -> promover para devnet / sondas mainnet
| fail -> corrigir, resetar ledger, apertar fixtures
v
[ próxima iteração ]
Estágio 1 - Build e identidade
Você compila bytecode do programa (.so) e fixa IDs de programa via keypairs e declare_id!. Clientes devem chamar o mesmo pubkey que o cluster carregou. Incompatibilidades parecem "conta não executável" ou chamadas a endereços vazios entre deploy, --bpf-program e overlays Surfpool.
Estágio 2 - Escolher um backend
solana-test-validator é o cluster padrão de nó único ajustado para velocidade de desenvolvedor: épocas curtas, inclusão imediata, restrições de ops relaxadas.
Surfpool é a opção moderna orientada a fork quando você precisa de estado em formato mainnet sem lista grande de clone. Hidrata a partir de RPC upstream da mainnet para simular contra grafos de programa realistas.
LiteSVM fica ao lado do caminho RPC para testes unitários puros de programa quando não precisa de HTTP, carteiras ou concorrência multi-cliente.
Estágio 3 - Semear estado
Gênesis local vazio funciona quando seu programa cria todas as contas. Trabalho de integração quase sempre precisa de seeds.
Fixtures são dumps JSON carregados na inicialização (--account): determinísticos, amigáveis ao git, ideais para CI. Clones buscam contas ao vivo no boot (--clone com --url), capturam layouts e bytecode reais, depois congelam até txs locais mutarem. Workspaces de fork (classe Surfpool) reduzem listar cada conta dependente para malhas DeFi ou de oráculo.
Semeie apenas o que suas instruções tocam. Tempo de inicialização e carga cognitiva escalam com o tamanho do seed.
Estágio 4 - Apontar o mundo para o cluster
CLI, URL do provider Anchor, RPC do frontend e RPC customizado da carteira devem concordar. Falha clássica é anchor test implantando na devnet enquanto a CLI faz airdrop em localhost.
Para sessões longas, inicie o validador você mesmo e anexe testes. Para CI, prefira --reset a cada job para que deriva de ledger não instabilize a suíte.
Estágio 5 - Exercitar e observar
Envie transações como faria remotamente. Inclusão local é rápida, então o feedback é lógica de programa e setup, não sorte de mempool.
Inicie assinantes de log antes do tráfego. Use solana logs, confirms verbosos e meta para logMessages e computeUnitsConsumed. Simulação local ilimitada supera RPCs públicos com rate limit para diagnóstico.
Estágio 6 - Resetar ou promover
Reset para determinismo. Persista ledger apenas para sessões exploratórias longas e documente essa escolha. Promova quando precisar de IDs de demo compartilhados, UX pública de carteira, coordenação multi-equipe ou sondas na mainnet com taxas reais.
Avançado
Use esta tabela ao escolher ambiente, não ao argumentar qual ferramenta é "melhor" em abstrato.
| Ambiente | Fidelidade | Velocidade | Melhor para | Fraco em |
|---|---|---|---|---|
| Testes unitários LiteSVM 0.6.x | Lógica de programa + contas injetadas | Subsegundos | Testes de instrução Rust, bordas PDA/math, micro-gates de CI | Clientes JSON-RPC completos, carteiras, apps multi-processo |
| solana-test-validator (simples) | Cluster local completo, gênesis vazio ou fixture | Boot rápido, inclusão rápida | Loop padrão Anchor/CLI, integração de cliente, CI | Grafos de pool mainnet ao vivo sem seeds |
| test-validator + clones/fixtures | Cluster completo + estado congelado em formato produção | Médio (custo de fetch de clone) | CPI em programas reais, layouts fixos de oráculo/mint | Grafos de dependência enormes; preços obsoletos após boot |
| Surfpool 0.12.0 | Realismo de fork mainnet com overlay local | Mais pesado que validador simples | Sims DeFi, metas de conta complexas, dry-runs pré-mainnet | CI mais leve; velocidade pura de unit; demos zero-dependência |
| Devnet | Cluster público compartilhado | Mais lento, fricção faucet/RPC | Demos de carteira, IDs compartilhados, QA multi-laptop | CI determinístico, airdrops ilimitados, estado estável de terceiros |
| Mainnet (sondas mínimas) | Realidade de produção | Caro, risco irreversível | Landing sob carga, taxas reais, verificações finais | Desenvolvimento diário, experimentação ampla |
Como a escada se compõe
Uma equipe saudável usa mais de um degrau. LiteSVM pega regressões de lógica em milissegundos. Validador local pega fiação de cliente e CPI. Surfpool ou clones ricos pegam surpresas de layout de produção. Devnet compartilha um deploy. Sondas na mainnet validam taxas e landing que você não pode falsificar.
Pular degraus cria falsa confiança. LiteSVM verde sozinho não prova UX de confirmação de carteira. Localnet verde sozinho não prova mercados de priority fee.
Cloning vs fork vs fixtures
Fixtures são artefatos escritos ou exportados: mais reproduzíveis, menos "ao vivo". Clones são fixtures automatizados buscados uma vez na inicialização: reproduzíveis na sessão, depois derivam conforme mercados se movem. Ferramentas estilo fork ficam mais perto da mainnet para simulação, custam mais recursos, dependem da qualidade do RPC upstream e ainda não garantem inclusão ou realidade de MEV.
Logs, fiação e observabilidade
O local vence porque observabilidade é gratuita: transmita logs, re-simule, faça dump de contas sem cotas. Prefira local para diagnóstico, depois reproduza caso mínimo na devnet quando precisar de artefato compartilhado.
URL do provider em Anchor.toml faz parte do design de ambiente, incluindo se anchor test possui o validador ou se anexa ao seu. Clientes em @solana/kit 7.0.0 tratam RPC local como qualquer endpoint HTTP. A parte difícil é higiene entre shells, .env e configurações de carteira, não o formato da chamada SDK.
Equívocos Comuns
Equívoco: Localnet é um brinquedo que não conta como Solana real.
Executa o mesmo modelo de programa e regras de conta. Falta dinâmica de consenso multi-validador, congestionamento público e adversários econômicos compartilhados.
Equívoco: Um ambiente pode servir testes unitários, CI, demos e dry-runs mainnet.
Perguntas diferentes precisam de fidelidade diferente. Forçar tudo na devnet ou tudo no LiteSVM falha de formas opostas.
Equívoco: Clonar a mainnet uma vez mantém seu cluster local "sincronizado".
Clones são snapshots. Preços e reservas divergem imediatamente. Atualize, reexporte fixtures ou use ferramentas de fork quando frescor importa.
Equívoco: Surfpool substitui solana-test-validator para todo trabalho.
Surfpool brilha em simulação de fork mainnet. Test-validator simples permanece o padrão leve para loops de programa e muitos jobs de CI.
Equívoco: Simulação local bem-sucedida significa que uma transação mainnet vai fazer landing.
Sucesso local significa execução contra aquela visão de estado, não capacidade de líder, mercados de taxa ou propagação real.
Equívoco: Congestionamento da devnet equivale ao da mainnet.
Devnet ensina campos de taxa e UX de confirmação. É proxy fraco para mercados de prioridade e MEV da mainnet.
Equívoco: Você deve clonar toda conta que talvez precise.
Conjuntos mínimos de seed iniciam mais rápido e falham mais claro. Expanda quando logs mostrarem conta faltando.
Equívoco: Fixtures são polimento opcional.
Sem fixtures ou resets, estado local vira conhecimento tribal e CI instável.
Equívoco: LiteSVM é só para quem odeia TypeScript.
É a ferramenta certa para velocidade de unit de programa. Mantenha testes de integração TS/JS em RPC de validador quando essa é a superfície do produto.
FAQs
Qual é o melhor padrão para trabalho diário de programa?
solana-test-validator com --reset para execuções limpas, mais fixtures ou conjunto pequeno de clone apenas quando seus testes precisarem.
Quando devo introduzir Surfpool?
Quando clones estáticos viram fardo de manutenção ou você precisa de simulação contínua de fork mainnet para grafos estilo DeFi. Permaneça no test-validator para loops mínimos só de programa.
Como LiteSVM difere de solana-test-validator?
LiteSVM é SVM in-process para testes Rust rápidos sem HTTP. O test validator é cluster local completo com RPC, faucet e acesso multi-cliente.
Preciso de devnet se localnet funciona?
Sim para demos compartilhadas, IDs de programa multi-pessoa e alguns fluxos de carteira. Não como padrão para todo PR e toda unidade de trabalho.
Quais portas importam para localnet?
RPC padrão é comumente 8899, com portas relacionadas de gossip/WebSocket e faucet configuráveis. Aponte toda ferramenta para a mesma URL de RPC que você realmente iniciou.
Por que meus testes passam localmente e falham na devnet?
Causas comuns são suposições obsoletas sobre airdrops, IDs de programa, deploys de terceiros, latência RPC e commitment de confirmação. Local também esconde pressão de mercado de taxas.
O CI deve usar clones da mainnet a cada PR?
Prefira fixtures commitados e --reset para determinismo. Se clonar, faça cache com cuidado e mantenha o conjunto pequeno para CI confiável sob limites de RPC.
Como funcionam logs de programa localmente?
Programas emitem logs na meta da transação; solana logs transmite. Inicie o assinante antes de enviar transações para não perder a janela de falha.
Carteiras podem falar com localhost?
Muitas podem via RPC customizado para http://127.0.0.1:8899, mas suporte varia. Devnet costuma ser mais fácil para demos externas de carteira.
O que `--bpf-program` oferece versus `anchor deploy`?
Pré-carregar no gênesis torna reinicializações e CI determinísticos. Deploy é melhor ao iterar fluxos de upgrade ou combinar com sessão longa de ledger local.
O timing de slot local é igual ao da mainnet?
Não. Test validators otimizam para throughput de desenvolvedor. Não trate cadência de slot local como benchmark de latência de produção.
Como fixtures se relacionam com cloning?
Cloning é fetch automatizado para estado de inicialização. Fixtures são arquivos duráveis que você versiona. Ambos semeiam contas; fixtures costumam ser melhores para verdade compartilhada de CI.
Onde o validador embutido do Anchor se encaixa?
anchor test pode iniciar um validador para você. Use isso para suítes em um comando. Gerencie o validador você mesmo para flags customizadas, sessões longas ou clientes paralelos.
Surfpool gasta SOL da mainnet?
Simulação e execução local com fork não são landings na mainnet. Você ainda precisa de RPC upstream confiável para hidratar estado. Envios reais na mainnet são passo separado.
Como um PR deve documentar a escolha de ambiente?
Registre URL do cluster, IDs de programa, fontes de fixture ou clone e pins da toolchain (Agave 4.1.1, Anchor 0.32.1, Surfpool 0.12.0 quando usado).
Relacionado
- Local Dev Basics - loop prático e exemplos iniciais
- solana-test-validator - flags, ciclo de vida e portas
- Surfpool - simulação local com fork da mainnet
- Cloning Mainnet Accounts - snapshot de contas de produção na localnet
- Loading Programs & Fixtures - seeds reproduzíveis e pré-carregamento de programa
- Localnet vs Devnet Workflow - árvore de decisão para escolha de ambiente
- Local Logs & Debugging - logs, CU e inspeção de falhas
- Local Dev Best Practices - checklist condensado de práticas
Versões da stack: Esta página foi escrita para Agave 4.1.1, Solana CLI 3.0.10, Anchor 0.32.1, Rust 1.91.1, @solana/kit 7.0.0, Surfpool 0.12.0 e LiteSVM 0.6.x.