lightningd: db migration to clean up any pending payments where theres no htlc.
Changelog-Fixed: JSON-RPC: `listpays`/`listsendpays` erroneously left `pending` in xpay are cleaned up. Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
This commit is contained in:
@@ -2469,7 +2469,6 @@ def test_old_htlcs_cleanup(node_factory, bitcoind):
|
||||
assert l1.rpc.listhtlcs() == {'htlcs': []}
|
||||
|
||||
|
||||
@pytest.mark.xfail(strict=True)
|
||||
@unittest.skipIf(os.getenv('TEST_DB_PROVIDER', 'sqlite3') != 'sqlite3', "Makes use of the sqlite3 db")
|
||||
@unittest.skipIf(TEST_NETWORK != 'regtest', "sqlite3 snapshot is regtest")
|
||||
def test_pending_payments_cleanup(node_factory, bitcoind):
|
||||
|
||||
25
wallet/db.c
25
wallet/db.c
@@ -84,6 +84,8 @@ static void migrate_convert_old_channel_keyidx(struct lightningd *ld,
|
||||
struct db *db);
|
||||
static void migrate_initialize_channel_htlcs_wait_indexes_and_fixup_forwards(struct lightningd *ld,
|
||||
struct db *db);
|
||||
static void migrate_fail_pending_payments_without_htlcs(struct lightningd *ld,
|
||||
struct db *db);
|
||||
|
||||
/* Do not reorder or remove elements from this array, it is used to
|
||||
* migrate existing databases from a previous state, based on the
|
||||
@@ -1098,6 +1100,7 @@ static struct migration dbmigrations[] = {
|
||||
" connect_attempted INTEGER NOT NULL,"
|
||||
" PRIMARY KEY (id)"
|
||||
")"), NULL},
|
||||
{NULL, migrate_fail_pending_payments_without_htlcs},
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -2127,3 +2130,25 @@ static void migrate_convert_old_channel_keyidx(struct lightningd *ld,
|
||||
db_bind_int(stmt, channel_state_in_db(CLOSED));
|
||||
db_exec_prepared_v2(take(stmt));
|
||||
}
|
||||
|
||||
static void migrate_fail_pending_payments_without_htlcs(struct lightningd *ld,
|
||||
struct db *db)
|
||||
{
|
||||
/* If channeld died or was offline at the right moment, we
|
||||
* could register a payment as pending, but then not create an
|
||||
* HTLC. Clean those up. */
|
||||
struct db_stmt *stmt;
|
||||
|
||||
stmt = db_prepare_v2(db, SQL("UPDATE payments AS p"
|
||||
" SET status = ?"
|
||||
" WHERE p.status = ?"
|
||||
" AND NOT EXISTS ("
|
||||
" SELECT 1"
|
||||
" FROM channel_htlcs AS h"
|
||||
" WHERE h.payment_hash = p.payment_hash"
|
||||
" AND h.groupid = p.groupid"
|
||||
" AND h.partid = p.partid);"));
|
||||
db_bind_int(stmt, payment_status_in_db(PAYMENT_FAILED));
|
||||
db_bind_int(stmt, payment_status_in_db(PAYMENT_PENDING));
|
||||
db_exec_prepared_v2(take(stmt));
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user