Skip to content

Commit b54268a

Browse files
authored
normalized wallet logs (#1826)
* Add invoiceId, withdrawalId to wallet logs * Truncate wallet logs * Fix extra db dips per log line * Fix leak of invoice for sender
1 parent e7eece7 commit b54268a

File tree

7 files changed

+92
-42
lines changed

7 files changed

+92
-42
lines changed

api/resolvers/wallet.js

+47-12
Original file line numberDiff line numberDiff line change
@@ -430,6 +430,10 @@ const resolvers = {
430430
lte: to ? new Date(Number(to)) : undefined
431431
}
432432
},
433+
include: {
434+
invoice: true,
435+
withdrawal: true
436+
},
433437
orderBy: [
434438
{ createdAt: 'desc' },
435439
{ id: 'desc' }
@@ -445,6 +449,10 @@ const resolvers = {
445449
lte: decodedCursor.time
446450
}
447451
},
452+
include: {
453+
invoice: true,
454+
withdrawal: true
455+
},
448456
orderBy: [
449457
{ createdAt: 'desc' },
450458
{ id: 'desc' }
@@ -745,11 +753,42 @@ const resolvers = {
745753
return item
746754
},
747755
sats: fact => msatsToSatsDecimal(fact.msats)
756+
},
757+
758+
WalletLogEntry: {
759+
context: async ({ level, context, invoice, withdrawal }, args, { models }) => {
760+
const isError = ['error', 'warn'].includes(level.toLowerCase())
761+
762+
if (withdrawal) {
763+
return {
764+
...await logContextFromBolt11(withdrawal.bolt11),
765+
...(withdrawal.preimage ? { preimage: withdrawal.preimage } : {}),
766+
...(isError ? { max_fee: formatMsats(withdrawal.msatsFeePaying) } : {})
767+
}
768+
}
769+
770+
// XXX never return invoice as context because it might leak sensitive sender details
771+
// if (invoice) { ... }
772+
773+
return context
774+
}
748775
}
749776
}
750777

751778
export default injectResolvers(resolvers)
752779

780+
const logContextFromBolt11 = async (bolt11) => {
781+
const decoded = await parsePaymentRequest({ request: bolt11 })
782+
return {
783+
bolt11,
784+
amount: formatMsats(decoded.mtokens),
785+
payment_hash: decoded.id,
786+
created_at: decoded.created_at,
787+
expires_at: decoded.expires_at,
788+
description: decoded.description
789+
}
790+
}
791+
753792
export const walletLogger = ({ wallet, models }) => {
754793
// no-op logger if wallet is not provided
755794
if (!wallet) {
@@ -762,31 +801,27 @@ export const walletLogger = ({ wallet, models }) => {
762801
}
763802

764803
// server implementation of wallet logger interface on client
765-
const log = (level) => async (message, context = {}) => {
804+
const log = (level) => async (message, ctx = {}) => {
766805
try {
767-
if (context?.bolt11) {
806+
let { invoiceId, withdrawalId, ...context } = ctx
807+
808+
if (context.bolt11) {
768809
// automatically populate context from bolt11 to avoid duplicating this code
769-
const decoded = await parsePaymentRequest({ request: context.bolt11 })
770810
context = {
771811
...context,
772-
amount: formatMsats(decoded.mtokens),
773-
payment_hash: decoded.id,
774-
created_at: decoded.created_at,
775-
expires_at: decoded.expires_at,
776-
description: decoded.description,
777-
// payments should affect wallet status
778-
status: true
812+
...await logContextFromBolt11(context.bolt11)
779813
}
780814
}
781-
context.recv = true
782815

783816
await models.walletLog.create({
784817
data: {
785818
userId: wallet.userId,
786819
wallet: wallet.type,
787820
level,
788821
message,
789-
context
822+
context,
823+
invoiceId,
824+
withdrawalId
790825
}
791826
})
792827
} catch (err) {

components/wallet-logger.js

+7-1
Original file line numberDiff line numberDiff line change
@@ -239,7 +239,13 @@ export function useWalletLogs (wallet, initialPage = 1, logsPerPage = 10) {
239239
const newLogs = data.walletLogs.entries.map(({ createdAt, wallet: walletType, ...log }) => ({
240240
ts: +new Date(createdAt),
241241
wallet: walletTag(getWalletByType(walletType)),
242-
...log
242+
...log,
243+
// required to resolve recv status
244+
context: {
245+
recv: true,
246+
status: !!log.context?.bolt11 && ['warn', 'error', 'success'].includes(log.level.toLowerCase()),
247+
...log.context
248+
}
243249
}))
244250
const combinedLogs = uniqueSort([...result.data, ...newLogs])
245251

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
ALTER TABLE "WalletLog"
2+
ADD COLUMN "invoiceId" INTEGER,
3+
ADD COLUMN "withdrawalId" INTEGER;
4+
5+
ALTER TABLE "WalletLog" ADD CONSTRAINT "WalletLog_invoiceId_fkey" FOREIGN KEY ("invoiceId") REFERENCES "Invoice"("id") ON DELETE SET NULL ON UPDATE CASCADE;
6+
ALTER TABLE "WalletLog" ADD CONSTRAINT "WalletLog_withdrawalId_fkey" FOREIGN KEY ("withdrawalId") REFERENCES "Withdrawl"("id") ON DELETE SET NULL ON UPDATE CASCADE;
7+
8+
TRUNCATE "WalletLog" RESTRICT;

prisma/schema.prisma

+14-8
Original file line numberDiff line numberDiff line change
@@ -264,14 +264,18 @@ model VaultEntry {
264264
}
265265

266266
model WalletLog {
267-
id Int @id @default(autoincrement())
268-
createdAt DateTime @default(now()) @map("created_at")
269-
userId Int
270-
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
271-
wallet WalletType
272-
level LogLevel
273-
message String
274-
context Json? @db.JsonB
267+
id Int @id @default(autoincrement())
268+
createdAt DateTime @default(now()) @map("created_at")
269+
userId Int
270+
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
271+
wallet WalletType
272+
level LogLevel
273+
message String
274+
invoiceId Int?
275+
invoice Invoice? @relation(fields: [invoiceId], references: [id])
276+
withdrawalId Int?
277+
withdrawal Withdrawl? @relation(fields: [withdrawalId], references: [id])
278+
context Json? @db.JsonB
275279
276280
@@index([userId, createdAt])
277281
}
@@ -971,6 +975,7 @@ model Invoice {
971975
Upload Upload[]
972976
PollVote PollVote[]
973977
PollBlindVote PollBlindVote[]
978+
WalletLog WalletLog[]
974979
975980
@@index([createdAt], map: "Invoice.created_at_index")
976981
@@index([userId], map: "Invoice.userId_index")
@@ -1048,6 +1053,7 @@ model Withdrawl {
10481053
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
10491054
wallet Wallet? @relation(fields: [walletId], references: [id], onDelete: SetNull)
10501055
invoiceForward InvoiceForward?
1056+
WalletLog WalletLog[]
10511057
10521058
@@index([createdAt], map: "Withdrawl.created_at_index")
10531059
@@index([userId], map: "Withdrawl.userId_index")

wallets/server.js

+1-2
Original file line numberDiff line numberDiff line change
@@ -39,8 +39,7 @@ export async function * createUserInvoice (userId, { msats, description, descrip
3939

4040
try {
4141
logger.info(
42-
`↙ incoming payment: ${formatSats(msatsToSats(msats))}`,
43-
{
42+
`↙ incoming payment: ${formatSats(msatsToSats(msats))}`, {
4443
amount: formatMsats(msats)
4544
})
4645

worker/paidAction.js

+13-14
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ import { getPaymentFailureStatus, hodlInvoiceCltvDetails, getPaymentOrNotSent }
22
import { paidActions } from '@/api/paidAction'
33
import { walletLogger } from '@/api/resolvers/wallet'
44
import { LND_PATHFINDING_TIME_PREF_PPM, LND_PATHFINDING_TIMEOUT_MS, PAID_ACTION_TERMINAL_STATES } from '@/lib/constants'
5-
import { formatMsats, formatSats, msatsToSats, toPositiveNumber } from '@/lib/format'
5+
import { formatSats, msatsToSats, toPositiveNumber } from '@/lib/format'
66
import { datePivot } from '@/lib/time'
77
import { Prisma } from '@prisma/client'
88
import {
@@ -317,17 +317,13 @@ export async function paidActionForwarded ({ data: { invoiceId, withdrawal, ...a
317317
}, { models, lnd, boss })
318318

319319
if (transitionedInvoice) {
320-
const { bolt11, msatsPaid } = transitionedInvoice.invoiceForward.withdrawl
320+
const withdrawal = transitionedInvoice.invoiceForward.withdrawl
321321

322322
const logger = walletLogger({ wallet: transitionedInvoice.invoiceForward.wallet, models })
323323
logger.ok(
324-
`↙ payment received: ${formatSats(msatsToSats(Number(msatsPaid)))}`,
325-
{
326-
bolt11,
327-
preimage: transitionedInvoice.preimage
328-
// we could show the outgoing fee that we paid from the incoming amount to the receiver
329-
// but we don't since it might look like the receiver paid the fee but that's not the case.
330-
// fee: formatMsats(msatsFeePaid)
324+
`↙ payment received: ${formatSats(msatsToSats(Number(withdrawal.msatsPaid)))}`, {
325+
invoiceId: transitionedInvoice.id,
326+
withdrawalId: withdrawal.id
331327
})
332328
}
333329

@@ -376,12 +372,11 @@ export async function paidActionFailedForward ({ data: { invoiceId, withdrawal:
376372
}, { models, lnd, boss })
377373

378374
if (transitionedInvoice) {
379-
const { bolt11, msatsFeePaying } = transitionedInvoice.invoiceForward.withdrawl
380-
const logger = walletLogger({ wallet: transitionedInvoice.invoiceForward.wallet, models })
375+
const fwd = transitionedInvoice.invoiceForward
376+
const logger = walletLogger({ wallet: fwd.wallet, models })
381377
logger.warn(
382378
`incoming payment failed: ${message}`, {
383-
bolt11,
384-
max_fee: formatMsats(msatsFeePaying)
379+
withdrawalId: fwd.withdrawl.id
385380
})
386381
}
387382

@@ -446,7 +441,11 @@ export async function paidActionCanceling ({ data: { invoiceId, ...args }, model
446441
const { wallet, bolt11 } = transitionedInvoice.invoiceForward
447442
const logger = walletLogger({ wallet, models })
448443
const decoded = await parsePaymentRequest({ request: bolt11 })
449-
logger.info(`invoice for ${formatSats(msatsToSats(decoded.mtokens))} canceled by payer`, { bolt11 })
444+
logger.info(
445+
`invoice for ${formatSats(msatsToSats(decoded.mtokens))} canceled by payer`, {
446+
bolt11,
447+
invoiceId: transitionedInvoice.id
448+
})
450449
}
451450
}
452451

worker/payingAction.js

+2-5
Original file line numberDiff line numberDiff line change
@@ -125,11 +125,8 @@ export async function payingActionConfirmed ({ data: args, models, lnd, boss })
125125

126126
const logger = walletLogger({ models, wallet: transitionedWithdrawal.wallet })
127127
logger?.ok(
128-
`↙ payment received: ${formatSats(msatsToSats(transitionedWithdrawal.msatsPaid))}`,
129-
{
130-
bolt11: transitionedWithdrawal.bolt11,
131-
preimage: transitionedWithdrawal.preimage,
132-
fee: formatMsats(transitionedWithdrawal.msatsFeePaid)
128+
`↙ payment received: ${formatSats(msatsToSats(transitionedWithdrawal.msatsPaid))}`, {
129+
withdrawalId: transitionedWithdrawal.id
133130
})
134131
}
135132
}

0 commit comments

Comments
 (0)