feat: forward channel route query

This commit is contained in:
AP 2019-12-11 22:42:23 +01:00
parent 831bc44fc5
commit 3ef05b338e
3 changed files with 149 additions and 31 deletions

View file

@ -1,15 +0,0 @@
import { GraphQLObjectType, GraphQLString } from "graphql";
export const ForwardChannelsType = new GraphQLObjectType({
name: "forwardChannelType",
fields: () => {
return {
incoming: {
type: GraphQLString
},
outgoing: {
type: GraphQLString
}
};
}
});

View file

@ -1,20 +1,34 @@
import { GraphQLString, GraphQLNonNull } from 'graphql';
import { getForwards as getLnForwards } from 'ln-service';
import {
getForwards as getLnForwards,
getNode,
getChannel,
getWalletInfo,
} from 'ln-service';
import { logger } from '../../../helpers/logger';
import { requestLimiter } from '../../../helpers/rateLimiter';
import { subHours, subDays } from 'date-fns';
import { countArray } from './Helpers';
import { countArray, countRoutes } from './Helpers';
import { ForwardCompleteProps } from './ForwardReport.interface';
import { ForwardChannelsType } from '../../../schemaTypes/query/report/ForwardChannels';
import { sortBy } from 'underscore';
import { getAuthLnd, getErrorMsg } from '../../../helpers/helpers';
interface NodeProps {
alias: string;
color: string;
}
interface ChannelsProps {
policies: { public_key: string }[];
}
export const getForwardChannelsReport = {
type: ForwardChannelsType,
type: GraphQLString,
args: {
auth: { type: new GraphQLNonNull(GraphQLString) },
time: { type: GraphQLString },
order: { type: GraphQLString },
type: { type: GraphQLString },
},
resolve: async (root: any, params: any, context: any) => {
await requestLimiter(context.ip, 'forwardChannels');
@ -32,6 +46,66 @@ export const getForwardChannelsReport = {
startDate = subHours(endDate, 24);
}
const getNodeAlias = async (id: string, publicKey: string) => {
const channelInfo: ChannelsProps = await getChannel({
lnd,
id,
});
const partnerPublicKey =
channelInfo.policies[0].public_key !== publicKey
? channelInfo.policies[0].public_key
: channelInfo.policies[1].public_key;
const nodeInfo: NodeProps = await getNode({
lnd,
is_omitting_channels: true,
public_key: partnerPublicKey,
});
return {
alias: nodeInfo.alias,
color: nodeInfo.color,
};
};
const getRouteAlias = (array: any[], publicKey: string) =>
Promise.all(
array.map(async channel => {
const nodeAliasIn = await getNodeAlias(
channel.in,
publicKey,
);
const nodeAliasOut = await getNodeAlias(
channel.out,
publicKey,
);
return {
aliasIn: nodeAliasIn.alias,
colorIn: nodeAliasIn.color,
aliasOut: nodeAliasOut.alias,
colorOut: nodeAliasOut.color,
...channel,
};
}),
);
const getAlias = (array: any[], publicKey: string) =>
Promise.all(
array.map(async channel => {
const nodeAlias = await getNodeAlias(
channel.name,
publicKey,
);
return {
alias: nodeAlias.alias,
color: nodeAlias.color,
...channel,
};
}),
);
try {
const forwardsList: ForwardCompleteProps = await getLnForwards({
lnd: lnd,
@ -40,20 +114,49 @@ export const getForwardChannelsReport = {
limit: 10000,
});
const incomingCount = countArray(forwardsList.forwards, true);
const outgoingCount = countArray(forwardsList.forwards, false);
const walletInfo: { public_key: string } = await getWalletInfo({
lnd,
});
const sortedInCount = sortBy(incomingCount, params.order)
.reverse()
.slice(0, 5);
const sortedOutCount = sortBy(outgoingCount, params.order)
.reverse()
.slice(0, 5);
if (params.type === 'route') {
const mapped = forwardsList.forwards.map(forward => {
return {
route: `${forward.incoming_channel} - ${forward.outgoing_channel}`,
...forward,
};
});
const grouped = countRoutes(mapped);
return {
incoming: JSON.stringify(sortedInCount),
outgoing: JSON.stringify(sortedOutCount),
};
const routeAlias = await getRouteAlias(
grouped,
walletInfo.public_key,
);
const sortedRoute = sortBy(routeAlias, params.order)
.reverse()
.slice(0, 10);
return JSON.stringify(sortedRoute);
} else if (params.type === 'incoming') {
const incomingCount = countArray(forwardsList.forwards, true);
const incomingAlias = await getAlias(
incomingCount,
walletInfo.public_key,
);
const sortedInCount = sortBy(incomingAlias, params.order)
.reverse()
.slice(0, 10);
return JSON.stringify(sortedInCount);
} else {
const outgoingCount = countArray(forwardsList.forwards, false);
const outgoingAlias = await getAlias(
outgoingCount,
walletInfo.public_key,
);
const sortedOutCount = sortBy(outgoingAlias, params.order)
.reverse()
.slice(0, 10);
return JSON.stringify(sortedOutCount);
}
} catch (error) {
logger.error('Error getting forward channel report: %o', error);
throw new Error(getErrorMsg(error));

View file

@ -74,3 +74,33 @@ export const countArray = (list: ForwardProps[], type: boolean) => {
return channelInfo;
};
export const countRoutes = (list: ForwardProps[]) => {
const grouped = groupBy(list, 'route');
const channelInfo = [];
for (const key in grouped) {
if (grouped.hasOwnProperty(key)) {
const element = grouped[key];
const fee = element
.map(forward => forward.fee)
.reduce((p, c) => p + c);
const tokens = element
.map(forward => forward.tokens)
.reduce((p, c) => p + c);
channelInfo.push({
route: key,
in: element[0].incoming_channel,
out: element[0].outgoing_channel,
amount: element.length,
fee: fee,
tokens: tokens,
});
}
}
return channelInfo;
};