From 96f05549b207bd86fe82f9fc192acb222f4a52b3 Mon Sep 17 00:00:00 2001 From: Rusty Russell Date: Thu, 27 Sep 2018 09:49:24 +0930 Subject: [PATCH] common/utils.h: add tal_arr_expand helper. We do this a lot, and had boutique helpers in various places. So add a more generic one; for convenience it returns a pointer to the new end element. I prefer the name tal_arr_expand to tal_arr_append, since it's up to the caller to populate the new array entry. Signed-off-by: Rusty Russell --- channeld/channeld.c | 33 +++++++++-------------- channeld/full_channel.c | 30 +++++---------------- common/bolt11.c | 9 ++----- common/decode_short_channel_ids.c | 9 +++---- common/memleak.c | 10 +++---- common/msg_queue.c | 5 ++-- common/utils.h | 10 +++++++ connectd/connectd.c | 31 +++++++-------------- gossipd/gossipd.c | 9 ++----- gossipd/routing.c | 14 +++------- lightningd/bitcoind.c | 4 +-- lightningd/chaintopology.c | 5 +--- lightningd/channel_control.c | 4 +-- lightningd/invoice.c | 7 ++--- lightningd/lightningd.c | 4 +-- lightningd/options.c | 9 +++---- lightningd/param.c | 5 +--- lightningd/peer_htlcs.c | 42 +++++++++++------------------ onchaind/onchaind.c | 11 +++----- tools/check-bolt.c | 10 +++---- wallet/db.c | 9 ++----- wallet/txfilter.c | 5 ++-- wallet/wallet.c | 45 ++++++++++++++----------------- 23 files changed, 111 insertions(+), 209 deletions(-) diff --git a/channeld/channeld.c b/channeld/channeld.c index 3cdd3b180..f249e3ad6 100644 --- a/channeld/channeld.c +++ b/channeld/channeld.c @@ -206,15 +206,6 @@ static void billboard_update(const struct peer *peer) announce_status, shutdown_status); } -/* Returns a pointer to the new end */ -static void *tal_arr_append_(void **p, size_t size) -{ - size_t n = tal_bytelen(*p) / size; - tal_resize_(p, size, n+1, false); - return (char *)(*p) + n * size; -} -#define tal_arr_append(p) tal_arr_append_((void **)(p), sizeof(**(p))) - static const u8 *hsm_req(const tal_t *ctx, const u8 *req TAKES) { u8 *msg; @@ -1171,8 +1162,8 @@ 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_append(&added); - struct secret *s = tal_arr_append(&shared_secret); + 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; @@ -1185,22 +1176,22 @@ static u8 *got_commitsig_msg(const tal_t *ctx, if (htlc->r) { struct fulfilled_htlc *f; assert(!htlc->fail); - f = tal_arr_append(&fulfilled); + f = tal_arr_expand(&fulfilled); f->id = htlc->id; f->payment_preimage = *htlc->r; } else { - struct failed_htlc **f; + struct failed_htlc *f; assert(htlc->fail); - f = tal_arr_append(&failed); - *f = tal(failed, struct failed_htlc); - (*f)->id = htlc->id; - (*f)->failcode = htlc->failcode; - (*f)->failreason = cast_const(u8 *, htlc->fail); - (*f)->scid = cast_const(struct short_channel_id *, + f = tal(failed, struct failed_htlc); + f->id = htlc->id; + f->failcode = htlc->failcode; + f->failreason = cast_const(u8 *, htlc->fail); + f->scid = cast_const(struct short_channel_id *, htlc->failed_scid); + *tal_arr_expand(&failed) = f; } } else { - struct changed_htlc *c = tal_arr_append(&changed); + struct changed_htlc *c = tal_arr_expand(&changed); assert(htlc->state == RCVD_REMOVE_ACK_COMMIT || htlc->state == RCVD_ADD_ACK_COMMIT); @@ -1351,7 +1342,7 @@ 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_append(&changed); + struct changed_htlc *c = tal_arr_expand(&changed); const struct htlc *htlc = changed_htlcs[i]; status_trace("HTLC %"PRIu64"[%s] => %s", diff --git a/channeld/full_channel.c b/channeld/full_channel.c index 98a22b5f8..c267536fc 100644 --- a/channeld/full_channel.c +++ b/channeld/full_channel.c @@ -63,12 +63,9 @@ struct channel *new_full_channel(const tal_t *ctx, static void htlc_arr_append(const struct htlc ***arr, const struct htlc *htlc) { - size_t n; if (!arr) return; - n = tal_count(*arr); - tal_resize(arr, n+1); - (*arr)[n] = htlc; + *tal_arr_expand(arr) = htlc; } /* What does adding the HTLC do to the balance for this side */ @@ -186,7 +183,7 @@ static void add_htlcs(struct bitcoin_tx ***txs, const struct keyset *keyset, enum side side) { - size_t i, n; + size_t i; struct bitcoin_txid txid; u32 feerate_per_kw = channel->view[side].feerate_per_kw; @@ -228,13 +225,10 @@ static void add_htlcs(struct bitcoin_tx ***txs, } /* Append to array. */ - n = tal_count(*txs); - assert(n == tal_count(*wscripts)); + assert(tal_count(*txs) == tal_count(*wscripts)); - tal_resize(wscripts, n+1); - tal_resize(txs, n+1); - (*wscripts)[n] = wscript; - (*txs)[n] = tx; + *tal_arr_expand(wscripts) = wscript; + *tal_arr_expand(txs) = tx; } } @@ -649,18 +643,6 @@ static void htlc_incstate(struct channel *channel, } } -static void append_htlc(const struct htlc ***htlcs, const struct htlc *h) -{ - size_t n; - - if (!htlcs) - return; - - n = tal_count(*htlcs); - tal_resize(htlcs, n+1); - (*htlcs)[n] = h; -} - /* Returns flags which were changed. */ static int change_htlcs(struct channel *channel, enum side sidechanged, @@ -681,7 +663,7 @@ static int change_htlcs(struct channel *channel, if (h->state == htlc_states[i]) { htlc_incstate(channel, h, sidechanged); dump_htlc(h, prefix); - append_htlc(htlcs, h); + htlc_arr_append(htlcs, h); cflags |= (htlc_state_flags(htlc_states[i]) ^ htlc_state_flags(h->state)); } diff --git a/common/bolt11.c b/common/bolt11.c index fad4b54fc..56928ec94 100644 --- a/common/bolt11.c +++ b/common/bolt11.c @@ -422,18 +422,13 @@ static char *decode_r(struct bolt11 *b11, pull_bits_certain(hu5, data, data_len, r8, data_length * 5, false); do { - tal_resize(&r, n+1); - if (!fromwire_route_info(&cursor, &rlen, &r[n])) { + if (!fromwire_route_info(&cursor, &rlen, tal_arr_expand(&r))) { return tal_fmt(b11, "r: hop %zu truncated", n); } - n++; } while (rlen); /* Append route */ - n = tal_count(b11->routes); - tal_resize(&b11->routes, n+1); - b11->routes[n] = 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 9ad56b261..4bdf89817 100644 --- a/common/decode_short_channel_ids.c +++ b/common/decode_short_channel_ids.c @@ -24,7 +24,7 @@ static u8 *unzlib(const tal_t *ctx, const u8 *encoded, size_t len) struct short_channel_id *decode_short_ids(const tal_t *ctx, const u8 *encoded) { struct short_channel_id *scids; - size_t max = tal_count(encoded), n; + size_t max = tal_count(encoded); enum scid_encode_types type; /* BOLT #7: @@ -46,11 +46,10 @@ struct short_channel_id *decode_short_ids(const tal_t *ctx, const u8 *encoded) max = tal_count(encoded); /* fall thru */ case SHORTIDS_UNCOMPRESSED: - n = 0; - scids = tal_arr(ctx, struct short_channel_id, n); + scids = tal_arr(ctx, struct short_channel_id, 0); while (max) { - tal_resize(&scids, n+1); - fromwire_short_channel_id(&encoded, &max, &scids[n++]); + fromwire_short_channel_id(&encoded, &max, + tal_arr_expand(&scids)); } /* encoded is set to NULL if we ran over */ diff --git a/common/memleak.c b/common/memleak.c index 3d12f8d64..488d00cc2 100644 --- a/common/memleak.c +++ b/common/memleak.c @@ -5,6 +5,7 @@ #include #include #include +#include #if DEVELOPER static const void **notleaks; @@ -43,17 +44,12 @@ static void notleak_change(tal_t *ctx, void *notleak_(const void *ptr, bool plus_children) { - size_t nleaks; - /* If we're not tracking, don't do anything. */ if (!notleaks) return cast_const(void *, ptr); - nleaks = tal_count(notleaks); - tal_resize(¬leaks, nleaks+1); - tal_resize(¬leak_children, nleaks+1); - notleaks[nleaks] = ptr; - notleak_children[nleaks] = 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 465779650..f5c934829 100644 --- a/common/msg_queue.c +++ b/common/msg_queue.c @@ -1,6 +1,7 @@ #include #include #include +#include #include void msg_queue_init(struct msg_queue *q, const tal_t *ctx) @@ -11,9 +12,7 @@ void msg_queue_init(struct msg_queue *q, const tal_t *ctx) static void do_enqueue(struct msg_queue *q, const u8 *add) { - size_t n = tal_count(q->q); - tal_resize(&q->q, n+1); - q->q[n] = tal_dup_arr(q->ctx, u8, add, tal_count(add), 0); + *tal_arr_expand(&q->q) = tal_dup_arr(q->ctx, u8, add, tal_count(add), 0); /* In case someone is waiting */ io_wake(q); diff --git a/common/utils.h b/common/utils.h index d6919fa9b..e43c82c22 100644 --- a/common/utils.h +++ b/common/utils.h @@ -19,6 +19,16 @@ 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 + /* Use the POSIX C locale. */ void setup_locale(void); diff --git a/connectd/connectd.c b/connectd/connectd.c index a6c6c46bd..5fc2e2806 100644 --- a/connectd/connectd.c +++ b/connectd/connectd.c @@ -541,10 +541,9 @@ static struct io_plan *connection_in(struct io_conn *conn, struct daemon *daemon static void add_listen_fd(struct daemon *daemon, int fd, bool mayfail) { - size_t n = tal_count(daemon->listen_fds); - tal_resize(&daemon->listen_fds, n+1); - daemon->listen_fds[n].fd = fd; - daemon->listen_fds[n].mayfail = mayfail; + struct listen_fd *l = tal_arr_expand(&daemon->listen_fds); + l->fd = fd; + l->mayfail = mayfail; } /* Return true if it created socket successfully. */ @@ -601,17 +600,13 @@ static bool public_address(struct daemon *daemon, struct wireaddr *wireaddr) static void add_announcable(struct wireaddr **announcable, const struct wireaddr *addr) { - size_t n = tal_count(*announcable); - tal_resize(announcable, n+1); - (*announcable)[n] = *addr; + *tal_arr_expand(announcable) = *addr; } static void add_binding(struct wireaddr_internal **binding, const struct wireaddr_internal *addr) { - size_t n = tal_count(*binding); - tal_resize(binding, n+1); - (*binding)[n] = *addr; + *tal_arr_expand(binding) = *addr; } static int wireaddr_cmp_type(const struct wireaddr *a, @@ -999,14 +994,6 @@ static struct io_plan *conn_proxy_init(struct io_conn *conn, return io_tor_connect(conn, reach->daemon->proxyaddr, host, port, reach); } -static void append_addr(struct wireaddr_internal **addrs, - const struct wireaddr_internal *addr) -{ - size_t n = tal_count(*addrs); - tal_resize(addrs, n+1); - (*addrs)[n] = *addr; -} - static const char *seedname(const tal_t *ctx, const struct pubkey *id) { char bech32[100]; @@ -1038,7 +1025,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)); - append_addr(addrs, &a); + *tal_arr_expand(addrs) = a; } } @@ -1065,7 +1052,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]; - append_addr(addrs, &addr); + *tal_arr_expand(addrs) = addr; } } @@ -1169,7 +1156,7 @@ static void try_reach_peer(struct daemon *daemon, addrs = tal_arr(tmpctx, struct wireaddr_internal, 0); if (addrhint) - append_addr(&addrs, addrhint); + *tal_arr_expand(&addrs) = *addrhint; add_gossip_addrs(&addrs, id); @@ -1180,7 +1167,7 @@ static void try_reach_peer(struct daemon *daemon, wireaddr_from_unresolved(&unresolved, seedname(tmpctx, id), DEFAULT_PORT); - append_addr(&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 56aa9e314..8eeb47f98 100644 --- a/gossipd/gossipd.c +++ b/gossipd/gossipd.c @@ -1334,14 +1334,11 @@ static void append_half_channel(struct gossip_getchannels_entry **entries, { const struct half_chan *c = &chan->half[idx]; struct gossip_getchannels_entry *e; - size_t n; if (!is_halfchan_defined(c)) return; - n = tal_count(*entries); - tal_resize(entries, n+1); - e = &(*entries)[n]; + e = tal_arr_expand(entries); e->source = chan->nodes[idx]->id; e->destination = chan->nodes[!idx]->id; @@ -1401,7 +1398,6 @@ static void append_node(const struct gossip_getnodes_entry ***nodes, const struct node *n) { struct gossip_getnodes_entry *new; - size_t num_nodes = tal_count(*nodes); new = tal(*nodes, struct gossip_getnodes_entry); new->nodeid = *nodeid; @@ -1416,8 +1412,7 @@ static void append_node(const struct gossip_getnodes_entry ***nodes, new->alias = n->alias; memcpy(new->color, n->rgb_color, 3); } - tal_resize(nodes, num_nodes + 1); - (*nodes)[num_nodes] = new; + *tal_arr_expand(nodes) = new; } static struct io_plan *getnodes(struct io_conn *conn, struct daemon *daemon, diff --git a/gossipd/routing.c b/gossipd/routing.c index 845fe53d9..3ba8a5628 100644 --- a/gossipd/routing.c +++ b/gossipd/routing.c @@ -291,7 +291,6 @@ struct chan *new_chan(struct routing_state *rstate, { struct chan *chan = tal(rstate, struct chan); int n1idx = pubkey_idx(id1, id2); - size_t n; struct node *n1, *n2; /* We should never add a channel twice */ @@ -314,12 +313,8 @@ struct chan *new_chan(struct routing_state *rstate, chan->satoshis = satoshis; chan->local_disabled = false; - n = tal_count(n2->chans); - tal_resize(&n2->chans, n+1); - n2->chans[n] = chan; - n = tal_count(n1->chans); - tal_resize(&n1->chans, n+1); - n1->chans[n] = chan; + *tal_arr_expand(&n2->chans) = chan; + *tal_arr_expand(&n1->chans) = chan; /* Populate with (inactive) connections */ init_half_chan(rstate, chan, n1idx); @@ -1252,7 +1247,6 @@ static struct wireaddr *read_addresses(const tal_t *ctx, const u8 *ser) const u8 *cursor = ser; size_t len = tal_count(ser); struct wireaddr *wireaddrs = tal_arr(ctx, struct wireaddr, 0); - int numaddrs = 0; while (cursor && len) { struct wireaddr wireaddr; @@ -1278,9 +1272,7 @@ static struct wireaddr *read_addresses(const tal_t *ctx, const u8 *ser) break; } - tal_resize(&wireaddrs, numaddrs+1); - wireaddrs[numaddrs] = wireaddr; - numaddrs++; + *tal_arr_expand(&wireaddrs) = wireaddr; } return wireaddrs; } diff --git a/lightningd/bitcoind.c b/lightningd/bitcoind.c index 20b434e24..79bcf9697 100644 --- a/lightningd/bitcoind.c +++ b/lightningd/bitcoind.c @@ -31,9 +31,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) { - size_t n = tal_count(*args); - tal_resize(args, n + 1); - (*args)[n] = 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 290142c56..76e089af5 100644 --- a/lightningd/chaintopology.c +++ b/lightningd/chaintopology.c @@ -153,7 +153,6 @@ static void broadcast_remainder(struct bitcoind *bitcoind, static void rebroadcast_txs(struct chain_topology *topo, struct command *cmd) { /* Copy txs now (peers may go away, and they own txs). */ - size_t num_txs = 0; struct txs_to_broadcast *txs; struct outgoing_tx *otx; @@ -166,9 +165,7 @@ static void rebroadcast_txs(struct chain_topology *topo, struct command *cmd) if (wallet_transaction_height(topo->ld->wallet, &otx->txid)) continue; - tal_resize(&txs->txs, num_txs+1); - txs->txs[num_txs] = tal_strdup(txs, otx->hextx); - num_txs++; + *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 3f68317af..cc354bf9d 100644 --- a/lightningd/channel_control.c +++ b/lightningd/channel_control.c @@ -471,9 +471,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)) { - i = tal_count(to_forget); - tal_resize(&to_forget, i + 1); - to_forget[i] = channel; + *tal_arr_expand(&to_forget) = channel; } } diff --git a/lightningd/invoice.c b/lightningd/invoice.c index b82a80140..ac031ba34 100644 --- a/lightningd/invoice.c +++ b/lightningd/invoice.c @@ -178,15 +178,12 @@ static void json_invoice(struct command *cmd, if (fallbacks) { const jsmntok_t *i, *end = json_next(fallbacks); - size_t n = 0; - fallback_scripts = tal_arr(cmd, const u8 *, n); + fallback_scripts = tal_arr(cmd, const u8 *, 0); for (i = fallbacks + 1; i < end; i = json_next(i)) { - tal_resize(&fallback_scripts, n+1); if (!parse_fallback(cmd, buffer, i, - &fallback_scripts[n])) + tal_arr_expand(&fallback_scripts))) return; - n++; } } diff --git a/lightningd/lightningd.c b/lightningd/lightningd.c index 336ce6e77..6f289565b 100644 --- a/lightningd/lightningd.c +++ b/lightningd/lightningd.c @@ -181,8 +181,8 @@ static struct lightningd *new_lightningd(const tal_t *ctx) /*~ Tal also explicitly supports arrays: it stores the number of * elements, which can be accessed with tal_count() (or tal_bytelen() * for raw bytecount). It's common for simple arrays to use - * tal_resize() to expand, which does not work on NULL. So we start - * with an zero-length array. */ + * tal_resize() (or tal_arr_expand) to expand, which does not work on + * NULL. So we start with an zero-length array. */ ld->proposed_wireaddr = tal_arr(ld, struct wireaddr_internal, 0); ld->proposed_listen_announce = tal_arr(ld, enum addr_listen_announce, 0); ld->portnum = DEFAULT_PORT; diff --git a/lightningd/options.c b/lightningd/options.c index bed2029f3..9d573f19f 100644 --- a/lightningd/options.c +++ b/lightningd/options.c @@ -126,16 +126,13 @@ static char *opt_add_addr_withtype(const char *arg, enum addr_listen_announce ala, bool wildcard_ok) { - size_t n = tal_count(ld->proposed_wireaddr); char const *err_msg; assert(arg != NULL); - tal_resize(&ld->proposed_wireaddr, n+1); - tal_resize(&ld->proposed_listen_announce, n+1); - ld->proposed_listen_announce[n] = ala; - - if (!parse_wireaddr_internal(arg, &ld->proposed_wireaddr[n], ld->portnum, + *tal_arr_expand(&ld->proposed_listen_announce) = ala; + if (!parse_wireaddr_internal(arg, tal_arr_expand(&ld->proposed_wireaddr), + ld->portnum, wildcard_ok, !ld->use_proxy_always, false, &err_msg)) { return tal_fmt(NULL, "Unable to parse address '%s': %s", arg, err_msg); diff --git a/lightningd/param.c b/lightningd/param.c index 0618db79c..6766f699e 100644 --- a/lightningd/param.c +++ b/lightningd/param.c @@ -23,10 +23,7 @@ static bool param_add(struct param **params, if (!(name && cbx && arg)) return false; #endif - struct param *last; - - tal_resize(params, tal_count(*params) + 1); - last = &(*params)[tal_count(*params) - 1]; + struct param *last = tal_arr_expand(params); last->is_set = false; last->name = name; diff --git a/lightningd/peer_htlcs.c b/lightningd/peer_htlcs.c index db7652feb..2c05f08d7 100644 --- a/lightningd/peer_htlcs.c +++ b/lightningd/peer_htlcs.c @@ -1377,14 +1377,6 @@ void peer_got_revoke(struct channel *channel, const u8 *msg) wallet_channel_save(ld->wallet, channel); } -static void *tal_arr_append_(void **p, size_t size) -{ - size_t n = tal_bytelen(*p) / size; - tal_resize_(p, size, n+1, false); - return (char *)(*p) + n * size; -} -#define tal_arr_append(p) tal_arr_append_((void **)(p), sizeof(**(p))) - static void add_htlc(struct added_htlc **htlcs, enum htlc_state **htlc_states, u64 id, @@ -1397,8 +1389,8 @@ static void add_htlc(struct added_htlc **htlcs, struct added_htlc *a; enum htlc_state *h; - a = tal_arr_append(htlcs); - h = tal_arr_append(htlc_states); + a = tal_arr_expand(htlcs); + h = tal_arr_expand(htlc_states); a->id = id; a->amount_msat = amount_msat; @@ -1417,8 +1409,8 @@ static void add_fulfill(u64 id, enum side side, struct fulfilled_htlc *f; enum side *s; - f = tal_arr_append(fulfilled_htlcs); - s = tal_arr_append(fulfilled_sides); + f = tal_arr_expand(fulfilled_htlcs); + s = tal_arr_expand(fulfilled_sides); f->id = id; f->payment_preimage = *payment_preimage; *s = side; @@ -1431,28 +1423,26 @@ static void add_fail(u64 id, enum side side, const struct failed_htlc ***failed_htlcs, enum side **failed_sides) { - struct failed_htlc **f; - enum side *s; + struct failed_htlc *newf; - f = tal_arr_append(failed_htlcs); - s = tal_arr_append(failed_sides); - - *f = tal(*failed_htlcs, struct failed_htlc); - (*f)->id = id; - (*f)->failcode = failcode; + newf = tal(*failed_htlcs, struct failed_htlc); + newf->id = id; + newf->failcode = failcode; if (failcode & UPDATE) { assert(failing_channel); - (*f)->scid = tal_dup(*f, struct short_channel_id, + newf->scid = tal_dup(newf, struct short_channel_id, failing_channel); } else - (*f)->scid = NULL; + newf->scid = NULL; if (failuremsg) - (*f)->failreason - = tal_dup_arr(*f, u8, failuremsg, tal_count(failuremsg), 0); + newf->failreason + = tal_dup_arr(newf, u8, failuremsg, tal_count(failuremsg), 0); else - (*f)->failreason = NULL; - *s = side; + newf->failreason = NULL; + + *tal_arr_expand(failed_htlcs) = newf; + *tal_arr_expand(failed_sides) = side; } /* FIXME: Load direct from db. */ diff --git a/onchaind/onchaind.c b/onchaind/onchaind.c index af1e3d733..835481f14 100644 --- a/onchaind/onchaind.c +++ b/onchaind/onchaind.c @@ -397,7 +397,6 @@ static struct tracked_output * const u8 *wscript, const secp256k1_ecdsa_signature *remote_htlc_sig) { - size_t n = tal_count(*outs); struct tracked_output *out = tal(*outs, struct tracked_output); status_trace("Tracking output %u of %s: %s/%s", @@ -419,8 +418,7 @@ static struct tracked_output * out->wscript = wscript; out->remote_htlc_sig = remote_htlc_sig; - tal_resize(outs, n+1); - (*outs)[n] = out; + *tal_arr_expand(outs) = out; return out; } @@ -1421,11 +1419,8 @@ static void note_missing_htlcs(u8 **htlc_scripts, &htlcs[i]); if (tell_immediately[i]) wire_sync_write(REQ_FD, take(msg)); - else { - size_t n = tal_count(missing_htlc_msgs); - tal_resize(&missing_htlc_msgs, n+1); - missing_htlc_msgs[n] = msg; - } + else + *tal_arr_expand(&missing_htlc_msgs) = msg; } } diff --git a/tools/check-bolt.c b/tools/check-bolt.c index 8fbbf7993..7f7877af4 100644 --- a/tools/check-bolt.c +++ b/tools/check-bolt.c @@ -47,7 +47,6 @@ static bool get_files(const char *dir, const char *subdir, { char *path = path_join(NULL, dir, subdir); DIR *d = opendir(path); - size_t n = tal_count(*files); struct dirent *e; if (!d) @@ -55,6 +54,7 @@ static bool get_files(const char *dir, const char *subdir, while ((e = readdir(d)) != NULL) { int preflen; + struct bolt_file *bf; /* Must end in .md */ if (!strends(e->d_name, ".md")) @@ -74,14 +74,12 @@ static bool get_files(const char *dir, const char *subdir, if (verbose) printf("Found bolt %.*s\n", preflen, e->d_name); - tal_resize(files, n+1); - (*files)[n].prefix = tal_strndup(*files, - e->d_name, preflen); - (*files)[n].contents + bf = tal_arr_expand(files); + bf->prefix = tal_strndup(*files, e->d_name, preflen); + bf->contents = canonicalize(grab_file(*files, path_join(path, path, e->d_name))); - n++; } return true; } diff --git a/wallet/db.c b/wallet/db.c index f7dd6b39b..758108cb4 100644 --- a/wallet/db.c +++ b/wallet/db.c @@ -762,7 +762,6 @@ sqlite3_column_short_channel_id_array(const tal_t *ctx, const u8 *ser; size_t len; struct short_channel_id *ret; - size_t n; /* Handle nulls early. */ if (sqlite3_column_type(stmt, col) == SQLITE_NULL) @@ -771,13 +770,9 @@ sqlite3_column_short_channel_id_array(const tal_t *ctx, ser = sqlite3_column_blob(stmt, col); len = sqlite3_column_bytes(stmt, col); ret = tal_arr(ctx, struct short_channel_id, 0); - n = 0; - while (len != 0) { - tal_resize(&ret, n + 1); - fromwire_short_channel_id(&ser, &len, &ret[n]); - ++n; - } + while (len != 0) + fromwire_short_channel_id(&ser, &len, tal_arr_expand(&ret)); return ret; } diff --git a/wallet/txfilter.c b/wallet/txfilter.c index 746be2db9..f18519165 100644 --- a/wallet/txfilter.c +++ b/wallet/txfilter.c @@ -54,9 +54,8 @@ struct txfilter *txfilter_new(const tal_t *ctx) void txfilter_add_scriptpubkey(struct txfilter *filter, const u8 *script TAKES) { - size_t count = tal_count(filter->scriptpubkeys); - tal_resize(&filter->scriptpubkeys, count + 1); - filter->scriptpubkeys[count] = 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 9f2216811..086b3141a 100644 --- a/wallet/wallet.c +++ b/wallet/wallet.c @@ -108,11 +108,10 @@ bool wallet_add_utxo(struct wallet *w, struct utxo *utxo, /** * wallet_stmt2output - Extract data from stmt and fill an UTXO - * - * Returns true on success. */ -static bool wallet_stmt2output(sqlite3_stmt *stmt, struct utxo *utxo) +static struct utxo *wallet_stmt2output(const tal_t *ctx, sqlite3_stmt *stmt) { + struct utxo *utxo = tal(ctx, struct utxo); u32 *blockheight, *spendheight; sqlite3_column_sha256_double(stmt, 0, &utxo->txid.shad); utxo->outnum = sqlite3_column_int(stmt, 1); @@ -144,7 +143,7 @@ static bool wallet_stmt2output(sqlite3_stmt *stmt, struct utxo *utxo) utxo->spendheight = spendheight; } - return true; + return utxo; } bool wallet_update_output_status(struct wallet *w, @@ -188,10 +187,10 @@ 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++) { - tal_resize(&results, i+1); - results[i] = tal(results, struct utxo); - wallet_stmt2output(stmt, results[i]); + struct utxo *u = wallet_stmt2output(results, stmt); + *tal_arr_expand(&results) = u; } + db_stmt_done(stmt); return results; @@ -208,9 +207,8 @@ 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++) { - tal_resize(&results, i+1); - results[i] = tal(results, struct utxo); - wallet_stmt2output(stmt, results[i]); + struct utxo *u = wallet_stmt2output(results, stmt); + *tal_arr_expand(&results) = u; } db_stmt_done(stmt); @@ -281,9 +279,9 @@ static const struct utxo **wallet_select(const tal_t *ctx, struct wallet *w, for (i = 0; i < tal_count(available); i++) { size_t input_weight; + struct utxo *u = tal_steal(utxos, available[i]); - tal_resize(&utxos, i + 1); - utxos[i] = tal_steal(utxos, available[i]); + *tal_arr_expand(&utxos) = u; if (!wallet_update_output_status( w, &available[i]->txid, available[i]->outnum, @@ -297,7 +295,7 @@ static const struct utxo **wallet_select(const tal_t *ctx, struct wallet *w, input_weight += 1 * 4; /* P2SH variants include push of <0 <20-byte-key-hash>> */ - if (utxos[i]->is_p2sh) + if (u->is_p2sh) input_weight += 23 * 4; /* Account for witness (1 byte count + sig + key) */ @@ -553,15 +551,13 @@ wallet_htlc_sigs_load(const tal_t *ctx, struct wallet *w, u64 channelid) sqlite3_stmt *stmt = db_prepare(w->db, "SELECT signature FROM htlc_sigs WHERE channelid = ?"); secp256k1_ecdsa_signature *htlc_sigs = tal_arr(ctx, secp256k1_ecdsa_signature, 0); sqlite3_bind_int64(stmt, 1, channelid); - size_t n = 0; - while (stmt && sqlite3_step(stmt) == SQLITE_ROW) { - tal_resize(&htlc_sigs, n+1); - sqlite3_column_signature(stmt, 0, &htlc_sigs[n]); - n++; - } + while (stmt && sqlite3_step(stmt) == SQLITE_ROW) + sqlite3_column_signature(stmt, 0, tal_arr_expand(&htlc_sigs)); + db_stmt_done(stmt); - log_debug(w->log, "Loaded %zu HTLC signatures from DB", n); + log_debug(w->log, "Loaded %zu HTLC signatures from DB", + tal_count(htlc_sigs)); return htlc_sigs; } @@ -1502,17 +1498,16 @@ 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) { - int n = tal_count(stubs); - tal_resize(&stubs, n+1); + struct htlc_stub *stub = tal_arr_expand(&stubs); assert(sqlite3_column_int64(stmt, 0) == chan->dbid); /* FIXME: merge these two enums */ - stubs[n].owner = sqlite3_column_int(stmt, 1)==DIRECTION_INCOMING?REMOTE:LOCAL; - stubs[n].cltv_expiry = sqlite3_column_int(stmt, 2); + stub->owner = sqlite3_column_int(stmt, 1)==DIRECTION_INCOMING?REMOTE:LOCAL; + stub->cltv_expiry = sqlite3_column_int(stmt, 2); sqlite3_column_sha256(stmt, 3, &payment_hash); - ripemd160(&stubs[n].ripemd, payment_hash.u.u8, sizeof(payment_hash.u)); + ripemd160(&stub->ripemd, payment_hash.u.u8, sizeof(payment_hash.u)); } db_stmt_done(stmt); return stubs;