Browse Source

coin moves: record cheats / loss due to 'unknown' txs

Whenever we detect an 'unknown' tx is published, we should count that as
a loss, as needed.
nifty/pset-pre
lisa neigut 5 years ago
committed by Rusty Russell
parent
commit
c215a00c45
  1. 77
      onchaind/onchaind.c

77
onchaind/onchaind.c

@ -243,6 +243,27 @@ static void record_mutual_closure(const struct bitcoin_txid *txid,
send_coin_mvt(take(mvt));
}
static void record_coin_loss(const struct bitcoin_txid *txid,
struct tracked_output *out)
{
struct chain_coin_mvt *mvt;
/* We don't for sure know that it's a 'penalty'
* but we write it as that anyway... */
mvt = new_chain_coin_mvt_sat(NULL, NULL,
txid, &out->txid,
out->outnum, NULL,
PENALTY, out->sat, false,
BTC);
if (!mvt)
status_failed(STATUS_FAIL_INTERNAL_ERROR,
"unable to convert %s to msat",
type_to_string(tmpctx, struct amount_sat,
&out->sat));
send_coin_mvt(take(mvt));
}
static void record_channel_withdrawal_minus_fees(const struct bitcoin_txid *tx_txid,
struct tracked_output *out,
struct amount_sat fees)
@ -274,6 +295,12 @@ static void record_channel_withdrawal_minus_fees(const struct bitcoin_txid *tx_t
}
static void record_channel_withdrawal(const struct bitcoin_txid *tx_txid,
struct tracked_output *out)
{
record_channel_withdrawal_minus_fees(tx_txid, out, AMOUNT_SAT(0));
}
static bool is_our_htlc_tx(struct tracked_output *out)
{
return out->resolved &&
@ -1265,6 +1292,7 @@ static void output_spent(const struct chainparams *chainparams,
case OUTPUT_TO_US:
case DELAYED_OUTPUT_TO_US:
unknown_spend(out, tx);
record_coin_loss(&txid, out);
break;
case THEIR_HTLC:
@ -2747,6 +2775,46 @@ static void handle_their_unilateral(const struct bitcoin_tx *tx,
wait_for_resolved(tx->chainparams, outs);
}
static void update_ledger_unknown(const struct bitcoin_txid *txid,
struct amount_sat amt_salvaged)
{
/* ideally, we'd be able to capture the loss to fees (if we funded
* the channel) here separately, but given that we don't know the htlc
* set (and thus which outputs are trimmed), this is difficult.
*
* instead, we count the difference between any recoverable output
* and our current channel balance as a loss (or gain) */
bool is_credit;
struct amount_msat diff;
struct chain_coin_mvt *mvt;
/* we do nothing if the amount withdrawn via 'salvage' is
* the same as our channel balance */
if (amount_msat_eq_sat(our_msat, amt_salvaged))
return;
/* if we've withdrawn *less* in salvage than we have on the books
* as being ours, we record the difference as a debit */
if (!amount_msat_sub_sat(&diff, our_msat, amt_salvaged)) {
is_credit = false;
if (!amount_sat_sub_msat(&diff, amt_salvaged, our_msat))
status_failed(STATUS_FAIL_INTERNAL_ERROR,
"overflow subtracting %s from %s",
type_to_string(tmpctx, struct amount_msat,
&our_msat),
type_to_string(tmpctx, struct amount_sat,
&amt_salvaged));
} else
is_credit = true;
/* FIXME: elements txs not in BTC ?? */
mvt = new_chain_coin_mvt(NULL, NULL,
txid, NULL, 0, NULL,
JOURNAL, diff,
is_credit, BTC);
send_coin_mvt(take(mvt));
}
static void handle_unknown_commitment(const struct bitcoin_tx *tx,
u32 tx_blockheight,
u64 commit_num,
@ -2759,6 +2827,7 @@ static void handle_unknown_commitment(const struct bitcoin_tx *tx,
{
int to_us_output = -1;
u8 *local_script;
struct amount_sat amt_salvaged = AMOUNT_SAT(0);
onchain_annotate_txin(txid, 0, TX_CHANNEL_UNILATERAL | TX_THEIRS);
@ -2767,8 +2836,9 @@ static void handle_unknown_commitment(const struct bitcoin_tx *tx,
/* If they don't give us a per-commitment point and we rotate keys,
* we're out of luck. */
if (!possible_remote_per_commitment_point
&& !option_static_remotekey)
&& !option_static_remotekey) {
goto search_done;
}
if (!option_static_remotekey) {
struct keyset *ks = tal(tmpctx, struct keyset);
@ -2822,6 +2892,7 @@ static void handle_unknown_commitment(const struct bitcoin_tx *tx,
i, amt,
OUTPUT_TO_US, NULL, NULL, NULL);
ignore_output(out);
record_channel_withdrawal(txid, out);
tell_wallet_to_remote(tx, i, txid,
tx_blockheight,
@ -2845,6 +2916,10 @@ search_done:
init_reply("ERROR: Unknown commitment, recovering our funds!");
}
/* update our accounting notions for this channel.
* should result in a channel balance of zero */
update_ledger_unknown(txid, amt_salvaged);
/* Tell master to give up on HTLCs immediately. */
for (size_t i = 0; i < tal_count(htlcs); i++) {
u8 *msg;

Loading…
Cancel
Save