diff --git a/channeld/channel_wire.csv b/channeld/channel_wire.csv index 27767d352..912067546 100644 --- a/channeld/channel_wire.csv +++ b/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 diff --git a/channeld/channeld.c b/channeld/channeld.c index 6049fb65e..bc03cad54 100644 --- a/channeld/channeld.c +++ b/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); diff --git a/channeld/channeld_htlc.h b/channeld/channeld_htlc.h index 5b2c54d45..482038bb3 100644 --- a/channeld/channeld_htlc.h +++ b/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) diff --git a/channeld/full_channel.c b/channeld/full_channel.c index b1c7f111b..69107e348 100644 --- a/channeld/full_channel.c +++ b/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 diff --git a/channeld/full_channel.h b/channeld/full_channel.h index 5c44460a7..c390c30b4 100644 --- a/channeld/full_channel.h +++ b/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 diff --git a/channeld/test/run-full_channel.c b/channeld/test/run-full_channel.c index 79a39964f..63dbaec3e 100644 --- a/channeld/test/run-full_channel.c +++ b/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 *)){ } diff --git a/common/htlc_wire.c b/common/htlc_wire.c index 881831693..ffce22015 100644 --- a/common/htlc_wire.c +++ b/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; diff --git a/common/htlc_wire.h b/common/htlc_wire.h index 030cbd451..7fe6b7465 100644 --- a/common/htlc_wire.h +++ b/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 { diff --git a/devtools/mkcommit.c b/devtools/mkcommit.c index 2af16d5dd..10b2debb4 100644 --- a/devtools/mkcommit.c +++ b/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, diff --git a/hsmd/hsmd.c b/hsmd/hsmd.c index 156de0324..cc4224365 100644 --- a/hsmd/hsmd.c +++ b/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. */ diff --git a/lightningd/channel_control.c b/lightningd/channel_control.c index 4ce3a80eb..d5c075528 100644 --- a/lightningd/channel_control.c +++ b/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, diff --git a/lightningd/htlc_end.h b/lightningd/htlc_end.h index 91d339e3f..e1db8c212 100644 --- a/lightningd/htlc_end.h +++ b/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; diff --git a/lightningd/peer_htlcs.c b/lightningd/peer_htlcs.c index 72ee361da..bb7ceccda 100644 --- a/lightningd/peer_htlcs.c +++ b/lightningd/peer_htlcs.c @@ -16,6 +16,7 @@ #include #include #include +#include #include #include #include @@ -33,6 +34,7 @@ #include #include #include +#include #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, diff --git a/wallet/test/run-wallet.c b/wallet/test/run-wallet.c index 802b5fdb7..9578c6d38 100644 --- a/wallet/test/run-wallet.c +++ b/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