solana_runtime/bank/
address_lookup_table.rs

1use {
2    super::Bank,
3    solana_address_lookup_table_interface::error::AddressLookupError,
4    solana_clock::Slot,
5    solana_message::{
6        v0::{LoadedAddresses, MessageAddressTableLookup},
7        AddressLoader,
8    },
9    solana_svm_transaction::message_address_table_lookup::SVMMessageAddressTableLookup,
10    solana_transaction_error::AddressLoaderError,
11};
12
13fn into_address_loader_error(err: AddressLookupError) -> AddressLoaderError {
14    match err {
15        AddressLookupError::LookupTableAccountNotFound => {
16            AddressLoaderError::LookupTableAccountNotFound
17        }
18        AddressLookupError::InvalidAccountOwner => AddressLoaderError::InvalidAccountOwner,
19        AddressLookupError::InvalidAccountData => AddressLoaderError::InvalidAccountData,
20        AddressLookupError::InvalidLookupIndex => AddressLoaderError::InvalidLookupIndex,
21    }
22}
23
24impl AddressLoader for &Bank {
25    fn load_addresses(
26        self,
27        address_table_lookups: &[MessageAddressTableLookup],
28    ) -> Result<LoadedAddresses, AddressLoaderError> {
29        self.load_addresses_from_ref(
30            address_table_lookups
31                .iter()
32                .map(SVMMessageAddressTableLookup::from),
33        )
34        .map(|(loaded_addresses, _deactivation_slot)| loaded_addresses)
35    }
36}
37
38impl Bank {
39    /// Load addresses from an iterator of `SVMMessageAddressTableLookup`,
40    /// additionally returning the minimum deactivation slot across all referenced ALTs
41    pub fn load_addresses_from_ref<'a>(
42        &self,
43        address_table_lookups: impl Iterator<Item = SVMMessageAddressTableLookup<'a>>,
44    ) -> Result<(LoadedAddresses, Slot), AddressLoaderError> {
45        let slot_hashes = self
46            .transaction_processor
47            .sysvar_cache()
48            .get_slot_hashes()
49            .map_err(|_| AddressLoaderError::SlotHashesSysvarNotFound)?;
50
51        let mut deactivation_slot = u64::MAX;
52        let mut loaded_addresses = LoadedAddresses::default();
53        for address_table_lookup in address_table_lookups {
54            deactivation_slot = deactivation_slot.min(
55                self.rc
56                    .accounts
57                    .load_lookup_table_addresses_into(
58                        &self.ancestors,
59                        address_table_lookup,
60                        &slot_hashes,
61                        &mut loaded_addresses,
62                    )
63                    .map_err(into_address_loader_error)?,
64            );
65        }
66
67        Ok((loaded_addresses, deactivation_slot))
68    }
69}