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