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

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions