mirror of
https://github.com/ElementsProject/lightning.git
synced 2025-01-18 05:12:45 +01:00
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.
This commit is contained in:
parent
034b2c7ee4
commit
c215a00c45
@ -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…
Reference in New Issue
Block a user