diff --git a/tests/test_misc.py b/tests/test_misc.py index b77e9cbc0..e5251e15e 100644 --- a/tests/test_misc.py +++ b/tests/test_misc.py @@ -2413,12 +2413,7 @@ def test_listforwards(node_factory, bitcoind): l1.rpc.waitsendpay(failed_inv['payment_hash']) all_forwards = l2.rpc.listforwards()['forwards'] - print(json.dumps(all_forwards, indent=True)) - assert len(all_forwards) == 3 - assert i31['payment_hash'] in map(lambda x: x['payment_hash'], all_forwards) - assert i41['payment_hash'] in map(lambda x: x['payment_hash'], all_forwards) - assert failed_inv['payment_hash'] in map(lambda x: x['payment_hash'], all_forwards) # status=settled settled_forwards = l2.rpc.listforwards(status='settled')['forwards'] diff --git a/tests/test_pay.py b/tests/test_pay.py index ea54a9eb5..382957eb5 100644 --- a/tests/test_pay.py +++ b/tests/test_pay.py @@ -1389,7 +1389,7 @@ def test_forward_stats(node_factory, bitcoind): # Select all forwardings, ordered by htlc_id to ensure the order # matches below forwardings = l2.db_query("SELECT *, in_msatoshi - out_msatoshi as fee " - "FROM forwarded_payments " + "FROM forwards " "ORDER BY in_htlc_id;") assert(len(forwardings) == 3) states = [f['state'] for f in forwardings] diff --git a/tests/test_plugin.py b/tests/test_plugin.py index 3c5dc0504..d16f80b26 100644 --- a/tests/test_plugin.py +++ b/tests/test_plugin.py @@ -1345,6 +1345,10 @@ def test_forward_event_notification(node_factory, bitcoind, executor): plugin_stats = l2.rpc.call('listforwards_plugin')['forwards'] assert len(plugin_stats) == 6 + # We don't have payment_hash in listforwards any more. + for p in plugin_stats: + del p['payment_hash'] + # use stats to build what we expect went to plugin. expect = stats[0].copy() # First event won't have conclusion. diff --git a/wallet/db.c b/wallet/db.c index 51a507543..ee9e94025 100644 --- a/wallet/db.c +++ b/wallet/db.c @@ -887,6 +887,39 @@ static struct migration dbmigrations[] = { {SQL("ALTER TABLE payments ADD completed_at INTEGER DEFAULT NULL;"), NULL}, {SQL("UPDATE payments SET completed_at = timestamp WHERE status != 0;"), NULL}, {SQL("CREATE INDEX payments_idx ON payments (payment_hash)"), NULL}, + /* forwards table outlives the channels, so we move there from old forwarded_payments table; + * but here the ids are the HTLC numbers, not the internal db ids. */ + {SQL("CREATE TABLE forwards (" + "in_channel_scid BIGINT" + ", in_htlc_id BIGINT" + ", out_channel_scid BIGINT" + ", out_htlc_id BIGINT" + ", in_msatoshi BIGINT" + ", out_msatoshi BIGINT" + ", state INTEGER" + ", received_time BIGINT" + ", resolved_time BIGINT" + ", failcode INTEGER" + ", forward_style INTEGER" + ", PRIMARY KEY(in_channel_scid, in_htlc_id))"), NULL}, + {SQL("INSERT INTO forwards SELECT" + " in_channel_scid" + ", (SELECT channel_htlc_id FROM channel_htlcs WHERE id = forwarded_payments.in_htlc_id)" + ", out_channel_scid" + ", (SELECT channel_htlc_id FROM channel_htlcs WHERE id = forwarded_payments.out_htlc_id)" + ", in_msatoshi" + ", out_msatoshi" + ", state" + ", received_time" + ", resolved_time" + ", failcode" + ", forward_style" + " FROM forwarded_payments" + " WHERE" + " in_htlc_id IS NOT NULL"), NULL}, + {SQL("DROP INDEX forwarded_payments_state;"), NULL}, + {SQL("DROP INDEX forwarded_payments_out_htlc_id;"), NULL}, + {SQL("DROP TABLE forwarded_payments;"), NULL}, }; /* Released versions are of form v{num}[.{num}]* */ diff --git a/wallet/wallet.c b/wallet/wallet.c index 93ffb9638..4e88bc5fe 100644 --- a/wallet/wallet.c +++ b/wallet/wallet.c @@ -4356,14 +4356,14 @@ static bool wallet_forwarded_payment_update(struct wallet *w, * having to have two versions of the update statement (one with and * one without the htlc_out restriction).*/ stmt = db_prepare_v2(w->db, - SQL("UPDATE forwarded_payments SET" + SQL("UPDATE forwards SET" " in_msatoshi=?" ", out_msatoshi=?" ", state=?" ", resolved_time=?" ", failcode=?" ", forward_style=?" - " WHERE in_htlc_id=?")); + " WHERE in_htlc_id=? AND in_channel_scid=?")); db_bind_amount_msat(stmt, 0, &in->msat); if (out) { @@ -4392,7 +4392,9 @@ static bool wallet_forwarded_payment_update(struct wallet *w, db_bind_null(stmt, 5); else db_bind_int(stmt, 5, forward_style_in_db(forward_style)); - db_bind_u64(stmt, 6, in->dbid); + db_bind_u64(stmt, 6, in->key.id); + db_bind_u64(stmt, 7, + channel_scid_or_local_alias(in->key.channel)->u64); db_exec_prepared_v2(stmt); changed = db_count_changes(stmt) != 0; tal_free(stmt); @@ -4421,7 +4423,7 @@ void wallet_forwarded_payment_add(struct wallet *w, const struct htlc_in *in, goto notify; stmt = db_prepare_v2(w->db, - SQL("INSERT INTO forwarded_payments (" + SQL("INSERT INTO forwards (" " in_htlc_id" ", out_htlc_id" ", in_channel_scid" @@ -4434,7 +4436,7 @@ void wallet_forwarded_payment_add(struct wallet *w, const struct htlc_in *in, ", failcode" ", forward_style" ") VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?);")); - db_bind_u64(stmt, 0, in->dbid); + db_bind_u64(stmt, 0, in->key.id); /* FORWARD_LOCAL_FAILED may occur before we get htlc_out */ if (!out || !scid_out) { @@ -4443,7 +4445,7 @@ void wallet_forwarded_payment_add(struct wallet *w, const struct htlc_in *in, } if (out) - db_bind_u64(stmt, 1, out->dbid); + db_bind_u64(stmt, 1, out->key.id); else db_bind_null(stmt, 1); @@ -4499,7 +4501,7 @@ struct amount_msat wallet_total_forward_fees(struct wallet *w) stmt = db_prepare_v2(w->db, SQL("SELECT" " CAST(COALESCE(SUM(in_msatoshi - out_msatoshi), 0) AS BIGINT)" - " FROM forwarded_payments " + " FROM forwards " "WHERE state = ?;")); db_bind_int(stmt, 0, wallet_forward_status_in_db(FORWARD_SETTLED)); db_query_prepared(stmt); @@ -4549,21 +4551,19 @@ const struct forwarding *wallet_forwarded_payments_get(struct wallet *w, stmt = db_prepare_v2( w->db, SQL("SELECT" - " f.state" + " state" ", in_msatoshi" ", out_msatoshi" - ", hin.payment_hash as payment_hash" ", in_channel_scid" ", out_channel_scid" - ", f.received_time" - ", f.resolved_time" - ", f.failcode " - ", f.forward_style " - "FROM forwarded_payments f " - "LEFT JOIN channel_htlcs hin ON (f.in_htlc_id = hin.id) " - "WHERE (1 = ? OR f.state = ?) AND " - "(1 = ? OR f.in_channel_scid = ?) AND " - "(1 = ? OR f.out_channel_scid = ?)")); + ", received_time" + ", resolved_time" + ", failcode " + ", forward_style " + "FROM forwards " + "WHERE (1 = ? OR state = ?) AND " + "(1 = ? OR in_channel_scid = ?) AND " + "(1 = ? OR out_channel_scid = ?)")); if (status == FORWARD_ANY) { // any status @@ -4600,7 +4600,7 @@ const struct forwarding *wallet_forwarded_payments_get(struct wallet *w, for (count=0; db_step(stmt); count++) { tal_resize(&results, count+1); struct forwarding *cur = &results[count]; - cur->status = db_col_int(stmt, "f.state"); + cur->status = db_col_int(stmt, "state"); db_col_amount_msat(stmt, "in_msatoshi", &cur->msat_in); if (!db_col_is_null(stmt, "out_msatoshi")) { @@ -4622,13 +4622,8 @@ const struct forwarding *wallet_forwarded_payments_get(struct wallet *w, cur->fee = AMOUNT_MSAT(0); } - if (!db_col_is_null(stmt, "payment_hash")) { - cur->payment_hash = tal(ctx, struct sha256); - db_col_sha256(stmt, "payment_hash", cur->payment_hash); - } else { - cur->payment_hash = NULL; - } - + /* FIXME: This now requires complex join to determine! */ + cur->payment_hash = NULL; cur->channel_in.u64 = db_col_u64(stmt, "in_channel_scid"); if (!db_col_is_null(stmt, "out_channel_scid")) { @@ -4639,28 +4634,28 @@ const struct forwarding *wallet_forwarded_payments_get(struct wallet *w, cur->channel_out.u64 = 0; } - cur->received_time = db_col_timeabs(stmt, "f.received_time"); + cur->received_time = db_col_timeabs(stmt, "received_time"); - if (!db_col_is_null(stmt, "f.resolved_time")) { + if (!db_col_is_null(stmt, "resolved_time")) { cur->resolved_time = tal(ctx, struct timeabs); *cur->resolved_time - = db_col_timeabs(stmt, "f.resolved_time"); + = db_col_timeabs(stmt, "resolved_time"); } else { cur->resolved_time = NULL; } - if (!db_col_is_null(stmt, "f.failcode")) { + if (!db_col_is_null(stmt, "failcode")) { assert(cur->status == FORWARD_FAILED || cur->status == FORWARD_LOCAL_FAILED); - cur->failcode = db_col_int(stmt, "f.failcode"); + cur->failcode = db_col_int(stmt, "failcode"); } else { cur->failcode = 0; } - if (db_col_is_null(stmt, "f.forward_style")) { + if (db_col_is_null(stmt, "forward_style")) { cur->forward_style = FORWARD_STYLE_UNKNOWN; } else { cur->forward_style - = forward_style_in_db(db_col_int(stmt, "f.forward_style")); + = forward_style_in_db(db_col_int(stmt, "forward_style")); } } tal_free(stmt);