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::{de::DeserializeOwned, Deserialize, Serialize};
16use vbs::version::Version;
17
18use super::block_contents::TestableBlock;
19use crate::{
20 data::Leaf2,
21 traits::{
22 node_implementation::{ConsensusTime, NodeType},
23 BlockPayload,
24 },
25};
26
27/// Instance-level state, which allows us to fetch missing validated state.
28pub trait InstanceState: Debug + Clone + Send + Sync {}
29
30/// Application-specific state delta, which will be used to store a list of merkle tree entries.
31pub trait StateDelta:
32 Debug + PartialEq + Eq + Send + Sync + Serialize + for<'a> Deserialize<'a>
33{
34}
35
36/// Abstraction over the state that blocks modify
37///
38/// This trait represents the behaviors that the 'global' ledger state must have:
39/// * A defined error type ([`Error`](ValidatedState::Error))
40/// * The type of block that modifies this type of state ([`BlockPayload`](`ValidatedStates::
41/// BlockPayload`))
42/// * The ability to validate that a block header is actually a valid extension of this state and
43/// produce a new state, with the modifications from the block applied
44///
45/// ([`validate_and_apply_header`](`ValidatedState::validate_and_apply_header`))
46pub trait ValidatedState<TYPES: NodeType>:
47 Serialize + DeserializeOwned + Debug + Default + PartialEq + Eq + Send + Sync + Clone
48{
49 /// The error type for this particular type of ledger state
50 type Error: Error + Debug + Send + Sync;
51 /// The type of the instance-level state this state is associated with
52 type Instance: InstanceState;
53 /// The type of the state delta this state is associated with.
54 type Delta: StateDelta;
55 /// Time compatibility needed for reward collection
56 type Time: ConsensusTime;
57
58 /// Check if the proposed block header is valid and apply it to the state if so.
59 ///
60 /// Returns the new state and state delta.
61 ///
62 /// # Arguments
63 /// * `instance` - Immutable instance-level state.
64 ///
65 /// # Errors
66 ///
67 /// If the block header is invalid or appending it would lead to an invalid state.
68 fn validate_and_apply_header(
69 &self,
70 instance: &Self::Instance,
71 parent_leaf: &Leaf2<TYPES>,
72 proposed_header: &TYPES::BlockHeader,
73 payload_byte_len: u32,
74 version: Version,
75 view_number: u64,
76 ) -> impl Future<Output = Result<(Self, Self::Delta), Self::Error>> + Send;
77
78 /// Construct the state with the given block header.
79 ///
80 /// This can also be used to rebuild the state for catchup.
81 fn from_header(block_header: &TYPES::BlockHeader) -> Self;
82
83 /// Construct a genesis validated state.
84 #[must_use]
85 fn genesis(instance: &Self::Instance) -> (Self, Self::Delta);
86
87 /// Gets called to notify the persistence backend that this state has been committed
88 fn on_commit(&self);
89}
90
91/// extra functions required on state to be usable by hotshot-testing
92pub trait TestableState<TYPES>: ValidatedState<TYPES>
93where
94 TYPES: NodeType,
95 TYPES::BlockPayload: TestableBlock<TYPES>,
96{
97 /// Creates random transaction if possible
98 /// otherwise panics
99 /// `padding` is the bytes of padding to add to the transaction
100 fn create_random_transaction(
101 state: Option<&Self>,
102 rng: &mut dyn rand::RngCore,
103 padding: u64,
104 ) -> <TYPES::BlockPayload as BlockPayload<TYPES>>::Transaction;
105}