Skip to content

Commit d1fab9d

Browse files
committed
test: Call ceildiv helper with integer
It returns an incorrect result when called with a Decimal, for which the "//" operator works differently. Also drop unnecessary call to satoshi_round.
1 parent 219d728 commit d1fab9d

File tree

2 files changed

+14
-6
lines changed

2 files changed

+14
-6
lines changed

test/functional/test_framework/util.py

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ def assert_approx(v, vexp, vspan=0.00001):
3636

3737
def assert_fee_amount(fee, tx_size, feerate_BTC_kvB):
3838
"""Assert the fee is in range."""
39+
assert isinstance(tx_size, int)
3940
target_fee = get_fee(tx_size, feerate_BTC_kvB)
4041
if fee < target_fee:
4142
raise AssertionError("Fee of %s BTC too low! (Should be %s BTC)" % (str(fee), str(target_fee)))
@@ -219,15 +220,21 @@ def str_to_b64str(string):
219220

220221

221222
def ceildiv(a, b):
222-
"""Divide 2 ints and round up to next int rather than round down"""
223+
"""
224+
Divide 2 ints and round up to next int rather than round down
225+
Implementation requires python integers, which have a // operator that does floor division.
226+
Other types like decimal.Decimal whose // operator truncates towards 0 will not work.
227+
"""
228+
assert isinstance(a, int)
229+
assert isinstance(b, int)
223230
return -(-a // b)
224231

225232

226233
def get_fee(tx_size, feerate_btc_kvb):
227234
"""Calculate the fee in BTC given a feerate is BTC/kvB. Reflects CFeeRate::GetFee"""
228235
feerate_sat_kvb = int(feerate_btc_kvb * Decimal(1e8)) # Fee in sat/kvb as an int to avoid float precision errors
229236
target_fee_sat = ceildiv(feerate_sat_kvb * tx_size, 1000) # Round calculated fee up to nearest sat
230-
return satoshi_round(target_fee_sat / Decimal(1e8)) # Truncate BTC result to nearest sat
237+
return target_fee_sat / Decimal(1e8) # Return result in BTC
231238

232239

233240
def satoshi_round(amount):

test/functional/wallet_send.py

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
assert_fee_amount,
1717
assert_greater_than,
1818
assert_raises_rpc_error,
19+
count_bytes,
1920
)
2021
from test_framework.wallet_util import bytes_to_wif
2122

@@ -320,20 +321,20 @@ def run_test(self):
320321

321322
res = self.test_send(from_wallet=w0, to_wallet=w1, amount=1, fee_rate=7, add_to_wallet=False)
322323
fee = self.nodes[1].decodepsbt(res["psbt"])["fee"]
323-
assert_fee_amount(fee, Decimal(len(res["hex"]) / 2), Decimal("0.00007"))
324+
assert_fee_amount(fee, count_bytes(res["hex"]), Decimal("0.00007"))
324325

325326
# "unset" and None are treated the same for estimate_mode
326327
res = self.test_send(from_wallet=w0, to_wallet=w1, amount=1, fee_rate=2, estimate_mode="unset", add_to_wallet=False)
327328
fee = self.nodes[1].decodepsbt(res["psbt"])["fee"]
328-
assert_fee_amount(fee, Decimal(len(res["hex"]) / 2), Decimal("0.00002"))
329+
assert_fee_amount(fee, count_bytes(res["hex"]), Decimal("0.00002"))
329330

330331
res = self.test_send(from_wallet=w0, to_wallet=w1, amount=1, arg_fee_rate=4.531, add_to_wallet=False)
331332
fee = self.nodes[1].decodepsbt(res["psbt"])["fee"]
332-
assert_fee_amount(fee, Decimal(len(res["hex"]) / 2), Decimal("0.00004531"))
333+
assert_fee_amount(fee, count_bytes(res["hex"]), Decimal("0.00004531"))
333334

334335
res = self.test_send(from_wallet=w0, to_wallet=w1, amount=1, arg_fee_rate=3, add_to_wallet=False)
335336
fee = self.nodes[1].decodepsbt(res["psbt"])["fee"]
336-
assert_fee_amount(fee, Decimal(len(res["hex"]) / 2), Decimal("0.00003"))
337+
assert_fee_amount(fee, count_bytes(res["hex"]), Decimal("0.00003"))
337338

338339
# Test that passing fee_rate as both an argument and an option raises.
339340
self.test_send(from_wallet=w0, to_wallet=w1, amount=1, arg_fee_rate=1, fee_rate=1, add_to_wallet=False,

0 commit comments

Comments
 (0)