hotshot_query_service/testing/
mocks.rs

1// Copyright (c) 2022 Espresso Systems (espressosys.com)
2// This file is part of the HotShot Query Service library.
3//
4// This program is free software: you can redistribute it and/or modify it under the terms of the GNU
5// General Public License as published by the Free Software Foundation, either version 3 of the
6// License, or (at your option) any later version.
7// This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without
8// even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
9// General Public License for more details.
10// You should have received a copy of the GNU General Public License along with this program. If not,
11// see <https://www.gnu.org/licenses/>.
12
13use hotshot::traits::{implementations::MemoryNetwork, NodeImplementation};
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, ViewNumber},
22    signature_key::{BLSPubKey, SchnorrPubKey},
23    traits::node_implementation::{NodeType, Versions},
24};
25use jf_merkle_tree_compat::{
26    prelude::{MerkleProof, Sha3Digest, Sha3Node},
27    universal_merkle_tree::UniversalMerkleTree,
28    ForgetableMerkleTreeScheme, ForgetableUniversalMerkleTreeScheme,
29};
30use serde::{Deserialize, Serialize};
31use vbs::version::StaticVersion;
32
33use crate::{
34    availability::{
35        QueryableHeader, QueryablePayload, TransactionIndex, VerifiableInclusion,
36        VidCommonQueryData,
37    },
38    explorer::traits::{ExplorerHeader, ExplorerTransaction},
39    merklized_state::MerklizedState,
40    types::HeightIndexed,
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        // Test types only support a single namespace.
57        if *i == 0 {
58            Some(0)
59        } else {
60            None
61        }
62    }
63
64    fn namespace_size(&self, i: &i64, payload_size: usize) -> u64 {
65        // Test types only support a single namespace.
66        if *i == 0 {
67            payload_size as u64
68        } else {
69            0
70        }
71    }
72}
73
74impl ExplorerHeader<MockTypes> for MockHeader {
75    type BalanceAmount = i128;
76    type WalletAddress = [u8; 32];
77    type ProposerId = [u8; 32];
78
79    fn proposer_id(&self) -> Self::ProposerId {
80        [0; 32]
81    }
82
83    fn fee_info_account(&self) -> Self::WalletAddress {
84        [0; 32]
85    }
86
87    fn fee_info_balance(&self) -> Self::BalanceAmount {
88        0
89    }
90
91    fn reward_balance(&self) -> Self::BalanceAmount {
92        0
93    }
94
95    fn namespace_ids(&self) -> Vec<i64> {
96        vec![0]
97    }
98}
99
100impl ExplorerTransaction<MockTypes> for MockTransaction {
101    fn namespace_id(&self) -> i64 {
102        0
103    }
104
105    fn payload_size(&self) -> u64 {
106        self.bytes().len() as u64
107    }
108}
109
110impl HeightIndexed for MockHeader {
111    fn height(&self) -> u64 {
112        self.block_number
113    }
114}
115
116/// A naive inclusion proof for `MockPayload` and `MockTransaction`.
117#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
118pub struct MockInclusionProof(MockPayload);
119
120impl VerifiableInclusion<MockTypes> for MockInclusionProof {
121    fn verify(
122        &self,
123        _metadata: &TestMetadata,
124        tx: &MockTransaction,
125        _payload_commitment: &VidCommitment,
126        _common: &VidCommon,
127    ) -> bool {
128        self.0.transactions.contains(tx)
129    }
130}
131
132impl QueryablePayload<MockTypes> for MockPayload {
133    type Iter<'a> = <Vec<TransactionIndex<MockTypes>> as IntoIterator>::IntoIter;
134    type InclusionProof = MockInclusionProof;
135
136    fn len(&self, _meta: &Self::Metadata) -> usize {
137        self.transactions.len()
138    }
139
140    fn iter(&self, meta: &Self::Metadata) -> Self::Iter<'_> {
141        (0..<TestBlockPayload as QueryablePayload<MockTypes>>::len(self, meta))
142            .map(|i| TransactionIndex {
143                ns_index: 0,
144                position: i as u32,
145            })
146            .collect::<Vec<_>>()
147            .into_iter()
148    }
149
150    fn transaction(
151        &self,
152        _meta: &Self::Metadata,
153        index: &TransactionIndex<MockTypes>,
154    ) -> Option<Self::Transaction> {
155        self.transactions.get(index.position as usize).cloned()
156    }
157
158    fn transaction_proof(
159        &self,
160        _meta: &Self::Metadata,
161        _vid: &VidCommonQueryData<MockTypes>,
162        _index: &TransactionIndex<MockTypes>,
163    ) -> Option<Self::InclusionProof> {
164        Some(MockInclusionProof(self.clone()))
165    }
166}
167
168#[derive(
169    Copy, Clone, Debug, Default, Hash, PartialEq, Eq, PartialOrd, Ord, Serialize, Deserialize,
170)]
171pub struct MockTypes;
172
173impl NodeType for MockTypes {
174    type View = ViewNumber;
175    type Epoch = ViewNumber;
176    type BlockHeader = MockHeader;
177    type BlockPayload = MockPayload;
178    type SignatureKey = BLSPubKey;
179    type Transaction = MockTransaction;
180    type InstanceState = TestInstanceState;
181    type ValidatedState = TestValidatedState;
182    type Membership = StrictMembership<MockTypes, StaticStakeTable<BLSPubKey, SchnorrPubKey>>;
183    type BuilderSignatureKey = BLSPubKey;
184    type StateSignatureKey = SchnorrPubKey;
185}
186
187#[derive(Clone, Debug, Copy)]
188pub struct MockVersions {}
189
190impl Versions for MockVersions {
191    type Base = StaticVersion<0, 1>;
192    type Upgrade = StaticVersion<0, 2>;
193    const UPGRADE_HASH: [u8; 32] = [
194        1, 0, 1, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0,
195        0, 0,
196    ];
197    type Epochs = StaticVersion<0, 4>;
198    type DrbAndHeaderUpgrade = StaticVersion<0, 5>;
199    type Vid2Upgrade = StaticVersion<0, 6>;
200}
201
202/// A type alias for the mock base version
203pub type MockBase = <MockVersions as Versions>::Base;
204
205pub type MockMembership = StrictMembership<MockTypes, StaticStakeTable<BLSPubKey, SchnorrPubKey>>;
206pub type MockQuorumProposal = QuorumProposal<MockTypes>;
207pub type MockNetwork = MemoryNetwork<BLSPubKey>;
208
209pub type MockStorage = TestStorage<MockTypes>;
210
211#[derive(
212    Copy, Clone, Debug, Default, Hash, PartialEq, Eq, PartialOrd, Ord, Serialize, Deserialize,
213)]
214pub struct MockNodeImpl;
215
216impl NodeImplementation<MockTypes> for MockNodeImpl {
217    type Network = MockNetwork;
218    type Storage = MockStorage;
219}
220
221pub type MockMerkleTree = UniversalMerkleTree<usize, Sha3Digest, usize, 8, Sha3Node>;
222
223impl MerklizedState<MockTypes, 8> for MockMerkleTree {
224    type Key = usize;
225    type Entry = usize;
226    type T = Sha3Node;
227    type Commit = Self::Commitment;
228    type Digest = Sha3Digest;
229
230    fn state_type() -> &'static str {
231        "test_tree"
232    }
233
234    fn header_state_commitment_field() -> &'static str {
235        "test_merkle_tree_root"
236    }
237
238    fn tree_height() -> usize {
239        12
240    }
241
242    fn insert_path(
243        &mut self,
244        key: Self::Key,
245        proof: &MerkleProof<Self::Entry, Self::Key, Self::T, 8>,
246    ) -> anyhow::Result<()> {
247        match proof.elem() {
248            Some(elem) => self.remember(key, elem, proof)?,
249            None => self.non_membership_remember(key, proof)?,
250        }
251        Ok(())
252    }
253}