v0.1.0-pre.064-065
This commit is contained in:
151
olddocs/archivekbot2/kb_execution_solana/README.md
Normal file
151
olddocs/archivekbot2/kb_execution_solana/README.md
Normal file
@@ -0,0 +1,151 @@
|
||||
<!-- file: kb_execution_solana/README.md -->
|
||||
<!-- version: 4 -->
|
||||
|
||||
# kb_execution_solana
|
||||
|
||||
`kb_execution_solana` transforme un `PreparedExecutionPlan` commun en message et transaction Solana, puis résout les signataires via l’interface Solana `Signer` et signe uniquement après une simulation autorisée par `kb_execution_safety`.
|
||||
|
||||
La crate est indépendante des exécuteurs concrets et des transports RPC. Elle assemble aussi bien les plans à recent blockhash que les transactions consommant réellement un durable nonce.
|
||||
|
||||
## API publique
|
||||
|
||||
| Export | Usage |
|
||||
|----------------------------------------|-------------------------------------------------------------------------------------------------------|
|
||||
| `build_legacy_transaction(...)` | Compile un plan `Latest` avec un recent blockhash explicite. |
|
||||
| `build_durable_nonce_transaction(...)` | Compile un plan `DurableNonce` avec un état nonce validé et injecte l’avance en première instruction. |
|
||||
| `durable_nonce_account_data_length()` | Fournit la longueur exacte à demander au RPC pour un compte nonce. |
|
||||
| `parse_durable_nonce_account(...)` | Valide et décode un snapshot complet de compte nonce System. |
|
||||
| `DurableNonceAccountState` | État validé exposant compte, autorité, nonce/blockhash et coût par signature. |
|
||||
| `UnsignedSolanaTransaction` | Message compilé non signé, destiné aux frais, à la simulation exacte et à la signature contrôlée. |
|
||||
| `SolanaSimulationEvidence` | Simulation liée au hash et au blockhash/nonce exacts du message. |
|
||||
| `SignedSolanaTransaction` | Transaction signée, vérifiable localement et sérialisable pour `sendTransaction`. |
|
||||
|
||||
### Méthodes des types
|
||||
|
||||
| Type | Méthodes publiques |
|
||||
|-----------------------------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
|
||||
| `DurableNonceAccountState` | `account()`, `authority()`, `blockhash()`, `lamports_per_signature()`. |
|
||||
| `UnsignedSolanaTransaction` | `plan()`, `message_hash()`, `blockhash()`, `required_signer_pubkeys()`, `message_base64()`, `transaction_base64()`, `bind_simulation(...)`, `sign_after_simulation(...)`. |
|
||||
| `SolanaSimulationEvidence` | `message_hash()`, `blockhash()`, `simulation()`. |
|
||||
| `SignedSolanaTransaction` | `message_hash()`, `primary_signature()`, `signer_pubkeys()`, `wire_length()`, `transaction_base64()`, `verify_signatures()`. |
|
||||
|
||||
## Exemple de flux
|
||||
|
||||
```rust
|
||||
let unsigned = kb_execution_solana::build_legacy_transaction(&plan, recent_blockhash)?;
|
||||
let simulation = rpc_simulation.to_execution_result(
|
||||
unsigned.message_hash(),
|
||||
unsigned.blockhash(),
|
||||
observed_cluster,
|
||||
)?;
|
||||
let evidence = unsigned.bind_simulation(simulation)?;
|
||||
let signed = unsigned.sign_after_simulation(&evidence, signers.as_slice())?;
|
||||
signed.verify_signatures()?;
|
||||
```
|
||||
|
||||
Le transport RPC reste extérieur : cette crate ne récupère pas le blockhash, ne charge pas le compte nonce et n’envoie pas le payload signé.
|
||||
|
||||
## Assemblage à recent blockhash
|
||||
|
||||
### `build_legacy_transaction(plan, recent_blockhash)`
|
||||
|
||||
Construit une transaction legacy non signée à partir d’un blockhash base58 obtenu par `getLatestBlockhash`.
|
||||
|
||||
La fonction vérifie :
|
||||
|
||||
- la politique `ExecutionBlockhashKind::Latest` ;
|
||||
- les public keys et le blockhash ;
|
||||
- la présence d’au moins une instruction ;
|
||||
- l’égalité exacte entre signataires déclarés et signataires compilés ;
|
||||
- la limite wire Solana de 1 232 octets.
|
||||
|
||||
Un plan `DurableNonce` est refusé et doit utiliser le chemin dédié.
|
||||
|
||||
## Lecture et validation d’un compte nonce
|
||||
|
||||
### `durable_nonce_account_data_length()`
|
||||
|
||||
Retourne la taille wire officielle d’un compte nonce, actuellement 80 octets. Cette valeur doit être utilisée comme limite exacte d’un appel `getAccountInfo` avec données complètes.
|
||||
|
||||
### `parse_durable_nonce_account(account, owner, executable, space, data)`
|
||||
|
||||
Décode l’état officiel `solana_nonce::versions::Versions` avec `wincode::deserialize_exact` et produit un `DurableNonceAccountState` uniquement lorsque toutes les conditions suivantes sont satisfaites :
|
||||
|
||||
- adresse du compte valide ;
|
||||
- owner égal au System Program ;
|
||||
- compte non exécutable ;
|
||||
- `space` et longueur décodée égaux à la taille officielle ;
|
||||
- version `Current` ;
|
||||
- état `Initialized` ;
|
||||
- autorité et valeur nonce extraites sans approximation.
|
||||
|
||||
Les états `Legacy`, `Uninitialized`, tronqués, suffixés ou possédés par un autre programme sont refusés. `DurableNonceAccountState` expose uniquement l’adresse, l’autorité, la valeur nonce utilisée comme blockhash et le coût par signature stocké dans l’état.
|
||||
|
||||
Le chargement réseau reste extérieur à cette crate. Le contrat RPC prévu est :
|
||||
|
||||
```rust
|
||||
let config = kb_rpc::GetAccountInfoConfig::confirmed_with_data(
|
||||
kb_execution_solana::durable_nonce_account_data_length(),
|
||||
)?;
|
||||
```
|
||||
|
||||
## Assemblage durable nonce
|
||||
|
||||
### `build_durable_nonce_transaction(plan, nonce_state)`
|
||||
|
||||
Construit une transaction non signée qui consomme l’état nonce validé.
|
||||
|
||||
La fonction exige :
|
||||
|
||||
- une politique `ExecutionBlockhashKind::DurableNonce` sans âge de blockhash récent ;
|
||||
- le même compte nonce dans la politique et dans l’état validé ;
|
||||
- la même autorité dans la politique et dans l’état validé ;
|
||||
- l’autorité nonce dans `required_signers` ;
|
||||
- au moins une instruction métier à exécuter après l’avance nonce.
|
||||
|
||||
L’assemblage utilise `Message::new_with_nonce`, place l’instruction officielle `AdvanceNonceAccount` en position zéro, puis remplace le champ `recent_blockhash` par la valeur nonce extraite de l’état. Le plan d’origine n’est pas muté : `UnsignedSolanaTransaction::plan()` expose un plan effectif cloné contenant l’instruction injectée.
|
||||
|
||||
Après compilation, la crate vérifie :
|
||||
|
||||
- la reconnaissance de la transaction par `solana_transaction::uses_durable_nonce` ;
|
||||
- l’égalité exacte entre signataires déclarés et signataires compilés ;
|
||||
- la taille wire ;
|
||||
- le hash du message et la valeur nonce effectivement compilée.
|
||||
|
||||
Les opérations de gestion du compte nonce elles-mêmes, telles que `initialize`, `authorize`, `withdraw` ou `upgrade`, restent des transactions ordinaires à recent blockhash. Elles ne passent pas par ce chemin.
|
||||
|
||||
## Simulation et signature
|
||||
|
||||
### `UnsignedSolanaTransaction`
|
||||
|
||||
Expose :
|
||||
|
||||
- le plan effectif ;
|
||||
- le hash exact du message ;
|
||||
- le recent blockhash ou la valeur nonce compilée ;
|
||||
- l’ordre exact des signataires ;
|
||||
- le message base64 pour `getFeeForMessage` ;
|
||||
- la transaction non signée base64 pour `simulateTransaction` avec `sigVerify = false` et `replaceRecentBlockhash = false`.
|
||||
|
||||
### `bind_simulation(result)`
|
||||
|
||||
Lie le résultat typé de simulation au hash du message **et** au blockhash/nonce compilé. Une simulation utilisant un autre message, une autre source de blockhash ou un blockhash de remplacement ne peut pas autoriser la signature.
|
||||
|
||||
### `sign_after_simulation(evidence, signers)`
|
||||
|
||||
Réévalue `kb_execution_safety`, exige une décision `Allow`, résout exactement tous les signataires via `&dyn solana_signer::Signer`, signe puis vérifie que la transaction est complète.
|
||||
|
||||
Les signataires manquants, supplémentaires ou dupliqués sont refusés. La fonction ne contacte aucun endpoint RPC et n’envoie rien.
|
||||
|
||||
### `SignedSolanaTransaction`
|
||||
|
||||
Expose uniquement des données non secrètes :
|
||||
|
||||
- hash du message ;
|
||||
- signature primaire ;
|
||||
- public keys des signataires ;
|
||||
- taille wire ;
|
||||
- payload base64 signé ;
|
||||
- vérification locale des signatures.
|
||||
|
||||
Le payload signé reste côté backend. Il ne doit pas être transféré automatiquement à Tauri. `kb_rpc::HttpClient::send_transaction` et sa variante pool imposent le preflight et refusent une signature RPC différente de la signature primaire locale.
|
||||
Reference in New Issue
Block a user