mirror of
https://github.com/ElementsProject/lightning.git
synced 2025-01-18 05:12:45 +01:00
daemon: HTLC expiry limits.
Don't accept an HTLC which is about to expire, nor one which will take too long to expire. Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
This commit is contained in:
parent
a3e3f83d9f
commit
1018823f97
@ -88,21 +88,31 @@ static void config_register_opts(struct lightningd_state *dstate)
|
|||||||
opt_register_arg("--closing-fee", opt_set_u64, opt_show_u64,
|
opt_register_arg("--closing-fee", opt_set_u64, opt_show_u64,
|
||||||
&dstate->config.closing_fee,
|
&dstate->config.closing_fee,
|
||||||
"Satoshis to use for mutual close transaction fee");
|
"Satoshis to use for mutual close transaction fee");
|
||||||
|
opt_register_arg("--min-expiry", opt_set_u32, opt_show_u32,
|
||||||
|
&dstate->config.min_expiry,
|
||||||
|
"Minimum number of seconds to accept an HTLC before expiry");
|
||||||
|
opt_register_arg("--max-expiry", opt_set_u32, opt_show_u32,
|
||||||
|
&dstate->config.max_expiry,
|
||||||
|
"Maximum number of seconds to accept an HTLC before expiry");
|
||||||
opt_register_arg("--bitcoind-poll", opt_set_u32, opt_show_u32,
|
opt_register_arg("--bitcoind-poll", opt_set_u32, opt_show_u32,
|
||||||
&dstate->config.poll_seconds,
|
&dstate->config.poll_seconds,
|
||||||
"Seconds between polling for new transactions");
|
"Seconds between polling for new transactions");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#define MINUTES 60
|
||||||
|
#define HOURS (60 * MINUTES)
|
||||||
|
#define DAYS (24 * HOURS)
|
||||||
|
|
||||||
static void default_config(struct config *config)
|
static void default_config(struct config *config)
|
||||||
{
|
{
|
||||||
/* aka. "Dude, where's my coins?" */
|
/* aka. "Dude, where's my coins?" */
|
||||||
config->testnet = true;
|
config->testnet = true;
|
||||||
|
|
||||||
/* One day to catch cheating attempts. */
|
/* One day to catch cheating attempts. */
|
||||||
config->rel_locktime = 60 * 60 * 24;
|
config->rel_locktime = 1 * DAYS;
|
||||||
|
|
||||||
/* They can have up to 3 days. */
|
/* They can have up to 3 days. */
|
||||||
config->rel_locktime_max = 60 * 60 * 24 * 3;
|
config->rel_locktime_max = 2 * DAYS;
|
||||||
|
|
||||||
/* We're fairly trusting, under normal circumstances. */
|
/* We're fairly trusting, under normal circumstances. */
|
||||||
config->anchor_confirms = 3;
|
config->anchor_confirms = 3;
|
||||||
@ -121,6 +131,11 @@ static void default_config(struct config *config)
|
|||||||
/* Use this for mutual close. */
|
/* Use this for mutual close. */
|
||||||
config->closing_fee = 10000;
|
config->closing_fee = 10000;
|
||||||
|
|
||||||
|
/* Don't bother me unless I have 6 hours to collect. */
|
||||||
|
config->min_expiry = 6 * HOURS;
|
||||||
|
/* Don't lock up channel for more than 5 days. */
|
||||||
|
config->max_expiry = 5 * DAYS;
|
||||||
|
|
||||||
config->poll_seconds = 30;
|
config->poll_seconds = 30;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -35,6 +35,9 @@ struct config {
|
|||||||
/* What fee we use for the closing transaction (satoshis) */
|
/* What fee we use for the closing transaction (satoshis) */
|
||||||
u64 closing_fee;
|
u64 closing_fee;
|
||||||
|
|
||||||
|
/* Minimum/maximum time for an expiring HTLC (seconds). */
|
||||||
|
u32 min_expiry, max_expiry;
|
||||||
|
|
||||||
/* How long (seconds) between polling bitcoind. */
|
/* How long (seconds) between polling bitcoind. */
|
||||||
u32 poll_seconds;
|
u32 poll_seconds;
|
||||||
};
|
};
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
#include "bitcoin/script.h"
|
#include "bitcoin/script.h"
|
||||||
#include "bitcoin/tx.h"
|
#include "bitcoin/tx.h"
|
||||||
|
#include "controlled_time.h"
|
||||||
#include "find_p2sh_out.h"
|
#include "find_p2sh_out.h"
|
||||||
#include "lightningd.h"
|
#include "lightningd.h"
|
||||||
#include "log.h"
|
#include "log.h"
|
||||||
@ -387,6 +388,18 @@ Pkt *accept_pkt_open_commit_sig(const tal_t *ctx,
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static Pkt *decline_htlc(const tal_t *ctx, const char *why)
|
||||||
|
{
|
||||||
|
UpdateDeclineHtlc *d = tal(ctx, UpdateDeclineHtlc);
|
||||||
|
|
||||||
|
update_decline_htlc__init(d);
|
||||||
|
/* FIXME: Define why in protocol! */
|
||||||
|
d->reason_case = UPDATE_DECLINE_HTLC__REASON_CANNOT_ROUTE;
|
||||||
|
d->cannot_route = true;
|
||||||
|
|
||||||
|
return make_pkt(ctx, PKT__PKT_UPDATE_DECLINE_HTLC, d);
|
||||||
|
}
|
||||||
|
|
||||||
Pkt *accept_pkt_htlc_update(const tal_t *ctx,
|
Pkt *accept_pkt_htlc_update(const tal_t *ctx,
|
||||||
struct peer *peer, const Pkt *pkt,
|
struct peer *peer, const Pkt *pkt,
|
||||||
Pkt **decline)
|
Pkt **decline)
|
||||||
@ -403,6 +416,26 @@ Pkt *accept_pkt_htlc_update(const tal_t *ctx,
|
|||||||
err = pkt_err(ctx, "Invalid HTLC expiry");
|
err = pkt_err(ctx, "Invalid HTLC expiry");
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* FIXME: Handle block-based expiry! */
|
||||||
|
if (!abs_locktime_is_seconds(&cur->htlc->expiry)) {
|
||||||
|
*decline = decline_htlc(ctx,
|
||||||
|
"HTLC expiry in blocks not supported!");
|
||||||
|
goto decline;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (abs_locktime_to_seconds(&cur->htlc->expiry) <
|
||||||
|
controlled_time().ts.tv_sec + peer->dstate->config.min_expiry) {
|
||||||
|
*decline = decline_htlc(ctx, "HTLC expiry too soon!");
|
||||||
|
goto decline;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (abs_locktime_to_seconds(&cur->htlc->expiry) >
|
||||||
|
controlled_time().ts.tv_sec + peer->dstate->config.max_expiry) {
|
||||||
|
*decline = decline_htlc(ctx, "HTLC expiry too far!");
|
||||||
|
goto decline;
|
||||||
|
}
|
||||||
|
|
||||||
cur->cstate = copy_funding(cur, peer->cstate);
|
cur->cstate = copy_funding(cur, peer->cstate);
|
||||||
if (!funding_delta(peer->them.offer_anchor == CMD_OPEN_WITH_ANCHOR,
|
if (!funding_delta(peer->them.offer_anchor == CMD_OPEN_WITH_ANCHOR,
|
||||||
peer->anchor.satoshis,
|
peer->anchor.satoshis,
|
||||||
@ -434,6 +467,11 @@ Pkt *accept_pkt_htlc_update(const tal_t *ctx,
|
|||||||
fail:
|
fail:
|
||||||
tal_free(cur);
|
tal_free(cur);
|
||||||
return err;
|
return err;
|
||||||
|
|
||||||
|
decline:
|
||||||
|
assert(*decline);
|
||||||
|
tal_free(cur);
|
||||||
|
return NULL;
|
||||||
};
|
};
|
||||||
|
|
||||||
Pkt *accept_pkt_htlc_routefail(const tal_t *ctx,
|
Pkt *accept_pkt_htlc_routefail(const tal_t *ctx,
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
#include "bitcoind.h"
|
#include "bitcoind.h"
|
||||||
#include "close_tx.h"
|
#include "close_tx.h"
|
||||||
#include "commit_tx.h"
|
#include "commit_tx.h"
|
||||||
|
#include "controlled_time.h"
|
||||||
#include "cryptopkt.h"
|
#include "cryptopkt.h"
|
||||||
#include "dns.h"
|
#include "dns.h"
|
||||||
#include "find_p2sh_out.h"
|
#include "find_p2sh_out.h"
|
||||||
@ -715,7 +716,9 @@ void peer_unexpected_pkt(struct peer *peer, const Pkt *pkt)
|
|||||||
/* Someone declined our HTLC: details in pkt (we will also get CMD_FAIL) */
|
/* Someone declined our HTLC: details in pkt (we will also get CMD_FAIL) */
|
||||||
void peer_htlc_declined(struct peer *peer, const Pkt *pkt)
|
void peer_htlc_declined(struct peer *peer, const Pkt *pkt)
|
||||||
{
|
{
|
||||||
FIXME_STUB(peer);
|
log_unusual(peer->log, "Peer declined htlc, reason %i",
|
||||||
|
pkt->update_decline_htlc->reason_case);
|
||||||
|
peer->current_htlc = tal_free(peer->current_htlc);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Called when their update overrides our update cmd. */
|
/* Called when their update overrides our update cmd. */
|
||||||
@ -1157,6 +1160,19 @@ static void json_newhtlc(struct command *cmd,
|
|||||||
buffer + expirytok->start);
|
buffer + expirytok->start);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (abs_locktime_to_seconds(&newhtlc->htlc->expiry) <
|
||||||
|
controlled_time().ts.tv_sec + peer->dstate->config.min_expiry) {
|
||||||
|
command_fail(cmd, "HTLC expiry too soon!");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (abs_locktime_to_seconds(&newhtlc->htlc->expiry) >
|
||||||
|
controlled_time().ts.tv_sec + peer->dstate->config.max_expiry) {
|
||||||
|
command_fail(cmd, "HTLC expiry too far!");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (!hex_decode(buffer + rhashtok->start,
|
if (!hex_decode(buffer + rhashtok->start,
|
||||||
rhashtok->end - rhashtok->start,
|
rhashtok->end - rhashtok->start,
|
||||||
&newhtlc->htlc->rhash,
|
&newhtlc->htlc->rhash,
|
||||||
|
@ -53,8 +53,8 @@ check_status()
|
|||||||
|
|
||||||
trap "echo Results in $DIR1 and $DIR2" EXIT
|
trap "echo Results in $DIR1 and $DIR2" EXIT
|
||||||
mkdir $DIR1 $DIR2
|
mkdir $DIR1 $DIR2
|
||||||
$PREFIX1 ../daemon/lightningd --log-level=debug --bitcoind-poll=1 --lightning-dir=$DIR1 > $REDIR1 &
|
$PREFIX1 ../daemon/lightningd --log-level=debug --bitcoind-poll=1 --min-expiry=900 --lightning-dir=$DIR1 > $REDIR1 &
|
||||||
$PREFIX2 ../daemon/lightningd --log-level=debug --bitcoind-poll=1 --lightning-dir=$DIR2 > $REDIR2 &
|
$PREFIX2 ../daemon/lightningd --log-level=debug --bitcoind-poll=1 --min-expiry=900 --lightning-dir=$DIR2 > $REDIR2 &
|
||||||
|
|
||||||
i=0
|
i=0
|
||||||
while ! $LCLI1 getlog | grep Hello; do
|
while ! $LCLI1 getlog | grep Hello; do
|
||||||
|
Loading…
Reference in New Issue
Block a user