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

Add eth-query types #1266

Merged
merged 10 commits into from
Apr 27, 2023
Merged

Add eth-query types #1266

merged 10 commits into from
Apr 27, 2023

Conversation

Gudahtt
Copy link
Member

@Gudahtt Gudahtt commented Apr 25, 2023

Description

Type definitions have been added for the eth-query package. These were copied from the type definitions used in the extension.

The addition of these types revealed various invalid assumptions we've made throughout the codebase, requiring the addition of runtime checks. Mostly this consists of throwing an error whenever someone tries to use the ethQuery instance before it has been set. In most cases, this would only introduce an error in code paths that would already throw an error.

The one exception to that is the gas fee controller, which used to get ethQuery upon construction. It has been updated to wait until the providerConfigChange event before attempting to fetch that, since it's never defined upon construction in practice anyway.

There are two places in the network controller where these types revealed that we're not validating the network response to the net_version and eth_getBlockByNumber calls made during network lookup. A comment has been left about validating this in a future PR.

Changes

@metamask/assets-controllers

  • BREAKING: The controller configuration now uses our EthQuery type definition for the provider config property

@metamask/controller-utils

  • CHANGED: The query function has improved type checks for the ethQuery argument
    • This type change could be breaking, but only if you were passing in an invalid ethQuery parameter. In that circumstance this would have thrown an error at runtime anyway. Effectively this should be non-breaking for any usage that isn't already broken.

@metamask/gas-fee-controller

  • BREAKING: NetworkController:getEthQuery is no longer called in the constructor
    • The internal ethQuery instance gets updated upon the providerConfigChange event. This means that the ethQuery instance won't get set until after provider initialization or the next network switch.
    • This should have no impact upon extension or mobile, but might affect projects that were constructing this controller after the network controller was initialized.

@metamask/network-controller

  • BREAKING: The exported Provider type has been updated to better reflect the provider type returned by the network controller
    • Previously this was set to any. Now it returns a type that mostly matches the provider returned (some semi-internal properties are omitted)
    • This affects the exported ProviderProxy type as well, which wraps the Provider type
  • BREAKING: The action NetworkController:getEthQuery will now throw an error if ethQuery is not set, rather than returning undefined

References

Closes #1204

Checklist

  • I've updated the test suite for new or updated code as appropriate
  • I've updated documentation for new or updated code as appropriate (note: this will usually be JSDoc)
  • I've highlighted breaking changes using the "BREAKING" category above as appropriate

@Gudahtt Gudahtt force-pushed the add-eth-query-types branch 2 times, most recently from c8fa5bc to 4881a29 Compare April 25, 2023 21:31
@Gudahtt Gudahtt changed the title Add eth-query types Add eth-query types [WIP] Apr 25, 2023
@Gudahtt Gudahtt force-pushed the add-eth-query-types branch 13 times, most recently from 621e59f to e9c594c Compare April 26, 2023 15:51
@Gudahtt Gudahtt changed the base branch from main to remove-has-property April 26, 2023 15:52
Base automatically changed from remove-has-property to main April 26, 2023 15:58
@Gudahtt Gudahtt force-pushed the add-eth-query-types branch 4 times, most recently from 8d8a93b to 3fc91b6 Compare April 26, 2023 16:15
@Gudahtt Gudahtt changed the title Add eth-query types [WIP] Add eth-query types Apr 26, 2023
Type definitions have been added for the `eth-query` package. These
were copied from the type definitions used in the extension.

The addition of these types revealed various invalid assumptions we've
made throughout the codebase, requiring the addition of runtime checks.
Mostly this consists of throwing an error whenever someone tries to use
the `ethQuery` instance before it has been set. In most cases, this
would only introduce an error in code paths that would already throw an
error.

The one exception to that is the gas fee controller, which used to get
`ethQuery` upon construction. It has been updated to wait until the
`providerConfigChange` event before attempting to fetch that, since
it's never defined upon construction in practice anyway.

There are two places in the network controller where these types
revealed that we're not validating the network response to the
`net_version` and `eth_getBlockByNumber` calls made during network
lookup. A comment has been left about validating this in a future PR.

Closes #1204
@Gudahtt Gudahtt marked this pull request as ready for review April 26, 2023 17:55
@Gudahtt Gudahtt requested a review from a team as a code owner April 26, 2023 17:55
Co-authored-by: Maarten Zuidhoorn <maarten@zuidhoorn.com>
@Gudahtt Gudahtt marked this pull request as draft April 27, 2023 13:02
@Gudahtt Gudahtt marked this pull request as ready for review April 27, 2023 14:12
@Gudahtt Gudahtt requested a review from Mrtenz April 27, 2023 14:12
@Gudahtt Gudahtt merged commit f52d891 into main Apr 27, 2023
@Gudahtt Gudahtt deleted the add-eth-query-types branch April 27, 2023 14:24
@@ -346,9 +346,6 @@ export class GasFeeController extends BaseControllerV2<
'NetworkController:getProviderConfig',
);
this.currentChainId = providerConfig.chainId;
this.ethQuery = this.messagingSystem.call(
Copy link
Member Author

Choose a reason for hiding this comment

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

In retrospect, my assumption here wasn't entirely true; in practice this likely was set upon construction. Just not in the tests. So this is breaking after all. We'll need to fix this before the next release.

Copy link
Member Author

Choose a reason for hiding this comment

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

Maybe the simplest fix would be to update getEthQuery to return EthQuery | undefined, and restore this line.

Copy link
Contributor

Choose a reason for hiding this comment

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

Okay, fixed via #1284.

if (error) {
reject(error);
return;
}
resolve(result);
};

if (typeof ethQuery[method] === 'function') {
if (
hasProperty(ethQuery, method) &&
Copy link
Member Author

Choose a reason for hiding this comment

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

This seems to have introduced a bug; the methods in question are on the ethQuery prototype, so this is returning false when this condition used to resolve to true

Copy link
Contributor

Choose a reason for hiding this comment

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

Right, that makes sense.

Gudahtt added a commit that referenced this pull request Jun 23, 2023
The `query` function was updated in #1266 to use `hasProperty` has part
of an effect to improve the types being used. Unfortunately this had
the unexpected affected of breaking this condition because
`hasProperty` doesn't look up the prototype chain, but the method we
were checking for was on the prototype. `hasProperty` is only meant to
be used with plain objects.

The condition has been updated to use `in`, and the tests have been
updated to use a more realistic EthQuery mock that has methods as
prototypes.
Gudahtt added a commit that referenced this pull request Jun 23, 2023
The `query` function was updated in #1266 to use `hasProperty` has part
of an effect to improve the types being used. Unfortunately this had
the unexpected affected of breaking this condition because
`hasProperty` doesn't look up the prototype chain, but the method we
were checking for was on the prototype. `hasProperty` is only meant to
be used with plain objects.

The condition has been updated to use `in`, and the tests have been
updated to use a more realistic EthQuery mock that has methods as
prototypes.

To fix various type errors, an old inlined EthQueryLike type has been
replaced by the real EthQuery type. This required adding `eth-query` as
a dependency to the controller utils package.
Gudahtt added a commit that referenced this pull request Jun 23, 2023
The `query` function was updated in #1266 to use `hasProperty` has part
of an effect to improve the types being used. Unfortunately this had
the unexpected affected of breaking this condition because
`hasProperty` doesn't look up the prototype chain, but the method we
were checking for was on the prototype. `hasProperty` is only meant to
be used with plain objects.

The condition has been updated to use `in`, and the tests have been
updated to use a more realistic EthQuery mock that has methods as
prototypes.

To fix various type errors, an old inlined EthQueryLike type has been
replaced by the real EthQuery type. This required adding `eth-query` as
a dependency to the controller utils package.
MajorLift pushed a commit that referenced this pull request Oct 11, 2023
Type definitions have been added for the `eth-query` package. These
were copied from the type definitions used in the extension.

The addition of these types revealed various invalid assumptions we've
made throughout the codebase, requiring the addition of runtime checks.
Mostly this consists of throwing an error whenever someone tries to use
the `ethQuery` instance before it has been set. In most cases, this
would only introduce an error in code paths that would already throw an
error.

The one exception to that is the gas fee controller, which used to get
`ethQuery` upon construction. It has been updated to wait until the
`providerConfigChange` event before attempting to fetch that, since
it's never defined upon construction in practice anyway.

There are two places in the network controller where these types
revealed that we're not validating the network response to the
`net_version` and `eth_getBlockByNumber` calls made during network
lookup. A comment has been left about validating this in a future PR.

Co-authored-by: Maarten Zuidhoorn <maarten@zuidhoorn.com>
MajorLift pushed a commit that referenced this pull request Oct 11, 2023
The `query` function was updated in #1266 to use `hasProperty` has part
of an effect to improve the types being used. Unfortunately this had
the unexpected affected of breaking this condition because
`hasProperty` doesn't look up the prototype chain, but the method we
were checking for was on the prototype. `hasProperty` is only meant to
be used with plain objects.

The condition has been updated to use `in`, and the tests have been
updated to use a more realistic EthQuery mock that has methods as
prototypes.

To fix various type errors, an old inlined EthQueryLike type has been
replaced by the real EthQuery type. This required adding `eth-query` as
a dependency to the controller utils package.
MajorLift pushed a commit that referenced this pull request Oct 11, 2023
Type definitions have been added for the `eth-query` package. These
were copied from the type definitions used in the extension.

The addition of these types revealed various invalid assumptions we've
made throughout the codebase, requiring the addition of runtime checks.
Mostly this consists of throwing an error whenever someone tries to use
the `ethQuery` instance before it has been set. In most cases, this
would only introduce an error in code paths that would already throw an
error.

The one exception to that is the gas fee controller, which used to get
`ethQuery` upon construction. It has been updated to wait until the
`providerConfigChange` event before attempting to fetch that, since
it's never defined upon construction in practice anyway.

There are two places in the network controller where these types
revealed that we're not validating the network response to the
`net_version` and `eth_getBlockByNumber` calls made during network
lookup. A comment has been left about validating this in a future PR.

Co-authored-by: Maarten Zuidhoorn <maarten@zuidhoorn.com>
MajorLift pushed a commit that referenced this pull request Oct 11, 2023
The `query` function was updated in #1266 to use `hasProperty` has part
of an effect to improve the types being used. Unfortunately this had
the unexpected affected of breaking this condition because
`hasProperty` doesn't look up the prototype chain, but the method we
were checking for was on the prototype. `hasProperty` is only meant to
be used with plain objects.

The condition has been updated to use `in`, and the tests have been
updated to use a more realistic EthQuery mock that has methods as
prototypes.

To fix various type errors, an old inlined EthQueryLike type has been
replaced by the real EthQuery type. This required adding `eth-query` as
a dependency to the controller utils package.
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.

Improve augmented types for eth-query, and use them in NetworkController
4 participants