Skip to content
This repository was archived by the owner on Apr 13, 2021. It is now read-only.

Use std::time API instead of u64s for timestamp and expiry time #8

Merged
merged 4 commits into from
Nov 27, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,10 @@
This repo provides datastructures for BOLT 11 lightning invoices.
It provides functions to parse and serialize invoices from and to bech32.

**Please be sure to run the test suite since we need to check assumptions
regarding `SystemTime`'s bounds on your platform. You can also call `check_platform`
on startup or in your test suite to do so.**

## Contributing
* same coding style standard as [rust-bitcoin/rust-lightning](https://github.com/rust-bitcoin/rust-lightning)
* use tabs and spaces (appropriately)
Expand Down
41 changes: 30 additions & 11 deletions src/de.rs
Original file line number Diff line number Diff line change
Expand Up @@ -311,8 +311,7 @@ impl FromBase32 for RawDataPart {
return Err(ParseError::TooShortDataPart);
}

let timestamp: u64 = parse_int_be(&data[0..7], 32)
.expect("7*5bit < 64bit, no overflow possible");
let timestamp = PositiveTimestamp::from_base32(&data[0..7])?;
let tagged = parse_tagged_parts(&data[7..])?;

Ok(RawDataPart {
Expand All @@ -322,6 +321,23 @@ impl FromBase32 for RawDataPart {
}
}

impl FromBase32 for PositiveTimestamp {
type Err = ParseError;

fn from_base32(b32: &[u5]) -> Result<Self, Self::Err> {
if b32.len() != 7 {
return Err(ParseError::InvalidSliceLength("PositiveTimestamp::from_base32()".into()));
}
let timestamp: u64 = parse_int_be(b32, 32)
.expect("7*5bit < 64bit, no overflow possible");
match PositiveTimestamp::from_unix_timestamp(timestamp) {
Ok(t) => Ok(t),
Err(CreationError::TimestampOutOfBounds) => Err(ParseError::TimestampOverflow),
Err(_) => unreachable!(),
}
}
}

impl FromBase32 for Signature {
type Err = ParseError;
fn from_base32(signature: &[u5]) -> Result<Self, Self::Err> {
Expand Down Expand Up @@ -469,11 +485,11 @@ impl FromBase32 for ExpiryTime {
type Err = ParseError;

fn from_base32(field_data: &[u5]) -> Result<ExpiryTime, ParseError> {
let expiry = parse_int_be::<u64, u5>(field_data, 32);
if let Some(expiry) = expiry {
Ok(ExpiryTime{seconds: expiry})
} else {
Err(ParseError::IntegerOverflowError)
match parse_int_be::<u64, u5>(field_data, 32)
.and_then(|t| ExpiryTime::from_seconds(t).ok()) // ok, since the only error is out of bounds
{
Some(t) => Ok(t),
None => Err(ParseError::IntegerOverflowError),
}
}
}
Expand Down Expand Up @@ -589,7 +605,8 @@ pub enum ParseError {
InvalidScriptHashLength,
InvalidRecoveryId,
InvalidSliceLength(String),
Skip
Skip,
TimestampOverflow,
}

#[derive(PartialEq, Debug, Clone)]
Expand Down Expand Up @@ -648,6 +665,7 @@ impl error::Error for ParseError {
InvalidRecoveryId => "recovery id is out of range (should be in [0,3])",
InvalidSliceLength(_) => "some slice had the wrong length",
Skip => "the tagged field has to be skipped because of an unexpected, but allowed property",
TimestampOverflow => "the invoice's timestamp could not be represented as SystemTime",
}
}
}
Expand Down Expand Up @@ -796,7 +814,7 @@ mod test {
use bech32::FromBase32;

let input = from_bech32("pu".as_bytes());
let expected = Ok(ExpiryTime{seconds: 60});
let expected = Ok(ExpiryTime::from_seconds(60).unwrap());
assert_eq!(ExpiryTime::from_base32(&input), expected);

let input_too_large = from_bech32("sqqqqqqqqqqqq".as_bytes());
Expand Down Expand Up @@ -924,7 +942,8 @@ mod test {
fn test_raw_signed_invoice_deserialization() {
use TaggedField::*;
use secp256k1::{RecoveryId, RecoverableSignature, Secp256k1};
use {SignedRawInvoice, Signature, RawInvoice, RawHrp, RawDataPart, Currency, Sha256};
use {SignedRawInvoice, Signature, RawInvoice, RawHrp, RawDataPart, Currency, Sha256,
PositiveTimestamp};

assert_eq!(
"lnbc1pvjluezpp5qqqsyqcyq5rqwzqfqqqsyqcyq5rqwzqfqqqsyqcyq5rqwzqfqypqdpl2pkx2ctnv5sxxmmw\
Expand All @@ -938,7 +957,7 @@ mod test {
si_prefix: None,
},
data: RawDataPart {
timestamp: 1496314658,
timestamp: PositiveTimestamp::from_unix_timestamp(1496314658).unwrap(),
tagged_fields: vec ! [
PaymentHash(Sha256(Sha256Hash::from_hex(
"0001020304050607080900010203040506070809000102030405060708090102"
Expand Down
Loading