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>
This commit is contained in:
Rusty Russell 2019-01-15 14:21:27 +10:30 committed by Christian Decker
parent a5ed98a2ea
commit 26dda57cc0
26 changed files with 170 additions and 151 deletions

View File

@ -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,

View File

@ -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);
}
}

View File

@ -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;
}

View File

@ -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 */

View File

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

View File

@ -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);

View File

@ -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;
}

View File

@ -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

View File

@ -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);

View File

@ -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);
}
}

View File

@ -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;
}

View File

@ -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,

View File

@ -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. */

View File

@ -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);
}
}

View File

@ -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);
}
}

View File

@ -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++;

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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;
struct added_htlc a;
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));
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;
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;
struct fulfilled_htlc f;
f = tal_arr_expand(fulfilled_htlcs);
s = tal_arr_expand(fulfilled_sides);
f->id = id;
f->payment_preimage = *payment_preimage;
*s = side;
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. */

View File

@ -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;
}

View File

@ -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,

View File

@ -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);
}
}

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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,

View File

@ -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;