Repository navigation
Conversation
| "name": "program_data", | ||
| "pda": { | ||
| "seeds": [ | ||
| { | ||
| "kind": "const", | ||
| "value": [ | ||
| 5, | ||
| 84, | ||
| 138, | ||
| 128, | ||
| 134, | ||
| 3, | ||
| 65, | ||
| 189, | ||
| 80, | ||
| 66, | ||
| 142, | ||
| 50, | ||
| 244, | ||
| 98, | ||
| 61, | ||
| 68, | ||
| 117, | ||
| 240, | ||
| 124, | ||
| 240, |
There was a problem hiding this comment.
this value needs to be manually updated. My suggestion is to just let AI handle it at this point 😓
| /// `payer` funds the new accounts' rent and signs. It must be the program's | ||
| /// upgrade authority, as recorded in `program_data`, which must be the |
| @@ -39,13 +41,14 @@ use crate::SettlementInstruction; | |||
| /// Wire format: `[discriminator=3, manager (32 bytes), solver_authority (32 | |||
| /// bytes), reclaim_authority (32 bytes), settlement_owned_order_authority (32 | |||
| /// bytes)]`, 129 bytes. Required accounts: `[payer (W,S), state_pda (W), | |||
| /// native_sol_buffer (W), system_program (R)]`. The system program must be available for the | |||
| /// native_sol_buffer (W), program_data (R), system_program (R)]`. The system program must be available for the | |||
There was a problem hiding this comment.
Nit, the line lenght is off.
| /// program's `ProgramData` account under the upgradeable loader. It is meant | ||
| /// to be the transaction's fee payer: the state is created once at deployment and never deallocated, | ||
| /// so there's no need for a dedicated funding account separate from whoever | ||
| /// pays for the deployment transaction. |
There was a problem hiding this comment.
Nit, not part of this PR. I think this is clear and we can drop it.
| /// program's `ProgramData` account under the upgradeable loader. It is meant | |
| /// to be the transaction's fee payer: the state is created once at deployment and never deallocated, | |
| /// so there's no need for a dedicated funding account separate from whoever | |
| /// pays for the deployment transaction. | |
| /// program's `ProgramData` account under the upgradeable loader. |
| }); | ||
| // Only the upgrade authority recorded in the resolved programData account | ||
| // may initialize. | ||
| const programData = initialize.accounts[3].address; |
There was a problem hiding this comment.
Let's not use magic numbers like 3, we should rederive the account we need.
Also, the next function's signature would look a lot more natural to me if it were setUpgradeAuthority(svm, program*Id*, payer.address), why should someone care about the program data at this point?
| /// Record `authority` as the upgrade authority in the `programData` account, | ||
| /// which LiteSVM deploys without one. The authority sits after the | ||
| /// `ProgramData` header's variant tag (4 bytes), slot (8 bytes) and | ||
| /// `Option` tag (1 byte). |
There was a problem hiding this comment.
Can't we do better than a lot of magic constants?
| if !payer.is_signer() || program_data.address() != &get_program_data_address(program_id) { | ||
| return Err(SettlementError::UnauthorizedInitialize.into()); | ||
| } | ||
| // The program bytes trail the loader state, which `deserialize` ignores. |
There was a problem hiding this comment.
Will need to read up on how this serializes.
There was a problem hiding this comment.
Suggested test: rejects_reinitializing_after_renouncing_upgrade_authority.
|
asked to simplify this PR to use the constant owner approach to prevent needing to understand BPF loader. will close this in favor of #191 |
# Description Make it so that only a hardcoded address defined in the program can call `Initialize`. ## Motivation Its technically possible that after program deployment, someone could come in and call `Initialize`, setting their own data and permissions, prior to us being able to do so. This, and could cause us to lose the ability to use a deployment address that we want to use. To prevent this from happening, we need some access control. ## Other considerations It was also previously considered in #187 to use the BPF Upgradalbe loader's upgrade authority. In honesty this is probably the best way to go as the deployer would always be matched up with whoever actually pushed up the program, but we are in a hurry and this option is much simpler and works almost as well. In the case that the program is accidentally deployed with the wrong `DEPLOYER` set, it is possible for the upgrade authority to redeploy the program with the correct `DEPLOYER` and try again, so the consequences of a mistaken deployment are low. --------- Co-authored-by: Federico Giacon <58218759+fedgiac@users.noreply.github.com>
Description
Make it so that only the BPF Upgradable Loader's upgrade authority (same as the original deployer of the program) can call
InitializeMotivation
Its technically possible that after program deployment, someone could come in and call
Initialize, setting their own data and permissions, prior to us being able to do so. This, and could cause us to lose the ability to use a deployment address that we want to use. To prevent this from happening, we need some access control. And conveniently, the address of the program deployer is stored in the BPF upgradable loader!Other considerations
In the absolute simplest case, we could have gated the initialize function to specified constant address. This would allow for no breaking change to the Initialize interface and absolute simplest change. But its not too hard to have it use the BPF upgradable address and we want to make sure the initialization process is as robust and straightforward as possible.
The Program Data account structure is well known and simple, so we could have hardcoded the data to decode it right in our project without depending upon the new
solana-loader-v3-interfacedependency. But as we are approaching launch and having this be overly complicated is unnecessary, I like this approach.