Browse Source

wallet: Add scriptPubkey to struct utxo

In order to avoid having to ask the HSM for public keys to
their_unilateral/to_us outputs we just store the `scriptPubkey` with the UTXO,
which can then be converted to the P2WPKH address.

Signed-off-by: Christian Decker <decker.christian@gmail.com>
pr-2391
Christian Decker 6 years ago
committed by neil saitug
parent
commit
df4e0a0022
  1. 5
      common/utxo.c
  2. 3
      common/utxo.h
  3. 1
      lightningd/onchain_control.c
  4. 1
      wallet/db.c
  5. 19
      wallet/wallet.c

5
common/utxo.c

@ -31,6 +31,11 @@ struct utxo *fromwire_utxo(const tal_t *ctx, const u8 **ptr, size_t *max)
utxo->amount = fromwire_amount_sat(ptr, max);
utxo->keyindex = fromwire_u32(ptr, max);
utxo->is_p2sh = fromwire_bool(ptr, max);
/* No need to tell hsmd about the scriptPubkey, it has all the info to
* derive it from the rest. */
utxo->scriptPubkey = NULL;
if (fromwire_bool(ptr, max)) {
utxo->close_info = tal(utxo, struct unilateral_close_info);
utxo->close_info->channel_id = fromwire_u64(ptr, max);

3
common/utxo.h

@ -35,6 +35,9 @@ struct utxo {
/* NULL if not spent yet, otherwise, the block the spending transaction is in */
const u32 *spendheight;
/* The scriptPubkey if it is known */
u8 *scriptPubkey;
};
void towire_utxo(u8 **pptr, const struct utxo *utxo);

1
lightningd/onchain_control.c

@ -272,6 +272,7 @@ static void onchain_add_utxo(struct channel *channel, const u8 *msg)
u->close_info->channel_id = channel->dbid;
u->close_info->peer_id = channel->peer->id;
u->spendheight = NULL;
u->scriptPubkey = NULL;
if (!fromwire_onchain_add_utxo(msg, &u->txid, &u->outnum,
&u->close_info->commitment_point,

1
wallet/db.c

@ -358,6 +358,7 @@ char *dbmigrations[] = {
"ALTER TABLE payments ADD faildirection INTEGER;", /* erring_direction */
/* Fix dangling peers with no channels. */
"DELETE FROM peers WHERE id NOT IN (SELECT peer_id FROM channels);",
"ALTER TABLE outputs ADD scriptpubkey BLOB;",
NULL,
};

19
wallet/wallet.c

@ -65,7 +65,7 @@ struct wallet *wallet_new(struct lightningd *ld,
#define UTXO_FIELDS \
"prev_out_tx, prev_out_index, value, type, status, keyindex, " \
"channel_id, peer_id, commitment_point, confirmation_height, " \
"spend_height"
"spend_height, scriptpubkey"
/* We actually use the db constraints to uniquify, so OK if this fails. */
bool wallet_add_utxo(struct wallet *w, struct utxo *utxo,
@ -75,7 +75,7 @@ bool wallet_add_utxo(struct wallet *w, struct utxo *utxo,
stmt = db_prepare(w->db, "INSERT INTO outputs ("
UTXO_FIELDS
") VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?);");
") VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?);");
sqlite3_bind_blob(stmt, 1, &utxo->txid, sizeof(utxo->txid), SQLITE_TRANSIENT);
sqlite3_bind_int(stmt, 2, utxo->outnum);
sqlite3_bind_amount_sat(stmt, 3, utxo->amount);
@ -102,6 +102,13 @@ bool wallet_add_utxo(struct wallet *w, struct utxo *utxo,
else
sqlite3_bind_null(stmt, 11);
if (utxo->scriptPubkey)
sqlite3_bind_blob(stmt, 12, utxo->scriptPubkey,
tal_bytelen(utxo->scriptPubkey),
SQLITE_TRANSIENT);
else
sqlite3_bind_null(stmt, 12);
/* May fail if we already know about the tx, e.g., because
* it's change or some internal tx. */
return db_exec_prepared_mayfail(w->db, stmt);
@ -131,6 +138,7 @@ static struct utxo *wallet_stmt2output(const tal_t *ctx, sqlite3_stmt *stmt)
utxo->blockheight = NULL;
utxo->spendheight = NULL;
utxo->scriptPubkey = NULL;
if (sqlite3_column_type(stmt, 9) != SQLITE_NULL) {
blockheight = tal(utxo, u32);
@ -144,6 +152,12 @@ static struct utxo *wallet_stmt2output(const tal_t *ctx, sqlite3_stmt *stmt)
utxo->spendheight = spendheight;
}
if (sqlite3_column_type(stmt, 11) != SQLITE_NULL) {
utxo->scriptPubkey =
tal_dup_arr(utxo, u8, sqlite3_column_blob(stmt, 11),
sqlite3_column_bytes(stmt, 11), 0);
}
return utxo;
}
@ -1162,6 +1176,7 @@ int wallet_extract_owned_outputs(struct wallet *w, const struct bitcoin_tx *tx,
utxo->blockheight = blockheight ? blockheight : NULL;
utxo->spendheight = NULL;
utxo->scriptPubkey = tx->output[output].script;
log_debug(w->log, "Owning output %zu %s (%s) txid %s%s",
output,

Loading…
Cancel
Save