fix htlc indicator in fwds, balanced open broadcast errs, fees via closed peer charting

This commit is contained in:
Alex Bosworth 2021-08-25 16:41:29 -07:00
parent fed26d07a0
commit 5331ed4ffc
No known key found for this signature in database
GPG key ID: E80D2F3F311FD87E
17 changed files with 64 additions and 731 deletions

View file

@ -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

View file

@ -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!

View file

@ -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`;

View file

@ -27,7 +27,6 @@ const uniq = arr => Array.from(new Set(arr));
[is_confirmed]: <Return Only Confirmed Utxos Bool>
lnd: <Authenticated gRPC LND API Object>
[min_tokens]: <Return Utxos of Value Above Tokens Size Number>
[node]: <Node Name String>
}
// Non-count response

View file

@ -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();

View file

@ -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,

View file

@ -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']);
}

4
package-lock.json generated
View file

@ -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",

View file

@ -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"
}

View file

@ -4,6 +4,10 @@ const uniq = arr => Array.from(new Set(arr));
/** Filter out forwards via a peer
{
closed_channels: [{
[id]: <Closed Channel Id String>
partner_public_key: <Partner Public Key Hex String>
}]
forwards: [{
created_at: <Forward Record Created At ISO 8601 Date String>
fee: <Fee Tokens Charged Number>
@ -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) {

View file

@ -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 : [],

View file

@ -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,
};

View file

@ -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});

View file

@ -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: <Ping Destination Public Key Hex String>
lnd: <Authenticated LND API Object>
logger: <Winston Logger Object>
}
@returns via cbk or Promise
{
received_pong: <Received a Pong Bool>
latency: <Descriptin of Time to Pong String>
sent: <Amount Sent String>
received_back: <Amount Received String>
received_via: [<Received Via Channel Id String>]
total_ping_cost: <Total Ping Cost String>
}
*/
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));
});
};

View file

@ -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: <Database Object>
logger: <Winston Logger Object>
nodes: [<Node Name String>]
}
@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));
});
};

View file

@ -5,6 +5,7 @@ const forwardsViaPeer = require('./../../routing/forwards_via_peer');
const tests = [
{
args: {
closed_channels: [],
forwards: [
{incoming_channel: '1x1x1'},
{outgoing_channel: '2x2x2'},

View file

@ -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',