From 23fafe98e3b4f4e15cdf764e1346d813d1eb8039 Mon Sep 17 00:00:00 2001 From: Rusty Russell Date: Sat, 22 Jul 2023 16:50:49 +0930 Subject: [PATCH] wallet: implement and use wallet_payment_new. We open-coded initialization in two places, now we will want a third, it's time to clean up. Signed-off-by: Rusty Russell --- lightningd/pay.c | 54 +++++++--------- wallet/wallet.c | 156 +++++++++++++++++++++++++---------------------- wallet/wallet.h | 24 ++++++++ 3 files changed, 129 insertions(+), 105 deletions(-) diff --git a/lightningd/pay.c b/lightningd/pay.c index 307ac60c6..00f8de2d7 100644 --- a/lightningd/pay.c +++ b/lightningd/pay.c @@ -1138,39 +1138,27 @@ send_payment_core(struct lightningd *ld, } /* If hout fails, payment should be freed too. */ - payment = tal(hout, struct wallet_payment); - payment->id = 0; - payment->payment_hash = *rhash; - payment->partid = partid; - payment->groupid = group; - payment->destination = tal_dup_or_null(payment, struct node_id, - destination); - payment->status = PAYMENT_PENDING; - payment->msatoshi = msat; - payment->msatoshi_sent = first_hop->amount; - payment->total_msat = total_msat; - payment->timestamp = time_now().ts.tv_sec; - payment->payment_preimage = NULL; - payment->path_secrets = tal_steal(payment, path_secrets); - payment->route_nodes = tal_steal(payment, route_nodes); - payment->route_channels = tal_steal(payment, route_channels); - payment->failonion = NULL; - payment->completed_at = NULL; - - if (label != NULL) - payment->label = tal_strdup(payment, label); - else - payment->label = NULL; - if (invstring != NULL) - payment->invstring = tal_strdup(payment, invstring); - else - payment->invstring = NULL; - if (description != NULL) - payment->description = tal_strdup(payment, description); - else - payment->description = NULL; - payment->local_invreq_id = tal_dup_or_null(payment, struct sha256, - local_invreq_id); + payment = wallet_payment_new(hout, + 0, /* ID is not in db yet */ + time_now().ts.tv_sec, + NULL, + rhash, + partid, + group, + PAYMENT_PENDING, + destination, + msat, + first_hop->amount, + total_msat, + NULL, + take(path_secrets), + take(route_nodes), + take(route_channels), + invstring, + label, + description, + NULL, + local_invreq_id); /* We write this into db when HTLC is actually sent. */ wallet_payment_setup(ld->wallet, payment); diff --git a/wallet/wallet.c b/wallet/wallet.c index cdc267e35..5bc92fe10 100644 --- a/wallet/wallet.c +++ b/wallet/wallet.c @@ -3299,87 +3299,99 @@ void wallet_payment_delete(struct wallet *wallet, db_exec_prepared_v2(take(stmt)); } +struct wallet_payment *wallet_payment_new(const tal_t *ctx, + u64 dbid, + u32 timestamp, + const u32 *completed_at, + const struct sha256 *payment_hash, + u64 partid, + u64 groupid, + enum payment_status status, + /* The destination may not be known if we used `sendonion` */ + const struct node_id *destination, + struct amount_msat msatoshi, + struct amount_msat msatoshi_sent, + struct amount_msat total_msat, + /* If and only if PAYMENT_COMPLETE */ + const struct preimage *payment_preimage, + const struct secret *path_secrets, + const struct node_id *route_nodes, + const struct short_channel_id *route_channels, + const char *invstring, + const char *label, + const char *description, + const u8 *failonion, + const struct sha256 *local_invreq_id) +{ + struct wallet_payment *payment = tal(ctx, struct wallet_payment); + + payment->id = dbid; + payment->status = status; + payment->timestamp = timestamp; + payment->payment_hash = *payment_hash; + payment->partid = partid; + payment->groupid = groupid; + payment->status = status; + payment->msatoshi = msatoshi; + payment->msatoshi_sent = msatoshi_sent; + payment->total_msat = total_msat; + + /* Optional fields */ + payment->completed_at = tal_dup_or_null(payment, u32, completed_at); + payment->destination = tal_dup_or_null(payment, struct node_id, destination); + payment->payment_preimage = tal_dup_or_null(payment, struct preimage, payment_preimage); + payment->path_secrets = tal_dup_talarr(payment, struct secret, path_secrets); + payment->route_nodes = tal_dup_talarr(payment, struct node_id, route_nodes); + payment->route_channels = tal_dup_talarr(payment, struct short_channel_id, route_channels); + payment->invstring = tal_strdup_or_null(payment, invstring); + payment->label = tal_strdup_or_null(payment, label); + payment->description = tal_strdup_or_null(payment, description); + payment->failonion = tal_dup_talarr(payment, u8, failonion); + payment->local_invreq_id = tal_dup_or_null(payment, struct sha256, local_invreq_id); + + return payment; +} + static struct wallet_payment *wallet_stmt2payment(const tal_t *ctx, struct db_stmt *stmt) { - struct wallet_payment *payment = tal(ctx, struct wallet_payment); - payment->id = db_col_u64(stmt, "id"); - payment->status = db_col_int(stmt, "status"); - payment->destination = db_col_optional(payment, stmt, "destination", - node_id); - payment->msatoshi = db_col_amount_msat(stmt, "msatoshi"); - db_col_sha256(stmt, "payment_hash", &payment->payment_hash); + struct wallet_payment *payment; + u32 *completed_at; + struct sha256 payment_hash; - payment->timestamp = db_col_int(stmt, "timestamp"); - payment->payment_preimage = db_col_optional(payment, stmt, - "payment_preimage", - preimage); + db_col_sha256(stmt, "payment_hash", &payment_hash); - /* We either used `sendpay` or `sendonion` with the `shared_secrets` - * argument. */ - if (!db_col_is_null(stmt, "path_secrets")) - payment->path_secrets - = db_col_secret_arr(payment, stmt, "path_secrets"); - else - payment->path_secrets = NULL; + if (!db_col_is_null(stmt, "completed_at")) { + completed_at = tal(tmpctx, u32); + *completed_at = db_col_int(stmt, "completed_at"); + } else + completed_at = NULL; + + payment = wallet_payment_new(ctx, + db_col_u64(stmt, "id"), + db_col_int(stmt, "timestamp"), + completed_at, + &payment_hash, + db_col_is_null(stmt, "partid") ? 0 : db_col_u64(stmt, "partid"), + db_col_u64(stmt, "groupid"), + payment_status_in_db(db_col_int(stmt, "status")), + take(db_col_optional(NULL, stmt, "destination", node_id)), + db_col_amount_msat(stmt, "msatoshi"), + db_col_amount_msat(stmt, "msatoshi_sent"), + db_col_amount_msat(stmt, "total_msat"), + take(db_col_optional(NULL, stmt, "payment_preimage", preimage)), + take(db_col_secret_arr(NULL, stmt, "path_secrets")), + take(db_col_node_id_arr(NULL, stmt, "route_nodes")), + take(db_col_short_channel_id_arr(NULL, stmt, "route_channels")), + take(db_col_strdup_optional(NULL, stmt, "bolt11")), + take(db_col_strdup_optional(NULL, stmt, "description")), + take(db_col_strdup_optional(NULL, stmt, "paydescription")), + take(db_col_arr(NULL, stmt, "failonionreply", u8)), + take(db_col_optional(NULL, stmt, "local_invreq_id", sha256))); /* Either none, or both are set */ assert(db_col_is_null(stmt, "route_nodes") == db_col_is_null(stmt, "route_channels")); - if (!db_col_is_null(stmt, "route_nodes")) { - payment->route_nodes - = db_col_node_id_arr(payment, stmt, "route_nodes"); - payment->route_channels = - db_col_short_channel_id_arr(payment, stmt, "route_channels"); - } else { - payment->route_nodes = NULL; - payment->route_channels = NULL; - } - - payment->msatoshi_sent = db_col_amount_msat(stmt, "msatoshi_sent"); - - if (!db_col_is_null(stmt, "description")) - payment->label = db_col_strdup(payment, stmt, "description"); - else - payment->label = NULL; - - if (!db_col_is_null(stmt, "paydescription")) - payment->description = db_col_strdup(payment, stmt, "paydescription"); - else - payment->description = NULL; - - if (!db_col_is_null(stmt, "bolt11")) - payment->invstring = db_col_strdup(payment, stmt, "bolt11"); - else - payment->invstring = NULL; - - if (!db_col_is_null(stmt, "failonionreply")) - payment->failonion - = db_col_arr(payment, stmt, "failonionreply", u8); - else - payment->failonion = NULL; - - if (!db_col_is_null(stmt, "total_msat")) - payment->total_msat = db_col_amount_msat(stmt, "total_msat"); - else - payment->total_msat = AMOUNT_MSAT(0); - - if (!db_col_is_null(stmt, "partid")) - payment->partid = db_col_u64(stmt, "partid"); - else - payment->partid = 0; - - 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); - *payment->completed_at = db_col_int(stmt, "completed_at"); - } else - payment->completed_at = NULL; - - payment->groupid = db_col_u64(stmt, "groupid"); - return payment; } diff --git a/wallet/wallet.h b/wallet/wallet.h index 28c8fdee2..6aa90a761 100644 --- a/wallet/wallet.h +++ b/wallet/wallet.h @@ -374,6 +374,30 @@ struct wallet_payment { struct sha256 *local_invreq_id; }; +struct wallet_payment *wallet_payment_new(const tal_t *ctx, + u64 dbid, + u32 timestamp, + const u32 *completed_at, + const struct sha256 *payment_hash, + u64 partid, + u64 groupid, + enum payment_status status, + /* The destination may not be known if we used `sendonion` */ + const struct node_id *destination TAKES, + struct amount_msat msatoshi, + struct amount_msat msatoshi_sent, + struct amount_msat total_msat, + /* If and only if PAYMENT_COMPLETE */ + const struct preimage *payment_preimage TAKES, + const struct secret *path_secrets TAKES, + const struct node_id *route_nodes TAKES, + const struct short_channel_id *route_channels TAKES, + const char *invstring TAKES, + const char *label TAKES, + const char *description TAKES, + const u8 *failonion TAKES, + const struct sha256 *local_invreq_id); + struct outpoint { struct bitcoin_outpoint outpoint; u32 blockheight;