Skip to content

Commit

Permalink
dualfund: add test to make sure that tx-sigs sent before commitment
Browse files Browse the repository at this point in the history
results in an error.
  • Loading branch information
niftynei authored and rustyrussell committed Nov 2, 2023
1 parent 30ec8cb commit fa8458c
Show file tree
Hide file tree
Showing 6 changed files with 45 additions and 2 deletions.
3 changes: 2 additions & 1 deletion common/dev_disconnect.c
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,8 @@ enum dev_disconnect dev_disconnect(const struct node_id *id, int pkt_type)
err(1, "lseek failure");
}

status_peer_debug(id, "dev_disconnect: %s (%s)", dev_disconnect_line,
status_peer_debug(id, "dev_disconnect: %s (%s)",
dev_disconnect_line,
peer_wire_name(pkt_type));
return dev_disconnect_line[0];
}
Expand Down
2 changes: 2 additions & 0 deletions common/dev_disconnect.h
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@ enum dev_disconnect {
DEV_DISCONNECT_BEFORE = '-',
/* Close connection after sending packet. */
DEV_DISCONNECT_AFTER = '+',
/* Drop message (don't send to peer) */
DEV_DISCONNECT_DROP = '$',
/* Swallow all writes from now on, and do no more reads. */
DEV_DISCONNECT_BLACKHOLE = '0',
/* Don't use connection after sending packet, but don't close. */
Expand Down
8 changes: 8 additions & 0 deletions connectd/multiplex.c
Original file line number Diff line number Diff line change
Expand Up @@ -446,6 +446,14 @@ static struct io_plan *encrypt_and_send(struct peer *peer,
break;
case DEV_DISCONNECT_NORMAL:
break;
case DEV_DISCONNECT_DROP:
/* Drop this message and continue */
if (taken(msg))
tal_free(msg);
/* Tell them to read again, */
io_wake(&peer->subds);
return msg_queue_wait(peer->to_peer, peer->peer_outq,
next, peer);
case DEV_DISCONNECT_DISABLE_AFTER:
peer->dev_read_enabled = false;
peer->dev_writes_enabled = tal(peer, u32);
Expand Down
1 change: 1 addition & 0 deletions connectd/peer_exchange_initmsg.c
Original file line number Diff line number Diff line change
Expand Up @@ -288,6 +288,7 @@ struct io_plan *peer_exchange_initmsg(struct io_conn *conn,
"Blackhole not supported during handshake");
break;
case DEV_DISCONNECT_NORMAL:
case DEV_DISCONNECT_DROP:
break;
case DEV_DISCONNECT_DISABLE_AFTER:
next = dev_peer_write_post_sabotage;
Expand Down
1 change: 0 additions & 1 deletion openingd/dualopend.c
Original file line number Diff line number Diff line change
Expand Up @@ -1628,7 +1628,6 @@ static u8 *opening_negotiate_msg(const tal_t *ctx, struct state *state)
case WIRE_TX_SIGNATURES:
/* We can get these when we restart and immediately
* startup an RBF */

handle_tx_sigs(state, msg);
continue;
case WIRE_CHANNEL_READY:
Expand Down
32 changes: 32 additions & 0 deletions tests/test_opening.py
Original file line number Diff line number Diff line change
Expand Up @@ -216,6 +216,38 @@ def test_v2_open_sigs_reconnect_1(node_factory, bitcoind):
l2.daemon.wait_for_log(r'to CHANNELD_NORMAL')


@unittest.skipIf(TEST_NETWORK != 'regtest', 'elementsd doesnt yet support PSBT features we need')
@pytest.mark.xfail
@pytest.mark.openchannel('v2')
def test_v2_open_sigs_out_of_order(node_factory, bitcoind):
""" Test what happens if the tx-sigs get sent "before" commitment signed """
disconnects = ['$WIRE_COMMITMENT_SIGNED']

l1, l2 = node_factory.get_nodes(2,
opts=[{},
{'disconnect': disconnects}])

l1.rpc.connect(l2.info['id'], 'localhost', l2.port)
amount = 2**24
chan_amount = 100000
bitcoind.rpc.sendtoaddress(l1.rpc.newaddr()['bech32'], amount / 10**8 + 0.01)
bitcoind.generate_block(1)
# Wait for it to arrive.
wait_for(lambda: len(l1.rpc.listfunds()['outputs']) > 0)

# Fund the channel, should error because L2 doesn't see our commitment-signed
# so they think we've sent things out of order
with pytest.raises(RpcError, match='tx_signatures sent before commitment sigs'):
l1.rpc.fundchannel(l2.info['id'], chan_amount)

# L1 should remove the in-progress channel
wait_for(lambda: l1.rpc.listpeerchannels()['channels'] == [])
# L2 should fail it to chain
l2.daemon.wait_for_logs([r'to AWAITING_UNILATERAL',
# We can't broadcast this, we don't have sigs for funding
'sendrawtx exit 25'])


@pytest.mark.openchannel('v2')
def test_v2_fail_second(node_factory, bitcoind):
""" Open a channel succeeds; opening a second channel
Expand Down

0 comments on commit fa8458c

Please sign in to comment.