mirror of
https://github.com/ElementsProject/lightning.git
synced 2025-01-17 19:03:42 +01:00
test_lightning.py: add test for onchain with different feerates.
Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
This commit is contained in:
parent
19d5305658
commit
5f1c77d249
@ -84,6 +84,10 @@ struct peer *new_peer(struct lightningd *ld, u64 dbid,
|
||||
list_head_init(&peer->channels);
|
||||
peer->direction = get_channel_direction(&peer->ld->id, &peer->id);
|
||||
|
||||
#if DEVELOPER
|
||||
peer->ignore_htlcs = false;
|
||||
#endif
|
||||
|
||||
/* Max 128k per peer. */
|
||||
peer->log_book = new_log_book(128*1024, get_log_level(ld->log_book));
|
||||
set_log_outfn(peer->log_book, copy_to_parent_log, ld->log);
|
||||
|
@ -45,6 +45,11 @@ struct peer {
|
||||
|
||||
/* If we open a channel our direction will be this */
|
||||
u8 direction;
|
||||
|
||||
#if DEVELOPER
|
||||
/* Swallow incoming HTLCs (for testing) */
|
||||
bool ignore_htlcs;
|
||||
#endif
|
||||
};
|
||||
|
||||
struct peer *find_peer_by_dbid(struct lightningd *ld, u64 dbid);
|
||||
|
@ -10,6 +10,7 @@
|
||||
#include <gossipd/gen_gossip_wire.h>
|
||||
#include <lightningd/chaintopology.h>
|
||||
#include <lightningd/htlc_end.h>
|
||||
#include <lightningd/jsonrpc.h>
|
||||
#include <lightningd/lightningd.h>
|
||||
#include <lightningd/log.h>
|
||||
#include <lightningd/pay.h>
|
||||
@ -576,6 +577,13 @@ static bool peer_accepted_htlc(struct channel *channel,
|
||||
if (!htlc_in_update_state(channel, hin, RCVD_ADD_ACK_REVOCATION))
|
||||
return false;
|
||||
|
||||
#if DEVELOPER
|
||||
if (channel->peer->ignore_htlcs) {
|
||||
log_debug(channel->log, "their htlc %"PRIu64" dev_ignore_htlcs",
|
||||
id);
|
||||
return true;
|
||||
}
|
||||
#endif
|
||||
/* BOLT #2:
|
||||
*
|
||||
* A sending node SHOULD fail to route any HTLC added after it
|
||||
@ -1618,3 +1626,40 @@ void notify_feerate_change(struct lightningd *ld)
|
||||
subd_send_msg(channel->owner, take(msg));
|
||||
}
|
||||
}
|
||||
|
||||
#if DEVELOPER
|
||||
static void json_dev_ignore_htlcs(struct command *cmd, const char *buffer,
|
||||
const jsmntok_t *params)
|
||||
{
|
||||
jsmntok_t *nodeidtok, *ignoretok;
|
||||
struct peer *peer;
|
||||
|
||||
if (!json_get_params(cmd, buffer, params,
|
||||
"id", &nodeidtok,
|
||||
"ignore", &ignoretok,
|
||||
NULL)) {
|
||||
return;
|
||||
}
|
||||
|
||||
peer = peer_from_json(cmd->ld, buffer, nodeidtok);
|
||||
if (!peer) {
|
||||
command_fail(cmd, "Could not find channel with that peer");
|
||||
return;
|
||||
}
|
||||
|
||||
if (!json_tok_bool(buffer, ignoretok, &peer->ignore_htlcs)) {
|
||||
command_fail(cmd, "Invalid boolean '%.*s'",
|
||||
ignoretok->end - ignoretok->start,
|
||||
buffer + ignoretok->start);
|
||||
return;
|
||||
}
|
||||
command_success(cmd, null_response(cmd));
|
||||
}
|
||||
|
||||
static const struct json_command dev_ignore_htlcs = {
|
||||
"dev-ignore-htlcs", json_dev_ignore_htlcs,
|
||||
"Set ignoring incoming HTLCs for peer {id} to {ignore}", false,
|
||||
"Set/unset ignoring of all incoming HTLCs. For testing only."
|
||||
};
|
||||
AUTODATA(json_command, &dev_ignore_htlcs);
|
||||
#endif /* DEVELOPER */
|
||||
|
@ -129,9 +129,10 @@ static u64 grind_htlc_tx_fee(struct bitcoin_tx *tx,
|
||||
}
|
||||
status_failed(STATUS_FAIL_INTERNAL_ERROR,
|
||||
"grind_fee failed from %u - %u"
|
||||
" for tx %s, signature %s, wscript %s, multiplier %"PRIu64,
|
||||
" for tx %s, inputamount %"PRIu64", signature %s, wscript %s, multiplier %"PRIu64,
|
||||
min_possible_feerate, max_possible_feerate,
|
||||
type_to_string(tmpctx, struct bitcoin_tx, tx),
|
||||
input_amount,
|
||||
type_to_string(tmpctx, secp256k1_ecdsa_signature, remotesig),
|
||||
tal_hex(tmpctx, wscript),
|
||||
multiplier);
|
||||
|
@ -1939,6 +1939,57 @@ class LightningDTests(BaseLightningDTests):
|
||||
bitcoind.generate_block(1)
|
||||
l1.daemon.wait_for_log('onchaind complete, forgetting peer')
|
||||
|
||||
@unittest.skipIf(not DEVELOPER, "needs DEVELOPER=1 for dev_fail")
|
||||
def test_onchain_different_fees(self):
|
||||
"""Onchain handling when we've had a range of fees"""
|
||||
|
||||
l1, l2 = self.connect()
|
||||
self.fund_channel(l1, l2, 10**7)
|
||||
|
||||
l2.rpc.dev_ignore_htlcs(id=l1.info['id'], ignore=True)
|
||||
p1 = self.pay(l1, l2, 1000000000, async=True)
|
||||
l1.daemon.wait_for_log('htlc 0: RCVD_ADD_ACK_COMMIT->SENT_ADD_ACK_REVOCATION')
|
||||
|
||||
l1.rpc.dev_setfees('14000')
|
||||
p2 = self.pay(l1, l2, 900000000, async=True)
|
||||
l1.daemon.wait_for_log('htlc 1: RCVD_ADD_ACK_COMMIT->SENT_ADD_ACK_REVOCATION')
|
||||
|
||||
l1.rpc.dev_setfees('5000')
|
||||
p3 = self.pay(l1, l2, 800000000, async=True)
|
||||
l1.daemon.wait_for_log('htlc 2: RCVD_ADD_ACK_COMMIT->SENT_ADD_ACK_REVOCATION')
|
||||
|
||||
# Drop to chain
|
||||
l1.rpc.dev_fail(l2.info['id'])
|
||||
l1.daemon.wait_for_log('sendrawtx exit 0')
|
||||
|
||||
bitcoind.generate_block(1)
|
||||
l1.daemon.wait_for_log(' to ONCHAIN')
|
||||
l2.daemon.wait_for_log(' to ONCHAIN')
|
||||
|
||||
# Both sides should have correct feerate
|
||||
assert l1.db_query('SELECT min_possible_feerate, max_possible_feerate FROM channels;') == [{'min_possible_feerate': 5000, 'max_possible_feerate': 14000}]
|
||||
assert l2.db_query('SELECT min_possible_feerate, max_possible_feerate FROM channels;') == [{'min_possible_feerate': 5000, 'max_possible_feerate': 14000}]
|
||||
|
||||
bitcoind.generate_block(5)
|
||||
# Three HTLCs, and one for the to-us output.
|
||||
l1.daemon.wait_for_logs(['sendrawtx exit 0'] * 4)
|
||||
|
||||
# We use 3 blocks for "reasonable depth"
|
||||
bitcoind.generate_block(3)
|
||||
|
||||
self.assertRaises(TimeoutError, p1.result, 10)
|
||||
self.assertRaises(TimeoutError, p2.result, 10)
|
||||
self.assertRaises(TimeoutError, p3.result, 10)
|
||||
|
||||
# Two more for HTLC timeout tx to be spent.
|
||||
bitcoind.generate_block(2)
|
||||
l1.daemon.wait_for_logs(['sendrawtx exit 0'] * 3)
|
||||
|
||||
# Now, 100 blocks it should be done.
|
||||
bitcoind.generate_block(100)
|
||||
wait_forget_channels(l1)
|
||||
wait_forget_channels(l2)
|
||||
|
||||
@unittest.skipIf(not DEVELOPER, "needs DEVELOPER=1")
|
||||
def test_permfail_new_commit(self):
|
||||
# Test case where we have two possible commits: it will use new one.
|
||||
|
Loading…
Reference in New Issue
Block a user