Ver Fonte

Drop the Address Lookup Table builtin (#5647)

* builtins: remove address lookup table program

* rm -rf programs/address-lookup-table

* clean up feature gate
Joe C há 7 meses atrás
pai
commit
e1c060721f

+ 0 - 44
Cargo.lock

@@ -6613,48 +6613,6 @@ dependencies = [
  "solana-slot-hashes",
 ]
 
-[[package]]
-name = "solana-address-lookup-table-program"
-version = "2.3.0"
-dependencies = [
- "agave-feature-set",
- "bincode",
- "bytemuck",
- "log",
- "num-derive",
- "num-traits",
- "solana-address-lookup-table-interface",
- "solana-bincode",
- "solana-clock",
- "solana-instruction",
- "solana-log-collector",
- "solana-packet",
- "solana-program-runtime",
- "solana-pubkey",
- "solana-system-interface",
- "solana-transaction-context 2.3.0",
- "thiserror 2.0.12",
-]
-
-[[package]]
-name = "solana-address-lookup-table-program-tests"
-version = "2.3.0"
-dependencies = [
- "agave-feature-set",
- "assert_matches",
- "bincode",
- "criterion",
- "solana-account",
- "solana-address-lookup-table-program",
- "solana-instruction",
- "solana-program-runtime",
- "solana-program-test",
- "solana-pubkey",
- "solana-sdk",
- "solana-sdk-ids",
- "solana-system-program",
-]
-
 [[package]]
 name = "solana-atomic-u64"
 version = "2.2.1"
@@ -6989,7 +6947,6 @@ name = "solana-builtins"
 version = "2.3.0"
 dependencies = [
  "agave-feature-set",
- "solana-address-lookup-table-program",
  "solana-bpf-loader-program",
  "solana-compute-budget-program",
  "solana-loader-v4-program",
@@ -7012,7 +6969,6 @@ dependencies = [
  "lazy_static",
  "log",
  "rand 0.8.5",
- "solana-address-lookup-table-program",
  "solana-bpf-loader-program",
  "solana-compute-budget-program",
  "solana-frozen-abi",

+ 0 - 3
Cargo.toml

@@ -87,8 +87,6 @@ members = [
     "precompiles",
     "program-runtime",
     "program-test",
-    "programs/address-lookup-table",
-    "programs/address-lookup-table-tests",
     "programs/bpf-loader-tests",
     "programs/bpf_loader",
     "programs/bpf_loader/gen-syscall-list",
@@ -383,7 +381,6 @@ solana-account-decoder-client-types = { path = "account-decoder-client-types", v
 solana-account-info = "2.2.1"
 solana-accounts-db = { path = "accounts-db", version = "=2.3.0" }
 solana-address-lookup-table-interface = "2.2.2"
-solana-address-lookup-table-program = { path = "programs/address-lookup-table", version = "=2.3.0" }
 solana-atomic-u64 = "2.2.1"
 solana-banks-client = { path = "banks-client", version = "=2.3.0" }
 solana-banks-interface = { path = "banks-interface", version = "=2.3.0" }

+ 0 - 1
builtins-default-costs/Cargo.toml

@@ -14,7 +14,6 @@ agave-feature-set = { workspace = true }
 ahash = { workspace = true }
 lazy_static = { workspace = true }
 log = { workspace = true }
-solana-address-lookup-table-program = { workspace = true }
 solana-bpf-loader-program = { workspace = true }
 solana-compute-budget-program = { workspace = true }
 solana-frozen-abi = { workspace = true, optional = true, features = [

+ 11 - 36
builtins-default-costs/src/lib.rs

@@ -6,8 +6,8 @@ use {
     lazy_static::lazy_static,
     solana_pubkey::Pubkey,
     solana_sdk_ids::{
-        address_lookup_table, bpf_loader, bpf_loader_deprecated, bpf_loader_upgradeable,
-        compute_budget, ed25519_program, loader_v4, secp256k1_program, stake, system_program, vote,
+        bpf_loader, bpf_loader_deprecated, bpf_loader_upgradeable, compute_budget, ed25519_program,
+        loader_v4, secp256k1_program, stake, system_program, vote,
     },
 };
 
@@ -101,32 +101,21 @@ lazy_static! {
 /// correctly furnishing `core_bpf_migration_feature`.
 ///
 #[allow(dead_code)]
-const TOTAL_COUNT_BUILTINS: usize = 11;
+const TOTAL_COUNT_BUILTINS: usize = 10;
 #[cfg(test)]
 static_assertions::const_assert_eq!(
     MIGRATING_BUILTINS_COSTS.len() + NON_MIGRATING_BUILTINS_COSTS.len(),
     TOTAL_COUNT_BUILTINS
 );
 
-pub const MIGRATING_BUILTINS_COSTS: &[(Pubkey, BuiltinCost)] = &[
-    (
-        stake::id(),
-        BuiltinCost::Migrating(MigratingBuiltinCost {
-            native_cost: solana_stake_program::stake_instruction::DEFAULT_COMPUTE_UNITS,
-            core_bpf_migration_feature: feature_set::migrate_stake_program_to_core_bpf::id(),
-            position: 0,
-        }),
-    ),
-    (
-        address_lookup_table::id(),
-        BuiltinCost::Migrating(MigratingBuiltinCost {
-            native_cost: solana_address_lookup_table_program::processor::DEFAULT_COMPUTE_UNITS,
-            core_bpf_migration_feature:
-                feature_set::migrate_address_lookup_table_program_to_core_bpf::id(),
-            position: 1,
-        }),
-    ),
-];
+pub const MIGRATING_BUILTINS_COSTS: &[(Pubkey, BuiltinCost)] = &[(
+    stake::id(),
+    BuiltinCost::Migrating(MigratingBuiltinCost {
+        native_cost: solana_stake_program::stake_instruction::DEFAULT_COMPUTE_UNITS,
+        core_bpf_migration_feature: feature_set::migrate_stake_program_to_core_bpf::id(),
+        position: 0,
+    }),
+)];
 
 const NON_MIGRATING_BUILTINS_COSTS: &[(Pubkey, BuiltinCost)] = &[
     (
@@ -331,20 +320,6 @@ mod test {
             get_migration_feature_id(feature_index),
             &feature_set::migrate_stake_program_to_core_bpf::id()
         );
-        let feature_index = get_builtin_migration_feature_index(&address_lookup_table::id());
-        assert!(matches!(
-            feature_index,
-            BuiltinMigrationFeatureIndex::BuiltinWithMigrationFeature(_)
-        ));
-        let BuiltinMigrationFeatureIndex::BuiltinWithMigrationFeature(feature_index) =
-            feature_index
-        else {
-            panic!("expect migrating builtin")
-        };
-        assert_eq!(
-            get_migration_feature_id(feature_index),
-            &feature_set::migrate_address_lookup_table_program_to_core_bpf::id()
-        );
     }
 
     #[test]

+ 0 - 1
builtins/Cargo.toml

@@ -14,7 +14,6 @@ dev-context-only-utils = []
 
 [dependencies]
 agave-feature-set = { workspace = true }
-solana-address-lookup-table-program = { workspace = true }
 solana-bpf-loader-program = { workspace = true }
 solana-compute-budget-program = { workspace = true }
 solana-loader-v4-program = { workspace = true }

+ 3 - 21
builtins/src/lib.rs

@@ -105,19 +105,6 @@ pub static BUILTINS: &[BuiltinPrototype] = &[
         program_id: solana_sdk_ids::compute_budget::id(),
         entrypoint: solana_compute_budget_program::Entrypoint::vm,
     }),
-    BuiltinPrototype {
-        core_bpf_migration_config: Some(CoreBpfMigrationConfig {
-            source_buffer_address: buffer_accounts::address_lookup_table_program::id(),
-            upgrade_authority_address: None,
-            feature_id: agave_feature_set::migrate_address_lookup_table_program_to_core_bpf::id(),
-            migration_target: CoreBpfMigrationTargetType::Builtin,
-            datapoint_name: "migrate_builtin_to_core_bpf_address_lookup_table_program",
-        }),
-        name: "address_lookup_table_program",
-        enable_feature_id: None,
-        program_id: solana_sdk_ids::address_lookup_table::id(),
-        entrypoint: solana_address_lookup_table_program::processor::Entrypoint::vm,
-    },
     testable_prototype!(BuiltinPrototype {
         core_bpf_migration_config: None,
         name: zk_token_proof_program,
@@ -145,9 +132,6 @@ pub static STATELESS_BUILTINS: &[StatelessBuiltinPrototype] = &[];
 
 /// Live source buffer accounts for builtin migrations.
 mod buffer_accounts {
-    pub mod address_lookup_table_program {
-        solana_pubkey::declare_id!("AhXWrD9BBUYcKjtpA3zuiiZG4ysbo6C6wjHo1QhERk6A");
-    }
     pub mod stake_program {
         solana_pubkey::declare_id!("8t3vv6v99tQA6Gp7fVdsBH66hQMaswH5qsJVqJqo8xvG");
     }
@@ -368,18 +352,16 @@ mod tests {
             &super::BUILTINS[6].core_bpf_migration_config,
             &Some(super::test_only::compute_budget_program::CONFIG)
         );
-        // Address Lookup Table has a live migration config, so it has no
-        // test-only configs to test here.
         assert_eq!(
-            &super::BUILTINS[8].core_bpf_migration_config,
+            &super::BUILTINS[7].core_bpf_migration_config,
             &Some(super::test_only::zk_token_proof_program::CONFIG)
         );
         assert_eq!(
-            &super::BUILTINS[9].core_bpf_migration_config,
+            &super::BUILTINS[8].core_bpf_migration_config,
             &Some(super::test_only::loader_v4::CONFIG)
         );
         assert_eq!(
-            &super::BUILTINS[10].core_bpf_migration_config,
+            &super::BUILTINS[9].core_bpf_migration_config,
             &Some(super::test_only::zk_elgamal_proof_program::CONFIG)
         );
     }

+ 9 - 20
compute-budget-instruction/src/builtin_programs_filter.rs

@@ -110,26 +110,15 @@ mod test {
         );
 
         // migrating builtins
-        for (migrating_builtin_pubkey, migration_feature_id) in [
-            (
-                solana_sdk_ids::stake::id(),
-                feature_set::migrate_stake_program_to_core_bpf::id(),
-            ),
-            (
-                solana_sdk_ids::address_lookup_table::id(),
-                feature_set::migrate_address_lookup_table_program_to_core_bpf::id(),
-            ),
-        ] {
-            index += 1;
-            assert_eq!(
-                test_store.get_program_kind(index, &migrating_builtin_pubkey),
-                ProgramKind::MigratingBuiltin {
-                    core_bpf_migration_feature_index: get_migration_feature_position(
-                        &migration_feature_id
-                    ),
-                }
-            );
-        }
+        index += 1;
+        assert_eq!(
+            test_store.get_program_kind(index, &solana_sdk_ids::stake::id()),
+            ProgramKind::MigratingBuiltin {
+                core_bpf_migration_feature_index: get_migration_feature_position(
+                    &feature_set::migrate_stake_program_to_core_bpf::id()
+                ),
+            }
+        );
     }
 
     #[test]

+ 7 - 10
program-test/src/programs.rs

@@ -1,12 +1,9 @@
-use {
-    agave_feature_set as feature_set,
-    solana_sdk::{
-        account::{Account, AccountSharedData},
-        bpf_loader,
-        bpf_loader_upgradeable::{self, get_program_data_address, UpgradeableLoaderState},
-        pubkey::Pubkey,
-        rent::Rent,
-    },
+use solana_sdk::{
+    account::{Account, AccountSharedData},
+    bpf_loader,
+    bpf_loader_upgradeable::{self, get_program_data_address, UpgradeableLoaderState},
+    pubkey::Pubkey,
+    rent::Rent,
 };
 
 mod spl_memo_1_0 {
@@ -51,7 +48,7 @@ static SPL_PROGRAMS: &[(Pubkey, Pubkey, &[u8])] = &[
 static CORE_BPF_PROGRAMS: &[(Pubkey, Option<Pubkey>, &[u8])] = &[
     (
         solana_sdk_ids::address_lookup_table::ID,
-        Some(feature_set::migrate_address_lookup_table_program_to_core_bpf::ID),
+        None,
         include_bytes!("programs/core_bpf_address_lookup_table-3.0.0.so"),
     ),
     (

+ 0 - 34
programs/address-lookup-table-tests/Cargo.toml

@@ -1,34 +0,0 @@
-# This package only exists to avoid circular dependencies during cargo publish:
-# solana-runtime -> solana-address-program -> solana-program-test -> solana-runtime
-
-[package]
-name = "solana-address-lookup-table-program-tests"
-publish = false
-version = { workspace = true }
-authors = { workspace = true }
-repository = { workspace = true }
-homepage = { workspace = true }
-license = { workspace = true }
-edition = { workspace = true }
-
-[dev-dependencies]
-agave-feature-set = { workspace = true }
-assert_matches = { workspace = true }
-bincode = { workspace = true }
-criterion = { workspace = true }
-solana-account = { workspace = true }
-solana-address-lookup-table-program = { workspace = true }
-solana-instruction = { workspace = true }
-solana-program-runtime = { workspace = true }
-solana-program-test = { workspace = true }
-solana-pubkey = { workspace = true }
-solana-sdk = { workspace = true }
-solana-sdk-ids = { workspace = true }
-solana-system-program = { workspace = true }
-
-[[bench]]
-name = "address_lookup_table"
-harness = false
-
-[package.metadata.docs.rs]
-targets = ["x86_64-unknown-linux-gnu"]

+ 0 - 267
programs/address-lookup-table-tests/benches/address_lookup_table.rs

@@ -1,267 +0,0 @@
-use {
-    criterion::{black_box, criterion_group, criterion_main, Criterion},
-    solana_account::{create_account_shared_data_for_test, AccountSharedData},
-    solana_instruction::AccountMeta,
-    solana_program_runtime::{
-        invoke_context::mock_process_instruction, loaded_programs::ProgramCacheEntry,
-    },
-    solana_pubkey::Pubkey,
-    solana_sdk::{
-        address_lookup_table::instruction::{derive_lookup_table_address, ProgramInstruction},
-        clock::{Clock, Slot},
-        hash::Hash,
-        rent::Rent,
-        sysvar::{clock, slot_hashes::SlotHashes},
-    },
-    solana_sdk_ids::{
-        address_lookup_table, system_program,
-        sysvar::{rent, slot_hashes},
-    },
-    std::sync::Arc,
-};
-
-const ACCOUNT_BALANCE: u64 = u64::MAX / 4;
-
-#[derive(Default)]
-struct TestSetup {
-    authority_address: Pubkey,
-    payer_address: Pubkey,
-    lookup_table_address: Pubkey,
-    bump_seed: u8,
-    recent_slot: Slot,
-    transaction_accounts: Vec<(Pubkey, AccountSharedData)>,
-    instruction_accounts: Vec<AccountMeta>,
-    instruction_data: Vec<u8>,
-}
-
-impl TestSetup {
-    fn new() -> Self {
-        let authority_address = Pubkey::new_unique();
-        let payer_address = Pubkey::new_unique();
-        let recent_slot = 1;
-        let mut slot_hashes = SlotHashes::default();
-        slot_hashes.add(recent_slot, Hash::new_unique());
-
-        let (lookup_table_address, bump_seed) =
-            derive_lookup_table_address(&authority_address, recent_slot);
-
-        let transaction_accounts: Vec<(Pubkey, AccountSharedData)> = vec![
-            // lookup table account is initially owned by system program, it later
-            // allocate() by native_invoke System program during create_lookup_table
-            (
-                lookup_table_address,
-                AccountSharedData::new(0, 0, &system_program::id()),
-            ),
-            (
-                authority_address,
-                AccountSharedData::new(ACCOUNT_BALANCE, 0, &Pubkey::new_unique()),
-            ),
-            (
-                payer_address,
-                AccountSharedData::new(ACCOUNT_BALANCE, 0, &system_program::id()),
-            ),
-            (
-                system_program::id(),
-                AccountSharedData::new(0, 0, &system_program::id()),
-            ),
-            (
-                slot_hashes::id(),
-                create_account_shared_data_for_test(&slot_hashes),
-            ),
-            (
-                rent::id(),
-                create_account_shared_data_for_test(&Rent::default()),
-            ),
-            (
-                clock::id(),
-                create_account_shared_data_for_test(&Clock::default()),
-            ),
-        ];
-
-        Self {
-            authority_address,
-            payer_address,
-            lookup_table_address,
-            bump_seed,
-            recent_slot,
-            transaction_accounts,
-            ..TestSetup::default()
-        }
-    }
-
-    fn prep_create_lookup_table(&mut self) {
-        self.instruction_accounts = vec![
-            AccountMeta::new(self.lookup_table_address, false),
-            AccountMeta::new_readonly(self.authority_address, false),
-            AccountMeta::new(self.payer_address, true),
-            AccountMeta::new_readonly(system_program::id(), false),
-        ];
-
-        self.instruction_data = bincode::serialize(&ProgramInstruction::CreateLookupTable {
-            recent_slot: self.recent_slot,
-            bump_seed: self.bump_seed,
-        })
-        .unwrap();
-    }
-
-    fn exec_create_lookup_table(&mut self) {
-        self.prep_create_lookup_table();
-        let accounts = self.run();
-
-        let lookup_table_account = accounts[0].clone();
-        self.transaction_accounts[0] = (self.lookup_table_address, lookup_table_account);
-    }
-
-    fn prep_extend_lookup_table(&mut self) {
-        self.instruction_accounts = vec![
-            AccountMeta::new(self.lookup_table_address, false),
-            AccountMeta::new_readonly(self.authority_address, true),
-            AccountMeta::new(self.payer_address, true),
-            AccountMeta::new_readonly(system_program::id(), false),
-        ];
-
-        // extend reasonable number of addresses at a time, so bench loop won't
-        // add more than LOOKUP_TABLE_MAX_ADDRESSES addresses to lookup_table
-        let new_addresses: Vec<_> = (0..16).map(|_| Pubkey::new_unique()).collect();
-        self.instruction_data =
-            bincode::serialize(&ProgramInstruction::ExtendLookupTable { new_addresses }).unwrap();
-    }
-
-    fn exec_extend_lookup_table(&mut self) {
-        self.prep_extend_lookup_table();
-        let accounts = self.run();
-
-        let lookup_table_account = accounts[0].clone();
-        self.transaction_accounts[0] = (self.lookup_table_address, lookup_table_account);
-    }
-
-    fn prep_freeze_lookup_table(&mut self) {
-        self.instruction_accounts = vec![
-            AccountMeta::new(self.lookup_table_address, false),
-            AccountMeta::new(self.authority_address, true),
-        ];
-
-        self.instruction_data = bincode::serialize(&ProgramInstruction::FreezeLookupTable).unwrap();
-    }
-
-    fn prep_deactivate_lookup_table(&mut self) {
-        self.instruction_accounts = vec![
-            AccountMeta::new(self.lookup_table_address, false),
-            AccountMeta::new(self.authority_address, true),
-        ];
-
-        self.instruction_data =
-            bincode::serialize(&ProgramInstruction::DeactivateLookupTable).unwrap();
-    }
-
-    fn exec_deactivate_lookup_table(&mut self) {
-        self.prep_deactivate_lookup_table();
-        let accounts = self.run();
-
-        let lookup_table_account = accounts[0].clone();
-        self.transaction_accounts[0] = (self.lookup_table_address, lookup_table_account);
-        // advance clock after deactivating
-        self.transaction_accounts[6] = (
-            clock::id(),
-            create_account_shared_data_for_test(&Clock {
-                slot: self.recent_slot.wrapping_add(1),
-                ..Clock::default()
-            }),
-        );
-    }
-
-    fn prep_close_lookup_table(&mut self) {
-        self.instruction_accounts = vec![
-            AccountMeta::new(self.lookup_table_address, false),
-            AccountMeta::new(self.authority_address, true),
-            AccountMeta::new(self.payer_address, false),
-        ];
-
-        self.instruction_data = bincode::serialize(&ProgramInstruction::CloseLookupTable).unwrap();
-    }
-
-    fn run(&self) -> Vec<AccountSharedData> {
-        mock_process_instruction(
-            &address_lookup_table::id(),
-            Vec::new(),
-            &self.instruction_data,
-            self.transaction_accounts.clone(),
-            self.instruction_accounts.clone(),
-            Ok(()), //expected_result,
-            solana_address_lookup_table_program::processor::Entrypoint::vm,
-            |invoke_context| {
-                // add System to program_cache_for_tx_batch, so it can be native_invoke()
-                invoke_context.program_cache_for_tx_batch.replenish(
-                    system_program::id(),
-                    Arc::new(ProgramCacheEntry::new_builtin(
-                        0,
-                        0,
-                        solana_system_program::system_processor::Entrypoint::vm,
-                    )),
-                );
-            },
-            |_invoke_context| {},
-        )
-    }
-}
-
-fn bench_create_lookup_table(c: &mut Criterion) {
-    let mut test_setup = TestSetup::new();
-    test_setup.prep_create_lookup_table();
-
-    c.bench_function("create_lookup_table", |bencher| {
-        bencher.iter(|| black_box(test_setup.run()))
-    });
-}
-
-fn bench_extend_lookup_table(c: &mut Criterion) {
-    let mut test_setup = TestSetup::new();
-    test_setup.exec_create_lookup_table();
-    test_setup.prep_extend_lookup_table();
-
-    c.bench_function("extend_lookup_table", |bencher| {
-        bencher.iter(|| black_box(test_setup.run()))
-    });
-}
-
-fn bench_freeze_lookup_table(c: &mut Criterion) {
-    let mut test_setup = TestSetup::new();
-    test_setup.exec_create_lookup_table();
-    test_setup.exec_extend_lookup_table();
-    test_setup.prep_freeze_lookup_table();
-
-    c.bench_function("freeze_lookup_table", |bencher| {
-        bencher.iter(|| black_box(test_setup.run()))
-    });
-}
-
-fn bench_deactivate_lookup_table(c: &mut Criterion) {
-    let mut test_setup = TestSetup::new();
-    test_setup.exec_create_lookup_table();
-    test_setup.prep_deactivate_lookup_table();
-
-    c.bench_function("deactivate_lookup_table", |bencher| {
-        bencher.iter(|| black_box(test_setup.run()))
-    });
-}
-
-fn bench_close_lookup_table(c: &mut Criterion) {
-    let mut test_setup = TestSetup::new();
-    test_setup.exec_create_lookup_table();
-    test_setup.exec_deactivate_lookup_table();
-    test_setup.prep_close_lookup_table();
-
-    c.bench_function("close_lookup_table", |bencher| {
-        bencher.iter(|| black_box(test_setup.run()))
-    });
-}
-
-criterion_group!(
-    benches,
-    bench_create_lookup_table,
-    bench_extend_lookup_table,
-    bench_freeze_lookup_table,
-    bench_deactivate_lookup_table,
-    bench_close_lookup_table,
-);
-criterion_main!(benches);

+ 0 - 216
programs/address-lookup-table-tests/tests/close_lookup_table_ix.rs

@@ -1,216 +0,0 @@
-use {
-    assert_matches::assert_matches,
-    common::{
-        add_lookup_table_account, assert_ix_error, new_address_lookup_table,
-        overwrite_slot_hashes_with_slots, setup_test_context,
-    },
-    solana_program_test::*,
-    solana_sdk::{
-        address_lookup_table::instruction::close_lookup_table,
-        clock::Clock,
-        instruction::InstructionError,
-        pubkey::Pubkey,
-        signature::{Keypair, Signer},
-        transaction::Transaction,
-    },
-};
-
-mod common;
-
-#[tokio::test]
-async fn test_close_lookup_table() {
-    let mut context = setup_test_context().await;
-    overwrite_slot_hashes_with_slots(&context, &[]);
-
-    let lookup_table_address = Pubkey::new_unique();
-    let authority_keypair = Keypair::new();
-    let initialized_table = {
-        let mut table = new_address_lookup_table(Some(authority_keypair.pubkey()), 0);
-        table.meta.deactivation_slot = 0;
-        table
-    };
-    add_lookup_table_account(&mut context, lookup_table_address, initialized_table).await;
-
-    let client = &mut context.banks_client;
-    let payer = &context.payer;
-    let recent_blockhash = context.last_blockhash;
-    let transaction = Transaction::new_signed_with_payer(
-        &[close_lookup_table(
-            lookup_table_address,
-            authority_keypair.pubkey(),
-            context.payer.pubkey(),
-        )],
-        Some(&payer.pubkey()),
-        &[payer, &authority_keypair],
-        recent_blockhash,
-    );
-
-    assert_matches!(client.process_transaction(transaction).await, Ok(()));
-    assert!(client
-        .get_account(lookup_table_address)
-        .await
-        .unwrap()
-        .is_none());
-}
-
-#[tokio::test]
-async fn test_close_lookup_table_not_deactivated() {
-    let mut context = setup_test_context().await;
-
-    let authority_keypair = Keypair::new();
-    let initialized_table = new_address_lookup_table(Some(authority_keypair.pubkey()), 0);
-    let lookup_table_address = Pubkey::new_unique();
-    add_lookup_table_account(&mut context, lookup_table_address, initialized_table).await;
-
-    let ix = close_lookup_table(
-        lookup_table_address,
-        authority_keypair.pubkey(),
-        context.payer.pubkey(),
-    );
-
-    // The ix should fail because the table hasn't been deactivated yet
-    assert_ix_error(
-        &mut context,
-        ix,
-        Some(&authority_keypair),
-        InstructionError::InvalidArgument,
-    )
-    .await;
-}
-
-#[tokio::test]
-async fn test_close_lookup_table_deactivated_in_current_slot() {
-    let mut context = setup_test_context().await;
-
-    let clock = context.banks_client.get_sysvar::<Clock>().await.unwrap();
-    let authority_keypair = Keypair::new();
-    let initialized_table = {
-        let mut table = new_address_lookup_table(Some(authority_keypair.pubkey()), 0);
-        table.meta.deactivation_slot = clock.slot;
-        table
-    };
-    let lookup_table_address = Pubkey::new_unique();
-    add_lookup_table_account(&mut context, lookup_table_address, initialized_table).await;
-
-    let ix = close_lookup_table(
-        lookup_table_address,
-        authority_keypair.pubkey(),
-        context.payer.pubkey(),
-    );
-
-    // Context sets up the slot hashes sysvar to have an entry
-    // for slot 0 which is when the table was deactivated.
-    // Because that slot is present, the ix should fail.
-    assert_ix_error(
-        &mut context,
-        ix,
-        Some(&authority_keypair),
-        InstructionError::InvalidArgument,
-    )
-    .await;
-}
-
-#[tokio::test]
-async fn test_close_lookup_table_recently_deactivated() {
-    let mut context = setup_test_context().await;
-
-    let authority_keypair = Keypair::new();
-    let initialized_table = {
-        let mut table = new_address_lookup_table(Some(authority_keypair.pubkey()), 0);
-        table.meta.deactivation_slot = 0;
-        table
-    };
-    let lookup_table_address = Pubkey::new_unique();
-    add_lookup_table_account(&mut context, lookup_table_address, initialized_table).await;
-
-    let ix = close_lookup_table(
-        lookup_table_address,
-        authority_keypair.pubkey(),
-        context.payer.pubkey(),
-    );
-
-    // Context sets up the slot hashes sysvar to have an entry
-    // for slot 0 which is when the table was deactivated.
-    // Because that slot is present, the ix should fail.
-    assert_ix_error(
-        &mut context,
-        ix,
-        Some(&authority_keypair),
-        InstructionError::InvalidArgument,
-    )
-    .await;
-}
-
-#[tokio::test]
-async fn test_close_immutable_lookup_table() {
-    let mut context = setup_test_context().await;
-
-    let initialized_table = new_address_lookup_table(None, 10);
-    let lookup_table_address = Pubkey::new_unique();
-    add_lookup_table_account(&mut context, lookup_table_address, initialized_table).await;
-
-    let authority = Keypair::new();
-    let ix = close_lookup_table(
-        lookup_table_address,
-        authority.pubkey(),
-        Pubkey::new_unique(),
-    );
-
-    assert_ix_error(
-        &mut context,
-        ix,
-        Some(&authority),
-        InstructionError::Immutable,
-    )
-    .await;
-}
-
-#[tokio::test]
-async fn test_close_lookup_table_with_wrong_authority() {
-    let mut context = setup_test_context().await;
-
-    let authority = Keypair::new();
-    let wrong_authority = Keypair::new();
-    let initialized_table = new_address_lookup_table(Some(authority.pubkey()), 10);
-    let lookup_table_address = Pubkey::new_unique();
-    add_lookup_table_account(&mut context, lookup_table_address, initialized_table).await;
-
-    let ix = close_lookup_table(
-        lookup_table_address,
-        wrong_authority.pubkey(),
-        Pubkey::new_unique(),
-    );
-
-    assert_ix_error(
-        &mut context,
-        ix,
-        Some(&wrong_authority),
-        InstructionError::IncorrectAuthority,
-    )
-    .await;
-}
-
-#[tokio::test]
-async fn test_close_lookup_table_without_signing() {
-    let mut context = setup_test_context().await;
-
-    let authority = Keypair::new();
-    let initialized_table = new_address_lookup_table(Some(authority.pubkey()), 10);
-    let lookup_table_address = Pubkey::new_unique();
-    add_lookup_table_account(&mut context, lookup_table_address, initialized_table).await;
-
-    let mut ix = close_lookup_table(
-        lookup_table_address,
-        authority.pubkey(),
-        Pubkey::new_unique(),
-    );
-    ix.accounts[1].is_signer = false;
-
-    assert_ix_error(
-        &mut context,
-        ix,
-        None,
-        InstructionError::MissingRequiredSignature,
-    )
-    .await;
-}

+ 0 - 99
programs/address-lookup-table-tests/tests/common.rs

@@ -1,99 +0,0 @@
-#![allow(dead_code)]
-use {
-    solana_program_test::*,
-    solana_sdk::{
-        account::AccountSharedData,
-        address_lookup_table::{
-            program::id,
-            state::{AddressLookupTable, LookupTableMeta},
-        },
-        clock::Slot,
-        hash::Hash,
-        instruction::{Instruction, InstructionError},
-        pubkey::Pubkey,
-        signature::{Keypair, Signer},
-        slot_hashes::SlotHashes,
-        transaction::{Transaction, TransactionError},
-    },
-    std::borrow::Cow,
-};
-
-pub async fn setup_test_context() -> ProgramTestContext {
-    let program_test = ProgramTest::new(
-        "",
-        id(),
-        Some(solana_address_lookup_table_program::processor::Entrypoint::vm),
-    );
-    program_test.start_with_context().await
-}
-
-pub async fn assert_ix_error(
-    context: &mut ProgramTestContext,
-    ix: Instruction,
-    authority_keypair: Option<&Keypair>,
-    expected_err: InstructionError,
-) {
-    let client = &mut context.banks_client;
-    let payer = &context.payer;
-    let recent_blockhash = context.last_blockhash;
-
-    let mut signers = vec![payer];
-    if let Some(authority) = authority_keypair {
-        signers.push(authority);
-    }
-
-    let transaction = Transaction::new_signed_with_payer(
-        &[ix],
-        Some(&payer.pubkey()),
-        &signers,
-        recent_blockhash,
-    );
-
-    assert_eq!(
-        client
-            .process_transaction(transaction)
-            .await
-            .unwrap_err()
-            .unwrap(),
-        TransactionError::InstructionError(0, expected_err),
-    );
-}
-
-pub fn new_address_lookup_table(
-    authority: Option<Pubkey>,
-    num_addresses: usize,
-) -> AddressLookupTable<'static> {
-    let mut addresses = Vec::with_capacity(num_addresses);
-    addresses.resize_with(num_addresses, Pubkey::new_unique);
-    AddressLookupTable {
-        meta: LookupTableMeta {
-            authority,
-            ..LookupTableMeta::default()
-        },
-        addresses: Cow::Owned(addresses),
-    }
-}
-
-pub async fn add_lookup_table_account(
-    context: &mut ProgramTestContext,
-    account_address: Pubkey,
-    address_lookup_table: AddressLookupTable<'static>,
-) -> AccountSharedData {
-    let data = address_lookup_table.serialize_for_tests().unwrap();
-    let rent = context.banks_client.get_rent().await.unwrap();
-    let rent_exempt_balance = rent.minimum_balance(data.len());
-
-    let mut account = AccountSharedData::new(rent_exempt_balance, data.len(), &id());
-    account.set_data_from_slice(&data);
-    context.set_account(&account_address, &account);
-
-    account
-}
-
-pub fn overwrite_slot_hashes_with_slots(context: &ProgramTestContext, slots: &[Slot]) {
-    let mut slot_hashes = SlotHashes::default();
-    for slot in slots {
-        slot_hashes.add(*slot, Hash::new_unique());
-    }
-    context.set_sysvar(&slot_hashes);
-}

+ 0 - 132
programs/address-lookup-table-tests/tests/create_lookup_table_ix.rs

@@ -1,132 +0,0 @@
-use {
-    assert_matches::assert_matches,
-    common::{assert_ix_error, overwrite_slot_hashes_with_slots, setup_test_context},
-    solana_program_test::*,
-    solana_sdk::{
-        address_lookup_table::{
-            instruction::create_lookup_table,
-            program::id,
-            state::{AddressLookupTable, LOOKUP_TABLE_META_SIZE},
-        },
-        clock::Slot,
-        instruction::InstructionError,
-        pubkey::Pubkey,
-        rent::Rent,
-        signature::Signer,
-        transaction::Transaction,
-    },
-};
-
-mod common;
-
-#[tokio::test]
-async fn test_create_lookup_table_idempotent() {
-    let mut context = setup_test_context().await;
-
-    let test_recent_slot = 123;
-    overwrite_slot_hashes_with_slots(&context, &[test_recent_slot]);
-
-    let client = &mut context.banks_client;
-    let payer = &context.payer;
-    let recent_blockhash = context.last_blockhash;
-    let authority_address = Pubkey::new_unique();
-    let (create_lookup_table_ix, lookup_table_address) =
-        create_lookup_table(authority_address, payer.pubkey(), test_recent_slot);
-
-    // First create should succeed
-    {
-        let transaction = Transaction::new_signed_with_payer(
-            &[create_lookup_table_ix.clone()],
-            Some(&payer.pubkey()),
-            &[payer],
-            recent_blockhash,
-        );
-
-        assert_matches!(client.process_transaction(transaction).await, Ok(()));
-        let lookup_table_account = client
-            .get_account(lookup_table_address)
-            .await
-            .unwrap()
-            .unwrap();
-        assert_eq!(lookup_table_account.owner, id());
-        assert_eq!(lookup_table_account.data.len(), LOOKUP_TABLE_META_SIZE);
-        assert_eq!(
-            lookup_table_account.lamports,
-            Rent::default().minimum_balance(LOOKUP_TABLE_META_SIZE)
-        );
-        let lookup_table = AddressLookupTable::deserialize(&lookup_table_account.data).unwrap();
-        assert_eq!(lookup_table.meta.deactivation_slot, Slot::MAX);
-        assert_eq!(lookup_table.meta.authority, Some(authority_address));
-        assert_eq!(lookup_table.meta.last_extended_slot, 0);
-        assert_eq!(lookup_table.meta.last_extended_slot_start_index, 0);
-        assert_eq!(lookup_table.addresses.len(), 0);
-    }
-
-    // Second create should succeed too
-    {
-        let recent_blockhash = client
-            .get_new_latest_blockhash(&recent_blockhash)
-            .await
-            .unwrap();
-        let transaction = Transaction::new_signed_with_payer(
-            &[create_lookup_table_ix],
-            Some(&payer.pubkey()),
-            &[payer],
-            recent_blockhash,
-        );
-
-        assert_matches!(client.process_transaction(transaction).await, Ok(()));
-    }
-}
-
-#[tokio::test]
-async fn test_create_lookup_table_use_payer_as_authority() {
-    let mut context = setup_test_context().await;
-
-    let test_recent_slot = 123;
-    overwrite_slot_hashes_with_slots(&context, &[test_recent_slot]);
-
-    let client = &mut context.banks_client;
-    let payer = &context.payer;
-    let recent_blockhash = context.last_blockhash;
-    let authority_address = payer.pubkey();
-    let transaction = Transaction::new_signed_with_payer(
-        &[create_lookup_table(authority_address, payer.pubkey(), test_recent_slot).0],
-        Some(&payer.pubkey()),
-        &[payer],
-        recent_blockhash,
-    );
-
-    assert_matches!(client.process_transaction(transaction).await, Ok(()));
-}
-
-#[tokio::test]
-async fn test_create_lookup_table_not_recent_slot() {
-    let mut context = setup_test_context().await;
-    let payer = &context.payer;
-    let authority_address = Pubkey::new_unique();
-
-    let ix = create_lookup_table(authority_address, payer.pubkey(), Slot::MAX).0;
-
-    assert_ix_error(
-        &mut context,
-        ix,
-        None,
-        InstructionError::InvalidInstructionData,
-    )
-    .await;
-}
-
-#[tokio::test]
-async fn test_create_lookup_table_pda_mismatch() {
-    let mut context = setup_test_context().await;
-    let test_recent_slot = 123;
-    overwrite_slot_hashes_with_slots(&context, &[test_recent_slot]);
-    let payer = &context.payer;
-    let authority_address = Pubkey::new_unique();
-
-    let mut ix = create_lookup_table(authority_address, payer.pubkey(), test_recent_slot).0;
-    ix.accounts[0].pubkey = Pubkey::new_unique();
-
-    assert_ix_error(&mut context, ix, None, InstructionError::InvalidArgument).await;
-}

+ 0 - 143
programs/address-lookup-table-tests/tests/deactivate_lookup_table_ix.rs

@@ -1,143 +0,0 @@
-use {
-    assert_matches::assert_matches,
-    common::{
-        add_lookup_table_account, assert_ix_error, new_address_lookup_table, setup_test_context,
-    },
-    solana_program_test::*,
-    solana_sdk::{
-        address_lookup_table::{instruction::deactivate_lookup_table, state::AddressLookupTable},
-        instruction::InstructionError,
-        pubkey::Pubkey,
-        signature::{Keypair, Signer},
-        transaction::Transaction,
-    },
-};
-
-mod common;
-
-#[tokio::test]
-async fn test_deactivate_lookup_table() {
-    let mut context = setup_test_context().await;
-
-    let authority = Keypair::new();
-    let mut initialized_table = new_address_lookup_table(Some(authority.pubkey()), 10);
-    let lookup_table_address = Pubkey::new_unique();
-    add_lookup_table_account(
-        &mut context,
-        lookup_table_address,
-        initialized_table.clone(),
-    )
-    .await;
-
-    let client = &mut context.banks_client;
-    let payer = &context.payer;
-    let recent_blockhash = context.last_blockhash;
-    let transaction = Transaction::new_signed_with_payer(
-        &[deactivate_lookup_table(
-            lookup_table_address,
-            authority.pubkey(),
-        )],
-        Some(&payer.pubkey()),
-        &[payer, &authority],
-        recent_blockhash,
-    );
-
-    assert_matches!(client.process_transaction(transaction).await, Ok(()));
-    let table_account = client
-        .get_account(lookup_table_address)
-        .await
-        .unwrap()
-        .unwrap();
-    let lookup_table = AddressLookupTable::deserialize(&table_account.data).unwrap();
-    assert_eq!(lookup_table.meta.deactivation_slot, 1);
-
-    // Check that only the deactivation slot changed
-    initialized_table.meta.deactivation_slot = 1;
-    assert_eq!(initialized_table, lookup_table);
-}
-
-#[tokio::test]
-async fn test_deactivate_immutable_lookup_table() {
-    let mut context = setup_test_context().await;
-
-    let initialized_table = new_address_lookup_table(None, 10);
-    let lookup_table_address = Pubkey::new_unique();
-    add_lookup_table_account(&mut context, lookup_table_address, initialized_table).await;
-
-    let authority = Keypair::new();
-    let ix = deactivate_lookup_table(lookup_table_address, authority.pubkey());
-
-    assert_ix_error(
-        &mut context,
-        ix,
-        Some(&authority),
-        InstructionError::Immutable,
-    )
-    .await;
-}
-
-#[tokio::test]
-async fn test_deactivate_already_deactivated() {
-    let mut context = setup_test_context().await;
-
-    let authority = Keypair::new();
-    let initialized_table = {
-        let mut table = new_address_lookup_table(Some(authority.pubkey()), 0);
-        table.meta.deactivation_slot = 0;
-        table
-    };
-    let lookup_table_address = Pubkey::new_unique();
-    add_lookup_table_account(&mut context, lookup_table_address, initialized_table).await;
-
-    let ix = deactivate_lookup_table(lookup_table_address, authority.pubkey());
-
-    assert_ix_error(
-        &mut context,
-        ix,
-        Some(&authority),
-        InstructionError::InvalidArgument,
-    )
-    .await;
-}
-
-#[tokio::test]
-async fn test_deactivate_lookup_table_with_wrong_authority() {
-    let mut context = setup_test_context().await;
-
-    let authority = Keypair::new();
-    let wrong_authority = Keypair::new();
-    let initialized_table = new_address_lookup_table(Some(authority.pubkey()), 10);
-    let lookup_table_address = Pubkey::new_unique();
-    add_lookup_table_account(&mut context, lookup_table_address, initialized_table).await;
-
-    let ix = deactivate_lookup_table(lookup_table_address, wrong_authority.pubkey());
-
-    assert_ix_error(
-        &mut context,
-        ix,
-        Some(&wrong_authority),
-        InstructionError::IncorrectAuthority,
-    )
-    .await;
-}
-
-#[tokio::test]
-async fn test_deactivate_lookup_table_without_signing() {
-    let mut context = setup_test_context().await;
-
-    let authority = Keypair::new();
-    let initialized_table = new_address_lookup_table(Some(authority.pubkey()), 10);
-    let lookup_table_address = Pubkey::new_unique();
-    add_lookup_table_account(&mut context, lookup_table_address, initialized_table).await;
-
-    let mut ix = deactivate_lookup_table(lookup_table_address, authority.pubkey());
-    ix.accounts[1].is_signer = false;
-
-    assert_ix_error(
-        &mut context,
-        ix,
-        None,
-        InstructionError::MissingRequiredSignature,
-    )
-    .await;
-}

+ 0 - 347
programs/address-lookup-table-tests/tests/extend_lookup_table_ix.rs

@@ -1,347 +0,0 @@
-use {
-    assert_matches::assert_matches,
-    common::{
-        add_lookup_table_account, assert_ix_error, new_address_lookup_table, setup_test_context,
-    },
-    solana_program_test::*,
-    solana_sdk::{
-        account::{ReadableAccount, WritableAccount},
-        address_lookup_table::{
-            instruction::extend_lookup_table,
-            state::{AddressLookupTable, LookupTableMeta},
-        },
-        clock::Clock,
-        instruction::{Instruction, InstructionError},
-        pubkey::{Pubkey, PUBKEY_BYTES},
-        signature::{Keypair, Signer},
-        transaction::{Transaction, TransactionError},
-    },
-    std::{borrow::Cow, result::Result},
-};
-
-mod common;
-
-struct ExpectedTableAccount {
-    lamports: u64,
-    data_len: usize,
-    state: AddressLookupTable<'static>,
-}
-
-struct TestCase<'a> {
-    lookup_table_address: Pubkey,
-    instruction: Instruction,
-    extra_signer: Option<&'a Keypair>,
-    expected_result: Result<ExpectedTableAccount, InstructionError>,
-}
-
-async fn run_test_case(context: &mut ProgramTestContext, test_case: TestCase<'_>) {
-    let client = &mut context.banks_client;
-    let payer = &context.payer;
-    let recent_blockhash = context.last_blockhash;
-
-    let mut signers = vec![payer];
-    if let Some(extra_signer) = test_case.extra_signer {
-        signers.push(extra_signer);
-    }
-
-    let transaction = Transaction::new_signed_with_payer(
-        &[test_case.instruction],
-        Some(&payer.pubkey()),
-        &signers,
-        recent_blockhash,
-    );
-
-    let process_result = client.process_transaction(transaction).await;
-
-    match test_case.expected_result {
-        Ok(expected_account) => {
-            assert_matches!(process_result, Ok(()));
-
-            let table_account = client
-                .get_account(test_case.lookup_table_address)
-                .await
-                .unwrap()
-                .unwrap();
-
-            let lookup_table = AddressLookupTable::deserialize(&table_account.data).unwrap();
-            assert_eq!(lookup_table, expected_account.state);
-            assert_eq!(table_account.lamports(), expected_account.lamports);
-            assert_eq!(table_account.data().len(), expected_account.data_len);
-        }
-        Err(expected_err) => {
-            assert_eq!(
-                process_result.unwrap_err().unwrap(),
-                TransactionError::InstructionError(0, expected_err),
-            );
-        }
-    }
-}
-
-#[tokio::test]
-async fn test_extend_lookup_table() {
-    let mut context = setup_test_context().await;
-    let authority = Keypair::new();
-    let current_bank_slot = 1;
-    let rent = context.banks_client.get_rent().await.unwrap();
-
-    for extend_same_slot in [true, false] {
-        for (num_existing_addresses, num_new_addresses, expected_result) in [
-            (0, 0, Err(InstructionError::InvalidInstructionData)),
-            (0, 1, Ok(())),
-            (0, 10, Ok(())),
-            (1, 1, Ok(())),
-            (1, 10, Ok(())),
-            (255, 1, Ok(())),
-            (255, 2, Err(InstructionError::InvalidInstructionData)),
-            (246, 10, Ok(())),
-            (256, 1, Err(InstructionError::InvalidArgument)),
-        ] {
-            let mut lookup_table =
-                new_address_lookup_table(Some(authority.pubkey()), num_existing_addresses);
-            if extend_same_slot {
-                lookup_table.meta.last_extended_slot = current_bank_slot;
-            }
-
-            let lookup_table_address = Pubkey::new_unique();
-            let lookup_table_account =
-                add_lookup_table_account(&mut context, lookup_table_address, lookup_table.clone())
-                    .await;
-
-            let mut new_addresses = Vec::with_capacity(num_new_addresses);
-            new_addresses.resize_with(num_new_addresses, Pubkey::new_unique);
-            let instruction = extend_lookup_table(
-                lookup_table_address,
-                authority.pubkey(),
-                Some(context.payer.pubkey()),
-                new_addresses.clone(),
-            );
-
-            let mut expected_addresses: Vec<Pubkey> = lookup_table.addresses.to_vec();
-            expected_addresses.extend(new_addresses);
-
-            let expected_result = expected_result.map(|_| {
-                let expected_data_len =
-                    lookup_table_account.data().len() + num_new_addresses * PUBKEY_BYTES;
-                let expected_lamports = rent.minimum_balance(expected_data_len);
-                let expected_lookup_table = AddressLookupTable {
-                    meta: LookupTableMeta {
-                        last_extended_slot: current_bank_slot,
-                        last_extended_slot_start_index: if extend_same_slot {
-                            0u8
-                        } else {
-                            num_existing_addresses as u8
-                        },
-                        deactivation_slot: lookup_table.meta.deactivation_slot,
-                        authority: lookup_table.meta.authority,
-                        _padding: 0u16,
-                    },
-                    addresses: Cow::Owned(expected_addresses),
-                };
-                ExpectedTableAccount {
-                    lamports: expected_lamports,
-                    data_len: expected_data_len,
-                    state: expected_lookup_table,
-                }
-            });
-
-            let test_case = TestCase {
-                lookup_table_address,
-                instruction,
-                extra_signer: Some(&authority),
-                expected_result,
-            };
-
-            run_test_case(&mut context, test_case).await;
-        }
-    }
-}
-
-#[tokio::test]
-async fn test_extend_lookup_table_with_wrong_authority() {
-    let mut context = setup_test_context().await;
-
-    let authority = Keypair::new();
-    let wrong_authority = Keypair::new();
-    let initialized_table = new_address_lookup_table(Some(authority.pubkey()), 0);
-    let lookup_table_address = Pubkey::new_unique();
-    add_lookup_table_account(&mut context, lookup_table_address, initialized_table).await;
-
-    let new_addresses = vec![Pubkey::new_unique()];
-    let ix = extend_lookup_table(
-        lookup_table_address,
-        wrong_authority.pubkey(),
-        Some(context.payer.pubkey()),
-        new_addresses,
-    );
-
-    assert_ix_error(
-        &mut context,
-        ix,
-        Some(&wrong_authority),
-        InstructionError::IncorrectAuthority,
-    )
-    .await;
-}
-
-#[tokio::test]
-async fn test_extend_lookup_table_without_signing() {
-    let mut context = setup_test_context().await;
-
-    let authority = Keypair::new();
-    let initialized_table = new_address_lookup_table(Some(authority.pubkey()), 10);
-    let lookup_table_address = Pubkey::new_unique();
-    add_lookup_table_account(&mut context, lookup_table_address, initialized_table).await;
-
-    let new_addresses = vec![Pubkey::new_unique()];
-    let mut ix = extend_lookup_table(
-        lookup_table_address,
-        authority.pubkey(),
-        Some(context.payer.pubkey()),
-        new_addresses,
-    );
-    ix.accounts[1].is_signer = false;
-
-    assert_ix_error(
-        &mut context,
-        ix,
-        None,
-        InstructionError::MissingRequiredSignature,
-    )
-    .await;
-}
-
-#[tokio::test]
-async fn test_extend_deactivated_lookup_table() {
-    let mut context = setup_test_context().await;
-
-    let authority = Keypair::new();
-    let initialized_table = {
-        let mut table = new_address_lookup_table(Some(authority.pubkey()), 0);
-        table.meta.deactivation_slot = 0;
-        table
-    };
-    let lookup_table_address = Pubkey::new_unique();
-    add_lookup_table_account(&mut context, lookup_table_address, initialized_table).await;
-
-    let new_addresses = vec![Pubkey::new_unique()];
-    let ix = extend_lookup_table(
-        lookup_table_address,
-        authority.pubkey(),
-        Some(context.payer.pubkey()),
-        new_addresses,
-    );
-
-    assert_ix_error(
-        &mut context,
-        ix,
-        Some(&authority),
-        InstructionError::InvalidArgument,
-    )
-    .await;
-}
-
-#[tokio::test]
-async fn test_extend_immutable_lookup_table() {
-    let mut context = setup_test_context().await;
-
-    let authority = Keypair::new();
-    let initialized_table = new_address_lookup_table(None, 1);
-    let lookup_table_address = Pubkey::new_unique();
-    add_lookup_table_account(&mut context, lookup_table_address, initialized_table).await;
-
-    let new_addresses = vec![Pubkey::new_unique()];
-    let ix = extend_lookup_table(
-        lookup_table_address,
-        authority.pubkey(),
-        Some(context.payer.pubkey()),
-        new_addresses,
-    );
-
-    assert_ix_error(
-        &mut context,
-        ix,
-        Some(&authority),
-        InstructionError::Immutable,
-    )
-    .await;
-}
-
-#[tokio::test]
-async fn test_extend_lookup_table_without_payer() {
-    let mut context = setup_test_context().await;
-
-    let authority = Keypair::new();
-    let initialized_table = new_address_lookup_table(Some(authority.pubkey()), 0);
-    let lookup_table_address = Pubkey::new_unique();
-    add_lookup_table_account(&mut context, lookup_table_address, initialized_table).await;
-
-    let new_addresses = vec![Pubkey::new_unique()];
-    let ix = extend_lookup_table(
-        lookup_table_address,
-        authority.pubkey(),
-        None,
-        new_addresses,
-    );
-
-    assert_ix_error(
-        &mut context,
-        ix,
-        Some(&authority),
-        InstructionError::NotEnoughAccountKeys,
-    )
-    .await;
-}
-
-#[tokio::test]
-async fn test_extend_prepaid_lookup_table_without_payer() {
-    let mut context = setup_test_context().await;
-
-    let authority = Keypair::new();
-    let lookup_table_address = Pubkey::new_unique();
-
-    let expected_state = {
-        // initialize lookup table
-        let empty_lookup_table = new_address_lookup_table(Some(authority.pubkey()), 0);
-        let mut lookup_table_account =
-            add_lookup_table_account(&mut context, lookup_table_address, empty_lookup_table).await;
-
-        // calculate required rent exempt balance for adding one address
-        let mut temp_lookup_table = new_address_lookup_table(Some(authority.pubkey()), 1);
-        let data = temp_lookup_table.clone().serialize_for_tests().unwrap();
-        let rent = context.banks_client.get_rent().await.unwrap();
-        let rent_exempt_balance = rent.minimum_balance(data.len());
-
-        // prepay for one address
-        lookup_table_account.set_lamports(rent_exempt_balance);
-        context.set_account(&lookup_table_address, &lookup_table_account);
-
-        // test will extend table in the current bank's slot
-        let clock = context.banks_client.get_sysvar::<Clock>().await.unwrap();
-        temp_lookup_table.meta.last_extended_slot = clock.slot;
-
-        ExpectedTableAccount {
-            lamports: rent_exempt_balance,
-            data_len: data.len(),
-            state: temp_lookup_table,
-        }
-    };
-
-    let new_addresses = expected_state.state.addresses.to_vec();
-    let instruction = extend_lookup_table(
-        lookup_table_address,
-        authority.pubkey(),
-        None,
-        new_addresses,
-    );
-
-    run_test_case(
-        &mut context,
-        TestCase {
-            lookup_table_address,
-            instruction,
-            extra_signer: Some(&authority),
-            expected_result: Ok(expected_state),
-        },
-    )
-    .await;
-}

+ 0 - 163
programs/address-lookup-table-tests/tests/freeze_lookup_table_ix.rs

@@ -1,163 +0,0 @@
-use {
-    assert_matches::assert_matches,
-    common::{
-        add_lookup_table_account, assert_ix_error, new_address_lookup_table, setup_test_context,
-    },
-    solana_program_test::*,
-    solana_sdk::{
-        address_lookup_table::{instruction::freeze_lookup_table, state::AddressLookupTable},
-        instruction::InstructionError,
-        pubkey::Pubkey,
-        signature::{Keypair, Signer},
-        transaction::Transaction,
-    },
-};
-
-mod common;
-
-#[tokio::test]
-async fn test_freeze_lookup_table() {
-    let mut context = setup_test_context().await;
-
-    let authority = Keypair::new();
-    let mut initialized_table = new_address_lookup_table(Some(authority.pubkey()), 10);
-    let lookup_table_address = Pubkey::new_unique();
-    add_lookup_table_account(
-        &mut context,
-        lookup_table_address,
-        initialized_table.clone(),
-    )
-    .await;
-
-    let client = &mut context.banks_client;
-    let payer = &context.payer;
-    let recent_blockhash = context.last_blockhash;
-    let transaction = Transaction::new_signed_with_payer(
-        &[freeze_lookup_table(
-            lookup_table_address,
-            authority.pubkey(),
-        )],
-        Some(&payer.pubkey()),
-        &[payer, &authority],
-        recent_blockhash,
-    );
-
-    assert_matches!(client.process_transaction(transaction).await, Ok(()));
-    let table_account = client
-        .get_account(lookup_table_address)
-        .await
-        .unwrap()
-        .unwrap();
-    let lookup_table = AddressLookupTable::deserialize(&table_account.data).unwrap();
-    assert_eq!(lookup_table.meta.authority, None);
-
-    // Check that only the authority changed
-    initialized_table.meta.authority = None;
-    assert_eq!(initialized_table, lookup_table);
-}
-
-#[tokio::test]
-async fn test_freeze_immutable_lookup_table() {
-    let mut context = setup_test_context().await;
-
-    let initialized_table = new_address_lookup_table(None, 10);
-    let lookup_table_address = Pubkey::new_unique();
-    add_lookup_table_account(&mut context, lookup_table_address, initialized_table).await;
-
-    let authority = Keypair::new();
-    let ix = freeze_lookup_table(lookup_table_address, authority.pubkey());
-
-    assert_ix_error(
-        &mut context,
-        ix,
-        Some(&authority),
-        InstructionError::Immutable,
-    )
-    .await;
-}
-
-#[tokio::test]
-async fn test_freeze_deactivated_lookup_table() {
-    let mut context = setup_test_context().await;
-
-    let authority = Keypair::new();
-    let initialized_table = {
-        let mut table = new_address_lookup_table(Some(authority.pubkey()), 10);
-        table.meta.deactivation_slot = 0;
-        table
-    };
-    let lookup_table_address = Pubkey::new_unique();
-    add_lookup_table_account(&mut context, lookup_table_address, initialized_table).await;
-
-    let ix = freeze_lookup_table(lookup_table_address, authority.pubkey());
-
-    assert_ix_error(
-        &mut context,
-        ix,
-        Some(&authority),
-        InstructionError::InvalidArgument,
-    )
-    .await;
-}
-
-#[tokio::test]
-async fn test_freeze_lookup_table_with_wrong_authority() {
-    let mut context = setup_test_context().await;
-
-    let authority = Keypair::new();
-    let wrong_authority = Keypair::new();
-    let initialized_table = new_address_lookup_table(Some(authority.pubkey()), 10);
-    let lookup_table_address = Pubkey::new_unique();
-    add_lookup_table_account(&mut context, lookup_table_address, initialized_table).await;
-
-    let ix = freeze_lookup_table(lookup_table_address, wrong_authority.pubkey());
-
-    assert_ix_error(
-        &mut context,
-        ix,
-        Some(&wrong_authority),
-        InstructionError::IncorrectAuthority,
-    )
-    .await;
-}
-
-#[tokio::test]
-async fn test_freeze_lookup_table_without_signing() {
-    let mut context = setup_test_context().await;
-
-    let authority = Keypair::new();
-    let initialized_table = new_address_lookup_table(Some(authority.pubkey()), 10);
-    let lookup_table_address = Pubkey::new_unique();
-    add_lookup_table_account(&mut context, lookup_table_address, initialized_table).await;
-
-    let mut ix = freeze_lookup_table(lookup_table_address, authority.pubkey());
-    ix.accounts[1].is_signer = false;
-
-    assert_ix_error(
-        &mut context,
-        ix,
-        None,
-        InstructionError::MissingRequiredSignature,
-    )
-    .await;
-}
-
-#[tokio::test]
-async fn test_freeze_empty_lookup_table() {
-    let mut context = setup_test_context().await;
-
-    let authority = Keypair::new();
-    let initialized_table = new_address_lookup_table(Some(authority.pubkey()), 0);
-    let lookup_table_address = Pubkey::new_unique();
-    add_lookup_table_account(&mut context, lookup_table_address, initialized_table).await;
-
-    let ix = freeze_lookup_table(lookup_table_address, authority.pubkey());
-
-    assert_ix_error(
-        &mut context,
-        ix,
-        Some(&authority),
-        InstructionError::InvalidInstructionData,
-    )
-    .await;
-}

+ 0 - 44
programs/address-lookup-table/Cargo.toml

@@ -1,44 +0,0 @@
-[package]
-name = "solana-address-lookup-table-program"
-description = "Solana address lookup table program"
-documentation = "https://docs.rs/solana-address-loookup-table-program"
-version = { workspace = true }
-authors = { workspace = true }
-repository = { workspace = true }
-homepage = { workspace = true }
-license = { workspace = true }
-edition = { workspace = true }
-
-[dependencies]
-agave-feature-set = { workspace = true }
-bincode = { workspace = true }
-bytemuck = { workspace = true }
-log = { workspace = true }
-num-derive = { workspace = true }
-num-traits = { workspace = true }
-solana-address-lookup-table-interface = { workspace = true, features = [
-    "bincode",
-    "bytemuck",
-] }
-thiserror = { workspace = true }
-
-[target.'cfg(not(target_os = "solana"))'.dependencies]
-solana-bincode = { workspace = true }
-solana-clock = { workspace = true }
-solana-instruction = { workspace = true }
-solana-log-collector = { workspace = true }
-solana-packet = { workspace = true }
-solana-program-runtime = { workspace = true }
-solana-pubkey = { workspace = true }
-solana-system-interface = { workspace = true, features = ["bincode"] }
-solana-transaction-context = { workspace = true, features = ["bincode"] }
-
-[lib]
-crate-type = ["lib"]
-name = "solana_address_lookup_table_program"
-
-[package.metadata.docs.rs]
-targets = ["x86_64-unknown-linux-gnu"]
-
-[lints]
-workspace = true

+ 0 - 5
programs/address-lookup-table/src/lib.rs

@@ -1,5 +0,0 @@
-#![allow(incomplete_features)]
-#![cfg_attr(feature = "frozen-abi", feature(specialization))]
-
-#[cfg(not(target_os = "solana"))]
-pub mod processor;

+ 0 - 447
programs/address-lookup-table/src/processor.rs

@@ -1,447 +0,0 @@
-use {
-    solana_address_lookup_table_interface::{
-        instruction::ProgramInstruction,
-        program::{check_id, id},
-        state::{
-            AddressLookupTable, LookupTableMeta, LookupTableStatus, ProgramState,
-            LOOKUP_TABLE_MAX_ADDRESSES, LOOKUP_TABLE_META_SIZE,
-        },
-    },
-    solana_bincode::limited_deserialize,
-    solana_clock::Slot,
-    solana_instruction::error::InstructionError,
-    solana_log_collector::ic_msg,
-    solana_program_runtime::{declare_process_instruction, invoke_context::InvokeContext},
-    solana_pubkey::{Pubkey, PUBKEY_BYTES},
-    solana_system_interface::instruction as system_instruction,
-    std::convert::TryFrom,
-};
-
-pub const DEFAULT_COMPUTE_UNITS: u64 = 750;
-
-declare_process_instruction!(Entrypoint, DEFAULT_COMPUTE_UNITS, |invoke_context| {
-    let transaction_context = &invoke_context.transaction_context;
-    let instruction_context = transaction_context.get_current_instruction_context()?;
-    let instruction_data = instruction_context.get_instruction_data();
-    match limited_deserialize(instruction_data, solana_packet::PACKET_DATA_SIZE as u64)? {
-        ProgramInstruction::CreateLookupTable {
-            recent_slot,
-            bump_seed,
-        } => Processor::create_lookup_table(invoke_context, recent_slot, bump_seed),
-        ProgramInstruction::FreezeLookupTable => Processor::freeze_lookup_table(invoke_context),
-        ProgramInstruction::ExtendLookupTable { new_addresses } => {
-            Processor::extend_lookup_table(invoke_context, new_addresses)
-        }
-        ProgramInstruction::DeactivateLookupTable => {
-            Processor::deactivate_lookup_table(invoke_context)
-        }
-        ProgramInstruction::CloseLookupTable => Processor::close_lookup_table(invoke_context),
-    }
-});
-
-fn checked_add(a: usize, b: usize) -> Result<usize, InstructionError> {
-    a.checked_add(b).ok_or(InstructionError::ArithmeticOverflow)
-}
-
-pub struct Processor;
-impl Processor {
-    fn create_lookup_table(
-        invoke_context: &mut InvokeContext,
-        untrusted_recent_slot: Slot,
-        bump_seed: u8,
-    ) -> Result<(), InstructionError> {
-        let transaction_context = &invoke_context.transaction_context;
-        let instruction_context = transaction_context.get_current_instruction_context()?;
-
-        let lookup_table_account =
-            instruction_context.try_borrow_instruction_account(transaction_context, 0)?;
-        let lookup_table_lamports = lookup_table_account.get_lamports();
-        let table_key = *lookup_table_account.get_key();
-        let lookup_table_owner = *lookup_table_account.get_owner();
-        drop(lookup_table_account);
-
-        let authority_account =
-            instruction_context.try_borrow_instruction_account(transaction_context, 1)?;
-        let authority_key = *authority_account.get_key();
-        drop(authority_account);
-
-        let payer_account =
-            instruction_context.try_borrow_instruction_account(transaction_context, 2)?;
-        let payer_key = *payer_account.get_key();
-        if !payer_account.is_signer() {
-            ic_msg!(invoke_context, "Payer account must be a signer");
-            return Err(InstructionError::MissingRequiredSignature);
-        }
-        drop(payer_account);
-
-        let derivation_slot = {
-            let slot_hashes = invoke_context.get_sysvar_cache().get_slot_hashes()?;
-            if slot_hashes.get(&untrusted_recent_slot).is_some() {
-                Ok(untrusted_recent_slot)
-            } else {
-                ic_msg!(
-                    invoke_context,
-                    "{} is not a recent slot",
-                    untrusted_recent_slot
-                );
-                Err(InstructionError::InvalidInstructionData)
-            }
-        }?;
-
-        // Use a derived address to ensure that an address table can never be
-        // initialized more than once at the same address.
-        let derived_table_key = Pubkey::create_program_address(
-            &[
-                authority_key.as_ref(),
-                &derivation_slot.to_le_bytes(),
-                &[bump_seed],
-            ],
-            &id(),
-        )?;
-
-        if table_key != derived_table_key {
-            ic_msg!(
-                invoke_context,
-                "Table address must match derived address: {}",
-                derived_table_key
-            );
-            return Err(InstructionError::InvalidArgument);
-        }
-
-        if check_id(&lookup_table_owner) {
-            return Ok(());
-        }
-
-        let table_account_data_len = LOOKUP_TABLE_META_SIZE;
-        let rent = invoke_context.get_sysvar_cache().get_rent()?;
-        let required_lamports = rent
-            .minimum_balance(table_account_data_len)
-            .max(1)
-            .saturating_sub(lookup_table_lamports);
-
-        if required_lamports > 0 {
-            invoke_context.native_invoke(
-                system_instruction::transfer(&payer_key, &table_key, required_lamports).into(),
-                &[payer_key],
-            )?;
-        }
-
-        invoke_context.native_invoke(
-            system_instruction::allocate(&table_key, table_account_data_len as u64).into(),
-            &[table_key],
-        )?;
-
-        invoke_context.native_invoke(
-            system_instruction::assign(&table_key, &id()).into(),
-            &[table_key],
-        )?;
-
-        let transaction_context = &invoke_context.transaction_context;
-        let instruction_context = transaction_context.get_current_instruction_context()?;
-        let mut lookup_table_account =
-            instruction_context.try_borrow_instruction_account(transaction_context, 0)?;
-        lookup_table_account.set_state(&ProgramState::LookupTable(LookupTableMeta::new(
-            authority_key,
-        )))?;
-
-        Ok(())
-    }
-
-    fn freeze_lookup_table(invoke_context: &mut InvokeContext) -> Result<(), InstructionError> {
-        let transaction_context = &invoke_context.transaction_context;
-        let instruction_context = transaction_context.get_current_instruction_context()?;
-
-        let lookup_table_account =
-            instruction_context.try_borrow_instruction_account(transaction_context, 0)?;
-        if *lookup_table_account.get_owner() != id() {
-            return Err(InstructionError::InvalidAccountOwner);
-        }
-        drop(lookup_table_account);
-
-        let authority_account =
-            instruction_context.try_borrow_instruction_account(transaction_context, 1)?;
-        let authority_key = *authority_account.get_key();
-        if !authority_account.is_signer() {
-            ic_msg!(invoke_context, "Authority account must be a signer");
-            return Err(InstructionError::MissingRequiredSignature);
-        }
-        drop(authority_account);
-
-        let mut lookup_table_account =
-            instruction_context.try_borrow_instruction_account(transaction_context, 0)?;
-        let lookup_table_data = lookup_table_account.get_data();
-        let lookup_table = AddressLookupTable::deserialize(lookup_table_data)?;
-
-        if lookup_table.meta.authority.is_none() {
-            ic_msg!(invoke_context, "Lookup table is already frozen");
-            return Err(InstructionError::Immutable);
-        }
-        if lookup_table.meta.authority != Some(authority_key) {
-            return Err(InstructionError::IncorrectAuthority);
-        }
-        if lookup_table.meta.deactivation_slot != Slot::MAX {
-            ic_msg!(invoke_context, "Deactivated tables cannot be frozen");
-            return Err(InstructionError::InvalidArgument);
-        }
-        if lookup_table.addresses.is_empty() {
-            ic_msg!(invoke_context, "Empty lookup tables cannot be frozen");
-            return Err(InstructionError::InvalidInstructionData);
-        }
-
-        let mut lookup_table_meta = lookup_table.meta;
-        lookup_table_meta.authority = None;
-        AddressLookupTable::overwrite_meta_data(
-            lookup_table_account.get_data_mut()?,
-            lookup_table_meta,
-        )?;
-
-        Ok(())
-    }
-
-    fn extend_lookup_table(
-        invoke_context: &mut InvokeContext,
-        new_addresses: Vec<Pubkey>,
-    ) -> Result<(), InstructionError> {
-        let transaction_context = &invoke_context.transaction_context;
-        let instruction_context = transaction_context.get_current_instruction_context()?;
-
-        let lookup_table_account =
-            instruction_context.try_borrow_instruction_account(transaction_context, 0)?;
-        let table_key = *lookup_table_account.get_key();
-        if *lookup_table_account.get_owner() != id() {
-            return Err(InstructionError::InvalidAccountOwner);
-        }
-        drop(lookup_table_account);
-
-        let authority_account =
-            instruction_context.try_borrow_instruction_account(transaction_context, 1)?;
-        let authority_key = *authority_account.get_key();
-        if !authority_account.is_signer() {
-            ic_msg!(invoke_context, "Authority account must be a signer");
-            return Err(InstructionError::MissingRequiredSignature);
-        }
-        drop(authority_account);
-
-        let mut lookup_table_account =
-            instruction_context.try_borrow_instruction_account(transaction_context, 0)?;
-        let lookup_table_data = lookup_table_account.get_data();
-        let lookup_table_lamports = lookup_table_account.get_lamports();
-        let mut lookup_table = AddressLookupTable::deserialize(lookup_table_data)?;
-
-        if lookup_table.meta.authority.is_none() {
-            return Err(InstructionError::Immutable);
-        }
-        if lookup_table.meta.authority != Some(authority_key) {
-            return Err(InstructionError::IncorrectAuthority);
-        }
-        if lookup_table.meta.deactivation_slot != Slot::MAX {
-            ic_msg!(invoke_context, "Deactivated tables cannot be extended");
-            return Err(InstructionError::InvalidArgument);
-        }
-        if lookup_table.addresses.len() >= LOOKUP_TABLE_MAX_ADDRESSES {
-            ic_msg!(
-                invoke_context,
-                "Lookup table is full and cannot contain more addresses"
-            );
-            return Err(InstructionError::InvalidArgument);
-        }
-
-        if new_addresses.is_empty() {
-            ic_msg!(invoke_context, "Must extend with at least one address");
-            return Err(InstructionError::InvalidInstructionData);
-        }
-
-        let new_table_addresses_len = lookup_table
-            .addresses
-            .len()
-            .saturating_add(new_addresses.len());
-        if new_table_addresses_len > LOOKUP_TABLE_MAX_ADDRESSES {
-            ic_msg!(
-                invoke_context,
-                "Extended lookup table length {} would exceed max capacity of {}",
-                new_table_addresses_len,
-                LOOKUP_TABLE_MAX_ADDRESSES
-            );
-            return Err(InstructionError::InvalidInstructionData);
-        }
-
-        let clock = invoke_context.get_sysvar_cache().get_clock()?;
-        if clock.slot != lookup_table.meta.last_extended_slot {
-            lookup_table.meta.last_extended_slot = clock.slot;
-            lookup_table.meta.last_extended_slot_start_index =
-                u8::try_from(lookup_table.addresses.len()).map_err(|_| {
-                    // This is impossible as long as the length of new_addresses
-                    // is non-zero and LOOKUP_TABLE_MAX_ADDRESSES == u8::MAX + 1.
-                    InstructionError::InvalidAccountData
-                })?;
-        }
-
-        let lookup_table_meta = lookup_table.meta;
-        let new_table_data_len = checked_add(
-            LOOKUP_TABLE_META_SIZE,
-            new_table_addresses_len.saturating_mul(PUBKEY_BYTES),
-        )?;
-        {
-            AddressLookupTable::overwrite_meta_data(
-                lookup_table_account.get_data_mut()?,
-                lookup_table_meta,
-            )?;
-            for new_address in new_addresses {
-                lookup_table_account.extend_from_slice(new_address.as_ref())?;
-            }
-        }
-        drop(lookup_table_account);
-
-        let rent = invoke_context.get_sysvar_cache().get_rent()?;
-        let required_lamports = rent
-            .minimum_balance(new_table_data_len)
-            .max(1)
-            .saturating_sub(lookup_table_lamports);
-
-        if required_lamports > 0 {
-            let payer_account =
-                instruction_context.try_borrow_instruction_account(transaction_context, 2)?;
-            let payer_key = *payer_account.get_key();
-            if !payer_account.is_signer() {
-                ic_msg!(invoke_context, "Payer account must be a signer");
-                return Err(InstructionError::MissingRequiredSignature);
-            }
-            drop(payer_account);
-
-            invoke_context.native_invoke(
-                system_instruction::transfer(&payer_key, &table_key, required_lamports).into(),
-                &[payer_key],
-            )?;
-        }
-
-        Ok(())
-    }
-
-    fn deactivate_lookup_table(invoke_context: &mut InvokeContext) -> Result<(), InstructionError> {
-        let transaction_context = &invoke_context.transaction_context;
-        let instruction_context = transaction_context.get_current_instruction_context()?;
-
-        let lookup_table_account =
-            instruction_context.try_borrow_instruction_account(transaction_context, 0)?;
-        if *lookup_table_account.get_owner() != id() {
-            return Err(InstructionError::InvalidAccountOwner);
-        }
-        drop(lookup_table_account);
-
-        let authority_account =
-            instruction_context.try_borrow_instruction_account(transaction_context, 1)?;
-        let authority_key = *authority_account.get_key();
-        if !authority_account.is_signer() {
-            ic_msg!(invoke_context, "Authority account must be a signer");
-            return Err(InstructionError::MissingRequiredSignature);
-        }
-        drop(authority_account);
-
-        let mut lookup_table_account =
-            instruction_context.try_borrow_instruction_account(transaction_context, 0)?;
-        let lookup_table_data = lookup_table_account.get_data();
-        let lookup_table = AddressLookupTable::deserialize(lookup_table_data)?;
-
-        if lookup_table.meta.authority.is_none() {
-            ic_msg!(invoke_context, "Lookup table is frozen");
-            return Err(InstructionError::Immutable);
-        }
-        if lookup_table.meta.authority != Some(authority_key) {
-            return Err(InstructionError::IncorrectAuthority);
-        }
-        if lookup_table.meta.deactivation_slot != Slot::MAX {
-            ic_msg!(invoke_context, "Lookup table is already deactivated");
-            return Err(InstructionError::InvalidArgument);
-        }
-
-        let mut lookup_table_meta = lookup_table.meta;
-        let clock = invoke_context.get_sysvar_cache().get_clock()?;
-        lookup_table_meta.deactivation_slot = clock.slot;
-
-        AddressLookupTable::overwrite_meta_data(
-            lookup_table_account.get_data_mut()?,
-            lookup_table_meta,
-        )?;
-
-        Ok(())
-    }
-
-    fn close_lookup_table(invoke_context: &mut InvokeContext) -> Result<(), InstructionError> {
-        let transaction_context = &invoke_context.transaction_context;
-        let instruction_context = transaction_context.get_current_instruction_context()?;
-
-        let lookup_table_account =
-            instruction_context.try_borrow_instruction_account(transaction_context, 0)?;
-        if *lookup_table_account.get_owner() != id() {
-            return Err(InstructionError::InvalidAccountOwner);
-        }
-        drop(lookup_table_account);
-
-        let authority_account =
-            instruction_context.try_borrow_instruction_account(transaction_context, 1)?;
-        let authority_key = *authority_account.get_key();
-        if !authority_account.is_signer() {
-            ic_msg!(invoke_context, "Authority account must be a signer");
-            return Err(InstructionError::MissingRequiredSignature);
-        }
-        drop(authority_account);
-
-        instruction_context.check_number_of_instruction_accounts(3)?;
-        if instruction_context.get_index_of_instruction_account_in_transaction(0)?
-            == instruction_context.get_index_of_instruction_account_in_transaction(2)?
-        {
-            ic_msg!(
-                invoke_context,
-                "Lookup table cannot be the recipient of reclaimed lamports"
-            );
-            return Err(InstructionError::InvalidArgument);
-        }
-
-        let lookup_table_account =
-            instruction_context.try_borrow_instruction_account(transaction_context, 0)?;
-        let withdrawn_lamports = lookup_table_account.get_lamports();
-        let lookup_table_data = lookup_table_account.get_data();
-        let lookup_table = AddressLookupTable::deserialize(lookup_table_data)?;
-
-        if lookup_table.meta.authority.is_none() {
-            ic_msg!(invoke_context, "Lookup table is frozen");
-            return Err(InstructionError::Immutable);
-        }
-        if lookup_table.meta.authority != Some(authority_key) {
-            return Err(InstructionError::IncorrectAuthority);
-        }
-
-        let sysvar_cache = invoke_context.get_sysvar_cache();
-        let clock = sysvar_cache.get_clock()?;
-        let slot_hashes = sysvar_cache.get_slot_hashes()?;
-
-        match lookup_table.meta.status(clock.slot, &slot_hashes) {
-            LookupTableStatus::Activated => {
-                ic_msg!(invoke_context, "Lookup table is not deactivated");
-                Err(InstructionError::InvalidArgument)
-            }
-            LookupTableStatus::Deactivating { remaining_blocks } => {
-                ic_msg!(
-                    invoke_context,
-                    "Table cannot be closed until it's fully deactivated in {} blocks",
-                    remaining_blocks
-                );
-                Err(InstructionError::InvalidArgument)
-            }
-            LookupTableStatus::Deactivated => Ok(()),
-        }?;
-        drop(lookup_table_account);
-
-        let mut recipient_account =
-            instruction_context.try_borrow_instruction_account(transaction_context, 2)?;
-        recipient_account.checked_add_lamports(withdrawn_lamports)?;
-        drop(recipient_account);
-
-        let mut lookup_table_account =
-            instruction_context.try_borrow_instruction_account(transaction_context, 0)?;
-        lookup_table_account.set_data_length(0)?;
-        lookup_table_account.set_lamports(0)?;
-
-        Ok(())
-    }
-}

+ 0 - 25
programs/sbf/Cargo.lock

@@ -5341,29 +5341,6 @@ dependencies = [
  "solana-slot-hashes",
 ]
 
-[[package]]
-name = "solana-address-lookup-table-program"
-version = "2.3.0"
-dependencies = [
- "agave-feature-set",
- "bincode",
- "bytemuck",
- "log",
- "num-derive",
- "num-traits",
- "solana-address-lookup-table-interface",
- "solana-bincode",
- "solana-clock",
- "solana-instruction",
- "solana-log-collector",
- "solana-packet",
- "solana-program-runtime",
- "solana-pubkey",
- "solana-system-interface",
- "solana-transaction-context 2.3.0",
- "thiserror 2.0.12",
-]
-
 [[package]]
 name = "solana-atomic-u64"
 version = "2.2.1"
@@ -5560,7 +5537,6 @@ name = "solana-builtins"
 version = "2.3.0"
 dependencies = [
  "agave-feature-set",
- "solana-address-lookup-table-program",
  "solana-bpf-loader-program",
  "solana-compute-budget-program",
  "solana-loader-v4-program",
@@ -5582,7 +5558,6 @@ dependencies = [
  "ahash 0.8.11",
  "lazy_static",
  "log",
- "solana-address-lookup-table-program",
  "solana-bpf-loader-program",
  "solana-compute-budget-program",
  "solana-loader-v4-program",

+ 0 - 1
runtime/src/bank/builtin_programs.rs

@@ -157,7 +157,6 @@ mod tests_core_bpf_migration {
     #[test_case(TestPrototype::Builtin(&BUILTINS[2]); "stake")]
     #[test_case(TestPrototype::Builtin(&BUILTINS[3]); "bpf_loader_deprecated")]
     #[test_case(TestPrototype::Builtin(&BUILTINS[4]); "bpf_loader")]
-    #[test_case(TestPrototype::Builtin(&BUILTINS[7]); "address_lookup_table")]
     fn test_core_bpf_migration(prototype: TestPrototype) {
         let (mut genesis_config, mint_keypair) =
             create_genesis_config(1_000_000 * LAMPORTS_PER_SOL);

+ 0 - 1
runtime/src/bank/builtins/core_bpf_migration/target_builtin.rs

@@ -105,7 +105,6 @@ mod tests {
         bank.store_account_and_update_capitalization(address, &account);
     }
 
-    #[test_case(solana_sdk::address_lookup_table::program::id(), None)]
     #[test_case(solana_sdk::bpf_loader::id(), None)]
     #[test_case(solana_sdk::bpf_loader_deprecated::id(), None)]
     #[test_case(solana_sdk::bpf_loader_upgradeable::id(), None)]

+ 5 - 5
runtime/src/bank/tests.rs

@@ -6515,26 +6515,26 @@ fn test_bank_hash_consistency() {
         if bank.slot == 0 {
             assert_eq!(
                 bank.hash().to_string(),
-                "5nHFM2YArJdULMoAEtn2cXSaqk4v1UXs9upTvoc2FMn7",
+                "5b72TRrdMhGED3boghe55CyX8hmnpYt7RTMrwrHTrNpP",
             );
         }
 
         if bank.slot == 32 {
             assert_eq!(
                 bank.hash().to_string(),
-                "FPr64zXMcEE45qWRYy7hpvNRpzZD2ckqHes13uyiU1to"
+                "2k9XFkra1XyobQb4Z73xSEgFsUdp87cmftYfWEpXQoah"
             );
         }
         if bank.slot == 64 {
             assert_eq!(
                 bank.hash().to_string(),
-                "HENrhATjg2gghYyV34CLPnMUq2VuTKwUjGXWwAz96Vzs"
+                "GpePwzXm6nomkj9CKPU4qwvrFnBcjYRrs3hSoRgHN5CP"
             );
         }
         if bank.slot == 128 {
             assert_eq!(
                 bank.hash().to_string(),
-                "GjpfTe9dmB1HbrnC4BMaETPAqPUtXvXNG5ccnHSeMPnH"
+                "8GjxSMXwRe7AyFZoF9R7XVcTC5wYoVKvdawU8ysRcBid"
             );
             break;
         }
@@ -6753,7 +6753,7 @@ fn test_shrink_candidate_slots_cached() {
     // No more slots should be shrunk
     assert_eq!(bank2.shrink_candidate_slots(), 0);
     // alive_counts represents the count of alive accounts in the three slots 0,1,2
-    assert_eq!(alive_counts, vec![14, 1, 6]);
+    assert_eq!(alive_counts, vec![13, 1, 6]);
 }
 
 #[test]

+ 1 - 1
runtime/src/genesis_utils.rs

@@ -29,7 +29,7 @@ pub fn bootstrap_validator_stake_lamports() -> u64 {
 
 // Number of lamports automatically used for genesis accounts
 pub const fn genesis_sysvar_and_builtin_program_lamports() -> u64 {
-    const NUM_BUILTIN_PROGRAMS: u64 = 8;
+    const NUM_BUILTIN_PROGRAMS: u64 = 7;
     const NUM_PRECOMPILES: u64 = 2;
     const STAKE_HISTORY_MIN_BALANCE: u64 = 114_979_200;
     const CLOCK_SYSVAR_MIN_BALANCE: u64 = 1_169_280;

+ 0 - 2
scripts/patch-crates.sh

@@ -40,7 +40,6 @@ update_solana_dependencies() {
     solana-poh
     solana-program-runtime
     solana-program-test
-    solana-address-lookup-table-program
     solana-bpf-loader-program
     solana-compute-budget-program
     solana-stake-program
@@ -130,7 +129,6 @@ patch_crates_io_solana_no_header() {
   crates_map+=("solana-poh poh")
   crates_map+=("solana-program-runtime program-runtime")
   crates_map+=("solana-program-test program-test")
-  crates_map+=("solana-address-lookup-table-program programs/address-lookup-table")
   crates_map+=("solana-bpf-loader-program programs/bpf_loader")
   crates_map+=("solana-compute-budget-program programs/compute-budget")
   crates_map+=("solana-stake-program programs/stake")

+ 0 - 25
svm/examples/Cargo.lock

@@ -5199,29 +5199,6 @@ dependencies = [
  "solana-slot-hashes",
 ]
 
-[[package]]
-name = "solana-address-lookup-table-program"
-version = "2.3.0"
-dependencies = [
- "agave-feature-set",
- "bincode",
- "bytemuck",
- "log",
- "num-derive",
- "num-traits",
- "solana-address-lookup-table-interface",
- "solana-bincode",
- "solana-clock",
- "solana-instruction",
- "solana-log-collector",
- "solana-packet",
- "solana-program-runtime",
- "solana-pubkey",
- "solana-system-interface",
- "solana-transaction-context 2.3.0",
- "thiserror 2.0.12",
-]
-
 [[package]]
 name = "solana-atomic-u64"
 version = "2.2.1"
@@ -5418,7 +5395,6 @@ name = "solana-builtins"
 version = "2.3.0"
 dependencies = [
  "agave-feature-set",
- "solana-address-lookup-table-program",
  "solana-bpf-loader-program",
  "solana-compute-budget-program",
  "solana-loader-v4-program",
@@ -5440,7 +5416,6 @@ dependencies = [
  "ahash 0.8.11",
  "lazy_static",
  "log",
- "solana-address-lookup-table-program",
  "solana-bpf-loader-program",
  "solana-compute-budget-program",
  "solana-loader-v4-program",

+ 11 - 5
test-validator/src/lib.rs

@@ -1303,8 +1303,8 @@ mod test {
     async fn test_core_bpf_programs() {
         let (test_validator, _payer) = TestValidatorGenesis::default()
             .deactivate_features(&[
-                // Don't migrate the lookup table program.
-                solana_sdk::feature_set::migrate_address_lookup_table_program_to_core_bpf::id(),
+                // Don't migrate the stake program.
+                solana_sdk::feature_set::migrate_stake_program_to_core_bpf::id(),
             ])
             .start_async()
             .await;
@@ -1316,16 +1316,17 @@ mod test {
                 solana_sdk_ids::address_lookup_table::id(),
                 solana_sdk_ids::config::id(),
                 solana_sdk_ids::feature::id(),
+                solana_sdk_ids::stake::id(),
             ])
             .await
             .unwrap();
 
-        // Address lookup table is builtin.
+        // Address lookup table is a BPF program.
         let account = fetched_programs[0].as_ref().unwrap();
-        assert_eq!(account.owner, solana_sdk_ids::native_loader::id());
+        assert_eq!(account.owner, solana_sdk_ids::bpf_loader_upgradeable::id());
         assert!(account.executable);
 
-        // Config is a a BPF program.
+        // Config is a BPF program.
         let account = fetched_programs[1].as_ref().unwrap();
         assert_eq!(account.owner, solana_sdk_ids::bpf_loader_upgradeable::id());
         assert!(account.executable);
@@ -1334,5 +1335,10 @@ mod test {
         let account = fetched_programs[2].as_ref().unwrap();
         assert_eq!(account.owner, solana_sdk_ids::bpf_loader_upgradeable::id());
         assert!(account.executable);
+
+        // Stake is a builtin.
+        let account = fetched_programs[3].as_ref().unwrap();
+        assert_eq!(account.owner, solana_sdk_ids::native_loader::id());
+        assert!(account.executable);
     }
 }