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