swaps: make SwapManager.percentage Decimal
If SwapManager.percentage was a 0.2 float, rounding differences would
cause an exception in the fee calculation inverse sanity check when entering 20
000 sats into the SwapDialog. By making self.percentage a decimal we can
prevent this kind of issue.
```
File "/home/user/code/vibecoding_vm/electrum/electrum/gui/qt/swap_dialog.py", line 294, in on_send_edited
recv_amount = self.swap_manager.get_recv_amount(send_amount, is_reverse=self.is_reverse)
File "/home/user/code/vibecoding_vm/electrum/electrum/submarine_swaps.py", line 1320, in get_recv_amount
if abs(send_amount - inverted_send_amount) > 1:
~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~
TypeError: unsupported operand type(s) for -: 'int' and 'NoneType'
```
This commit is contained in:
@@ -2016,7 +2016,7 @@ class Commands(Logger):
|
||||
result = {}
|
||||
for offer in offers:
|
||||
result[offer.server_npub] = {
|
||||
"percentage_fee": offer.pairs.percentage,
|
||||
"percentage_fee": float(offer.pairs.percentage),
|
||||
"max_forward_sat": offer.pairs.max_forward,
|
||||
"max_reverse_sat": offer.pairs.max_reverse,
|
||||
"min_amount_sat": offer.pairs.min_amount,
|
||||
|
||||
@@ -75,7 +75,7 @@ class QESwapServerNPubListModel(QAbstractListModel):
|
||||
return {
|
||||
'npub': x.server_npub,
|
||||
'server_pubkey': x.server_pubkey,
|
||||
'percentage_fee': x.pairs.percentage,
|
||||
'percentage_fee': float(x.pairs.percentage),
|
||||
'mining_fee': x.pairs.mining_fee,
|
||||
'min_amount': x.pairs.min_amount,
|
||||
'max_forward_amount': x.pairs.max_forward,
|
||||
|
||||
@@ -95,7 +95,7 @@ class HttpSwapServer(Logger, EventListener):
|
||||
"minimal": sm._min_amount,
|
||||
},
|
||||
"fees": {
|
||||
"percentage": sm.percentage,
|
||||
"percentage": float(sm.percentage), # cast to float for <= 4.7.1 backwards compatibility
|
||||
"minerFees": {
|
||||
"baseAsset": {
|
||||
"normal": sm.mining_fee,
|
||||
|
||||
@@ -168,7 +168,7 @@ def now():
|
||||
|
||||
@attr.s(frozen=True)
|
||||
class SwapFees:
|
||||
percentage = attr.ib(type=int)
|
||||
percentage = attr.ib(type=Decimal)
|
||||
mining_fee = attr.ib(type=int)
|
||||
min_amount = attr.ib(type=int)
|
||||
max_forward = attr.ib(type=int)
|
||||
@@ -235,7 +235,7 @@ class SwapManager(Logger):
|
||||
def __init__(self, *, wallet: 'Abstract_Wallet', lnworker: 'LNWallet'):
|
||||
Logger.__init__(self)
|
||||
self.mining_fee = None
|
||||
self.percentage = None
|
||||
self.percentage = None # type: Optional[Decimal]
|
||||
self._min_amount = None
|
||||
self._max_forward = None
|
||||
self._max_reverse = None
|
||||
@@ -1193,7 +1193,7 @@ class SwapManager(Logger):
|
||||
|
||||
def server_update_pairs(self) -> None:
|
||||
""" for server """
|
||||
self.percentage = float(self.config.SWAPSERVER_FEE_MILLIONTHS) / 10000 # type: ignore
|
||||
self.percentage = Decimal(self.config.SWAPSERVER_FEE_MILLIONTHS) / 10000 # type: ignore
|
||||
self._min_amount = MIN_SWAP_AMOUNT_SAT
|
||||
oc_balance_sat: int = self.wallet.get_spendable_balance_sat()
|
||||
max_forward: int = min(int(self.lnworker.num_sats_can_receive()), oc_balance_sat, 10000000)
|
||||
@@ -1259,7 +1259,7 @@ class SwapManager(Logger):
|
||||
if send_amount is None:
|
||||
return None
|
||||
x = Decimal(send_amount)
|
||||
percentage = Decimal(self.percentage)
|
||||
percentage = self.percentage
|
||||
if is_reverse:
|
||||
if not self.check_invoice_amount(x, is_reverse):
|
||||
return None
|
||||
@@ -1289,7 +1289,7 @@ class SwapManager(Logger):
|
||||
if not recv_amount:
|
||||
return None
|
||||
x = Decimal(recv_amount)
|
||||
percentage = Decimal(self.percentage)
|
||||
percentage = self.percentage
|
||||
if is_reverse:
|
||||
# see/ref:
|
||||
# https://github.com/BoltzExchange/boltz-backend/blob/e7e2d30f42a5bea3665b164feb85f84c64d86658/lib/service/Service.ts#L928
|
||||
@@ -1638,7 +1638,7 @@ class HttpTransport(SwapServerTransport):
|
||||
fees = response['pairs']['BTC/BTC']['fees']
|
||||
limits = response['pairs']['BTC/BTC']['limits']
|
||||
pairs = SwapFees(
|
||||
percentage=fees['percentage'],
|
||||
percentage=Decimal(str(fees['percentage'])),
|
||||
mining_fee=fees['minerFees']['baseAsset']['mining_fee'],
|
||||
min_amount=limits['minimal'],
|
||||
max_forward=limits['max_forward_amount'],
|
||||
@@ -1777,7 +1777,7 @@ class NostrTransport(SwapServerTransport):
|
||||
self.logger.warning(f"not publishing swap offer, no liquidity available: {sm._max_forward=}, {sm._max_reverse=}")
|
||||
return
|
||||
offer = {
|
||||
'percentage_fee': sm.percentage,
|
||||
'percentage_fee': float(sm.percentage), # cast to float for <= 4.7.1 backwards compatibility
|
||||
'mining_fee': sm.mining_fee,
|
||||
'min_amount': sm._min_amount,
|
||||
'max_forward_amount': sm._max_forward,
|
||||
@@ -1883,7 +1883,7 @@ class NostrTransport(SwapServerTransport):
|
||||
continue
|
||||
try:
|
||||
pairs = SwapFees(
|
||||
percentage=content['percentage_fee'],
|
||||
percentage=Decimal(str(content['percentage_fee'])),
|
||||
mining_fee=content['mining_fee'],
|
||||
min_amount=content['min_amount'],
|
||||
max_forward=content['max_forward_amount'],
|
||||
|
||||
@@ -678,7 +678,7 @@ class TestCommandsTestnet(ElectrumTestCase):
|
||||
|
||||
offer1 = SwapOffer(
|
||||
pairs=SwapFees(
|
||||
percentage=0.5,
|
||||
percentage=Decimal('0.5'),
|
||||
mining_fee=2000,
|
||||
min_amount=10000,
|
||||
max_forward=1000000,
|
||||
@@ -692,7 +692,7 @@ class TestCommandsTestnet(ElectrumTestCase):
|
||||
|
||||
offer2 = SwapOffer(
|
||||
pairs=SwapFees(
|
||||
percentage=1.0,
|
||||
percentage=Decimal('1.0'),
|
||||
mining_fee=3000,
|
||||
min_amount=20000,
|
||||
max_forward=2000000,
|
||||
|
||||
Reference in New Issue
Block a user