SIMD-0162
Remove Accounts `is_executable` Flag Checks
Feature Gate Status
FXs1zh47QbNnhXcnB6YiAQoJ4sGB91tKF3UFHLcKT7PM
TL;DR
Remove all checks of accounts `is_executable` flag which can throw errors in the runtime.
Summary
Remove all checks of accounts `is_executable` flag which can throw errors in the runtime.
Motivation
Currently, a program account which satisfies the following conditions can be invoked / executed: - Has the `is_executable` flag set - Is owned by a loader - Contains a successfully verified ELF, contains the address of a program data account which does or is a built-in program The second condition can be used as a performance optimization to filter out accounts which definitely do not contain programs and the third condition alone would be sufficient to guarantee correct execution. The first condition is however is not only useless, it is downright deceptive and entangled with the confusing proxy account workaround in loader-v3. Originally, the `is_executable` flag meant that a program was deployed and finalized, which effectively renders its program account read-only forever, as the `is_executable` can not be cleared / reset. With the introduction of the upgradeable loader (loader-v3), instead of removing the first condition back then, a workaround was created: The program account became a proxy account which has the `is_executable` flag set and then points to the actual program data account which does not have the `is_executable` flag set. Meaning the `is_executable` flag now neither does reliably indicate that an account contains a program (as the program data account does not have the flag set), nor does it indicate that a program is finalized (as the program account has it set while the program remains upgradeable). Removing the first condition not only removes some redundant error checks from the runtime and confusion for future maintainers, but more importantly enables us to deploy loader-v4 which is upgradeable like loader-v3 but without the need for proxy accounts.
Key Changes
- Setting of the is_executable flag during program deployment in loader-v3
- Calculation of the account hashes
- Minimization of snapshots
- Serialization of instruction accounts is_executable flag for dapps
- CPI ignores changes made by the caller to instruction accounts which have
- ExecutableLamportChange during execution (transaction succeeds instead)
- during transaction loading:
- InvalidProgramForExecution (fallthrough to UnsupportedProgramId during execution)
- AccountNotExecutable (fallthrough to UnsupportedProgramId during execution)
- Meaning the transaction loading checks are effectively deferred until
- in the Upgrade instruction of loader-v3:
- AccountNotExecutable (fallthrough to IncorrectProgramId or InvalidAccountData, depending on the owner)
- during execution:
- IncorrectProgramId (fallthrough to UnsupportedProgramId during execution)
- ExecutableDataModified (fallthrough to ExternalAccountDataModified during execution)
- ExecutableModified (is unreachable, as it is overshadowed by owner and writability checks)
- ModifiedProgramId (is unreachable, as it is overshadowed by owner and writability checks)
- InvalidAccountData for programs which are closed, in visibility delay,
- IncorrectProgramId for unrecognized built-in programs
- InvalidProgramForExecution
Impact
Error codes of these conditions, which are rarely triggered, will change. The only consensus relevant change is that it will become possible (for everybody) to donate funds to program accounts. That however is expected not to break any existing programs.
Security Considerations
None.