Skip to content

Commit 2c4ef30

Browse files
committed
plugins: lsps: remove anyhow from tlvs
Remove anyhow as a dependency from the tlv module. This allows for a cleaner error handling Signed-off-by: Peter Neuroth <pet.v.ne@gmail.com>
1 parent 921b643 commit 2c4ef30

File tree

1 file changed

+31
-45
lines changed
  • plugins/lsps-plugin/src/core

1 file changed

+31
-45
lines changed

plugins/lsps-plugin/src/core/tlv.rs

Lines changed: 31 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
1-
use anyhow::Result;
21
use serde::{de::Error as DeError, Deserialize, Deserializer, Serialize, Serializer};
32
use std::{convert::TryFrom, fmt};
3+
use thiserror::Error;
44

55
pub const TLV_FORWARD_AMT: u64 = 2;
66
pub const TLV_OUTGOING_CLTV: u64 = 4;
@@ -16,41 +16,31 @@ pub struct TlvRecord {
1616
#[derive(Clone, Debug, Default, PartialEq, Eq, PartialOrd, Ord)]
1717
pub struct TlvStream(pub Vec<TlvRecord>);
1818

19-
#[derive(Debug)]
19+
#[derive(Debug, Error)]
2020
pub enum TlvError {
21+
#[error("duplicate tlv type {0}")]
2122
DuplicateType(u64),
23+
#[error("tlv types are not strictly increasing")]
2224
NotSorted,
25+
#[error("length mismatch type {0}: expected {1}, got {2}")]
2326
LengthMismatch(u64, usize, usize),
27+
#[error("truncated input")]
2428
Truncated,
29+
#[error("non-canonical bigsize encoding")]
2530
NonCanonicalBigSize,
31+
#[error("leftover bytes after parsing")]
2632
TrailingBytes,
27-
Hex(hex::FromHexError),
28-
Other(String),
33+
#[error("")]
34+
Hex(#[from] hex::FromHexError),
35+
#[error("length overflow")]
36+
Overflow,
37+
#[error("tu64 is not minimal, got a leading zero")]
38+
LeadingZero,
39+
#[error("failed to parse bytes to u64")]
40+
BytesToU64,
2941
}
3042

31-
impl fmt::Display for TlvError {
32-
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
33-
match self {
34-
TlvError::DuplicateType(t) => write!(f, "duplicate tlv type {}", t),
35-
TlvError::NotSorted => write!(f, "tlv types must be strictly increasing"),
36-
TlvError::LengthMismatch(t, e, g) => {
37-
write!(f, "length mismatch type {}: expected {}, got {}", t, e, g)
38-
}
39-
TlvError::Truncated => write!(f, "truncated input"),
40-
TlvError::NonCanonicalBigSize => write!(f, "non-canonical bigsize encoding"),
41-
TlvError::TrailingBytes => write!(f, "leftover bytes after parsing"),
42-
TlvError::Hex(e) => write!(f, "hex error: {}", e),
43-
TlvError::Other(s) => write!(f, "{}", s),
44-
}
45-
}
46-
}
47-
48-
impl std::error::Error for TlvError {}
49-
impl From<hex::FromHexError> for TlvError {
50-
fn from(e: hex::FromHexError) -> Self {
51-
TlvError::Hex(e)
52-
}
53-
}
43+
type Result<T> = std::result::Result<T, TlvError>;
5444

5545
impl TlvStream {
5646
pub fn to_bytes(&mut self) -> Result<Vec<u8>> {
@@ -82,7 +72,7 @@ impl TlvStream {
8272
let (len, n2) = decode_bigsize(bytes)?;
8373
bytes = &bytes[n2..];
8474

85-
let l = usize::try_from(len).map_err(|_| TlvError::Other("length too large".into()))?;
75+
let l = usize::try_from(len).map_err(|_| TlvError::Overflow)?;
8676
if bytes.len() < l {
8777
return Err(TlvError::Truncated.into());
8878
}
@@ -111,8 +101,7 @@ impl TlvStream {
111101
let (length, length_bytes) = decode_bigsize(bytes)?;
112102
let remaining = &bytes[length_bytes..];
113103

114-
let length_usize = usize::try_from(length)
115-
.map_err(|_| TlvError::Other("length prefix too large".into()))?;
104+
let length_usize = usize::try_from(length).map_err(|_| TlvError::Overflow)?;
116105

117106
if remaining.len() != length_usize {
118107
return Err(TlvError::LengthMismatch(0, length_usize, remaining.len()).into());
@@ -181,7 +170,7 @@ impl TlvStream {
181170

182171
/// Read a `tu64` if present, validating minimal encoding.
183172
/// Returns Ok(None) if the type isn't present.
184-
pub fn get_tu64(&self, type_: u64) -> Result<Option<u64>, TlvError> {
173+
pub fn get_tu64(&self, type_: u64) -> Result<Option<u64>> {
185174
if let Some(rec) = self.0.iter().find(|r| r.type_ == type_) {
186175
Ok(Some(decode_tu64(&rec.value)?))
187176
} else {
@@ -202,13 +191,10 @@ impl TlvStream {
202191
}
203192

204193
/// Read a `u64` if present.Returns Ok(None) if the type isn't present.
205-
pub fn get_u64(&self, type_: u64) -> Result<Option<u64>, TlvError> {
194+
pub fn get_u64(&self, type_: u64) -> Result<Option<u64>> {
206195
if let Some(rec) = self.0.iter().find(|r| r.type_ == type_) {
207-
let value = u64::from_be_bytes(
208-
rec.value[..]
209-
.try_into()
210-
.map_err(|e| TlvError::Other(format!("failed not decode to u64: {e}")))?,
211-
);
196+
let value =
197+
u64::from_be_bytes(rec.value[..].try_into().map_err(|_| TlvError::BytesToU64)?);
212198
Ok(Some(value))
213199
} else {
214200
Ok(None)
@@ -217,22 +203,22 @@ impl TlvStream {
217203
}
218204

219205
impl Serialize for TlvStream {
220-
fn serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
206+
fn serialize<S: Serializer>(&self, serializer: S) -> std::result::Result<S::Ok, S::Error> {
221207
let mut tmp = self.clone();
222208
let bytes = tmp.to_bytes().map_err(serde::ser::Error::custom)?;
223209
serializer.serialize_str(&hex::encode(bytes))
224210
}
225211
}
226212

227213
impl<'de> Deserialize<'de> for TlvStream {
228-
fn deserialize<D: Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
214+
fn deserialize<D: Deserializer<'de>>(deserializer: D) -> std::result::Result<Self, D::Error> {
229215
struct V;
230216
impl<'de> serde::de::Visitor<'de> for V {
231217
type Value = TlvStream;
232218
fn expecting(&self, f: &mut fmt::Formatter) -> fmt::Result {
233219
write!(f, "a hex string representing a Lightning TLV stream")
234220
}
235-
fn visit_str<E: DeError>(self, s: &str) -> Result<Self::Value, E> {
221+
fn visit_str<E: DeError>(self, s: &str) -> std::result::Result<Self::Value, E> {
236222
let bytes = hex::decode(s).map_err(E::custom)?;
237223
TlvStream::from_bytes_auto(&bytes).map_err(E::custom)
238224
}
@@ -242,8 +228,8 @@ impl<'de> Deserialize<'de> for TlvStream {
242228
}
243229

244230
impl TryFrom<&[u8]> for TlvStream {
245-
type Error = anyhow::Error;
246-
fn try_from(value: &[u8]) -> Result<Self> {
231+
type Error = TlvError;
232+
fn try_from(value: &[u8]) -> std::result::Result<Self, Self::Error> {
247233
TlvStream::from_bytes(value)
248234
}
249235
}
@@ -326,15 +312,15 @@ pub fn encode_tu64(v: u64) -> Vec<u8> {
326312

327313
/// Decode a BOLT #1 `tu64`, enforcing minimal form.
328314
/// Empty slice -> 0. Leading 0x00 or >8 bytes is invalid.
329-
fn decode_tu64(raw: &[u8]) -> Result<u64, TlvError> {
315+
fn decode_tu64(raw: &[u8]) -> Result<u64> {
330316
if raw.is_empty() {
331317
return Ok(0);
332318
}
333319
if raw.len() > 8 {
334-
return Err(TlvError::Other("tu64 too long".into()));
320+
return Err(TlvError::Overflow);
335321
}
336322
if raw[0] == 0 {
337-
return Err(TlvError::Other("non-minimal tu64 (leading zero)".into()));
323+
return Err(TlvError::LeadingZero);
338324
}
339325
let mut buf = [0u8; 8];
340326
buf[8 - raw.len()..].copy_from_slice(raw);

0 commit comments

Comments
 (0)