@@ -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,37 @@ 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 ( ) ;
135- if term_changed {
136- len += TERM_LEN ;
137- }
138-
139146 let params_changed = self . seq != 0 ;
140- if params_changed {
141- if !term_changed {
142- len += TERM_LEN ;
147+ let term_params_exist = self . term_params . is_some ( ) ;
148+
149+ let mut len = INITIAL_LEN ;
150+ // Clippy complain how `let mut len` statements are constructed,
151+ // but their alternative is uglier
152+ #[ allow( clippy:: useless_let_if_seq) ]
153+ {
154+ if term_changed {
155+ len = TERM_LEN ;
156+ }
157+ if params_changed {
158+ len = PARAMS_LEN ;
159+ }
160+ if term_params_exist {
161+ if !params_changed {
162+ panic ! ( "Term params only can be changed if params changed" ) ;
163+ }
164+ len = TERM_PARAMS_LEN ;
143165 }
144- len += PARAMS_LEN ;
145166 }
167+
146168 s. begin_list ( len)
147169 . append ( & PREFIX )
148170 . append ( & self . number_of_shards )
@@ -159,48 +181,63 @@ impl Encodable for Metadata {
159181 }
160182 s. append ( & self . seq ) . append ( self . params . as_ref ( ) . unwrap ( ) ) ;
161183 }
184+ if term_params_exist {
185+ if !params_changed {
186+ unreachable ! ( "Term params only can be changed if params changed" ) ;
187+ }
188+ s. append ( self . term_params . as_ref ( ) . unwrap ( ) ) ;
189+ }
162190 }
163191}
164192
165193impl Decodable for Metadata {
166194 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- } ;
195+ let item_count = rlp. item_count ( ) ?;
196+ if !VALID_LEN . contains ( & item_count) {
197+ return Err ( DecoderError :: RlpInvalidLength {
198+ got : item_count,
199+ expected : 4 ,
200+ } )
201+ }
202+
192203 let prefix = rlp. val_at :: < u8 > ( 0 ) ?;
193204 if PREFIX != prefix {
194205 cdebug ! ( STATE , "{} is not an expected prefix for asset" , prefix) ;
195206 return Err ( DecoderError :: Custom ( "Unexpected prefix" ) )
196207 }
208+ let number_of_shards = rlp. val_at ( 1 ) ?;
209+ let number_of_initial_shards = rlp. val_at ( 2 ) ?;
210+ let hashes = rlp. list_at ( 3 ) ?;
211+
212+ let term = if item_count >= TERM_LEN {
213+ TermMetadata {
214+ last_term_finished_block_num : rlp. val_at ( 4 ) ?,
215+ current_term_id : rlp. val_at ( 5 ) ?,
216+ }
217+ } else {
218+ TermMetadata :: default ( )
219+ } ;
220+
221+ let ( seq, params) = if item_count >= PARAMS_LEN {
222+ ( rlp. val_at ( 6 ) ?, Some ( rlp. val_at ( 7 ) ?) )
223+ } else {
224+ Default :: default ( )
225+ } ;
226+
227+ let term_params = if item_count >= TERM_PARAMS_LEN {
228+ Some ( rlp. val_at ( 8 ) ?)
229+ } else {
230+ Default :: default ( )
231+ } ;
232+
197233 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 ) ? ,
234+ number_of_shards,
235+ number_of_initial_shards,
236+ hashes,
201237 term,
202238 seq,
203239 params,
240+ term_params,
204241 } )
205242 }
206243}
@@ -266,6 +303,7 @@ mod tests {
266303 term : Default :: default ( ) ,
267304 seq : 0 ,
268305 params : None ,
306+ term_params : None ,
269307 } ;
270308 let mut rlp = RlpStream :: new_list ( 4 ) ;
271309 rlp. append ( & PREFIX ) . append ( & 10u16 ) . append ( & 1u16 ) . append_list :: < H256 , H256 > ( & [ ] ) ;
@@ -281,6 +319,7 @@ mod tests {
281319 term : Default :: default ( ) ,
282320 seq : 3 ,
283321 params : Some ( CommonParams :: default_for_test ( ) ) ,
322+ term_params : Some ( CommonParams :: default_for_test ( ) ) ,
284323 } ;
285324 rlp_encode_and_decode_test ! ( metadata) ;
286325 }
@@ -297,6 +336,7 @@ mod tests {
297336 } ,
298337 seq : 0 ,
299338 params : None ,
339+ term_params : None ,
300340 } ;
301341 rlp_encode_and_decode_test ! ( metadata) ;
302342 }
@@ -313,6 +353,24 @@ mod tests {
313353 } ,
314354 seq : 3 ,
315355 params : Some ( CommonParams :: default_for_test ( ) ) ,
356+ term_params : Some ( CommonParams :: default_for_test ( ) ) ,
357+ } ;
358+ rlp_encode_and_decode_test ! ( metadata) ;
359+ }
360+
361+ #[ test]
362+ fn metadata_with_term_and_seq_but_not_term_params ( ) {
363+ let metadata = Metadata {
364+ number_of_shards : 10 ,
365+ number_of_initial_shards : 1 ,
366+ hashes : vec ! [ ] ,
367+ term : TermMetadata {
368+ last_term_finished_block_num : 1 ,
369+ current_term_id : 100 ,
370+ } ,
371+ seq : 3 ,
372+ params : Some ( CommonParams :: default_for_test ( ) ) ,
373+ term_params : None ,
316374 } ;
317375 rlp_encode_and_decode_test ! ( metadata) ;
318376 }
0 commit comments