From 9882a9fb296e23b4bd1233f0c44d96a14da62d27 Mon Sep 17 00:00:00 2001 From: Christian Decker Date: Tue, 23 May 2017 22:07:20 +0200 Subject: [PATCH] wallet: Start the wallet interface and link it into lightningd The database is hidden behind the wallet interface, which has all the wallet specific functionality. First up is the tracking of outputs. --- lightningd/Makefile | 5 ++-- lightningd/lightningd.c | 3 +++ lightningd/lightningd.h | 3 +++ wallet/Makefile | 5 ++-- wallet/db.c | 2 +- wallet/wallet.c | 27 +++++++++++++++++++++ wallet/wallet.h | 53 +++++++++++++++++++++++++++++++++++++++++ 7 files changed, 93 insertions(+), 5 deletions(-) create mode 100644 wallet/wallet.c create mode 100644 wallet/wallet.h diff --git a/lightningd/Makefile b/lightningd/Makefile index 0337d7376..a4b17ca61 100644 --- a/lightningd/Makefile +++ b/lightningd/Makefile @@ -95,7 +95,8 @@ LIGHTNINGD_HEADERS_NOGEN = \ $(BITCOIN_HEADERS) \ $(CORE_HEADERS) \ $(CORE_TX_HEADERS) \ - $(DAEMON_HEADERS) + $(DAEMON_HEADERS) \ + $(WALLET_LIB_HEADERS) # Generated headers LIGHTNINGD_HEADERS_GEN = \ @@ -138,7 +139,7 @@ check-makefile: check-lightningd-makefile check-lightningd-makefile: @for f in lightningd/*.h lightningd/*/*.h; do if ! echo $(LIGHTNINGD_HEADERS_NOGEN) $(LIGHTNINGD_HEADERS_GEN) "" | grep -q "$$f "; then echo $$f not mentioned in LIGHTNINGD_HEADERS_NOGEN or LIGHTNINGD_HEADERS_GEN >&2; exit 1; fi; done -lightningd/lightningd: $(LIGHTNINGD_OBJS) $(LIGHTNINGD_OLD_OBJS) $(LIGHTNINGD_OLD_LIB_OBJS) $(LIGHTNINGD_LIB_OBJS) $(LIGHTNINGD_JSMN_OBJS) $(CORE_OBJS) $(CORE_TX_OBJS) $(BITCOIN_OBJS) $(WIRE_OBJS) $(WIRE_ONION_OBJS) $(CCAN_OBJS) $(CCAN_SHACHAIN48_OBJ) $(LIGHTNINGD_HSM_CONTROL_OBJS) $(LIGHTNINGD_HANDSHAKE_CONTROL_OBJS) $(LIGHTNINGD_GOSSIP_CONTROL_OBJS) $(LIBBASE58_OBJS) $(LIGHTNINGD_OPENING_CONTROL_OBJS) $(LIGHTNINGD_CHANNEL_CONTROL_OBJS) libsecp256k1.a libsodium.a libwallycore.a +lightningd/lightningd: $(LIGHTNINGD_OBJS) $(LIGHTNINGD_OLD_OBJS) $(LIGHTNINGD_OLD_LIB_OBJS) $(LIGHTNINGD_LIB_OBJS) $(LIGHTNINGD_JSMN_OBJS) $(CORE_OBJS) $(CORE_TX_OBJS) $(BITCOIN_OBJS) $(WIRE_OBJS) $(WIRE_ONION_OBJS) $(CCAN_OBJS) $(CCAN_SHACHAIN48_OBJ) $(LIGHTNINGD_HSM_CONTROL_OBJS) $(LIGHTNINGD_HANDSHAKE_CONTROL_OBJS) $(LIGHTNINGD_GOSSIP_CONTROL_OBJS) $(LIBBASE58_OBJS) $(LIGHTNINGD_OPENING_CONTROL_OBJS) $(LIGHTNINGD_CHANNEL_CONTROL_OBJS) $(WALLET_LIB_OBJS) libsecp256k1.a libsodium.a libwallycore.a clean: lightningd-clean diff --git a/lightningd/lightningd.c b/lightningd/lightningd.c index e642ea851..48d84d86d 100644 --- a/lightningd/lightningd.c +++ b/lightningd/lightningd.c @@ -254,6 +254,9 @@ int main(int argc, char *argv[]) /* Make sure we can reach other daemons, and versions match. */ test_daemons(ld); + /* Initialize wallet, now that we are in the correct directory */ + ld->wallet = wallet_new(ld, ld->log); + /* Mark ourselves live. */ log_info(ld->log, "Hello world from %s!", version()); diff --git a/lightningd/lightningd.h b/lightningd/lightningd.h index ca281ce57..2e2fbc993 100644 --- a/lightningd/lightningd.h +++ b/lightningd/lightningd.h @@ -5,6 +5,7 @@ #include #include #include +#include /* BOLT #1: * @@ -60,6 +61,8 @@ struct lightningd { struct htlc_end_map htlc_ends; u32 broadcast_interval; + + struct wallet *wallet; }; void derive_peer_seed(struct lightningd *ld, struct privkey *peer_seed, diff --git a/wallet/Makefile b/wallet/Makefile index 9d468d0ec..8b648489c 100644 --- a/wallet/Makefile +++ b/wallet/Makefile @@ -6,8 +6,9 @@ wallet-wrongdir: check: wallet/tests -WALLET_LIB_SRC := \ - wallet/db.c +WALLET_LIB_SRC := \ + wallet/db.c \ + wallet/wallet.c WALLET_LIB_OBJS := $(WALLET_LIB_SRC:.c=.o) WALLET_LIB_HEADERS := $(WALLET_LIB_SRC:.c=.h) diff --git a/wallet/db.c b/wallet/db.c index e565bd978..771cafdfd 100644 --- a/wallet/db.c +++ b/wallet/db.c @@ -14,7 +14,7 @@ char *dbmigrations[] = { "CREATE TABLE version (version INTEGER)", "INSERT INTO version VALUES (1)", "CREATE TABLE outputs ( \ - prev_out_tx BLOB, \ + prev_out_tx CHAR(64), \ prev_out_index INTEGER, \ value INTEGER, \ type INTEGER, \ diff --git a/wallet/wallet.c b/wallet/wallet.c new file mode 100644 index 000000000..d593d4e7c --- /dev/null +++ b/wallet/wallet.c @@ -0,0 +1,27 @@ +#include "wallet.h" + +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; +} diff --git a/wallet/wallet.h b/wallet/wallet.h new file mode 100644 index 000000000..d2630bd54 --- /dev/null +++ b/wallet/wallet.h @@ -0,0 +1,53 @@ +#ifndef WALLET_WALLET_H +#define WALLET_WALLET_H + +#include "config.h" +#include "db.h" +#include +#include + +struct wallet { + struct db *db; + struct log *log; +}; + +/* Possible states for tracked outputs in the database. Not sure yet + * whether we really want to have reservations reflected in the + * database, it would simplify queries at the cost of some IO ops */ +enum output_status { + output_state_available= 0, + output_state_reserved = 1, + output_state_spent = 2, + /* Special status used to express that we don't care in + * queries */ + output_state_any = 255 +}; + +/* Enumeration of all known output types. These include all types that + * could ever end up on-chain and we may need to react upon. Notice + * that `to_local`, `htlc_offer`, and `htlc_recv` may need immediate + * action since they are encumbered with a CSV. */ +enum wallet_output_type { + p2sh_wpkh = 0, + to_local = 1, + htlc_offer = 3, + htlc_recv = 4 +}; + +/** + * wallet_new - Constructor for a new sqlite3 based wallet + * + * This is guaranteed to either return a valid wallet, or abort with + * `fatal` if it cannot be initialized. + */ +struct wallet *wallet_new(const tal_t *ctx, struct log *log); + +/** + * wallet_add_utxo - Register a UTXO which we (partially) own + * + * Add a UTXO to the set of outputs we care about. + */ +bool wallet_add_utxo(struct wallet *w, struct utxo *utxo, + enum wallet_output_type type); + +#endif /* WALLET_WALLET_H */