Browse Source

channeld: get the onionreply back from lightningd for failed htlcs.

Instead of making it ourselves, lightningd does it.  Now we only have
two cases of failed htlcs: completely malformed (BADONION), and with
an already-wrapped onion reply to send.

This makes channeld's job much simpler.

Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
travis-debug
Rusty Russell 5 years ago
parent
commit
ed839bfda0
  1. 3
      channeld/channel_wire.csv
  2. 357
      channeld/channeld.c
  3. 21
      channeld/channeld_htlc.h
  4. 61
      channeld/full_channel.c
  5. 6
      channeld/full_channel.h
  6. 4
      channeld/test/run-full_channel.c
  7. 42
      common/htlc_wire.c
  8. 16
      common/htlc_wire.h
  9. 3
      devtools/mkcommit.c
  10. 2
      hsmd/hsmd.c
  11. 3
      lightningd/channel_control.c
  12. 2
      lightningd/htlc_end.h
  13. 318
      lightningd/peer_htlcs.c
  14. 86
      wallet/test/run-wallet.c

3
channeld/channel_wire.csv

@ -49,7 +49,6 @@ msgdata,channel_init,num_failed_in,u16,
msgdata,channel_init,failed_in,failed_htlc,num_failed_in
msgdata,channel_init,num_failed_out,u16,
msgdata,channel_init,failed_out,u64,num_failed_out
msgdata,channel_init,failheight,u32,
msgdata,channel_init,local_funding_locked,bool,
msgdata,channel_init,remote_funding_locked,bool,
msgdata,channel_init,funding_short_id,short_channel_id,
@ -100,7 +99,6 @@ msgdata,channel_fulfill_htlc,fulfilled_htlc,fulfilled_htlc,
# Main daemon says HTLC failed
msgtype,channel_fail_htlc,1006
msgdata,channel_fail_htlc,failed_htlc,failed_htlc,
msgdata,channel_fail_htlc,failheight,u32,
# When we receive funding_locked.
msgtype,channel_got_funding_locked,1019
@ -130,7 +128,6 @@ msgdata,channel_got_commitsig,htlc_signature,secp256k1_ecdsa_signature,num_htlcs
# RCVD_ADD_COMMIT: we're now committed to their new offered HTLCs.
msgdata,channel_got_commitsig,num_added,u16,
msgdata,channel_got_commitsig,added,added_htlc,num_added
msgdata,channel_got_commitsig,shared_secret,secret,num_added
# RCVD_REMOVE_COMMIT: we're now no longer committed to these HTLCs.
msgdata,channel_got_commitsig,num_fulfilled,u16,
msgdata,channel_got_commitsig,fulfilled,fulfilled_htlc,num_fulfilled

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

357
channeld/channeld.c

@ -581,43 +581,6 @@ static void handle_peer_announcement_signatures(struct peer *peer, const u8 *msg
channel_announcement_negotiate(peer);
}
static struct secret *get_shared_secret(const tal_t *ctx,
const struct htlc *htlc,
enum onion_type *why_bad,
struct sha256 *next_onion_sha)
{
struct onionpacket op;
struct secret *secret = tal(ctx, struct secret);
const u8 *msg;
struct route_step *rs;
/* We unwrap the onion now. */
*why_bad = parse_onionpacket(htlc->routing, TOTAL_PACKET_SIZE, &op);
if (*why_bad != 0)
return tal_free(secret);
/* Because wire takes struct pubkey. */
msg = hsm_req(tmpctx, towire_hsm_ecdh_req(tmpctx, &op.ephemeralkey));
if (!fromwire_hsm_ecdh_resp(msg, secret))
status_failed(STATUS_FAIL_HSM_IO, "Reading ecdh response");
/* We make sure we can parse onion packet, so we know if shared secret
* is actually valid (this checks hmac). */
rs = process_onionpacket(tmpctx, &op, secret,
htlc->rhash.u.u8,
sizeof(htlc->rhash));
if (!rs) {
*why_bad = WIRE_INVALID_ONION_HMAC;
return tal_free(secret);
}
/* Calculate sha256 we'll hand to next peer, in case they complain. */
msg = serialize_onionpacket(tmpctx, rs->next);
sha256(next_onion_sha, msg, tal_bytelen(msg));
return secret;
}
static void handle_peer_add_htlc(struct peer *peer, const u8 *msg)
{
struct channel_id channel_id;
@ -644,12 +607,6 @@ static void handle_peer_add_htlc(struct peer *peer, const u8 *msg)
&peer->channel_id,
"Bad peer_add_htlc: %s",
channel_add_err_name(add_err));
/* If this is wrong, we don't complain yet; when it's confirmed we'll
* send it to the master which handles all HTLC failures. */
htlc->shared_secret = get_shared_secret(htlc, htlc,
&htlc->why_bad_onion,
&htlc->next_onion_sha);
}
static void handle_peer_feechange(struct peer *peer, const u8 *msg)
@ -815,166 +772,6 @@ static u8 *master_wait_sync_reply(const tal_t *ctx,
return reply;
}
static u8 *gossipd_wait_sync_reply(const tal_t *ctx,
struct peer *peer, const u8 *msg,
enum gossip_peerd_wire_type replytype)
{
/* We can forward gossip packets while waiting for our reply. */
u8 *reply;
status_debug("Sending gossipd %u", fromwire_peektype(msg));
wire_sync_write(peer->pps->gossip_fd, msg);
status_debug("... , awaiting %u", replytype);
for (;;) {
int type;
reply = wire_sync_read(tmpctx, peer->pps->gossip_fd);
/* Gossipd hangs up on us to kill us when a new
* connection comes in. */
if (!reply)
peer_failed_connection_lost();
type = fromwire_peektype(reply);
if (type == replytype) {
status_debug("Got it!");
break;
}
handle_gossip_msg(peer->pps, take(reply));
}
return reply;
}
static u8 *foreign_channel_update(const tal_t *ctx,
struct peer *peer,
const struct short_channel_id *scid)
{
u8 *msg, *update, *channel_update;
msg = towire_gossipd_get_update(NULL, scid);
msg = gossipd_wait_sync_reply(tmpctx, peer, take(msg),
WIRE_GOSSIPD_GET_UPDATE_REPLY);
if (!fromwire_gossipd_get_update_reply(ctx, msg, &update))
status_failed(STATUS_FAIL_GOSSIP_IO,
"Invalid update reply");
/* Strip the type from the channel_update. Due to the specification
* being underspecified, some implementations skipped the type
* prefix. Since we are in the minority we adapt (See #1730 and
* lightningnetwork/lnd#1599 for details). */
if (update && fromwire_peektype(update) == WIRE_CHANNEL_UPDATE) {
assert(tal_bytelen(update) > 2);
channel_update = tal_arr(ctx, u8, 0);
towire(&channel_update, update + 2, tal_bytelen(update) - 2);
tal_free(update);
return channel_update;
} else {
return update;
}
}
static u8 *make_failmsg(const tal_t *ctx,
struct peer *peer,
const struct htlc *htlc,
enum onion_type failcode,
const struct short_channel_id *scid,
const struct sha256 *sha256,
u32 failheight)
{
u8 *msg, *channel_update = NULL;
u32 cltv_expiry = abs_locktime_to_blocks(&htlc->expiry);
switch (failcode) {
case WIRE_INVALID_REALM:
msg = towire_invalid_realm(ctx);
goto done;
case WIRE_TEMPORARY_NODE_FAILURE:
msg = towire_temporary_node_failure(ctx);
goto done;
case WIRE_PERMANENT_NODE_FAILURE:
msg = towire_permanent_node_failure(ctx);
goto done;
case WIRE_REQUIRED_NODE_FEATURE_MISSING:
msg = towire_required_node_feature_missing(ctx);
goto done;
case WIRE_TEMPORARY_CHANNEL_FAILURE:
channel_update = foreign_channel_update(ctx, peer, scid);
msg = towire_temporary_channel_failure(ctx, channel_update);
goto done;
case WIRE_CHANNEL_DISABLED:
msg = towire_channel_disabled(ctx);
goto done;
case WIRE_PERMANENT_CHANNEL_FAILURE:
msg = towire_permanent_channel_failure(ctx);
goto done;
case WIRE_REQUIRED_CHANNEL_FEATURE_MISSING:
msg = towire_required_channel_feature_missing(ctx);
goto done;
case WIRE_UNKNOWN_NEXT_PEER:
msg = towire_unknown_next_peer(ctx);
goto done;
case WIRE_AMOUNT_BELOW_MINIMUM:
channel_update = foreign_channel_update(ctx, peer, scid);
msg = towire_amount_below_minimum(ctx, htlc->amount,
channel_update);
goto done;
case WIRE_FEE_INSUFFICIENT:
channel_update = foreign_channel_update(ctx, peer, scid);
msg = towire_fee_insufficient(ctx, htlc->amount,
channel_update);
goto done;
case WIRE_INCORRECT_CLTV_EXPIRY:
channel_update = foreign_channel_update(ctx, peer, scid);
msg = towire_incorrect_cltv_expiry(ctx, cltv_expiry,
channel_update);
goto done;
case WIRE_EXPIRY_TOO_SOON:
channel_update = foreign_channel_update(ctx, peer, scid);
msg = towire_expiry_too_soon(ctx, channel_update);
goto done;
case WIRE_EXPIRY_TOO_FAR:
msg = towire_expiry_too_far(ctx);
goto done;
case WIRE_INCORRECT_OR_UNKNOWN_PAYMENT_DETAILS:
assert(failheight);
msg = towire_incorrect_or_unknown_payment_details(
ctx, htlc->amount, failheight);
goto done;
case WIRE_FINAL_INCORRECT_CLTV_EXPIRY:
msg = towire_final_incorrect_cltv_expiry(ctx, cltv_expiry);
goto done;
case WIRE_FINAL_INCORRECT_HTLC_AMOUNT:
msg = towire_final_incorrect_htlc_amount(ctx, htlc->amount);
goto done;
case WIRE_INVALID_ONION_VERSION:
msg = towire_invalid_onion_version(ctx, sha256);
goto done;
case WIRE_INVALID_ONION_HMAC:
msg = towire_invalid_onion_hmac(ctx, sha256);
goto done;
case WIRE_INVALID_ONION_KEY:
msg = towire_invalid_onion_key(ctx, sha256);
goto done;
case WIRE_INVALID_ONION_PAYLOAD:
/* FIXME: wire this into tlv parser somehow. */
msg = towire_invalid_onion_payload(ctx, 0, 0);
goto done;
case WIRE_MPP_TIMEOUT:
msg = towire_mpp_timeout(ctx);
goto done;
}
status_failed(STATUS_FAIL_INTERNAL_ERROR,
"Asked to create failmsg %u (%s)",
failcode, onion_type_name(failcode));
done:
tal_free(channel_update);
return msg;
}
/* Returns HTLC sigs, sets commit_sig */
static secp256k1_ecdsa_signature *calc_commitsigs(const tal_t *ctx,
const struct peer *peer,
@ -1268,12 +1065,10 @@ static void marshall_htlc_info(const tal_t *ctx,
struct changed_htlc **changed,
struct fulfilled_htlc **fulfilled,
const struct failed_htlc ***failed,
struct added_htlc **added,
struct secret **shared_secret)
struct added_htlc **added)
{
*changed = tal_arr(ctx, struct changed_htlc, 0);
*added = tal_arr(ctx, struct added_htlc, 0);
*shared_secret = tal_arr(ctx, struct secret, 0);
*failed = tal_arr(ctx, const struct failed_htlc *, 0);
*fulfilled = tal_arr(ctx, struct fulfilled_htlc, 0);
@ -1281,7 +1076,6 @@ static void marshall_htlc_info(const tal_t *ctx,
const struct htlc *htlc = changed_htlcs[i];
if (htlc->state == RCVD_ADD_COMMIT) {
struct added_htlc a;
struct secret s;
a.id = htlc->id;
a.amount = htlc->amount;
@ -1290,31 +1084,17 @@ static void marshall_htlc_info(const tal_t *ctx,
memcpy(a.onion_routing_packet,
htlc->routing,
sizeof(a.onion_routing_packet));
/* Invalid shared secret gets set to all-zero: our
* code generator can't make arrays of optional values */
if (!htlc->shared_secret)
memset(&s, 0, sizeof(s));
else
s = *htlc->shared_secret;
tal_arr_expand(added, a);
tal_arr_expand(shared_secret, s);
} else if (htlc->state == RCVD_REMOVE_COMMIT) {
if (htlc->r) {
struct fulfilled_htlc f;
assert(!htlc->fail && !htlc->failcode);
assert(!htlc->failed);
f.id = htlc->id;
f.payment_preimage = *htlc->r;
tal_arr_expand(fulfilled, f);
} else {
struct failed_htlc *f;
assert(htlc->fail || htlc->failcode);
f = tal(*failed, struct failed_htlc);
f->id = htlc->id;
f->failcode = htlc->failcode;
f->failreason = htlc->fail;
f->scid = cast_const(struct short_channel_id *,
htlc->failed_scid);
tal_arr_expand(failed, f);
assert(!htlc->r);
tal_arr_expand(failed, htlc->failed);
}
} else {
struct changed_htlc c;
@ -1338,7 +1118,6 @@ static void send_revocation(struct peer *peer,
struct fulfilled_htlc *fulfilled;
const struct failed_htlc **failed;
struct added_htlc *added;
struct secret *shared_secret;
const u8 *msg_for_master;
/* Marshall it now before channel_sending_revoke_and_ack changes htlcs */
@ -1348,8 +1127,7 @@ static void send_revocation(struct peer *peer,
&changed,
&fulfilled,
&failed,
&added,
&shared_secret);
&added);
/* Revoke previous commit, get new point. */
u8 *msg = make_revocation_msg(peer, peer->next_index[LOCAL]-1,
@ -1374,7 +1152,6 @@ static void send_revocation(struct peer *peer,
peer->channel->fee_states,
commit_sig, htlc_sigs,
added,
shared_secret,
fulfilled,
failed,
changed,
@ -1660,6 +1437,7 @@ static void handle_peer_fail_htlc(struct peer *peer, const u8 *msg)
enum channel_remove_err e;
u8 *reason;
struct htlc *htlc;
struct failed_htlc *f;
/* reason is not an onionreply because spec doesn't know about that */
if (!fromwire_update_fail_htlc(msg, msg,
@ -1672,10 +1450,10 @@ static void handle_peer_fail_htlc(struct peer *peer, const u8 *msg)
e = channel_fail_htlc(peer->channel, LOCAL, id, &htlc);
switch (e) {
case CHANNEL_ERR_REMOVE_OK: {
/* Save reason for when we tell master. */
struct onionreply *r = tal(htlc, struct onionreply);
r->contents = tal_steal(r, reason);
htlc->fail = r;
htlc->failed = f = tal(htlc, struct failed_htlc);
f->id = id;
f->sha256_of_onion = NULL;
f->onion = new_onionreply(f, take(reason));
start_commit_timer(peer);
return;
}
@ -1698,9 +1476,10 @@ static void handle_peer_fail_malformed_htlc(struct peer *peer, const u8 *msg)
struct channel_id channel_id;
u64 id;
enum channel_remove_err e;
struct sha256 sha256_of_onion, our_sha256_of_onion;
struct sha256 sha256_of_onion;
u16 failure_code;
struct htlc *htlc;
struct failed_htlc *f;
if (!fromwire_update_fail_malformed_htlc(msg, &channel_id, &id,
&sha256_of_onion,
@ -1724,35 +1503,14 @@ static void handle_peer_fail_malformed_htlc(struct peer *peer, const u8 *msg)
failure_code);
}
/* BOLT #2:
*
* - if the `sha256_of_onion` in `update_fail_malformed_htlc`
* doesn't match the onion it sent:
* - MAY retry or choose an alternate error response.
*/
htlc = channel_get_htlc(peer->channel, LOCAL, id);
sha256(&our_sha256_of_onion, htlc->routing, tal_count(htlc->routing));
if (!sha256_eq(&sha256_of_onion, &our_sha256_of_onion))
status_unusual("update_fail_malformed_htlc for bad onion"
" for htlc with id %"PRIu64".", id);
/* We only handle these cases in make_failmsg, so convert any
* (future?) unknown one. */
if (failure_code != WIRE_INVALID_ONION_VERSION
&& failure_code != WIRE_INVALID_ONION_HMAC
&& failure_code != WIRE_INVALID_ONION_KEY) {
status_unusual("Unknown update_fail_malformed_htlc code %u:"
" sending temporary_channel_failure",
failure_code);
failure_code = WIRE_TEMPORARY_CHANNEL_FAILURE;
}
e = channel_fail_htlc(peer->channel, LOCAL, id, &htlc);
switch (e) {
case CHANNEL_ERR_REMOVE_OK:
/* This is the only case where we set failcode for a non-local
* failure; in a way, it is, since we have to report it. */
htlc->failcode = failure_code;
htlc->failed = f = tal(htlc, struct failed_htlc);
f->id = id;
f->onion = NULL;
f->sha256_of_onion = tal_dup(f, struct sha256, &sha256_of_onion);
f->badonion = failure_code;
start_commit_timer(peer);
return;
case CHANNEL_ERR_NO_SUCH_ID:
@ -1956,39 +1714,18 @@ static void send_fail_or_fulfill(struct peer *peer, const struct htlc *h)
{
u8 *msg;
/* Note that if h->shared_secret is NULL, it means that we knew
* this HTLC was invalid, but we still needed to hand it to lightningd
* for the db, etc. So in that case, we use our own saved failcode.
*
* This also lets us distinguish between "we can't decode onion" and
* "next hop said it can't decode onion". That second case is the
* only case where we use a failcode for a non-local error. */
/* Malformed: use special reply since we can't onion. */
if (!h->shared_secret) {
struct sha256 sha256_of_onion;
sha256(&sha256_of_onion, h->routing, tal_count(h->routing));
msg = towire_update_fail_malformed_htlc(NULL, &peer->channel_id,
h->id, &sha256_of_onion,
h->why_bad_onion);
} else if (h->failcode || h->fail) {
const struct onionreply *onion;
if (h->failcode) {
/* Local failure, make a message. */
u8 *failmsg = make_failmsg(tmpctx, peer, h, h->failcode,
h->failed_scid,
&h->next_onion_sha,
h->failblock);
onion = create_onionreply(tmpctx, h->shared_secret,
failmsg);
} else /* Remote failure, just forward. */
onion = h->fail;
/* Now we wrap, just before sending out. */
msg = towire_update_fail_htlc(peer, &peer->channel_id, h->id,
wrap_onionreply(tmpctx,
h->shared_secret,
onion)->contents);
if (h->failed) {
const struct failed_htlc *f = h->failed;
if (f->sha256_of_onion) {
msg = towire_update_fail_malformed_htlc(NULL,
&peer->channel_id,
h->id,
f->sha256_of_onion,
f->badonion);
} else {
msg = towire_update_fail_htlc(peer, &peer->channel_id, h->id,
f->onion->contents);
}
} else if (h->r) {
msg = towire_update_fulfill_htlc(NULL, &peer->channel_id, h->id,
h->r);
@ -2805,18 +2542,14 @@ static void handle_fail(struct peer *peer, const u8 *inmsg)
struct failed_htlc *failed_htlc;
enum channel_remove_err e;
struct htlc *h;
u32 failheight;
if (!fromwire_channel_fail_htlc(inmsg, inmsg, &failed_htlc, &failheight))
if (!fromwire_channel_fail_htlc(inmsg, inmsg, &failed_htlc))
master_badmsg(WIRE_CHANNEL_FAIL_HTLC, inmsg);
e = channel_fail_htlc(peer->channel, REMOTE, failed_htlc->id, &h);
switch (e) {
case CHANNEL_ERR_REMOVE_OK:
h->failcode = failed_htlc->failcode;
h->fail = tal_steal(h, failed_htlc->failreason);
h->failed_scid = tal_steal(h, failed_htlc->scid);
h->failblock = failheight;
h->failed = tal_steal(h, failed_htlc);
send_fail_or_fulfill(peer, h);
start_commit_timer(peer);
return;
@ -2973,24 +2706,6 @@ static void req_in(struct peer *peer, const u8 *msg)
master_badmsg(-1, msg);
}
static void init_shared_secrets(struct channel *channel,
const struct added_htlc *htlcs,
const enum htlc_state *hstates)
{
for (size_t i = 0; i < tal_count(htlcs); i++) {
struct htlc *htlc;
/* We only derive this for HTLCs *they* added. */
if (htlc_state_owner(hstates[i]) != REMOTE)
continue;
htlc = channel_get_htlc(channel, REMOTE, htlcs[i].id);
htlc->shared_secret = get_shared_secret(htlc, htlc,
&htlc->why_bad_onion,
&htlc->next_onion_sha);
}
}
/* We do this synchronously. */
static void init_channel(struct peer *peer)
{
@ -3012,7 +2727,7 @@ static void init_channel(struct peer *peer)
u8 *funding_signed;
const u8 *msg;
struct fee_states *fee_states;
u32 minimum_depth, failheight;
u32 minimum_depth;
struct secret last_remote_per_commit_secret;
secp256k1_ecdsa_signature *remote_ann_node_sig;
secp256k1_ecdsa_signature *remote_ann_bitcoin_sig;
@ -3062,7 +2777,6 @@ static void init_channel(struct peer *peer)
&fulfilled_sides,
&failed_in,
&failed_out,
&failheight,
&peer->funding_locked[LOCAL],
&peer->funding_locked[REMOTE],
&peer->short_channel_ids[LOCAL],
@ -3144,15 +2858,10 @@ static void init_channel(struct peer *peer)
fulfilled, fulfilled_sides,
cast_const2(const struct failed_htlc **,
failed_in),
failed_out,
failheight))
failed_out))
status_failed(STATUS_FAIL_INTERNAL_ERROR,
"Could not restore HTLCs");
/* We derive shared secrets for each remote HTLC, so we can
* create error packet if necessary. */
init_shared_secrets(peer->channel, htlcs, hstates);
/* We don't need these any more, so free them. */
tal_free(htlcs);
tal_free(hstates);

21
channeld/channeld_htlc.h

@ -22,26 +22,11 @@ struct htlc {
/* The preimage which hashes to rhash (if known) */
struct preimage *r;
/* The routing shared secret (only for incoming) */
struct secret *shared_secret;
/* If incoming HTLC has shared_secret, this is which BADONION error */
enum onion_type why_bad_onion;
/* sha256 of next_onion, in case peer says it was malformed. */
struct sha256 next_onion_sha;
/* If they fail the HTLC, we store why here. */
const struct failed_htlc *failed;
/* FIXME: We could union these together: */
/* Routing information sent with this HTLC. */
/* Routing information sent with this HTLC (outgoing only). */
const u8 *routing;
/* Failure message we received or generated. */
const struct onionreply *fail;
/* For a local failure, we might have to generate fail ourselves
* (or, if BADONION we send a update_fail_malformed_htlc). */
enum onion_type failcode;
/* If failcode & UPDATE, this is channel which failed. Otherwise NULL. */
const struct short_channel_id *failed_scid;
/* Block height it failed at */
u32 failblock;
};
static inline bool htlc_has(const struct htlc *h, int flag)

61
channeld/full_channel.c

@ -149,9 +149,8 @@ static void dump_htlc(const struct htlc *htlc, const char *prefix)
htlc->id,
htlc_state_name(htlc->state),
htlc_state_name(remote_state),
htlc->r ? "FULFILLED" : htlc->fail ? "FAILED" :
htlc->failcode
? tal_fmt(tmpctx, "FAILCODE:%u", htlc->failcode) : "");
htlc->r ? "FULFILLED" : htlc->failed ? "FAILED"
: "");
}
void dump_htlcs(const struct channel *channel, const char *prefix)
@ -466,7 +465,6 @@ static enum channel_add_err add_htlc(struct channel *channel,
htlc->id = id;
htlc->amount = amount;
htlc->state = state;
htlc->shared_secret = NULL;
/* FIXME: Change expiry to simple u32 */
@ -483,9 +481,7 @@ static enum channel_add_err add_htlc(struct channel *channel,
}
htlc->rhash = *payment_hash;
htlc->fail = NULL;
htlc->failcode = 0;
htlc->failed_scid = NULL;
htlc->failed = NULL;
htlc->r = NULL;
htlc->routing = tal_dup_arr(htlc, u8, routing, TOTAL_PACKET_SIZE, 0);
@ -1168,7 +1164,7 @@ static bool adjust_balance(struct balance view_owed[NUM_SIDES][NUM_SIDES],
if (htlc_has(htlc, HTLC_FLAG(side, HTLC_F_COMMITTED)))
continue;
if (!htlc->fail && !htlc->failcode && !htlc->r) {
if (!htlc->failed && !htlc->r) {
status_broken("%s HTLC %"PRIu64
" %s neither fail nor fulfill?",
htlc_state_owner(htlc->state) == LOCAL
@ -1189,8 +1185,7 @@ bool channel_force_htlcs(struct channel *channel,
const struct fulfilled_htlc *fulfilled,
const enum side *fulfilled_sides,
const struct failed_htlc **failed_in,
const u64 *failed_out,
u32 failheight)
const u64 *failed_out)
{
size_t i;
struct htlc *htlc;
@ -1253,18 +1248,12 @@ bool channel_force_htlcs(struct channel *channel,
fulfilled[i].id);
return false;
}
if (htlc->fail) {
if (htlc->failed) {
status_broken("Fulfill %s HTLC %"PRIu64" already failed",
fulfilled_sides[i] == LOCAL ? "out" : "in",
fulfilled[i].id);
return false;
}
if (htlc->failcode) {
status_broken("Fulfill %s HTLC %"PRIu64" already fail %u",
fulfilled_sides[i] == LOCAL ? "out" : "in",
fulfilled[i].id, htlc->failcode);
return false;
}
if (!htlc_has(htlc, HTLC_REMOVING)) {
status_broken("Fulfill %s HTLC %"PRIu64" state %s",
fulfilled_sides[i] == LOCAL ? "out" : "in",
@ -1289,37 +1278,12 @@ bool channel_force_htlcs(struct channel *channel,
failed_in[i]->id);
return false;
}
if (htlc->fail) {
if (htlc->failed) {
status_broken("Fail in HTLC %"PRIu64" already failed_in",
failed_in[i]->id);
return false;
}
if (htlc->failcode) {
status_broken("Fail in HTLC %"PRIu64" already fail %u",
failed_in[i]->id, htlc->failcode);
return false;
}
if (!htlc_has(htlc, HTLC_REMOVING)) {
status_broken("Fail in HTLC %"PRIu64" state %s",
failed_in[i]->id,
htlc_state_name(htlc->state));
return false;
}
htlc->failcode = failed_in[i]->failcode;
/* We assume they all failed_in at the same height, which is
* not necessarily true in case of restart. But it's only
* a hint. */
htlc->failblock = failheight;
if (failed_in[i]->failreason)
htlc->fail = dup_onionreply(htlc, failed_in[i]->failreason);
else
htlc->fail = NULL;
if (failed_in[i]->scid)
htlc->failed_scid = tal_dup(htlc,
struct short_channel_id,
failed_in[i]->scid);
else
htlc->failed_scid = NULL;
htlc->failed = tal_steal(htlc, failed_in[i]);
}
for (i = 0; i < tal_count(failed_out); i++) {
@ -1336,16 +1300,11 @@ bool channel_force_htlcs(struct channel *channel,
failed_out[i]);
return false;
}
if (htlc->fail) {
if (htlc->failed) {
status_broken("Fail out HTLC %"PRIu64" already failed",
failed_out[i]);
return false;
}
if (htlc->failcode) {
status_broken("Fail out HTLC %"PRIu64" already fail %u",
failed_out[i], htlc->failcode);
return false;
}
if (!htlc_has(htlc, HTLC_REMOVING)) {
status_broken("Fail out HTLC %"PRIu64" state %s",
failed_out[i],
@ -1355,7 +1314,7 @@ bool channel_force_htlcs(struct channel *channel,
/* Now, we don't really care why our htlcs failed: lightningd
* already knows. Just mark it failed using anything. */
htlc->fail = tal(htlc, struct onionreply);
htlc->failed = tal(htlc, struct failed_htlc);
}
/* You'd think, since we traverse HTLCs in ID order, this would never

6
channeld/full_channel.h

@ -231,9 +231,8 @@ size_t num_channel_htlcs(const struct channel *channel);
* @hstates: the states for the htlcs (tal_arr of same size)
* @fulfilled: htlcs of those which are fulfilled
* @fulfilled_sides: sides for ids in @fulfilled
* @failed_in: incoming htlcs which are failed
* @failed_in: incoming htlcs which are failed (stolen!)
* @failed_out: outgoing htlc ids which are failed
* @failheight: block number which htlcs failed at.
*
* This is used for restoring a channel state.
*/
@ -243,8 +242,7 @@ bool channel_force_htlcs(struct channel *channel,
const struct fulfilled_htlc *fulfilled,
const enum side *fulfilled_sides,
const struct failed_htlc **failed_in,
const u64 *failed_out,
u32 failheight);
const u64 *failed_out);
/**
* dump_htlcs: debugging dump of all HTLCs

4
channeld/test/run-full_channel.c

@ -21,10 +21,6 @@ size_t bigsize_get(const u8 *p UNNEEDED, size_t max UNNEEDED, bigsize_t *val UNN
/* Generated stub for bigsize_put */
size_t bigsize_put(u8 buf[BIGSIZE_MAX_LEN] UNNEEDED, bigsize_t v UNNEEDED)
{ fprintf(stderr, "bigsize_put called!\n"); abort(); }
/* Generated stub for dup_onionreply */
struct onionreply *dup_onionreply(const tal_t *ctx UNNEEDED,
const struct onionreply *r TAKES UNNEEDED)
{ fprintf(stderr, "dup_onionreply called!\n"); abort(); }
/* Generated stub for memleak_add_helper_ */
void memleak_add_helper_(const tal_t *p UNNEEDED, void (*cb)(struct htable *memtable UNNEEDED,
const tal_t *)){ }

42
common/htlc_wire.c

@ -26,20 +26,16 @@ void towire_fulfilled_htlc(u8 **pptr, const struct fulfilled_htlc *fulfilled)
void towire_failed_htlc(u8 **pptr, const struct failed_htlc *failed)
{
/* Only one can be set. */
assert(failed->failcode || failed->failreason);
assert(!failed->failcode || !failed->failreason);
towire_u64(pptr, failed->id);
towire_u16(pptr, failed->failcode);
if (failed->failcode & UPDATE) {
assert(!failed->failreason);
towire_short_channel_id(pptr, failed->scid);
/* Only one can be set. */
if (failed->sha256_of_onion) {
assert(!failed->onion);
assert(failed->badonion & BADONION);
towire_u16(pptr, failed->badonion);
towire_sha256(pptr, failed->sha256_of_onion);
} else {
assert(!failed->scid);
if (!failed->failcode) {
assert(failed->failreason);
towire_onionreply(pptr, failed->failreason);
}
towire_u16(pptr, 0);
towire_onionreply(pptr, failed->onion);
}
}
@ -93,20 +89,20 @@ void fromwire_fulfilled_htlc(const u8 **cursor, size_t *max,
struct failed_htlc *fromwire_failed_htlc(const tal_t *ctx, const u8 **cursor, size_t *max)
{
struct failed_htlc *failed = tal(ctx, struct failed_htlc);
enum onion_type badonion;
failed->id = fromwire_u64(cursor, max);
failed->failcode = fromwire_u16(cursor, max);
if (failed->failcode == 0) {
failed->scid = NULL;
failed->failreason = fromwire_onionreply(failed, cursor, max);
badonion = fromwire_u16(cursor, max);
if (badonion) {
failed->onion = NULL;
if (!(badonion & BADONION))
return tal_free(failed);
failed->badonion = badonion;
failed->sha256_of_onion = tal(failed, struct sha256);
fromwire_sha256(cursor, max, failed->sha256_of_onion);
} else {
failed->failreason = NULL;
if (failed->failcode & UPDATE) {
failed->scid = tal(failed, struct short_channel_id);
fromwire_short_channel_id(cursor, max, failed->scid);
} else {
failed->scid = NULL;
}
failed->sha256_of_onion = NULL;
failed->onion = fromwire_onionreply(failed, cursor, max);
}
return failed;

16
common/htlc_wire.h

@ -27,11 +27,17 @@ struct fulfilled_htlc {
struct failed_htlc {
u64 id;
/* Either this is 0 and failreason non-NULL, or vice versa. */
enum onion_type failcode;
const struct onionreply *failreason;
/* Non-NULL if failcode & UPDATE */
struct short_channel_id *scid;
/* If this is non-NULL, then the onion was malformed and this is the
* SHA256 of what we got: send update_fail_malformed_htlc, using
* failcode. */
struct sha256 *sha256_of_onion;
/* WIRE_INVALID_ONION_VERSION, WIRE_INVALID_ONION_KEY or
* WIRE_INVALID_ONION_HMAC (ie. must have BADONION) */
enum onion_type badonion;
/* Otherwise, this is the onion ready to send to them. */
const struct onionreply *onion;
};
struct changed_htlc {

3
devtools/mkcommit.c

@ -393,8 +393,7 @@ int main(int argc, char *argv[])
option_static_remotekey,
fee_payer);
if (!channel_force_htlcs(channel, htlcs, hstates, NULL, NULL, NULL, NULL,
0))
if (!channel_force_htlcs(channel, htlcs, hstates, NULL, NULL, NULL, NULL))
errx(1, "Cannot add HTLCs");
u8 *funding_wscript = bitcoin_redeem_2of2(NULL,

2
hsmd/hsmd.c

@ -2055,7 +2055,7 @@ int main(int argc, char *argv[])
status_setup_async(status_conn);
uintmap_init(&clients);
master = new_client(NULL, NULL, NULL, 0, HSM_CAP_MASTER | HSM_CAP_SIGN_GOSSIP,
master = new_client(NULL, NULL, NULL, 0, HSM_CAP_MASTER | HSM_CAP_SIGN_GOSSIP | HSM_CAP_ECDH,
REQ_FD);
/* First client == lightningd. */

3
lightningd/channel_control.c

@ -493,9 +493,6 @@ void peer_start_channeld(struct channel *channel,
htlcs, htlc_states,
fulfilled_htlcs, fulfilled_sides,
failed_in, failed_out,
/* This is an approximation, but failing
* on restart is a corner case */
get_block_height(ld->topology),
channel->scid != NULL,
channel->remote_funding_locked,
&scid,

2
lightningd/htlc_end.h

@ -36,6 +36,7 @@ struct htlc_in {
/* Shared secret for us to send any failure message (NULL if malformed) */
struct secret *shared_secret;
/* FIXME: Use failed_htlc here */
/* If a local error, this is non-zero. */
enum onion_type failcode;
@ -68,6 +69,7 @@ struct htlc_out {
/* Onion information */
u8 onion_routing_packet[TOTAL_PACKET_SIZE];
/* FIXME: Use failed_htlc here */
/* If a local error, this is non-zero. */
enum onion_type failcode;

318
lightningd/peer_htlcs.c

@ -16,6 +16,7 @@
#include <common/timeout.h>
#include <common/utils.h>
#include <gossipd/gen_gossip_wire.h>
#include <hsmd/gen_hsm_wire.h>
#include <lightningd/chaintopology.h>
#include <lightningd/htlc_end.h>
#include <lightningd/htlc_set.h>
@ -33,6 +34,7 @@
#include <onchaind/onchain_wire.h>
#include <wallet/wallet.h>
#include <wire/gen_onion_wire.h>
#include <wire/wire_sync.h>
#ifndef SUPERVERBOSE
#define SUPERVERBOSE(...)
@ -95,12 +97,134 @@ static bool htlc_out_update_state(struct channel *channel,
return true;
}
/* FIXME: Do this direclty in callers! */
static u8 *make_failmsg(const tal_t *ctx,
const struct htlc_in *hin,
enum onion_type failcode,
const u8 *channel_update,
const struct sha256 *sha256,
u32 failheight)
{
u8 *msg;
switch (failcode) {
case WIRE_INVALID_REALM:
msg = towire_invalid_realm(ctx);
goto done;
case WIRE_TEMPORARY_NODE_FAILURE:
msg = towire_temporary_node_failure(ctx);
goto done;
case WIRE_PERMANENT_NODE_FAILURE:
msg = towire_permanent_node_failure(ctx);
goto done;
case WIRE_REQUIRED_NODE_FEATURE_MISSING:
msg = towire_required_node_feature_missing(ctx);
goto done;
case WIRE_TEMPORARY_CHANNEL_FAILURE:
msg = towire_temporary_channel_failure(ctx, channel_update);
goto done;
case WIRE_CHANNEL_DISABLED:
msg = towire_channel_disabled(ctx);
goto done;
case WIRE_PERMANENT_CHANNEL_FAILURE:
msg = towire_permanent_channel_failure(ctx);
goto done;
case WIRE_REQUIRED_CHANNEL_FEATURE_MISSING:
msg = towire_required_channel_feature_missing(ctx);
goto done;
case WIRE_UNKNOWN_NEXT_PEER:
msg = towire_unknown_next_peer(ctx);
goto done;
case WIRE_AMOUNT_BELOW_MINIMUM:
msg = towire_amount_below_minimum(ctx, hin->msat,
channel_update);
goto done;
case WIRE_FEE_INSUFFICIENT:
msg = towire_fee_insufficient(ctx, hin->msat,
channel_update);
goto done;
case WIRE_INCORRECT_CLTV_EXPIRY:
msg = towire_incorrect_cltv_expiry(ctx, hin->cltv_expiry,
channel_update);
goto done;
case WIRE_EXPIRY_TOO_SOON:
msg = towire_expiry_too_soon(ctx, channel_update);
goto done;
case WIRE_EXPIRY_TOO_FAR:
msg = towire_expiry_too_far(ctx);
goto done;
case WIRE_INCORRECT_OR_UNKNOWN_PAYMENT_DETAILS:
assert(failheight);
msg = towire_incorrect_or_unknown_payment_details(
ctx, hin->msat, failheight);
goto done;
case WIRE_FINAL_INCORRECT_CLTV_EXPIRY:
msg = towire_final_incorrect_cltv_expiry(ctx, hin->cltv_expiry);
goto done;
case WIRE_FINAL_INCORRECT_HTLC_AMOUNT:
msg = towire_final_incorrect_htlc_amount(ctx, hin->msat);
goto done;
case WIRE_INVALID_ONION_VERSION:
msg = towire_invalid_onion_version(ctx, sha256);
goto done;
case WIRE_INVALID_ONION_HMAC:
msg = towire_invalid_onion_hmac(ctx, sha256);
goto done;
case WIRE_INVALID_ONION_KEY:
msg = towire_invalid_onion_key(ctx, sha256);
goto done;
case WIRE_INVALID_ONION_PAYLOAD:
/* FIXME: wire this into tlv parser somehow. */
msg = towire_invalid_onion_payload(ctx, 0, 0);
goto done;
case WIRE_MPP_TIMEOUT:
msg = towire_mpp_timeout(ctx);
goto done;
}
fatal("Asked to create failmsg %u (%s)",
failcode, onion_type_name(failcode));
done:
return msg;
}
static struct failed_htlc *mk_failed_htlc(const tal_t *ctx,
const struct htlc_in *hin,
enum onion_type failcode,
const struct onionreply *failonion,
const u8 *channel_update)
{
struct failed_htlc *f = tal(ctx, struct failed_htlc);
f->id = hin->key.id;
if (failcode & BADONION) {
f->onion = NULL;
f->badonion = failcode;
f->sha256_of_onion = tal(f, struct sha256);
sha256(f->sha256_of_onion, hin->onion_routing_packet,
sizeof(hin->onion_routing_packet));
} else {
f->sha256_of_onion = NULL;
if (!failonion) {
const u8 *failmsg = make_failmsg(tmpctx, hin, failcode, channel_update, NULL, get_block_height(hin->key.channel->owner->ld->topology));
failonion = create_onionreply(tmpctx, hin->shared_secret,
failmsg);
}
/* Wrap onion error */
f->onion = wrap_onionreply(tmpctx, hin->shared_secret, failonion);
}
return f;
}
static void fail_in_htlc(struct htlc_in *hin,
enum onion_type failcode,
const struct onionreply *failonion,
const struct short_channel_id *out_channelid)
const u8 *channel_update)
{
struct failed_htlc failed_htlc;
struct failed_htlc *failed_htlc;
assert(!hin->preimage);
assert(failcode || failonion);
@ -108,18 +232,6 @@ static void fail_in_htlc(struct htlc_in *hin,
if (failonion)
hin->failonion = dup_onionreply(hin, failonion);
/* We need this set, since we send it to channeld. */
if (hin->failcode & UPDATE) {
/* We don't save the outgoing channel which failed; probably
* not worth it for this corner case. So we can't set
* hin->failoutchannel to tell channeld what update to send,
* thus we turn those into a WIRE_TEMPORARY_NODE_FAILURE. */
if (!out_channelid)
hin->failcode = WIRE_TEMPORARY_NODE_FAILURE;
else
hin->failoutchannel = *out_channelid;
}
/* We update state now to signal it's in progress, for persistence. */
htlc_in_update_state(hin->key.channel, hin, SENT_REMOVE_HTLC);
htlc_in_check(hin, __func__);
@ -132,26 +244,20 @@ static void fail_in_htlc(struct htlc_in *hin,
if (channel_on_chain(hin->key.channel))
return;
failed_htlc.id = hin->key.id;
failed_htlc.failcode = hin->failcode;
failed_htlc.failreason = hin->failonion;
if (failed_htlc.failcode & UPDATE)
failed_htlc.scid = &hin->failoutchannel;
else
failed_htlc.scid = NULL;
failed_htlc = mk_failed_htlc(tmpctx, hin, failcode, failonion,
channel_update);
subd_send_msg(hin->key.channel->owner,
take(towire_channel_fail_htlc(NULL, &failed_htlc,
get_block_height(hin->key.channel->owner->ld->topology))));
take(towire_channel_fail_htlc(NULL, failed_htlc)));
}
/* This is used for cases where we can immediately fail the HTLC. */
static void local_fail_htlc(struct htlc_in *hin, enum onion_type failcode,
const struct short_channel_id *out_channel)
const u8 *out_channel_update)
{
log_info(hin->key.channel->log, "failed htlc %"PRIu64" code 0x%04x (%s)",
hin->key.id, failcode, onion_type_name(failcode));
fail_in_htlc(hin, failcode, NULL, out_channel);
fail_in_htlc(hin, failcode, NULL, out_channel_update);
}
void fail_htlc(struct htlc_in *hin, enum onion_type failcode)
@ -172,7 +278,7 @@ static void fail_out_htlc(struct htlc_out *hout, const char *localfail)
payment_failed(hout->key.channel->peer->ld, hout, localfail);
} else if (hout->in) {
fail_in_htlc(hout->in, hout->failcode, hout->failonion,
hout->key.channel->scid);
hout->key.channel->stripped_update);
}
}
@ -407,7 +513,7 @@ static void rcvd_htlc_reply(struct subd *subd, const u8 *msg, const int *fds UNU
} else if (hout->in) {
local_fail_htlc(hout->in, failure_code,
hout->key.channel->scid);
hout->key.channel->stripped_update);
/* here we haven't called connect_htlc_out(),
* so set htlc field with NULL */
@ -611,7 +717,7 @@ static void forward_htlc(struct htlc_in *hin,
return;
fail:
local_fail_htlc(hin, failcode, next->scid);
local_fail_htlc(hin, failcode, next->stripped_update);
wallet_forwarded_payment_add(ld->wallet,
hin, next->scid, hout,
FORWARD_LOCAL_FAILED,
@ -874,9 +980,8 @@ htlc_accepted_hook_callback(struct htlc_accepted_hook_payload *request,
failure_code = WIRE_TEMPORARY_NODE_FAILURE;
}
}
fail_in_htlc(hin, failure_code, NULL,
request->payload
? request->payload->forward_channel : NULL);
/* FIXME: Supply update in this case! */
fail_in_htlc(hin, failure_code, NULL, NULL);
break;
case htlc_accepted_resolve:
fulfill_htlc(hin, &payment_preimage);
@ -950,24 +1055,11 @@ static bool peer_accepted_htlc(struct channel *channel, u64 id,
* a subset of the cltv check done in handle_localpay and
* forward_htlc. */
/* Channeld sets this to NULL if couldn't parse onion */
if (!hin->shared_secret) {
*failcode = WIRE_INVALID_ONION_KEY;
goto out;
}
/* FIXME: Have channeld hand through just the route_step! */
/* channeld calls both parse_onionpacket and process_onionpacket,
* so they should succeed.. */
*failcode = parse_onionpacket(hin->onion_routing_packet,
sizeof(hin->onion_routing_packet),
&op);
if (*failcode != 0) {
channel_internal_error(channel,
"bad onion in got_revoke: %s",
tal_hexstr(channel, hin->onion_routing_packet,
sizeof(hin->onion_routing_packet)));
sizeof(hin->onion_routing_packet),
&op);
if (*failcode) {
/* Now we can fail it. */
return false;
}
@ -975,10 +1067,7 @@ static bool peer_accepted_htlc(struct channel *channel, u64 id,
hin->payment_hash.u.u8,
sizeof(hin->payment_hash));
if (!rs) {
channel_internal_error(channel,
"bad process_onionpacket in got_revoke: %s",
tal_hexstr(channel, hin->onion_routing_packet,
sizeof(hin->onion_routing_packet)));
*failcode = WIRE_INVALID_ONION_HMAC;
return false;
}
@ -994,7 +1083,6 @@ static bool peer_accepted_htlc(struct channel *channel, u64 id,
plugin_hook_call_htlc_accepted(ld, hook_payload, hook_payload);
/* Falling through here is ok, after all the HTLC locked */
*failcode = 0;
out:
log_debug(channel->log, "their htlc %"PRIu64" %s",
id, *failcode ? onion_type_name(*failcode) : "locked");
@ -1104,11 +1192,61 @@ static bool peer_failed_our_htlc(struct channel *channel,
if (!htlc_out_update_state(channel, hout, RCVD_REMOVE_COMMIT))
return false;
hout->failcode = failed->failcode;
if (!failed->failcode)
hout->failonion = dup_onionreply(hout, failed->failreason);
else
hout->failonion = NULL;
if (failed->sha256_of_onion) {
struct sha256 our_sha256_of_onion;
/* BOLT #2:
*
* - if the `sha256_of_onion` in `update_fail_malformed_htlc`
* doesn't match the onion it sent:
* - MAY retry or choose an alternate error response.
*/
sha256(&our_sha256_of_onion, hout->onion_routing_packet,
sizeof(hout->onion_routing_packet));
if (!sha256_eq(failed->sha256_of_onion, &our_sha256_of_onion))
log_unusual(channel->log,
"update_fail_malformed_htlc for bad onion"
" for htlc with id %"PRIu64".",
hout->key.id);
/* We only handle these cases in make_failmsg, so convert any
* (future?) unknown one. */
if (failed->badonion != WIRE_INVALID_ONION_VERSION
&& failed->badonion != WIRE_INVALID_ONION_HMAC
&& failed->badonion != WIRE_INVALID_ONION_KEY) {
log_unusual(channel->log,
"Unknown update_fail_malformed_htlc code %u:"
" sending WIRE_INVALID_ONION_VERSION",
failed->badonion);
hout->failcode = WIRE_INVALID_ONION_VERSION;
} else
hout->failcode = failed->badonion;
/* BOLT #2:
*
* - otherwise, a receiving node which has an outgoing HTLC
* canceled by `update_fail_malformed_htlc`:
*
* - MUST return an error in the `update_fail_htlc`
* sent to the link which originally sent the HTLC, using the
* `failure_code` given and setting the data to
* `sha256_of_onion`.
*/
if (hout->in) {
const u8 *f;
f = make_failmsg(tmpctx, hout->in, hout->failcode,
hout->key.channel->stripped_update,
failed->sha256_of_onion,
get_block_height(hout->key.channel->owner->ld->topology));
hout->failonion = create_onionreply(hout,
hout->in->shared_secret,
f);
hout->failcode = 0;
}
} else {
hout->failonion = dup_onionreply(hout, failed->onion);
}
log_debug(channel->log, "Our HTLC %"PRIu64" failed (%u)", failed->id,
hout->failcode);
@ -1154,7 +1292,7 @@ void onchain_failed_our_htlc(const struct channel *channel,
tal_free(localfail);
} else if (hout->in) {
local_fail_htlc(hout->in, WIRE_PERMANENT_CHANNEL_FAILURE,
hout->key.channel->scid);
hout->key.channel->stripped_update);
wallet_forwarded_payment_add(hout->key.channel->peer->ld->wallet,
hout->in, channel->scid, hout,
FORWARD_LOCAL_FAILED,
@ -1460,11 +1598,13 @@ void peer_sending_commitsig(struct channel *channel, const u8 *msg)
}
static bool channel_added_their_htlc(struct channel *channel,
const struct added_htlc *added,
const struct secret *shared_secret)
const struct added_htlc *added)
{
struct lightningd *ld = channel->peer->ld;
struct htlc_in *hin;
struct secret shared_secret;
struct onionpacket op;
enum onion_type failcode;
/* BOLT #2:
*
@ -1485,16 +1625,27 @@ static bool channel_added_their_htlc(struct channel *channel,
return false;
}
/* FIXME: Our wire generator can't handle optional elems in arrays,
* so we translate all-zero-shared-secret to NULL. */
if (memeqzero(shared_secret, sizeof(*shared_secret)))
shared_secret = NULL;
/* Do the work of extracting shared secret now if possible. */
failcode = parse_onionpacket(added->onion_routing_packet,
sizeof(added->onion_routing_packet),
&op);
if (!failcode) {
/* Because wire takes struct pubkey. */
u8 *msg = towire_hsm_ecdh_req(tmpctx, &op.ephemeralkey);
if (!wire_sync_write(ld->hsm_fd, take(msg)))
fatal("Could not write to HSM: %s", strerror(errno));
msg = wire_sync_read(tmpctx, ld->hsm_fd);
if (!fromwire_hsm_ecdh_resp(msg, &shared_secret))
fatal("Reading ecdh response: %s", strerror(errno));
}
/* This stays around even if we fail it immediately: it *is*
* part of the current commitment. */
hin = new_htlc_in(channel, channel, added->id, added->amount,
added->cltv_expiry, &added->payment_hash,
shared_secret, added->onion_routing_packet);
failcode ? NULL : &shared_secret,
added->onion_routing_packet);
/* Save an incoming htlc to the wallet */
wallet_htlc_save_in(ld->wallet, channel, hin);
@ -1566,7 +1717,6 @@ void peer_got_commitsig(struct channel *channel, const u8 *msg)
struct bitcoin_signature commit_sig;
secp256k1_ecdsa_signature *htlc_sigs;
struct added_htlc *added;
struct secret *shared_secrets;
struct fulfilled_htlc *fulfilled;
struct failed_htlc **failed;
struct changed_htlc *changed;
@ -1580,7 +1730,6 @@ void peer_got_commitsig(struct channel *channel, const u8 *msg)
&commit_sig,
&htlc_sigs,
&added,
&shared_secrets,
&fulfilled,
&failed,
&changed,
@ -1621,7 +1770,7 @@ void peer_got_commitsig(struct channel *channel, const u8 *msg)
/* New HTLCs */
for (i = 0; i < tal_count(added); i++) {
if (!channel_added_their_htlc(channel, &added[i], &shared_secrets[i]))
if (!channel_added_their_htlc(channel, &added[i]))
return;
}
@ -1819,29 +1968,24 @@ static void add_fulfill(u64 id, enum side side,
tal_arr_expand(fulfilled_sides, side);
}
static void add_fail(u64 id,
static void add_fail(struct htlc_in *hin,
enum onion_type failcode,
const struct short_channel_id *failing_channel,
const u8 *failing_channel_update,
const struct onionreply *failonion,
const struct failed_htlc ***failed_htlcs)
{
struct failed_htlc *newf;
newf = tal(*failed_htlcs, struct failed_htlc);
newf->id = id;
newf->failcode = failcode;
if (failcode & UPDATE) {
assert(failing_channel);
newf->scid = tal_dup(newf, struct short_channel_id,
failing_channel);
} else
newf->scid = NULL;
if (failonion)
newf->failreason = dup_onionreply(newf, failonion);
else
newf->failreason = NULL;
if ((failcode & UPDATE) && !failing_channel_update) {
/* We don't save the outgoing channel which failed; probably
* not worth it for this corner case. So we can't set
* hin->failoutchannel to tell channeld what update to send,
* thus we turn those into a WIRE_TEMPORARY_NODE_FAILURE. */
failcode = WIRE_TEMPORARY_NODE_FAILURE;
}
newf = mk_failed_htlc(*failed_htlcs, hin, failcode, failonion,
failing_channel_update);
tal_arr_expand(failed_htlcs, newf);
}
@ -1880,8 +2024,8 @@ void peer_htlcs(const tal_t *ctx,
hin->hstate);
if (hin->failonion || hin->failcode)
add_fail(hin->key.id, hin->failcode,
&hin->failoutchannel,
add_fail(hin, hin->failcode,
NULL,
hin->failonion, failed_in);
if (hin->preimage)
add_fulfill(hin->key.id, REMOTE, hin->preimage,

86
wallet/test/run-wallet.c

@ -82,6 +82,11 @@ struct command_result *command_success(struct command *cmd UNNEEDED,
/* Generated stub for connect_succeeded */
void connect_succeeded(struct lightningd *ld UNNEEDED, const struct node_id *id UNNEEDED)
{ fprintf(stderr, "connect_succeeded called!\n"); abort(); }
/* Generated stub for create_onionreply */
struct onionreply *create_onionreply(const tal_t *ctx UNNEEDED,
const struct secret *shared_secret UNNEEDED,
const u8 *failure_msg UNNEEDED)
{ fprintf(stderr, "create_onionreply called!\n"); abort(); }
/* Generated stub for delay_then_reconnect */
void delay_then_reconnect(struct channel *channel UNNEEDED, u32 seconds_delay UNNEEDED,
const struct wireaddr_internal *addrhint TAKES UNNEEDED)
@ -98,7 +103,7 @@ void fatal(const char *fmt UNNEEDED, ...)
bool fromwire_channel_dev_memleak_reply(const void *p UNNEEDED, bool *leak UNNEEDED)
{ fprintf(stderr, "fromwire_channel_dev_memleak_reply called!\n"); abort(); }
/* Generated stub for fromwire_channel_got_commitsig */
bool fromwire_channel_got_commitsig(const tal_t *ctx UNNEEDED, const void *p UNNEEDED, u64 *commitnum UNNEEDED, struct fee_states **fee_states UNNEEDED, struct bitcoin_signature *signature UNNEEDED, secp256k1_ecdsa_signature **htlc_signature UNNEEDED, struct added_htlc **added UNNEEDED, struct secret **shared_secret UNNEEDED, struct fulfilled_htlc **fulfilled UNNEEDED, struct failed_htlc ***failed UNNEEDED, struct changed_htlc **changed UNNEEDED, struct bitcoin_tx **tx UNNEEDED)
bool fromwire_channel_got_commitsig(const tal_t *ctx UNNEEDED, const void *p UNNEEDED, u64 *commitnum UNNEEDED, struct fee_states **fee_states UNNEEDED, struct bitcoin_signature *signature UNNEEDED, secp256k1_ecdsa_signature **htlc_signature UNNEEDED, struct added_htlc **added UNNEEDED, struct fulfilled_htlc **fulfilled UNNEEDED, struct failed_htlc ***failed UNNEEDED, struct changed_htlc **changed UNNEEDED, struct bitcoin_tx **tx UNNEEDED)
{ fprintf(stderr, "fromwire_channel_got_commitsig called!\n"); abort(); }
/* Generated stub for fromwire_channel_got_revoke */
bool fromwire_channel_got_revoke(const tal_t *ctx UNNEEDED, const void *p UNNEEDED, u64 *revokenum UNNEEDED, struct secret *per_commitment_secret UNNEEDED, struct pubkey *next_per_commit_point UNNEEDED, struct fee_states **fee_states UNNEEDED, struct changed_htlc **changed UNNEEDED)
@ -118,6 +123,9 @@ bool fromwire_custommsg_in(const tal_t *ctx UNNEEDED, const void *p UNNEEDED, u8
/* Generated stub for fromwire_gossip_get_channel_peer_reply */
bool fromwire_gossip_get_channel_peer_reply(const tal_t *ctx UNNEEDED, const void *p UNNEEDED, struct node_id **peer_id UNNEEDED, u8 **stripped_update UNNEEDED)
{ fprintf(stderr, "fromwire_gossip_get_channel_peer_reply called!\n"); abort(); }
/* Generated stub for fromwire_hsm_ecdh_resp */
bool fromwire_hsm_ecdh_resp(const void *p UNNEEDED, struct secret *ss UNNEEDED)
{ fprintf(stderr, "fromwire_hsm_ecdh_resp called!\n"); abort(); }
/* Generated stub for fromwire_hsm_sign_commitment_tx_reply */
bool fromwire_hsm_sign_commitment_tx_reply(const void *p UNNEEDED, struct bitcoin_signature *sig UNNEEDED)
{ fprintf(stderr, "fromwire_hsm_sign_commitment_tx_reply called!\n"); abort(); }
@ -569,14 +577,20 @@ void topology_add_sync_waiter_(const tal_t *ctx UNNEEDED,
void *arg) UNNEEDED,
void *arg UNNEEDED)
{ fprintf(stderr, "topology_add_sync_waiter_ called!\n"); abort(); }
/* Generated stub for towire_amount_below_minimum */
u8 *towire_amount_below_minimum(const tal_t *ctx UNNEEDED, struct amount_msat htlc_msat UNNEEDED, const u8 *channel_update UNNEEDED)
{ fprintf(stderr, "towire_amount_below_minimum called!\n"); abort(); }
/* Generated stub for towire_channel_dev_memleak */
u8 *towire_channel_dev_memleak(const tal_t *ctx UNNEEDED)
{ fprintf(stderr, "towire_channel_dev_memleak called!\n"); abort(); }
/* Generated stub for towire_channel_dev_reenable_commit */
u8 *towire_channel_dev_reenable_commit(const tal_t *ctx UNNEEDED)
{ fprintf(stderr, "towire_channel_dev_reenable_commit called!\n"); abort(); }
/* Generated stub for towire_channel_disabled */
u8 *towire_channel_disabled(const tal_t *ctx UNNEEDED)
{ fprintf(stderr, "towire_channel_disabled called!\n"); abort(); }
/* Generated stub for towire_channel_fail_htlc */
u8 *towire_channel_fail_htlc(const tal_t *ctx UNNEEDED, const struct failed_htlc *failed_htlc UNNEEDED, u32 failheight UNNEEDED)
u8 *towire_channel_fail_htlc(const tal_t *ctx UNNEEDED, const struct failed_htlc *failed_htlc UNNEEDED)
{ fprintf(stderr, "towire_channel_fail_htlc called!\n"); abort(); }
/* Generated stub for towire_channel_fulfill_htlc */
u8 *towire_channel_fulfill_htlc(const tal_t *ctx UNNEEDED, const struct fulfilled_htlc *fulfilled_htlc UNNEEDED)
@ -613,18 +627,81 @@ u8 *towire_errorfmt(const tal_t *ctx UNNEEDED,
const struct channel_id *channel UNNEEDED,
const char *fmt UNNEEDED, ...)
{ fprintf(stderr, "towire_errorfmt called!\n"); abort(); }
/* Generated stub for towire_expiry_too_far */
u8 *towire_expiry_too_far(const tal_t *ctx UNNEEDED)
{ fprintf(stderr, "towire_expiry_too_far called!\n"); abort(); }
/* Generated stub for towire_expiry_too_soon */
u8 *towire_expiry_too_soon(const tal_t *ctx UNNEEDED, const u8 *channel_update UNNEEDED)
{ fprintf(stderr, "towire_expiry_too_soon called!\n"); abort(); }
/* Generated stub for towire_fee_insufficient */
u8 *towire_fee_insufficient(const tal_t *ctx UNNEEDED, struct amount_msat htlc_msat UNNEEDED, const u8 *channel_update UNNEEDED)
{ fprintf(stderr, "towire_fee_insufficient called!\n"); abort(); }
/* Generated stub for towire_final_incorrect_cltv_expiry */
u8 *towire_final_incorrect_cltv_expiry(const tal_t *ctx UNNEEDED, u32 cltv_expiry UNNEEDED)
{ fprintf(stderr, "towire_final_incorrect_cltv_expiry called!\n"); abort(); }
/* Generated stub for towire_final_incorrect_htlc_amount */
u8 *towire_final_incorrect_htlc_amount(const tal_t *ctx UNNEEDED, struct amount_msat incoming_htlc_amt UNNEEDED)
{ fprintf(stderr, "towire_final_incorrect_htlc_amount called!\n"); abort(); }
/* Generated stub for towire_gossip_get_channel_peer */
u8 *towire_gossip_get_channel_peer(const tal_t *ctx UNNEEDED, const struct short_channel_id *channel_id UNNEEDED)
{ fprintf(stderr, "towire_gossip_get_channel_peer called!\n"); abort(); }
/* Generated stub for towire_hsm_ecdh_req */
u8 *towire_hsm_ecdh_req(const tal_t *ctx UNNEEDED, const struct pubkey *point UNNEEDED)
{ fprintf(stderr, "towire_hsm_ecdh_req called!\n"); abort(); }
/* Generated stub for towire_hsm_sign_commitment_tx */
u8 *towire_hsm_sign_commitment_tx(const tal_t *ctx UNNEEDED, const struct node_id *peer_id UNNEEDED, u64 channel_dbid UNNEEDED, const struct bitcoin_tx *tx UNNEEDED, const struct pubkey *remote_funding_key UNNEEDED, struct amount_sat funding_amount UNNEEDED)
{ fprintf(stderr, "towire_hsm_sign_commitment_tx called!\n"); abort(); }
/* Generated stub for towire_incorrect_cltv_expiry */
u8 *towire_incorrect_cltv_expiry(const tal_t *ctx UNNEEDED, u32 cltv_expiry UNNEEDED, const u8 *channel_update UNNEEDED)
{ fprintf(stderr, "towire_incorrect_cltv_expiry called!\n"); abort(); }
/* Generated stub for towire_incorrect_or_unknown_payment_details */
u8 *towire_incorrect_or_unknown_payment_details(const tal_t *ctx UNNEEDED, struct amount_msat htlc_msat UNNEEDED, u32 height UNNEEDED)
{ fprintf(stderr, "towire_incorrect_or_unknown_payment_details called!\n"); abort(); }
/* Generated stub for towire_invalid_onion_hmac */
u8 *towire_invalid_onion_hmac(const tal_t *ctx UNNEEDED, const struct sha256 *sha256_of_onion UNNEEDED)
{ fprintf(stderr, "towire_invalid_onion_hmac called!\n"); abort(); }
/* Generated stub for towire_invalid_onion_key */
u8 *towire_invalid_onion_key(const tal_t *ctx UNNEEDED, const struct sha256 *sha256_of_onion UNNEEDED)
{ fprintf(stderr, "towire_invalid_onion_key called!\n"); abort(); }
/* Generated stub for towire_invalid_onion_payload */
u8 *towire_invalid_onion_payload(const tal_t *ctx UNNEEDED, varint type UNNEEDED, u16 offset UNNEEDED)
{ fprintf(stderr, "towire_invalid_onion_payload called!\n"); abort(); }
/* Generated stub for towire_invalid_onion_version */
u8 *towire_invalid_onion_version(const tal_t *ctx UNNEEDED, const struct sha256 *sha256_of_onion UNNEEDED)
{ fprintf(stderr, "towire_invalid_onion_version called!\n"); abort(); }
/* Generated stub for towire_invalid_realm */
u8 *towire_invalid_realm(const tal_t *ctx UNNEEDED)
{ fprintf(stderr, "towire_invalid_realm called!\n"); abort(); }
/* Generated stub for towire_mpp_timeout */
u8 *towire_mpp_timeout(const tal_t *ctx UNNEEDED)
{ fprintf(stderr, "towire_mpp_timeout called!\n"); abort(); }
/* Generated stub for towire_onchain_dev_memleak */
u8 *towire_onchain_dev_memleak(const tal_t *ctx UNNEEDED)
{ fprintf(stderr, "towire_onchain_dev_memleak called!\n"); abort(); }
/* Generated stub for towire_onchain_known_preimage */
u8 *towire_onchain_known_preimage(const tal_t *ctx UNNEEDED, const struct preimage *preimage UNNEEDED)
{ fprintf(stderr, "towire_onchain_known_preimage called!\n"); abort(); }
/* Generated stub for towire_permanent_channel_failure */
u8 *towire_permanent_channel_failure(const tal_t *ctx UNNEEDED)
{ fprintf(stderr, "towire_permanent_channel_failure called!\n"); abort(); }
/* Generated stub for towire_permanent_node_failure */
u8 *towire_permanent_node_failure(const tal_t *ctx UNNEEDED)
{ fprintf(stderr, "towire_permanent_node_failure called!\n"); abort(); }
/* Generated stub for towire_required_channel_feature_missing */
u8 *towire_required_channel_feature_missing(const tal_t *ctx UNNEEDED)
{ fprintf(stderr, "towire_required_channel_feature_missing called!\n"); abort(); }
/* Generated stub for towire_required_node_feature_missing */
u8 *towire_required_node_feature_missing(const tal_t *ctx UNNEEDED)
{ fprintf(stderr, "towire_required_node_feature_missing called!\n"); abort(); }
/* Generated stub for towire_temporary_channel_failure */
u8 *towire_temporary_channel_failure(const tal_t *ctx UNNEEDED, const u8 *channel_update UNNEEDED)
{ fprintf(stderr, "towire_temporary_channel_failure called!\n"); abort(); }
/* Generated stub for towire_temporary_node_failure */
u8 *towire_temporary_node_failure(const tal_t *ctx UNNEEDED)
{ fprintf(stderr, "towire_temporary_node_failure called!\n"); abort(); }
/* Generated stub for towire_unknown_next_peer */
u8 *towire_unknown_next_peer(const tal_t *ctx UNNEEDED)
{ fprintf(stderr, "towire_unknown_next_peer called!\n"); abort(); }
/* Generated stub for watch_txid */
struct txwatch *watch_txid(const tal_t *ctx UNNEEDED,
struct chain_topology *topo UNNEEDED,
@ -653,6 +730,11 @@ bool wire_type_is_defined(u16 type UNNEEDED)
/* Generated stub for wire_type_name */
const char *wire_type_name(int e UNNEEDED)
{ fprintf(stderr, "wire_type_name called!\n"); abort(); }
/* Generated stub for wrap_onionreply */
struct onionreply *wrap_onionreply(const tal_t *ctx UNNEEDED,
const struct secret *shared_secret UNNEEDED,
const struct onionreply *reply UNNEEDED)
{ fprintf(stderr, "wrap_onionreply called!\n"); abort(); }
/* AUTOGENERATED MOCKS END */
#if DEVELOPER

Loading…
Cancel
Save