From 35d8ff55992fd91222ae5278e22d73a0236a0860 Mon Sep 17 00:00:00 2001 From: Overtorment Date: Sat, 13 Apr 2019 00:27:07 +0100 Subject: [PATCH] FIX: improve stuck payments processing --- class/Paym.js | 20 +++++++++++++++-- lightning.js | 2 +- scripts/process-locked-payments.js | 35 +++++++++++++++++++++++++++--- 3 files changed, 51 insertions(+), 6 deletions(-) diff --git a/class/Paym.js b/class/Paym.js index 09bf618..1bb0fda 100644 --- a/class/Paym.js +++ b/class/Paym.js @@ -126,13 +126,29 @@ export class Paym { return await this.sendToRouteSync(routes.routes); } + async listPayments() { + return new Promise((resolve, reject) => { + this._lightning.listPayments({}, function(err, response) { + if (err) return reject(err); + resolve(response); + }); + }); + } + async isExpired() { if (!this._bolt11) throw new Error('bolt11 is not provided'); const decoded = await this.decodePayReqViaRpc(this._bolt11); return +decoded.timestamp + +decoded.expiry < +new Date() / 1000; } - decodePayReq(payReq) { - this._decoded = lightningPayReq.decode(payReq); + decodePayReqLocally(payReq) { + this._decoded_locally = lightningPayReq.decode(payReq); + } + + async getPaymentHash() { + if (!this._bolt11) throw new Error('bolt11 is not provided'); + if (!this._decoded) await this.decodePayReqViaRpc(this._bolt11); + + return this._decoded['payment_hash']; } } diff --git a/lightning.js b/lightning.js index 4178efe..31fb7b3 100644 --- a/lightning.js +++ b/lightning.js @@ -44,4 +44,4 @@ if (config.lnd.password) { ); } -module.exports = new lnrpc.Lightning(config.lnd.url, creds); +module.exports = new lnrpc.Lightning(config.lnd.url, creds, { 'grpc.max_receive_message_length': 1024 * 1024 * 1024 }); diff --git a/scripts/process-locked-payments.js b/scripts/process-locked-payments.js index ff1f87a..75de03c 100644 --- a/scripts/process-locked-payments.js +++ b/scripts/process-locked-payments.js @@ -11,6 +11,11 @@ let lightning = require('../lightning'); let keys = await redis.keys('locked_payments_for_*'); keys = User._shuffle(keys); + console.log('fetching listPayments...'); + let tempPaym = new Paym(redis, bitcoinclient, lightning); + let listPayments = await tempPaym.listPayments(); + console.log('done', 'got', listPayments['payments'].length, 'payments'); + for (let key of keys) { const userid = key.replace('locked_payments_for_', ''); console.log('==================================================================================='); @@ -18,13 +23,16 @@ let lightning = require('../lightning'); let user = new User(redis, bitcoinclient, lightning); user._userid = userid; let lockedPayments = await user.getLockedPayments(); + // lockedPayments = [{pay_req : 'lnbc2m1pwgd4tdpp5vjz80mm8murdkskrnre6w4kphzy3d6gap5jyffr93u02ruaj0wtsdq2xgcrqvpsxqcqzysk34zva4h9ce9jdf08nfdm2sh2ek4y4hjse8ww9jputneltjl24krkv50sene4jh0wpull6ujgrg632u2qt3lkva74vpkqr5e5tuuljspasqfhx'}]; for (let lockedPayment of lockedPayments) { - console.log('processing lockedPayment=', lockedPayment); + let daysPassed = (+new Date() / 1000 - lockedPayment.timestamp) / 3600 / 24; + console.log('processing lockedPayment=', lockedPayment, daysPassed, 'days passed'); let payment = new Paym(redis, bitcoinclient, lightning); payment.setInvoice(lockedPayment.pay_req); - if (await payment.isExpired()) { + if (daysPassed < 2) { + // if (!await payment.isExpired()) { let sendResult; try { sendResult = await payment.attemptPayToRoute(); @@ -50,7 +58,28 @@ let lightning = require('../lightning'); } console.log('sleeping 5 sec...'); console.log('-----------------------------------------------------------------------------------'); - await User._sleep(5); + await User._sleep(0); + } else if (daysPassed > 4) { + // trying to lookup this stuck payment in an array of delivered payments + let isPaid = false; + for (let sentPayment of listPayments['payments']) { + if ((await payment.getPaymentHash()) == sentPayment.payment_hash) { + console.log('found this payment in listPayments array, so it is paid successfully'); + let sendResult = payment.processSendPaymentResponse({ payment_error: 'already paid' } /* hacky */); // adds fees + console.log('saving paid invoice:', sendResult); + await user.savePaidLndInvoice(sendResult); + await user.unlockFunds(lockedPayment.pay_req); + isPaid = true; + console.log('!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!', await payment.getPaymentHash(), sentPayment.payment_hash); + process.exit(); + break; + } + } + + if (!isPaid) { + console.log('very old payment, evict the lock'); + await user.unlockFunds(lockedPayment.pay_req); + } } } }