hotshot_builder_refactored/
block_store.rs

1use std::marker::PhantomData;
2
3use hotshot::traits::BlockPayload;
4use hotshot_builder_api::v0_1::block_info::AvailableBlockInfo;
5use hotshot_builder_shared::{
6    block::{BlockId, BuilderStateId},
7    coordinator::tiered_view_map::TieredViewMap,
8    error::Error,
9    utils::BuilderKeys,
10};
11use hotshot_types::{
12    data::ViewNumber,
13    traits::{node_implementation::NodeType, signature_key::BuilderSignatureKey},
14};
15
16// It holds all the necessary information for a block
17#[derive(Debug, Clone)]
18pub struct BlockInfo<Types: NodeType> {
19    pub block_payload: Types::BlockPayload,
20    pub metadata: <<Types as NodeType>::BlockPayload as BlockPayload<Types>>::Metadata,
21    pub block_size: u64,
22    pub offered_fee: u64,
23    // Could we have included more transactions with this block, but chose not to?
24    pub truncated: bool,
25}
26
27impl<Types: NodeType> BlockInfo<Types> {
28    pub fn signed_response(
29        &self,
30        keys: &BuilderKeys<Types>,
31    ) -> Result<AvailableBlockInfo<Types>, Error<Types>> {
32        let block_hash = self.block_payload.builder_commitment(&self.metadata);
33        let signature = <Types as NodeType>::BuilderSignatureKey::sign_block_info(
34            &keys.1,
35            self.block_size,
36            self.offered_fee,
37            &block_hash,
38        )
39        .map_err(Error::Signing)?;
40        Ok(AvailableBlockInfo {
41            block_hash,
42            block_size: self.block_size,
43            offered_fee: self.offered_fee,
44            signature,
45            sender: keys.0.clone(),
46            _phantom: PhantomData,
47        })
48    }
49}
50
51#[derive(Default)]
52pub struct BlockStore<Types: NodeType> {
53    pub(crate) blocks: TieredViewMap<BlockId, BlockInfo<Types>>,
54    pub(crate) block_cache: TieredViewMap<BuilderStateId, BlockId>,
55}
56
57impl<Types: NodeType> BlockStore<Types> {
58    pub fn new() -> Self {
59        Self::default()
60    }
61
62    pub fn update(
63        &mut self,
64        built_by: BuilderStateId,
65        block_id: BlockId,
66        block_info: BlockInfo<Types>,
67    ) {
68        self.blocks.insert(block_id.clone(), block_info);
69        self.block_cache.insert(built_by, block_id);
70    }
71
72    pub fn get_cached(&self, builder_id: &BuilderStateId) -> Option<&BlockInfo<Types>> {
73        let block_id = self.block_cache.get(builder_id)?;
74        self.blocks.get(block_id)
75    }
76
77    pub fn get_block(&self, block_id: &BlockId) -> Option<&BlockInfo<Types>> {
78        self.blocks.get(block_id)
79    }
80
81    pub fn prune(&mut self, cutoff: ViewNumber) {
82        self.blocks.prune(cutoff);
83        self.block_cache.prune(cutoff);
84    }
85}