Conversation
## Problem WebSocket clients intermittently failed to receive orderUpdates when multiple wallets were connected concurrently. The issue appeared to be a race condition but was actually a case-sensitive string comparison bug. ## Root Cause Ethereum addresses were compared using exact string matching: - Wallet recovery (via signature) returns checksummed addresses (e.g., "0xeb5Df7323c643f01b8C0643bE808a0e6486621e8") - WebSocket subscriptions may use lowercase addresses (e.g., "0xeb5df7323c643f01b8c0643be808a0e6486621e8") - String comparison: "0xeb5Df7..." != "0xeb5df7..." ❌ This caused order broadcasts to be filtered out incorrectly, appearing intermittent because different test wallets have different checksums. ## Solution Normalize all Ethereum addresses to lowercase before comparison, as Ethereum addresses are case-insensitive (EIP-55 checksum is optional). ## Changes - Added normalizeAddress() helper function to both websocket.go and handlers.go - Updated WebSocket subscription storage to normalize addresses (websocket.go:207) - Updated broadcast filtering to compare normalized addresses (websocket.go:383) - Updated order status queries to compare normalized addresses (handlers.go:551) - Added comprehensive test suite for address normalization ## Testing Added address_normalization_test.go with tests covering: - Identical addresses (lowercase, uppercase, mixed case) - EIP-55 checksummed vs non-checksummed addresses - Different addresses (should not match) - Empty addresses Fixes the intermittent WebSocket orderUpdates delivery issue in concurrent/parallel test execution scenarios.
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| // normalizeAddress converts an Ethereum address to lowercase for case-insensitive comparison. | ||
| // Ethereum addresses are case-insensitive; the mixed case (EIP-55 checksum) is optional validation. | ||
| func normalizeAddress(addr string) string { | ||
| return strings.ToLower(addr) |
There was a problem hiding this comment.
Remove duplicate normalizeAddress declaration
This commit defines normalizeAddress twice in the server package (here and again in handlers.go). Go packages cannot contain two top‑level functions with the same name, so any build or test will fail with normalizeAddress redeclared before your new tests even run. Please keep a single helper—e.g. move it to a shared file—and have both call sites reuse it.
Useful? React with 👍 / 👎.
The normalizeAddress function was declared in both handlers.go and websocket.go, causing a compilation error. Since they're in the same package, only one declaration is needed. Kept the declaration in handlers.go and removed the duplicate from websocket.go. Both files can access the shared function.
Problem
WebSocket clients intermittently failed to receive orderUpdates when
multiple wallets were connected concurrently. The issue appeared to be
a race condition but was actually a case-sensitive string comparison bug.
Root Cause
Ethereum addresses were compared using exact string matching:
(e.g., "0xeb5Df7323c643f01b8C0643bE808a0e6486621e8")
(e.g., "0xeb5df7323c643f01b8c0643be808a0e6486621e8")
This caused order broadcasts to be filtered out incorrectly, appearing
intermittent because different test wallets have different checksums.
Solution
Normalize all Ethereum addresses to lowercase before comparison, as
Ethereum addresses are case-insensitive (EIP-55 checksum is optional).
Changes
Testing
Added address_normalization_test.go with tests covering:
Fixes the intermittent WebSocket orderUpdates delivery issue in
concurrent/parallel test execution scenarios.