Why Transactions Fail to Land
Transações falham em aterrissar quando blockhashes expiram, orçamentos de compute se esgotam, priority fees são muito baixas ou o envio via RPC nunca chega a um leader.
Receita
Cartão de receita para referência rápida - pronto para copiar e colar.
solana confirm -v <SIGNATURE>
solana transaction <SIGNATURE> --output json-compact | jq '.meta.err, .meta.logMessages'const sim = await rpc.simulateTransaction(wireTx, { sigVerify: false }).send();
console.log(sim.value.err, sim.value.unitsConsumed);Quando usar:
- Usuários reportam transações pendentes "travadas".
- Simulação tem sucesso, mas envio na mainnet nunca confirma.
- Falhas intermitentes durante mints de NFT ou airdrops.
- Post-mortem após picos de incidentes.
Exemplo Prático
import { createSolanaRpc } from "@solana/kit";
const rpc = createSolanaRpc(process.env.RPC_URL!);
const status = await rpc.getSignatureStatuses([signature]).send();
const value = status.value[0];
console.log({
confirmationStatus: value?.confirmationStatus,
err: value?.err,
slot: value?.slot,
});
const tx = await rpc
.getTransaction(signature, { encoding: "json", maxSupportedTransactionVersion: 0 })
.send();
console.log("landed err:", tx?.value?.meta?.err);
console.log("logs tail:", tx?.value?.meta?.logMessages?.slice(-5));O que isso demonstra:
getSignatureStatusesmostra se a assinatura é desconhecida (descartada) vs falhou vs confirmada.- Txs que aterrissaram com falha incluem erros de programa em meta.
- Assinatura desconhecida frequentemente significa nunca incluída antes da expiração do blockhash.
Aprofundamento
Como funciona
- Leaders priorizam transações por fee e compute price durante congestionamento.
- Recent blockhash na transação expira após ~150 slots (~60-90s de relógio).
- Medidor de CU interrompe execução quando o limite é excedido - transação falha on-chain.
- RPC pode aceitar
sendTransaction, mas o validador descarta a tx se estiver subprecificada.
Categorias de falha
| Sintoma | Causa provável | Direção de correção |
|---|---|---|
| Assinatura não encontrada | Descartada / blockhash expirado | Reconstruir tx, priority fee maior |
| Erro de programa em meta | Bug de lógica | Corrigir programa ou contas |
| CU excedido | Limite muito baixo | Aumentar compute budget |
| Blockhash não encontrado | Muito antigo | Blockhash novo + retry |
Notas bash
# Check if still valid blockhash age at send time - compare current slot to tx slot in logs
solana slotErros comuns
- Assumir que RPC OK significa aterrissagem -
sendTransactionretorna assinatura antes da inclusão. Correção: rastreie status de confirmação separadamente. - Priority fee zero na mainnet congestionada - tx fica na fila. Correção: fees dinâmicas (Setting Priority Fees).
- 200k CU padrão muito baixo - txs complexas falham na simulação. Correção: estime CU (Estimating Compute Units).
- Envio único via RPC - perda de pacote ou peer ruim. Correção: rebroadcast com retries (Retries & Blockhash Management).
- Transação legacy oversized - excede tamanho de pacote. Correção: v0 + ALTs (Address Lookup Tables in Practice).
Alternativas
| Alternativa | Use quando | Não use quando |
|---|---|---|
| Jito bundles | Aterrissagem em alta contenção | Testes simples em devnet |
| Durable nonce | Fluxo de assinatura longo | Txs normais com blockhash fresco |
| Envio via RPC privado | Melhor propagação | MVP sensível a custo |
| Janela de tráfego menor | Mitigação operacional | UX em tempo real para usuário |
FAQs
Falha na simulação garante que não aterrissa?
Geralmente - mas condições de corrida são raras; trate simulação como sinal forte.
Por que sucesso em devnet mas não na mainnet?
Congestionamento na mainnet e maior contenção de account lock - fees e CU diferem.
O que é expiração de blockhash?
Recent blockhash da transação deve estar na fila de recent blockhashes conhecida pelos validadores - hashes obsoletos rejeitam inclusão.
Uma tx pode aterrissar e depois falhar?
Sim - incluída no bloco com falha de programa meta.err; você ainda paga a base fee.
Como detectar txs descartadas?
getSignatureStatuses retorna null para assinatura desconhecida após período de espera.
Priority fees garantem aterrissagem?
Não - melhoram probabilidade sob contenção; erros de programa e CU ainda falham.
Papel do skipPreflight?
false captura erros cedo; true envio mais rápido, mas mais txs ruins descartadas.
Relevância de transação versionada?
v0 habilita ALTs para caber listas grandes de contas - limites de tamanho legacy causam descartes silenciosos.
Jito vs priority fee?
Tips Jito pagam validadores no caminho de bundle; priority fees são compute unit price nativo - complementares.
Onde está o pipeline completo de aterrissagem?
Relacionados
- Estimating Compute Units - falhas de CU
- Setting Priority Fees - estratégia de fee
- Retries & Blockhash Management - tratamento de expiração
- Priority Fee & Simulation APIs - ferramentas RPC
Versões da stack: Esta página foi escrita para Agave 4.1.1, Solana CLI 3.0.10, Anchor 0.32.1, anchor-lang 0.32.1, Rust 1.91.1, @solana/kit 7.0.0, Surfpool 0.12.0 e LiteSVM 0.6.x.