Kora è un workspace Rust composto da tre crate:
kora-libcontiene la logica principale e il server RPC,kora-clicompila il binariokoraeseguito dagli operatori ekora-deployè uno strumento specializzato per il deployment dei programmi, con versioning separato. Tutto ciò che segue si trova incrates/lib/src, salvo diversa indicazione.
Il ciclo di vita della richiesta
Il diagramma seguente mostra il flusso generale di una transazione in Kora. Comprendere il percorso delle chiamate è importante per configurare un nodo Kora e per aggiungere nuove funzionalità.
Dove si trova ciascuna fase
| Fase nel diagramma | Sorgente | Punto di ingresso |
|---|---|---|
| Gateway | rpc_server/server.rs | run_rpc_server |
| Smistamento | rpc_server/rpc.rs | KoraRpc |
| Logica per metodo | rpc_server/method/ | un file per ogni metodo JSON-RPC |
| Validazione | validator/transaction_validator.rs | TransactionValidator |
| Plugin | plugin/mod.rs | TransactionPluginRunner |
| Firma | signer/ | basata sul crate solana-keychain |
Altri due file da conoscere: config.rs definisce l'intero schema di kora.toml, e
state.rs contiene la configurazione deserializzata nello stato globale del processo.
Leggere il server RPC
rpc.rs è un sottile livello di smistamento, un metodo per ogni endpoint JSON-RPC, e il
modo più rapido per vedere l'intera API. La logica di ciascun metodo si trova in un file dedicato in
rpc_server/method/. Leggi sign_transaction.rs dall'inizio alla fine; gli altri metodi
di firma ne sono varianti.
Leggere il validatore
transaction_validator.rs e transaction/instruction_util.rs contengono la logica per
validare transazioni e istruzioni. Inoltre, i test delle proprietà di
sicurezza della fee-payer-policy, che risiedono in un file per ogni programma controllato in
validator/transaction_validator/fee_payer_policy_props/.
Convenzioni da conoscere
Validazione predefinita. Ogni flag sotto [validation.fee_payer_policy]
ha come valore predefinito false, e le struct della policy portano #[serde(default)]. Questo
abbinamento è voluto: aggiungere un'istruzione appena controllata non deve compromettere la
configurazione di un operatore esistente, e deve tradursi in un rifiuto anziché in un
consenso accidentale. Mantieni entrambe le caratteristiche quando aggiungi un flag.
Valida la transazione risolta, mai quella grezza. La
VersionedTransaction grezza espone solo le chiavi account statiche, quindi validare o
calcolare il prezzo di una transazione V0 a partire da essa ignora silenziosamente gli account delle lookup table e
addebita meno del dovuto. VersionedTransactionResolved::from_transaction risolve in anticipo quegli
indirizzi, ed è per questo che ogni fase successiva accetta il tipo risolto.
Aggiungere un plugin per le transazioni
I plugin implementano il trait TransactionPlugin in plugin/mod.rs. Ha due
metodi: validate viene eseguito per ogni transazione durante i flussi di firma, e
validate_config viene eseguito una sola volta all'avvio e restituisce errori e avvisi per
l'operatore. Un PluginExecutionContext indica al plugin quale dei quattro metodi
di firma lo ha invocato.
TransactionPluginRunner::from_config esegue il match su TransactionPluginType,
definito in config.rs. Un nuovo plugin integrato corrisponde a una nuova variante in quel punto più un nuovo
braccio di match nel runner. I due plugin attualmente forniti sono gas_swap e
deploy_authority.
Test
Kora mantiene la configurazione nello stato globale del processo, quindi tests/ dichiara un
target [[test]] per ogni fase, e ciascun target avvia il proprio surfnet incorporato più
un nodo Kora, inizializzati da zero. Una configurazione per binario: una nuova fase richiede un nuovo
target, non un nuovo modulo in uno esistente.
cargo test -p tests --test <target>
Tutto il resto è collegato tramite il justfile. Leggi quel file anziché
ricostruire i comandi a mano.
Is this page helpful?