channeld: add dev-disable-commit-after instead of dev-disconnect -nocommit

It was always a hack, but an impossible one once connectd will be
interpreting dev-disconnect!

Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
This commit is contained in:
Rusty Russell 2021-12-29 13:56:40 +10:30
parent 888745be16
commit 70ed47d77a
11 changed files with 198 additions and 181 deletions

View file

@ -158,6 +158,10 @@ struct peer {
struct msg_queue *update_queue;
#endif
#if DEVELOPER
/* If set, don't fire commit counter when this hits 0 */
u32 *dev_disable_commit;
#endif
/* Information used for reestablishment. */
bool last_was_revoke;
struct changed_htlc *last_sent_commit;
@ -1248,8 +1252,7 @@ static void send_commit(struct peer *peer)
u32 feerate_target;
#if DEVELOPER
/* Hack to suppress all commit sends if dev_disconnect says to */
if (dev_suppress_commit) {
if (peer->dev_disable_commit && !*peer->dev_disable_commit) {
peer->commit_timer = NULL;
return;
}
@ -1384,6 +1387,14 @@ static void send_commit(struct peer *peer)
} else
pbase = NULL;
#if DEVELOPER
if (peer->dev_disable_commit) {
(*peer->dev_disable_commit)--;
if (*peer->dev_disable_commit == 0)
status_unusual("dev-disable-commit-after: disabling");
}
#endif
status_debug("Telling master we're about to commit...");
/* Tell master to save this next commit to database, then wait. */
msg = sending_commitsig_msg(NULL, peer->next_index[REMOTE],
@ -3655,7 +3666,7 @@ static void handle_send_ping(struct peer *peer, const u8 *msg)
#if DEVELOPER
static void handle_dev_reenable_commit(struct peer *peer)
{
dev_suppress_commit = false;
peer->dev_disable_commit = tal_free(peer->dev_disable_commit);
start_commit_timer(peer);
status_debug("dev_reenable_commit");
wire_sync_write(MASTER_FD,
@ -3828,6 +3839,7 @@ static void init_channel(struct peer *peer)
struct penalty_base *pbases;
u8 *reestablish_only;
struct channel_type *channel_type;
u32 *dev_disable_commit; /* Always NULL */
#if !DEVELOPER
bool dev_fail_process_onionpacket; /* Ignored */
#endif
@ -3836,66 +3848,71 @@ static void init_channel(struct peer *peer)
msg = wire_sync_read(tmpctx, MASTER_FD);
if (!fromwire_channeld_init(peer, msg,
&chainparams,
&peer->our_features,
&peer->channel_id,
&funding,
&funding_sats,
&minimum_depth,
&peer->our_blockheight,
&blockheight_states,
&lease_expiry,
&conf[LOCAL], &conf[REMOTE],
&fee_states,
&peer->feerate_min,
&peer->feerate_max,
&peer->feerate_penalty,
&peer->their_commit_sig,
&peer->pps,
&funding_pubkey[REMOTE],
&points[REMOTE],
&peer->remote_per_commit,
&peer->old_remote_per_commit,
&opener,
&peer->fee_base,
&peer->fee_per_satoshi,
&local_msat,
&points[LOCAL],
&funding_pubkey[LOCAL],
&peer->node_ids[LOCAL],
&peer->node_ids[REMOTE],
&peer->commit_msec,
&peer->cltv_delta,
&peer->last_was_revoke,
&peer->last_sent_commit,
&peer->next_index[LOCAL],
&peer->next_index[REMOTE],
&peer->revocations_received,
&peer->htlc_id,
&htlcs,
&peer->funding_locked[LOCAL],
&peer->funding_locked[REMOTE],
&peer->short_channel_ids[LOCAL],
&reconnected,
&peer->send_shutdown,
&peer->shutdown_sent[REMOTE],
&peer->final_scriptpubkey,
&peer->channel_flags,
&fwd_msg,
&peer->announce_depth_reached,
&last_remote_per_commit_secret,
&peer->their_features,
&peer->remote_upfront_shutdown_script,
&remote_ann_node_sig,
&remote_ann_bitcoin_sig,
&channel_type,
&dev_fast_gossip,
&dev_fail_process_onionpacket,
&pbases,
&reestablish_only)) {
&chainparams,
&peer->our_features,
&peer->channel_id,
&funding,
&funding_sats,
&minimum_depth,
&peer->our_blockheight,
&blockheight_states,
&lease_expiry,
&conf[LOCAL], &conf[REMOTE],
&fee_states,
&peer->feerate_min,
&peer->feerate_max,
&peer->feerate_penalty,
&peer->their_commit_sig,
&peer->pps,
&funding_pubkey[REMOTE],
&points[REMOTE],
&peer->remote_per_commit,
&peer->old_remote_per_commit,
&opener,
&peer->fee_base,
&peer->fee_per_satoshi,
&local_msat,
&points[LOCAL],
&funding_pubkey[LOCAL],
&peer->node_ids[LOCAL],
&peer->node_ids[REMOTE],
&peer->commit_msec,
&peer->cltv_delta,
&peer->last_was_revoke,
&peer->last_sent_commit,
&peer->next_index[LOCAL],
&peer->next_index[REMOTE],
&peer->revocations_received,
&peer->htlc_id,
&htlcs,
&peer->funding_locked[LOCAL],
&peer->funding_locked[REMOTE],
&peer->short_channel_ids[LOCAL],
&reconnected,
&peer->send_shutdown,
&peer->shutdown_sent[REMOTE],
&peer->final_scriptpubkey,
&peer->channel_flags,
&fwd_msg,
&peer->announce_depth_reached,
&last_remote_per_commit_secret,
&peer->their_features,
&peer->remote_upfront_shutdown_script,
&remote_ann_node_sig,
&remote_ann_bitcoin_sig,
&channel_type,
&dev_fast_gossip,
&dev_fail_process_onionpacket,
&dev_disable_commit,
&pbases,
&reestablish_only)) {
master_badmsg(WIRE_CHANNELD_INIT, msg);
}
#if DEVELOPER
peer->dev_disable_commit = dev_disable_commit;
#endif
status_debug("option_static_remotekey = %u, option_anchor_outputs = %u",
channel_type_has(channel_type, OPT_STATIC_REMOTEKEY),
channel_type_has(channel_type, OPT_ANCHOR_OUTPUTS));

View file

@ -74,6 +74,7 @@ msgdata,channeld_init,remote_ann_bitcoin_sig,?secp256k1_ecdsa_signature,
msgdata,channeld_init,desired_type,channel_type,
msgdata,channeld_init,dev_fast_gossip,bool,
msgdata,channeld_init,dev_fail_process_onionpacket,bool,
msgdata,channeld_init,dev_disable_commit,?u32,
msgdata,channeld_init,num_penalty_bases,u32,
msgdata,channeld_init,pbases,penalty_base,num_penalty_bases
msgdata,channeld_init,reestablish_only_len,u16,

Can't render this file because it has a wrong number of fields in line 14.

View file

@ -15,9 +15,6 @@
static int dev_disconnect_fd = -1;
static char dev_disconnect_line[200];
static int dev_disconnect_count, dev_disconnect_len;
static bool dev_disconnect_nocommit;
bool dev_suppress_commit;
static void next_dev_disconnect(void)
{
@ -36,12 +33,6 @@ static void next_dev_disconnect(void)
dev_disconnect_line[r] = '\n';
dev_disconnect_len = strcspn(dev_disconnect_line, "\n");
dev_disconnect_line[dev_disconnect_len] = '\0';
if (strends(dev_disconnect_line, "-nocommit")) {
dev_disconnect_line[strlen(dev_disconnect_line)
- strlen("-nocommit")] = '\0';
dev_disconnect_nocommit = true;
} else
dev_disconnect_nocommit = false;
asterisk = strchr(dev_disconnect_line, '*');
if (asterisk) {
@ -79,10 +70,7 @@ enum dev_disconnect dev_disconnect(int pkt_type)
err(1, "lseek failure");
}
status_debug("dev_disconnect: %s%s", dev_disconnect_line,
dev_disconnect_nocommit ? "-nocommit" : "");
if (dev_disconnect_nocommit)
dev_suppress_commit = true;
status_debug("dev_disconnect: %s", dev_disconnect_line);
return dev_disconnect_line[0];
}

View file

@ -29,8 +29,6 @@ void dev_blackhole_fd(int fd);
/* For debug code to set in daemon. */
void dev_disconnect_init(int fd);
/* Hack for channeld to do DEV_DISCONNECT_SUPPRESS_COMMIT. */
extern bool dev_suppress_commit;
#endif /* DEVELOPER */
#endif /* LIGHTNING_COMMON_DEV_DISCONNECT_H */

View file

@ -653,68 +653,72 @@ void peer_start_channeld(struct channel *channel,
tmpctx, channel->peer->ld->wallet, channel->dbid);
initmsg = towire_channeld_init(tmpctx,
chainparams,
ld->our_features,
&channel->cid,
&channel->funding,
channel->funding_sats,
channel->minimum_depth,
get_block_height(ld->topology),
channel->blockheight_states,
channel->lease_expiry,
&channel->our_config,
&channel->channel_info.their_config,
channel->fee_states,
feerate_min(ld, NULL),
feerate_max(ld, NULL),
try_get_feerate(ld->topology, FEERATE_PENALTY),
&channel->last_sig,
pps,
&channel->channel_info.remote_fundingkey,
&channel->channel_info.theirbase,
&channel->channel_info.remote_per_commit,
&channel->channel_info.old_remote_per_commit,
channel->opener,
channel->feerate_base,
channel->feerate_ppm,
channel->our_msat,
&channel->local_basepoints,
&channel->local_funding_pubkey,
&ld->id,
&channel->peer->id,
cfg->commit_time_ms,
cfg->cltv_expiry_delta,
channel->last_was_revoke,
channel->last_sent_commit,
channel->next_index[LOCAL],
channel->next_index[REMOTE],
num_revocations,
channel->next_htlc_id,
htlcs,
channel->scid != NULL,
channel->remote_funding_locked,
&scid,
reconnected,
chainparams,
ld->our_features,
&channel->cid,
&channel->funding,
channel->funding_sats,
channel->minimum_depth,
get_block_height(ld->topology),
channel->blockheight_states,
channel->lease_expiry,
&channel->our_config,
&channel->channel_info.their_config,
channel->fee_states,
feerate_min(ld, NULL),
feerate_max(ld, NULL),
try_get_feerate(ld->topology, FEERATE_PENALTY),
&channel->last_sig,
pps,
&channel->channel_info.remote_fundingkey,
&channel->channel_info.theirbase,
&channel->channel_info.remote_per_commit,
&channel->channel_info.old_remote_per_commit,
channel->opener,
channel->feerate_base,
channel->feerate_ppm,
channel->our_msat,
&channel->local_basepoints,
&channel->local_funding_pubkey,
&ld->id,
&channel->peer->id,
cfg->commit_time_ms,
cfg->cltv_expiry_delta,
channel->last_was_revoke,
channel->last_sent_commit,
channel->next_index[LOCAL],
channel->next_index[REMOTE],
num_revocations,
channel->next_htlc_id,
htlcs,
channel->scid != NULL,
channel->remote_funding_locked,
&scid,
reconnected,
/* Anything that indicates we are or have
* shut down */
channel->state == CHANNELD_SHUTTING_DOWN
channel->state == CHANNELD_SHUTTING_DOWN
|| channel->state == CLOSINGD_SIGEXCHANGE
|| channel_closed(channel),
channel->shutdown_scriptpubkey[REMOTE] != NULL,
channel->shutdown_scriptpubkey[LOCAL],
channel->channel_flags,
fwd_msg,
reached_announce_depth,
&last_remote_per_commit_secret,
channel->peer->their_features,
channel->remote_upfront_shutdown_script,
remote_ann_node_sig,
remote_ann_bitcoin_sig,
channel->type,
IFDEV(ld->dev_fast_gossip, false),
IFDEV(dev_fail_process_onionpacket, false),
pbases,
reestablish_only);
channel->shutdown_scriptpubkey[REMOTE] != NULL,
channel->shutdown_scriptpubkey[LOCAL],
channel->channel_flags,
fwd_msg,
reached_announce_depth,
&last_remote_per_commit_secret,
channel->peer->their_features,
channel->remote_upfront_shutdown_script,
remote_ann_node_sig,
remote_ann_bitcoin_sig,
channel->type,
IFDEV(ld->dev_fast_gossip, false),
IFDEV(dev_fail_process_onionpacket, false),
IFDEV(ld->dev_disable_commit == -1
? NULL
: (u32 *)&ld->dev_disable_commit,
NULL),
pbases,
reestablish_only);
/* We don't expect a response: we are triggered by funding_depth_cb. */
subd_send_msg(channel->owner, take(initmsg));

View file

@ -133,6 +133,7 @@ static struct lightningd *new_lightningd(const tal_t *ctx)
ld->dev_max_funding_unconfirmed = 2016;
ld->dev_ignore_modern_onion = false;
ld->dev_ignore_obsolete_onion = false;
ld->dev_disable_commit = -1;
#endif
/*~ These are CCAN lists: an embedded double-linked list. It's not

View file

@ -250,6 +250,9 @@ struct lightningd {
/* Special switches to test onion compatibility */
bool dev_ignore_modern_onion, dev_ignore_obsolete_onion;
/* Tell channeld to disable commits after this many. */
int dev_disable_commit;
#endif /* DEVELOPER */
/* tor support */

View file

@ -697,6 +697,10 @@ static void dev_register_opts(struct lightningd *ld)
opt_register_noarg("--dev-no-obsolete-onion", opt_set_bool,
&ld->dev_ignore_obsolete_onion,
"Ignore obsolete onion messages");
opt_register_arg("--dev-disable-commit-after",
opt_set_intval, opt_show_intval,
&ld->dev_disable_commit,
"Disable commit timer after this many commits");
}
#endif /* DEVELOPER */

View file

@ -530,7 +530,7 @@ def test_closing_negotiation_step_700sat(node_factory, bitcoind, chainparams):
closing_negotiation_step(node_factory, bitcoind, chainparams, opts)
@pytest.mark.developer("needs DEVELOPER=1")
@pytest.mark.developer("needs dev-disable-commit-after")
def test_penalty_inhtlc(node_factory, bitcoind, executor, chainparams):
"""Test penalty transaction with an incoming HTLC"""
@ -538,12 +538,12 @@ def test_penalty_inhtlc(node_factory, bitcoind, executor, chainparams):
coin_mvt_plugin = os.path.join(os.getcwd(), 'tests/plugins/coin_movements.py')
# We suppress each one after first commit; HTLC gets added not fulfilled.
# Feerates identical so we don't get gratuitous commit to update them
l1, l2 = node_factory.line_graph(2, opts=[{'disconnect': ['=WIRE_COMMITMENT_SIGNED-nocommit'],
l1, l2 = node_factory.line_graph(2, opts=[{'dev-disable-commit-after': 1,
'may_fail': True,
'feerates': (7500, 7500, 7500, 7500),
'allow_broken_log': True,
'plugin': coin_mvt_plugin},
{'disconnect': ['=WIRE_COMMITMENT_SIGNED-nocommit'],
{'dev-disable-commit-after': 1,
'plugin': coin_mvt_plugin}])
channel_id = first_channel_id(l1, l2)
@ -555,8 +555,8 @@ def test_penalty_inhtlc(node_factory, bitcoind, executor, chainparams):
assert len(l2.getactivechannels()) == 2
# They should both have commitments blocked now.
l1.daemon.wait_for_log('=WIRE_COMMITMENT_SIGNED-nocommit')
l2.daemon.wait_for_log('=WIRE_COMMITMENT_SIGNED-nocommit')
l1.daemon.wait_for_log('dev-disable-commit-after: disabling')
l2.daemon.wait_for_log('dev-disable-commit-after: disabling')
# Make sure l1 got l2's commitment to the HTLC, and sent to master.
l1.daemon.wait_for_log('got commitsig')
@ -652,7 +652,7 @@ def test_penalty_inhtlc(node_factory, bitcoind, executor, chainparams):
check_utxos_channel(l2, [channel_id], expected_2, tags)
@pytest.mark.developer("needs DEVELOPER=1")
@pytest.mark.developer("needs dev-disable-commit-after")
def test_penalty_outhtlc(node_factory, bitcoind, executor, chainparams):
"""Test penalty transaction with an outgoing HTLC"""
@ -661,20 +661,20 @@ def test_penalty_outhtlc(node_factory, bitcoind, executor, chainparams):
# First we need to get funds to l2, so suppress after second.
# Feerates identical so we don't get gratuitous commit to update them
l1, l2 = node_factory.line_graph(2,
opts=[{'disconnect': ['=WIRE_COMMITMENT_SIGNED*3-nocommit'],
opts=[{'dev-disable-commit-after': 3,
'may_fail': True,
'feerates': (7500, 7500, 7500, 7500),
'allow_broken_log': True,
'plugin': coin_mvt_plugin},
{'disconnect': ['=WIRE_COMMITMENT_SIGNED*3-nocommit'],
{'dev-disable-commit-after': 3,
'plugin': coin_mvt_plugin}])
channel_id = first_channel_id(l1, l2)
# Move some across to l2.
l1.pay(l2, 200000000)
assert not l1.daemon.is_in_log('=WIRE_COMMITMENT_SIGNED')
assert not l2.daemon.is_in_log('=WIRE_COMMITMENT_SIGNED')
assert not l1.daemon.is_in_log('dev-disable-commit-after: disabling')
assert not l2.daemon.is_in_log('dev-disable-commit-after: disabling')
# Now, this will get stuck due to l1 commit being disabled..
t = executor.submit(l2.pay, l1, 100000000)
@ -684,8 +684,8 @@ def test_penalty_outhtlc(node_factory, bitcoind, executor, chainparams):
l1.daemon.wait_for_log('peer_in WIRE_COMMITMENT_SIGNED')
# They should both have commitments blocked now.
l1.daemon.wait_for_log('dev_disconnect: =WIRE_COMMITMENT_SIGNED')
l2.daemon.wait_for_log('dev_disconnect: =WIRE_COMMITMENT_SIGNED')
l1.daemon.wait_for_log('dev-disable-commit-after: disabling')
l2.daemon.wait_for_log('dev-disable-commit-after: disabling')
# Make sure both sides got revoke_and_ack for that commitment.
l1.daemon.wait_for_log('peer_in WIRE_REVOKE_AND_ACK')
@ -1567,10 +1567,10 @@ def test_penalty_rbf_normal(node_factory, bitcoind, executor, chainparams):
# l1 is the thief, which causes our honest upstanding lightningd
# code to break, so l1 can fail.
# Initially, disconnect before the HTLC can be resolved.
l1 = node_factory.get_node(disconnect=['=WIRE_COMMITMENT_SIGNED-nocommit'],
l1 = node_factory.get_node(options={'dev-disable-commit-after': 1},
may_fail=True, allow_broken_log=True)
l2 = node_factory.get_node(disconnect=['=WIRE_COMMITMENT_SIGNED-nocommit'],
options={'watchtime-blocks': to_self_delay,
l2 = node_factory.get_node(options={'dev-disable-commit-after': 1,
'watchtime-blocks': to_self_delay,
'plugin': coin_mvt_plugin})
l1.rpc.connect(l2.info['id'], 'localhost', l2.port)
@ -1585,8 +1585,8 @@ def test_penalty_rbf_normal(node_factory, bitcoind, executor, chainparams):
assert len(l2.getactivechannels()) == 2
# Wait for the disconnection.
l1.daemon.wait_for_log('=WIRE_COMMITMENT_SIGNED-nocommit')
l2.daemon.wait_for_log('=WIRE_COMMITMENT_SIGNED-nocommit')
l1.daemon.wait_for_log('dev-disable-commit-after: disabling')
l2.daemon.wait_for_log('dev-disable-commit-after: disabling')
# Make sure l1 gets the new HTLC.
l1.daemon.wait_for_log('got commitsig')
@ -1692,10 +1692,10 @@ def test_penalty_rbf_burn(node_factory, bitcoind, executor, chainparams):
# l1 is the thief, which causes our honest upstanding lightningd
# code to break, so l1 can fail.
# Initially, disconnect before the HTLC can be resolved.
l1 = node_factory.get_node(disconnect=['=WIRE_COMMITMENT_SIGNED-nocommit'],
l1 = node_factory.get_node(options={'dev-disable-commit-after': 1},
may_fail=True, allow_broken_log=True)
l2 = node_factory.get_node(disconnect=['=WIRE_COMMITMENT_SIGNED-nocommit'],
options={'watchtime-blocks': to_self_delay,
l2 = node_factory.get_node(options={'dev-disable-commit-after': 1,
'watchtime-blocks': to_self_delay,
'plugin': coin_mvt_plugin})
l1.rpc.connect(l2.info['id'], 'localhost', l2.port)
@ -1710,8 +1710,8 @@ def test_penalty_rbf_burn(node_factory, bitcoind, executor, chainparams):
assert len(l2.getactivechannels()) == 2
# Wait for the disconnection.
l1.daemon.wait_for_log('=WIRE_COMMITMENT_SIGNED-nocommit')
l2.daemon.wait_for_log('=WIRE_COMMITMENT_SIGNED-nocommit')
l1.daemon.wait_for_log('dev-disable-commit-after: disabling')
l2.daemon.wait_for_log('dev-disable-commit-after: disabling')
# Make sure l1 gets the new HTLC.
l1.daemon.wait_for_log('got commitsig')

View file

@ -643,8 +643,8 @@ def test_reconnect_normal(node_factory):
@pytest.mark.openchannel('v2')
def test_reconnect_sender_add1(node_factory):
# Fail after add is OK, will cause payment failure though.
disconnects = ['-WIRE_UPDATE_ADD_HTLC-nocommit',
'+WIRE_UPDATE_ADD_HTLC-nocommit']
disconnects = ['-WIRE_UPDATE_ADD_HTLC',
'+WIRE_UPDATE_ADD_HTLC']
# Feerates identical so we don't get gratuitous commit to update them
l1 = node_factory.get_node(disconnect=disconnects,
@ -2085,14 +2085,14 @@ def test_channel_persistence(node_factory, bitcoind, executor):
# mysteriously die while committing the first HTLC so we can
# check that HTLCs reloaded from the DB work.
# Feerates identical so we don't get gratuitous commit to update them
disconnect = ['=WIRE_COMMITMENT_SIGNED-nocommit']
disable_commit_after = 1
if EXPERIMENTAL_DUAL_FUND:
disconnect = ['=WIRE_COMMITMENT_SIGNED'] + disconnect
disable_commit_after = 2
l1 = node_factory.get_node(may_reconnect=True, feerates=(7500, 7500, 7500,
7500))
l2 = node_factory.get_node(disconnect=disconnect, may_reconnect=True)
l2 = node_factory.get_node(options={'dev-disable-commit-after': disable_commit_after},
may_reconnect=True)
l1.rpc.connect(l2.info['id'], 'localhost', l2.port)
# Neither node should have a channel open, they are just connected
@ -2119,7 +2119,7 @@ def test_channel_persistence(node_factory, bitcoind, executor):
l2.daemon.kill()
# Clear the disconnect and timer stop so we can proceed normally
del l2.daemon.opts['dev-disconnect']
del l2.daemon.opts['dev-disable-commit-after']
# Wait for l1 to notice
wait_for(lambda: 'connected' not in only_one(l1.rpc.listpeers()['peers'][0]['channels']))
@ -2845,10 +2845,9 @@ def test_dataloss_protection(node_factory, bitcoind):
@pytest.mark.developer("needs dev_disconnect")
def test_restart_multi_htlc_rexmit(node_factory, bitcoind, executor):
# l1 disables commit timer once we send first htlc, dies on commit
disconnects = ['=WIRE_UPDATE_ADD_HTLC-nocommit',
'-WIRE_COMMITMENT_SIGNED']
l1, l2 = node_factory.line_graph(2, opts=[{'disconnect': disconnects,
'may_reconnect': True},
l1, l2 = node_factory.line_graph(2, opts=[{'disconnect': ['-WIRE_COMMITMENT_SIGNED'],
'may_reconnect': True,
'dev-disable-commit-after': 0},
{'may_reconnect': True}])
executor.submit(l1.pay, l2, 20000)
@ -3397,9 +3396,9 @@ def test_htlc_retransmit_order(node_factory, executor):
l1, l2 = node_factory.line_graph(2,
opts=[{'may_reconnect': True,
'feerates': (7500, 7500, 7500, 7500),
'disconnect': ['=WIRE_UPDATE_ADD_HTLC-nocommit',
'=WIRE_UPDATE_ADD_HTLC*' + str(NUM_HTLCS - 1),
'-WIRE_COMMITMENT_SIGNED']},
'disconnect': ['=WIRE_UPDATE_ADD_HTLC*' + str(NUM_HTLCS),
'-WIRE_COMMITMENT_SIGNED'],
'dev-disable-commit-after': 0},
{'may_reconnect': True}])
invoices = [l2.rpc.invoice(1000, str(x), str(x)) for x in range(NUM_HTLCS)]
@ -3412,7 +3411,7 @@ def test_htlc_retransmit_order(node_factory, executor):
for inv in invoices:
executor.submit(l1.rpc.sendpay, [routestep], inv['payment_hash'], payment_secret=inv['payment_secret'])
l1.daemon.wait_for_logs(['dev_disconnect'] * 2)
l1.daemon.wait_for_log('dev_disconnect')
l1.rpc.call('dev-reenable-commit', [l2.info['id']])
l1.daemon.wait_for_log('dev_disconnect')
@ -3619,8 +3618,7 @@ def test_upgrade_statickey_fail(node_factory, executor, bitcoind):
l1_disconnects = ['-WIRE_COMMITMENT_SIGNED',
'-WIRE_REVOKE_AND_ACK']
l2_disconnects = ['-WIRE_REVOKE_AND_ACK',
'-WIRE_COMMITMENT_SIGNED',
'=WIRE_UPDATE_FAIL_HTLC-nocommit']
'-WIRE_COMMITMENT_SIGNED']
l1, l2 = node_factory.line_graph(2, opts=[{'may_reconnect': True,
'dev-no-reconnect': None,
@ -3630,13 +3628,14 @@ def test_upgrade_statickey_fail(node_factory, executor, bitcoind):
'feerates': (7500, 7500, 7500, 7500)},
{'may_reconnect': True,
'dev-no-reconnect': None,
'disconnect': l2_disconnects}])
'disconnect': l2_disconnects,
'dev-disable-commit-after': 1}])
# This HTLC will fail
l1.rpc.sendpay([{'msatoshi': 1000, 'id': l2.info['id'], 'delay': 5, 'channel': '1x1x1'}], '00' * 32, payment_secret='00' * 32)
# Each one should cause one disconnection, no upgrade.
for d in l1_disconnects + l2_disconnects[:-1]:
for d in l1_disconnects + l2_disconnects:
l1.daemon.wait_for_log('Peer connection lost')
l2.daemon.wait_for_log('Peer connection lost')
assert not l1.daemon.is_in_log('option_static_remotekey enabled')

View file

@ -450,7 +450,7 @@ def test_payment_failed_persistence(node_factory, executor):
@pytest.mark.developer("needs DEVELOPER=1")
def test_payment_duplicate_uncommitted(node_factory, executor):
# We want to test two payments at the same time, before we send commit
l1 = node_factory.get_node(disconnect=['=WIRE_UPDATE_ADD_HTLC-nocommit'])
l1 = node_factory.get_node(options={'dev-disable-commit-after': 0})
l2 = node_factory.get_node()
l1.rpc.connect(l2.info['id'], 'localhost', l2.port)
@ -463,7 +463,7 @@ def test_payment_duplicate_uncommitted(node_factory, executor):
fut = executor.submit(l1.rpc.pay, inv1['bolt11'])
# Make sure that's started...
l1.daemon.wait_for_log('dev_disconnect: =WIRE_UPDATE_ADD_HTLC-nocommit')
l1.daemon.wait_for_log('peer_out WIRE_UPDATE_ADD_HTLC')
# We should see it in listsendpays
payments = l1.rpc.listsendpays()['payments']
@ -2809,12 +2809,12 @@ def test_sendonion_rpc(node_factory):
assert(e.error['data']['raw_message'] == "400f00000000000003e80000006c")
@pytest.mark.developer("needs dev-disconnect, dev-no-htlc-timeout")
@pytest.mark.developer("needs dev-disable-commit-after, dev-no-htlc-timeout")
@pytest.mark.openchannel('v1')
@pytest.mark.openchannel('v2')
def test_partial_payment(node_factory, bitcoind, executor):
# We want to test two payments at the same time, before we send commit
l1, l2, l3, l4 = node_factory.get_nodes(4, [{}] + [{'disconnect': ['=WIRE_UPDATE_ADD_HTLC-nocommit'], 'dev-no-htlc-timeout': None}] * 2 + [{'plugin': os.path.join(os.getcwd(), 'tests/plugins/print_htlc_onion.py')}])
l1, l2, l3, l4 = node_factory.get_nodes(4, [{}] + [{'dev-disable-commit-after': 0, 'dev-no-htlc-timeout': None}] * 2 + [{'plugin': os.path.join(os.getcwd(), 'tests/plugins/print_htlc_onion.py')}])
# Two routes to l4: one via l2, and one via l3.
l1.rpc.connect(l2.info['id'], 'localhost', l2.port)
@ -2925,13 +2925,15 @@ def test_partial_payment(node_factory, bitcoind, executor):
groupid=1,
)
# Make sure they've done the suppress-commitment thing before we unsuppress
l2.daemon.wait_for_log(r'dev_disconnect')
l3.daemon.wait_for_log(r'dev_disconnect')
# Make sure they've got the HTLCs before we unsuppress
l2.daemon.wait_for_logs('peer_in WIRE_UPDATE_ADD_HTLC')
l3.daemon.wait_for_log('peer_in WIRE_UPDATE_ADD_HTLC')
# Now continue, payments will succeed due to MPP.
l2.rpc.dev_reenable_commit(l4.info['id'])
l3.rpc.dev_reenable_commit(l4.info['id'])
l2.rpc.dev_reenable_commit(l1.info['id'])
l3.rpc.dev_reenable_commit(l1.info['id'])
res = l1.rpc.waitsendpay(payment_hash=inv['payment_hash'], partid=1)
assert res['partid'] == 1