aboutsummaryrefslogtreecommitdiff
path: root/test
diff options
context:
space:
mode:
authorlaanwj <126646+laanwj@users.noreply.github.com>2022-06-17 22:44:32 +0200
committerlaanwj <126646+laanwj@users.noreply.github.com>2022-06-17 22:51:42 +0200
commitf8586b25f6a4f1e30a54e58f45dd28aaf580bbc6 (patch)
tree55d9f3abf82e28db99f74be45f7e5c56193091ab /test
parente5df0ba0d97e5f8cfd748f09d6ed77b7bfc45471 (diff)
parentdcf36fe8e3e1fc1e865072232281b72889586e40 (diff)
downloadbitcoin-f8586b25f6a4f1e30a54e58f45dd28aaf580bbc6.tar.xz
Merge bitcoin/bitcoin#25289: test: implement 'bech32m' mode for `getnewdestination()` helper
dcf36fe8e3e1fc1e865072232281b72889586e40 test: implement 'bech32m' mode for `getnewdestination()` helper (Sebastian Falbesoner) 1999dcfa40ddedb6cf15f9d66b90fa0f537b4842 test: add helpers for creating P2TR scripts/addresses from output key (Sebastian Falbesoner) Pull request description: This PR adds the missing 'bech32m' mode for the `getnewdestination()` helper and sets it as default, i.e. the function returns a tuple (output x-only-pubkey, scriptPubKey, taproot address) now if not specified otherwise. In a preparation commit, the helpers `output_key_to_p2tr{_script}` are introduced. Note that in contrast to all other common script output types, there are usually _two_ keys involved in creating a taproot output (internal key and output key), hence the prefix `output_` is used to clarify that the output key is expected and the helpers don't do any key tweaking. Thanks to michaelfolkson (for pointing out this TODO that I forgot about) and sipa (for patiently explaining basic things about BIP341). ACKs for top commit: michaelfolkson: ACK dcf36fe8e3e1fc1e865072232281b72889586e40 w0xlt: reACK https://github.com/bitcoin/bitcoin/pull/25289/commits/dcf36fe8e3e1fc1e865072232281b72889586e40 Tree-SHA512: 5bb8d5fd96c63092ede10c3f022ffb2e13c14e333c4aa73348d95deb70cbf0a74745218dc4a7c419eb846793dd69e8217a7b4332a13ae2b2758e100b51fb1a9f
Diffstat (limited to 'test')
-rwxr-xr-xtest/functional/rpc_createmultisig.py6
-rw-r--r--test/functional/test_framework/address.py7
-rwxr-xr-xtest/functional/test_framework/script_util.py5
-rw-r--r--test/functional/test_framework/wallet.py17
-rwxr-xr-xtest/functional/wallet_taproot.py8
5 files changed, 27 insertions, 16 deletions
diff --git a/test/functional/rpc_createmultisig.py b/test/functional/rpc_createmultisig.py
index 716ee8f7ef..1ad3fc24c9 100755
--- a/test/functional/rpc_createmultisig.py
+++ b/test/functional/rpc_createmultisig.py
@@ -43,7 +43,7 @@ class RpcCreateMultiSigTest(BitcoinTestFramework):
if self.is_bdb_compiled():
self.final = node2.getnewaddress()
else:
- self.final = getnewdestination()[2]
+ self.final = getnewdestination('bech32')[2]
def run_test(self):
node0, node1, node2 = self.nodes
@@ -66,9 +66,7 @@ class RpcCreateMultiSigTest(BitcoinTestFramework):
# Test mixed compressed and uncompressed pubkeys
self.log.info('Mixed compressed and uncompressed multisigs are not allowed')
- pk0 = getnewdestination()[0].hex()
- pk1 = getnewdestination()[0].hex()
- pk2 = getnewdestination()[0].hex()
+ pk0, pk1, pk2 = [getnewdestination('bech32')[0].hex() for _ in range(3)]
# decompress pk2
pk_obj = ECPubKey()
diff --git a/test/functional/test_framework/address.py b/test/functional/test_framework/address.py
index fcea24655b..92244b5ed8 100644
--- a/test/functional/test_framework/address.py
+++ b/test/functional/test_framework/address.py
@@ -47,8 +47,7 @@ def create_deterministic_address_bcrt1_p2tr_op_true():
Returns a tuple with the generated address and the internal key.
"""
internal_key = (1).to_bytes(32, 'big')
- scriptPubKey = taproot_construct(internal_key, [(None, CScript([OP_TRUE]))]).scriptPubKey
- address = encode_segwit_address("bcrt", 1, scriptPubKey[2:])
+ address = output_key_to_p2tr(taproot_construct(internal_key, [(None, CScript([OP_TRUE]))]).output_pubkey)
assert_equal(address, 'bcrt1p9yfmy5h72durp7zrhlw9lf7jpwjgvwdg0jr0lqmmjtgg83266lqsekaqka')
return (address, internal_key)
@@ -141,6 +140,10 @@ def script_to_p2sh_p2wsh(script, main=False):
p2shscript = CScript([OP_0, sha256(script)])
return script_to_p2sh(p2shscript, main)
+def output_key_to_p2tr(key, main=False):
+ assert len(key) == 32
+ return program_to_witness(1, key, main)
+
def check_key(key):
if (type(key) is str):
key = bytes.fromhex(key) # Assuming this is hex string
diff --git a/test/functional/test_framework/script_util.py b/test/functional/test_framework/script_util.py
index f7d8422eee..b114002145 100755
--- a/test/functional/test_framework/script_util.py
+++ b/test/functional/test_framework/script_util.py
@@ -105,6 +105,11 @@ def script_to_p2sh_p2wsh_script(script):
return script_to_p2sh_script(p2shscript)
+def output_key_to_p2tr_script(key):
+ assert len(key) == 32
+ return program_to_witness_script(1, key)
+
+
def check_key(key):
if isinstance(key, str):
key = bytes.fromhex(key) # Assuming this is hex string
diff --git a/test/functional/test_framework/wallet.py b/test/functional/test_framework/wallet.py
index 93f3ea9e81..e192c3b3e9 100644
--- a/test/functional/test_framework/wallet.py
+++ b/test/functional/test_framework/wallet.py
@@ -19,9 +19,13 @@ from test_framework.address import (
key_to_p2pkh,
key_to_p2sh_p2wpkh,
key_to_p2wpkh,
+ output_key_to_p2tr,
)
from test_framework.descriptors import descsum_create
-from test_framework.key import ECKey
+from test_framework.key import (
+ ECKey,
+ compute_xonly_pubkey,
+)
from test_framework.messages import (
COIN,
COutPoint,
@@ -38,6 +42,7 @@ from test_framework.script import (
OP_NOP,
OP_TRUE,
SIGHASH_ALL,
+ taproot_construct,
)
from test_framework.script_util import (
key_to_p2pk_script,
@@ -286,10 +291,10 @@ class MiniWallet:
return txid
-def getnewdestination(address_type='bech32'):
+def getnewdestination(address_type='bech32m'):
"""Generate a random destination of the specified type and return the
corresponding public key, scriptPubKey and address. Supported types are
- 'legacy', 'p2sh-segwit' and 'bech32'. Can be used when a random
+ 'legacy', 'p2sh-segwit', 'bech32' and 'bech32m'. Can be used when a random
destination is needed, but no compiled wallet is available (e.g. as
replacement to the getnewaddress/getaddressinfo RPCs)."""
key = ECKey()
@@ -304,7 +309,11 @@ def getnewdestination(address_type='bech32'):
elif address_type == 'bech32':
scriptpubkey = key_to_p2wpkh_script(pubkey)
address = key_to_p2wpkh(pubkey)
- # TODO: also support bech32m (need to generate x-only-pubkey)
+ elif address_type == 'bech32m':
+ tap = taproot_construct(compute_xonly_pubkey(key.get_bytes())[0])
+ pubkey = tap.output_pubkey
+ scriptpubkey = tap.scriptPubKey
+ address = output_key_to_p2tr(pubkey)
else:
assert False
return pubkey, scriptpubkey, address
diff --git a/test/functional/wallet_taproot.py b/test/functional/wallet_taproot.py
index a4d836c8fe..d238c50bca 100755
--- a/test/functional/wallet_taproot.py
+++ b/test/functional/wallet_taproot.py
@@ -7,19 +7,18 @@
import random
from decimal import Decimal
+from test_framework.address import output_key_to_p2tr
from test_framework.test_framework import BitcoinTestFramework
from test_framework.util import assert_equal
from test_framework.descriptors import descsum_create
from test_framework.script import (
CScript,
MAX_PUBKEYS_PER_MULTI_A,
- OP_1,
OP_CHECKSIG,
OP_CHECKSIGADD,
OP_NUMEQUAL,
taproot_construct,
)
-from test_framework.segwit_addr import encode_segwit_address
# xprvs/xpubs, and m/* derived x-only pubkeys (created using independent implementation)
KEYS = [
@@ -183,10 +182,7 @@ def multi_a(k, hex_keys, sort=False):
def compute_taproot_address(pubkey, scripts):
"""Compute the address for a taproot output with given inner key and scripts."""
- tap = taproot_construct(pubkey, scripts)
- assert tap.scriptPubKey[0] == OP_1
- assert tap.scriptPubKey[1] == 0x20
- return encode_segwit_address("bcrt", 1, tap.scriptPubKey[2:])
+ return output_key_to_p2tr(taproot_construct(pubkey, scripts).output_pubkey)
class WalletTaprootTest(BitcoinTestFramework):
"""Test generation and spending of P2TR address outputs."""