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 /// * `payload_byte_len` - Size of the block payload, or `None` when the caller does not
60 /// hold it. Pass `None` only for a proposal a quorum has already certified: the
61 /// implementation skips the checks that depend on the payload size.
62 ///
63 /// # Errors
64 ///
65 /// If the block header is invalid or appending it would lead to an invalid state.
66 fn validate_and_apply_header(
67 &self,
68 instance: &Self::Instance,
69 parent_leaf: &Leaf2<TYPES>,
70 proposed_header: &TYPES::BlockHeader,
71 payload_byte_len: Option<u32>,
72 version: Version,
73 view_number: u64,
74 ) -> impl Future<Output = Result<(Self, Self::Delta), Self::Error>> + Send;
75
76 /// Construct the state with the given block header.
77 ///
78 /// This can also be used to rebuild the state for catchup.
79 fn from_header(block_header: &TYPES::BlockHeader) -> Self;
80
81 /// Construct a genesis validated state.
82 #[must_use]
83 fn genesis(instance: &Self::Instance) -> (Self, Self::Delta);
84
85 /// Gets called to notify the persistence backend that this state has been committed
86 fn on_commit(&self);
87}
88
89/// extra functions required on state to be usable by hotshot-testing
90pub trait TestableState<TYPES>: ValidatedState<TYPES>
91where
92 TYPES: NodeType,
93 TYPES::BlockPayload: TestableBlock<TYPES>,
94{
95 /// Creates random transaction if possible
96 /// otherwise panics
97 /// `padding` is the bytes of padding to add to the transaction
98 fn create_random_transaction(
99 state: Option<&Self>,
100 rng: &mut dyn rand::RngCore,
101 padding: u64,
102 ) -> <TYPES::BlockPayload as BlockPayload<TYPES>>::Transaction;
103}