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}