diff --git a/Cargo.lock b/Cargo.lock index a525b81c5..ec06b6038 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2787,12 +2787,13 @@ dependencies = [ "ed25519-dalek", "hex", "rand 0.7.3", - "solana-feature-set", + "solana-feature-set-interface", "solana-hash", "solana-instruction", "solana-keypair", "solana-logger", "solana-precompile-error", + "solana-pubkey", "solana-sdk", "solana-sdk-ids", "solana-signer", @@ -2890,6 +2891,7 @@ dependencies = [ "ahash", "lazy_static", "solana-epoch-schedule", + "solana-feature-set-interface", "solana-frozen-abi", "solana-frozen-abi-macro", "solana-hash", @@ -3329,7 +3331,7 @@ version = "2.2.1" dependencies = [ "lazy_static", "solana-ed25519-program", - "solana-feature-set", + "solana-feature-set-interface", "solana-message", "solana-precompile-error", "solana-pubkey", @@ -3563,7 +3565,7 @@ name = "solana-reserved-account-keys" version = "2.2.1" dependencies = [ "lazy_static", - "solana-feature-set", + "solana-feature-set-interface", "solana-frozen-abi", "solana-frozen-abi-macro", "solana-message", @@ -3615,6 +3617,7 @@ dependencies = [ "solana-epoch-info", "solana-epoch-rewards-hasher", "solana-feature-set", + "solana-feature-set-interface", "solana-fee-structure", "solana-genesis-config", "solana-hard-forks", @@ -3694,7 +3697,7 @@ dependencies = [ "serde_derive", "sha3", "solana-account-info", - "solana-feature-set", + "solana-feature-set-interface", "solana-hash", "solana-instruction", "solana-instructions-sysvar", @@ -3730,10 +3733,12 @@ version = "2.2.1" dependencies = [ "bytemuck", "openssl", - "solana-feature-set", + "solana-feature-set-interface", "solana-instruction", "solana-logger", "solana-precompile-error", + "solana-pubkey", + "solana-reserved-account-keys", "solana-sdk", "solana-sdk-ids", ] @@ -3998,7 +4003,7 @@ dependencies = [ "serde", "serde_derive", "solana-bincode", - "solana-feature-set", + "solana-feature-set-interface", "solana-frozen-abi", "solana-frozen-abi-macro", "solana-hash", diff --git a/ed25519-program/Cargo.toml b/ed25519-program/Cargo.toml index b1506086e..8b6afc2fd 100644 --- a/ed25519-program/Cargo.toml +++ b/ed25519-program/Cargo.toml @@ -13,9 +13,10 @@ edition = { workspace = true } bytemuck = { workspace = true } bytemuck_derive = { workspace = true } ed25519-dalek = { workspace = true } -solana-feature-set = { workspace = true } +solana-feature-set-interface = { workspace = true } solana-instruction = { workspace = true, features = ["std"] } solana-precompile-error = { workspace = true } +solana-pubkey = { workspace = true } solana-sdk-ids = { workspace = true } [dev-dependencies] diff --git a/ed25519-program/src/lib.rs b/ed25519-program/src/lib.rs index fccd50b20..1fb705051 100644 --- a/ed25519-program/src/lib.rs +++ b/ed25519-program/src/lib.rs @@ -6,7 +6,7 @@ use { bytemuck::bytes_of, bytemuck_derive::{Pod, Zeroable}, ed25519_dalek::{ed25519::signature::Signature, Signer, Verifier}, - solana_feature_set::{ed25519_precompile_verify_strict, FeatureSet}, + solana_feature_set_interface::FeatureSet, solana_instruction::Instruction, solana_precompile_error::PrecompileError, }; @@ -18,6 +18,11 @@ pub const SIGNATURE_OFFSETS_SERIALIZED_SIZE: usize = 14; pub const SIGNATURE_OFFSETS_START: usize = 2; pub const DATA_START: usize = SIGNATURE_OFFSETS_SERIALIZED_SIZE + SIGNATURE_OFFSETS_START; +/// Copy from agave-feature-set +mod ed25519_precompile_verify_strict { + solana_pubkey::declare_id!("ed9tNscbWLYBooxWA7FE2B5KHWs8A6sxfY8EzezEcoo"); +} + #[derive(Default, Debug, Copy, Clone, Zeroable, Pod, Eq, PartialEq)] #[repr(C)] pub struct Ed25519SignatureOffsets { @@ -220,13 +225,19 @@ pub mod test { ed25519_dalek::Signer as EdSigner, hex, rand0_7::{thread_rng, Rng}, - solana_feature_set::FeatureSet, + solana_feature_set_interface::FeatureSet, solana_hash::Hash, solana_keypair::Keypair, solana_sdk::transaction::Transaction, solana_signer::Signer, }; + fn feature_set_with_strict() -> FeatureSet { + let mut feature_set = FeatureSet::default(); + feature_set.activate(&ed25519_precompile_verify_strict::id(), 0); + feature_set + } + pub fn new_ed25519_instruction_raw( pubkey: &[u8], signature: &[u8], @@ -297,7 +308,7 @@ pub mod test { verify( &instruction_data, &[&[0u8; 100]], - &FeatureSet::all_enabled(), + &feature_set_with_strict(), ) } @@ -315,7 +326,7 @@ pub mod test { verify( &instruction_data, &[&[0u8; 100]], - &FeatureSet::all_enabled(), + &feature_set_with_strict(), ), Err(PrecompileError::InvalidInstructionDataSize) ); @@ -441,7 +452,7 @@ pub mod test { let message_arr = b"hello"; let mut instruction = new_ed25519_instruction(&privkey, message_arr); let mint_keypair = Keypair::new(); - let feature_set = FeatureSet::all_enabled(); + let feature_set = feature_set_with_strict(); let tx = Transaction::new_signed_with_payer( &[instruction.clone()], @@ -512,7 +523,7 @@ pub mod test { } let mint_keypair = Keypair::new(); - let feature_set = FeatureSet::all_enabled(); + let feature_set = feature_set_with_strict(); let tx = Transaction::new_signed_with_payer( &[instruction.clone()], @@ -560,7 +571,7 @@ pub mod test { let feature_set = FeatureSet::default(); assert!(tx.verify_precompiles(&feature_set).is_ok()); - let feature_set = FeatureSet::all_enabled(); + let feature_set = feature_set_with_strict(); assert!(tx.verify_precompiles(&feature_set).is_ok()); // malleable sig: verify_strict does NOT pass @@ -583,7 +594,7 @@ pub mod test { let feature_set = FeatureSet::default(); assert!(tx.verify_precompiles(&feature_set).is_ok()); - let feature_set = FeatureSet::all_enabled(); + let feature_set = feature_set_with_strict(); assert!(tx.verify_precompiles(&feature_set).is_err()); // verify_strict does NOT pass } } diff --git a/feature-set-interface/src/lib.rs b/feature-set-interface/src/lib.rs index ac742b704..5f13bae87 100644 --- a/feature-set-interface/src/lib.rs +++ b/feature-set-interface/src/lib.rs @@ -7,7 +7,7 @@ use { /// `FeatureSet` holds the set of currently active/inactive runtime features #[cfg_attr(feature = "frozen-abi", derive(solana_frozen_abi_macro::AbiExample))] -#[derive(Debug, Clone, Eq, PartialEq)] +#[derive(Debug, Default, Clone, Eq, PartialEq)] pub struct FeatureSet { pub active: AHashMap, pub inactive: AHashSet, diff --git a/feature-set/Cargo.toml b/feature-set/Cargo.toml index c160b2cb0..1468e5aa2 100644 --- a/feature-set/Cargo.toml +++ b/feature-set/Cargo.toml @@ -13,6 +13,7 @@ edition = { workspace = true } ahash = { workspace = true } lazy_static = { workspace = true } solana-epoch-schedule = { workspace = true } +solana-feature-set-interface = { workspace = true } solana-frozen-abi = { workspace = true, optional = true, features = [ "frozen-abi", ] } diff --git a/feature-set/src/lib.rs b/feature-set/src/lib.rs index 75a8b17f8..43e6a9691 100644 --- a/feature-set/src/lib.rs +++ b/feature-set/src/lib.rs @@ -1225,10 +1225,13 @@ lazy_static! { /// `FeatureSet` holds the set of currently active/inactive runtime features #[cfg_attr(feature = "frozen-abi", derive(solana_frozen_abi_macro::AbiExample))] #[derive(Debug, Clone, Eq, PartialEq)] +#[deprecated] +#[allow(deprecated)] pub struct FeatureSet { pub active: AHashMap, pub inactive: AHashSet, } +#[allow(deprecated)] impl Default for FeatureSet { fn default() -> Self { // All features disabled @@ -1238,6 +1241,7 @@ impl Default for FeatureSet { } } } +#[allow(deprecated)] impl FeatureSet { pub fn is_active(&self, feature_id: &Pubkey) -> bool { self.active.contains_key(feature_id) @@ -1291,8 +1295,18 @@ impl FeatureSet { .map(|slot| epoch_schedule.get_epoch(slot)) } } +#[allow(deprecated)] +impl From for solana_feature_set_interface::FeatureSet { + fn from(feature_set: FeatureSet) -> Self { + Self { + active: feature_set.active, + inactive: feature_set.inactive, + } + } +} #[cfg(test)] +#[allow(deprecated)] mod test { use super::*; diff --git a/precompiles/Cargo.toml b/precompiles/Cargo.toml index acd533ae6..273889ad8 100644 --- a/precompiles/Cargo.toml +++ b/precompiles/Cargo.toml @@ -12,7 +12,7 @@ edition = { workspace = true } [dependencies] lazy_static = { workspace = true } solana-ed25519-program = { workspace = true } -solana-feature-set = { workspace = true } +solana-feature-set-interface = { workspace = true } solana-message = { workspace = true } solana-precompile-error = { workspace = true } solana-pubkey = { workspace = true } diff --git a/precompiles/src/lib.rs b/precompiles/src/lib.rs index 8ca16951e..f4b3d20ec 100644 --- a/precompiles/src/lib.rs +++ b/precompiles/src/lib.rs @@ -1,6 +1,6 @@ #![cfg_attr(docsrs, feature(doc_auto_cfg))] use { - lazy_static::lazy_static, solana_feature_set::FeatureSet, + lazy_static::lazy_static, solana_feature_set_interface::FeatureSet, solana_message::compiled_instruction::CompiledInstruction, solana_precompile_error::PrecompileError, solana_pubkey::Pubkey, }; @@ -61,7 +61,7 @@ lazy_static! { ), Precompile::new( solana_sdk_ids::secp256r1_program::id(), - Some(solana_feature_set::enable_secp256r1_precompile::id()), + Some(solana_secp256r1_program::enable_secp256r1_precompile::id()), solana_secp256r1_program::verify, ) ]; diff --git a/reserved-account-keys/Cargo.toml b/reserved-account-keys/Cargo.toml index c99cba983..a04176c96 100644 --- a/reserved-account-keys/Cargo.toml +++ b/reserved-account-keys/Cargo.toml @@ -11,7 +11,7 @@ edition = { workspace = true } [dependencies] lazy_static = { workspace = true } -solana-feature-set = { workspace = true } +solana-feature-set-interface = { workspace = true } solana-frozen-abi = { workspace = true, optional = true, features = [ "frozen-abi", ] } diff --git a/reserved-account-keys/src/lib.rs b/reserved-account-keys/src/lib.rs index 06cad17e2..f0dabaf48 100644 --- a/reserved-account-keys/src/lib.rs +++ b/reserved-account-keys/src/lib.rs @@ -5,7 +5,7 @@ #![cfg_attr(docsrs, feature(doc_auto_cfg))] use { lazy_static::lazy_static, - solana_feature_set::{self as feature_set, FeatureSet}, + solana_feature_set_interface::FeatureSet, solana_pubkey::Pubkey, solana_sdk_ids::{ address_lookup_table, bpf_loader, bpf_loader_deprecated, bpf_loader_upgradeable, @@ -135,39 +135,47 @@ impl ReservedAccount { } } +mod add_new_reserved_account_keys { + solana_pubkey::declare_id!("8U4skmMVnF6k2kMvrWbQuRUT3qQSiTYpSjqmhmgfthZu"); +} + +pub mod enable_secp256r1_precompile { + solana_pubkey::declare_id!("srremy31J5Y25FrAApwVb9kZcfXbusYMMsvTK9aWv5q"); +} + // New reserved accounts should be added in alphabetical order and must specify // a feature id for activation. Reserved accounts cannot be removed from this // list without breaking consensus. lazy_static! { static ref RESERVED_ACCOUNTS: Vec = [ // builtin programs - ReservedAccount::new_pending(address_lookup_table::id(), feature_set::add_new_reserved_account_keys::id()), + ReservedAccount::new_pending(address_lookup_table::id(), add_new_reserved_account_keys::id()), ReservedAccount::new_active(bpf_loader::id()), ReservedAccount::new_active(bpf_loader_deprecated::id()), ReservedAccount::new_active(bpf_loader_upgradeable::id()), - ReservedAccount::new_pending(compute_budget::id(), feature_set::add_new_reserved_account_keys::id()), + ReservedAccount::new_pending(compute_budget::id(), add_new_reserved_account_keys::id()), ReservedAccount::new_active(config::id()), - ReservedAccount::new_pending(ed25519_program::id(), feature_set::add_new_reserved_account_keys::id()), + ReservedAccount::new_pending(ed25519_program::id(), add_new_reserved_account_keys::id()), ReservedAccount::new_active(feature::id()), - ReservedAccount::new_pending(loader_v4::id(), feature_set::add_new_reserved_account_keys::id()), - ReservedAccount::new_pending(secp256k1_program::id(), feature_set::add_new_reserved_account_keys::id()), - ReservedAccount::new_pending(secp256r1_program::id(), feature_set::enable_secp256r1_precompile::id()), + ReservedAccount::new_pending(loader_v4::id(), add_new_reserved_account_keys::id()), + ReservedAccount::new_pending(secp256k1_program::id(), add_new_reserved_account_keys::id()), + ReservedAccount::new_pending(secp256r1_program::id(), enable_secp256r1_precompile::id()), #[allow(deprecated)] ReservedAccount::new_active(stake::config::id()), ReservedAccount::new_active(stake::id()), ReservedAccount::new_active(system_program::id()), ReservedAccount::new_active(vote::id()), - ReservedAccount::new_pending(zk_elgamal_proof_program::id(), feature_set::add_new_reserved_account_keys::id()), - ReservedAccount::new_pending(zk_token_proof_program::id(), feature_set::add_new_reserved_account_keys::id()), + ReservedAccount::new_pending(zk_elgamal_proof_program::id(), add_new_reserved_account_keys::id()), + ReservedAccount::new_pending(zk_token_proof_program::id(), add_new_reserved_account_keys::id()), // sysvars ReservedAccount::new_active(sysvar::clock::id()), - ReservedAccount::new_pending(sysvar::epoch_rewards::id(), feature_set::add_new_reserved_account_keys::id()), + ReservedAccount::new_pending(sysvar::epoch_rewards::id(), add_new_reserved_account_keys::id()), ReservedAccount::new_active(sysvar::epoch_schedule::id()), #[allow(deprecated)] ReservedAccount::new_active(sysvar::fees::id()), ReservedAccount::new_active(sysvar::instructions::id()), - ReservedAccount::new_pending(sysvar::last_restart_slot::id(), feature_set::add_new_reserved_account_keys::id()), + ReservedAccount::new_pending(sysvar::last_restart_slot::id(), add_new_reserved_account_keys::id()), #[allow(deprecated)] ReservedAccount::new_active(sysvar::recent_blockhashes::id()), ReservedAccount::new_active(sysvar::rent::id()), @@ -178,7 +186,7 @@ lazy_static! { // other ReservedAccount::new_active(native_loader::id()), - ReservedAccount::new_pending(sysvar::id(), feature_set::add_new_reserved_account_keys::id()), + ReservedAccount::new_pending(sysvar::id(), add_new_reserved_account_keys::id()), ].to_vec(); } diff --git a/sdk/Cargo.toml b/sdk/Cargo.toml index 789882edf..a33785dea 100644 --- a/sdk/Cargo.toml +++ b/sdk/Cargo.toml @@ -60,6 +60,7 @@ dev-context-only-utils = [ "solana-transaction/dev-context-only-utils", ] frozen-abi = [ + "solana-feature-set-interface/frozen-abi", "solana-feature-set/frozen-abi", "solana-fee-structure/frozen-abi", "solana-account/frozen-abi", @@ -103,6 +104,7 @@ solana-ed25519-program = { workspace = true, optional = true } solana-epoch-info = { workspace = true, features = ["serde"] } solana-epoch-rewards-hasher = { workspace = true } solana-feature-set = { workspace = true } +solana-feature-set-interface = { workspace = true } solana-fee-structure = { workspace = true, features = ["serde"] } solana-genesis-config = { workspace = true, features = [ "serde" diff --git a/sdk/benches/ed25519_instructions.rs b/sdk/benches/ed25519_instructions.rs index 0bd727335..790dd73e5 100644 --- a/sdk/benches/ed25519_instructions.rs +++ b/sdk/benches/ed25519_instructions.rs @@ -3,7 +3,6 @@ extern crate test; use { rand0_7::{thread_rng, Rng}, - solana_feature_set::FeatureSet, solana_sdk::{ ed25519_instruction::new_ed25519_instruction, hash::Hash, @@ -38,7 +37,8 @@ fn create_test_transactions(message_length: u16) -> Vec { #[bench] fn bench_ed25519_len_032(b: &mut Bencher) { - let feature_set = FeatureSet::all_enabled(); + #[allow(deprecated)] + let feature_set = solana_feature_set::FeatureSet::all_enabled().into(); let txs = create_test_transactions(32); let mut tx_iter = txs.iter().cycle(); b.iter(|| { @@ -52,7 +52,8 @@ fn bench_ed25519_len_032(b: &mut Bencher) { #[bench] fn bench_ed25519_len_128(b: &mut Bencher) { - let feature_set = FeatureSet::all_enabled(); + #[allow(deprecated)] + let feature_set = solana_feature_set::FeatureSet::all_enabled().into(); let txs = create_test_transactions(128); let mut tx_iter = txs.iter().cycle(); b.iter(|| { @@ -66,7 +67,8 @@ fn bench_ed25519_len_128(b: &mut Bencher) { #[bench] fn bench_ed25519_len_32k(b: &mut Bencher) { - let feature_set = FeatureSet::all_enabled(); + #[allow(deprecated)] + let feature_set = solana_feature_set::FeatureSet::all_enabled().into(); let txs = create_test_transactions(32 * 1024); let mut tx_iter = txs.iter().cycle(); b.iter(|| { @@ -81,7 +83,8 @@ fn bench_ed25519_len_32k(b: &mut Bencher) { #[bench] fn bench_ed25519_len_max(b: &mut Bencher) { let required_extra_space = 113_u16; // len for pubkey, sig, and offsets - let feature_set = FeatureSet::all_enabled(); + #[allow(deprecated)] + let feature_set = solana_feature_set::FeatureSet::all_enabled().into(); let txs = create_test_transactions(u16::MAX - required_extra_space); let mut tx_iter = txs.iter().cycle(); b.iter(|| { diff --git a/sdk/benches/secp256k1_instructions.rs b/sdk/benches/secp256k1_instructions.rs index 8940bda5a..a8109bc5d 100644 --- a/sdk/benches/secp256k1_instructions.rs +++ b/sdk/benches/secp256k1_instructions.rs @@ -3,7 +3,6 @@ extern crate test; use { rand0_7::{thread_rng, Rng}, - solana_feature_set::FeatureSet, solana_sdk::{ hash::Hash, secp256k1_instruction::new_secp256k1_instruction, @@ -38,7 +37,8 @@ fn create_test_transactions(message_length: u16) -> Vec { #[bench] fn bench_secp256k1_len_032(b: &mut Bencher) { - let feature_set = FeatureSet::all_enabled(); + #[allow(deprecated)] + let feature_set = solana_feature_set::FeatureSet::all_enabled().into(); let txs = create_test_transactions(32); let mut tx_iter = txs.iter().cycle(); b.iter(|| { @@ -52,7 +52,8 @@ fn bench_secp256k1_len_032(b: &mut Bencher) { #[bench] fn bench_secp256k1_len_256(b: &mut Bencher) { - let feature_set = FeatureSet::all_enabled(); + #[allow(deprecated)] + let feature_set = solana_feature_set::FeatureSet::all_enabled().into(); let txs = create_test_transactions(256); let mut tx_iter = txs.iter().cycle(); b.iter(|| { @@ -66,7 +67,8 @@ fn bench_secp256k1_len_256(b: &mut Bencher) { #[bench] fn bench_secp256k1_len_32k(b: &mut Bencher) { - let feature_set = FeatureSet::all_enabled(); + #[allow(deprecated)] + let feature_set = solana_feature_set::FeatureSet::all_enabled().into(); let txs = create_test_transactions(32 * 1024); let mut tx_iter = txs.iter().cycle(); b.iter(|| { @@ -81,7 +83,8 @@ fn bench_secp256k1_len_32k(b: &mut Bencher) { #[bench] fn bench_secp256k1_len_max(b: &mut Bencher) { let required_extra_space = 113_u16; // len for pubkey, sig, and offsets - let feature_set = FeatureSet::all_enabled(); + #[allow(deprecated)] + let feature_set = solana_feature_set::FeatureSet::all_enabled().into(); let txs = create_test_transactions(u16::MAX - required_extra_space); let mut tx_iter = txs.iter().cycle(); b.iter(|| { diff --git a/sdk/benches/secp256r1_instructions.rs b/sdk/benches/secp256r1_instructions.rs index 9af312688..f12d253c8 100644 --- a/sdk/benches/secp256r1_instructions.rs +++ b/sdk/benches/secp256r1_instructions.rs @@ -7,7 +7,6 @@ use { nid::Nid, }, rand0_7::{thread_rng, Rng}, - solana_feature_set::FeatureSet, solana_sdk::{ hash::Hash, signature::{Keypair, Signer}, @@ -43,7 +42,8 @@ fn create_test_transactions(message_length: u16) -> Vec { #[bench] fn bench_secp256r1_len_032(b: &mut Bencher) { - let feature_set = FeatureSet::all_enabled(); + #[allow(deprecated)] + let feature_set = solana_feature_set::FeatureSet::all_enabled().into(); let txs = create_test_transactions(32); let mut tx_iter = txs.iter().cycle(); b.iter(|| { @@ -57,7 +57,8 @@ fn bench_secp256r1_len_032(b: &mut Bencher) { #[bench] fn bench_secp256r1_len_256(b: &mut Bencher) { - let feature_set = FeatureSet::all_enabled(); + #[allow(deprecated)] + let feature_set = solana_feature_set::FeatureSet::all_enabled().into(); let txs = create_test_transactions(256); let mut tx_iter = txs.iter().cycle(); b.iter(|| { @@ -71,7 +72,8 @@ fn bench_secp256r1_len_256(b: &mut Bencher) { #[bench] fn bench_secp256r1_len_32k(b: &mut Bencher) { - let feature_set = FeatureSet::all_enabled(); + #[allow(deprecated)] + let feature_set = solana_feature_set::FeatureSet::all_enabled().into(); let txs = create_test_transactions(32 * 1024); let mut tx_iter = txs.iter().cycle(); b.iter(|| { @@ -86,7 +88,8 @@ fn bench_secp256r1_len_32k(b: &mut Bencher) { #[bench] fn bench_secp256r1_len_max(b: &mut Bencher) { let required_extra_space = 113_u16; // len for pubkey, sig, and offsets - let feature_set = FeatureSet::all_enabled(); + #[allow(deprecated)] + let feature_set = solana_feature_set::FeatureSet::all_enabled().into(); let txs = create_test_transactions(u16::MAX - required_extra_space); let mut tx_iter = txs.iter().cycle(); b.iter(|| { diff --git a/secp256k1-program/Cargo.toml b/secp256k1-program/Cargo.toml index e0440293d..37aceadfa 100644 --- a/secp256k1-program/Cargo.toml +++ b/secp256k1-program/Cargo.toml @@ -16,7 +16,7 @@ libsecp256k1 = { workspace = true, features = ["hmac"] } serde = { workspace = true, optional = true } serde_derive = { workspace = true, optional = true } sha3 = { workspace = true } -solana-feature-set = { workspace = true, optional = true } +solana-feature-set-interface = { workspace = true, optional = true } solana-instruction = { workspace = true, features = ["std"], optional = true } solana-precompile-error = { workspace = true, optional = true } solana-sdk-ids = { workspace = true, optional = true } @@ -40,7 +40,7 @@ solana-signer = { workspace = true } [features] bincode = [ "dep:bincode", - "dep:solana-feature-set", + "dep:solana-feature-set-interface", "dep:solana-instruction", "dep:solana-precompile-error", "dep:solana-sdk-ids", diff --git a/secp256k1-program/src/lib.rs b/secp256k1-program/src/lib.rs index 7aad00809..1bd083924 100644 --- a/secp256k1-program/src/lib.rs +++ b/secp256k1-program/src/lib.rs @@ -913,7 +913,7 @@ pub fn construct_eth_pubkey( pub fn verify( data: &[u8], instruction_datas: &[&[u8]], - _feature_set: &solana_feature_set::FeatureSet, + _feature_set: &solana_feature_set_interface::FeatureSet, ) -> Result<(), PrecompileError> { if data.is_empty() { return Err(PrecompileError::InvalidInstructionDataSize); @@ -1021,7 +1021,7 @@ pub mod test { use { super::*, rand0_7::{thread_rng, Rng}, - solana_feature_set::FeatureSet, + solana_feature_set_interface::FeatureSet, solana_hash::Hash, solana_keccak_hasher as keccak, solana_keypair::Keypair, @@ -1037,7 +1037,7 @@ pub mod test { instruction_data[0] = num_signatures; let writer = std::io::Cursor::new(&mut instruction_data[1..]); bincode::serialize_into(writer, &offsets).unwrap(); - let feature_set = FeatureSet::all_enabled(); + let feature_set = FeatureSet::default(); verify(&instruction_data, &[&[0u8; 100]], &feature_set) } @@ -1051,7 +1051,7 @@ pub mod test { let writer = std::io::Cursor::new(&mut instruction_data[1..]); bincode::serialize_into(writer, &offsets).unwrap(); instruction_data.truncate(instruction_data.len() - 1); - let feature_set = FeatureSet::all_enabled(); + let feature_set = FeatureSet::default(); assert_eq!( verify(&instruction_data, &[&[0u8; 100]], &feature_set), @@ -1180,7 +1180,7 @@ pub mod test { instruction_data[0] = 0; let writer = std::io::Cursor::new(&mut instruction_data[1..]); bincode::serialize_into(writer, &offsets).unwrap(); - let feature_set = FeatureSet::all_enabled(); + let feature_set = FeatureSet::default(); assert_eq!( verify(&instruction_data, &[&[0u8; 100]], &feature_set), @@ -1201,7 +1201,7 @@ pub mod test { let message_arr = b"hello"; let mut secp_instruction = new_secp256k1_instruction(&secp_privkey, message_arr); let mint_keypair = Keypair::new(); - let feature_set = solana_feature_set::FeatureSet::all_enabled(); + let feature_set = FeatureSet::default(); let tx = Transaction::new_signed_with_payer( &[secp_instruction.clone()], @@ -1288,7 +1288,7 @@ pub mod test { verify( &instruction_data, &[&instruction_data], - &FeatureSet::all_enabled(), + &FeatureSet::default(), ) .unwrap(); } diff --git a/secp256r1-program/Cargo.toml b/secp256r1-program/Cargo.toml index 5cdfcdfe5..e6c7caaee 100644 --- a/secp256r1-program/Cargo.toml +++ b/secp256r1-program/Cargo.toml @@ -11,8 +11,9 @@ edition = { workspace = true } [dependencies] bytemuck = { workspace = true, features = ["derive"] } -solana-feature-set = { workspace = true } +solana-feature-set-interface = { workspace = true } solana-precompile-error = { workspace = true } +solana-pubkey = { workspace = true } solana-sdk-ids = { workspace = true } [target.'cfg(all(not(target_arch = "wasm32"), not(target_os = "solana")))'.dependencies] @@ -21,6 +22,7 @@ openssl = { workspace = true } [dev-dependencies] solana-logger = { workspace = true } +solana-reserved-account-keys = { workspace = true } solana-sdk = { path = "../sdk" } [features] diff --git a/secp256r1-program/src/lib.rs b/secp256r1-program/src/lib.rs index 65d4ab1b9..0a860cb61 100644 --- a/secp256r1-program/src/lib.rs +++ b/secp256r1-program/src/lib.rs @@ -37,6 +37,10 @@ pub struct Secp256r1SignatureOffsets { pub message_instruction_index: u16, } +pub mod enable_secp256r1_precompile { + solana_pubkey::declare_id!("srremy31J5Y25FrAApwVb9kZcfXbusYMMsvTK9aWv5q"); +} + #[cfg(all(not(target_arch = "wasm32"), not(target_os = "solana")))] mod target_arch { use { @@ -50,7 +54,7 @@ mod target_arch { pkey::{PKey, Private}, sign::{Signer, Verifier}, }, - solana_feature_set::FeatureSet, + solana_feature_set_interface::FeatureSet, solana_instruction::Instruction, solana_precompile_error::PrecompileError, }; @@ -329,7 +333,7 @@ mod target_arch { mod test { use { super::*, - solana_feature_set::FeatureSet, + solana_feature_set_interface::FeatureSet, solana_sdk::{ hash::Hash, signature::{Keypair, Signer}, @@ -350,11 +354,7 @@ mod target_arch { instruction_data[0..SIGNATURE_OFFSETS_START].copy_from_slice(bytes_of(&num_signatures)); instruction_data[SIGNATURE_OFFSETS_START..DATA_START] .copy_from_slice(bytes_of(offsets)); - verify( - &instruction_data, - &[&[0u8; 100]], - &FeatureSet::all_enabled(), - ) + verify(&instruction_data, &[&[0u8; 100]], &FeatureSet::default()) } #[test] @@ -369,11 +369,7 @@ mod target_arch { instruction_data.truncate(instruction_data.len() - 1); assert_eq!( - verify( - &instruction_data, - &[&[0u8; 100]], - &FeatureSet::all_enabled() - ), + verify(&instruction_data, &[&[0u8; 100]], &FeatureSet::default()), Err(PrecompileError::InvalidInstructionDataSize) ); @@ -412,7 +408,7 @@ mod target_arch { // Test data.len() < SIGNATURE_OFFSETS_START let small_data = vec![0u8; SIGNATURE_OFFSETS_START - 1]; assert_eq!( - verify(&small_data, &[&[]], &FeatureSet::all_enabled()), + verify(&small_data, &[&[]], &FeatureSet::default()), Err(PrecompileError::InvalidInstructionDataSize) ); @@ -420,7 +416,7 @@ mod target_arch { let mut zero_sigs_data = vec![0u8; DATA_START]; zero_sigs_data[0] = 0; // Set num_signatures to 0 assert_eq!( - verify(&zero_sigs_data, &[&[]], &FeatureSet::all_enabled()), + verify(&zero_sigs_data, &[&[]], &FeatureSet::default()), Err(PrecompileError::InvalidInstructionDataSize) ); @@ -428,7 +424,7 @@ mod target_arch { let mut too_many_sigs = vec![0u8; DATA_START]; too_many_sigs[0] = 9; // Set num_signatures to 9 assert_eq!( - verify(&too_many_sigs, &[&[]], &FeatureSet::all_enabled()), + verify(&too_many_sigs, &[&[]], &FeatureSet::default()), Err(PrecompileError::InvalidInstructionDataSize) ); } @@ -525,7 +521,8 @@ mod target_arch { let signing_key = EcKey::generate(&group).unwrap(); let mut instruction = new_secp256r1_instruction(message_arr, signing_key).unwrap(); let mint_keypair = Keypair::new(); - let feature_set = FeatureSet::all_enabled(); + let mut feature_set = FeatureSet::default(); + feature_set.activate(&crate::enable_secp256r1_precompile::id(), 0); let tx = Transaction::new_signed_with_payer( &[instruction.clone()], @@ -560,7 +557,7 @@ mod target_arch { let mut instruction = new_secp256r1_instruction(message_arr, signing_key).unwrap(); // To double check that the untampered low-S value signature passes - let feature_set = FeatureSet::all_enabled(); + let feature_set = FeatureSet::default(); let tx_pass = verify( instruction.data.as_slice(), &[instruction.data.as_slice()], @@ -628,7 +625,7 @@ mod target_arch { Hash::default(), ); - let feature_set = FeatureSet::all_enabled(); + let feature_set = FeatureSet::default(); assert!(tx.verify_precompiles(&feature_set).is_ok()); break; } @@ -733,12 +730,20 @@ mod target_arch { .unwrap(); assert_eq!(double_half_order, expected_order_minus_one); } + + #[test] + fn check_feature() { + assert_eq!( + crate::enable_secp256r1_precompile::id(), + solana_reserved_account_keys::enable_secp256r1_precompile::id() + ); + } } } #[cfg(any(target_arch = "wasm32", target_os = "solana"))] mod target_arch { - use {solana_feature_set::FeatureSet, solana_precompile_error::PrecompileError}; + use {solana_feature_set_interface::FeatureSet, solana_precompile_error::PrecompileError}; pub fn verify( _data: &[u8], diff --git a/transaction/Cargo.toml b/transaction/Cargo.toml index c00ed92e7..05b7e0a18 100644 --- a/transaction/Cargo.toml +++ b/transaction/Cargo.toml @@ -14,7 +14,7 @@ bincode = { workspace = true, optional = true } serde = { workspace = true, optional = true } serde_derive = { workspace = true, optional = true } solana-bincode = { workspace = true, optional = true } -solana-feature-set = { workspace = true, optional = true } +solana-feature-set-interface = { workspace = true, optional = true } solana-frozen-abi = { workspace = true, optional = true } solana-frozen-abi-macro = { workspace = true, optional = true } solana-hash = { workspace = true } @@ -73,7 +73,7 @@ frozen-abi = [ "dep:solana-frozen-abi-macro", "dep:solana-logger", ] -precompiles = ["dep:solana-feature-set", "dep:solana-precompiles"] +precompiles = ["dep:solana-feature-set-interface", "dep:solana-precompiles"] serde = [ "dep:serde", "dep:serde_derive", diff --git a/transaction/src/lib.rs b/transaction/src/lib.rs index 43a913843..3957aa2c5 100644 --- a/transaction/src/lib.rs +++ b/transaction/src/lib.rs @@ -1059,7 +1059,10 @@ impl Transaction { #[cfg(feature = "precompiles")] /// Verify the precompiled programs in this transaction. - pub fn verify_precompiles(&self, feature_set: &solana_feature_set::FeatureSet) -> Result<()> { + pub fn verify_precompiles( + &self, + feature_set: &solana_feature_set_interface::FeatureSet, + ) -> Result<()> { for instruction in &self.message().instructions { // The Transaction may not be sanitized at this point if instruction.program_id_index as usize >= self.message().account_keys.len() { diff --git a/transaction/src/sanitized.rs b/transaction/src/sanitized.rs index 2d0f3639c..14cc25deb 100644 --- a/transaction/src/sanitized.rs +++ b/transaction/src/sanitized.rs @@ -288,7 +288,10 @@ impl SanitizedTransaction { #[cfg(feature = "precompiles")] /// Verify the precompiled programs in this transaction - pub fn verify_precompiles(&self, feature_set: &solana_feature_set::FeatureSet) -> Result<()> { + pub fn verify_precompiles( + &self, + feature_set: &solana_feature_set_interface::FeatureSet, + ) -> Result<()> { for (index, (program_id, instruction)) in self.message.program_instructions_iter().enumerate() {