mirror of
https://github.com/bitcoin/bitcoin.git
synced 2025-04-29 06:49:38 -04:00
Merge 23ee07dd0f
into c5e44a0435
This commit is contained in:
commit
081a6f6c1f
2 changed files with 79 additions and 0 deletions
|
@ -29,8 +29,12 @@ from test_framework.psbt import (
|
|||
PSBT_IN_SHA256,
|
||||
PSBT_IN_HASH160,
|
||||
PSBT_IN_HASH256,
|
||||
PSBT_IN_MUSIG2_PARTIAL_SIG,
|
||||
PSBT_IN_MUSIG2_PARTICIPANT_PUBKEYS,
|
||||
PSBT_IN_MUSIG2_PUB_NONCE,
|
||||
PSBT_IN_NON_WITNESS_UTXO,
|
||||
PSBT_IN_WITNESS_UTXO,
|
||||
PSBT_OUT_MUSIG2_PARTICIPANT_PUBKEYS,
|
||||
PSBT_OUT_TAP_TREE,
|
||||
)
|
||||
from test_framework.script import CScript, OP_TRUE
|
||||
|
@ -959,6 +963,74 @@ class PSBTTest(BitcoinTestFramework):
|
|||
assert hash.hex() in res_input[preimage_key]
|
||||
assert_equal(res_input[preimage_key][hash.hex()], preimage.hex())
|
||||
|
||||
self.log.info("Test decoding PSBT with MuSig2 per-input and per-output types")
|
||||
# create 2-of-2 musig2 using fake aggregate key, leaf hash, pubnonce, and partial sig
|
||||
# TODO: actually implement MuSig2 aggregation (for decoding only it doesn't matter though)
|
||||
_, in_pubkey1 = generate_keypair()
|
||||
_, in_pubkey2 = generate_keypair()
|
||||
_, in_fake_agg_pubkey = generate_keypair()
|
||||
fake_leaf_hash = randbytes(32)
|
||||
fake_pubnonce = randbytes(66)
|
||||
fake_partialsig = randbytes(32)
|
||||
tx = CTransaction()
|
||||
tx.vin = [CTxIn(outpoint=COutPoint(hash=int('ee' * 32, 16), n=0), scriptSig=b"")]
|
||||
tx.vout = [CTxOut(nValue=0, scriptPubKey=b"")]
|
||||
psbt = PSBT()
|
||||
psbt.g = PSBTMap({PSBT_GLOBAL_UNSIGNED_TX: tx.serialize()})
|
||||
participant1_keydata = in_pubkey1 + in_fake_agg_pubkey + fake_leaf_hash
|
||||
psbt.i = [PSBTMap({
|
||||
bytes([PSBT_IN_MUSIG2_PARTICIPANT_PUBKEYS]) + in_fake_agg_pubkey: [in_pubkey1, in_pubkey2],
|
||||
bytes([PSBT_IN_MUSIG2_PUB_NONCE]) + participant1_keydata: fake_pubnonce,
|
||||
bytes([PSBT_IN_MUSIG2_PARTIAL_SIG]) + participant1_keydata: fake_partialsig,
|
||||
})]
|
||||
_, out_pubkey1 = generate_keypair()
|
||||
_, out_pubkey2 = generate_keypair()
|
||||
_, out_fake_agg_pubkey = generate_keypair()
|
||||
psbt.o = [PSBTMap({
|
||||
bytes([PSBT_OUT_MUSIG2_PARTICIPANT_PUBKEYS]) + out_fake_agg_pubkey: [out_pubkey1, out_pubkey2],
|
||||
})]
|
||||
res = self.nodes[0].decodepsbt(psbt.to_base64())
|
||||
assert_equal(len(res["inputs"]), 1)
|
||||
res_input = res["inputs"][0]
|
||||
assert_equal(len(res["outputs"]), 1)
|
||||
res_output = res["outputs"][0]
|
||||
|
||||
assert "musig2_participant_pubkeys" in res_input
|
||||
in_participant_pks = res_input["musig2_participant_pubkeys"][0]
|
||||
assert "aggregate_pubkey" in in_participant_pks
|
||||
assert_equal(in_participant_pks["aggregate_pubkey"], in_fake_agg_pubkey.hex())
|
||||
assert "participant_pubkeys" in in_participant_pks
|
||||
assert_equal(in_participant_pks["participant_pubkeys"], [in_pubkey1.hex(), in_pubkey2.hex()])
|
||||
|
||||
assert "musig2_pubnonces" in res_input
|
||||
in_pubnonce = res_input["musig2_pubnonces"][0]
|
||||
assert "participant_pubkey" in in_pubnonce
|
||||
assert_equal(in_pubnonce["participant_pubkey"], in_pubkey1.hex())
|
||||
assert "aggregate_pubkey" in in_pubnonce
|
||||
assert_equal(in_pubnonce["aggregate_pubkey"], in_fake_agg_pubkey.hex())
|
||||
assert "leaf_hash" in in_pubnonce
|
||||
assert_equal(in_pubnonce["leaf_hash"], fake_leaf_hash.hex())
|
||||
assert "pubnonce" in in_pubnonce
|
||||
assert_equal(in_pubnonce["pubnonce"], fake_pubnonce.hex())
|
||||
|
||||
assert "musig2_partial_sigs" in res_input
|
||||
in_partialsig = res_input["musig2_partial_sigs"][0]
|
||||
assert "participant_pubkey" in in_partialsig
|
||||
assert_equal(in_partialsig["participant_pubkey"], in_pubkey1.hex())
|
||||
assert "aggregate_pubkey" in in_pubnonce
|
||||
assert_equal(in_partialsig["aggregate_pubkey"], in_fake_agg_pubkey.hex())
|
||||
assert "leaf_hash" in in_partialsig
|
||||
assert_equal(in_partialsig["leaf_hash"], fake_leaf_hash.hex())
|
||||
assert "partial_sig" in in_partialsig
|
||||
assert_equal(in_partialsig["partial_sig"], fake_partialsig.hex())
|
||||
|
||||
assert "musig2_participant_pubkeys" in res_output
|
||||
out_participant_pks = res_output["musig2_participant_pubkeys"][0]
|
||||
assert "aggregate_pubkey" in out_participant_pks
|
||||
assert_equal(out_participant_pks["aggregate_pubkey"], out_fake_agg_pubkey.hex())
|
||||
assert "participant_pubkeys" in out_participant_pks
|
||||
assert_equal(out_participant_pks["participant_pubkeys"], [out_pubkey1.hex(), out_pubkey2.hex()])
|
||||
|
||||
self.log.info("Test that combining PSBTs with different transactions fails")
|
||||
tx = CTransaction()
|
||||
tx.vin = [CTxIn(outpoint=COutPoint(hash=int('aa' * 32, 16), n=0), scriptSig=b"")]
|
||||
|
|
|
@ -50,6 +50,9 @@ PSBT_IN_TAP_LEAF_SCRIPT = 0x15
|
|||
PSBT_IN_TAP_BIP32_DERIVATION = 0x16
|
||||
PSBT_IN_TAP_INTERNAL_KEY = 0x17
|
||||
PSBT_IN_TAP_MERKLE_ROOT = 0x18
|
||||
PSBT_IN_MUSIG2_PARTICIPANT_PUBKEYS = 0x1a
|
||||
PSBT_IN_MUSIG2_PUB_NONCE = 0x1b
|
||||
PSBT_IN_MUSIG2_PARTIAL_SIG = 0x1c
|
||||
PSBT_IN_PROPRIETARY = 0xfc
|
||||
|
||||
# per-output types
|
||||
|
@ -61,6 +64,7 @@ PSBT_OUT_SCRIPT = 0x04
|
|||
PSBT_OUT_TAP_INTERNAL_KEY = 0x05
|
||||
PSBT_OUT_TAP_TREE = 0x06
|
||||
PSBT_OUT_TAP_BIP32_DERIVATION = 0x07
|
||||
PSBT_OUT_MUSIG2_PARTICIPANT_PUBKEYS = 0x08
|
||||
PSBT_OUT_PROPRIETARY = 0xfc
|
||||
|
||||
|
||||
|
@ -88,6 +92,9 @@ class PSBTMap:
|
|||
for k,v in self.map.items():
|
||||
if isinstance(k, int) and 0 <= k and k <= 255:
|
||||
k = bytes([k])
|
||||
if isinstance(v, list):
|
||||
assert any(type(elem) is bytes for elem in v)
|
||||
v = b"".join(v) # simply concatenate the byte-strings w/o size prefixes
|
||||
m += ser_compact_size(len(k)) + k
|
||||
m += ser_compact_size(len(v)) + v
|
||||
m += b"\x00"
|
||||
|
|
Loading…
Add table
Reference in a new issue