From 1099f6a5e155ba4aa2bb37afded0bb82f18bdd12 Mon Sep 17 00:00:00 2001 From: Rusty Russell Date: Thu, 23 Jan 2020 10:08:04 +1030 Subject: [PATCH] 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 --- channeld/Makefile | 1 + channeld/channeld.c | 15 ++++++--- channeld/channeld_htlc.h | 2 +- channeld/full_channel.c | 6 ++-- channeld/test/run-full_channel.c | 4 +++ closingd/Makefile | 1 + common/htlc_wire.c | 15 +++------ common/htlc_wire.h | 2 +- common/sphinx.c | 53 +++++++++++++++++++------------- common/sphinx.h | 15 ++++++--- common/test/run-sphinx.c | 9 +++--- connectd/Makefile | 1 + devtools/Makefile | 1 + gossipd/Makefile | 1 + lightningd/Makefile | 1 + lightningd/htlc_end.h | 4 +-- lightningd/notification.c | 6 ++-- lightningd/notification.h | 4 ++- lightningd/pay.c | 11 ++++--- lightningd/pay.h | 3 +- lightningd/peer_htlcs.c | 16 +++++----- onchaind/Makefile | 1 + openingd/Makefile | 1 + wallet/test/Makefile | 1 + wallet/test/run-wallet.c | 7 +++-- wallet/wallet.c | 28 ++++++++++------- wallet/wallet.h | 7 +++-- 27 files changed, 126 insertions(+), 90 deletions(-) diff --git a/channeld/Makefile b/channeld/Makefile index 920879cb2..a3f657b1c 100644 --- a/channeld/Makefile +++ b/channeld/Makefile @@ -63,6 +63,7 @@ CHANNELD_COMMON_OBJS := \ common/msg_queue.o \ common/node_id.o \ common/onion.o \ + common/onionreply.o \ common/peer_billboard.o \ common/peer_failed.o \ common/per_peer_state.o \ diff --git a/channeld/channeld.c b/channeld/channeld.c index c200c4902..4e6bf6f44 100644 --- a/channeld/channeld.c +++ b/channeld/channeld.c @@ -36,6 +36,7 @@ #include #include #include +#include #include #include #include @@ -1306,7 +1307,7 @@ static void marshall_htlc_info(const tal_t *ctx, f = tal(*failed, struct failed_htlc); f->id = htlc->id; f->failcode = htlc->failcode; - f->failreason = cast_const(u8 *, htlc->fail); + f->failreason = htlc->fail; f->scid = cast_const(struct short_channel_id *, htlc->failed_scid); tal_arr_expand(failed, f); @@ -1656,6 +1657,7 @@ static void handle_peer_fail_htlc(struct peer *peer, const u8 *msg) u8 *reason; struct htlc *htlc; + /* reason is not an onionreply because spec doesn't know about that */ if (!fromwire_update_fail_htlc(msg, msg, &channel_id, &id, &reason)) { 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); switch (e) { - case CHANNEL_ERR_REMOVE_OK: + case CHANNEL_ERR_REMOVE_OK: { /* 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); return; + } case CHANNEL_ERR_NO_SUCH_ID: case CHANNEL_ERR_ALREADY_FULFILLED: 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->why_bad_onion); } else if (h->failcode || h->fail) { - const u8 *onion; + const struct onionreply *onion; if (h->failcode) { /* Local failure, make a message. */ 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, wrap_onionreply(tmpctx, h->shared_secret, - onion)); + onion)->contents); } else if (h->r) { msg = towire_update_fulfill_htlc(NULL, &peer->channel_id, h->id, h->r); diff --git a/channeld/channeld_htlc.h b/channeld/channeld_htlc.h index 6a5a30351..5b2c54d45 100644 --- a/channeld/channeld_htlc.h +++ b/channeld/channeld_htlc.h @@ -34,7 +34,7 @@ struct htlc { const u8 *routing; /* Failure message we received or generated. */ - const u8 *fail; + 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; diff --git a/channeld/full_channel.c b/channeld/full_channel.c index fc38bb827..9e7b39128 100644 --- a/channeld/full_channel.c +++ b/channeld/full_channel.c @@ -17,6 +17,7 @@ #include #include #include +#include #include #include #include @@ -1254,10 +1255,7 @@ bool channel_force_htlcs(struct channel *channel, * a hint. */ htlc->failblock = failheight; if (failed[i]->failreason) - htlc->fail = tal_dup_arr(htlc, u8, - failed[i]->failreason, - tal_count(failed[i]->failreason), - 0); + htlc->fail = dup_onionreply(htlc, failed[i]->failreason); else htlc->fail = NULL; if (failed[i]->scid) diff --git a/channeld/test/run-full_channel.c b/channeld/test/run-full_channel.c index 63dbaec3e..79a39964f 100644 --- a/channeld/test/run-full_channel.c +++ b/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 */ size_t bigsize_put(u8 buf[BIGSIZE_MAX_LEN] UNNEEDED, bigsize_t v UNNEEDED) { fprintf(stderr, "bigsize_put called!\n"); abort(); } +/* Generated stub for dup_onionreply */ +struct onionreply *dup_onionreply(const tal_t *ctx UNNEEDED, + const struct onionreply *r TAKES UNNEEDED) +{ fprintf(stderr, "dup_onionreply called!\n"); abort(); } /* Generated stub for memleak_add_helper_ */ void memleak_add_helper_(const tal_t *p UNNEEDED, void (*cb)(struct htable *memtable UNNEEDED, const tal_t *)){ } diff --git a/closingd/Makefile b/closingd/Makefile index 15462a2ec..847d8ef4c 100644 --- a/closingd/Makefile +++ b/closingd/Makefile @@ -63,6 +63,7 @@ CLOSINGD_COMMON_OBJS := \ common/key_derive.o \ common/memleak.o \ common/msg_queue.o \ + common/onionreply.o \ common/peer_billboard.o \ common/peer_failed.o \ common/per_peer_state.o \ diff --git a/common/htlc_wire.c b/common/htlc_wire.c index 58d0922c2..881831693 100644 --- a/common/htlc_wire.c +++ b/common/htlc_wire.c @@ -3,6 +3,7 @@ #include #include #include +#include #include /* 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) { /* Only one can be set. */ - assert(failed->failcode || tal_count(failed->failreason)); - assert(!failed->failcode || !tal_count(failed->failreason)); + assert(failed->failcode || failed->failreason); + assert(!failed->failcode || !failed->failreason); towire_u64(pptr, failed->id); towire_u16(pptr, failed->failcode); if (failed->failcode & UPDATE) { @@ -37,9 +38,7 @@ void towire_failed_htlc(u8 **pptr, const struct failed_htlc *failed) assert(!failed->scid); if (!failed->failcode) { assert(failed->failreason); - towire_u16(pptr, tal_count(failed->failreason)); - towire_u8_array(pptr, failed->failreason, - tal_count(failed->failreason)); + towire_onionreply(pptr, 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->failcode = fromwire_u16(cursor, max); if (failed->failcode == 0) { - u16 failreason_len; failed->scid = NULL; - failreason_len = fromwire_u16(cursor, max); - failed->failreason = tal_arr(failed, u8, failreason_len); - fromwire_u8_array(cursor, max, failed->failreason, - failreason_len); + failed->failreason = fromwire_onionreply(failed, cursor, max); } else { failed->failreason = NULL; if (failed->failcode & UPDATE) { diff --git a/common/htlc_wire.h b/common/htlc_wire.h index 5841ea61b..030cbd451 100644 --- a/common/htlc_wire.h +++ b/common/htlc_wire.h @@ -29,7 +29,7 @@ struct failed_htlc { u64 id; /* Either this is 0 and failreason non-NULL, or vice versa. */ enum onion_type failcode; - u8 *failreason; + const struct onionreply *failreason; /* Non-NULL if failcode & UPDATE */ struct short_channel_id *scid; }; diff --git a/common/sphinx.c b/common/sphinx.c index 3695be913..1aef8551a 100644 --- a/common/sphinx.c +++ b/common/sphinx.c @@ -6,6 +6,7 @@ #include #include #include +#include #include #include @@ -529,12 +530,14 @@ struct route_step *process_onionpacket( return step; } -u8 *create_onionreply(const tal_t *ctx, const struct secret *shared_secret, - const u8 *failure_msg) +struct onionreply *create_onionreply(const tal_t *ctx, + const struct secret *shared_secret, + const u8 *failure_msg) { size_t msglen = tal_count(failure_msg); 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 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); 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); return reply; } -u8 *wrap_onionreply(const tal_t *ctx, - const struct secret *shared_secret, const u8 *reply) +struct onionreply *wrap_onionreply(const tal_t *ctx, + const struct secret *shared_secret, + const struct onionreply *reply) { u8 key[KEY_LEN]; - size_t streamlen = tal_count(reply); + size_t streamlen = tal_count(reply->contents); u8 stream[streamlen]; - u8 *result = tal_arr(ctx, u8, streamlen); + struct onionreply *result = tal(ctx, struct onionreply); /* BOLT #4: * @@ -600,39 +605,43 @@ u8 *wrap_onionreply(const tal_t *ctx, */ generate_key(key, "ammag", 5, shared_secret->data); 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; } u8 *unwrap_onionreply(const tal_t *ctx, const struct secret *shared_secrets, - const int numhops, const u8 *reply, + const int numhops, + const struct onionreply *reply, int *origin_index) { - u8 *msg = tal_arr(tmpctx, u8, tal_count(reply)), *final; + struct onionreply *r; u8 key[KEY_LEN], hmac[HMAC_SIZE]; const u8 *cursor; + u8 *final; size_t max; 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; } - memcpy(msg, reply, tal_count(reply)); + r = new_onionreply(tmpctx, reply->contents); *origin_index = -1; for (int i = 0; i < numhops; i++) { /* Since the encryption is just XORing with the cipher * 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 * the origin */ generate_key(key, "um", 2, shared_secrets[i].data); - compute_hmac(hmac, msg + sizeof(hmac), - tal_count(msg) - sizeof(hmac), key, KEY_LEN); - if (memcmp(hmac, msg, sizeof(hmac)) == 0) { + compute_hmac(hmac, r->contents + sizeof(hmac), + tal_count(r->contents) - sizeof(hmac), + key, KEY_LEN); + if (memcmp(hmac, r->contents, sizeof(hmac)) == 0) { *origin_index = i; break; } @@ -641,8 +650,8 @@ u8 *unwrap_onionreply(const tal_t *ctx, return NULL; } - cursor = msg + sizeof(hmac); - max = tal_count(msg) - sizeof(hmac); + cursor = r->contents + sizeof(hmac); + max = tal_count(r->contents) - sizeof(hmac); msglen = fromwire_u16(&cursor, &max); if (msglen > ONION_REPLY_SIZE) { @@ -650,7 +659,7 @@ u8 *unwrap_onionreply(const tal_t *ctx, } final = tal_arr(ctx, u8, msglen); - fromwire(&cursor, &max, final, msglen); - + if (!fromwire(&cursor, &max, final, msglen)) + return tal_free(final); return final; } diff --git a/common/sphinx.h b/common/sphinx.h index d20050f3a..94bbdd72a 100644 --- a/common/sphinx.h +++ b/common/sphinx.h @@ -164,8 +164,9 @@ enum onion_type parse_onionpacket(const u8 *src, * HMAC * @failure_msg: message (must support tal_len) */ -u8 *create_onionreply(const tal_t *ctx, const struct secret *shared_secret, - const u8 *failure_msg); +struct onionreply *create_onionreply(const tal_t *ctx, + const struct secret *shared_secret, + const u8 *failure_msg); /** * 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. * @reply: the reply to wrap */ -u8 *wrap_onionreply(const tal_t *ctx, const struct secret *shared_secret, - const u8 *reply); +struct onionreply *wrap_onionreply(const tal_t *ctx, + const struct secret *shared_secret, + const struct onionreply *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 * @reply: the incoming reply * @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, const struct secret *shared_secrets, - const int numhops, const u8 *reply, + const int numhops, + const struct onionreply *reply, int *origin_index); /** diff --git a/common/test/run-sphinx.c b/common/test/run-sphinx.c index 38936d6dc..b89ee9cf2 100644 --- a/common/test/run-sphinx.c +++ b/common/test/run-sphinx.c @@ -1,4 +1,5 @@ #include "../onion.c" +#include "../onionreply.c" #include "../sphinx.c" #include #include @@ -61,8 +62,8 @@ static struct secret secret_from_hex(const char *hex) static void run_unit_tests(void) { u8 *oreply; + struct onionreply *reply; int origin_index; - u8 *reply; u8 *raw = tal_hexdata(tmpctx, "2002", 4); /* 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); 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); - printf("obfuscated_packet %s\n", tal_hex(tmpctx, reply)); - assert(memcmp(reply, intermediates[i], tal_count(reply)) == 0); + printf("obfuscated_packet %s\n", tal_hex(tmpctx, reply->contents)); + assert(memcmp(reply->contents, intermediates[i], tal_count(reply->contents)) == 0); } oreply = unwrap_onionreply(tmpctx, ss, 5, reply, &origin_index); diff --git a/connectd/Makefile b/connectd/Makefile index 472328b16..27f2dd2b7 100644 --- a/connectd/Makefile +++ b/connectd/Makefile @@ -57,6 +57,7 @@ CONNECTD_COMMON_OBJS := \ common/memleak.o \ common/msg_queue.o \ common/node_id.o \ + common/onionreply.o \ common/per_peer_state.o \ common/pseudorand.o \ common/status.o \ diff --git a/devtools/Makefile b/devtools/Makefile index 176345ad7..1f9b3df91 100644 --- a/devtools/Makefile +++ b/devtools/Makefile @@ -23,6 +23,7 @@ DEVTOOLS_COMMON_OBJS := \ common/memleak.o \ common/node_id.o \ common/onion.o \ + common/onionreply.o \ common/per_peer_state.o \ common/pseudorand.o \ common/json.o \ diff --git a/gossipd/Makefile b/gossipd/Makefile index fa68afb0e..7de9fae19 100644 --- a/gossipd/Makefile +++ b/gossipd/Makefile @@ -60,6 +60,7 @@ GOSSIPD_COMMON_OBJS := \ common/memleak.o \ common/msg_queue.o \ common/node_id.o \ + common/onionreply.o \ common/per_peer_state.o \ common/ping.o \ common/pseudorand.o \ diff --git a/lightningd/Makefile b/lightningd/Makefile index 45603626b..b91cada36 100644 --- a/lightningd/Makefile +++ b/lightningd/Makefile @@ -47,6 +47,7 @@ LIGHTNINGD_COMMON_OBJS := \ common/msg_queue.o \ common/node_id.o \ common/onion.o \ + common/onionreply.o \ common/param.o \ common/per_peer_state.o \ common/permute_tx.o \ diff --git a/lightningd/htlc_end.h b/lightningd/htlc_end.h index bd9bd883a..5564b5847 100644 --- a/lightningd/htlc_end.h +++ b/lightningd/htlc_end.h @@ -40,7 +40,7 @@ struct htlc_in { enum onion_type failcode; /* For a remote error. */ - const u8 *failuremsg; + const struct onionreply *failuremsg; /* If failcode & UPDATE, this is the channel which failed. */ struct short_channel_id failoutchannel; @@ -72,7 +72,7 @@ struct htlc_out { enum onion_type failcode; /* For a remote error. */ - const u8 *failuremsg; + const struct onionreply *failuremsg; /* If we fulfilled, here's the preimage. */ /* FIXME: This is basically unused, except as a bool! */ diff --git a/lightningd/notification.c b/lightningd/notification.c index 841482a42..8eff67dbf 100644 --- a/lightningd/notification.c +++ b/lightningd/notification.c @@ -255,7 +255,7 @@ void notify_sendpay_success(struct lightningd *ld, static void sendpay_failure_notification_serialize(struct json_stream *stream, const struct wallet_payment *payment, int pay_errcode, - const u8 *onionreply, + const struct onionreply *onionreply, const struct routing_failure *fail, char *errmsg) { @@ -283,14 +283,14 @@ REGISTER_NOTIFICATION(sendpay_failure, void notify_sendpay_failure(struct lightningd *ld, const struct wallet_payment *payment, int pay_errcode, - const u8 *onionreply, + const struct onionreply *onionreply, const struct routing_failure *fail, const char *errmsg) { void (*serialize)(struct json_stream *, const struct wallet_payment *, int, - const u8 *, + const struct onionreply *, const struct routing_failure *, const char *) = sendpay_failure_notification_gen.serialize; diff --git a/lightningd/notification.h b/lightningd/notification.h index 5ff809e22..24557862b 100644 --- a/lightningd/notification.h +++ b/lightningd/notification.h @@ -17,6 +17,8 @@ #include #include +struct onionreply; + bool notifications_have_topic(const char *topic); struct notification { @@ -61,7 +63,7 @@ void notify_sendpay_success(struct lightningd *ld, void notify_sendpay_failure(struct lightningd *ld, const struct wallet_payment *payment, int pay_errcode, - const u8 *onionreply, + const struct onionreply *onionreply, const struct routing_failure *fail, const char *errmsg); diff --git a/lightningd/pay.c b/lightningd/pay.c index 823e429f7..da4340f1d 100644 --- a/lightningd/pay.c +++ b/lightningd/pay.c @@ -6,6 +6,7 @@ #include #include #include +#include #include #include #include @@ -172,14 +173,14 @@ json_add_routefail_info(struct json_stream *js, void json_sendpay_fail_fields(struct json_stream *js, const struct wallet_payment *payment, int pay_errcode, - const u8 *onionreply, + const struct onionreply *onionreply, const struct routing_failure *fail) { /* "immediate_routing_failure" is before payment creation. */ if (payment) json_add_payment_fields(js, payment); if (pay_errcode == PAY_UNPARSEABLE_ONION) - json_add_hex_talarr(js, "onionreply", onionreply); + json_add_hex_talarr(js, "onionreply", onionreply->contents); else json_add_routefail_info(js, fail->erring_index, @@ -210,7 +211,7 @@ static struct command_result * sendpay_fail(struct command *cmd, const struct wallet_payment *payment, int pay_errcode, - const u8 *onionreply, + const struct onionreply *onionreply, const struct routing_failure *fail, const char *errmsg) { @@ -243,7 +244,7 @@ static void tell_waiters_failed(struct lightningd *ld, const struct sha256 *payment_hash, const struct wallet_payment *payment, int pay_errcode, - const u8 *onionreply, + const struct onionreply *onionreply, const struct routing_failure *fail, const char *details) { @@ -620,7 +621,7 @@ static struct command_result *wait_payment(struct lightningd *ld, u64 partid) { struct wallet_payment *payment; - u8 *failonionreply; + struct onionreply *failonionreply; bool faildestperm; int failindex; enum onion_type failcode; diff --git a/lightningd/pay.h b/lightningd/pay.h index 945953bd3..185445455 100644 --- a/lightningd/pay.h +++ b/lightningd/pay.h @@ -5,6 +5,7 @@ struct htlc_out; struct lightningd; +struct onionreply; struct preimage; struct sha256; 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, const struct wallet_payment *t, int pay_errcode, - const u8 *onionreply, + const struct onionreply *onionreply, const struct routing_failure *fail); #endif /* LIGHTNING_LIGHTNINGD_PAY_H */ diff --git a/lightningd/peer_htlcs.c b/lightningd/peer_htlcs.c index 65615ec7e..ae545660c 100644 --- a/lightningd/peer_htlcs.c +++ b/lightningd/peer_htlcs.c @@ -9,6 +9,7 @@ #include #include #include +#include #include #include #include @@ -96,7 +97,7 @@ static bool htlc_out_update_state(struct channel *channel, static void fail_in_htlc(struct htlc_in *hin, enum onion_type failcode, - const u8 *failuremsg, + const struct onionreply *failuremsg, const struct short_channel_id *out_channelid) { struct failed_htlc failed_htlc; @@ -105,7 +106,7 @@ static void fail_in_htlc(struct htlc_in *hin, assert(failcode || failuremsg); hin->failcode = failcode; 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. */ 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.failcode = hin->failcode; - failed_htlc.failreason = cast_const(u8 *, hin->failuremsg); + failed_htlc.failreason = hin->failuremsg; if (failed_htlc.failcode & UPDATE) failed_htlc.scid = &hin->failoutchannel; else @@ -1079,9 +1080,7 @@ static bool peer_failed_our_htlc(struct channel *channel, hout->failcode = failed->failcode; if (!failed->failcode) - hout->failuremsg = tal_dup_arr(hout, u8, failed->failreason, - tal_count(failed->failreason), 0); - + hout->failuremsg = dup_onionreply(hout, failed->failreason); else 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, enum onion_type failcode, const struct short_channel_id *failing_channel, - const u8 *failuremsg, + const struct onionreply *failuremsg, const struct failed_htlc ***failed_htlcs, enum side **failed_sides) { @@ -1813,8 +1812,7 @@ static void add_fail(u64 id, enum side side, newf->scid = NULL; if (failuremsg) - newf->failreason - = tal_dup_arr(newf, u8, failuremsg, tal_count(failuremsg), 0); + newf->failreason = dup_onionreply(newf, failuremsg); else newf->failreason = NULL; diff --git a/onchaind/Makefile b/onchaind/Makefile index 2b9112da9..09f5feb62 100644 --- a/onchaind/Makefile +++ b/onchaind/Makefile @@ -62,6 +62,7 @@ ONCHAIND_COMMON_OBJS := \ common/key_derive.o \ common/memleak.o \ common/msg_queue.o \ + common/onionreply.o \ common/peer_billboard.o \ common/permute_tx.o \ common/status.o \ diff --git a/openingd/Makefile b/openingd/Makefile index ea146d7e1..326715aa3 100644 --- a/openingd/Makefile +++ b/openingd/Makefile @@ -62,6 +62,7 @@ OPENINGD_COMMON_OBJS := \ common/keyset.o \ common/memleak.o \ common/msg_queue.o \ + common/onionreply.o \ common/per_peer_state.o \ common/peer_billboard.o \ common/peer_failed.o \ diff --git a/wallet/test/Makefile b/wallet/test/Makefile index fca59ea10..c594429f4 100644 --- a/wallet/test/Makefile +++ b/wallet/test/Makefile @@ -12,6 +12,7 @@ WALLET_TEST_COMMON_OBJS := \ common/type_to_string.o \ common/memleak.o \ common/node_id.o \ + common/onionreply.o \ common/key_derive.o \ common/pseudorand.o \ common/timeout.o \ diff --git a/wallet/test/run-wallet.c b/wallet/test/run-wallet.c index 60f672915..5571bd912 100644 --- a/wallet/test/run-wallet.c +++ b/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) { fprintf(stderr, "payment_failed called!\n"); abort(); } /* Generated stub for payment_store */ -void payment_store(struct lightningd *ld UNNEEDED, - struct wallet_payment *payment UNNEEDED) +void payment_store(struct lightningd *ld UNNEEDED, struct wallet_payment *payment UNNEEDED) { fprintf(stderr, "payment_store called!\n"); abort(); } /* Generated stub for payment_succeeded */ 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 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 onionreply *onionreply; /* Make sure we have our references correct */ db_begin_transaction(w->db); @@ -1215,8 +1215,9 @@ static bool test_htlc_crud(struct lightningd *ld, const tal_t *ctx) CHECK_MSG( transaction_wrap(w->db, wallet_htlc_update(w, in.dbid, SENT_REMOVE_HTLC, &payment_key, 0, NULL)), "Update HTLC with payment_key failed"); + onionreply = new_onionreply(tmpctx, tal_arrz(tmpctx, u8, 100)); 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"); CHECK_MSG(transaction_wrap(w->db, wallet_htlc_save_out(w, chan, &out)), diff --git a/wallet/wallet.c b/wallet/wallet.c index 66ad26d1b..05ff3974a 100644 --- a/wallet/wallet.c +++ b/wallet/wallet.c @@ -8,6 +8,7 @@ #include #include #include +#include #include #include #include @@ -1757,7 +1758,8 @@ void wallet_htlc_save_out(struct wallet *wallet, void wallet_htlc_update(struct wallet *wallet, const u64 htlc_dbid, const enum htlc_state new_state, const struct preimage *payment_key, - enum onion_type failcode, const u8 *failuremsg) + enum onion_type failcode, + const struct onionreply *failuremsg) { 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); if (failuremsg) - db_bind_blob(stmt, 3, failuremsg, tal_bytelen(failuremsg)); + db_bind_onionreply(stmt, 3, failuremsg); else 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), 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); 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), 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->in = NULL; @@ -2473,7 +2481,7 @@ void wallet_payment_get_failinfo(const tal_t *ctx, const struct sha256 *payment_hash, u64 partid, /* outputs */ - u8 **failonionreply, + struct onionreply **failonionreply, bool *faildestperm, int *failindex, enum onion_type *failcode, @@ -2503,9 +2511,7 @@ void wallet_payment_get_failinfo(const tal_t *ctx, if (db_column_is_null(stmt, 0)) *failonionreply = NULL; else { - len = db_column_bytes(stmt, 0); - *failonionreply = tal_arr(ctx, u8, len); - memcpy(*failonionreply, db_column_blob(stmt, 0), len); + *failonionreply = db_column_onionreply(ctx, stmt, 0); } *faildestperm = db_column_int(stmt, 1) != 0; *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, const struct sha256 *payment_hash, u64 partid, - const u8 *failonionreply /*tal_arr*/, + const struct onionreply *failonionreply, bool faildestperm, int failindex, enum onion_type failcode, @@ -2570,8 +2576,8 @@ void wallet_payment_set_failinfo(struct wallet *wallet, " WHERE payment_hash=?" " AND partid=?;")); if (failonionreply) - db_bind_blob(stmt, 0, failonionreply, - tal_count(failonionreply)); + db_bind_blob(stmt, 0, failonionreply->contents, + tal_count(failonionreply->contents)); else db_bind_null(stmt, 0); diff --git a/wallet/wallet.h b/wallet/wallet.h index 5d82eb36f..00e5a7368 100644 --- a/wallet/wallet.h +++ b/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, const enum htlc_state new_state, 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. @@ -998,7 +999,7 @@ void wallet_payment_get_failinfo(const tal_t *ctx, const struct sha256 *payment_hash, u64 partid, /* outputs */ - u8 **failonionreply, + struct onionreply **failonionreply, bool *faildestperm, int *failindex, 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, const struct sha256 *payment_hash, u64 partid, - const u8 *failonionreply, + const struct onionreply *failonionreply, bool faildestperm, int failindex, enum onion_type failcode,