Skip to content

Commit

Permalink
wallet: Add new htlc column "localfailmsg" for outgoing htlcs.
Browse files Browse the repository at this point in the history
We're going to change our internal structure next, so this is preparation.
We populate existing errors with temporary node failures, for simplicity.

Signed-off-by: Rusty Russell <[email protected]>
  • Loading branch information
rustyrussell committed Feb 25, 2020
1 parent cec18df commit a150b09
Show file tree
Hide file tree
Showing 6 changed files with 41 additions and 13 deletions.
2 changes: 2 additions & 0 deletions devtools/sql-rewrite.py
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,8 @@ def rewrite_single(self, query):
r'BIGSERIAL': 'INTEGER',
r'CURRENT_TIMESTAMP\(\)': "strftime('%s', 'now')",
r'INSERT INTO[ \t]+(.*)[ \t]+ON CONFLICT.*DO NOTHING;': 'INSERT OR IGNORE INTO \\1;',
# Rewrite "decode('abcd', 'hex')" to become "x'abcd'"
r'decode\((.*),\s*[\'\"]hex[\'\"]\)': 'x\\1',
}
return self.rewrite_types(query, typemapping)

Expand Down
11 changes: 7 additions & 4 deletions lightningd/peer_htlcs.c
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ static bool htlc_in_update_state(struct channel *channel,

wallet_htlc_update(channel->peer->ld->wallet,
hin->dbid, newstate, hin->preimage,
hin->failcode, hin->failonion);
hin->failcode, hin->failonion, NULL);

hin->hstate = newstate;
return true;
Expand All @@ -91,7 +91,8 @@ static bool htlc_out_update_state(struct channel *channel,
return false;

wallet_htlc_update(channel->peer->ld->wallet, hout->dbid, newstate,
hout->preimage, hout->failcode, hout->failonion);
hout->preimage, hout->failcode, hout->failonion,
NULL);

hout->hstate = newstate;
return true;
Expand Down Expand Up @@ -1100,7 +1101,8 @@ static void fulfill_our_htlc_out(struct channel *channel, struct htlc_out *hout,
htlc_out_check(hout, __func__);

wallet_htlc_update(ld->wallet, hout->dbid, hout->hstate,
hout->preimage, hout->failcode, hout->failonion);
hout->preimage, hout->failcode, hout->failonion,
NULL);
/* Update channel stats */
wallet_channel_stats_incr_out_fulfilled(ld->wallet,
channel->dbid,
Expand Down Expand Up @@ -1281,7 +1283,8 @@ void onchain_failed_our_htlc(const struct channel *channel,
hout->hstate = RCVD_REMOVE_HTLC;
htlc_out_check(hout, __func__);
wallet_htlc_update(ld->wallet, hout->dbid, hout->hstate,
hout->preimage, hout->failcode, hout->failonion);
hout->preimage, hout->failcode, hout->failonion,
NULL);

if (hout->am_origin) {
assert(why != NULL);
Expand Down
4 changes: 4 additions & 0 deletions wallet/db.c
Original file line number Diff line number Diff line change
Expand Up @@ -592,6 +592,10 @@ static struct migration dbmigrations[] = {
NULL},
/* FIXME: Remove now-unused local_feerate_per_kw and remote_feerate_per_kw from channels */
{SQL("INSERT INTO vars (name, intval) VALUES ('data_version', 0);"), NULL},
/* For outgoing HTLCs, we now keep a localmsg instead of a failcode.
* Turn anything in transition into a WIRE_TEMPORARY_NODE_FAILURE. */
{SQL("ALTER TABLE channel_htlcs ADD localfailmsg BLOB;"), NULL},
{SQL("UPDATE channel_htlcs SET localfailmsg=decode('2002', 'hex') WHERE malformed_onion != 0 AND direction = 1;"), NULL},
};

/* Leak tracking. */
Expand Down
14 changes: 10 additions & 4 deletions wallet/test/run-wallet.c
Original file line number Diff line number Diff line change
Expand Up @@ -1316,15 +1316,18 @@ static bool test_htlc_crud(struct lightningd *ld, const tal_t *ctx)
wallet_err = tal_free(wallet_err);

/* Update */
CHECK_MSG(transaction_wrap(w->db, wallet_htlc_update(w, in.dbid, RCVD_ADD_HTLC, NULL, 0, NULL)),
CHECK_MSG(transaction_wrap(w->db, wallet_htlc_update(w, in.dbid, RCVD_ADD_HTLC, NULL, 0, NULL, NULL)),
"Update HTLC with null payment_key failed");
CHECK_MSG(
transaction_wrap(w->db, wallet_htlc_update(w, in.dbid, SENT_REMOVE_HTLC, &payment_key, 0, NULL)),
transaction_wrap(w->db, wallet_htlc_update(w, in.dbid, SENT_REMOVE_HTLC, &payment_key, 0, NULL, NULL)),
"Update HTLC with payment_key failed");
onionreply = new_onionreply(tmpctx, tal_arrz(tmpctx, u8, 100));
CHECK_MSG(
transaction_wrap(w->db, wallet_htlc_update(w, in.dbid, SENT_REMOVE_HTLC, NULL, 0, onionreply)),
"Update HTLC with failreason failed");
transaction_wrap(w->db, wallet_htlc_update(w, in.dbid, SENT_REMOVE_HTLC, NULL, 0, onionreply, NULL)),
"Update HTLC with failonion failed");
CHECK_MSG(
transaction_wrap(w->db, wallet_htlc_update(w, in.dbid, SENT_REMOVE_HTLC, NULL, 0x2002, NULL, NULL)),
"Update HTLC with failcode failed");

CHECK_MSG(transaction_wrap(w->db, wallet_htlc_save_out(w, chan, &out)),
tal_fmt(ctx, "Save htlc_out failed: %s", wallet_err));
Expand All @@ -1334,6 +1337,9 @@ static bool test_htlc_crud(struct lightningd *ld, const tal_t *ctx)
"Saving two HTLCs with the same data must not succeed.");
CHECK(wallet_err);
wallet_err = tal_free(wallet_err);
CHECK_MSG(
transaction_wrap(w->db, wallet_htlc_update(w, out.dbid, SENT_ADD_ACK_REVOCATION, NULL, 0, NULL, tal_arrz(tmpctx, u8, 100))),
"Update outgoing HTLC with failmsg failed");

/* Attempt to load them from the DB again */
htlc_in_map_init(htlcs_in);
Expand Down
17 changes: 14 additions & 3 deletions wallet/wallet.c
Original file line number Diff line number Diff line change
Expand Up @@ -1755,11 +1755,13 @@ void wallet_htlc_save_out(struct wallet *wallet,
tal_free(stmt);
}

/* input htlcs use failcode & failonion, output htlcs use failmsg & failonion */
void wallet_htlc_update(struct wallet *wallet, const u64 htlc_dbid,
const enum htlc_state new_state,
const struct preimage *payment_key,
enum onion_type failcode,
const struct onionreply *failonion)
const struct onionreply *failonion,
const u8 *failmsg)
{
struct db_stmt *stmt;

Expand All @@ -1768,23 +1770,30 @@ void wallet_htlc_update(struct wallet *wallet, const u64 htlc_dbid,
assert(htlc_dbid);
stmt = db_prepare_v2(
wallet->db, SQL("UPDATE channel_htlcs SET hstate=?, payment_key=?, "
"malformed_onion=?, failuremsg=? WHERE id=?"));
"malformed_onion=?, failuremsg=?, localfailmsg=?"
" WHERE id=?"));

/* FIXME: htlc_state_in_db */
db_bind_int(stmt, 0, new_state);
db_bind_u64(stmt, 4, htlc_dbid);
db_bind_u64(stmt, 5, htlc_dbid);

if (payment_key)
db_bind_preimage(stmt, 1, payment_key);
else
db_bind_null(stmt, 1);

db_bind_int(stmt, 2, failcode);

if (failonion)
db_bind_onionreply(stmt, 3, failonion);
else
db_bind_null(stmt, 3);

if (failmsg)
db_bind_blob(stmt, 4, failmsg, tal_bytelen(failmsg));
else
db_bind_null(stmt, 4);

db_exec_prepared_v2(take(stmt));
}

Expand Down Expand Up @@ -1872,6 +1881,7 @@ static bool wallet_stmt2htlc_out(struct wallet *wallet,
out->failonion = NULL;
else
out->failonion = db_column_onionreply(out, stmt, 8);

out->failcode = db_column_int_or_default(stmt, 9, 0);
out->in = NULL;

Expand Down Expand Up @@ -2002,6 +2012,7 @@ bool wallet_htlcs_load_out_for_channel(struct wallet *wallet,
", shared_secret"
", received_time"
", partid"
", localfailmsg"
" FROM channel_htlcs"
" WHERE direction = ?"
" AND channel_id = ?"
Expand Down
6 changes: 4 additions & 2 deletions wallet/wallet.h
Original file line number Diff line number Diff line change
Expand Up @@ -582,7 +582,8 @@ void wallet_htlc_save_out(struct wallet *wallet,
* @payment_key: the `payment_key` which hashes to the `payment_hash`,
* or NULL if unknown.
* @failcode: the current failure code, or 0.
* @failonion: the current failure message (from peer), or NULL.
* @failonion: the current failure onion message (from peer), or NULL.
* @failmsg: the current local failure message, or NULL.
*
* 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
Expand All @@ -592,7 +593,8 @@ void wallet_htlc_update(struct wallet *wallet, const u64 htlc_dbid,
const enum htlc_state new_state,
const struct preimage *payment_key,
enum onion_type failcode,
const struct onionreply *failonion);
const struct onionreply *failonion,
const u8 *failmsg);

/**
* wallet_htlcs_load_in_for_channel - Load incoming HTLCs associated with chan from DB.
Expand Down

0 comments on commit a150b09

Please sign in to comment.