diff --git a/CHANGELOG.md b/CHANGELOG.md index 92ccceb..e5ab7d1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,11 @@ # Versions +## Version 10.9.2 + +- `chart-fees-earned`: Fix forwards in closed channels not counting for pubkey charts +- `forwards`: Show HTLC in-flight indicator when there is a pending payment +- `open-balanced-channel`: Reduce superfluous tx broadcast error reporting + ## Version 10.9.1 - `accounting`: Change default fiat rate provider to coingecko diff --git a/README.md b/README.md index e2970ab..fb7300d 100644 --- a/README.md +++ b/README.md @@ -179,6 +179,7 @@ bos utxos - The `open` [command howto](https://satbase.org/bos-open/) - The `rebalance` [command howto](https://yalls.org/articles/97d67df1-d721-417d-a6c0-11d793739be9:0965AC5E-56CD-4870-9041-E69616660E6F/327ed9f6-3a73-41c2-a9c7-8c4e274bdd54) - Another `rebalance` [command howto](https://yalls.org/articles/97d67df1-d721-417d-a6c0-11d793739be9:0965AC5E-56CD-4870-9041-E69616660E6F/30a7c519-0ec0-4644-b3aa-341c41bac296) +- Running `telegram` [via nohup/tmux howto](https://plebnet.wiki/wiki/Umbrel_-_Installing_BoS) Want to stack some sats? Write your own LN paywalled guide! diff --git a/balances/get_accounting_report.js b/balances/get_accounting_report.js index 2bf26b6..6eb3852 100644 --- a/balances/get_accounting_report.js +++ b/balances/get_accounting_report.js @@ -86,7 +86,7 @@ module.exports = (args, cbk) => { cbk); }], - // Accounting + // Convert the accounting CSV into rows for table display output accounting: ['getAccounting', ({getAccounting}, cbk) => { const csvType = `${categories[args.category]}_csv`; diff --git a/chain/get_utxos.js b/chain/get_utxos.js index 3141760..3d8c4f0 100644 --- a/chain/get_utxos.js +++ b/chain/get_utxos.js @@ -27,7 +27,6 @@ const uniq = arr => Array.from(new Set(arr)); [is_confirmed]: lnd: [min_tokens]: - [node]: } // Non-count response diff --git a/commands/fetch_request.js b/commands/fetch_request.js index 4a59722..562df1b 100644 --- a/commands/fetch_request.js +++ b/commands/fetch_request.js @@ -1,6 +1,6 @@ const {stringify} = require('querystring'); -const {AbortController} = require("abort-controller") +const {AbortController} = require('abort-controller'); const encodeQs = qs => !qs ? '' : '?' + stringify(qs); const timeoutSignals = new WeakMap(); diff --git a/network/get_forwards.js b/network/get_forwards.js index bc19ca4..956e57a 100644 --- a/network/get_forwards.js +++ b/network/get_forwards.js @@ -221,6 +221,9 @@ module.exports = (args, cbk) => { .filter(n => n.is_opening) .filter(n => n.partner_public_key === node.id); + const hasHtlcChannel = connected + .find(n => !!n.pending_payments.length); + const local = [].concat(nodeChannels).concat(pending) .filter(n => !!n.local_balance) .reduce((sum, n) => sum + n.local_balance, Number()); @@ -239,6 +242,7 @@ module.exports = (args, cbk) => { earned_outbound_fees: forwards.reduce((sum, n) => sum + n.fee, 0), icons: !!nodeIcons ? nodeIcons.icons : undefined, is_disconnected: isDisconnected || undefined, + is_forwarding: hasHtlcChannel || undefined, is_inactive: !isDisconnected && !active.length || undefined, is_pending: !!pending.length || undefined, is_private: !!isHidden || undefined, @@ -292,6 +296,7 @@ module.exports = (args, cbk) => { alias: peer.alias, icons: peer.icons, is_disconnected: peer.is_disconnected, + is_forwarding: peer.is_forwarding, is_inactive: peer.is_inactive, is_pending: peer.is_pending, is_private: peer.is_private, diff --git a/network/remove_peer.js b/network/remove_peer.js index 6dca607..b2f314a 100644 --- a/network/remove_peer.js +++ b/network/remove_peer.js @@ -15,6 +15,7 @@ const {floor} = Math; const defaultDays = 365 * 2; const getMempoolRetries = 10; const {isArray} = Array; +const isPublicKey = n => !!n && /^0[2-3][0-9A-F]{64}$/i.test(n); const maxMempoolSize = 2e6; const regularConf = 72; const slowConf = 144; @@ -67,6 +68,10 @@ module.exports = (args, cbk) => { return cbk([400, 'ExpectedSpecificOutpointsToRemoveFromPeer']); } + if (!!args.public_key && !isPublicKey(args.public_key)) { + return cbk([400, 'ExpectedPublicKeyOfPeerToRemove']); + } + if (!args.request) { return cbk([400, 'RequestIsRequiredToRemovePeer']); } diff --git a/package-lock.json b/package-lock.json index 01a31c2..bb33711 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "balanceofsatoshis", - "version": "10.9.1", + "version": "10.9.2", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "balanceofsatoshis", - "version": "10.9.1", + "version": "10.9.2", "license": "MIT", "dependencies": { "@alexbosworth/html2unicode": "1.1.5", diff --git a/package.json b/package.json index dc9c646..b2fc8bd 100644 --- a/package.json +++ b/package.json @@ -79,5 +79,5 @@ "postpublish": "docker buildx build --platform linux/amd64,linux/arm64,linux/arm/v7 -t alexbosworth/balanceofsatoshis --push .", "test": "tap --branches=1 --functions=1 --lines=1 --statements=1 -t 60 test/arrays/*.js test/balances/*.js test/chain/*.js test/display/*.js test/encryption/*.js test/fiat/*.js test/lnd/*.js test/network/*.js test/nodes/*.js test/peers/*.js test/responses/*.js test/routing/*.js test/services/*.js test/swaps/*.js test/tags/*.js test/wallets/*.js" }, - "version": "10.9.1" + "version": "10.9.2" } diff --git a/routing/forwards_via_peer.js b/routing/forwards_via_peer.js index ac6f966..6287d38 100644 --- a/routing/forwards_via_peer.js +++ b/routing/forwards_via_peer.js @@ -4,6 +4,10 @@ const uniq = arr => Array.from(new Set(arr)); /** Filter out forwards via a peer { + closed_channels: [{ + [id]: + partner_public_key: + }] forwards: [{ created_at: fee: @@ -41,13 +45,22 @@ module.exports = args => { return {forwards: args.forwards}; } + const closedChans = args.closed_channels + .filter(channel => channel.partner_public_key === args.via) + .map(({id}) => id); + const privateChans = args.private_channels .filter(channel => channel.partner_public_key === args.via) .map(({id}) => id); const publicChans = args.public_channels.map(({id}) => id); - const channelIds = uniq([].concat(privateChans).concat(publicChans)); + const allChans = [] + .concat(closedChans) + .concat(privateChans) + .concat(publicChans); + + const channelIds = uniq(allChans); const forwards = args.forwards.filter(forward => { if (channelIds.indexOf(forward.incoming_channel) !== notFound) { diff --git a/routing/get_forwards.js b/routing/get_forwards.js index 45daf33..90e09d2 100644 --- a/routing/get_forwards.js +++ b/routing/get_forwards.js @@ -1,6 +1,7 @@ const asyncAuto = require('async/auto'); const asyncUntil = require('async/until'); const {getChannels} = require('ln-service'); +const {getClosedChannels} = require('ln-service'); const {getForwards} = require('ln-service'); const {getNode} = require('ln-service'); const {returnResult} = require('asyncjs-util'); @@ -51,6 +52,16 @@ module.exports = ({after, lnd, via}, cbk) => { return cbk(); }, + // Get closed channels with via peer + getClosedChannels: ['validate', ({}, cbk) => { + // Exit early when there is no via node specified + if (!via) { + return cbk(); + } + + return getClosedChannels({lnd}, cbk); + }], + // Get forwards getForwards: ['validate', ({}, cbk) => { const forwards = []; @@ -117,13 +128,15 @@ module.exports = ({after, lnd, via}, cbk) => { // Full set of forwards forwards: [ + 'getClosedChannels', 'getForwards', 'getNode', 'getPrivateChannels', - ({getForwards, getNode, getPrivateChannels}, cbk) => + ({getClosedChannels, getForwards, getNode, getPrivateChannels}, cbk) => { const {forwards} = forwardsViaPeer({ via, + closed_channels: !!via ? getClosedChannels.channels : [], forwards: getForwards, private_channels: !!via ? getPrivateChannels.channels : [], public_channels: !!via ? getNode.channels : [], diff --git a/services/index.js b/services/index.js index 64de2eb..b00203c 100644 --- a/services/index.js +++ b/services/index.js @@ -1,17 +1,11 @@ const advertise = require('./advertise'); const openBalancedChannel = require('./open_balanced_channel'); -const purchasePing = require('./purchase_ping'); -const serviceKeySendRequests = require('./service_key_send_requests'); const servicePaidRequests = require('./service_paid_requests'); -const simulateKeySendRequest = require('./simulate_key_send_request'); const usePaidService = require('./use_paid_service'); module.exports = { advertise, openBalancedChannel, - purchasePing, - serviceKeySendRequests, servicePaidRequests, - simulateKeySendRequest, usePaidService, }; diff --git a/services/open_balanced_channel.js b/services/open_balanced_channel.js index 6b5fa4d..cbb4276 100644 --- a/services/open_balanced_channel.js +++ b/services/open_balanced_channel.js @@ -27,6 +27,7 @@ const format = 'p2wpkh'; const hexAsBuffer = hex => Buffer.from(hex, 'hex'); const interval = 1000 * 15; const isOldNodeVersion = () => !Buffer.alloc(0).writeBigUInt64BE; +const minErrorCount = 4; const networkMainnet = 'btc'; const networkTestnet = 'btctestnet'; const {p2wpkh} = payments; @@ -281,6 +282,7 @@ module.exports = ({after, ask, lnd, logger, recover}, cbk) => { 'initiate', ({accept, initiate}, cbk) => { + const broadcastErrors = []; const ready = accept || initiate; logger.info({ @@ -292,6 +294,15 @@ module.exports = ({after, ask, lnd, logger, recover}, cbk) => { return asyncEachSeries(ready.transactions, (transaction, cbk) => { return asyncRetry({interval, times}, cbk => { return broadcastChainTransaction({lnd, transaction}, (err, r) => { + if (!!err) { + broadcastErrors.push(err); + } + + // Exit early when there are not many errors yet + if (!!err && broadcastErrors.length < minErrorCount) { + return cbk(err); + } + // Exit early when there is an error broadcasting the tx if (!!err) { logger.error({err}); diff --git a/services/purchase_ping.js b/services/purchase_ping.js deleted file mode 100644 index 086a829..0000000 --- a/services/purchase_ping.js +++ /dev/null @@ -1,140 +0,0 @@ -const asyncAuto = require('async/auto'); -const {createInvoice} = require('ln-service'); -const {formatTokens} = require('ln-sync'); -const moment = require('moment'); -const {returnResult} = require('asyncjs-util'); -const {subscribeToInvoice} = require('ln-service'); - -const {probeDestination} = require('./../network'); - -const description = '(bos) pong'; -const {duration} = moment; -const expiration = () => moment().add(1, 'day').toISOString(); -const {now} = Date; -const pingBackMessage = request => `(bos) Please ping me back at ${request}`; -const pingCost = 10; -const responsePingTokens = 1; -const typePing = '8470534167946609795'; -const utf8AsHex = utf8 => Buffer.from(utf8).toString('hex'); - -/** Purchase a ping - - { - destination: - lnd: - logger: - } - - @returns via cbk or Promise - { - received_pong: - latency: - sent: - received_back: - received_via: [] - total_ping_cost: - } -*/ -module.exports = ({destination, lnd, logger}, cbk) => { - return new Promise((resolve, reject) => { - return asyncAuto({ - // Check arguments - validate: cbk => { - if (!destination) { - return cbk([400, 'ExpectedDestinationToPurchasePing']); - } - - if (!lnd) { - return cbk([400, 'ExpectedLndToPurchasePing']); - } - - if (!logger) { - return cbk([400, 'ExpectedLoggerToPurchasePing']); - } - - return cbk(); - }, - - // Create a pingback invoice - createInvoice: ['validate', ({}, cbk) => { - return createInvoice({ - description, - lnd, - expires_at: expiration(), - tokens: responsePingTokens, - }, - cbk); - }], - - // Ping and then wait for a pong response - ping: ['createInvoice', ({createInvoice}, cbk) => { - const sub = subscribeToInvoice({lnd, id: createInvoice.id}); - - sub.once('error', err => cbk(err)); - - let payment; - const {request} = createInvoice; - const start = now(); - - sub.on('invoice_updated', invoice => { - // Exit early when the ping is expired - if (!!invoice.is_canceled) { - sub.removeAllListeners(); - - return cbk([504, 'FailedToGetPongResponseInTime']); - } - - // Exit early when the invoice has not been paid - if (!invoice.is_confirmed) { - return; - } - - sub.removeAllListeners(); - - const channels = invoice.payments.filter(n => !!n.is_confirmed); - - const cost = payment.paid - invoice.received; - - const [via, viaMore] = channels.map(n => n.in_channel); - - return cbk(null, { - received_pong: true, - latency_ms: now() - start, - received_back: formatTokens({tokens: invoice.received}).display, - received_via: !viaMore ? via : channels.map(n => n.in_channel), - total_ping_cost: formatTokens({tokens: cost}).display, - }); - }); - - probeDestination({ - destination, - lnd, - logger, - is_push: true, - is_real_payment: true, - max_fee: pingCost, - message: pingBackMessage(request), - messages: [{type: typePing, value: utf8AsHex(request)}], - tokens: pingCost, - }, - (err, res) => { - if (!!err) { - sub.removeAllListeners(); - - return cbk(err); - } - - logger.info({ - ping: res.id, - sent: formatTokens({tokens: res.paid}).display, - }); - - payment = res; - - return; - }); - }], - }, - returnResult({reject, resolve, of: 'ping'}, cbk)); - }); -}; diff --git a/telegram/watch.js b/telegram/watch.js deleted file mode 100644 index ea1b2d7..0000000 --- a/telegram/watch.js +++ /dev/null @@ -1,577 +0,0 @@ -const asyncAuto = require('async/auto'); -const asyncEach = require('async/each'); -const asyncMap = require('async/map'); -const {describeAttemptPaymentFail} = require('ln-sync'); -const {describeAttemptPaymentSent} = require('ln-sync'); -const {describeAttemptingPayment} = require('ln-sync'); -const {describeBaseFeeUpdated} = require('ln-sync'); -const {describeBlockAdded} = require('ln-sync'); -const {describeChannelAdded} = require('ln-sync'); -const {describeChannelClosed} = require('ln-sync'); -const {describeChannelDisabled} = require('ln-sync'); -const {describeChannelEnabled} = require('ln-sync'); -const {describeFeeRateUpdated} = require('ln-sync'); -const {describeForwardFailed} = require('ln-sync'); -const {describeForwardStarting} = require('ln-sync'); -const {describeForwardSucceeded} = require('ln-sync'); -const {describeHtlcReceived} = require('ln-sync'); -const {describeMaxHtlcUpdated} = require('ln-sync'); -const {describeMinHtlcUpdated} = require('ln-sync'); -const {describeNodeAdded} = require('ln-sync'); -const {describePaymentRejected} = require('ln-sync'); -const {describePeerConnected} = require('ln-sync'); -const {describePeerDisconnected} = require('ln-sync'); -const {describePeerReconnected} = require('ln-sync'); -const {describePolicyCltvUpdated} = require('ln-sync'); -const {describePolicyDisabled} = require('ln-sync'); -const {describePolicyEnabled} = require('ln-sync'); -const {describeProbeReceived} = require('ln-sync'); -const {getWalletInfo} = require('ln-service'); -const {logLineForChangeEvent} = require('ln-sync'); -const {returnResult} = require('asyncjs-util'); -const {subscribeToChanges} = require('ln-sync'); -const {syncCurrentRecords} = require('ln-sync'); - -const {getLnds} = require('./../lnd'); - -const {isArray} = Array; -const mode = 'local'; - -/** Watch syncing happening in relation to nodes - - { - db: - logger: - nodes: [] - } - - @returns via cbk or Promise -*/ -module.exports = ({db, logger, nodes}, cbk) => { - return new Promise((resolve, reject) => { - return asyncAuto({ - // Check arguments - validate: cbk => { - if (!db) { - return cbk([400, 'ExpectedDatabaseToWatchNodes']); - } - - if (!logger) { - return cbk([400, 'ExpectedLoggerToWatchNodes']); - } - - if (!isArray(nodes)) { - return cbk([400, 'ExpectedArrayOfNodesToWatch']); - } - - return cbk(); - }, - - // Get LNDs - getLnds: ['validate', ({}, cbk) => getLnds({logger, nodes}, cbk)], - - // Get the public keys of the nodes - getKeys: ['getLnds', ({getLnds}, cbk) => { - return asyncMap(getLnds.lnds, (lnd, cbk) => { - return getWalletInfo({lnd}, cbk); - }, - cbk); - }], - - // Start watching for new records - syncChanges: ['getKeys', 'getLnds', ({getKeys, getLnds}, cbk) => { - const fromNodes = nodes.map((node, i) => { - return {node, lnd: getLnds.lnds[i]}; - }); - - asyncEach(fromNodes, ({lnd, node}, cbk) => { - let sub; - - try { - sub = subscribeToChanges({db, lnd}); - } catch (err) { - return cbk([503, 'FailedToSubscribeToChanges', {err}]); - } - - sub.on('attempt_payment_sent', async payment => { - try { - const {description} = await describeAttemptPaymentSent({ - db, - mtokens: payment.mtokens, - out_channel: payment.out_channel, - public_key: payment.public_key, - }); - - const event = 'attempt_payment_sent'; - - const {line} = logLineForChangeEvent({description, event, mode}); - - return !!line ? logger.info(line) : null; - } catch (err) { - return logger.error({err}); - } - }); - - sub.on('attempt_payment_failed', async payment => { - try { - const {description} = await describeAttemptPaymentFail({ - db, - mtokens: payment.mtokens, - out_channel: payment.out_channel, - public_key: payment.public_key, - }); - - const event = 'attempt_payment_failed'; - - const {line} = logLineForChangeEvent({description, event, mode}); - - return !!line ? logger.info(line) : null; - } catch (err) { - return logger.error({err}); - } - }); - - sub.on('attempting_payment', async payment => { - try { - const {description} = await describeAttemptingPayment({ - db, - mtokens: payment.mtokens, - out_channel: payment.out_channel, - public_key: payment.public_key, - }); - - const event = 'attempting_payment'; - - const {line} = logLineForChangeEvent({description, event, mode}); - - return !!line ? logger.info(line) : null; - } catch (err) { - return logger.error({err}); - } - }); - - sub.on('block_added', async block => { - const {description} = describeBlockAdded(block); - const event = 'block_added'; - - const {line} = logLineForChangeEvent({description, event, mode}); - - return !!line ? logger.info(line) : null; - }); - - sub.on('channel_added', async channel => { - try { - const event = 'channel_added'; - const {id} = channel; - - const {description} = await describeChannelAdded({db, id}); - - const {line} = logLineForChangeEvent({description, event, mode}); - - return !!line ? logger.info(line) : null; - } catch (err) { - return logger.error({err}); - } - }); - - sub.on('channel_closed', async channel => { - try { - const event = 'channel_closed'; - const {id} = channel; - - const {description} = await describeChannelClosed({db, id}); - - const {line} = logLineForChangeEvent({description, event, mode}); - - return !!line ? logger.info(line) : null; - } catch (err) { - return logger.error({err}); - } - }); - - sub.on('channel_disabled', async channel => { - try { - const event = 'channel_disabled'; - - const {description} = await describeChannelDisabled({ - db, - id: channel.id, - public_key: channel.public_key, - }); - - const {line} = logLineForChangeEvent({description, event, mode}); - - return !!line ? logger.info(line) : null; - } catch (err) { - return logger.error({err}); - } - }); - - sub.on('channel_enabled', async channel => { - try { - const event = 'channel_enabled'; - - const {description} = await describeChannelEnabled({ - db, - id: channel.id, - public_key: channel.public_key, - }); - - const {line} = logLineForChangeEvent({description, event, mode}); - - return !!line ? logger.info(line) : null; - } catch (err) { - return logger.error({err}); - } - }); - - sub.on('disconnected', async disconnected => { - try { - const event = 'disconnected'; - - const {description} = await describePeerDisconnected({ - db, - node: disconnected.node, - from: disconnected.from, - }); - - const {line} = logLineForChangeEvent({description, event, mode}); - - return !!line ? logger.info(line) : null; - } catch (err) { - return logger.error({err}); - } - }); - - sub.on('error', err => logger.error(err)); - - sub.on('failed_forward', async forward => { - try { - const event = 'failed_forward'; - - const {description} = await describeForwardFailed({ - db, - in_channel: forward.in_channel, - internal_failure: forward.internal_failure, - mtokens: forward.mtokens, - out_channel: forward.out_channel, - public_key: forward.public_key, - }); - - const {line} = logLineForChangeEvent({description, event, mode}); - - return !!line ? logger.info(line) : null; - } catch (err) { - return logger.error({err}); - } - }); - - sub.on('forwarded_payment', async forward => { - try { - const event = 'forwarded_payment'; - - const {description} = await describeForwardSucceeded({ - db, - fee_mtokens: forward.fee_mtokens, - in_channel: forward.in_channel, - mtokens: forward.mtokens, - out_channel: forward.out_channel, - public_key: forward.public_key, - }); - - const {line} = logLineForChangeEvent({description, event, mode}); - - return !!line ? logger.info(line) : null; - } catch (err) { - return logger.error({err}); - } - }); - - sub.on('forwarding', async forward => { - try { - const event = 'forwarding'; - - const {description} = await describeForwardStarting({ - db, - in_channel: forward.in_channel, - mtokens: forward.mtokens, - out_channel: forward.out_channel, - public_key: forward.public_key, - }); - - const {line} = logLineForChangeEvent({description, event, mode}); - - return !!line ? logger.info(line) : null; - } catch (err) { - return logger.error({err}); - } - }); - - sub.on('new_peer', async details => { - try { - const event = 'new_peer'; - - const {description} = await describePeerConnected({ - db, - node: details.node, - to: details.to, - }); - - const {line} = logLineForChangeEvent({description, event, mode}); - - return !!line ? logger.info(line) : null; - } catch (err) { - return logger.error({err}); - } - }); - - sub.on('node_added', async node => { - try { - const event = 'node_added'; - - const {description} = await describeNodeAdded({ - db, - id: node.public_key, - }); - - const {line} = logLineForChangeEvent({description, event, mode}); - - return !!line ? logger.info(line) : null; - } catch (err) { - return logger.error({err}); - } - }); - - sub.on('policy_base_fee_updated', async policy => { - try { - const event = 'policy_base_fee_updated'; - - const {description} = await describeBaseFeeUpdated({ - db, - id: policy.id, - local_keys: getKeys.map(n => n.public_key), - previous: policy.previous, - public_key: policy.public_key, - updated: policy.updated, - }); - - const {line} = logLineForChangeEvent({description, event, mode}); - - return !!line ? logger.info(line) : null; - } catch (err) { - return logger.error({err}); - } - }); - - sub.on('policy_cltv_delta_updated', async policy => { - try { - const {description} = await describePolicyCltvUpdated({ - db, - id: policy.id, - local_keys: getKeys.map(n => n.public_key), - previous: policy.previous, - public_key: policy.public_key, - updated: policy.updated, - }); - - const event = 'policy_cltv_delta_updated'; - - const {line} = logLineForChangeEvent({description, event, mode}); - - return !!line ? logger.info(line) : null; - } catch (err) { - return logger.error({err}); - } - }); - - sub.on('policy_disabled', async policy => { - try { - const {description} = await describePolicyDisabled({ - db, - id: policy.id, - local_keys: getKeys.map(n => n.public_key), - public_key: policy.public_key, - }); - - const event = 'policy_disabled'; - - const {line} = logLineForChangeEvent({description, event, mode}); - - return !!line ? logger.info(line) : null; - } catch (err) { - return logger.error({err}); - } - }); - - sub.on('policy_enabled', async policy => { - try { - const {description} = await describePolicyEnabled({ - db, - id: policy.id, - local_keys: getKeys.map(n => n.public_key), - public_key: policy.public_key, - }); - - const event = 'policy_enabled'; - - const {line} = logLineForChangeEvent({description, event, mode}); - - return !!line ? logger.info(line) : null; - } catch (err) { - return logger.error({err}); - } - }); - - sub.on('policy_fee_rate_updated', async policy => { - try { - const event = 'policy_fee_rate_updated'; - - const {description} = await describeFeeRateUpdated({ - db, - id: policy.id, - local_keys: getKeys.map(n => n.public_key), - previous: policy.previous, - public_key: policy.public_key, - updated: policy.updated, - }); - - const {line} = logLineForChangeEvent({description, event, mode}); - - return !!line ? logger.info(line) : null; - } catch (err) { - return logger.error({err}); - } - }); - - sub.on('policy_max_htlc_mtokens_updated', async policy => { - try { - const event = 'policy_max_htlc_mtokens_updated'; - - const {description} = await describeMaxHtlcUpdated({ - db, - id: policy.id, - local_keys: getKeys.map(n => n.public_key), - previous: policy.previous, - public_key: policy.public_key, - updated: policy.updated, - }); - - const {line} = logLineForChangeEvent({description, event, mode}); - - return !!line ? logger.info(line) : null; - } catch (err) { - return logger.error({err}); - } - }); - - sub.on('policy_min_htlc_mtokens_updated', async policy => { - try { - const event = 'policy_min_htlc_mtokens_updated'; - - const {description} = await describeMinHtlcUpdated({ - db, - id: policy.id, - local_keys: getKeys.map(n => n.public_key), - previous: policy.previous, - public_key: policy.public_key, - updated: policy.updated, - }); - - const {line} = logLineForChangeEvent({description, event, mode}); - - return !!line ? logger.info(line) : null; - } catch (err) { - return logger.error({err}); - } - }); - - sub.on('received_htlc', async htlc => { - try { - const {description} = await describeHtlcReceived({ - db, - in_channel: htlc.in_channel, - public_key: htlc.public_key, - }); - - const event = 'received_htlc'; - - const {line} = logLineForChangeEvent({description, event, mode}); - - return !!line ? logger.info(line) : null; - } catch (err) { - return logger.error({err}); - } - }); - - sub.on('reconnected', async reconnect => { - try { - const event = 'reconnected'; - - const {description} = await describePeerReconnected({ - db, - node: reconnect.node, - to: reconnect.to, - }); - - const {line} = logLineForChangeEvent({description, event, mode}); - - return !!line ? logger.info(line) : null; - } catch (err) { - return logger.error({err}); - } - }); - - sub.on('rejected_payment', async rejection => { - try { - switch (rejection.internal_failure) { - case 'UNKNOWN_INVOICE': - { - const event = 'probe_received'; - - const {description} = await describeProbeReceived({ - db, - in_channel: rejection.in_channel, - public_key: rejection.public_key, - }); - - const {line} = logLineForChangeEvent({ - description, - event, - mode, - }); - - return !!line ? logger.info(line) : null; - } - - default: - { - const event = 'rejected_payment'; - - const {description} = await describePaymentRejected({ - db, - in_channel: rejection.in_channel, - public_key: rejection.public_key, - }); - - const {line} = logLineForChangeEvent({ - description, - event, - mode, - }); - - return !!line ? logger.info(line) : null; - } - } - } catch (err) { - return logger.error({err}); - } - }); - - return; - }, - cbk); - }], - }, - returnResult({reject, resolve}, cbk)); - }); -}; diff --git a/test/routing/test_forwards_via_peer.js b/test/routing/test_forwards_via_peer.js index 7755fae..012e5ed 100644 --- a/test/routing/test_forwards_via_peer.js +++ b/test/routing/test_forwards_via_peer.js @@ -5,6 +5,7 @@ const forwardsViaPeer = require('./../../routing/forwards_via_peer'); const tests = [ { args: { + closed_channels: [], forwards: [ {incoming_channel: '1x1x1'}, {outgoing_channel: '2x2x2'}, diff --git a/test/routing/test_get_fees_chart.js b/test/routing/test_get_fees_chart.js index 7503c9f..53cbd30 100644 --- a/test/routing/test_get_fees_chart.js +++ b/test/routing/test_get_fees_chart.js @@ -7,6 +7,7 @@ const {versionInfoResponse} = require('./../fixtures'); const lnds = [{ default: { + closedChannels: ({}, cbk) => cbk(null, {channels: []}), forwardingHistory: ({}, cbk) => cbk(null, { forwarding_events: [], last_offset_index: '0', @@ -44,6 +45,7 @@ const tests = [ days: 100, lnds: [{ default: { + closedChannels: ({}, cbk) => cbk(null, {channels: []}), forwardingHistory: ({}, cbk) => cbk(null, { forwarding_events: [], last_offset_index: '0',