Resumo
Verificações de tempo de execução após cada instrução: apenas o proprietário pode debitar lamports ou modificar dados, os dados podem crescer no máximo 10 KiB por instrução, mudanças de proprietário requerem dados inicializados a zero, e a flag executável é irreversível.
O tempo de execução Solana aplica estas regras após a execução de cada instrução
através dos métodos
BorrowedInstructionAccount.
Cada regra é verificada no momento da modificação, e a transação é revertida se
alguma verificação falhar.
Regras de lamports
| Regra | Aplicação | Erro |
|---|---|---|
| Apenas o proprietário pode debitar lamports | set_lamports(): verifica is_owned_by_current_program() quando lamports < current | ExternalAccountLamportSpend |
| Contas somente leitura não podem ter lamports alterados | set_lamports(): verifica is_writable() | ReadonlyLamportChange |
| Qualquer programa pode creditar lamports a uma conta gravável | set_lamports(): a verificação de propriedade aplica-se apenas quando o novo saldo é inferior ao saldo atual; a verificação de gravável ainda se aplica | ReadonlyLamportChange |
| Lamports devem estar equilibrados numa instrução | TransactionContext::pop(): verifica get_lamports_delta() == 0 | UnbalancedInstruction |
Regras de dados
| Regra | Aplicação | Erro |
|---|---|---|
| Apenas o proprietário pode modificar dados | can_data_be_changed(): verifica is_owned_by_current_program() | ExternalAccountDataModified |
| Contas somente leitura não podem ter dados modificados | can_data_be_changed(): verifica is_writable() | ReadonlyDataModified |
| Apenas o proprietário pode redimensionar dados | can_data_be_resized(): verifica is_owned_by_current_program() quando new_len != old_len | AccountDataSizeChanged |
| Tamanho máximo de dados: 10 MiB | TransactionAccounts::can_data_be_resized(): verifica new_len <= MAX_ACCOUNT_DATA_LEN | InvalidRealloc |
| Crescimento máximo por instrução: 10 KiB | Desserialização em deserialize_parameters_aligned(): verifica post_len - pre_len <= MAX_PERMITTED_DATA_INCREASE | InvalidRealloc |
| Crescimento máximo por transação: 20 MiB | TransactionAccounts::can_data_be_resized(): verifica resize_delta <= MAX_ACCOUNT_DATA_GROWTH_PER_TRANSACTION cumulativo | MaxAccountsDataAllocationsExceeded |
Regras do proprietário
| Regra | Aplicação | Erro |
|---|---|---|
| Apenas o proprietário atual pode reatribuir o proprietário | set_owner(): verifica is_owned_by_current_program() | ModifiedProgramId |
| A conta deve ser gravável | set_owner(): verifica is_writable() | ModifiedProgramId |
| Os dados devem estar inicializados com zero | set_owner(): verifica is_zeroed(data) | ModifiedProgramId |
Regras da flag executável
| Regra | Aplicação | Erro |
|---|---|---|
| A conta deve estar isenta de rent | set_executable(): verifica rent.is_exempt(lamports, data_len) | ExecutableAccountNotRentExempt |
| Apenas o proprietário pode definir a flag | set_executable(): verifica is_owned_by_current_program() | ExecutableModified |
| A conta deve ser gravável | set_executable(): verifica is_writable() | ExecutableModified |
Transições de estado de rent
As contas existem num de três valores
RentState:
Uninitialized (0 lamports), RentPaying (acima de 0 mas abaixo do
mínimo de isenção de rent), e RentExempt (no mínimo ou acima). Transições
não permitidas produzem TransactionError::InsufficientFundsForRent.
O runtime aplica estas regras através de
transition_allowed():
- Qualquer conta pode transitar para
Uninitialized(fechar) ouRentExempt. - Nenhuma conta pode entrar em
RentPayinga partir deUninitializedouRentExempt. Todas as novas contas devem estar isentas de rent.
Regras de empréstimo de contas
Durante a execução de instruções, o runtime aplica semântica de empréstimo de
escritor único as contas. Um programa pode obter uma referência mutável ou
múltiplas referências imutáveis a uma conta, mas não ambas simultaneamente. Se
um programa tentar emprestar uma conta que já está mutavelmente emprestada (ou
emprestar mutavelmente uma conta que já está imutuavelmente emprestada), a
instrução falha com AccountBorrowFailed através de
try_borrow()
e
try_borrow_mut().
Se uma instrução for concluída enquanto um empréstimo ainda estiver pendente, o
runtime retorna AccountBorrowOutstanding em
TransactionContext::pop().
Is this page helpful?