LIGHTNING-HOOK-DB_WRITE(7)

πŸ“¦
version 26.06.9 Β· 2 versions
, in nixpkgs unstable

πŸ’… LIGHTNING-HOOK-DB_WRITE β€” db_write, aka the hook that fires right before database writes get committed πŸŽ€

okay bestie, so the manual page is called LIGHTNING-HOOK-DB_WRITE (section 7, iykyk) and the star of the show is db_write. Let's get into it ✨


🌸 NAME 🌸

db_write β€” the hook that fires before database writes are committed. it's giving "last chance to peek before it's permanent" πŸ’–


πŸ¦‹ DESCRIPTION πŸ¦‹

So the db_write hook gets called whenever a change is about to be committed to the database β€” but only if you're using a SQLITE3 database (which, fun fact, is the default). If you're running a PostgreSQL database, this hook is lowkey useless: the "writes" field will always be empty. no cap. πŸ™ˆ


πŸ’€ the restriction era (read this fr)

This hook is extremely restricted, like, more than your parents' screen time rules:

  1. A plugin registering for this hook should not perform anything that may cause a database operation in response β€” pretty much anything but logging, bestie. logging only. that's it.
  2. A plugin registering for this hook should not register for other hooks or commands, because these may become intermingled and break rule #1. and we do NOT break rule #1. πŸ’…
  3. The hook will be called before your plugin is initialized! yes, before. not a drill. 😭
Also this hook is strongly synchronous: lightningd will halt almost all processing until all plugins have responded. main character energy, honestly β€” everything waits on you πŸ‘‘

πŸŽ€ what it's actually for

This hook is intended for creating continuous backups. The intent is that your backup plugin maintains three pieces of information (possibly in separate files):

  1. A snapshot of the database πŸ“
  2. A log of database queries that will bring that snapshot up-to-date πŸ“
  3. The previous data_version ⭐

πŸ”₯ the fields, explained

data_version is an unsigned 32-bit number that will always increment by 1 each time db_write is called. Heads up though β€” it will wrap around at the 32-bit limit. the circle of life πŸŒ€

writes is an array of strings, where each string is a database query that modifies the database. If the data_version above is validated correctly, then you can simply append this to the log of database queries. easy peasy 🌸


πŸ‘‘ the validation rules (this is the whole assignment)

Your plugin MUST validate the data_version. It MUST keep track of the previous data_version it got, and:

  1. If the new data_version is exactly one higher than the previous β€” that's the ideal case, nothing bad happened, save this and continue. slay πŸ’–
  2. If the new data_version is exactly the same value as the previous β€” the previous set of queries was not committed. Your plugin MAY overwrite the previous set of queries with the current set, or it MAY overwrite its entire backup with a new snapshot of the database and the current writes array (treating this case as if data_version were two or more higher than the previous). dealer's choice ✨
  3. If the new data_version is less than the previous β€” your plugin MUST halt and catch fire, and have the operator inspect what exactly happened here. not me being dramatic, this is literally the instruction πŸ”₯πŸ’€
  4. Otherwise (so, it jumped by more than one), some queries were lost and your plugin SHOULD recover by creating a new snapshot of the database: copy the database file, back up the given writes array, then delete (or atomically rename if in a POSIX filesystem) the previous backups of the database and SQL statements β€” or you MAY fail the hook to abort lightningd. pick your fighter 🫢
Ngl, the "rolling up" of the database could be done periodically as well, if the log of SQL statements has grown large. spring cleaning but for SQL 🧹

😭 the response rules

Any response other than {"result": "continue"} will cause lightningd to error without committing to the database! And yes β€” this is the expected way to halt and catch fire. iconic behaviour, honestly πŸ’…

db_write is a parallel-chained hook, i.e., multiple plugins can register it, and all of them will be invoked simultaneously without regard for order of registration. The hook is considered handled if all registered plugins return {"result": "continue"}. If any plugin returns anything else, lightningd will error without committing to the database. one hater ruins the group chat 😀


🧚 HOOK PAYLOAD 🧚

  • data_version (u32) β€” A monotonically increasing 32-bit unsigned integer representing the database version. Wraps around at the 32-bit limit. πŸŒ€
  • writes (array of strings) β€” Array of SQL statements that modify the database. If using PostgreSQL, this array will always be empty. Each entry is a SQL query string.:
    • (string, optional)

🌈 HOOK RETURN 🌈

  • result (string) (always "continue") β€” Must be "continue" for the database commit to proceed. Any other value will abort the commit and cause lightningd to error. no exceptions, bestie πŸ’–

⚠️ reminder bestie: this hook runs before your plugin is initialized, it's strongly synchronous, and it's SQLITE3-only for the writes goods. don't do database stuff in it. don't get cute with other hooks. just log, validate your data_version, and slay responsibly πŸŽ€

okay that's the whole page, mwah πŸ’‹ this was brought to you by Core Lightning v26.06.9, page LIGHTNING-HOOK-DB_WRITE(7) β€” go forth and back up continuously, you gorgeous nerd πŸ¦‹πŸ’œ

πŸ“¦ where this page comes from