diff --git a/wallet/db.c b/wallet/db.c index 7184ad7ff..cd3e9671c 100644 --- a/wallet/db.c +++ b/wallet/db.c @@ -750,6 +750,88 @@ static struct migration dbmigrations[] = { NULL}, {SQL("CREATE INDEX channel_state_changes_channel_id" " ON channel_state_changes (channel_id);"), NULL}, + /* We need to switch the unique key to cover the groupid as well, + * so we can attempt payments multiple times. */ + {SQL("ALTER TABLE payments RENAME TO temp_payments;"), NULL}, + {SQL("CREATE TABLE payments (" + " id BIGSERIAL" + ", timestamp INTEGER" + ", status INTEGER" + ", payment_hash BLOB" + ", destination BLOB" + ", msatoshi BIGINT" + ", payment_preimage BLOB" + ", path_secrets BLOB" + ", route_nodes BLOB" + ", route_channels BLOB" + ", failonionreply BLOB" + ", faildestperm INTEGER" + ", failindex INTEGER" + ", failcode INTEGER" + ", failnode BLOB" + ", failchannel TEXT" + ", failupdate BLOB" + ", msatoshi_sent BIGINT" + ", faildetail TEXT" + ", description TEXT" + ", faildirection INTEGER" + ", bolt11 TEXT" + ", total_msat BIGINT" + ", partid BIGINT" + ", groupid BIGINT NOT NULL DEFAULT 0" + ", local_offer_id BLOB DEFAULT NULL REFERENCES offers(offer_id)" + ", PRIMARY KEY (id)" + ", UNIQUE (payment_hash, partid, groupid))"), NULL}, + {SQL("INSERT INTO payments (" + "id" + ", timestamp" + ", status" + ", payment_hash" + ", destination" + ", msatoshi" + ", payment_preimage" + ", path_secrets" + ", route_nodes" + ", route_channels" + ", failonionreply" + ", faildestperm" + ", failindex" + ", failcode" + ", failnode" + ", failchannel" + ", failupdate" + ", msatoshi_sent" + ", faildetail" + ", description" + ", faildirection" + ", bolt11" + ", groupid" + ", local_offer_id)" + "SELECT id" + ", timestamp" + ", status" + ", payment_hash" + ", destination" + ", msatoshi" + ", payment_preimage" + ", path_secrets" + ", route_nodes" + ", route_channels" + ", failonionreply" + ", faildestperm" + ", failindex" + ", failcode" + ", failnode" + ", failchannel" + ", failupdate" + ", msatoshi_sent" + ", faildetail" + ", description" + ", faildirection" + ", bolt11" + ", 0" + ", local_offer_id FROM temp_payments;"), NULL}, + {SQL("DROP TABLE temp_payments;"), NULL}, }; /* Leak tracking. */ diff --git a/wallet/wallet.c b/wallet/wallet.c index 631ad4573..20aaa9986 100644 --- a/wallet/wallet.c +++ b/wallet/wallet.c @@ -2931,8 +2931,9 @@ void wallet_payment_store(struct wallet *wallet, " bolt11," " total_msat," " partid," - " local_offer_id" - ") VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?);")); + " local_offer_id," + " groupid" + ") VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?);")); db_bind_int(stmt, 0, payment->status); db_bind_sha256(stmt, 1, &payment->payment_hash); @@ -2979,6 +2980,8 @@ void wallet_payment_store(struct wallet *wallet, else db_bind_null(stmt, 13); + db_bind_u64(stmt, 14, payment->groupid); + db_exec_prepared_v2(stmt); payment->id = db_last_insert_id_v2(stmt); assert(payment->id > 0); @@ -3105,6 +3108,11 @@ static struct wallet_payment *wallet_stmt2payment(const tal_t *ctx, } else payment->local_offer_id = NULL; + if (!db_column_is_null(stmt, 17)) + payment->groupid = db_column_u64(stmt, 17); + else + payment->groupid = 0; + return payment; } @@ -3139,6 +3147,7 @@ wallet_payment_by_hash(const tal_t *ctx, struct wallet *wallet, ", total_msat" ", partid" ", local_offer_id" + ", groupid" " FROM payments" " WHERE payment_hash = ?" " AND partid = ?")); @@ -3370,6 +3379,7 @@ wallet_payment_list(const tal_t *ctx, ", total_msat" ", partid" ", local_offer_id" + ", groupid" " FROM payments" " WHERE" " (payment_hash = ? OR 1=?) AND" @@ -3435,6 +3445,7 @@ wallet_payments_by_offer(const tal_t *ctx, ", total_msat" ", partid" ", local_offer_id" + ", groupid" " FROM payments" " WHERE local_offer_id = ?;")); db_bind_sha256(stmt, 0, local_offer_id); diff --git a/wallet/wallet.h b/wallet/wallet.h index 4814b2022..21bd5dd00 100644 --- a/wallet/wallet.h +++ b/wallet/wallet.h @@ -222,9 +222,10 @@ struct wallet_payment { u64 id; u32 timestamp; - /* The combination of these two fields is unique: */ + /* The combination of these three fields is unique: */ struct sha256 payment_hash; u64 partid; + u64 groupid; enum wallet_payment_status status;