Resumen
Verificaciones del runtime después de cada instrucción: solo el propietario puede debitar lamports o modificar datos, los datos pueden crecer máximo 10 KiB por instrucción, los cambios de propietario requieren datos inicializados en cero, y la bandera ejecutable es irreversible.
El runtime de Solana aplica estas reglas después de que cada instrucción se
ejecuta mediante los métodos
BorrowedInstructionAccount.
Cada regla se verifica en el punto de modificación, y la transacción se revierte
si alguna verificación falla.
Reglas de lamports
| Regla | Aplicación | Error |
|---|---|---|
| Solo el propietario puede debitar lamports | set_lamports(): verifica is_owned_by_current_program() cuando lamports < current | ExternalAccountLamportSpend |
| Las cuentas de solo lectura no pueden tener lamports modificados | set_lamports(): verifica is_writable() | ReadonlyLamportChange |
| Cualquier programa puede acreditar lamports a una cuenta escribible | set_lamports(): la verificación de propiedad solo aplica cuando el nuevo saldo es menor que el saldo actual; la verificación de escritura aún aplica | ReadonlyLamportChange |
| Los lamports deben balancearse a través de una instrucción | TransactionContext::pop(): verifica get_lamports_delta() == 0 | UnbalancedInstruction |
Reglas de datos
| Regla | Aplicación | Error |
|---|---|---|
| Solo el propietario puede modificar datos | can_data_be_changed(): verifica is_owned_by_current_program() | ExternalAccountDataModified |
| Las cuentas de solo lectura no pueden tener datos modificados | can_data_be_changed(): verifica is_writable() | ReadonlyDataModified |
| Solo el propietario puede redimensionar datos | can_data_be_resized(): verifica is_owned_by_current_program() cuando new_len != old_len | AccountDataSizeChanged |
| Tamaño máximo de datos: 10 MiB | TransactionAccounts::can_data_be_resized(): verifica new_len <= MAX_ACCOUNT_DATA_LEN | InvalidRealloc |
| Crecimiento máximo por instrucción: 10 KiB | Deserialización en deserialize_parameters_aligned(): verifica post_len - pre_len <= MAX_PERMITTED_DATA_INCREASE | InvalidRealloc |
| Crecimiento máximo por transacción: 20 MiB | TransactionAccounts::can_data_be_resized(): verifica resize_delta <= MAX_ACCOUNT_DATA_GROWTH_PER_TRANSACTION acumulativo | MaxAccountsDataAllocationsExceeded |
Reglas del propietario
| Regla | Aplicación | Error |
|---|---|---|
| Solo el propietario actual puede reasignar el propietario | set_owner(): verifica is_owned_by_current_program() | ModifiedProgramId |
| La cuenta debe ser escribible | set_owner(): verifica is_writable() | ModifiedProgramId |
| Los datos deben estar inicializados en cero | set_owner(): verifica is_zeroed(data) | ModifiedProgramId |
Reglas de bandera ejecutable
| Regla | Aplicación | Error |
|---|---|---|
| La cuenta debe estar exenta de rent | set_executable(): verifica rent.is_exempt(lamports, data_len) | ExecutableAccountNotRentExempt |
| Solo el propietario puede establecer la bandera | set_executable(): verifica is_owned_by_current_program() | ExecutableModified |
| La cuenta debe ser escribible | set_executable(): verifica is_writable() | ExecutableModified |
Transiciones de estado de rent
Las cuentas existen en uno de tres valores
RentState:
Uninitialized (0 lamports), RentPaying (por encima de 0 pero por
debajo del mínimo exento de rent), y RentExempt (igual o por encima del
mínimo). Las transiciones no permitidas producen
TransactionError::InsufficientFundsForRent.
El runtime aplica estas reglas mediante
transition_allowed():
- Cualquier cuenta puede transicionar a
Uninitialized(cerrar) oRentExempt. - Ninguna cuenta puede entrar en
RentPayingdesdeUninitializedoRentExempt. Todas las cuentas nuevas deben estar exentas de rent.
Reglas de préstamo de cuentas
Durante la ejecución de instrucciones, el runtime aplica semántica de préstamo
de escritor único en las cuentas. Un programa puede obtener una referencia
mutable o múltiples referencias inmutables a una cuenta, pero no ambas
simultáneamente. Si un programa intenta tomar prestada una cuenta que ya está
prestada de forma mutable (o prestar de forma mutable una cuenta que ya está
prestada de forma inmutable), la instrucción falla con AccountBorrowFailed
mediante
try_borrow()
y
try_borrow_mut().
Si una instrucción se completa mientras un préstamo aún está pendiente, el
runtime devuelve AccountBorrowOutstanding en
TransactionContext::pop().
Is this page helpful?