Περίληψη
Έλεγχοι runtime μετά από κάθε εντολή: μόνο ο owner μπορεί να χρεώσει lamports ή να τροποποιήσει δεδομένα, τα δεδομένα μπορούν να αυξηθούν κατά μέγιστο 10 KiB ανά εντολή, οι αλλαγές owner απαιτούν δεδομένα μηδενικής αρχικοποίησης και το executable flag είναι μη αναστρέψιμο.
Το Solana runtime επιβάλλει αυτούς τους κανόνες μετά την εκτέλεση κάθε εντολής
μέσω
BorrowedInstructionAccount
μεθόδων. Κάθε κανόνας ελέγχεται κατά το σημείο τροποποίησης και η συναλλαγή
αναιρείται εάν αποτύχει οποιοσδήποτε έλεγχος.
Κανόνες lamports
| Κανόνας | Επιβολή | Σφάλμα |
|---|---|---|
| Μόνο ο owner μπορεί να χρεώσει lamports | set_lamports(): ελέγχει is_owned_by_current_program() όταν lamports < current | ExternalAccountLamportSpend |
| Οι λογαριασμοί μόνο για ανάγνωση δεν μπορούν να έχουν αλλαγές στα lamports | set_lamports(): ελέγχει is_writable() | ReadonlyLamportChange |
| Οποιοδήποτε πρόγραμμα μπορεί να πιστώσει lamports σε εγγράψιμο λογαριασμό | set_lamports(): ο έλεγχος ιδιοκτησίας ισχύει μόνο όταν το νέο υπόλοιπο είναι μικρότερο από το τρέχον υπόλοιπο· ο έλεγχος εγγραψιμότητας εξακολουθεί να ισχύει | ReadonlyLamportChange |
| Τα lamports πρέπει να ισοσκελίζονται σε μια εντολή | TransactionContext::pop(): επαληθεύει get_lamports_delta() == 0 | UnbalancedInstruction |
Κανόνες δεδομένων
| Κανόνας | Επιβολή | Σφάλμα |
|---|---|---|
| Μόνο ο owner μπορεί να τροποποιήσει δεδομένα | can_data_be_changed(): ελέγχει is_owned_by_current_program() | ExternalAccountDataModified |
| Οι λογαριασμοί μόνο για ανάγνωση δεν μπορούν να έχουν τροποποιημένα δεδομένα | can_data_be_changed(): ελέγχει is_writable() | ReadonlyDataModified |
| Μόνο ο owner μπορεί να αλλάξει το μέγεθος των δεδομένων | can_data_be_resized(): ελέγχει is_owned_by_current_program() όταν new_len != old_len | AccountDataSizeChanged |
| Μέγιστο μέγεθος δεδομένων: 10 MiB | TransactionAccounts::can_data_be_resized(): ελέγχει new_len <= MAX_ACCOUNT_DATA_LEN | InvalidRealloc |
| Μέγιστη αύξηση ανά εντολή: 10 KiB | Deserialization στο deserialize_parameters_aligned(): ελέγχει post_len - pre_len <= MAX_PERMITTED_DATA_INCREASE | InvalidRealloc |
| Μέγιστη αύξηση ανά συναλλαγή: 20 MiB | TransactionAccounts::can_data_be_resized(): ελέγχει σωρευτικό resize_delta <= MAX_ACCOUNT_DATA_GROWTH_PER_TRANSACTION | MaxAccountsDataAllocationsExceeded |
Κανόνες ιδιοκτήτη
| Κανόνας | Επιβολή | Σφάλμα |
|---|---|---|
| Μόνο ο τρέχων ιδιοκτήτης μπορεί να αναθέσει εκ νέου τον ιδιοκτήτη | set_owner(): ελέγχει is_owned_by_current_program() | ModifiedProgramId |
| Ο λογαριασμός πρέπει να είναι εγγράψιμος | set_owner(): ελέγχει is_writable() | ModifiedProgramId |
| Τα δεδομένα πρέπει να είναι μηδενικά αρχικοποιημένα | set_owner(): ελέγχει is_zeroed(data) | ModifiedProgramId |
Κανόνες σημαίας εκτελέσιμου
| Κανόνας | Επιβολή | Σφάλμα |
|---|---|---|
| Ο λογαριασμός πρέπει να είναι απαλλαγμένος από rent | set_executable(): ελέγχει rent.is_exempt(lamports, data_len) | ExecutableAccountNotRentExempt |
| Μόνο ο ιδιοκτήτης μπορεί να ορίσει τη σημαία | set_executable(): ελέγχει is_owned_by_current_program() | ExecutableModified |
| Ο λογαριασμός πρέπει να είναι εγγράψιμος | set_executable(): ελέγχει is_writable() | ExecutableModified |
Μεταβάσεις κατάστασης rent
Οι λογαριασμοί υπάρχουν σε μία από τρεις
RentState
τιμές: Uninitialized (0 lamports), RentPaying (πάνω από 0 αλλά κάτω
από το ελάχιστο απαλλαγής από rent), και RentExempt (στο ή πάνω από το
ελάχιστο). Οι μη επιτρεπόμενες μεταβάσεις παράγουν
TransactionError::InsufficientFundsForRent.
Το runtime επιβάλλει αυτούς τους κανόνες μέσω
transition_allowed():
- Οποιοσδήποτε λογαριασμός μπορεί να μεταβεί σε
Uninitialized(κλείσιμο) ήRentExempt. - Κανένας λογαριασμός δεν μπορεί να εισέλθει σε
RentPayingαπόUninitializedήRentExempt. Όλοι οι νέοι λογαριασμοί πρέπει να είναι απαλλαγμένοι από rent.
Κανόνες δανεισμού λογαριασμού
Κατά την εκτέλεση εντολών, το runtime επιβάλλει σημασιολογία δανεισμού μονού
εγγραφέα στους λογαριασμούς. Ένα πρόγραμμα μπορεί να αποκτήσει είτε μία
μεταβλητή αναφορά είτε πολλαπλές αμετάβλητες αναφορές σε έναν λογαριασμό, αλλά
όχι και τα δύο ταυτόχρονα. Εάν ένα πρόγραμμα επιχειρήσει να δανειστεί έναν
λογαριασμό που είναι ήδη δανεισμένος μεταβλητά (ή να δανειστεί μεταβλητά έναν
λογαριασμό που είναι ήδη δανεισμένος αμετάβλητα), η εντολή αποτυγχάνει με
AccountBorrowFailed μέσω
try_borrow()
και
try_borrow_mut().
Εάν μια εντολή ολοκληρωθεί ενώ ένας δανεισμός εξακολουθεί να είναι σε
εκκρεμότητα, το runtime επιστρέφει AccountBorrowOutstanding στο
TransactionContext::pop().
Is this page helpful?