1use time::{Duration, OffsetDateTime};
4
5use crate::{
6 crypto::{AlgorithmType, PublicKey},
7 model, utils,
8};
9
10pub struct Genesis<AppState> {
12 pub genesis_time: OffsetDateTime,
14
15 pub chain_id: String,
17
18 pub initial_height: i64,
20
21 pub consensus_params: ConsensusParams,
23
24 pub validators: Vec<ValidatorInfo>,
26
27 pub app_hash: Vec<u8>,
29
30 pub app_state: Option<AppState>,
32}
33
34pub struct ConsensusParams {
35 pub block: Block,
37
38 pub evidence: Evidence,
40
41 pub validator: Validator,
43
44 pub version: Version,
46}
47
48pub struct Block {
50 pub max_bytes: u64,
52
53 pub max_gas: i64,
55
56 pub time_iota_ms: i64,
58}
59
60pub struct Evidence {
61 pub max_age_num_blocks: u64,
63
64 pub max_age_duration: Duration,
66
67 pub max_bytes: i64,
69}
70
71pub struct Validator {
72 pub pub_key_types: Vec<AlgorithmType>,
73}
74
75pub struct Version {
76 pub app_version: Option<u64>,
77}
78
79pub struct ValidatorInfo {
80 pub address: [u8; 20],
81
82 pub public_key: PublicKey,
83
84 pub power: u64,
86
87 pub name: Option<String>,
89
90 pub proposer_priority: i64,
92}
93
94impl ValidatorInfo {
95 pub fn generate(public_key: PublicKey) -> Self {
96 Self {
97 address: public_key.address(),
98 public_key,
99 power: 10,
100 name: None,
101 proposer_priority: 0,
102 }
103 }
104}
105
106impl<AppState> Genesis<AppState> {
107 pub fn generate(public_key: PublicKey) -> Genesis<()> {
108 let block = Block {
109 max_bytes: 22020096,
110 max_gas: -1,
111 time_iota_ms: 1000,
112 };
113
114 let evidence = Evidence {
115 max_age_num_blocks: 100000,
116 max_age_duration: Duration::days(2000),
117 max_bytes: 1048576,
118 };
119
120 let validator = Validator {
121 pub_key_types: vec![AlgorithmType::Ed25519],
122 };
123
124 let consensus_params = ConsensusParams {
125 block,
126 evidence,
127 validator,
128 version: Version { app_version: None },
129 };
130
131 let chain_id = String::from("test-chain");
132
133 let validator_info = ValidatorInfo::generate(public_key);
134
135 Genesis {
136 genesis_time: OffsetDateTime::now_utc(),
137 chain_id,
138 initial_height: 0,
139 consensus_params,
140 validators: vec![validator_info],
141 app_hash: Vec::new(),
142 app_state: None,
143 }
144 }
145
146 pub(crate) fn into_model(self) -> model::Genesis<AppState> {
147 let mut validators = Vec::with_capacity(self.validators.len());
148
149 for v in self.validators {
150 let vi = model::ValidatorInfo {
151 address: hex::encode(v.address),
152 pub_key: v.public_key.into_model(),
153 power: format!("{}", v.power),
154 name: v.name,
155 proposer_priority: format!("{}", v.proposer_priority),
156 };
157
158 validators.push(vi);
159 }
160
161 let block = model::BlockSize {
162 max_bytes: format!("{}", self.consensus_params.block.max_bytes),
163 max_gas: format!("{}", self.consensus_params.block.max_gas),
164 time_iota_ms: format!("{}", self.consensus_params.block.time_iota_ms),
165 };
166
167 let evidence = model::EvidenceParams {
168 max_bytes: format!("{}", self.consensus_params.evidence.max_bytes),
169 max_age_duration: format!(
170 "{}",
171 self.consensus_params
172 .evidence
173 .max_age_duration
174 .whole_seconds()
175 ),
176 max_age_num_blocks: format!("{}", self.consensus_params.evidence.max_age_num_blocks),
177 };
178
179 let validator = model::ValidatorParams {
180 pub_key_types: self
181 .consensus_params
182 .validator
183 .pub_key_types
184 .into_iter()
185 .map(|e| e.into())
186 .collect(),
187 };
188
189 let version = model::VersionParams {
190 app_version: self
191 .consensus_params
192 .version
193 .app_version
194 .map(|e| format!("{}", e)),
195 };
196
197 let consensus_params = model::ConsensusParams {
198 block,
199 evidence,
200 validator,
201 version,
202 };
203
204 model::Genesis {
205 chain_id: self.chain_id,
206 genesis_time: utils::to_rfc3339_nanos(self.genesis_time),
207 initial_height: format!("{}", self.initial_height),
208 app_hash: hex::encode(self.app_hash),
209 validators,
210 consensus_params,
211 app_state: self.app_state,
212 }
213 }
214}