Merge pull request #3349 from TheBlueMatt/2024-10-3270-followups

Minor #3270 Followups
This commit is contained in:
Matt Corallo 2024-10-11 13:47:39 +00:00 committed by GitHub
commit ad19d93180
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
4 changed files with 19 additions and 17 deletions

View file

@ -1,3 +1,4 @@
use alloc::string;
#[cfg(feature = "std")] #[cfg(feature = "std")]
use std::error; use std::error;
#[cfg(not(feature = "std"))] #[cfg(not(feature = "std"))]
@ -5,7 +6,6 @@ use core::convert::TryFrom;
use core::fmt; use core::fmt;
use core::fmt::{Display, Formatter}; use core::fmt::{Display, Formatter};
use core::num::ParseIntError; use core::num::ParseIntError;
use core::str;
use core::str::FromStr; use core::str::FromStr;
use bech32::primitives::decode::{CheckedHrpstring, CheckedHrpstringError}; use bech32::primitives::decode::{CheckedHrpstring, CheckedHrpstringError};
@ -613,7 +613,7 @@ impl FromBase32 for Description {
fn from_base32(field_data: &[Fe32]) -> Result<Description, Bolt11ParseError> { fn from_base32(field_data: &[Fe32]) -> Result<Description, Bolt11ParseError> {
let bytes = Vec::<u8>::from_base32(field_data)?; let bytes = Vec::<u8>::from_base32(field_data)?;
let description = String::from(str::from_utf8(&bytes)?); let description = String::from_utf8(bytes)?;
Ok(Description::new(description).expect( Ok(Description::new(description).expect(
"Max len is 639=floor(1023*5/8) since the len field is only 10bits long" "Max len is 639=floor(1023*5/8) since the len field is only 10bits long"
)) ))
@ -712,7 +712,7 @@ impl FromBase32 for PrivateRoute {
return Err(Bolt11ParseError::UnexpectedEndOfTaggedFields); return Err(Bolt11ParseError::UnexpectedEndOfTaggedFields);
} }
let mut route_hops = Vec::<RouteHintHop>::new(); let mut route_hops = Vec::with_capacity(bytes.len() / 51);
let mut bytes = bytes.as_slice(); let mut bytes = bytes.as_slice();
while !bytes.is_empty() { while !bytes.is_empty() {
@ -824,7 +824,7 @@ macro_rules! from_error {
from_error!(Bolt11ParseError::MalformedSignature, bitcoin::secp256k1::Error); from_error!(Bolt11ParseError::MalformedSignature, bitcoin::secp256k1::Error);
from_error!(Bolt11ParseError::ParseAmountError, ParseIntError); from_error!(Bolt11ParseError::ParseAmountError, ParseIntError);
from_error!(Bolt11ParseError::DescriptionDecodeError, str::Utf8Error); from_error!(Bolt11ParseError::DescriptionDecodeError, string::FromUtf8Error);
impl From<CheckedHrpstringError> for Bolt11ParseError { impl From<CheckedHrpstringError> for Bolt11ParseError {
fn from(e: CheckedHrpstringError) -> Self { fn from(e: CheckedHrpstringError) -> Self {

View file

@ -51,7 +51,7 @@ use core::num::ParseIntError;
use core::ops::Deref; use core::ops::Deref;
use core::slice::Iter; use core::slice::Iter;
use core::time::Duration; use core::time::Duration;
use core::str; use alloc::string;
#[cfg(feature = "serde")] #[cfg(feature = "serde")]
use serde::{Deserialize, Deserializer,Serialize, Serializer, de::Error}; use serde::{Deserialize, Deserializer,Serialize, Serializer, de::Error};
@ -98,7 +98,7 @@ pub enum Bolt11ParseError {
MalformedHRP, MalformedHRP,
TooShortDataPart, TooShortDataPart,
UnexpectedEndOfTaggedFields, UnexpectedEndOfTaggedFields,
DescriptionDecodeError(str::Utf8Error), DescriptionDecodeError(string::FromUtf8Error),
PaddingError, PaddingError,
IntegerOverflowError, IntegerOverflowError,
InvalidSegWitProgramLength, InvalidSegWitProgramLength,
@ -313,6 +313,7 @@ impl RawHrp {
pub fn to_hrp(&self) -> bech32::Hrp { pub fn to_hrp(&self) -> bech32::Hrp {
let hrp_str = self.to_string(); let hrp_str = self.to_string();
let s = core::str::from_utf8(&hrp_str.as_bytes()).expect("HRP bytes should be ASCII"); let s = core::str::from_utf8(&hrp_str.as_bytes()).expect("HRP bytes should be ASCII");
debug_assert!(bech32::Hrp::parse(s).is_ok(), "We should always build BIP 173-valid HRPs");
bech32::Hrp::parse_unchecked(s) bech32::Hrp::parse_unchecked(s)
} }
} }

View file

@ -29,7 +29,7 @@ pub(crate) trait Base32Len: Base32Iterable {
impl<const N: usize> Base32Iterable for [u8; N] { impl<const N: usize> Base32Iterable for [u8; N] {
fn fe_iter<'s>(&'s self) -> Box<dyn Iterator<Item = Fe32> + 's> { fn fe_iter<'s>(&'s self) -> Box<dyn Iterator<Item = Fe32> + 's> {
Box::new((*self).into_iter().bytes_to_fes()) self[..].fe_iter()
} }
} }
@ -218,19 +218,20 @@ impl Display for SiPrefix {
} }
/// Encode an integer to base32, big endian, without leading zeros /// Encode an integer to base32, big endian, without leading zeros
fn encode_int_be_base32(int: u64) -> Vec<Fe32> { fn encode_int_be_base32(int: u64) -> impl ExactSizeIterator<Item=Fe32> {
let base = 32u64; let base = 32u64;
// (64 + 4) / 5 == 13 // (64 + 4) / 5 == 13
let mut out_vec = Vec::<Fe32>::with_capacity(13); let mut out = [Fe32::Q; 13];
let mut out_pos = 0;
let mut rem_int = int; let mut rem_int = int;
while rem_int != 0 { while rem_int != 0 {
out_vec.push(Fe32::try_from((rem_int % base) as u8).expect("always <32")); out[out_pos] = Fe32::try_from((rem_int % base) as u8).expect("always <32");
out_pos += 1;
rem_int /= base; rem_int /= base;
} }
out_vec.reverse(); out.into_iter().take(out_pos).rev()
out_vec
} }
/// The length of the output of `encode_int_be_base32`. /// The length of the output of `encode_int_be_base32`.
@ -252,7 +253,7 @@ impl Base32Iterable for PositiveTimestamp {
let fes = encode_int_be_base32(self.as_unix_timestamp()); let fes = encode_int_be_base32(self.as_unix_timestamp());
debug_assert!(fes.len() <= 7, "Invalid timestamp length"); debug_assert!(fes.len() <= 7, "Invalid timestamp length");
let to_pad = 7 - fes.len(); let to_pad = 7 - fes.len();
Box::new(core::iter::repeat(Fe32::Q).take(to_pad).chain(fes.into_iter())) Box::new(core::iter::repeat(Fe32::Q).take(to_pad).chain(fes))
} }
} }
@ -305,7 +306,7 @@ impl Base32Len for PayeePubKey {
impl Base32Iterable for ExpiryTime { impl Base32Iterable for ExpiryTime {
fn fe_iter<'s>(&'s self) -> Box<dyn Iterator<Item = Fe32> + 's> { fn fe_iter<'s>(&'s self) -> Box<dyn Iterator<Item = Fe32> + 's> {
Box::new(encode_int_be_base32(self.as_seconds()).into_iter()) Box::new(encode_int_be_base32(self.as_seconds()))
} }
} }
@ -317,7 +318,7 @@ impl Base32Len for ExpiryTime {
impl Base32Iterable for MinFinalCltvExpiryDelta { impl Base32Iterable for MinFinalCltvExpiryDelta {
fn fe_iter<'s>(&'s self) -> Box<dyn Iterator<Item = Fe32> + 's> { fn fe_iter<'s>(&'s self) -> Box<dyn Iterator<Item = Fe32> + 's> {
Box::new(encode_int_be_base32(self.0).into_iter()) Box::new(encode_int_be_base32(self.0))
} }
} }
@ -504,6 +505,6 @@ mod test {
.map(|v| Fe32::try_from(v).expect("<= 31")) .map(|v| Fe32::try_from(v).expect("<= 31"))
.collect::<Vec<Fe32>>(); .collect::<Vec<Fe32>>();
assert_eq!(expected_out, encode_int_be_base32(input)); assert_eq!(expected_out, encode_int_be_base32(input).collect::<Vec<Fe32>>());
} }
} }

View file

@ -58,7 +58,7 @@ mod sealed {
let parsed = CheckedHrpstring::new::<NoChecksum>(encoded.as_ref())?; let parsed = CheckedHrpstring::new::<NoChecksum>(encoded.as_ref())?;
let hrp = parsed.hrp(); let hrp = parsed.hrp();
if hrp.to_string() != Self::BECH32_HRP { if hrp.as_str() != Self::BECH32_HRP {
return Err(Bolt12ParseError::InvalidBech32Hrp); return Err(Bolt12ParseError::InvalidBech32Hrp);
} }