hal_elements/
block.rs

1use bitcoin::hashes::sha256;
2use elements::{dynafed, Block, BlockExtData, BlockHeader, BlockHash, TxMerkleNode, Txid};
3use serde::{Deserialize, Serialize};
4
5use ::{GetInfo, Network, HexBytes};
6
7use tx::TransactionInfo;
8
9#[derive(Clone, PartialEq, Eq, Debug, Deserialize, Serialize)]
10#[serde(rename_all = "lowercase")]
11pub enum ParamsType {
12	Null,
13	Compact,
14	Full,
15}
16
17impl Default for ParamsType {
18	fn default() -> ParamsType {
19		ParamsType::Null
20	}
21}
22
23#[derive(Clone, PartialEq, Eq, Debug, Default, Deserialize, Serialize)]
24pub struct ParamsInfo {
25	pub params_type: ParamsType,
26	// both
27	pub signblockscript: Option<HexBytes>,
28	pub signblock_witness_limit: Option<u32>,
29	// compact only
30	#[serde(skip_serializing_if = "Option::is_none")]
31	pub elided_root: Option<sha256::Midstate>,
32	// full only
33	#[serde(skip_serializing_if = "Option::is_none")]
34	pub fedpeg_program: Option<HexBytes>,
35	#[serde(skip_serializing_if = "Option::is_none")]
36	pub fedpeg_script: Option<HexBytes>,
37	#[serde(skip_serializing_if = "Option::is_none")]
38	pub extension_space: Option<Vec<HexBytes>>,
39}
40
41impl<'a> GetInfo<ParamsInfo> for dynafed::Params {
42	fn get_info(&self, _network: Network) -> ParamsInfo {
43		ParamsInfo {
44			params_type: match self {
45				dynafed::Params::Null => ParamsType::Null,
46				dynafed::Params::Compact {
47					..
48				} => ParamsType::Compact,
49				dynafed::Params::Full {
50					..
51				} => ParamsType::Full,
52			},
53			signblockscript: self.signblockscript().map(|s| s.to_bytes().into()),
54			signblock_witness_limit: self.signblock_witness_limit(),
55			elided_root: self.elided_root().map(|r| *r),
56			fedpeg_program: self.fedpeg_program().map(|p| p[..].into()),
57			fedpeg_script: self.fedpegscript().map(|s| s[..].into()),
58			extension_space: self
59				.extension_space()
60				.map(|s| s.iter().map(|v| v[..].into()).collect()),
61		}
62	}
63}
64
65#[derive(Clone, PartialEq, Eq, Debug, Deserialize, Serialize)]
66pub struct BlockHeaderInfo {
67	#[serde(skip_serializing_if = "Option::is_none")]
68	pub block_hash: Option<BlockHash>,
69	pub version: u32,
70	pub previous_block_hash: BlockHash,
71	pub merkle_root: TxMerkleNode,
72	pub time: u32,
73	pub height: u32,
74	pub dynafed: bool,
75	#[serde(skip_serializing_if = "Option::is_none")]
76	pub legacy_challenge: Option<HexBytes>,
77	#[serde(skip_serializing_if = "Option::is_none")]
78	pub legacy_solution: Option<HexBytes>,
79	#[serde(skip_serializing_if = "Option::is_none")]
80	pub dynafed_current: Option<ParamsInfo>,
81	#[serde(skip_serializing_if = "Option::is_none")]
82	pub dynafed_proposed: Option<ParamsInfo>,
83	#[serde(skip_serializing_if = "Option::is_none")]
84	pub dynafed_witness: Option<Vec<HexBytes>>,
85}
86
87impl<'a> GetInfo<BlockHeaderInfo> for BlockHeader {
88	fn get_info(&self, network: Network) -> BlockHeaderInfo {
89		let mut info = BlockHeaderInfo {
90			block_hash: Some(self.block_hash()),
91			version: self.version,
92			previous_block_hash: self.prev_blockhash,
93			merkle_root: self.merkle_root,
94			time: self.time,
95			height: self.height,
96			dynafed: Default::default(),
97			legacy_challenge: Default::default(),
98			legacy_solution: Default::default(),
99			dynafed_current: Default::default(),
100			dynafed_proposed: Default::default(),
101			dynafed_witness: Default::default(),
102		};
103		match self.ext {
104			BlockExtData::Proof {
105				ref challenge,
106				ref solution,
107			} => {
108				info.dynafed = false;
109				info.legacy_challenge = Some(challenge.to_bytes().into());
110				info.legacy_solution = Some(solution.to_bytes().into());
111			}
112			BlockExtData::Dynafed {
113				ref current,
114				ref proposed,
115				ref signblock_witness,
116			} => {
117				info.dynafed = true;
118				info.dynafed_current = Some(current.get_info(network));
119				info.dynafed_proposed = Some(proposed.get_info(network));
120				info.dynafed_witness =
121					Some(signblock_witness.iter().map(|b| b[..].into()).collect());
122			}
123		};
124		info
125	}
126}
127
128#[derive(Clone, PartialEq, Eq, Debug, Deserialize, Serialize)]
129pub struct BlockInfo {
130	pub header: BlockHeaderInfo,
131	#[serde(skip_serializing_if = "Option::is_none")]
132	pub transactions: Option<Vec<TransactionInfo>>,
133
134	#[serde(skip_serializing_if = "Option::is_none")]
135	pub txids: Option<Vec<Txid>>,
136	#[serde(skip_serializing_if = "Option::is_none")]
137	pub raw_transactions: Option<Vec<HexBytes>>,
138}
139
140impl GetInfo<BlockInfo> for Block {
141	fn get_info(&self, network: Network) -> BlockInfo {
142		BlockInfo {
143			header: self.header.get_info(network),
144			transactions: Some(self.txdata.iter().map(|t| t.get_info(network)).collect()),
145			txids: None,
146			raw_transactions: None,
147		}
148	}
149}