Merge rust-bitcoin/rust-bitcoin#1544: amount parses 0 msats

0cf6da4f03 amount parses 0 msats (bnabi)

Pull request description:

  Closes #1529

  0 msats should be parasable.

ACKs for top commit:
  Kixunil:
    ACK 0cf6da4f03
  tcharding:
    ACK 0cf6da4f03
  apoelstra:
    ACK 0cf6da4f03

Tree-SHA512: aeb15ed46f21b3e75bbd80094a103900ad0f42995abdd32476db771c623aea6e3c557a4180f1d9a92d0ad62e703b9ad838d9be1b43d61624dd6e6bce31a8b81b
This commit is contained in:
Andrew Poelstra 2023-01-23 21:40:02 +00:00
commit c4b8d452da
No known key found for this signature in database
GPG Key ID: C588D63CE41B97C1
1 changed files with 28 additions and 10 deletions

View File

@ -253,7 +253,10 @@ fn parse_signed_to_satoshi(
// many as the difference in precision.
let last_n = unsigned_abs(precision_diff).into();
if is_too_precise(s, last_n) {
return Err(ParseAmountError::TooPrecise);
match s.parse::<i64>() {
Ok(v) if v == 0_i64 => return Ok((is_negative, 0)),
_ => return Err(ParseAmountError::TooPrecise),
}
}
s = &s[0..s.len() - last_n];
0
@ -1545,6 +1548,30 @@ mod tests {
use super::*;
#[test]
fn from_str_zero() {
let denoms = vec!["BTC", "mBTC", "uBTC", "nBTC", "pBTC", "bits", "sats", "msats"];
for denom in denoms {
for v in &["0", "000"] {
let s = format!("{} {}", v, denom);
match Amount::from_str(&s) {
Err(e) => panic!("Failed to crate amount from {}: {:?}", s, e),
Ok(amount) => assert_eq!(amount, Amount::from_sat(0)),
}
}
let s = format!("-0 {}", denom);
match Amount::from_str(&s) {
Err(e) => assert_eq!(e, ParseAmountError::Negative),
Ok(_) => panic!("Unsigned amount from {}", s),
}
match SignedAmount::from_str(&s) {
Err(e) => panic!("Failed to crate amount from {}: {:?}", s, e),
Ok(amount) => assert_eq!(amount, SignedAmount::from_sat(0)),
}
}
}
#[test]
fn mul_div() {
let sat = Amount::from_sat;
@ -1939,15 +1966,6 @@ mod tests {
scase("-200000000000 BTC", Err(E::TooBig));
case("18446744073709551616 sat", Err(E::TooBig));
scase("0 msat", Err(E::TooPrecise));
scase("-0 msat", Err(E::TooPrecise));
scase("000 msat", Err(E::TooPrecise));
scase("-000 msat", Err(E::TooPrecise));
case("0 msat", Err(E::TooPrecise));
case("-0 msat", Err(E::TooPrecise));
case("000 msat", Err(E::TooPrecise));
case("-000 msat", Err(E::TooPrecise));
case(".5 bits", Ok(Amount::from_sat(50)));
scase("-.5 bits", Ok(SignedAmount::from_sat(-50)));
case("0.00253583 BTC", Ok(Amount::from_sat(253583)));