Execução de Programas

Resumo

Os programas são compilados para sBPF via LLVM e executados numa VM isolada com um orçamento de 1,4 M CU por transação. O runtime armazena em cache até 512 programas compilados, fornece syscalls para logging, CPI, criptografia e memória, e atrasa novos deployments em 1 slot.

Compilação

A Solana usa LLVM para compilar programas em binários ELF contendo o Solana Bytecode Format (sBPF). O binário ELF é armazenado onchain numa conta executável.

sBPF é a variante personalizada da Solana do bytecode eBPF, adaptada para o runtime da Solana. Não é eBPF padrão e possui modificações específicas da Solana.

Escrever programas

Os programas Solana são escritos principalmente em Rust usando uma das três abordagens:

Consulte Cross-Program Invocations para conceitos e exemplos de CPI que se aplicam a todas essas abordagens.

Modelo de execução de programas

Quando uma transação é processada, o runtime executa cada instrução sequencialmente por meio de process_message(). Para cada instrução, o runtime:

  1. Prepara o contexto da instrução. Chama prepare_next_top_level_instruction() para mapear os índices de conta da instrução, definir flags de signatário e de escrita, e configurar o TransactionContext.

  2. Verifica os precompiles. Se o programa for um precompile, o runtime chama process_precompile(), que ainda empurra e retira um frame de pilha (via push() e pop()) mas ignora a VM sBPF e a busca no cache de programas, executando código nativo diretamente.

  3. Empurra um frame de pilha. (Os passos 3-6 ocorrem dentro de InvokeContext::process_instruction() e process_executable_chain(), chamados a partir de process_message().) Chama push() em InvokeContext, que incrementa a altura da pilha de instruções e aplica a regra de reentrância: um programa só pode reingressar em si mesmo se o chamador imediato (o programa no topo atual da pilha de instruções) for o mesmo programa. A autorrecursão profunda (A -> A -> A) é permitida, sujeita aos limites de profundidade de pilha. Outros padrões de reentrância (ex.: A chama B que chama A) retornam InstructionError::ReentrancyNotAllowed.

  4. Resolve o programa. O runtime chama process_executable_chain() que determina o loader. Se o proprietário do program account for o native loader, o programa é um builtin e sua função de entrypoint é consultada diretamente do ProgramCacheForTxBatch. Se o proprietário for um dos BPF loaders (bpf_loader_deprecated, bpf_loader, bpf_loader_upgradeable ou loader_v4), o próprio entrypoint builtin do loader é invocado.

  5. Executa o programa BPF. Para programas BPF, o entrypoint do loader busca o executável compilado no cache de programas. A função execute() então:

    • Serializa os dados da conta num buffer de parâmetros plano
    • Cria a VM sBPF com regiões de pilha, heap e memória
    • Executa o código compilado, consumindo unidades de computação durante a execução. Retorna ComputationalBudgetExceeded se o orçamento for excedido.
    • Desserializa os dados da conta do buffer de volta ao estado da conta
  6. Retira o frame de pilha. Chama pop() que verifica se a instrução não violou as regras de contabilidade do runtime (os saldos de lamport estão equilibrados, as contas somente leitura não foram modificadas, os tamanhos dos dados das contas estão dentro dos limites).

  7. Acumula unidades de computação. As unidades de computação consumidas pela instrução são adicionadas ao total da transação via saturating_add.

Cache de programas

O runtime mantém um ProgramCache global que armazena programas verificados e compilados. Ele é ciente do fork-graph e lida com regras de visibilidade de deployment, evicção e recompilação no limite de epoch.

Tipos de entrada no cache

Cada programa em cache possui um ProgramCacheEntryType que determina seu comportamento em tempo de execução:

TipoDescrição
LoadedPrograma verificado e compilado, pronto para execução.
BuiltinPrograma nativo compilado no binário do validator (System, Stake, Vote, etc.). Não armazenado onchain.
UnloadedPrograma previamente verificado cujo executável compilado foi removido da memória para liberar espaço. Ainda rastreia estatísticas de uso. Pode ser recarregado sem reverificação.
FailedVerificationTombstone para programas que não passaram no verificador sBPF com o conjunto de funcionalidades atual. Pode tornar-se Loaded se as ativações de funcionalidades alterarem as regras de verificação.
ClosedTombstone para programas que foram explicitamente encerrados ou nunca implantados. Também usado para contas (como contas de buffer) que pertencem a um loader mas não contêm código executável.
DelayVisibilityTombstone sintético retornado por ProgramCacheForTxBatch::find() quando uma entrada Loaded existe mas ainda não está em vigor (seu effective_slot está no futuro). Nunca armazenado diretamente no cache.

Atraso de visibilidade

Programas recém-implantados ou atualizados não entram em vigor imediatamente. A constante DELAY_VISIBILITY_SLOT_OFFSET é 1, o que significa que um programa implantado no slot N entra em vigor no slot N+1. Durante o slot de implantação, qualquer tentativa de invocar a nova versão retorna DelayVisibility, fazendo com que o runtime reporte "Program is not deployed."

Política de evicção

O cache comporta até MAX_LOADED_ENTRY_COUNT (512) entradas de programas compilados. Quando o limite é atingido, os programas menos utilizados são removidos para o estado Unloaded. O uso é rastreado por tx_usage_counter (incrementado cada vez que uma transação referencia o programa) e latest_access_slot.

Recompilação no limite de epoch

Se uma ativação de funcionalidade alterar os ProgramRuntimeEnvironments no limite de um epoch, todos os programas em cache são recompilados contra o novo ambiente.

Dados de retorno

Os programas podem definir dados de retorno via a syscall sol_set_return_data. Os dados são armazenados numa TransactionReturnData estrutura em nível de transação que contém os bytes de dados e o program_id do programa cuja instrução chamou a syscall. O tamanho máximo é de 1.024 bytes (MAX_RETURN_DATA).

Is this page helpful?

Índice

Editar Página
© 2026 Fundação Solana. Todos os direitos reservados.