Browse Source

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 <rusty@rustcorp.com.au>
plugin-timeout-inc
Rusty Russell 6 years ago
committed by Christian Decker
parent
commit
26dda57cc0
  1. 47
      channeld/channeld.c
  2. 6
      channeld/full_channel.c
  3. 6
      common/bolt11.c
  4. 5
      common/decode_short_channel_ids.c
  5. 4
      common/memleak.c
  6. 2
      common/msg_queue.c
  7. 14
      common/param.c
  8. 16
      common/utils.h
  9. 19
      connectd/connectd.c
  10. 68
      gossipd/gossipd.c
  11. 6
      gossipd/routing.c
  12. 2
      lightningd/bitcoind.c
  13. 2
      lightningd/chaintopology.c
  14. 2
      lightningd/channel_control.c
  15. 5
      lightningd/invoice.c
  16. 2
      lightningd/json_stream.c
  17. 7
      lightningd/jsonrpc.c
  18. 7
      lightningd/options.c
  19. 43
      lightningd/peer_htlcs.c
  20. 6
      lightningd/plugin.c
  21. 9
      lightningd/test/run-invoice-select-inchan.c
  22. 6
      onchaind/onchaind.c
  23. 8
      tools/check-bolt.c
  24. 7
      wallet/db.c
  25. 4
      wallet/txfilter.c
  26. 24
      wallet/wallet.c

47
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++) { for (size_t i = 0; i < tal_count(changed_htlcs); i++) {
const struct htlc *htlc = changed_htlcs[i]; const struct htlc *htlc = changed_htlcs[i];
if (htlc->state == RCVD_ADD_COMMIT) { if (htlc->state == RCVD_ADD_COMMIT) {
struct added_htlc *a = tal_arr_expand(&added); struct added_htlc a;
struct secret *s = tal_arr_expand(&shared_secret); struct secret s;
a->id = htlc->id;
a->amount_msat = htlc->msatoshi; a.id = htlc->id;
a->payment_hash = htlc->rhash; a.amount_msat = htlc->msatoshi;
a->cltv_expiry = abs_locktime_to_blocks(&htlc->expiry); a.payment_hash = htlc->rhash;
memcpy(a->onion_routing_packet, a.cltv_expiry = abs_locktime_to_blocks(&htlc->expiry);
memcpy(a.onion_routing_packet,
htlc->routing, htlc->routing,
sizeof(a->onion_routing_packet)); sizeof(a.onion_routing_packet));
/* Invalid shared secret gets set to all-zero: our /* Invalid shared secret gets set to all-zero: our
* code generator can't make arrays of optional values */ * code generator can't make arrays of optional values */
if (!htlc->shared_secret) if (!htlc->shared_secret)
memset(s, 0, sizeof(*s)); memset(&s, 0, sizeof(s));
else 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) { } else if (htlc->state == RCVD_REMOVE_COMMIT) {
if (htlc->r) { if (htlc->r) {
struct fulfilled_htlc *f; struct fulfilled_htlc f;
assert(!htlc->fail && !htlc->failcode); assert(!htlc->fail && !htlc->failcode);
f = tal_arr_expand(&fulfilled); f.id = htlc->id;
f->id = htlc->id; f.payment_preimage = *htlc->r;
f->payment_preimage = *htlc->r; tal_arr_expand(&fulfilled, f);
} else { } else {
struct failed_htlc *f; struct failed_htlc *f;
assert(htlc->fail || htlc->failcode); 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->failreason = cast_const(u8 *, 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);
} }
} else { } else {
struct changed_htlc *c = tal_arr_expand(&changed); struct changed_htlc c;
assert(htlc->state == RCVD_REMOVE_ACK_COMMIT assert(htlc->state == RCVD_REMOVE_ACK_COMMIT
|| htlc->state == RCVD_ADD_ACK_COMMIT); || htlc->state == RCVD_ADD_ACK_COMMIT);
c->id = htlc->id; c.id = htlc->id;
c->newstate = htlc->state; 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); struct changed_htlc *changed = tal_arr(tmpctx, struct changed_htlc, 0);
for (size_t i = 0; i < tal_count(changed_htlcs); i++) { 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]; const struct htlc *htlc = changed_htlcs[i];
status_trace("HTLC %"PRIu64"[%s] => %s", status_trace("HTLC %"PRIu64"[%s] => %s",
htlc->id, side_to_str(htlc_owner(htlc)), htlc->id, side_to_str(htlc_owner(htlc)),
htlc_state_name(htlc->state)); htlc_state_name(htlc->state));
c->id = changed_htlcs[i]->id; c.id = changed_htlcs[i]->id;
c->newstate = changed_htlcs[i]->state; c.newstate = changed_htlcs[i]->state;
tal_arr_expand(&changed, c);
} }
msg = towire_channel_got_revoke(ctx, revoke_num, per_commitment_secret, msg = towire_channel_got_revoke(ctx, revoke_num, per_commitment_secret,

6
channeld/full_channel.c

@ -65,7 +65,7 @@ static void htlc_arr_append(const struct htlc ***arr, const struct htlc *htlc)
{ {
if (!arr) if (!arr)
return; return;
*tal_arr_expand(arr) = htlc; tal_arr_expand(arr, htlc);
} }
/* What does adding the HTLC do to the balance for this side */ /* 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. */ /* Append to array. */
assert(tal_count(*txs) == tal_count(*wscripts)); assert(tal_count(*txs) == tal_count(*wscripts));
*tal_arr_expand(wscripts) = wscript; tal_arr_expand(wscripts, wscript);
*tal_arr_expand(txs) = tx; tal_arr_expand(txs, tx);
} }
} }

6
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); pull_bits_certain(hu5, data, data_len, r8, data_length * 5, false);
do { 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); return tal_fmt(b11, "r: hop %zu truncated", n);
} }
tal_arr_expand(&r, ri);
} while (rlen); } while (rlen);
/* Append route */ /* Append route */
*tal_arr_expand(&b11->routes) = tal_steal(b11, r); tal_arr_expand(&b11->routes, tal_steal(b11, r));
return NULL; return NULL;
} }

5
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: case SHORTIDS_UNCOMPRESSED:
scids = tal_arr(ctx, struct short_channel_id, 0); scids = tal_arr(ctx, struct short_channel_id, 0);
while (max) { while (max) {
fromwire_short_channel_id(&encoded, &max, struct short_channel_id scid;
tal_arr_expand(&scids)); fromwire_short_channel_id(&encoded, &max, &scid);
tal_arr_expand(&scids, scid);
} }
/* encoded is set to NULL if we ran over */ /* encoded is set to NULL if we ran over */

4
common/memleak.c

@ -48,8 +48,8 @@ void *notleak_(const void *ptr, bool plus_children)
if (!notleaks) if (!notleaks)
return cast_const(void *, ptr); return cast_const(void *, ptr);
*tal_arr_expand(&notleaks) = ptr; tal_arr_expand(&notleaks, ptr);
*tal_arr_expand(&notleak_children) = plus_children; tal_arr_expand(&notleak_children, plus_children);
tal_add_notifier(ptr, TAL_NOTIFY_FREE|TAL_NOTIFY_MOVE, notleak_change); tal_add_notifier(ptr, TAL_NOTIFY_FREE|TAL_NOTIFY_MOVE, notleak_change);
return cast_const(void *, ptr); return cast_const(void *, ptr);

2
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) 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 */ /* In case someone is waiting */
io_wake(q); io_wake(q);

14
common/param.c

@ -21,13 +21,15 @@ static bool param_add(struct param **params,
if (!(name && cbx && arg)) if (!(name && cbx && arg))
return false; return false;
#endif #endif
struct param *last = tal_arr_expand(params); struct param last;
last->is_set = false; last.is_set = false;
last->name = name; last.name = name;
last->required = required; last.required = required;
last->cbx = cbx; last.cbx = cbx;
last->arg = arg; last.arg = arg;
tal_arr_expand(params, last);
return true; return true;
} }

16
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. */ /* 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); 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. */ /* Note: p is never a complex expression, otherwise this multi-evaluates! */
#if HAVE_STATEMENT_EXPR #define tal_arr_expand(p, s) \
/* More efficient version calls tal_count() once */ do { \
#define tal_arr_expand(p) \ size_t n = tal_count(*(p)); \
({ size_t n = tal_count(*p); tal_resize((p), n+1); *(p) + n; }) tal_resize((p), n+1); \
#else (*(p))[n] = (s); \
#define tal_arr_expand(p) \ } while(0)
(tal_resize((p), tal_count(*(p))+1), (*p) + tal_count(*(p))-1)
#endif
/** /**
* Remove an element from an array * Remove an element from an array

19
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 /*~ utils.h contains a convenience macro tal_arr_expand which
* reallocates a tal_arr to make it one longer, then returns a pointer * reallocates a tal_arr to make it one longer, then returns a pointer
* to the (new) last element. */ * to the (new) last element. */
struct listen_fd *l = tal_arr_expand(&daemon->listen_fds); struct listen_fd l;
l->fd = fd; l.fd = fd;
l->mayfail = mayfail; l.mayfail = mayfail;
tal_arr_expand(&daemon->listen_fds, l);
} }
/*~ Helper routine to create and bind a socket of a given type; like many /*~ 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, static void add_announcable(struct wireaddr **announcable,
const struct wireaddr *addr) const struct wireaddr *addr)
{ {
*tal_arr_expand(announcable) = *addr; tal_arr_expand(announcable, *addr);
} }
static void add_binding(struct wireaddr_internal **binding, static void add_binding(struct wireaddr_internal **binding,
const struct wireaddr_internal *addr) 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 /*~ 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, status_trace("Resolved %s to %s", addr,
type_to_string(tmpctx, struct wireaddr, type_to_string(tmpctx, struct wireaddr,
&a.u.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; struct wireaddr_internal addr;
addr.itype = ADDR_INTERNAL_WIREADDR; addr.itype = ADDR_INTERNAL_WIREADDR;
addr.u.wireaddr = normal_addrs[i]; 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 */ /* They can supply an optional address for the connect RPC */
if (addrhint) if (addrhint)
*tal_arr_expand(&addrs) = *addrhint; tal_arr_expand(&addrs, *addrhint);
add_gossip_addrs(&addrs, id); add_gossip_addrs(&addrs, id);
@ -1297,7 +1298,7 @@ static void try_connect_peer(struct daemon *daemon,
wireaddr_from_unresolved(&unresolved, wireaddr_from_unresolved(&unresolved,
seedname(tmpctx, id), seedname(tmpctx, id),
DEFAULT_PORT); DEFAULT_PORT);
*tal_arr_expand(&addrs) = unresolved; tal_arr_expand(&addrs, unresolved);
} else if (daemon->use_dns) { } else if (daemon->use_dns) {
add_seed_addrs(&addrs, id, add_seed_addrs(&addrs, id,
daemon->broken_resolver_response); daemon->broken_resolver_response);

68
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); queue_peer_msg(peer, chan->half[1].channel_update);
/* Record node ids for later transmission of node_announcement */ /* 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[0]->id);
*tal_arr_expand(&peer->scid_query_nodes) = chan->nodes[1]->id; tal_arr_expand(&peer->scid_query_nodes, chan->nodes[1]->id);
sent = true; sent = true;
} }
@ -1919,14 +1919,12 @@ static void append_half_channel(struct gossip_getchannels_entry **entries,
int idx) int idx)
{ {
const struct half_chan *c = &chan->half[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 we've never seen a channel_update for this direction... */
if (!is_halfchan_defined(c)) if (!is_halfchan_defined(c))
return; return;
e = tal_arr_expand(entries);
/* Our 'struct chan' contains two nodes: they are in pubkey_cmp order /* 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 * (ie. chan->nodes[0] is the lesser pubkey) and this is the same as
* the direction bit in `channel_update`s `channel_flags`. * 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 * 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 * we're on the same architecture as lightningd, so we just send them
* raw in this case. */ * raw in this case. */
raw_pubkey(e->source, &chan->nodes[idx]->id); raw_pubkey(e.source, &chan->nodes[idx]->id);
raw_pubkey(e->destination, &chan->nodes[!idx]->id); raw_pubkey(e.destination, &chan->nodes[!idx]->id);
e->satoshis = chan->satoshis; e.satoshis = chan->satoshis;
e->channel_flags = c->channel_flags; e.channel_flags = c->channel_flags;
e->message_flags = c->message_flags; e.message_flags = c->message_flags;
e->local_disabled = chan->local_disabled; e.local_disabled = chan->local_disabled;
e->public = is_chan_public(chan); e.public = is_chan_public(chan);
e->short_channel_id = chan->scid; e.short_channel_id = chan->scid;
e->last_update_timestamp = c->last_timestamp; e.last_update_timestamp = c->last_timestamp;
e->base_fee_msat = c->base_fee; e.base_fee_msat = c->base_fee;
e->fee_per_millionth = c->proportional_fee; e.fee_per_millionth = c->proportional_fee;
e->delay = c->delay; e.delay = c->delay;
tal_arr_expand(entries, e);
} }
/*~ Marshal (possibly) both channel directions into entries */ /*~ 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; struct gossip_getnodes_entry *e;
*tal_arr_expand(entries) = e e = tal(*entries, struct gossip_getnodes_entry);
= tal(*entries, struct gossip_getnodes_entry);
raw_pubkey(e->nodeid, &n->id); raw_pubkey(e->nodeid, &n->id);
e->last_timestamp = n->last_timestamp; e->last_timestamp = n->last_timestamp;
/* Timestamp on wire is an unsigned 32 bit: we use a 64-bit signed, so /* Timestamp on wire is an unsigned 32 bit: we use a 64-bit signed, so
* -1 means "we never received a channel_update". */ * -1 means "we never received a channel_update". */
if (e->last_timestamp < 0) if (e->last_timestamp >= 0) {
return; 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; tal_arr_expand(entries, e);
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));
} }
/* Simply routine when they ask for `listnodes` */ /* 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++) { for (size_t i = 0; i < tal_count(node->chans); i++) {
const struct chan *c = node->chans[i]; const struct chan *c = node->chans[i];
const struct half_chan *hc; const struct half_chan *hc;
struct route_info *ri; struct route_info ri;
/* Don't leak private channels. */ /* Don't leak private channels. */
if (!is_chan_public(c)) 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)) if (!is_halfchan_enabled(hc))
continue; continue;
ri = tal_arr_expand(&r); ri.pubkey = other_node(node, c)->id;
ri->pubkey = other_node(node, c)->id; ri.short_channel_id = c->scid;
ri->short_channel_id = c->scid; ri.fee_base_msat = hc->base_fee;
ri->fee_base_msat = hc->base_fee; ri.fee_proportional_millionths = hc->proportional_fee;
ri->fee_proportional_millionths = hc->proportional_fee; ri.cltv_expiry_delta = hc->delay;
ri->cltv_expiry_delta = hc->delay; tal_arr_expand(&r, ri);
} }
} }

6
gossipd/routing.c

@ -314,8 +314,8 @@ struct chan *new_chan(struct routing_state *rstate,
chan->satoshis = satoshis; chan->satoshis = satoshis;
chan->local_disabled = false; chan->local_disabled = false;
*tal_arr_expand(&n2->chans) = chan; tal_arr_expand(&n2->chans, chan);
*tal_arr_expand(&n1->chans) = chan; tal_arr_expand(&n1->chans, chan);
/* Populate with (inactive) connections */ /* Populate with (inactive) connections */
init_half_chan(rstate, chan, n1idx); init_half_chan(rstate, chan, n1idx);
@ -1306,7 +1306,7 @@ static struct wireaddr *read_addresses(const tal_t *ctx, const u8 *ser)
break; break;
} }
*tal_arr_expand(&wireaddrs) = wireaddr; tal_arr_expand(&wireaddrs, wireaddr);
} }
return wireaddrs; return wireaddrs;
} }

2
lightningd/bitcoind.c

@ -32,7 +32,7 @@
/* Add the n'th arg to *args, incrementing n and keeping args of size n+1 */ /* 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) 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, static const char **gather_args(const struct bitcoind *bitcoind,

2
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)) if (wallet_transaction_height(topo->ld->wallet, &otx->txid))
continue; 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. */ /* Let this do the dirty work. */

2
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 (&ld->peers, peer, list) {
list_for_each (&peer->channels, channel, list) list_for_each (&peer->channels, channel, list)
if (is_fundee_should_forget(ld, channel, block_height)) { if (is_fundee_should_forget(ld, channel, block_height)) {
*tal_arr_expand(&to_forget) = channel; tal_arr_expand(&to_forget, channel);
} }
} }

5
lightningd/invoice.c

@ -343,10 +343,11 @@ static struct command_result *json_invoice(struct command *cmd,
fallback_scripts = tal_arr(cmd, const u8 *, 0); fallback_scripts = tal_arr(cmd, const u8 *, 0);
for (i = fallbacks + 1; i < end; i = json_next(i)) { for (i = fallbacks + 1; i < end; i = json_next(i)) {
struct command_result *r; struct command_result *r;
r = parse_fallback(cmd, buffer, i, const u8 *fs;
tal_arr_expand(&fallback_scripts)); r = parse_fallback(cmd, buffer, i, &fs);
if (r) if (r)
return r; return r;
tal_arr_expand(&fallback_scripts, fs);
} }
} }

2
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) static void js_indent(struct json_stream *js, jsmntype_t type)
{ {
#if DEVELOPER #if DEVELOPER
*tal_arr_expand(&js->wrapping) = type; tal_arr_expand(&js->wrapping, type);
#endif #endif
js->empty = true; js->empty = true;
js->indent++; js->indent++;

7
lightningd/jsonrpc.c

@ -114,11 +114,14 @@ static struct json_stream *jcon_new_json_stream(const tal_t *ctx,
struct json_connection *jcon, struct json_connection *jcon,
struct command *writer) struct command *writer)
{ {
struct json_stream *js = new_json_stream(ctx, writer);
/* Wake writer to start streaming, in case it's not already. */ /* Wake writer to start streaming, in case it's not already. */
io_wake(jcon); io_wake(jcon);
/* FIXME: Keep streams around for recycling. */ /* 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, 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)) if (streq(rpc->commands[i]->name, command->name))
return false; return false;
*tal_arr_expand(&rpc->commands) = command; tal_arr_expand(&rpc->commands, command);
return true; return true;
} }

7
lightningd/options.c

@ -129,17 +129,18 @@ static char *opt_add_addr_withtype(const char *arg,
bool wildcard_ok) bool wildcard_ok)
{ {
char const *err_msg; char const *err_msg;
struct wireaddr_internal wi;
assert(arg != NULL); assert(arg != NULL);
*tal_arr_expand(&ld->proposed_listen_announce) = ala; tal_arr_expand(&ld->proposed_listen_announce, ala);
if (!parse_wireaddr_internal(arg, tal_arr_expand(&ld->proposed_wireaddr), if (!parse_wireaddr_internal(arg, &wi,
ld->portnum, ld->portnum,
wildcard_ok, !ld->use_proxy_always, false, wildcard_ok, !ld->use_proxy_always, false,
&err_msg)) { &err_msg)) {
return tal_fmt(NULL, "Unable to parse address '%s': %s", arg, err_msg); return tal_fmt(NULL, "Unable to parse address '%s': %s", arg, err_msg);
} }
tal_arr_expand(&ld->proposed_wireaddr, wi);
return NULL; return NULL;
} }

43
lightningd/peer_htlcs.c

@ -1389,19 +1389,17 @@ static void add_htlc(struct added_htlc **htlcs,
const u8 onion_routing_packet[TOTAL_PACKET_SIZE], const u8 onion_routing_packet[TOTAL_PACKET_SIZE],
enum htlc_state state) enum htlc_state state)
{ {
struct added_htlc *a; struct added_htlc a;
enum htlc_state *h;
a.id = id;
a = tal_arr_expand(htlcs); a.amount_msat = amount_msat;
h = tal_arr_expand(htlc_states); a.payment_hash = *payment_hash;
a.cltv_expiry = cltv_expiry;
a->id = id; memcpy(a.onion_routing_packet, onion_routing_packet,
a->amount_msat = amount_msat; sizeof(a.onion_routing_packet));
a->payment_hash = *payment_hash;
a->cltv_expiry = cltv_expiry; tal_arr_expand(htlcs, a);
memcpy(a->onion_routing_packet, onion_routing_packet, tal_arr_expand(htlc_states, state);
sizeof(a->onion_routing_packet));
*h = state;
} }
static void add_fulfill(u64 id, enum side side, 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, struct fulfilled_htlc **fulfilled_htlcs,
enum side **fulfilled_sides) enum side **fulfilled_sides)
{ {
struct fulfilled_htlc *f; struct fulfilled_htlc f;
enum side *s;
f.id = id;
f = tal_arr_expand(fulfilled_htlcs); f.payment_preimage = *payment_preimage;
s = tal_arr_expand(fulfilled_sides);
f->id = id; tal_arr_expand(fulfilled_htlcs, f);
f->payment_preimage = *payment_preimage; tal_arr_expand(fulfilled_sides, side);
*s = side;
} }
static void add_fail(u64 id, enum side side, static void add_fail(u64 id, enum side side,
@ -1444,8 +1441,8 @@ static void add_fail(u64 id, enum side side,
else else
newf->failreason = NULL; newf->failreason = NULL;
*tal_arr_expand(failed_htlcs) = newf; tal_arr_expand(failed_htlcs, newf);
*tal_arr_expand(failed_sides) = side; tal_arr_expand(failed_sides, side);
} }
/* FIXME: Load direct from db. */ /* FIXME: Load direct from db. */

6
lightningd/plugin.c

@ -234,7 +234,7 @@ plugin_request_new_(struct plugin *plugin,
static void plugin_send(struct plugin *plugin, struct json_stream *stream) static void plugin_send(struct plugin *plugin, struct json_stream *stream)
{ {
tal_steal(plugin->js_arr, stream); tal_steal(plugin->js_arr, stream);
*tal_arr_expand(&plugin->js_arr) = stream; tal_arr_expand(&plugin->js_arr, stream);
io_wake(plugin); io_wake(plugin);
} }
@ -746,7 +746,7 @@ static bool plugin_rpcmethod_add(struct plugin *plugin,
cmd->name); cmd->name);
return false; return false;
} }
*tal_arr_expand(&plugin->methods) = cmd->name; tal_arr_expand(&plugin->methods, cmd->name);
return true; return true;
} }
@ -808,7 +808,7 @@ static bool plugin_subscriptions_add(struct plugin *plugin, const char *buffer,
return false; return false;
} }
*tal_arr_expand(&plugin->subscriptions) = topic; tal_arr_expand(&plugin->subscriptions, topic);
} }
return true; return true;
} }

9
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) static void add_inchan(struct route_info **inchans, int n)
{ {
struct route_info *r = tal_arr_expand(inchans); struct route_info r;
memset(&r->pubkey, n, sizeof(r->pubkey)); memset(&r.pubkey, n, sizeof(r.pubkey));
memset(&r->short_channel_id, n, sizeof(r->short_channel_id)); memset(&r.short_channel_id, n, sizeof(r.short_channel_id));
r->fee_base_msat = r->fee_proportional_millionths = r->cltv_expiry_delta r.fee_base_msat = r.fee_proportional_millionths = r.cltv_expiry_delta
= n; = n;
tal_arr_expand(inchans, r);
} }
static void add_peer(struct lightningd *ld, int n, enum channel_state state, static void add_peer(struct lightningd *ld, int n, enum channel_state state,

6
onchaind/onchaind.c

@ -410,7 +410,7 @@ static struct tracked_output *
} else } else
out->remote_htlc_sig = NULL; out->remote_htlc_sig = NULL;
*tal_arr_expand(outs) = out; tal_arr_expand(outs, out);
return 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, if (memeq(tx->output[outnum].script + 2,
tal_count(tx->output[outnum].script) - 2, tal_count(tx->output[outnum].script) - 2,
&sha, sizeof(sha))) &sha, sizeof(sha)))
*tal_arr_expand(&matches) = i; tal_arr_expand(&matches, i);
} }
return matches; return matches;
} }
@ -1560,7 +1560,7 @@ static void note_missing_htlcs(u8 **htlc_scripts,
if (tell_immediately[i]) if (tell_immediately[i])
wire_sync_write(REQ_FD, take(msg)); wire_sync_write(REQ_FD, take(msg));
else else
*tal_arr_expand(&missing_htlc_msgs) = msg; tal_arr_expand(&missing_htlc_msgs, msg);
} }
} }

8
tools/check-bolt.c

@ -54,7 +54,7 @@ static bool get_files(const char *dir, const char *subdir,
while ((e = readdir(d)) != NULL) { while ((e = readdir(d)) != NULL) {
int preflen; int preflen;
struct bolt_file *bf; struct bolt_file bf;
/* Must end in .md */ /* Must end in .md */
if (!strends(e->d_name, ".md")) if (!strends(e->d_name, ".md"))
@ -74,12 +74,12 @@ static bool get_files(const char *dir, const char *subdir,
if (verbose) if (verbose)
printf("Found bolt %.*s\n", preflen, e->d_name); printf("Found bolt %.*s\n", preflen, e->d_name);
bf = tal_arr_expand(files); bf.prefix = tal_strndup(*files, e->d_name, preflen);
bf->prefix = tal_strndup(*files, e->d_name, preflen); bf.contents
bf->contents
= canonicalize(grab_file(*files, = canonicalize(grab_file(*files,
path_join(path, path, path_join(path, path,
e->d_name))); e->d_name)));
tal_arr_expand(files, bf);
} }
return true; return true;
} }

7
wallet/db.c

@ -782,8 +782,11 @@ sqlite3_column_short_channel_id_array(const tal_t *ctx,
len = sqlite3_column_bytes(stmt, col); len = sqlite3_column_bytes(stmt, col);
ret = tal_arr(ctx, struct short_channel_id, 0); ret = tal_arr(ctx, struct short_channel_id, 0);
while (len != 0) while (len != 0) {
fromwire_short_channel_id(&ser, &len, tal_arr_expand(&ret)); struct short_channel_id scid;
fromwire_short_channel_id(&ser, &len, &scid);
tal_arr_expand(&ret, scid);
}
return ret; return ret;
} }

4
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) void txfilter_add_scriptpubkey(struct txfilter *filter, const u8 *script TAKES)
{ {
*tal_arr_expand(&filter->scriptpubkeys) tal_arr_expand(&filter->scriptpubkeys,
= tal_dup_arr(filter, u8, script, tal_count(script), 0); tal_dup_arr(filter, u8, script, tal_count(script), 0));
} }
void txfilter_add_derkey(struct txfilter *filter, void txfilter_add_derkey(struct txfilter *filter,

24
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); results = tal_arr(ctx, struct utxo*, 0);
for (i=0; sqlite3_step(stmt) == SQLITE_ROW; i++) { for (i=0; sqlite3_step(stmt) == SQLITE_ROW; i++) {
struct utxo *u = wallet_stmt2output(results, stmt); struct utxo *u = wallet_stmt2output(results, stmt);
*tal_arr_expand(&results) = u; tal_arr_expand(&results, u);
} }
db_stmt_done(stmt); 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); results = tal_arr(ctx, struct utxo*, 0);
for (i=0; sqlite3_step(stmt) == SQLITE_ROW; i++) { for (i=0; sqlite3_step(stmt) == SQLITE_ROW; i++) {
struct utxo *u = wallet_stmt2output(results, stmt); struct utxo *u = wallet_stmt2output(results, stmt);
*tal_arr_expand(&results) = u; tal_arr_expand(&results, u);
} }
db_stmt_done(stmt); 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; size_t input_weight;
struct utxo *u = tal_steal(utxos, available[i]); struct utxo *u = tal_steal(utxos, available[i]);
*tal_arr_expand(&utxos) = u; tal_arr_expand(&utxos, u);
if (!wallet_update_output_status( if (!wallet_update_output_status(
w, &available[i]->txid, available[i]->outnum, 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); secp256k1_ecdsa_signature *htlc_sigs = tal_arr(ctx, secp256k1_ecdsa_signature, 0);
sqlite3_bind_int64(stmt, 1, channelid); sqlite3_bind_int64(stmt, 1, channelid);
while (stmt && sqlite3_step(stmt) == SQLITE_ROW) while (stmt && sqlite3_step(stmt) == SQLITE_ROW) {
sqlite3_column_signature(stmt, 0, tal_arr_expand(&htlc_sigs)); secp256k1_ecdsa_signature sig;
sqlite3_column_signature(stmt, 0, &sig);
tal_arr_expand(&htlc_sigs, sig);
}
db_stmt_done(stmt); db_stmt_done(stmt);
log_debug(w->log, "Loaded %zu HTLC signatures from DB", 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); stubs = tal_arr(ctx, struct htlc_stub, 0);
while (sqlite3_step(stmt) == SQLITE_ROW) { 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); assert(sqlite3_column_int64(stmt, 0) == chan->dbid);
/* FIXME: merge these two enums */ /* FIXME: merge these two enums */
stub->owner = sqlite3_column_int(stmt, 1)==DIRECTION_INCOMING?REMOTE:LOCAL; stub.owner = sqlite3_column_int(stmt, 1)==DIRECTION_INCOMING?REMOTE:LOCAL;
stub->cltv_expiry = sqlite3_column_int(stmt, 2); stub.cltv_expiry = sqlite3_column_int(stmt, 2);
stub->id = sqlite3_column_int(stmt, 3); stub.id = sqlite3_column_int(stmt, 3);
sqlite3_column_sha256(stmt, 4, &payment_hash); 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); db_stmt_done(stmt);
return stubs; return stubs;

Loading…
Cancel
Save