simperby_core/
test_utils.rs

1use crate::*;
2
3pub fn generate_fi(member_number: usize) -> (FinalizationInfo, Vec<(PublicKey, PrivateKey)>) {
4    let (rs, keys) = generate_standard_genesis(member_number);
5    let fi = FinalizationInfo {
6        header: rs.genesis_info.header.clone(),
7        commit_hash: CommitHash::zero(),
8        proof: rs.genesis_info.genesis_proof.clone(),
9        reserved_state: rs,
10    };
11    (fi, keys)
12}
13
14/// Generates a standard test chain config returning the genesis reserved-state
15/// and the associated key pairs of the members.
16pub fn generate_standard_genesis(
17    member_number: usize,
18) -> (ReservedState, Vec<(PublicKey, PrivateKey)>) {
19    let keys = (0..member_number)
20        .map(|i| generate_keypair(format!("{i}")))
21        .collect::<Vec<_>>();
22    let members = keys
23        .iter()
24        .enumerate()
25        .map(|(i, (public_key, _))| Member {
26            public_key: public_key.clone(),
27            // lexicographically ordered
28            name: format!("member-{i:04}"),
29            governance_voting_power: 1,
30            consensus_voting_power: 1,
31            governance_delegatee: None,
32            consensus_delegatee: None,
33            expelled: false,
34        })
35        .collect::<Vec<_>>();
36    let genesis_header = BlockHeader {
37        author: PublicKey::zero(),
38        prev_block_finalization_proof: FinalizationProof::genesis(),
39        previous_hash: Hash256::zero(),
40        height: 0,
41        timestamp: 0,
42        commit_merkle_root: Hash256::zero(),
43        repository_merkle_root: Hash256::zero(),
44        validator_set: members
45            .iter()
46            .map(|member| (member.public_key.clone(), member.consensus_voting_power))
47            .collect::<Vec<_>>(),
48        version: SIMPERBY_CORE_PROTOCOL_VERSION.to_string(),
49    };
50    let genesis_info = GenesisInfo {
51        header: genesis_header.clone(),
52        genesis_proof: FinalizationProof {
53            round: 0,
54            signatures: keys
55                .iter()
56                .map(|(_, private_key)| {
57                    TypedSignature::sign(
58                        &FinalizationSignTarget {
59                            block_hash: genesis_header.to_hash256(),
60                            round: 0,
61                        },
62                        private_key,
63                    )
64                    .unwrap()
65                })
66                .collect::<Vec<_>>(),
67        },
68        chain_name: "test-chain".to_string(),
69    };
70    (
71        ReservedState {
72            genesis_info,
73            members,
74            consensus_leader_order: (0..member_number)
75                .map(|i| format!("member-{i:04}"))
76                .collect::<Vec<_>>(),
77            version: SIMPERBY_CORE_PROTOCOL_VERSION.to_string(),
78        },
79        keys,
80    )
81}
82
83/// Generates a standard test chain config returning the genesis reserved-state
84/// and the associated key pairs of the members.
85///
86/// member-0000 delegates to member-0002 for governance and consensus if `governance` is true and
87/// member-0000 delegates to member-0002 for consensus only if `governance` is false.
88pub fn generate_delegated_genesis(
89    member_number: usize,
90    governance: bool,
91) -> (ReservedState, Vec<(PublicKey, PrivateKey)>) {
92    let keys = (0..member_number)
93        .map(|i| generate_keypair(format!("{i}")))
94        .collect::<Vec<_>>();
95    // member-0000 delegates to member-0002
96    let members = keys
97        .iter()
98        .enumerate()
99        .map(|(i, (public_key, _))| Member {
100            public_key: public_key.clone(),
101            // lexicographically ordered
102            name: format!("member-{i:04}"),
103            governance_voting_power: 1,
104            consensus_voting_power: 1,
105            governance_delegatee: if i == 0 && governance {
106                Some("member-0002".into())
107            } else {
108                None
109            },
110            consensus_delegatee: if i == 0 {
111                Some("member-0002".into())
112            } else {
113                None
114            },
115            expelled: false,
116        })
117        .collect::<Vec<_>>();
118    let genesis_header = BlockHeader {
119        author: PublicKey::zero(),
120        prev_block_finalization_proof: FinalizationProof::genesis(),
121        previous_hash: Hash256::zero(),
122        height: 0,
123        timestamp: 0,
124        commit_merkle_root: Hash256::zero(),
125        repository_merkle_root: Hash256::zero(),
126        validator_set: members
127            .iter()
128            .map(|member| (member.public_key.clone(), member.consensus_voting_power))
129            .collect::<Vec<_>>(),
130        version: "0.1.0".to_string(),
131    };
132    let genesis_info = GenesisInfo {
133        header: genesis_header.clone(),
134        genesis_proof: FinalizationProof {
135            round: 0,
136            signatures: keys
137                .iter()
138                .map(|(_, private_key)| {
139                    TypedSignature::sign(
140                        &FinalizationSignTarget {
141                            block_hash: genesis_header.to_hash256(),
142                            round: 0,
143                        },
144                        private_key,
145                    )
146                    .unwrap()
147                })
148                .collect::<Vec<_>>(),
149        },
150        chain_name: "test-chain".to_string(),
151    };
152    (
153        ReservedState {
154            genesis_info,
155            members,
156            consensus_leader_order: (1..member_number)
157                .map(|i| format!("member-{i:04}"))
158                .collect::<Vec<_>>(),
159            version: "0.1.0".to_string(),
160        },
161        keys,
162    )
163}