Skip to content
Open
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
34 commits
Select commit Hold shift + click to select a range
d4e5a30
bookkeeper: fix printing of bad JSON results.
rustyrussell Nov 10, 2025
8b7f351
plugins/sql: remove size limit.
rustyrussell Nov 10, 2025
0c7c415
plugins/sql: print times taken to do list comand, populate table, and…
rustyrussell Nov 10, 2025
76687dd
bookkeeper: no longer read listchannelmoves 1000 entries at a time.
rustyrussell Nov 10, 2025
0cd1624
Revert "bookkeeper: don't flood logs if we have many channelmoves all…
rustyrussell Nov 10, 2025
76f5ae8
pytest: latency and speed test on large coinmoves.
rustyrussell Nov 10, 2025
52b479a
lightningd: don't copy hooks array into hook request, simply don't sh…
rustyrussell Nov 10, 2025
19a05e7
lightningd: don't loop through all commands every time one finishes.
rustyrussell Nov 10, 2025
10d2745
common: remove tracing exponential behaviour from large numbers of re…
rustyrussell Nov 10, 2025
fca97f7
common: avoid allocations for small numbers of traces.
rustyrussell Nov 10, 2025
3f13e71
pytest: increase test_generate_coinmoves to 2M entries.
rustyrussell Nov 10, 2025
b76ad39
lightningd: handle large numbers of command outputs gracefully.
rustyrussell Nov 10, 2025
15ea6c1
JSONRPC: use a bigger default buffer.
rustyrussell Nov 10, 2025
f9cadf5
lightningd: support "filters" in plugins manifest to restrict when ho…
rustyrussell Nov 10, 2025
f80602b
lightningd: add support for filters on "rpc_command" hook.
rustyrussell Nov 10, 2025
9cfe0d0
libplugin: allow plugins to register optional filters for each hook t…
rustyrussell Nov 10, 2025
4c90473
xpay: use filtering on rpc_command so we only get called on "pay".
rustyrussell Nov 10, 2025
c0a5f62
pyln-client: support hook filters.
rustyrussell Nov 10, 2025
ed4349b
lightningd: allow filtering on custommsg hook too.
rustyrussell Nov 10, 2025
c5044ef
commando, chanbackup: use custommsg hooks.
rustyrussell Nov 10, 2025
800ff96
common: increase jsonrpc_io buffer size temporarily to aggrevate perf…
rustyrussell Nov 10, 2025
2d01a34
common: optimize json parsing.
rustyrussell Nov 10, 2025
817367c
ccan: update to get io_loop fairness.
rustyrussell Nov 10, 2025
13f93e6
lightningd: don't process more than 100 commands from a JSONRPC at once.
rustyrussell Nov 10, 2025
fd989ae
lightningd: don't process more than 100 commands from a plugin at once.
rustyrussell Nov 10, 2025
0dc876c
plugins/sql: use modern data style, not globals.
rustyrussell Nov 10, 2025
cfb27fb
sql: if we use `dev-sqlfilename`, don't bother syncing it to disk.
rustyrussell Nov 10, 2025
54cab8e
sql: use wait RPC so we don't have to check listchannelmoves/listchai…
rustyrussell Nov 10, 2025
46c551e
lightningd: optimize find_cmd.
rustyrussell Nov 10, 2025
bee028f
bookkeeper: restore limit on asking for all channelmoves at once.
rustyrussell Nov 10, 2025
db1f508
sql: limit how many chainmoves/channelmoves entries we ask for at once.
rustyrussell Nov 10, 2025
025e7d9
pytest: increase test_generate_coinmoves to 5M entries.
rustyrussell Nov 10, 2025
41f254d
pytest: test for 1M JSONRPC calls which don't need transactions.
rustyrussell Nov 10, 2025
aec622c
db: don't start transactions unless we really need to.
rustyrussell Nov 10, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions db/common.h
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,8 @@
struct db {
char *filename;
const char *in_transaction;
/* For lazy transaction activation */
bool transaction_started;

/* DB-specific context */
void *conn;
Expand Down
4 changes: 4 additions & 0 deletions db/db_sqlite3.c
Original file line number Diff line number Diff line change
Expand Up @@ -474,12 +474,14 @@ static char **prepare_table_manip(const tal_t *ctx,

/* But core insists we're "in a transaction" for all ops, so fake it */
db->in_transaction = "Not really";
db->transaction_started = true;
/* Turn off foreign keys first. */
db_prepare_for_changes(db);
db_exec_prepared_v2(take(db_prepare_untranslated(db,
"PRAGMA foreign_keys = OFF;")));
db_report_changes(db, NULL, 0);
db->in_transaction = NULL;
db->transaction_started = false;

db_begin_transaction(db);
cmd = tal_fmt(tmpctx, "ALTER TABLE %s RENAME TO temp_%s;",
Expand Down Expand Up @@ -525,11 +527,13 @@ static bool complete_table_manip(struct db *db,

/* Allow links between them (esp. cascade deletes!) */
db->in_transaction = "Not really";
db->transaction_started = true;
db_prepare_for_changes(db);
db_exec_prepared_v2(take(db_prepare_untranslated(db,
"PRAGMA foreign_keys = ON;")));
db_report_changes(db, NULL, 0);
db->in_transaction = NULL;
db->transaction_started = false;

/* migrations are performed inside transactions, so start one. */
db_begin_transaction(db);
Expand Down
24 changes: 21 additions & 3 deletions db/exec.c
Original file line number Diff line number Diff line change
Expand Up @@ -121,19 +121,29 @@ static void db_data_version_incr(struct db *db)

void db_begin_transaction_(struct db *db, const char *location)
{
bool ok;
if (db->in_transaction)
db_fatal(db, "Already in transaction from %s", db->in_transaction);

db->in_transaction = location;
/* No writes yet. */
db->dirty = false;
}

void db_need_transaction(struct db *db, const char *location)
{
bool ok;

if (!db->in_transaction)
db_fatal(db, "Not in a transaction for %s", location);

if (db->transaction_started)
return;

db_prepare_for_changes(db);
ok = db->config->begin_tx_fn(db);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Technically we could save 1/2 RTT by pipelining the transaction start with the first command, i.e., we fire and forget the BEGIN command, and immediately queue the actual query that caused us to init a tx behind it. That saves us the return-path from server for BEGIN. At that point we're splitting hairs though ^^

Copy link
Contributor Author

@rustyrussell rustyrussell Nov 14, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

😲

Wow! We could just prepend "BEGIN;" to the query string. That is... remarkably fugly.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nope, that would not work, since in prepared statements mode there is no slicing statements apart on the server side. It has to be two separate network packets.

if (!ok)
db_fatal(db, "Failed to start DB transaction: %s", db->error);

db->in_transaction = location;
db->transaction_started = true;
}

bool db_in_transaction(struct db *db)
Expand All @@ -150,6 +160,13 @@ void db_commit_transaction(struct db *db)
{
bool ok;
assert(db->in_transaction);

if (!db->transaction_started) {
db->in_transaction = NULL;
assert(!db->dirty);
return;
}

db_assert_no_outstanding_statements(db);

/* Increment before reporting changes to an eventual plugin. */
Expand All @@ -164,4 +181,5 @@ void db_commit_transaction(struct db *db)

db->in_transaction = NULL;
db->dirty = false;
db->transaction_started = false;
}
5 changes: 5 additions & 0 deletions db/exec.h
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,11 @@ void db_begin_transaction_(struct db *db, const char *location);

bool db_in_transaction(struct db *db);

/**
* db_need_transaction: we now need to actually enable the transaction, if not
* already. */
void db_need_transaction(struct db *db, const char *location);

/**
* db_commit_transaction - Commit a running transaction
*
Expand Down
8 changes: 7 additions & 1 deletion db/utils.c
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
#include <ccan/tal/str/str.h>
#include <common/trace.h>
#include <db/common.h>
#include <db/exec.h>
#include <db/utils.h>

/* Matches the hash function used in devtools/sql-rewrite.py */
Expand Down Expand Up @@ -143,6 +144,7 @@ bool db_query_prepared_canfail(struct db_stmt *stmt)
assert(stmt->query->readonly);
trace_span_start("db_query_prepared", stmt);
trace_span_tag(stmt, "query", stmt->query->query);
db_need_transaction(stmt->db, stmt->query->query);
ret = stmt->db->config->query_fn(stmt);
stmt->executed = true;
list_del_from(&stmt->db->pending_statements, &stmt->list);
Expand Down Expand Up @@ -174,9 +176,12 @@ bool db_step(struct db_stmt *stmt)

void db_exec_prepared_v2(struct db_stmt *stmt TAKES)
{
bool ret;

db_need_transaction(stmt->db, stmt->query->query);
trace_span_start("db_exec_prepared", stmt);
trace_span_tag(stmt, "query", stmt->query->query);
bool ret = stmt->db->config->exec_fn(stmt);
ret = stmt->db->config->exec_fn(stmt);
trace_span_end(stmt);

if (stmt->db->readonly)
Expand Down Expand Up @@ -358,6 +363,7 @@ struct db *db_open_(const tal_t *ctx, const char *filename,
db_fatal(db, "Unable to find DB queries for %s", db->config->name);

db->in_transaction = NULL;
db->transaction_started = false;
db->changes = NULL;

/* This must be outside a transaction, so catch it */
Expand Down
Loading