diff --git a/test/functional/feature_framework_miniwallet.py b/test/functional/feature_framework_miniwallet.py index 1f381df236e..d1aa24e7cd7 100755 --- a/test/functional/feature_framework_miniwallet.py +++ b/test/functional/feature_framework_miniwallet.py @@ -3,6 +3,9 @@ # Distributed under the MIT software license, see the accompanying # file COPYING or http://www.opensource.org/licenses/mit-license.php. """Test MiniWallet.""" +import random +import string + from test_framework.blocktools import COINBASE_MATURITY from test_framework.test_framework import BitcoinTestFramework from test_framework.util import ( @@ -31,6 +34,20 @@ class FeatureFrameworkMiniWalletTest(BitcoinTestFramework): assert_greater_than_or_equal(tx.get_weight(), target_weight) assert_greater_than_or_equal(target_weight + 3, tx.get_weight()) + def test_wallet_tagging(self): + """Verify that tagged wallet instances are able to send funds.""" + self.log.info(f"Test tagged wallet instances...") + node = self.nodes[0] + untagged_wallet = self.wallets[0][1] + for i in range(10): + tag = ''.join(random.choice(string.ascii_letters) for _ in range(20)) + self.log.debug(f"-> ({i}) tag name: {tag}") + tagged_wallet = MiniWallet(node, tag_name=tag) + untagged_wallet.send_to(from_node=node, scriptPubKey=tagged_wallet.get_scriptPubKey(), amount=100000) + tagged_wallet.rescan_utxos() + tagged_wallet.send_self_transfer(from_node=node) + self.generate(node, 1) # clear mempool + def run_test(self): node = self.nodes[0] self.wallets = [ @@ -43,6 +60,7 @@ class FeatureFrameworkMiniWalletTest(BitcoinTestFramework): self.generate(wallet, COINBASE_MATURITY) self.test_tx_padding() + self.test_wallet_tagging() if __name__ == '__main__': diff --git a/test/functional/test_framework/address.py b/test/functional/test_framework/address.py index bcb38b21cd0..968069ff18a 100644 --- a/test/functional/test_framework/address.py +++ b/test/functional/test_framework/address.py @@ -53,13 +53,14 @@ def create_deterministic_address_bcrt1_p2tr_op_true(explicit_internal_key=None): can be spent with a witness stack of OP_TRUE and the control block with internal public key (script-path spending). - Returns a tuple with the generated address and the internal key. + Returns a tuple with the generated address and the TaprootInfo object. """ internal_key = explicit_internal_key or (1).to_bytes(32, 'big') - address = output_key_to_p2tr(taproot_construct(internal_key, [(None, CScript([OP_TRUE]))]).output_pubkey) + taproot_info = taproot_construct(internal_key, [("only-path", CScript([OP_TRUE]))]) + address = output_key_to_p2tr(taproot_info.output_pubkey) if explicit_internal_key is None: assert_equal(address, 'bcrt1p9yfmy5h72durp7zrhlw9lf7jpwjgvwdg0jr0lqmmjtgg83266lqsekaqka') - return (address, internal_key) + return (address, taproot_info) def byte_to_base58(b, version): diff --git a/test/functional/test_framework/wallet.py b/test/functional/test_framework/wallet.py index cb0d2913615..f3713f297e6 100644 --- a/test/functional/test_framework/wallet.py +++ b/test/functional/test_framework/wallet.py @@ -39,7 +39,6 @@ from test_framework.messages import ( ) from test_framework.script import ( CScript, - LEAF_VERSION_TAPSCRIPT, OP_1, OP_NOP, OP_RETURN, @@ -106,8 +105,8 @@ class MiniWallet: pub_key = self._priv_key.get_pubkey() self._scriptPubKey = key_to_p2pk_script(pub_key.get_bytes()) elif mode == MiniWalletMode.ADDRESS_OP_TRUE: - internal_key = None if tag_name is None else hash256(tag_name.encode()) - self._address, self._internal_key = create_deterministic_address_bcrt1_p2tr_op_true(internal_key) + internal_key = None if tag_name is None else compute_xonly_pubkey(hash256(tag_name.encode()))[0] + self._address, self._taproot_info = create_deterministic_address_bcrt1_p2tr_op_true(internal_key) self._scriptPubKey = address_to_scriptpubkey(self._address) # When the pre-mined test framework chain is used, it contains coinbase @@ -195,7 +194,12 @@ class MiniWallet: elif self._mode == MiniWalletMode.ADDRESS_OP_TRUE: tx.wit.vtxinwit = [CTxInWitness()] * len(tx.vin) for i in tx.wit.vtxinwit: - i.scriptWitness.stack = [CScript([OP_TRUE]), bytes([LEAF_VERSION_TAPSCRIPT]) + self._internal_key] + assert_equal(len(self._taproot_info.leaves), 1) + leaf_info = list(self._taproot_info.leaves.values())[0] + i.scriptWitness.stack = [ + leaf_info.script, + bytes([leaf_info.version | self._taproot_info.negflag]) + self._taproot_info.internal_pubkey, + ] else: assert False