MetaMask / MetaMask/metamask-extension

How to handle cancellation TX in private mempools?

Open
#20,020 0 comments 1 reaction 0 assignees View on GitHub
developerQuestion team-wallet-api-platform-deprecated
Dominant language
TypeScript
Stars
13.2k
Forks
5.6k
Avg merge
2d 5h
Merged PRs (30d)
451

Description

## Preface

As an operator of a pre- or private mempool, we want to handle cancellation TX correctly so that they appear as "successful" in MM.
This, however, is very tricky - there are two main cases:

- The easy case: The TX has already been forwarded to public mempool. The replacement TX will be sent there, too - everything's fine.
- The problematic case: The TX has not left the pre-mempool. The cancellation TX is recognized by `from === to && value === 0 && nonce === isKnownNonce(from, nonce)` (pseudo code)

In the latter case, the RPC / pre-mempool can cancel the initial TX for free by simply dropping it. However, MM will try to get a valid TX receipt for either the initial TX or the cancellation TX. As none of the two has ever been included, no TX receipt can be sent - and MM will keep re-submitting the TX until the nonce is used.

## Question

How can the RPC handle this case so that MM would either confirm the cancellation TX or drop both the initial and the cancellation TX?

Also: In the case of a confirmation MM should not consider the nonce of the cancellation TX as used (as nothing happend on-chain with it - this might prefigure that we'd want to lead MM to consider both initial and cancellation TXs as 'dropped', actually).

### Steps to reproduce

1. Connect to a private mempool or other RPC that withholds the TX from the blockchain or public mempool until inclusion.
2. Send initial TX (RPC will respond with TX hash, TX will be in "pending" state in MM)
3. Hit "cancel" in MM's TX list, in order to send out a cancellation TX
4. RPC responds with TX hash of cancellation TX, deletes initial TX for free
5. Observe that MM will keep retrying cancellation TX

### Error messages or log output

_No response_

### Version

all

### Build type

None

### Browser

Other (please elaborate in the "Additional Context" section)

### Operating system

Other (please elaborate in the "Additional Context" section)

### Hardware wallet

_No response_

### Additional context

Probably on all active versions and all OSs

Contributor guide

Open the contributing guide

Research direction

No files, tests, or code entry points are named. Start by tracing the cancellation flow from the transaction list through the RPC and receipt polling, then determine how private-mempool cancellation differs from an on-chain replacement. Done means the RPC can confirm cancellation or drop both transactions without treating the cancellation nonce as used.

Written by the indexing model from the issue text.

Assessment

Tech stack
typescript
Domain
blockchain
Issue type
Feature
Difficulty
5/5
Estimated time
Over a week
Activity status
Stale
Clarity
Needs clarification
Newbie friendliness
25/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.