Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

pyln: extend msat floating testcases #4246

Merged
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
6 changes: 3 additions & 3 deletions contrib/pyln-client/pyln/client/lightning.py
Original file line number Diff line number Diff line change
Expand Up @@ -177,13 +177,13 @@ def __sub__(self, other: 'Millisatoshi') -> 'Millisatoshi':
return Millisatoshi(int(self) - int(other))

def __mul__(self, other: int) -> 'Millisatoshi':
return Millisatoshi(self.millisatoshis * other)
return Millisatoshi(floor(self.millisatoshis * other))

def __truediv__(self, other: Union[int, float]) -> 'Millisatoshi':
return Millisatoshi(int(self.millisatoshis / other))
return Millisatoshi(floor(self.millisatoshis / other))

def __floordiv__(self, other: Union[int, float]) -> 'Millisatoshi':
return Millisatoshi(int(self.millisatoshis // float(other)))
return Millisatoshi(floor(self.millisatoshis // float(other)))

def __mod__(self, other: Union[float, int]) -> 'Millisatoshi':
return Millisatoshi(int(self.millisatoshis % other))
Expand Down
214 changes: 211 additions & 3 deletions contrib/pyln-client/tests/test_units.py
Original file line number Diff line number Diff line change
Expand Up @@ -53,11 +53,219 @@ def test_floats():
# test floating point arithmetic
amount = Millisatoshi("1000msat") * 0.1
assert int(amount) == 100
amount = Millisatoshi("100msat") * 0.1
assert int(amount) == 10
amount = Millisatoshi("10msat") * 0.1
assert int(amount) == 1


def test_zero():
# zero amounts are of course valid
amount = Millisatoshi("0btc")
assert int(amount) == 0
amount = Millisatoshi("0sat")
assert int(amount) == 0
amount = Millisatoshi("0msat")
assert int(amount) == 0

# zero floating amount as well
amount = Millisatoshi("0.0btc")
assert int(amount) == 0
amount = Millisatoshi("0.0sat")
assert int(amount) == 0
amount = Millisatoshi("0.0msat")
assert int(amount) == 0

# also anything multiplied by zero
amount = Millisatoshi("1btc") * 0
assert int(amount) == 0
amount = Millisatoshi("1sat") * 0
assert int(amount) == 0
amount = Millisatoshi("1msat") * 0
assert int(amount) == 0

# and multiplied by a floating zero
amount = Millisatoshi("1btc") * 0.0
assert int(amount) == 0
amount = Millisatoshi("1sat") * 0.0
assert int(amount) == 0
amount = Millisatoshi("1msat") * 0.0
assert int(amount) == 0


def test_round_zero():
# everything below 1msat should round down to zero
amount = Millisatoshi("1msat") * 0.9
assert int(amount) == 0
amount = Millisatoshi("10msat") * 0.09
assert int(amount) == 0
amount = Millisatoshi("100msat") * 0.009
assert int(amount) == 0
amount = Millisatoshi("1000msat") * 0.0009
assert int(amount) == 0

amount = Millisatoshi("1sat") * 0.0009
assert int(amount) == 0
amount = Millisatoshi("0.1sat") * 0.009
assert int(amount) == 0
amount = Millisatoshi("0.01sat") * 0.09
assert int(amount) == 0
amount = Millisatoshi("0.001sat") * 0.9
assert int(amount) == 0

amount = Millisatoshi("10sat") * 0.00009
assert int(amount) == 0
amount = Millisatoshi("100sat") * 0.000009
assert int(amount) == 0
amount = Millisatoshi("1000sat") * 0.0000009
assert int(amount) == 0
amount = Millisatoshi("10000sat") * 0.00000009
assert int(amount) == 0
amount = Millisatoshi("10000sat") * 0.00000009
assert int(amount) == 0

amount = Millisatoshi("1btc") * 0.000000000009
assert int(amount) == 0
amount = Millisatoshi("0.1btc") * 0.00000000009
assert int(amount) == 0
amount = Millisatoshi("0.01btc") * 0.0000000009
assert int(amount) == 0
amount = Millisatoshi("0.001btc") * 0.000000009
assert int(amount) == 0
amount = Millisatoshi("0.0001btc") * 0.00000009
assert int(amount) == 0
amount = Millisatoshi("0.00001btc") * 0.0000009
assert int(amount) == 0
amount = Millisatoshi("0.000001btc") * 0.000009
assert int(amount) == 0
amount = Millisatoshi("0.0000001btc") * 0.00009
assert int(amount) == 0
amount = Millisatoshi("0.00000001btc") * 0.0009
assert int(amount) == 0
amount = Millisatoshi("0.000000001btc") * 0.009
assert int(amount) == 0
amount = Millisatoshi("0.0000000001btc") * 0.09
assert int(amount) == 0
amount = Millisatoshi("0.00000000001btc") * 0.9
assert int(amount) == 0


def test_round_down():
# sub msat significatns should be floored
amount = Millisatoshi("2msat") * 0.9
assert int(amount) == 1
amount = Millisatoshi("20msat") * 0.09
assert int(amount) == 1
amount = Millisatoshi("200msat") * 0.009
assert int(amount) == 1
amount = Millisatoshi("2000msat") * 0.0009
assert int(amount) == 1

amount = Millisatoshi("2sat") * 0.0009
assert int(amount) == 1
amount = Millisatoshi("0.2sat") * 0.009
assert int(amount) == 1
amount = Millisatoshi("0.02sat") * 0.09
assert int(amount) == 1
amount = Millisatoshi("0.002sat") * 0.9
assert int(amount) == 1

amount = Millisatoshi("20sat") * 0.00009
assert int(amount) == 1
amount = Millisatoshi("200sat") * 0.000009
assert int(amount) == 1
amount = Millisatoshi("2000sat") * 0.0000009
assert int(amount) == 1
amount = Millisatoshi("20000sat") * 0.00000009
assert int(amount) == 1
amount = Millisatoshi("20000sat") * 0.00000009
assert int(amount) == 1

amount = Millisatoshi("2btc") * 0.000000000009
assert int(amount) == 1
amount = Millisatoshi("0.2btc") * 0.00000000009
assert int(amount) == 1
amount = Millisatoshi("0.02btc") * 0.0000000009
assert int(amount) == 1
amount = Millisatoshi("0.002btc") * 0.000000009
assert int(amount) == 1
amount = Millisatoshi("0.0002btc") * 0.00000009
assert int(amount) == 1
amount = Millisatoshi("0.00002btc") * 0.0000009
assert int(amount) == 1
amount = Millisatoshi("0.000002btc") * 0.000009
assert int(amount) == 1
amount = Millisatoshi("0.0000002btc") * 0.00009
assert int(amount) == 1
amount = Millisatoshi("0.00000002btc") * 0.0009
assert int(amount) == 1
amount = Millisatoshi("0.000000002btc") * 0.009
assert int(amount) == 1
amount = Millisatoshi("0.0000000002btc") * 0.09
assert int(amount) == 1
amount = Millisatoshi("0.00000000002btc") * 0.9
assert int(amount) == 1


def test_nosubmsat():
# sub millisatoshi are not a concept yet
with pytest.raises(ValueError, match='Millisatoshi must be a whole number'):
amount = Millisatoshi("0.000000000001btc")
Millisatoshi("0.1msat")
with pytest.raises(ValueError, match='Millisatoshi must be a whole number'):
Millisatoshi(".1msat")
with pytest.raises(ValueError, match='Millisatoshi must be a whole number'):
Millisatoshi("0.0001sat")
with pytest.raises(ValueError, match='Millisatoshi must be a whole number'):
amount = Millisatoshi("0.0001sat")
Millisatoshi(".0001sat")
with pytest.raises(ValueError, match='Millisatoshi must be a whole number'):
amount = Millisatoshi("0.1msat")
Millisatoshi("0.000000000001btc")
with pytest.raises(ValueError, match='Millisatoshi must be a whole number'):
Millisatoshi(".000000000001btc")


def test_nonegative():
with pytest.raises(ValueError, match='Millisatoshi must be >= 0'):
Millisatoshi("-1btc")
with pytest.raises(ValueError, match='Millisatoshi must be >= 0'):
Millisatoshi("-1.0btc")
with pytest.raises(ValueError, match='Millisatoshi must be >= 0'):
Millisatoshi("-0.1btc")
with pytest.raises(ValueError, match='Millisatoshi must be >= 0'):
Millisatoshi("-.1btc")
with pytest.raises(ValueError, match='Millisatoshi must be >= 0'):
Millisatoshi("-1sat")
with pytest.raises(ValueError, match='Millisatoshi must be >= 0'):
Millisatoshi("-1.0sat")
with pytest.raises(ValueError, match='Millisatoshi must be >= 0'):
Millisatoshi("-0.1sat")
with pytest.raises(ValueError, match='Millisatoshi must be >= 0'):
Millisatoshi("-.1sat")
with pytest.raises(ValueError, match='Millisatoshi must be >= 0'):
Millisatoshi("-1msat")
with pytest.raises(ValueError, match='Millisatoshi must be >= 0'):
Millisatoshi("-1.0msat")

with pytest.raises(ValueError, match='Millisatoshi must be >= 0'):
Millisatoshi("1msat") * -1
with pytest.raises(ValueError, match='Millisatoshi must be >= 0'):
Millisatoshi("1msat") * -42
with pytest.raises(ValueError, match='Millisatoshi must be >= 0'):
Millisatoshi("1sat") * -1
with pytest.raises(ValueError, match='Millisatoshi must be >= 0'):
Millisatoshi("1btc") * -1

with pytest.raises(ValueError, match='Millisatoshi must be >= 0'):
Millisatoshi("1msat") / -1
with pytest.raises(ValueError, match='Millisatoshi must be >= 0'):
Millisatoshi("1msat") / -0.5
with pytest.raises(ValueError, match='Millisatoshi must be >= 0'):
Millisatoshi("1sat") / -1
with pytest.raises(ValueError, match='Millisatoshi must be >= 0'):
Millisatoshi("1btc") / -1

with pytest.raises(ValueError, match='Millisatoshi must be >= 0'):
Millisatoshi("1msat") // -1
with pytest.raises(ValueError, match='Millisatoshi must be >= 0'):
Millisatoshi("1sat") // -1
with pytest.raises(ValueError, match='Millisatoshi must be >= 0'):
Millisatoshi("1btc") // -1