sawtooth/journal/genesis/
builder.rs1use std::path::PathBuf;
19
20use cylinder::Signer;
21
22use crate::journal::block_manager::BlockManager;
23use crate::journal::chain::ChainObserver;
24use crate::journal::{chain::ChainReader, chain_id_manager::ChainIdManager};
25use crate::state::merkle::CborMerkleState;
26use crate::state::state_view_factory::StateViewFactory;
27use crate::transact::execution::executor::ExecutionTaskSubmitter;
28use crate::transact::scheduler::SchedulerFactory;
29
30use super::error::GenesisControllerBuildError;
31use super::GenesisController;
32
33const GENESIS_FILE: &str = "genesis.batch";
34
35#[derive(Default)]
37pub struct GenesisControllerBuilder {
38 transaction_executor: Option<ExecutionTaskSubmitter>,
39 scheduler_factory: Option<Box<dyn SchedulerFactory>>,
40 block_manager: Option<BlockManager>,
41 chain_reader: Option<Box<dyn ChainReader>>,
42 state_view_factory: Option<StateViewFactory>,
43 identity_signer: Option<Box<dyn Signer>>,
44 data_dir: Option<String>,
45 chain_id_manager: Option<ChainIdManager>,
46 observers: Option<Vec<Box<dyn ChainObserver>>>,
47 initial_state_root: Option<String>,
48 merkle_state: Option<CborMerkleState>,
49}
50
51impl GenesisControllerBuilder {
52 pub fn new() -> Self {
54 GenesisControllerBuilder::default()
55 }
56
57 pub fn with_transaction_executor(
58 mut self,
59 executor: ExecutionTaskSubmitter,
60 ) -> GenesisControllerBuilder {
61 self.transaction_executor = Some(executor);
62 self
63 }
64
65 pub fn with_scheduler_factory(
66 mut self,
67 scheduler_factory: Box<dyn SchedulerFactory>,
68 ) -> GenesisControllerBuilder {
69 self.scheduler_factory = Some(scheduler_factory);
70 self
71 }
72
73 pub fn with_block_manager(mut self, block_manager: BlockManager) -> GenesisControllerBuilder {
74 self.block_manager = Some(block_manager);
75 self
76 }
77
78 pub fn with_chain_reader(
79 mut self,
80 chain_reader: Box<dyn ChainReader>,
81 ) -> GenesisControllerBuilder {
82 self.chain_reader = Some(chain_reader);
83 self
84 }
85
86 pub fn with_state_view_factory(
87 mut self,
88 state_view_factory: StateViewFactory,
89 ) -> GenesisControllerBuilder {
90 self.state_view_factory = Some(state_view_factory);
91 self
92 }
93
94 pub fn with_data_dir(mut self, data_dir: String) -> GenesisControllerBuilder {
95 self.data_dir = Some(data_dir);
96 self
97 }
98
99 pub fn with_chain_id_manager(
100 mut self,
101 chain_id_manager: ChainIdManager,
102 ) -> GenesisControllerBuilder {
103 self.chain_id_manager = Some(chain_id_manager);
104 self
105 }
106
107 pub fn with_observers(
108 mut self,
109 observers: Vec<Box<dyn ChainObserver>>,
110 ) -> GenesisControllerBuilder {
111 self.observers = Some(observers);
112 self
113 }
114
115 pub fn with_initial_state_root(
116 mut self,
117 initial_state_root: String,
118 ) -> GenesisControllerBuilder {
119 self.initial_state_root = Some(initial_state_root);
120 self
121 }
122
123 pub fn with_merkle_state(mut self, merkle_state: CborMerkleState) -> GenesisControllerBuilder {
124 self.merkle_state = Some(merkle_state);
125 self
126 }
127
128 pub fn with_identity_signer(
129 mut self,
130 identity_signer: Box<dyn Signer>,
131 ) -> GenesisControllerBuilder {
132 self.identity_signer = Some(identity_signer);
133 self
134 }
135
136 pub fn build(self) -> Result<GenesisController, GenesisControllerBuildError> {
140 let transaction_executor = self.transaction_executor.ok_or_else(|| {
141 GenesisControllerBuildError::MissingField(
142 "'transaction_executor' field is required".to_string(),
143 )
144 })?;
145
146 let scheduler_factory = self.scheduler_factory.ok_or_else(|| {
147 GenesisControllerBuildError::MissingField(
148 "'scheduler_factory' field is required".to_string(),
149 )
150 })?;
151
152 let block_manager = self.block_manager.ok_or_else(|| {
153 GenesisControllerBuildError::MissingField(
154 "'block_manager' field is required".to_string(),
155 )
156 })?;
157
158 let chain_reader = self.chain_reader.ok_or_else(|| {
159 GenesisControllerBuildError::MissingField(
160 "'chain_reader' field is required".to_string(),
161 )
162 })?;
163
164 let state_view_factory = self.state_view_factory.ok_or_else(|| {
165 GenesisControllerBuildError::MissingField(
166 "'state_view_factory' field is required".to_string(),
167 )
168 })?;
169
170 let data_dir = self.data_dir.ok_or_else(|| {
171 GenesisControllerBuildError::MissingField("'data_dir' field is required".to_string())
172 })?;
173
174 let chain_id_manager = self.chain_id_manager.ok_or_else(|| {
175 GenesisControllerBuildError::MissingField(
176 "'chain_id_manager' field is required".to_string(),
177 )
178 })?;
179
180 let observers = self.observers.ok_or_else(|| {
181 GenesisControllerBuildError::MissingField("'observers' field is required".to_string())
182 })?;
183
184 let initial_state_root = self.initial_state_root.ok_or_else(|| {
185 GenesisControllerBuildError::MissingField(
186 "'initial_state_root' field is required".to_string(),
187 )
188 })?;
189
190 let merkle_state = self.merkle_state.ok_or_else(|| {
191 GenesisControllerBuildError::MissingField(
192 "'merkle_state' field is required".to_string(),
193 )
194 })?;
195
196 let identity_signer = self.identity_signer.ok_or_else(|| {
197 GenesisControllerBuildError::MissingField(
198 "'identity_signer' field is required".to_string(),
199 )
200 })?;
201
202 let mut genesis_path_buf = PathBuf::from(data_dir);
203 genesis_path_buf.push(GENESIS_FILE);
204
205 Ok(GenesisController {
206 transaction_executor,
207 scheduler_factory,
208 block_manager,
209 chain_reader,
210 state_view_factory,
211 identity_signer,
212 chain_id_manager,
213 observers,
214 genesis_file_path: genesis_path_buf,
215 initial_state_root,
216 merkle_state,
217 })
218 }
219}