Repository: bitcoin/bitcoin
File: test/functional/rpc_psbt.py (Python)

Code before:
                 })]
        _, 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_partialsig
        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()])

    def assert_change_type(self, psbtx, expected_type):
        """Assert that the given PSBT has a change output with the given type."""

Review comment (refactor):
Nit feel free to ignore: I ignored this duplication in the first commit but now that it's being done twice, a refactor could be to just iterate this in a loop of sighash types. 

Code after:
                    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_partialsig
        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()])

    def test_sighash_mismatch(self):