Skip to content

Commit

Permalink
utxo: expose is_reserved, make enum constants upper case.
Browse files Browse the repository at this point in the history
Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
  • Loading branch information
rustyrussell committed Aug 14, 2020
1 parent 8ccab01 commit 91e98ef
Show file tree
Hide file tree
Showing 6 changed files with 76 additions and 76 deletions.
25 changes: 24 additions & 1 deletion common/utxo.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,13 +21,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 */
Expand All @@ -46,6 +60,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);

Expand Down
16 changes: 8 additions & 8 deletions wallet/reservation.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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);
Expand Down Expand Up @@ -96,15 +96,15 @@ 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,
struct bitcoin_txid,
&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,
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -457,7 +457,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,
Expand Down Expand Up @@ -506,7 +506,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,
Expand Down
16 changes: 8 additions & 8 deletions wallet/test/run-wallet.c
Original file line number Diff line number Diff line change
Expand Up @@ -958,26 +958,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 */
Expand Down
44 changes: 22 additions & 22 deletions wallet/wallet.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand Down Expand Up @@ -120,7 +120,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);
Expand Down Expand Up @@ -212,7 +212,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=?"));
Expand Down Expand Up @@ -240,7 +240,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"
Expand Down Expand Up @@ -369,8 +369,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);
}

/**
Expand All @@ -379,8 +379,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");
}
}
Expand All @@ -405,7 +405,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");
}
}
Expand All @@ -415,7 +415,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);
Expand All @@ -433,12 +433,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();
}

Expand All @@ -448,7 +448,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);

Expand All @@ -457,13 +457,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;
Expand Down Expand Up @@ -524,8 +524,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
Expand Down Expand Up @@ -588,7 +588,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);
Expand Down Expand Up @@ -1717,7 +1717,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;
Expand Down Expand Up @@ -3010,7 +3010,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);

Expand Down
28 changes: 7 additions & 21 deletions wallet/wallet.h
Original file line number Diff line number Diff line change
Expand Up @@ -53,34 +53,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);
Expand Down

0 comments on commit 91e98ef

Please sign in to comment.