O Kora é um workspace Rust com três crates:
kora-libcontém a lógica principal e o servidor RPC,kora-clicompila o bináriokoraque os operadores executam, ekora-deployé uma ferramenta especializada de implantação de programas, com versionamento próprio. Tudo o que está abaixo fica emcrates/lib/src, salvo indicação em contrário.
O ciclo de vida da requisição
O diagrama abaixo mostra o fluxo geral de uma transação através do Kora. Compreender o caminho das chamadas é importante para configurar um nó Kora e adicionar novos recursos.
Onde cada etapa está localizada
| Etapa no diagrama | Código-fonte | Ponto de entrada |
|---|---|---|
| Gateway | rpc_server/server.rs | run_rpc_server |
| Despacho | rpc_server/rpc.rs | KoraRpc |
| Lógica por método | rpc_server/method/ | um arquivo por método JSON-RPC |
| Validação | validator/transaction_validator.rs | TransactionValidator |
| Plugins | plugin/mod.rs | TransactionPluginRunner |
| Assinatura | signer/ | baseada no crate solana-keychain |
Mais dois arquivos que vale conhecer: config.rs define todo o esquema do kora.toml, e
state.rs mantém a configuração desserializada em um estado global do processo.
Lendo o servidor RPC
rpc.rs é uma camada fina de despacho, com um método por endpoint JSON-RPC, e a
forma mais rápida de ver toda a API. A lógica de cada método fica em seu próprio arquivo em
rpc_server/method/. Leia sign_transaction.rs de ponta a ponta; os outros métodos
de assinatura são variações dele.
Lendo o validador
transaction_validator.rs e transaction/instruction_util.rs contêm a lógica de
validação de transações e instruções. Além disso, os testes de propriedades de
segurança da fee-payer-policy, que ficam em um arquivo por programa controlado em
validator/transaction_validator/fee_payer_policy_props/.
Convenções que vale conhecer
Validação padrão. Toda flag em [validation.fee_payer_policy]
tem false como padrão, e as structs de política possuem #[serde(default)]. Essa
combinação é deliberada: adicionar uma nova instrução controlada não deve quebrar a
configuração de um operador existente, e deve resultar em uma negação, e não em uma
permissão acidental. Preserve ambos ao adicionar uma flag.
Valide a transação resolvida, nunca a bruta. A
VersionedTransaction bruta expõe apenas as chaves de conta estáticas, de modo que validar ou
calcular o preço de uma transação V0 a partir dela ignora silenciosamente as contas de tabelas de consulta e
cobra a menos. VersionedTransactionResolved::from_transaction resolve esses
endereços logo no início, e é por isso que todas as etapas seguintes recebem o tipo resolvido.
Adicionando um plugin de transação
Os plugins implementam a trait TransactionPlugin em plugin/mod.rs. Ela tem dois
métodos: validate é executado por transação durante os fluxos de assinatura, e
validate_config é executado uma vez na inicialização e retorna erros e avisos para o
operador. Um PluginExecutionContext informa ao plugin qual dos quatro métodos de assinatura
o invocou.
TransactionPluginRunner::from_config faz o match em TransactionPluginType,
definido em config.rs. Um novo plugin integrado consiste em uma nova variante ali, mais um novo
braço de match no runner. Os dois plugins fornecidos atualmente são gas_swap e
deploy_authority.
Testes
O Kora mantém a configuração em estado global do processo, então tests/ declara um
alvo [[test]] por fase, e cada alvo inicia seu próprio surfnet embutido junto com um
nó Kora, preparado do zero. Uma configuração por binário: uma nova fase exige um novo
alvo, e não um novo módulo em um já existente.
cargo test -p tests --test <target>
Todo o resto é conectado por meio do justfile. Leia-o em vez de
reconstruir os comandos manualmente.
Is this page helpful?