fix(lee,lez): derive PDAs from AccountId instead of ProgramId

CallerData and the PDA derivation primitives keyed authorization off a
program's image id (ProgramId), so two deployments of identical bytecode
with different update_auth collided on the same PDA. Switch derivation,
wire fields, and comparisons to the program's real dispatch AccountId
throughout the host, guest, and test-harness code, including the
privacy-circuit test harness's default dispatch address and the
wrapped_token/ping_receiver governance-authorization check, which
compared against the wrong address via the legacy bijection.
This commit is contained in:
Marvin Jones
2026-08-23 00:27:07 -04:00
parent 31b5b51a6c
commit 013e439c60
118 changed files with 1346 additions and 1357 deletions
+13 -9
View File
@@ -90,26 +90,26 @@ fn deploy_seed(
#[must_use]
pub fn deploy_header_account_id(
loader_program_id: ProgramId,
loader_account_id: AccountId,
image_id: ProgramId,
segment_number: u32,
update_auth: AccountId,
) -> AccountId {
AccountId::for_public_pda(
&loader_program_id,
&loader_account_id,
&deploy_header_pda_seed(image_id, segment_number, update_auth),
)
}
#[must_use]
pub fn deploy_segment_account_id(
loader_program_id: ProgramId,
loader_account_id: AccountId,
image_id: ProgramId,
segment_number: u32,
update_auth: AccountId,
) -> AccountId {
AccountId::for_public_pda(
&loader_program_id,
&loader_account_id,
&deploy_segment_pda_seed(image_id, segment_number, update_auth),
)
}
@@ -121,8 +121,12 @@ pub fn deploy_segment_account_id(
/// and any `Deploy` submitted with a default `update_auth`, dispatches at.
#[must_use]
pub fn immutable_deploy_account_id(image_id: ProgramId) -> AccountId {
let loader_id = ProgramId::from(lee_core::program::RESERVED_DEPLOYMENT_PROGRAM_ACCOUNT_ID);
deploy_header_account_id(loader_id, image_id, 0, AccountId::default())
deploy_header_account_id(
lee_core::program::RESERVED_DEPLOYMENT_PROGRAM_ACCOUNT_ID,
image_id,
0,
AccountId::default(),
)
}
/// Executes the `Deploy` instruction.
@@ -132,7 +136,7 @@ pub fn immutable_deploy_account_id(image_id: ProgramId) -> AccountId {
/// shortcut, which runs this instead of interpreting a guest ELF.
#[must_use]
pub fn execute_deploy(
self_program_id: ProgramId,
self_account_id: AccountId,
pre_states: Vec<AccountWithMetadata>,
bytecode: Vec<u8>,
) -> Vec<AccountPostState> {
@@ -143,8 +147,8 @@ pub fn execute_deploy(
let update_auth = AccountId::default();
let header_seed = deploy_header_pda_seed(image_id, segment_number, update_auth);
let segment_seed = deploy_segment_pda_seed(image_id, segment_number, update_auth);
let header_pda = AccountId::for_public_pda(&self_program_id, &header_seed);
let segment_pda = AccountId::for_public_pda(&self_program_id, &segment_seed);
let header_pda = AccountId::for_public_pda(&self_account_id, &header_seed);
let segment_pda = AccountId::for_public_pda(&self_account_id, &segment_seed);
let [header_target, segment_target] = pre_states
.try_into()