diff --git a/bitcoin/script.c b/bitcoin/script.c index 060cfc829..02df5b22e 100644 --- a/bitcoin/script.c +++ b/bitcoin/script.c @@ -8,6 +8,7 @@ #include #include #include +#include /* Some standard ops */ #define OP_0 0x00 @@ -451,8 +452,7 @@ u8 **bitcoin_witness_sig_and_element(const tal_t *ctx, witness[0] = stack_sig(witness, sig); witness[1] = tal_dup_arr(witness, u8, elem, elemsize, 0); - witness[2] = tal_dup_arr(witness, u8, - witnessscript, tal_count(witnessscript), 0); + witness[2] = tal_dup_talarr(witness, u8, witnessscript); return witness; } @@ -675,7 +675,7 @@ u8 **bitcoin_witness_htlc_timeout_tx(const tal_t *ctx, witness[1] = stack_sig(witness, remotehtlcsig); witness[2] = stack_sig(witness, localhtlcsig); witness[3] = stack_number(witness, 0); - witness[4] = tal_dup_arr(witness, u8, wscript, tal_count(wscript), 0); + witness[4] = tal_dup_talarr(witness, u8, wscript); return witness; } @@ -692,7 +692,7 @@ u8 **bitcoin_witness_htlc_success_tx(const tal_t *ctx, witness[1] = stack_sig(witness, remotesig); witness[2] = stack_sig(witness, localhtlcsig); witness[3] = stack_preimage(witness, preimage); - witness[4] = tal_dup_arr(witness, u8, wscript, tal_count(wscript), 0); + witness[4] = tal_dup_talarr(witness, u8, wscript); return witness; } diff --git a/common/close_tx.c b/common/close_tx.c index c013008e5..cb2d02c2e 100644 --- a/common/close_tx.c +++ b/common/close_tx.c @@ -3,6 +3,7 @@ #include "close_tx.h" #include "permute_tx.h" #include +#include struct bitcoin_tx *create_close_tx(const tal_t *ctx, const struct chainparams *chainparams, @@ -41,16 +42,14 @@ struct bitcoin_tx *create_close_tx(const tal_t *ctx, BITCOIN_TX_DEFAULT_SEQUENCE, funding, NULL); if (amount_sat_greater_eq(to_us, dust_limit)) { - script = - tal_dup_arr(tx, u8, our_script, tal_count(our_script), 0); + script = tal_dup_talarr(tx, u8, our_script); /* One output is to us. */ bitcoin_tx_add_output(tx, script, to_us); num_outputs++; } if (amount_sat_greater_eq(to_them, dust_limit)) { - script = tal_dup_arr(tx, u8, their_script, - tal_count(their_script), 0); + script = tal_dup_talarr(tx, u8, their_script); /* Other output is to them. */ bitcoin_tx_add_output(tx, script, to_them); num_outputs++; diff --git a/common/msg_queue.c b/common/msg_queue.c index 14823d87d..76bc76fac 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_talarr(q, u8, add)); /* In case someone is waiting */ io_wake(q); diff --git a/common/onionreply.c b/common/onionreply.c index a0a20e10f..445b5e2ea 100644 --- a/common/onionreply.c +++ b/common/onionreply.c @@ -28,13 +28,13 @@ struct onionreply *dup_onionreply(const tal_t *ctx, return cast_const(struct onionreply *, tal_steal(ctx, r)); n = tal(ctx, struct onionreply); - n->contents = tal_dup_arr(n, u8, r->contents, tal_count(r->contents), 0); + n->contents = tal_dup_talarr(n, u8, r->contents); return n; } struct onionreply *new_onionreply(const tal_t *ctx, const u8 *contents TAKES) { struct onionreply *r = tal(ctx, struct onionreply); - r->contents = tal_dup_arr(r, u8, contents, tal_count(contents), 0); + r->contents = tal_dup_talarr(r, u8, contents); return r; } diff --git a/common/param.c b/common/param.c index 46485477e..346d500dc 100644 --- a/common/param.c +++ b/common/param.c @@ -214,8 +214,7 @@ static bool check_params(struct param *params) return false; /* duplicate so we can sort */ - struct param *copy = tal_dup_arr(params, struct param, - params, tal_count(params), 0); + struct param *copy = tal_dup_talarr(params, struct param, params); /* check for repeated names and args */ if (!check_unique(copy, comp_by_name)) diff --git a/common/read_peer_msg.c b/common/read_peer_msg.c index da52b903e..6245cf69b 100644 --- a/common/read_peer_msg.c +++ b/common/read_peer_msg.c @@ -116,7 +116,7 @@ void handle_gossip_msg(struct per_peer_state *pps, const u8 *msg TAKES) goto out; } else /* It's a raw gossip msg: this copies or takes() */ - gossip = tal_dup_arr(tmpctx, u8, msg, tal_bytelen(msg), 0); + gossip = tal_dup_talarr(tmpctx, u8, msg); /* Gossipd can send us gossip messages, OR errors */ if (fromwire_peektype(gossip) == WIRE_ERROR) { diff --git a/common/sphinx.c b/common/sphinx.c index 66a735780..0849c218e 100644 --- a/common/sphinx.c +++ b/common/sphinx.c @@ -62,8 +62,7 @@ struct sphinx_path { struct sphinx_path *sphinx_path_new(const tal_t *ctx, const u8 *associated_data) { struct sphinx_path *sp = tal(ctx, struct sphinx_path); - sp->associated_data = tal_dup_arr(sp, u8, associated_data, - tal_bytelen(associated_data), 0); + sp->associated_data = tal_dup_talarr(sp, u8, associated_data); sp->session_key = NULL; sp->hops = tal_arr(sp, struct sphinx_hop, 0); return sp; @@ -95,7 +94,7 @@ void sphinx_add_hop(struct sphinx_path *path, const struct pubkey *pubkey, const u8 *payload TAKES) { struct sphinx_hop sp; - sp.raw_payload = tal_dup_arr(path, u8, payload, tal_count(payload), 0); + sp.raw_payload = tal_dup_talarr(path, u8, payload); sp.pubkey = *pubkey; tal_arr_expand(&path->hops, sp); } diff --git a/common/test/run-features.c b/common/test/run-features.c index 4286475f5..d96994c77 100644 --- a/common/test/run-features.c +++ b/common/test/run-features.c @@ -112,14 +112,14 @@ int main(void) /* We can add random odd features, no problem. */ for (size_t i = 1; i < 16; i += 2) { - bits = tal_dup_arr(tmpctx, u8, lf, tal_count(lf), 0); + bits = tal_dup_talarr(tmpctx, u8, lf); set_feature_bit(&bits, i); assert(features_unsupported(bits) == -1); } /* We can't add random even features. */ for (size_t i = 0; i < 16; i += 2) { - bits = tal_dup_arr(tmpctx, u8, lf, tal_count(lf), 0); + bits = tal_dup_talarr(tmpctx, u8, lf); set_feature_bit(&bits, i); /* Special case for missing compulsory feature */ diff --git a/common/utils.c b/common/utils.c index 07a3a13c7..62432f600 100644 --- a/common/utils.c +++ b/common/utils.c @@ -141,3 +141,10 @@ void tal_arr_remove_(void *p, size_t elemsize, size_t n) len - (elemsize * (n+1))); tal_resize((char **)p, len - elemsize); } + +void *tal_dup_talarr_(const tal_t *ctx, const tal_t *src, const char *label) +{ + if (!src) + return NULL; + return tal_dup_(ctx, src, 1, tal_bytelen(src), 0, label); +} diff --git a/common/utils.h b/common/utils.h index 35e9e1517..484da8ea1 100644 --- a/common/utils.h +++ b/common/utils.h @@ -56,6 +56,17 @@ void clear_softref_(const tal_t *outer, size_t outersize, void **ptr); #define tal_arr_remove(p, n) tal_arr_remove_((p), sizeof(**p), (n)) void tal_arr_remove_(void *p, size_t elemsize, size_t n); +/** + * The comon case of duplicating an entire tal array. + * + * A macro because we must not double-evaluate p. + */ +#define tal_dup_talarr(ctx, type, p) \ + ((type *)tal_dup_talarr_((ctx), tal_typechk_(p, type *), \ + TAL_LABEL(type, "[]"))) +void *tal_dup_talarr_(const tal_t *ctx, const tal_t *src TAKES, + const char *label); + /* Use the POSIX C locale. */ void setup_locale(void); diff --git a/connectd/connectd.c b/connectd/connectd.c index 491a3f6db..819661def 100644 --- a/connectd/connectd.c +++ b/connectd/connectd.c @@ -395,9 +395,9 @@ static struct io_plan *peer_reconnected(struct io_conn *conn, pr->cs = *cs; pr->addr = *addr; - /*~ Note that tal_dup_arr() will do handle the take() of features + /*~ Note that tal_dup_talarr() will do handle the take() of features * (turning it into a simply tal_steal() in those cases). */ - pr->features = tal_dup_arr(pr, u8, features, tal_count(features), 0); + pr->features = tal_dup_talarr(pr, u8, features); /*~ ccan/io supports waiting on an address: in this case, the key in * the peer set. When someone calls `io_wake()` on that address, it diff --git a/gossipd/gossipd.c b/gossipd/gossipd.c index 8333898c4..695793249 100644 --- a/gossipd/gossipd.c +++ b/gossipd/gossipd.c @@ -1421,8 +1421,7 @@ static u8 *patch_channel_update(const tal_t *ctx, u8 *channel_update TAKES) tal_free(channel_update); return fixed; } else { - return tal_dup_arr(ctx, u8, - channel_update, tal_count(channel_update), 0); + return tal_dup_talarr(ctx, u8, channel_update); } } diff --git a/gossipd/routing.c b/gossipd/routing.c index 69f3ac6dc..db213d9c2 100644 --- a/gossipd/routing.c +++ b/gossipd/routing.c @@ -1650,7 +1650,7 @@ bool routing_add_channel_announcement(struct routing_state *rstate, } uc = tal(rstate, struct unupdated_channel); - uc->channel_announce = tal_dup_arr(uc, u8, msg, tal_count(msg), 0); + uc->channel_announce = tal_dup_talarr(uc, u8, msg); uc->added = gossip_time_now(rstate); uc->index = index; uc->sat = sat; @@ -1694,8 +1694,7 @@ u8 *handle_channel_announcement(struct routing_state *rstate, pending->updates[0] = NULL; pending->updates[1] = NULL; pending->update_peer_softref[0] = pending->update_peer_softref[1] = NULL; - pending->announce = tal_dup_arr(pending, u8, - announce, tal_count(announce), 0); + pending->announce = tal_dup_talarr(pending, u8, announce); pending->update_timestamps[0] = pending->update_timestamps[1] = 0; if (!fromwire_channel_announcement(pending, pending->announce, @@ -1973,7 +1972,8 @@ static void update_pending(struct pending_cannouncement *pending, "Replacing existing update"); tal_free(pending->updates[direction]); } - pending->updates[direction] = tal_dup_arr(pending, u8, update, tal_count(update), 0); + pending->updates[direction] + = tal_dup_talarr(pending, u8, update); pending->update_timestamps[direction] = timestamp; clear_softref(pending, &pending->update_peer_softref[direction]); set_softref(pending, &pending->update_peer_softref[direction], @@ -2473,9 +2473,7 @@ bool routing_add_node_announcement(struct routing_state *rstate, pna->index = index; tal_free(pna->node_announcement); clear_softref(pna, &pna->peer_softref); - pna->node_announcement = tal_dup_arr(pna, u8, msg, - tal_count(msg), - 0); + pna->node_announcement = tal_dup_talarr(pna, u8, msg); set_softref(pna, &pna->peer_softref, peer); return true; } diff --git a/lightningd/jsonrpc.c b/lightningd/jsonrpc.c index 8a433cddd..9504c302c 100644 --- a/lightningd/jsonrpc.c +++ b/lightningd/jsonrpc.c @@ -831,10 +831,8 @@ parse_request(struct json_connection *jcon, const jsmntok_t tok[]) rpc_hook = tal(c, struct rpc_command_hook_payload); rpc_hook->cmd = c; /* Duplicate since we might outlive the connection */ - rpc_hook->buffer = tal_dup_arr(rpc_hook, char, jcon->buffer, - tal_count(jcon->buffer), 0); - rpc_hook->request = tal_dup_arr(rpc_hook, const jsmntok_t, tok, - tal_count(tok), 0); + rpc_hook->buffer = tal_dup_talarr(rpc_hook, char, jcon->buffer); + rpc_hook->request = tal_dup_talarr(rpc_hook, jsmntok_t, tok); /* Prevent a race between was_pending and still_pending */ new_reltimer(c->ld->timers, rpc_hook, time_from_msec(1), call_rpc_command_hook, rpc_hook); diff --git a/lightningd/pay.c b/lightningd/pay.c index 7483deeaf..99104acef 100644 --- a/lightningd/pay.c +++ b/lightningd/pay.c @@ -468,8 +468,7 @@ remote_routing_failure(const tal_t *ctx, routing_failure->erring_index = (unsigned int) (origin_index + 1); routing_failure->failcode = failcode; - routing_failure->msg = tal_dup_arr(routing_failure, u8, failuremsg, - tal_count(failuremsg), 0); + routing_failure->msg = tal_dup_talarr(routing_failure, u8, failuremsg); if (erring_node != NULL) routing_failure->erring_node = diff --git a/lightningd/peer_control.c b/lightningd/peer_control.c index 957e3f9d6..ef0714299 100644 --- a/lightningd/peer_control.c +++ b/lightningd/peer_control.c @@ -77,8 +77,7 @@ static void destroy_peer(struct peer *peer) static void peer_update_features(struct peer *peer, const u8 *features TAKES) { tal_free(peer->features); - peer->features = tal_dup_arr(peer, u8, - features, tal_count(features), 0); + peer->features = tal_dup_talarr(peer, u8, features); } struct peer *new_peer(struct lightningd *ld, u64 dbid, @@ -386,9 +385,7 @@ void channel_errmsg(struct channel *channel, /* Do we have an error to send? */ if (err_for_them && !channel->error) - channel->error = tal_dup_arr(channel, u8, - err_for_them, - tal_count(err_for_them), 0); + channel->error = tal_dup_talarr(channel, u8, err_for_them); /* Other implementations chose to ignore errors early on. Not * surprisingly, they now spew out spurious errors frequently, diff --git a/lightningd/peer_htlcs.c b/lightningd/peer_htlcs.c index 0d1b92e8a..a2f54e97b 100644 --- a/lightningd/peer_htlcs.c +++ b/lightningd/peer_htlcs.c @@ -1748,7 +1748,7 @@ void peer_got_commitsig(struct channel *channel, const u8 *msg) /* If subdaemon dies, we want to forget this. */ d = tal(channel->owner, struct deferred_commitsig); d->channel = channel; - d->msg = tal_dup_arr(d, u8, msg, tal_count(msg), 0); + d->msg = tal_dup_talarr(d, u8, msg); topology_add_sync_waiter(d, ld->topology, retry_deferred_commitsig, d); return; diff --git a/plugins/pay.c b/plugins/pay.c index 24bde72cb..f02ca195a 100644 --- a/plugins/pay.c +++ b/plugins/pay.c @@ -868,8 +868,7 @@ static struct command_result *getroute_error(struct command *cmd, /* Deep copy of excludes array. */ static const char **dup_excludes(const tal_t *ctx, const char **excludes) { - const char **ret = tal_dup_arr(ctx, const char *, - excludes, tal_count(excludes), 0); + const char **ret = tal_dup_talarr(ctx, const char *, excludes); for (size_t i = 0; i < tal_count(ret); i++) ret[i] = tal_strdup(ret, excludes[i]); return ret; diff --git a/wallet/txfilter.c b/wallet/txfilter.c index 8eae0c9b9..41f0816e4 100644 --- a/wallet/txfilter.c +++ b/wallet/txfilter.c @@ -82,7 +82,7 @@ void txfilter_add_scriptpubkey(struct txfilter *filter, const u8 *script TAKES) { scriptpubkeyset_add( &filter->scriptpubkeyset, - notleak(tal_dup_arr(filter, u8, script, tal_count(script), 0))); + notleak(tal_dup_talarr(filter, u8, script))); } void txfilter_add_derkey(struct txfilter *filter, diff --git a/wallet/wallet.c b/wallet/wallet.c index 65c0e4469..d643c2f94 100644 --- a/wallet/wallet.c +++ b/wallet/wallet.c @@ -1612,7 +1612,7 @@ int wallet_extract_owned_outputs(struct wallet *w, const struct bitcoin_tx *tx, utxo->blockheight = blockheight ? blockheight : NULL; utxo->spendheight = NULL; - utxo->scriptPubkey = tal_dup_arr(utxo, u8, script, tal_bytelen(script), 0); + utxo->scriptPubkey = tal_dup_talarr(utxo, u8, script); log_debug(w->log, "Owning output %zu %s (%s) txid %s%s", output, diff --git a/wire/wire_io.c b/wire/wire_io.c index e4b180bdb..03fe82494 100644 --- a/wire/wire_io.c +++ b/wire/wire_io.c @@ -4,6 +4,7 @@ #include #include #include +#include #include #include @@ -136,9 +137,8 @@ struct io_plan *io_write_wire_(struct io_conn *conn, return io_close(conn); } - arg->u1.const_vp = tal_dup_arr(conn, u8, - memcheck(data, tal_bytelen(data)), - tal_bytelen(data), 0); + arg->u1.const_vp = tal_dup_talarr(conn, u8, + memcheck(data, tal_bytelen(data))); /* We use u2 to store the length we've written. */ arg->u2.s = INSIDE_HEADER_BIT;