@@ -34,6 +34,7 @@ pub struct Metadata {
3434 term : TermMetadata ,
3535 seq : u64 ,
3636 params : Option < CommonParams > ,
37+ term_params : Option < CommonParams > ,
3738}
3839
3940impl Metadata {
@@ -45,6 +46,7 @@ impl Metadata {
4546 term : Default :: default ( ) ,
4647 seq : 0 ,
4748 params : None ,
49+ term_params : None ,
4850 }
4951 }
5052
@@ -93,6 +95,14 @@ impl Metadata {
9395 self . params = Some ( params) ;
9496 }
9597
98+ pub fn term_params ( & self ) -> Option < & CommonParams > {
99+ self . term_params . as_ref ( )
100+ }
101+
102+ pub fn snapshot_term_params ( & mut self ) {
103+ self . term_params = self . params ;
104+ }
105+
96106 pub fn increase_term_id ( & mut self , last_term_finished_block_num : u64 ) {
97107 assert ! ( self . term. last_term_finished_block_num < last_term_finished_block_num) ;
98108 self . term . last_term_finished_block_num = last_term_finished_block_num;
@@ -124,25 +134,32 @@ impl CacheableItem for Metadata {
124134
125135const PREFIX : u8 = super :: METADATA_PREFIX ;
126136
137+ const INITIAL_LEN : usize = 4 ;
138+ const TERM_LEN : usize = INITIAL_LEN + 2 ;
139+ const PARAMS_LEN : usize = TERM_LEN + 2 ;
140+ const TERM_PARAMS_LEN : usize = PARAMS_LEN + 1 ;
141+ const VALID_LEN : & [ usize ] = & [ INITIAL_LEN , TERM_LEN , PARAMS_LEN , TERM_PARAMS_LEN ] ;
142+
127143impl Encodable for Metadata {
128144 fn rlp_append ( & self , s : & mut RlpStream ) {
129- const INITIAL_LEN : usize = 4 ;
130- const TERM_LEN : usize = 2 ;
131- const PARAMS_LEN : usize = 2 ;
132- let mut len = INITIAL_LEN ;
133-
134145 let term_changed = self . term != Default :: default ( ) ;
146+ let params_changed = self . seq != 0 ;
147+ let term_params_exist = self . term_params . is_some ( ) ;
148+
149+ let mut len = INITIAL_LEN ;
135150 if term_changed {
136- len + = TERM_LEN ;
151+ len = TERM_LEN ;
137152 }
138-
139- let params_changed = self . seq != 0 ;
140153 if params_changed {
141- if !term_changed {
142- len += TERM_LEN ;
154+ len = PARAMS_LEN ;
155+ }
156+ if term_params_exist {
157+ if !params_changed {
158+ panic ! ( "Term params only can be changed if params changed" ) ;
143159 }
144- len += PARAMS_LEN ;
160+ len = TERM_PARAMS_LEN ;
145161 }
162+
146163 s. begin_list ( len)
147164 . append ( & PREFIX )
148165 . append ( & self . number_of_shards )
@@ -159,48 +176,63 @@ impl Encodable for Metadata {
159176 }
160177 s. append ( & self . seq ) . append ( self . params . as_ref ( ) . unwrap ( ) ) ;
161178 }
179+ if term_params_exist {
180+ if !params_changed {
181+ unreachable ! ( "Term params only can be changed if params changed" ) ;
182+ }
183+ s. append ( self . term_params . as_ref ( ) . unwrap ( ) ) ;
184+ }
162185 }
163186}
164187
165188impl Decodable for Metadata {
166189 fn decode ( rlp : & Rlp ) -> Result < Self , DecoderError > {
167- let ( term, seq, params) = match rlp. item_count ( ) ? {
168- 4 => ( TermMetadata :: default ( ) , 0 , None ) ,
169- 6 => (
170- TermMetadata {
171- last_term_finished_block_num : rlp. val_at ( 4 ) ?,
172- current_term_id : rlp. val_at ( 5 ) ?,
173- } ,
174- 0 ,
175- None ,
176- ) ,
177- 8 => (
178- TermMetadata {
179- last_term_finished_block_num : rlp. val_at ( 4 ) ?,
180- current_term_id : rlp. val_at ( 5 ) ?,
181- } ,
182- rlp. val_at ( 6 ) ?,
183- Some ( rlp. val_at ( 7 ) ?) ,
184- ) ,
185- item_count => {
186- return Err ( DecoderError :: RlpInvalidLength {
187- got : item_count,
188- expected : 4 ,
189- } )
190- }
191- } ;
190+ let item_count = rlp. item_count ( ) ?;
191+ if !VALID_LEN . contains ( & item_count) {
192+ return Err ( DecoderError :: RlpInvalidLength {
193+ got : item_count,
194+ expected : 4 ,
195+ } )
196+ }
197+
192198 let prefix = rlp. val_at :: < u8 > ( 0 ) ?;
193199 if PREFIX != prefix {
194200 cdebug ! ( STATE , "{} is not an expected prefix for asset" , prefix) ;
195201 return Err ( DecoderError :: Custom ( "Unexpected prefix" ) )
196202 }
203+ let number_of_shards = rlp. val_at ( 1 ) ?;
204+ let number_of_initial_shards = rlp. val_at ( 2 ) ?;
205+ let hashes = rlp. list_at ( 3 ) ?;
206+
207+ let term = if item_count >= TERM_LEN {
208+ TermMetadata {
209+ last_term_finished_block_num : rlp. val_at ( 4 ) ?,
210+ current_term_id : rlp. val_at ( 5 ) ?,
211+ }
212+ } else {
213+ TermMetadata :: default ( )
214+ } ;
215+
216+ let ( seq, params) = if item_count >= PARAMS_LEN {
217+ ( rlp. val_at ( 6 ) ?, Some ( rlp. val_at ( 7 ) ?) )
218+ } else {
219+ Default :: default ( )
220+ } ;
221+
222+ let term_params = if item_count >= TERM_PARAMS_LEN {
223+ Some ( rlp. val_at ( 8 ) ?)
224+ } else {
225+ Default :: default ( )
226+ } ;
227+
197228 Ok ( Self {
198- number_of_shards : rlp . val_at ( 1 ) ? ,
199- number_of_initial_shards : rlp . val_at ( 2 ) ? ,
200- hashes : rlp . list_at ( 3 ) ? ,
229+ number_of_shards,
230+ number_of_initial_shards,
231+ hashes,
201232 term,
202233 seq,
203234 params,
235+ term_params,
204236 } )
205237 }
206238}
@@ -266,6 +298,7 @@ mod tests {
266298 term : Default :: default ( ) ,
267299 seq : 0 ,
268300 params : None ,
301+ term_params : None ,
269302 } ;
270303 let mut rlp = RlpStream :: new_list ( 4 ) ;
271304 rlp. append ( & PREFIX ) . append ( & 10u16 ) . append ( & 1u16 ) . append_list :: < H256 , H256 > ( & [ ] ) ;
@@ -281,6 +314,7 @@ mod tests {
281314 term : Default :: default ( ) ,
282315 seq : 3 ,
283316 params : Some ( CommonParams :: default_for_test ( ) ) ,
317+ term_params : Some ( CommonParams :: default_for_test ( ) ) ,
284318 } ;
285319 rlp_encode_and_decode_test ! ( metadata) ;
286320 }
@@ -297,6 +331,7 @@ mod tests {
297331 } ,
298332 seq : 0 ,
299333 params : None ,
334+ term_params : None ,
300335 } ;
301336 rlp_encode_and_decode_test ! ( metadata) ;
302337 }
@@ -313,6 +348,24 @@ mod tests {
313348 } ,
314349 seq : 3 ,
315350 params : Some ( CommonParams :: default_for_test ( ) ) ,
351+ term_params : Some ( CommonParams :: default_for_test ( ) ) ,
352+ } ;
353+ rlp_encode_and_decode_test ! ( metadata) ;
354+ }
355+
356+ #[ test]
357+ fn metadata_with_term_and_seq_but_not_term_params ( ) {
358+ let metadata = Metadata {
359+ number_of_shards : 10 ,
360+ number_of_initial_shards : 1 ,
361+ hashes : vec ! [ ] ,
362+ term : TermMetadata {
363+ last_term_finished_block_num : 1 ,
364+ current_term_id : 100 ,
365+ } ,
366+ seq : 3 ,
367+ params : Some ( CommonParams :: default_for_test ( ) ) ,
368+ term_params : None ,
316369 } ;
317370 rlp_encode_and_decode_test ! ( metadata) ;
318371 }
0 commit comments