Skip to content

Commit

Permalink
Fixes bug with incorrect conversion of JsonValue to Txid.
Browse files Browse the repository at this point in the history
The bug happens when there is a call to a bitcoind that expects a transaction id as a response and
results in a corrupted Txid being returned.
  • Loading branch information
yellowred committed Dec 15, 2023
1 parent c9d52cf commit 6b3c2c6
Showing 1 changed file with 18 additions and 21 deletions.
39 changes: 18 additions & 21 deletions lightning-block-sync/src/convert.rs
Original file line number Diff line number Diff line change
Expand Up @@ -162,25 +162,8 @@ impl TryInto<(BlockHash, Option<u32>)> for JsonResponse {
impl TryInto<Txid> for JsonResponse {
type Error = std::io::Error;
fn try_into(self) -> std::io::Result<Txid> {
match self.0.as_str() {
None => Err(std::io::Error::new(
std::io::ErrorKind::InvalidData,
"expected JSON string",
)),
Some(hex_data) => match Vec::<u8>::from_hex(hex_data) {
Err(_) => Err(std::io::Error::new(
std::io::ErrorKind::InvalidData,
"invalid hex data",
)),
Ok(txid_data) => match encode::deserialize(&txid_data) {
Err(_) => Err(std::io::Error::new(
std::io::ErrorKind::InvalidData,
"invalid txid",
)),
Ok(txid) => Ok(txid),
},
},
}
let hex_data = self.0.as_str().ok_or(Self::Error::new(std::io::ErrorKind::InvalidData, "expected JSON string" ))?;
Txid::from_str(hex_data).map_err(|err|Self::Error::new(std::io::ErrorKind::InvalidData, err.to_string() ))
}
}

Expand Down Expand Up @@ -622,7 +605,7 @@ pub(crate) mod tests {
match TryInto::<Txid>::try_into(response) {
Err(e) => {
assert_eq!(e.kind(), std::io::ErrorKind::InvalidData);
assert_eq!(e.get_ref().unwrap().to_string(), "invalid hex data");
assert_eq!(e.get_ref().unwrap().to_string(), "bad hex string length 6 (expected 64)");
}
Ok(_) => panic!("Expected error"),
}
Expand All @@ -634,7 +617,7 @@ pub(crate) mod tests {
match TryInto::<Txid>::try_into(response) {
Err(e) => {
assert_eq!(e.kind(), std::io::ErrorKind::InvalidData);
assert_eq!(e.get_ref().unwrap().to_string(), "invalid txid");
assert_eq!(e.get_ref().unwrap().to_string(), "bad hex string length 4 (expected 64)");
}
Ok(_) => panic!("Expected error"),
}
Expand All @@ -650,6 +633,20 @@ pub(crate) mod tests {
}
}

#[test]
fn into_txid_from_bitcoind_rpc_json_response() {
let mut rpc_response = serde_json::json!(
{"error": "", "id": "770", "result": "7934f775149929a8b742487129a7c3a535dfb612f0b726cc67bc10bc2628f906"}

);
let r: std::io::Result<Txid> = JsonResponse(rpc_response.get_mut("result").unwrap().take())
.try_into();
assert_eq!(
r.unwrap().to_string(),
"7934f775149929a8b742487129a7c3a535dfb612f0b726cc67bc10bc2628f906"
);
}

// TryInto<Transaction> can be used in two ways, first with plain hex response where data is
// the hex encoded transaction (e.g. as a result of getrawtransaction) or as a JSON object
// where the hex encoded transaction can be found in the hex field of the object (if present)
Expand Down

0 comments on commit 6b3c2c6

Please sign in to comment.