Channel component
This commit is contained in:
@@ -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) {
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
38
lightning-backend/src/server.ts
Normal file
38
lightning-backend/src/server.ts
Normal 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();
|
||||
@@ -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));
|
||||
|
||||
Reference in New Issue
Block a user