mirror of
https://github.com/ElementsProject/lightning.git
synced 2025-01-18 05:12:45 +01:00
onchaind: add recovery scans for option-will-fund
option_will_fund changes the to_remote/to_local commitment tx outputs by altering the CSV lock for leased channels. We need to grind/scan for these outputs now, provided the defaults don't work.
This commit is contained in:
parent
5989433810
commit
5041073a55
@ -36,6 +36,7 @@
|
||||
/* stdin == requests */
|
||||
#define REQ_FD STDIN_FILENO
|
||||
#define HSM_FD 3
|
||||
#define max(a, b) ((a) > (b) ? (a) : (b))
|
||||
|
||||
/* Required in various places: keys for commitment transaction. */
|
||||
static const struct keyset *keyset;
|
||||
@ -2583,12 +2584,66 @@ static u8 *scriptpubkey_to_remote(const tal_t *ctx,
|
||||
}
|
||||
}
|
||||
|
||||
static void our_unilateral_to_us(struct tracked_output ***outs,
|
||||
const struct tx_parts *tx,
|
||||
u32 tx_blockheight,
|
||||
size_t index,
|
||||
struct amount_sat amt,
|
||||
u16 sequence,
|
||||
const u8 *local_scriptpubkey,
|
||||
const u8 *local_wscript,
|
||||
bool is_replay)
|
||||
{
|
||||
struct bitcoin_tx *to_us;
|
||||
struct tracked_output *out;
|
||||
enum tx_type tx_type = OUR_DELAYED_RETURN_TO_WALLET;
|
||||
|
||||
/* BOLT #5:
|
||||
*
|
||||
* A node:
|
||||
* - upon discovering its *local commitment
|
||||
* transaction*:
|
||||
* - SHOULD spend the `to_local` output to a
|
||||
* convenient address.
|
||||
* - MUST wait until the `OP_CHECKSEQUENCEVERIFY`
|
||||
* delay has passed (as specified by the remote
|
||||
* node's `to_self_delay` field) before spending
|
||||
* the output.
|
||||
*/
|
||||
out = new_tracked_output(outs, &tx->txid, tx_blockheight,
|
||||
OUR_UNILATERAL, index,
|
||||
amt,
|
||||
DELAYED_OUTPUT_TO_US,
|
||||
NULL, NULL, NULL);
|
||||
/* BOLT #3:
|
||||
*
|
||||
* The output is spent by an input with
|
||||
* `nSequence` field set to `to_self_delay` (which can
|
||||
* only be valid after that duration has passed) and
|
||||
* witness:
|
||||
*
|
||||
* <local_delayedsig> <>
|
||||
*/
|
||||
to_us = tx_to_us(out, delayed_payment_to_us, out,
|
||||
sequence, 0, NULL, 0,
|
||||
local_wscript, &tx_type,
|
||||
delayed_to_us_feerate);
|
||||
|
||||
/* BOLT #5:
|
||||
*
|
||||
* Note: if the output is spent (as recommended), the
|
||||
* output is *resolved* by the spending transaction
|
||||
*/
|
||||
propose_resolution(out, to_us, sequence, tx_type, is_replay);
|
||||
}
|
||||
|
||||
static void handle_our_unilateral(const struct tx_parts *tx,
|
||||
u32 tx_blockheight,
|
||||
const struct basepoints basepoints[NUM_SIDES],
|
||||
const struct htlc_stub *htlcs,
|
||||
const bool *tell_if_missing,
|
||||
const bool *tell_immediately,
|
||||
const enum side opener,
|
||||
const struct bitcoin_signature *remote_htlc_sigs,
|
||||
struct tracked_output **outs,
|
||||
bool is_replay)
|
||||
@ -2701,47 +2756,10 @@ static void handle_our_unilateral(const struct tx_parts *tx,
|
||||
} else if (script[LOCAL]
|
||||
&& wally_tx_output_scripteq(tx->outputs[i],
|
||||
script[LOCAL])) {
|
||||
struct bitcoin_tx *to_us;
|
||||
enum tx_type tx_type = OUR_DELAYED_RETURN_TO_WALLET;
|
||||
|
||||
/* BOLT #5:
|
||||
*
|
||||
* A node:
|
||||
* - upon discovering its *local commitment
|
||||
* transaction*:
|
||||
* - SHOULD spend the `to_local` output to a
|
||||
* convenient address.
|
||||
* - MUST wait until the `OP_CHECKSEQUENCEVERIFY`
|
||||
* delay has passed (as specified by the remote
|
||||
* node's `to_self_delay` field) before spending
|
||||
* the output.
|
||||
*/
|
||||
out = new_tracked_output(&outs, &tx->txid, tx_blockheight,
|
||||
OUR_UNILATERAL, i,
|
||||
amt,
|
||||
DELAYED_OUTPUT_TO_US,
|
||||
NULL, NULL, NULL);
|
||||
/* BOLT #3:
|
||||
*
|
||||
* The output is spent by an input with
|
||||
* `nSequence` field set to `to_self_delay` (which can
|
||||
* only be valid after that duration has passed) and
|
||||
* witness:
|
||||
*
|
||||
* <local_delayedsig> <>
|
||||
*/
|
||||
to_us = tx_to_us(out, delayed_payment_to_us, out,
|
||||
to_self_delay[LOCAL], 0, NULL, 0,
|
||||
local_wscript, &tx_type,
|
||||
delayed_to_us_feerate);
|
||||
|
||||
/* BOLT #5:
|
||||
*
|
||||
* Note: if the output is spent (as recommended), the
|
||||
* output is *resolved* by the spending transaction
|
||||
*/
|
||||
propose_resolution(out, to_us, to_self_delay[LOCAL],
|
||||
tx_type, is_replay);
|
||||
our_unilateral_to_us(&outs, tx, tx_blockheight,
|
||||
i, amt, to_self_delay[LOCAL],
|
||||
script[LOCAL],
|
||||
local_wscript, is_replay);
|
||||
|
||||
script[LOCAL] = NULL;
|
||||
add_amt(&our_outs, amt);
|
||||
@ -2798,6 +2816,81 @@ static void handle_our_unilateral(const struct tx_parts *tx,
|
||||
matches = match_htlc_output(tmpctx, tx->outputs[i], htlc_scripts);
|
||||
/* FIXME: limp along when this happens! */
|
||||
if (tal_count(matches) == 0) {
|
||||
bool found = false;
|
||||
|
||||
/* Maybe they're using option_will_fund? */
|
||||
if (opener == REMOTE && script[LOCAL]) {
|
||||
status_debug("Grinding for our to_local");
|
||||
/* We already tried `1` */
|
||||
for (size_t csv = 2;
|
||||
csv <= LEASE_RATE_DURATION;
|
||||
csv++) {
|
||||
|
||||
local_wscript
|
||||
= to_self_wscript(tmpctx,
|
||||
to_self_delay[LOCAL],
|
||||
csv, keyset);
|
||||
|
||||
script[LOCAL]
|
||||
= scriptpubkey_p2wsh(tmpctx,
|
||||
local_wscript);
|
||||
if (!wally_tx_output_scripteq(
|
||||
tx->outputs[i],
|
||||
script[LOCAL]))
|
||||
continue;
|
||||
|
||||
our_unilateral_to_us(&outs, tx,
|
||||
tx_blockheight,
|
||||
i, amt,
|
||||
max(to_self_delay[LOCAL], csv),
|
||||
script[LOCAL],
|
||||
local_wscript,
|
||||
is_replay);
|
||||
|
||||
script[LOCAL] = NULL;
|
||||
add_amt(&our_outs, amt);
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
} else if (opener == LOCAL && script[REMOTE]) {
|
||||
status_debug("Grinding for to_remote (ours)");
|
||||
/* We already tried `1` */
|
||||
for (size_t csv = 2;
|
||||
csv <= LEASE_RATE_DURATION;
|
||||
csv++) {
|
||||
|
||||
script[REMOTE]
|
||||
= scriptpubkey_to_remote(tmpctx,
|
||||
&keyset->other_payment_key,
|
||||
csv);
|
||||
|
||||
if (!wally_tx_output_scripteq(tx->outputs[i], script[REMOTE]))
|
||||
continue;
|
||||
|
||||
/* BOLT #5:
|
||||
*
|
||||
* - MAY ignore the `to_remote` output.
|
||||
* - Note: No action is required by the local
|
||||
* node, as `to_remote` is considered *resolved*
|
||||
* by the commitment transaction itself.
|
||||
*/
|
||||
out = new_tracked_output(&outs, &tx->txid, tx_blockheight,
|
||||
OUR_UNILATERAL, i,
|
||||
amt,
|
||||
OUTPUT_TO_THEM,
|
||||
NULL, NULL, NULL);
|
||||
ignore_output(out);
|
||||
script[REMOTE] = NULL;
|
||||
add_amt(&their_outs, amt);
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (found)
|
||||
continue;
|
||||
|
||||
onchain_annotate_txout(&tx->txid, i, TX_CHANNEL_PENALTY | TX_THEIRS);
|
||||
status_failed(STATUS_FAIL_INTERNAL_ERROR,
|
||||
"Could not find resolution for output %zu",
|
||||
@ -2919,7 +3012,8 @@ static void tell_wallet_to_remote(const struct tx_parts *tx,
|
||||
u32 tx_blockheight,
|
||||
const u8 *scriptpubkey,
|
||||
const struct pubkey *per_commit_point,
|
||||
bool option_static_remotekey)
|
||||
bool option_static_remotekey,
|
||||
u32 csv_lock)
|
||||
{
|
||||
struct amount_asset asset = wally_tx_output_get_amount(tx->outputs[outnum]);
|
||||
struct amount_sat amt;
|
||||
@ -2971,6 +3065,47 @@ static void update_ledger_cheat(const struct bitcoin_txid *txid,
|
||||
blockheight, amt, true)));
|
||||
}
|
||||
|
||||
static void their_unilateral_local(struct tracked_output ***outs,
|
||||
const struct tx_parts *tx,
|
||||
u32 tx_blockheight,
|
||||
size_t index,
|
||||
struct amount_sat amt,
|
||||
const u8 *local_scriptpubkey,
|
||||
enum tx_type tx_type,
|
||||
bool is_replay,
|
||||
u32 csv_lock)
|
||||
{
|
||||
struct tracked_output *out;
|
||||
/* BOLT #5:
|
||||
*
|
||||
* - MAY take no action in regard to the associated
|
||||
* `to_remote`, which is simply a P2WPKH output to
|
||||
* the *local node*.
|
||||
* - Note: `to_remote` is considered *resolved* by the
|
||||
* commitment transaction itself.
|
||||
*/
|
||||
out = new_tracked_output(outs,
|
||||
&tx->txid,
|
||||
tx_blockheight,
|
||||
tx_type,
|
||||
index, amt,
|
||||
OUTPUT_TO_US,
|
||||
NULL, NULL,
|
||||
NULL);
|
||||
ignore_output(out);
|
||||
|
||||
if (!is_replay)
|
||||
record_channel_withdrawal(&tx->txid, tx_blockheight, out);
|
||||
|
||||
tell_wallet_to_remote(tx, index,
|
||||
tx_blockheight,
|
||||
local_scriptpubkey,
|
||||
remote_per_commitment_point,
|
||||
commit_num >= static_remotekey_start[REMOTE],
|
||||
csv_lock);
|
||||
}
|
||||
|
||||
|
||||
/* BOLT #5:
|
||||
*
|
||||
* If any node tries to cheat by broadcasting an outdated commitment
|
||||
@ -2985,6 +3120,7 @@ static void handle_their_cheat(const struct tx_parts *tx,
|
||||
const struct htlc_stub *htlcs,
|
||||
const bool *tell_if_missing,
|
||||
const bool *tell_immediately,
|
||||
const enum side opener,
|
||||
struct tracked_output **outs,
|
||||
bool is_replay)
|
||||
{
|
||||
@ -3140,28 +3276,10 @@ static void handle_their_cheat(const struct tx_parts *tx,
|
||||
if (script[LOCAL]
|
||||
&& wally_tx_output_scripteq(tx->outputs[i],
|
||||
script[LOCAL])) {
|
||||
/* BOLT #5:
|
||||
*
|
||||
* - MAY take no action regarding the _local node's
|
||||
* main output_, as this is a simple P2WPKH output
|
||||
* to itself.
|
||||
* - Note: this output is considered *resolved* by
|
||||
* the commitment transaction itself.
|
||||
*/
|
||||
out = new_tracked_output(&outs, &tx->txid, tx_blockheight,
|
||||
their_unilateral_local(&outs, tx, tx_blockheight,
|
||||
i, amt, script[LOCAL],
|
||||
THEIR_REVOKED_UNILATERAL,
|
||||
i, amt,
|
||||
OUTPUT_TO_US, NULL, NULL, NULL);
|
||||
ignore_output(out);
|
||||
|
||||
if (!is_replay)
|
||||
record_channel_withdrawal(&tx->txid, tx_blockheight, out);
|
||||
|
||||
tell_wallet_to_remote(tx, i,
|
||||
tx_blockheight,
|
||||
script[LOCAL],
|
||||
remote_per_commitment_point,
|
||||
commit_num >= static_remotekey_start[REMOTE]);
|
||||
is_replay, 1);
|
||||
script[LOCAL] = NULL;
|
||||
add_amt(&total_outs, amt);
|
||||
continue;
|
||||
@ -3214,7 +3332,71 @@ static void handle_their_cheat(const struct tx_parts *tx,
|
||||
|
||||
matches = match_htlc_output(tmpctx, tx->outputs[i], htlc_scripts);
|
||||
if (tal_count(matches) == 0) {
|
||||
status_broken("Could not find resolution for output %zu: did *we* cheat?", i);
|
||||
bool found = false;
|
||||
if (opener == REMOTE && script[LOCAL]) {
|
||||
status_debug("Grinding for commitment to_remote"
|
||||
" (ours)");
|
||||
/* We already tried `1` */
|
||||
for (size_t csv = 2;
|
||||
csv <= LEASE_RATE_DURATION;
|
||||
csv++) {
|
||||
script[LOCAL]
|
||||
= scriptpubkey_to_remote(tmpctx,
|
||||
&keyset->other_payment_key,
|
||||
csv);
|
||||
if (!wally_tx_output_scripteq(
|
||||
tx->outputs[i],
|
||||
script[LOCAL]))
|
||||
continue;
|
||||
|
||||
their_unilateral_local(&outs, tx,
|
||||
tx_blockheight,
|
||||
i, amt,
|
||||
script[LOCAL],
|
||||
THEIR_REVOKED_UNILATERAL,
|
||||
is_replay,
|
||||
csv);
|
||||
script[LOCAL] = NULL;
|
||||
add_amt(&total_outs, amt);
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
} else if (opener == LOCAL && script[REMOTE]) {
|
||||
status_debug("Grinding for commitment to_local"
|
||||
" (theirs)");
|
||||
for (size_t csv = 2;
|
||||
csv <= LEASE_RATE_DURATION;
|
||||
csv++) {
|
||||
remote_wscript
|
||||
= to_self_wscript(tmpctx,
|
||||
to_self_delay[REMOTE],
|
||||
csv, keyset);
|
||||
script[REMOTE]
|
||||
= scriptpubkey_p2wsh(tmpctx,
|
||||
remote_wscript);
|
||||
|
||||
|
||||
if (!wally_tx_output_scripteq(tx->outputs[i], script[REMOTE]))
|
||||
continue;
|
||||
|
||||
out = new_tracked_output(&outs, &tx->txid, tx_blockheight,
|
||||
THEIR_REVOKED_UNILATERAL, i,
|
||||
amt,
|
||||
DELAYED_CHEAT_OUTPUT_TO_THEM,
|
||||
NULL, NULL, NULL);
|
||||
steal_to_them_output(out, csv,
|
||||
is_replay);
|
||||
script[REMOTE] = NULL;
|
||||
add_amt(&total_outs, amt);
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!found)
|
||||
status_broken("Could not find resolution"
|
||||
" for output %zu: did"
|
||||
" *we* cheat?", i);
|
||||
continue;
|
||||
}
|
||||
|
||||
@ -3283,6 +3465,7 @@ static void handle_their_unilateral(const struct tx_parts *tx,
|
||||
const struct htlc_stub *htlcs,
|
||||
const bool *tell_if_missing,
|
||||
const bool *tell_immediately,
|
||||
const enum side opener,
|
||||
struct tracked_output **outs,
|
||||
bool is_replay)
|
||||
{
|
||||
@ -3368,26 +3551,9 @@ static void handle_their_unilateral(const struct tx_parts *tx,
|
||||
type_to_string(tmpctx, struct pubkey,
|
||||
&keyset->other_htlc_key));
|
||||
|
||||
remote_wscript = to_self_wscript(tmpctx, to_self_delay[REMOTE],
|
||||
1, keyset);
|
||||
|
||||
/* Figure out what to-them output looks like. */
|
||||
script[REMOTE] = scriptpubkey_p2wsh(tmpctx, remote_wscript);
|
||||
|
||||
/* Figure out what direct to-us output looks like. */
|
||||
script[LOCAL] = scriptpubkey_to_remote(tmpctx,
|
||||
&keyset->other_payment_key, 1);
|
||||
|
||||
/* Calculate all the HTLC scripts so we can match them */
|
||||
htlc_scripts = derive_htlc_scripts(htlcs, REMOTE);
|
||||
|
||||
status_debug("Script to-them: %u: %s (%s)",
|
||||
to_self_delay[REMOTE],
|
||||
tal_hex(tmpctx, script[REMOTE]),
|
||||
tal_hex(tmpctx, remote_wscript));
|
||||
status_debug("Script to-me: %s",
|
||||
tal_hex(tmpctx, script[LOCAL]));
|
||||
|
||||
get_anchor_scriptpubkeys(tmpctx, anchor);
|
||||
|
||||
for (i = 0; i < tal_count(tx->outputs); i++) {
|
||||
@ -3398,6 +3564,21 @@ static void handle_their_unilateral(const struct tx_parts *tx,
|
||||
tx->outputs[i]->script_len));
|
||||
}
|
||||
|
||||
remote_wscript = to_self_wscript(tmpctx, to_self_delay[REMOTE],
|
||||
1, keyset);
|
||||
script[REMOTE] = scriptpubkey_p2wsh(tmpctx, remote_wscript);
|
||||
|
||||
script[LOCAL] = scriptpubkey_to_remote(tmpctx,
|
||||
&keyset->other_payment_key,
|
||||
1);
|
||||
|
||||
status_debug("Script to-them: %u: %s (%s)",
|
||||
to_self_delay[REMOTE],
|
||||
tal_hex(tmpctx, script[REMOTE]),
|
||||
tal_hex(tmpctx, remote_wscript));
|
||||
status_debug("Script to-me: %s",
|
||||
tal_hex(tmpctx, script[LOCAL]));
|
||||
|
||||
for (i = 0; i < tal_count(tx->outputs); i++) {
|
||||
struct tracked_output *out;
|
||||
const size_t *matches;
|
||||
@ -3421,28 +3602,11 @@ static void handle_their_unilateral(const struct tx_parts *tx,
|
||||
} else if (script[LOCAL]
|
||||
&& wally_tx_output_scripteq(tx->outputs[i],
|
||||
script[LOCAL])) {
|
||||
/* BOLT #5:
|
||||
*
|
||||
* - MAY take no action in regard to the associated
|
||||
* `to_remote`, which is simply a P2WPKH output to
|
||||
* the *local node*.
|
||||
* - Note: `to_remote` is considered *resolved* by the
|
||||
* commitment transaction itself.
|
||||
*/
|
||||
out = new_tracked_output(&outs, &tx->txid, tx_blockheight,
|
||||
their_unilateral_local(&outs, tx, tx_blockheight,
|
||||
i, amt, script[LOCAL],
|
||||
THEIR_UNILATERAL,
|
||||
i, amt,
|
||||
OUTPUT_TO_US, NULL, NULL, NULL);
|
||||
ignore_output(out);
|
||||
is_replay, 1);
|
||||
|
||||
if (!is_replay)
|
||||
record_channel_withdrawal(&tx->txid, tx_blockheight, out);
|
||||
|
||||
tell_wallet_to_remote(tx, i,
|
||||
tx_blockheight,
|
||||
script[LOCAL],
|
||||
remote_per_commitment_point,
|
||||
commit_num >= static_remotekey_start[REMOTE]);
|
||||
script[LOCAL] = NULL;
|
||||
add_amt(&our_outs, amt);
|
||||
continue;
|
||||
@ -3496,10 +3660,75 @@ static void handle_their_unilateral(const struct tx_parts *tx,
|
||||
}
|
||||
|
||||
matches = match_htlc_output(tmpctx, tx->outputs[i], htlc_scripts);
|
||||
if (tal_count(matches) == 0)
|
||||
if (tal_count(matches) == 0) {
|
||||
bool found = false;
|
||||
|
||||
/* We need to hunt for it (option_will_fund?) */
|
||||
if (opener == REMOTE && script[LOCAL]) {
|
||||
status_debug("Grinding for commitment to_remote"
|
||||
" (ours)");
|
||||
/* We already tried `1` */
|
||||
for (size_t csv = 2;
|
||||
csv <= LEASE_RATE_DURATION;
|
||||
csv++) {
|
||||
script[LOCAL]
|
||||
= scriptpubkey_to_remote(tmpctx,
|
||||
&keyset->other_payment_key,
|
||||
csv);
|
||||
if (!wally_tx_output_scripteq(
|
||||
tx->outputs[i],
|
||||
script[LOCAL]))
|
||||
continue;
|
||||
|
||||
their_unilateral_local(&outs, tx,
|
||||
tx_blockheight,
|
||||
i, amt,
|
||||
script[LOCAL],
|
||||
THEIR_UNILATERAL,
|
||||
is_replay, csv);
|
||||
script[LOCAL] = NULL;
|
||||
add_amt(&our_outs, amt);
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
} else if (opener == LOCAL && script[REMOTE]) {
|
||||
status_debug("Grinding for commitment to_local"
|
||||
" (theirs)");
|
||||
/* We already tried `1` */
|
||||
for (size_t csv = 2;
|
||||
csv <= LEASE_RATE_DURATION;
|
||||
csv++) {
|
||||
remote_wscript
|
||||
= to_self_wscript(tmpctx,
|
||||
to_self_delay[REMOTE],
|
||||
csv, keyset);
|
||||
script[REMOTE]
|
||||
= scriptpubkey_p2wsh(tmpctx,
|
||||
remote_wscript);
|
||||
|
||||
|
||||
if (!wally_tx_output_scripteq(tx->outputs[i], script[REMOTE]))
|
||||
continue;
|
||||
|
||||
out = new_tracked_output(&outs, &tx->txid, tx_blockheight,
|
||||
THEIR_UNILATERAL, i,
|
||||
amt,
|
||||
DELAYED_OUTPUT_TO_THEM,
|
||||
NULL, NULL, NULL);
|
||||
ignore_output(out);
|
||||
add_amt(&their_outs, amt);
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (found)
|
||||
continue;
|
||||
|
||||
status_failed(STATUS_FAIL_INTERNAL_ERROR,
|
||||
"Could not find resolution for output %zu",
|
||||
i);
|
||||
}
|
||||
|
||||
if (matches_direction(matches, htlcs) == LOCAL) {
|
||||
/* BOLT #5:
|
||||
@ -3629,10 +3858,13 @@ static void handle_unknown_commitment(const struct tx_parts *tx,
|
||||
local_scripts[0] = NULL;
|
||||
}
|
||||
|
||||
/* For option_will_fund, we need to figure out what CSV lock was used */
|
||||
for (size_t csv = 1; csv <= LEASE_RATE_DURATION; csv++) {
|
||||
|
||||
/* Other possible local script is for option_static_remotekey */
|
||||
local_scripts[1] = scriptpubkey_to_remote(tmpctx,
|
||||
&basepoints[LOCAL].payment,
|
||||
1);
|
||||
csv);
|
||||
|
||||
for (size_t i = 0; i < tal_count(tx->outputs); i++) {
|
||||
struct tracked_output *out;
|
||||
@ -3677,11 +3909,15 @@ static void handle_unknown_commitment(const struct tx_parts *tx,
|
||||
tx_blockheight,
|
||||
local_scripts[which_script],
|
||||
possible_remote_per_commitment_point,
|
||||
which_script == 1);
|
||||
which_script == 1,
|
||||
csv);
|
||||
local_scripts[0] = local_scripts[1] = NULL;
|
||||
to_us_output = i;
|
||||
goto script_found;
|
||||
}
|
||||
}
|
||||
|
||||
script_found:
|
||||
if (to_us_output == -1) {
|
||||
status_broken("FUNDS LOST. Unknown commitment #%"PRIu64"!",
|
||||
commit_num);
|
||||
@ -3870,6 +4106,7 @@ int main(int argc, char *argv[])
|
||||
basepoints,
|
||||
htlcs,
|
||||
tell_if_missing, tell_immediately,
|
||||
opener,
|
||||
remote_htlc_sigs,
|
||||
outs,
|
||||
open_is_replay);
|
||||
@ -3888,6 +4125,7 @@ int main(int argc, char *argv[])
|
||||
basepoints,
|
||||
htlcs,
|
||||
tell_if_missing, tell_immediately,
|
||||
opener,
|
||||
outs,
|
||||
open_is_replay);
|
||||
/* BOLT #5:
|
||||
@ -3907,6 +4145,7 @@ int main(int argc, char *argv[])
|
||||
htlcs,
|
||||
tell_if_missing,
|
||||
tell_immediately,
|
||||
opener,
|
||||
outs,
|
||||
open_is_replay);
|
||||
} else if (commit_num == revocations_received(&shachain) + 1) {
|
||||
@ -3917,6 +4156,7 @@ int main(int argc, char *argv[])
|
||||
htlcs,
|
||||
tell_if_missing,
|
||||
tell_immediately,
|
||||
opener,
|
||||
outs,
|
||||
open_is_replay);
|
||||
} else {
|
||||
|
Loading…
Reference in New Issue
Block a user