mirror of
https://github.com/alexbosworth/balanceofsatoshis.git
synced 2026-08-13 12:33:37 +02:00
fix htlc indicator in fwds, balanced open broadcast errs, fees via closed peer charting
This commit is contained in:
parent
fed26d07a0
commit
5331ed4ffc
17 changed files with 64 additions and 731 deletions
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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!
|
||||
|
||||
|
|
|
|||
|
|
@ -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`;
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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
4
package-lock.json
generated
|
|
@ -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",
|
||||
|
|
|
|||
|
|
@ -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"
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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) {
|
||||
|
|
|
|||
|
|
@ -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 : [],
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
};
|
||||
|
|
|
|||
|
|
@ -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});
|
||||
|
|
|
|||
|
|
@ -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));
|
||||
});
|
||||
};
|
||||
|
|
@ -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));
|
||||
});
|
||||
};
|
||||
|
|
@ -5,6 +5,7 @@ const forwardsViaPeer = require('./../../routing/forwards_via_peer');
|
|||
const tests = [
|
||||
{
|
||||
args: {
|
||||
closed_channels: [],
|
||||
forwards: [
|
||||
{incoming_channel: '1x1x1'},
|
||||
{outgoing_channel: '2x2x2'},
|
||||
|
|
|
|||
|
|
@ -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',
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue