Channel component

This commit is contained in:
softsimon
2022-05-01 03:01:27 +04:00
parent f5325b3a6d
commit 795bb6a7a6
23 changed files with 536 additions and 59 deletions

View File

@@ -2,9 +2,20 @@ import logger from '../../logger';
import DB from '../../database';
class ChannelsApi {
public async $getChannel(shortId: string): Promise<any> {
try {
const query = `SELECT n1.alias AS alias_left, n2.alias AS alias_right, channels.* FROM channels LEFT JOIN nodes AS n1 ON n1.public_key = channels.node1_public_key LEFT JOIN nodes AS n2 ON n2.public_key = channels.node2_public_key WHERE channels.id = ?`;
const [rows]: any = await DB.query(query, [shortId]);
return rows[0];
} catch (e) {
logger.err('$getChannel error: ' + (e instanceof Error ? e.message : e));
throw e;
}
}
public async $getChannelsForNode(public_key: string): Promise<any> {
try {
const query = `SELECT * FROM channels WHERE node1_public_key = ? OR node2_public_key = ?`;
const query = `SELECT n1.alias AS alias_left, n2.alias AS alias_right, channels.* FROM channels LEFT JOIN nodes AS n1 ON n1.public_key = channels.node1_public_key LEFT JOIN nodes AS n2 ON n2.public_key = channels.node2_public_key WHERE node1_public_key = ? OR node2_public_key = ?`;
const [rows]: any = await DB.query(query, [public_key, public_key]);
return rows;
} catch (e) {

View File

@@ -3,16 +3,36 @@ import { Express, Request, Response } from 'express';
import channelsApi from './channels.api';
class ChannelsRoutes {
constructor(app: Express) {
constructor() { }
public initRoutes(app: Express) {
app
.get(config.MEMPOOL.API_URL_PREFIX + 'channels/:public_key', this.$getChannels)
.get(config.MEMPOOL.API_URL_PREFIX + 'channels/:short_id', this.$getChannel)
.get(config.MEMPOOL.API_URL_PREFIX + 'channels', this.$getChannels)
;
}
private async $getChannel(req: Request, res: Response) {
try {
const channel = await channelsApi.$getChannel(req.params.short_id);
if (!channel) {
res.status(404).send('Channel not found');
return;
}
res.json(channel);
} catch (e) {
res.status(500).send(e instanceof Error ? e.message : e);
}
}
private async $getChannels(req: Request, res: Response) {
try {
const channels = await channelsApi.$getChannelsForNode(req.params.public_key);
res.json(channels);
if (typeof req.query.public_key !== 'string') {
res.status(501).send('Missing parameter: public_key');
return;
}
const channels = await channelsApi.$getChannelsForNode(req.query.public_key);
res.json(channels);
} catch (e) {
res.status(500).send(e instanceof Error ? e.message : e);
}
@@ -20,4 +40,4 @@ class ChannelsRoutes {
}
export default ChannelsRoutes;
export default new ChannelsRoutes();

View File

@@ -1,14 +1,15 @@
import config from '../../config';
import { Express, Request, Response } from 'express';
import nodesApi from './nodes.api';
import channelsApi from './channels.api';
class NodesRoutes {
constructor(app: Express) {
constructor() { }
public initRoutes(app: Express) {
app
.get(config.MEMPOOL.API_URL_PREFIX + 'statistics/latest', this.$getGeneralStats)
.get(config.MEMPOOL.API_URL_PREFIX + 'nodes/top', this.$getTopNodes)
.get(config.MEMPOOL.API_URL_PREFIX + 'nodes/:public_key', this.$getNode)
;
.get(config.MEMPOOL.API_URL_PREFIX + 'statistics/latest', this.$getGeneralStats)
.get(config.MEMPOOL.API_URL_PREFIX + 'nodes/top', this.$getTopNodes)
.get(config.MEMPOOL.API_URL_PREFIX + 'nodes/:public_key', this.$getNode)
;
}
private async $getNode(req: Request, res: Response) {
@@ -47,4 +48,4 @@ class NodesRoutes {
}
}
export default NodesRoutes;
export default new NodesRoutes();

View File

@@ -1,21 +1,14 @@
import config from './config';
import * as express from 'express';
import * as http from 'http';
import logger from './logger';
import DB from './database';
import { Express, Request, Response, NextFunction } from 'express';
import databaseMigration from './database-migration';
import statsUpdater from './tasks/stats-updater.service';
import nodeSyncService from './tasks/node-sync.service';
import NodesRoutes from './api/nodes/nodes.routes';
import ChannelsRoutes from './api/nodes/channels.routes';
import server from './server';
logger.notice(`Mempool Server is running on port ${config.MEMPOOL.HTTP_PORT}`);
class LightningServer {
private server: http.Server | undefined;
private app: Express = express();
constructor() {
this.init();
}
@@ -27,27 +20,7 @@ class LightningServer {
statsUpdater.startService();
nodeSyncService.startService();
this.startServer();
}
startServer() {
this.app
.use((req: Request, res: Response, next: NextFunction) => {
res.setHeader('Access-Control-Allow-Origin', '*');
next();
})
.use(express.urlencoded({ extended: true }))
.use(express.text())
;
this.server = http.createServer(this.app);
this.server.listen(config.MEMPOOL.HTTP_PORT, () => {
logger.notice(`Mempool Lightning is running on port ${config.MEMPOOL.HTTP_PORT}`);
});
const nodeRoutes = new NodesRoutes(this.app);
const channelsRoutes = new ChannelsRoutes(this.app);
server.startServer();
}
}

View File

@@ -0,0 +1,38 @@
import { Express, Request, Response, NextFunction } from 'express';
import * as express from 'express';
import * as http from 'http';
import logger from './logger';
import config from './config';
import nodesRoutes from './api/nodes/nodes.routes';
import channelsRoutes from './api/nodes/channels.routes';
class Server {
private server: http.Server | undefined;
private app: Express = express();
public startServer() {
this.app
.use((req: Request, res: Response, next: NextFunction) => {
res.setHeader('Access-Control-Allow-Origin', '*');
next();
})
.use(express.urlencoded({ extended: true }))
.use(express.text())
;
this.server = http.createServer(this.app);
this.server.listen(config.MEMPOOL.HTTP_PORT, () => {
logger.notice(`Mempool Lightning is running on port ${config.MEMPOOL.HTTP_PORT}`);
});
this.initRoutes();
}
private initRoutes() {
nodesRoutes.initRoutes(this.app);
channelsRoutes.initRoutes(this.app);
}
}
export default new Server();

View File

@@ -15,12 +15,13 @@ class LightningStatsUpdater {
setTimeout(() => {
this.$logLightningStats();
this.$logNodeStatsDaily();
setInterval(() => {
this.$logLightningStats();
this.$logNodeStatsDaily();
}, 1000 * 60 * 60);
}, difference);
this.$logNodeStatsDaily();
}
private async $logNodeStatsDaily() {
@@ -28,7 +29,7 @@ class LightningStatsUpdater {
try {
const [state]: any = await DB.query(`SELECT string FROM state WHERE name = 'last_node_stats'`);
// Only store once per day
if (state[0] === currentDate) {
if (state[0].string === currentDate) {
return;
}
@@ -42,6 +43,7 @@ class LightningStatsUpdater {
node.channels_count_left, node.channels_count_right]);
}
await DB.query(`UPDATE state SET string = ? WHERE name = 'last_node_stats'`, [currentDate]);
logger.debug('Daily node stats has updated.');
} catch (e) {
logger.err('$logNodeStatsDaily() error: ' + (e instanceof Error ? e.message : e));
}
@@ -49,22 +51,26 @@ class LightningStatsUpdater {
private async $logLightningStats() {
try {
const networkInfo = await lightningApi.$getNetworkInfo();
const networkGraph = await lightningApi.$getNetworkGraph();
let total_capacity = 0;
for (const channel of networkGraph.channels) {
if (channel.capacity) {
total_capacity += channel.capacity;
}
}
const query = `INSERT INTO statistics(
added,
channel_count,
node_count,
total_capacity,
average_channel_size
total_capacity
)
VALUES (NOW(), ?, ?, ?, ?)`;
VALUES (NOW(), ?, ?, ?)`;
await DB.query(query, [
networkInfo.channel_count,
networkInfo.node_count,
networkInfo.total_capacity,
networkInfo.average_channel_size
networkGraph.channels.length,
networkGraph.nodes.length,
total_capacity,
]);
} catch (e) {
logger.err('$logLightningStats() error: ' + (e instanceof Error ? e.message : e));