From e3219d3aa0b0289f32c32172cb405ba4c574cd08 Mon Sep 17 00:00:00 2001 From: Rusty Russell Date: Fri, 28 Aug 2020 13:26:34 +0930 Subject: [PATCH] utxo: expose is_reserved, make enum constants upper case. Signed-off-by: Rusty Russell --- common/utxo.h | 25 ++++++++++++++++++++++- wallet/reservation.c | 16 +++++++-------- wallet/test/run-wallet.c | 16 +++++++-------- wallet/wallet.c | 44 ++++++++++++++++++++-------------------- wallet/wallet.h | 28 +++++++------------------ wallet/walletrpc.c | 23 +++++++-------------- 6 files changed, 76 insertions(+), 76 deletions(-) diff --git a/common/utxo.h b/common/utxo.h index 8ee7fac25..f779328ea 100644 --- a/common/utxo.h +++ b/common/utxo.h @@ -22,13 +22,27 @@ struct unilateral_close_info { struct pubkey *commitment_point; }; +/* 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 */ +/* /!\ This is a DB ENUM, please do not change the numbering of any + * already defined elements (adding is ok) /!\ */ +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 +}; + struct utxo { struct bitcoin_txid txid; u32 outnum; struct amount_sat amount; u32 keyindex; bool is_p2sh; - u8 status; + enum output_status status; /* Optional unilateral close information, NULL if this is just * a HD key */ @@ -47,6 +61,15 @@ struct utxo { u8 *scriptPubkey; }; +/* We lazy-evaluate whether a utxo is really still reserved. */ +static inline bool utxo_is_reserved(const struct utxo *utxo, u32 current_height) +{ + if (utxo->status != OUTPUT_STATE_RESERVED) + return false; + + return utxo->reserved_til > current_height; +} + void towire_utxo(u8 **pptr, const struct utxo *utxo); struct utxo *fromwire_utxo(const tal_t *ctx, const u8 **ptr, size_t *max); diff --git a/wallet/reservation.c b/wallet/reservation.c index 7e489a6b1..b1df871f0 100644 --- a/wallet/reservation.c +++ b/wallet/reservation.c @@ -15,7 +15,7 @@ static bool was_reserved(enum output_status oldstatus, u32 reserved_til, u32 current_height) { - if (oldstatus != output_state_reserved) + if (oldstatus != OUTPUT_STATE_RESERVED) return false; return reserved_til > current_height; @@ -33,8 +33,8 @@ static void json_add_reservestatus(struct json_stream *response, json_add_bool(response, "was_reserved", was_reserved(oldstatus, old_res, current_height)); json_add_bool(response, "reserved", - is_reserved(utxo, current_height)); - if (is_reserved(utxo, current_height)) + utxo_is_reserved(utxo, current_height)); + if (utxo_is_reserved(utxo, current_height)) json_add_u32(response, "reserved_to_block", utxo->reserved_til); json_object_end(response); @@ -96,7 +96,7 @@ static struct command_result *json_reserveinputs(struct command *cmd, &txid, psbt->tx->inputs[i].index); if (!utxo) continue; - if (*exclusive && is_reserved(utxo, current_height)) { + if (*exclusive && utxo_is_reserved(utxo, current_height)) { return command_fail(cmd, JSONRPC2_INVALID_PARAMS, "%s:%u already reserved", type_to_string(tmpctx, @@ -104,7 +104,7 @@ static struct command_result *json_reserveinputs(struct command *cmd, &utxo->txid), utxo->outnum); } - if (utxo->status == output_state_spent) + if (utxo->status == OUTPUT_STATE_SPENT) return command_fail(cmd, JSONRPC2_INVALID_PARAMS, "%s:%u already spent", type_to_string(tmpctx, @@ -152,7 +152,7 @@ static struct command_result *json_unreserveinputs(struct command *cmd, wally_tx_input_get_txid(&psbt->tx->inputs[i], &txid); utxo = wallet_utxo_get(cmd, cmd->ld->wallet, &txid, psbt->tx->inputs[i].index); - if (!utxo || utxo->status != output_state_reserved) + if (!utxo || utxo->status != OUTPUT_STATE_RESERVED) continue; oldstatus = utxo->status; @@ -477,7 +477,7 @@ static struct command_result *param_txout(struct command *cmd, &txid), outnum); } - if (utxo->status == output_state_spent) { + if (utxo->status == OUTPUT_STATE_SPENT) { return command_fail(cmd, JSONRPC2_INVALID_PARAMS, "Already spent UTXO %s:%u", type_to_string(tmpctx, @@ -527,7 +527,7 @@ static struct command_result *json_utxopsbt(struct command *cmd, for (size_t i = 0; i < tal_count(utxos); i++) { const struct utxo *utxo = utxos[i]; - if (!*reserved_ok && is_reserved(utxo, current_height)) + if (!*reserved_ok && utxo_is_reserved(utxo, current_height)) return command_fail(cmd, JSONRPC2_INVALID_PARAMS, "UTXO %s:%u already reserved", type_to_string(tmpctx, diff --git a/wallet/test/run-wallet.c b/wallet/test/run-wallet.c index 652da3ea6..dec6a47e0 100644 --- a/wallet/test/run-wallet.c +++ b/wallet/test/run-wallet.c @@ -961,26 +961,26 @@ static bool test_wallet_outputs(struct lightningd *ld, const tal_t *ctx) /* Attempt to reserve the utxo */ CHECK_MSG(wallet_update_output_status(w, &u.txid, u.outnum, - output_state_available, - output_state_reserved), + OUTPUT_STATE_AVAILABLE, + OUTPUT_STATE_RESERVED), "could not reserve available output"); /* Reserving twice should fail */ CHECK_MSG(!wallet_update_output_status(w, &u.txid, u.outnum, - output_state_available, - output_state_reserved), + OUTPUT_STATE_AVAILABLE, + OUTPUT_STATE_RESERVED), "could reserve already reserved output"); /* Un-reserving should work */ CHECK_MSG(wallet_update_output_status(w, &u.txid, u.outnum, - output_state_reserved, - output_state_available), + OUTPUT_STATE_RESERVED, + OUTPUT_STATE_AVAILABLE), "could not unreserve reserved output"); /* Switching from any to something else */ CHECK_MSG(wallet_update_output_status(w, &u.txid, u.outnum, - output_state_any, - output_state_spent), + OUTPUT_STATE_ANY, + OUTPUT_STATE_SPENT), "could not change output state ignoring oldstate"); /* Attempt to save an UTXO with close_info set, no commitment_point */ diff --git a/wallet/wallet.c b/wallet/wallet.c index 013105780..8e13bb530 100644 --- a/wallet/wallet.c +++ b/wallet/wallet.c @@ -34,7 +34,7 @@ static void outpointfilters_init(struct wallet *w) { struct db_stmt *stmt; - struct utxo **utxos = wallet_get_utxos(NULL, w, output_state_any); + struct utxo **utxos = wallet_get_utxos(NULL, w, OUTPUT_STATE_ANY); struct bitcoin_txid txid; u32 outnum; @@ -121,7 +121,7 @@ static bool wallet_add_utxo(struct wallet *w, struct utxo *utxo, db_bind_int(stmt, 1, utxo->outnum); db_bind_amount_sat(stmt, 2, &utxo->amount); db_bind_int(stmt, 3, wallet_output_type_in_db(type)); - db_bind_int(stmt, 4, output_state_available); + db_bind_int(stmt, 4, OUTPUT_STATE_AVAILABLE); db_bind_int(stmt, 5, utxo->keyindex); if (utxo->close_info) { db_bind_u64(stmt, 6, utxo->close_info->channel_id); @@ -217,7 +217,7 @@ bool wallet_update_output_status(struct wallet *w, { struct db_stmt *stmt; size_t changes; - if (oldstatus != output_state_any) { + if (oldstatus != OUTPUT_STATE_ANY) { stmt = db_prepare_v2( w->db, SQL("UPDATE outputs SET status=? WHERE status=? AND " "prev_out_tx=? AND prev_out_index=?")); @@ -245,7 +245,7 @@ struct utxo **wallet_get_utxos(const tal_t *ctx, struct wallet *w, const enum ou int i; struct db_stmt *stmt; - if (state == output_state_any) { + if (state == OUTPUT_STATE_ANY) { stmt = db_prepare_v2(w->db, SQL("SELECT" " prev_out_tx" ", prev_out_index" @@ -378,8 +378,8 @@ bool wallet_unreserve_output(struct wallet *w, const u32 outnum) { return wallet_update_output_status(w, txid, outnum, - output_state_reserved, - output_state_available); + OUTPUT_STATE_RESERVED, + OUTPUT_STATE_AVAILABLE); } /** @@ -388,8 +388,8 @@ bool wallet_unreserve_output(struct wallet *w, static void unreserve_utxo(struct wallet *w, const struct utxo *unres) { if (!wallet_update_output_status(w, &unres->txid, unres->outnum, - output_state_reserved, - output_state_available)) { + OUTPUT_STATE_RESERVED, + OUTPUT_STATE_AVAILABLE)) { fatal("Unable to unreserve output"); } } @@ -414,7 +414,7 @@ void wallet_confirm_utxos(struct wallet *w, const struct utxo **utxos) for (size_t i = 0; i < tal_count(utxos); i++) { if (!wallet_update_output_status( w, &utxos[i]->txid, utxos[i]->outnum, - output_state_reserved, output_state_spent)) { + OUTPUT_STATE_RESERVED, OUTPUT_STATE_SPENT)) { fatal("Unable to mark output as spent"); } } @@ -424,7 +424,7 @@ static void db_set_utxo(struct db *db, const struct utxo *utxo) { struct db_stmt *stmt; - if (utxo->status == output_state_reserved) + if (utxo->status == OUTPUT_STATE_RESERVED) assert(utxo->reserved_til); else assert(!utxo->reserved_til); @@ -442,12 +442,12 @@ static void db_set_utxo(struct db *db, const struct utxo *utxo) bool wallet_reserve_utxo(struct wallet *w, struct utxo *utxo, u32 current_height) { switch (utxo->status) { - case output_state_spent: + case OUTPUT_STATE_SPENT: return false; - case output_state_available: - case output_state_reserved: + case OUTPUT_STATE_AVAILABLE: + case OUTPUT_STATE_RESERVED: break; - case output_state_any: + case OUTPUT_STATE_ANY: abort(); } @@ -457,7 +457,7 @@ bool wallet_reserve_utxo(struct wallet *w, struct utxo *utxo, u32 current_height else utxo->reserved_til = current_height + RESERVATION_INC; - utxo->status = output_state_reserved; + utxo->status = OUTPUT_STATE_RESERVED; db_set_utxo(w->db, utxo); @@ -466,13 +466,13 @@ bool wallet_reserve_utxo(struct wallet *w, struct utxo *utxo, u32 current_height void wallet_unreserve_utxo(struct wallet *w, struct utxo *utxo, u32 current_height) { - if (utxo->status != output_state_reserved) + if (utxo->status != OUTPUT_STATE_RESERVED) fatal("UTXO %s:%u is not reserved", type_to_string(tmpctx, struct bitcoin_txid, &utxo->txid), utxo->outnum); if (utxo->reserved_til <= current_height + RESERVATION_INC) { - utxo->status = output_state_available; + utxo->status = OUTPUT_STATE_AVAILABLE; utxo->reserved_til = 0; } else utxo->reserved_til -= RESERVATION_INC; @@ -534,8 +534,8 @@ struct utxo *wallet_find_utxo(const tal_t *ctx, struct wallet *w, " WHERE status = ?" " OR (status = ? AND reserved_til <= ?)" "ORDER BY RANDOM();")); - db_bind_int(stmt, 0, output_status_in_db(output_state_available)); - db_bind_int(stmt, 1, output_status_in_db(output_state_reserved)); + db_bind_int(stmt, 0, output_status_in_db(OUTPUT_STATE_AVAILABLE)); + db_bind_int(stmt, 1, output_status_in_db(OUTPUT_STATE_RESERVED)); db_bind_u64(stmt, 2, current_blockheight); /* FIXME: Use feerate + estimate of input cost to establish @@ -599,7 +599,7 @@ bool wallet_add_onchaind_utxo(struct wallet *w, db_bind_int(stmt, 1, outnum); db_bind_amount_sat(stmt, 2, &amount); db_bind_int(stmt, 3, wallet_output_type_in_db(p2wpkh)); - db_bind_int(stmt, 4, output_state_available); + db_bind_int(stmt, 4, OUTPUT_STATE_AVAILABLE); db_bind_int(stmt, 5, 0); db_bind_u64(stmt, 6, channel->dbid); db_bind_node_id(stmt, 7, &channel->peer->id); @@ -1734,7 +1734,7 @@ int wallet_extract_owned_outputs(struct wallet *w, const struct wally_tx *wtx, utxo->keyindex = index; utxo->is_p2sh = is_p2sh; utxo->amount = amount_asset_to_sat(&asset); - utxo->status = output_state_available; + utxo->status = OUTPUT_STATE_AVAILABLE; wally_txid(wtx, &utxo->txid); utxo->outnum = output; utxo->close_info = NULL; @@ -3019,7 +3019,7 @@ wallet_outpoint_spend(struct wallet *w, const tal_t *ctx, const u32 blockheight, " AND prev_out_index = ?")); db_bind_int(stmt, 0, blockheight); - db_bind_int(stmt, 1, output_status_in_db(output_state_spent)); + db_bind_int(stmt, 1, output_status_in_db(OUTPUT_STATE_SPENT)); db_bind_sha256d(stmt, 2, &txid->shad); db_bind_int(stmt, 3, outnum); diff --git a/wallet/wallet.h b/wallet/wallet.h index 73b2347e2..8220408a6 100644 --- a/wallet/wallet.h +++ b/wallet/wallet.h @@ -52,34 +52,20 @@ struct wallet { u64 keyscan_gap; }; -/* 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 */ -/* /!\ This is a DB ENUM, please do not change the numbering of any - * already defined elements (adding is ok) /!\ */ -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 -}; - static inline enum output_status output_status_in_db(enum output_status s) { switch (s) { - case output_state_available: - BUILD_ASSERT(output_state_available == 0); + case OUTPUT_STATE_AVAILABLE: + BUILD_ASSERT(OUTPUT_STATE_AVAILABLE == 0); return s; - case output_state_reserved: - BUILD_ASSERT(output_state_reserved == 1); + case OUTPUT_STATE_RESERVED: + BUILD_ASSERT(OUTPUT_STATE_RESERVED == 1); return s; - case output_state_spent: - BUILD_ASSERT(output_state_spent == 2); + case OUTPUT_STATE_SPENT: + BUILD_ASSERT(OUTPUT_STATE_SPENT == 2); return s; /* This one doesn't go into db */ - case output_state_any: + case OUTPUT_STATE_ANY: break; } fatal("%s: %u is invalid", __func__, s); diff --git a/wallet/walletrpc.c b/wallet/walletrpc.c index ce5f3aa94..26f8073d3 100644 --- a/wallet/walletrpc.c +++ b/wallet/walletrpc.c @@ -244,15 +244,6 @@ static const struct json_command listaddrs_command = { }; AUTODATA(json_command, &listaddrs_command); -bool is_reserved(const struct utxo *utxo, u32 current_height) -{ - if (utxo->status != output_state_reserved) - return false; - - return utxo->reserved_til > current_height; -} - - static void json_add_utxo(struct json_stream *response, const char *fieldname, struct wallet *wallet, @@ -297,8 +288,8 @@ static void json_add_utxo(struct json_stream *response, json_add_string(response, "status", "unconfirmed"); json_add_bool(response, "reserved", - is_reserved(utxo, - get_block_height(wallet->ld->topology))); + utxo_is_reserved(utxo, + get_block_height(wallet->ld->topology))); json_object_end(response); } @@ -324,8 +315,8 @@ static struct command_result *json_listfunds(struct command *cmd, response = json_stream_success(cmd); - utxos = wallet_get_utxos(cmd, cmd->ld->wallet, output_state_available); - reserved_utxos = wallet_get_utxos(cmd, cmd->ld->wallet, output_state_reserved); + utxos = wallet_get_utxos(cmd, cmd->ld->wallet, OUTPUT_STATE_AVAILABLE); + reserved_utxos = wallet_get_utxos(cmd, cmd->ld->wallet, OUTPUT_STATE_RESERVED); json_array_start(response, "outputs"); json_add_utxos(response, cmd->ld->wallet, utxos); json_add_utxos(response, cmd->ld->wallet, reserved_utxos); @@ -391,7 +382,7 @@ static void process_utxo_result(struct bitcoind *bitcoind, struct json_stream *response = rescan->response; struct utxo *u = rescan->utxos[0]; enum output_status newstate = - txout == NULL ? output_state_spent : output_state_available; + txout == NULL ? OUTPUT_STATE_SPENT : OUTPUT_STATE_AVAILABLE; json_object_start(rescan->response, NULL); json_add_txid(response, "txid", &u->txid); @@ -432,7 +423,7 @@ static struct command_result *json_dev_rescan_outputs(struct command *cmd, /* Open the outputs structure so we can incrementally add results */ json_array_start(rescan->response, "outputs"); - rescan->utxos = wallet_get_utxos(rescan, cmd->ld->wallet, output_state_any); + rescan->utxos = wallet_get_utxos(rescan, cmd->ld->wallet, OUTPUT_STATE_ANY); if (tal_count(rescan->utxos) == 0) { json_array_end(rescan->response); return command_success(cmd, rescan->response); @@ -654,7 +645,7 @@ static struct command_result *match_psbt_inputs_to_utxos(struct command *cmd, } /* Oops we haven't reserved this utxo yet! */ - if (!is_reserved(utxo, get_block_height(cmd->ld->topology))) + if (!utxo_is_reserved(utxo, get_block_height(cmd->ld->topology))) return command_fail(cmd, LIGHTNINGD, "Aborting PSBT signing. UTXO %s:%u is not reserved", type_to_string(tmpctx, struct bitcoin_txid,