Skip to main content

brk_query/impl/addr/
activity.rs

1use brk_error::{Error, OptionData, Result};
2use brk_types::{Addr, AddrIndexTxIndex, Height, Txid, Unit};
3
4use crate::Query;
5
6impl Query {
7    /// Height of the last on-chain activity for an address (last tx_index to height).
8    /// With `before_txid`, returns the newest activity strictly older than that
9    /// cursor. Used by paginated chain etags so a new tx above the cursor
10    /// doesn't invalidate deeper pages.
11    pub fn addr_last_activity_height(
12        &self,
13        addr: &Addr,
14        before_txid: Option<&Txid>,
15    ) -> Result<Height> {
16        let (output_type, type_index) = self.resolve_addr(addr)?;
17        let store = self
18            .indexer()
19            .stores
20            .addr_type_to_addr_index_and_tx_index
21            .get(output_type)
22            .data()?;
23        let tx_index_len = self.safe_lengths().tx_index;
24        let last_tx_index = match before_txid {
25            Some(txid) => {
26                let before_tx_index = self.resolve_tx_index(txid)?;
27                let min = AddrIndexTxIndex::min_for_addr(type_index);
28                let cursor = AddrIndexTxIndex::from((type_index, before_tx_index));
29                store
30                    .range(min..cursor)
31                    .rev()
32                    .map(|(key, _): (AddrIndexTxIndex, Unit)| key.tx_index())
33                    .find(|tx_index| *tx_index < tx_index_len)
34                    .ok_or(Error::UnknownAddr)?
35            }
36            None => store
37                .prefix(type_index)
38                .rev()
39                .map(|(key, _): (AddrIndexTxIndex, Unit)| key.tx_index())
40                .find(|tx_index| *tx_index < tx_index_len)
41                .ok_or(Error::UnknownAddr)?,
42        };
43        self.confirmed_status_height(last_tx_index)
44    }
45}