Browse Source

wallet: Add new htlc column "localfailmsg" for outgoing htlcs.

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 <rusty@rustcorp.com.au>
travis-debug
Rusty Russell 5 years ago
parent
commit
a150b09665
  1. 2
      devtools/sql-rewrite.py
  2. 11
      lightningd/peer_htlcs.c
  3. 4
      wallet/db.c
  4. 14
      wallet/test/run-wallet.c
  5. 17
      wallet/wallet.c
  6. 6
      wallet/wallet.h

2
devtools/sql-rewrite.py

@ -41,6 +41,8 @@ class Sqlite3Rewriter(Rewriter):
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)

11
lightningd/peer_htlcs.c

@ -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;
@ -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;
@ -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,
@ -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);

4
wallet/db.c

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

14
wallet/test/run-wallet.c

@ -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));
@ -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);

17
wallet/wallet.c

@ -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;
@ -1768,11 +1770,12 @@ 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);
@ -1780,11 +1783,17 @@ void wallet_htlc_update(struct wallet *wallet, const u64 htlc_dbid,
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));
}
@ -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;
@ -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 = ?"

6
wallet/wallet.h

@ -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
@ -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.

Loading…
Cancel
Save