Skip to content

waitForReceipt loops forever when a transaction is dropped from the mempool #5

@ZuozuoAI

Description

@ZuozuoAI

TL;DR

chain/jsonRpcWriteClient.ts polls for a transaction receipt in an infinite for (;;) loop with no timeout or maximum retry count.

Details

// sandbox/src/chain/jsonRpcWriteClient.ts ~line 108
for (;;) {
  const receipt = await jsonRpcRequest<RawTransactionReceipt | null>(...);
  if (!receipt) {
    await sleep(pollIntervalMs);
    continue;   // no exit condition other than receipt arriving
  }
  // ...
}

If the transaction is dropped (nonce collision, gas price too low, RPC node restart), receipt is always null and the function never returns. The caller — the audit writeback path — hangs indefinitely, blocking the entire listener daemon.

Suggested Fix

Add a deadline parameter:

const deadline = Date.now() + timeoutMs;
for (;;) {
  if (Date.now() > deadline) throw new Error(`waitForReceipt timed out after ${timeoutMs}ms`);
  const receipt = await jsonRpcRequest<RawTransactionReceipt | null>(...);
  if (receipt) return receipt;
  await sleep(pollIntervalMs);
}

References

  • sandbox/src/chain/jsonRpcWriteClient.ts:108 — the loop
  • sandbox/src/listener/retryWritebackQueue.ts — the caller that would hang

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions