Skip to main content

hotshot_query_service/merklized_state/
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 [`merklized_state`](super) API.
14//!
15//! This module facilitates storing the state of a Merkle Tree at a specific point in time
16//! and provides methods for querying and reconstructing the snapshot.
17//!
18
19use std::cmp::Ordering;
20
21use async_trait::async_trait;
22use derivative::Derivative;
23use derive_more::with_trait::Display;
24pub use hotshot_query_service_types::merklized_state::MerklizedState;
25use hotshot_types::traits::node_implementation::NodeType;
26use jf_merkle_tree_compat::prelude::MerkleProof;
27
28use crate::QueryResult;
29
30/// This trait defines methods that a data source should implement
31/// It enables retrieval of the membership path for a leaf node, which can be used to reconstruct the Merkle tree state.
32#[async_trait]
33pub trait MerklizedStateDataSource<Types, State, const ARITY: usize>
34where
35    Types: NodeType,
36    State: MerklizedState<Types, ARITY>,
37{
38    async fn get_path(
39        &self,
40        snapshot: Snapshot<Types, State, ARITY>,
41        key: State::Key,
42    ) -> QueryResult<MerkleProof<State::Entry, State::Key, State::T, ARITY>>;
43}
44
45/// This trait defines methods for updating the storage with the merkle tree state.
46#[async_trait]
47pub trait UpdateStateData<Types: NodeType, State: MerklizedState<Types, ARITY>, const ARITY: usize>:
48    Send + Sync
49{
50    async fn set_last_state_height(&mut self, height: usize) -> anyhow::Result<()>;
51    async fn insert_merkle_nodes(
52        &mut self,
53        path: MerkleProof<State::Entry, State::Key, State::T, ARITY>,
54        traversal_path: Vec<usize>,
55        block_number: u64,
56    ) -> anyhow::Result<()>;
57    async fn insert_merkle_nodes_batch(
58        &mut self,
59        proofs: Vec<(
60            MerkleProof<State::Entry, State::Key, State::T, ARITY>,
61            Vec<usize>,
62        )>,
63        block_number: u64,
64    ) -> anyhow::Result<()>;
65}
66
67#[async_trait]
68pub trait MerklizedStateHeightPersistence {
69    async fn get_last_state_height(&self) -> QueryResult<usize>;
70}
71
72type StateCommitment<Types, T, const ARITY: usize> = <T as MerklizedState<Types, ARITY>>::Commit;
73
74/// Snapshot can be queried by block height (index) or merkle tree commitment
75#[derive(Derivative, Display)]
76#[derivative(Ord = "feature_allow_slow_enum")]
77#[derivative(
78    Copy(bound = ""),
79    Debug(bound = ""),
80    PartialEq(bound = ""),
81    Eq(bound = ""),
82    Ord(bound = ""),
83    Hash(bound = "")
84)]
85pub enum Snapshot<Types: NodeType, T: MerklizedState<Types, ARITY>, const ARITY: usize> {
86    #[display("{_0}")]
87    Commit(StateCommitment<Types, T, ARITY>),
88    #[display("{_0}")]
89    Index(u64),
90}
91
92impl<T: MerklizedState<Types, ARITY>, Types: NodeType, const ARITY: usize> Clone
93    for Snapshot<Types, T, ARITY>
94{
95    fn clone(&self) -> Self {
96        *self
97    }
98}
99
100impl<T: MerklizedState<Types, ARITY>, Types: NodeType, const ARITY: usize> PartialOrd
101    for Snapshot<Types, T, ARITY>
102{
103    fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
104        Some(self.cmp(other))
105    }
106}