hotshot_contract_adapter/
light_client.rs

1//! Helpers and test mocks for Light Client logic
2
3use alloy::primitives::U256;
4use ark_ff::PrimeField;
5use hotshot_types::light_client::{GenericLightClientState, GenericStakeTableState};
6use rand::Rng;
7
8use crate::{
9    field_to_u256,
10    sol_types::{LightClient, LightClientStateSol, StakeTableStateSol},
11    u256_to_field,
12};
13
14impl LightClientStateSol {
15    /// Return a dummy new genesis that will pass constructor/initializer sanity checks
16    /// in the contract.
17    ///
18    /// # Warning
19    /// NEVER use this for production, this is test only.
20    pub fn dummy_genesis() -> Self {
21        Self {
22            viewNum: 0,
23            blockHeight: 0,
24            blockCommRoot: U256::from(42),
25        }
26    }
27
28    /// Return a random value
29    pub fn rand<R: Rng>(rng: &mut R) -> Self {
30        Self {
31            viewNum: rng.gen::<u64>(),
32            blockHeight: rng.gen::<u64>(),
33            blockCommRoot: U256::from_limbs(rng.gen::<[u64; 4]>()),
34        }
35    }
36}
37
38impl From<LightClient::finalizedStateReturn> for LightClientStateSol {
39    fn from(v: LightClient::finalizedStateReturn) -> Self {
40        let tuple: (u64, u64, U256) = v.into();
41        tuple.into()
42    }
43}
44
45impl<F: PrimeField> From<LightClientStateSol> for GenericLightClientState<F> {
46    fn from(v: LightClientStateSol) -> Self {
47        Self {
48            view_number: v.viewNum,
49            block_height: v.blockHeight,
50            block_comm_root: u256_to_field(v.blockCommRoot),
51        }
52    }
53}
54
55impl<F: PrimeField> From<GenericLightClientState<F>> for LightClientStateSol {
56    fn from(v: GenericLightClientState<F>) -> Self {
57        Self {
58            viewNum: v.view_number,
59            blockHeight: v.block_height,
60            blockCommRoot: field_to_u256(v.block_comm_root),
61        }
62    }
63}
64
65impl StakeTableStateSol {
66    /// Return a dummy new genesis stake state that will pass constructor/initializer sanity checks
67    /// in the contract.
68    ///
69    /// # Warning
70    /// NEVER use this for production, this is test only.
71    pub fn dummy_genesis() -> Self {
72        Self {
73            threshold: U256::from(1),
74            blsKeyComm: U256::from(123),
75            schnorrKeyComm: U256::from(123),
76            amountComm: U256::from(20),
77        }
78    }
79
80    /// Returns a random value
81    pub fn rand<R: Rng>(rng: &mut R) -> Self {
82        Self {
83            threshold: U256::from_limbs(rng.gen::<[u64; 4]>()),
84            blsKeyComm: U256::from_limbs(rng.gen::<[u64; 4]>()),
85            schnorrKeyComm: U256::from_limbs(rng.gen::<[u64; 4]>()),
86            amountComm: U256::from_limbs(rng.gen::<[u64; 4]>()),
87        }
88    }
89}
90
91impl From<LightClient::genesisStakeTableStateReturn> for StakeTableStateSol {
92    fn from(v: LightClient::genesisStakeTableStateReturn) -> Self {
93        let tuple: (U256, U256, U256, U256) = v.into();
94        tuple.into()
95    }
96}
97
98impl<F: PrimeField> From<StakeTableStateSol> for GenericStakeTableState<F> {
99    fn from(s: StakeTableStateSol) -> Self {
100        Self {
101            threshold: u256_to_field(s.threshold),
102            bls_key_comm: u256_to_field(s.blsKeyComm),
103            schnorr_key_comm: u256_to_field(s.schnorrKeyComm),
104            amount_comm: u256_to_field(s.amountComm),
105        }
106    }
107}
108
109impl<F: PrimeField> From<GenericStakeTableState<F>> for StakeTableStateSol {
110    fn from(v: GenericStakeTableState<F>) -> Self {
111        Self {
112            blsKeyComm: field_to_u256(v.bls_key_comm),
113            schnorrKeyComm: field_to_u256(v.schnorr_key_comm),
114            amountComm: field_to_u256(v.amount_comm),
115            threshold: field_to_u256(v.threshold),
116        }
117    }
118}