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 pub signblockscript: Option<HexBytes>,
28 pub signblock_witness_limit: Option<u32>,
29 #[serde(skip_serializing_if = "Option::is_none")]
31 pub elided_root: Option<sha256::Midstate>,
32 #[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}