Merge branch 'master' into simon/empty-tx-value-fix

This commit is contained in:
wiz 2022-08-25 23:53:29 +09:00 committed by GitHub
commit 5eac69b6df
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 85 additions and 43 deletions

View File

@ -288,21 +288,36 @@ class ChannelsApi {
const channels: any[] = [] const channels: any[] = []
for (const row of allChannels) { for (const row of allChannels) {
const activeChannelsStats: any = await nodesApi.$getActiveChannelsStats(row.public_key); let channel;
channels.push({ if (index >= 0) {
status: row.status, const activeChannelsStats: any = await nodesApi.$getActiveChannelsStats(row.public_key);
closing_reason: row.closing_reason, channel = {
capacity: row.capacity ?? 0, status: row.status,
short_id: row.short_id, closing_reason: row.closing_reason,
id: row.id, capacity: row.capacity ?? 0,
fee_rate: row.node1_fee_rate ?? row.node2_fee_rate ?? 0, short_id: row.short_id,
node: { id: row.id,
alias: row.alias.length > 0 ? row.alias : row.public_key.slice(0, 20), fee_rate: row.node1_fee_rate ?? row.node2_fee_rate ?? 0,
public_key: row.public_key, node: {
channels: activeChannelsStats.active_channel_count ?? 0, alias: row.alias.length > 0 ? row.alias : row.public_key.slice(0, 20),
capacity: activeChannelsStats.capacity ?? 0, public_key: row.public_key,
} channels: activeChannelsStats.active_channel_count ?? 0,
}); capacity: activeChannelsStats.capacity ?? 0,
}
};
} else if (index === -1) {
channel = {
capacity: row.capacity ?? 0,
short_id: row.short_id,
id: row.id,
node: {
alias: row.alias.length > 0 ? row.alias : row.public_key.slice(0, 20),
public_key: row.public_key,
}
};
}
channels.push(channel);
} }
return channels; return channels;

View File

@ -47,8 +47,17 @@ class ChannelsRoutes {
res.status(400).send('Missing parameter: public_key'); res.status(400).send('Missing parameter: public_key');
return; return;
} }
const index = parseInt(typeof req.query.index === 'string' ? req.query.index : '0', 10) || 0; const index = parseInt(typeof req.query.index === 'string' ? req.query.index : '0', 10) || 0;
const status: string = typeof req.query.status === 'string' ? req.query.status : ''; const status: string = typeof req.query.status === 'string' ? req.query.status : '';
if (index < -1) {
res.status(400).send('Invalid index');
}
if (['open', 'active', 'closed'].includes(status) === false) {
res.status(400).send('Invalid status');
}
const channels = await channelsApi.$getChannelsForNode(req.query.public_key, index, 10, status); const channels = await channelsApi.$getChannelsForNode(req.query.public_key, index, 10, status);
const channelsCount = await channelsApi.$getChannelsCountForNode(req.query.public_key, status); const channelsCount = await channelsApi.$getChannelsCountForNode(req.query.public_key, status);
res.header('Pragma', 'public'); res.header('Pragma', 'public');

View File

@ -7,6 +7,7 @@ import { ILightningApi } from '../../../api/lightning/lightning-api.interface';
import { isIP } from 'net'; import { isIP } from 'net';
import { Common } from '../../../api/common'; import { Common } from '../../../api/common';
import channelsApi from '../../../api/explorer/channels.api'; import channelsApi from '../../../api/explorer/channels.api';
import nodesApi from '../../../api/explorer/nodes.api';
const fsPromises = promises; const fsPromises = promises;
@ -32,7 +33,26 @@ class LightningStatsImporter {
let clearnetTorNodes = 0; let clearnetTorNodes = 0;
let unannouncedNodes = 0; let unannouncedNodes = 0;
const [nodesInDbRaw]: any[] = await DB.query(`SELECT public_key FROM nodes`);
const nodesInDb = {};
for (const node of nodesInDbRaw) {
nodesInDb[node.public_key] = node;
}
for (const node of networkGraph.nodes) { for (const node of networkGraph.nodes) {
// If we don't know about this node, insert it in db
if (isHistorical === true && !nodesInDb[node.pub_key]) {
await nodesApi.$saveNode({
last_update: node.last_update,
pub_key: node.pub_key,
alias: node.alias,
addresses: node.addresses,
color: node.color,
features: node.features,
});
nodesInDb[node.pub_key] = node;
}
let hasOnion = false; let hasOnion = false;
let hasClearnet = false; let hasClearnet = false;
let isUnnanounced = true; let isUnnanounced = true;
@ -69,7 +89,7 @@ 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 [channelsInDbRaw]: any[] = await DB.query(`SELECT short_id FROM channels`);
const channelsInDb = {}; const channelsInDb = {};
for (const channel of channelsInDbRaw) { for (const channel of channelsInDbRaw) {
channelsInDb[channel.short_id] = channel; channelsInDb[channel.short_id] = channel;
@ -84,29 +104,19 @@ class LightningStatsImporter {
continue; continue;
} }
// Channel is already in db, check if we need to update 'created' field // If we don't know about this channel, insert it in db
if (isHistorical === true) { if (isHistorical === true && !channelsInDb[short_id]) {
//@ts-ignore await channelsApi.$saveChannel({
if (channelsInDb[short_id] && channel.timestamp < channel.created) { channel_id: short_id,
await DB.query(` chan_point: `${tx.txid}:${short_id.split('x')[2]}`,
UPDATE channels SET created = FROM_UNIXTIME(?) WHERE channels.short_id = ?`, last_update: channel.last_update,
//@ts-ignore node1_pub: channel.node1_pub,
[channel.timestamp, short_id] node2_pub: channel.node2_pub,
); capacity: (tx.value * 100000000).toString(),
} else if (!channelsInDb[short_id]) { node1_policy: null,
await channelsApi.$saveChannel({ node2_policy: null,
channel_id: short_id, }, 0);
chan_point: `${tx.txid}:${short_id.split('x')[2]}`, channelsInDb[channel.channel_id] = channel;
//@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]) {
@ -281,6 +291,7 @@ class LightningStatsImporter {
* Import topology files LN historical data into the database * Import topology files LN historical data into the database
*/ */
async $importHistoricalLightningStats(): Promise<void> { async $importHistoricalLightningStats(): Promise<void> {
logger.debug('Run the historical importer');
try { try {
let fileList: string[] = []; let fileList: string[] = [];
try { try {
@ -294,7 +305,7 @@ class LightningStatsImporter {
fileList.sort().reverse(); fileList.sort().reverse();
const [rows]: any[] = await DB.query(` const [rows]: any[] = await DB.query(`
SELECT UNIX_TIMESTAMP(added) AS added, node_count SELECT UNIX_TIMESTAMP(added) AS added
FROM lightning_stats FROM lightning_stats
ORDER BY added DESC ORDER BY added DESC
`); `);
@ -391,12 +402,16 @@ class LightningStatsImporter {
}); });
} }
let rgb = node.rgb_color ?? '#000000';
if (rgb.indexOf('#') === -1) {
rgb = `#${rgb}`;
}
newGraph.nodes.push({ newGraph.nodes.push({
last_update: node.timestamp ?? 0, last_update: node.timestamp ?? 0,
pub_key: node.id ?? null, pub_key: node.id ?? null,
alias: node.alias ?? null, alias: node.alias ?? node.id.slice(0, 20),
addresses: addresses, addresses: addresses,
color: node.rgb_color ?? null, color: rgb,
features: {}, features: {},
}); });
} }

View File

@ -119,7 +119,7 @@
</div> </div>
<div *ngIf="!error"> <div *ngIf="!error">
<div class="row"> <div class="row" *ngIf="node.as_number">
<div class="col-sm"> <div class="col-sm">
<app-nodes-channels-map [style]="'nodepage'" [publicKey]="node.public_key" [hasLocation]="!!node.as_number"></app-nodes-channels-map> <app-nodes-channels-map [style]="'nodepage'" [publicKey]="node.public_key" [hasLocation]="!!node.as_number"></app-nodes-channels-map>
</div> </div>
@ -127,6 +127,9 @@
<app-node-statistics-chart [publicKey]="node.public_key"></app-node-statistics-chart> <app-node-statistics-chart [publicKey]="node.public_key"></app-node-statistics-chart>
</div> </div>
</div> </div>
<div *ngIf="!node.as_number">
<app-node-statistics-chart [publicKey]="node.public_key"></app-node-statistics-chart>
</div>
<h2 i18n="lightning.active-channels-map">Active channels map</h2> <h2 i18n="lightning.active-channels-map">Active channels map</h2>
<app-node-channels style="display:block;margin-bottom: 40px" [publicKey]="node.public_key"></app-node-channels> <app-node-channels style="display:block;margin-bottom: 40px" [publicKey]="node.public_key"></app-node-channels>