소스 검색

fix: 增加 monitor 和 parser 的 debug 日志

之前交易被跳过时完全没有日志输出,无法定位问题。
现在在以下关键节点增加了日志:
- WebSocket 收到/去重跳过
- processTransaction 各种跳过原因(已处理/RPC 返回空/parse 失败)
- parseTransaction 各种返回 null 原因(无 BYREAL 指令/无法检测操作类型/nftOwner 不匹配)
- 当 watched address 在 tx 中但 parse 返回 null 时特别标注

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
zhangchunrui 1 주 전
부모
커밋
e4d96713fc
2개의 변경된 파일46개의 추가작업 그리고 7개의 파일을 삭제
  1. 30 4
      src/lib/monitor/index.ts
  2. 16 3
      src/lib/monitor/parser.ts

+ 30 - 4
src/lib/monitor/index.ts

@@ -232,7 +232,12 @@ export class MonitorService {
     if (logs.err) return
 
     const sig = logs.signature
-    if (!this.markSeen(sig)) return // Already seen within TTL window
+    if (!this.markSeen(sig)) {
+      console.log(`[Monitor] WS dedup skip: ${sig.slice(0, 12)}...`)
+      return
+    }
+
+    console.log(`[Monitor] WS received: ${sig.slice(0, 12)}...`)
 
     try {
       await this.processTransaction(sig)
@@ -286,12 +291,18 @@ export class MonitorService {
   }
 
   private async processTransaction(signature: string) {
+    const shortSig = `${signature.slice(0, 12)}...`
+
     // Skip if already processing (in-flight lock)
-    if (this.processingSigs.has(signature)) return
+    if (this.processingSigs.has(signature)) {
+      console.log(`[Monitor] Skip ${shortSig}: already processing`)
+      return
+    }
     this.processingSigs.add(signature)
 
     try {
       if (isTxProcessed(signature)) {
+        console.log(`[Monitor] Skip ${shortSig}: already in DB`)
         return
       }
 
@@ -301,10 +312,25 @@ export class MonitorService {
         maxSupportedTransactionVersion: 0,
       })
 
-      if (!tx) return
+      if (!tx) {
+        console.log(`[Monitor] Skip ${shortSig}: getParsedTransaction returned null`)
+        return
+      }
 
       const parsed = parseTransaction(tx, this.watchedAddresses)
-      if (!parsed) return
+      if (!parsed) {
+        // Debug: check if any watched address is in this tx
+        const txAddrs = tx.transaction.message.accountKeys.map((k) =>
+          typeof k === 'string' ? k : 'pubkey' in k ? k.pubkey.toBase58() : '',
+        )
+        const matchedAddr = txAddrs.find((a) => this.watchedAddresses.has(a))
+        if (matchedAddr) {
+          console.log(
+            `[Monitor] Skip ${shortSig}: parseTransaction returned null but watched address ${matchedAddr.slice(0, 12)}... IS in tx accounts`,
+          )
+        }
+        return
+      }
 
       console.log(`[Monitor] Detected ${parsed.type} from ${parsed.signer} (tx: ${signature})`)
 

+ 16 - 3
src/lib/monitor/parser.ts

@@ -285,14 +285,21 @@ export function parseTransaction(
       break
     }
   }
-  if (!signerAddress) return null
+  if (!signerAddress) {
+    return null // No watched address in this tx — expected for most BYREAL txs
+  }
+
+  const shortSig = `${signature.slice(0, 12)}...`
 
   // Detect operation type from logs (fast path)
   let operationType = detectOperationFromLogs(logs)
 
   // Find the BYREAL instruction
   const byrealIx = findByrealInstruction(tx)
-  if (!byrealIx) return null
+  if (!byrealIx) {
+    console.log(`[Parser] ${shortSig}: watched address found but no BYREAL instruction`)
+    return null
+  }
 
   // Get instruction accounts
   const ixAccounts: string[] =
@@ -306,7 +313,10 @@ export function parseTransaction(
     operationType = detectOperationFromInstruction(dataBuf)
   }
 
-  if (!operationType) return null
+  if (!operationType) {
+    console.log(`[Parser] ${shortSig}: cannot detect operation type`)
+    return null
+  }
 
   // Get token balance changes for amounts
   const balanceChanges = getSignerTokenBalanceChanges(tx, signerAddress)
@@ -347,6 +357,9 @@ export function parseTransaction(
         result.amountB = createEvent.amount1
         // Validate: nftOwner must match signer (watched address)
         if (createEvent.nftOwner !== signerAddress) {
+          console.log(
+            `[Parser] ${shortSig}: nftOwner mismatch — event.nftOwner=${createEvent.nftOwner.slice(0, 12)}... != signer=${signerAddress.slice(0, 12)}...`,
+          )
           return null // Not the target wallet's operation
         }
       } else {