Skip to content

Commit 86e94c4

Browse files
authored
Merge pull request #2116 from TheBlueMatt/2023-03-serde-sucks
Drop `serde` dependency from `lightning-block-sync`
2 parents 48fa2fd + b701a6c commit 86e94c4

File tree

2 files changed

+25
-44
lines changed

2 files changed

+25
-44
lines changed

lightning-block-sync/Cargo.toml

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -14,15 +14,14 @@ all-features = true
1414
rustdoc-args = ["--cfg", "docsrs"]
1515

1616
[features]
17-
rest-client = [ "serde", "serde_json", "chunked_transfer" ]
18-
rpc-client = [ "serde", "serde_json", "chunked_transfer" ]
17+
rest-client = [ "serde_json", "chunked_transfer" ]
18+
rpc-client = [ "serde_json", "chunked_transfer" ]
1919

2020
[dependencies]
2121
bitcoin = "0.29.0"
2222
lightning = { version = "0.0.114", path = "../lightning" }
2323
futures-util = { version = "0.3" }
2424
tokio = { version = "1.0", features = [ "io-util", "net", "time" ], optional = true }
25-
serde = { version = "1.0", features = ["derive"], optional = true }
2625
serde_json = { version = "1.0", optional = true }
2726
chunked_transfer = { version = "1.4", optional = true }
2827

lightning-block-sync/src/convert.rs

Lines changed: 23 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -5,11 +5,9 @@ use crate::{BlockHeaderData, BlockSourceError};
55
use bitcoin::blockdata::block::{Block, BlockHeader};
66
use bitcoin::consensus::encode;
77
use bitcoin::hash_types::{BlockHash, TxMerkleNode, Txid};
8-
use bitcoin::hashes::hex::{FromHex, ToHex};
8+
use bitcoin::hashes::hex::FromHex;
99
use bitcoin::Transaction;
1010

11-
use serde::Deserialize;
12-
1311
use serde_json;
1412

1513
use std::convert::From;
@@ -46,7 +44,7 @@ impl TryInto<BlockHeaderData> for JsonResponse {
4644
type Error = std::io::Error;
4745

4846
fn try_into(self) -> std::io::Result<BlockHeaderData> {
49-
let mut header = match self.0 {
47+
let header = match self.0 {
5048
serde_json::Value::Array(mut array) if !array.is_empty() => array.drain(..).next().unwrap(),
5149
serde_json::Value::Object(_) => self.0,
5250
_ => return Err(std::io::Error::new(std::io::ErrorKind::InvalidData, "unexpected JSON type")),
@@ -57,51 +55,34 @@ impl TryInto<BlockHeaderData> for JsonResponse {
5755
}
5856

5957
// Add an empty previousblockhash for the genesis block.
60-
if let None = header.get("previousblockhash") {
61-
let hash: BlockHash = BlockHash::all_zeros();
62-
header.as_object_mut().unwrap().insert("previousblockhash".to_string(), serde_json::json!(hash.to_hex()));
63-
}
64-
65-
match serde_json::from_value::<GetHeaderResponse>(header) {
66-
Err(_) => Err(std::io::Error::new(std::io::ErrorKind::InvalidData, "invalid header response")),
67-
Ok(response) => match response.try_into() {
68-
Err(_) => Err(std::io::Error::new(std::io::ErrorKind::InvalidData, "invalid header data")),
69-
Ok(header) => Ok(header),
70-
},
58+
match header.try_into() {
59+
Err(_) => Err(std::io::Error::new(std::io::ErrorKind::InvalidData, "invalid header data")),
60+
Ok(header) => Ok(header),
7161
}
7262
}
7363
}
7464

75-
/// Response data from `getblockheader` RPC and `headers` REST requests.
76-
#[derive(Deserialize)]
77-
struct GetHeaderResponse {
78-
pub version: i32,
79-
pub merkleroot: String,
80-
pub time: u32,
81-
pub nonce: u32,
82-
pub bits: String,
83-
pub previousblockhash: String,
84-
85-
pub chainwork: String,
86-
pub height: u32,
87-
}
65+
impl TryFrom<serde_json::Value> for BlockHeaderData {
66+
type Error = ();
8867

89-
/// Converts from `GetHeaderResponse` to `BlockHeaderData`.
90-
impl TryFrom<GetHeaderResponse> for BlockHeaderData {
91-
type Error = bitcoin::hashes::hex::Error;
68+
fn try_from(response: serde_json::Value) -> Result<Self, ()> {
69+
macro_rules! get_field { ($name: expr, $ty_access: tt) => {
70+
response.get($name).ok_or(())?.$ty_access().ok_or(())?
71+
} }
9272

93-
fn try_from(response: GetHeaderResponse) -> Result<Self, bitcoin::hashes::hex::Error> {
9473
Ok(BlockHeaderData {
9574
header: BlockHeader {
96-
version: response.version,
97-
prev_blockhash: BlockHash::from_hex(&response.previousblockhash)?,
98-
merkle_root: TxMerkleNode::from_hex(&response.merkleroot)?,
99-
time: response.time,
100-
bits: u32::from_be_bytes(<[u8; 4]>::from_hex(&response.bits)?),
101-
nonce: response.nonce,
75+
version: get_field!("version", as_i64).try_into().map_err(|_| ())?,
76+
prev_blockhash: if let Some(hash_str) = response.get("previousblockhash") {
77+
BlockHash::from_hex(hash_str.as_str().ok_or(())?).map_err(|_| ())?
78+
} else { BlockHash::all_zeros() },
79+
merkle_root: TxMerkleNode::from_hex(get_field!("merkleroot", as_str)).map_err(|_| ())?,
80+
time: get_field!("time", as_u64).try_into().map_err(|_| ())?,
81+
bits: u32::from_be_bytes(<[u8; 4]>::from_hex(get_field!("bits", as_str)).map_err(|_| ())?),
82+
nonce: get_field!("nonce", as_u64).try_into().map_err(|_| ())?,
10283
},
103-
chainwork: hex_to_uint256(&response.chainwork)?,
104-
height: response.height,
84+
chainwork: hex_to_uint256(get_field!("chainwork", as_str)).map_err(|_| ())?,
85+
height: get_field!("height", as_u64).try_into().map_err(|_| ())?,
10586
})
10687
}
10788
}
@@ -250,6 +231,7 @@ pub(crate) mod tests {
250231
use super::*;
251232
use bitcoin::blockdata::constants::genesis_block;
252233
use bitcoin::hashes::Hash;
234+
use bitcoin::hashes::hex::ToHex;
253235
use bitcoin::network::constants::Network;
254236
use serde_json::value::Number;
255237
use serde_json::Value;
@@ -308,7 +290,7 @@ pub(crate) mod tests {
308290
match TryInto::<BlockHeaderData>::try_into(response) {
309291
Err(e) => {
310292
assert_eq!(e.kind(), std::io::ErrorKind::InvalidData);
311-
assert_eq!(e.get_ref().unwrap().to_string(), "invalid header response");
293+
assert_eq!(e.get_ref().unwrap().to_string(), "invalid header data");
312294
},
313295
Ok(_) => panic!("Expected error"),
314296
}

0 commit comments

Comments
 (0)