hotshot_types/traits/
states.rs

1// Copyright (c) 2021-2024 Espresso Systems (espressosys.com)
2// This file is part of the HotShot repository.
3
4// You should have received a copy of the MIT License
5// along with the HotShot repository. If not, see <https://mit-license.org/>.
6
7//! Abstractions over the immutable instance-level state and the global state that blocks modify.
8//!
9//! This module provides the [`InstanceState`] and [`ValidatedState`] traits, which serve as
10//! compatibilities over the current network state, which is modified by the transactions contained
11//! within blocks.
12
13use std::{error::Error, fmt::Debug, future::Future};
14
15use serde::{Deserialize, Serialize, de::DeserializeOwned};
16use vbs::version::Version;
17
18use super::block_contents::TestableBlock;
19use crate::{
20    data::Leaf2,
21    traits::{BlockPayload, node_implementation::NodeType},
22};
23
24/// Instance-level state, which allows us to fetch missing validated state.
25pub trait InstanceState: Debug + Clone + Send + Sync {}
26
27/// Application-specific state delta, which will be used to store a list of merkle tree entries.
28pub trait StateDelta:
29    Debug + PartialEq + Eq + Send + Sync + Serialize + for<'a> Deserialize<'a>
30{
31}
32
33/// Abstraction over the state that blocks modify
34///
35/// This trait represents the behaviors that the 'global' ledger state must have:
36///   * A defined error type ([`Error`](ValidatedState::Error))
37///   * The type of block that modifies this type of state ([`BlockPayload`](`ValidatedStates::
38/// BlockPayload`))
39///   * The ability to validate that a block header is actually a valid extension of this state and
40///     produce a new state, with the modifications from the block applied
41///
42/// ([`validate_and_apply_header`](`ValidatedState::validate_and_apply_header`))
43pub trait ValidatedState<TYPES: NodeType>:
44    Serialize + DeserializeOwned + Debug + Default + PartialEq + Eq + Send + Sync + Clone
45{
46    /// The error type for this particular type of ledger state
47    type Error: Error + Debug + Send + Sync;
48    /// The type of the instance-level state this state is associated with
49    type Instance: InstanceState;
50    /// The type of the state delta this state is associated with.
51    type Delta: StateDelta;
52
53    /// Check if the proposed block header is valid and apply it to the state if so.
54    ///
55    /// Returns the new state and state delta.
56    ///
57    /// # Arguments
58    /// * `instance` - Immutable instance-level state.
59    ///
60    /// # Errors
61    ///
62    /// If the block header is invalid or appending it would lead to an invalid state.
63    fn validate_and_apply_header(
64        &self,
65        instance: &Self::Instance,
66        parent_leaf: &Leaf2<TYPES>,
67        proposed_header: &TYPES::BlockHeader,
68        payload_byte_len: u32,
69        version: Version,
70        view_number: u64,
71    ) -> impl Future<Output = Result<(Self, Self::Delta), Self::Error>> + Send;
72
73    /// Construct the state with the given block header.
74    ///
75    /// This can also be used to rebuild the state for catchup.
76    fn from_header(block_header: &TYPES::BlockHeader) -> Self;
77
78    /// Construct a genesis validated state.
79    #[must_use]
80    fn genesis(instance: &Self::Instance) -> (Self, Self::Delta);
81
82    /// Gets called to notify the persistence backend that this state has been committed
83    fn on_commit(&self);
84}
85
86/// extra functions required on state to be usable by hotshot-testing
87pub trait TestableState<TYPES>: ValidatedState<TYPES>
88where
89    TYPES: NodeType,
90    TYPES::BlockPayload: TestableBlock<TYPES>,
91{
92    /// Creates random transaction if possible
93    /// otherwise panics
94    /// `padding` is the bytes of padding to add to the transaction
95    fn create_random_transaction(
96        state: Option<&Self>,
97        rng: &mut dyn rand::RngCore,
98        padding: u64,
99    ) -> <TYPES::BlockPayload as BlockPayload<TYPES>>::Transaction;
100}