From b081a93679c31daaac4773c4a76194bd7d966734 Mon Sep 17 00:00:00 2001 From: Andrew Poelstra Date: Thu, 7 Nov 2019 18:53:55 +0000 Subject: [PATCH 1/2] dynafed: replace `calculate_root` with new version --- src/block.rs | 81 ++++++++++++++++++++++++++++++-------------------- src/dynafed.rs | 48 +++++++++++++++++++++++++----- 2 files changed, 90 insertions(+), 39 deletions(-) diff --git a/src/block.rs b/src/block.rs index e19a943b..39b109f7 100644 --- a/src/block.rs +++ b/src/block.rs @@ -638,24 +638,34 @@ mod tests { #[test] fn dynafed_block() { + // Copied from elements RPC during a functionary integration test run let block: Block = hex_deserialize!("\ - 000000a07a7159e1b793a80d826f72ddcfb11397160773ebc6e5ea10f3adb6ef\ - ef481eb2cb94ec7aafb983b5ef45a33d49b725088abc43a127c035ef636a8852\ - ecf9526d7bf2305d01000000012200204ae81572f06e1b88fd5ced7a1a000945\ - 432e83e1551e6f721ee9c00b8cc332604b000000000101510102000000010100\ - 00000000000000000000000000000000000000000000000000000000000000ff\ - ffffff03510101ffffffff0201ed455f3f6bd15c60a3e770a04cbfcc482cb1bf\ - 95a0ac1db9bede08cac049783901000000000000000000016a01ed455f3f6bd1\ - 5c60a3e770a04cbfcc482cb1bf95a0ac1db9bede08cac0497839010000000000\ - 00000000266a24aa21a9ed94f15ed3a62165e4a0b99699cc28b48e19cb5bc1b1\ - f47155db62d63f1e047d45000000000000012000000000000000000000000000\ - 000000000000000000000000000000000000000000000000\ + 000000a0da9d569617d1d65c3390a01c18c4fa7c4d0f4738b6fc2b5c5faf2e8a\ + 463abbaa46eb9123808e1e2ff75e9472fa0f0589b53b7518a69d3d6fcb9228ed\ + 345734ea06b9c45d070000000122002057c555a91edf9552282d88624d1473c2\ + 75e64b7218870eb8fb0335b442976b8d02010000fbee9cea00d8efdc49cfbec3\ + 28537e0d7032194de6ebf3cf42e5c05bb89a08b100040047304402206f55bc87\ + 1387a9840489d47624b02995e774e3b70fed56d1eb43a9a53d4fd3e102201e1c\ + bfbbd1079f5bea3bc216882d3fefbf6f27aa761820d3a88f12e5a5ea7ff00148\ + 3045022100c072816f6561e73ee6c0ae32d55c3eec4da73b035425e4eb05ab50\ + 772591b4360220311bf295010094a489d9b280d9dafb724d776a1d99b9ede31c\ + 4b59bc2095c5c30169522103cadff18e928133df2e670a3715c4e7a81d357de3\ + 6ddaa5016628e70a3e6a452f21021f0d8638c413ef7769cd711ce84c8f192f5a\ + 85f0fd6d8e63ddb4d2cf6740b23b210296db75c11ea3a292a372f6c94f5013ea\ + eb379f701857a702f3b83f88da21be6f53ae0102000000010100000000000000\ + 00000000000000000000000000000000000000000000000000ffffffff035701\ + 01ffffffff020137c495f58d698979ff9124e8c7455fe79b13ddb96afa25c458\ + 94eb059868a8c001000000000000000000016a0137c495f58d698979ff9124e8\ + c7455fe79b13ddb96afa25c45894eb059868a8c001000000000000000000266a\ + 24aa21a9ed94f15ed3a62165e4a0b99699cc28b48e19cb5bc1b1f47155db62d6\ + 3f1e047d45000000000000012000000000000000000000000000000000000000\ + 000000000000000000000000000000000000\ "); // Test that this is a block with compact current params and null proposed params if let ExtData::Dynafed { current, proposed, .. } = block.clone().header.ext { if let dynafed::Params::Compact { signblock_witness_limit, .. } = current { - assert_eq!(signblock_witness_limit, 75); + assert_eq!(signblock_witness_limit, 258); } else { panic!("Current block dynafed params not compact"); } @@ -670,30 +680,37 @@ mod tests { assert_eq!( block.bitcoin_hash().to_string(), - "4c7b60fc11a380811cfb8a17201ba54506a896eb1f53e9646d8bc2398d2448bd" + "4961df970cf12d789383974e6ab439f780d956b5a50162ca9d281362e46c605a" ); assert_eq!(block.header.version, 0x20000000); // Full current and proposal let block: Block = hex_deserialize!("\ - 000000a08b73cb590b11730880dd9c042101e853bcd2d5195f8efcffa66df48e\ - bf39d8c10a9de8013a78fb0acc86dd7e1c137581e4951b196d7c9d8f96a90bd3\ - c4768c575f535c5dcc010000022200204ae81572f06e1b88fd5ced7a1a000945\ - 432e83e1551e6f721ee9c00b8cc332604b00000017a91472c44f957fc011d97e\ - 3406667dca5b1c930c4026870151014202fcba7ecf41bc7e1be4ee122d9d22e3\ - 333671eb0a3a87b5cdf099d59874e1940f02fcba7ecf41bc7e1be4ee122d9d22\ - e3333671eb0a3a87b5cdf099d59874e1940f021600142bb5aebe7c280263fa60\ - 6c97e4f6c07ee62dddf0640000002200208c2574892063f995fdf756bce07f46\ - c1a5193e54cd52837ed91e32008ccf41ac0152014203808355deeb0555203b53\ - df7ef8f36edaf66ab0207ca1b11968a7ac421554e62102fcba7ecf41bc7e1be4\ - ee122d9d22e3333671eb0a3a87b5cdf099d59874e1940f010151010200000001\ - 0100000000000000000000000000000000000000000000000000000000000000\ - 00ffffffff0502cc010101ffffffff0201230f4f5d4b7c6fa845806ee4f67713\ - 459e1b69e8e60fcee2e4940c7a0d5de1b201000000002540be4000015101230f\ - 4f5d4b7c6fa845806ee4f67713459e1b69e8e60fcee2e4940c7a0d5de1b20100\ - 0000000000000000266a24aa21a9ed94f15ed3a62165e4a0b99699cc28b48e19\ - cb5bc1b1f47155db62d63f1e047d450000000000000120000000000000000000\ - 00000000000000000000000000000000000000000000000000000000\ + 000000a01ecf88cda4d9e6339109c685417c526e8316fe0d3ea058765634dcbb\ + 205d3081bd83073b1f1793154ab820c70a1fda32a0d45bb0e1f40c0c61ae0350\ + 7f49c293debcc45d1400000002220020a6794de47a1612cc94c1b978d5bd1b25\ + 873f4cab0b1a76260b0b8af9ad954dc74b0100002200204ae81572f06e1b88fd\ + 5ced7a1a000945432e83e1551e6f721ee9c00b8cc33260015100022200204cb4\ + 0d59d6e1bbe963f3a63021b0d7d5474b87206978a1129fbffc4d1c1cf7e44b01\ + 00002200204ae81572f06e1b88fd5ced7a1a000945432e83e1551e6f721ee9c0\ + 0b8cc332600151000500483045022100ab2203a8a68d7eca8a3a0fac91e7c780\ + 2656d937535800da82f7102e1c06f7b80220576f004cb14b95178c71e36bf947\ + bfea496b00b66c18d2eb8febf46362d50e2b0147304402202d4630887d661a50\ + b76b7b32555fd76906ad298ce24483df42310ffbf62d451802200e0d64069e58\ + 047c271c1b4051c1ff3d1cba7d32e56abb0d8b8bc30e1bed075b014830450221\ + 00c6b196967c661c4543802a895ae731af44862e75d9e3c65b8efdd668727a34\ + af022041ff4d67029052eb6305d25d0fc4813d21a939ff5316a12562d0c90389\ + 76f8e1016953210296db75c11ea3a292a372f6c94f5013eaeb379f701857a702\ + f3b83f88da21be6f21021f0d8638c413ef7769cd711ce84c8f192f5a85f0fd6d\ + 8e63ddb4d2cf6740b23b2103cadff18e928133df2e670a3715c4e7a81d357de3\ + 6ddaa5016628e70a3e6a452f53ae010200000001010000000000000000000000\ + 000000000000000000000000000000000000000000ffffffff0401140101ffff\ + ffff020137c495f58d698979ff9124e8c7455fe79b13ddb96afa25c45894eb05\ + 9868a8c001000000000000000000016a0137c495f58d698979ff9124e8c7455f\ + e79b13ddb96afa25c45894eb059868a8c001000000000000000000266a24aa21\ + a9ed94f15ed3a62165e4a0b99699cc28b48e19cb5bc1b1f47155db62d63f1e04\ + 7d45000000000000012000000000000000000000000000000000000000000000\ + 000000000000000000000000000000\ "); // Test that this is a block with full current params and full proposed params @@ -713,7 +730,7 @@ mod tests { } assert_eq!( block.bitcoin_hash().to_string(), - "6d6d1172376a187579396df29cd6bbf36761d504fb400eea2f314b3d6b6b44f5" + "e9a5176b1690a448f76fb691ab4d516e60e13a6e7a49454c62dbf0d611ffcce7" ); } } diff --git a/src/dynafed.rs b/src/dynafed.rs index 6da0cd43..d35c5afa 100644 --- a/src/dynafed.rs +++ b/src/dynafed.rs @@ -36,6 +36,8 @@ pub enum Params { signblockscript: bitcoin::Script, /// Maximum, in bytes, of the size of a blocksigning witness signblock_witness_limit: u32, + /// Merkle root of extra data + elided_root: sha256::Midstate, }, /// Full dynamic federations parameters Full { @@ -139,12 +141,27 @@ impl Params { return sha256::Midstate::from_inner([0u8; 32]); } + let extra_root = match *self { + Params::Null => return sha256::Midstate::from_inner([0u8; 32]), + Params::Compact { ref elided_root, .. } => *elided_root, + Params::Full { ref fedpeg_program, ref fedpegscript, ref extension_space, .. } => { + let leaves = [ + serialize_hash(fedpeg_program).into_inner(), + serialize_hash(fedpegscript).into_inner(), + serialize_hash(extension_space).into_inner(), + ]; + ::fast_merkle_root::fast_merkle_root(&leaves[..]) + }, + }; let leaves = [ serialize_hash(self.signblockscript().unwrap()).into_inner(), serialize_hash(&self.signblock_witness_limit().unwrap()).into_inner(), - serialize_hash(self.fedpeg_program().unwrap_or(&bitcoin::Script::new())).into_inner(), - serialize_hash(self.fedpegscript().unwrap_or(&Vec::new())).into_inner(), - serialize_hash(self.extension_space().unwrap_or(&Vec::new())).into_inner(), + ]; + let compact_root = ::fast_merkle_root::fast_merkle_root(&leaves[..]); + + let leaves = [ + compact_root.into_inner(), + extra_root.into_inner(), ]; ::fast_merkle_root::fast_merkle_root(&leaves[..]) } @@ -159,6 +176,7 @@ impl<'de> Deserialize<'de> for Params { Unknown, SignblockScript, SignblockWitnessLimit, + ElidedRoot, FedpegProgram, FedpegScript, ExtSpace, @@ -176,6 +194,7 @@ impl<'de> Deserialize<'de> for Params { match v { "signblockscript" => Ok(Enum::SignblockScript), "signblock_witness_limit" => Ok(Enum::SignblockWitnessLimit), + "elided_root" => Ok(Enum::ElidedRoot), "fedpeg_program" => Ok(Enum::FedpegProgram), "fedpegscript" => Ok(Enum::FedpegScript), "extension_space" => Ok(Enum::ExtSpace), @@ -204,6 +223,7 @@ impl<'de> Deserialize<'de> for Params { { let mut signblockscript = None; let mut signblock_witness_limit = None; + let mut elided_root = None; let mut fedpeg_program = None; let mut fedpegscript = None; let mut extension_space = None; @@ -219,6 +239,9 @@ impl<'de> Deserialize<'de> for Params { Some(Enum::SignblockWitnessLimit) => { signblock_witness_limit = Some(map.next_value()?); }, + Some(Enum::ElidedRoot) => { + elided_root = Some(map.next_value()?); + }, Some(Enum::FedpegProgram) => { fedpeg_program = Some(map.next_value()?); }, @@ -235,6 +258,7 @@ impl<'de> Deserialize<'de> for Params { match ( signblockscript, signblock_witness_limit, + elided_root, fedpeg_program, fedpegscript, extension_space, @@ -242,6 +266,7 @@ impl<'de> Deserialize<'de> for Params { ( Some(signblockscript), Some(signblock_witness_limit), + _, Some(fedpeg_program), Some(fedpegscript), Some(extension_space), @@ -255,12 +280,14 @@ impl<'de> Deserialize<'de> for Params { ( Some(signblockscript), Some(signblock_witness_limit), + Some(elided_root), _, _, _ ) => Ok(Params::Compact { signblockscript, signblock_witness_limit, + elided_root, }), // We should probably be stricter about errors here _ => Ok(Params::Null), @@ -292,10 +319,12 @@ impl Serialize for Params { Params::Compact { ref signblockscript, ref signblock_witness_limit, + ref elided_root, } => { let mut st = s.serialize_struct("Params", 2)?; st.serialize_field("signblockscript", signblockscript)?; st.serialize_field("signblock_witness_limit", signblock_witness_limit)?; + st.serialize_field("elided_root", elided_root)?; st.end() }, Params::Full { @@ -324,10 +353,12 @@ impl Encodable for Params { Params::Compact { ref signblockscript, ref signblock_witness_limit, + ref elided_root, } => { Encodable::consensus_encode(&1u8, &mut s)? + Encodable::consensus_encode(signblockscript, &mut s)? + - Encodable::consensus_encode(signblock_witness_limit, &mut s)? + Encodable::consensus_encode(signblock_witness_limit, &mut s)? + + Encodable::consensus_encode(&elided_root.into_inner(), &mut s)? }, Params::Full { ref signblockscript, @@ -355,6 +386,7 @@ impl Decodable for Params { 1 => Ok(Params::Compact { signblockscript: Decodable::consensus_decode(&mut d)?, signblock_witness_limit: Decodable::consensus_decode(&mut d)?, + elided_root: sha256::Midstate::from_inner(Decodable::consensus_decode(&mut d)?), }), 2 => Ok(Params::Full { signblockscript: Decodable::consensus_decode(&mut d)?, @@ -376,6 +408,7 @@ mod tests { use bitcoin; use bitcoin::hashes::hex::ToHex; + use bitcoin::hashes::sha256; #[test] fn test_param_roots() { @@ -415,10 +448,11 @@ mod tests { let compact_entry = Params::Compact { signblockscript: signblockscript.clone(), signblock_witness_limit: signblock_wl, + elided_root: sha256::Midstate::from_inner([0; 32]), }; assert_eq!( compact_entry.calculate_root().to_hex(), - "dff5f3793abc06a6d75e80fe3cfd47406f732fa4ec9305960ae2a229222a1ad5" + "f98f149fd11da6fbe26d0ee53cadd28372fa9eed2cb7080f41da7ca311531777" ); let full_entry = Params::Full { @@ -430,7 +464,7 @@ mod tests { }; assert_eq!( full_entry.calculate_root().to_hex(), - "175be2087ba7cc0e33348bef493bd3e34f31f64bf9226e5881ab310dafa432ff" + "8eb1b83cce69a3d8b0bfb7fbe77ae8f1d24b57a9cae047b8c0aba084ad878249" ); let header = ::block::BlockHeader{ @@ -443,7 +477,7 @@ mod tests { }; assert_eq!( header.calculate_dynafed_params_root().unwrap().to_hex(), - "e56cf79487952dfa85fe6a85829600adc19714ba6ab1157fdff02b25ae60cee2" + "113160f76dc17fe367a2def79aefe06feeea9c795310c9e88aeedc23e145982e" ); } } From 52ab7cb1585b8e76de33f0982605e7a9b7f88f00 Mon Sep 17 00:00:00 2001 From: Andrew Poelstra Date: Fri, 8 Nov 2019 00:59:02 +0000 Subject: [PATCH 2/2] bump major version number --- Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Cargo.toml b/Cargo.toml index cbc6d698..43a8298b 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "elements" -version = "0.9.2" +version = "0.10.0" authors = ["Andrew Poelstra "] description = "Library with support for de/serialization, parsing and executing on data structures and network messages related to Elements" license = "CC0-1.0"