diff options
| author | Adam Soltys <[email protected]> | 2026-07-30 10:28:23 -0700 |
|---|---|---|
| committer | Adam Soltys <[email protected]> | 2026-07-30 10:38:43 -0700 |
| commit | fd1617ea66e01557e71debc7e45ca08cfe01bf70 (patch) | |
| tree | 8c3600a86d60dc7731130397c98e818970d63990 /lib/logging.ts | |
| parent | f5a5b1ff856efcd2849275a301daabb80ef76638 (diff) | |
| download | coinos-server-fd1617ea66e01557e71debc7e45ca08cfe01bf70.tar.gz coinos-server-fd1617ea66e01557e71debc7e45ca08cfe01bf70.zip | |
mint/lightning: refuse caller-supplied invoices, tiered fees, log hygiene
- invoices: reject caller-supplied bolt11/bolt12; the server always mints its
own. Closes the invoice-registration path behind the shared-node credit and
payment-hijack vectors.
- lightning: skip mint-owned invoices (lbl* label) in the paid-invoice listener.
- payments: lightning free-tier fee credit, withheld for flagged high-throughput
(ln:nofree) accounts which pay an elevated rate; the failed-send reversal
restores credit at the same rate. freezeCheck made crash-resilient. Lightning
and bolt12 sends stay pending until the preimage settles.
- payments (route): validate payment-request / invoice input types.
- logging: collapse repeated xpay failure lines into one.
Co-Authored-By: Claude Opus 4.8 <[email protected]>
Diffstat (limited to 'lib/logging.ts')
| -rw-r--r-- | lib/logging.ts | 19 |
1 files changed, 19 insertions, 0 deletions
diff --git a/lib/logging.ts b/lib/logging.ts index aab110c2..c68a3199 100644 --- a/lib/logging.ts +++ b/lib/logging.ts @@ -4,6 +4,25 @@ export const l = (...msgs) => pino().info(msgs.join(" ")); export const warn = (...msgs) => pino().warn(msgs.join(" ")); export const err = (...msgs) => pino().error(msgs.join(" ")); +// Collapse a verbose error message for logging. CLN's xpay concatenates one +// failure sentence per routing retry (e.g. "We got temporary_channel_failure +// for X … updating our map." repeated 50+ times), which floods the logs on an +// ordinary failed lightning send. Dedupe repeated sentences and cap length. +export const shortError = (msg: any, max = 400): string => { + let s = typeof msg === "string" ? msg : msg?.message ?? String(msg); + const parts = s.split(/(?<=\.)\s+/); + const seen = new Set<string>(); + const uniq: string[] = []; + for (const p of parts) { + const t = p.trim(); + if (t && !seen.has(t)) { seen.add(t); uniq.push(t); } + } + s = uniq.join(" "); + const dropped = parts.length - uniq.length; + if (dropped > 0) s += ` [${dropped} repeated lines collapsed]`; + return s.length > max ? `${s.slice(0, max)}…` : s; +}; + export const line = () => { const stack = new Error().stack; const stackLine = stack.split("\n")[1]; |
