From d67b0476a2ce33c56810446838456b9fa2e35d6a Mon Sep 17 00:00:00 2001 From: Michael Schmoock Date: Tue, 1 Dec 2020 13:38:43 +0100 Subject: [PATCH 1/2] pyln: fix msat from float str Changelog-fixed: pyln: parsing msat from a float string --- contrib/pyln-client/pyln/client/lightning.py | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/contrib/pyln-client/pyln/client/lightning.py b/contrib/pyln-client/pyln/client/lightning.py index 4a7ee33f038b..febc4b9449fa 100644 --- a/contrib/pyln-client/pyln/client/lightning.py +++ b/contrib/pyln-client/pyln/client/lightning.py @@ -49,19 +49,19 @@ def __init__(self, v: Union[int, str, Decimal]): """ if isinstance(v, str): if v.endswith("msat"): - self.millisatoshis = int(v[0:-4]) + parsed = Decimal(v[0:-4]) elif v.endswith("sat"): - self.millisatoshis = int(v[0:-3]) * 1000 + parsed = Decimal(v[0:-3]) * 1000 elif v.endswith("btc"): - self.millisatoshis = int(v[0:-3]) * 1000 * 10**8 + parsed = Decimal(v[0:-3]) * 1000 * 10**8 else: raise TypeError( "Millisatoshi must be string with msat/sat/btc suffix or" " int" ) - if self.millisatoshis != int(self.millisatoshis): + if parsed != int(parsed): raise ValueError("Millisatoshi must be a whole number") - self.millisatoshis = int(self.millisatoshis) + self.millisatoshis = int(parsed) elif isinstance(v, Millisatoshi): self.millisatoshis = v.millisatoshis From a32a686c9f47f3d1644e0e76362af5e82b0b84dc Mon Sep 17 00:00:00 2001 From: Michael Schmoock Date: Mon, 30 Nov 2020 17:33:48 +0100 Subject: [PATCH 2/2] pyln: failing test msat from float str We were not able to create pyln Millisatoshi from floats, e.g.: - "0.01btc" - "0.1sat" - ... This adds a test that makes sure this won't happen again. --- contrib/pyln-client/tests/test_units.py | 27 +++++++++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/contrib/pyln-client/tests/test_units.py b/contrib/pyln-client/tests/test_units.py index 0af11e168c33..0491338032b0 100644 --- a/contrib/pyln-client/tests/test_units.py +++ b/contrib/pyln-client/tests/test_units.py @@ -1,4 +1,5 @@ from pyln.client import Millisatoshi +import pytest # type: ignore def test_to_approx_str(): @@ -34,3 +35,29 @@ def test_to_approx_str(): assert amount.to_approx_str() == "12btc" amount = Millisatoshi('1200000000sat') assert amount.to_approx_str(1) == "12btc" # note: no rounding + + +def test_floats(): + # test parsing amounts from floating number strings + amount = Millisatoshi("0.01btc") + assert amount.to_satoshi() == 10**6 + amount = Millisatoshi("1.01btc") + assert amount.to_satoshi() == 10**8 + 10**6 + amount = Millisatoshi("0.1sat") + assert int(amount) == 100 + amount = Millisatoshi("0.01sat") + assert int(amount) == 10 + amount = Millisatoshi("1.1sat") + assert int(amount) == 1100 + + # test floating point arithmetic + amount = Millisatoshi("1000msat") * 0.1 + assert int(amount) == 100 + + # sub millisatoshi are not a concept yet + with pytest.raises(ValueError, match='Millisatoshi must be a whole number'): + amount = Millisatoshi("0.000000000001btc") + with pytest.raises(ValueError, match='Millisatoshi must be a whole number'): + amount = Millisatoshi("0.0001sat") + with pytest.raises(ValueError, match='Millisatoshi must be a whole number'): + amount = Millisatoshi("0.1msat")