@@ -21,11 +21,18 @@ use ctypes::{CommonParams, ShardId};
2121
2222use crate :: CacheableItem ;
2323
24+ #[ derive( Clone , Debug , Default , PartialEq ) ]
25+ struct TermMetadata {
26+ last_term_finished_block_num : u64 ,
27+ current_term_id : u64 ,
28+ }
29+
2430#[ derive( Clone , Debug , PartialEq ) ]
2531pub struct Metadata {
2632 number_of_shards : ShardId ,
2733 number_of_initial_shards : ShardId ,
2834 hashes : Vec < H256 > ,
35+ term : TermMetadata ,
2936 seq : usize ,
3037 params : Option < CommonParams > ,
3138}
@@ -36,6 +43,7 @@ impl Metadata {
3643 number_of_shards,
3744 number_of_initial_shards : number_of_shards,
3845 hashes : vec ! [ ] ,
46+ term : Default :: default ( ) ,
3947 seq : 0 ,
4048 params : None ,
4149 }
@@ -73,6 +81,13 @@ impl Metadata {
7381 pub fn params ( & self ) -> Option < & CommonParams > {
7482 self . params . as_ref ( )
7583 }
84+
85+ pub fn change_term ( & mut self , last_term_finished_block_num : u64 , current_term_id : u64 ) {
86+ assert ! ( self . term. last_term_finished_block_num < last_term_finished_block_num) ;
87+ assert ! ( self . term. current_term_id < current_term_id) ;
88+ self . term . last_term_finished_block_num = last_term_finished_block_num;
89+ self . term . current_term_id = current_term_id;
90+ }
7691}
7792
7893impl Default for Metadata {
@@ -93,28 +108,62 @@ const PREFIX: u8 = super::METADATA_PREFIX;
93108
94109impl Encodable for Metadata {
95110 fn rlp_append ( & self , s : & mut RlpStream ) {
111+ const INITIAL_LEN : usize = 4 ;
112+ const TERM_LEN : usize = 2 ;
113+ const PARAMS_LEN : usize = 2 ;
114+ let mut len = INITIAL_LEN ;
115+
116+ let term_changed = self . term != Default :: default ( ) ;
117+ if term_changed {
118+ len += TERM_LEN ;
119+ }
120+
96121 let params_changed = self . seq != 0 ;
97122 if params_changed {
98- s. begin_list ( 6 ) ;
99- } else {
100- s. begin_list ( 4 ) ;
123+ if !term_changed {
124+ len += TERM_LEN ;
125+ }
126+ len += PARAMS_LEN ;
101127 }
102- s. append ( & PREFIX )
128+ s. begin_list ( len)
129+ . append ( & PREFIX )
103130 . append ( & self . number_of_shards )
104131 . append ( & self . number_of_initial_shards )
105132 . append_list ( & self . hashes ) ;
133+ if term_changed {
134+ s. append ( & self . term . last_term_finished_block_num ) . append ( & self . term . current_term_id ) ;
135+ }
106136 if params_changed {
107- s. append ( & self . seq ) ;
108- s. append ( self . params . as_ref ( ) . unwrap ( ) ) ;
137+ if !term_changed {
138+ const DEFAULT_LAST_TERM_FINISHED_BLOCK_NUM : u64 = 0 ;
139+ const DEFAULT_CURRENT_TERM_ID : u64 = 0 ;
140+ s. append ( & DEFAULT_LAST_TERM_FINISHED_BLOCK_NUM ) . append ( & DEFAULT_CURRENT_TERM_ID ) ;
141+ }
142+ s. append ( & self . seq ) . append ( self . params . as_ref ( ) . unwrap ( ) ) ;
109143 }
110144 }
111145}
112146
113147impl Decodable for Metadata {
114148 fn decode ( rlp : & UntrustedRlp ) -> Result < Self , DecoderError > {
115- let ( seq, params) = match rlp. item_count ( ) ? {
116- 4 => ( 0 , None ) ,
117- 6 => ( rlp. val_at ( 4 ) ?, Some ( rlp. val_at ( 5 ) ?) ) ,
149+ let ( term, seq, params) = match rlp. item_count ( ) ? {
150+ 4 => ( TermMetadata :: default ( ) , 0 , None ) ,
151+ 6 => (
152+ TermMetadata {
153+ last_term_finished_block_num : rlp. val_at ( 4 ) ?,
154+ current_term_id : rlp. val_at ( 5 ) ?,
155+ } ,
156+ 0 ,
157+ None ,
158+ ) ,
159+ 8 => (
160+ TermMetadata {
161+ last_term_finished_block_num : rlp. val_at ( 4 ) ?,
162+ current_term_id : rlp. val_at ( 5 ) ?,
163+ } ,
164+ rlp. val_at ( 6 ) ?,
165+ Some ( rlp. val_at ( 7 ) ?) ,
166+ ) ,
118167 item_count => {
119168 return Err ( DecoderError :: RlpInvalidLength {
120169 got : item_count,
@@ -131,6 +180,7 @@ impl Decodable for Metadata {
131180 number_of_shards : rlp. val_at ( 1 ) ?,
132181 number_of_initial_shards : rlp. val_at ( 2 ) ?,
133182 hashes : rlp. list_at ( 3 ) ?,
183+ term,
134184 seq,
135185 params,
136186 } )
@@ -190,11 +240,59 @@ mod tests {
190240 }
191241
192242 #[ test]
193- fn metadata_with_seq ( ) {
243+ fn check_backward_compatibility ( ) {
244+ let metadata = Metadata {
245+ number_of_shards : 10 ,
246+ number_of_initial_shards : 1 ,
247+ hashes : vec ! [ ] ,
248+ term : Default :: default ( ) ,
249+ seq : 0 ,
250+ params : None ,
251+ } ;
252+ let mut rlp = RlpStream :: new_list ( 4 ) ;
253+ rlp. append ( & PREFIX ) . append ( & 10u16 ) . append ( & 1u16 ) . append_list :: < H256 , H256 > ( & [ ] ) ;
254+ assert_eq ! ( metadata. rlp_bytes( ) , rlp. drain( ) ) ;
255+ }
256+
257+ #[ test]
258+ fn metadata_without_term_with_seq ( ) {
259+ let metadata = Metadata {
260+ number_of_shards : 10 ,
261+ number_of_initial_shards : 1 ,
262+ hashes : vec ! [ ] ,
263+ term : Default :: default ( ) ,
264+ seq : 3 ,
265+ params : Some ( CommonParams :: default_for_test ( ) ) ,
266+ } ;
267+ rlp_encode_and_decode_test ! ( metadata) ;
268+ }
269+
270+ #[ test]
271+ fn metadata_with_term_without_seq ( ) {
272+ let metadata = Metadata {
273+ number_of_shards : 10 ,
274+ number_of_initial_shards : 1 ,
275+ hashes : vec ! [ ] ,
276+ term : TermMetadata {
277+ last_term_finished_block_num : 1 ,
278+ current_term_id : 100 ,
279+ } ,
280+ seq : 0 ,
281+ params : None ,
282+ } ;
283+ rlp_encode_and_decode_test ! ( metadata) ;
284+ }
285+
286+ #[ test]
287+ fn metadata_with_term_and_seq ( ) {
194288 let metadata = Metadata {
195289 number_of_shards : 10 ,
196290 number_of_initial_shards : 1 ,
197291 hashes : vec ! [ ] ,
292+ term : TermMetadata {
293+ last_term_finished_block_num : 1 ,
294+ current_term_id : 100 ,
295+ } ,
198296 seq : 3 ,
199297 params : Some ( CommonParams :: default_for_test ( ) ) ,
200298 } ;
0 commit comments