Skip to content

Commit

Permalink
fix (cherry-pick): transaction resubmit on multiple endpoints (#30079) (
Browse files Browse the repository at this point in the history
#30077)

## **Description**

Cherry-pick of #30079 for release `12.10.4`.

[![Open in GitHub
Codespaces](https://github.com/codespaces/badge.svg)](https://codespaces.new/MetaMask/metamask-extension/pull/30077?quickstart=1)

## **Related issues**

## **Manual testing steps**

## **Screenshots/Recordings**

### **Before**

### **After**

## **Pre-merge author checklist**

- [x] I've followed [MetaMask Contributor
Docs](https://github.com/MetaMask/contributor-docs) and [MetaMask
Extension Coding
Standards](https://github.com/MetaMask/metamask-extension/blob/main/.github/guidelines/CODING_GUIDELINES.md).
- [x] I've completed the PR template to the best of my ability
- [x] I’ve included tests if applicable
- [x] I’ve documented my code using [JSDoc](https://jsdoc.app/) format
if applicable
- [x] I’ve applied the right labels on the PR (see [labeling
guidelines](https://github.com/MetaMask/metamask-extension/blob/main/.github/guidelines/LABELING_GUIDELINES.md)).
Not required for external contributors.

## **Pre-merge reviewer checklist**

- [ ] I've manually tested the PR (e.g. pull and build branch, run the
app, test code being changed).
- [ ] I confirm that this PR addresses all acceptance criteria described
in the ticket it closes and includes the necessary testing evidence such
as recordings and or screenshots.
  • Loading branch information
matthewwalsh0 authored Feb 4, 2025
1 parent 7eea5f5 commit 93ef626
Show file tree
Hide file tree
Showing 3 changed files with 167 additions and 3 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,130 @@
diff --git a/dist/TransactionController.cjs b/dist/TransactionController.cjs
index 7764cca7fd50be8eb1d4cf0a8a4a5d7f6430c8bc..905258c7f8a107dd3b95a10e7241b42cfa70eed7 100644
--- a/dist/TransactionController.cjs
+++ b/dist/TransactionController.cjs
@@ -1808,12 +1808,13 @@ _TransactionController_internalEvents = new WeakMap(), _TransactionController_me
getPendingTransactions: __classPrivateFieldGet(this, _TransactionController_instances, "m", _TransactionController_getNonceTrackerPendingTransactions).bind(this, chainId),
getConfirmedTransactions: this.getNonceTrackerTransactions.bind(this, types_1.TransactionStatus.confirmed, chainId),
});
-}, _TransactionController_createPendingTransactionTracker = function _TransactionController_createPendingTransactionTracker({ provider, blockTracker, chainId, }) {
+}, _TransactionController_createPendingTransactionTracker = function _TransactionController_createPendingTransactionTracker({ provider, blockTracker, chainId, networkClientId, }) {
const ethQuery = new eth_query_1.default(provider);
const pendingTransactionTracker = new PendingTransactionTracker_1.PendingTransactionTracker({
blockTracker,
getChainId: () => chainId,
getEthQuery: () => ethQuery,
+ getNetworkClientId: () => networkClientId,
getTransactions: () => this.state.transactions,
isResubmitEnabled: __classPrivateFieldGet(this, _TransactionController_pendingTransactionOptions, "f").isResubmitEnabled,
getGlobalLock: () => __classPrivateFieldGet(this, _TransactionController_multichainTrackingHelper, "f").acquireNonceLockForChainIdKey({
diff --git a/dist/helpers/MultichainTrackingHelper.cjs b/dist/helpers/MultichainTrackingHelper.cjs
index 3e1204fc775639e07f617dd455907ef68f1764eb..442c32d95eee884aa97aea11e84aff87db3b5cb4 100644
--- a/dist/helpers/MultichainTrackingHelper.cjs
+++ b/dist/helpers/MultichainTrackingHelper.cjs
@@ -191,6 +191,7 @@ _MultichainTrackingHelper_findNetworkClientIdByChainId = new WeakMap(), _Multich
provider,
blockTracker,
chainId,
+ networkClientId,
});
__classPrivateFieldGet(this, _MultichainTrackingHelper_trackingMap, "f").set(networkClientId, {
nonceTracker,
diff --git a/dist/helpers/PendingTransactionTracker.cjs b/dist/helpers/PendingTransactionTracker.cjs
index 0b88c6d6df8dac03c4704051345f8c03ca7e97af..97e46f0494788f114b018ef66f5b4c0b1738fc20 100644
--- a/dist/helpers/PendingTransactionTracker.cjs
+++ b/dist/helpers/PendingTransactionTracker.cjs
@@ -13,17 +13,17 @@ var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
-var _PendingTransactionTracker_instances, _PendingTransactionTracker_droppedBlockCountByHash, _PendingTransactionTracker_getChainId, _PendingTransactionTracker_getEthQuery, _PendingTransactionTracker_getTransactions, _PendingTransactionTracker_isResubmitEnabled, _PendingTransactionTracker_listener, _PendingTransactionTracker_log, _PendingTransactionTracker_getGlobalLock, _PendingTransactionTracker_publishTransaction, _PendingTransactionTracker_running, _PendingTransactionTracker_transactionPoller, _PendingTransactionTracker_beforeCheckPendingTransaction, _PendingTransactionTracker_beforePublish, _PendingTransactionTracker_start, _PendingTransactionTracker_onLatestBlock, _PendingTransactionTracker_checkTransactions, _PendingTransactionTracker_resubmitTransactions, _PendingTransactionTracker_isKnownTransactionError, _PendingTransactionTracker_resubmitTransaction, _PendingTransactionTracker_isResubmitDue, _PendingTransactionTracker_checkTransaction, _PendingTransactionTracker_onTransactionConfirmed, _PendingTransactionTracker_isTransactionDropped, _PendingTransactionTracker_isNonceTaken, _PendingTransactionTracker_getPendingTransactions, _PendingTransactionTracker_warnTransaction, _PendingTransactionTracker_failTransaction, _PendingTransactionTracker_dropTransaction, _PendingTransactionTracker_updateTransaction, _PendingTransactionTracker_getTransactionReceipt, _PendingTransactionTracker_getBlockByHash, _PendingTransactionTracker_getNetworkTransactionCount, _PendingTransactionTracker_getCurrentChainTransactions;
+var _PendingTransactionTracker_instances, _PendingTransactionTracker_droppedBlockCountByHash, _PendingTransactionTracker_getChainId, _PendingTransactionTracker_getEthQuery, _PendingTransactionTracker_getNetworkClientId, _PendingTransactionTracker_getTransactions, _PendingTransactionTracker_isResubmitEnabled, _PendingTransactionTracker_listener, _PendingTransactionTracker_log, _PendingTransactionTracker_getGlobalLock, _PendingTransactionTracker_publishTransaction, _PendingTransactionTracker_running, _PendingTransactionTracker_transactionPoller, _PendingTransactionTracker_beforeCheckPendingTransaction, _PendingTransactionTracker_beforePublish, _PendingTransactionTracker_start, _PendingTransactionTracker_onLatestBlock, _PendingTransactionTracker_checkTransactions, _PendingTransactionTracker_resubmitTransactions, _PendingTransactionTracker_isKnownTransactionError, _PendingTransactionTracker_resubmitTransaction, _PendingTransactionTracker_isResubmitDue, _PendingTransactionTracker_checkTransaction, _PendingTransactionTracker_onTransactionConfirmed, _PendingTransactionTracker_isTransactionDropped, _PendingTransactionTracker_isNonceTaken, _PendingTransactionTracker_getPendingTransactions, _PendingTransactionTracker_warnTransaction, _PendingTransactionTracker_failTransaction, _PendingTransactionTracker_dropTransaction, _PendingTransactionTracker_updateTransaction, _PendingTransactionTracker_getTransactionReceipt, _PendingTransactionTracker_getBlockByHash, _PendingTransactionTracker_getNetworkTransactionCount, _PendingTransactionTracker_getChainTransactions, _PendingTransactionTracker_getNetworkClientTransactions;
Object.defineProperty(exports, "__esModule", { value: true });
exports.PendingTransactionTracker = void 0;
const controller_utils_1 = require("@metamask/controller-utils");
// This package purposefully relies on Node's EventEmitter module.
-// eslint-disable-next-line import/no-nodejs-modules
+// eslint-disable-next-line import-x/no-nodejs-modules
const events_1 = __importDefault(require("events"));
const lodash_1 = require("lodash");
+const TransactionPoller_1 = require("./TransactionPoller.cjs");
const logger_1 = require("../logger.cjs");
const types_1 = require("../types.cjs");
-const TransactionPoller_1 = require("./TransactionPoller.cjs");
/**
* We wait this many blocks before emitting a 'transaction-dropped' event
* This is because we could be talking to a node that is out of sync
@@ -42,11 +42,12 @@ const KNOWN_TRANSACTION_ERRORS = [
];
const log = (0, logger_1.createModuleLogger)(logger_1.projectLogger, 'pending-transactions');
class PendingTransactionTracker {
- constructor({ blockTracker, getChainId, getEthQuery, getTransactions, isResubmitEnabled, getGlobalLock, publishTransaction, hooks, }) {
+ constructor({ blockTracker, getChainId, getEthQuery, getNetworkClientId, getTransactions, isResubmitEnabled, getGlobalLock, publishTransaction, hooks, }) {
_PendingTransactionTracker_instances.add(this);
_PendingTransactionTracker_droppedBlockCountByHash.set(this, void 0);
_PendingTransactionTracker_getChainId.set(this, void 0);
_PendingTransactionTracker_getEthQuery.set(this, void 0);
+ _PendingTransactionTracker_getNetworkClientId.set(this, void 0);
_PendingTransactionTracker_getTransactions.set(this, void 0);
_PendingTransactionTracker_isResubmitEnabled.set(this, void 0);
// TODO: Replace `any` with type
@@ -72,16 +73,17 @@ class PendingTransactionTracker {
__classPrivateFieldSet(this, _PendingTransactionTracker_droppedBlockCountByHash, new Map(), "f");
__classPrivateFieldSet(this, _PendingTransactionTracker_getChainId, getChainId, "f");
__classPrivateFieldSet(this, _PendingTransactionTracker_getEthQuery, getEthQuery, "f");
+ __classPrivateFieldSet(this, _PendingTransactionTracker_getNetworkClientId, getNetworkClientId, "f");
__classPrivateFieldSet(this, _PendingTransactionTracker_getTransactions, getTransactions, "f");
__classPrivateFieldSet(this, _PendingTransactionTracker_isResubmitEnabled, isResubmitEnabled ?? (() => true), "f");
__classPrivateFieldSet(this, _PendingTransactionTracker_listener, __classPrivateFieldGet(this, _PendingTransactionTracker_instances, "m", _PendingTransactionTracker_onLatestBlock).bind(this), "f");
- __classPrivateFieldSet(this, _PendingTransactionTracker_log, (0, logger_1.createModuleLogger)(log, getChainId()), "f");
__classPrivateFieldSet(this, _PendingTransactionTracker_getGlobalLock, getGlobalLock, "f");
__classPrivateFieldSet(this, _PendingTransactionTracker_publishTransaction, publishTransaction, "f");
__classPrivateFieldSet(this, _PendingTransactionTracker_running, false, "f");
__classPrivateFieldSet(this, _PendingTransactionTracker_transactionPoller, new TransactionPoller_1.TransactionPoller(blockTracker), "f");
__classPrivateFieldSet(this, _PendingTransactionTracker_beforePublish, hooks?.beforePublish ?? (() => true), "f");
__classPrivateFieldSet(this, _PendingTransactionTracker_beforeCheckPendingTransaction, hooks?.beforeCheckPendingTransaction ?? (() => true), "f");
+ __classPrivateFieldSet(this, _PendingTransactionTracker_log, (0, logger_1.createModuleLogger)(log, `${getChainId()}:${getNetworkClientId()}`), "f");
}
/**
* Force checks the network if the given transaction is confirmed and updates it's status.
@@ -111,7 +113,7 @@ class PendingTransactionTracker {
}
}
exports.PendingTransactionTracker = PendingTransactionTracker;
-_PendingTransactionTracker_droppedBlockCountByHash = new WeakMap(), _PendingTransactionTracker_getChainId = new WeakMap(), _PendingTransactionTracker_getEthQuery = new WeakMap(), _PendingTransactionTracker_getTransactions = new WeakMap(), _PendingTransactionTracker_isResubmitEnabled = new WeakMap(), _PendingTransactionTracker_listener = new WeakMap(), _PendingTransactionTracker_log = new WeakMap(), _PendingTransactionTracker_getGlobalLock = new WeakMap(), _PendingTransactionTracker_publishTransaction = new WeakMap(), _PendingTransactionTracker_running = new WeakMap(), _PendingTransactionTracker_transactionPoller = new WeakMap(), _PendingTransactionTracker_beforeCheckPendingTransaction = new WeakMap(), _PendingTransactionTracker_beforePublish = new WeakMap(), _PendingTransactionTracker_instances = new WeakSet(), _PendingTransactionTracker_start = function _PendingTransactionTracker_start(pendingTransactions) {
+_PendingTransactionTracker_droppedBlockCountByHash = new WeakMap(), _PendingTransactionTracker_getChainId = new WeakMap(), _PendingTransactionTracker_getEthQuery = new WeakMap(), _PendingTransactionTracker_getNetworkClientId = new WeakMap(), _PendingTransactionTracker_getTransactions = new WeakMap(), _PendingTransactionTracker_isResubmitEnabled = new WeakMap(), _PendingTransactionTracker_listener = new WeakMap(), _PendingTransactionTracker_log = new WeakMap(), _PendingTransactionTracker_getGlobalLock = new WeakMap(), _PendingTransactionTracker_publishTransaction = new WeakMap(), _PendingTransactionTracker_running = new WeakMap(), _PendingTransactionTracker_transactionPoller = new WeakMap(), _PendingTransactionTracker_beforeCheckPendingTransaction = new WeakMap(), _PendingTransactionTracker_beforePublish = new WeakMap(), _PendingTransactionTracker_instances = new WeakSet(), _PendingTransactionTracker_start = function _PendingTransactionTracker_start(pendingTransactions) {
__classPrivateFieldGet(this, _PendingTransactionTracker_transactionPoller, "f").setPendingTransactions(pendingTransactions);
if (__classPrivateFieldGet(this, _PendingTransactionTracker_running, "f")) {
return;
@@ -295,13 +297,13 @@ _PendingTransactionTracker_droppedBlockCountByHash = new WeakMap(), _PendingTran
return true;
}, _PendingTransactionTracker_isNonceTaken = function _PendingTransactionTracker_isNonceTaken(txMeta) {
const { id, txParams } = txMeta;
- return __classPrivateFieldGet(this, _PendingTransactionTracker_instances, "m", _PendingTransactionTracker_getCurrentChainTransactions).call(this).some((tx) => tx.id !== id &&
+ return __classPrivateFieldGet(this, _PendingTransactionTracker_instances, "m", _PendingTransactionTracker_getChainTransactions).call(this).some((tx) => tx.id !== id &&
tx.txParams.from === txParams.from &&
tx.status === types_1.TransactionStatus.confirmed &&
tx.txParams.nonce === txParams.nonce &&
tx.type !== types_1.TransactionType.incoming);
}, _PendingTransactionTracker_getPendingTransactions = function _PendingTransactionTracker_getPendingTransactions() {
- return __classPrivateFieldGet(this, _PendingTransactionTracker_instances, "m", _PendingTransactionTracker_getCurrentChainTransactions).call(this).filter((tx) => tx.status === types_1.TransactionStatus.submitted &&
+ return __classPrivateFieldGet(this, _PendingTransactionTracker_instances, "m", _PendingTransactionTracker_getNetworkClientTransactions).call(this).filter((tx) => tx.status === types_1.TransactionStatus.submitted &&
!tx.verifiedOnBlockchain &&
!tx.isUserOperation);
}, _PendingTransactionTracker_warnTransaction = function _PendingTransactionTracker_warnTransaction(txMeta, error, message) {
@@ -326,8 +328,11 @@ _PendingTransactionTracker_droppedBlockCountByHash = new WeakMap(), _PendingTran
]);
}, _PendingTransactionTracker_getNetworkTransactionCount = async function _PendingTransactionTracker_getNetworkTransactionCount(address) {
return await (0, controller_utils_1.query)(__classPrivateFieldGet(this, _PendingTransactionTracker_getEthQuery, "f").call(this), 'getTransactionCount', [address]);
-}, _PendingTransactionTracker_getCurrentChainTransactions = function _PendingTransactionTracker_getCurrentChainTransactions() {
- const currentChainId = __classPrivateFieldGet(this, _PendingTransactionTracker_getChainId, "f").call(this);
- return __classPrivateFieldGet(this, _PendingTransactionTracker_getTransactions, "f").call(this).filter((tx) => tx.chainId === currentChainId);
+}, _PendingTransactionTracker_getChainTransactions = function _PendingTransactionTracker_getChainTransactions() {
+ const chainId = __classPrivateFieldGet(this, _PendingTransactionTracker_getChainId, "f").call(this);
+ return __classPrivateFieldGet(this, _PendingTransactionTracker_getTransactions, "f").call(this).filter((tx) => tx.chainId === chainId);
+}, _PendingTransactionTracker_getNetworkClientTransactions = function _PendingTransactionTracker_getNetworkClientTransactions() {
+ const networkClientId = __classPrivateFieldGet(this, _PendingTransactionTracker_getNetworkClientId, "f").call(this);
+ return __classPrivateFieldGet(this, _PendingTransactionTracker_getTransactions, "f").call(this).filter((tx) => tx.networkClientId === networkClientId);
};
//# sourceMappingURL=PendingTransactionTracker.cjs.map
\ No newline at end of file
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -348,7 +348,7 @@
"@metamask/snaps-sdk": "^6.13.0",
"@metamask/snaps-utils": "^8.6.1",
"@metamask/solana-wallet-snap": "^1.0.4",
"@metamask/transaction-controller": "^42.0.0",
"@metamask/transaction-controller": "patch:@metamask/transaction-controller@npm%3A42.0.0#~/.yarn/patches/@metamask-transaction-controller-npm-42.0.0-9e6d74c3e2.patch",
"@metamask/user-operation-controller": "^19.0.0",
"@metamask/utils": "^10.0.1",
"@ngraveio/bc-ur": "^1.1.12",
Expand Down
38 changes: 36 additions & 2 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -6436,7 +6436,7 @@ __metadata:
languageName: node
linkType: hard

"@metamask/transaction-controller@npm:^42.0.0":
"@metamask/transaction-controller@npm:42.0.0":
version: 42.0.0
resolution: "@metamask/transaction-controller@npm:42.0.0"
dependencies:
Expand Down Expand Up @@ -6470,6 +6470,40 @@ __metadata:
languageName: node
linkType: hard

"@metamask/transaction-controller@patch:@metamask/transaction-controller@npm%3A42.0.0#~/.yarn/patches/@metamask-transaction-controller-npm-42.0.0-9e6d74c3e2.patch":
version: 42.0.0
resolution: "@metamask/transaction-controller@patch:@metamask/transaction-controller@npm%3A42.0.0#~/.yarn/patches/@metamask-transaction-controller-npm-42.0.0-9e6d74c3e2.patch::version=42.0.0&hash=215c7f"
dependencies:
"@ethereumjs/common": "npm:^3.2.0"
"@ethereumjs/tx": "npm:^4.2.0"
"@ethereumjs/util": "npm:^8.1.0"
"@ethersproject/abi": "npm:^5.7.0"
"@ethersproject/contracts": "npm:^5.7.0"
"@ethersproject/providers": "npm:^5.7.0"
"@metamask/base-controller": "npm:^7.0.2"
"@metamask/controller-utils": "npm:^11.4.4"
"@metamask/eth-query": "npm:^4.0.0"
"@metamask/metamask-eth-abis": "npm:^3.1.1"
"@metamask/nonce-tracker": "npm:^6.0.0"
"@metamask/rpc-errors": "npm:^7.0.1"
"@metamask/utils": "npm:^10.0.0"
async-mutex: "npm:^0.5.0"
bn.js: "npm:^5.2.1"
eth-method-registry: "npm:^4.0.0"
fast-json-patch: "npm:^3.1.1"
lodash: "npm:^4.17.21"
uuid: "npm:^8.3.2"
peerDependencies:
"@babel/runtime": ^7.0.0
"@metamask/accounts-controller": ^20.0.0
"@metamask/approval-controller": ^7.0.0
"@metamask/eth-block-tracker": ">=9"
"@metamask/gas-fee-controller": ^22.0.0
"@metamask/network-controller": ^22.0.0
checksum: 10/84c88f7d8a0a5a67431aea5645c3fb1bb8920c4ae86a7f7202c05e670cb0602a568668b21ad4148c9a927d44415637ad0e4cc6ed741ccb283b437bbd81ba31a2
languageName: node
linkType: hard

"@metamask/user-operation-controller@npm:^19.0.0":
version: 19.0.0
resolution: "@metamask/user-operation-controller@npm:19.0.0"
Expand Down Expand Up @@ -26640,7 +26674,7 @@ __metadata:
"@metamask/solana-wallet-snap": "npm:^1.0.4"
"@metamask/test-bundler": "npm:^1.0.0"
"@metamask/test-dapp": "npm:8.13.0"
"@metamask/transaction-controller": "npm:^42.0.0"
"@metamask/transaction-controller": "patch:@metamask/transaction-controller@npm%3A42.0.0#~/.yarn/patches/@metamask-transaction-controller-npm-42.0.0-9e6d74c3e2.patch"
"@metamask/user-operation-controller": "npm:^19.0.0"
"@metamask/utils": "npm:^10.0.1"
"@ngraveio/bc-ur": "npm:^1.1.12"
Expand Down

0 comments on commit 93ef626

Please sign in to comment.