Pontos-chave do Runtime Sealevel
Sealevel é o runtime paralelo da Solana para programas on-chain: agenda trabalho a partir de acesso declarado a contas, mede compute e mantém lógica de programa separada de estado durável.
Esta página é o mapa conceitual de Programs & Sealevel Runtime - bytecode executável, entrypoint do SVM, locks de conta, concorrência, orçamentos de compute e loaders no Agave 4.1.1.
Resumo
- Programas Solana são executáveis stateless; Sealevel os executa contra contas que a transação listou antecipadamente, bloqueando essas contas para que trabalho não sobreposto possa prosseguir em paralelo.
- Por que importa: Quase toda escolha de design - PDAs, forma de instrução, limites de CU, upgrades - segue de como o runtime bloqueia contas e mede compute, não de como você armazenaria dados dentro de um contrato.
- Conceitos-chave: conta de programa executável, sBPF / SVM, entrypoint, AccountMeta, locks read/write, compute units (CU), upgradeable loader / ProgramData.
- Quando usar este modelo: Projetar layouts de estado, raciocinar sobre throughput sob contenção, depurar contas ausentes ou falhas de CU, ou ensinar execução Solana a colegas de runtime sequencial.
- Limitações / trade-offs: Paralelismo não é automático - uma conta writable compartilhada serializa trabalho, e todo caminho pesado custa CU dentro de um orçamento finito de transação.
- Tópicos relacionados: Noções Básicas de Programas, O SVM e sBPF, Execução Paralela Sealevel, Locks de Conta e Conflitos, Compute Units e Orçamentos, Programas Stateless.
Fundamentos
Um programa na Solana é uma conta executável: seus dados são bytecode que o runtime pode executar, não registros de aplicação que você muta instrução por instrução.
Estado durável vive em outras contas que o programa possui (ou pode ler). O binário não embute um banco de dados crescente de usuários, saldos ou mapeamentos.
Você escreve lógica em Rust (ou outra linguagem suportada), compila para sBPF (Solana BPF) e faz deploy do shared object para validators carregarem.
O SVM (Solana Virtual Machine) em validators Agave executa esse sBPF, impõe regras de ownership, mede compute e atende syscalls.
Uma instrução nomeia um program ID, uma lista de contas e uma fatia opaca de bytes de instruction-data.
O entrypoint do programa é a função única que o runtime chama para toda instrução àquele programa.
Na forma nativa, o entrypoint recebe aproximadamente program_id, uma fatia de valores AccountInfo e os dados da instrução. A macro #[program] do Anchor gera esse entrypoint e faz dispatch em um discriminador de 8 bytes para seus handlers.
Toda instrução deve declarar AccountMeta para cada conta que o runtime tocará: chave pública, is_signer e is_writable.
Essas flags são pedidos de lock que Sealevel usa antes de qualquer bytecode executar, não dicas opcionais no client.
Mecânica e interações
A execução começa fora do seu programa: uma transação é montada com uma ou mais instruções, cada uma listando program ID, contas e dados, depois assinada e enviada com blockhash recente.
O runtime valida assinaturas, saldo do fee payer e que toda conta aparecendo em qualquer instrução está na lista de contas da transação com meta flags consistentes.
Antes de agendar, Sealevel deriva locks desses metas: conta writable precisa de lock de escrita exclusivo; conta readonly precisa de lock de leitura compartilhado.
Múltiplas transações podem manter locks de leitura na mesma conta concorrentemente.
Lock de escrita exclui outros escritores e leitores na mesma conta durante o trabalho conflitante.
Essa regra produz o comportamento central de agendamento: transações cujos conjuntos de contas bloqueadas não conflitam podem executar em paralelo; sobreposições write-write e write-read devem serializar.
Chaves de conta:
A = PDA de posição Alice (writable nas txs de Alice)
B = PDA de posição Bob (writable nas txs de Bob)
G = Vault global (writable quando alguém toca)
C = Config (readonly em ambos designs)
Locks disjuntos - podem executar concorrentemente:
Tx1: write(A), read(C)
Tx2: write(B), read(C)
-> locks: A exclusivo, B exclusivo, C compartilhado -> sem conflito
Locks sobrepostos - devem serializar:
Tx3: write(G), write(A), read(C)
Tx4: write(G), write(B), read(C)
-> ambas precisam de G exclusivo -> Tx3 e Tx4 não podem executar em paralelo
Dentro de uma transação agendada, instruções executam em ordem; dentro de uma instrução o SVM carrega o programa, chama o entrypoint e passa apenas as contas que a instrução listou.
Seu handler pode ler dados de conta, escrever apenas contas que possui (e que foram marcadas writable), transferir lamports sob regras usuais e emitir CPIs para outros programas - mas toda conta que um CPI precisa já deve estar no conjunto declarado da transação.
Enquanto o entrypoint executa, o runtime mede compute units (CU). Syscalls, logging, deserialização e aritmética desenham do orçamento em nível de transação.
Na Solana moderna (incluindo Agave 4.1.1), o orçamento de compute padrão da transação é cerca de 1.400.000 CU a menos que uma instrução Compute Budget aumente (ou diminua) o limite dentro dos caps do protocolo.
Se qualquer caminho exceder o orçamento restante, a transação falha e mudanças de estado daquela transação não são commitadas.
CU mede trabalho permitido; priority fees influenciam inclusão sob carga - controles relacionados, trabalhos diferentes.
Após sucesso, atualizações de conta são commitadas sob os locks já mantidos; transações falhas liberam locks sem aplicar essas escritas.
Upgrades ficam ao lado da execução, não dentro do estado da app. Com o BPF Upgradeable Loader, a conta program ID aponta para uma conta ProgramData que mantém bytecode.
Uma upgrade authority (se definida) pode fazer deploy de novo .so no ProgramData; limpar essa authority congela o caminho de upgrade do loader.
Como programas são stateless, upgrades trocam lógica sem migrar armazenamento do binário - contas de dados permanecem, então código novo deve permanecer compatível com layout ou enviar migração explícita.
Considerações avançadas e aplicações
A decisão de design de maior alavancagem sob Sealevel é o que você marca writable.
Uma única conta writable global - config "mutex", ledger compartilhado, contador global que todo usuário deve tocar - força toda transação contendente em um único arquivo, não importa quão eficiente o sBPF seja.
Fazer shard de estado para que cada usuário (ou cada ordem, posição ou sessão) tenha sua própria PDA mantém a maioria das transações em chaves disjuntas para o scheduler executá-las juntas.
| Design | Contas writable por ação de usuário | Paralelismo sob carga | Quando se encaixa | Custo de errar |
|---|---|---|---|---|
| PDAs por usuário / entidade | Geralmente PDA daquele usuário (+ contas de token conforme necessário) | Alto - usuários diferentes raramente bloqueiam as mesmas chaves | Perfis, posições, inventários, sessões | Um pouco mais de contas para passar e criar |
| Tabelas shardadas (muitas PDAs por chave de shard) | Uma PDA de shard entre muitas | Alto se carga se espalha entre shards | Índices de alto throughput, order books, filas | Chaves de shard quentes ainda serializam essa fatia de tráfego |
| Config global (readonly em caminho quente) | Nenhuma para config se só leitura | Leitores compartilham lock da config | Parâmetros, taxas, feature flags | Marcar config writable em toda tx mata paralelismo |
| Conta mutex global (sempre writable) | A mesma conta global para todos | Baixo - essencialmente sequencial naquela chave | Ops admin raras, invariantes globais que devem serializar | Teto de throughput igual a um escritor por vez |
| Híbrido: caminho quente shardado, caminho frio global | PDA de usuário no caminho quente; global só em admin/settle | Caminho quente escala; caminho admin serializa intencionalmente | Mercados que liquidam contra vault compartilhado em agenda | Acidentalmente colocar vault no caminho quente |
Prefira readonly sempre que não mutar: uma config PDA compartilhada marcada readonly permite que muitas transações mantenham locks de leitura concorrentes.
Mantenha conjuntos writable mínimos e previsíveis para clients construírem listas de contas e o grafo de locks permanecer esparso.
Observe CU da mesma forma que observa locks: deserialização grande de conta, logging verboso msg! e loops sem limite queimam orçamento e podem empurrar caminhos comuns em direção ao teto padrão de ~1.400.000 CU.
Solicite limite maior com instrução Compute Budget quando simulação mostrar necessidade; ainda otimize o caminho quente para não pagar priority fee por desperdício.
Pense em loaders em produção: retenha upgrade authority apenas enquanto precisar, use verifiable builds e trate upgrades de ProgramData como processo de change-control - comprometimento de authority é risco de reescrita total de código.
Ao testar em stacks alinhados ao Agave 4.1.1 (CLI 3.0.10, Anchor 0.32.1, LiteSVM 0.6.x, Surfpool 0.12.0), exercite CU e casos de contas contidas antes que tráfego mainnet o faça.
Equívocos comuns
- "Programas mantêm estado de aplicação como contratos EVM." Programas mantêm bytecode executável; estado de aplicação vive em contas separadas que o programa possui - veja Programas Stateless.
- "Sealevel paraleliza toda transação automaticamente." Apenas transações com conjuntos de lock não conflitantes executam juntas; contas writable compartilhadas forçam serialização.
- "Se duas transações só leem a mesma conta, devem esperar." Múltiplos leitores podem compartilhar lock de leitura; conflitos aparecem quando pelo menos um lado precisa de lock de escrita na mesma chave.
- "O programa pode puxar qualquer conta que quiser em runtime." Toda conta deve aparecer na lista declarada da transação com flags signer/writable corretas antes da execução começar.
- "Exceder compute só falha uma instrução." Compute é medido contra orçamento da transação; esgotamento falha a transação e reverte seus efeitos.
- "CU padrão é ilimitado até eu definir orçamento." Há teto padrão por transação (cerca de 1.400.000 CU na Solana moderna); você pode solicitar limite diferente dentro dos limites do protocolo via instruções Compute Budget.
- "is_writable é opcional se meu código só escreve às vezes." Meta flags definem locks e autorização para escritas; subdeclarar writable ou contas ausentes falha em runtime ou impede mutações pretendidas.
- "Upgrade do programa reescreve dados de conta do usuário." Upgradeable loader troca bytecode no ProgramData; contas de dados existentes permanecem como estão a menos que você envie lógica de migração.
- "CPI me deixa descobrir contas callee dinamicamente sem listá-las." CPI ainda exige que toda conta necessária tenha sido fornecida na lista de contas da transação externa.
- "Uma conta grande é mais simples e tão rápida." Pode ser mais simples de codificar, mas vira mutex global sob Sealevel e limita throughput a um escritor por vez.
FAQs
O que exatamente é um programa Solana sob Sealevel?
Uma conta executável cujos dados são bytecode sBPF que o SVM pode executar. É invocada por instruções que nomeiam seu program ID e passam contas mais instruction data.
Onde meu estado de app fica se o programa é stateless?
Em contas de dados owned pelo seu programa (frequentemente PDAs). O programa lê e escreve essas contas quando passadas e marcadas apropriadamente.
O que o entrypoint recebe?
O program ID, uma fatia de account infos para as contas listadas na instrução e os bytes de instruction data. Frameworks como Anchor 0.32.1 geram esse entrypoint e fazem dispatch para handlers tipados.
Por que clients devem declarar is_signer e is_writable?
Essas flags AccountMeta dizem ao runtime quem autorizou a transação e quais contas precisam de locks de escrita exclusivos versus locks de leitura compartilhados. Flags erradas causam falhas ou privilégios de escrita ausentes.
Quando duas transações podem executar ao mesmo tempo?
Quando seus locks necessários não conflitam - tipicamente quando tocam conjuntos writable disjuntos e contas compartilhadas são readonly para todos os leitores concorrentes. Veja Execução Paralela Sealevel.
Quais conflitos de lock forçam serialização?
Write-write na mesma conta, e write-read na mesma conta. Dois leitores puros da mesma conta não precisam serializar entre si. Detalhes em Locks de Conta e Conflitos.
Qual orçamento de compute padrão devo assumir?
Na Solana moderna incluindo Agave 4.1.1, planeje em torno de orçamento de compute padrão de transação de cerca de 1.400.000 CU a menos que instruções Compute Budget definam limite diferente dentro dos limites do protocolo.
O que acontece se minha instrução usa compute units demais?
A transação falha com erro de orçamento de compute e não commita mudanças de estado daquela transação. Simule, meça logs (consumed) e otimize ou solicite limite maior. Veja Compute Units e Orçamentos.
Como Rust, sBPF e SVM se relacionam?
Você compila Rust para sBPF com toolchain Solana/Agave (cargo build-sbf / Anchor build). Validators executam esse bytecode no SVM sob regras de agendamento e medição do Sealevel. Veja O SVM e sBPF.
Como funcionam programas upgradeable?
O BPF Upgradeable Loader mantém conta de programa que aponta para ProgramData com bytecode. Upgrade authority pode fazer deploy de novo bytecode; remover authority congela esse caminho de upgrade.
Upgrade muda meus endereços PDA?
Não. Endereços PDA derivam de program ID e seeds. Program ID permanece o mesmo entre upgrades do mesmo programa deployado; apenas bytecode no ProgramData muda.
Como devo projetar contas para máximo paralelismo?
Dê a cada ator ou entidade independente sua própria conta writable (comumente PDA), mantenha contas globais readonly em caminhos quentes e evite uma conta writable única que todo usuário deve tocar.
Posso mutar conta que meu programa não possui?
Não para escritas arbitrárias de dados - apenas o programa owner pode modificar dados de conta. Outros programas interagem via CPI no owner (por exemplo SPL Token) com contas e signers corretos.
CPIs têm orçamento de compute separado?
CPIs consomem CU do mesmo orçamento de transação. Chamadas aninhadas ainda desenham do pool compartilhado; pilhas de CPI profundas ou pesadas precisam de orçamento e simulação.
Como este modelo muda sob Alpenglow ou outro trabalho de consenso?
Latência de confirmação pode mudar, mas o modelo mental de programa - contas declaradas, locks, executáveis stateless, medição de CU - permanece Sealevel como descrito aqui.
Relacionados
- Noções Básicas de Programas - o que é um programa e como é invocado
- O SVM e sBPF - alvo de compilação e máquina virtual
- Execução Paralela Sealevel - agendamento de transações não conflitantes
- Locks de Conta e Conflitos - regras de lock read/write em detalhe
- Compute Units e Orçamentos - medição, limites e otimização
- Programas Stateless - por que lógica e estado permanecem separados
- O Entrypoint do Programa - entrypoint, fatia de contas, instruction data
- Loaders de Programa e Upgradeability - upgradeable loader e ProgramData
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.