Browse Source

channeld: support HTLCs with blinding (EXPERIMENTAL_FEATURES)

Note that it's channeld which calculates the shared secret, too.  This
minimizes the work that lightningd has to do, at cost of passing this
through.

We also don't yet save the blinding field(s) to the database.

Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
travis-debug
Rusty Russell 5 years ago
parent
commit
b29d1ed3ff
  1. 1
      channeld/channel_wire.csv
  2. 42
      channeld/channeld.c
  3. 3
      channeld/channeld_htlc.h
  4. 13
      channeld/full_channel.c
  5. 2
      channeld/full_channel.h
  6. 5
      channeld/test/run-full_channel.c
  7. 29
      common/htlc_wire.c
  8. 9
      common/htlc_wire.h
  9. 3
      connectd/test/run-responder-success.c
  10. 1
      lightningd/Makefile
  11. 12
      lightningd/htlc_end.c
  12. 11
      lightningd/htlc_end.h
  13. 17
      lightningd/pay.c
  14. 116
      lightningd/peer_htlcs.c
  15. 1
      lightningd/peer_htlcs.h
  16. 8
      lightningd/test/run-invoice-select-inchan.c
  17. 38
      wallet/test/run-wallet.c
  18. 4
      wallet/wallet.c
  19. 2
      wire/extracted_peer_experimental_add_htlc-plus-blinding

1
channeld/channel_wire.csv

@ -77,6 +77,7 @@ msgdata,channel_offer_htlc,amount_msat,amount_msat,
msgdata,channel_offer_htlc,cltv_expiry,u32, msgdata,channel_offer_htlc,cltv_expiry,u32,
msgdata,channel_offer_htlc,payment_hash,sha256, msgdata,channel_offer_htlc,payment_hash,sha256,
msgdata,channel_offer_htlc,onion_routing_packet,u8,1366 msgdata,channel_offer_htlc,onion_routing_packet,u8,1366
msgdata,channel_offer_htlc,blinding,?pubkey,
# Reply; synchronous since IDs have to increment. # Reply; synchronous since IDs have to increment.
msgtype,channel_offer_htlc_reply,1104 msgtype,channel_offer_htlc_reply,1104

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

42
channeld/channeld.c

@ -624,6 +624,7 @@ static void handle_peer_add_htlc(struct peer *peer, const u8 *msg)
#if EXPERIMENTAL_FEATURES #if EXPERIMENTAL_FEATURES
struct tlv_update_add_tlvs *tlvs = tlv_update_add_tlvs_new(msg); struct tlv_update_add_tlvs *tlvs = tlv_update_add_tlvs_new(msg);
#endif #endif
struct pubkey *blinding = NULL;
if (!fromwire_update_add_htlc(msg, &channel_id, &id, &amount, if (!fromwire_update_add_htlc(msg, &channel_id, &id, &amount,
&payment_hash, &cltv_expiry, &payment_hash, &cltv_expiry,
@ -636,9 +637,13 @@ static void handle_peer_add_htlc(struct peer *peer, const u8 *msg)
&peer->channel_id, &peer->channel_id,
"Bad peer_add_htlc %s", tal_hex(msg, msg)); "Bad peer_add_htlc %s", tal_hex(msg, msg));
#if EXPERIMENTAL_FEATURES
if (tlvs->blinding)
blinding = &tlvs->blinding->blinding;
#endif
add_err = channel_add_htlc(peer->channel, REMOTE, id, amount, add_err = channel_add_htlc(peer->channel, REMOTE, id, amount,
cltv_expiry, &payment_hash, cltv_expiry, &payment_hash,
onion_routing_packet, &htlc, NULL); onion_routing_packet, blinding, &htlc, NULL);
if (add_err != CHANNEL_ERR_ADD_OK) if (add_err != CHANNEL_ERR_ADD_OK)
peer_failed(peer->pps, peer_failed(peer->pps,
&peer->channel_id, &peer->channel_id,
@ -1122,6 +1127,11 @@ static void marshall_htlc_info(const tal_t *ctx,
memcpy(a.onion_routing_packet, memcpy(a.onion_routing_packet,
htlc->routing, htlc->routing,
sizeof(a.onion_routing_packet)); sizeof(a.onion_routing_packet));
if (htlc->blinding) {
a.blinding = htlc->blinding;
ecdh(a.blinding, &a.blinding_ss);
} else
a.blinding = NULL;
tal_arr_expand(added, a); tal_arr_expand(added, a);
} else if (htlc->state == RCVD_REMOVE_COMMIT) { } else if (htlc->state == RCVD_REMOVE_COMMIT) {
if (htlc->r) { if (htlc->r) {
@ -2052,6 +2062,15 @@ static void resend_commitment(struct peer *peer, const struct changed_htlc *last
last[i].id); last[i].id);
if (h->state == SENT_ADD_COMMIT) { if (h->state == SENT_ADD_COMMIT) {
#if EXPERIMENTAL_FEATURES
struct tlv_update_add_tlvs *tlvs;
if (h->blinding) {
tlvs = tlv_update_add_tlvs_new(tmpctx);
tlvs->blinding = tal(tlvs, struct tlv_update_add_tlvs_blinding);
tlvs->blinding->blinding = *h->blinding;
} else
tlvs = NULL;
#endif
u8 *msg = towire_update_add_htlc(NULL, &peer->channel_id, u8 *msg = towire_update_add_htlc(NULL, &peer->channel_id,
h->id, h->amount, h->id, h->amount,
&h->rhash, &h->rhash,
@ -2059,7 +2078,7 @@ static void resend_commitment(struct peer *peer, const struct changed_htlc *last
&h->expiry), &h->expiry),
h->routing h->routing
#if EXPERIMENTAL_FEATURES #if EXPERIMENTAL_FEATURES
, NULL , tlvs
#endif #endif
); );
sync_crypto_write(peer->pps, take(msg)); sync_crypto_write(peer->pps, take(msg));
@ -2671,19 +2690,30 @@ static void handle_offer_htlc(struct peer *peer, const u8 *inmsg)
const u8 *failwiremsg; const u8 *failwiremsg;
const char *failstr; const char *failstr;
struct amount_sat htlc_fee; struct amount_sat htlc_fee;
struct pubkey *blinding;
if (!peer->funding_locked[LOCAL] || !peer->funding_locked[REMOTE]) if (!peer->funding_locked[LOCAL] || !peer->funding_locked[REMOTE])
status_failed(STATUS_FAIL_MASTER_IO, status_failed(STATUS_FAIL_MASTER_IO,
"funding not locked for offer_htlc"); "funding not locked for offer_htlc");
if (!fromwire_channel_offer_htlc(inmsg, &amount, if (!fromwire_channel_offer_htlc(tmpctx, inmsg, &amount,
&cltv_expiry, &payment_hash, &cltv_expiry, &payment_hash,
onion_routing_packet)) onion_routing_packet, &blinding))
master_badmsg(WIRE_CHANNEL_OFFER_HTLC, inmsg); master_badmsg(WIRE_CHANNEL_OFFER_HTLC, inmsg);
#if EXPERIMENTAL_FEATURES
struct tlv_update_add_tlvs *tlvs;
if (blinding) {
tlvs = tlv_update_add_tlvs_new(tmpctx);
tlvs->blinding = tal(tlvs, struct tlv_update_add_tlvs_blinding);
tlvs->blinding->blinding = *blinding;
} else
tlvs = NULL;
#endif
e = channel_add_htlc(peer->channel, LOCAL, peer->htlc_id, e = channel_add_htlc(peer->channel, LOCAL, peer->htlc_id,
amount, cltv_expiry, &payment_hash, amount, cltv_expiry, &payment_hash,
onion_routing_packet, NULL, &htlc_fee); onion_routing_packet, take(blinding), NULL, &htlc_fee);
status_debug("Adding HTLC %"PRIu64" amount=%s cltv=%u gave %s", status_debug("Adding HTLC %"PRIu64" amount=%s cltv=%u gave %s",
peer->htlc_id, peer->htlc_id,
type_to_string(tmpctx, struct amount_msat, &amount), type_to_string(tmpctx, struct amount_msat, &amount),
@ -2698,7 +2728,7 @@ static void handle_offer_htlc(struct peer *peer, const u8 *inmsg)
&payment_hash, cltv_expiry, &payment_hash, cltv_expiry,
onion_routing_packet onion_routing_packet
#if EXPERIMENTAL_FEATURES #if EXPERIMENTAL_FEATURES
, NULL , tlvs
#endif #endif
); );
sync_crypto_write(peer->pps, take(msg)); sync_crypto_write(peer->pps, take(msg));

3
channeld/channeld_htlc.h

@ -27,6 +27,9 @@ struct htlc {
/* Routing information sent with this HTLC (outgoing only). */ /* Routing information sent with this HTLC (outgoing only). */
const u8 *routing; const u8 *routing;
/* Blinding (optional). */
struct pubkey *blinding;
}; };
static inline bool htlc_has(const struct htlc *h, int flag) static inline bool htlc_has(const struct htlc *h, int flag)

13
channeld/full_channel.c

@ -447,6 +447,7 @@ static enum channel_add_err add_htlc(struct channel *channel,
u32 cltv_expiry, u32 cltv_expiry,
const struct sha256 *payment_hash, const struct sha256 *payment_hash,
const u8 routing[TOTAL_PACKET_SIZE], const u8 routing[TOTAL_PACKET_SIZE],
const struct pubkey *blinding TAKES,
struct htlc **htlcp, struct htlc **htlcp,
bool enforce_aggregate_limits, bool enforce_aggregate_limits,
struct amount_sat *htlc_fee) struct amount_sat *htlc_fee)
@ -479,6 +480,10 @@ static enum channel_add_err add_htlc(struct channel *channel,
} }
htlc->rhash = *payment_hash; htlc->rhash = *payment_hash;
if (blinding)
htlc->blinding = tal_dup(htlc, struct pubkey, blinding);
else
htlc->blinding = NULL;
htlc->failed = NULL; htlc->failed = NULL;
htlc->r = NULL; htlc->r = NULL;
htlc->routing = tal_dup_arr(htlc, u8, routing, TOTAL_PACKET_SIZE, 0); htlc->routing = tal_dup_arr(htlc, u8, routing, TOTAL_PACKET_SIZE, 0);
@ -694,6 +699,7 @@ enum channel_add_err channel_add_htlc(struct channel *channel,
u32 cltv_expiry, u32 cltv_expiry,
const struct sha256 *payment_hash, const struct sha256 *payment_hash,
const u8 routing[TOTAL_PACKET_SIZE], const u8 routing[TOTAL_PACKET_SIZE],
const struct pubkey *blinding TAKES,
struct htlc **htlcp, struct htlc **htlcp,
struct amount_sat *htlc_fee) struct amount_sat *htlc_fee)
{ {
@ -705,7 +711,8 @@ enum channel_add_err channel_add_htlc(struct channel *channel,
state = RCVD_ADD_HTLC; state = RCVD_ADD_HTLC;
return add_htlc(channel, state, id, amount, cltv_expiry, return add_htlc(channel, state, id, amount, cltv_expiry,
payment_hash, routing, htlcp, true, htlc_fee); payment_hash, routing, blinding,
htlcp, true, htlc_fee);
} }
struct htlc *channel_get_htlc(struct channel *channel, enum side sender, u64 id) struct htlc *channel_get_htlc(struct channel *channel, enum side sender, u64 id)
@ -1212,7 +1219,9 @@ bool channel_force_htlcs(struct channel *channel,
htlcs[i]->id, htlcs[i]->amount, htlcs[i]->id, htlcs[i]->amount,
htlcs[i]->cltv_expiry, htlcs[i]->cltv_expiry,
&htlcs[i]->payment_hash, &htlcs[i]->payment_hash,
htlcs[i]->onion_routing_packet, &htlc, false, NULL); htlcs[i]->onion_routing_packet,
htlcs[i]->blinding,
&htlc, false, NULL);
if (e != CHANNEL_ERR_ADD_OK) { if (e != CHANNEL_ERR_ADD_OK) {
status_broken("%s HTLC %"PRIu64" failed error %u", status_broken("%s HTLC %"PRIu64" failed error %u",
htlc_state_owner(htlcs[i]->state) == LOCAL htlc_state_owner(htlcs[i]->state) == LOCAL

2
channeld/full_channel.h

@ -92,6 +92,7 @@ u32 actual_feerate(const struct channel *channel,
* @cltv_expiry: block number when HTLC can no longer be redeemed. * @cltv_expiry: block number when HTLC can no longer be redeemed.
* @payment_hash: hash whose preimage can redeem HTLC. * @payment_hash: hash whose preimage can redeem HTLC.
* @routing: routing information (copied) * @routing: routing information (copied)
* @blinding: optional blinding information for this HTLC.
* @htlcp: optional pointer for resulting htlc: filled in if and only if CHANNEL_ERR_NONE. * @htlcp: optional pointer for resulting htlc: filled in if and only if CHANNEL_ERR_NONE.
* *
* If this returns CHANNEL_ERR_NONE, the fee htlc was added and * If this returns CHANNEL_ERR_NONE, the fee htlc was added and
@ -105,6 +106,7 @@ enum channel_add_err channel_add_htlc(struct channel *channel,
u32 cltv_expiry, u32 cltv_expiry,
const struct sha256 *payment_hash, const struct sha256 *payment_hash,
const u8 routing[TOTAL_PACKET_SIZE], const u8 routing[TOTAL_PACKET_SIZE],
const struct pubkey *blinding TAKES,
struct htlc **htlcp, struct htlc **htlcp,
struct amount_sat *htlc_fee); struct amount_sat *htlc_fee);

5
channeld/test/run-full_channel.c

@ -165,7 +165,7 @@ static const struct htlc **include_htlcs(struct channel *channel, enum side side
memset(&preimage, i, sizeof(preimage)); memset(&preimage, i, sizeof(preimage));
sha256(&hash, &preimage, sizeof(preimage)); sha256(&hash, &preimage, sizeof(preimage));
e = channel_add_htlc(channel, sender, i, msatoshi, 500+i, &hash, e = channel_add_htlc(channel, sender, i, msatoshi, 500+i, &hash,
dummy_routing, NULL, NULL); dummy_routing, NULL, NULL, NULL);
assert(e == CHANNEL_ERR_ADD_OK); assert(e == CHANNEL_ERR_ADD_OK);
htlcs[i] = channel_get_htlc(channel, sender, i); htlcs[i] = channel_get_htlc(channel, sender, i);
} }
@ -257,7 +257,8 @@ static void send_and_fulfill_htlc(struct channel *channel,
sha256(&rhash, &r, sizeof(r)); sha256(&rhash, &r, sizeof(r));
assert(channel_add_htlc(channel, sender, 1337, msatoshi, 900, &rhash, assert(channel_add_htlc(channel, sender, 1337, msatoshi, 900, &rhash,
dummy_routing, NULL, NULL) == CHANNEL_ERR_ADD_OK); dummy_routing, NULL, NULL, NULL)
== CHANNEL_ERR_ADD_OK);
changed_htlcs = tal_arr(channel, const struct htlc *, 0); changed_htlcs = tal_arr(channel, const struct htlc *, 0);

29
common/htlc_wire.c

@ -35,7 +35,8 @@ struct existing_htlc *new_existing_htlc(const tal_t *ctx,
const struct sha256 *payment_hash, const struct sha256 *payment_hash,
u32 cltv_expiry, u32 cltv_expiry,
const u8 onion_routing_packet[TOTAL_PACKET_SIZE], const u8 onion_routing_packet[TOTAL_PACKET_SIZE],
const struct preimage *preimage, const struct pubkey *blinding TAKES,
const struct preimage *preimage TAKES,
const struct failed_htlc *failed TAKES) const struct failed_htlc *failed TAKES)
{ {
struct existing_htlc *existing = tal(ctx, struct existing_htlc); struct existing_htlc *existing = tal(ctx, struct existing_htlc);
@ -47,6 +48,10 @@ struct existing_htlc *new_existing_htlc(const tal_t *ctx,
existing->payment_hash = *payment_hash; existing->payment_hash = *payment_hash;
memcpy(existing->onion_routing_packet, onion_routing_packet, memcpy(existing->onion_routing_packet, onion_routing_packet,
sizeof(existing->onion_routing_packet)); sizeof(existing->onion_routing_packet));
if (blinding)
existing->blinding = tal_dup(existing, struct pubkey, blinding);
else
existing->blinding = NULL;
if (preimage) if (preimage)
existing->payment_preimage existing->payment_preimage
= tal_dup(existing, struct preimage, preimage); = tal_dup(existing, struct preimage, preimage);
@ -70,6 +75,12 @@ void towire_added_htlc(u8 **pptr, const struct added_htlc *added)
towire_u32(pptr, added->cltv_expiry); towire_u32(pptr, added->cltv_expiry);
towire(pptr, added->onion_routing_packet, towire(pptr, added->onion_routing_packet,
sizeof(added->onion_routing_packet)); sizeof(added->onion_routing_packet));
if (added->blinding) {
towire_bool(pptr, true);
towire_pubkey(pptr, added->blinding);
towire_secret(pptr, &added->blinding_ss);
} else
towire_bool(pptr, false);
} }
void towire_existing_htlc(u8 **pptr, const struct existing_htlc *existing) void towire_existing_htlc(u8 **pptr, const struct existing_htlc *existing)
@ -91,6 +102,11 @@ void towire_existing_htlc(u8 **pptr, const struct existing_htlc *existing)
towire_failed_htlc(pptr, existing->failed); towire_failed_htlc(pptr, existing->failed);
} else } else
towire_bool(pptr, false); towire_bool(pptr, false);
if (existing->blinding) {
towire_bool(pptr, true);
towire_pubkey(pptr, existing->blinding);
} else
towire_bool(pptr, false);
} }
void towire_fulfilled_htlc(u8 **pptr, const struct fulfilled_htlc *fulfilled) void towire_fulfilled_htlc(u8 **pptr, const struct fulfilled_htlc *fulfilled)
@ -152,6 +168,12 @@ void fromwire_added_htlc(const u8 **cursor, size_t *max,
added->cltv_expiry = fromwire_u32(cursor, max); added->cltv_expiry = fromwire_u32(cursor, max);
fromwire(cursor, max, added->onion_routing_packet, fromwire(cursor, max, added->onion_routing_packet,
sizeof(added->onion_routing_packet)); sizeof(added->onion_routing_packet));
if (fromwire_bool(cursor, max)) {
added->blinding = tal(added, struct pubkey);
fromwire_pubkey(cursor, max, added->blinding);
fromwire_secret(cursor, max, &added->blinding_ss);
} else
added->blinding = NULL;
} }
struct existing_htlc *fromwire_existing_htlc(const tal_t *ctx, struct existing_htlc *fromwire_existing_htlc(const tal_t *ctx,
@ -175,6 +197,11 @@ struct existing_htlc *fromwire_existing_htlc(const tal_t *ctx,
existing->failed = fromwire_failed_htlc(existing, cursor, max); existing->failed = fromwire_failed_htlc(existing, cursor, max);
else else
existing->failed = NULL; existing->failed = NULL;
if (fromwire_bool(cursor, max)) {
existing->blinding = tal(existing, struct pubkey);
fromwire_pubkey(cursor, max, existing->blinding);
} else
existing->blinding = NULL;
return existing; return existing;
} }

9
common/htlc_wire.h

@ -18,6 +18,10 @@ struct added_htlc {
struct sha256 payment_hash; struct sha256 payment_hash;
u32 cltv_expiry; u32 cltv_expiry;
u8 onion_routing_packet[TOTAL_PACKET_SIZE]; u8 onion_routing_packet[TOTAL_PACKET_SIZE];
/* If this is non-NULL, secret is the resulting shared secret */
struct pubkey *blinding;
struct secret blinding_ss;
}; };
/* This is how lightningd tells us about HTLCs which already exist at startup */ /* This is how lightningd tells us about HTLCs which already exist at startup */
@ -28,6 +32,8 @@ struct existing_htlc {
struct sha256 payment_hash; struct sha256 payment_hash;
u32 cltv_expiry; u32 cltv_expiry;
u8 onion_routing_packet[TOTAL_PACKET_SIZE]; u8 onion_routing_packet[TOTAL_PACKET_SIZE];
/* If this is non-NULL, this is blinding to send with (outgoing) HTLC */
struct pubkey *blinding;
/* If fulfilled, this is non-NULL */ /* If fulfilled, this is non-NULL */
struct preimage *payment_preimage; struct preimage *payment_preimage;
/* If failed, this is set */ /* If failed, this is set */
@ -66,7 +72,8 @@ struct existing_htlc *new_existing_htlc(const tal_t *ctx,
const struct sha256 *payment_hash, const struct sha256 *payment_hash,
u32 cltv_expiry, u32 cltv_expiry,
const u8 onion_routing_packet[TOTAL_PACKET_SIZE], const u8 onion_routing_packet[TOTAL_PACKET_SIZE],
const struct preimage *preimage, const struct pubkey *blinding TAKES,
const struct preimage *preimage TAKES,
const struct failed_htlc *failed TAKES); const struct failed_htlc *failed TAKES);
struct failed_htlc *failed_htlc_dup(const tal_t *ctx, const struct failed_htlc *f TAKES); struct failed_htlc *failed_htlc_dup(const tal_t *ctx, const struct failed_htlc *f TAKES);

3
connectd/test/run-responder-success.c

@ -40,9 +40,6 @@ u8 *fromwire_tal_arrn(const tal_t *ctx UNNEEDED,
/* Generated stub for fromwire_u16 */ /* Generated stub for fromwire_u16 */
u16 fromwire_u16(const u8 **cursor UNNEEDED, size_t *max UNNEEDED) u16 fromwire_u16(const u8 **cursor UNNEEDED, size_t *max UNNEEDED)
{ fprintf(stderr, "fromwire_u16 called!\n"); abort(); } { fprintf(stderr, "fromwire_u16 called!\n"); abort(); }
/* Generated stub for notleak_ */
void *notleak_(const void *ptr UNNEEDED, bool plus_children UNNEEDED)
{ fprintf(stderr, "notleak_ called!\n"); abort(); }
/* Generated stub for towire_u16 */ /* Generated stub for towire_u16 */
void towire_u16(u8 **pptr UNNEEDED, u16 v UNNEEDED) void towire_u16(u8 **pptr UNNEEDED, u16 v UNNEEDED)
{ fprintf(stderr, "towire_u16 called!\n"); abort(); } { fprintf(stderr, "towire_u16 called!\n"); abort(); }

1
lightningd/Makefile

@ -22,6 +22,7 @@ LIGHTNINGD_COMMON_OBJS := \
common/bech32_util.o \ common/bech32_util.o \
common/bigsize.o \ common/bigsize.o \
common/bip32.o \ common/bip32.o \
common/blinding.o \
common/bolt11.o \ common/bolt11.o \
common/channel_config.o \ common/channel_config.o \
common/configdir.o \ common/configdir.o \

12
lightningd/htlc_end.c

@ -130,6 +130,8 @@ struct htlc_in *new_htlc_in(const tal_t *ctx,
struct amount_msat msat, u32 cltv_expiry, struct amount_msat msat, u32 cltv_expiry,
const struct sha256 *payment_hash, const struct sha256 *payment_hash,
const struct secret *shared_secret TAKES, const struct secret *shared_secret TAKES,
const struct pubkey *blinding TAKES,
const struct secret *blinding_ss,
const u8 *onion_routing_packet) const u8 *onion_routing_packet)
{ {
struct htlc_in *hin = tal(ctx, struct htlc_in); struct htlc_in *hin = tal(ctx, struct htlc_in);
@ -144,6 +146,11 @@ struct htlc_in *new_htlc_in(const tal_t *ctx,
hin->shared_secret = tal_dup(hin, struct secret, shared_secret); hin->shared_secret = tal_dup(hin, struct secret, shared_secret);
else else
hin->shared_secret = NULL; hin->shared_secret = NULL;
if (blinding) {
hin->blinding = tal_dup(hin, struct pubkey, blinding);
hin->blinding_ss = *blinding_ss;
} else
hin->blinding = NULL;
memcpy(hin->onion_routing_packet, onion_routing_packet, memcpy(hin->onion_routing_packet, onion_routing_packet,
sizeof(hin->onion_routing_packet)); sizeof(hin->onion_routing_packet));
@ -267,6 +274,7 @@ struct htlc_out *new_htlc_out(const tal_t *ctx,
u32 cltv_expiry, u32 cltv_expiry,
const struct sha256 *payment_hash, const struct sha256 *payment_hash,
const u8 *onion_routing_packet, const u8 *onion_routing_packet,
const struct pubkey *blinding,
bool am_origin, bool am_origin,
u64 partid, u64 partid,
struct htlc_in *in) struct htlc_in *in)
@ -289,6 +297,10 @@ struct htlc_out *new_htlc_out(const tal_t *ctx,
hout->failonion = NULL; hout->failonion = NULL;
hout->preimage = NULL; hout->preimage = NULL;
if (blinding)
hout->blinding = tal_dup(hout, struct pubkey, blinding);
else
hout->blinding = NULL;
hout->am_origin = am_origin; hout->am_origin = am_origin;
if (am_origin) if (am_origin)
hout->partid = partid; hout->partid = partid;

11
lightningd/htlc_end.h

@ -48,6 +48,11 @@ struct htlc_in {
/* Remember the timestamp we received this HTLC so we can later record /* Remember the timestamp we received this HTLC so we can later record
* it, and the resolution time, in the forwards table. */ * it, and the resolution time, in the forwards table. */
struct timeabs received_time; struct timeabs received_time;
/* If it was blinded. */
struct pubkey *blinding;
/* Only set if blinding != NULL */
struct secret blinding_ss;
}; };
struct htlc_out { struct htlc_out {
@ -83,6 +88,9 @@ struct htlc_out {
/* Where it's from, if not going to us. */ /* Where it's from, if not going to us. */
struct htlc_in *in; struct htlc_in *in;
/* Blinding to send alongside, if any. */
struct pubkey *blinding;
}; };
static inline const struct htlc_key *keyof_htlc_in(const struct htlc_in *in) static inline const struct htlc_key *keyof_htlc_in(const struct htlc_in *in)
@ -133,6 +141,8 @@ struct htlc_in *new_htlc_in(const tal_t *ctx,
struct amount_msat msat, u32 cltv_expiry, struct amount_msat msat, u32 cltv_expiry,
const struct sha256 *payment_hash, const struct sha256 *payment_hash,
const struct secret *shared_secret TAKES, const struct secret *shared_secret TAKES,
const struct pubkey *blinding TAKES,
const struct secret *blinding_ss,
const u8 *onion_routing_packet); const u8 *onion_routing_packet);
/* You need to set the ID, then connect_htlc_out this! */ /* You need to set the ID, then connect_htlc_out this! */
@ -142,6 +152,7 @@ struct htlc_out *new_htlc_out(const tal_t *ctx,
u32 cltv_expiry, u32 cltv_expiry,
const struct sha256 *payment_hash, const struct sha256 *payment_hash,
const u8 *onion_routing_packet, const u8 *onion_routing_packet,
const struct pubkey *blinding,
bool am_origin, bool am_origin,
u64 partid, u64 partid,
struct htlc_in *in); struct htlc_in *in);

17
lightningd/pay.c

@ -732,12 +732,13 @@ static bool should_use_tlv(enum route_hop_style style)
/* Returns failmsg on failure, tallocated off ctx */ /* Returns failmsg on failure, tallocated off ctx */
static const u8 *send_onion(const tal_t *ctx, struct lightningd *ld, static const u8 *send_onion(const tal_t *ctx, struct lightningd *ld,
const struct onionpacket *packet, const struct onionpacket *packet,
const struct route_hop *first_hop, const struct route_hop *first_hop,
const struct sha256 *payment_hash, const struct sha256 *payment_hash,
u64 partid, const struct pubkey *blinding,
struct channel *channel, u64 partid,
struct htlc_out **hout) struct channel *channel,
struct htlc_out **hout)
{ {
const u8 *onion; const u8 *onion;
unsigned int base_expiry; unsigned int base_expiry;
@ -746,7 +747,7 @@ static const u8 *send_onion(const tal_t *ctx, struct lightningd *ld,
onion = serialize_onionpacket(tmpctx, packet); onion = serialize_onionpacket(tmpctx, packet);
return send_htlc_out(ctx, channel, first_hop->amount, return send_htlc_out(ctx, channel, first_hop->amount,
base_expiry + first_hop->delay, base_expiry + first_hop->delay,
payment_hash, partid, onion, NULL, hout, payment_hash, blinding, partid, onion, NULL, hout,
&dont_care_about_channel_update); &dont_care_about_channel_update);
} }
@ -887,7 +888,7 @@ send_payment_core(struct lightningd *ld,
return command_failed(cmd, data); return command_failed(cmd, data);
} }
failmsg = send_onion(tmpctx, ld, packet, first_hop, rhash, partid, failmsg = send_onion(tmpctx, ld, packet, first_hop, rhash, NULL, partid,
channel, &hout); channel, &hout);
if (failmsg) { if (failmsg) {

116
lightningd/peer_htlcs.c

@ -6,6 +6,8 @@
#include <ccan/mem/mem.h> #include <ccan/mem/mem.h>
#include <ccan/tal/str/str.h> #include <ccan/tal/str/str.h>
#include <channeld/gen_channel_wire.h> #include <channeld/gen_channel_wire.h>
#include <common/blinding.h>
#include <common/ecdh.h>
#include <common/json_command.h> #include <common/json_command.h>
#include <common/jsonrpc_errors.h> #include <common/jsonrpc_errors.h>
#include <common/onion.h> #include <common/onion.h>
@ -204,7 +206,15 @@ static void fail_in_htlc(struct htlc_in *hin,
htlc_in_update_state(hin->key.channel, hin, SENT_REMOVE_HTLC); htlc_in_update_state(hin->key.channel, hin, SENT_REMOVE_HTLC);
htlc_in_check(hin, __func__); htlc_in_check(hin, __func__);
failed_htlc = mk_failed_htlc(tmpctx, hin, hin->failonion); #if EXPERIMENTAL_FEATURES
/* In a blinded path, all failures become invalid_onion_blinding */
if (hin->blinding) {
failed_htlc = mk_failed_htlc_badonion(tmpctx, hin,
WIRE_INVALID_ONION_BLINDING);
} else
#endif
failed_htlc = mk_failed_htlc(tmpctx, hin, hin->failonion);
tell_channeld_htlc_failed(hin, failed_htlc); tell_channeld_htlc_failed(hin, failed_htlc);
} }
@ -599,6 +609,7 @@ const u8 *send_htlc_out(const tal_t *ctx,
struct channel *out, struct channel *out,
struct amount_msat amount, u32 cltv, struct amount_msat amount, u32 cltv,
const struct sha256 *payment_hash, const struct sha256 *payment_hash,
const struct pubkey *blinding,
u64 partid, u64 partid,
const u8 *onion_routing_packet, const u8 *onion_routing_packet,
struct htlc_in *in, struct htlc_in *in,
@ -631,7 +642,8 @@ const u8 *send_htlc_out(const tal_t *ctx,
/* Make peer's daemon own it, catch if it dies. */ /* Make peer's daemon own it, catch if it dies. */
*houtp = new_htlc_out(out->owner, out, amount, cltv, *houtp = new_htlc_out(out->owner, out, amount, cltv,
payment_hash, onion_routing_packet, in == NULL, payment_hash, onion_routing_packet,
blinding, in == NULL,
partid, in); partid, in);
tal_add_destructor(*houtp, destroy_hout_subd_died); tal_add_destructor(*houtp, destroy_hout_subd_died);
@ -642,7 +654,7 @@ const u8 *send_htlc_out(const tal_t *ctx,
htlc_offer_timeout, htlc_offer_timeout,
out); out);
msg = towire_channel_offer_htlc(out, amount, cltv, payment_hash, msg = towire_channel_offer_htlc(out, amount, cltv, payment_hash,
onion_routing_packet); onion_routing_packet, blinding);
subd_req(out->peer->ld, out->owner, take(msg), -1, 0, rcvd_htlc_reply, subd_req(out->peer->ld, out->owner, take(msg), -1, 0, rcvd_htlc_reply,
*houtp); *houtp);
@ -654,7 +666,8 @@ static void forward_htlc(struct htlc_in *hin,
struct amount_msat amt_to_forward, struct amount_msat amt_to_forward,
u32 outgoing_cltv_value, u32 outgoing_cltv_value,
const struct short_channel_id *scid, const struct short_channel_id *scid,
const u8 next_onion[TOTAL_PACKET_SIZE]) const u8 next_onion[TOTAL_PACKET_SIZE],
const struct pubkey *next_blinding)
{ {
const u8 *failmsg; const u8 *failmsg;
struct amount_msat fee; struct amount_msat fee;
@ -749,7 +762,7 @@ static void forward_htlc(struct htlc_in *hin,
failmsg = send_htlc_out(tmpctx, next, amt_to_forward, failmsg = send_htlc_out(tmpctx, next, amt_to_forward,
outgoing_cltv_value, &hin->payment_hash, outgoing_cltv_value, &hin->payment_hash,
0, next_onion, hin, next_blinding, 0, next_onion, hin,
&hout, &needs_update_appended); &hout, &needs_update_appended);
if (!failmsg) if (!failmsg)
return; return;
@ -775,6 +788,7 @@ struct htlc_accepted_hook_payload {
struct htlc_in *hin; struct htlc_in *hin;
struct channel *channel; struct channel *channel;
struct lightningd *ld; struct lightningd *ld;
struct pubkey *next_blinding;
u8 *next_onion; u8 *next_onion;
u64 failtlvtype; u64 failtlvtype;
size_t failtlvpos; size_t failtlvpos;
@ -988,7 +1002,8 @@ htlc_accepted_hook_callback(struct htlc_accepted_hook_payload *request,
request->payload->amt_to_forward, request->payload->amt_to_forward,
request->payload->outgoing_cltv, request->payload->outgoing_cltv,
request->payload->forward_channel, request->payload->forward_channel,
serialize_onionpacket(tmpctx, rs->next)); serialize_onionpacket(tmpctx, rs->next),
request->next_blinding);
} else } else
handle_localpay(hin, handle_localpay(hin,
request->payload->amt_to_forward, request->payload->amt_to_forward,
@ -1015,6 +1030,35 @@ REGISTER_PLUGIN_HOOK(htlc_accepted, PLUGIN_HOOK_CHAIN,
htlc_accepted_hook_serialize, htlc_accepted_hook_serialize,
struct htlc_accepted_hook_payload *); struct htlc_accepted_hook_payload *);
/* Apply tweak to ephemeral key if blinding is non-NULL, then do ECDH */
static bool ecdh_maybe_blinding(const struct pubkey *ephemeral_key,
const struct pubkey *blinding,
const struct secret *blinding_ss,
struct secret *ss)
{
struct pubkey point = *ephemeral_key;
#if EXPERIMENTAL_FEATURES
if (blinding) {
struct secret hmac;
/* b(i) = HMAC256("blinded_node_id", ss(i)) * k(i) */
subkey_from_hmac("blinded_node_id", blinding_ss, &hmac);
/* We instead tweak the *ephemeral* key from the onion and use
* our normal privkey: since hsmd knows only how to ECDH with
* our real key */
if (secp256k1_ec_pubkey_tweak_mul(secp256k1_ctx,
&point.pubkey,
hmac.data) != 1) {
return false;
}
}
#endif /* EXPERIMENTAL_FEATURES */
ecdh(&point, ss);
return true;
}
/** /**
* Everyone is committed to this htlc of theirs * Everyone is committed to this htlc of theirs
* *
@ -1048,12 +1092,12 @@ static bool peer_accepted_htlc(const tal_t *ctx,
channel_internal_error(channel, channel_internal_error(channel,
"peer_got_revoke unknown htlc %"PRIu64, id); "peer_got_revoke unknown htlc %"PRIu64, id);
*failmsg = towire_temporary_node_failure(ctx); *failmsg = towire_temporary_node_failure(ctx);
return false; goto fail;
} }
if (!replay && !htlc_in_update_state(channel, hin, RCVD_ADD_ACK_REVOCATION)) { if (!replay && !htlc_in_update_state(channel, hin, RCVD_ADD_ACK_REVOCATION)) {
*failmsg = towire_temporary_node_failure(ctx); *failmsg = towire_temporary_node_failure(ctx);
return false; goto fail;
} }
htlc_in_check(hin, __func__); htlc_in_check(hin, __func__);
@ -1075,7 +1119,7 @@ static bool peer_accepted_htlc(const tal_t *ctx,
"Rejecting their htlc %"PRIu64 "Rejecting their htlc %"PRIu64
" since we're shutting down", " since we're shutting down",
id); id);
return false; goto fail;
} }
/* BOLT #2: /* BOLT #2:
@ -1099,7 +1143,7 @@ static bool peer_accepted_htlc(const tal_t *ctx,
" since onion is unparsable %s", " since onion is unparsable %s",
id, onion_type_name(*badonion)); id, onion_type_name(*badonion));
/* Now we can fail it. */ /* Now we can fail it. */
return false; goto fail;
} }
rs = process_onionpacket(tmpctx, &op, hin->shared_secret, rs = process_onionpacket(tmpctx, &op, hin->shared_secret,
@ -1109,16 +1153,17 @@ static bool peer_accepted_htlc(const tal_t *ctx,
*badonion = WIRE_INVALID_ONION_HMAC; *badonion = WIRE_INVALID_ONION_HMAC;
log_debug(channel->log, log_debug(channel->log,
"Rejecting their htlc %"PRIu64 "Rejecting their htlc %"PRIu64
" since onion is unprocessable %s", " since onion is unprocessable %s ss=%s",
id, onion_type_name(*badonion)); id, onion_type_name(*badonion),
return false; type_to_string(tmpctx, struct secret, hin->shared_secret));
goto fail;
} }
hook_payload = tal(hin, struct htlc_accepted_hook_payload); hook_payload = tal(hin, struct htlc_accepted_hook_payload);
hook_payload->route_step = tal_steal(hook_payload, rs); hook_payload->route_step = tal_steal(hook_payload, rs);
hook_payload->payload = onion_decode(hook_payload, rs, hook_payload->payload = onion_decode(hook_payload, rs,
NULL, NULL, hin->blinding, &hin->blinding_ss,
&hook_payload->failtlvtype, &hook_payload->failtlvtype,
&hook_payload->failtlvpos); &hook_payload->failtlvpos);
hook_payload->ld = ld; hook_payload->ld = ld;
@ -1126,10 +1171,34 @@ static bool peer_accepted_htlc(const tal_t *ctx,
hook_payload->channel = channel; hook_payload->channel = channel;
hook_payload->next_onion = serialize_onionpacket(hook_payload, rs->next); hook_payload->next_onion = serialize_onionpacket(hook_payload, rs->next);
#if EXPERIMENTAL_FEATURES
/* We could have blinding from hin or from inside onion. */
if (hook_payload->payload && hook_payload->payload->blinding) {
struct sha256 sha;
blinding_hash_e_and_ss(hook_payload->payload->blinding,
&hook_payload->payload->blinding_ss,
&sha);
hook_payload->next_blinding = tal(hook_payload, struct pubkey);
blinding_next_pubkey(hook_payload->payload->blinding, &sha,
hook_payload->next_blinding);
} else
#endif
hook_payload->next_blinding = NULL;
plugin_hook_call_htlc_accepted(ld, hook_payload, hook_payload); plugin_hook_call_htlc_accepted(ld, hook_payload, hook_payload);
/* Falling through here is ok, after all the HTLC locked */ /* Falling through here is ok, after all the HTLC locked */
return true; return true;
fail:
#if EXPERIMENTAL_FEATURES
/* In a blinded path, *all* failures are "invalid_onion_blinding" */
if (hin->blinding) {
*failmsg = tal_free(*failmsg);
*badonion = WIRE_INVALID_ONION_BLINDING;
}
#endif
return false;
} }
static void fulfill_our_htlc_out(struct channel *channel, struct htlc_out *hout, static void fulfill_our_htlc_out(struct channel *channel, struct htlc_out *hout,
@ -1659,18 +1728,18 @@ static bool channel_added_their_htlc(struct channel *channel,
} }
/* Do the work of extracting shared secret now if possible. */ /* Do the work of extracting shared secret now if possible. */
/* FIXME: We do this *again* in peer_accepted_htlc! */
failcode = parse_onionpacket(added->onion_routing_packet, failcode = parse_onionpacket(added->onion_routing_packet,
sizeof(added->onion_routing_packet), sizeof(added->onion_routing_packet),
&op); &op);
if (!failcode) { if (!failcode) {
/* Because wire takes struct pubkey. */ if (!ecdh_maybe_blinding(&op.ephemeralkey,
u8 *msg = towire_hsm_ecdh_req(tmpctx, &op.ephemeralkey); added->blinding, &added->blinding_ss,
if (!wire_sync_write(ld->hsm_fd, take(msg))) &shared_secret)) {
fatal("Could not write to HSM: %s", strerror(errno)); log_debug(channel->log, "htlc %"PRIu64
": can't tweak pubkey", added->id);
msg = wire_sync_read(tmpctx, ld->hsm_fd); return false;
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* /* This stays around even if we fail it immediately: it *is*
@ -1678,6 +1747,7 @@ static bool channel_added_their_htlc(struct channel *channel,
hin = new_htlc_in(channel, channel, added->id, added->amount, hin = new_htlc_in(channel, channel, added->id, added->amount,
added->cltv_expiry, &added->payment_hash, added->cltv_expiry, &added->payment_hash,
failcode ? NULL : &shared_secret, failcode ? NULL : &shared_secret,
added->blinding, &added->blinding_ss,
added->onion_routing_packet); added->onion_routing_packet);
/* Save an incoming htlc to the wallet */ /* Save an incoming htlc to the wallet */
@ -2006,6 +2076,7 @@ const struct existing_htlc **peer_htlcs(const tal_t *ctx,
hin->msat, &hin->payment_hash, hin->msat, &hin->payment_hash,
hin->cltv_expiry, hin->cltv_expiry,
hin->onion_routing_packet, hin->onion_routing_packet,
hin->blinding,
hin->preimage, hin->preimage,
f); f);
tal_arr_expand(&htlcs, existing); tal_arr_expand(&htlcs, existing);
@ -2037,6 +2108,7 @@ const struct existing_htlc **peer_htlcs(const tal_t *ctx,
hout->msat, &hout->payment_hash, hout->msat, &hout->payment_hash,
hout->cltv_expiry, hout->cltv_expiry,
hout->onion_routing_packet, hout->onion_routing_packet,
hout->blinding,
hout->preimage, hout->preimage,
f); f);
tal_arr_expand(&htlcs, existing); tal_arr_expand(&htlcs, existing);

1
lightningd/peer_htlcs.h

@ -46,6 +46,7 @@ const u8 *send_htlc_out(const tal_t *ctx,
struct channel *out, struct channel *out,
struct amount_msat amount, u32 cltv, struct amount_msat amount, u32 cltv,
const struct sha256 *payment_hash, const struct sha256 *payment_hash,
const struct pubkey *blinding,
u64 partid, u64 partid,
const u8 *onion_routing_packet, const u8 *onion_routing_packet,
struct htlc_in *in, struct htlc_in *in,

8
lightningd/test/run-invoice-select-inchan.c

@ -23,7 +23,7 @@ void bitcoind_getutxout_(struct bitcoind *bitcoind UNNEEDED,
{ fprintf(stderr, "bitcoind_getutxout_ called!\n"); abort(); } { fprintf(stderr, "bitcoind_getutxout_ called!\n"); abort(); }
/* Generated stub for bolt11_decode */ /* Generated stub for bolt11_decode */
struct bolt11 *bolt11_decode(const tal_t *ctx UNNEEDED, const char *str UNNEEDED, struct bolt11 *bolt11_decode(const tal_t *ctx UNNEEDED, const char *str UNNEEDED,
const struct feature_set *fset UNNEEDED, const struct feature_set *our_features UNNEEDED,
const char *description UNNEEDED, char **fail UNNEEDED) const char *description UNNEEDED, char **fail UNNEEDED)
{ fprintf(stderr, "bolt11_decode called!\n"); abort(); } { fprintf(stderr, "bolt11_decode called!\n"); abort(); }
/* Generated stub for bolt11_encode_ */ /* Generated stub for bolt11_encode_ */
@ -48,9 +48,6 @@ bool channel_tell_depth(struct lightningd *ld UNNEEDED,
const struct bitcoin_txid *txid UNNEEDED, const struct bitcoin_txid *txid UNNEEDED,
u32 depth UNNEEDED) u32 depth UNNEEDED)
{ fprintf(stderr, "channel_tell_depth called!\n"); abort(); } { fprintf(stderr, "channel_tell_depth called!\n"); abort(); }
/* Generated stub for command_check_only */
bool command_check_only(const struct command *cmd UNNEEDED)
{ fprintf(stderr, "command_check_only called!\n"); abort(); }
/* Generated stub for command_fail */ /* Generated stub for command_fail */
struct command_result *command_fail(struct command *cmd UNNEEDED, errcode_t code UNNEEDED, struct command_result *command_fail(struct command *cmd UNNEEDED, errcode_t code UNNEEDED,
const char *fmt UNNEEDED, ...) const char *fmt UNNEEDED, ...)
@ -103,9 +100,6 @@ void fatal(const char *fmt UNNEEDED, ...)
/* Generated stub for feature_is_set */ /* Generated stub for feature_is_set */
bool feature_is_set(const u8 *features UNNEEDED, size_t bit UNNEEDED) bool feature_is_set(const u8 *features UNNEEDED, size_t bit UNNEEDED)
{ fprintf(stderr, "feature_is_set called!\n"); abort(); } { fprintf(stderr, "feature_is_set called!\n"); abort(); }
/* Generated stub for featurebits_or */
u8 *featurebits_or(const tal_t *ctx UNNEEDED, const u8 *f1 TAKES UNNEEDED, const u8 *f2 TAKES UNNEEDED)
{ fprintf(stderr, "featurebits_or called!\n"); abort(); }
/* Generated stub for fixup_htlcs_out */ /* Generated stub for fixup_htlcs_out */
void fixup_htlcs_out(struct lightningd *ld UNNEEDED) void fixup_htlcs_out(struct lightningd *ld UNNEEDED)
{ fprintf(stderr, "fixup_htlcs_out called!\n"); abort(); } { fprintf(stderr, "fixup_htlcs_out called!\n"); abort(); }

38
wallet/test/run-wallet.c

@ -45,6 +45,16 @@ void bitcoind_getutxout_(struct bitcoind *bitcoind UNNEEDED,
void *arg) UNNEEDED, void *arg) UNNEEDED,
void *arg UNNEEDED) void *arg UNNEEDED)
{ fprintf(stderr, "bitcoind_getutxout_ called!\n"); abort(); } { fprintf(stderr, "bitcoind_getutxout_ called!\n"); abort(); }
/* Generated stub for blinding_hash_e_and_ss */
void blinding_hash_e_and_ss(const struct pubkey *e UNNEEDED,
const struct secret *ss UNNEEDED,
struct sha256 *sha UNNEEDED)
{ fprintf(stderr, "blinding_hash_e_and_ss called!\n"); abort(); }
/* Generated stub for blinding_next_pubkey */
bool blinding_next_pubkey(const struct pubkey *pk UNNEEDED,
const struct sha256 *h UNNEEDED,
struct pubkey *next UNNEEDED)
{ fprintf(stderr, "blinding_next_pubkey called!\n"); abort(); }
/* Generated stub for broadcast_tx */ /* Generated stub for broadcast_tx */
void broadcast_tx(struct chain_topology *topo UNNEEDED, void broadcast_tx(struct chain_topology *topo UNNEEDED,
struct channel *channel UNNEEDED, const struct bitcoin_tx *tx UNNEEDED, struct channel *channel UNNEEDED, const struct bitcoin_tx *tx UNNEEDED,
@ -58,9 +68,6 @@ bool channel_tell_depth(struct lightningd *ld UNNEEDED,
const struct bitcoin_txid *txid UNNEEDED, const struct bitcoin_txid *txid UNNEEDED,
u32 depth UNNEEDED) u32 depth UNNEEDED)
{ fprintf(stderr, "channel_tell_depth called!\n"); abort(); } { fprintf(stderr, "channel_tell_depth called!\n"); abort(); }
/* Generated stub for command_check_only */
bool command_check_only(const struct command *cmd UNNEEDED)
{ fprintf(stderr, "command_check_only called!\n"); abort(); }
/* Generated stub for command_fail */ /* Generated stub for command_fail */
struct command_result *command_fail(struct command *cmd UNNEEDED, errcode_t code UNNEEDED, struct command_result *command_fail(struct command *cmd UNNEEDED, errcode_t code UNNEEDED,
const char *fmt UNNEEDED, ...) const char *fmt UNNEEDED, ...)
@ -91,6 +98,9 @@ struct onionreply *create_onionreply(const tal_t *ctx UNNEEDED,
void delay_then_reconnect(struct channel *channel UNNEEDED, u32 seconds_delay UNNEEDED, void delay_then_reconnect(struct channel *channel UNNEEDED, u32 seconds_delay UNNEEDED,
const struct wireaddr_internal *addrhint TAKES UNNEEDED) const struct wireaddr_internal *addrhint TAKES UNNEEDED)
{ fprintf(stderr, "delay_then_reconnect called!\n"); abort(); } { fprintf(stderr, "delay_then_reconnect called!\n"); abort(); }
/* Generated stub for ecdh */
void ecdh(const struct pubkey *point UNNEEDED, struct secret *ss UNNEEDED)
{ fprintf(stderr, "ecdh called!\n"); abort(); }
/* Generated stub for encode_scriptpubkey_to_addr */ /* Generated stub for encode_scriptpubkey_to_addr */
char *encode_scriptpubkey_to_addr(const tal_t *ctx UNNEEDED, char *encode_scriptpubkey_to_addr(const tal_t *ctx UNNEEDED,
const struct chainparams *chainparams UNNEEDED, const struct chainparams *chainparams UNNEEDED,
@ -123,9 +133,6 @@ bool fromwire_custommsg_in(const tal_t *ctx UNNEEDED, const void *p UNNEEDED, u8
/* Generated stub for fromwire_gossip_get_stripped_cupdate_reply */ /* Generated stub for fromwire_gossip_get_stripped_cupdate_reply */
bool fromwire_gossip_get_stripped_cupdate_reply(const tal_t *ctx UNNEEDED, const void *p UNNEEDED, u8 **stripped_update UNNEEDED) bool fromwire_gossip_get_stripped_cupdate_reply(const tal_t *ctx UNNEEDED, const void *p UNNEEDED, u8 **stripped_update UNNEEDED)
{ fprintf(stderr, "fromwire_gossip_get_stripped_cupdate_reply called!\n"); abort(); } { fprintf(stderr, "fromwire_gossip_get_stripped_cupdate_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 */ /* 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) 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(); } { fprintf(stderr, "fromwire_hsm_sign_commitment_tx_reply called!\n"); abort(); }
@ -342,15 +349,6 @@ char *json_strdup(const tal_t *ctx UNNEEDED, const char *buffer UNNEEDED, const
/* Generated stub for json_stream_success */ /* Generated stub for json_stream_success */
struct json_stream *json_stream_success(struct command *cmd UNNEEDED) struct json_stream *json_stream_success(struct command *cmd UNNEEDED)
{ fprintf(stderr, "json_stream_success called!\n"); abort(); } { fprintf(stderr, "json_stream_success called!\n"); abort(); }
/* Generated stub for json_to_address_scriptpubkey */
enum address_parse_result json_to_address_scriptpubkey(const tal_t *ctx UNNEEDED,
const struct chainparams *chainparams UNNEEDED,
const char *buffer UNNEEDED,
const jsmntok_t *tok UNNEEDED, const u8 **scriptpubkey UNNEEDED)
{ fprintf(stderr, "json_to_address_scriptpubkey called!\n"); abort(); }
/* Generated stub for json_to_bool */
bool json_to_bool(const char *buffer UNNEEDED, const jsmntok_t *tok UNNEEDED, bool *b UNNEEDED)
{ fprintf(stderr, "json_to_bool called!\n"); abort(); }
/* Generated stub for json_to_node_id */ /* Generated stub for json_to_node_id */
bool json_to_node_id(const char *buffer UNNEEDED, const jsmntok_t *tok UNNEEDED, bool json_to_node_id(const char *buffer UNNEEDED, const jsmntok_t *tok UNNEEDED,
struct node_id *id UNNEEDED) struct node_id *id UNNEEDED)
@ -580,6 +578,11 @@ void subd_req_(const tal_t *ctx UNNEEDED,
/* Generated stub for subd_send_msg */ /* Generated stub for subd_send_msg */
void subd_send_msg(struct subd *sd UNNEEDED, const u8 *msg_out UNNEEDED) void subd_send_msg(struct subd *sd UNNEEDED, const u8 *msg_out UNNEEDED)
{ fprintf(stderr, "subd_send_msg called!\n"); abort(); } { fprintf(stderr, "subd_send_msg called!\n"); abort(); }
/* Generated stub for subkey_from_hmac */
void subkey_from_hmac(const char *prefix UNNEEDED,
const struct secret *base UNNEEDED,
struct secret *key UNNEEDED)
{ fprintf(stderr, "subkey_from_hmac called!\n"); abort(); }
/* Generated stub for topology_add_sync_waiter_ */ /* Generated stub for topology_add_sync_waiter_ */
void topology_add_sync_waiter_(const tal_t *ctx UNNEEDED, void topology_add_sync_waiter_(const tal_t *ctx UNNEEDED,
struct chain_topology *topo UNNEEDED, struct chain_topology *topo UNNEEDED,
@ -609,7 +612,7 @@ u8 *towire_channel_got_commitsig_reply(const tal_t *ctx UNNEEDED)
u8 *towire_channel_got_revoke_reply(const tal_t *ctx UNNEEDED) u8 *towire_channel_got_revoke_reply(const tal_t *ctx UNNEEDED)
{ fprintf(stderr, "towire_channel_got_revoke_reply called!\n"); abort(); } { fprintf(stderr, "towire_channel_got_revoke_reply called!\n"); abort(); }
/* Generated stub for towire_channel_offer_htlc */ /* Generated stub for towire_channel_offer_htlc */
u8 *towire_channel_offer_htlc(const tal_t *ctx UNNEEDED, struct amount_msat amount_msat UNNEEDED, u32 cltv_expiry UNNEEDED, const struct sha256 *payment_hash UNNEEDED, const u8 onion_routing_packet[1366]) u8 *towire_channel_offer_htlc(const tal_t *ctx UNNEEDED, struct amount_msat amount_msat UNNEEDED, u32 cltv_expiry UNNEEDED, const struct sha256 *payment_hash UNNEEDED, const u8 onion_routing_packet[1366] UNNEEDED, const struct pubkey *blinding UNNEEDED)
{ fprintf(stderr, "towire_channel_offer_htlc called!\n"); abort(); } { fprintf(stderr, "towire_channel_offer_htlc called!\n"); abort(); }
/* Generated stub for towire_channel_send_shutdown */ /* Generated stub for towire_channel_send_shutdown */
u8 *towire_channel_send_shutdown(const tal_t *ctx UNNEEDED, const u8 *shutdown_scriptpubkey UNNEEDED) u8 *towire_channel_send_shutdown(const tal_t *ctx UNNEEDED, const u8 *shutdown_scriptpubkey UNNEEDED)
@ -652,9 +655,6 @@ u8 *towire_final_incorrect_htlc_amount(const tal_t *ctx UNNEEDED, struct amount_
/* Generated stub for towire_gossip_get_stripped_cupdate */ /* Generated stub for towire_gossip_get_stripped_cupdate */
u8 *towire_gossip_get_stripped_cupdate(const tal_t *ctx UNNEEDED, const struct short_channel_id *channel_id UNNEEDED) u8 *towire_gossip_get_stripped_cupdate(const tal_t *ctx UNNEEDED, const struct short_channel_id *channel_id UNNEEDED)
{ fprintf(stderr, "towire_gossip_get_stripped_cupdate called!\n"); abort(); } { fprintf(stderr, "towire_gossip_get_stripped_cupdate 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 */ /* 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) 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(); } { fprintf(stderr, "towire_hsm_sign_commitment_tx called!\n"); abort(); }

4
wallet/wallet.c

@ -1812,6 +1812,8 @@ static bool wallet_stmt2htlc_in(struct channel *channel,
db_column_amount_msat(stmt, 2, &in->msat); db_column_amount_msat(stmt, 2, &in->msat);
in->cltv_expiry = db_column_int(stmt, 3); in->cltv_expiry = db_column_int(stmt, 3);
in->hstate = db_column_int(stmt, 4); in->hstate = db_column_int(stmt, 4);
/* FIXME: save blinding in db !*/
in->blinding = NULL;
db_column_sha256(stmt, 5, &in->payment_hash); db_column_sha256(stmt, 5, &in->payment_hash);
@ -1884,6 +1886,8 @@ static bool wallet_stmt2htlc_out(struct wallet *wallet,
out->cltv_expiry = db_column_int(stmt, 3); out->cltv_expiry = db_column_int(stmt, 3);
out->hstate = db_column_int(stmt, 4); out->hstate = db_column_int(stmt, 4);
db_column_sha256(stmt, 5, &out->payment_hash); db_column_sha256(stmt, 5, &out->payment_hash);
/* FIXME: save blinding in db !*/
out->blinding = NULL;
if (!db_column_is_null(stmt, 6)) { if (!db_column_is_null(stmt, 6)) {
out->preimage = tal(out, struct preimage); out->preimage = tal(out, struct preimage);

2
wire/extracted_peer_experimental_add_htlc-plus-blinding

@ -8,7 +8,7 @@ index 5a2a8c23f..7b26242e3 100644
msgdata,update_add_htlc,onion_routing_packet,byte,1366 msgdata,update_add_htlc,onion_routing_packet,byte,1366
+msgdata,update_add_htlc,tlvs,update_add_tlvs, +msgdata,update_add_htlc,tlvs,update_add_tlvs,
+tlvtype,update_add_tlvs,blinding,2 +tlvtype,update_add_tlvs,blinding,2
+tlvdata,update_add_tlvs,blinding,ecdh,byte,32 +tlvdata,update_add_tlvs,blinding,blinding,point,
msgtype,update_fulfill_htlc,130 msgtype,update_fulfill_htlc,130
msgdata,update_fulfill_htlc,channel_id,channel_id, msgdata,update_fulfill_htlc,channel_id,channel_id,
msgdata,update_fulfill_htlc,id,u64, msgdata,update_fulfill_htlc,id,u64,

Loading…
Cancel
Save