* Remove native id check in pda creation (#19595)
(cherry picked from commit 529fefc7cc
)
# Conflicts:
# programs/bpf/rust/invoke/src/lib.rs
# programs/bpf_loader/src/syscalls.rs
# sdk/src/feature_set.rs
* resolve conflicts
Co-authored-by: Jack May <jack@solana.com>
This commit is contained in:
@ -263,10 +263,9 @@ fn process_instruction(
|
|||||||
)?,
|
)?,
|
||||||
accounts[DERIVED_KEY1_INDEX].key
|
accounts[DERIVED_KEY1_INDEX].key
|
||||||
);
|
);
|
||||||
let not_native_program_id = Pubkey::new_from_array([6u8; 32]);
|
let new_program_id = Pubkey::new_from_array([6u8; 32]);
|
||||||
assert!(!not_native_program_id.is_native_program_id());
|
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
Pubkey::create_program_address(&[b"You pass butter"], ¬_native_program_id)
|
Pubkey::create_program_address(&[b"You pass butter"], &new_program_id)
|
||||||
.unwrap_err(),
|
.unwrap_err(),
|
||||||
PubkeyError::InvalidSeeds
|
PubkeyError::InvalidSeeds
|
||||||
);
|
);
|
||||||
@ -278,10 +277,9 @@ fn process_instruction(
|
|||||||
Pubkey::try_find_program_address(&[b"You pass butter"], program_id).unwrap();
|
Pubkey::try_find_program_address(&[b"You pass butter"], program_id).unwrap();
|
||||||
assert_eq!(&address, accounts[DERIVED_KEY1_INDEX].key);
|
assert_eq!(&address, accounts[DERIVED_KEY1_INDEX].key);
|
||||||
assert_eq!(bump_seed, bump_seed1);
|
assert_eq!(bump_seed, bump_seed1);
|
||||||
let not_native_program_id = Pubkey::new_from_array([6u8; 32]);
|
let new_program_id = Pubkey::new_from_array([6u8; 32]);
|
||||||
assert!(!not_native_program_id.is_native_program_id());
|
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
Pubkey::create_program_address(&[b"You pass butter"], ¬_native_program_id)
|
Pubkey::create_program_address(&[b"You pass butter"], &new_program_id)
|
||||||
.unwrap_err(),
|
.unwrap_err(),
|
||||||
PubkeyError::InvalidSeeds
|
PubkeyError::InvalidSeeds
|
||||||
);
|
);
|
||||||
@ -653,16 +651,3 @@ fn process_instruction(
|
|||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
|
||||||
mod test {
|
|
||||||
use super::*;
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn create_program_address_is_defined() {
|
|
||||||
assert_eq!(
|
|
||||||
Pubkey::create_program_address(&[b"You pass butter"], &Pubkey::default()).unwrap_err(),
|
|
||||||
PubkeyError::InvalidSeeds
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
@ -19,10 +19,11 @@ use solana_sdk::{
|
|||||||
entrypoint::{MAX_PERMITTED_DATA_INCREASE, SUCCESS},
|
entrypoint::{MAX_PERMITTED_DATA_INCREASE, SUCCESS},
|
||||||
epoch_schedule::EpochSchedule,
|
epoch_schedule::EpochSchedule,
|
||||||
feature_set::{
|
feature_set::{
|
||||||
close_upgradeable_program_accounts, cpi_data_cost, demote_program_write_locks,
|
allow_native_ids, close_upgradeable_program_accounts, cpi_data_cost,
|
||||||
enforce_aligned_host_addrs, keccak256_syscall_enabled, libsecp256k1_0_5_upgrade_enabled,
|
demote_program_write_locks, enforce_aligned_host_addrs, keccak256_syscall_enabled,
|
||||||
mem_overlap_fix, memory_ops_syscalls, secp256k1_recover_syscall_enabled,
|
libsecp256k1_0_5_upgrade_enabled, mem_overlap_fix, memory_ops_syscalls,
|
||||||
set_upgrade_authority_via_cpi_enabled, sysvar_via_syscall, update_data_on_realloc,
|
secp256k1_recover_syscall_enabled, set_upgrade_authority_via_cpi_enabled,
|
||||||
|
sysvar_via_syscall, update_data_on_realloc,
|
||||||
},
|
},
|
||||||
hash::{Hasher, HASH_BYTES},
|
hash::{Hasher, HASH_BYTES},
|
||||||
ic_msg,
|
ic_msg,
|
||||||
@ -31,7 +32,7 @@ use solana_sdk::{
|
|||||||
keyed_account::KeyedAccount,
|
keyed_account::KeyedAccount,
|
||||||
native_loader,
|
native_loader,
|
||||||
process_instruction::{self, stable_log, ComputeMeter, InvokeContext, Logger},
|
process_instruction::{self, stable_log, ComputeMeter, InvokeContext, Logger},
|
||||||
pubkey::{Pubkey, PubkeyError, MAX_SEEDS},
|
pubkey::{Pubkey, PubkeyError, MAX_SEEDS, MAX_SEED_LEN},
|
||||||
rent::Rent,
|
rent::Rent,
|
||||||
secp256k1_recover::{
|
secp256k1_recover::{
|
||||||
Secp256k1RecoverError, SECP256K1_PUBLIC_KEY_LENGTH, SECP256K1_SIGNATURE_LENGTH,
|
Secp256k1RecoverError, SECP256K1_PUBLIC_KEY_LENGTH, SECP256K1_SIGNATURE_LENGTH,
|
||||||
@ -247,22 +248,24 @@ pub fn bind_syscall_context_objects<'a>(
|
|||||||
None,
|
None,
|
||||||
)?;
|
)?;
|
||||||
|
|
||||||
|
let allow_native_ids = invoke_context.is_feature_active(&allow_native_ids::id());
|
||||||
vm.bind_syscall_context_object(
|
vm.bind_syscall_context_object(
|
||||||
Box::new(SyscallCreateProgramAddress {
|
Box::new(SyscallCreateProgramAddress {
|
||||||
cost: bpf_compute_budget.create_program_address_units,
|
cost: bpf_compute_budget.create_program_address_units,
|
||||||
compute_meter: invoke_context.get_compute_meter(),
|
compute_meter: invoke_context.get_compute_meter(),
|
||||||
loader_id,
|
loader_id,
|
||||||
enforce_aligned_host_addrs,
|
enforce_aligned_host_addrs,
|
||||||
|
allow_native_ids,
|
||||||
}),
|
}),
|
||||||
None,
|
None,
|
||||||
)?;
|
)?;
|
||||||
|
|
||||||
vm.bind_syscall_context_object(
|
vm.bind_syscall_context_object(
|
||||||
Box::new(SyscallTryFindProgramAddress {
|
Box::new(SyscallTryFindProgramAddress {
|
||||||
cost: bpf_compute_budget.create_program_address_units,
|
cost: bpf_compute_budget.create_program_address_units,
|
||||||
compute_meter: invoke_context.get_compute_meter(),
|
compute_meter: invoke_context.get_compute_meter(),
|
||||||
loader_id,
|
loader_id,
|
||||||
enforce_aligned_host_addrs,
|
enforce_aligned_host_addrs,
|
||||||
|
allow_native_ids,
|
||||||
}),
|
}),
|
||||||
None,
|
None,
|
||||||
)?;
|
)?;
|
||||||
@ -830,12 +833,42 @@ fn translate_program_address_inputs<'a>(
|
|||||||
Ok((seeds, program_id))
|
Ok((seeds, program_id))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn is_native_id(seeds: &[&[u8]], program_id: &Pubkey) -> bool {
|
||||||
|
use solana_sdk::{config, feature, secp256k1_program, stake, system_program, vote};
|
||||||
|
// Does more than just check native ids in order to emulate the same failure
|
||||||
|
// signature that `compute_program_address` had before the removal of the
|
||||||
|
// check.
|
||||||
|
if seeds.len() > MAX_SEEDS {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
for seed in seeds.iter() {
|
||||||
|
if seed.len() > MAX_SEED_LEN {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
let native_ids = [
|
||||||
|
bpf_loader::id(),
|
||||||
|
bpf_loader_deprecated::id(),
|
||||||
|
feature::id(),
|
||||||
|
config::program::id(),
|
||||||
|
stake::program::id(),
|
||||||
|
stake::config::id(),
|
||||||
|
vote::program::id(),
|
||||||
|
secp256k1_program::id(),
|
||||||
|
system_program::id(),
|
||||||
|
sysvar::id(),
|
||||||
|
];
|
||||||
|
native_ids.contains(program_id)
|
||||||
|
}
|
||||||
|
|
||||||
/// Create a program address
|
/// Create a program address
|
||||||
struct SyscallCreateProgramAddress<'a> {
|
struct SyscallCreateProgramAddress<'a> {
|
||||||
cost: u64,
|
cost: u64,
|
||||||
compute_meter: Rc<RefCell<dyn ComputeMeter>>,
|
compute_meter: Rc<RefCell<dyn ComputeMeter>>,
|
||||||
loader_id: &'a Pubkey,
|
loader_id: &'a Pubkey,
|
||||||
enforce_aligned_host_addrs: bool,
|
enforce_aligned_host_addrs: bool,
|
||||||
|
allow_native_ids: bool,
|
||||||
}
|
}
|
||||||
impl<'a> SyscallObject<BpfError> for SyscallCreateProgramAddress<'a> {
|
impl<'a> SyscallObject<BpfError> for SyscallCreateProgramAddress<'a> {
|
||||||
fn call(
|
fn call(
|
||||||
@ -861,6 +894,12 @@ impl<'a> SyscallObject<BpfError> for SyscallCreateProgramAddress<'a> {
|
|||||||
);
|
);
|
||||||
|
|
||||||
question_mark!(self.compute_meter.consume(self.cost), result);
|
question_mark!(self.compute_meter.consume(self.cost), result);
|
||||||
|
|
||||||
|
if !self.allow_native_ids && is_native_id(&seeds, program_id) {
|
||||||
|
*result = Ok(1);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
let new_address = match Pubkey::create_program_address(&seeds, program_id) {
|
let new_address = match Pubkey::create_program_address(&seeds, program_id) {
|
||||||
Ok(address) => address,
|
Ok(address) => address,
|
||||||
Err(_) => {
|
Err(_) => {
|
||||||
@ -889,6 +928,7 @@ struct SyscallTryFindProgramAddress<'a> {
|
|||||||
compute_meter: Rc<RefCell<dyn ComputeMeter>>,
|
compute_meter: Rc<RefCell<dyn ComputeMeter>>,
|
||||||
loader_id: &'a Pubkey,
|
loader_id: &'a Pubkey,
|
||||||
enforce_aligned_host_addrs: bool,
|
enforce_aligned_host_addrs: bool,
|
||||||
|
allow_native_ids: bool,
|
||||||
}
|
}
|
||||||
impl<'a> SyscallObject<BpfError> for SyscallTryFindProgramAddress<'a> {
|
impl<'a> SyscallObject<BpfError> for SyscallTryFindProgramAddress<'a> {
|
||||||
fn call(
|
fn call(
|
||||||
@ -920,32 +960,35 @@ impl<'a> SyscallObject<BpfError> for SyscallTryFindProgramAddress<'a> {
|
|||||||
seeds_with_bump.push(&bump_seed);
|
seeds_with_bump.push(&bump_seed);
|
||||||
|
|
||||||
question_mark!(self.compute_meter.consume(self.cost), result);
|
question_mark!(self.compute_meter.consume(self.cost), result);
|
||||||
if let Ok(new_address) =
|
|
||||||
Pubkey::create_program_address(&seeds_with_bump, program_id)
|
if self.allow_native_ids || !is_native_id(&seeds, program_id) {
|
||||||
{
|
if let Ok(new_address) =
|
||||||
let bump_seed_ref = question_mark!(
|
Pubkey::create_program_address(&seeds_with_bump, program_id)
|
||||||
translate_type_mut::<u8>(
|
{
|
||||||
memory_mapping,
|
let bump_seed_ref = question_mark!(
|
||||||
bump_seed_addr,
|
translate_type_mut::<u8>(
|
||||||
self.loader_id,
|
memory_mapping,
|
||||||
self.enforce_aligned_host_addrs,
|
bump_seed_addr,
|
||||||
),
|
self.loader_id,
|
||||||
result
|
self.enforce_aligned_host_addrs,
|
||||||
);
|
),
|
||||||
let address = question_mark!(
|
result
|
||||||
translate_slice_mut::<u8>(
|
);
|
||||||
memory_mapping,
|
let address = question_mark!(
|
||||||
address_addr,
|
translate_slice_mut::<u8>(
|
||||||
32,
|
memory_mapping,
|
||||||
self.loader_id,
|
address_addr,
|
||||||
self.enforce_aligned_host_addrs,
|
32,
|
||||||
),
|
self.loader_id,
|
||||||
result
|
self.enforce_aligned_host_addrs,
|
||||||
);
|
),
|
||||||
*bump_seed_ref = bump_seed[0];
|
result
|
||||||
address.copy_from_slice(new_address.as_ref());
|
);
|
||||||
*result = Ok(0);
|
*bump_seed_ref = bump_seed[0];
|
||||||
return;
|
address.copy_from_slice(new_address.as_ref());
|
||||||
|
*result = Ok(0);
|
||||||
|
return;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
bump_seed[0] -= 1;
|
bump_seed[0] -= 1;
|
||||||
|
@ -1,8 +1,5 @@
|
|||||||
#![allow(clippy::integer_arithmetic)]
|
#![allow(clippy::integer_arithmetic)]
|
||||||
use crate::{
|
use crate::{decode_error::DecodeError, hash::hashv};
|
||||||
bpf_loader, bpf_loader_deprecated, config, decode_error::DecodeError, feature, hash::hashv,
|
|
||||||
secp256k1_program, stake, system_program, sysvar, vote,
|
|
||||||
};
|
|
||||||
|
|
||||||
use borsh::{BorshDeserialize, BorshSchema, BorshSerialize};
|
use borsh::{BorshDeserialize, BorshSchema, BorshSerialize};
|
||||||
use num_derive::{FromPrimitive, ToPrimitive};
|
use num_derive::{FromPrimitive, ToPrimitive};
|
||||||
@ -214,10 +211,6 @@ impl Pubkey {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if program_id.is_native_program_id() {
|
|
||||||
return Err(PubkeyError::IllegalOwner);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Perform the calculation inline, calling this from within a program is
|
// Perform the calculation inline, calling this from within a program is
|
||||||
// not supported
|
// not supported
|
||||||
#[cfg(not(target_arch = "bpf"))]
|
#[cfg(not(target_arch = "bpf"))]
|
||||||
@ -368,22 +361,6 @@ impl Pubkey {
|
|||||||
#[cfg(not(target_arch = "bpf"))]
|
#[cfg(not(target_arch = "bpf"))]
|
||||||
crate::program_stubs::sol_log(&self.to_string());
|
crate::program_stubs::sol_log(&self.to_string());
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn is_native_program_id(&self) -> bool {
|
|
||||||
let all_program_ids = [
|
|
||||||
bpf_loader::id(),
|
|
||||||
bpf_loader_deprecated::id(),
|
|
||||||
feature::id(),
|
|
||||||
config::program::id(),
|
|
||||||
stake::program::id(),
|
|
||||||
stake::config::id(),
|
|
||||||
vote::program::id(),
|
|
||||||
secp256k1_program::id(),
|
|
||||||
system_program::id(),
|
|
||||||
sysvar::id(),
|
|
||||||
];
|
|
||||||
all_program_ids.contains(self)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl AsRef<[u8]> for Pubkey {
|
impl AsRef<[u8]> for Pubkey {
|
||||||
@ -600,20 +577,6 @@ mod tests {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn test_is_native_program_id() {
|
|
||||||
assert!(bpf_loader::id().is_native_program_id());
|
|
||||||
assert!(bpf_loader_deprecated::id().is_native_program_id());
|
|
||||||
assert!(config::program::id().is_native_program_id());
|
|
||||||
assert!(feature::id().is_native_program_id());
|
|
||||||
assert!(secp256k1_program::id().is_native_program_id());
|
|
||||||
assert!(stake::program::id().is_native_program_id());
|
|
||||||
assert!(stake::config::id().is_native_program_id());
|
|
||||||
assert!(system_program::id().is_native_program_id());
|
|
||||||
assert!(sysvar::id().is_native_program_id());
|
|
||||||
assert!(vote::program::id().is_native_program_id());
|
|
||||||
}
|
|
||||||
|
|
||||||
fn pubkey_from_seed_by_marker(marker: &[u8]) -> Result<Pubkey, PubkeyError> {
|
fn pubkey_from_seed_by_marker(marker: &[u8]) -> Result<Pubkey, PubkeyError> {
|
||||||
let key = Pubkey::new_unique();
|
let key = Pubkey::new_unique();
|
||||||
let owner = Pubkey::default();
|
let owner = Pubkey::default();
|
||||||
|
@ -191,6 +191,10 @@ pub mod demote_program_write_locks {
|
|||||||
solana_sdk::declare_id!("3E3jV7v9VcdJL8iYZUMax9DiDno8j7EWUVbhm9RtShj2");
|
solana_sdk::declare_id!("3E3jV7v9VcdJL8iYZUMax9DiDno8j7EWUVbhm9RtShj2");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub mod allow_native_ids {
|
||||||
|
solana_sdk::declare_id!("GVnDbNkECwrzLM7aVBGWpBYo3yH1ACaXB4ottNX8pedZ");
|
||||||
|
}
|
||||||
|
|
||||||
lazy_static! {
|
lazy_static! {
|
||||||
/// Map of feature identifiers to user-visible description
|
/// Map of feature identifiers to user-visible description
|
||||||
pub static ref FEATURE_NAMES: HashMap<Pubkey, &'static str> = [
|
pub static ref FEATURE_NAMES: HashMap<Pubkey, &'static str> = [
|
||||||
@ -239,6 +243,7 @@ lazy_static! {
|
|||||||
(close_upgradeable_program_accounts::id(), "enable closing upgradeable program accounts"),
|
(close_upgradeable_program_accounts::id(), "enable closing upgradeable program accounts"),
|
||||||
(stake_program_advance_activating_credits_observed::id(), "Enable advancing credits observed for activation epoch #19309"),
|
(stake_program_advance_activating_credits_observed::id(), "Enable advancing credits observed for activation epoch #19309"),
|
||||||
(demote_program_write_locks::id(), "demote program write locks to readonly #19593"),
|
(demote_program_write_locks::id(), "demote program write locks to readonly #19593"),
|
||||||
|
(allow_native_ids::id(), "allow native program ids in program derived addresses"),
|
||||||
/*************** ADD NEW FEATURES HERE ***************/
|
/*************** ADD NEW FEATURES HERE ***************/
|
||||||
]
|
]
|
||||||
.iter()
|
.iter()
|
||||||
|
Reference in New Issue
Block a user