diff options
Diffstat (limited to 'names')
| -rw-r--r-- | names/server.js | 22 |
1 files changed, 20 insertions, 2 deletions
diff --git a/names/server.js b/names/server.js index f8fa378..f2a9f41 100644 --- a/names/server.js +++ b/names/server.js @@ -440,7 +440,24 @@ async function forwardOnce(name, sat, hash, pubkey) { // 2026-10-27 ("crit1 … double payout", ~5M). So: done is done, still out // is wait, and only a payment that really failed is tried again. const sent = hash && state.inflight?.[hash]; - if (sent) { + // ...and the same for a float send: one that threw can still have moved + // the coins (the cosign landed, the answer didn't). The float wallet keeps + // every send as an action; the one made for this payment says what it did. + if (sent?.float) { + const acts = (fwd?.state?.actions || []).filter((a) => a.type === 'send' && a.destAddress === sent.dest + && a.amountSat === sent.sat && Number(String(a.id).slice(5).replace(/-+$/, '')) >= sent.after); + if (acts.some((a) => a.step === 'done')) { + delete state.inflight[hash]; + recordLnReceipt(name, sat, hash); + persist(); + log(`delivered ${sat} sat to ${name}: the earlier float send completed`); + return; + } + if (acts.some((a) => a.step !== 'failed')) throw new Error('float send for this payment still unresolved — not paying again'); + log(`forward: the earlier float send for ${name} ${acts.length ? 'failed' : 'never started'} — trying again`); + delete state.inflight[hash]; + persist(); + } else if (sent) { const pays = (await ln.call('listpays', { payment_hash: sent.paymentHash })).pays || []; if (pays.some((x) => x.status === 'complete')) { delete state.inflight[hash]; @@ -465,7 +482,8 @@ async function forwardOnce(name, sat, hash, pubkey) { const viaFloat = async () => { if (!ownServer || fwd.balance().spendableSat < sat) return false; - try { await fwd.send(dest, sat); } + if (hash) { (state.inflight ||= {})[hash] = { float: true, dest, sat, name, after: Date.now() }; persist(); } + try { await fwd.send(dest, sat); settled(); } catch (e) { // enough sats, too many coins: merge them, and the queue's next try goes if (/too many coins/.test(e.message)) consolidateFloat().catch((x) => log('float consolidate failed: ' + x.message)); |
