Browse Source

utxo: Add blockheight and spendheight to outputs to track state

Signed-off-by: Christian Decker <decker.christian@gmail.com>
ppa-0.6.1
Christian Decker 7 years ago
parent
commit
227dc36146
  1. 6
      common/utxo.h
  2. 12
      lightningd/chaintopology.c
  3. 3
      lightningd/onchain_control.c
  4. 2
      lightningd/opening_control.c
  5. 50
      wallet/wallet.c
  6. 2
      wallet/wallet.h
  7. 2
      wallet/walletrpc.c

6
common/utxo.h

@ -26,6 +26,12 @@ struct utxo {
/* Optional unilateral close information, NULL if this is just
* a HD key */
struct unilateral_close_info *close_info;
/* NULL if we haven't seen it in a block, otherwise the block it's in */
const int *blockheight;
/* NULL if not spent yet, otherwise, the block the spending transaction is in */
const int *spendheight;
};
void towire_utxo(u8 **pptr, const struct utxo *utxo);

12
lightningd/chaintopology.c

@ -77,7 +77,7 @@ static void filter_block_txs(struct chain_topology *topo, struct block *b)
satoshi_owned = 0;
if (txfilter_match(topo->bitcoind->ld->owned_txfilter, tx)) {
wallet_extract_owned_outputs(topo->bitcoind->ld->wallet,
tx, &satoshi_owned);
tx, b, &satoshi_owned);
}
/* We did spends first, in case that tells us to watch tx. */
@ -350,17 +350,17 @@ static void updates_complete(struct chain_topology *topo)
static void add_tip(struct chain_topology *topo, struct block *b)
{
/* Only keep the transactions we care about. */
filter_block_txs(topo, b);
block_map_add(&topo->block_map, b);
/* Attach to tip; b is now the tip. */
assert(b->height == topo->tip->height + 1);
b->prev = topo->tip;
topo->tip->next = b;
topo->tip = b;
wallet_block_add(topo->wallet, b);
/* Only keep the transactions we care about. */
filter_block_txs(topo, b);
block_map_add(&topo->block_map, b);
}
static struct block *new_block(struct chain_topology *topo,

3
lightningd/onchain_control.c

@ -226,6 +226,8 @@ static void onchain_add_utxo(struct channel *channel, const u8 *msg)
u->status = output_state_available;
u->close_info->channel_id = channel->dbid;
u->close_info->peer_id = channel->peer->id;
u->blockheight = NULL;
u->spendheight = NULL;
if (!fromwire_onchain_add_utxo(msg, &u->txid, &u->outnum,
&u->close_info->commitment_point,
@ -457,4 +459,3 @@ enum watch_result funding_spent(struct channel *channel,
/* We keep watching until peer finally deleted, for reorgs. */
return KEEP_WATCHING;
}

2
lightningd/opening_control.c

@ -354,7 +354,7 @@ static void opening_funder_finished(struct subd *openingd, const u8 *resp,
tal_hex(msg, resp));
/* Extract the change output and add it to the DB */
wallet_extract_owned_outputs(ld->wallet, fundingtx, &change_satoshi);
wallet_extract_owned_outputs(ld->wallet, fundingtx, NULL, &change_satoshi);
/* Send it out and watch for confirms. */
broadcast_tx(ld->topology, channel, fundingtx, funding_broadcast_failed);

50
wallet/wallet.c

@ -35,7 +35,18 @@ bool wallet_add_utxo(struct wallet *w, struct utxo *utxo,
{
sqlite3_stmt *stmt;
stmt = db_prepare(w->db, "INSERT INTO outputs (prev_out_tx, prev_out_index, value, type, status, keyindex, channel_id, peer_id, commitment_point) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?);");
stmt = db_prepare(w->db, "INSERT INTO outputs ("
"prev_out_tx, "
"prev_out_index, "
"value, "
"type, "
"status, "
"keyindex, "
"channel_id, "
"peer_id, "
"commitment_point, "
"confirmation_height, "
"spend_height) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?);");
sqlite3_bind_blob(stmt, 1, &utxo->txid, sizeof(utxo->txid), SQLITE_TRANSIENT);
sqlite3_bind_int(stmt, 2, utxo->outnum);
sqlite3_bind_int64(stmt, 3, utxo->amount);
@ -51,6 +62,19 @@ bool wallet_add_utxo(struct wallet *w, struct utxo *utxo,
sqlite3_bind_null(stmt, 8);
sqlite3_bind_null(stmt, 9);
}
if (utxo->blockheight) {
sqlite3_bind_int(stmt, 10, *utxo->blockheight);
} else
sqlite3_bind_null(stmt, 10);
if (utxo->spendheight)
sqlite3_bind_int(stmt, 11, *utxo->spendheight);
else
sqlite3_bind_null(stmt, 11);
/* 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);
}
@ -61,6 +85,7 @@ bool wallet_add_utxo(struct wallet *w, struct utxo *utxo,
*/
static bool wallet_stmt2output(sqlite3_stmt *stmt, struct utxo *utxo)
{
int *blockheight, *spendheight;
sqlite3_column_sha256_double(stmt, 0, &utxo->txid.shad);
utxo->outnum = sqlite3_column_int(stmt, 1);
utxo->amount = sqlite3_column_int64(stmt, 2);
@ -76,6 +101,21 @@ static bool wallet_stmt2output(sqlite3_stmt *stmt, struct utxo *utxo)
utxo->close_info = NULL;
}
utxo->blockheight = NULL;
utxo->spendheight = NULL;
if (sqlite3_column_type(stmt, 9) != SQLITE_NULL) {
blockheight = tal(utxo, int);
*blockheight = sqlite3_column_int(stmt, 9);
utxo->blockheight = blockheight;
}
if (sqlite3_column_type(stmt, 10) != SQLITE_NULL) {
spendheight = tal(utxo, int);
*spendheight = sqlite3_column_int(stmt, 10);
utxo->spendheight = spendheight;
}
return true;
}
@ -110,7 +150,7 @@ struct utxo **wallet_get_utxos(const tal_t *ctx, struct wallet *w, const enum ou
sqlite3_stmt *stmt = db_prepare(
w->db, "SELECT prev_out_tx, prev_out_index, value, type, status, keyindex, "
"channel_id, peer_id, commitment_point "
"channel_id, peer_id, commitment_point, confirmation_height, spend_height "
"FROM outputs WHERE status=?1 OR ?1=255");
sqlite3_bind_int(stmt, 1, state);
@ -942,7 +982,7 @@ void wallet_peer_delete(struct wallet *w, u64 peer_dbid)
}
int wallet_extract_owned_outputs(struct wallet *w, const struct bitcoin_tx *tx,
u64 *total_satoshi)
const struct block *block, u64 *total_satoshi)
{
int num_utxos = 0;
for (size_t output = 0; output < tal_count(tx->output); output++) {
@ -962,6 +1002,10 @@ int wallet_extract_owned_outputs(struct wallet *w, const struct bitcoin_tx *tx,
bitcoin_txid(tx, &utxo->txid);
utxo->outnum = output;
utxo->close_info = NULL;
utxo->blockheight = block?&block->height:NULL;
utxo->spendheight = NULL;
log_debug(w->log, "Owning output %zu %"PRIu64" (%s) txid %s",
output, tx->output[output].amount,
is_p2sh ? "P2SH" : "SEGWIT",

2
wallet/wallet.h

@ -279,7 +279,7 @@ u32 wallet_first_blocknum(struct wallet *w, u32 first_possible);
* wallet_extract_owned_outputs - given a tx, extract all of our outputs
*/
int wallet_extract_owned_outputs(struct wallet *w, const struct bitcoin_tx *tx,
u64 *total_satoshi);
const struct block *block, u64 *total_satoshi);
/**
* wallet_htlc_save_in - store an htlc_in in the database

2
wallet/walletrpc.c

@ -58,7 +58,7 @@ static void wallet_withdrawal_broadcast(struct bitcoind *bitcoind UNUSED,
* generated the hex tx, so this should always work */
tx = bitcoin_tx_from_hex(withdraw, withdraw->hextx, strlen(withdraw->hextx));
assert(tx != NULL);
wallet_extract_owned_outputs(ld->wallet, tx, &change_satoshi);
wallet_extract_owned_outputs(ld->wallet, tx, NULL, &change_satoshi);
/* Note normally, change_satoshi == withdraw->changesatoshi, but
* not if we're actually making a payment to ourselves! */

Loading…
Cancel
Save