mirror of
https://github.com/aljazceru/lightning.git
synced 2025-12-19 23:24:27 +01:00
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>
This commit is contained in:
@@ -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
|
||||
|
||||
|
@@ -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. */
|
||||
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,
|
||||
wrap_onionreply(tmpctx,
|
||||
h->shared_secret,
|
||||
onion)->contents);
|
||||
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);
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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 *)){ }
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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. */
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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)));
|
||||
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,
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user