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 */