Skip to content

Commit

Permalink
psbt: database migration for converting last_tx to a psbt
Browse files Browse the repository at this point in the history
We update the `last_tx` in `channels` to be psbt format, instead
of a linearized transaction.

We need the amount of the input populated, which we have since
this is the 'funding' amount. Ideally we'd also populate the funding
scriptPubkey, but to do that we'd need to access the HSM module to fetch
our local funding pubkey, which isn't initialized at the time that the
database migrations are run.

Since the only field the HSM uses currently when signing these is the
amount field, it's ok to just leave it out.

needs a test!
  • Loading branch information
niftynei authored and cdecker committed Jun 11, 2020
1 parent 57488cd commit bb589e0
Show file tree
Hide file tree
Showing 3 changed files with 84 additions and 0 deletions.
76 changes: 76 additions & 0 deletions wallet/db.c
Original file line number Diff line number Diff line change
@@ -1,12 +1,15 @@
#include "db.h"

#include <bitcoin/psbt.h>
#include <bitcoin/script.h>
#include <ccan/array_size/array_size.h>
#include <ccan/tal/str/str.h>
#include <common/derive_basepoints.h>
#include <common/node_id.h>
#include <common/onionreply.h>
#include <common/version.h>
#include <inttypes.h>
#include <lightningd/channel.h>
#include <lightningd/lightningd.h>
#include <lightningd/log.h>
#include <lightningd/plugin_hook.h>
Expand Down Expand Up @@ -613,6 +616,7 @@ static struct migration dbmigrations[] = {
{SQL("ALTER TABLE channel_htlcs ADD we_filled INTEGER;"), NULL},
/* We track the counter for coin_moves, as a convenience for notification consumers */
{SQL("INSERT INTO vars (name, intval) VALUES ('coin_moves_count', 0);"), NULL},
{NULL, migrate_last_tx_to_psbt},
};

/* Leak tracking. */
Expand Down Expand Up @@ -1111,6 +1115,78 @@ static void migrate_our_funding(struct lightningd *ld, struct db *db)
tal_free(stmt);
}

/* We're moving everything over to PSBTs from tx's, particularly our last_tx's
* which are commitment transactions for channels.
* This migration loads all of the last_tx's and 're-formats' them into psbts,
* adds the required input witness utxo information, and then saves it back to disk
* */
void migrate_last_tx_to_psbt(struct lightningd *ld, struct db *db)
{
struct db_stmt *stmt, *update_stmt;

stmt = db_prepare_v2(db, SQL("SELECT "
" c.id"
", p.node_id"
", c.last_tx"
", c.funding_satoshi"
", c.fundingkey_remote"
", c.last_sig"
" FROM channels c"
" LEFT OUTER JOIN peers p"
" ON p.id = c.peer_id;"));

db_query_prepared(stmt);
while (db_step(stmt)) {
struct bitcoin_tx *last_tx;
struct amount_sat funding_sat;
struct node_id peer_id;
struct pubkey local_funding_pubkey, remote_funding_pubkey;
struct basepoints local_basepoints UNUSED;
struct bitcoin_signature last_sig;
u64 cdb_id;
u8 *funding_wscript;

cdb_id = db_column_u64(stmt, 0);
last_tx = db_column_tx(stmt, stmt, 2);
assert(last_tx != NULL);

db_column_node_id(stmt, 1, &peer_id);
db_column_amount_sat(stmt, 3, &funding_sat);
db_column_pubkey(stmt, 4, &remote_funding_pubkey);

get_channel_basepoints(ld, &peer_id, cdb_id,
&local_basepoints, &local_funding_pubkey);

funding_wscript = bitcoin_redeem_2of2(stmt, &local_funding_pubkey,
&remote_funding_pubkey);

psbt_input_set_prev_utxo_wscript(last_tx->psbt,
0, funding_wscript,
funding_sat);

if (!db_column_signature(stmt, 5, &last_sig.s))
abort();

last_sig.sighash_type = SIGHASH_ALL;
psbt_input_set_partial_sig(last_tx->psbt, 0,
&remote_funding_pubkey, &last_sig);
psbt_input_add_pubkey(last_tx->psbt, 0,
&local_funding_pubkey);
psbt_input_add_pubkey(last_tx->psbt, 0,
&remote_funding_pubkey);

update_stmt = db_prepare_v2(db, SQL("UPDATE channels"
" SET last_tx = ?"
" WHERE id = ?;"));
db_bind_psbt(update_stmt, 0, last_tx->psbt);
db_bind_int(update_stmt, 1, cdb_id);
db_exec_prepared_v2(update_stmt);
tal_free(update_stmt);
}

tal_free(stmt);
}

void db_bind_null(struct db_stmt *stmt, int pos)
{
assert(pos < tal_count(stmt->bindings));
Expand Down
1 change: 1 addition & 0 deletions wallet/db.h
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ struct db_stmt;
struct db;
struct wally_psbt;

void migrate_last_tx_to_psbt(struct lightningd *ld, struct db *db);
/**
* Macro to annotate a named SQL query.
*
Expand Down
7 changes: 7 additions & 0 deletions wallet/test/run-db.c
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,13 @@ static void db_log_(struct log *log UNUSED, enum log_level level UNUSED, const s
/* Generated stub for fatal */
void fatal(const char *fmt UNNEEDED, ...)
{ fprintf(stderr, "fatal called!\n"); abort(); }
/* Generated stub for get_channel_basepoints */
void get_channel_basepoints(struct lightningd *ld UNNEEDED,
const struct node_id *peer_id UNNEEDED,
const u64 dbid UNNEEDED,
struct basepoints *local_basepoints UNNEEDED,
struct pubkey *local_funding_pubkey UNNEEDED)
{ fprintf(stderr, "get_channel_basepoints called!\n"); abort(); }
/* Generated stub for new_log */
struct log *new_log(const tal_t *ctx UNNEEDED, struct log_book *record UNNEEDED,
const struct node_id *default_node_id UNNEEDED,
Expand Down

0 comments on commit bb589e0

Please sign in to comment.