handle batched channel opens. infer funding balances in both directions.
This commit is contained in:
parent
35ae672177
commit
dc7d5bc94d
@ -282,7 +282,7 @@ class ChannelsApi {
|
|||||||
const query = `
|
const query = `
|
||||||
SELECT
|
SELECT
|
||||||
channels.id, channels.node1_public_key, channels.node2_public_key,
|
channels.id, channels.node1_public_key, channels.node2_public_key,
|
||||||
channels.closing_reason, channels.closing_transaction_id,
|
channels.closing_reason, channels.closing_transaction_id, channels.capacity,
|
||||||
forensics.*
|
forensics.*
|
||||||
FROM channels
|
FROM channels
|
||||||
LEFT JOIN channels_forensics as forensics ON forensics.channel_id = channels.id
|
LEFT JOIN channels_forensics as forensics ON forensics.channel_id = channels.id
|
||||||
@ -304,7 +304,7 @@ class ChannelsApi {
|
|||||||
const query = `
|
const query = `
|
||||||
SELECT
|
SELECT
|
||||||
channels.id, channels.node1_public_key, channels.node2_public_key,
|
channels.id, channels.node1_public_key, channels.node2_public_key,
|
||||||
channels.status, channels.transaction_id,
|
channels.status, channels.transaction_id, channels.capacity,
|
||||||
forensics.*
|
forensics.*
|
||||||
FROM channels
|
FROM channels
|
||||||
LEFT JOIN channels_forensics as forensics ON forensics.channel_id = channels.id
|
LEFT JOIN channels_forensics as forensics ON forensics.channel_id = channels.id
|
||||||
@ -312,8 +312,10 @@ class ChannelsApi {
|
|||||||
`;
|
`;
|
||||||
const [rows]: any = await DB.query(query, [transactionId]);
|
const [rows]: any = await DB.query(query, [transactionId]);
|
||||||
if (rows.length > 0) {
|
if (rows.length > 0) {
|
||||||
rows[0].outputs = JSON.parse(rows[0].outputs);
|
return rows.map(row => {
|
||||||
return rows[0];
|
row.outputs = JSON.parse(row.outputs);
|
||||||
|
return row;
|
||||||
|
});
|
||||||
}
|
}
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
logger.err('$getChannelForensicsByOpeningId error: ' + (e instanceof Error ? e.message : e));
|
logger.err('$getChannelForensicsByOpeningId error: ' + (e instanceof Error ? e.message : e));
|
||||||
@ -344,15 +346,15 @@ class ChannelsApi {
|
|||||||
const jsonOutputs = JSON.stringify(channelInfo.outputs);
|
const jsonOutputs = JSON.stringify(channelInfo.outputs);
|
||||||
await DB.query<ResultSetHeader>(query, [
|
await DB.query<ResultSetHeader>(query, [
|
||||||
channelInfo.id,
|
channelInfo.id,
|
||||||
channelInfo.node1_closing_balance,
|
channelInfo.node1_closing_balance || 0,
|
||||||
channelInfo.node2_closing_balance,
|
channelInfo.node2_closing_balance || 0,
|
||||||
channelInfo.closed_by,
|
channelInfo.closed_by,
|
||||||
channelInfo.closing_fee,
|
channelInfo.closing_fee || 0,
|
||||||
jsonOutputs,
|
jsonOutputs,
|
||||||
channelInfo.node1_closing_balance,
|
channelInfo.node1_closing_balance || 0,
|
||||||
channelInfo.node2_closing_balance,
|
channelInfo.node2_closing_balance || 0,
|
||||||
channelInfo.closed_by,
|
channelInfo.closed_by,
|
||||||
channelInfo.closing_fee,
|
channelInfo.closing_fee || 0,
|
||||||
jsonOutputs
|
jsonOutputs
|
||||||
]);
|
]);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
@ -382,12 +384,12 @@ class ChannelsApi {
|
|||||||
`;
|
`;
|
||||||
await DB.query<ResultSetHeader>(query, [
|
await DB.query<ResultSetHeader>(query, [
|
||||||
channelInfo.id,
|
channelInfo.id,
|
||||||
channelInfo.node1_funding_balance,
|
channelInfo.node1_funding_balance || 0,
|
||||||
channelInfo.node2_funding_balance,
|
channelInfo.node2_funding_balance || 0,
|
||||||
channelInfo.funding_ratio,
|
channelInfo.funding_ratio,
|
||||||
channelInfo.single_funded ? 1 : 0,
|
channelInfo.single_funded ? 1 : 0,
|
||||||
channelInfo.node1_funding_balance,
|
channelInfo.node1_funding_balance || 0,
|
||||||
channelInfo.node2_funding_balance,
|
channelInfo.node2_funding_balance || 0,
|
||||||
channelInfo.funding_ratio,
|
channelInfo.funding_ratio,
|
||||||
channelInfo.single_funded ? 1 : 0,
|
channelInfo.single_funded ? 1 : 0,
|
||||||
]);
|
]);
|
||||||
|
@ -372,9 +372,12 @@ class NetworkSyncService {
|
|||||||
// this input directly spends a channel close output
|
// this input directly spends a channel close output
|
||||||
await this.$attributeChannelBalances(closeChannel, openChannel, input);
|
await this.$attributeChannelBalances(closeChannel, openChannel, input);
|
||||||
} else {
|
} else {
|
||||||
const prevOpenChannel = await channelsApi.$getChannelForensicsByOpeningId(input.txid);
|
const prevOpenChannels = await channelsApi.$getChannelForensicsByOpeningId(input.txid);
|
||||||
if (prevOpenChannel) {
|
if (prevOpenChannels?.length) {
|
||||||
await this.$attributeChannelBalances(prevOpenChannel, openChannel, input, null, null, true);
|
// this input spends a channel open change output
|
||||||
|
for (const prevOpenChannel of prevOpenChannels) {
|
||||||
|
await this.$attributeChannelBalances(prevOpenChannel, openChannel, input, null, null, true);
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
// check if this input spends any swept channel close outputs
|
// check if this input spends any swept channel close outputs
|
||||||
await this.$attributeSweptChannelCloses(openChannel, input);
|
await this.$attributeSweptChannelCloses(openChannel, input);
|
||||||
@ -435,33 +438,33 @@ class NetworkSyncService {
|
|||||||
): Promise<void> {
|
): Promise<void> {
|
||||||
// figure out which node controls the input/output
|
// figure out which node controls the input/output
|
||||||
let openSide;
|
let openSide;
|
||||||
let closeLocal;
|
let prevLocal;
|
||||||
let closeRemote;
|
let prevRemote;
|
||||||
let matched = false;
|
let matched = false;
|
||||||
let ambiguous = false; // if counterparties are the same in both channels, we can't tell them apart
|
let ambiguous = false; // if counterparties are the same in both channels, we can't tell them apart
|
||||||
if (openChannel.node1_public_key === prevChannel.node1_public_key) {
|
if (openChannel.node1_public_key === prevChannel.node1_public_key) {
|
||||||
openSide = 1;
|
openSide = 1;
|
||||||
closeLocal = 1;
|
prevLocal = 1;
|
||||||
closeRemote = 2;
|
prevRemote = 2;
|
||||||
matched = true;
|
matched = true;
|
||||||
} else if (openChannel.node1_public_key === prevChannel.node2_public_key) {
|
} else if (openChannel.node1_public_key === prevChannel.node2_public_key) {
|
||||||
openSide = 1;
|
openSide = 1;
|
||||||
closeLocal = 2;
|
prevLocal = 2;
|
||||||
closeRemote = 1;
|
prevRemote = 1;
|
||||||
matched = true;
|
matched = true;
|
||||||
}
|
}
|
||||||
if (openChannel.node2_public_key === prevChannel.node1_public_key) {
|
if (openChannel.node2_public_key === prevChannel.node1_public_key) {
|
||||||
openSide = 2;
|
openSide = 2;
|
||||||
closeLocal = 1;
|
prevLocal = 1;
|
||||||
closeRemote = 2;
|
prevRemote = 2;
|
||||||
if (matched) {
|
if (matched) {
|
||||||
ambiguous = true;
|
ambiguous = true;
|
||||||
}
|
}
|
||||||
matched = true;
|
matched = true;
|
||||||
} else if (openChannel.node2_public_key === prevChannel.node2_public_key) {
|
} else if (openChannel.node2_public_key === prevChannel.node2_public_key) {
|
||||||
openSide = 2;
|
openSide = 2;
|
||||||
closeLocal = 2;
|
prevLocal = 2;
|
||||||
closeRemote = 1;
|
prevRemote = 1;
|
||||||
if (matched) {
|
if (matched) {
|
||||||
ambiguous = true;
|
ambiguous = true;
|
||||||
}
|
}
|
||||||
@ -508,7 +511,7 @@ class NetworkSyncService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// attribute outputs to each counterparty, and sum up total known balances
|
// attribute outputs to each counterparty, and sum up total known balances
|
||||||
prevChannel.outputs[input.vout].node = closeLocal;
|
prevChannel.outputs[input.vout].node = prevLocal;
|
||||||
const isPenalty = prevChannel.outputs.filter((out) => out.type === 2 || out.type === 4)?.length > 0;
|
const isPenalty = prevChannel.outputs.filter((out) => out.type === 2 || out.type === 4)?.length > 0;
|
||||||
const normalOutput = [1,3].includes(prevChannel.outputs[input.vout].type);
|
const normalOutput = [1,3].includes(prevChannel.outputs[input.vout].type);
|
||||||
let localClosingBalance = 0;
|
let localClosingBalance = 0;
|
||||||
@ -519,7 +522,7 @@ class NetworkSyncService {
|
|||||||
localClosingBalance += output.value;
|
localClosingBalance += output.value;
|
||||||
} else if (output.node) {
|
} else if (output.node) {
|
||||||
// this output determinstically linked to one of the counterparties
|
// this output determinstically linked to one of the counterparties
|
||||||
if (output.node === closeLocal) {
|
if (output.node === prevLocal) {
|
||||||
localClosingBalance += output.value;
|
localClosingBalance += output.value;
|
||||||
} else {
|
} else {
|
||||||
remoteClosingBalance += output.value;
|
remoteClosingBalance += output.value;
|
||||||
@ -529,17 +532,25 @@ class NetworkSyncService {
|
|||||||
remoteClosingBalance += output.value;
|
remoteClosingBalance += output.value;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
prevChannel[`node${closeLocal}_closing_balance`] = localClosingBalance;
|
prevChannel[`node${prevLocal}_closing_balance`] = localClosingBalance;
|
||||||
prevChannel[`node${closeRemote}_closing_balance`] = remoteClosingBalance;
|
prevChannel[`node${prevRemote}_closing_balance`] = remoteClosingBalance;
|
||||||
prevChannel.closing_fee = prevChannelTx.fee;
|
prevChannel.closing_fee = prevChannelTx.fee;
|
||||||
|
|
||||||
if (initiator && !linkedOpenings) {
|
if (initiator && !linkedOpenings) {
|
||||||
const initiatorSide = initiator === 'remote' ? closeRemote : closeLocal;
|
const initiatorSide = initiator === 'remote' ? prevRemote : prevLocal;
|
||||||
prevChannel.closed_by = prevChannel[`node${initiatorSide}_public_key`];
|
prevChannel.closed_by = prevChannel[`node${initiatorSide}_public_key`];
|
||||||
}
|
}
|
||||||
|
|
||||||
// save changes to the closing channel
|
// save changes to the closing channel
|
||||||
await channelsApi.$updateClosingInfo(prevChannel);
|
await channelsApi.$updateClosingInfo(prevChannel);
|
||||||
|
} else {
|
||||||
|
if (prevChannelTx.vin.length <= 1) {
|
||||||
|
prevChannel[`node${prevLocal}_funding_balance`] = prevChannel.capacity;
|
||||||
|
prevChannel.single_funded = true;
|
||||||
|
prevChannel.funding_ratio = 1;
|
||||||
|
// save changes to the closing channel
|
||||||
|
await channelsApi.$updateOpeningInfo(prevChannel);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
openChannel[`node${openSide}_funding_balance`] = openChannel[`node${openSide}_funding_balance`] + (openContribution || prevChannelTx?.vout[input.vout]?.value || 0);
|
openChannel[`node${openSide}_funding_balance`] = openChannel[`node${openSide}_funding_balance`] + (openContribution || prevChannelTx?.vout[input.vout]?.value || 0);
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user