Tóm tắt
Kiểm tra runtime sau mỗi instruction: chỉ owner mới có thể trừ lamports hoặc sửa đổi dữ liệu, dữ liệu có thể tăng tối đa 10 KiB mỗi instruction, thay đổi owner yêu cầu dữ liệu được khởi tạo bằng không, và cờ executable là không thể đảo ngược.
Solana runtime thực thi các quy tắc này sau khi mỗi instruction được thực thi
thông qua các phương thức
BorrowedInstructionAccount.
Mỗi quy tắc được kiểm tra tại thời điểm sửa đổi, và transaction sẽ bị rollback
nếu bất kỳ kiểm tra nào thất bại.
Quy tắc lamports
| Quy tắc | Thực thi | Lỗi |
|---|---|---|
| Chỉ owner mới có thể trừ lamports | set_lamports(): kiểm tra is_owned_by_current_program() khi lamports < current | ExternalAccountLamportSpend |
| Tài khoản read-only không thể thay đổi lamports | set_lamports(): kiểm tra is_writable() | ReadonlyLamportChange |
| Bất kỳ program nào cũng có thể cộng lamports vào tài khoản writable | set_lamports(): kiểm tra ownership chỉ áp dụng khi số dư mới nhỏ hơn số dư hiện tại; kiểm tra writable vẫn được áp dụng | ReadonlyLamportChange |
| Lamports phải cân bằng trong một instruction | TransactionContext::pop(): xác minh get_lamports_delta() == 0 | UnbalancedInstruction |
Quy tắc dữ liệu
| Quy tắc | Thực thi | Lỗi |
|---|---|---|
| Chỉ owner mới có thể sửa đổi dữ liệu | can_data_be_changed(): kiểm tra is_owned_by_current_program() | ExternalAccountDataModified |
| Tài khoản read-only không thể sửa đổi dữ liệu | can_data_be_changed(): kiểm tra is_writable() | ReadonlyDataModified |
| Chỉ owner mới có thể thay đổi kích thước dữ liệu | can_data_be_resized(): kiểm tra is_owned_by_current_program() khi new_len != old_len | AccountDataSizeChanged |
| Kích thước dữ liệu tối đa: 10 MiB | TransactionAccounts::can_data_be_resized(): kiểm tra new_len <= MAX_ACCOUNT_DATA_LEN | InvalidRealloc |
| Tăng trưởng tối đa mỗi instruction: 10 KiB | Deserialization trong deserialize_parameters_aligned(): kiểm tra post_len - pre_len <= MAX_PERMITTED_DATA_INCREASE | InvalidRealloc |
| Tăng trưởng tối đa mỗi transaction: 20 MiB | TransactionAccounts::can_data_be_resized(): kiểm tra tích lũy resize_delta <= MAX_ACCOUNT_DATA_GROWTH_PER_TRANSACTION | MaxAccountsDataAllocationsExceeded |
Quy tắc owner
| Quy tắc | Thực thi | Lỗi |
|---|---|---|
| Chỉ owner hiện tại mới có thể chỉ định lại owner | set_owner(): kiểm tra is_owned_by_current_program() | ModifiedProgramId |
| Tài khoản phải có thể ghi | set_owner(): kiểm tra is_writable() | ModifiedProgramId |
| Dữ liệu phải được khởi tạo bằng zero | set_owner(): kiểm tra is_zeroed(data) | ModifiedProgramId |
Quy tắc cờ executable
| Quy tắc | Thực thi | Lỗi |
|---|---|---|
| Tài khoản phải miễn rent | set_executable(): kiểm tra rent.is_exempt(lamports, data_len) | ExecutableAccountNotRentExempt |
| Chỉ owner mới có thể đặt cờ | set_executable(): kiểm tra is_owned_by_current_program() | ExecutableModified |
| Tài khoản phải có thể ghi | set_executable(): kiểm tra is_writable() | ExecutableModified |
Chuyển đổi trạng thái rent
Tài khoản tồn tại ở một trong ba giá trị
RentState:
Uninitialized (0 lamports), RentPaying (trên 0 nhưng dưới mức tối
thiểu miễn rent), và RentExempt (bằng hoặc trên mức tối thiểu). Các chuyển
đổi không được phép tạo ra TransactionError::InsufficientFundsForRent.
Runtime thực thi các quy tắc này thông qua
transition_allowed():
- Bất kỳ tài khoản nào cũng có thể chuyển sang
Uninitialized(đóng) hoặcRentExempt. - Không có tài khoản nào có thể chuyển vào
RentPayingtừUninitializedhoặcRentExempt. Tất cả tài khoản mới phải miễn rent.
Quy tắc borrow tài khoản
Trong quá trình thực thi instruction, runtime thực thi ngữ nghĩa borrow
single-writer trên các tài khoản. Một program có thể lấy một mutable reference
hoặc nhiều immutable reference đến một tài khoản, nhưng không thể có cả hai cùng
lúc. Nếu một program cố gắng borrow một tài khoản đã được mutably borrow (hoặc
mutably borrow một tài khoản đã được immutably borrow), instruction sẽ thất bại
với AccountBorrowFailed thông qua
try_borrow()
và
try_borrow_mut().
Nếu một instruction hoàn thành trong khi một borrow vẫn còn tồn tại, runtime trả
về AccountBorrowOutstanding trong
TransactionContext::pop().
Is this page helpful?