@@ -30,7 +30,9 @@ use super::super::consensus::{CodeChainEngine, NullEngine, Solo, SoloAuthority,
3030use super :: super :: error:: Error ;
3131use super :: super :: header:: Header ;
3232use super :: super :: pod_state:: { PodAccounts , PodShards } ;
33- use super :: super :: state:: { Backend , BasicBackend } ;
33+ use super :: super :: state:: {
34+ Backend , BasicBackend , Metadata , MetadataAddress , Shard , ShardAddress , ShardMetadataAddress ,
35+ } ;
3436use super :: seal:: Generic as GenericSeal ;
3537use super :: Genesis ;
3638
@@ -131,9 +133,21 @@ impl Spec {
131133 }
132134 }
133135
134- fn initialize_accounts < DB : Backend > ( & self , trie_factory : & TrieFactory , mut db : DB ) -> Result < DB , Error > {
135- let mut root = BLAKE_NULL_RLP ;
136+ fn initialize_state < DB : Backend > ( & self , trie_factory : & TrieFactory , db : DB ) -> Result < DB , Error > {
137+ let root = BLAKE_NULL_RLP ;
138+ let ( db, root) = self . initialize_accounts ( trie_factory, db, root) ?;
139+ let ( db, root) = self . initialize_shards ( trie_factory, db, root) ?;
136140
141+ * self . state_root_memo . write ( ) = root;
142+ Ok ( db)
143+ }
144+
145+ fn initialize_accounts < DB : Backend > (
146+ & self ,
147+ trie_factory : & TrieFactory ,
148+ mut db : DB ,
149+ mut root : H256 ,
150+ ) -> Result < ( DB , H256 ) , Error > {
137151 // basic accounts in spec.
138152 {
139153 let mut t = trie_factory. create ( db. as_hashdb_mut ( ) , & mut root) ;
@@ -145,8 +159,63 @@ impl Spec {
145159 }
146160 }
147161
148- * self . state_root_memo . write ( ) = root;
149- Ok ( db)
162+ Ok ( ( db, root) )
163+ }
164+
165+ fn initialize_shards < DB : Backend > (
166+ & self ,
167+ trie_factory : & TrieFactory ,
168+ mut db : DB ,
169+ mut root : H256 ,
170+ ) -> Result < ( DB , H256 ) , Error > {
171+ let mut shard_roots = Vec :: < ( u32 , H256 ) > :: with_capacity ( self . genesis_shards . len ( ) ) ;
172+
173+ // Initialize shard-level tries
174+ for ( shard_id, shard) in & * self . genesis_shards {
175+ let mut shard_root = BLAKE_NULL_RLP ;
176+
177+ {
178+ let mut t = trie_factory. from_existing ( db. as_hashdb_mut ( ) , & mut shard_root) ?;
179+ let address = ShardMetadataAddress :: new ( * shard_id) ;
180+
181+ let r = t. insert ( & * address, & shard. rlp_bytes ( ) ) ;
182+ debug_assert_eq ! ( Ok ( None ) , r) ;
183+ r?;
184+ }
185+ shard_roots. push ( ( * shard_id, shard_root) ) ;
186+ }
187+
188+ debug_assert ! (
189+ shard_roots. len( ) <= :: std:: u32 :: MAX as usize ,
190+ "{} <= {}" ,
191+ shard_roots. len( ) ,
192+ :: std:: u32 :: MAX as usize
193+ ) ;
194+ let global_metadata = Metadata :: new ( shard_roots. len ( ) as u32 ) ;
195+
196+ // Initialize shards
197+ for ( shard_id, shard_root) in shard_roots. into_iter ( ) {
198+ {
199+ let mut t = trie_factory. from_existing ( db. as_hashdb_mut ( ) , & mut root) ?;
200+ let address = ShardAddress :: new ( shard_id) ;
201+
202+ let shard = Shard :: new ( shard_root) ;
203+ let r = t. insert ( & * address, & shard. rlp_bytes ( ) ) ;
204+ debug_assert_eq ! ( Ok ( None ) , r) ;
205+ r?;
206+ }
207+ }
208+
209+ {
210+ let mut t = trie_factory. from_existing ( db. as_hashdb_mut ( ) , & mut root) ?;
211+ let address = MetadataAddress :: new ( ) ;
212+
213+ let r = t. insert ( & * address, & global_metadata. rlp_bytes ( ) ) ;
214+ debug_assert_eq ! ( Ok ( None ) , r) ;
215+ r?;
216+ }
217+
218+ Ok ( ( db, root) )
150219 }
151220
152221 /// Ensure that the given state DB has the trie nodes in for the genesis state.
@@ -155,8 +224,7 @@ impl Spec {
155224 return Ok ( db)
156225 }
157226
158- let db = self . initialize_accounts ( trie_factory, db) ?;
159- Ok ( db)
227+ Ok ( self . initialize_state ( trie_factory, db) ?)
160228 }
161229
162230 /// Return the state root for the genesis state, memoising accordingly.
@@ -259,7 +327,9 @@ fn load_from(s: cjson::spec::Spec) -> Result<Spec, Error> {
259327 match g. state_root {
260328 Some ( root) => * s. state_root_memo . get_mut ( ) = root,
261329 None => {
262- let _ = s. initialize_accounts ( & TrieFactory :: new ( Default :: default ( ) ) , BasicBackend ( MemoryDB :: new ( ) ) ) ?;
330+ let db = BasicBackend ( MemoryDB :: new ( ) ) ;
331+ let trie_factory = TrieFactory :: new ( Default :: default ( ) ) ;
332+ let _ = s. initialize_state ( & trie_factory, db) ?;
263333 }
264334 }
265335
0 commit comments