Browse Source

wallet: Added unilateral close info to utxo

This is necessary to grad the their_unilateral/to-us outputs since
they aren't being harvested by `onchaind`

Signed-off-by: Christian Decker <decker.christian@gmail.com>
ppa-0.6.1
Christian Decker 7 years ago
parent
commit
0bb264e1a2
  1. 13
      common/utxo.h
  2. 1
      lightningd/test/run-funding_tx.c
  3. 15
      wallet/db.c
  4. 3
      wallet/db.h
  5. 31
      wallet/test/run-wallet.c
  6. 26
      wallet/wallet.c

13
common/utxo.h

@ -1,11 +1,20 @@
#ifndef LIGHTNING_COMMON_UTXO_H
#define LIGHTNING_COMMON_UTXO_H
#include "config.h"
#include <bitcoin/pubkey.h>
#include <bitcoin/shadouble.h>
#include <bitcoin/tx.h>
#include <ccan/short_types/short_types.h>
#include <ccan/tal/tal.h>
#include <stdbool.h>
/* Information needed for their_unilateral/to-us outputs */
struct unilateral_close_info {
u64 channel_id;
struct pubkey peer_id;
struct pubkey commitment_point;
};
struct utxo {
struct bitcoin_txid txid;
u32 outnum;
@ -13,6 +22,10 @@ struct utxo {
u32 keyindex;
bool is_p2sh;
u8 status;
/* Optional unilateral close information, NULL if this is just
* a HD key */
struct unilateral_close_info *close_info;
};
void towire_utxo(u8 **pptr, const struct utxo *utxo);

1
lightningd/test/run-funding_tx.c

@ -99,6 +99,7 @@ int main(void)
utxo.outnum = 0;
utxo.amount = 5000000000;
utxo.is_p2sh = false;
utxo.close_info = NULL;
funding_satoshis = 10000000;
fee = 13920;

15
wallet/db.c

@ -150,6 +150,9 @@ char *dbmigrations[] = {
* pre-release software, so it's forgivable. */
"ALTER TABLE channels ADD first_blocknum INTEGER;",
"UPDATE channels SET first_blocknum=CAST(short_channel_id AS INTEGER) WHERE short_channel_id IS NOT NULL;",
"ALTER TABLE outputs ADD COLUMN channel_id INTEGER;",
"ALTER TABLE outputs ADD COLUMN peer_id BLOB;",
"ALTER TABLE outputs ADD COLUMN commitment_point BLOB;",
NULL,
};
@ -493,3 +496,15 @@ bool sqlite3_bind_sha256(sqlite3_stmt *stmt, int col, const struct sha256 *p)
sqlite3_bind_blob(stmt, col, p, sizeof(struct sha256), SQLITE_TRANSIENT);
return true;
}
bool sqlite3_column_sha256_double(sqlite3_stmt *stmt, int col, struct sha256_double *dest)
{
assert(sqlite3_column_bytes(stmt, col) == sizeof(struct sha256_double));
return memcpy(dest, sqlite3_column_blob(stmt, col), sizeof(struct sha256_double));
}
bool sqlite3_bind_sha256_double(sqlite3_stmt *stmt, int col, const struct sha256_double *p)
{
sqlite3_bind_blob(stmt, col, p, sizeof(struct sha256_double), SQLITE_TRANSIENT);
return true;
}

3
wallet/db.h

@ -132,4 +132,7 @@ bool sqlite3_bind_preimage(sqlite3_stmt *stmt, int col, const struct preimage *p
bool sqlite3_column_sha256(sqlite3_stmt *stmt, int col, struct sha256 *dest);
bool sqlite3_bind_sha256(sqlite3_stmt *stmt, int col, const struct sha256 *p);
bool sqlite3_column_sha256_double(sqlite3_stmt *stmt, int col, struct sha256_double *dest);
bool sqlite3_bind_sha256_double(sqlite3_stmt *stmt, int col, const struct sha256_double *p);
#endif /* WALLET_DB_H */

31
wallet/test/run-wallet.c

@ -17,6 +17,7 @@ static void db_log_(struct log *log, enum log_level level, const char *fmt, ...)
#include <ccan/tal/str/str.h>
#include <common/memleak.h>
#include <stdarg.h>
#include <stddef.h>
#include <stdio.h>
#include <unistd.h>
@ -87,16 +88,22 @@ static bool test_wallet_outputs(void)
char filename[] = "/tmp/ldb-XXXXXX";
struct utxo u;
int fd = mkstemp(filename);
struct wallet *w = tal(NULL, struct wallet);
CHECK_MSG(fd != -1, "Unable to generate temp filename");
close(fd);
struct wallet *w = tal(NULL, struct wallet);
struct pubkey pk;
u64 fee_estimate, change_satoshis;
const struct utxo **utxos;
w->db = db_open(w, filename);
CHECK_MSG(w->db, "Failed opening the db");
db_migrate(w->db, NULL);
CHECK_MSG(!wallet_err, "DB migration failed");
memset(&u, 0, sizeof(u));
u.amount = 1;
pubkey_from_der(tal_hexdata(w, "02a1633cafcc01ebfb6d78e39f687a1f0995c62fc95f51ead10a02ee0be551b5dc", 66), 33, &pk);
db_begin_transaction(w->db);
@ -108,6 +115,27 @@ static bool test_wallet_outputs(void)
CHECK_MSG(!wallet_add_utxo(w, &u, p2sh_wpkh),
"wallet_add_utxo succeeded on second add");
/* Attempt to save a utxo with close_info set */
memset(&u.txid, 1, sizeof(u.txid));
u.close_info = tal(w, struct unilateral_close_info);
u.close_info->channel_id = 42;
u.close_info->peer_id = pk;
u.close_info->commitment_point = pk;
CHECK_MSG(wallet_add_utxo(w, &u, p2sh_wpkh),
"wallet_add_utxo with close_info");
/* Now select them */
utxos = wallet_select_coins(w, w, 2, 0, 21, &fee_estimate, &change_satoshis);
CHECK(utxos && tal_count(utxos) == 2);
u = *utxos[1];
CHECK(u.close_info->channel_id == 42 &&
pubkey_eq(&u.close_info->commitment_point, &pk) &&
pubkey_eq(&u.close_info->peer_id, &pk));
/* Now un-reserve them for the tests below */
tal_free(utxos);
/* Attempt to reserve the utxo */
CHECK_MSG(wallet_update_output_status(w, &u.txid, u.outnum,
output_state_available,
@ -133,6 +161,7 @@ static bool test_wallet_outputs(void)
"could not change output state ignoring oldstate");
db_commit_transaction(w->db);
tal_free(w);
return true;
}

26
wallet/wallet.c

@ -29,13 +29,22 @@ 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) 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) 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);
sqlite3_bind_int(stmt, 4, type);
sqlite3_bind_int(stmt, 5, output_state_available);
sqlite3_bind_int(stmt, 6, utxo->keyindex);
if (utxo->close_info) {
sqlite3_bind_int64(stmt, 7, utxo->close_info->channel_id);
sqlite3_bind_pubkey(stmt, 8, &utxo->close_info->peer_id);
sqlite3_bind_pubkey(stmt, 9, &utxo->close_info->commitment_point);
} else {
sqlite3_bind_null(stmt, 7);
sqlite3_bind_null(stmt, 8);
sqlite3_bind_null(stmt, 9);
}
return db_exec_prepared_mayfail(w->db, stmt);
}
@ -46,12 +55,21 @@ bool wallet_add_utxo(struct wallet *w, struct utxo *utxo,
*/
static bool wallet_stmt2output(sqlite3_stmt *stmt, struct utxo *utxo)
{
memcpy(&utxo->txid, sqlite3_column_blob(stmt, 0), sqlite3_column_bytes(stmt, 0));
sqlite3_column_sha256_double(stmt, 0, &utxo->txid.shad);
utxo->outnum = sqlite3_column_int(stmt, 1);
utxo->amount = sqlite3_column_int(stmt, 2);
utxo->is_p2sh = sqlite3_column_int(stmt, 3) == p2sh_wpkh;
utxo->status = sqlite3_column_int(stmt, 4);
utxo->keyindex = sqlite3_column_int(stmt, 5);
if (sqlite3_column_type(stmt, 6) != SQLITE_NULL) {
utxo->close_info = tal(utxo, struct unilateral_close_info);
utxo->close_info->channel_id = sqlite3_column_int64(stmt, 6);
sqlite3_column_pubkey(stmt, 7, &utxo->close_info->peer_id);
sqlite3_column_pubkey(stmt, 8, &utxo->close_info->commitment_point);
} else {
utxo->close_info = NULL;
}
return true;
}
@ -85,7 +103,8 @@ struct utxo **wallet_get_utxos(const tal_t *ctx, struct wallet *w, const enum ou
int i;
sqlite3_stmt *stmt = db_prepare(
w->db, "SELECT prev_out_tx, prev_out_index, value, type, status, keyindex "
w->db, "SELECT prev_out_tx, prev_out_index, value, type, status, keyindex, "
"channel_id, peer_id, commitment_point "
"FROM outputs WHERE status=?1 OR ?1=255");
sqlite3_bind_int(stmt, 1, state);
@ -829,6 +848,7 @@ int wallet_extract_owned_outputs(struct wallet *w, const struct bitcoin_tx *tx,
utxo->status = output_state_available;
bitcoin_txid(tx, &utxo->txid);
utxo->outnum = output;
utxo->close_info = NULL;
log_debug(w->log, "Owning output %zu %"PRIu64" (%s) txid %s",
output, tx->output[output].amount,
is_p2sh ? "P2SH" : "SEGWIT",

Loading…
Cancel
Save