Wrap esplora call into try/catch when scanning channel forensics
This commit is contained in:
parent
7fe9029a4e
commit
7d5ed66db1
@ -285,44 +285,66 @@ class NetworkSyncService {
|
|||||||
for (const channel of channels) {
|
for (const channel of channels) {
|
||||||
let reason = 0;
|
let reason = 0;
|
||||||
// Only Esplora backend can retrieve spent transaction outputs
|
// Only Esplora backend can retrieve spent transaction outputs
|
||||||
const outspends = await bitcoinApi.$getOutspends(channel.closing_transaction_id);
|
try {
|
||||||
const lightningScriptReasons: number[] = [];
|
let outspends: IEsploraApi.Outspend[] | undefined;
|
||||||
for (const outspend of outspends) {
|
try {
|
||||||
if (outspend.spent && outspend.txid) {
|
outspends = await bitcoinApi.$getOutspends(channel.closing_transaction_id);
|
||||||
const spendingTx = await bitcoinApi.$getRawTransaction(outspend.txid);
|
} catch (e) {
|
||||||
const lightningScript = this.findLightningScript(spendingTx.vin[outspend.vin || 0]);
|
logger.err(`Failed to call ${config.ESPLORA.REST_API_URL + '/tx/' + channel.closing_transaction_id + '/outspends'}. Reason ${e instanceof Error ? e.message : e}`);
|
||||||
lightningScriptReasons.push(lightningScript);
|
continue;
|
||||||
}
|
}
|
||||||
}
|
const lightningScriptReasons: number[] = [];
|
||||||
if (lightningScriptReasons.length === outspends.length
|
for (const outspend of outspends) {
|
||||||
&& lightningScriptReasons.filter((r) => r === 1).length === outspends.length) {
|
if (outspend.spent && outspend.txid) {
|
||||||
reason = 1;
|
let spendingTx: IEsploraApi.Transaction | undefined;
|
||||||
} else {
|
try {
|
||||||
const filteredReasons = lightningScriptReasons.filter((r) => r !== 1);
|
spendingTx = await bitcoinApi.$getRawTransaction(outspend.txid);
|
||||||
if (filteredReasons.length) {
|
} catch (e) {
|
||||||
if (filteredReasons.some((r) => r === 2 || r === 4)) {
|
logger.err(`Failed to call ${config.ESPLORA.REST_API_URL + '/tx/' + outspend.txid}. Reason ${e instanceof Error ? e.message : e}`);
|
||||||
reason = 3;
|
continue;
|
||||||
} else {
|
}
|
||||||
reason = 2;
|
const lightningScript = this.findLightningScript(spendingTx.vin[outspend.vin || 0]);
|
||||||
|
lightningScriptReasons.push(lightningScript);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
if (lightningScriptReasons.length === outspends.length
|
||||||
|
&& lightningScriptReasons.filter((r) => r === 1).length === outspends.length) {
|
||||||
|
reason = 1;
|
||||||
} else {
|
} else {
|
||||||
/*
|
const filteredReasons = lightningScriptReasons.filter((r) => r !== 1);
|
||||||
We can detect a commitment transaction (force close) by reading Sequence and Locktime
|
if (filteredReasons.length) {
|
||||||
https://github.com/lightning/bolts/blob/master/03-transactions.md#commitment-transaction
|
if (filteredReasons.some((r) => r === 2 || r === 4)) {
|
||||||
*/
|
reason = 3;
|
||||||
const closingTx = await bitcoinApi.$getRawTransaction(channel.closing_transaction_id);
|
} else {
|
||||||
const sequenceHex: string = closingTx.vin[0].sequence.toString(16);
|
reason = 2;
|
||||||
const locktimeHex: string = closingTx.locktime.toString(16);
|
}
|
||||||
if (sequenceHex.substring(0, 2) === '80' && locktimeHex.substring(0, 2) === '20') {
|
|
||||||
reason = 2; // Here we can't be sure if it's a penalty or not
|
|
||||||
} else {
|
} else {
|
||||||
reason = 1;
|
/*
|
||||||
|
We can detect a commitment transaction (force close) by reading Sequence and Locktime
|
||||||
|
https://github.com/lightning/bolts/blob/master/03-transactions.md#commitment-transaction
|
||||||
|
*/
|
||||||
|
let closingTx: IEsploraApi.Transaction | undefined;
|
||||||
|
try {
|
||||||
|
closingTx = await bitcoinApi.$getRawTransaction(channel.closing_transaction_id);
|
||||||
|
} catch (e) {
|
||||||
|
logger.err(`Failed to call ${config.ESPLORA.REST_API_URL + '/tx/' + channel.closing_transaction_id}. Reason ${e instanceof Error ? e.message : e}`);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
const sequenceHex: string = closingTx.vin[0].sequence.toString(16);
|
||||||
|
const locktimeHex: string = closingTx.locktime.toString(16);
|
||||||
|
if (sequenceHex.substring(0, 2) === '80' && locktimeHex.substring(0, 2) === '20') {
|
||||||
|
reason = 2; // Here we can't be sure if it's a penalty or not
|
||||||
|
} else {
|
||||||
|
reason = 1;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
if (reason) {
|
||||||
if (reason) {
|
logger.debug('Setting closing reason ' + reason + ' for channel: ' + channel.id + '.');
|
||||||
logger.debug('Setting closing reason ' + reason + ' for channel: ' + channel.id + '.');
|
await DB.query(`UPDATE channels SET closing_reason = ? WHERE id = ?`, [reason, channel.id]);
|
||||||
await DB.query(`UPDATE channels SET closing_reason = ? WHERE id = ?`, [reason, channel.id]);
|
}
|
||||||
|
} catch (e) {
|
||||||
|
logger.err(`$runClosedChannelsForensics() failed for channel ${channel.short_id}. Reason: ${e instanceof Error ? e.message : e}`);
|
||||||
}
|
}
|
||||||
|
|
||||||
++progress;
|
++progress;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user