Zusammenfassung
Laufzeitprüfungen nach jeder Anweisung: Nur der Eigentümer kann Lamports abbuchen oder Daten ändern, Daten können maximal 10 KiB pro Anweisung wachsen, Eigentümerwechsel erfordern nullinitialisierte Daten, und das ausführbare Flag ist irreversibel.
Die Solana-Laufzeitumgebung setzt diese Regeln nach jeder Anweisungsausführung
über
BorrowedInstructionAccount
Methoden durch. Jede Regel wird zum Zeitpunkt der Änderung geprüft, und die
Transaktion wird zurückgesetzt, wenn eine Prüfung fehlschlägt.
Lamports-Regeln
| Regel | Durchsetzung | Fehler |
|---|---|---|
| Nur der Eigentümer kann Lamports abbuchen | set_lamports(): prüft is_owned_by_current_program() wenn lamports < current | ExternalAccountLamportSpend |
| Schreibgeschützte Konten können keine Lamports-Änderungen haben | set_lamports(): prüft is_writable() | ReadonlyLamportChange |
| Jedes Programm kann Lamports einem beschreibbaren Konto gutschreiben | set_lamports(): die Eigentümerprüfung gilt nur, wenn der neue Saldo kleiner als der aktuelle Saldo ist; die Beschreibbarkeitsprüfung gilt weiterhin | ReadonlyLamportChange |
| Lamports müssen über eine Anweisung hinweg ausgeglichen sein | TransactionContext::pop(): verifiziert get_lamports_delta() == 0 | UnbalancedInstruction |
Datenregeln
| Regel | Durchsetzung | Fehler |
|---|---|---|
| Nur der Eigentümer kann Daten ändern | can_data_be_changed(): prüft is_owned_by_current_program() | ExternalAccountDataModified |
| Schreibgeschützte Konten können keine Datenänderungen haben | can_data_be_changed(): prüft is_writable() | ReadonlyDataModified |
| Nur der Eigentümer kann die Datengröße ändern | can_data_be_resized(): prüft is_owned_by_current_program() wenn new_len != old_len | AccountDataSizeChanged |
| Maximale Datengröße: 10 MiB | TransactionAccounts::can_data_be_resized(): prüft new_len <= MAX_ACCOUNT_DATA_LEN | InvalidRealloc |
| Maximales Wachstum pro Anweisung: 10 KiB | Deserialisierung in deserialize_parameters_aligned(): prüft post_len - pre_len <= MAX_PERMITTED_DATA_INCREASE | InvalidRealloc |
| Maximales Wachstum pro Transaktion: 20 MiB | TransactionAccounts::can_data_be_resized(): prüft kumulatives resize_delta <= MAX_ACCOUNT_DATA_GROWTH_PER_TRANSACTION | MaxAccountsDataAllocationsExceeded |
Eigentümerregeln
| Regel | Durchsetzung | Fehler |
|---|---|---|
| Nur der aktuelle Eigentümer kann den Eigentümer neu zuweisen | set_owner(): prüft is_owned_by_current_program() | ModifiedProgramId |
| Konto muss beschreibbar sein | set_owner(): prüft is_writable() | ModifiedProgramId |
| Daten müssen nullinitialisiert sein | set_owner(): prüft is_zeroed(data) | ModifiedProgramId |
Regeln für ausführbare Flags
| Regel | Durchsetzung | Fehler |
|---|---|---|
| Konto muss mietbefreit sein | set_executable(): prüft rent.is_exempt(lamports, data_len) | ExecutableAccountNotRentExempt |
| Nur der Eigentümer kann das Flag setzen | set_executable(): prüft is_owned_by_current_program() | ExecutableModified |
| Konto muss beschreibbar sein | set_executable(): prüft is_writable() | ExecutableModified |
Mietstatusübergänge
Konten existieren in einem von drei
RentState
Werten: Uninitialized (0 Lamports), RentPaying (über 0, aber unter
dem Mietbefreiungsminimum) und RentExempt (am oder über dem Minimum).
Nicht zulässige Übergänge erzeugen
TransactionError::InsufficientFundsForRent.
Die Runtime setzt diese Regeln über
transition_allowed()
durch:
- Jedes Konto kann zu
Uninitialized(schließen) oderRentExemptübergehen. - Kein Konto kann von
UninitializedoderRentExemptinRentPayingeintreten. Alle neuen Konten müssen mietbefreit sein.
Regeln für Kontoausleihe
Während der Anweisungsausführung setzt die Runtime Single-Writer-Ausleihsemantik
für Konten durch. Ein Programm kann entweder eine veränderbare Referenz oder
mehrere unveränderbare Referenzen auf ein Konto erhalten, aber nicht beides
gleichzeitig. Wenn ein Programm versucht, ein Konto auszuleihen, das bereits
veränderbar ausgeliehen ist (oder veränderbar ein Konto auszuleihen, das bereits
unveränderbar ausgeliehen ist), schlägt die Anweisung mit
AccountBorrowFailed über
try_borrow()
und
try_borrow_mut()
fehl. Wenn eine Anweisung abgeschlossen wird, während eine Ausleihe noch
aussteht, gibt die Runtime AccountBorrowOutstanding in
TransactionContext::pop()
zurück.
Is this page helpful?