mirror of
https://github.com/bitcoin/bitcoin.git
synced 2025-04-08 12:19:07 +02:00
Merge bitcoin/bitcoin#24454: tests: Fix calculation of external input weights
9f5ab670e7c8165f161ec44dbd95778c5515ece0 tests: Use descriptor that requires both legacy and segwit (Andrew Chow) 8a04a386f75d099f4b9864b0cdf7f26442b5801f tests: Calculate input weight more accurately (Andrew Chow) Pull request description: The external input tests with specifying input weight would sometimes result in a test failure because it would add 2 to the calculated byte size in order to account for some of the variation in signature and script sizes. However 1 in 128 signatures are actually 1 byte smaller than we expect, so the difference between the actual signature size and our calculated size becomes 3 bytes which is outside of the tolerance of `assert_fee_amount` and would thus cause the test failure. To resolve this, the 2 byte buffer is reduced to 1 byte, so in the above scenario, the difference is 2 bytes which is within the tolerance of `assert_fee_amount`. Additionally, instead of putting a fixed size that we assume is the correct size for the length of the compact size length prefix of data, we actually get the length of the compact size uint. Lastly, the size calculation for a scriptWitness was simply incorrect and used fields that did not exist. This is fixed, and the test slightly modified so that it also produces a scriptWitness. Fixes #24151 ACKs for top commit: jonatack: re-ACK 9f5ab670e7c8165f161ec44dbd95778c5515ece0 glozow: code review ACK 9f5ab670e7c8165f161ec44dbd95778c5515ece0 Tree-SHA512: b7c7ffe8fb0c07bc9e72fbff1f9ef57ee01a57c56bf54b8873345c8b9572c3ce9402b24dc211910b478114a9e6420faef5a4bf8866f38c299971354e54ec4745
This commit is contained in:
commit
aa54132bac
@ -10,6 +10,10 @@ from itertools import product
|
||||
|
||||
from test_framework.descriptors import descsum_create
|
||||
from test_framework.key import ECKey
|
||||
from test_framework.messages import (
|
||||
ser_compact_size,
|
||||
WITNESS_SCALE_FACTOR,
|
||||
)
|
||||
from test_framework.test_framework import BitcoinTestFramework
|
||||
from test_framework.util import (
|
||||
assert_approx,
|
||||
@ -615,8 +619,8 @@ class PSBTTest(BitcoinTestFramework):
|
||||
self.nodes[1].createwallet("extfund")
|
||||
wallet = self.nodes[1].get_wallet_rpc("extfund")
|
||||
|
||||
# Make a weird but signable script. sh(pkh()) descriptor accomplishes this
|
||||
desc = descsum_create("sh(pkh({}))".format(privkey))
|
||||
# Make a weird but signable script. sh(wsh(pkh())) descriptor accomplishes this
|
||||
desc = descsum_create("sh(wsh(pkh({})))".format(privkey))
|
||||
if self.options.descriptors:
|
||||
res = self.nodes[0].importdescriptors([{"desc": desc, "timestamp": "now"}])
|
||||
else:
|
||||
@ -634,7 +638,7 @@ class PSBTTest(BitcoinTestFramework):
|
||||
assert_raises_rpc_error(-4, "Insufficient funds", wallet.walletcreatefundedpsbt, [ext_utxo], {self.nodes[0].getnewaddress(): 15})
|
||||
|
||||
# But funding should work when the solving data is provided
|
||||
psbt = wallet.walletcreatefundedpsbt([ext_utxo], {self.nodes[0].getnewaddress(): 15}, 0, {"add_inputs": True, "solving_data": {"pubkeys": [addr_info['pubkey']], "scripts": [addr_info["embedded"]["scriptPubKey"]]}})
|
||||
psbt = wallet.walletcreatefundedpsbt([ext_utxo], {self.nodes[0].getnewaddress(): 15}, 0, {"add_inputs": True, "solving_data": {"pubkeys": [addr_info['pubkey']], "scripts": [addr_info["embedded"]["scriptPubKey"], addr_info["embedded"]["embedded"]["scriptPubKey"]]}})
|
||||
signed = wallet.walletprocesspsbt(psbt['psbt'])
|
||||
assert not signed['complete']
|
||||
signed = self.nodes[0].walletprocesspsbt(signed['psbt'])
|
||||
@ -655,10 +659,11 @@ class PSBTTest(BitcoinTestFramework):
|
||||
break
|
||||
psbt_in = dec["inputs"][input_idx]
|
||||
# Calculate the input weight
|
||||
# (prevout + sequence + length of scriptSig + 2 bytes buffer) * 4 + len of scriptwitness
|
||||
# (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
|
||||
len_scriptsig = len(psbt_in["final_scriptSig"]["hex"]) // 2 if "final_scriptSig" in psbt_in else 0
|
||||
len_scriptwitness = len(psbt_in["final_scriptwitness"]["hex"]) // 2 if "final_scriptwitness" in psbt_in else 0
|
||||
input_weight = ((41 + len_scriptsig + 2) * 4) + len_scriptwitness
|
||||
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
|
||||
low_input_weight = input_weight // 2
|
||||
high_input_weight = input_weight * 2
|
||||
|
||||
|
@ -10,6 +10,10 @@ from itertools import product
|
||||
from test_framework.authproxy import JSONRPCException
|
||||
from test_framework.descriptors import descsum_create
|
||||
from test_framework.key import ECKey
|
||||
from test_framework.messages import (
|
||||
ser_compact_size,
|
||||
WITNESS_SCALE_FACTOR,
|
||||
)
|
||||
from test_framework.test_framework import BitcoinTestFramework
|
||||
from test_framework.util import (
|
||||
assert_equal,
|
||||
@ -488,8 +492,8 @@ class WalletSendTest(BitcoinTestFramework):
|
||||
self.nodes[1].createwallet("extfund")
|
||||
ext_fund = self.nodes[1].get_wallet_rpc("extfund")
|
||||
|
||||
# Make a weird but signable script. sh(pkh()) descriptor accomplishes this
|
||||
desc = descsum_create("sh(pkh({}))".format(privkey))
|
||||
# Make a weird but signable script. sh(wsh(pkh())) descriptor accomplishes this
|
||||
desc = descsum_create("sh(wsh(pkh({})))".format(privkey))
|
||||
if self.options.descriptors:
|
||||
res = ext_fund.importdescriptors([{"desc": desc, "timestamp": "now"}])
|
||||
else:
|
||||
@ -507,7 +511,7 @@ class WalletSendTest(BitcoinTestFramework):
|
||||
self.test_send(from_wallet=ext_wallet, to_wallet=self.nodes[0], amount=15, inputs=[ext_utxo], add_inputs=True, psbt=True, include_watching=True, expect_error=(-4, "Insufficient funds"))
|
||||
|
||||
# But funding should work when the solving data is provided
|
||||
res = self.test_send(from_wallet=ext_wallet, to_wallet=self.nodes[0], amount=15, inputs=[ext_utxo], add_inputs=True, psbt=True, include_watching=True, solving_data={"pubkeys": [addr_info['pubkey']], "scripts": [addr_info["embedded"]["scriptPubKey"]]})
|
||||
res = self.test_send(from_wallet=ext_wallet, to_wallet=self.nodes[0], amount=15, inputs=[ext_utxo], add_inputs=True, psbt=True, include_watching=True, solving_data={"pubkeys": [addr_info['pubkey']], "scripts": [addr_info["embedded"]["scriptPubKey"], addr_info["embedded"]["embedded"]["scriptPubKey"]]})
|
||||
signed = ext_wallet.walletprocesspsbt(res["psbt"])
|
||||
signed = ext_fund.walletprocesspsbt(res["psbt"])
|
||||
assert signed["complete"]
|
||||
@ -526,10 +530,11 @@ class WalletSendTest(BitcoinTestFramework):
|
||||
break
|
||||
psbt_in = dec["inputs"][input_idx]
|
||||
# Calculate the input weight
|
||||
# (prevout + sequence + length of scriptSig + 2 bytes buffer) * 4 + len of scriptwitness
|
||||
# (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
|
||||
len_scriptsig = len(psbt_in["final_scriptSig"]["hex"]) // 2 if "final_scriptSig" in psbt_in else 0
|
||||
len_scriptwitness = len(psbt_in["final_scriptwitness"]["hex"]) // 2 if "final_scriptwitness" in psbt_in else 0
|
||||
input_weight = ((41 + len_scriptsig + 2) * 4) + len_scriptwitness
|
||||
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
|
||||
|
||||
# Input weight error conditions
|
||||
assert_raises_rpc_error(
|
||||
|
Loading…
x
Reference in New Issue
Block a user