Skip to content

Commit 25f4311

Browse files
committed
types: Split v19 blockchain module up
Split the module up as we do for others. Done in preparation for adding support for `getblockfilter`. Note we use the same public re-export of errors with a wildcard. Its a know problem I still need to fix crate wide.
1 parent 7249aa1 commit 25f4311

File tree

3 files changed

+345
-320
lines changed

3 files changed

+345
-320
lines changed

types/src/v19/blockchain/error.rs

Lines changed: 176 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,176 @@
1+
// SPDX-License-Identifier: CC0-1.0
2+
3+
use core::fmt;
4+
5+
use bitcoin::amount::ParseAmountError;
6+
use bitcoin::error::UnprefixedHexError;
7+
use bitcoin::{hex, network};
8+
9+
use crate::error::write_err;
10+
use crate::NumericError;
11+
12+
/// Error when converting a `GetBlockchainInfo` type into the model type.
13+
#[derive(Debug)]
14+
pub enum GetBlockchainInfoError {
15+
/// Conversion of numeric type to expected type failed.
16+
Numeric(NumericError),
17+
/// Conversion of the `chain` field failed.
18+
Chain(network::ParseNetworkError),
19+
/// Conversion of the `best_block_hash` field failed.
20+
BestBlockHash(hex::HexToArrayError),
21+
/// Conversion of the `chain_work` field failed.
22+
ChainWork(UnprefixedHexError),
23+
}
24+
25+
impl fmt::Display for GetBlockchainInfoError {
26+
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
27+
use GetBlockchainInfoError::*;
28+
29+
match *self {
30+
Numeric(ref e) => write_err!(f, "numeric"; e),
31+
Chain(ref e) => write_err!(f, "conversion of the `chain` field failed"; e),
32+
BestBlockHash(ref e) => {
33+
write_err!(f, "conversion of the `best_block_hash` field failed"; e)
34+
}
35+
ChainWork(ref e) => write_err!(f, "conversion of the `chain_work` field failed"; e),
36+
}
37+
}
38+
}
39+
40+
#[cfg(feature = "std")]
41+
impl std::error::Error for GetBlockchainInfoError {
42+
fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
43+
use GetBlockchainInfoError::*;
44+
45+
match *self {
46+
Numeric(ref e) => Some(e),
47+
Chain(ref e) => Some(e),
48+
BestBlockHash(ref e) => Some(e),
49+
ChainWork(ref e) => Some(e),
50+
}
51+
}
52+
}
53+
54+
impl From<NumericError> for GetBlockchainInfoError {
55+
fn from(e: NumericError) -> Self { Self::Numeric(e) }
56+
}
57+
58+
/// Error when converting a `MapMempoolEntry` into the model type.
59+
#[derive(Debug)]
60+
pub enum MapMempoolEntryError {
61+
/// Conversion of a `txid` failed.
62+
Txid(hex::HexToArrayError),
63+
/// Conversion of a `MempoolEntry` failed.
64+
MempoolEntry(MempoolEntryError),
65+
}
66+
67+
impl fmt::Display for MapMempoolEntryError {
68+
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
69+
use MapMempoolEntryError as E;
70+
71+
match *self {
72+
E::Txid(ref e) => write_err!(f, "conversion of a `txid` failed"; e),
73+
E::MempoolEntry(ref e) => write_err!(f, "conversion of an `MempoolEntry` failed"; e),
74+
}
75+
}
76+
}
77+
78+
#[cfg(feature = "std")]
79+
impl std::error::Error for MapMempoolEntryError {
80+
fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
81+
use MapMempoolEntryError as E;
82+
83+
match *self {
84+
E::Txid(ref e) => Some(e),
85+
E::MempoolEntry(ref e) => Some(e),
86+
}
87+
}
88+
}
89+
90+
/// Error when converting a `Mem` type into the model type.
91+
#[derive(Debug)]
92+
pub enum MempoolEntryError {
93+
/// Conversion of numeric type to expected type failed.
94+
Numeric(NumericError),
95+
/// Conversion of the `wtxid` field failed.
96+
Wtxid(hex::HexToArrayError),
97+
/// Conversion of the `MempoolEntryFees` type failed.
98+
Fees(MempoolEntryFeesError),
99+
/// Conversion of the `depends` field failed.
100+
Depends(hex::HexToArrayError),
101+
/// Conversion of the `spent_by` field failed.
102+
SpentBy(hex::HexToArrayError),
103+
}
104+
105+
impl From<NumericError> for MempoolEntryError {
106+
fn from(e: NumericError) -> Self { Self::Numeric(e) }
107+
}
108+
109+
impl fmt::Display for MempoolEntryError {
110+
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
111+
use MempoolEntryError as E;
112+
113+
match *self {
114+
E::Numeric(ref e) => write_err!(f, "numeric"; e),
115+
E::Wtxid(ref e) => write_err!(f, "conversion of the `wtxid` field failed"; e),
116+
E::Fees(ref e) => write_err!(f, "conversion of the `fees` field failed"; e),
117+
E::Depends(ref e) => write_err!(f, "conversion of the `depends` field failed"; e),
118+
E::SpentBy(ref e) => write_err!(f, "conversion of the `spent_by` field failed"; e),
119+
}
120+
}
121+
}
122+
123+
#[cfg(feature = "std")]
124+
impl std::error::Error for MempoolEntryError {
125+
fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
126+
use MempoolEntryError as E;
127+
128+
match *self {
129+
E::Numeric(ref e) => Some(e),
130+
E::Wtxid(ref e) => Some(e),
131+
E::Fees(ref e) => Some(e),
132+
E::Depends(ref e) => Some(e),
133+
E::SpentBy(ref e) => Some(e),
134+
}
135+
}
136+
}
137+
138+
/// Error when converting a `MempoolEntryFeesError` type into the model type.
139+
#[derive(Debug)]
140+
pub enum MempoolEntryFeesError {
141+
/// Conversion of the `base` field failed.
142+
Base(ParseAmountError),
143+
/// Conversion of the `modified` field failed.
144+
Modified(ParseAmountError),
145+
/// Conversion of the `ancestor` field failed.
146+
MempoolEntry(ParseAmountError),
147+
/// Conversion of the `descendant` field failed.
148+
Descendant(ParseAmountError),
149+
}
150+
151+
impl fmt::Display for MempoolEntryFeesError {
152+
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
153+
use MempoolEntryFeesError as E;
154+
155+
match *self {
156+
E::Base(ref e) => write_err!(f, "conversion of the `base` field failed"; e),
157+
E::Modified(ref e) => write_err!(f, "conversion of the `modified` field failed"; e),
158+
E::MempoolEntry(ref e) => write_err!(f, "conversion of the `ancestor` field failed"; e),
159+
E::Descendant(ref e) => write_err!(f, "conversion of the `descendant` field failed"; e),
160+
}
161+
}
162+
}
163+
164+
#[cfg(feature = "std")]
165+
impl std::error::Error for MempoolEntryFeesError {
166+
fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
167+
use MempoolEntryFeesError as E;
168+
169+
match *self {
170+
E::Base(ref e) => Some(e),
171+
E::Modified(ref e) => Some(e),
172+
E::MempoolEntry(ref e) => Some(e),
173+
E::Descendant(ref e) => Some(e),
174+
}
175+
}
176+
}

types/src/v19/blockchain/into.rs

Lines changed: 164 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,164 @@
1+
// SPDX-License-Identifier: CC0-1.0
2+
3+
use std::collections::BTreeMap;
4+
5+
use bitcoin::{hex, Amount, BlockHash, Network, Txid, Work, Wtxid};
6+
7+
use super::error::{
8+
GetBlockchainInfoError, MapMempoolEntryError, MempoolEntryError,
9+
MempoolEntryFeesError,
10+
};
11+
use super::{
12+
GetBlockchainInfo, GetMempoolAncestors, GetMempoolAncestorsVerbose,
13+
GetMempoolDescendants, GetMempoolDescendantsVerbose, GetMempoolEntry, MempoolEntry,
14+
MempoolEntryFees,
15+
};
16+
use crate::model;
17+
18+
impl GetBlockchainInfo {
19+
/// Converts version specific type to a version nonspecific, more strongly typed type.
20+
pub fn into_model(self) -> Result<model::GetBlockchainInfo, GetBlockchainInfoError> {
21+
use GetBlockchainInfoError as E;
22+
23+
let chain = Network::from_core_arg(&self.chain).map_err(E::Chain)?;
24+
let best_block_hash =
25+
self.best_block_hash.parse::<BlockHash>().map_err(E::BestBlockHash)?;
26+
let chain_work = Work::from_unprefixed_hex(&self.chain_work).map_err(E::ChainWork)?;
27+
let prune_height =
28+
self.prune_height.map(|h| crate::to_u32(h, "prune_height")).transpose()?;
29+
let prune_target_size =
30+
self.prune_target_size.map(|h| crate::to_u32(h, "prune_target_size")).transpose()?;
31+
let softforks = BTreeMap::new(); // TODO: Handle softforks stuff.
32+
33+
Ok(model::GetBlockchainInfo {
34+
chain,
35+
blocks: crate::to_u32(self.blocks, "blocks")?,
36+
headers: crate::to_u32(self.headers, "headers")?,
37+
best_block_hash,
38+
difficulty: self.difficulty,
39+
median_time: crate::to_u32(self.median_time, "median_time")?,
40+
verification_progress: self.verification_progress,
41+
initial_block_download: self.initial_block_download,
42+
chain_work,
43+
size_on_disk: self.size_on_disk,
44+
pruned: self.pruned,
45+
prune_height,
46+
automatic_pruning: self.automatic_pruning,
47+
prune_target_size,
48+
softforks,
49+
warnings: vec![self.warnings],
50+
})
51+
}
52+
}
53+
54+
impl GetMempoolAncestors {
55+
/// Converts version specific type to a version nonspecific, more strongly typed type.
56+
pub fn into_model(self) -> Result<model::GetMempoolAncestors, hex::HexToArrayError> {
57+
let v = self.0.iter().map(|t| t.parse::<Txid>()).collect::<Result<Vec<_>, _>>()?;
58+
Ok(model::GetMempoolAncestors(v))
59+
}
60+
}
61+
62+
impl GetMempoolAncestorsVerbose {
63+
/// Converts version specific type to a version nonspecific, more strongly typed type.
64+
pub fn into_model(self) -> Result<model::GetMempoolAncestorsVerbose, MapMempoolEntryError> {
65+
use MapMempoolEntryError as E;
66+
67+
let mut map = BTreeMap::new();
68+
for (k, v) in self.0.into_iter() {
69+
let txid = k.parse::<Txid>().map_err(E::Txid)?;
70+
let relative = v.into_model().map_err(E::MempoolEntry)?;
71+
map.insert(txid, relative);
72+
}
73+
Ok(model::GetMempoolAncestorsVerbose(map))
74+
}
75+
}
76+
77+
impl GetMempoolDescendants {
78+
/// Converts version specific type to a version nonspecific, more strongly typed type.
79+
pub fn into_model(self) -> Result<model::GetMempoolDescendants, hex::HexToArrayError> {
80+
let v = self.0.iter().map(|t| t.parse::<Txid>()).collect::<Result<Vec<_>, _>>()?;
81+
Ok(model::GetMempoolDescendants(v))
82+
}
83+
}
84+
85+
impl GetMempoolDescendantsVerbose {
86+
/// Converts version specific type to a version nonspecific, more strongly typed type.
87+
pub fn into_model(self) -> Result<model::GetMempoolDescendantsVerbose, MapMempoolEntryError> {
88+
use MapMempoolEntryError as E;
89+
90+
let mut map = BTreeMap::new();
91+
for (k, v) in self.0.into_iter() {
92+
let txid = k.parse::<Txid>().map_err(E::Txid)?;
93+
let relative = v.into_model().map_err(E::MempoolEntry)?;
94+
map.insert(txid, relative);
95+
}
96+
Ok(model::GetMempoolDescendantsVerbose(map))
97+
}
98+
}
99+
100+
impl GetMempoolEntry {
101+
/// Converts version specific type to a version nonspecific, more strongly typed type.
102+
pub fn into_model(self) -> Result<model::GetMempoolEntry, MempoolEntryError> {
103+
Ok(model::GetMempoolEntry(self.0.into_model()?))
104+
}
105+
}
106+
107+
impl MempoolEntry {
108+
/// Converts version specific type to a version nonspecific, more strongly typed type.
109+
pub fn into_model(self) -> Result<model::MempoolEntry, MempoolEntryError> {
110+
use MempoolEntryError as E;
111+
112+
let size = None;
113+
let weight = Some(crate::to_u32(self.weight, "weight")?);
114+
let time = crate::to_u32(self.time, "time")?;
115+
let height = crate::to_u32(self.height, "height")?;
116+
let descendant_count = crate::to_u32(self.descendant_count, "descendant_count")?;
117+
let descendant_size = crate::to_u32(self.descendant_size, "descendant_size")?;
118+
let ancestor_count = crate::to_u32(self.ancestor_count, "ancestor_count")?;
119+
let ancestor_size = crate::to_u32(self.ancestor_size, "ancestor_size")?;
120+
let wtxid = self.wtxid.parse::<Wtxid>().map_err(E::Wtxid)?;
121+
let fees = self.fees.into_model().map_err(E::Fees)?;
122+
let depends = self
123+
.depends
124+
.iter()
125+
.map(|txid| txid.parse::<Txid>())
126+
.collect::<Result<Vec<_>, _>>()
127+
.map_err(E::Depends)?;
128+
let spent_by = self
129+
.spent_by
130+
.iter()
131+
.map(|txid| txid.parse::<Txid>())
132+
.collect::<Result<Vec<_>, _>>()
133+
.map_err(E::SpentBy)?;
134+
135+
Ok(model::MempoolEntry {
136+
size,
137+
weight,
138+
time,
139+
height,
140+
descendant_count,
141+
descendant_size,
142+
ancestor_count,
143+
ancestor_size,
144+
wtxid,
145+
fees,
146+
depends,
147+
spent_by,
148+
})
149+
}
150+
}
151+
152+
impl MempoolEntryFees {
153+
/// Converts version specific type to a version nonspecific, more strongly typed type.
154+
pub fn into_model(self) -> Result<model::MempoolEntryFees, MempoolEntryFeesError> {
155+
use MempoolEntryFeesError as E;
156+
157+
Ok(model::MempoolEntryFees {
158+
base: Amount::from_btc(self.base).map_err(E::Base)?,
159+
modified: Amount::from_btc(self.modified).map_err(E::Modified)?,
160+
ancestor: Amount::from_btc(self.ancestor).map_err(E::MempoolEntry)?,
161+
descendant: Amount::from_btc(self.descendant).map_err(E::Descendant)?,
162+
})
163+
}
164+
}

0 commit comments

Comments
 (0)