wallet: use db_col_optional.

We don't cover three common patterns:
1. Optional integers (db_col_u64 has different form from structs)
2. Optional strings.
3. Optional array fields.

But it does neaten and reduce the scope for cut&paste errors in the
common "if not-NULL, tal and assign".

Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
This commit is contained in:
Rusty Russell 2023-03-20 10:48:59 +10:30
parent aae77802ef
commit f720e0ff0b
3 changed files with 33 additions and 105 deletions

View File

@ -1101,11 +1101,7 @@ void fillin_missing_scriptpubkeys(struct lightningd *ld, struct db *db)
channel_id = db_col_u64(stmt, "channel_id");
db_col_node_id(stmt, "peer_id", &peer_id);
if (!db_col_is_null(stmt, "commitment_point")) {
commitment_point = tal(stmt, struct pubkey);
db_col_pubkey(stmt, "commitment_point", commitment_point);
} else
commitment_point = NULL;
commitment_point = db_col_optional(stmt, stmt, "commitment_point", pubkey);
/* Have to go ask the HSM to derive the pubkey for us */
msg = towire_hsmd_get_output_scriptpubkey(NULL,

View File

@ -87,13 +87,7 @@ static struct invoice_details *wallet_stmt2invoice_details(const tal_t *ctx,
dtl->label = db_col_json_escape(dtl, stmt, "label");
if (!db_col_is_null(stmt, "msatoshi")) {
dtl->msat = tal(dtl, struct amount_msat);
db_col_amount_msat(stmt, "msatoshi", dtl->msat);
} else {
dtl->msat = NULL;
}
dtl->msat = db_col_optional(dtl, stmt, "msatoshi", amount_msat);
dtl->expiry_time = db_col_u64(stmt, "expiry_time");
if (dtl->state == PAID) {
@ -115,12 +109,7 @@ static struct invoice_details *wallet_stmt2invoice_details(const tal_t *ctx,
dtl->description = NULL;
dtl->features = db_col_arr(dtl, stmt, "features", u8);
if (!db_col_is_null(stmt, "local_offer_id")) {
dtl->local_offer_id = tal(dtl, struct sha256);
db_col_sha256(stmt, "local_offer_id",
dtl->local_offer_id);
} else
dtl->local_offer_id = NULL;
dtl->local_offer_id = db_col_optional(dtl, stmt, "local_offer_id", sha256);
return dtl;
}

View File

@ -207,13 +207,10 @@ static struct utxo *wallet_stmt2output(const tal_t *ctx, struct db_stmt *stmt)
utxo->close_info = tal(utxo, struct unilateral_close_info);
utxo->close_info->channel_id = db_col_u64(stmt, "channel_id");
db_col_node_id(stmt, "peer_id", &utxo->close_info->peer_id);
if (!db_col_is_null(stmt, "commitment_point")) {
utxo->close_info->commitment_point
= tal(utxo->close_info, struct pubkey);
db_col_pubkey(stmt, "commitment_point",
utxo->close_info->commitment_point);
} else
utxo->close_info->commitment_point = NULL;
utxo->close_info->commitment_point
= db_col_optional(utxo->close_info, stmt,
"commitment_point",
pubkey);
utxo->close_info->option_anchor_outputs
= db_col_int(stmt, "option_anchor_outputs");
utxo->close_info->csv = db_col_int(stmt, "csv_lock");
@ -1315,26 +1312,11 @@ static struct channel *wallet_stmt2channel(struct wallet *w, struct db_stmt *stm
}
}
if (!db_col_is_null(stmt, "scid")) {
scid = tal(tmpctx, struct short_channel_id);
db_col_short_channel_id(stmt, "scid", scid);
} else {
scid = NULL;
}
if (!db_col_is_null(stmt, "alias_local")) {
alias[LOCAL] = tal(tmpctx, struct short_channel_id);
db_col_short_channel_id(stmt, "alias_local", alias[LOCAL]);
} else {
alias[LOCAL] = NULL;
}
if (!db_col_is_null(stmt, "alias_remote")) {
alias[REMOTE] = tal(tmpctx, struct short_channel_id);
db_col_short_channel_id(stmt, "alias_remote", alias[REMOTE]);
} else {
alias[REMOTE] = NULL;
}
scid = db_col_optional(tmpctx, stmt, "scid", short_channel_id);
alias[LOCAL] = db_col_optional(tmpctx, stmt, "alias_local",
short_channel_id);
alias[REMOTE] = db_col_optional(tmpctx, stmt, "alias_remote",
short_channel_id);
ok &= wallet_shachain_load(w, db_col_u64(stmt, "shachain_remote_id"),
&wshachain);
@ -1368,12 +1350,9 @@ static struct channel *wallet_stmt2channel(struct wallet *w, struct db_stmt *stm
db_col_ignore(stmt, "last_sent_commit_state");
db_col_ignore(stmt, "last_sent_commit_id");
if (!db_col_is_null(stmt, "future_per_commitment_point")) {
future_per_commitment_point = tal(tmpctx, struct pubkey);
db_col_pubkey(stmt, "future_per_commitment_point",
future_per_commitment_point);
} else
future_per_commitment_point = NULL;
future_per_commitment_point = db_col_optional(tmpctx, stmt,
"future_per_commitment_point",
pubkey);
db_col_channel_id(stmt, "full_channel_id", &cid);
channel_config_id = db_col_u64(stmt, "channel_config_local");
@ -2626,12 +2605,7 @@ static bool wallet_stmt2htlc_in(struct channel *channel,
db_col_sha256(stmt, "payment_hash", &in->payment_hash);
if (!db_col_is_null(stmt, "payment_key")) {
in->preimage = tal(in, struct preimage);
db_col_preimage(stmt, "payment_key", in->preimage);
} else {
in->preimage = NULL;
}
in->preimage = db_col_optional(in, stmt, "payment_key", preimage);
assert(db_col_bytes(stmt, "routing_onion")
== sizeof(in->onion_routing_packet));
@ -2643,18 +2617,12 @@ static bool wallet_stmt2htlc_in(struct channel *channel,
else
in->failonion = db_col_onionreply(in, stmt, "failuremsg");
in->badonion = db_col_int(stmt, "malformed_onion");
if (db_col_is_null(stmt, "shared_secret")) {
in->shared_secret = NULL;
} else {
assert(db_col_bytes(stmt, "shared_secret") == sizeof(struct secret));
in->shared_secret = tal(in, struct secret);
memcpy(in->shared_secret, db_col_blob(stmt, "shared_secret"),
sizeof(struct secret));
in->shared_secret = db_col_optional(in, stmt, "shared_secret", secret);
#ifdef COMPAT_V062
if (memeqzero(in->shared_secret, sizeof(*in->shared_secret)))
in->shared_secret = tal_free(in->shared_secret);
if (in->shared_secret
&& memeqzero(in->shared_secret, sizeof(*in->shared_secret)))
in->shared_secret = tal_free(in->shared_secret);
#endif
}
#ifdef COMPAT_V072
if (db_col_is_null(stmt, "received_time")) {
@ -2707,12 +2675,7 @@ static bool wallet_stmt2htlc_out(struct wallet *wallet,
/* FIXME: save blinding in db !*/
out->blinding = NULL;
if (!db_col_is_null(stmt, "payment_key")) {
out->preimage = tal(out, struct preimage);
db_col_preimage(stmt, "payment_key", out->preimage);
} else {
out->preimage = NULL;
}
out->preimage = db_col_optional(out, stmt, "payment_key", preimage);
assert(db_col_bytes(stmt, "routing_onion")
== sizeof(out->onion_routing_packet));
@ -3229,24 +3192,15 @@ static struct wallet_payment *wallet_stmt2payment(const tal_t *ctx,
struct wallet_payment *payment = tal(ctx, struct wallet_payment);
payment->id = db_col_u64(stmt, "id");
payment->status = db_col_int(stmt, "status");
if (!db_col_is_null(stmt, "destination")) {
payment->destination = tal(payment, struct node_id);
db_col_node_id(stmt, "destination", payment->destination);
} else {
payment->destination = NULL;
}
payment->destination = db_col_optional(payment, stmt, "destination",
node_id);
db_col_amount_msat(stmt, "msatoshi", &payment->msatoshi);
db_col_sha256(stmt, "payment_hash", &payment->payment_hash);
payment->timestamp = db_col_int(stmt, "timestamp");
if (!db_col_is_null(stmt, "payment_preimage")) {
payment->payment_preimage = tal(payment, struct preimage);
db_col_preimage(stmt, "payment_preimage",
payment->payment_preimage);
} else
payment->payment_preimage = NULL;
payment->payment_preimage = db_col_optional(payment, stmt,
"payment_preimage",
preimage);
/* We either used `sendpay` or `sendonion` with the `shared_secrets`
* argument. */
@ -3302,11 +3256,8 @@ static struct wallet_payment *wallet_stmt2payment(const tal_t *ctx,
else
payment->partid = 0;
if (!db_col_is_null(stmt, "local_invreq_id")) {
payment->local_invreq_id = tal(payment, struct sha256);
db_col_sha256(stmt, "local_invreq_id", payment->local_invreq_id);
} else
payment->local_invreq_id = NULL;
payment->local_invreq_id = db_col_optional(payment, stmt,
"local_invreq_id", sha256);
if (!db_col_is_null(stmt, "completed_at")) {
payment->completed_at = tal(payment, u32);
@ -3471,21 +3422,13 @@ void wallet_payment_get_failinfo(const tal_t *ctx,
*faildestperm = db_col_int(stmt, "faildestperm") != 0;
*failindex = db_col_int(stmt, "failindex");
*failcode = (enum onion_wire) db_col_int(stmt, "failcode");
if (db_col_is_null(stmt, "failnode"))
*failnode = NULL;
else {
*failnode = tal(ctx, struct node_id);
db_col_node_id(stmt, "failnode", *failnode);
}
if (db_col_is_null(stmt, "failscid")) {
db_col_ignore(stmt, "faildirection");
*failchannel = NULL;
} else {
*failchannel = tal(ctx, struct short_channel_id);
db_col_short_channel_id(stmt, "failscid", *failchannel);
*failnode = db_col_optional(ctx, stmt, "failnode", node_id);
*failchannel = db_col_optional(ctx, stmt, "failscid", short_channel_id);
if (*failchannel) {
/* For pre-0.6.2 dbs, direction will be 0 */
*faildirection = db_col_int(stmt, "faildirection");
} else {
db_col_ignore(stmt, "faildirection");
}
if (db_col_is_null(stmt, "failupdate"))
*failupdate = NULL;