Browse Source

wallet-htlc: add 'we-filled' flag to saved htlc state

The current plan for coin movements involves tagging
origination/destination htlc's with a separate tag from 'routed' htlcs
(which pass through our node). In order to do this, we need a persistent flag on
incoming htlcs as to whether or not we are the final destination.
nifty/pset-pre
lisa neigut 5 years ago
committed by Rusty Russell
parent
commit
434cad0c3b
  1. 1
      lightningd/htlc_end.c
  2. 2
      lightningd/htlc_end.h
  3. 3
      lightningd/htlc_set.c
  4. 12
      lightningd/peer_htlcs.c
  5. 3
      wallet/db.c
  6. 10
      wallet/test/run-wallet.c
  7. 18
      wallet/wallet.c
  8. 4
      wallet/wallet.h

1
lightningd/htlc_end.c

@ -158,6 +158,7 @@ struct htlc_in *new_htlc_in(const tal_t *ctx,
hin->badonion = 0; hin->badonion = 0;
hin->failonion = NULL; hin->failonion = NULL;
hin->preimage = NULL; hin->preimage = NULL;
hin->we_filled = false;
hin->received_time = time_now(); hin->received_time = time_now();

2
lightningd/htlc_end.h

@ -53,6 +53,8 @@ struct htlc_in {
struct pubkey *blinding; struct pubkey *blinding;
/* Only set if blinding != NULL */ /* Only set if blinding != NULL */
struct secret blinding_ss; struct secret blinding_ss;
/* true if we supplied the preimage */
bool we_filled;
}; };
struct htlc_out { struct htlc_out {

3
lightningd/htlc_set.c

@ -57,6 +57,9 @@ void htlc_set_fulfill(struct htlc_set *set, const struct preimage *preimage)
for (size_t i = 0; i < tal_count(set->htlcs); i++) { for (size_t i = 0; i < tal_count(set->htlcs); i++) {
/* Don't remove from set */ /* Don't remove from set */
tal_del_destructor2(set->htlcs[i], htlc_set_hin_destroyed, set); tal_del_destructor2(set->htlcs[i], htlc_set_hin_destroyed, set);
/* mark that we filled -- needed for tagging coin mvt */
set->htlcs[i]->we_filled = true;
fulfill_htlc(set->htlcs[i], preimage); fulfill_htlc(set->htlcs[i], preimage);
} }
tal_free(set); tal_free(set);

12
lightningd/peer_htlcs.c

@ -78,7 +78,8 @@ static bool htlc_in_update_state(struct channel *channel,
wallet_htlc_update(channel->peer->ld->wallet, wallet_htlc_update(channel->peer->ld->wallet,
hin->dbid, newstate, hin->preimage, hin->dbid, newstate, hin->preimage,
hin->badonion, hin->failonion, NULL); hin->badonion, hin->failonion, NULL,
hin->we_filled);
hin->hstate = newstate; hin->hstate = newstate;
return true; return true;
@ -94,7 +95,7 @@ static bool htlc_out_update_state(struct channel *channel,
wallet_htlc_update(channel->peer->ld->wallet, hout->dbid, newstate, wallet_htlc_update(channel->peer->ld->wallet, hout->dbid, newstate,
hout->preimage, 0, hout->failonion, hout->preimage, 0, hout->failonion,
hout->failmsg); hout->failmsg, false);
hout->hstate = newstate; hout->hstate = newstate;
return true; return true;
@ -187,7 +188,7 @@ static void failmsg_update_reply(struct subd *gossipd,
cbdata->hin->dbid, cbdata->hin->hstate, cbdata->hin->dbid, cbdata->hin->hstate,
cbdata->hin->preimage, cbdata->hin->preimage,
cbdata->hin->badonion, cbdata->hin->badonion,
cbdata->hin->failonion, NULL); cbdata->hin->failonion, NULL, false);
failed_htlc = mk_failed_htlc(tmpctx, failed_htlc = mk_failed_htlc(tmpctx,
cbdata->hin, cbdata->hin->failonion); cbdata->hin, cbdata->hin->failonion);
@ -850,6 +851,7 @@ htlc_accepted_hook_try_resolve(struct htlc_accepted_hook_payload *request,
towire_u16(&unknown_details, 0x400f); towire_u16(&unknown_details, 0x400f);
local_fail_in_htlc(hin, take(unknown_details)); local_fail_in_htlc(hin, take(unknown_details));
} else { } else {
hin->we_filled = true;
fulfill_htlc(hin, payment_preimage); fulfill_htlc(hin, payment_preimage);
} }
} }
@ -1247,7 +1249,7 @@ static void fulfill_our_htlc_out(struct channel *channel, struct htlc_out *hout,
wallet_htlc_update(ld->wallet, hout->dbid, hout->hstate, wallet_htlc_update(ld->wallet, hout->dbid, hout->hstate,
hout->preimage, 0, hout->failonion, hout->preimage, 0, hout->failonion,
hout->failmsg); hout->failmsg, false);
/* Update channel stats */ /* Update channel stats */
wallet_channel_stats_incr_out_fulfilled(ld->wallet, wallet_channel_stats_incr_out_fulfilled(ld->wallet,
channel->dbid, channel->dbid,
@ -1416,7 +1418,7 @@ void onchain_failed_our_htlc(const struct channel *channel,
htlc_out_check(hout, __func__); htlc_out_check(hout, __func__);
wallet_htlc_update(ld->wallet, hout->dbid, hout->hstate, wallet_htlc_update(ld->wallet, hout->dbid, hout->hstate,
hout->preimage, 0, hout->failonion, hout->preimage, 0, hout->failonion,
hout->failmsg); hout->failmsg, false);
if (hout->am_origin) { if (hout->am_origin) {
assert(why != NULL); assert(why != NULL);

3
wallet/db.c

@ -607,6 +607,9 @@ static struct migration dbmigrations[] = {
", amount BIGINT" ", amount BIGINT"
", PRIMARY KEY (channel_id, commitnum)" ", PRIMARY KEY (channel_id, commitnum)"
");"), NULL}, ");"), NULL},
/* For incoming HTLCs, we now keep track of whether or not we provided
* the preimage for it, or not. */
{SQL("ALTER TABLE channel_htlcs ADD we_filled INTEGER;"), NULL},
}; };
/* Leak tracking. */ /* Leak tracking. */

10
wallet/test/run-wallet.c

@ -1311,17 +1311,17 @@ static bool test_htlc_crud(struct lightningd *ld, const tal_t *ctx)
wallet_err = tal_free(wallet_err); wallet_err = tal_free(wallet_err);
/* Update */ /* Update */
CHECK_MSG(transaction_wrap(w->db, wallet_htlc_update(w, in.dbid, RCVD_ADD_HTLC, NULL, 0, NULL, NULL)), CHECK_MSG(transaction_wrap(w->db, wallet_htlc_update(w, in.dbid, RCVD_ADD_HTLC, NULL, 0, NULL, NULL, false)),
"Update HTLC with null payment_key failed"); "Update HTLC with null payment_key failed");
CHECK_MSG( CHECK_MSG(
transaction_wrap(w->db, wallet_htlc_update(w, in.dbid, SENT_REMOVE_HTLC, &payment_key, 0, NULL, NULL)), transaction_wrap(w->db, wallet_htlc_update(w, in.dbid, SENT_REMOVE_HTLC, &payment_key, 0, NULL, NULL, false)),
"Update HTLC with payment_key failed"); "Update HTLC with payment_key failed");
onionreply = new_onionreply(tmpctx, tal_arrz(tmpctx, u8, 100)); onionreply = new_onionreply(tmpctx, tal_arrz(tmpctx, u8, 100));
CHECK_MSG( CHECK_MSG(
transaction_wrap(w->db, wallet_htlc_update(w, in.dbid, SENT_REMOVE_HTLC, NULL, 0, onionreply, NULL)), transaction_wrap(w->db, wallet_htlc_update(w, in.dbid, SENT_REMOVE_HTLC, NULL, 0, onionreply, NULL, false)),
"Update HTLC with failonion failed"); "Update HTLC with failonion failed");
CHECK_MSG( CHECK_MSG(
transaction_wrap(w->db, wallet_htlc_update(w, in.dbid, SENT_REMOVE_HTLC, NULL, WIRE_INVALID_ONION_VERSION, NULL, NULL)), transaction_wrap(w->db, wallet_htlc_update(w, in.dbid, SENT_REMOVE_HTLC, NULL, WIRE_INVALID_ONION_VERSION, NULL, NULL, false)),
"Update HTLC with failcode failed"); "Update HTLC with failcode failed");
CHECK_MSG(transaction_wrap(w->db, wallet_htlc_save_out(w, chan, &out)), CHECK_MSG(transaction_wrap(w->db, wallet_htlc_save_out(w, chan, &out)),
@ -1333,7 +1333,7 @@ static bool test_htlc_crud(struct lightningd *ld, const tal_t *ctx)
CHECK(wallet_err); CHECK(wallet_err);
wallet_err = tal_free(wallet_err); wallet_err = tal_free(wallet_err);
CHECK_MSG( CHECK_MSG(
transaction_wrap(w->db, wallet_htlc_update(w, out.dbid, SENT_ADD_ACK_REVOCATION, NULL, 0, NULL, tal_arrz(tmpctx, u8, 100))), transaction_wrap(w->db, wallet_htlc_update(w, out.dbid, SENT_ADD_ACK_REVOCATION, NULL, 0, NULL, tal_arrz(tmpctx, u8, 100), false)),
"Update outgoing HTLC with failmsg failed"); "Update outgoing HTLC with failmsg failed");
/* Attempt to load them from the DB again */ /* Attempt to load them from the DB again */

18
wallet/wallet.c

@ -1785,13 +1785,14 @@ void wallet_htlc_save_out(struct wallet *wallet,
tal_free(stmt); tal_free(stmt);
} }
/* input htlcs use failcode & failonion, output htlcs use failmsg & failonion */ /* input htlcs use failcode & failonion & we_filled, output htlcs use failmsg & failonion */
void wallet_htlc_update(struct wallet *wallet, const u64 htlc_dbid, void wallet_htlc_update(struct wallet *wallet, const u64 htlc_dbid,
const enum htlc_state new_state, const enum htlc_state new_state,
const struct preimage *payment_key, const struct preimage *payment_key,
enum onion_type badonion, enum onion_type badonion,
const struct onionreply *failonion, const struct onionreply *failonion,
const u8 *failmsg) const u8 *failmsg,
bool we_filled)
{ {
struct db_stmt *stmt; struct db_stmt *stmt;
@ -1803,12 +1804,13 @@ void wallet_htlc_update(struct wallet *wallet, const u64 htlc_dbid,
assert(htlc_dbid); assert(htlc_dbid);
stmt = db_prepare_v2( stmt = db_prepare_v2(
wallet->db, SQL("UPDATE channel_htlcs SET hstate=?, payment_key=?, " wallet->db, SQL("UPDATE channel_htlcs SET hstate=?, payment_key=?, "
"malformed_onion=?, failuremsg=?, localfailmsg=?" "malformed_onion=?, failuremsg=?, localfailmsg=?, "
"we_filled=?"
" WHERE id=?")); " WHERE id=?"));
/* FIXME: htlc_state_in_db */ /* FIXME: htlc_state_in_db */
db_bind_int(stmt, 0, new_state); db_bind_int(stmt, 0, new_state);
db_bind_u64(stmt, 5, htlc_dbid); db_bind_u64(stmt, 6, htlc_dbid);
if (payment_key) if (payment_key)
db_bind_preimage(stmt, 1, payment_key); db_bind_preimage(stmt, 1, payment_key);
@ -1827,6 +1829,11 @@ void wallet_htlc_update(struct wallet *wallet, const u64 htlc_dbid,
else else
db_bind_null(stmt, 4); db_bind_null(stmt, 4);
if (we_filled)
db_bind_int(stmt, 5, 1);
else
db_bind_null(stmt, 5);
db_exec_prepared_v2(take(stmt)); db_exec_prepared_v2(take(stmt));
} }
@ -1897,6 +1904,8 @@ static bool wallet_stmt2htlc_in(struct channel *channel,
} }
#endif #endif
in->we_filled = !db_column_is_null(stmt, 13);
return ok; return ok;
} }
@ -2023,6 +2032,7 @@ bool wallet_htlcs_load_in_for_channel(struct wallet *wallet,
", origin_htlc" ", origin_htlc"
", shared_secret" ", shared_secret"
", received_time" ", received_time"
", we_filled"
" FROM channel_htlcs" " FROM channel_htlcs"
" WHERE direction= ?" " WHERE direction= ?"
" AND channel_id= ?" " AND channel_id= ?"

4
wallet/wallet.h

@ -596,6 +596,7 @@ void wallet_htlc_save_out(struct wallet *wallet,
* @badonion: the current BADONION failure code, or 0. * @badonion: the current BADONION failure code, or 0.
* @failonion: the current failure onion message (from peer), or NULL. * @failonion: the current failure onion message (from peer), or NULL.
* @failmsg: the current local failure message, or NULL. * @failmsg: the current local failure message, or NULL.
* @we_filled: for htlc-ins, true if we originated the preimage.
* *
* Used to update the state of an HTLC, either a `struct htlc_in` or a * Used to update the state of an HTLC, either a `struct htlc_in` or a
* `struct htlc_out` and optionally set the `payment_key` should the * `struct htlc_out` and optionally set the `payment_key` should the
@ -606,7 +607,8 @@ void wallet_htlc_update(struct wallet *wallet, const u64 htlc_dbid,
const struct preimage *payment_key, const struct preimage *payment_key,
enum onion_type badonion, enum onion_type badonion,
const struct onionreply *failonion, const struct onionreply *failonion,
const u8 *failmsg); const u8 *failmsg,
bool we_filled);
/** /**
* wallet_htlcs_load_in_for_channel - Load incoming HTLCs associated with chan from DB. * wallet_htlcs_load_in_for_channel - Load incoming HTLCs associated with chan from DB.

Loading…
Cancel
Save