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}