Browse Source

common: use struct onionreply.

This makes it clear we're dealing with a message which is a wrapped error
reply (needing unwrap_onionreply), not an already-wrapped one.

Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
travis-debug
Rusty Russell 5 years ago
parent
commit
1099f6a5e1
  1. 1
      channeld/Makefile
  2. 15
      channeld/channeld.c
  3. 2
      channeld/channeld_htlc.h
  4. 6
      channeld/full_channel.c
  5. 4
      channeld/test/run-full_channel.c
  6. 1
      closingd/Makefile
  7. 15
      common/htlc_wire.c
  8. 2
      common/htlc_wire.h
  9. 53
      common/sphinx.c
  10. 15
      common/sphinx.h
  11. 9
      common/test/run-sphinx.c
  12. 1
      connectd/Makefile
  13. 1
      devtools/Makefile
  14. 1
      gossipd/Makefile
  15. 1
      lightningd/Makefile
  16. 4
      lightningd/htlc_end.h
  17. 6
      lightningd/notification.c
  18. 4
      lightningd/notification.h
  19. 11
      lightningd/pay.c
  20. 3
      lightningd/pay.h
  21. 16
      lightningd/peer_htlcs.c
  22. 1
      onchaind/Makefile
  23. 1
      openingd/Makefile
  24. 1
      wallet/test/Makefile
  25. 7
      wallet/test/run-wallet.c
  26. 28
      wallet/wallet.c
  27. 7
      wallet/wallet.h

1
channeld/Makefile

@ -63,6 +63,7 @@ CHANNELD_COMMON_OBJS := \
common/msg_queue.o \ common/msg_queue.o \
common/node_id.o \ common/node_id.o \
common/onion.o \ common/onion.o \
common/onionreply.o \
common/peer_billboard.o \ common/peer_billboard.o \
common/peer_failed.o \ common/peer_failed.o \
common/per_peer_state.o \ common/per_peer_state.o \

15
channeld/channeld.c

@ -36,6 +36,7 @@
#include <common/memleak.h> #include <common/memleak.h>
#include <common/msg_queue.h> #include <common/msg_queue.h>
#include <common/node_id.h> #include <common/node_id.h>
#include <common/onionreply.h>
#include <common/peer_billboard.h> #include <common/peer_billboard.h>
#include <common/peer_failed.h> #include <common/peer_failed.h>
#include <common/ping.h> #include <common/ping.h>
@ -1306,7 +1307,7 @@ static void marshall_htlc_info(const tal_t *ctx,
f = tal(*failed, struct failed_htlc); f = tal(*failed, struct failed_htlc);
f->id = htlc->id; f->id = htlc->id;
f->failcode = htlc->failcode; f->failcode = htlc->failcode;
f->failreason = cast_const(u8 *, htlc->fail); f->failreason = htlc->fail;
f->scid = cast_const(struct short_channel_id *, f->scid = cast_const(struct short_channel_id *,
htlc->failed_scid); htlc->failed_scid);
tal_arr_expand(failed, f); tal_arr_expand(failed, f);
@ -1656,6 +1657,7 @@ static void handle_peer_fail_htlc(struct peer *peer, const u8 *msg)
u8 *reason; u8 *reason;
struct htlc *htlc; struct htlc *htlc;
/* reason is not an onionreply because spec doesn't know about that */
if (!fromwire_update_fail_htlc(msg, msg, if (!fromwire_update_fail_htlc(msg, msg,
&channel_id, &id, &reason)) { &channel_id, &id, &reason)) {
peer_failed(peer->pps, peer_failed(peer->pps,
@ -1665,11 +1667,14 @@ static void handle_peer_fail_htlc(struct peer *peer, const u8 *msg)
e = channel_fail_htlc(peer->channel, LOCAL, id, &htlc); e = channel_fail_htlc(peer->channel, LOCAL, id, &htlc);
switch (e) { switch (e) {
case CHANNEL_ERR_REMOVE_OK: case CHANNEL_ERR_REMOVE_OK: {
/* Save reason for when we tell master. */ /* Save reason for when we tell master. */
htlc->fail = tal_steal(htlc, reason); struct onionreply *r = tal(htlc, struct onionreply);
r->contents = tal_steal(r, reason);
htlc->fail = r;
start_commit_timer(peer); start_commit_timer(peer);
return; return;
}
case CHANNEL_ERR_NO_SUCH_ID: case CHANNEL_ERR_NO_SUCH_ID:
case CHANNEL_ERR_ALREADY_FULFILLED: case CHANNEL_ERR_ALREADY_FULFILLED:
case CHANNEL_ERR_HTLC_UNCOMMITTED: case CHANNEL_ERR_HTLC_UNCOMMITTED:
@ -1934,7 +1939,7 @@ static void send_fail_or_fulfill(struct peer *peer, const struct htlc *h)
h->id, &sha256_of_onion, h->id, &sha256_of_onion,
h->why_bad_onion); h->why_bad_onion);
} else if (h->failcode || h->fail) { } else if (h->failcode || h->fail) {
const u8 *onion; const struct onionreply *onion;
if (h->failcode) { if (h->failcode) {
/* Local failure, make a message. */ /* Local failure, make a message. */
u8 *failmsg = make_failmsg(tmpctx, peer, h, h->failcode, u8 *failmsg = make_failmsg(tmpctx, peer, h, h->failcode,
@ -1950,7 +1955,7 @@ static void send_fail_or_fulfill(struct peer *peer, const struct htlc *h)
msg = towire_update_fail_htlc(peer, &peer->channel_id, h->id, msg = towire_update_fail_htlc(peer, &peer->channel_id, h->id,
wrap_onionreply(tmpctx, wrap_onionreply(tmpctx,
h->shared_secret, h->shared_secret,
onion)); onion)->contents);
} else if (h->r) { } else if (h->r) {
msg = towire_update_fulfill_htlc(NULL, &peer->channel_id, h->id, msg = towire_update_fulfill_htlc(NULL, &peer->channel_id, h->id,
h->r); h->r);

2
channeld/channeld_htlc.h

@ -34,7 +34,7 @@ struct htlc {
const u8 *routing; const u8 *routing;
/* Failure message we received or generated. */ /* Failure message we received or generated. */
const u8 *fail; const struct onionreply *fail;
/* For a local failure, we might have to generate fail ourselves /* For a local failure, we might have to generate fail ourselves
* (or, if BADONION we send a update_fail_malformed_htlc). */ * (or, if BADONION we send a update_fail_malformed_htlc). */
enum onion_type failcode; enum onion_type failcode;

6
channeld/full_channel.c

@ -17,6 +17,7 @@
#include <common/key_derive.h> #include <common/key_derive.h>
#include <common/keyset.h> #include <common/keyset.h>
#include <common/memleak.h> #include <common/memleak.h>
#include <common/onionreply.h>
#include <common/status.h> #include <common/status.h>
#include <common/type_to_string.h> #include <common/type_to_string.h>
#include <inttypes.h> #include <inttypes.h>
@ -1254,10 +1255,7 @@ bool channel_force_htlcs(struct channel *channel,
* a hint. */ * a hint. */
htlc->failblock = failheight; htlc->failblock = failheight;
if (failed[i]->failreason) if (failed[i]->failreason)
htlc->fail = tal_dup_arr(htlc, u8, htlc->fail = dup_onionreply(htlc, failed[i]->failreason);
failed[i]->failreason,
tal_count(failed[i]->failreason),
0);
else else
htlc->fail = NULL; htlc->fail = NULL;
if (failed[i]->scid) if (failed[i]->scid)

4
channeld/test/run-full_channel.c

@ -21,6 +21,10 @@ size_t bigsize_get(const u8 *p UNNEEDED, size_t max UNNEEDED, bigsize_t *val UNN
/* Generated stub for bigsize_put */ /* Generated stub for bigsize_put */
size_t bigsize_put(u8 buf[BIGSIZE_MAX_LEN] UNNEEDED, bigsize_t v UNNEEDED) size_t bigsize_put(u8 buf[BIGSIZE_MAX_LEN] UNNEEDED, bigsize_t v UNNEEDED)
{ fprintf(stderr, "bigsize_put called!\n"); abort(); } { 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_ */ /* Generated stub for memleak_add_helper_ */
void memleak_add_helper_(const tal_t *p UNNEEDED, void (*cb)(struct htable *memtable UNNEEDED, void memleak_add_helper_(const tal_t *p UNNEEDED, void (*cb)(struct htable *memtable UNNEEDED,
const tal_t *)){ } const tal_t *)){ }

1
closingd/Makefile

@ -63,6 +63,7 @@ CLOSINGD_COMMON_OBJS := \
common/key_derive.o \ common/key_derive.o \
common/memleak.o \ common/memleak.o \
common/msg_queue.o \ common/msg_queue.o \
common/onionreply.o \
common/peer_billboard.o \ common/peer_billboard.o \
common/peer_failed.o \ common/peer_failed.o \
common/per_peer_state.o \ common/per_peer_state.o \

15
common/htlc_wire.c

@ -3,6 +3,7 @@
#include <ccan/crypto/shachain/shachain.h> #include <ccan/crypto/shachain/shachain.h>
#include <common/htlc_wire.h> #include <common/htlc_wire.h>
#include <common/memleak.h> #include <common/memleak.h>
#include <common/onionreply.h>
#include <wire/wire.h> #include <wire/wire.h>
/* FIXME: We could adapt tools/generate-wire.py to generate structures /* FIXME: We could adapt tools/generate-wire.py to generate structures
@ -26,8 +27,8 @@ void towire_fulfilled_htlc(u8 **pptr, const struct fulfilled_htlc *fulfilled)
void towire_failed_htlc(u8 **pptr, const struct failed_htlc *failed) void towire_failed_htlc(u8 **pptr, const struct failed_htlc *failed)
{ {
/* Only one can be set. */ /* Only one can be set. */
assert(failed->failcode || tal_count(failed->failreason)); assert(failed->failcode || failed->failreason);
assert(!failed->failcode || !tal_count(failed->failreason)); assert(!failed->failcode || !failed->failreason);
towire_u64(pptr, failed->id); towire_u64(pptr, failed->id);
towire_u16(pptr, failed->failcode); towire_u16(pptr, failed->failcode);
if (failed->failcode & UPDATE) { if (failed->failcode & UPDATE) {
@ -37,9 +38,7 @@ void towire_failed_htlc(u8 **pptr, const struct failed_htlc *failed)
assert(!failed->scid); assert(!failed->scid);
if (!failed->failcode) { if (!failed->failcode) {
assert(failed->failreason); assert(failed->failreason);
towire_u16(pptr, tal_count(failed->failreason)); towire_onionreply(pptr, failed->failreason);
towire_u8_array(pptr, failed->failreason,
tal_count(failed->failreason));
} }
} }
} }
@ -98,12 +97,8 @@ struct failed_htlc *fromwire_failed_htlc(const tal_t *ctx, const u8 **cursor, si
failed->id = fromwire_u64(cursor, max); failed->id = fromwire_u64(cursor, max);
failed->failcode = fromwire_u16(cursor, max); failed->failcode = fromwire_u16(cursor, max);
if (failed->failcode == 0) { if (failed->failcode == 0) {
u16 failreason_len;
failed->scid = NULL; failed->scid = NULL;
failreason_len = fromwire_u16(cursor, max); failed->failreason = fromwire_onionreply(failed, cursor, max);
failed->failreason = tal_arr(failed, u8, failreason_len);
fromwire_u8_array(cursor, max, failed->failreason,
failreason_len);
} else { } else {
failed->failreason = NULL; failed->failreason = NULL;
if (failed->failcode & UPDATE) { if (failed->failcode & UPDATE) {

2
common/htlc_wire.h

@ -29,7 +29,7 @@ struct failed_htlc {
u64 id; u64 id;
/* Either this is 0 and failreason non-NULL, or vice versa. */ /* Either this is 0 and failreason non-NULL, or vice versa. */
enum onion_type failcode; enum onion_type failcode;
u8 *failreason; const struct onionreply *failreason;
/* Non-NULL if failcode & UPDATE */ /* Non-NULL if failcode & UPDATE */
struct short_channel_id *scid; struct short_channel_id *scid;
}; };

53
common/sphinx.c

@ -6,6 +6,7 @@
#include <ccan/mem/mem.h> #include <ccan/mem/mem.h>
#include <common/node_id.h> #include <common/node_id.h>
#include <common/onion.h> #include <common/onion.h>
#include <common/onionreply.h>
#include <common/sphinx.h> #include <common/sphinx.h>
#include <common/utils.h> #include <common/utils.h>
@ -529,12 +530,14 @@ struct route_step *process_onionpacket(
return step; return step;
} }
u8 *create_onionreply(const tal_t *ctx, const struct secret *shared_secret, struct onionreply *create_onionreply(const tal_t *ctx,
const u8 *failure_msg) const struct secret *shared_secret,
const u8 *failure_msg)
{ {
size_t msglen = tal_count(failure_msg); size_t msglen = tal_count(failure_msg);
size_t padlen = ONION_REPLY_SIZE - msglen; size_t padlen = ONION_REPLY_SIZE - msglen;
u8 *reply = tal_arr(ctx, u8, 0), *payload = tal_arr(ctx, u8, 0); struct onionreply *reply = tal(ctx, struct onionreply);
u8 *payload = tal_arr(ctx, u8, 0);
u8 key[KEY_LEN]; u8 key[KEY_LEN];
u8 hmac[HMAC_SIZE]; u8 hmac[HMAC_SIZE];
@ -574,21 +577,23 @@ u8 *create_onionreply(const tal_t *ctx, const struct secret *shared_secret,
generate_key(key, "um", 2, shared_secret->data); generate_key(key, "um", 2, shared_secret->data);
compute_hmac(hmac, payload, tal_count(payload), key, KEY_LEN); compute_hmac(hmac, payload, tal_count(payload), key, KEY_LEN);
towire(&reply, hmac, sizeof(hmac)); reply->contents = tal_arr(reply, u8, 0),
towire(&reply->contents, hmac, sizeof(hmac));
towire(&reply, payload, tal_count(payload)); towire(&reply->contents, payload, tal_count(payload));
tal_free(payload); tal_free(payload);
return reply; return reply;
} }
u8 *wrap_onionreply(const tal_t *ctx, struct onionreply *wrap_onionreply(const tal_t *ctx,
const struct secret *shared_secret, const u8 *reply) const struct secret *shared_secret,
const struct onionreply *reply)
{ {
u8 key[KEY_LEN]; u8 key[KEY_LEN];
size_t streamlen = tal_count(reply); size_t streamlen = tal_count(reply->contents);
u8 stream[streamlen]; u8 stream[streamlen];
u8 *result = tal_arr(ctx, u8, streamlen); struct onionreply *result = tal(ctx, struct onionreply);
/* BOLT #4: /* BOLT #4:
* *
@ -600,39 +605,43 @@ u8 *wrap_onionreply(const tal_t *ctx,
*/ */
generate_key(key, "ammag", 5, shared_secret->data); generate_key(key, "ammag", 5, shared_secret->data);
generate_cipher_stream(stream, key, streamlen); generate_cipher_stream(stream, key, streamlen);
xorbytes(result, stream, reply, streamlen); result->contents = tal_arr(result, u8, streamlen);
xorbytes(result->contents, stream, reply->contents, streamlen);
return result; return result;
} }
u8 *unwrap_onionreply(const tal_t *ctx, u8 *unwrap_onionreply(const tal_t *ctx,
const struct secret *shared_secrets, const struct secret *shared_secrets,
const int numhops, const u8 *reply, const int numhops,
const struct onionreply *reply,
int *origin_index) int *origin_index)
{ {
u8 *msg = tal_arr(tmpctx, u8, tal_count(reply)), *final; struct onionreply *r;
u8 key[KEY_LEN], hmac[HMAC_SIZE]; u8 key[KEY_LEN], hmac[HMAC_SIZE];
const u8 *cursor; const u8 *cursor;
u8 *final;
size_t max; size_t max;
u16 msglen; u16 msglen;
if (tal_count(reply) != ONION_REPLY_SIZE + sizeof(hmac) + 4) { if (tal_count(reply->contents) != ONION_REPLY_SIZE + sizeof(hmac) + 4) {
return NULL; return NULL;
} }
memcpy(msg, reply, tal_count(reply)); r = new_onionreply(tmpctx, reply->contents);
*origin_index = -1; *origin_index = -1;
for (int i = 0; i < numhops; i++) { for (int i = 0; i < numhops; i++) {
/* Since the encryption is just XORing with the cipher /* Since the encryption is just XORing with the cipher
* stream encryption is identical to decryption */ * stream encryption is identical to decryption */
msg = wrap_onionreply(tmpctx, &shared_secrets[i], msg); r = wrap_onionreply(tmpctx, &shared_secrets[i], r);
/* Check if the HMAC matches, this means that this is /* Check if the HMAC matches, this means that this is
* the origin */ * the origin */
generate_key(key, "um", 2, shared_secrets[i].data); generate_key(key, "um", 2, shared_secrets[i].data);
compute_hmac(hmac, msg + sizeof(hmac), compute_hmac(hmac, r->contents + sizeof(hmac),
tal_count(msg) - sizeof(hmac), key, KEY_LEN); tal_count(r->contents) - sizeof(hmac),
if (memcmp(hmac, msg, sizeof(hmac)) == 0) { key, KEY_LEN);
if (memcmp(hmac, r->contents, sizeof(hmac)) == 0) {
*origin_index = i; *origin_index = i;
break; break;
} }
@ -641,8 +650,8 @@ u8 *unwrap_onionreply(const tal_t *ctx,
return NULL; return NULL;
} }
cursor = msg + sizeof(hmac); cursor = r->contents + sizeof(hmac);
max = tal_count(msg) - sizeof(hmac); max = tal_count(r->contents) - sizeof(hmac);
msglen = fromwire_u16(&cursor, &max); msglen = fromwire_u16(&cursor, &max);
if (msglen > ONION_REPLY_SIZE) { if (msglen > ONION_REPLY_SIZE) {
@ -650,7 +659,7 @@ u8 *unwrap_onionreply(const tal_t *ctx,
} }
final = tal_arr(ctx, u8, msglen); final = tal_arr(ctx, u8, msglen);
fromwire(&cursor, &max, final, msglen); if (!fromwire(&cursor, &max, final, msglen))
return tal_free(final);
return final; return final;
} }

15
common/sphinx.h

@ -164,8 +164,9 @@ enum onion_type parse_onionpacket(const u8 *src,
* HMAC * HMAC
* @failure_msg: message (must support tal_len) * @failure_msg: message (must support tal_len)
*/ */
u8 *create_onionreply(const tal_t *ctx, const struct secret *shared_secret, struct onionreply *create_onionreply(const tal_t *ctx,
const u8 *failure_msg); const struct secret *shared_secret,
const u8 *failure_msg);
/** /**
* wrap_onionreply - Add another encryption layer to the reply. * wrap_onionreply - Add another encryption layer to the reply.
@ -175,8 +176,9 @@ u8 *create_onionreply(const tal_t *ctx, const struct secret *shared_secret,
* encryption. * encryption.
* @reply: the reply to wrap * @reply: the reply to wrap
*/ */
u8 *wrap_onionreply(const tal_t *ctx, const struct secret *shared_secret, struct onionreply *wrap_onionreply(const tal_t *ctx,
const u8 *reply); const struct secret *shared_secret,
const struct onionreply *reply);
/** /**
* unwrap_onionreply - Remove layers, check integrity and parse reply * unwrap_onionreply - Remove layers, check integrity and parse reply
@ -186,10 +188,13 @@ u8 *wrap_onionreply(const tal_t *ctx, const struct secret *shared_secret,
* @numhops: path length and number of shared_secrets provided * @numhops: path length and number of shared_secrets provided
* @reply: the incoming reply * @reply: the incoming reply
* @origin_index: the index in the path where the reply came from (-1 if unknown) * @origin_index: the index in the path where the reply came from (-1 if unknown)
*
* Reverses create_onionreply and wrap_onionreply.
*/ */
u8 *unwrap_onionreply(const tal_t *ctx, u8 *unwrap_onionreply(const tal_t *ctx,
const struct secret *shared_secrets, const struct secret *shared_secrets,
const int numhops, const u8 *reply, const int numhops,
const struct onionreply *reply,
int *origin_index); int *origin_index);
/** /**

9
common/test/run-sphinx.c

@ -1,4 +1,5 @@
#include "../onion.c" #include "../onion.c"
#include "../onionreply.c"
#include "../sphinx.c" #include "../sphinx.c"
#include <secp256k1.h> #include <secp256k1.h>
#include <ccan/opt/opt.h> #include <ccan/opt/opt.h>
@ -61,8 +62,8 @@ static struct secret secret_from_hex(const char *hex)
static void run_unit_tests(void) static void run_unit_tests(void)
{ {
u8 *oreply; u8 *oreply;
struct onionreply *reply;
int origin_index; int origin_index;
u8 *reply;
u8 *raw = tal_hexdata(tmpctx, "2002", 4); u8 *raw = tal_hexdata(tmpctx, "2002", 4);
/* Shared secrets we already have from the forward path */ /* Shared secrets we already have from the forward path */
@ -158,10 +159,10 @@ static void run_unit_tests(void)
reply = create_onionreply(tmpctx, &ss[4], raw); reply = create_onionreply(tmpctx, &ss[4], raw);
for (int i = 4; i >= 0; i--) { for (int i = 4; i >= 0; i--) {
printf("input_packet %s\n", tal_hex(tmpctx, reply)); printf("input_packet %s\n", tal_hex(tmpctx, reply->contents));
reply = wrap_onionreply(tmpctx, &ss[i], reply); reply = wrap_onionreply(tmpctx, &ss[i], reply);
printf("obfuscated_packet %s\n", tal_hex(tmpctx, reply)); printf("obfuscated_packet %s\n", tal_hex(tmpctx, reply->contents));
assert(memcmp(reply, intermediates[i], tal_count(reply)) == 0); assert(memcmp(reply->contents, intermediates[i], tal_count(reply->contents)) == 0);
} }
oreply = unwrap_onionreply(tmpctx, ss, 5, reply, &origin_index); oreply = unwrap_onionreply(tmpctx, ss, 5, reply, &origin_index);

1
connectd/Makefile

@ -57,6 +57,7 @@ CONNECTD_COMMON_OBJS := \
common/memleak.o \ common/memleak.o \
common/msg_queue.o \ common/msg_queue.o \
common/node_id.o \ common/node_id.o \
common/onionreply.o \
common/per_peer_state.o \ common/per_peer_state.o \
common/pseudorand.o \ common/pseudorand.o \
common/status.o \ common/status.o \

1
devtools/Makefile

@ -23,6 +23,7 @@ DEVTOOLS_COMMON_OBJS := \
common/memleak.o \ common/memleak.o \
common/node_id.o \ common/node_id.o \
common/onion.o \ common/onion.o \
common/onionreply.o \
common/per_peer_state.o \ common/per_peer_state.o \
common/pseudorand.o \ common/pseudorand.o \
common/json.o \ common/json.o \

1
gossipd/Makefile

@ -60,6 +60,7 @@ GOSSIPD_COMMON_OBJS := \
common/memleak.o \ common/memleak.o \
common/msg_queue.o \ common/msg_queue.o \
common/node_id.o \ common/node_id.o \
common/onionreply.o \
common/per_peer_state.o \ common/per_peer_state.o \
common/ping.o \ common/ping.o \
common/pseudorand.o \ common/pseudorand.o \

1
lightningd/Makefile

@ -47,6 +47,7 @@ LIGHTNINGD_COMMON_OBJS := \
common/msg_queue.o \ common/msg_queue.o \
common/node_id.o \ common/node_id.o \
common/onion.o \ common/onion.o \
common/onionreply.o \
common/param.o \ common/param.o \
common/per_peer_state.o \ common/per_peer_state.o \
common/permute_tx.o \ common/permute_tx.o \

4
lightningd/htlc_end.h

@ -40,7 +40,7 @@ struct htlc_in {
enum onion_type failcode; enum onion_type failcode;
/* For a remote error. */ /* For a remote error. */
const u8 *failuremsg; const struct onionreply *failuremsg;
/* If failcode & UPDATE, this is the channel which failed. */ /* If failcode & UPDATE, this is the channel which failed. */
struct short_channel_id failoutchannel; struct short_channel_id failoutchannel;
@ -72,7 +72,7 @@ struct htlc_out {
enum onion_type failcode; enum onion_type failcode;
/* For a remote error. */ /* For a remote error. */
const u8 *failuremsg; const struct onionreply *failuremsg;
/* If we fulfilled, here's the preimage. */ /* If we fulfilled, here's the preimage. */
/* FIXME: This is basically unused, except as a bool! */ /* FIXME: This is basically unused, except as a bool! */

6
lightningd/notification.c

@ -255,7 +255,7 @@ void notify_sendpay_success(struct lightningd *ld,
static void sendpay_failure_notification_serialize(struct json_stream *stream, static void sendpay_failure_notification_serialize(struct json_stream *stream,
const struct wallet_payment *payment, const struct wallet_payment *payment,
int pay_errcode, int pay_errcode,
const u8 *onionreply, const struct onionreply *onionreply,
const struct routing_failure *fail, const struct routing_failure *fail,
char *errmsg) char *errmsg)
{ {
@ -283,14 +283,14 @@ REGISTER_NOTIFICATION(sendpay_failure,
void notify_sendpay_failure(struct lightningd *ld, void notify_sendpay_failure(struct lightningd *ld,
const struct wallet_payment *payment, const struct wallet_payment *payment,
int pay_errcode, int pay_errcode,
const u8 *onionreply, const struct onionreply *onionreply,
const struct routing_failure *fail, const struct routing_failure *fail,
const char *errmsg) const char *errmsg)
{ {
void (*serialize)(struct json_stream *, void (*serialize)(struct json_stream *,
const struct wallet_payment *, const struct wallet_payment *,
int, int,
const u8 *, const struct onionreply *,
const struct routing_failure *, const struct routing_failure *,
const char *) = sendpay_failure_notification_gen.serialize; const char *) = sendpay_failure_notification_gen.serialize;

4
lightningd/notification.h

@ -17,6 +17,8 @@
#include <wallet/wallet.h> #include <wallet/wallet.h>
#include <wire/gen_onion_wire.h> #include <wire/gen_onion_wire.h>
struct onionreply;
bool notifications_have_topic(const char *topic); bool notifications_have_topic(const char *topic);
struct notification { struct notification {
@ -61,7 +63,7 @@ void notify_sendpay_success(struct lightningd *ld,
void notify_sendpay_failure(struct lightningd *ld, void notify_sendpay_failure(struct lightningd *ld,
const struct wallet_payment *payment, const struct wallet_payment *payment,
int pay_errcode, int pay_errcode,
const u8 *onionreply, const struct onionreply *onionreply,
const struct routing_failure *fail, const struct routing_failure *fail,
const char *errmsg); const char *errmsg);

11
lightningd/pay.c

@ -6,6 +6,7 @@
#include <common/json_helpers.h> #include <common/json_helpers.h>
#include <common/jsonrpc_errors.h> #include <common/jsonrpc_errors.h>
#include <common/onion.h> #include <common/onion.h>
#include <common/onionreply.h>
#include <common/param.h> #include <common/param.h>
#include <common/timeout.h> #include <common/timeout.h>
#include <gossipd/gen_gossip_wire.h> #include <gossipd/gen_gossip_wire.h>
@ -172,14 +173,14 @@ json_add_routefail_info(struct json_stream *js,
void json_sendpay_fail_fields(struct json_stream *js, void json_sendpay_fail_fields(struct json_stream *js,
const struct wallet_payment *payment, const struct wallet_payment *payment,
int pay_errcode, int pay_errcode,
const u8 *onionreply, const struct onionreply *onionreply,
const struct routing_failure *fail) const struct routing_failure *fail)
{ {
/* "immediate_routing_failure" is before payment creation. */ /* "immediate_routing_failure" is before payment creation. */
if (payment) if (payment)
json_add_payment_fields(js, payment); json_add_payment_fields(js, payment);
if (pay_errcode == PAY_UNPARSEABLE_ONION) if (pay_errcode == PAY_UNPARSEABLE_ONION)
json_add_hex_talarr(js, "onionreply", onionreply); json_add_hex_talarr(js, "onionreply", onionreply->contents);
else else
json_add_routefail_info(js, json_add_routefail_info(js,
fail->erring_index, fail->erring_index,
@ -210,7 +211,7 @@ static struct command_result *
sendpay_fail(struct command *cmd, sendpay_fail(struct command *cmd,
const struct wallet_payment *payment, const struct wallet_payment *payment,
int pay_errcode, int pay_errcode,
const u8 *onionreply, const struct onionreply *onionreply,
const struct routing_failure *fail, const struct routing_failure *fail,
const char *errmsg) const char *errmsg)
{ {
@ -243,7 +244,7 @@ static void tell_waiters_failed(struct lightningd *ld,
const struct sha256 *payment_hash, const struct sha256 *payment_hash,
const struct wallet_payment *payment, const struct wallet_payment *payment,
int pay_errcode, int pay_errcode,
const u8 *onionreply, const struct onionreply *onionreply,
const struct routing_failure *fail, const struct routing_failure *fail,
const char *details) const char *details)
{ {
@ -620,7 +621,7 @@ static struct command_result *wait_payment(struct lightningd *ld,
u64 partid) u64 partid)
{ {
struct wallet_payment *payment; struct wallet_payment *payment;
u8 *failonionreply; struct onionreply *failonionreply;
bool faildestperm; bool faildestperm;
int failindex; int failindex;
enum onion_type failcode; enum onion_type failcode;

3
lightningd/pay.h

@ -5,6 +5,7 @@
struct htlc_out; struct htlc_out;
struct lightningd; struct lightningd;
struct onionreply;
struct preimage; struct preimage;
struct sha256; struct sha256;
struct json_stream; struct json_stream;
@ -28,7 +29,7 @@ void json_add_payment_fields(struct json_stream *response,
void json_sendpay_fail_fields(struct json_stream *js, void json_sendpay_fail_fields(struct json_stream *js,
const struct wallet_payment *t, const struct wallet_payment *t,
int pay_errcode, int pay_errcode,
const u8 *onionreply, const struct onionreply *onionreply,
const struct routing_failure *fail); const struct routing_failure *fail);
#endif /* LIGHTNING_LIGHTNINGD_PAY_H */ #endif /* LIGHTNING_LIGHTNINGD_PAY_H */

16
lightningd/peer_htlcs.c

@ -9,6 +9,7 @@
#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>
#include <common/onionreply.h>
#include <common/overflows.h> #include <common/overflows.h>
#include <common/param.h> #include <common/param.h>
#include <common/sphinx.h> #include <common/sphinx.h>
@ -96,7 +97,7 @@ static bool htlc_out_update_state(struct channel *channel,
static void fail_in_htlc(struct htlc_in *hin, static void fail_in_htlc(struct htlc_in *hin,
enum onion_type failcode, enum onion_type failcode,
const u8 *failuremsg, const struct onionreply *failuremsg,
const struct short_channel_id *out_channelid) const struct short_channel_id *out_channelid)
{ {
struct failed_htlc failed_htlc; struct failed_htlc failed_htlc;
@ -105,7 +106,7 @@ static void fail_in_htlc(struct htlc_in *hin,
assert(failcode || failuremsg); assert(failcode || failuremsg);
hin->failcode = failcode; hin->failcode = failcode;
if (failuremsg) if (failuremsg)
hin->failuremsg = tal_dup_arr(hin, u8, failuremsg, tal_count(failuremsg), 0); hin->failuremsg = dup_onionreply(hin, failuremsg);
/* We need this set, since we send it to channeld. */ /* We need this set, since we send it to channeld. */
if (hin->failcode & UPDATE) if (hin->failcode & UPDATE)
@ -125,7 +126,7 @@ static void fail_in_htlc(struct htlc_in *hin,
failed_htlc.id = hin->key.id; failed_htlc.id = hin->key.id;
failed_htlc.failcode = hin->failcode; failed_htlc.failcode = hin->failcode;
failed_htlc.failreason = cast_const(u8 *, hin->failuremsg); failed_htlc.failreason = hin->failuremsg;
if (failed_htlc.failcode & UPDATE) if (failed_htlc.failcode & UPDATE)
failed_htlc.scid = &hin->failoutchannel; failed_htlc.scid = &hin->failoutchannel;
else else
@ -1079,9 +1080,7 @@ static bool peer_failed_our_htlc(struct channel *channel,
hout->failcode = failed->failcode; hout->failcode = failed->failcode;
if (!failed->failcode) if (!failed->failcode)
hout->failuremsg = tal_dup_arr(hout, u8, failed->failreason, hout->failuremsg = dup_onionreply(hout, failed->failreason);
tal_count(failed->failreason), 0);
else else
hout->failuremsg = NULL; hout->failuremsg = NULL;
@ -1796,7 +1795,7 @@ static void add_fulfill(u64 id, enum side side,
static void add_fail(u64 id, enum side side, static void add_fail(u64 id, enum side side,
enum onion_type failcode, enum onion_type failcode,
const struct short_channel_id *failing_channel, const struct short_channel_id *failing_channel,
const u8 *failuremsg, const struct onionreply *failuremsg,
const struct failed_htlc ***failed_htlcs, const struct failed_htlc ***failed_htlcs,
enum side **failed_sides) enum side **failed_sides)
{ {
@ -1813,8 +1812,7 @@ static void add_fail(u64 id, enum side side,
newf->scid = NULL; newf->scid = NULL;
if (failuremsg) if (failuremsg)
newf->failreason newf->failreason = dup_onionreply(newf, failuremsg);
= tal_dup_arr(newf, u8, failuremsg, tal_count(failuremsg), 0);
else else
newf->failreason = NULL; newf->failreason = NULL;

1
onchaind/Makefile

@ -62,6 +62,7 @@ ONCHAIND_COMMON_OBJS := \
common/key_derive.o \ common/key_derive.o \
common/memleak.o \ common/memleak.o \
common/msg_queue.o \ common/msg_queue.o \
common/onionreply.o \
common/peer_billboard.o \ common/peer_billboard.o \
common/permute_tx.o \ common/permute_tx.o \
common/status.o \ common/status.o \

1
openingd/Makefile

@ -62,6 +62,7 @@ OPENINGD_COMMON_OBJS := \
common/keyset.o \ common/keyset.o \
common/memleak.o \ common/memleak.o \
common/msg_queue.o \ common/msg_queue.o \
common/onionreply.o \
common/per_peer_state.o \ common/per_peer_state.o \
common/peer_billboard.o \ common/peer_billboard.o \
common/peer_failed.o \ common/peer_failed.o \

1
wallet/test/Makefile

@ -12,6 +12,7 @@ WALLET_TEST_COMMON_OBJS := \
common/type_to_string.o \ common/type_to_string.o \
common/memleak.o \ common/memleak.o \
common/node_id.o \ common/node_id.o \
common/onionreply.o \
common/key_derive.o \ common/key_derive.o \
common/pseudorand.o \ common/pseudorand.o \
common/timeout.o \ common/timeout.o \

7
wallet/test/run-wallet.c

@ -485,8 +485,7 @@ void payment_failed(struct lightningd *ld UNNEEDED, const struct htlc_out *hout
const char *localfail UNNEEDED) const char *localfail UNNEEDED)
{ fprintf(stderr, "payment_failed called!\n"); abort(); } { fprintf(stderr, "payment_failed called!\n"); abort(); }
/* Generated stub for payment_store */ /* Generated stub for payment_store */
void payment_store(struct lightningd *ld UNNEEDED, void payment_store(struct lightningd *ld UNNEEDED, struct wallet_payment *payment UNNEEDED)
struct wallet_payment *payment UNNEEDED)
{ fprintf(stderr, "payment_store called!\n"); abort(); } { fprintf(stderr, "payment_store called!\n"); abort(); }
/* Generated stub for payment_succeeded */ /* Generated stub for payment_succeeded */
void payment_succeeded(struct lightningd *ld UNNEEDED, struct htlc_out *hout UNNEEDED, void payment_succeeded(struct lightningd *ld UNNEEDED, struct htlc_out *hout UNNEEDED,
@ -1173,6 +1172,7 @@ static bool test_htlc_crud(struct lightningd *ld, const tal_t *ctx)
struct wallet *w = create_test_wallet(ld, ctx); struct wallet *w = create_test_wallet(ld, ctx);
struct htlc_in_map *htlcs_in = tal(ctx, struct htlc_in_map), *rem; struct htlc_in_map *htlcs_in = tal(ctx, struct htlc_in_map), *rem;
struct htlc_out_map *htlcs_out = tal(ctx, struct htlc_out_map); struct htlc_out_map *htlcs_out = tal(ctx, struct htlc_out_map);
struct onionreply *onionreply;
/* Make sure we have our references correct */ /* Make sure we have our references correct */
db_begin_transaction(w->db); db_begin_transaction(w->db);
@ -1215,8 +1215,9 @@ static bool test_htlc_crud(struct lightningd *ld, const tal_t *ctx)
CHECK_MSG( CHECK_MSG(
transaction_wrap(w->db, wallet_htlc_update(w, in.dbid, SENT_REMOVE_HTLC, &payment_key, 0, NULL)), transaction_wrap(w->db, wallet_htlc_update(w, in.dbid, SENT_REMOVE_HTLC, &payment_key, 0, NULL)),
"Update HTLC with payment_key failed"); "Update HTLC with payment_key failed");
onionreply = new_onionreply(tmpctx, tal_arrz(tmpctx, u8, 100));
CHECK_MSG( CHECK_MSG(
transaction_wrap(w->db, wallet_htlc_update(w, in.dbid, SENT_REMOVE_HTLC, NULL, 0, tal_arrz(tmpctx, u8, 100))), transaction_wrap(w->db, wallet_htlc_update(w, in.dbid, SENT_REMOVE_HTLC, NULL, 0, onionreply)),
"Update HTLC with failreason failed"); "Update HTLC with failreason failed");
CHECK_MSG(transaction_wrap(w->db, wallet_htlc_save_out(w, chan, &out)), CHECK_MSG(transaction_wrap(w->db, wallet_htlc_save_out(w, chan, &out)),

28
wallet/wallet.c

@ -8,6 +8,7 @@
#include <common/fee_states.h> #include <common/fee_states.h>
#include <common/key_derive.h> #include <common/key_derive.h>
#include <common/memleak.h> #include <common/memleak.h>
#include <common/onionreply.h>
#include <common/wireaddr.h> #include <common/wireaddr.h>
#include <inttypes.h> #include <inttypes.h>
#include <lightningd/lightningd.h> #include <lightningd/lightningd.h>
@ -1757,7 +1758,8 @@ void wallet_htlc_save_out(struct wallet *wallet,
void wallet_htlc_update(struct wallet *wallet, const u64 htlc_dbid, void wallet_htlc_update(struct wallet *wallet, const u64 htlc_dbid,
const enum htlc_state new_state, const enum htlc_state new_state,
const struct preimage *payment_key, const struct preimage *payment_key,
enum onion_type failcode, const u8 *failuremsg) enum onion_type failcode,
const struct onionreply *failuremsg)
{ {
struct db_stmt *stmt; struct db_stmt *stmt;
@ -1779,7 +1781,7 @@ void wallet_htlc_update(struct wallet *wallet, const u64 htlc_dbid,
db_bind_int(stmt, 2, failcode); db_bind_int(stmt, 2, failcode);
if (failuremsg) if (failuremsg)
db_bind_blob(stmt, 3, failuremsg, tal_bytelen(failuremsg)); db_bind_onionreply(stmt, 3, failuremsg);
else else
db_bind_null(stmt, 3); db_bind_null(stmt, 3);
@ -1810,7 +1812,10 @@ static bool wallet_stmt2htlc_in(struct channel *channel,
memcpy(&in->onion_routing_packet, db_column_blob(stmt, 7), memcpy(&in->onion_routing_packet, db_column_blob(stmt, 7),
sizeof(in->onion_routing_packet)); sizeof(in->onion_routing_packet));
in->failuremsg = db_column_arr(in, stmt, 8, u8); if (db_column_is_null(stmt, 8))
in->failuremsg = NULL;
else
in->failuremsg = db_column_onionreply(in, stmt, 8);
in->failcode = db_column_int(stmt, 9); in->failcode = db_column_int(stmt, 9);
if (db_column_is_null(stmt, 11)) { if (db_column_is_null(stmt, 11)) {
@ -1857,7 +1862,10 @@ static bool wallet_stmt2htlc_out(struct wallet *wallet,
memcpy(&out->onion_routing_packet, db_column_blob(stmt, 7), memcpy(&out->onion_routing_packet, db_column_blob(stmt, 7),
sizeof(out->onion_routing_packet)); sizeof(out->onion_routing_packet));
out->failuremsg = db_column_arr(out, stmt, 8, u8); if (db_column_is_null(stmt, 8))
out->failuremsg = NULL;
else
out->failuremsg = db_column_onionreply(out, stmt, 8);
out->failcode = db_column_int_or_default(stmt, 9, 0); out->failcode = db_column_int_or_default(stmt, 9, 0);
out->in = NULL; out->in = NULL;
@ -2473,7 +2481,7 @@ void wallet_payment_get_failinfo(const tal_t *ctx,
const struct sha256 *payment_hash, const struct sha256 *payment_hash,
u64 partid, u64 partid,
/* outputs */ /* outputs */
u8 **failonionreply, struct onionreply **failonionreply,
bool *faildestperm, bool *faildestperm,
int *failindex, int *failindex,
enum onion_type *failcode, enum onion_type *failcode,
@ -2503,9 +2511,7 @@ void wallet_payment_get_failinfo(const tal_t *ctx,
if (db_column_is_null(stmt, 0)) if (db_column_is_null(stmt, 0))
*failonionreply = NULL; *failonionreply = NULL;
else { else {
len = db_column_bytes(stmt, 0); *failonionreply = db_column_onionreply(ctx, stmt, 0);
*failonionreply = tal_arr(ctx, u8, len);
memcpy(*failonionreply, db_column_blob(stmt, 0), len);
} }
*faildestperm = db_column_int(stmt, 1) != 0; *faildestperm = db_column_int(stmt, 1) != 0;
*failindex = db_column_int(stmt, 2); *failindex = db_column_int(stmt, 2);
@ -2545,7 +2551,7 @@ void wallet_payment_get_failinfo(const tal_t *ctx,
void wallet_payment_set_failinfo(struct wallet *wallet, void wallet_payment_set_failinfo(struct wallet *wallet,
const struct sha256 *payment_hash, const struct sha256 *payment_hash,
u64 partid, u64 partid,
const u8 *failonionreply /*tal_arr*/, const struct onionreply *failonionreply,
bool faildestperm, bool faildestperm,
int failindex, int failindex,
enum onion_type failcode, enum onion_type failcode,
@ -2570,8 +2576,8 @@ void wallet_payment_set_failinfo(struct wallet *wallet,
" WHERE payment_hash=?" " WHERE payment_hash=?"
" AND partid=?;")); " AND partid=?;"));
if (failonionreply) if (failonionreply)
db_bind_blob(stmt, 0, failonionreply, db_bind_blob(stmt, 0, failonionreply->contents,
tal_count(failonionreply)); tal_count(failonionreply->contents));
else else
db_bind_null(stmt, 0); db_bind_null(stmt, 0);

7
wallet/wallet.h

@ -591,7 +591,8 @@ void wallet_htlc_save_out(struct wallet *wallet,
void wallet_htlc_update(struct wallet *wallet, const u64 htlc_dbid, void wallet_htlc_update(struct wallet *wallet, const u64 htlc_dbid,
const enum htlc_state new_state, const enum htlc_state new_state,
const struct preimage *payment_key, const struct preimage *payment_key,
enum onion_type failcode, const u8 *failuremsg); enum onion_type failcode,
const struct onionreply *failuremsg);
/** /**
* wallet_htlcs_load_in_for_channel - Load incoming HTLCs associated with chan from DB. * wallet_htlcs_load_in_for_channel - Load incoming HTLCs associated with chan from DB.
@ -998,7 +999,7 @@ void wallet_payment_get_failinfo(const tal_t *ctx,
const struct sha256 *payment_hash, const struct sha256 *payment_hash,
u64 partid, u64 partid,
/* outputs */ /* outputs */
u8 **failonionreply, struct onionreply **failonionreply,
bool *faildestperm, bool *faildestperm,
int *failindex, int *failindex,
enum onion_type *failcode, enum onion_type *failcode,
@ -1014,7 +1015,7 @@ void wallet_payment_get_failinfo(const tal_t *ctx,
void wallet_payment_set_failinfo(struct wallet *wallet, void wallet_payment_set_failinfo(struct wallet *wallet,
const struct sha256 *payment_hash, const struct sha256 *payment_hash,
u64 partid, u64 partid,
const u8 *failonionreply, const struct onionreply *failonionreply,
bool faildestperm, bool faildestperm,
int failindex, int failindex,
enum onion_type failcode, enum onion_type failcode,

Loading…
Cancel
Save