generated from MetaMask/metamask-module-template
-
Notifications
You must be signed in to change notification settings - Fork 7
Add message sequencing and acknowledgment to remote messaging #744
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Open
FUDCo
wants to merge
20
commits into
main
Choose a base branch
from
chip/message-ack-retransmission
base: main
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Conversation
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
8 tasks
74790e7 to
7697239
Compare
12d0fcf to
2a0f438
Compare
2da52d4 to
1e8e95c
Compare
Implements message acknowledgment and retransmission: - Update RemoteCommand type to include seq (sequence number) and ack (piggybacked ACK) fields - Add per-peer sequence tracking that persists across reconnections - Implement data structures with cumulative ACK support - Implement transmission timeout with limited retries - Reject pending promises when giving up on reconnection
- Fix deadlock in receiveMessage by using fire-and-forget for reply sends - Fix PlatformServices to return reply instead of sending it - Add handleAck and updateReceivedSeq to PlatformServices interface - Implement delayed ACK mechanism (50ms timer) for standalone ACKs - Add timeout to libp2p.stop() to prevent cleanup hangs - Close channel streams explicitly on stop to unblock pending reads - Fix e2e test cleanup with parallel stops and increased hook timeout - Skip flaky "handles connection failure and recovery" test Co-Authored-By: Claude Opus 4.5 <[email protected]>
Restored validateMessageSize, checkConnectionLimit, and cleanupStalePeers functions that were accidentally removed during message sequencing changes. Also restored lastConnectionTime tracking and cleanup interval setup/teardown. Co-Authored-By: Claude Opus 4.5 <[email protected]>
…scarding The browser runtime's #handleRemoteMessage was always returning an empty string, discarding the reply from the remoteDeliver RPC call. This broke reply-based protocols like ocap URL redemption. Co-Authored-By: Claude Opus 4.5 <[email protected]>
Previously getNextSeq() was called before attempting to add a message to the queue, so rejected messages would still consume sequence numbers. This caused gaps in sequence numbering, which led to incorrect sequence numbers during retransmission since they were inferred from position. Changed addPendingMessage to assign and return the sequence number internally, only incrementing after successful enqueue. Co-Authored-By: Claude Opus 4.5 <[email protected]>
In the browser runtime, when the kernel worker calls sendRemoteMessage, the offscreen document awaits sendWithAck which waits for an ACK. When the ACK arrives via remoteDeliver, the kernel worker calls handleAck back to the offscreen. If handleAck awaited, this creates a deadlock because the offscreen's RPC message handler is blocked on the original sendRemoteMessage request. Making handleAck fire-and-forget breaks the deadlock while still ensuring ACKs are processed correctly. Co-Authored-By: Claude Opus 4.5 <[email protected]>
Make the network layer a "dumb pipe" that only sends/receives strings. All message sequencing, ACK tracking, and retransmission logic now lives in RemoteHandle within the kernel. - Change SendRemoteMessage to take a string instead of RemoteMessageBase - Remove handleAck and updateReceivedSeq RPC methods - Remove message queueing from network layer - Update all platform services implementations and tests Co-Authored-By: Claude Opus 4.5 <[email protected]>
Remove Kernel.sendRemoteMessage and RemoteManager.sendRemoteMessage which bypassed the seq/ack protocol. All message sending should go through RemoteHandle to ensure reliable delivery. Co-Authored-By: Claude Opus 4.5 <[email protected]>
- Bug 1: Initialize startSeq when first message added to empty queue - Bug 2: Remove unused promiseKit from PendingMessage type - Update e2e test to expect correct error message Co-Authored-By: Claude Opus 4.5 <[email protected]>
Reject pending redemptions when intentional close error is detected during message send, enabling fast failure for intentional disconnect. Co-Authored-By: Claude Opus 4.5 <[email protected]>
Co-Authored-By: Claude Opus 4.5 <[email protected]>
These files were created but never integrated - RemoteHandle uses its own simpler inline implementation instead. Co-Authored-By: Claude Opus 4.5 <[email protected]>
- Add MAX_PENDING_MESSAGES (200) limit to prevent memory overflow - Throw error when pending queue is at capacity - Add onGiveUp callback to notify RemoteManager when we give up - RemoteManager now rejects kernel promises when RemoteHandle gives up Co-Authored-By: Claude Opus 4.5 <[email protected]>
- Reply messages now use seq/ACK protocol via #sendRemoteCommand - Reject pending URL redemptions when giving up after max retries - Add registerChannel() to properly close old channels on replacement - Add reuseOrReturnChannel() for connection race condition handling Co-Authored-By: Claude Opus 4.5 <[email protected]>
Co-Authored-By: Claude Opus 4.5 <[email protected]>
When #sendRemoteCommand is called from within an RPC handler (e.g., during remoteDeliver for a reply), awaiting registerLocationHints can cause deadlock if the browser RPC doesn't support nested calls. Co-Authored-By: Claude Opus 4.5 <[email protected]>
When RemoteHandle.deliverMessage throws (e.g., queue at capacity), the error was propagating up and crashing the kernel run loop. This fix catches delivery errors, rejects the kernel promise for that message, and allows the kernel to continue processing other messages. Also updated the e2e test to reflect actual behavior: new messages are rejected when queue is full, not oldest messages dropped. Co-Authored-By: Claude Opus 4.5 <[email protected]>
…mmand Move the queue capacity check to before #getNextSeq() and #clearDelayedAck() to avoid wasting sequence numbers and disrupting ACK timing when the queue is full. Co-Authored-By: Claude Opus 4.5 <[email protected]>
a629b12 to
e71188d
Compare
Without calling #onGiveUp, kernel promises for messages sent to intentionally closed connections would hang forever. The RemoteManager needs this callback to reject kernel promises via getPromisesByDecider. Co-Authored-By: Claude Opus 4.5 <[email protected]>
Added cleanup() method to RemoteHandle that clears #ackTimeoutHandle and #delayedAckHandle timers. RemoteManager.cleanup() now calls this for each RemoteHandle before clearing its maps, preventing timers from continuing to run and keeping instances alive after shutdown. Co-Authored-By: Claude Opus 4.5 <[email protected]>
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Implements message acknowledgment and retransmission.
Closes #656
Note
Implements a robust remote messaging protocol with sequencing, acknowledgments, and retransmission, while simplifying APIs to operate on serialized strings.
RemoteHandlewith pending queue, ACK timeouts, retransmits, delayed standalone ACKs, and give-up callbacks; include cleanup of timerssendRemoteMessageto accept a pre-serialized message string across browser/node implementations; update tests and docs accordinglyhandleRemoteMessagenow returns''and sends replies viasendRemoteCommandMessageQueueand its tests; rework network tests to best-effort send semantics, explicit errors on timeouts/write failures, and reconnection behaviorKernel.sendRemoteMessage; inKernelRouter, catch delivery failures and reject the originating kernel promise; exportRemoteMessageBaselibp2p.stop(); add E2E cleanup helper with timeouts; increase Vitest hook timeoutWritten by Cursor Bugbot for commit 7b31086. This will update automatically on new commits. Configure here.