Skip to content
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

TransactionController MultiChain Refactor #3643

Merged
merged 153 commits into from
Feb 15, 2024
Merged

Conversation

shanejonas
Copy link
Contributor

@shanejonas shanejonas commented Dec 8, 2023

Explanation

Resolves: https://github.com/MetaMask/MetaMask-planning/issues/1019

Changelog

@metamask/transaction-controller

Added

  • BREAKING: Constructor now expects a getNetworkClientRegistry callback function
  • BREAKING: Messenger now requires NetworkController:stateChange to be an allowed event
  • BREAKING: Messenger now requires NetworkController:findNetworkClientByChainId and NetworkController:getNetworkClientById actions
  • Adds a feature flag parameter isMultichainEnabled passed via the constructor (and defaulted to false), which when passed a truthy value will initialize incomingTransactionHelper, pendingTransactionTracker, nonceTracker per networkClientId from the NetworkController’s networkClientRegistry and a EtherScanRemoteTransactionSource helper per chainId in the registry.
  • Adds destroy() method that stops/removes internal polling and listeners
  • Exports PendingTransactionOptions type
  • Exports TransactionControllerOptions type
  • Adds stopAllIncomingTransactionPolling() that stops the global IncomingTransactionHelper and each networkClientId's IncomingTransactionHelper

Changed

  • BREAKING: approveTransactionsWithSameNonce() now requires chainId to be populated in for each TransactionParams that is passed
  • addTransaction() now accepts optional networkClientId in its options param which specifies the network client that the transaction will be processed with during its lifecycle if the isMultichainEnabled feature flag is on
  • estimateGas() now accepts optional networkClientId as its last param which specifies the network client that should be used to estimate the required gas for the given transaction
  • estimateGasBuffered() now accepts optional networkClientId as its last param which specifies the network client that should be used to estimate the required gas plus buffer for the given transaction
  • getNonceLock() now accepts optional networkClientId as its last param which specifies which the network client's nonceTracker should be used to determine the next nonce.
    • When used with the enableMultichain feature flag on and with networkClientId specified, this method will also restrict acquiring the next nonce by chainId, i.e. if this method is called with two different networkClientIds on the same chainId, only the first call will return immediately with a lock from its respective nonceTracker with the second call being blocked until the first caller releases its lock
  • Approval of transactions previously used the chainId from the global provider state as the source of truth. Instead it will now use the chainId from the TransactionMeta object. Not sure we really need to put this in the changelog since all tx will have chainId populated
  • EtherscanRemoteTransactionSource now enforces a 5 second delay between requests to avoid rate limiting
  • TransactionMeta type now specifies an optional networkClientId field
  • startIncomingTransactionPolling() now accepts an optional array of networkClientIds. When provided, the IncomingTransactionHelpers for those networkClientIds will be started. If empty or not provided, the global IncomingTransactionHelper will be started.
  • stopIncomingTransactionPolling() now accepts an optional array of networkClientIds. When provided, the IncomingTransactionHelpers for those networkClientIds will be stoppped. If empty or not provided, the global IncomingTransactionHelper will be stopped.

Removed

Checklist

  • I've updated the test suite for new or updated code as appropriate
  • I've updated documentation (JSDoc, Markdown, etc.) for new or updated code as appropriate
  • I've highlighted breaking changes using the "BREAKING" category above as appropriate

@shanejonas shanejonas requested a review from a team as a code owner December 8, 2023 14:15
shanejonas and others added 14 commits December 11, 2023 10:06
* Update `getCurrentNetworkEIP1559Compatibility` hook type to accept
optional networkClientId param
* It already does this in networkController, but perhaps it should be
renamed getEIP1559Compatibility?
* Update `getExternalPendingTransactions` hook type to accept optional
chainId param
  * SmartTransactionController and extension need to be updated
* Add `getNetworkClientIdForDomain` hook to constructor param
* Add `getEthQuery` method that accepts optional networkClientId and
returns the correct EthQuery instance
* Update `addTransaction`
  * Add optional `networkClientId` to options object param
  * Use correct networkClientId/chainId
* Update `stopTransaction` to use correct networkClientId/chainId
* Update `estimateGas`
  * Add optional `networkClientId` param
  * Use correct networkClientId/chainId
* Update `estimateGasBuffered` to accept optional networkClientId
  * SmartTransactionController and extension need to be updated 
* Update `updateGasProperties` to use correct networkClientId (from
txMeta)
* Update `approveTransaction` to use correct networkClientId (from
txMeta)
* Update `publishTransaction` to accept required ethQuery
* Update `getEIP1559Compatibility` to accept optional networkClientId
* GasFeeController has a similar method of it's own that we may need to
update
* Update `getNonceTrackerPendingTransactions` to pass `chainId` to
`getExternalPendingTransactions`
* Add optional `networkClientId` to `TransactionMeta` type
* Update `UpdateGasRequest` to accept either providerConfig or
NetworkClientConfiguration
  * Probably should rename the arg from `providerConfig`

Questions:
* should `wipeTransactions` be updated to filter by optional chainId?
* should `getNonceLock` take in chainId (non-optional) to get correct
nonceTracker nonceLock?
* should `getTransactions` accept chainId and/or networkClientId param
for filtering?
* `createApprovalsForUnapprovedTransactions` isn't used anywhere in our
repos? Remove it?
* `approveTransaction` sets txMeta.txParams.chainId to the
currentChainId. Shouldn't it read the value from txMeta instead?
* shouldn't `addExternalTransaction` filter against the txMeta chainId,
not the currentChainId?
* shouldn't `markNonceDuplicatesDropped ` filter against the txMeta
chainId, not the currentChainId?

---------

Co-authored-by: Jiexi Luan <[email protected]>
## Explanation

Break `UpdateGasRequest.providerConfig `into `chainId` and
`isCustomNetwork`

## References

<!--
Are there any issues that this pull request is tied to? Are there other
links that reviewers should consult to understand these changes better?

For example:

* Fixes #12345
* Related to #67890
-->

## Changelog

<!--
If you're making any consumer-facing changes, list those changes here as
if you were updating a changelog, using the template below as a guide.

(CATEGORY is one of BREAKING, ADDED, CHANGED, DEPRECATED, REMOVED, or
FIXED. For security-related issues, follow the Security Advisory
process.)

Please take care to name the exact pieces of the API you've added or
changed (e.g. types, interfaces, functions, or methods).

If there are any breaking changes, make sure to offer a solution for
consumers to follow once they upgrade to the changes.

Finally, if you're only making changes to development scripts or tests,
you may replace the template below with "None".
-->

### `@metamask/package-a`

- **<CATEGORY>**: Your change here
- **<CATEGORY>**: Your change here

### `@metamask/package-b`

- **<CATEGORY>**: Your change here
- **<CATEGORY>**: Your change here

## Checklist

- [ ] I've updated the test suite for new or updated code as appropriate
- [ ] I've updated documentation (JSDoc, Markdown, etc.) for new or
updated code as appropriate
- [ ] I've highlighted breaking changes using the "BREAKING" category
above as appropriate
* Update `getCurrentNetworkEIP1559Compatibility` hook type to accept
optional networkClientId param
* It already does this in networkController, but perhaps it should be
renamed getEIP1559Compatibility?
* Update `getExternalPendingTransactions` hook type to accept optional
chainId param
  * SmartTransactionController and extension need to be updated
* Add `getNetworkClientIdForDomain` hook to constructor param
* Add `getEthQuery` method that accepts optional networkClientId and
returns the correct EthQuery instance
* Update `addTransaction`
  * Add optional `networkClientId` to options object param
  * Use correct networkClientId/chainId
* Update `stopTransaction` to use correct networkClientId/chainId
* Update `estimateGas`
  * Add optional `networkClientId` param
  * Use correct networkClientId/chainId
* Update `estimateGasBuffered` to accept optional networkClientId
  * SmartTransactionController and extension need to be updated 
* Update `updateGasProperties` to use correct networkClientId (from
txMeta)
* Update `approveTransaction` to use correct networkClientId (from
txMeta)
* Update `publishTransaction` to accept required ethQuery
* Update `getEIP1559Compatibility` to accept optional networkClientId
* GasFeeController has a similar method of it's own that we may need to
update
* Update `getNonceTrackerPendingTransactions` to pass `chainId` to
`getExternalPendingTransactions`
* Add optional `networkClientId` to `TransactionMeta` type
* Update `UpdateGasRequest` to accept either providerConfig or
NetworkClientConfiguration
  * Probably should rename the arg from `providerConfig`

Questions:
* should `wipeTransactions` be updated to filter by optional chainId?
* should `getNonceLock` take in chainId (non-optional) to get correct
nonceTracker nonceLock?
* should `getTransactions` accept chainId and/or networkClientId param
for filtering?
* `createApprovalsForUnapprovedTransactions` isn't used anywhere in our
repos? Remove it?
* `approveTransaction` sets txMeta.txParams.chainId to the
currentChainId. Shouldn't it read the value from txMeta instead?
* shouldn't `addExternalTransaction` filter against the txMeta chainId,
not the currentChainId?
* shouldn't `markNonceDuplicatesDropped ` filter against the txMeta
chainId, not the currentChainId?

---------

Co-authored-by: Jiexi Luan <[email protected]>
## Explanation

Break `UpdateGasRequest.providerConfig `into `chainId` and
`isCustomNetwork`

## References

<!--
Are there any issues that this pull request is tied to? Are there other
links that reviewers should consult to understand these changes better?

For example:

* Fixes #12345
* Related to #67890
-->

## Changelog

<!--
If you're making any consumer-facing changes, list those changes here as
if you were updating a changelog, using the template below as a guide.

(CATEGORY is one of BREAKING, ADDED, CHANGED, DEPRECATED, REMOVED, or
FIXED. For security-related issues, follow the Security Advisory
process.)

Please take care to name the exact pieces of the API you've added or
changed (e.g. types, interfaces, functions, or methods).

If there are any breaking changes, make sure to offer a solution for
consumers to follow once they upgrade to the changes.

Finally, if you're only making changes to development scripts or tests,
you may replace the template below with "None".
-->

### `@metamask/package-a`

- **<CATEGORY>**: Your change here
- **<CATEGORY>**: Your change here

### `@metamask/package-b`

- **<CATEGORY>**: Your change here
- **<CATEGORY>**: Your change here

## Checklist

- [ ] I've updated the test suite for new or updated code as appropriate
- [ ] I've updated documentation (JSDoc, Markdown, etc.) for new or
updated code as appropriate
- [ ] I've highlighted breaking changes using the "BREAKING" category
above as appropriate
@shanejonas shanejonas force-pushed the transaction-multichain branch from 558a2ef to 134cea6 Compare December 15, 2023 19:32
## Explanation
This fixes `startTrackingByNetworkClientId`'s trackingMap as well as
adds `stopTrackingByNetworkClientId` and some initial tests for them
both
@jiexi jiexi marked this pull request as draft December 15, 2023 20:35
jiexi and others added 10 commits December 15, 2023 15:28
# Conflicts:
#	packages/transaction-controller/src/TransactionController.ts
#	packages/transaction-controller/src/helpers/PendingTransactionTracker.test.ts
#	packages/transaction-controller/src/helpers/PendingTransactionTracker.ts
## Explanation

* Makes `stop()` public on `PendingTransactionTracker`
* Calls `stop()` on `PendingTransactionTracker` in the `trackingMap`
* Moves subscription of transaction state changes (and now network state
changes due to upstream controller changes) out of
`PendingTransactionTracker` and into a loop in `TransactionController`

## References

<!--
Are there any issues that this pull request is tied to? Are there other
links that reviewers should consult to understand these changes better?

For example:

* Fixes #12345
* Related to #67890
-->

## Changelog

<!--
If you're making any consumer-facing changes, list those changes here as
if you were updating a changelog, using the template below as a guide.

(CATEGORY is one of BREAKING, ADDED, CHANGED, DEPRECATED, REMOVED, or
FIXED. For security-related issues, follow the Security Advisory
process.)

Please take care to name the exact pieces of the API you've added or
changed (e.g. types, interfaces, functions, or methods).

If there are any breaking changes, make sure to offer a solution for
consumers to follow once they upgrade to the changes.

Finally, if you're only making changes to development scripts or tests,
you may replace the template below with "None".
-->

### `@metamask/package-a`

- **<CATEGORY>**: Your change here
- **<CATEGORY>**: Your change here

### `@metamask/package-b`

- **<CATEGORY>**: Your change here
- **<CATEGORY>**: Your change here

## Checklist

- [ ] I've updated the test suite for new or updated code as appropriate
- [ ] I've updated documentation (JSDoc, Markdown, etc.) for new or
updated code as appropriate
- [ ] I've highlighted breaking changes using the "BREAKING" category
above as appropriate
## Explanation

* Update `getCommonConfiguration` with required `chainId` param
* Use `chainId` param instead of current selected chainId to generate
commonConfiguration object
* Add `prepareUnsignedEthTx` required `chainId` param
* Pass in chainId to `prepareUnsignedEthTx` from relevant tx object
* Pass in chainId to `getCommonConfiguration` from relevant tx object
* Update `approveTransactionsWithSameNonce` param type to include
`{chainId: Hex}` to match what extension is actually calling it with

## References

<!--
Are there any issues that this pull request is tied to? Are there other
links that reviewers should consult to understand these changes better?

For example:

* Fixes #12345
* Related to #67890
-->

## Changelog

<!--
If you're making any consumer-facing changes, list those changes here as
if you were updating a changelog, using the template below as a guide.

(CATEGORY is one of BREAKING, ADDED, CHANGED, DEPRECATED, REMOVED, or
FIXED. For security-related issues, follow the Security Advisory
process.)

Please take care to name the exact pieces of the API you've added or
changed (e.g. types, interfaces, functions, or methods).

If there are any breaking changes, make sure to offer a solution for
consumers to follow once they upgrade to the changes.

Finally, if you're only making changes to development scripts or tests,
you may replace the template below with "None".
-->

### `@metamask/package-a`

- **<CATEGORY>**: Your change here
- **<CATEGORY>**: Your change here

### `@metamask/package-b`

- **<CATEGORY>**: Your change here
- **<CATEGORY>**: Your change here

## Checklist

- [ ] I've updated the test suite for new or updated code as appropriate
- [ ] I've updated documentation (JSDoc, Markdown, etc.) for new or
updated code as appropriate
- [ ] I've highlighted breaking changes using the "BREAKING" category
above as appropriate

---------

Co-authored-by: Alex Donesky <[email protected]>
## Explanation

Naively couples existing mutex with nonceLock mutex. Doesn't seem to
cause a deadlock

## References

<!--
Are there any issues that this pull request is tied to? Are there other
links that reviewers should consult to understand these changes better?

For example:

* Fixes #12345
* Related to #67890
-->

## Changelog

<!--
If you're making any consumer-facing changes, list those changes here as
if you were updating a changelog, using the template below as a guide.

(CATEGORY is one of BREAKING, ADDED, CHANGED, DEPRECATED, REMOVED, or
FIXED. For security-related issues, follow the Security Advisory
process.)

Please take care to name the exact pieces of the API you've added or
changed (e.g. types, interfaces, functions, or methods).

If there are any breaking changes, make sure to offer a solution for
consumers to follow once they upgrade to the changes.

Finally, if you're only making changes to development scripts or tests,
you may replace the template below with "None".
-->

### `@metamask/package-a`

- **<CATEGORY>**: Your change here
- **<CATEGORY>**: Your change here

### `@metamask/package-b`

- **<CATEGORY>**: Your change here
- **<CATEGORY>**: Your change here

## Checklist

- [ ] I've updated the test suite for new or updated code as appropriate
- [ ] I've updated documentation (JSDoc, Markdown, etc.) for new or
updated code as appropriate
- [ ] I've highlighted breaking changes using the "BREAKING" category
above as appropriate
## Explanation

Fixes the PendingTransactionTracker specs. The specs should probably be
cleaned up to use a helper rather than relying on mocking in beforeEach

## References

<!--
Are there any issues that this pull request is tied to? Are there other
links that reviewers should consult to understand these changes better?

For example:

* Fixes #12345
* Related to #67890
-->

## Changelog

<!--
If you're making any consumer-facing changes, list those changes here as
if you were updating a changelog, using the template below as a guide.

(CATEGORY is one of BREAKING, ADDED, CHANGED, DEPRECATED, REMOVED, or
FIXED. For security-related issues, follow the Security Advisory
process.)

Please take care to name the exact pieces of the API you've added or
changed (e.g. types, interfaces, functions, or methods).

If there are any breaking changes, make sure to offer a solution for
consumers to follow once they upgrade to the changes.

Finally, if you're only making changes to development scripts or tests,
you may replace the template below with "None".
-->

### `@metamask/package-a`

- **<CATEGORY>**: Your change here
- **<CATEGORY>**: Your change here

### `@metamask/package-b`

- **<CATEGORY>**: Your change here
- **<CATEGORY>**: Your change here

## Checklist

- [ ] I've updated the test suite for new or updated code as appropriate
- [ ] I've updated documentation (JSDoc, Markdown, etc.) for new or
updated code as appropriate
- [ ] I've highlighted breaking changes using the "BREAKING" category
above as appropriate
jiexi and others added 4 commits February 5, 2024 12:09
## Explanation

* Remove feature flag setter
* Rename `enableMultichain` to `isMultichainEnabled`

<!--
Thanks for your contribution! Take a moment to answer these questions so
that reviewers have the information they need to properly understand
your changes:

* What is the current state of things and why does it need to change?
* What is the solution your changes offer and how does it work?
* Are there any changes whose purpose might not obvious to those
unfamiliar with the domain?
* If your primary goal was to update one package but you found you had
to update another one along the way, why did you do so?
* If you had to upgrade a dependency, why did you do so?
-->

## References

<!--
Are there any issues that this pull request is tied to? Are there other
links that reviewers should consult to understand these changes better?

For example:

* Fixes #12345
* Related to #67890
-->

## Changelog

<!--
If you're making any consumer-facing changes, list those changes here as
if you were updating a changelog, using the template below as a guide.

(CATEGORY is one of BREAKING, ADDED, CHANGED, DEPRECATED, REMOVED, or
FIXED. For security-related issues, follow the Security Advisory
process.)

Please take care to name the exact pieces of the API you've added or
changed (e.g. types, interfaces, functions, or methods).

If there are any breaking changes, make sure to offer a solution for
consumers to follow once they upgrade to the changes.

Finally, if you're only making changes to development scripts or tests,
you may replace the template below with "None".
-->

### `@metamask/package-a`

- **<CATEGORY>**: Your change here
- **<CATEGORY>**: Your change here

### `@metamask/package-b`

- **<CATEGORY>**: Your change here
- **<CATEGORY>**: Your change here

## Checklist

- [ ] I've updated the test suite for new or updated code as appropriate
- [ ] I've updated documentation (JSDoc, Markdown, etc.) for new or
updated code as appropriate
- [ ] I've highlighted breaking changes using the "BREAKING" category
above as appropriate

---------

Co-authored-by: Alex Donesky <[email protected]>
## Explanation

* Log failed promises in `updateIncomingTransactions()`

<!--
Thanks for your contribution! Take a moment to answer these questions so
that reviewers have the information they need to properly understand
your changes:

* What is the current state of things and why does it need to change?
* What is the solution your changes offer and how does it work?
* Are there any changes whose purpose might not obvious to those
unfamiliar with the domain?
* If your primary goal was to update one package but you found you had
to update another one along the way, why did you do so?
* If you had to upgrade a dependency, why did you do so?
-->

## References

<!--
Are there any issues that this pull request is tied to? Are there other
links that reviewers should consult to understand these changes better?

For example:

* Fixes #12345
* Related to #67890
-->

## Changelog

<!--
If you're making any consumer-facing changes, list those changes here as
if you were updating a changelog, using the template below as a guide.

(CATEGORY is one of BREAKING, ADDED, CHANGED, DEPRECATED, REMOVED, or
FIXED. For security-related issues, follow the Security Advisory
process.)

Please take care to name the exact pieces of the API you've added or
changed (e.g. types, interfaces, functions, or methods).

If there are any breaking changes, make sure to offer a solution for
consumers to follow once they upgrade to the changes.

Finally, if you're only making changes to development scripts or tests,
you may replace the template below with "None".
-->

### `@metamask/package-a`

- **<CATEGORY>**: Your change here
- **<CATEGORY>**: Your change here

### `@metamask/package-b`

- **<CATEGORY>**: Your change here
- **<CATEGORY>**: Your change here

## Checklist

- [ ] I've updated the test suite for new or updated code as appropriate
- [ ] I've updated documentation (JSDoc, Markdown, etc.) for new or
updated code as appropriate
- [ ] I've highlighted breaking changes using the "BREAKING" category
above as appropriate
@jiexi
Copy link
Contributor

jiexi commented Feb 5, 2024

Remaining todo tests implemented here #3894

jiexi added 2 commits February 5, 2024 15:05
## Explanation

* Add `markNonceDuplicatesDropped` side effect checks to cancelled and
speed up scenarios
* Add global network scenarios for `startIncomingTransactionPolling`,
`stopIncomingTransactionPolling` and `updateIncomingTransactions`


<!--
Thanks for your contribution! Take a moment to answer these questions so
that reviewers have the information they need to properly understand
your changes:

* What is the current state of things and why does it need to change?
* What is the solution your changes offer and how does it work?
* Are there any changes whose purpose might not obvious to those
unfamiliar with the domain?
* If your primary goal was to update one package but you found you had
to update another one along the way, why did you do so?
* If you had to upgrade a dependency, why did you do so?
-->

## References

<!--
Are there any issues that this pull request is tied to? Are there other
links that reviewers should consult to understand these changes better?

For example:

* Fixes #12345
* Related to #67890
-->

## Changelog

<!--
If you're making any consumer-facing changes, list those changes here as
if you were updating a changelog, using the template below as a guide.

(CATEGORY is one of BREAKING, ADDED, CHANGED, DEPRECATED, REMOVED, or
FIXED. For security-related issues, follow the Security Advisory
process.)

Please take care to name the exact pieces of the API you've added or
changed (e.g. types, interfaces, functions, or methods).

If there are any breaking changes, make sure to offer a solution for
consumers to follow once they upgrade to the changes.

Finally, if you're only making changes to development scripts or tests,
you may replace the template below with "None".
-->

### `@metamask/package-a`

- **<CATEGORY>**: Your change here
- **<CATEGORY>**: Your change here

### `@metamask/package-b`

- **<CATEGORY>**: Your change here
- **<CATEGORY>**: Your change here

## Checklist

- [ ] I've updated the test suite for new or updated code as appropriate
- [ ] I've updated documentation (JSDoc, Markdown, etc.) for new or
updated code as appropriate
- [ ] I've highlighted breaking changes using the "BREAKING" category
above as appropriate
## Explanation

* Add and export `TransactionControllerOptions` type
* Export existing option types


<!--
Thanks for your contribution! Take a moment to answer these questions so
that reviewers have the information they need to properly understand
your changes:

* What is the current state of things and why does it need to change?
* What is the solution your changes offer and how does it work?
* Are there any changes whose purpose might not obvious to those
unfamiliar with the domain?
* If your primary goal was to update one package but you found you had
to update another one along the way, why did you do so?
* If you had to upgrade a dependency, why did you do so?
-->

## References

<!--
Are there any issues that this pull request is tied to? Are there other
links that reviewers should consult to understand these changes better?

For example:

* Fixes #12345
* Related to #67890
-->

## Changelog

<!--
If you're making any consumer-facing changes, list those changes here as
if you were updating a changelog, using the template below as a guide.

(CATEGORY is one of BREAKING, ADDED, CHANGED, DEPRECATED, REMOVED, or
FIXED. For security-related issues, follow the Security Advisory
process.)

Please take care to name the exact pieces of the API you've added or
changed (e.g. types, interfaces, functions, or methods).

If there are any breaking changes, make sure to offer a solution for
consumers to follow once they upgrade to the changes.

Finally, if you're only making changes to development scripts or tests,
you may replace the template below with "None".
-->

### `@metamask/package-a`

- **<CATEGORY>**: Your change here
- **<CATEGORY>**: Your change here

### `@metamask/package-b`

- **<CATEGORY>**: Your change here
- **<CATEGORY>**: Your change here

## Checklist

- [ ] I've updated the test suite for new or updated code as appropriate
- [ ] I've updated documentation (JSDoc, Markdown, etc.) for new or
updated code as appropriate
- [ ] I've highlighted breaking changes using the "BREAKING" category
above as appropriate
@jiexi
Copy link
Contributor

jiexi commented Feb 6, 2024

Potential MultichainHelper

#3896

@jiexi
Copy link
Contributor

jiexi commented Feb 6, 2024

Update approveTransactionsWithSameNonce (used by SwapsController) to work with multichain

#3898

jiexi and others added 7 commits February 7, 2024 13:11
…entId resolution (#3898)

## Explanation

Currently `approveTransactionsWithSameNonce` may need to populate the
txParams it is passed with a nonce, but the current implementation only
works correctly when calling this method while globally selected network
is on the same chainId.

To get this to work with multichain, we attempt to resolve the txParams
chainId to a networkClientId which we then use to pull a NonceTracker on
the right chain out of the trackingMap. One downside of this approach is
that it's possible to use the NonceTracker for a different network
client that's also on the same chain than the network client that this
tx is being submitted on.

I recommend reading my comment in the issue linked below for a more
thorough explanation of current state and options.

## References

See:
MetaMask/MetaMask-planning#2023 (comment)

## Changelog

<!--
If you're making any consumer-facing changes, list those changes here as
if you were updating a changelog, using the template below as a guide.

(CATEGORY is one of BREAKING, ADDED, CHANGED, DEPRECATED, REMOVED, or
FIXED. For security-related issues, follow the Security Advisory
process.)

Please take care to name the exact pieces of the API you've added or
changed (e.g. types, interfaces, functions, or methods).

If there are any breaking changes, make sure to offer a solution for
consumers to follow once they upgrade to the changes.

Finally, if you're only making changes to development scripts or tests,
you may replace the template below with "None".
-->

### `@metamask/package-a`

- **<CATEGORY>**: Your change here
- **<CATEGORY>**: Your change here

### `@metamask/package-b`

- **<CATEGORY>**: Your change here
- **<CATEGORY>**: Your change here

## Checklist

- [ ] I've updated the test suite for new or updated code as appropriate
- [ ] I've updated documentation (JSDoc, Markdown, etc.) for new or
updated code as appropriate
- [ ] I've highlighted breaking changes using the "BREAKING" category
above as appropriate
## Explanation

Example of what the MultichainHelper would look like. There is tight
coupling between the TransactionController and the MultichainHelper due
to the dependencies of instantiating the IncomingTxHelper,
PendingTxHelper, and nonceTracker. Even if the global trackers/helpers
are also pushed into the MultichainHelper, many of
TransactionControllers methods need to passed into MultichainHelper.
This also effectively makes MultichainHelper really the TrackingHelper.

Note that the Integration tests still pass.

<!--
Thanks for your contribution! Take a moment to answer these questions so
that reviewers have the information they need to properly understand
your changes:

* What is the current state of things and why does it need to change?
* What is the solution your changes offer and how does it work?
* Are there any changes whose purpose might not obvious to those
unfamiliar with the domain?
* If your primary goal was to update one package but you found you had
to update another one along the way, why did you do so?
* If you had to upgrade a dependency, why did you do so?
-->

## References

<!--
Are there any issues that this pull request is tied to? Are there other
links that reviewers should consult to understand these changes better?

For example:

* Fixes #12345
* Related to #67890
-->

## Changelog

<!--
If you're making any consumer-facing changes, list those changes here as
if you were updating a changelog, using the template below as a guide.

(CATEGORY is one of BREAKING, ADDED, CHANGED, DEPRECATED, REMOVED, or
FIXED. For security-related issues, follow the Security Advisory
process.)

Please take care to name the exact pieces of the API you've added or
changed (e.g. types, interfaces, functions, or methods).

If there are any breaking changes, make sure to offer a solution for
consumers to follow once they upgrade to the changes.

Finally, if you're only making changes to development scripts or tests,
you may replace the template below with "None".
-->

### `@metamask/package-a`

- **<CATEGORY>**: Your change here
- **<CATEGORY>**: Your change here

### `@metamask/package-b`

- **<CATEGORY>**: Your change here
- **<CATEGORY>**: Your change here

## Checklist

- [ ] I've updated the test suite for new or updated code as appropriate
- [ ] I've updated documentation (JSDoc, Markdown, etc.) for new or
updated code as appropriate
- [ ] I've highlighted breaking changes using the "BREAKING" category
above as appropriate

---------

Co-authored-by: Alex <[email protected]>
Copy link
Contributor

@mcmire mcmire left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good!

Copy link
Member

@matthewwalsh0 matthewwalsh0 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Excellent work, thanks everyone!

And a special shoutout to the great encapsulation in the MultichainTrackingHelper.

Approving assuming we have tested adoption in the extension and have a passing pipeline.

@adonesky1
Copy link
Contributor

@metamaskbot publish-preview

Copy link
Contributor

Preview builds have been published. See these instructions for more information about preview builds.

Expand for full list of packages and versions.
{
  "@metamask-previews/accounts-controller": "10.0.0-preview.280e51c7",
  "@metamask-previews/address-book-controller": "3.1.7-preview.280e51c7",
  "@metamask-previews/announcement-controller": "5.0.2-preview.280e51c7",
  "@metamask-previews/approval-controller": "5.1.2-preview.280e51c7",
  "@metamask-previews/assets-controllers": "25.0.0-preview.280e51c7",
  "@metamask-previews/base-controller": "4.1.1-preview.280e51c7",
  "@metamask-previews/build-utils": "1.0.2-preview.280e51c7",
  "@metamask-previews/composable-controller": "5.0.1-preview.280e51c7",
  "@metamask-previews/controller-utils": "8.0.2-preview.280e51c7",
  "@metamask-previews/ens-controller": "9.0.0-preview.280e51c7",
  "@metamask-previews/eth-json-rpc-provider": "2.3.2-preview.280e51c7",
  "@metamask-previews/gas-fee-controller": "13.0.0-preview.280e51c7",
  "@metamask-previews/json-rpc-engine": "7.3.2-preview.280e51c7",
  "@metamask-previews/json-rpc-middleware-stream": "6.0.2-preview.280e51c7",
  "@metamask-previews/keyring-controller": "12.2.0-preview.280e51c7",
  "@metamask-previews/logging-controller": "2.0.2-preview.280e51c7",
  "@metamask-previews/message-manager": "7.3.8-preview.280e51c7",
  "@metamask-previews/name-controller": "5.0.0-preview.280e51c7",
  "@metamask-previews/network-controller": "17.2.0-preview.280e51c7",
  "@metamask-previews/notification-controller": "4.0.2-preview.280e51c7",
  "@metamask-previews/permission-controller": "8.0.0-preview.280e51c7",
  "@metamask-previews/permission-log-controller": "0.0.0-preview.280e51c7",
  "@metamask-previews/phishing-controller": "8.0.2-preview.280e51c7",
  "@metamask-previews/polling-controller": "5.0.0-preview.280e51c7",
  "@metamask-previews/preferences-controller": "7.0.0-preview.280e51c7",
  "@metamask-previews/queued-request-controller": "0.4.0-preview.280e51c7",
  "@metamask-previews/rate-limit-controller": "4.0.2-preview.280e51c7",
  "@metamask-previews/selected-network-controller": "7.0.1-preview.280e51c7",
  "@metamask-previews/signature-controller": "12.0.0-preview.280e51c7",
  "@metamask-previews/transaction-controller": "21.2.0-preview.280e51c7",
  "@metamask-previews/user-operation-controller": "3.0.0-preview.280e51c7"
}

@adonesky1 adonesky1 merged commit 1fcddc8 into main Feb 15, 2024
136 checks passed
@adonesky1 adonesky1 deleted the transaction-multichain branch February 15, 2024 20:57
MajorLift pushed a commit that referenced this pull request Feb 16, 2024
## Explanation

Resolves: MetaMask/MetaMask-planning#1019

## Changelog

### `@metamask/transaction-controller`

### Added
- **BREAKING:** Constructor now expects a `getNetworkClientRegistry`
callback function
- **BREAKING:** Messenger now requires `NetworkController:stateChange`
to be an allowed event
- **BREAKING:** Messenger now requires
`NetworkController:findNetworkClientByChainId` and
`NetworkController:getNetworkClientById` actions
- Adds a feature flag parameter `isMultichainEnabled ` passed via the
constructor (and defaulted to false), which when passed a truthy value
will initialize `incomingTransactionHelper`,
`pendingTransactionTracker`, `nonceTracker` per networkClientId from the
NetworkController’s `networkClientRegistry` and a
`EtherScanRemoteTransactionSource` helper per chainId in the registry.
- Adds `destroy()` method that stops/removes internal polling and
listeners
- Exports `PendingTransactionOptions` type
- Exports `TransactionControllerOptions` type
- Adds `stopAllIncomingTransactionPolling()` that stops the global
IncomingTransactionHelper and each networkClientId's
IncomingTransactionHelper


### Changed
- **BREAKING:** `approveTransactionsWithSameNonce()` now requires
`chainId` to be populated in for each TransactionParams that is passed
- `addTransaction()` now accepts optional `networkClientId` in its
options param which specifies the network client that the transaction
will be processed with during its lifecycle if the `isMultichainEnabled`
feature flag is on
- `estimateGas()` now accepts optional networkClientId as its last param
which specifies the network client that should be used to estimate the
required gas for the given transaction
- `estimateGasBuffered()` now accepts optional networkClientId as its
last param which specifies the network client that should be used to
estimate the required gas plus buffer for the given transaction
- `getNonceLock()` now accepts optional networkClientId as its last
param which specifies which the network client's nonceTracker should be
used to determine the next nonce.
- When used with the `enableMultichain` feature flag on and with
networkClientId specified, this method will also restrict acquiring the
next nonce by chainId, i.e. if this method is called with two different
networkClientIds on the same chainId, only the first call will return
immediately with a lock from its respective nonceTracker with the second
call being blocked until the first caller releases its lock
- Approval of transactions previously used the chainId from the global
provider state as the source of truth. Instead it will now use the
chainId from the TransactionMeta object. **Not sure we really need to
put this in the changelog since all tx will have chainId populated**
- `EtherscanRemoteTransactionSource` now enforces a 5 second delay
between requests to avoid rate limiting
- `TransactionMeta` type now specifies an optional `networkClientId`
field
- `startIncomingTransactionPolling()` now accepts an optional array of
networkClientIds. When provided, the IncomingTransactionHelpers for
those networkClientIds will be started. If empty or not provided, the
global IncomingTransactionHelper will be started.
- `stopIncomingTransactionPolling()` now accepts an optional array of
networkClientIds. When provided, the IncomingTransactionHelpers for
those networkClientIds will be stoppped. If empty or not provided, the
global IncomingTransactionHelper will be stopped.

### Removed


## Checklist

- [ ] I've updated the test suite for new or updated code as appropriate
- [ ] I've updated documentation (JSDoc, Markdown, etc.) for new or
updated code as appropriate
- [ ] I've highlighted breaking changes using the "BREAKING" category
above as appropriate

---------

Co-authored-by: Jiexi Luan <[email protected]>
Co-authored-by: Alex Donesky <[email protected]>
Co-authored-by: Matthew Walsh <[email protected]>
Co-authored-by: Elliot Winkler <[email protected]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants