Skip to content

Commit

Permalink
psbt: support externally provided preimages for Miniscript satisfaction
Browse files Browse the repository at this point in the history
  • Loading branch information
darosior committed Feb 11, 2023
1 parent ea53211 commit 3c6e3e0
Show file tree
Hide file tree
Showing 2 changed files with 34 additions and 1 deletion.
12 changes: 12 additions & 0 deletions src/psbt.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
23 changes: 22 additions & 1 deletion test/functional/wallet_miniscript.py
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down Expand Up @@ -60,6 +61,17 @@
"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]}/*))",
Expand Down Expand Up @@ -167,7 +179,9 @@ def watchonly_test(self, ms):
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(
Expand Down Expand Up @@ -208,6 +222,12 @@ def signing_test(self, ms, sequence, locktime, sigs_count, stack_size):
)

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
Expand Down Expand Up @@ -266,6 +286,7 @@ def run_test(self):
ms["locktime"],
ms["sigs_count"],
ms["stack_size"],
ms.get("sha256_preimages"),
)


Expand Down

0 comments on commit 3c6e3e0

Please sign in to comment.