wallet: fix type error in _bump_fee_through_decreasing_outputs

fixes #5483
This commit is contained in:
SomberNight 2019-07-04 17:23:34 +02:00
parent 194bf84418
commit 94b721baa4
No known key found for this signature in database
GPG key ID: B33B5F232C6271E9
4 changed files with 16 additions and 13 deletions

View file

@ -151,7 +151,7 @@ class CoinChooserBase(Logger):
def penalty_func(self, base_tx, *, tx_from_buckets) -> Callable[[List[Bucket]], ScoredCandidate]: def penalty_func(self, base_tx, *, tx_from_buckets) -> Callable[[List[Bucket]], ScoredCandidate]:
raise NotImplementedError raise NotImplementedError
def _change_amounts(self, tx, count, fee_estimator_numchange): def _change_amounts(self, tx, count, fee_estimator_numchange) -> List[int]:
# Break change up if bigger than max_change # Break change up if bigger than max_change
output_amounts = [o.value for o in tx.outputs()] output_amounts = [o.value for o in tx.outputs()]
# Don't split change of less than 0.02 BTC # Don't split change of less than 0.02 BTC
@ -197,7 +197,7 @@ class CoinChooserBase(Logger):
# no more than 10**max_dp_to_round_for_privacy # no more than 10**max_dp_to_round_for_privacy
# e.g. a max of 2 decimal places means losing 100 satoshis to fees # e.g. a max of 2 decimal places means losing 100 satoshis to fees
max_dp_to_round_for_privacy = 2 if self.enable_output_value_rounding else 0 max_dp_to_round_for_privacy = 2 if self.enable_output_value_rounding else 0
N = pow(10, min(max_dp_to_round_for_privacy, zeroes[0])) N = int(pow(10, min(max_dp_to_round_for_privacy, zeroes[0])))
amount = (remaining // N) * N amount = (remaining // N) * N
amounts.append(amount) amounts.append(amount)
@ -209,6 +209,7 @@ class CoinChooserBase(Logger):
amounts = self._change_amounts(tx, len(change_addrs), fee_estimator_numchange) amounts = self._change_amounts(tx, len(change_addrs), fee_estimator_numchange)
assert min(amounts) >= 0 assert min(amounts) >= 0
assert len(change_addrs) >= len(amounts) assert len(change_addrs) >= len(amounts)
assert all([isinstance(amt, int) for amt in amounts])
# If change is above dust threshold after accounting for the # If change is above dust threshold after accounting for the
# size of the change output, add it to the transaction. # size of the change output, add it to the transaction.
amounts = [amount for amount in amounts if amount >= dust_threshold] amounts = [amount for amount in amounts if amount >= dust_threshold]

View file

@ -896,7 +896,7 @@ class TestWalletSending(TestCaseForTestnet):
self.assertEqual((0, funding_output_value - 2500000 - 5000, 0), wallet.get_balance()) self.assertEqual((0, funding_output_value - 2500000 - 5000, 0), wallet.get_balance())
# bump tx # bump tx
tx = wallet.bump_fee(tx=Transaction(tx.serialize()), new_fee_rate=70, config=self.config) tx = wallet.bump_fee(tx=Transaction(tx.serialize()), new_fee_rate=70.0, config=self.config)
tx.locktime = 1325501 tx.locktime = 1325501
tx.version = 1 tx.version = 1
self.assertFalse(tx.is_complete()) self.assertFalse(tx.is_complete())
@ -985,7 +985,7 @@ class TestWalletSending(TestCaseForTestnet):
self.assertEqual((0, funding_output_value - 2500000 - 5000, 0), wallet.get_balance()) self.assertEqual((0, funding_output_value - 2500000 - 5000, 0), wallet.get_balance())
# bump tx # bump tx
tx = wallet.bump_fee(tx=Transaction(tx.serialize()), new_fee_rate=70, config=self.config) tx = wallet.bump_fee(tx=Transaction(tx.serialize()), new_fee_rate=70.0, config=self.config)
tx.locktime = 1325500 tx.locktime = 1325500
tx.version = 1 tx.version = 1
self.assertFalse(tx.is_complete()) self.assertFalse(tx.is_complete())
@ -1039,7 +1039,7 @@ class TestWalletSending(TestCaseForTestnet):
self.assertEqual((0, 0, 0), wallet.get_balance()) self.assertEqual((0, 0, 0), wallet.get_balance())
# bump tx # bump tx
tx = wallet.bump_fee(tx=Transaction(tx.serialize()), new_fee_rate=70, config=self.config) tx = wallet.bump_fee(tx=Transaction(tx.serialize()), new_fee_rate=70.0, config=self.config)
tx.locktime = 1325500 tx.locktime = 1325500
tx.version = 1 tx.version = 1
self.assertFalse(tx.is_complete()) self.assertFalse(tx.is_complete())
@ -1102,7 +1102,7 @@ class TestWalletSending(TestCaseForTestnet):
self.assertEqual((0, 5_000_000, 0), wallet.get_balance()) self.assertEqual((0, 5_000_000, 0), wallet.get_balance())
# bump tx # bump tx
tx = wallet.bump_fee(tx=Transaction(tx.serialize()), new_fee_rate=70, config=self.config) tx = wallet.bump_fee(tx=Transaction(tx.serialize()), new_fee_rate=70.0, config=self.config)
tx.locktime = 1325500 tx.locktime = 1325500
tx.version = 1 tx.version = 1
self.assertFalse(tx.is_complete()) self.assertFalse(tx.is_complete())

View file

@ -1039,13 +1039,13 @@ class Transaction:
self.raw = None self.raw = None
self.BIP69_sort(inputs=False) self.BIP69_sort(inputs=False)
def input_value(self): def input_value(self) -> int:
return sum(x['value'] for x in self.inputs()) return sum(x['value'] for x in self.inputs())
def output_value(self): def output_value(self) -> int:
return sum(o.value for o in self.outputs()) return sum(o.value for o in self.outputs())
def get_fee(self): def get_fee(self) -> int:
return self.input_value() - self.output_value() return self.input_value() - self.output_value()
def is_final(self): def is_final(self):

View file

@ -993,18 +993,20 @@ class Abstract_Wallet(AddressSynchronizer):
# prioritize low value outputs, to get rid of dust # prioritize low value outputs, to get rid of dust
s = sorted(s, key=lambda o: o.value) s = sorted(s, key=lambda o: o.value)
for o in s: for o in s:
target_fee = tx.estimated_size() * new_fee_rate target_fee = int(round(tx.estimated_size() * new_fee_rate))
delta = target_fee - tx.get_fee() delta = target_fee - tx.get_fee()
i = outputs.index(o) i = outputs.index(o)
if o.value - delta >= self.dust_threshold(): if o.value - delta >= self.dust_threshold():
outputs[i] = o._replace(value=o.value - delta) new_output_value = o.value - delta
assert isinstance(new_output_value, int)
outputs[i] = o._replace(value=new_output_value)
delta = 0 delta = 0
break break
else: else:
del outputs[i] del outputs[i]
delta -= o.value delta -= o.value
if delta > 0: # note: delta might be negative now, in which case
continue # the value of the next output will be increased
if delta > 0: if delta > 0:
raise CannotBumpFee(_('Cannot bump fee') + ': ' + _('could not find suitable outputs')) raise CannotBumpFee(_('Cannot bump fee') + ': ' + _('could not find suitable outputs'))