common: tal_dup_talarr() helper.

This is a common thing to do, so create a macro.

Unfortunately, it still needs the type arg, because the paramter may
be const, and the return cannot be, and C doesn't have a general
"(-const)" cast.

Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
This commit is contained in:
Rusty Russell
2020-02-27 12:47:01 +10:30
parent 684ed4231f
commit 2aad3ffcf8
21 changed files with 54 additions and 49 deletions

View File

@@ -8,6 +8,7 @@
#include <ccan/crypto/sha256/sha256.h> #include <ccan/crypto/sha256/sha256.h>
#include <ccan/endian/endian.h> #include <ccan/endian/endian.h>
#include <ccan/mem/mem.h> #include <ccan/mem/mem.h>
#include <common/utils.h>
/* Some standard ops */ /* Some standard ops */
#define OP_0 0x00 #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[0] = stack_sig(witness, sig);
witness[1] = tal_dup_arr(witness, u8, elem, elemsize, 0); witness[1] = tal_dup_arr(witness, u8, elem, elemsize, 0);
witness[2] = tal_dup_arr(witness, u8, witness[2] = tal_dup_talarr(witness, u8, witnessscript);
witnessscript, tal_count(witnessscript), 0);
return witness; return witness;
} }
@@ -675,7 +675,7 @@ u8 **bitcoin_witness_htlc_timeout_tx(const tal_t *ctx,
witness[1] = stack_sig(witness, remotehtlcsig); witness[1] = stack_sig(witness, remotehtlcsig);
witness[2] = stack_sig(witness, localhtlcsig); witness[2] = stack_sig(witness, localhtlcsig);
witness[3] = stack_number(witness, 0); 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; return witness;
} }
@@ -692,7 +692,7 @@ u8 **bitcoin_witness_htlc_success_tx(const tal_t *ctx,
witness[1] = stack_sig(witness, remotesig); witness[1] = stack_sig(witness, remotesig);
witness[2] = stack_sig(witness, localhtlcsig); witness[2] = stack_sig(witness, localhtlcsig);
witness[3] = stack_preimage(witness, preimage); 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; return witness;
} }

View File

@@ -3,6 +3,7 @@
#include "close_tx.h" #include "close_tx.h"
#include "permute_tx.h" #include "permute_tx.h"
#include <assert.h> #include <assert.h>
#include <common/utils.h>
struct bitcoin_tx *create_close_tx(const tal_t *ctx, struct bitcoin_tx *create_close_tx(const tal_t *ctx,
const struct chainparams *chainparams, const struct chainparams *chainparams,
@@ -41,16 +42,14 @@ struct bitcoin_tx *create_close_tx(const tal_t *ctx,
BITCOIN_TX_DEFAULT_SEQUENCE, funding, NULL); BITCOIN_TX_DEFAULT_SEQUENCE, funding, NULL);
if (amount_sat_greater_eq(to_us, dust_limit)) { if (amount_sat_greater_eq(to_us, dust_limit)) {
script = script = tal_dup_talarr(tx, u8, our_script);
tal_dup_arr(tx, u8, our_script, tal_count(our_script), 0);
/* One output is to us. */ /* One output is to us. */
bitcoin_tx_add_output(tx, script, to_us); bitcoin_tx_add_output(tx, script, to_us);
num_outputs++; num_outputs++;
} }
if (amount_sat_greater_eq(to_them, dust_limit)) { if (amount_sat_greater_eq(to_them, dust_limit)) {
script = tal_dup_arr(tx, u8, their_script, script = tal_dup_talarr(tx, u8, their_script);
tal_count(their_script), 0);
/* Other output is to them. */ /* Other output is to them. */
bitcoin_tx_add_output(tx, script, to_them); bitcoin_tx_add_output(tx, script, to_them);
num_outputs++; num_outputs++;

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

View File

@@ -28,13 +28,13 @@ struct onionreply *dup_onionreply(const tal_t *ctx,
return cast_const(struct onionreply *, tal_steal(ctx, r)); return cast_const(struct onionreply *, tal_steal(ctx, r));
n = tal(ctx, struct onionreply); 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; return n;
} }
struct onionreply *new_onionreply(const tal_t *ctx, const u8 *contents TAKES) struct onionreply *new_onionreply(const tal_t *ctx, const u8 *contents TAKES)
{ {
struct onionreply *r = tal(ctx, struct onionreply); 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; return r;
} }

View File

@@ -214,8 +214,7 @@ static bool check_params(struct param *params)
return false; return false;
/* duplicate so we can sort */ /* duplicate so we can sort */
struct param *copy = tal_dup_arr(params, struct param, struct param *copy = tal_dup_talarr(params, struct param, params);
params, tal_count(params), 0);
/* check for repeated names and args */ /* check for repeated names and args */
if (!check_unique(copy, comp_by_name)) if (!check_unique(copy, comp_by_name))

View File

@@ -116,7 +116,7 @@ void handle_gossip_msg(struct per_peer_state *pps, const u8 *msg TAKES)
goto out; goto out;
} else } else
/* It's a raw gossip msg: this copies or takes() */ /* 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 */ /* Gossipd can send us gossip messages, OR errors */
if (fromwire_peektype(gossip) == WIRE_ERROR) { if (fromwire_peektype(gossip) == WIRE_ERROR) {

View File

@@ -62,8 +62,7 @@ struct sphinx_path {
struct sphinx_path *sphinx_path_new(const tal_t *ctx, const u8 *associated_data) struct sphinx_path *sphinx_path_new(const tal_t *ctx, const u8 *associated_data)
{ {
struct sphinx_path *sp = tal(ctx, struct sphinx_path); struct sphinx_path *sp = tal(ctx, struct sphinx_path);
sp->associated_data = tal_dup_arr(sp, u8, associated_data, sp->associated_data = tal_dup_talarr(sp, u8, associated_data);
tal_bytelen(associated_data), 0);
sp->session_key = NULL; sp->session_key = NULL;
sp->hops = tal_arr(sp, struct sphinx_hop, 0); sp->hops = tal_arr(sp, struct sphinx_hop, 0);
return sp; return sp;
@@ -95,7 +94,7 @@ void sphinx_add_hop(struct sphinx_path *path, const struct pubkey *pubkey,
const u8 *payload TAKES) const u8 *payload TAKES)
{ {
struct sphinx_hop sp; 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; sp.pubkey = *pubkey;
tal_arr_expand(&path->hops, sp); tal_arr_expand(&path->hops, sp);
} }

View File

@@ -112,14 +112,14 @@ int main(void)
/* We can add random odd features, no problem. */ /* We can add random odd features, no problem. */
for (size_t i = 1; i < 16; i += 2) { 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); set_feature_bit(&bits, i);
assert(features_unsupported(bits) == -1); assert(features_unsupported(bits) == -1);
} }
/* We can't add random even features. */ /* We can't add random even features. */
for (size_t i = 0; i < 16; i += 2) { 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); set_feature_bit(&bits, i);
/* Special case for missing compulsory feature */ /* Special case for missing compulsory feature */

View File

@@ -141,3 +141,10 @@ void tal_arr_remove_(void *p, size_t elemsize, size_t n)
len - (elemsize * (n+1))); len - (elemsize * (n+1)));
tal_resize((char **)p, len - elemsize); 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);
}

View File

@@ -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)) #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); 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. */ /* Use the POSIX C locale. */
void setup_locale(void); void setup_locale(void);

View File

@@ -395,9 +395,9 @@ static struct io_plan *peer_reconnected(struct io_conn *conn,
pr->cs = *cs; pr->cs = *cs;
pr->addr = *addr; 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). */ * (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 /*~ 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 * the peer set. When someone calls `io_wake()` on that address, it

View File

@@ -1421,8 +1421,7 @@ static u8 *patch_channel_update(const tal_t *ctx, u8 *channel_update TAKES)
tal_free(channel_update); tal_free(channel_update);
return fixed; return fixed;
} else { } else {
return tal_dup_arr(ctx, u8, return tal_dup_talarr(ctx, u8, channel_update);
channel_update, tal_count(channel_update), 0);
} }
} }

View File

@@ -1650,7 +1650,7 @@ bool routing_add_channel_announcement(struct routing_state *rstate,
} }
uc = tal(rstate, struct unupdated_channel); 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->added = gossip_time_now(rstate);
uc->index = index; uc->index = index;
uc->sat = sat; uc->sat = sat;
@@ -1694,8 +1694,7 @@ u8 *handle_channel_announcement(struct routing_state *rstate,
pending->updates[0] = NULL; pending->updates[0] = NULL;
pending->updates[1] = NULL; pending->updates[1] = NULL;
pending->update_peer_softref[0] = pending->update_peer_softref[1] = NULL; pending->update_peer_softref[0] = pending->update_peer_softref[1] = NULL;
pending->announce = tal_dup_arr(pending, u8, pending->announce = tal_dup_talarr(pending, u8, announce);
announce, tal_count(announce), 0);
pending->update_timestamps[0] = pending->update_timestamps[1] = 0; pending->update_timestamps[0] = pending->update_timestamps[1] = 0;
if (!fromwire_channel_announcement(pending, pending->announce, if (!fromwire_channel_announcement(pending, pending->announce,
@@ -1973,7 +1972,8 @@ static void update_pending(struct pending_cannouncement *pending,
"Replacing existing update"); "Replacing existing update");
tal_free(pending->updates[direction]); 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; pending->update_timestamps[direction] = timestamp;
clear_softref(pending, &pending->update_peer_softref[direction]); clear_softref(pending, &pending->update_peer_softref[direction]);
set_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; pna->index = index;
tal_free(pna->node_announcement); tal_free(pna->node_announcement);
clear_softref(pna, &pna->peer_softref); clear_softref(pna, &pna->peer_softref);
pna->node_announcement = tal_dup_arr(pna, u8, msg, pna->node_announcement = tal_dup_talarr(pna, u8, msg);
tal_count(msg),
0);
set_softref(pna, &pna->peer_softref, peer); set_softref(pna, &pna->peer_softref, peer);
return true; return true;
} }

View File

@@ -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 = tal(c, struct rpc_command_hook_payload);
rpc_hook->cmd = c; rpc_hook->cmd = c;
/* Duplicate since we might outlive the connection */ /* Duplicate since we might outlive the connection */
rpc_hook->buffer = tal_dup_arr(rpc_hook, char, jcon->buffer, rpc_hook->buffer = tal_dup_talarr(rpc_hook, char, jcon->buffer);
tal_count(jcon->buffer), 0); rpc_hook->request = tal_dup_talarr(rpc_hook, jsmntok_t, tok);
rpc_hook->request = tal_dup_arr(rpc_hook, const jsmntok_t, tok,
tal_count(tok), 0);
/* Prevent a race between was_pending and still_pending */ /* Prevent a race between was_pending and still_pending */
new_reltimer(c->ld->timers, rpc_hook, time_from_msec(1), new_reltimer(c->ld->timers, rpc_hook, time_from_msec(1),
call_rpc_command_hook, rpc_hook); call_rpc_command_hook, rpc_hook);

View File

@@ -468,8 +468,7 @@ remote_routing_failure(const tal_t *ctx,
routing_failure->erring_index = (unsigned int) (origin_index + 1); routing_failure->erring_index = (unsigned int) (origin_index + 1);
routing_failure->failcode = failcode; routing_failure->failcode = failcode;
routing_failure->msg = tal_dup_arr(routing_failure, u8, failuremsg, routing_failure->msg = tal_dup_talarr(routing_failure, u8, failuremsg);
tal_count(failuremsg), 0);
if (erring_node != NULL) if (erring_node != NULL)
routing_failure->erring_node = routing_failure->erring_node =

View File

@@ -77,8 +77,7 @@ static void destroy_peer(struct peer *peer)
static void peer_update_features(struct peer *peer, const u8 *features TAKES) static void peer_update_features(struct peer *peer, const u8 *features TAKES)
{ {
tal_free(peer->features); tal_free(peer->features);
peer->features = tal_dup_arr(peer, u8, peer->features = tal_dup_talarr(peer, u8, features);
features, tal_count(features), 0);
} }
struct peer *new_peer(struct lightningd *ld, u64 dbid, 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? */ /* Do we have an error to send? */
if (err_for_them && !channel->error) if (err_for_them && !channel->error)
channel->error = tal_dup_arr(channel, u8, channel->error = tal_dup_talarr(channel, u8, err_for_them);
err_for_them,
tal_count(err_for_them), 0);
/* Other implementations chose to ignore errors early on. Not /* Other implementations chose to ignore errors early on. Not
* surprisingly, they now spew out spurious errors frequently, * surprisingly, they now spew out spurious errors frequently,

View File

@@ -1748,7 +1748,7 @@ void peer_got_commitsig(struct channel *channel, const u8 *msg)
/* If subdaemon dies, we want to forget this. */ /* If subdaemon dies, we want to forget this. */
d = tal(channel->owner, struct deferred_commitsig); d = tal(channel->owner, struct deferred_commitsig);
d->channel = channel; 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, topology_add_sync_waiter(d, ld->topology,
retry_deferred_commitsig, d); retry_deferred_commitsig, d);
return; return;

View File

@@ -868,8 +868,7 @@ static struct command_result *getroute_error(struct command *cmd,
/* Deep copy of excludes array. */ /* Deep copy of excludes array. */
static const char **dup_excludes(const tal_t *ctx, const char **excludes) static const char **dup_excludes(const tal_t *ctx, const char **excludes)
{ {
const char **ret = tal_dup_arr(ctx, const char *, const char **ret = tal_dup_talarr(ctx, const char *, excludes);
excludes, tal_count(excludes), 0);
for (size_t i = 0; i < tal_count(ret); i++) for (size_t i = 0; i < tal_count(ret); i++)
ret[i] = tal_strdup(ret, excludes[i]); ret[i] = tal_strdup(ret, excludes[i]);
return ret; return ret;

View File

@@ -82,7 +82,7 @@ void txfilter_add_scriptpubkey(struct txfilter *filter, const u8 *script TAKES)
{ {
scriptpubkeyset_add( scriptpubkeyset_add(
&filter->scriptpubkeyset, &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, void txfilter_add_derkey(struct txfilter *filter,

View File

@@ -1612,7 +1612,7 @@ int wallet_extract_owned_outputs(struct wallet *w, const struct bitcoin_tx *tx,
utxo->blockheight = blockheight ? blockheight : NULL; utxo->blockheight = blockheight ? blockheight : NULL;
utxo->spendheight = 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", log_debug(w->log, "Owning output %zu %s (%s) txid %s%s",
output, output,

View File

@@ -4,6 +4,7 @@
#include <ccan/mem/mem.h> #include <ccan/mem/mem.h>
#include <ccan/take/take.h> #include <ccan/take/take.h>
#include <ccan/tal/tal.h> #include <ccan/tal/tal.h>
#include <common/utils.h>
#include <errno.h> #include <errno.h>
#include <wire/wire_io.h> #include <wire/wire_io.h>
@@ -136,9 +137,8 @@ struct io_plan *io_write_wire_(struct io_conn *conn,
return io_close(conn); return io_close(conn);
} }
arg->u1.const_vp = tal_dup_arr(conn, u8, arg->u1.const_vp = tal_dup_talarr(conn, u8,
memcheck(data, tal_bytelen(data)), memcheck(data, tal_bytelen(data)));
tal_bytelen(data), 0);
/* We use u2 to store the length we've written. */ /* We use u2 to store the length we've written. */
arg->u2.s = INSIDE_HEADER_BIT; arg->u2.s = INSIDE_HEADER_BIT;