From 02d9406235d548c061f82d6430c33ed6398aeda3 Mon Sep 17 00:00:00 2001 From: jamaljsr <1356600+jamaljsr@users.noreply.github.com> Date: Mon, 14 Oct 2019 08:58:39 -0400 Subject: [PATCH] refactor(lnd): move LND default responses to shared folder --- electron/lnd/lndProxyServer.ts | 3 +- src/shared/index.ts | 1 + .../responses.ts => src/shared/lndDefaults.ts | 63 +++++++++++-------- src/store/models/designer.ts | 4 +- src/utils/chart.spec.ts | 55 ++++++++++++++++ src/utils/chart.ts | 30 ++++----- 6 files changed, 108 insertions(+), 48 deletions(-) rename electron/lnd/responses.ts => src/shared/lndDefaults.ts (75%) create mode 100644 src/utils/chart.spec.ts diff --git a/electron/lnd/lndProxyServer.ts b/electron/lnd/lndProxyServer.ts index f30ea88..7784250 100644 --- a/electron/lnd/lndProxyServer.ts +++ b/electron/lnd/lndProxyServer.ts @@ -1,9 +1,8 @@ import { IpcMain } from 'electron'; import { debug } from 'electron-log'; import createLndRpc, * as LND from '@radar/lnrpc'; -import { ipcChannels } from '../../src/shared'; +import { DefaultsKey, ipcChannels, withDefaults } from '../../src/shared'; import { LndNode } from '../types'; -import { DefaultsKey, withDefaults } from './responses'; /** * mapping of node name <-> LnRpc to cache these objects. The createLndRpc function diff --git a/src/shared/index.ts b/src/shared/index.ts index bacd8ac..18b04f7 100644 --- a/src/shared/index.ts +++ b/src/shared/index.ts @@ -1 +1,2 @@ export { default as ipcChannels } from './ipcChannels'; +export * from './lndDefaults'; diff --git a/electron/lnd/responses.ts b/src/shared/lndDefaults.ts similarity index 75% rename from electron/lnd/responses.ts rename to src/shared/lndDefaults.ts index 5c11c33..0f402b2 100644 --- a/electron/lnd/responses.ts +++ b/src/shared/lndDefaults.ts @@ -1,7 +1,28 @@ import * as LND from '@radar/lnrpc'; -import { ipcChannels } from '../../src/shared'; +import { ipcChannels } from './'; -const defaultChannel = (value: LND.Channel): LND.Channel => ({ +export const defaultInfo = ( + value: Partial, +): LND.GetInfoResponse => ({ + identityPubkey: '', + alias: '', + numPendingChannels: 0, + numActiveChannels: 0, + numPeers: 0, + blockHeight: 0, + blockHash: '', + syncedToChain: false, + testnet: false, + chains: [], + uris: [], + bestHeaderTimestamp: '', + version: '', + numInactiveChannels: 0, + color: '', + ...value, +}); + +export const defaultChannel = (value: Partial): LND.Channel => ({ active: false, remotePubkey: '', channelPoint: '', @@ -26,7 +47,9 @@ const defaultChannel = (value: LND.Channel): LND.Channel => ({ ...value, }); -const defaultPendingChannel = (value: LND.PendingChannel): LND.PendingChannel => ({ +export const defaultPendingChannel = ( + value: Partial, +): LND.PendingChannel => ({ remoteNodePub: '', channelPoint: '', capacity: '0', @@ -37,8 +60,8 @@ const defaultPendingChannel = (value: LND.PendingChannel): LND.PendingChannel => ...value, }); -const defaultPendingOpenChannel = ( - value: LND.PendingOpenChannel, +export const defaultPendingOpenChannel = ( + value: Partial, ): LND.PendingOpenChannel => ({ channel: defaultPendingChannel(value.channel as LND.PendingChannel), confirmationHeight: 0, @@ -48,14 +71,16 @@ const defaultPendingOpenChannel = ( ...value, }); -const defaultClosedChannel = (value: LND.ClosedChannel): LND.ClosedChannel => ({ +export const defaultClosedChannel = ( + value: Partial, +): LND.ClosedChannel => ({ channel: defaultPendingChannel(value.channel as LND.PendingChannel), closingTxid: '', ...value, }); -const defaultForceClosedChannel = ( - value: LND.ForceClosedChannel, +export const defaultForceClosedChannel = ( + value: Partial, ): LND.ForceClosedChannel => ({ channel: defaultPendingChannel(value.channel as LND.PendingChannel), closingTxid: '', @@ -67,8 +92,8 @@ const defaultForceClosedChannel = ( ...value, }); -const defaultWaitingCloseChannel = ( - value: LND.WaitingCloseChannel, +export const defaultWaitingCloseChannel = ( + value: Partial, ): LND.WaitingCloseChannel => ({ channel: defaultPendingChannel(value.channel as LND.PendingChannel), limboBalance: '0', @@ -78,23 +103,7 @@ const defaultWaitingCloseChannel = ( const mapArray = (arr: T[], func: (value: T) => T) => (arr || []).map(func); const defaults = { - [ipcChannels.getInfo]: { - identityPubkey: '', - alias: '', - numPendingChannels: 0, - numActiveChannels: 0, - numPeers: 0, - blockHeight: 0, - blockHash: '', - syncedToChain: false, - testnet: false, - chains: [], - uris: [], - bestHeaderTimestamp: '', - version: '', - numInactiveChannels: 0, - color: '', - } as LND.GetInfoResponse, + [ipcChannels.getInfo]: defaultInfo, [ipcChannels.walletBalance]: { confirmedBalance: '0', totalBalance: '0', diff --git a/src/store/models/designer.ts b/src/store/models/designer.ts index 07537f4..ea64b86 100644 --- a/src/store/models/designer.ts +++ b/src/store/models/designer.ts @@ -12,7 +12,7 @@ import { thunkOn, } from 'easy-peasy'; import { Network, Status, StoreInjections } from 'types'; -import { updateChartFromNetwork } from 'utils/chart'; +import { updateChartFromLnd } from 'utils/chart'; import { RootModel } from './'; export const rotate = ( @@ -107,7 +107,7 @@ const designerModel: DesignerModel = { const nodesData = getStoreState().lnd.nodes; const { allCharts } = getState(); // sync the chart with data from all of the nodes - const chart = updateChartFromNetwork(allCharts[network.id], nodesData); + const chart = updateChartFromLnd(allCharts[network.id], nodesData); actions.setAllCharts({ ...allCharts, [network.id]: chart, diff --git a/src/utils/chart.spec.ts b/src/utils/chart.spec.ts new file mode 100644 index 0000000..ad59faa --- /dev/null +++ b/src/utils/chart.spec.ts @@ -0,0 +1,55 @@ +import { IChart } from '@mrblenny/react-flow-chart'; +import { defaultChannel, defaultInfo } from 'shared'; +import { LndNodeMapping } from 'store/models/lnd'; +import { Network } from 'types'; +import { initChartFromNetwork, updateChartFromLnd } from './chart'; +import { getNetwork } from './tests'; + +describe('Chart Util', () => { + let network: Network; + let chart: IChart; + let lndData: LndNodeMapping; + + beforeEach(() => { + network = getNetwork(); + chart = initChartFromNetwork(network); + lndData = { + [network.nodes.lightning[0].name]: { + info: defaultInfo({ identityPubkey: 'lnd1pubkey' }), + channels: { + open: [ + defaultChannel({ + remotePubkey: 'lnd2pubkey', + channelPoint: 'xxxxxxxxxxxxxxxx:0', + capacity: '1000', + localBalance: '400', + remoteBalance: '600', + initiator: true, + }), + ], + opening: [], + closing: [], + forceClosing: [], + waitingClose: [], + }, + }, + [network.nodes.lightning[1].name]: { + info: defaultInfo({ identityPubkey: 'lnd2pubkey' }), + channels: { + open: [], + opening: [], + closing: [], + forceClosing: [], + waitingClose: [], + }, + }, + }; + }); + + describe('updateChartFromNetwork', () => { + it('should create link for a channel', () => { + const result = updateChartFromLnd(chart, lndData); + expect(result.links['xxxxxxxxxx:0']).toBeTruthy(); + }); + }); +}); diff --git a/src/utils/chart.ts b/src/utils/chart.ts index d591d9c..e190b6c 100644 --- a/src/utils/chart.ts +++ b/src/utils/chart.ts @@ -157,42 +157,38 @@ const updateLinksAndPorts = ( }; }; -export const updateChartFromNetwork = ( - chart: IChart, - nodesData: LndNodeMapping, -): IChart => { +export const updateChartFromLnd = (chart: IChart, lndData: LndNodeMapping): IChart => { // create a mapping of node name to pubkey for lookups const pubkeys: Record = {}; - Object.entries(nodesData).forEach(([name, data]) => { + Object.entries(lndData).forEach(([name, data]) => { if (!data.info || !data.info.identityPubkey) return; pubkeys[data.info.identityPubkey] = name; }); const nodes = { ...chart.nodes }; const links = { ...chart.links }; - const linkIds: string[] = []; + const createdLinkIds: string[] = []; // update the node and links for each node - Object.entries(nodesData).forEach(([fromName, data]) => { - // const { newNode, newLinks } = updateNode(fromName, nodes[fromName], data, pubkeys); + Object.entries(lndData).forEach(([fromName, data]) => { const fromNode = nodes[fromName]; if (data.channels) { const { open, opening, closing, forceClosing, waitingClose } = data.channels; // merge all of the channel types into one array - const mapPending = (c: any) => c.channel as PendingChannel; + const pluckChan = (c: any) => c.channel as PendingChannel; const allChannels = [ ...open.filter(c => c.initiator).map(mapOpenChannel), - ...opening.map(mapPending).map(mapPendingChannel('Opening')), - ...closing.map(mapPending).map(mapPendingChannel('Closing')), - ...forceClosing.map(mapPending).map(mapPendingChannel('Force Closing')), - ...waitingClose.map(mapPending).map(mapPendingChannel('Waiting to Close')), + ...opening.map(pluckChan).map(mapPendingChannel('Opening')), + ...closing.map(pluckChan).map(mapPendingChannel('Closing')), + ...forceClosing.map(pluckChan).map(mapPendingChannel('Force Closing')), + ...waitingClose.map(pluckChan).map(mapPendingChannel('Waiting to Close')), ]; allChannels.forEach(channel => { updateLinksAndPorts(channel, pubkeys, nodes, fromNode, links); - linkIds.push(channel.uniqueId); + createdLinkIds.push(channel.uniqueId); }); nodes[fromName] = { @@ -204,7 +200,7 @@ export const updateChartFromNetwork = ( // remove links for channels that no longer exist Object.keys(links).forEach(linkId => { // don't remove links for existing channels - if (linkIds.includes(linkId)) return; + if (createdLinkIds.includes(linkId)) return; // don't remove links to bitcoin nodes if (linkId.endsWith('-backend')) return; // delete all other links @@ -217,14 +213,14 @@ export const updateChartFromNetwork = ( // don't remove special ports if (['empty-left', 'empty-right', 'backend'].includes(portId)) return; // don't remove ports for existing channels - if (linkIds.includes(portId)) return; + if (createdLinkIds.includes(portId)) return; // delete all other ports delete node.ports[portId]; }); }); // resize chart nodes if necessary to fit new ports - Object.keys(nodesData).forEach(name => updateNodeSize(nodes[name])); + Object.keys(lndData).forEach(name => updateNodeSize(nodes[name])); return { ...chart,