Insert channels from historical data
This commit is contained in:
parent
1ef4485a26
commit
e7d99e9653
@ -248,7 +248,6 @@ class DatabaseMigration {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (databaseSchemaVersion < 25 && isBitcoin === true) {
|
if (databaseSchemaVersion < 25 && isBitcoin === true) {
|
||||||
await this.$executeQuery(`INSERT INTO state VALUES('last_node_stats', 0, '1970-01-01');`);
|
|
||||||
await this.$executeQuery(this.getCreateLightningStatisticsQuery(), await this.$checkIfTableExists('lightning_stats'));
|
await this.$executeQuery(this.getCreateLightningStatisticsQuery(), await this.$checkIfTableExists('lightning_stats'));
|
||||||
await this.$executeQuery(this.getCreateNodesQuery(), await this.$checkIfTableExists('nodes'));
|
await this.$executeQuery(this.getCreateNodesQuery(), await this.$checkIfTableExists('nodes'));
|
||||||
await this.$executeQuery(this.getCreateChannelsQuery(), await this.$checkIfTableExists('channels'));
|
await this.$executeQuery(this.getCreateChannelsQuery(), await this.$checkIfTableExists('channels'));
|
||||||
|
@ -61,9 +61,14 @@ class ChannelsApi {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public async $getChannelsByStatus(status: number): Promise<any[]> {
|
public async $getChannelsByStatus(status: number | number[]): Promise<any[]> {
|
||||||
try {
|
try {
|
||||||
const query = `SELECT * FROM channels WHERE status = ?`;
|
let query: string;
|
||||||
|
if (Array.isArray(status)) {
|
||||||
|
query = `SELECT * FROM channels WHERE status IN (${status.join(',')})`;
|
||||||
|
} else {
|
||||||
|
query = `SELECT * FROM channels WHERE status = ?`;
|
||||||
|
}
|
||||||
const [rows]: any = await DB.query(query, [status]);
|
const [rows]: any = await DB.query(query, [status]);
|
||||||
return rows;
|
return rows;
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
@ -337,7 +342,7 @@ class ChannelsApi {
|
|||||||
/**
|
/**
|
||||||
* Save or update a channel present in the graph
|
* Save or update a channel present in the graph
|
||||||
*/
|
*/
|
||||||
public async $saveChannel(channel: ILightningApi.Channel): Promise<void> {
|
public async $saveChannel(channel: ILightningApi.Channel, status = 1): Promise<void> {
|
||||||
const [ txid, vout ] = channel.chan_point.split(':');
|
const [ txid, vout ] = channel.chan_point.split(':');
|
||||||
|
|
||||||
const policy1: Partial<ILightningApi.RoutingPolicy> = channel.node1_policy || {};
|
const policy1: Partial<ILightningApi.RoutingPolicy> = channel.node1_policy || {};
|
||||||
@ -369,11 +374,11 @@ class ChannelsApi {
|
|||||||
node2_min_htlc_mtokens,
|
node2_min_htlc_mtokens,
|
||||||
node2_updated_at
|
node2_updated_at
|
||||||
)
|
)
|
||||||
VALUES (?, ?, ?, ?, ?, ?, 1, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
|
VALUES (?, ?, ?, ?, ?, ?, ${status}, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
|
||||||
ON DUPLICATE KEY UPDATE
|
ON DUPLICATE KEY UPDATE
|
||||||
capacity = ?,
|
capacity = ?,
|
||||||
updated_at = ?,
|
updated_at = ?,
|
||||||
status = 1,
|
status = ${status},
|
||||||
node1_public_key = ?,
|
node1_public_key = ?,
|
||||||
node1_base_fee_mtokens = ?,
|
node1_base_fee_mtokens = ?,
|
||||||
node1_cltv_delta = ?,
|
node1_cltv_delta = ?,
|
||||||
|
@ -232,8 +232,8 @@ class NetworkSyncService {
|
|||||||
let progress = 0;
|
let progress = 0;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
logger.info(`Starting closed channels scan...`);
|
logger.info(`Starting closed channels scan`);
|
||||||
const channels = await channelsApi.$getChannelsByStatus(0);
|
const channels = await channelsApi.$getChannelsByStatus([0, 1]);
|
||||||
for (const channel of channels) {
|
for (const channel of channels) {
|
||||||
const spendingTx = await bitcoinApi.$getOutspend(channel.transaction_id, channel.transaction_vout);
|
const spendingTx = await bitcoinApi.$getOutspend(channel.transaction_id, channel.transaction_vout);
|
||||||
if (spendingTx.spent === true && spendingTx.status?.confirmed === true) {
|
if (spendingTx.spent === true && spendingTx.status?.confirmed === true) {
|
||||||
|
@ -5,6 +5,8 @@ import fundingTxFetcher from './funding-tx-fetcher';
|
|||||||
import config from '../../../config';
|
import config from '../../../config';
|
||||||
import { ILightningApi } from '../../../api/lightning/lightning-api.interface';
|
import { ILightningApi } from '../../../api/lightning/lightning-api.interface';
|
||||||
import { isIP } from 'net';
|
import { isIP } from 'net';
|
||||||
|
import { Common } from '../../../api/common';
|
||||||
|
import channelsApi from '../../../api/explorer/channels.api';
|
||||||
|
|
||||||
const fsPromises = promises;
|
const fsPromises = promises;
|
||||||
|
|
||||||
@ -22,7 +24,8 @@ class LightningStatsImporter {
|
|||||||
/**
|
/**
|
||||||
* Generate LN network stats for one day
|
* Generate LN network stats for one day
|
||||||
*/
|
*/
|
||||||
public async computeNetworkStats(timestamp: number, networkGraph: ILightningApi.NetworkGraph): Promise<unknown> {
|
public async computeNetworkStats(timestamp: number,
|
||||||
|
networkGraph: ILightningApi.NetworkGraph, isHistorical: boolean = false): Promise<unknown> {
|
||||||
// Node counts and network shares
|
// Node counts and network shares
|
||||||
let clearnetNodes = 0;
|
let clearnetNodes = 0;
|
||||||
let torNodes = 0;
|
let torNodes = 0;
|
||||||
@ -66,11 +69,14 @@ class LightningStatsImporter {
|
|||||||
const baseFees: number[] = [];
|
const baseFees: number[] = [];
|
||||||
const alreadyCountedChannels = {};
|
const alreadyCountedChannels = {};
|
||||||
|
|
||||||
|
const [channelsInDbRaw]: any[] = await DB.query(`SELECT short_id, created FROM channels`);
|
||||||
|
const channelsInDb = {};
|
||||||
|
for (const channel of channelsInDbRaw) {
|
||||||
|
channelsInDb[channel.short_id] = channel;
|
||||||
|
}
|
||||||
|
|
||||||
for (const channel of networkGraph.edges) {
|
for (const channel of networkGraph.edges) {
|
||||||
let short_id = channel.channel_id;
|
const short_id = Common.channelIntegerIdToShortId(channel.channel_id);
|
||||||
if (short_id.indexOf('/') !== -1) {
|
|
||||||
short_id = short_id.slice(0, -2);
|
|
||||||
}
|
|
||||||
|
|
||||||
const tx = await fundingTxFetcher.$fetchChannelOpenTx(short_id);
|
const tx = await fundingTxFetcher.$fetchChannelOpenTx(short_id);
|
||||||
if (!tx) {
|
if (!tx) {
|
||||||
@ -78,6 +84,31 @@ class LightningStatsImporter {
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Channel is already in db, check if we need to update 'created' field
|
||||||
|
if (isHistorical === true) {
|
||||||
|
//@ts-ignore
|
||||||
|
if (channelsInDb[short_id] && channel.timestamp < channel.created) {
|
||||||
|
await DB.query(`
|
||||||
|
UPDATE channels SET created = FROM_UNIXTIME(?) WHERE channels.short_id = ?`,
|
||||||
|
//@ts-ignore
|
||||||
|
[channel.timestamp, short_id]
|
||||||
|
);
|
||||||
|
} else if (!channelsInDb[short_id]) {
|
||||||
|
await channelsApi.$saveChannel({
|
||||||
|
channel_id: short_id,
|
||||||
|
chan_point: `${tx.txid}:${short_id.split('x')[2]}`,
|
||||||
|
//@ts-ignore
|
||||||
|
last_update: channel.timestamp,
|
||||||
|
node1_pub: channel.node1_pub,
|
||||||
|
node2_pub: channel.node2_pub,
|
||||||
|
capacity: (tx.value * 100000000).toString(),
|
||||||
|
node1_policy: null,
|
||||||
|
node2_policy: null,
|
||||||
|
}, 0);
|
||||||
|
channelsInDb[channel.channel_id] = channel;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (!nodeStats[channel.node1_pub]) {
|
if (!nodeStats[channel.node1_pub]) {
|
||||||
nodeStats[channel.node1_pub] = {
|
nodeStats[channel.node1_pub] = {
|
||||||
capacity: 0,
|
capacity: 0,
|
||||||
@ -102,7 +133,7 @@ class LightningStatsImporter {
|
|||||||
nodeStats[channel.node2_pub].channels++;
|
nodeStats[channel.node2_pub].channels++;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (channel.node1_policy !== undefined) { // Coming from the node
|
if (isHistorical === false) { // Coming from the node
|
||||||
for (const policy of [channel.node1_policy, channel.node2_policy]) {
|
for (const policy of [channel.node1_policy, channel.node2_policy]) {
|
||||||
if (policy && parseInt(policy.fee_rate_milli_msat, 10) < 5000) {
|
if (policy && parseInt(policy.fee_rate_milli_msat, 10) < 5000) {
|
||||||
avgFeeRate += parseInt(policy.fee_rate_milli_msat, 10);
|
avgFeeRate += parseInt(policy.fee_rate_milli_msat, 10);
|
||||||
@ -113,7 +144,7 @@ class LightningStatsImporter {
|
|||||||
baseFees.push(parseInt(policy.fee_base_msat, 10));
|
baseFees.push(parseInt(policy.fee_base_msat, 10));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else { // Coming from the historical import
|
} else {
|
||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
if (channel.fee_rate_milli_msat < 5000) {
|
if (channel.fee_rate_milli_msat < 5000) {
|
||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
|
Loading…
x
Reference in New Issue
Block a user