hotshot_query_service/testing/
mocks.rs1use hotshot::traits::{NodeImplementation, implementations::MemoryNetwork};
14use hotshot_example_types::{
15 block_types::{TestBlockHeader, TestBlockPayload, TestMetadata, TestTransaction},
16 membership::{static_committee::StaticStakeTable, strict_membership::StrictMembership},
17 state_types::{TestInstanceState, TestValidatedState},
18 storage_types::TestStorage,
19};
20use hotshot_types::{
21 data::{QuorumProposal, VidCommitment, VidCommon},
22 signature_key::{BLSPubKey, SchnorrPubKey},
23 traits::node_implementation::NodeType,
24};
25use jf_merkle_tree_compat::{
26 ForgetableMerkleTreeScheme, ForgetableUniversalMerkleTreeScheme,
27 prelude::{MerkleProof, Sha3Digest, Sha3Node},
28 universal_merkle_tree::UniversalMerkleTree,
29};
30use serde::{Deserialize, Serialize};
31use vbs::version::StaticVersion;
32use versions::{Upgrade, version};
33
34use crate::{
35 availability::{
36 QueryableHeader, QueryablePayload, TransactionIndex, VerifiableInclusion,
37 VidCommonQueryData,
38 },
39 explorer::traits::{ExplorerHeader, ExplorerTransaction},
40 merklized_state::MerklizedState,
41 types::HeightIndexed,
42};
43
44pub type MockHeader = TestBlockHeader;
45pub type MockPayload = TestBlockPayload;
46pub type MockTransaction = TestTransaction;
47
48pub fn mock_transaction(payload: Vec<u8>) -> MockTransaction {
49 TestTransaction::new(payload)
50}
51
52impl QueryableHeader<MockTypes> for MockHeader {
53 type NamespaceId = i64;
54 type NamespaceIndex = i64;
55
56 fn namespace_id(&self, i: &i64) -> Option<i64> {
57 if *i == 0 { Some(0) } else { None }
59 }
60
61 fn namespace_size(&self, i: &i64, payload_size: usize) -> u64 {
62 if *i == 0 { payload_size as u64 } else { 0 }
64 }
65
66 fn ns_table(&self) -> String {
67 self.metadata.to_string()
68 }
69}
70
71impl ExplorerHeader<MockTypes> for MockHeader {
72 type BalanceAmount = i128;
73 type WalletAddress = [u8; 32];
74 type ProposerId = [u8; 32];
75
76 fn proposer_id(&self) -> Self::ProposerId {
77 [0; 32]
78 }
79
80 fn fee_info_account(&self) -> Self::WalletAddress {
81 [0; 32]
82 }
83
84 fn fee_info_balance(&self) -> Self::BalanceAmount {
85 0
86 }
87
88 fn reward_balance(&self) -> Self::BalanceAmount {
89 0
90 }
91
92 fn namespace_ids(&self) -> Vec<i64> {
93 vec![0]
94 }
95}
96
97impl ExplorerTransaction<MockTypes> for MockTransaction {
98 fn namespace_id(&self) -> i64 {
99 0
100 }
101
102 fn payload_size(&self) -> u64 {
103 self.bytes().len() as u64
104 }
105}
106
107impl HeightIndexed for MockHeader {
108 fn height(&self) -> u64 {
109 self.block_number
110 }
111}
112
113#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
115pub struct MockInclusionProof(MockPayload);
116
117impl VerifiableInclusion<MockTypes> for MockInclusionProof {
118 fn verify(
119 &self,
120 _metadata: &TestMetadata,
121 tx: &MockTransaction,
122 _payload_commitment: &VidCommitment,
123 _common: &VidCommon,
124 ) -> bool {
125 self.0.transactions.contains(tx)
126 }
127}
128
129impl QueryablePayload<MockTypes> for MockPayload {
130 type Iter<'a> = <Vec<TransactionIndex<MockTypes>> as IntoIterator>::IntoIter;
131 type InclusionProof = MockInclusionProof;
132
133 fn len(&self, _meta: &Self::Metadata) -> usize {
134 self.transactions.len()
135 }
136
137 fn iter(&self, meta: &Self::Metadata) -> Self::Iter<'_> {
138 (0..<TestBlockPayload as QueryablePayload<MockTypes>>::len(self, meta))
139 .map(|i| TransactionIndex {
140 ns_index: 0,
141 position: i as u32,
142 })
143 .collect::<Vec<_>>()
144 .into_iter()
145 }
146
147 fn transaction(
148 &self,
149 _meta: &Self::Metadata,
150 index: &TransactionIndex<MockTypes>,
151 ) -> Option<Self::Transaction> {
152 self.transactions.get(index.position as usize).cloned()
153 }
154
155 fn transaction_proof(
156 &self,
157 _meta: &Self::Metadata,
158 _vid: &VidCommonQueryData<MockTypes>,
159 _index: &TransactionIndex<MockTypes>,
160 ) -> Option<Self::InclusionProof> {
161 Some(MockInclusionProof(self.clone()))
162 }
163}
164
165#[derive(
166 Copy, Clone, Debug, Default, Hash, PartialEq, Eq, PartialOrd, Ord, Serialize, Deserialize,
167)]
168pub struct MockTypes;
169
170impl NodeType for MockTypes {
171 type BlockHeader = MockHeader;
172 type BlockPayload = MockPayload;
173 type SignatureKey = BLSPubKey;
174 type Transaction = MockTransaction;
175 type InstanceState = TestInstanceState;
176 type ValidatedState = TestValidatedState;
177 type Membership = StrictMembership<MockTypes, StaticStakeTable<BLSPubKey, SchnorrPubKey>>;
178 type BuilderSignatureKey = BLSPubKey;
179 type StateSignatureKey = SchnorrPubKey;
180}
181
182pub const MOCK_UPGRADE: Upgrade = Upgrade::new(version(0, 1), version(0, 2));
183
184pub type MockBase = StaticVersion<0, 1>;
185
186pub type MockMembership = StrictMembership<MockTypes, StaticStakeTable<BLSPubKey, SchnorrPubKey>>;
187pub type MockQuorumProposal = QuorumProposal<MockTypes>;
188pub type MockNetwork = MemoryNetwork<BLSPubKey>;
189
190pub type MockStorage = TestStorage<MockTypes>;
191
192#[derive(
193 Copy, Clone, Debug, Default, Hash, PartialEq, Eq, PartialOrd, Ord, Serialize, Deserialize,
194)]
195pub struct MockNodeImpl;
196
197impl NodeImplementation<MockTypes> for MockNodeImpl {
198 type Network = MockNetwork;
199 type Storage = MockStorage;
200}
201
202pub type MockMerkleTree = UniversalMerkleTree<usize, Sha3Digest, usize, 8, Sha3Node>;
203
204impl MerklizedState<MockTypes, 8> for MockMerkleTree {
205 type Key = usize;
206 type Entry = usize;
207 type T = Sha3Node;
208 type Commit = Self::Commitment;
209 type Digest = Sha3Digest;
210
211 fn state_type() -> &'static str {
212 "test_tree"
213 }
214
215 fn header_state_commitment_field() -> &'static str {
216 "test_merkle_tree_root"
217 }
218
219 fn tree_height() -> usize {
220 12
221 }
222
223 fn insert_path(
224 &mut self,
225 key: Self::Key,
226 proof: &MerkleProof<Self::Entry, Self::Key, Self::T, 8>,
227 ) -> anyhow::Result<()> {
228 match proof.elem() {
229 Some(elem) => self.remember(key, elem, proof)?,
230 None => self.non_membership_remember(key, proof)?,
231 }
232 Ok(())
233 }
234}