2017-05-23 22:07:20 +02:00
|
|
|
#include "wallet.h"
|
|
|
|
|
2017-06-05 13:59:51 +02:00
|
|
|
#include <ccan/str/hex/hex.h>
|
|
|
|
|
2017-05-23 22:07:20 +02:00
|
|
|
struct wallet *wallet_new(const tal_t *ctx, struct log *log)
|
|
|
|
{
|
|
|
|
struct wallet *wallet = tal(ctx, struct wallet);
|
|
|
|
wallet->db = db_setup(wallet);
|
|
|
|
wallet->log = log;
|
|
|
|
if (!wallet->db) {
|
|
|
|
fatal("Unable to setup the wallet database");
|
|
|
|
}
|
|
|
|
return wallet;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool wallet_add_utxo(struct wallet *w, struct utxo *utxo,
|
|
|
|
enum wallet_output_type type)
|
|
|
|
{
|
|
|
|
tal_t *tmpctx = tal_tmpctx(w);
|
|
|
|
char *hextxid = tal_hexstr(tmpctx, &utxo->txid, 32);
|
|
|
|
bool result = db_exec(
|
|
|
|
__func__, w->db,
|
|
|
|
"INSERT INTO outputs (prev_out_tx, prev_out_index, value, type, "
|
|
|
|
"status, keyindex) VALUES ('%s', %d, %zu, %d, %d, %d);",
|
|
|
|
hextxid, utxo->outnum, utxo->amount, type, output_state_available,
|
|
|
|
utxo->keyindex);
|
|
|
|
tal_free(tmpctx);
|
|
|
|
return result;
|
|
|
|
}
|
2017-05-31 16:16:59 +02:00
|
|
|
|
2017-06-05 13:59:51 +02:00
|
|
|
/**
|
|
|
|
* wallet_stmt2output - Extract data from stmt and fill a utxo
|
|
|
|
*
|
|
|
|
* Returns true on success.
|
|
|
|
*/
|
|
|
|
static bool wallet_stmt2output(sqlite3_stmt *stmt, struct utxo *utxo)
|
|
|
|
{
|
|
|
|
const unsigned char *hextxid = sqlite3_column_text(stmt, 0);
|
|
|
|
hex_decode((const char*)hextxid, sizeof(utxo->txid) * 2, &utxo->txid, sizeof(utxo->txid));
|
|
|
|
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);
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2017-05-31 16:16:59 +02:00
|
|
|
bool wallet_update_output_status(struct wallet *w,
|
|
|
|
const struct sha256_double *txid,
|
|
|
|
const u32 outnum, enum output_status oldstatus,
|
|
|
|
enum output_status newstatus)
|
|
|
|
{
|
|
|
|
tal_t *tmpctx = tal_tmpctx(w);
|
|
|
|
char *hextxid = tal_hexstr(tmpctx, txid, sizeof(*txid));
|
|
|
|
if (oldstatus != output_state_any) {
|
|
|
|
db_exec(__func__, w->db,
|
|
|
|
"UPDATE outputs SET status=%d WHERE status=%d "
|
|
|
|
"AND prev_out_tx = '%s' AND prev_out_index = "
|
|
|
|
"%d;",
|
|
|
|
newstatus, oldstatus, hextxid, outnum);
|
|
|
|
} else {
|
|
|
|
db_exec(__func__, w->db,
|
|
|
|
"UPDATE outputs SET status=%d WHERE "
|
|
|
|
"AND prev_out_tx = '%s' AND prev_out_index = "
|
|
|
|
"%d;",
|
|
|
|
newstatus, hextxid, outnum);
|
|
|
|
}
|
|
|
|
tal_free(tmpctx);
|
|
|
|
return sqlite3_changes(w->db->sql) > 0;
|
|
|
|
}
|
2017-06-05 13:59:51 +02:00
|
|
|
|
|
|
|
struct utxo **wallet_get_utxos(const tal_t *ctx, struct wallet *w, const enum output_status state)
|
|
|
|
{
|
|
|
|
struct utxo **results;
|
|
|
|
int i;
|
|
|
|
sqlite3_stmt *stmt =
|
|
|
|
db_query(__func__, w->db, "SELECT prev_out_tx, prev_out_index, "
|
|
|
|
"value, type, status, keyindex FROM "
|
|
|
|
"outputs WHERE status=%d OR %d=255",
|
|
|
|
state, state);
|
|
|
|
|
|
|
|
if (!stmt)
|
|
|
|
return NULL;
|
|
|
|
|
|
|
|
results = tal_arr(ctx, struct utxo*, 0);
|
|
|
|
for (i=0; sqlite3_step(stmt) == SQLITE_ROW; i++) {
|
|
|
|
tal_resize(&results, i+1);
|
|
|
|
results[i] = tal(results, struct utxo);
|
|
|
|
wallet_stmt2output(stmt, results[i]);
|
|
|
|
}
|
|
|
|
sqlite3_finalize(stmt);
|
|
|
|
|
|
|
|
return results;
|
|
|
|
}
|