Skip to content

Commit 3593bec

Browse files
committed
Add feature gate
1 parent 7fc5a1b commit 3593bec

File tree

5 files changed

+92
-35
lines changed

5 files changed

+92
-35
lines changed

feature-set/src/lib.rs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1220,6 +1220,10 @@ pub mod bls_pubkey_management_in_vote_account {
12201220
solana_pubkey::declare_id!("EGJLweNUVskAPEwpjvNB7JT6uUi6h4mFhowNYXVSrimG");
12211221
}
12221222

1223+
pub mod relax_programdata_account_check_migration {
1224+
solana_pubkey::declare_id!("rexav5eNTUSNT1K2N7cfRjnthwhcP5BC25v2tA4rW4h");
1225+
}
1226+
12231227
pub static FEATURE_NAMES: LazyLock<AHashMap<Pubkey, &'static str>> = LazyLock::new(|| {
12241228
[
12251229
(secp256k1_program_enabled::id(), "secp256k1 program"),
@@ -2187,6 +2191,10 @@ pub static FEATURE_NAMES: LazyLock<AHashMap<Pubkey, &'static str>> = LazyLock::n
21872191
bls_pubkey_management_in_vote_account::id(),
21882192
"SIMD-0387: BLS Pubkey Management in Vote Account",
21892193
),
2194+
(
2195+
relax_programdata_account_check_migration::id(),
2196+
"SIMD-0444: Relax program data account check in migration",
2197+
),
21902198
/*************** ADD NEW FEATURES HERE ***************/
21912199
]
21922200
.iter()

runtime/src/bank.rs

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,7 @@ use {
6161
accounts_lt_hash::{CacheValue as AccountsLtHashCacheValue, Stats as AccountsLtHashStats},
6262
agave_feature_set::{
6363
self as feature_set, increase_cpi_account_info_limit, raise_cpi_nesting_limit_to_8,
64-
FeatureSet,
64+
relax_programdata_account_check_migration, FeatureSet,
6565
},
6666
agave_precompiles::{get_precompile, get_precompiles, is_precompile},
6767
agave_reserved_account_keys::ReservedAccountKeys,
@@ -5440,6 +5440,8 @@ impl Bank {
54405440
if let Err(e) = self.upgrade_loader_v2_program_with_loader_v3_program(
54415441
&feature_set::replace_spl_token_with_p_token::SPL_TOKEN_PROGRAM_ID,
54425442
&feature_set::replace_spl_token_with_p_token::PTOKEN_PROGRAM_BUFFER,
5443+
self.feature_set
5444+
.is_active(&relax_programdata_account_check_migration::id()),
54435445
"replace_spl_token_with_p_token",
54445446
) {
54455447
warn!(
@@ -5474,9 +5476,12 @@ impl Bank {
54745476
// activation, perform the migration which will remove it from
54755477
// the builtins list and the cache.
54765478
if new_feature_activations.contains(&core_bpf_migration_config.feature_id) {
5477-
if let Err(e) = self
5478-
.migrate_builtin_to_core_bpf(&builtin.program_id, core_bpf_migration_config)
5479-
{
5479+
if let Err(e) = self.migrate_builtin_to_core_bpf(
5480+
&builtin.program_id,
5481+
core_bpf_migration_config,
5482+
self.feature_set
5483+
.is_active(&relax_programdata_account_check_migration::id()),
5484+
) {
54805485
warn!(
54815486
"Failed to migrate builtin {} to Core BPF: {}",
54825487
builtin.name, e
@@ -5495,6 +5500,8 @@ impl Bank {
54955500
if let Err(e) = self.migrate_builtin_to_core_bpf(
54965501
&stateless_builtin.program_id,
54975502
core_bpf_migration_config,
5503+
self.feature_set
5504+
.is_active(&relax_programdata_account_check_migration::id()),
54985505
) {
54995506
warn!(
55005507
"Failed to migrate stateless builtin {} to Core BPF: {}",

runtime/src/bank/builtins/core_bpf_migration/mod.rs

Lines changed: 19 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -217,11 +217,16 @@ impl Bank {
217217
&mut self,
218218
builtin_program_id: &Pubkey,
219219
config: &CoreBpfMigrationConfig,
220+
allow_prefunded: bool,
220221
) -> Result<(), CoreBpfMigrationError> {
221222
datapoint_info!(config.datapoint_name, ("slot", self.slot, i64));
222223

223-
let target =
224-
TargetBuiltin::new_checked(self, builtin_program_id, &config.migration_target)?;
224+
let target = TargetBuiltin::new_checked(
225+
self,
226+
builtin_program_id,
227+
&config.migration_target,
228+
allow_prefunded,
229+
)?;
225230
let source = if let Some(expected_hash) = config.verified_build_hash {
226231
SourceBuffer::new_checked_with_verified_build_hash(
227232
self,
@@ -382,6 +387,7 @@ impl Bank {
382387
/// self.upgrade_loader_v2_program_with_loader_v3_program(
383388
/// &bpf_loader_v2_program_address,
384389
/// &source_buffer_address,
390+
/// true,
385391
/// "test_upgrade_loader_v2_program_with_loader_v3_program",
386392
/// );
387393
/// }
@@ -393,11 +399,13 @@ impl Bank {
393399
&mut self,
394400
loader_v2_bpf_program_address: &Pubkey,
395401
source_buffer_address: &Pubkey,
402+
allow_prefunded: bool,
396403
datapoint_name: &'static str,
397404
) -> Result<(), CoreBpfMigrationError> {
398405
datapoint_info!(datapoint_name, ("slot", self.slot, i64));
399406

400-
let target = TargetBpfV2::new_checked(self, loader_v2_bpf_program_address)?;
407+
let target =
408+
TargetBpfV2::new_checked(self, loader_v2_bpf_program_address, allow_prefunded)?;
401409
let source = SourceBuffer::new_checked(self, source_buffer_address)?;
402410

403411
// Attempt serialization first before modifying the bank.
@@ -795,7 +803,7 @@ pub(crate) mod tests {
795803

796804
// Perform the migration.
797805
let migration_slot = bank.slot();
798-
bank.migrate_builtin_to_core_bpf(&builtin_id, &core_bpf_migration_config)
806+
bank.migrate_builtin_to_core_bpf(&builtin_id, &core_bpf_migration_config, true)
799807
.unwrap();
800808

801809
// Run the post-migration program checks.
@@ -860,7 +868,7 @@ pub(crate) mod tests {
860868

861869
// Perform the migration.
862870
let migration_slot = bank.slot();
863-
bank.migrate_builtin_to_core_bpf(&builtin_id, &core_bpf_migration_config)
871+
bank.migrate_builtin_to_core_bpf(&builtin_id, &core_bpf_migration_config, true)
864872
.unwrap();
865873

866874
// Run the post-migration program checks.
@@ -927,7 +935,7 @@ pub(crate) mod tests {
927935
};
928936

929937
assert_matches!(
930-
bank.migrate_builtin_to_core_bpf(&builtin_id, &core_bpf_migration_config)
938+
bank.migrate_builtin_to_core_bpf(&builtin_id, &core_bpf_migration_config, true)
931939
.unwrap_err(),
932940
CoreBpfMigrationError::UpgradeAuthorityMismatch(_, _)
933941
)
@@ -981,7 +989,7 @@ pub(crate) mod tests {
981989
};
982990

983991
assert_matches!(
984-
bank.migrate_builtin_to_core_bpf(&builtin_id, &core_bpf_migration_config)
992+
bank.migrate_builtin_to_core_bpf(&builtin_id, &core_bpf_migration_config, true)
985993
.unwrap_err(),
986994
CoreBpfMigrationError::BuildHashMismatch(_, _)
987995
)
@@ -1043,7 +1051,7 @@ pub(crate) mod tests {
10431051
datapoint_name: "test_migrate_builtin",
10441052
};
10451053

1046-
bank.migrate_builtin_to_core_bpf(&builtin_id, &core_bpf_migration_config)
1054+
bank.migrate_builtin_to_core_bpf(&builtin_id, &core_bpf_migration_config, true)
10471055
.unwrap();
10481056

10491057
let program_data_address = get_program_data_address(&builtin_id);
@@ -1813,6 +1821,7 @@ pub(crate) mod tests {
18131821
bank.upgrade_loader_v2_program_with_loader_v3_program(
18141822
&bpf_loader_v2_program_address,
18151823
&source_buffer_address,
1824+
true,
18161825
"test_upgrade_loader_v2_program_with_loader_v3_program",
18171826
)
18181827
.unwrap();
@@ -1893,6 +1902,7 @@ pub(crate) mod tests {
18931902
bank.upgrade_loader_v2_program_with_loader_v3_program(
18941903
&bpf_loader_v2_program_address,
18951904
&source_buffer_address,
1905+
true,
18961906
"test_upgrade_loader_v2_program_with_loader_v3_program",
18971907
)
18981908
.unwrap_err(),
@@ -2090,6 +2100,7 @@ pub(crate) mod tests {
20902100
bank.upgrade_loader_v2_program_with_loader_v3_program(
20912101
&bpf_loader_v2_program_address,
20922102
&source_buffer_address,
2103+
true,
20932104
"test_upgrade_loader_v2_program_with_loader_v3_program",
20942105
)
20952106
.unwrap();

runtime/src/bank/builtins/core_bpf_migration/target_bpf_v2.rs

Lines changed: 24 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ use {
55
solana_account::{AccountSharedData, ReadableAccount},
66
solana_loader_v3_interface::get_program_data_address,
77
solana_pubkey::Pubkey,
8-
solana_sdk_ids::{bpf_loader, system_program},
8+
solana_sdk_ids::{bpf_loader, system_program::ID as SYSTEM_PROGRAM_ID},
99
};
1010

1111
/// The account details of a Loader v2 BPF program slated to be upgraded.
@@ -25,6 +25,7 @@ impl TargetBpfV2 {
2525
pub(crate) fn new_checked(
2626
bank: &Bank,
2727
program_address: &Pubkey,
28+
allow_prefunded: bool,
2829
) -> Result<Self, CoreBpfMigrationError> {
2930
// The program account should exist.
3031
let program_account = bank
@@ -45,20 +46,32 @@ impl TargetBpfV2 {
4546

4647
let program_data_address = get_program_data_address(program_address);
4748

48-
// The program data account is expected not to exist.
49-
let program_data_account_lamports =
49+
let program_data_account_lamports = if allow_prefunded {
50+
// The program data account should not exist, but a system account with funded
51+
// lamports is acceptable.
5052
if let Some(account) = bank.get_account_with_fixed_root(&program_data_address) {
51-
// The program data account should not exist, but a system account with funded
52-
// lamports is acceptable.
53-
if account.owner() != &system_program::id() {
53+
if account.owner() != &SYSTEM_PROGRAM_ID {
5454
return Err(CoreBpfMigrationError::ProgramHasDataAccount(
5555
*program_address,
5656
));
5757
}
5858
account.lamports()
5959
} else {
6060
0
61-
};
61+
}
62+
} else {
63+
// The program data account should not exist and have zero lamports.
64+
if bank
65+
.get_account_with_fixed_root(&program_data_address)
66+
.is_some()
67+
{
68+
return Err(CoreBpfMigrationError::ProgramHasDataAccount(
69+
*program_address,
70+
));
71+
}
72+
73+
0
74+
};
6275

6376
Ok(Self {
6477
program_address: *program_address,
@@ -94,7 +107,7 @@ mod tests {
94107

95108
// Fail if the program account does not exist.
96109
assert_matches!(
97-
TargetBpfV2::new_checked(&bank, &program_address).unwrap_err(),
110+
TargetBpfV2::new_checked(&bank, &program_address, true).unwrap_err(),
98111
CoreBpfMigrationError::AccountNotFound(..)
99112
);
100113

@@ -107,7 +120,7 @@ mod tests {
107120
true,
108121
);
109122
assert_matches!(
110-
TargetBpfV2::new_checked(&bank, &program_address).unwrap_err(),
123+
TargetBpfV2::new_checked(&bank, &program_address, true).unwrap_err(),
111124
CoreBpfMigrationError::IncorrectOwner(..)
112125
);
113126

@@ -120,14 +133,14 @@ mod tests {
120133
false, // Not executable
121134
);
122135
assert_matches!(
123-
TargetBpfV2::new_checked(&bank, &program_address).unwrap_err(),
136+
TargetBpfV2::new_checked(&bank, &program_address, true).unwrap_err(),
124137
CoreBpfMigrationError::ProgramAccountNotExecutable(..)
125138
);
126139

127140
// Success
128141
store_account(&bank, &program_address, &elf, &bpf_loader::id(), true);
129142

130-
let target_bpf_v2 = TargetBpfV2::new_checked(&bank, &program_address).unwrap();
143+
let target_bpf_v2 = TargetBpfV2::new_checked(&bank, &program_address, true).unwrap();
131144

132145
assert_eq!(target_bpf_v2.program_address, program_address);
133146
assert_eq!(target_bpf_v2.program_account.data(), elf.as_slice());

runtime/src/bank/builtins/core_bpf_migration/target_builtin.rs

Lines changed: 30 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ impl TargetBuiltin {
2626
bank: &Bank,
2727
program_address: &Pubkey,
2828
migration_target: &CoreBpfMigrationTargetType,
29+
allow_prefunded: bool,
2930
) -> Result<Self, CoreBpfMigrationError> {
3031
let program_account = match migration_target {
3132
CoreBpfMigrationTargetType::Builtin => {
@@ -53,11 +54,10 @@ impl TargetBuiltin {
5354

5455
let program_data_address = get_program_data_address(program_address);
5556

56-
// The program data account is expected not to exist.
57-
let program_data_account_lamports =
57+
let program_data_account_lamports = if allow_prefunded {
58+
// The program data account should not exist, but a system account with funded
59+
// lamports is acceptable.
5860
if let Some(account) = bank.get_account_with_fixed_root(&program_data_address) {
59-
// The program data account should not exist, but a system account with funded
60-
// lamports is acceptable.
6161
if account.owner() != &SYSTEM_PROGRAM_ID {
6262
return Err(CoreBpfMigrationError::ProgramHasDataAccount(
6363
*program_address,
@@ -66,7 +66,20 @@ impl TargetBuiltin {
6666
account.lamports()
6767
} else {
6868
0
69-
};
69+
}
70+
} else {
71+
// The program data account should not exist and have zero lamports.
72+
if bank
73+
.get_account_with_fixed_root(&program_data_address)
74+
.is_some()
75+
{
76+
return Err(CoreBpfMigrationError::ProgramHasDataAccount(
77+
*program_address,
78+
));
79+
}
80+
81+
0
82+
};
7083

7184
Ok(Self {
7285
program_address: *program_address,
@@ -147,7 +160,7 @@ mod tests {
147160

148161
// Success
149162
let target_builtin =
150-
TargetBuiltin::new_checked(&bank, &program_address, &migration_target).unwrap();
163+
TargetBuiltin::new_checked(&bank, &program_address, &migration_target, true).unwrap();
151164
assert_eq!(target_builtin.program_address, program_address);
152165
assert_eq!(target_builtin.program_account, program_account);
153166
assert_eq!(target_builtin.program_data_address, program_data_address);
@@ -161,7 +174,8 @@ mod tests {
161174
&Pubkey::new_unique(), // Not the native loader
162175
);
163176
assert_matches!(
164-
TargetBuiltin::new_checked(&bank, &program_address, &migration_target).unwrap_err(),
177+
TargetBuiltin::new_checked(&bank, &program_address, &migration_target, true)
178+
.unwrap_err(),
165179
CoreBpfMigrationError::IncorrectOwner(..)
166180
);
167181

@@ -184,7 +198,8 @@ mod tests {
184198
&BPF_LOADER_UPGRADEABLE_ID,
185199
);
186200
assert_matches!(
187-
TargetBuiltin::new_checked(&bank, &program_address, &migration_target).unwrap_err(),
201+
TargetBuiltin::new_checked(&bank, &program_address, &migration_target, true)
202+
.unwrap_err(),
188203
CoreBpfMigrationError::ProgramHasDataAccount(..)
189204
);
190205

@@ -194,7 +209,8 @@ mod tests {
194209
&AccountSharedData::default(),
195210
);
196211
assert_matches!(
197-
TargetBuiltin::new_checked(&bank, &program_address, &migration_target).unwrap_err(),
212+
TargetBuiltin::new_checked(&bank, &program_address, &migration_target, true)
213+
.unwrap_err(),
198214
CoreBpfMigrationError::AccountNotFound(..)
199215
);
200216
}
@@ -210,7 +226,7 @@ mod tests {
210226

211227
// Success
212228
let target_builtin =
213-
TargetBuiltin::new_checked(&bank, &program_address, &migration_target).unwrap();
229+
TargetBuiltin::new_checked(&bank, &program_address, &migration_target, true).unwrap();
214230
assert_eq!(target_builtin.program_address, program_address);
215231
assert_eq!(target_builtin.program_account, program_account);
216232
assert_eq!(target_builtin.program_data_address, program_data_address);
@@ -227,7 +243,8 @@ mod tests {
227243
&BPF_LOADER_UPGRADEABLE_ID,
228244
);
229245
assert_matches!(
230-
TargetBuiltin::new_checked(&bank, &program_address, &migration_target).unwrap_err(),
246+
TargetBuiltin::new_checked(&bank, &program_address, &migration_target, true)
247+
.unwrap_err(),
231248
CoreBpfMigrationError::ProgramHasDataAccount(..)
232249
);
233250

@@ -240,7 +257,8 @@ mod tests {
240257
&NATIVE_LOADER_ID,
241258
);
242259
assert_matches!(
243-
TargetBuiltin::new_checked(&bank, &program_address, &migration_target).unwrap_err(),
260+
TargetBuiltin::new_checked(&bank, &program_address, &migration_target, true)
261+
.unwrap_err(),
244262
CoreBpfMigrationError::AccountExists(..)
245263
);
246264
}

0 commit comments

Comments
 (0)