From 26dda57cc091347a2c22000c41913880fa2898ab Mon Sep 17 00:00:00 2001 From: Rusty Russell Date: Tue, 15 Jan 2019 14:21:27 +1030 Subject: [PATCH] utils: make tal_arr_expand safer. Christian and I both unwittingly used it in form: *tal_arr_expand(&x) = tal(x, ...) Since '=' isn't a sequence point, the compiler can (and does!) cache the value of x, handing it to tal *after* tal_arr_expand() moves it due to tal_resize(). The new version is somewhat less convenient to use, but doesn't have this problem, since the assignment is always evaluated after the resize. Signed-off-by: Rusty Russell --- channeld/channeld.c | 47 +++++++------- channeld/full_channel.c | 6 +- common/bolt11.c | 6 +- common/decode_short_channel_ids.c | 5 +- common/memleak.c | 4 +- common/msg_queue.c | 2 +- common/param.c | 14 +++-- common/utils.h | 16 +++-- connectd/connectd.c | 19 +++--- gossipd/gossipd.c | 68 ++++++++++----------- gossipd/routing.c | 6 +- lightningd/bitcoind.c | 2 +- lightningd/chaintopology.c | 2 +- lightningd/channel_control.c | 2 +- lightningd/invoice.c | 5 +- lightningd/json_stream.c | 2 +- lightningd/jsonrpc.c | 7 ++- lightningd/options.c | 7 ++- lightningd/peer_htlcs.c | 43 ++++++------- lightningd/plugin.c | 6 +- lightningd/test/run-invoice-select-inchan.c | 9 +-- onchaind/onchaind.c | 6 +- tools/check-bolt.c | 8 +-- wallet/db.c | 7 ++- wallet/txfilter.c | 4 +- wallet/wallet.c | 24 +++++--- 26 files changed, 173 insertions(+), 154 deletions(-) diff --git a/channeld/channeld.c b/channeld/channeld.c index 89707e29a361..c0e357e9ca8e 100644 --- a/channeld/channeld.c +++ b/channeld/channeld.c @@ -1224,28 +1224,31 @@ static u8 *got_commitsig_msg(const tal_t *ctx, for (size_t i = 0; i < tal_count(changed_htlcs); i++) { const struct htlc *htlc = changed_htlcs[i]; if (htlc->state == RCVD_ADD_COMMIT) { - struct added_htlc *a = tal_arr_expand(&added); - struct secret *s = tal_arr_expand(&shared_secret); - a->id = htlc->id; - a->amount_msat = htlc->msatoshi; - a->payment_hash = htlc->rhash; - a->cltv_expiry = abs_locktime_to_blocks(&htlc->expiry); - memcpy(a->onion_routing_packet, + struct added_htlc a; + struct secret s; + + a.id = htlc->id; + a.amount_msat = htlc->msatoshi; + a.payment_hash = htlc->rhash; + a.cltv_expiry = abs_locktime_to_blocks(&htlc->expiry); + memcpy(a.onion_routing_packet, htlc->routing, - sizeof(a->onion_routing_packet)); + sizeof(a.onion_routing_packet)); /* Invalid shared secret gets set to all-zero: our * code generator can't make arrays of optional values */ if (!htlc->shared_secret) - memset(s, 0, sizeof(*s)); + memset(&s, 0, sizeof(s)); else - *s = *htlc->shared_secret; + s = *htlc->shared_secret; + tal_arr_expand(&added, a); + tal_arr_expand(&shared_secret, s); } else if (htlc->state == RCVD_REMOVE_COMMIT) { if (htlc->r) { - struct fulfilled_htlc *f; + struct fulfilled_htlc f; assert(!htlc->fail && !htlc->failcode); - f = tal_arr_expand(&fulfilled); - f->id = htlc->id; - f->payment_preimage = *htlc->r; + f.id = htlc->id; + f.payment_preimage = *htlc->r; + tal_arr_expand(&fulfilled, f); } else { struct failed_htlc *f; assert(htlc->fail || htlc->failcode); @@ -1255,15 +1258,16 @@ static u8 *got_commitsig_msg(const tal_t *ctx, f->failreason = cast_const(u8 *, htlc->fail); f->scid = cast_const(struct short_channel_id *, htlc->failed_scid); - *tal_arr_expand(&failed) = f; + tal_arr_expand(&failed, f); } } else { - struct changed_htlc *c = tal_arr_expand(&changed); + struct changed_htlc c; assert(htlc->state == RCVD_REMOVE_ACK_COMMIT || htlc->state == RCVD_ADD_ACK_COMMIT); - c->id = htlc->id; - c->newstate = htlc->state; + c.id = htlc->id; + c.newstate = htlc->state; + tal_arr_expand(&changed, c); } } @@ -1418,15 +1422,16 @@ static u8 *got_revoke_msg(const tal_t *ctx, u64 revoke_num, struct changed_htlc *changed = tal_arr(tmpctx, struct changed_htlc, 0); for (size_t i = 0; i < tal_count(changed_htlcs); i++) { - struct changed_htlc *c = tal_arr_expand(&changed); + struct changed_htlc c; const struct htlc *htlc = changed_htlcs[i]; status_trace("HTLC %"PRIu64"[%s] => %s", htlc->id, side_to_str(htlc_owner(htlc)), htlc_state_name(htlc->state)); - c->id = changed_htlcs[i]->id; - c->newstate = changed_htlcs[i]->state; + c.id = changed_htlcs[i]->id; + c.newstate = changed_htlcs[i]->state; + tal_arr_expand(&changed, c); } msg = towire_channel_got_revoke(ctx, revoke_num, per_commitment_secret, diff --git a/channeld/full_channel.c b/channeld/full_channel.c index cffada329f6d..91a91dd81c59 100644 --- a/channeld/full_channel.c +++ b/channeld/full_channel.c @@ -65,7 +65,7 @@ static void htlc_arr_append(const struct htlc ***arr, const struct htlc *htlc) { if (!arr) return; - *tal_arr_expand(arr) = htlc; + tal_arr_expand(arr, htlc); } /* What does adding the HTLC do to the balance for this side */ @@ -227,8 +227,8 @@ static void add_htlcs(struct bitcoin_tx ***txs, /* Append to array. */ assert(tal_count(*txs) == tal_count(*wscripts)); - *tal_arr_expand(wscripts) = wscript; - *tal_arr_expand(txs) = tx; + tal_arr_expand(wscripts, wscript); + tal_arr_expand(txs, tx); } } diff --git a/common/bolt11.c b/common/bolt11.c index 553bd6412775..6f8285714512 100644 --- a/common/bolt11.c +++ b/common/bolt11.c @@ -424,13 +424,15 @@ static char *decode_r(struct bolt11 *b11, pull_bits_certain(hu5, data, data_len, r8, data_length * 5, false); do { - if (!fromwire_route_info(&cursor, &rlen, tal_arr_expand(&r))) { + struct route_info ri; + if (!fromwire_route_info(&cursor, &rlen, &ri)) { return tal_fmt(b11, "r: hop %zu truncated", n); } + tal_arr_expand(&r, ri); } while (rlen); /* Append route */ - *tal_arr_expand(&b11->routes) = tal_steal(b11, r); + tal_arr_expand(&b11->routes, tal_steal(b11, r)); return NULL; } diff --git a/common/decode_short_channel_ids.c b/common/decode_short_channel_ids.c index 4bdf89817015..c97abe4abc84 100644 --- a/common/decode_short_channel_ids.c +++ b/common/decode_short_channel_ids.c @@ -48,8 +48,9 @@ struct short_channel_id *decode_short_ids(const tal_t *ctx, const u8 *encoded) case SHORTIDS_UNCOMPRESSED: scids = tal_arr(ctx, struct short_channel_id, 0); while (max) { - fromwire_short_channel_id(&encoded, &max, - tal_arr_expand(&scids)); + struct short_channel_id scid; + fromwire_short_channel_id(&encoded, &max, &scid); + tal_arr_expand(&scids, scid); } /* encoded is set to NULL if we ran over */ diff --git a/common/memleak.c b/common/memleak.c index 488d00cc2ff8..82c1ed1e5b4f 100644 --- a/common/memleak.c +++ b/common/memleak.c @@ -48,8 +48,8 @@ void *notleak_(const void *ptr, bool plus_children) if (!notleaks) return cast_const(void *, ptr); - *tal_arr_expand(¬leaks) = ptr; - *tal_arr_expand(¬leak_children) = plus_children; + tal_arr_expand(¬leaks, ptr); + tal_arr_expand(¬leak_children, plus_children); tal_add_notifier(ptr, TAL_NOTIFY_FREE|TAL_NOTIFY_MOVE, notleak_change); return cast_const(void *, ptr); diff --git a/common/msg_queue.c b/common/msg_queue.c index d5e82beaa2a7..6190de97dfa5 100644 --- a/common/msg_queue.c +++ b/common/msg_queue.c @@ -16,7 +16,7 @@ struct msg_queue *msg_queue_new(const tal_t *ctx) static void do_enqueue(struct msg_queue *q, const u8 *add TAKES) { - *tal_arr_expand(&q->q) = tal_dup_arr(q, u8, add, tal_count(add), 0); + tal_arr_expand(&q->q, tal_dup_arr(q, u8, add, tal_count(add), 0)); /* In case someone is waiting */ io_wake(q); diff --git a/common/param.c b/common/param.c index d576abab5b22..adabdd1f1b38 100644 --- a/common/param.c +++ b/common/param.c @@ -21,13 +21,15 @@ static bool param_add(struct param **params, if (!(name && cbx && arg)) return false; #endif - struct param *last = tal_arr_expand(params); + struct param last; - last->is_set = false; - last->name = name; - last->required = required; - last->cbx = cbx; - last->arg = arg; + last.is_set = false; + last.name = name; + last.required = required; + last.cbx = cbx; + last.arg = arg; + + tal_arr_expand(params, last); return true; } diff --git a/common/utils.h b/common/utils.h index 5cff73610468..f7106ca7691e 100644 --- a/common/utils.h +++ b/common/utils.h @@ -19,15 +19,13 @@ char *tal_hex(const tal_t *ctx, const tal_t *data); /* Allocate and fill a buffer with the data of this hex string. */ u8 *tal_hexdata(const tal_t *ctx, const void *str, size_t len); -/* Helper macro to extend tal_arr and return pointer new last element. */ -#if HAVE_STATEMENT_EXPR -/* More efficient version calls tal_count() once */ -#define tal_arr_expand(p) \ - ({ size_t n = tal_count(*p); tal_resize((p), n+1); *(p) + n; }) -#else -#define tal_arr_expand(p) \ - (tal_resize((p), tal_count(*(p))+1), (*p) + tal_count(*(p))-1) -#endif +/* Note: p is never a complex expression, otherwise this multi-evaluates! */ +#define tal_arr_expand(p, s) \ + do { \ + size_t n = tal_count(*(p)); \ + tal_resize((p), n+1); \ + (*(p))[n] = (s); \ + } while(0) /** * Remove an element from an array diff --git a/connectd/connectd.c b/connectd/connectd.c index 8ccb76df9bfe..5d49246e211a 100644 --- a/connectd/connectd.c +++ b/connectd/connectd.c @@ -767,9 +767,10 @@ static void add_listen_fd(struct daemon *daemon, int fd, bool mayfail) /*~ utils.h contains a convenience macro tal_arr_expand which * reallocates a tal_arr to make it one longer, then returns a pointer * to the (new) last element. */ - struct listen_fd *l = tal_arr_expand(&daemon->listen_fds); - l->fd = fd; - l->mayfail = mayfail; + struct listen_fd l; + l.fd = fd; + l.mayfail = mayfail; + tal_arr_expand(&daemon->listen_fds, l); } /*~ Helper routine to create and bind a socket of a given type; like many @@ -876,13 +877,13 @@ static bool public_address(struct daemon *daemon, struct wireaddr *wireaddr) static void add_announcable(struct wireaddr **announcable, const struct wireaddr *addr) { - *tal_arr_expand(announcable) = *addr; + tal_arr_expand(announcable, *addr); } static void add_binding(struct wireaddr_internal **binding, const struct wireaddr_internal *addr) { - *tal_arr_expand(binding) = *addr; + tal_arr_expand(binding, *addr); } /*~ ccan/asort provides a type-safe sorting function; it requires a comparison @@ -1223,7 +1224,7 @@ static void add_seed_addrs(struct wireaddr_internal **addrs, status_trace("Resolved %s to %s", addr, type_to_string(tmpctx, struct wireaddr, &a.u.wireaddr)); - *tal_arr_expand(addrs) = a; + tal_arr_expand(addrs, a); } } @@ -1254,7 +1255,7 @@ static void add_gossip_addrs(struct wireaddr_internal **addrs, struct wireaddr_internal addr; addr.itype = ADDR_INTERNAL_WIREADDR; addr.u.wireaddr = normal_addrs[i]; - *tal_arr_expand(addrs) = addr; + tal_arr_expand(addrs, addr); } } @@ -1284,7 +1285,7 @@ static void try_connect_peer(struct daemon *daemon, /* They can supply an optional address for the connect RPC */ if (addrhint) - *tal_arr_expand(&addrs) = *addrhint; + tal_arr_expand(&addrs, *addrhint); add_gossip_addrs(&addrs, id); @@ -1297,7 +1298,7 @@ static void try_connect_peer(struct daemon *daemon, wireaddr_from_unresolved(&unresolved, seedname(tmpctx, id), DEFAULT_PORT); - *tal_arr_expand(&addrs) = unresolved; + tal_arr_expand(&addrs, unresolved); } else if (daemon->use_dns) { add_seed_addrs(&addrs, id, daemon->broken_resolver_response); diff --git a/gossipd/gossipd.c b/gossipd/gossipd.c index d04300a5c910..7dbddca70dd8 100644 --- a/gossipd/gossipd.c +++ b/gossipd/gossipd.c @@ -1022,8 +1022,8 @@ static void maybe_create_next_scid_reply(struct peer *peer) queue_peer_msg(peer, chan->half[1].channel_update); /* Record node ids for later transmission of node_announcement */ - *tal_arr_expand(&peer->scid_query_nodes) = chan->nodes[0]->id; - *tal_arr_expand(&peer->scid_query_nodes) = chan->nodes[1]->id; + tal_arr_expand(&peer->scid_query_nodes, chan->nodes[0]->id); + tal_arr_expand(&peer->scid_query_nodes, chan->nodes[1]->id); sent = true; } @@ -1919,14 +1919,12 @@ static void append_half_channel(struct gossip_getchannels_entry **entries, int idx) { const struct half_chan *c = &chan->half[idx]; - struct gossip_getchannels_entry *e; + struct gossip_getchannels_entry e; /* If we've never seen a channel_update for this direction... */ if (!is_halfchan_defined(c)) return; - e = tal_arr_expand(entries); - /* Our 'struct chan' contains two nodes: they are in pubkey_cmp order * (ie. chan->nodes[0] is the lesser pubkey) and this is the same as * the direction bit in `channel_update`s `channel_flags`. @@ -1936,18 +1934,20 @@ static void append_half_channel(struct gossip_getchannels_entry **entries, * pubkeys to DER and back: that proves quite expensive, and we assume * we're on the same architecture as lightningd, so we just send them * raw in this case. */ - raw_pubkey(e->source, &chan->nodes[idx]->id); - raw_pubkey(e->destination, &chan->nodes[!idx]->id); - e->satoshis = chan->satoshis; - e->channel_flags = c->channel_flags; - e->message_flags = c->message_flags; - e->local_disabled = chan->local_disabled; - e->public = is_chan_public(chan); - e->short_channel_id = chan->scid; - e->last_update_timestamp = c->last_timestamp; - e->base_fee_msat = c->base_fee; - e->fee_per_millionth = c->proportional_fee; - e->delay = c->delay; + raw_pubkey(e.source, &chan->nodes[idx]->id); + raw_pubkey(e.destination, &chan->nodes[!idx]->id); + e.satoshis = chan->satoshis; + e.channel_flags = c->channel_flags; + e.message_flags = c->message_flags; + e.local_disabled = chan->local_disabled; + e.public = is_chan_public(chan); + e.short_channel_id = chan->scid; + e.last_update_timestamp = c->last_timestamp; + e.base_fee_msat = c->base_fee; + e.fee_per_millionth = c->proportional_fee; + e.delay = c->delay; + + tal_arr_expand(entries, e); } /*~ Marshal (possibly) both channel directions into entries */ @@ -2002,21 +2002,21 @@ static void append_node(const struct gossip_getnodes_entry ***entries, { struct gossip_getnodes_entry *e; - *tal_arr_expand(entries) = e - = tal(*entries, struct gossip_getnodes_entry); + e = tal(*entries, struct gossip_getnodes_entry); raw_pubkey(e->nodeid, &n->id); e->last_timestamp = n->last_timestamp; /* Timestamp on wire is an unsigned 32 bit: we use a 64-bit signed, so * -1 means "we never received a channel_update". */ - if (e->last_timestamp < 0) - return; + if (e->last_timestamp >= 0) { + e->globalfeatures = n->globalfeatures; + e->addresses = n->addresses; + BUILD_ASSERT(ARRAY_SIZE(e->alias) == ARRAY_SIZE(n->alias)); + BUILD_ASSERT(ARRAY_SIZE(e->color) == ARRAY_SIZE(n->rgb_color)); + memcpy(e->alias, n->alias, ARRAY_SIZE(e->alias)); + memcpy(e->color, n->rgb_color, ARRAY_SIZE(e->color)); + } - e->globalfeatures = n->globalfeatures; - e->addresses = n->addresses; - BUILD_ASSERT(ARRAY_SIZE(e->alias) == ARRAY_SIZE(n->alias)); - BUILD_ASSERT(ARRAY_SIZE(e->color) == ARRAY_SIZE(n->rgb_color)); - memcpy(e->alias, n->alias, ARRAY_SIZE(e->alias)); - memcpy(e->color, n->rgb_color, ARRAY_SIZE(e->color)); + tal_arr_expand(entries, e); } /* Simply routine when they ask for `listnodes` */ @@ -2125,7 +2125,7 @@ static struct io_plan *get_incoming_channels(struct io_conn *conn, for (size_t i = 0; i < tal_count(node->chans); i++) { const struct chan *c = node->chans[i]; const struct half_chan *hc; - struct route_info *ri; + struct route_info ri; /* Don't leak private channels. */ if (!is_chan_public(c)) @@ -2136,12 +2136,12 @@ static struct io_plan *get_incoming_channels(struct io_conn *conn, if (!is_halfchan_enabled(hc)) continue; - ri = tal_arr_expand(&r); - ri->pubkey = other_node(node, c)->id; - ri->short_channel_id = c->scid; - ri->fee_base_msat = hc->base_fee; - ri->fee_proportional_millionths = hc->proportional_fee; - ri->cltv_expiry_delta = hc->delay; + ri.pubkey = other_node(node, c)->id; + ri.short_channel_id = c->scid; + ri.fee_base_msat = hc->base_fee; + ri.fee_proportional_millionths = hc->proportional_fee; + ri.cltv_expiry_delta = hc->delay; + tal_arr_expand(&r, ri); } } diff --git a/gossipd/routing.c b/gossipd/routing.c index c92be999e3e4..217ebe6dcf5d 100644 --- a/gossipd/routing.c +++ b/gossipd/routing.c @@ -314,8 +314,8 @@ struct chan *new_chan(struct routing_state *rstate, chan->satoshis = satoshis; chan->local_disabled = false; - *tal_arr_expand(&n2->chans) = chan; - *tal_arr_expand(&n1->chans) = chan; + tal_arr_expand(&n2->chans, chan); + tal_arr_expand(&n1->chans, chan); /* Populate with (inactive) connections */ init_half_chan(rstate, chan, n1idx); @@ -1306,7 +1306,7 @@ static struct wireaddr *read_addresses(const tal_t *ctx, const u8 *ser) break; } - *tal_arr_expand(&wireaddrs) = wireaddr; + tal_arr_expand(&wireaddrs, wireaddr); } return wireaddrs; } diff --git a/lightningd/bitcoind.c b/lightningd/bitcoind.c index da0bbca87449..9baa22e71a84 100644 --- a/lightningd/bitcoind.c +++ b/lightningd/bitcoind.c @@ -32,7 +32,7 @@ /* Add the n'th arg to *args, incrementing n and keeping args of size n+1 */ static void add_arg(const char ***args, const char *arg) { - *tal_arr_expand(args) = arg; + tal_arr_expand(args, arg); } static const char **gather_args(const struct bitcoind *bitcoind, diff --git a/lightningd/chaintopology.c b/lightningd/chaintopology.c index 3e94d84986d1..c9bfa5e8d28c 100644 --- a/lightningd/chaintopology.c +++ b/lightningd/chaintopology.c @@ -167,7 +167,7 @@ static void rebroadcast_txs(struct chain_topology *topo, struct command *cmd) if (wallet_transaction_height(topo->ld->wallet, &otx->txid)) continue; - *tal_arr_expand(&txs->txs) = tal_strdup(txs, otx->hextx); + tal_arr_expand(&txs->txs, tal_strdup(txs, otx->hextx)); } /* Let this do the dirty work. */ diff --git a/lightningd/channel_control.c b/lightningd/channel_control.c index 6fce5239e28b..8e3e0b932635 100644 --- a/lightningd/channel_control.c +++ b/lightningd/channel_control.c @@ -474,7 +474,7 @@ void channel_notify_new_block(struct lightningd *ld, list_for_each (&ld->peers, peer, list) { list_for_each (&peer->channels, channel, list) if (is_fundee_should_forget(ld, channel, block_height)) { - *tal_arr_expand(&to_forget) = channel; + tal_arr_expand(&to_forget, channel); } } diff --git a/lightningd/invoice.c b/lightningd/invoice.c index 9e42d5ad24aa..179bb7f922e9 100644 --- a/lightningd/invoice.c +++ b/lightningd/invoice.c @@ -343,10 +343,11 @@ static struct command_result *json_invoice(struct command *cmd, fallback_scripts = tal_arr(cmd, const u8 *, 0); for (i = fallbacks + 1; i < end; i = json_next(i)) { struct command_result *r; - r = parse_fallback(cmd, buffer, i, - tal_arr_expand(&fallback_scripts)); + const u8 *fs; + r = parse_fallback(cmd, buffer, i, &fs); if (r) return r; + tal_arr_expand(&fallback_scripts, fs); } } diff --git a/lightningd/json_stream.c b/lightningd/json_stream.c index 611537a6b896..b90723d9100e 100644 --- a/lightningd/json_stream.c +++ b/lightningd/json_stream.c @@ -204,7 +204,7 @@ static void json_start_member(struct json_stream *js, const char *fieldname) static void js_indent(struct json_stream *js, jsmntype_t type) { #if DEVELOPER - *tal_arr_expand(&js->wrapping) = type; + tal_arr_expand(&js->wrapping, type); #endif js->empty = true; js->indent++; diff --git a/lightningd/jsonrpc.c b/lightningd/jsonrpc.c index 89a4dfdd597f..927bbb5d41ce 100644 --- a/lightningd/jsonrpc.c +++ b/lightningd/jsonrpc.c @@ -114,11 +114,14 @@ static struct json_stream *jcon_new_json_stream(const tal_t *ctx, struct json_connection *jcon, struct command *writer) { + struct json_stream *js = new_json_stream(ctx, writer); + /* Wake writer to start streaming, in case it's not already. */ io_wake(jcon); /* FIXME: Keep streams around for recycling. */ - return *tal_arr_expand(&jcon->js_arr) = new_json_stream(ctx, writer); + tal_arr_expand(&jcon->js_arr, js); + return js; } static void jcon_remove_json_stream(struct json_connection *jcon, @@ -768,7 +771,7 @@ bool jsonrpc_command_add(struct jsonrpc *rpc, struct json_command *command) if (streq(rpc->commands[i]->name, command->name)) return false; - *tal_arr_expand(&rpc->commands) = command; + tal_arr_expand(&rpc->commands, command); return true; } diff --git a/lightningd/options.c b/lightningd/options.c index 09a1b7719361..90b4786ae948 100644 --- a/lightningd/options.c +++ b/lightningd/options.c @@ -129,17 +129,18 @@ static char *opt_add_addr_withtype(const char *arg, bool wildcard_ok) { char const *err_msg; + struct wireaddr_internal wi; assert(arg != NULL); - *tal_arr_expand(&ld->proposed_listen_announce) = ala; - if (!parse_wireaddr_internal(arg, tal_arr_expand(&ld->proposed_wireaddr), + tal_arr_expand(&ld->proposed_listen_announce, ala); + if (!parse_wireaddr_internal(arg, &wi, ld->portnum, wildcard_ok, !ld->use_proxy_always, false, &err_msg)) { return tal_fmt(NULL, "Unable to parse address '%s': %s", arg, err_msg); } - + tal_arr_expand(&ld->proposed_wireaddr, wi); return NULL; } diff --git a/lightningd/peer_htlcs.c b/lightningd/peer_htlcs.c index 83dd766b9d58..3f6463511e4c 100644 --- a/lightningd/peer_htlcs.c +++ b/lightningd/peer_htlcs.c @@ -1389,19 +1389,17 @@ static void add_htlc(struct added_htlc **htlcs, const u8 onion_routing_packet[TOTAL_PACKET_SIZE], enum htlc_state state) { - struct added_htlc *a; - enum htlc_state *h; - - a = tal_arr_expand(htlcs); - h = tal_arr_expand(htlc_states); - - a->id = id; - a->amount_msat = amount_msat; - a->payment_hash = *payment_hash; - a->cltv_expiry = cltv_expiry; - memcpy(a->onion_routing_packet, onion_routing_packet, - sizeof(a->onion_routing_packet)); - *h = state; + struct added_htlc a; + + a.id = id; + a.amount_msat = amount_msat; + a.payment_hash = *payment_hash; + a.cltv_expiry = cltv_expiry; + memcpy(a.onion_routing_packet, onion_routing_packet, + sizeof(a.onion_routing_packet)); + + tal_arr_expand(htlcs, a); + tal_arr_expand(htlc_states, state); } static void add_fulfill(u64 id, enum side side, @@ -1409,14 +1407,13 @@ static void add_fulfill(u64 id, enum side side, struct fulfilled_htlc **fulfilled_htlcs, enum side **fulfilled_sides) { - struct fulfilled_htlc *f; - enum side *s; - - f = tal_arr_expand(fulfilled_htlcs); - s = tal_arr_expand(fulfilled_sides); - f->id = id; - f->payment_preimage = *payment_preimage; - *s = side; + struct fulfilled_htlc f; + + f.id = id; + f.payment_preimage = *payment_preimage; + + tal_arr_expand(fulfilled_htlcs, f); + tal_arr_expand(fulfilled_sides, side); } static void add_fail(u64 id, enum side side, @@ -1444,8 +1441,8 @@ static void add_fail(u64 id, enum side side, else newf->failreason = NULL; - *tal_arr_expand(failed_htlcs) = newf; - *tal_arr_expand(failed_sides) = side; + tal_arr_expand(failed_htlcs, newf); + tal_arr_expand(failed_sides, side); } /* FIXME: Load direct from db. */ diff --git a/lightningd/plugin.c b/lightningd/plugin.c index 9299c8765e5a..e2b0d5bfcbe3 100644 --- a/lightningd/plugin.c +++ b/lightningd/plugin.c @@ -234,7 +234,7 @@ plugin_request_new_(struct plugin *plugin, static void plugin_send(struct plugin *plugin, struct json_stream *stream) { tal_steal(plugin->js_arr, stream); - *tal_arr_expand(&plugin->js_arr) = stream; + tal_arr_expand(&plugin->js_arr, stream); io_wake(plugin); } @@ -746,7 +746,7 @@ static bool plugin_rpcmethod_add(struct plugin *plugin, cmd->name); return false; } - *tal_arr_expand(&plugin->methods) = cmd->name; + tal_arr_expand(&plugin->methods, cmd->name); return true; } @@ -808,7 +808,7 @@ static bool plugin_subscriptions_add(struct plugin *plugin, const char *buffer, return false; } - *tal_arr_expand(&plugin->subscriptions) = topic; + tal_arr_expand(&plugin->subscriptions, topic); } return true; } diff --git a/lightningd/test/run-invoice-select-inchan.c b/lightningd/test/run-invoice-select-inchan.c index 20e31fd5afe2..f5da0dbe8743 100644 --- a/lightningd/test/run-invoice-select-inchan.c +++ b/lightningd/test/run-invoice-select-inchan.c @@ -543,11 +543,12 @@ bool dev_disconnect_permanent(struct lightningd *ld UNNEEDED) static void add_inchan(struct route_info **inchans, int n) { - struct route_info *r = tal_arr_expand(inchans); - memset(&r->pubkey, n, sizeof(r->pubkey)); - memset(&r->short_channel_id, n, sizeof(r->short_channel_id)); - r->fee_base_msat = r->fee_proportional_millionths = r->cltv_expiry_delta + struct route_info r; + memset(&r.pubkey, n, sizeof(r.pubkey)); + memset(&r.short_channel_id, n, sizeof(r.short_channel_id)); + r.fee_base_msat = r.fee_proportional_millionths = r.cltv_expiry_delta = n; + tal_arr_expand(inchans, r); } static void add_peer(struct lightningd *ld, int n, enum channel_state state, diff --git a/onchaind/onchaind.c b/onchaind/onchaind.c index 813438018f91..5ef5c773c18d 100644 --- a/onchaind/onchaind.c +++ b/onchaind/onchaind.c @@ -410,7 +410,7 @@ static struct tracked_output * } else out->remote_htlc_sig = NULL; - *tal_arr_expand(outs) = out; + tal_arr_expand(outs, out); return out; } @@ -1521,7 +1521,7 @@ static const size_t *match_htlc_output(const tal_t *ctx, if (memeq(tx->output[outnum].script + 2, tal_count(tx->output[outnum].script) - 2, &sha, sizeof(sha))) - *tal_arr_expand(&matches) = i; + tal_arr_expand(&matches, i); } return matches; } @@ -1560,7 +1560,7 @@ static void note_missing_htlcs(u8 **htlc_scripts, if (tell_immediately[i]) wire_sync_write(REQ_FD, take(msg)); else - *tal_arr_expand(&missing_htlc_msgs) = msg; + tal_arr_expand(&missing_htlc_msgs, msg); } } diff --git a/tools/check-bolt.c b/tools/check-bolt.c index 7f7877af4988..bda9db19ee24 100644 --- a/tools/check-bolt.c +++ b/tools/check-bolt.c @@ -54,7 +54,7 @@ static bool get_files(const char *dir, const char *subdir, while ((e = readdir(d)) != NULL) { int preflen; - struct bolt_file *bf; + struct bolt_file bf; /* Must end in .md */ if (!strends(e->d_name, ".md")) @@ -74,12 +74,12 @@ static bool get_files(const char *dir, const char *subdir, if (verbose) printf("Found bolt %.*s\n", preflen, e->d_name); - bf = tal_arr_expand(files); - bf->prefix = tal_strndup(*files, e->d_name, preflen); - bf->contents + bf.prefix = tal_strndup(*files, e->d_name, preflen); + bf.contents = canonicalize(grab_file(*files, path_join(path, path, e->d_name))); + tal_arr_expand(files, bf); } return true; } diff --git a/wallet/db.c b/wallet/db.c index 9eb00d247cc1..1ec399ca53ea 100644 --- a/wallet/db.c +++ b/wallet/db.c @@ -782,8 +782,11 @@ sqlite3_column_short_channel_id_array(const tal_t *ctx, len = sqlite3_column_bytes(stmt, col); ret = tal_arr(ctx, struct short_channel_id, 0); - while (len != 0) - fromwire_short_channel_id(&ser, &len, tal_arr_expand(&ret)); + while (len != 0) { + struct short_channel_id scid; + fromwire_short_channel_id(&ser, &len, &scid); + tal_arr_expand(&ret, scid); + } return ret; } diff --git a/wallet/txfilter.c b/wallet/txfilter.c index f18519165632..581aa1dc3e76 100644 --- a/wallet/txfilter.c +++ b/wallet/txfilter.c @@ -54,8 +54,8 @@ struct txfilter *txfilter_new(const tal_t *ctx) void txfilter_add_scriptpubkey(struct txfilter *filter, const u8 *script TAKES) { - *tal_arr_expand(&filter->scriptpubkeys) - = tal_dup_arr(filter, u8, script, tal_count(script), 0); + tal_arr_expand(&filter->scriptpubkeys, + tal_dup_arr(filter, u8, script, tal_count(script), 0)); } void txfilter_add_derkey(struct txfilter *filter, diff --git a/wallet/wallet.c b/wallet/wallet.c index be34a30a66bf..956f80df6119 100644 --- a/wallet/wallet.c +++ b/wallet/wallet.c @@ -189,7 +189,7 @@ struct utxo **wallet_get_utxos(const tal_t *ctx, struct wallet *w, const enum ou results = tal_arr(ctx, struct utxo*, 0); for (i=0; sqlite3_step(stmt) == SQLITE_ROW; i++) { struct utxo *u = wallet_stmt2output(results, stmt); - *tal_arr_expand(&results) = u; + tal_arr_expand(&results, u); } db_stmt_done(stmt); @@ -209,7 +209,7 @@ struct utxo **wallet_get_unconfirmed_closeinfo_utxos(const tal_t *ctx, struct wa results = tal_arr(ctx, struct utxo*, 0); for (i=0; sqlite3_step(stmt) == SQLITE_ROW; i++) { struct utxo *u = wallet_stmt2output(results, stmt); - *tal_arr_expand(&results) = u; + tal_arr_expand(&results, u); } db_stmt_done(stmt); @@ -282,7 +282,7 @@ static const struct utxo **wallet_select(const tal_t *ctx, struct wallet *w, size_t input_weight; struct utxo *u = tal_steal(utxos, available[i]); - *tal_arr_expand(&utxos) = u; + tal_arr_expand(&utxos, u); if (!wallet_update_output_status( w, &available[i]->txid, available[i]->outnum, @@ -549,8 +549,11 @@ wallet_htlc_sigs_load(const tal_t *ctx, struct wallet *w, u64 channelid) secp256k1_ecdsa_signature *htlc_sigs = tal_arr(ctx, secp256k1_ecdsa_signature, 0); sqlite3_bind_int64(stmt, 1, channelid); - while (stmt && sqlite3_step(stmt) == SQLITE_ROW) - sqlite3_column_signature(stmt, 0, tal_arr_expand(&htlc_sigs)); + while (stmt && sqlite3_step(stmt) == SQLITE_ROW) { + secp256k1_ecdsa_signature sig; + sqlite3_column_signature(stmt, 0, &sig); + tal_arr_expand(&htlc_sigs, sig); + } db_stmt_done(stmt); log_debug(w->log, "Loaded %zu HTLC signatures from DB", @@ -1565,17 +1568,18 @@ struct htlc_stub *wallet_htlc_stubs(const tal_t *ctx, struct wallet *wallet, stubs = tal_arr(ctx, struct htlc_stub, 0); while (sqlite3_step(stmt) == SQLITE_ROW) { - struct htlc_stub *stub = tal_arr_expand(&stubs); + struct htlc_stub stub; assert(sqlite3_column_int64(stmt, 0) == chan->dbid); /* FIXME: merge these two enums */ - stub->owner = sqlite3_column_int(stmt, 1)==DIRECTION_INCOMING?REMOTE:LOCAL; - stub->cltv_expiry = sqlite3_column_int(stmt, 2); - stub->id = sqlite3_column_int(stmt, 3); + stub.owner = sqlite3_column_int(stmt, 1)==DIRECTION_INCOMING?REMOTE:LOCAL; + stub.cltv_expiry = sqlite3_column_int(stmt, 2); + stub.id = sqlite3_column_int(stmt, 3); sqlite3_column_sha256(stmt, 4, &payment_hash); - ripemd160(&stub->ripemd, payment_hash.u.u8, sizeof(payment_hash.u)); + ripemd160(&stub.ripemd, payment_hash.u.u8, sizeof(payment_hash.u)); + tal_arr_expand(&stubs, stub); } db_stmt_done(stmt); return stubs;