From 526d3a232e0ec3648a2f44efcd79856b26e160c2 Mon Sep 17 00:00:00 2001 From: Rusty Russell Date: Thu, 8 Feb 2018 11:54:46 +1030 Subject: [PATCH] tools/generate_wire.py: generate varlen arrays properly. These are now logically arrays of pointers. This is much more natural, and gets rid of the horrible utxo array converters. Signed-off-by: Rusty Russell --- channeld/channel.c | 19 +++++++++++-------- channeld/full_channel.c | 21 +++++++++++---------- channeld/full_channel.h | 2 +- common/utxo.c | 21 --------------------- common/utxo.h | 5 ----- gossipd/gossip.c | 28 ++++++++++++++++------------ hsmd/hsm.c | 29 +++++++++++++---------------- lightningd/gossip_control.c | 18 +++++++++--------- lightningd/peer_control.c | 12 ++++-------- lightningd/peer_htlcs.c | 24 +++++++++++++----------- lightningd/peer_htlcs.h | 2 +- openingd/opening.c | 10 +++++----- tools/generate-wire.py | 28 +++++++++++++++++++--------- wallet/walletrpc.c | 5 +---- 14 files changed, 104 insertions(+), 120 deletions(-) diff --git a/channeld/channel.c b/channeld/channel.c index 63104b28b..09f9cbad4 100644 --- a/channeld/channel.c +++ b/channeld/channel.c @@ -1064,7 +1064,7 @@ static u8 *got_commitsig_msg(const tal_t *ctx, const tal_t *tmpctx = tal_tmpctx(ctx); struct changed_htlc *changed; struct fulfilled_htlc *fulfilled; - struct failed_htlc *failed; + const struct failed_htlc **failed; struct added_htlc *added; struct secret *shared_secret; u8 *msg; @@ -1072,7 +1072,7 @@ static u8 *got_commitsig_msg(const tal_t *ctx, changed = tal_arr(tmpctx, struct changed_htlc, 0); added = tal_arr(tmpctx, struct added_htlc, 0); shared_secret = tal_arr(tmpctx, struct secret, 0); - failed = tal_arr(tmpctx, struct failed_htlc, 0); + failed = tal_arr(tmpctx, const struct failed_htlc *, 0); fulfilled = tal_arr(tmpctx, struct fulfilled_htlc, 0); for (size_t i = 0; i < tal_count(changed_htlcs); i++) { @@ -1096,12 +1096,13 @@ static u8 *got_commitsig_msg(const tal_t *ctx, 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->id = htlc->id; - f->malformed = htlc->malformed; - f->failreason = cast_const(u8 *, htlc->fail); + *f = tal(failed, struct failed_htlc); + (*f)->id = htlc->id; + (*f)->malformed = htlc->malformed; + (*f)->failreason = cast_const(u8 *, htlc->fail); } } else { struct changed_htlc *c = tal_arr_append(&changed); @@ -2421,7 +2422,7 @@ static void init_channel(struct peer *peer) enum htlc_state *hstates; struct fulfilled_htlc *fulfilled; enum side *fulfilled_sides; - struct failed_htlc *failed; + struct failed_htlc **failed; enum side *failed_sides; struct added_htlc *htlcs; bool reconnected; @@ -2521,7 +2522,9 @@ static void init_channel(struct peer *peer) if (!channel_force_htlcs(peer->channel, htlcs, hstates, fulfilled, fulfilled_sides, - failed, failed_sides)) + cast_const2(const struct failed_htlc **, + failed), + failed_sides)) status_failed(STATUS_FAIL_INTERNAL_ERROR, "Could not restore HTLCs"); diff --git a/channeld/full_channel.c b/channeld/full_channel.c index 1c2c824cb..cc3f9e6f3 100644 --- a/channeld/full_channel.c +++ b/channeld/full_channel.c @@ -918,7 +918,7 @@ bool channel_force_htlcs(struct channel *channel, const enum htlc_state *hstates, const struct fulfilled_htlc *fulfilled, const enum side *fulfilled_sides, - const struct failed_htlc *failed, + const struct failed_htlc **failed, const enum side *failed_sides) { size_t i; @@ -1002,29 +1002,29 @@ bool channel_force_htlcs(struct channel *channel, for (i = 0; i < tal_count(failed); i++) { struct htlc *htlc; htlc = channel_get_htlc(channel, failed_sides[i], - failed[i].id); + failed[i]->id); if (!htlc) { status_trace("Fail %s HTLC %"PRIu64" not found", failed_sides[i] == LOCAL ? "out" : "in", - failed[i].id); + failed[i]->id); return false; } if (htlc->r) { status_trace("Fail %s HTLC %"PRIu64" already fulfilled", failed_sides[i] == LOCAL ? "out" : "in", - failed[i].id); + failed[i]->id); return false; } if (htlc->fail) { status_trace("Fail %s HTLC %"PRIu64" already failed", failed_sides[i] == LOCAL ? "out" : "in", - failed[i].id); + failed[i]->id); return false; } if (htlc->malformed) { status_trace("Fail %s HTLC %"PRIu64" already malformed", failed_sides[i] == LOCAL ? "out" : "in", - failed[i].id); + failed[i]->id); return false; } if (!htlc_has(htlc, HTLC_REMOVING)) { @@ -1034,11 +1034,12 @@ bool channel_force_htlcs(struct channel *channel, htlc_state_name(htlc->state)); return false; } - if (failed[i].malformed) - htlc->malformed = failed[i].malformed; + if (failed[i]->malformed) + htlc->malformed = failed[i]->malformed; else - htlc->fail = tal_dup_arr(htlc, u8, failed[i].failreason, - tal_len(failed[i].failreason), + htlc->fail = tal_dup_arr(htlc, u8, + failed[i]->failreason, + tal_len(failed[i]->failreason), 0); } diff --git a/channeld/full_channel.h b/channeld/full_channel.h index d51d8e202..7cf121ff7 100644 --- a/channeld/full_channel.h +++ b/channeld/full_channel.h @@ -268,7 +268,7 @@ bool channel_force_htlcs(struct channel *channel, const enum htlc_state *hstates, const struct fulfilled_htlc *fulfilled, const enum side *fulfilled_sides, - const struct failed_htlc *failed, + const struct failed_htlc **failed, const enum side *failed_sides); /** diff --git a/common/utxo.c b/common/utxo.c index 5114fe664..d1821f155 100644 --- a/common/utxo.c +++ b/common/utxo.c @@ -39,24 +39,3 @@ struct utxo *fromwire_utxo(const tal_t *ctx, const u8 **ptr, size_t *max) } return utxo; } - - -struct utxo *from_utxoptr_arr(const tal_t *ctx, const struct utxo **utxos) -{ - size_t i, n = tal_count(utxos); - struct utxo *utxo = tal_arr(ctx, struct utxo, n); - - for (i = 0; i < n; i++) - utxo[i] = *utxos[i]; - return utxo; -} - -const struct utxo **to_utxoptr_arr(const tal_t *ctx, const struct utxo *utxos) -{ - size_t i, n = tal_count(utxos); - const struct utxo **utxo = tal_arr(ctx, const struct utxo *, n); - - for (i = 0; i < n; i++) - utxo[i] = &utxos[i]; - return utxo; -} diff --git a/common/utxo.h b/common/utxo.h index dc6a1b3a9..a1ba5e4ee 100644 --- a/common/utxo.h +++ b/common/utxo.h @@ -30,9 +30,4 @@ struct utxo { void towire_utxo(u8 **pptr, const struct utxo *utxo); struct utxo *fromwire_utxo(const tal_t *ctx, const u8 **ptr, size_t *max); - -/* build_utxos/funding_tx use array of pointers, but marshall code - * wants arr of structs */ -struct utxo *from_utxoptr_arr(const tal_t *ctx, const struct utxo **utxos); -const struct utxo **to_utxoptr_arr(const tal_t *ctx, const struct utxo *utxos); #endif /* LIGHTNING_COMMON_UTXO_H */ diff --git a/gossipd/gossip.c b/gossipd/gossip.c index 7db101439..5d2a67b3c 100644 --- a/gossipd/gossip.c +++ b/gossipd/gossip.c @@ -1,4 +1,5 @@ #include +#include #include #include #include @@ -1118,21 +1119,24 @@ static struct io_plan *getchannels_req(struct io_conn *conn, struct daemon *daem return daemon_conn_read_next(conn, &daemon->master); } -static void append_node(struct gossip_getnodes_entry **nodes, +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); - tal_resize(nodes, num_nodes + 1); - (*nodes)[num_nodes].nodeid = n->id; - (*nodes)[num_nodes].last_timestamp = n->last_timestamp; + + new = tal(*nodes, struct gossip_getnodes_entry); + new->nodeid = n->id; + new->last_timestamp = n->last_timestamp; if (n->last_timestamp < 0) { - (*nodes)[num_nodes].addresses = NULL; - return; + new->addresses = NULL; + } else { + new->addresses = n->addresses; + new->alias = n->alias; + memcpy(new->color, n->rgb_color, 3); } - - (*nodes)[num_nodes].addresses = n->addresses; - (*nodes)[num_nodes].alias = n->alias; - memcpy((*nodes)[num_nodes].color, n->rgb_color, 3); + tal_resize(nodes, num_nodes + 1); + (*nodes)[num_nodes] = new; } static struct io_plan *getnodes(struct io_conn *conn, struct daemon *daemon, @@ -1141,12 +1145,12 @@ static struct io_plan *getnodes(struct io_conn *conn, struct daemon *daemon, tal_t *tmpctx = tal_tmpctx(daemon); u8 *out; struct node *n; - struct gossip_getnodes_entry *nodes; + const struct gossip_getnodes_entry **nodes; struct pubkey *ids; fromwire_gossip_getnodes_request(tmpctx, msg, NULL, &ids); - nodes = tal_arr(tmpctx, struct gossip_getnodes_entry, 0); + nodes = tal_arr(tmpctx, const struct gossip_getnodes_entry *, 0); if (ids) { for (size_t i = 0; i < tal_count(ids); i++) { n = node_map_get(daemon->rstate->nodes, &ids[i].pubkey); diff --git a/hsmd/hsm.c b/hsmd/hsm.c index 9f3b4f5ee..2fcd76d59 100644 --- a/hsmd/hsm.c +++ b/hsmd/hsm.c @@ -3,6 +3,7 @@ #include #include #include +#include #include #include #include @@ -610,8 +611,7 @@ static void sign_funding_tx(struct daemon_conn *master, const u8 *msg) u64 satoshi_out, change_out; u32 change_keyindex; struct pubkey local_pubkey, remote_pubkey; - struct utxo *inputs; - const struct utxo **utxomap; + struct utxo **utxomap; struct bitcoin_tx *tx; u8 *wscript; u16 outnum; @@ -623,21 +623,20 @@ static void sign_funding_tx(struct daemon_conn *master, const u8 *msg) if (!fromwire_hsm_sign_funding(tmpctx, msg, NULL, &satoshi_out, &change_out, &change_keyindex, &local_pubkey, - &remote_pubkey, &inputs)) + &remote_pubkey, &utxomap)) master_badmsg(WIRE_HSM_SIGN_FUNDING, msg); - utxomap = to_utxoptr_arr(tmpctx, inputs); - if (change_out) bitcoin_pubkey(&changekey, change_keyindex); - tx = funding_tx(tmpctx, &outnum, utxomap, + tx = funding_tx(tmpctx, &outnum, + cast_const2(const struct utxo **, utxomap), satoshi_out, &local_pubkey, &remote_pubkey, change_out, &changekey, NULL); - scriptSigs = tal_arr(tmpctx, u8*, tal_count(inputs)); - for (i = 0; i < tal_count(inputs); i++) { + scriptSigs = tal_arr(tmpctx, u8*, tal_count(utxomap)); + for (i = 0; i < tal_count(utxomap); i++) { struct pubkey inkey; struct privkey inprivkey; const struct utxo *in = utxomap[i]; @@ -657,14 +656,14 @@ static void sign_funding_tx(struct daemon_conn *master, const u8 *msg) tx->input[i].witness = bitcoin_witness_p2wpkh(tx, &sig, &inkey); - if (inputs[i].is_p2sh) + if (utxomap[i]->is_p2sh) scriptSigs[i] = bitcoin_scriptsig_p2sh_p2wpkh(tx, &inkey); else scriptSigs[i] = NULL; } /* Now complete the transaction by attaching the scriptSigs where necessary */ - for (size_t i=0; iinput[i].script = scriptSigs[i]; daemon_conn_send(master, @@ -680,8 +679,7 @@ static void sign_withdrawal_tx(struct daemon_conn *master, const u8 *msg) const tal_t *tmpctx = tal_tmpctx(master); u64 satoshi_out, change_out; u32 change_keyindex; - struct utxo *inutxos; - const struct utxo **utxos; + struct utxo **utxos; u8 *wscript; u8 **scriptSigs; struct bitcoin_tx *tx; @@ -691,7 +689,7 @@ static void sign_withdrawal_tx(struct daemon_conn *master, const u8 *msg) if (!fromwire_hsm_sign_withdrawal(tmpctx, msg, NULL, &satoshi_out, &change_out, &change_keyindex, - &scriptpubkey, &inutxos)) { + &scriptpubkey, &utxos)) { status_broken("Failed to parse sign_withdrawal: %s", tal_hex(trc, msg)); return; @@ -704,11 +702,10 @@ static void sign_withdrawal_tx(struct daemon_conn *master, const u8 *msg) return; } - /* We need an array of pointers, since withdraw_tx permutes them */ - utxos = to_utxoptr_arr(tmpctx, inutxos); pubkey_from_der(ext.pub_key, sizeof(ext.pub_key), &changekey); tx = withdraw_tx( - tmpctx, utxos, scriptpubkey, satoshi_out, + tmpctx, cast_const2(const struct utxo **, utxos), + scriptpubkey, satoshi_out, &changekey, change_out, NULL); scriptSigs = tal_arr(tmpctx, u8*, tal_count(utxos)); diff --git a/lightningd/gossip_control.c b/lightningd/gossip_control.c index 300f6cb5a..d7edfd142 100644 --- a/lightningd/gossip_control.c +++ b/lightningd/gossip_control.c @@ -191,7 +191,7 @@ static void json_getnodes_reply(struct subd *gossip, const u8 *reply, const int *fds, struct command *cmd) { - struct gossip_getnodes_entry *nodes; + struct gossip_getnodes_entry **nodes; struct json_result *response = new_json_result(cmd); size_t i, j; @@ -205,21 +205,21 @@ static void json_getnodes_reply(struct subd *gossip, const u8 *reply, for (i = 0; i < tal_count(nodes); i++) { json_object_start(response, NULL); - json_add_pubkey(response, "nodeid", &nodes[i].nodeid); - if (nodes[i].last_timestamp < 0) { + json_add_pubkey(response, "nodeid", &nodes[i]->nodeid); + if (nodes[i]->last_timestamp < 0) { json_object_end(response); continue; } json_add_string(response, "alias", - tal_strndup(response, (char *)nodes[i].alias, - tal_len(nodes[i].alias))); + tal_strndup(response, (char *)nodes[i]->alias, + tal_len(nodes[i]->alias))); json_add_hex(response, "color", - nodes[i].color, ARRAY_SIZE(nodes[i].color)); + nodes[i]->color, ARRAY_SIZE(nodes[i]->color)); json_add_u64(response, "last_timestamp", - nodes[i].last_timestamp); + nodes[i]->last_timestamp); json_array_start(response, "addresses"); - for (j=0; jaddresses); j++) { + json_add_address(response, NULL, &nodes[i]->addresses[j]); } json_array_end(response); json_object_end(response); diff --git a/lightningd/peer_control.c b/lightningd/peer_control.c index 352c361c7..dd93c2fe5 100644 --- a/lightningd/peer_control.c +++ b/lightningd/peer_control.c @@ -2067,7 +2067,7 @@ static bool peer_start_channeld(struct peer *peer, enum htlc_state *htlc_states; struct fulfilled_htlc *fulfilled_htlcs; enum side *fulfilled_sides; - struct failed_htlc *failed_htlcs; + const struct failed_htlc **failed_htlcs; enum side *failed_sides; struct short_channel_id funding_channel_id; const u8 *shutdown_scriptpubkey; @@ -2206,7 +2206,6 @@ static void opening_funder_finished(struct subd *opening, const u8 *resp, tal_t *tmpctx = tal_tmpctx(fc); u8 *msg; struct channel_info *channel_info; - struct utxo *utxos; struct bitcoin_tx *fundingtx; struct bitcoin_txid funding_txid; struct pubkey changekey; @@ -2308,12 +2307,11 @@ static void opening_funder_finished(struct subd *opening, const u8 *resp, /* Get HSM to sign the funding tx. */ log_debug(fc->peer->log, "Getting HSM to sign funding tx"); - utxos = from_utxoptr_arr(tmpctx, fc->utxomap); msg = towire_hsm_sign_funding(tmpctx, fc->peer->funding_satoshi, fc->change, fc->change_keyindex, &local_fundingkey, &channel_info->remote_fundingkey, - utxos); + fc->utxomap); /* Unowned (will free openingd). */ peer_set_owner(fc->peer, NULL); @@ -2533,7 +2531,6 @@ static void peer_offer_channel(struct lightningd *ld, u8 *msg; u32 max_to_self_delay, max_minimum_depth; u64 min_effective_htlc_capacity_msat; - struct utxo *utxos; /* We make a new peer. */ fc->peer = new_peer(ld, &fc->peerid, addr, @@ -2586,15 +2583,14 @@ static void peer_offer_channel(struct lightningd *ld, cs, gossip_index, fc->peer->seed); subd_send_msg(fc->peer->owner, take(msg)); - utxos = from_utxoptr_arr(fc, fc->utxomap); - msg = towire_opening_funder(fc, fc->peer->funding_satoshi, fc->peer->push_msat, get_feerate(ld->topology, FEERATE_NORMAL), max_minimum_depth, fc->change, fc->change_keyindex, fc->peer->channel_flags, - utxos, fc->peer->ld->wallet->bip32_base); + fc->utxomap, + fc->peer->ld->wallet->bip32_base); /* Peer now owns fc; if it dies, we fail fc. */ tal_steal(fc->peer, fc); diff --git a/lightningd/peer_htlcs.c b/lightningd/peer_htlcs.c index 08ead4aee..3c6fc006f 100644 --- a/lightningd/peer_htlcs.c +++ b/lightningd/peer_htlcs.c @@ -1035,7 +1035,7 @@ static bool peer_added_their_htlc(struct peer *peer, static bool peer_sending_revocation(struct peer *peer, struct added_htlc *added, struct fulfilled_htlc *fulfilled, - struct failed_htlc *failed, + struct failed_htlc **failed, struct changed_htlc *changed) { size_t i; @@ -1050,7 +1050,7 @@ static bool peer_sending_revocation(struct peer *peer, return false; } for (i = 0; i < tal_count(failed); i++) { - if (!update_out_htlc(peer, failed[i].id, SENT_REMOVE_REVOCATION)) + if (!update_out_htlc(peer, failed[i]->id, SENT_REMOVE_REVOCATION)) return false; } for (i = 0; i < tal_count(changed); i++) { @@ -1079,7 +1079,7 @@ void peer_got_commitsig(struct peer *peer, const u8 *msg) struct added_htlc *added; struct secret *shared_secrets; struct fulfilled_htlc *fulfilled; - struct failed_htlc *failed; + struct failed_htlc **failed; struct changed_htlc *changed; struct bitcoin_tx *tx = tal(msg, struct bitcoin_tx); size_t i; @@ -1120,7 +1120,7 @@ void peer_got_commitsig(struct peer *peer, const u8 *msg) } for (i = 0; i < tal_count(failed); i++) { - if (!peer_failed_our_htlc(peer, &failed[i])) + if (!peer_failed_our_htlc(peer, failed[i])) return; } @@ -1305,17 +1305,19 @@ static void add_fulfill(u64 id, enum side side, static void add_fail(u64 id, enum side side, const u8 *failuremsg, - struct failed_htlc **failed_htlcs, + const struct failed_htlc ***failed_htlcs, enum side **failed_sides) { - struct failed_htlc *f; + struct failed_htlc **f; enum side *s; f = tal_arr_append(failed_htlcs); s = tal_arr_append(failed_sides); - f->id = id; - f->failreason = tal_dup_arr(*failed_htlcs, u8, - failuremsg, tal_len(failuremsg), 0); + + *f = tal(*failed_htlcs, struct failed_htlc); + (*f)->id = id; + (*f)->failreason + = tal_dup_arr(*f, u8, failuremsg, tal_len(failuremsg), 0); *s = side; } @@ -1326,7 +1328,7 @@ void peer_htlcs(const tal_t *ctx, enum htlc_state **htlc_states, struct fulfilled_htlc **fulfilled_htlcs, enum side **fulfilled_sides, - struct failed_htlc **failed_htlcs, + const struct failed_htlc ***failed_htlcs, enum side **failed_sides) { struct htlc_in_map_iter ini; @@ -1338,7 +1340,7 @@ void peer_htlcs(const tal_t *ctx, *htlc_states = tal_arr(ctx, enum htlc_state, 0); *fulfilled_htlcs = tal_arr(ctx, struct fulfilled_htlc, 0); *fulfilled_sides = tal_arr(ctx, enum side, 0); - *failed_htlcs = tal_arr(ctx, struct failed_htlc, 0); + *failed_htlcs = tal_arr(ctx, const struct failed_htlc *, 0); *failed_sides = tal_arr(ctx, enum side, 0); for (hin = htlc_in_map_first(&peer->ld->htlcs_in, &ini); diff --git a/lightningd/peer_htlcs.h b/lightningd/peer_htlcs.h index 585d16667..569202b24 100644 --- a/lightningd/peer_htlcs.h +++ b/lightningd/peer_htlcs.h @@ -25,7 +25,7 @@ void peer_htlcs(const tal_t *ctx, enum htlc_state **htlc_states, struct fulfilled_htlc **fulfilled_htlcs, enum side **fulfilled_sides, - struct failed_htlc **failed_htlcs, + const struct failed_htlc ***failed_htlcs, enum side **failed_sides); void peer_sending_commitsig(struct peer *peer, const u8 *msg); diff --git a/openingd/opening.c b/openingd/opening.c index b0548b301..d53ae219a 100644 --- a/openingd/opening.c +++ b/openingd/opening.c @@ -3,6 +3,7 @@ #include #include #include +#include #include #include #include @@ -234,7 +235,7 @@ static u8 *funder_channel(struct state *state, u32 max_minimum_depth, u64 change_satoshis, u32 change_keyindex, u8 channel_flags, - const struct utxo *utxos, + struct utxo **utxos, const struct ext_key *bip32_base) { struct channel_id id_in; @@ -246,7 +247,6 @@ static u8 *funder_channel(struct state *state, u32 minimum_depth; const u8 *wscript; struct bitcoin_tx *funding; - const struct utxo **utxomap; set_reserve(&state->localconf.channel_reserve_satoshis, state->funding_satoshis); @@ -352,9 +352,9 @@ static u8 *funder_channel(struct state *state, "Bad change key %u", change_keyindex); } - utxomap = to_utxoptr_arr(state, utxos); funding = funding_tx(state, &state->funding_txout, - utxomap, state->funding_satoshis, + cast_const2(const struct utxo **, utxos), + state->funding_satoshis, our_funding_pubkey, &their_funding_pubkey, change_satoshis, &changekey, @@ -713,7 +713,7 @@ int main(int argc, char *argv[]) u64 change_satoshis; u32 change_keyindex; u8 channel_flags; - struct utxo *utxos; + struct utxo **utxos; struct ext_key bip32_base; u32 network_index; diff --git a/tools/generate-wire.py b/tools/generate-wire.py index fcbaa2931..260ce4a8d 100755 --- a/tools/generate-wire.py +++ b/tools/generate-wire.py @@ -281,8 +281,8 @@ class Message(object): subcalls.append('\t\t({})[i] = fromwire_{}(&cursor, plen);' .format(name, basetype)) elif basetype in varlen_structs: - subcalls.append('\t\t{}[i] = fromwire_{}(ctx, &cursor, plen);' - .format(f.name, basetype)) + subcalls.append('\t\t({})[i] = fromwire_{}(ctx, &cursor, plen);' + .format(name, basetype)) else: subcalls.append('\t\tfromwire_{}(&cursor, plen, {} + i);' .format(basetype, name)) @@ -297,12 +297,16 @@ class Message(object): continue elif f.is_array(): args.append(', {} {}[{}]'.format(f.fieldtype.name, f.name, f.num_elems)) - elif f.is_variable_size(): - args.append(', {} **{}'.format(f.fieldtype.name, f.name)) - elif f.basetype() in varlen_structs: - args.append(', {} **{}'.format(f.fieldtype.name, f.name)) else: - args.append(', {} *{}'.format(f.fieldtype.name, f.name)) + ptrs='*' + # If we're handing a variable array, we need a ptr-to-ptr. + if f.is_variable_size(): + ptrs += '*' + # If each type is a variable length, we need a ptr to that. + if f.basetype() in varlen_structs: + ptrs += '*' + + args.append(', {} {}{}'.format(f.fieldtype.name, ptrs, f.name)) template = fromwire_header_templ if is_header else fromwire_impl_templ fields = ['\t{} {};\n'.format(f.fieldtype.name, f.name) for f in self.fields if f.is_len_var] @@ -322,8 +326,12 @@ class Message(object): f.num_elems) elif f.is_variable_size(): subcalls.append("\t//2nd case {name}".format(name=f.name)) + typename = f.fieldtype.name + # If structs are varlen, need array of ptrs to them. + if basetype in varlen_structs: + typename += ' *' subcalls.append('\t*{} = {} ? tal_arr(ctx, {}, {}) : NULL;' - .format(f.name, f.lenvar, f.fieldtype.name, f.lenvar)) + .format(f.name, f.lenvar, typename, f.lenvar)) self.print_fromwire_array(subcalls, basetype, f, '*'+f.name, f.lenvar) @@ -358,7 +366,7 @@ class Message(object): else: subcalls.append('\tfor (size_t i = 0; i < {}; i++)\n' .format(num_elems)) - if f.fieldtype.is_assignable(): + if f.fieldtype.is_assignable() or basetype in varlen_structs: subcalls.append('\t\ttowire_{}(&p, {}[i]);' .format(basetype, f.name)) else: @@ -375,6 +383,8 @@ class Message(object): args.append(', const {} {}[{}]'.format(f.fieldtype.name, f.name, f.num_elems)) elif f.is_assignable(): args.append(', {} {}'.format(f.fieldtype.name, f.name)) + elif f.is_variable_size() and f.basetype() in varlen_structs: + args.append(', const {} **{}'.format(f.fieldtype.name, f.name)) else: args.append(', const {} *{}'.format(f.fieldtype.name, f.name)) diff --git a/wallet/walletrpc.c b/wallet/walletrpc.c index a0997a27e..70c9444c9 100644 --- a/wallet/walletrpc.c +++ b/wallet/walletrpc.c @@ -196,7 +196,6 @@ static void json_withdraw(struct command *cmd, bool testnet; u32 feerate_per_kw = get_feerate(cmd->ld->topology, FEERATE_NORMAL); u64 fee_estimate; - struct utxo *utxos; struct bitcoin_tx *tx; bool withdraw_all = false; @@ -277,14 +276,12 @@ static void json_withdraw(struct command *cmd, else withdraw->change_key_index = 0; - utxos = from_utxoptr_arr(withdraw, withdraw->utxos); u8 *msg = towire_hsm_sign_withdrawal(cmd, withdraw->amount, withdraw->changesatoshi, withdraw->change_key_index, withdraw->destination, - utxos); - tal_free(utxos); + withdraw->utxos); if (!wire_sync_write(cmd->ld->hsm_fd, take(msg))) fatal("Could not write sign_withdrawal to HSM: %s",