Résumé
Vérifications du runtime après chaque instruction : seul le propriétaire peut débiter des lamports ou modifier les données, les données peuvent croître de 10 Kio maximum par instruction, les changements de propriétaire nécessitent des données initialisées à zéro, et le flag exécutable est irréversible.
Le runtime Solana applique ces règles après l'exécution de chaque instruction
via les méthodes
BorrowedInstructionAccount.
Chaque règle est vérifiée au moment de la modification, et la transaction est
annulée si une vérification échoue.
Règles des lamports
| Règle | Application | Erreur |
|---|---|---|
| Seul le propriétaire peut débiter des lamports | set_lamports() : vérifie is_owned_by_current_program() quand lamports < current | ExternalAccountLamportSpend |
| Les comptes en lecture seule ne peuvent pas voir leurs lamports modifiés | set_lamports() : vérifie is_writable() | ReadonlyLamportChange |
| Tout programme peut créditer des lamports sur un compte modifiable | set_lamports() : la vérification de propriété s'applique uniquement lorsque le nouveau solde est inférieur au solde actuel ; la vérification de modification s'applique toujours | ReadonlyLamportChange |
| Les lamports doivent être équilibrés dans une instruction | TransactionContext::pop() : vérifie get_lamports_delta() == 0 | UnbalancedInstruction |
Règles des données
| Règle | Application | Erreur |
|---|---|---|
| Seul le propriétaire peut modifier les données | can_data_be_changed() : vérifie is_owned_by_current_program() | ExternalAccountDataModified |
| Les comptes en lecture seule ne peuvent pas voir leurs données modifiées | can_data_be_changed() : vérifie is_writable() | ReadonlyDataModified |
| Seul le propriétaire peut redimensionner les données | can_data_be_resized() : vérifie is_owned_by_current_program() quand new_len != old_len | AccountDataSizeChanged |
| Taille maximale des données : 10 Mio | TransactionAccounts::can_data_be_resized() : vérifie new_len <= MAX_ACCOUNT_DATA_LEN | InvalidRealloc |
| Croissance maximale par instruction : 10 Kio | Désérialisation dans deserialize_parameters_aligned() : vérifie post_len - pre_len <= MAX_PERMITTED_DATA_INCREASE | InvalidRealloc |
| Croissance maximale par transaction : 20 Mio | TransactionAccounts::can_data_be_resized() : vérifie le cumul resize_delta <= MAX_ACCOUNT_DATA_GROWTH_PER_TRANSACTION | MaxAccountsDataAllocationsExceeded |
Règles du propriétaire
| Règle | Application | Erreur |
|---|---|---|
| Seul le propriétaire actuel peut réassigner le propriétaire | set_owner() : vérifie is_owned_by_current_program() | ModifiedProgramId |
| Le compte doit être modifiable | set_owner() : vérifie is_writable() | ModifiedProgramId |
| Les données doivent être initialisées à zéro | set_owner() : vérifie is_zeroed(data) | ModifiedProgramId |
Règles du drapeau exécutable
| Règle | Application | Erreur |
|---|---|---|
| Le compte doit être exempté de rent | set_executable() : vérifie rent.is_exempt(lamports, data_len) | ExecutableAccountNotRentExempt |
| Seul le propriétaire peut définir le drapeau | set_executable() : vérifie is_owned_by_current_program() | ExecutableModified |
| Le compte doit être modifiable | set_executable() : vérifie is_writable() | ExecutableModified |
Transitions d'état de rent
Les comptes existent dans l'une des trois valeurs
RentState
: Uninitialized (0 lamport), RentPaying (au-dessus de 0 mais en
dessous du minimum d'exemption de rent), et RentExempt (au minimum ou
au-dessus). Les transitions interdites produisent
TransactionError::InsufficientFundsForRent.
Le runtime applique ces règles via
transition_allowed()
:
- Tout compte peut passer à
Uninitialized(fermer) ouRentExempt. - Aucun compte ne peut entrer dans
RentPayingdepuisUninitializedouRentExempt. Tous les nouveaux comptes doivent être exemptés de rent.
Règles d'emprunt de compte
Pendant l'exécution des instructions, le runtime applique une sémantique
d'emprunt à écrivain unique sur les comptes. Un programme peut obtenir soit une
référence mutable, soit plusieurs références immuables à un compte, mais pas les
deux simultanément. Si un programme tente d'emprunter un compte qui est déjà
emprunté de manière mutable (ou d'emprunter de manière mutable un compte qui est
déjà emprunté de manière immuable), l'instruction échoue avec
AccountBorrowFailed via
try_borrow()
et
try_borrow_mut().
Si une instruction se termine alors qu'un emprunt est toujours en cours, le
runtime renvoie AccountBorrowOutstanding dans
TransactionContext::pop().
Is this page helpful?