hotshot_query_service/node/
data_source.rs

1// Copyright (c) 2022 Espresso Systems (espressosys.com)
2// This file is part of the HotShot Query Service library.
3//
4// This program is free software: you can redistribute it and/or modify it under the terms of the GNU
5// General Public License as published by the Free Software Foundation, either version 3 of the
6// License, or (at your option) any later version.
7// This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without
8// even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
9// General Public License for more details.
10// You should have received a copy of the GNU General Public License along with this program. If not,
11// see <https://www.gnu.org/licenses/>.
12
13//! Data for the [`node`](super) API.
14//!
15//! This module is just an alternative view of the same data provided by the
16//! [`availability`](crate::availability) API. It provides more insight into what data the node
17//! actually has at present, as opposed to trying to present a perfect view of an abstract chain,
18//! fetching data from other sources as needed. It is also more liberal with provided aggregate
19//! counts and statistics which may be inaccurate if data is missing.
20//!
21//! Due to this relationship with the availability module, this module has its own [data source
22//! trait](`NodeDataSource`) but not its own update trait. The node data source is expected to read
23//! its data from the same underlying database as the availability API, and as such the data is
24//! updated implicitly via the [availability API update
25//! trait](crate::availability::UpdateAvailabilityData).
26
27use std::ops::RangeBounds;
28
29use async_trait::async_trait;
30use derivative::Derivative;
31use derive_more::From;
32use hotshot_types::{data::VidShare, traits::node_implementation::NodeType};
33
34use super::query_data::{BlockHash, BlockId, SyncStatus, TimeWindowQueryData};
35use crate::{
36    availability::{NamespaceId, QueryableHeader},
37    Header, QueryResult,
38};
39
40#[derive(Derivative, From)]
41#[derivative(Copy(bound = ""), Debug(bound = ""))]
42pub enum WindowStart<Types: NodeType> {
43    #[from(ignore)]
44    Time(u64),
45    #[from(ignore)]
46    Height(u64),
47    Hash(BlockHash<Types>),
48}
49
50impl<Types: NodeType> Clone for WindowStart<Types> {
51    fn clone(&self) -> Self {
52        *self
53    }
54}
55
56#[async_trait]
57pub trait NodeDataSource<Types>
58where
59    Types: NodeType,
60    Header<Types>: QueryableHeader<Types>,
61{
62    async fn block_height(&self) -> QueryResult<usize>;
63    async fn count_transactions_in_range(
64        &self,
65        range: impl RangeBounds<usize> + Send,
66        namespace: Option<NamespaceId<Types>>,
67    ) -> QueryResult<usize>;
68    async fn payload_size_in_range(
69        &self,
70        range: impl RangeBounds<usize> + Send,
71        namespace: Option<NamespaceId<Types>>,
72    ) -> QueryResult<usize>;
73    async fn vid_share<ID>(&self, id: ID) -> QueryResult<VidShare>
74    where
75        ID: Into<BlockId<Types>> + Send + Sync;
76    async fn get_header_window(
77        &self,
78        start: impl Into<WindowStart<Types>> + Send + Sync,
79        end: u64,
80        limit: usize,
81    ) -> QueryResult<TimeWindowQueryData<Header<Types>>>;
82
83    /// Search the database for missing objects and generate a report.
84    async fn sync_status(&self) -> QueryResult<SyncStatus>;
85
86    async fn count_transactions(&self) -> QueryResult<usize> {
87        self.count_transactions_in_range(0.., None).await
88    }
89
90    async fn payload_size(&self) -> QueryResult<usize> {
91        self.payload_size_in_range(0.., None).await
92    }
93}