Skip to content

pyln-testing raises ValueError if a wrong psbt is passed to openchannel_update #8953

@enaples

Description

@enaples

Issue reproduction

Run the following test (#8947):

@unittest.skipIf(TEST_NETWORK != 'regtest', 'elementsd doesnt yet support PSBT features we need')
@pytest.mark.openchannel('v2')
def test_openchannel_wrong_psbt_doesnt_crash_peer(node_factory, bitcoind):
    """Test passing a wrong PSBT to openchannel_update must not crash the peer.
    """
    l1, l2 = node_factory.get_nodes(2, opts={'may_reconnect': True})
    l1.rpc.connect(l2.info['id'], 'localhost', l2.port)

    chan_amount = 100000
    amount_btc = 0.02

    # Fund l1 with two separate UTXOs so we can build two genuinely different PSBTs
    bitcoind.rpc.sendmany("", {
        l1.rpc.newaddr()['p2tr']: amount_btc,
        l1.rpc.newaddr()['p2tr']: amount_btc,
    })
    bitcoind.generate_block(1)
    wait_for(lambda: len(l1.rpc.listfunds()['outputs']) >= 2)

    utxos = l1.rpc.listfunds()['outputs']
    utxo_a = '{}:{}'.format(utxos[0]['txid'], utxos[0]['output'])
    utxo_b = '{}:{}'.format(utxos[1]['txid'], utxos[1]['output'])

    # Build two PSBTs spending different UTXOs
    psbt_a_res = l1.rpc.utxopsbt(chan_amount, 'opening', 250, [utxo_a],
                                  excess_as_change=True)
    psbt_b = l1.rpc.utxopsbt(chan_amount, 'opening', 250, [utxo_b],
                              excess_as_change=True)['psbt']
    funding_feerate = '{}perkw'.format(psbt_a_res['feerate_per_kw'])

    init = l1.rpc.openchannel_init(l2.info['id'], chan_amount, psbt_a_res['psbt'],
                                   funding_feerate=funding_feerate)
    chan_id = init['channel_id']

    # Pass the wrong PSBT (different inputs).
    # FIXME: ideally this would raise a more specific error about the PSBT mismatch, 
    # but it raises a ValueError from pyl-testing library.
    with pytest.raises(ValueError):
        l1.rpc.openchannel_update(chan_id, psbt_b)

    # l2 must still be running and responsive
    assert l2.rpc.getinfo()['id'] == l2.info['id']

Error logs

FAILED tests/test_opening.py::test_openchannel_wrong_psbt_doesnt_crash_peer - jsonschema.exceptions.ValidationError: 'funding_outnum' is a required property

Failed validating 'required' in schema:
    {'required': ['channel_id',
                  'psbt',
                  'commitments_secured',
                  'channel_type',
                  'funding_outnum'],
     'additionalProperties': False,
     'properties': {'channel_id': {'type': 'hash',
                                   'description': ['The channel id of the '
                                                   'channel.']},
                    'channel_type': {'type': 'object',
                                     'description': ['Channel_type as '
                                                     'negotiated with '
                                                     'peer.'],
                                     'added': 'v24.02',
                                     'additionalProperties': False,
                                     'required': ['bits', 'names'],
                                     'properties': {'bits': {'type': 'array',
                                                             'description': ['Each '
                                                                             'bit '
                                                                             'set '
                                                                             'in '
                                                                             'this '
                                                                             'channel_type.'],
                                                             'added': 'v24.02',
                                                             'items': {'type': 'u32',
                                                                       'description': ['Bit '
                                                                                       'number.']}},
                                                    'names': {'type': 'array',
                                                              'description': ['Feature '
                                                                              'name '
                                                                              'for '
                                                                              'each '
                                                                              'bit '
                                                                              'set '
                                                                              'in '
                                                                              'this '
                                                                              'channel_type. '
                                                                              'Note '
                                                                              'that '
                                                                              '*anchors_zero_fee_htlc_tx* '
                                                                              'is '
                                                                              'a '
                                                                              'deprecated '
                                                                              'synonym '
                                                                              'for '
                                                                              '*anchors*.'],
                                                              'added': 'v24.02',
                                                              'items': {'type': 'string',
                                                                        'enum': ['static_remotekey/even',
                                                                                 'anchor_outputs/even',
                                                                                 'anchors_zero_fee_htlc_tx/even',
                                                                                 'anchors/even',
                                                                                 'scid_alias/even',
                                                                                 'zeroconf/even'],
                                                                        'description': ['Name '
                                                                                        'of '
                                                                                        'feature '
                                                                                        'bit.']}}}},
                    'psbt': {'type': 'string',
                             'description': ['The PSBT of the funding '
                                             'transaction.']},
                    'commitments_secured': {'type': 'boolean',
                                            'description': ['Whether the '
                                                            '*psbt* is '
                                                            'complete (if '
                                                            'true, sign '
                                                            '*psbt* and '
                                                            'call '
                                                            '`openchannel_signed` '
                                                            'to complete '
                                                            'the channel '
                                                            'open).']},
                    'funding_outnum': {'type': 'u32',
                                       'description': ['The index of the '
                                                       'funding output in '
                                                       'the psbt.']},
                    'close_to': {'type': 'hex',
                                 'description': ['Scriptpubkey which we '
                                                 'have to close to if we '
                                                 'mutual close.']},
                    'requires_confirmed_inputs': {'type': 'boolean',
                                                  'description': ['Does '
                                                                  'peer '
                                                                  'require '
                                                                  'confirmed '
                                                                  'inputs '
                                                                  'in '
                                                                  'psbt?']}},
     'allOf': [{'if': {'additionalProperties': True,
                       'properties': {'commitments_secured': {'type': 'boolean',
                                                              'enum': [True]}}},
                'then': {'additionalProperties': True,
                         'required': ['channel_id', 'funding_outnum'],
                         'properties': {'commitments_secured': {},
                                        'channel_id': {'type': 'hash',
                                                       'description': ['The '
                                                                       'derived '
                                                                       'channel '
                                                                       'id.']},
                                        'close_to': {'type': 'hex',
                                                     'description': ['If a '
                                                                     '`close_to` '
                                                                     'address '
                                                                     'was '
                                                                     'provided '
                                                                     'to '
                                                                     '`openchannel_init` '
                                                                     'and '
                                                                     'the '
                                                                     'peer '
                                                                     'supports '
                                                                     '`option_upfront_shutdownscript`.']},
                                        'funding_outnum': {'type': 'u32',
                                                           'description': ['The '
                                                                           'index '
                                                                           'of '
                                                                           'the '
                                                                           'funding '
                                                                           'output '
                                                                           'for '
                                                                           'this '
                                                                           'channel '
                                                                           'in '
                                                                           'the '
                                                                           'funding '
                                                                           'transaction.']}}},
                'else': {'additionalProperties': False,
                         'properties': {'commitments_secured': {}}}}]}

On instance:
    {'channel_id': '2c383675809577b343f57acbea98d51dd913817874a3b621173f3fe2ea519c45',
     'psbt': 'cHNidP8BAgQCAAAAAQMEZgAAAAEEAQEBBQEBAQYBAwH7BAIAAAAAAQC0AgAAAAHeXUqJ+FMURF99QfNesChSzK29vAwv0ihuBf7QmaKCVQAAAAAA/f///wMw6MgpAQAAACJRIBgbpQcLvoxNWf3/x8OKAJYfeeIl3uZmfsd7Bc9w3HSjgIQeAAAAAAAiUSC5UNiwZgMpisf3FGL565UvuL4AQpOWN0jlcQ/ii1Nww4CEHgAAAAAAIlEgn6TSTp2kPFv4/A2XNtTkRSOKzXFNBoEW31Fl0Hkduh1lAAAAAQErgIQeAAAAAAAiUSCfpNJOnaQ8W/j8DZc21ORFI4rNcU0GgRbfUWXQeR26HQEOIPnY/JD6DVlLzXo7V7sgDxHVu4zCxZ3UBSP7ttjjASwoAQ8EAgAAAAEQBP3///8M/AlsaWdodG5pbmcBCD9OB5zUzdoUAAEDCMbqHAAAAAAAAQQiUSDLmLufQyk2EMedQ8Kz3wihNg/lGfQmqqD9Ce/mACuAugz8CWxpZ2h0bmluZwEIV5Xu3sckCyQA',
     'channel_type': {'bits': [12, 22],
                      'names': ['static_remotekey/even', 'anchors/even']},
     'commitments_secured': False,
     'funding_serial': 3014915220181719196,
     'requires_confirmed_inputs': False}


ERROR tests/test_opening.py::test_openchannel_wrong_psbt_doesnt_crash_peer - ValueError: 
Node errors:
 - lightningd-1: had BROKEN or That's weird messages
 - lightningd-1: had memleak messages
Global errors:
 - Node /tmp/ltests-v1hn5dn1/test_openchannel_wrong_psbt_doesnt_crash_peer_1/lightning-1/ has memory leaks: [
    {
        "subdaemon": "dualopend"
    }
]

Metadata

Metadata

Assignees

No one assigned

    Labels

    QABlockstream QA team have reproduced, or a test has been created! Look for the linked PR/Issue

    Type

    No type

    Projects

    No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions