commonware_consensus/marshal/standard/
variant.rs1use crate::{
7 marshal::{
8 ancestry::BlockProvider,
9 core::{Buffer, CommitmentFallback, Mailbox, Variant},
10 },
11 simplex::scheme::Scheme as SimplexScheme,
12 types::Round,
13 Block,
14};
15use commonware_broadcast::buffered;
16use commonware_codec::Read;
17use commonware_cryptography::{certificate::Scheme, Digestible, PublicKey};
18use commonware_p2p::Recipients;
19use commonware_utils::channel::oneshot;
20use std::{future::Future, sync::Arc};
21
22#[derive(Default, Clone, Copy)]
26pub struct Standard<B: Block>(std::marker::PhantomData<B>);
27
28impl<B> Variant for Standard<B>
29where
30 B: Block,
31{
32 type ApplicationBlock = B;
33 type Block = B;
34 type StoredBlock = B;
35 type Commitment = <B as Digestible>::Digest;
36
37 fn commitment(block: &Self::Block) -> Self::Commitment {
38 block.digest()
40 }
41
42 fn stored_commitment(block: &Self::StoredBlock) -> Self::Commitment {
43 block.digest()
44 }
45
46 fn commitment_to_inner(commitment: Self::Commitment) -> <Self::Block as Digestible>::Digest {
47 commitment
49 }
50
51 fn parent_commitment(block: &Self::Block) -> Self::Commitment {
52 block.parent()
54 }
55
56 fn check_payload<S>(_scheme: &S, _payload: Self::Commitment) -> bool
57 where
58 S: SimplexScheme<Self::Commitment>,
59 {
60 true
61 }
62
63 fn block_cfg(
64 block_cfg: &<Self::ApplicationBlock as Read>::Cfg,
65 _expected: Self::Commitment,
66 ) -> <Self::Block as Read>::Cfg {
67 block_cfg.clone()
68 }
69
70 fn into_inner(block: Self::Block) -> Self::ApplicationBlock {
71 block
72 }
73
74 fn into_inner_shared(block: Arc<Self::Block>) -> Arc<Self::ApplicationBlock> {
75 block
76 }
77
78 fn owned_into_inner_shared(block: Self::Block) -> Arc<Self::ApplicationBlock> {
79 Arc::new(block)
80 }
81
82 fn from_application_block(
83 block: Self::ApplicationBlock,
84 _payload: Self::Commitment,
85 ) -> Self::Block {
86 block
87 }
88}
89
90impl<B, K> Buffer<Standard<B>> for buffered::Mailbox<K, B>
91where
92 B: Block,
93 K: PublicKey,
94{
95 type PublicKey = K;
96
97 async fn find_by_digest(&self, digest: B::Digest) -> Option<Arc<B>> {
98 self.get(digest).await
99 }
100
101 async fn find_by_commitment(&self, commitment: B::Digest) -> Option<Arc<B>> {
102 self.find_by_digest(commitment).await
103 }
104
105 fn subscribe_by_digest(&self, digest: B::Digest) -> Option<oneshot::Receiver<Arc<B>>> {
106 Some(self.subscribe(digest))
107 }
108
109 fn subscribe_by_commitment(&self, commitment: B::Digest) -> Option<oneshot::Receiver<Arc<B>>> {
110 self.subscribe_by_digest(commitment)
111 }
112
113 fn finalized(&self, _commitment: B::Digest) {
114 }
116
117 fn send(&self, _round: Round, block: Arc<B>, recipients: Recipients<K>) {
118 self.broadcast_shared(recipients, block);
119 }
120}
121
122impl<S, B> BlockProvider for Mailbox<S, Standard<B>>
123where
124 S: Scheme,
125 B: Block,
126{
127 type Block = B;
128
129 fn subscribe_parent(
130 &self,
131 block: &Self::Block,
132 ) -> impl Future<Output = Option<Arc<Self::Block>>> + Send + 'static {
133 let receiver = block.height().previous().map(|parent_height| {
134 self.subscribe_by_commitment(
135 block.parent(),
136 CommitmentFallback::FetchByCommitment {
137 height: parent_height,
138 },
139 )
140 });
141 async move { receiver?.await.ok() }
142 }
143}