mirror of
https://github.com/ElementsProject/lightning.git
synced 2024-11-19 18:11:28 +01:00
daemon: check and use routing info in HTLC packet.
We only support being the end node for the moment. Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
This commit is contained in:
parent
f4f0c1aa18
commit
b2fdc86740
@ -188,9 +188,10 @@ void queue_pkt_htlc_add(struct peer *peer,
|
||||
if (!blocks_to_abs_locktime(expiry, &locktime))
|
||||
fatal("Invalid locktime?");
|
||||
u->expiry = abs_locktime_to_proto(u, &locktime);
|
||||
/* FIXME: routing! */
|
||||
u->route = tal(u, Routing);
|
||||
routing__init(u->route);
|
||||
u->route->info.data = tal_dup_arr(u, u8, route, tal_count(route), 0);
|
||||
u->route->info.len = tal_count(u->route->info.data);
|
||||
|
||||
/* BOLT #2:
|
||||
*
|
||||
|
113
daemon/peer.c
113
daemon/peer.c
@ -534,6 +534,7 @@ static void state_event(struct peer *peer,
|
||||
}
|
||||
}
|
||||
|
||||
/* FIXME: Reason! */
|
||||
static bool command_htlc_fail(struct peer *peer, u64 id)
|
||||
{
|
||||
if (!state_can_remove_htlc(peer->state))
|
||||
@ -2251,6 +2252,96 @@ static const char *owner_name(enum channel_side side)
|
||||
return side == OURS ? "our" : "their";
|
||||
}
|
||||
|
||||
static void route_htlc_onwards(struct peer *peer,
|
||||
const struct channel_htlc *htlc,
|
||||
u64 msatoshis,
|
||||
const BitcoinPubkey *pb_id,
|
||||
const u8 *rest_of_route)
|
||||
{
|
||||
/* FIXME: implement */
|
||||
}
|
||||
|
||||
static void their_htlc_added(struct peer *peer, const struct channel_htlc *htlc)
|
||||
{
|
||||
RouteStep *step;
|
||||
const u8 *rest_of_route;
|
||||
struct payment *payment;
|
||||
|
||||
if (abs_locktime_is_seconds(&htlc->expiry)) {
|
||||
log_unusual(peer->log, "HTLC %"PRIu64" is in seconds", htlc->id);
|
||||
command_htlc_fail(peer, htlc->id);
|
||||
return;
|
||||
}
|
||||
|
||||
if (abs_locktime_to_blocks(&htlc->expiry) <=
|
||||
get_block_height(peer->dstate) + peer->dstate->config.min_htlc_expiry) {
|
||||
log_unusual(peer->log, "HTLC %"PRIu64" expires too soon:"
|
||||
" block %u",
|
||||
htlc->id, abs_locktime_to_blocks(&htlc->expiry));
|
||||
command_htlc_fail(peer, htlc->id);
|
||||
return;
|
||||
}
|
||||
|
||||
if (abs_locktime_to_blocks(&htlc->expiry) >
|
||||
get_block_height(peer->dstate) + peer->dstate->config.max_htlc_expiry) {
|
||||
log_unusual(peer->log, "HTLC %"PRIu64" expires too far:"
|
||||
" block %u",
|
||||
htlc->id, abs_locktime_to_blocks(&htlc->expiry));
|
||||
command_htlc_fail(peer, htlc->id);
|
||||
return;
|
||||
}
|
||||
|
||||
step = onion_unwrap(peer, htlc->routing, tal_count(htlc->routing),
|
||||
&rest_of_route);
|
||||
if (!step) {
|
||||
log_unusual(peer->log, "Bad onion, failing HTLC %"PRIu64,
|
||||
htlc->id);
|
||||
command_htlc_fail(peer, htlc->id);
|
||||
return;
|
||||
}
|
||||
|
||||
switch (step->next_case) {
|
||||
case ROUTE_STEP__NEXT_END:
|
||||
payment = find_payment(peer->dstate, &htlc->rhash);
|
||||
if (!payment) {
|
||||
log_unusual(peer->log, "No payment for HTLC %"PRIu64,
|
||||
htlc->id);
|
||||
log_add_struct(peer->log, " rhash=%s",
|
||||
struct sha256, &htlc->rhash);
|
||||
if (unlikely(!peer->dstate->dev_never_routefail))
|
||||
command_htlc_fail(peer, htlc->id);
|
||||
goto free_rest;
|
||||
}
|
||||
|
||||
if (htlc->msatoshis != payment->msatoshis) {
|
||||
log_unusual(peer->log, "Short payment for HTLC %"PRIu64
|
||||
": %"PRIu64" not %"PRIu64 " satoshi!",
|
||||
htlc->id,
|
||||
htlc->msatoshis,
|
||||
payment->msatoshis);
|
||||
command_htlc_fail(peer, htlc->id);
|
||||
return;
|
||||
}
|
||||
|
||||
log_info(peer->log, "Immediately resolving HTLC %"PRIu64,
|
||||
htlc->id);
|
||||
command_htlc_fulfill(peer, htlc->id, &payment->r);
|
||||
goto free_rest;
|
||||
|
||||
case ROUTE_STEP__NEXT_BITCOIN:
|
||||
route_htlc_onwards(peer, htlc, step->amount, step->bitcoin,
|
||||
rest_of_route);
|
||||
goto free_rest;
|
||||
default:
|
||||
log_info(peer->log, "Unknown step type %u", step->next_case);
|
||||
command_htlc_fail(peer, htlc->id);
|
||||
goto free_rest;
|
||||
}
|
||||
|
||||
free_rest:
|
||||
tal_free(rest_of_route);
|
||||
}
|
||||
|
||||
/* When changes are committed to. */
|
||||
void peer_both_committed_to(struct peer *peer,
|
||||
const union htlc_staging *changes,
|
||||
@ -2311,29 +2402,9 @@ void peer_both_committed_to(struct peer *peer,
|
||||
return;
|
||||
|
||||
for (i = 0; i < n; i++) {
|
||||
struct payment *payment;
|
||||
|
||||
switch (changes[i].type) {
|
||||
case HTLC_ADD:
|
||||
payment = find_payment(peer->dstate, &changes[i].add.htlc.rhash);
|
||||
if (payment) {
|
||||
if (changes[i].add.htlc.msatoshis != payment->msatoshis) {
|
||||
log_unusual(peer->log, "Got payment for %"PRIu64
|
||||
" not %"PRIu64 " satoshi!",
|
||||
changes[i].add.htlc.msatoshis,
|
||||
payment->msatoshis);
|
||||
command_htlc_fail(peer,
|
||||
changes[i].add.htlc.id);
|
||||
} else {
|
||||
log_info(peer->log,
|
||||
"Immediately resolving HTLC %"PRIu64,
|
||||
changes[i].add.htlc.id);
|
||||
command_htlc_fulfill(peer,
|
||||
changes[i].add.htlc.id,
|
||||
&payment->r);
|
||||
}
|
||||
}
|
||||
/* FIXME: Otherwise, route. */
|
||||
their_htlc_added(peer, &changes[i].add.htlc);
|
||||
break;
|
||||
case HTLC_FULFILL:
|
||||
/* FIXME: resolve_one_htlc(peer, id, preimage); */
|
||||
|
@ -358,6 +358,10 @@ $CLI generate 3
|
||||
check_peerstate lcli1 STATE_NORMAL
|
||||
check_peerstate lcli2 STATE_NORMAL
|
||||
|
||||
# We turn off routing failure for the moment.
|
||||
lcli1 dev-routefail false
|
||||
lcli2 dev-routefail false
|
||||
|
||||
if [ -n "$DIFFERENT_FEES" ]; then
|
||||
# This is 100,000 satoshi, so covers fees.
|
||||
HTLC_AMOUNT=100000000
|
||||
@ -731,6 +735,8 @@ B_AMOUNT=$(($B_AMOUNT + $HTLC_AMOUNT * 2))
|
||||
check_status $A_AMOUNT $A_FEE "" $B_AMOUNT $B_FEE ""
|
||||
|
||||
# Now, use automatic payment redemption
|
||||
lcli1 dev-routefail true
|
||||
lcli2 dev-routefail true
|
||||
RHASH3=`lcli2 accept-payment $HTLC_AMOUNT | sed 's/.*"\([0-9a-f]*\)".*/\1/'`
|
||||
|
||||
lcli1 newhtlc $ID2 $HTLC_AMOUNT $EXPIRY $RHASH3
|
||||
@ -748,6 +754,9 @@ check_status $A_AMOUNT $A_FEE "" $B_AMOUNT $B_FEE ""
|
||||
# Now, failed payment (didn't pay enough)
|
||||
RHASH4=`lcli2 accept-payment $HTLC_AMOUNT | sed 's/.*"\([0-9a-f]*\)".*/\1/'`
|
||||
|
||||
# Shouldn't have this already.
|
||||
if lcli2 getlog | $FGREP 'Short payment for HTLC'; then exit 1; fi
|
||||
|
||||
lcli1 newhtlc $ID2 $(($HTLC_AMOUNT - 1)) $EXPIRY $RHASH4
|
||||
[ ! -n "$MANUALCOMMIT" ] || lcli1 commit $ID2
|
||||
[ ! -n "$MANUALCOMMIT" ] || lcli2 commit $ID1
|
||||
@ -755,7 +764,7 @@ lcli1 newhtlc $ID2 $(($HTLC_AMOUNT - 1)) $EXPIRY $RHASH4
|
||||
[ ! -n "$MANUALCOMMIT" ] || lcli2 commit $ID1
|
||||
[ ! -n "$MANUALCOMMIT" ] || lcli1 commit $ID2
|
||||
|
||||
check lcli2 "getlog | $FGREP 'Got payment for '$(($HTLC_AMOUNT - 1))' not '$HTLC_AMOUNT"
|
||||
check lcli2 "getlog | $FGREP 'Short payment for HTLC'"
|
||||
check_status $A_AMOUNT $A_FEE "" $B_AMOUNT $B_FEE ""
|
||||
|
||||
lcli1 close $ID2
|
||||
|
Loading…
Reference in New Issue
Block a user