mirror of
https://github.com/bitcoin/bitcoin.git
synced 2025-02-08 10:31:50 -05:00
Merge bitcoin/bitcoin#29502: test: modify weight estimate in functional tests
e67ab174c9
test: fix flaky wallet_send functional test (Max Edwards)3c49e69670
test: fix weight estimates in functional tests (Max Edwards) Pull request description: Fixes: https://github.com/bitcoin/bitcoin/issues/25164 The wallet_send functional test has been flaky due to a slightly overestimated weight calculation. This PR makes the weight calculation more accurate, although occasionally, due to how ECDSA signatures can be different lengths it might slightly over estimate. The assertion in the test can handle this slight variation and so should continue passing. Update: Because the signature can be shorter that is used in the weight estimation or the final transaction the estimate could be both slightly smaller or slightly larger. ACKs for top commit: achow101: ACKe67ab174c9
S3RK: Code review ACKe67ab174c9
Tree-SHA512: 3bf73b355309dce860fa1520afb8461e94268e4bcf0e92a8273c279b41b058c44472cf59daafa15a515529b50bd665b5d498bbe4d934f2315dbe810a05bc73f9
This commit is contained in:
commit
2b260eadf7
2 changed files with 24 additions and 10 deletions
|
@ -753,11 +753,16 @@ class PSBTTest(BitcoinTestFramework):
|
|||
break
|
||||
psbt_in = dec["inputs"][input_idx]
|
||||
# Calculate the input weight
|
||||
# (prevout + sequence + length of scriptSig + scriptsig + 1 byte buffer) * WITNESS_SCALE_FACTOR + num scriptWitness stack items + (length of stack item + stack item) * N stack items + 1 byte buffer
|
||||
# (prevout + sequence + length of scriptSig + scriptsig) * WITNESS_SCALE_FACTOR + len of num scriptWitness stack items + (length of stack item + stack item) * N stack items
|
||||
# Note that occasionally this weight estimate may be slightly larger or smaller than the real weight
|
||||
# as sometimes ECDSA signatures are one byte shorter than expected with a probability of 1/128
|
||||
len_scriptsig = len(psbt_in["final_scriptSig"]["hex"]) // 2 if "final_scriptSig" in psbt_in else 0
|
||||
len_scriptsig += len(ser_compact_size(len_scriptsig)) + 1
|
||||
len_scriptwitness = (sum([(len(x) // 2) + len(ser_compact_size(len(x) // 2)) for x in psbt_in["final_scriptwitness"]]) + len(psbt_in["final_scriptwitness"]) + 1) if "final_scriptwitness" in psbt_in else 0
|
||||
input_weight = ((40 + len_scriptsig) * WITNESS_SCALE_FACTOR) + len_scriptwitness
|
||||
len_scriptsig += len(ser_compact_size(len_scriptsig))
|
||||
len_scriptwitness = (sum([(len(x) // 2) + len(ser_compact_size(len(x) // 2)) for x in psbt_in["final_scriptwitness"]]) + len(ser_compact_size(len(psbt_in["final_scriptwitness"])))) if "final_scriptwitness" in psbt_in else 0
|
||||
len_prevout_txid = 32
|
||||
len_prevout_index = 4
|
||||
len_sequence = 4
|
||||
input_weight = ((len_prevout_txid + len_prevout_index + len_sequence + len_scriptsig) * WITNESS_SCALE_FACTOR) + len_scriptwitness
|
||||
low_input_weight = input_weight // 2
|
||||
high_input_weight = input_weight * 2
|
||||
|
||||
|
|
|
@ -543,11 +543,16 @@ class WalletSendTest(BitcoinTestFramework):
|
|||
break
|
||||
psbt_in = dec["inputs"][input_idx]
|
||||
# Calculate the input weight
|
||||
# (prevout + sequence + length of scriptSig + scriptsig + 1 byte buffer) * WITNESS_SCALE_FACTOR + num scriptWitness stack items + (length of stack item + stack item) * N stack items + 1 byte buffer
|
||||
# (prevout + sequence + length of scriptSig + scriptsig) * WITNESS_SCALE_FACTOR + len of num scriptWitness stack items + (length of stack item + stack item) * N stack items
|
||||
# Note that occasionally this weight estimate may be slightly larger or smaller than the real weight
|
||||
# as sometimes ECDSA signatures are one byte shorter than expected with a probability of 1/128
|
||||
len_scriptsig = len(psbt_in["final_scriptSig"]["hex"]) // 2 if "final_scriptSig" in psbt_in else 0
|
||||
len_scriptsig += len(ser_compact_size(len_scriptsig)) + 1
|
||||
len_scriptwitness = (sum([(len(x) // 2) + len(ser_compact_size(len(x) // 2)) for x in psbt_in["final_scriptwitness"]]) + len(psbt_in["final_scriptwitness"]) + 1) if "final_scriptwitness" in psbt_in else 0
|
||||
input_weight = ((40 + len_scriptsig) * WITNESS_SCALE_FACTOR) + len_scriptwitness
|
||||
len_scriptsig += len(ser_compact_size(len_scriptsig))
|
||||
len_scriptwitness = (sum([(len(x) // 2) + len(ser_compact_size(len(x) // 2)) for x in psbt_in["final_scriptwitness"]]) + len(ser_compact_size(len(psbt_in["final_scriptwitness"])))) if "final_scriptwitness" in psbt_in else 0
|
||||
len_prevout_txid = 32
|
||||
len_prevout_index = 4
|
||||
len_sequence = 4
|
||||
input_weight = ((len_prevout_txid + len_prevout_index + len_sequence + len_scriptsig) * WITNESS_SCALE_FACTOR) + len_scriptwitness
|
||||
|
||||
# Input weight error conditions
|
||||
assert_raises_rpc_error(
|
||||
|
@ -558,6 +563,7 @@ class WalletSendTest(BitcoinTestFramework):
|
|||
options={"inputs": [ext_utxo], "input_weights": [{"txid": ext_utxo["txid"], "vout": ext_utxo["vout"], "weight": 1000}]}
|
||||
)
|
||||
|
||||
target_fee_rate_sat_vb = 10
|
||||
# Funding should also work when input weights are provided
|
||||
res = self.test_send(
|
||||
from_wallet=ext_wallet,
|
||||
|
@ -567,14 +573,17 @@ class WalletSendTest(BitcoinTestFramework):
|
|||
add_inputs=True,
|
||||
psbt=True,
|
||||
include_watching=True,
|
||||
fee_rate=10
|
||||
fee_rate=target_fee_rate_sat_vb
|
||||
)
|
||||
signed = ext_wallet.walletprocesspsbt(res["psbt"])
|
||||
signed = ext_fund.walletprocesspsbt(res["psbt"])
|
||||
assert signed["complete"]
|
||||
testres = self.nodes[0].testmempoolaccept([signed["hex"]])[0]
|
||||
assert_equal(testres["allowed"], True)
|
||||
assert_fee_amount(testres["fees"]["base"], testres["vsize"], Decimal(0.0001))
|
||||
actual_fee_rate_sat_vb = Decimal(testres["fees"]["base"]) * Decimal(1e8) / Decimal(testres["vsize"])
|
||||
# Due to ECDSA signatures not always being the same length, the actual fee rate may be slightly different
|
||||
# but rounded to nearest integer, it should be the same as the target fee rate
|
||||
assert_equal(round(actual_fee_rate_sat_vb), target_fee_rate_sat_vb)
|
||||
|
||||
if __name__ == '__main__':
|
||||
WalletSendTest().main()
|
||||
|
|
Loading…
Add table
Reference in a new issue