Pārlūkot izejas kodu

Add agave-reserved-account-keys crate (#5513)

Justin Starry 8 mēneši atpakaļ
vecāks
revīzija
df2d3d83c8
45 mainītis faili ar 398 papildinājumiem un 46 dzēšanām
  1. 26 7
      Cargo.lock
  2. 2 1
      Cargo.toml
  3. 1 1
      cli-output/Cargo.toml
  4. 1 1
      cli-output/src/display.rs
  5. 1 0
      core/Cargo.toml
  6. 1 1
      core/src/banking_stage/consumer.rs
  7. 1 1
      core/src/banking_stage/unprocessed_packet_batches.rs
  8. 1 1
      cost-model/Cargo.toml
  9. 1 1
      cost-model/src/transaction_cost.rs
  10. 1 1
      entry/Cargo.toml
  11. 1 1
      entry/benches/entry_sigverify.rs
  12. 1 1
      entry/src/entry.rs
  13. 1 0
      ledger-tool/Cargo.toml
  14. 1 1
      ledger-tool/src/main.rs
  15. 1 0
      ledger/Cargo.toml
  16. 1 1
      ledger/src/transaction_address_lookup_table_scanner.rs
  17. 16 3
      programs/sbf/Cargo.lock
  18. 2 0
      programs/sbf/Cargo.toml
  19. 1 1
      programs/sbf/tests/programs.rs
  20. 37 0
      reserved-account-keys/Cargo.toml
  21. 260 0
      reserved-account-keys/src/lib.rs
  22. 1 0
      rpc/Cargo.toml
  23. 1 1
      rpc/src/rpc.rs
  24. 1 1
      rpc/src/transaction_status_service.rs
  25. 1 1
      runtime-transaction/Cargo.toml
  26. 1 1
      runtime-transaction/src/runtime_transaction/sdk_transactions.rs
  27. 1 1
      runtime-transaction/src/runtime_transaction/transaction_view.rs
  28. 1 0
      runtime/Cargo.toml
  29. 1 1
      runtime/src/bank.rs
  30. 1 1
      runtime/src/snapshot_minimizer.rs
  31. 1 1
      storage-bigtable/Cargo.toml
  32. 1 1
      storage-bigtable/src/lib.rs
  33. 1 1
      svm/Cargo.toml
  34. 16 3
      svm/examples/Cargo.lock
  35. 1 0
      svm/examples/Cargo.toml
  36. 1 0
      svm/examples/json-rpc/server/Cargo.toml
  37. 1 1
      svm/examples/json-rpc/server/src/rpc_process.rs
  38. 1 1
      svm/src/account_loader.rs
  39. 1 1
      svm/src/message_processor.rs
  40. 1 1
      svm/src/transaction_account_state_info.rs
  41. 1 1
      svm/src/transaction_processor.rs
  42. 1 1
      svm/tests/transaction_builder.rs
  43. 1 1
      transaction-status/Cargo.toml
  44. 1 1
      transaction-status/src/lib.rs
  45. 2 2
      transaction-status/src/parse_accounts.rs

+ 26 - 7
Cargo.lock

@@ -204,6 +204,7 @@ dependencies = [
 name = "agave-ledger-tool"
 version = "2.3.0"
 dependencies = [
+ "agave-reserved-account-keys",
  "assert_cmd",
  "bs58",
  "chrono",
@@ -260,6 +261,20 @@ dependencies = [
  "tokio",
 ]
 
+[[package]]
+name = "agave-reserved-account-keys"
+version = "2.3.0"
+dependencies = [
+ "lazy_static",
+ "solana-feature-set",
+ "solana-frozen-abi",
+ "solana-frozen-abi-macro",
+ "solana-message",
+ "solana-pubkey",
+ "solana-sdk-ids",
+ "solana-sysvar",
+]
+
 [[package]]
 name = "agave-store-histogram"
 version = "2.3.0"
@@ -7178,6 +7193,7 @@ name = "solana-cli-output"
 version = "2.3.0"
 dependencies = [
  "Inflector",
+ "agave-reserved-account-keys",
  "base64 0.22.1",
  "chrono",
  "clap 2.33.3",
@@ -7203,7 +7219,6 @@ dependencies = [
  "solana-packet",
  "solana-program",
  "solana-pubkey",
- "solana-reserved-account-keys",
  "solana-rpc-client-api",
  "solana-sdk-ids",
  "solana-signature",
@@ -7479,6 +7494,7 @@ name = "solana-core"
 version = "2.3.0"
 dependencies = [
  "agave-banking-stage-ingress-types",
+ "agave-reserved-account-keys",
  "agave-transaction-view",
  "ahash 0.8.11",
  "anyhow",
@@ -7589,6 +7605,7 @@ dependencies = [
 name = "solana-cost-model"
 version = "2.3.0"
 dependencies = [
+ "agave-reserved-account-keys",
  "ahash 0.8.11",
  "itertools 0.12.1",
  "lazy_static",
@@ -7615,7 +7632,6 @@ dependencies = [
  "solana-metrics",
  "solana-packet",
  "solana-pubkey",
- "solana-reserved-account-keys",
  "solana-runtime-transaction",
  "solana-sdk-ids",
  "solana-signature",
@@ -7758,6 +7774,7 @@ dependencies = [
 name = "solana-entry"
 version = "2.3.0"
 dependencies = [
+ "agave-reserved-account-keys",
  "assert_matches",
  "bincode",
  "crossbeam-channel",
@@ -7778,7 +7795,6 @@ dependencies = [
  "solana-perf",
  "solana-pubkey",
  "solana-rayon-threadlimit",
- "solana-reserved-account-keys",
  "solana-runtime-transaction",
  "solana-sha256-hasher",
  "solana-signature",
@@ -8397,6 +8413,7 @@ dependencies = [
 name = "solana-ledger"
 version = "2.3.0"
 dependencies = [
+ "agave-reserved-account-keys",
  "anyhow",
  "assert_matches",
  "bincode",
@@ -9385,6 +9402,7 @@ dependencies = [
 name = "solana-rpc"
 version = "2.3.0"
 dependencies = [
+ "agave-reserved-account-keys",
  "base64 0.22.1",
  "bincode",
  "bs58",
@@ -9611,6 +9629,7 @@ dependencies = [
 name = "solana-runtime"
 version = "2.3.0"
 dependencies = [
+ "agave-reserved-account-keys",
  "agave-transaction-view",
  "ahash 0.8.11",
  "aquamarine",
@@ -9710,6 +9729,7 @@ dependencies = [
 name = "solana-runtime-transaction"
 version = "2.3.0"
 dependencies = [
+ "agave-reserved-account-keys",
  "agave-transaction-view",
  "bincode",
  "criterion",
@@ -9725,7 +9745,6 @@ dependencies = [
  "solana-message",
  "solana-program",
  "solana-pubkey",
- "solana-reserved-account-keys",
  "solana-sdk-ids",
  "solana-signature",
  "solana-signer",
@@ -10163,6 +10182,7 @@ dependencies = [
 name = "solana-storage-bigtable"
 version = "2.3.0"
 dependencies = [
+ "agave-reserved-account-keys",
  "backoff",
  "bincode",
  "bytes",
@@ -10187,7 +10207,6 @@ dependencies = [
  "solana-message",
  "solana-metrics",
  "solana-pubkey",
- "solana-reserved-account-keys",
  "solana-serde",
  "solana-signature",
  "solana-storage-proto",
@@ -10280,6 +10299,7 @@ dependencies = [
 name = "solana-svm"
 version = "2.3.0"
 dependencies = [
+ "agave-reserved-account-keys",
  "ahash 0.8.11",
  "assert_matches",
  "bincode",
@@ -10327,7 +10347,6 @@ dependencies = [
  "solana-pubkey",
  "solana-rent",
  "solana-rent-debits",
- "solana-reserved-account-keys",
  "solana-sbpf",
  "solana-sdk",
  "solana-sdk-ids",
@@ -10839,6 +10858,7 @@ name = "solana-transaction-status"
 version = "2.3.0"
 dependencies = [
  "Inflector",
+ "agave-reserved-account-keys",
  "base64 0.22.1",
  "bincode",
  "borsh 1.5.6",
@@ -10857,7 +10877,6 @@ dependencies = [
  "solana-message",
  "solana-program",
  "solana-pubkey",
- "solana-reserved-account-keys",
  "solana-reward-info",
  "solana-sdk-ids",
  "solana-signature",

+ 2 - 1
Cargo.toml

@@ -108,6 +108,7 @@ members = [
     "rayon-threadlimit",
     "rbpf-cli",
     "remote-wallet",
+    "reserved-account-keys",
     "rpc",
     "rpc-client",
     "rpc-client-api",
@@ -181,6 +182,7 @@ Inflector = "0.11.4"
 axum = "0.7.9"
 agave-banking-stage-ingress-types = { path = "banking-stage-ingress-types", version = "=2.3.0" }
 agave-feature-set = { path = "feature-set", version = "=2.3.0" }
+agave-reserved-account-keys = { path = "reserved-account-keys", version = "=2.3.0" }
 agave-transaction-view = { path = "transaction-view", version = "=2.3.0" }
 aquamarine = "0.6.0"
 aes-gcm-siv = "0.11.1"
@@ -493,7 +495,6 @@ solana-remote-wallet = { path = "remote-wallet", version = "=2.3.0", default-fea
 solana-rent = "=2.2.1"
 solana-rent-collector = "=2.2.1"
 solana-rent-debits = "=2.2.1"
-solana-reserved-account-keys = "=2.2.1"
 solana-reward-info = "=2.2.1"
 solana-sanitize = "=2.2.1"
 solana-secp256r1-program = "=2.2.1"

+ 1 - 1
cli-output/Cargo.toml

@@ -11,6 +11,7 @@ edition = { workspace = true }
 
 [dependencies]
 Inflector = { workspace = true }
+agave-reserved-account-keys = { workspace = true }
 base64 = { workspace = true }
 chrono = { workspace = true, features = ["default", "serde"] }
 clap = "2.33.0"
@@ -34,7 +35,6 @@ solana-native-token = { workspace = true }
 solana-packet = { workspace = true }
 solana-program = { workspace = true }
 solana-pubkey = { workspace = true }
-solana-reserved-account-keys = { workspace = true }
 solana-rpc-client-api = { workspace = true }
 solana-sdk-ids = { workspace = true }
 solana-signature = { workspace = true }

+ 1 - 1
cli-output/src/display.rs

@@ -1,5 +1,6 @@
 use {
     crate::cli_output::CliSignatureVerificationStatus,
+    agave_reserved_account_keys::ReservedAccountKeys,
     base64::{prelude::BASE64_STANDARD, Engine},
     chrono::{DateTime, Local, SecondsFormat, TimeZone, Utc},
     console::style,
@@ -12,7 +13,6 @@ use {
     solana_native_token::lamports_to_sol,
     solana_program::stake,
     solana_pubkey::Pubkey,
-    solana_reserved_account_keys::ReservedAccountKeys,
     solana_signature::Signature,
     solana_transaction::versioned::{TransactionVersion, VersionedTransaction},
     solana_transaction_error::TransactionError,

+ 1 - 0
core/Cargo.toml

@@ -108,6 +108,7 @@ tokio = { workspace = true, features = ["full"] }
 trees = { workspace = true }
 
 [dev-dependencies]
+agave-reserved-account-keys = { workspace = true }
 criterion = { workspace = true }
 fs_extra = { workspace = true }
 serde_json = { workspace = true }

+ 1 - 1
core/src/banking_stage/consumer.rs

@@ -858,6 +858,7 @@ mod tests {
         crate::banking_stage::tests::{
             create_slow_genesis_config, sanitize_transactions, simulate_poh,
         },
+        agave_reserved_account_keys::ReservedAccountKeys,
         crossbeam_channel::{unbounded, Receiver},
         solana_cost_model::{cost_model::CostModel, transaction_cost::TransactionCost},
         solana_entry::entry::{next_entry, next_versioned_entry},
@@ -890,7 +891,6 @@ mod tests {
             nonce_account::verify_nonce_account,
             poh_config::PohConfig,
             pubkey::Pubkey,
-            reserved_account_keys::ReservedAccountKeys,
             signature::Keypair,
             signer::Signer,
             system_program, system_transaction,

+ 1 - 1
core/src/banking_stage/unprocessed_packet_batches.rs

@@ -50,11 +50,11 @@ impl Ord for DeserializedPacket {
 mod tests {
     use {
         super::*,
+        agave_reserved_account_keys::ReservedAccountKeys,
         solana_perf::packet::PacketFlags,
         solana_runtime::bank::Bank,
         solana_sdk::{
             hash::Hash,
-            reserved_account_keys::ReservedAccountKeys,
             signature::{Keypair, Signer},
             system_transaction,
             transaction::Transaction,

+ 1 - 1
cost-model/Cargo.toml

@@ -48,6 +48,7 @@ crate-type = ["lib"]
 name = "solana_cost_model"
 
 [dev-dependencies]
+agave-reserved-account-keys = { workspace = true }
 itertools = { workspace = true }
 rand = "0.8.5"
 # See order-crates-for-publishing.py for using this unusual `path = "."`
@@ -61,7 +62,6 @@ solana-instruction = { workspace = true }
 solana-keypair = { workspace = true }
 solana-logger = { workspace = true }
 solana-pubkey = { workspace = true, features = ["rand"] }
-solana-reserved-account-keys = { workspace = true }
 solana-runtime-transaction = { workspace = true, features = [
     "dev-context-only-utils",
 ] }

+ 1 - 1
cost-model/src/transaction_cost.rs

@@ -295,11 +295,11 @@ mod tests {
     use {
         super::*,
         crate::cost_model::CostModel,
+        agave_reserved_account_keys::ReservedAccountKeys,
         solana_feature_set::FeatureSet,
         solana_hash::Hash,
         solana_keypair::Keypair,
         solana_message::SimpleAddressLoader,
-        solana_reserved_account_keys::ReservedAccountKeys,
         solana_runtime_transaction::runtime_transaction::RuntimeTransaction,
         solana_transaction::{sanitized::MessageHash, versioned::VersionedTransaction},
         solana_vote::vote_transaction,

+ 1 - 1
entry/Cargo.toml

@@ -31,13 +31,13 @@ solana-transaction = { workspace = true }
 solana-transaction-error = { workspace = true }
 
 [dev-dependencies]
+agave-reserved-account-keys = { workspace = true }
 assert_matches = { workspace = true }
 solana-keypair = { workspace = true }
 solana-logger = { workspace = true }
 solana-message = { workspace = true }
 solana-perf = { workspace = true, features = ["dev-context-only-utils"] }
 solana-pubkey = { workspace = true }
-solana-reserved-account-keys = { workspace = true }
 solana-signature = { workspace = true }
 solana-signer = { workspace = true }
 solana-system-transaction = { workspace = true }

+ 1 - 1
entry/benches/entry_sigverify.rs

@@ -1,11 +1,11 @@
 #![feature(test)]
 extern crate test;
 use {
+    agave_reserved_account_keys::ReservedAccountKeys,
     solana_entry::entry::{self, VerifyRecyclers},
     solana_hash::Hash,
     solana_message::SimpleAddressLoader,
     solana_perf::test_tx::test_tx,
-    solana_reserved_account_keys::ReservedAccountKeys,
     solana_runtime_transaction::runtime_transaction::RuntimeTransaction,
     solana_transaction::{
         sanitized::{MessageHash, SanitizedTransaction},

+ 1 - 1
entry/src/entry.rs

@@ -974,12 +974,12 @@ pub fn thread_pool_for_benches() -> ThreadPool {
 mod tests {
     use {
         super::*,
+        agave_reserved_account_keys::ReservedAccountKeys,
         solana_hash::Hash,
         solana_keypair::Keypair,
         solana_message::SimpleAddressLoader,
         solana_perf::test_tx::{test_invalid_tx, test_tx},
         solana_pubkey::Pubkey,
-        solana_reserved_account_keys::ReservedAccountKeys,
         solana_runtime_transaction::runtime_transaction::RuntimeTransaction,
         solana_sha256_hasher::hash,
         solana_signer::Signer,

+ 1 - 0
ledger-tool/Cargo.toml

@@ -10,6 +10,7 @@ license = { workspace = true }
 edition = { workspace = true }
 
 [dependencies]
+agave-reserved-account-keys = { workspace = true }
 bs58 = { workspace = true }
 chrono = { workspace = true, features = ["default"] }
 clap = { workspace = true }

+ 1 - 1
ledger-tool/src/main.rs

@@ -12,6 +12,7 @@ use {
         },
         program::*,
     },
+    agave_reserved_account_keys::ReservedAccountKeys,
     clap::{
         crate_description, crate_name, value_t, value_t_or_exit, values_t_or_exit, App,
         AppSettings, Arg, ArgMatches, SubCommand,
@@ -74,7 +75,6 @@ use {
         native_token::{lamports_to_sol, sol_to_lamports, Sol},
         pubkey::Pubkey,
         rent::Rent,
-        reserved_account_keys::ReservedAccountKeys,
         shred_version::compute_shred_version,
         stake::{self, state::StakeStateV2},
         system_program,

+ 1 - 0
ledger/Cargo.toml

@@ -10,6 +10,7 @@ license = { workspace = true }
 edition = { workspace = true }
 
 [dependencies]
+agave-reserved-account-keys = { workspace = true }
 anyhow = { workspace = true }
 assert_matches = { workspace = true }
 bincode = { workspace = true }

+ 1 - 1
ledger/src/transaction_address_lookup_table_scanner.rs

@@ -1,10 +1,10 @@
 use {
+    agave_reserved_account_keys::ReservedAccountKeys,
     bincode::deserialize,
     lazy_static::lazy_static,
     solana_sdk::{
         address_lookup_table::{self, instruction::ProgramInstruction},
         pubkey::Pubkey,
-        reserved_account_keys::ReservedAccountKeys,
         transaction::SanitizedVersionedTransaction,
     },
     std::collections::HashSet,

+ 16 - 3
programs/sbf/Cargo.lock

@@ -83,6 +83,16 @@ dependencies = [
  "thiserror 2.0.12",
 ]
 
+[[package]]
+name = "agave-reserved-account-keys"
+version = "2.3.0"
+dependencies = [
+ "lazy_static",
+ "solana-feature-set",
+ "solana-pubkey",
+ "solana-sdk-ids",
+]
+
 [[package]]
 name = "agave-transaction-view"
 version = "2.3.0"
@@ -5647,6 +5657,7 @@ name = "solana-cli-output"
 version = "2.3.0"
 dependencies = [
  "Inflector",
+ "agave-reserved-account-keys",
  "base64 0.22.1",
  "chrono",
  "clap",
@@ -5670,7 +5681,6 @@ dependencies = [
  "solana-packet",
  "solana-program",
  "solana-pubkey",
- "solana-reserved-account-keys",
  "solana-rpc-client-api",
  "solana-sdk-ids",
  "solana-signature",
@@ -6548,6 +6558,7 @@ dependencies = [
 name = "solana-ledger"
 version = "2.3.0"
 dependencies = [
+ "agave-reserved-account-keys",
  "anyhow",
  "assert_matches",
  "bincode",
@@ -7516,6 +7527,7 @@ dependencies = [
 name = "solana-runtime"
 version = "2.3.0"
 dependencies = [
+ "agave-reserved-account-keys",
  "ahash 0.8.11",
  "aquamarine",
  "arrayref",
@@ -7626,6 +7638,7 @@ checksum = "61f1bc1357b8188d9c4a3af3fc55276e56987265eb7ad073ae6f8180ee54cecf"
 name = "solana-sbf-programs"
 version = "2.3.0"
 dependencies = [
+ "agave-reserved-account-keys",
  "agave-validator",
  "bincode",
  "borsh 1.5.6",
@@ -8495,6 +8508,7 @@ dependencies = [
 name = "solana-storage-bigtable"
 version = "2.3.0"
 dependencies = [
+ "agave-reserved-account-keys",
  "backoff",
  "bincode",
  "bytes",
@@ -8517,7 +8531,6 @@ dependencies = [
  "solana-message",
  "solana-metrics",
  "solana-pubkey",
- "solana-reserved-account-keys",
  "solana-serde",
  "solana-signature",
  "solana-storage-proto",
@@ -8994,6 +9007,7 @@ name = "solana-transaction-status"
 version = "2.3.0"
 dependencies = [
  "Inflector",
+ "agave-reserved-account-keys",
  "base64 0.22.1",
  "bincode",
  "borsh 1.5.6",
@@ -9011,7 +9025,6 @@ dependencies = [
  "solana-message",
  "solana-program",
  "solana-pubkey",
- "solana-reserved-account-keys",
  "solana-reward-info",
  "solana-sdk-ids",
  "solana-signature",

+ 2 - 0
programs/sbf/Cargo.toml

@@ -15,6 +15,7 @@ check-cfg = [
 ]
 
 [workspace.dependencies]
+agave-reserved-account-keys = { path = "../../reserved-account-keys", version = "=2.3.0" }
 array-bytes = "=1.4.1"
 bincode = { version = "1.1.4", default-features = false }
 blake3 = "1.0.0"
@@ -103,6 +104,7 @@ dummy-for-ci-check = ["sbf_c", "sbf_rust", "sbf_sanity_list"]
 frozen-abi = []
 
 [dev-dependencies]
+agave-reserved-account-keys = { workspace = true }
 agave-validator = { workspace = true }
 bincode = { workspace = true }
 borsh = { workspace = true }

+ 1 - 1
programs/sbf/tests/programs.rs

@@ -9,6 +9,7 @@
 
 #[cfg(feature = "sbf_rust")]
 use {
+    agave_reserved_account_keys::ReservedAccountKeys,
     borsh::{from_slice, to_vec, BorshDeserialize, BorshSerialize},
     solana_compute_budget::compute_budget::ComputeBudget,
     solana_compute_budget_instruction::instructions_processor::process_compute_budget_instructions,
@@ -47,7 +48,6 @@ use {
         message::{Message, SanitizedMessage},
         pubkey::Pubkey,
         rent::Rent,
-        reserved_account_keys::ReservedAccountKeys,
         signature::{Keypair, Signer},
         stake,
         system_instruction::MAX_PERMITTED_DATA_LENGTH,

+ 37 - 0
reserved-account-keys/Cargo.toml

@@ -0,0 +1,37 @@
+[package]
+name = "agave-reserved-account-keys"
+description = "Reserved Solana account keys"
+documentation = "https://docs.rs/agave-reserved-account-keys"
+version = { workspace = true }
+authors = { workspace = true }
+repository = { workspace = true }
+homepage = { workspace = true }
+license = { workspace = true }
+edition = { workspace = true }
+
+[dependencies]
+lazy_static = { workspace = true }
+solana-feature-set = { workspace = true }
+solana-frozen-abi = { workspace = true, optional = true, features = [
+    "frozen-abi",
+] }
+solana-frozen-abi-macro = { workspace = true, optional = true, features = [
+    "frozen-abi",
+] }
+solana-pubkey = { workspace = true, default-features = false }
+solana-sdk-ids = { workspace = true }
+
+[dev-dependencies]
+solana-message = { workspace = true }
+solana-sysvar = { workspace = true }
+
+[features]
+frozen-abi = ["dep:solana-frozen-abi", "dep:solana-frozen-abi-macro"]
+
+[package.metadata.docs.rs]
+targets = ["x86_64-unknown-linux-gnu"]
+all-features = true
+rustdoc-args = ["--cfg=docsrs"]
+
+[lints]
+workspace = true

+ 260 - 0
reserved-account-keys/src/lib.rs

@@ -0,0 +1,260 @@
+//! Collection of reserved account keys that cannot be write-locked by transactions.
+//! New reserved account keys may be added as long as they specify a feature
+//! gate that transitions the key into read-only at an epoch boundary.
+#![cfg_attr(feature = "frozen-abi", feature(min_specialization))]
+#![cfg_attr(docsrs, feature(doc_auto_cfg))]
+use {
+    lazy_static::lazy_static,
+    solana_feature_set::{self as feature_set, FeatureSet},
+    solana_pubkey::Pubkey,
+    solana_sdk_ids::{
+        address_lookup_table, bpf_loader, bpf_loader_deprecated, bpf_loader_upgradeable,
+        compute_budget, config, ed25519_program, feature, loader_v4, native_loader,
+        secp256k1_program, secp256r1_program, stake, system_program, sysvar, vote,
+        zk_elgamal_proof_program, zk_token_proof_program,
+    },
+    std::collections::{HashMap, HashSet},
+};
+
+// ReservedAccountKeys is not serialized into or deserialized from bank
+// snapshots but the bank requires this trait to be implemented anyways.
+#[cfg(feature = "frozen-abi")]
+impl ::solana_frozen_abi::abi_example::AbiExample for ReservedAccountKeys {
+    fn example() -> Self {
+        // ReservedAccountKeys is not Serialize so just rely on Default.
+        ReservedAccountKeys::default()
+    }
+}
+
+/// `ReservedAccountKeys` holds the set of currently active/inactive
+/// account keys that are reserved by the protocol and may not be write-locked
+/// during transaction processing.
+#[derive(Debug, Clone, PartialEq)]
+pub struct ReservedAccountKeys {
+    /// Set of currently active reserved account keys
+    pub active: HashSet<Pubkey>,
+    /// Set of currently inactive reserved account keys that will be moved to the
+    /// active set when their feature id is activated
+    inactive: HashMap<Pubkey, Pubkey>,
+}
+
+impl Default for ReservedAccountKeys {
+    fn default() -> Self {
+        Self::new(&RESERVED_ACCOUNTS)
+    }
+}
+
+impl ReservedAccountKeys {
+    /// Compute a set of active / inactive reserved account keys from a list of
+    /// keys with a designated feature id. If a reserved account key doesn't
+    /// designate a feature id, it's already activated and should be inserted
+    /// into the active set. If it does have a feature id, insert the key and
+    /// its feature id into the inactive map.
+    fn new(reserved_accounts: &[ReservedAccount]) -> Self {
+        Self {
+            active: reserved_accounts
+                .iter()
+                .filter(|reserved| reserved.feature_id.is_none())
+                .map(|reserved| reserved.key)
+                .collect(),
+            inactive: reserved_accounts
+                .iter()
+                .filter_map(|ReservedAccount { key, feature_id }| {
+                    feature_id.as_ref().map(|feature_id| (*key, *feature_id))
+                })
+                .collect(),
+        }
+    }
+
+    /// Compute a set with all reserved keys active, regardless of whether their
+    /// feature was activated. This is not to be used by the runtime. Useful for
+    /// off-chain utilities that need to filter out reserved accounts.
+    pub fn new_all_activated() -> Self {
+        Self {
+            active: Self::all_keys_iter().copied().collect(),
+            inactive: HashMap::default(),
+        }
+    }
+
+    /// Returns whether the specified key is reserved
+    pub fn is_reserved(&self, key: &Pubkey) -> bool {
+        self.active.contains(key)
+    }
+
+    /// Move inactive reserved account keys to the active set if their feature
+    /// is active.
+    pub fn update_active_set(&mut self, feature_set: &FeatureSet) {
+        self.inactive.retain(|reserved_key, feature_id| {
+            if feature_set.is_active(feature_id) {
+                self.active.insert(*reserved_key);
+                false
+            } else {
+                true
+            }
+        });
+    }
+
+    /// Return an iterator over all active / inactive reserved keys. This is not
+    /// to be used by the runtime. Useful for off-chain utilities that need to
+    /// filter out reserved accounts.
+    pub fn all_keys_iter() -> impl Iterator<Item = &'static Pubkey> {
+        RESERVED_ACCOUNTS
+            .iter()
+            .map(|reserved_key| &reserved_key.key)
+    }
+
+    /// Return an empty set of reserved keys for visibility when using in
+    /// tests where the dynamic reserved key set is not available
+    pub fn empty_key_set() -> HashSet<Pubkey> {
+        HashSet::default()
+    }
+}
+
+/// `ReservedAccount` represents a reserved account that will not be
+/// write-lockable by transactions. If a feature id is set, the account will
+/// become read-only only after the feature has been activated.
+#[derive(Debug, Clone, Copy, Eq, PartialEq)]
+struct ReservedAccount {
+    key: Pubkey,
+    feature_id: Option<Pubkey>,
+}
+
+impl ReservedAccount {
+    fn new_pending(key: Pubkey, feature_id: Pubkey) -> Self {
+        Self {
+            key,
+            feature_id: Some(feature_id),
+        }
+    }
+
+    fn new_active(key: Pubkey) -> Self {
+        Self {
+            key,
+            feature_id: None,
+        }
+    }
+}
+
+// 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<ReservedAccount> = [
+        // builtin programs
+        ReservedAccount::new_pending(address_lookup_table::id(), feature_set::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_active(config::id()),
+        ReservedAccount::new_pending(ed25519_program::id(), feature_set::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()),
+        #[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()),
+
+        // sysvars
+        ReservedAccount::new_active(sysvar::clock::id()),
+        ReservedAccount::new_pending(sysvar::epoch_rewards::id(), feature_set::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()),
+        #[allow(deprecated)]
+        ReservedAccount::new_active(sysvar::recent_blockhashes::id()),
+        ReservedAccount::new_active(sysvar::rent::id()),
+        ReservedAccount::new_active(sysvar::rewards::id()),
+        ReservedAccount::new_active(sysvar::slot_hashes::id()),
+        ReservedAccount::new_active(sysvar::slot_history::id()),
+        ReservedAccount::new_active(sysvar::stake_history::id()),
+
+        // other
+        ReservedAccount::new_active(native_loader::id()),
+        ReservedAccount::new_pending(sysvar::id(), feature_set::add_new_reserved_account_keys::id()),
+    ].to_vec();
+}
+
+#[cfg(test)]
+mod tests {
+    #![allow(deprecated)]
+    use {super::*, solana_message::legacy::BUILTIN_PROGRAMS_KEYS, solana_sysvar::ALL_IDS};
+
+    #[test]
+    fn test_is_reserved() {
+        let feature_id = Pubkey::new_unique();
+        let active_reserved_account = ReservedAccount::new_active(Pubkey::new_unique());
+        let pending_reserved_account =
+            ReservedAccount::new_pending(Pubkey::new_unique(), feature_id);
+        let reserved_account_keys =
+            ReservedAccountKeys::new(&[active_reserved_account, pending_reserved_account]);
+
+        assert!(
+            reserved_account_keys.is_reserved(&active_reserved_account.key),
+            "active reserved accounts should be inserted into the active set"
+        );
+        assert!(
+            !reserved_account_keys.is_reserved(&pending_reserved_account.key),
+            "pending reserved accounts should NOT be inserted into the active set"
+        );
+    }
+
+    #[test]
+    fn test_update_active_set() {
+        let feature_ids = [Pubkey::new_unique(), Pubkey::new_unique()];
+        let active_reserved_key = Pubkey::new_unique();
+        let pending_reserved_keys = [Pubkey::new_unique(), Pubkey::new_unique()];
+        let reserved_accounts = vec![
+            ReservedAccount::new_active(active_reserved_key),
+            ReservedAccount::new_pending(pending_reserved_keys[0], feature_ids[0]),
+            ReservedAccount::new_pending(pending_reserved_keys[1], feature_ids[1]),
+        ];
+
+        let mut reserved_account_keys = ReservedAccountKeys::new(&reserved_accounts);
+        assert!(reserved_account_keys.is_reserved(&active_reserved_key));
+        assert!(!reserved_account_keys.is_reserved(&pending_reserved_keys[0]));
+        assert!(!reserved_account_keys.is_reserved(&pending_reserved_keys[1]));
+
+        // Updating the active set with a default feature set should be a no-op
+        let previous_reserved_account_keys = reserved_account_keys.clone();
+        let mut feature_set = FeatureSet::default();
+        reserved_account_keys.update_active_set(&feature_set);
+        assert_eq!(reserved_account_keys, previous_reserved_account_keys);
+
+        // Updating the active set with an activated feature should also activate
+        // the corresponding reserved key from inactive to active
+        feature_set.active.insert(feature_ids[0], 0);
+        reserved_account_keys.update_active_set(&feature_set);
+
+        assert!(reserved_account_keys.is_reserved(&active_reserved_key));
+        assert!(reserved_account_keys.is_reserved(&pending_reserved_keys[0]));
+        assert!(!reserved_account_keys.is_reserved(&pending_reserved_keys[1]));
+
+        // Update the active set again to ensure that the inactive map is
+        // properly retained
+        feature_set.active.insert(feature_ids[1], 0);
+        reserved_account_keys.update_active_set(&feature_set);
+
+        assert!(reserved_account_keys.is_reserved(&active_reserved_key));
+        assert!(reserved_account_keys.is_reserved(&pending_reserved_keys[0]));
+        assert!(reserved_account_keys.is_reserved(&pending_reserved_keys[1]));
+    }
+
+    #[test]
+    fn test_static_list_compat() {
+        let mut static_set = HashSet::new();
+        static_set.extend(ALL_IDS.iter().cloned());
+        static_set.extend(BUILTIN_PROGRAMS_KEYS.iter().cloned());
+
+        let initial_active_set = ReservedAccountKeys::default().active;
+
+        assert_eq!(initial_active_set, static_set);
+    }
+}

+ 1 - 0
rpc/Cargo.toml

@@ -67,6 +67,7 @@ tokio = { workspace = true, features = ["full"] }
 tokio-util = { workspace = true, features = ["codec", "compat"] }
 
 [dev-dependencies]
+agave-reserved-account-keys = { workspace = true }
 serial_test = { workspace = true }
 solana-net-utils = { workspace = true }
 solana-rpc = { path = ".", features = ["dev-context-only-utils"] }

+ 1 - 1
rpc/src/rpc.rs

@@ -4507,6 +4507,7 @@ pub mod tests {
             rpc_service::service_runtime,
             rpc_subscriptions::RpcSubscriptions,
         },
+        agave_reserved_account_keys::ReservedAccountKeys,
         bincode::deserialize,
         jsonrpc_core::{futures, ErrorCode, MetaIoHandler, Output, Response, Value},
         jsonrpc_core_client::transports::local,
@@ -4548,7 +4549,6 @@ pub mod tests {
                 Message, MessageHeader, VersionedMessage,
             },
             nonce::{self, state::DurableNonce},
-            reserved_account_keys::ReservedAccountKeys,
             rpc_port,
             signature::{Keypair, Signer},
             slot_hashes::SlotHashes,

+ 1 - 1
rpc/src/transaction_status_service.rs

@@ -261,6 +261,7 @@ pub(crate) mod tests {
     use {
         super::*,
         crate::transaction_notifier_interface::TransactionNotifier,
+        agave_reserved_account_keys::ReservedAccountKeys,
         crossbeam_channel::unbounded,
         dashmap::DashMap,
         solana_account_decoder::{
@@ -277,7 +278,6 @@ pub(crate) mod tests {
             nonce_account,
             pubkey::Pubkey,
             rent_debits::RentDebits,
-            reserved_account_keys::ReservedAccountKeys,
             signature::{Keypair, Signature, Signer},
             system_transaction,
             transaction::{

+ 1 - 1
runtime-transaction/Cargo.toml

@@ -29,6 +29,7 @@ crate-type = ["lib"]
 name = "solana_runtime_transaction"
 
 [dev-dependencies]
+agave-reserved-account-keys = { workspace = true }
 bincode = { workspace = true }
 criterion = { workspace = true }
 rand = { workspace = true }
@@ -39,7 +40,6 @@ solana-instruction = { workspace = true }
 solana-keypair = { workspace = true }
 solana-program = { workspace = true }
 solana-pubkey = { workspace = true, features = ["rand"] }
-solana-reserved-account-keys = { workspace = true }
 solana-signer = { workspace = true }
 solana-system-interface = { workspace = true, features = ["bincode"] }
 solana-system-transaction = { workspace = true }

+ 1 - 1
runtime-transaction/src/runtime_transaction/sdk_transactions.rs

@@ -153,6 +153,7 @@ impl RuntimeTransaction<SanitizedTransaction> {
 mod tests {
     use {
         super::*,
+        agave_reserved_account_keys::ReservedAccountKeys,
         solana_compute_budget_interface::ComputeBudgetInstruction,
         solana_feature_set::FeatureSet,
         solana_hash::Hash,
@@ -160,7 +161,6 @@ mod tests {
         solana_keypair::Keypair,
         solana_message::{Message, SimpleAddressLoader},
         solana_program::vote::{self, state::Vote},
-        solana_reserved_account_keys::ReservedAccountKeys,
         solana_signer::Signer,
         solana_system_interface::instruction as system_instruction,
         solana_transaction::{versioned::VersionedTransaction, Transaction},

+ 1 - 1
runtime-transaction/src/runtime_transaction/transaction_view.rs

@@ -192,10 +192,10 @@ impl<D: TransactionData> TransactionWithMeta for RuntimeTransaction<ResolvedTran
 mod tests {
     use {
         super::*,
+        agave_reserved_account_keys::ReservedAccountKeys,
         solana_hash::Hash,
         solana_keypair::Keypair,
         solana_message::{v0, AddressLookupTableAccount, SimpleAddressLoader},
-        solana_reserved_account_keys::ReservedAccountKeys,
         solana_signature::Signature,
         solana_system_interface::instruction as system_instruction,
         solana_system_transaction as system_transaction,

+ 1 - 0
runtime/Cargo.toml

@@ -10,6 +10,7 @@ license = { workspace = true }
 edition = { workspace = true }
 
 [dependencies]
+agave-reserved-account-keys = { workspace = true }
 ahash = { workspace = true }
 aquamarine = { workspace = true }
 arrayref = { workspace = true }

+ 1 - 1
runtime/src/bank.rs

@@ -59,6 +59,7 @@ use {
         verify_precompiles::verify_precompiles,
     },
     accounts_lt_hash::{CacheValue as AccountsLtHashCacheValue, Stats as AccountsLtHashStats},
+    agave_reserved_account_keys::ReservedAccountKeys,
     ahash::AHashSet,
     dashmap::{DashMap, DashSet},
     log::*,
@@ -137,7 +138,6 @@ use {
         pubkey::Pubkey,
         rent_collector::{CollectedInfo, RentCollector},
         rent_debits::RentDebits,
-        reserved_account_keys::ReservedAccountKeys,
         reward_info::RewardInfo,
         signature::{Keypair, Signature},
         slot_hashes::SlotHashes,

+ 1 - 1
runtime/src/snapshot_minimizer.rs

@@ -2,6 +2,7 @@
 
 use {
     crate::{bank::Bank, static_ids},
+    agave_reserved_account_keys::ReservedAccountKeys,
     dashmap::DashSet,
     log::info,
     rayon::{
@@ -22,7 +23,6 @@ use {
         bpf_loader_upgradeable::{self, UpgradeableLoaderState},
         clock::Slot,
         pubkey::Pubkey,
-        reserved_account_keys::ReservedAccountKeys,
     },
     std::{
         collections::HashSet,

+ 1 - 1
storage-bigtable/Cargo.toml

@@ -10,6 +10,7 @@ license = { workspace = true }
 edition = { workspace = true }
 
 [dependencies]
+agave-reserved-account-keys = { workspace = true }
 backoff = { workspace = true, features = ["tokio"] }
 bincode = { workspace = true }
 bytes = { workspace = true }
@@ -34,7 +35,6 @@ solana-clock = { workspace = true }
 solana-message = { workspace = true }
 solana-metrics = { workspace = true }
 solana-pubkey = { workspace = true }
-solana-reserved-account-keys = { workspace = true }
 solana-serde = { workspace = true }
 solana-signature = { workspace = true }
 solana-storage-proto = { workspace = true }

+ 1 - 1
storage-bigtable/src/lib.rs

@@ -2,13 +2,13 @@
 
 use {
     crate::bigtable::RowKey,
+    agave_reserved_account_keys::ReservedAccountKeys,
     log::*,
     serde::{Deserialize, Serialize},
     solana_clock::{Slot, UnixTimestamp},
     solana_message::v0::LoadedAddresses,
     solana_metrics::datapoint_info,
     solana_pubkey::Pubkey,
-    solana_reserved_account_keys::ReservedAccountKeys,
     solana_serde::default_on_eof,
     solana_signature::Signature,
     solana_storage_proto::convert::{entries, generated, tx_by_addr},

+ 1 - 1
svm/Cargo.toml

@@ -58,6 +58,7 @@ crate-type = ["lib"]
 name = "solana_svm"
 
 [dev-dependencies]
+agave-reserved-account-keys = { workspace = true }
 assert_matches = { workspace = true }
 bincode = { workspace = true }
 ed25519-dalek = { workspace = true }
@@ -80,7 +81,6 @@ solana-native-token = { workspace = true }
 solana-program-runtime = { workspace = true, features = ["dev-context-only-utils"] }
 solana-pubkey = { workspace = true }
 solana-rent = { workspace = true }
-solana-reserved-account-keys = { workspace = true }
 solana-sbpf = { workspace = true }
 solana-sdk = { workspace = true, features = ["dev-context-only-utils"] }
 solana-secp256k1-program = { workspace = true }

+ 16 - 3
svm/examples/Cargo.lock

@@ -83,6 +83,16 @@ dependencies = [
  "thiserror 2.0.12",
 ]
 
+[[package]]
+name = "agave-reserved-account-keys"
+version = "2.3.0"
+dependencies = [
+ "lazy_static",
+ "solana-feature-set",
+ "solana-pubkey",
+ "solana-sdk-ids",
+]
+
 [[package]]
 name = "agave-transaction-view"
 version = "2.3.0"
@@ -2746,6 +2756,7 @@ dependencies = [
 name = "json-rpc-server"
 version = "2.3.0"
 dependencies = [
+ "agave-reserved-account-keys",
  "base64 0.22.1",
  "bincode",
  "bs58",
@@ -5502,6 +5513,7 @@ name = "solana-cli-output"
 version = "2.3.0"
 dependencies = [
  "Inflector",
+ "agave-reserved-account-keys",
  "base64 0.22.1",
  "chrono",
  "clap",
@@ -5525,7 +5537,6 @@ dependencies = [
  "solana-packet",
  "solana-program",
  "solana-pubkey",
- "solana-reserved-account-keys",
  "solana-rpc-client-api",
  "solana-sdk-ids",
  "solana-signature",
@@ -6369,6 +6380,7 @@ dependencies = [
 name = "solana-ledger"
 version = "2.3.0"
 dependencies = [
+ "agave-reserved-account-keys",
  "anyhow",
  "assert_matches",
  "bincode",
@@ -7337,6 +7349,7 @@ dependencies = [
 name = "solana-runtime"
 version = "2.3.0"
 dependencies = [
+ "agave-reserved-account-keys",
  "ahash 0.8.11",
  "aquamarine",
  "arrayref",
@@ -7815,6 +7828,7 @@ dependencies = [
 name = "solana-storage-bigtable"
 version = "2.3.0"
 dependencies = [
+ "agave-reserved-account-keys",
  "backoff",
  "bincode",
  "bytes",
@@ -7837,7 +7851,6 @@ dependencies = [
  "solana-message",
  "solana-metrics",
  "solana-pubkey",
- "solana-reserved-account-keys",
  "solana-serde",
  "solana-signature",
  "solana-storage-proto",
@@ -8332,6 +8345,7 @@ name = "solana-transaction-status"
 version = "2.3.0"
 dependencies = [
  "Inflector",
+ "agave-reserved-account-keys",
  "base64 0.22.1",
  "bincode",
  "borsh 1.5.6",
@@ -8349,7 +8363,6 @@ dependencies = [
  "solana-message",
  "solana-program",
  "solana-pubkey",
- "solana-reserved-account-keys",
  "solana-reward-info",
  "solana-sdk-ids",
  "solana-signature",

+ 1 - 0
svm/examples/Cargo.toml

@@ -12,6 +12,7 @@ license = "Apache-2.0"
 edition = "2021"
 
 [workspace.dependencies]
+agave-reserved-account-keys = { path = "../../reserved-account-keys" }
 base64 = "0.22.1"
 bincode = "1.3.3"
 borsh = { version = "1.5.2", features = ["derive"] }

+ 1 - 0
svm/examples/json-rpc/server/Cargo.toml

@@ -6,6 +6,7 @@ edition = { workspace = true }
 publish = false
 
 [dependencies]
+agave-reserved-account-keys = { workspace = true }
 base64 = { workspace = true }
 bincode = { workspace = true }
 bs58 = { workspace = true }

+ 1 - 1
svm/examples/json-rpc/server/src/rpc_process.rs

@@ -3,6 +3,7 @@ use {
         create_executable_environment, LoadAndExecuteTransactionsOutput, MockBankCallback,
         MockForkGraph, TransactionBatch,
     },
+    agave_reserved_account_keys::ReservedAccountKeys,
     base64::{prelude::BASE64_STANDARD, Engine},
     bincode::config::Options,
     jsonrpc_core::{types::error, Error, Metadata, Result},
@@ -37,7 +38,6 @@ use {
         },
         nonce::state::DurableNonce,
         pubkey::Pubkey,
-        reserved_account_keys::ReservedAccountKeys,
         signature::Signature,
         system_instruction, sysvar,
         transaction::{

+ 1 - 1
svm/src/account_loader.rs

@@ -675,6 +675,7 @@ mod tests {
             transaction_account_state_info::TransactionAccountStateInfo,
             transaction_processing_callback::TransactionProcessingCallback,
         },
+        agave_reserved_account_keys::ReservedAccountKeys,
         solana_account::{Account, AccountSharedData, ReadableAccount, WritableAccount},
         solana_epoch_schedule::EpochSchedule,
         solana_feature_set::FeatureSet,
@@ -695,7 +696,6 @@ mod tests {
         solana_pubkey::Pubkey,
         solana_rent::Rent,
         solana_rent_debits::RentDebits,
-        solana_reserved_account_keys::ReservedAccountKeys,
         solana_sdk::rent_collector::{RentCollector, RENT_EXEMPT_RENT_EPOCH},
         solana_sdk_ids::{
             bpf_loader, bpf_loader_upgradeable, native_loader, system_program, sysvar,

+ 1 - 1
svm/src/message_processor.rs

@@ -116,6 +116,7 @@ pub(crate) fn process_message(
 mod tests {
     use {
         super::*,
+        agave_reserved_account_keys::ReservedAccountKeys,
         openssl::{
             ec::{EcGroup, EcKey},
             nid::Nid,
@@ -136,7 +137,6 @@ mod tests {
         },
         solana_pubkey::Pubkey,
         solana_rent::Rent,
-        solana_reserved_account_keys::ReservedAccountKeys,
         solana_sdk::native_loader::create_loadable_account_for_test,
         solana_sdk_ids::{ed25519_program, native_loader, secp256k1_program, system_program},
         solana_secp256k1_program::new_secp256k1_instruction,

+ 1 - 1
svm/src/transaction_account_state_info.rs

@@ -70,6 +70,7 @@ impl TransactionAccountStateInfo {
 mod test {
     use {
         super::*,
+        agave_reserved_account_keys::ReservedAccountKeys,
         solana_account::AccountSharedData,
         solana_hash::Hash,
         solana_keypair::Keypair,
@@ -78,7 +79,6 @@ mod test {
             SanitizedMessage,
         },
         solana_rent::Rent,
-        solana_reserved_account_keys::ReservedAccountKeys,
         solana_sdk::rent_collector::RentCollector,
         solana_signer::Signer,
         solana_transaction_context::TransactionContext,

+ 1 - 1
svm/src/transaction_processor.rs

@@ -1161,6 +1161,7 @@ mod tests {
             rollback_accounts::RollbackAccounts,
             transaction_processing_callback::AccountState,
         },
+        agave_reserved_account_keys::ReservedAccountKeys,
         solana_account::{create_account_shared_data_for_test, WritableAccount},
         solana_clock::Clock,
         solana_compute_budget_interface::ComputeBudgetInstruction,
@@ -1178,7 +1179,6 @@ mod tests {
         },
         solana_rent::Rent,
         solana_rent_debits::RentDebits,
-        solana_reserved_account_keys::ReservedAccountKeys,
         solana_sdk::rent_collector::{RentCollector, RENT_EXEMPT_RENT_EPOCH},
         solana_sdk_ids::{bpf_loader, system_program, sysvar},
         solana_signature::Signature,

+ 1 - 1
svm/tests/transaction_builder.rs

@@ -1,4 +1,5 @@
 use {
+    agave_reserved_account_keys::ReservedAccountKeys,
     solana_sdk::{
         hash::Hash,
         instruction::{AccountMeta, CompiledInstruction},
@@ -7,7 +8,6 @@ use {
             AddressLoader, AddressLoaderError, Message, MessageHeader, VersionedMessage,
         },
         pubkey::Pubkey,
-        reserved_account_keys::ReservedAccountKeys,
         signature::Signature,
         transaction::{
             SanitizedTransaction, SanitizedVersionedTransaction, TransactionError,

+ 1 - 1
transaction-status/Cargo.toml

@@ -11,6 +11,7 @@ edition = { workspace = true }
 
 [dependencies]
 Inflector = { workspace = true }
+agave-reserved-account-keys = { workspace = true }
 base64 = { workspace = true }
 bincode = { workspace = true }
 borsh = { workspace = true }
@@ -28,7 +29,6 @@ solana-loader-v2-interface = { workspace = true, features = ["bincode"] }
 solana-message = { workspace = true }
 solana-program = { workspace = true }
 solana-pubkey = { workspace = true }
-solana-reserved-account-keys = { workspace = true }
 solana-reward-info = { workspace = true }
 solana-sdk-ids = { workspace = true }
 solana-signature = { workspace = true }

+ 1 - 1
transaction-status/src/lib.rs

@@ -22,6 +22,7 @@ use {
         parse_accounts::{parse_legacy_message_accounts, parse_v0_message_accounts},
         parse_instruction::parse,
     },
+    agave_reserved_account_keys::ReservedAccountKeys,
     base64::{prelude::BASE64_STANDARD, Engine},
     solana_clock::{Slot, UnixTimestamp},
     solana_hash::Hash,
@@ -31,7 +32,6 @@ use {
         AccountKeys, Message, VersionedMessage,
     },
     solana_pubkey::Pubkey,
-    solana_reserved_account_keys::ReservedAccountKeys,
     solana_signature::Signature,
     solana_transaction::{
         versioned::{TransactionVersion, VersionedTransaction},

+ 2 - 2
transaction-status/src/parse_accounts.rs

@@ -1,7 +1,7 @@
 pub use solana_transaction_status_client_types::{ParsedAccount, ParsedAccountSource};
 use {
+    agave_reserved_account_keys::ReservedAccountKeys,
     solana_message::{v0::LoadedMessage, Message},
-    solana_reserved_account_keys::ReservedAccountKeys,
 };
 
 pub fn parse_legacy_message_accounts(message: &Message) -> Vec<ParsedAccount> {
@@ -40,9 +40,9 @@ pub fn parse_v0_message_accounts(message: &LoadedMessage) -> Vec<ParsedAccount>
 mod test {
     use {
         super::*,
+        agave_reserved_account_keys::ReservedAccountKeys,
         solana_message::{v0, v0::LoadedAddresses, MessageHeader},
         solana_pubkey::Pubkey,
-        solana_reserved_account_keys::ReservedAccountKeys,
     };
 
     #[test]