diff options
author | Antoine Poinsot <darosior@protonmail.com> | 2023-02-11 12:57:52 +0100 |
---|---|---|
committer | Antoine Poinsot <darosior@protonmail.com> | 2023-02-13 15:39:25 +0100 |
commit | 6c7a17a8e0eec377f83ed1399f003ae70b898270 (patch) | |
tree | 3c3d8a5eb4d3078e287c27d6921a2c55611d65e4 | |
parent | 840a396029316896beda46600aec3c1af09a899c (diff) |
psbt: support externally provided preimages for Miniscript satisfaction
Co-Authored-By: Andrew Chow <github@achow101.com>
-rw-r--r-- | src/psbt.cpp | 12 | ||||
-rwxr-xr-x | test/functional/wallet_miniscript.py | 25 |
2 files changed, 35 insertions, 2 deletions
diff --git a/src/psbt.cpp b/src/psbt.cpp index 461987c503..701b085c20 100644 --- a/src/psbt.cpp +++ b/src/psbt.cpp @@ -132,6 +132,18 @@ void PSBTInput::FillSignatureData(SignatureData& sigdata) const for (const auto& [pubkey, leaf_origin] : m_tap_bip32_paths) { sigdata.taproot_misc_pubkeys.emplace(pubkey, leaf_origin); } + for (const auto& [hash, preimage] : ripemd160_preimages) { + sigdata.ripemd160_preimages.emplace(std::vector<unsigned char>(hash.begin(), hash.end()), preimage); + } + for (const auto& [hash, preimage] : sha256_preimages) { + sigdata.sha256_preimages.emplace(std::vector<unsigned char>(hash.begin(), hash.end()), preimage); + } + for (const auto& [hash, preimage] : hash160_preimages) { + sigdata.hash160_preimages.emplace(std::vector<unsigned char>(hash.begin(), hash.end()), preimage); + } + for (const auto& [hash, preimage] : hash256_preimages) { + sigdata.hash256_preimages.emplace(std::vector<unsigned char>(hash.begin(), hash.end()), preimage); + } } void PSBTInput::FromSignatureData(const SignatureData& sigdata) diff --git a/test/functional/wallet_miniscript.py b/test/functional/wallet_miniscript.py index e8b89513d0..7e3cbcbda3 100755 --- a/test/functional/wallet_miniscript.py +++ b/test/functional/wallet_miniscript.py @@ -5,6 +5,7 @@ """Test Miniscript descriptors integration in the wallet.""" from test_framework.descriptors import descsum_create +from test_framework.psbt import PSBT, PSBT_IN_SHA256 from test_framework.test_framework import BitcoinTestFramework from test_framework.util import assert_equal @@ -60,6 +61,17 @@ MINISCRIPTS_PRIV = [ "sigs_count": 3, "stack_size": 5, }, + # The same policy but we provide the preimage. This path will be chosen as it's a smaller witness. + { + "ms": f"andor(ndv:older(2),and_v(v:pk({TPRVS[0]}),sha256(61e33e9dbfefc45f6a194187684d278f789fd4d5e207a357e79971b6519a8b12)),and_v(v:pkh({TPRVS[1]}),pk({TPRVS[2]}/*)))", + "sequence": 2, + "locktime": None, + "sigs_count": 3, + "stack_size": 4, + "sha256_preimages": { + "61e33e9dbfefc45f6a194187684d278f789fd4d5e207a357e79971b6519a8b12": "e8774f330f5f330c23e8bbefc5595cb87009ddb7ac3b8deaaa8e9e41702d919c" + }, + }, # Signature with a relative timelock { "ms": f"and_v(v:older(2),pk({TPRVS[0]}/*))", @@ -167,7 +179,9 @@ class WalletMiniscriptTest(BitcoinTestFramework): utxo = self.ms_wo_wallet.listunspent(minconf=0, addresses=[addr])[0] assert utxo["txid"] == txid and utxo["solvable"] - def signing_test(self, ms, sequence, locktime, sigs_count, stack_size): + def signing_test( + self, ms, sequence, locktime, sigs_count, stack_size, sha256_preimages + ): self.log.info(f"Importing private Miniscript '{ms}'") desc = descsum_create(f"wsh({ms})") res = self.ms_sig_wallet.importdescriptors( @@ -208,6 +222,12 @@ class WalletMiniscriptTest(BitcoinTestFramework): ) self.log.info("Signing it and checking the satisfaction.") + if sha256_preimages is not None: + psbt = PSBT.from_base64(psbt) + for (h, preimage) in sha256_preimages.items(): + k = PSBT_IN_SHA256.to_bytes(1, "big") + bytes.fromhex(h) + psbt.i[0].map[k] = bytes.fromhex(preimage) + psbt = psbt.to_base64() res = self.ms_sig_wallet.walletprocesspsbt(psbt=psbt, finalize=False) psbtin = self.nodes[0].rpc.decodepsbt(res["psbt"])["inputs"][0] assert len(psbtin["partial_signatures"]) == sigs_count @@ -258,7 +278,7 @@ class WalletMiniscriptTest(BitcoinTestFramework): for ms in MINISCRIPTS: self.watchonly_test(ms) - # Test we can sign most Miniscript (all but ones requiring preimages, for now) + # Test we can sign for any Miniscript. for ms in MINISCRIPTS_PRIV: self.signing_test( ms["ms"], @@ -266,6 +286,7 @@ class WalletMiniscriptTest(BitcoinTestFramework): ms["locktime"], ms["sigs_count"], ms["stack_size"], + ms.get("sha256_preimages"), ) |