Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "elements"
version = "0.9.2"
version = "0.10.0"
authors = ["Andrew Poelstra <apoelstra@blockstream.com>"]
description = "Library with support for de/serialization, parsing and executing on data structures and network messages related to Elements"
license = "CC0-1.0"
Expand Down
81 changes: 49 additions & 32 deletions src/block.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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");
}
Expand All @@ -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
Expand All @@ -713,7 +730,7 @@ mod tests {
}
assert_eq!(
block.bitcoin_hash().to_string(),
"6d6d1172376a187579396df29cd6bbf36761d504fb400eea2f314b3d6b6b44f5"
"e9a5176b1690a448f76fb691ab4d516e60e13a6e7a49454c62dbf0d611ffcce7"
);
}
}
Expand Down
48 changes: 41 additions & 7 deletions src/dynafed.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down Expand Up @@ -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[..])
}
Expand All @@ -159,6 +176,7 @@ impl<'de> Deserialize<'de> for Params {
Unknown,
SignblockScript,
SignblockWitnessLimit,
ElidedRoot,
FedpegProgram,
FedpegScript,
ExtSpace,
Expand All @@ -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),
Expand Down Expand Up @@ -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;
Expand All @@ -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()?);
},
Expand All @@ -235,13 +258,15 @@ impl<'de> Deserialize<'de> for Params {
match (
signblockscript,
signblock_witness_limit,
elided_root,
fedpeg_program,
fedpegscript,
extension_space,
) {
(
Some(signblockscript),
Some(signblock_witness_limit),
_,
Some(fedpeg_program),
Some(fedpegscript),
Some(extension_space),
Expand All @@ -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),
Expand Down Expand Up @@ -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 {
Expand Down Expand Up @@ -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,
Expand Down Expand Up @@ -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)?,
Expand All @@ -376,6 +408,7 @@ mod tests {

use bitcoin;
use bitcoin::hashes::hex::ToHex;
use bitcoin::hashes::sha256;

#[test]
fn test_param_roots() {
Expand Down Expand Up @@ -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 {
Expand All @@ -430,7 +464,7 @@ mod tests {
};
assert_eq!(
full_entry.calculate_root().to_hex(),
"175be2087ba7cc0e33348bef493bd3e34f31f64bf9226e5881ab310dafa432ff"
"8eb1b83cce69a3d8b0bfb7fbe77ae8f1d24b57a9cae047b8c0aba084ad878249"
);

let header = ::block::BlockHeader{
Expand All @@ -443,7 +477,7 @@ mod tests {
};
assert_eq!(
header.calculate_dynafed_params_root().unwrap().to_hex(),
"e56cf79487952dfa85fe6a85829600adc19714ba6ab1157fdff02b25ae60cee2"
"113160f76dc17fe367a2def79aefe06feeea9c795310c9e88aeedc23e145982e"
);
}
}