@@ -36,6 +36,8 @@ pub enum Params {
3636 signblockscript : bitcoin:: Script ,
3737 /// Maximum, in bytes, of the size of a blocksigning witness
3838 signblock_witness_limit : u32 ,
39+ /// Merkle root of extra data
40+ elided_root : sha256:: Midstate ,
3941 } ,
4042 /// Full dynamic federations parameters
4143 Full {
@@ -139,12 +141,27 @@ impl Params {
139141 return sha256:: Midstate :: from_inner ( [ 0u8 ; 32 ] ) ;
140142 }
141143
144+ let extra_root = match * self {
145+ Params :: Null => return sha256:: Midstate :: from_inner ( [ 0u8 ; 32 ] ) ,
146+ Params :: Compact { ref elided_root, .. } => * elided_root,
147+ Params :: Full { ref fedpeg_program, ref fedpegscript, ref extension_space, .. } => {
148+ let leaves = [
149+ serialize_hash ( fedpeg_program) . into_inner ( ) ,
150+ serialize_hash ( fedpegscript) . into_inner ( ) ,
151+ serialize_hash ( extension_space) . into_inner ( ) ,
152+ ] ;
153+ :: fast_merkle_root:: fast_merkle_root ( & leaves[ ..] )
154+ } ,
155+ } ;
142156 let leaves = [
143157 serialize_hash ( self . signblockscript ( ) . unwrap ( ) ) . into_inner ( ) ,
144158 serialize_hash ( & self . signblock_witness_limit ( ) . unwrap ( ) ) . into_inner ( ) ,
145- serialize_hash ( self . fedpeg_program ( ) . unwrap_or ( & bitcoin:: Script :: new ( ) ) ) . into_inner ( ) ,
146- serialize_hash ( self . fedpegscript ( ) . unwrap_or ( & Vec :: new ( ) ) ) . into_inner ( ) ,
147- serialize_hash ( self . extension_space ( ) . unwrap_or ( & Vec :: new ( ) ) ) . into_inner ( ) ,
159+ ] ;
160+ let compact_root = :: fast_merkle_root:: fast_merkle_root ( & leaves[ ..] ) ;
161+
162+ let leaves = [
163+ compact_root. into_inner ( ) ,
164+ extra_root. into_inner ( ) ,
148165 ] ;
149166 :: fast_merkle_root:: fast_merkle_root ( & leaves[ ..] )
150167 }
@@ -159,6 +176,7 @@ impl<'de> Deserialize<'de> for Params {
159176 Unknown ,
160177 SignblockScript ,
161178 SignblockWitnessLimit ,
179+ ElidedRoot ,
162180 FedpegProgram ,
163181 FedpegScript ,
164182 ExtSpace ,
@@ -176,6 +194,7 @@ impl<'de> Deserialize<'de> for Params {
176194 match v {
177195 "signblockscript" => Ok ( Enum :: SignblockScript ) ,
178196 "signblock_witness_limit" => Ok ( Enum :: SignblockWitnessLimit ) ,
197+ "elided_root" => Ok ( Enum :: ElidedRoot ) ,
179198 "fedpeg_program" => Ok ( Enum :: FedpegProgram ) ,
180199 "fedpegscript" => Ok ( Enum :: FedpegScript ) ,
181200 "extension_space" => Ok ( Enum :: ExtSpace ) ,
@@ -204,6 +223,7 @@ impl<'de> Deserialize<'de> for Params {
204223 {
205224 let mut signblockscript = None ;
206225 let mut signblock_witness_limit = None ;
226+ let mut elided_root = None ;
207227 let mut fedpeg_program = None ;
208228 let mut fedpegscript = None ;
209229 let mut extension_space = None ;
@@ -219,6 +239,9 @@ impl<'de> Deserialize<'de> for Params {
219239 Some ( Enum :: SignblockWitnessLimit ) => {
220240 signblock_witness_limit = Some ( map. next_value ( ) ?) ;
221241 } ,
242+ Some ( Enum :: ElidedRoot ) => {
243+ elided_root = Some ( map. next_value ( ) ?) ;
244+ } ,
222245 Some ( Enum :: FedpegProgram ) => {
223246 fedpeg_program = Some ( map. next_value ( ) ?) ;
224247 } ,
@@ -235,13 +258,15 @@ impl<'de> Deserialize<'de> for Params {
235258 match (
236259 signblockscript,
237260 signblock_witness_limit,
261+ elided_root,
238262 fedpeg_program,
239263 fedpegscript,
240264 extension_space,
241265 ) {
242266 (
243267 Some ( signblockscript) ,
244268 Some ( signblock_witness_limit) ,
269+ _,
245270 Some ( fedpeg_program) ,
246271 Some ( fedpegscript) ,
247272 Some ( extension_space) ,
@@ -255,12 +280,14 @@ impl<'de> Deserialize<'de> for Params {
255280 (
256281 Some ( signblockscript) ,
257282 Some ( signblock_witness_limit) ,
283+ Some ( elided_root) ,
258284 _,
259285 _,
260286 _
261287 ) => Ok ( Params :: Compact {
262288 signblockscript,
263289 signblock_witness_limit,
290+ elided_root,
264291 } ) ,
265292 // We should probably be stricter about errors here
266293 _ => Ok ( Params :: Null ) ,
@@ -292,10 +319,12 @@ impl Serialize for Params {
292319 Params :: Compact {
293320 ref signblockscript,
294321 ref signblock_witness_limit,
322+ ref elided_root,
295323 } => {
296324 let mut st = s. serialize_struct ( "Params" , 2 ) ?;
297325 st. serialize_field ( "signblockscript" , signblockscript) ?;
298326 st. serialize_field ( "signblock_witness_limit" , signblock_witness_limit) ?;
327+ st. serialize_field ( "elided_root" , elided_root) ?;
299328 st. end ( )
300329 } ,
301330 Params :: Full {
@@ -324,10 +353,12 @@ impl Encodable for Params {
324353 Params :: Compact {
325354 ref signblockscript,
326355 ref signblock_witness_limit,
356+ ref elided_root,
327357 } => {
328358 Encodable :: consensus_encode ( & 1u8 , & mut s) ? +
329359 Encodable :: consensus_encode ( signblockscript, & mut s) ? +
330- Encodable :: consensus_encode ( signblock_witness_limit, & mut s) ?
360+ Encodable :: consensus_encode ( signblock_witness_limit, & mut s) ? +
361+ Encodable :: consensus_encode ( & elided_root. into_inner ( ) , & mut s) ?
331362 } ,
332363 Params :: Full {
333364 ref signblockscript,
@@ -355,6 +386,7 @@ impl Decodable for Params {
355386 1 => Ok ( Params :: Compact {
356387 signblockscript : Decodable :: consensus_decode ( & mut d) ?,
357388 signblock_witness_limit : Decodable :: consensus_decode ( & mut d) ?,
389+ elided_root : sha256:: Midstate :: from_inner ( Decodable :: consensus_decode ( & mut d) ?) ,
358390 } ) ,
359391 2 => Ok ( Params :: Full {
360392 signblockscript : Decodable :: consensus_decode ( & mut d) ?,
@@ -376,6 +408,7 @@ mod tests {
376408
377409 use bitcoin;
378410 use bitcoin:: hashes:: hex:: ToHex ;
411+ use bitcoin:: hashes:: sha256;
379412
380413 #[ test]
381414 fn test_param_roots ( ) {
@@ -415,10 +448,11 @@ mod tests {
415448 let compact_entry = Params :: Compact {
416449 signblockscript : signblockscript. clone ( ) ,
417450 signblock_witness_limit : signblock_wl,
451+ elided_root : sha256:: Midstate :: from_inner ( [ 0 ; 32 ] ) ,
418452 } ;
419453 assert_eq ! (
420454 compact_entry. calculate_root( ) . to_hex( ) ,
421- "dff5f3793abc06a6d75e80fe3cfd47406f732fa4ec9305960ae2a229222a1ad5 "
455+ "f98f149fd11da6fbe26d0ee53cadd28372fa9eed2cb7080f41da7ca311531777 "
422456 ) ;
423457
424458 let full_entry = Params :: Full {
@@ -430,7 +464,7 @@ mod tests {
430464 } ;
431465 assert_eq ! (
432466 full_entry. calculate_root( ) . to_hex( ) ,
433- "175be2087ba7cc0e33348bef493bd3e34f31f64bf9226e5881ab310dafa432ff "
467+ "8eb1b83cce69a3d8b0bfb7fbe77ae8f1d24b57a9cae047b8c0aba084ad878249 "
434468 ) ;
435469
436470 let header = :: block:: BlockHeader {
@@ -443,7 +477,7 @@ mod tests {
443477 } ;
444478 assert_eq ! (
445479 header. calculate_dynafed_params_root( ) . unwrap( ) . to_hex( ) ,
446- "e56cf79487952dfa85fe6a85829600adc19714ba6ab1157fdff02b25ae60cee2 "
480+ "113160f76dc17fe367a2def79aefe06feeea9c795310c9e88aeedc23e145982e "
447481 ) ;
448482 }
449483}
0 commit comments