Skip to content

Commit

Permalink
Expands on how loader v3 to v4 migration works.
Browse files Browse the repository at this point in the history
  • Loading branch information
Lichtso committed Jan 16, 2025
1 parent a4f4116 commit 4f5de70
Showing 1 changed file with 77 additions and 32 deletions.
109 changes: 77 additions & 32 deletions proposals/0167-loader-v4.md
Original file line number Diff line number Diff line change
Expand Up @@ -50,8 +50,9 @@ The associated feature gate must:
- add loader-v4 to the write lock demotion exceptions
- enable loader-v4 `LoaderV411111111111111111111111111111111111` program
management and execution
- simultaneously disable new deployments on loader-v3
(`BPFLoaderUpgradeab1e11111111111111111111111`),
- disable new deployments on loader-v3
`BPFLoaderUpgradeab1e11111111111111111111111`
- enable the loader-v3 migration instruction
throwing `InvalidIstructionData` if `DeployWithMaxDataLen` is called.

### Owned Program Accounts
Expand Down Expand Up @@ -125,14 +126,37 @@ All program management instructions must cost 2000 CUs.
- Copy the chunk into the program account at the offset shifted by the
header size

#### Copy

- Instruction accounts:
- `[writable]` The program account to copy to.
- `[signer]` The authority of the program.
- `[]` The program account to copy from, which can be owned by any loader.
- Instruction data:
- Enum variant `1u32`
- `u32` Offset at which to write.
- `u32` Offset at which to read.
- `u32` Length of the chunk to copy in bytes.
- Behavior:
- Check there are at least three instruction accounts,
otherwise throw `NotEnoughAccountKeys`
- Verify the program account
- Check the status stored in the program account is retracted,
otherwise throw `InvalidArgument`
- Check that the end offset (sum of offset and length of the chunk) does
not exceed the maximum (program account length minus the header size),
otherwise throw `AccountDataTooSmall`
- Copy the chunk between the program accounts at the offsets, each shifted by
the header size of their loader respectively

#### Truncate

- Instruction accounts:
- `[(signer), writable]` The program account to change the size of.
- `[signer]` The authority of the program.
- `[writable]` Optional, the recipient account.
- Instruction data:
- Enum variant `1u32`
- Enum variant `2u32`
- `u32` The new size after the operation.
- Behavior:
- Check there are at least two instruction accounts,
Expand Down Expand Up @@ -177,7 +201,7 @@ All program management instructions must cost 2000 CUs.
- `[writable]` Optional, an undeployed source program account to take data
and lamports from.
- Instruction data:
- Enum variant `2u32`
- Enum variant `3u32`
- Behavior:
- Check there are at least two instruction accounts,
otherwise throw `NotEnoughAccountKeys`
Expand Down Expand Up @@ -212,7 +236,7 @@ All program management instructions must cost 2000 CUs.
- `[writable]` The program account to retract.
- `[signer]` The authority of the program.
- Instruction data:
- Enum variant `3u32`
- Enum variant `4u32`
- Behavior:
- Check there are at least two instruction accounts,
otherwise throw `NotEnoughAccountKeys`
Expand All @@ -232,7 +256,7 @@ All program management instructions must cost 2000 CUs.
- `[signer]` The current authority of the program.
- `[signer]` The new authority of the program.
- Instruction data:
- Enum variant `4u32`
- Enum variant `5u32`
- Behavior:
- Check there are at least three instruction accounts,
otherwise throw `NotEnoughAccountKeys`
Expand All @@ -250,7 +274,7 @@ All program management instructions must cost 2000 CUs.
- `[signer]` The current authority of the program.
- `[]` Optional, the reserved address for the next version of the program.
- Instruction data:
- Enum variant `5u32`
- Enum variant `6u32`
- Behavior:
- Check there are at least three instruction accounts,
otherwise throw `NotEnoughAccountKeys`
Expand All @@ -271,6 +295,33 @@ All program management instructions must cost 2000 CUs.
the previous versions program account
- Change the status stored in the program account to finalized

### Loader-v3 Migration Instruction

- Instruction accounts:
- `[writable]` The program data account.
- `[writable]` The program account.
- `[signer]` The global migration authority.
- Instruction data:
- Enum variant `8u32`
- Behavior:
- Check that the provided authority is the global migration authority
(pubkey is TBD),
otherwise throw `IncorrectAuthority`
- Check that the program account is a program and not a buffer account,
otherwise throw `InvalidArgument`
- Transfer all funds from the program data account to the program account
- Clear the program account (setting its size to zero)
- Sets the owner of the program account to loader-v4
- CPI loader-v4 `Truncate` the program account to the size of the program
data account and copy the program authority from the program data account
- If the program data account was not closed (size was greater 0):
- CPI loader-v4 `Copy` the program data account into the program account
- CPI loader-v4 `Deploy` the program account
- If the program data account was finalized:
- CPI loader-v4 `Finalize` without a next version forwarding
- The program data account still owned by loader-v3 is under-funded and will
be automatically deleted by rent collection at the end of the transaction

## Impact

This proposal:
Expand All @@ -290,35 +341,29 @@ exception when shortening the length of program accounts or closing them.
instruction, instead of having to build and redeploy an empty program.
- properly alignes the executable file relative to the beginning of the
account. In loader-v3 it is misaligned.
- once all loader-v3 programs are migrated:
- allows transaction account loading to be simplifed, because every program
would load exactly one account, no need to load the proxy account to get to
the actual program data (which is not listed in the transaction accounts).
- allows the removal of the write lock demotion exception if loader-v3 is
present in a transaction.
- corrects the miscounting of the proxy account size towards the total
transaction account loading limit.

Once loader-v4 is enabled and new programs can not be deployed on loader-v3
anymore, the list of all loader-v3 programs becomes fixed and can be extracted
from a snapshot. Using the added loader-v3 migration instruction and the global
migration authority, the core protocol developers will then migrate all
loader-v3 programs to loader-v4 programs, which once completed:

- allows transaction account loading to be simplifed, because every program
would load exactly one account, no need to load the proxy account to get to
the actual program data (which is not listed in the transaction accounts).
- allows the removal of the write lock demotion exception if loader-v3 is
present in a transaction.
- corrects the miscounting of the program data account size towards the total
transaction account loading limit.
- allows dApp devs to resuscitate closed loader-v3 programs if they still
control the program authority. This allows redeployment at the same address
or completely closing the program account in order to retrieve the locked
funds.

## Security Considerations

None.

## Backwards Compatibility

This proposal does not break any existing programs. However, dapp developers
might want to profit from the new program mangement instructions without
influencing their users work flows. To do so they would need a way to turn the
program accounts of loader-v3 to program accounts of loader-v4, changing the
account owner but keeping the program address. A potential issue is that the
programdata header of loader-v3 is only 45 bytes long while loader-v4 takes 48
bytes. An automatic mechanism in the program runtime (triggered by feature
activation) could then perform the following steps per program:

- loader-v3 clears the program proxy account (setting its size to zero)
- loader-v3 transfers all funds from the programdata to the proxy account
- loader-v3 gifts the program proxy account to loader-v4
- loader-v4 initializes it via `Truncate`
- loader-v4 copies the data from the programdata account via `Write`
- loader-v4 deploys it via `Deploy`
- Optinally, loader-v4 finalizes it without a next version forwarding
- loader-v3 closes the programdata account (setting its size to zero)
None.

0 comments on commit 4f5de70

Please sign in to comment.