mirror of
https://github.com/ElementsProject/lightning.git
synced 2025-01-18 05:12:45 +01:00
daemon: routefail command.
This should be renamed: it's actually any kind of after-the-fact failure. Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
This commit is contained in:
parent
86f4bd772c
commit
2346f6bf14
@ -240,6 +240,7 @@ static const struct json_command *cmdlist[] = {
|
||||
&getpeers_command,
|
||||
&newhtlc_command,
|
||||
&fulfillhtlc_command,
|
||||
&failhtlc_command,
|
||||
/* Developer/debugging options. */
|
||||
&echo_command,
|
||||
&rhash_command,
|
||||
|
@ -60,4 +60,5 @@ extern const struct json_command connect_command;
|
||||
extern const struct json_command getpeers_command;
|
||||
extern const struct json_command newhtlc_command;
|
||||
extern const struct json_command fulfillhtlc_command;
|
||||
extern const struct json_command failhtlc_command;
|
||||
#endif /* LIGHTNING_DAEMON_JSONRPC_H */
|
||||
|
@ -168,7 +168,14 @@ Pkt *pkt_htlc_timedout(const tal_t *ctx, const struct peer *peer,
|
||||
Pkt *pkt_htlc_routefail(const tal_t *ctx, const struct peer *peer,
|
||||
const struct htlc_progress *htlc_prog)
|
||||
{
|
||||
FIXME_STUB(peer);
|
||||
UpdateRoutefailHtlc *f = tal(ctx, UpdateRoutefailHtlc);
|
||||
|
||||
update_routefail_htlc__init(f);
|
||||
|
||||
f->revocation_hash = sha256_to_proto(f, &htlc_prog->our_revocation_hash);
|
||||
f->r_hash = sha256_to_proto(f, &htlc_prog->htlc->rhash);
|
||||
|
||||
return make_pkt(ctx, PKT__PKT_UPDATE_ROUTEFAIL_HTLC, f);
|
||||
}
|
||||
|
||||
Pkt *pkt_update_accept(const tal_t *ctx, const struct peer *peer)
|
||||
@ -432,7 +439,50 @@ fail:
|
||||
Pkt *accept_pkt_htlc_routefail(const tal_t *ctx,
|
||||
struct peer *peer, const Pkt *pkt)
|
||||
{
|
||||
FIXME_STUB(peer);
|
||||
const UpdateRoutefailHtlc *f = pkt->update_routefail_htlc;
|
||||
struct htlc_progress *cur = tal(peer, struct htlc_progress);
|
||||
Pkt *err;
|
||||
size_t i;
|
||||
struct sha256 rhash;
|
||||
|
||||
proto_to_sha256(f->revocation_hash, &cur->their_revocation_hash);
|
||||
proto_to_sha256(f->r_hash, &rhash);
|
||||
|
||||
i = funding_find_htlc(&peer->cstate->a, &rhash);
|
||||
if (i == tal_count(peer->cstate->a.htlcs)) {
|
||||
err = pkt_err(ctx, "Unknown HTLC");
|
||||
goto fail;
|
||||
}
|
||||
|
||||
cur->htlc = &peer->cstate->a.htlcs[i];
|
||||
|
||||
/* Removing it should not fail: we regain HTLC amount */
|
||||
cur->cstate = copy_funding(cur, peer->cstate);
|
||||
if (!funding_delta(peer->us.offer_anchor == CMD_OPEN_WITH_ANCHOR,
|
||||
peer->anchor.satoshis,
|
||||
0, -cur->htlc->msatoshis,
|
||||
&cur->cstate->a, &cur->cstate->b)) {
|
||||
fatal("Unexpected failure fulfilling HTLC of %"PRIu64
|
||||
" milli-satoshis", cur->htlc->msatoshis);
|
||||
}
|
||||
funding_remove_htlc(&cur->cstate->a, i);
|
||||
|
||||
peer_get_revocation_hash(peer, peer->num_htlcs+1,
|
||||
&cur->our_revocation_hash);
|
||||
|
||||
/* Now we create the commit tx pair. */
|
||||
make_commit_txs(cur, peer, &cur->our_revocation_hash,
|
||||
&cur->their_revocation_hash,
|
||||
cur->cstate,
|
||||
&cur->our_commit, &cur->their_commit);
|
||||
|
||||
assert(!peer->current_htlc);
|
||||
peer->current_htlc = cur;
|
||||
return NULL;
|
||||
|
||||
fail:
|
||||
tal_free(cur);
|
||||
return err;
|
||||
}
|
||||
|
||||
Pkt *accept_pkt_htlc_timedout(const tal_t *ctx,
|
||||
|
@ -1157,3 +1157,89 @@ const struct json_command fulfillhtlc_command = {
|
||||
"Redeem htlc proposed by {id} using {r}",
|
||||
"Returns an empty result on success"
|
||||
};
|
||||
|
||||
|
||||
static void json_failhtlc(struct command *cmd,
|
||||
const char *buffer, const jsmntok_t *params)
|
||||
{
|
||||
struct peer *peer;
|
||||
jsmntok_t *idtok, *rhashtok;
|
||||
struct pubkey id;
|
||||
struct sha256 rhash;
|
||||
struct htlc_progress *cur;
|
||||
size_t i;
|
||||
|
||||
json_get_params(buffer, params,
|
||||
"id", &idtok,
|
||||
"rhash", &rhashtok,
|
||||
NULL);
|
||||
|
||||
if (!idtok || !rhashtok) {
|
||||
command_fail(cmd, "Need id and rhash");
|
||||
return;
|
||||
}
|
||||
|
||||
if (!pubkey_from_hexstr(cmd->dstate->secpctx,
|
||||
buffer + idtok->start,
|
||||
idtok->end - idtok->start, &id)) {
|
||||
command_fail(cmd, "Not a valid id");
|
||||
return;
|
||||
}
|
||||
peer = find_peer(cmd->dstate, &id);
|
||||
if (!peer) {
|
||||
command_fail(cmd, "Could not find peer with that id");
|
||||
return;
|
||||
}
|
||||
|
||||
/* Attach to cmd until it's complete. */
|
||||
cur = tal(cmd, struct htlc_progress);
|
||||
|
||||
if (!hex_decode(buffer + rhashtok->start,
|
||||
rhashtok->end - rhashtok->start,
|
||||
&rhash, sizeof(rhash))) {
|
||||
command_fail(cmd, "'%.*s' is not a valid sha256 preimage",
|
||||
(int)(rhashtok->end - rhashtok->start),
|
||||
buffer + rhashtok->start);
|
||||
return;
|
||||
}
|
||||
|
||||
i = funding_find_htlc(&peer->cstate->b, &rhash);
|
||||
if (i == tal_count(peer->cstate->b.htlcs)) {
|
||||
command_fail(cmd, "'%.*s' htlc not found",
|
||||
(int)(rhashtok->end - rhashtok->start),
|
||||
buffer + rhashtok->start);
|
||||
return;
|
||||
}
|
||||
cur->htlc = &peer->cstate->b.htlcs[i];
|
||||
|
||||
/* Removing it should not fail: they gain HTLC amount */
|
||||
cur->cstate = copy_funding(cur, peer->cstate);
|
||||
if (!funding_delta(peer->them.offer_anchor == CMD_OPEN_WITH_ANCHOR,
|
||||
peer->anchor.satoshis,
|
||||
0,
|
||||
-cur->htlc->msatoshis,
|
||||
&cur->cstate->b, &cur->cstate->a)) {
|
||||
fatal("Unexpected failure routefailing HTLC of %"PRIu64
|
||||
" milli-satoshis", cur->htlc->msatoshis);
|
||||
return;
|
||||
}
|
||||
funding_remove_htlc(&cur->cstate->b, i);
|
||||
|
||||
peer_get_revocation_hash(peer, peer->num_htlcs+1,
|
||||
&cur->our_revocation_hash);
|
||||
|
||||
peer->current_htlc = tal_steal(peer, cur);
|
||||
peer->jsoncmd = cmd;
|
||||
|
||||
/* FIXME: do we need this? */
|
||||
peer->cmddata.htlc_prog = peer->current_htlc;
|
||||
peer->cmd = CMD_SEND_HTLC_ROUTEFAIL;
|
||||
try_command(peer);
|
||||
}
|
||||
|
||||
const struct json_command failhtlc_command = {
|
||||
"failhtlc",
|
||||
json_failhtlc,
|
||||
"Fail htlc proposed by {id} which has redeem hash {rhash}",
|
||||
"Returns an empty result on success"
|
||||
};
|
||||
|
@ -111,6 +111,17 @@ $LCLI2 fulfillhtlc $ID1 $SECRET
|
||||
# We've transferred the HTLC amount to 2, who now has to pay fees.
|
||||
check_status 949999000 49000000 "" 0 1000000 ""
|
||||
|
||||
# A new one, at 10x the amount.
|
||||
$LCLI1 newhtlc $ID2 10000000 $EXPIRY $RHASH
|
||||
|
||||
# Check channel status
|
||||
check_status 939999000 49000000 '{ "msatoshis" : 10000000, "expiry" : { "second" : '$EXPIRY' }, "rhash" : "'$RHASH'" } ' 0 1000000 ""
|
||||
|
||||
$LCLI2 failhtlc $ID1 $RHASH
|
||||
|
||||
# Back to how we were before.
|
||||
check_status 949999000 49000000 "" 0 1000000 ""
|
||||
|
||||
sleep 1
|
||||
|
||||
$LCLI1 stop
|
||||
|
Loading…
Reference in New Issue
Block a user