Changeset View
Changeset View
Standalone View
Standalone View
chronik/chronik-indexer/src/query/group_history.rs
// Copyright (c) 2023 The Bitcoin developers | // Copyright (c) 2023 The Bitcoin developers | ||||
// Distributed under the MIT software license, see the accompanying | // Distributed under the MIT software license, see the accompanying | ||||
// file COPYING or http://www.opensource.org/licenses/mit-license.php. | // file COPYING or http://www.opensource.org/licenses/mit-license.php. | ||||
//! Module for [`QueryGroupHistory`], to query the tx history of a group. | //! Module for [`QueryGroupHistory`], to query the tx history of a group. | ||||
use std::collections::BTreeSet; | use std::collections::BTreeSet; | ||||
use abc_rust_error::Result; | use abc_rust_error::Result; | ||||
use bitcoinsuite_core::tx::{Tx, TxId}; | use bitcoinsuite_core::tx::{Tx, TxId}; | ||||
use chronik_bridge::ffi; | |||||
use chronik_db::{ | use chronik_db::{ | ||||
db::Db, | db::Db, | ||||
group::Group, | group::Group, | ||||
io::{BlockReader, GroupHistoryReader, SpentByReader, TxNum, TxReader}, | io::{BlockReader, GroupHistoryReader, SpentByReader, TxNum, TxReader}, | ||||
mem::{Mempool, MempoolGroupHistory}, | mem::{Mempool, MempoolGroupHistory}, | ||||
}; | }; | ||||
use chronik_proto::proto; | use chronik_proto::proto; | ||||
use chronik_util::log; | use chronik_util::log; | ||||
use thiserror::Error; | use thiserror::Error; | ||||
use crate::{ | use crate::{ | ||||
avalanche::Avalanche, | avalanche::Avalanche, | ||||
indexer::Node, | |||||
query::{make_tx_proto, OutputsSpent, TxTokenData}, | query::{make_tx_proto, OutputsSpent, TxTokenData}, | ||||
}; | }; | ||||
/// Smallest allowed page size | /// Smallest allowed page size | ||||
pub const MIN_HISTORY_PAGE_SIZE: usize = 1; | pub const MIN_HISTORY_PAGE_SIZE: usize = 1; | ||||
/// Largest allowed page size | /// Largest allowed page size | ||||
pub const MAX_HISTORY_PAGE_SIZE: usize = 200; | pub const MAX_HISTORY_PAGE_SIZE: usize = 200; | ||||
static EMPTY_MEMBER_TX_HISTORY: BTreeSet<(i64, TxId)> = BTreeSet::new(); | static EMPTY_MEMBER_TX_HISTORY: BTreeSet<(i64, TxId)> = BTreeSet::new(); | ||||
/// Query pages of the tx history of a group | /// Query pages of the tx history of a group | ||||
#[derive(Debug)] | #[derive(Debug)] | ||||
pub struct QueryGroupHistory<'a, G: Group> { | pub struct QueryGroupHistory<'a, G: Group> { | ||||
/// Database | /// Database | ||||
pub db: &'a Db, | pub db: &'a Db, | ||||
/// Avalanche | /// Avalanche | ||||
pub avalanche: &'a Avalanche, | pub avalanche: &'a Avalanche, | ||||
/// Mempool | /// Mempool | ||||
pub mempool: &'a Mempool, | pub mempool: &'a Mempool, | ||||
/// The part of the mempool we search for this group's history. | /// The part of the mempool we search for this group's history. | ||||
pub mempool_history: &'a MempoolGroupHistory<G>, | pub mempool_history: &'a MempoolGroupHistory<G>, | ||||
/// Group to query txs by | /// Group to query txs by | ||||
pub group: G, | pub group: G, | ||||
/// Access to bitcoind to read txs | |||||
pub node: &'a Node, | |||||
/// Whether the SLP/ALP token index is enabled | /// Whether the SLP/ALP token index is enabled | ||||
pub is_token_index_enabled: bool, | pub is_token_index_enabled: bool, | ||||
} | } | ||||
/// Errors indicating something went wrong with reading txs. | /// Errors indicating something went wrong with reading txs. | ||||
#[derive(Debug, Error, PartialEq)] | #[derive(Debug, Error, PartialEq)] | ||||
pub enum QueryGroupHistoryError { | pub enum QueryGroupHistoryError { | ||||
/// Transaction not in mempool. | /// Transaction not in mempool. | ||||
▲ Show 20 Lines • Show All 321 Lines • ▼ Show 20 Lines | fn read_block_tx(&self, tx_num: TxNum) -> Result<proto::Tx> { | ||||
let tx_reader = TxReader::new(self.db)?; | let tx_reader = TxReader::new(self.db)?; | ||||
let block_reader = BlockReader::new(self.db)?; | let block_reader = BlockReader::new(self.db)?; | ||||
let spent_by_reader = SpentByReader::new(self.db)?; | let spent_by_reader = SpentByReader::new(self.db)?; | ||||
let block_tx = | let block_tx = | ||||
tx_reader.tx_by_tx_num(tx_num)?.ok_or(MissingDbTx(tx_num))?; | tx_reader.tx_by_tx_num(tx_num)?.ok_or(MissingDbTx(tx_num))?; | ||||
let block = block_reader | let block = block_reader | ||||
.by_height(block_tx.block_height)? | .by_height(block_tx.block_height)? | ||||
.ok_or(MissingDbTxBlock(tx_num))?; | .ok_or(MissingDbTxBlock(tx_num))?; | ||||
let tx = Tx::from(ffi::load_tx( | let tx = Tx::from(self.node.bridge.load_tx( | ||||
block.file_num, | block.file_num, | ||||
block_tx.entry.data_pos, | block_tx.entry.data_pos, | ||||
block_tx.entry.undo_pos, | block_tx.entry.undo_pos, | ||||
)?); | )?); | ||||
let outputs_spent = OutputsSpent::query( | let outputs_spent = OutputsSpent::query( | ||||
&spent_by_reader, | &spent_by_reader, | ||||
&tx_reader, | &tx_reader, | ||||
self.mempool.spent_by().outputs_spent(&block_tx.entry.txid), | self.mempool.spent_by().outputs_spent(&block_tx.entry.txid), | ||||
Show All 19 Lines |