* Allow SetUpgradeAuthority instruction in CPI calls (#16676)
* feat: allow SetAuthority in CLI calls
* chore: clippy match_like_matches_macro
* chore: clippy match_like_matches_macro
* chore: rename CLI to CPI
* chore: move check for cpi authorised instruction to syscalls
* chore: add set_upgrade_authority cpi test
* chore: assert upgrade authority was changed
* feat: gate set_upgrade_authority via cpi with a feature
* chore: move feature to the end of the list
* chore: remove white spaces
* chore: remove white spaces
* chore: update comment to rerun build
(cherry picked from commit 1a658c7f31
)
# Conflicts:
# programs/bpf/Cargo.toml
# programs/bpf_loader/src/syscalls.rs
# sdk/src/feature_set.rs
* chore: fixe merge conflicts
Co-authored-by: Sebastian Bor <Sebastian_Bor@hotmail.com>
This commit is contained in:
@@ -192,6 +192,10 @@ pub fn is_upgrade_instruction(instruction_data: &[u8]) -> bool {
|
||||
3 == instruction_data[0]
|
||||
}
|
||||
|
||||
pub fn is_set_authority_instruction(instruction_data: &[u8]) -> bool {
|
||||
4 == instruction_data[0]
|
||||
}
|
||||
|
||||
/// Returns the instructions required to set a buffers's authority.
|
||||
pub fn set_buffer_authority(
|
||||
buffer_address: &Pubkey,
|
||||
@@ -262,44 +266,82 @@ mod tests {
|
||||
);
|
||||
}
|
||||
|
||||
fn assert_is_instruction<F>(
|
||||
is_instruction_fn: F,
|
||||
expected_instruction: UpgradeableLoaderInstruction,
|
||||
) where
|
||||
F: Fn(&[u8]) -> bool,
|
||||
{
|
||||
let result = is_instruction_fn(
|
||||
&bincode::serialize(&UpgradeableLoaderInstruction::InitializeBuffer).unwrap(),
|
||||
);
|
||||
let expected_result = matches!(
|
||||
expected_instruction,
|
||||
UpgradeableLoaderInstruction::InitializeBuffer
|
||||
);
|
||||
assert_eq!(expected_result, result);
|
||||
|
||||
let result = is_instruction_fn(
|
||||
&bincode::serialize(&UpgradeableLoaderInstruction::Write {
|
||||
offset: 0,
|
||||
bytes: vec![],
|
||||
})
|
||||
.unwrap(),
|
||||
);
|
||||
let expected_result = matches!(
|
||||
expected_instruction,
|
||||
UpgradeableLoaderInstruction::Write {
|
||||
offset: _,
|
||||
bytes: _,
|
||||
}
|
||||
);
|
||||
assert_eq!(expected_result, result);
|
||||
|
||||
let result = is_instruction_fn(
|
||||
&bincode::serialize(&UpgradeableLoaderInstruction::DeployWithMaxDataLen {
|
||||
max_data_len: 0,
|
||||
})
|
||||
.unwrap(),
|
||||
);
|
||||
let expected_result = matches!(
|
||||
expected_instruction,
|
||||
UpgradeableLoaderInstruction::DeployWithMaxDataLen { max_data_len: _ }
|
||||
);
|
||||
assert_eq!(expected_result, result);
|
||||
|
||||
let result =
|
||||
is_instruction_fn(&bincode::serialize(&UpgradeableLoaderInstruction::Upgrade).unwrap());
|
||||
let expected_result = matches!(expected_instruction, UpgradeableLoaderInstruction::Upgrade);
|
||||
assert_eq!(expected_result, result);
|
||||
|
||||
let result = is_instruction_fn(
|
||||
&bincode::serialize(&UpgradeableLoaderInstruction::SetAuthority).unwrap(),
|
||||
);
|
||||
let expected_result = matches!(
|
||||
expected_instruction,
|
||||
UpgradeableLoaderInstruction::SetAuthority
|
||||
);
|
||||
assert_eq!(expected_result, result);
|
||||
|
||||
let result =
|
||||
is_instruction_fn(&bincode::serialize(&UpgradeableLoaderInstruction::Close).unwrap());
|
||||
let expected_result = matches!(expected_instruction, UpgradeableLoaderInstruction::Close);
|
||||
assert_eq!(expected_result, result);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_is_set_authority_instruction() {
|
||||
assert_is_instruction(
|
||||
is_set_authority_instruction,
|
||||
UpgradeableLoaderInstruction::SetAuthority {},
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_is_upgrade_instruction() {
|
||||
assert_eq!(
|
||||
false,
|
||||
is_upgrade_instruction(
|
||||
&bincode::serialize(&UpgradeableLoaderInstruction::InitializeBuffer).unwrap()
|
||||
)
|
||||
);
|
||||
assert_eq!(
|
||||
false,
|
||||
is_upgrade_instruction(
|
||||
&bincode::serialize(&UpgradeableLoaderInstruction::Write {
|
||||
offset: 0,
|
||||
bytes: vec![],
|
||||
})
|
||||
.unwrap()
|
||||
)
|
||||
);
|
||||
assert_eq!(
|
||||
false,
|
||||
is_upgrade_instruction(
|
||||
&bincode::serialize(&UpgradeableLoaderInstruction::DeployWithMaxDataLen {
|
||||
max_data_len: 0,
|
||||
})
|
||||
.unwrap()
|
||||
)
|
||||
);
|
||||
assert_eq!(
|
||||
true,
|
||||
is_upgrade_instruction(
|
||||
&bincode::serialize(&UpgradeableLoaderInstruction::Upgrade).unwrap()
|
||||
)
|
||||
);
|
||||
assert_eq!(
|
||||
false,
|
||||
is_upgrade_instruction(
|
||||
&bincode::serialize(&UpgradeableLoaderInstruction::SetAuthority).unwrap()
|
||||
)
|
||||
assert_is_instruction(
|
||||
is_upgrade_instruction,
|
||||
UpgradeableLoaderInstruction::Upgrade {},
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@@ -126,6 +126,9 @@ pub mod check_duplicates_by_hash {
|
||||
pub mod enforce_aligned_host_addrs {
|
||||
solana_sdk::declare_id!("6Qob9Z4RwGdf599FDVCqsjuKjR8ZFR3oVs2ByRLWBsua");
|
||||
}
|
||||
pub mod set_upgrade_authority_via_cpi_enabled {
|
||||
solana_sdk::declare_id!("GQdjCCptpGECG7QfE35hKTAopB1umGoSrdKfax2VmZWy");
|
||||
}
|
||||
|
||||
pub mod update_data_on_realloc {
|
||||
solana_sdk::declare_id!("BkPcYCrwHXBoTsv9vMhiRF9gteZmDj3Uwisz9CDjoMKp");
|
||||
@@ -164,6 +167,7 @@ lazy_static! {
|
||||
(check_duplicates_by_hash::id(), "use transaction message hash for duplicate check"),
|
||||
(enforce_aligned_host_addrs::id(), "enforce aligned host addresses"),
|
||||
(update_data_on_realloc::id(), "Retain updated data values modified after realloc via CPI"),
|
||||
(set_upgrade_authority_via_cpi_enabled::id(), "set upgrade authority instruction via cpi calls for upgradable programs"),
|
||||
/*************** ADD NEW FEATURES HERE ***************/
|
||||
]
|
||||
.iter()
|
||||
|
Reference in New Issue
Block a user