@@ -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,31 @@ 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 len = if term_params_exist {
150+ if !params_changed {
151+ panic ! ( "Term params only can be changed if params changed" ) ;
143152 }
144- len += PARAMS_LEN ;
145- }
153+ TERM_PARAMS_LEN
154+ } else if params_changed {
155+ PARAMS_LEN
156+ } else if term_changed {
157+ TERM_LEN
158+ } else {
159+ INITIAL_LEN
160+ } ;
161+
146162 s. begin_list ( len)
147163 . append ( & PREFIX )
148164 . append ( & self . number_of_shards )
@@ -159,48 +175,63 @@ impl Encodable for Metadata {
159175 }
160176 s. append ( & self . seq ) . append ( self . params . as_ref ( ) . unwrap ( ) ) ;
161177 }
178+ if term_params_exist {
179+ if !params_changed {
180+ unreachable ! ( "Term params only can be changed if params changed" ) ;
181+ }
182+ s. append ( self . term_params . as_ref ( ) . unwrap ( ) ) ;
183+ }
162184 }
163185}
164186
165187impl Decodable for Metadata {
166188 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- } ;
189+ let item_count = rlp. item_count ( ) ?;
190+ if !VALID_LEN . contains ( & item_count) {
191+ return Err ( DecoderError :: RlpInvalidLength {
192+ got : item_count,
193+ expected : 4 ,
194+ } )
195+ }
196+
192197 let prefix = rlp. val_at :: < u8 > ( 0 ) ?;
193198 if PREFIX != prefix {
194199 cdebug ! ( STATE , "{} is not an expected prefix for asset" , prefix) ;
195200 return Err ( DecoderError :: Custom ( "Unexpected prefix" ) )
196201 }
202+ let number_of_shards = rlp. val_at ( 1 ) ?;
203+ let number_of_initial_shards = rlp. val_at ( 2 ) ?;
204+ let hashes = rlp. list_at ( 3 ) ?;
205+
206+ let term = if item_count >= TERM_LEN {
207+ TermMetadata {
208+ last_term_finished_block_num : rlp. val_at ( 4 ) ?,
209+ current_term_id : rlp. val_at ( 5 ) ?,
210+ }
211+ } else {
212+ TermMetadata :: default ( )
213+ } ;
214+
215+ let ( seq, params) = if item_count >= PARAMS_LEN {
216+ ( rlp. val_at ( 6 ) ?, Some ( rlp. val_at ( 7 ) ?) )
217+ } else {
218+ Default :: default ( )
219+ } ;
220+
221+ let term_params = if item_count >= TERM_PARAMS_LEN {
222+ Some ( rlp. val_at ( 8 ) ?)
223+ } else {
224+ Default :: default ( )
225+ } ;
226+
197227 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 ) ? ,
228+ number_of_shards,
229+ number_of_initial_shards,
230+ hashes,
201231 term,
202232 seq,
203233 params,
234+ term_params,
204235 } )
205236 }
206237}
@@ -266,6 +297,7 @@ mod tests {
266297 term : Default :: default ( ) ,
267298 seq : 0 ,
268299 params : None ,
300+ term_params : None ,
269301 } ;
270302 let mut rlp = RlpStream :: new_list ( 4 ) ;
271303 rlp. append ( & PREFIX ) . append ( & 10u16 ) . append ( & 1u16 ) . append_list :: < H256 , H256 > ( & [ ] ) ;
@@ -281,6 +313,7 @@ mod tests {
281313 term : Default :: default ( ) ,
282314 seq : 3 ,
283315 params : Some ( CommonParams :: default_for_test ( ) ) ,
316+ term_params : Some ( CommonParams :: default_for_test ( ) ) ,
284317 } ;
285318 rlp_encode_and_decode_test ! ( metadata) ;
286319 }
@@ -297,6 +330,7 @@ mod tests {
297330 } ,
298331 seq : 0 ,
299332 params : None ,
333+ term_params : None ,
300334 } ;
301335 rlp_encode_and_decode_test ! ( metadata) ;
302336 }
@@ -313,6 +347,24 @@ mod tests {
313347 } ,
314348 seq : 3 ,
315349 params : Some ( CommonParams :: default_for_test ( ) ) ,
350+ term_params : Some ( CommonParams :: default_for_test ( ) ) ,
351+ } ;
352+ rlp_encode_and_decode_test ! ( metadata) ;
353+ }
354+
355+ #[ test]
356+ fn metadata_with_term_and_seq_but_not_term_params ( ) {
357+ let metadata = Metadata {
358+ number_of_shards : 10 ,
359+ number_of_initial_shards : 1 ,
360+ hashes : vec ! [ ] ,
361+ term : TermMetadata {
362+ last_term_finished_block_num : 1 ,
363+ current_term_id : 100 ,
364+ } ,
365+ seq : 3 ,
366+ params : Some ( CommonParams :: default_for_test ( ) ) ,
367+ term_params : None ,
316368 } ;
317369 rlp_encode_and_decode_test ! ( metadata) ;
318370 }
0 commit comments