1
0
mirror of https://github.com/kremalicious/metamask-extension.git synced 2024-10-22 11:22:43 +02:00

Update eth-json-rpc-middleware to v9.0.1 (#16096)

This update includes fixes for our `block-ref` and `retry-on-empty`
middleware.

The `block-ref` middleware resolves the block reference `latest` to a
specific block number, the latest one we are aware of. This is meant to
protect against situations where the network gives inconsistent answers
for what the latest block number is due to some nodes being out-of-sync
with each other (this was a frequent problem years ago with Infura).

It was broken in that the `latest` resolution was failing, and we were
submitting an additional redundant request to Infura for each request.

The `retry-on-empty` middleware is meant to retry certain methods
when they return an empty response. This was also meant to deal with
network synchronization issues that were more common years ago. This
middleware works by making a "child" request over and over until either
a retry limit is reached, or a non-empty response is received.

It was broken in that the final response recieved was thrown away, so
it's as though the middleware was not used. Except that it did result
in additional redundant network requests.

As a result of this update we should see that the extension is more
resilient to certain network synchronization issues. But this is
difficult to test, and these issues may not happen in production
anymore today.

We should see a reduction in requests to Infura as well. This should
be easier to test.
This commit is contained in:
Mark Stacey 2022-10-10 11:46:58 -04:00 committed by GitHub
parent 1b3dc0db54
commit f6f8edfd15
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 99 additions and 220 deletions

View File

@ -673,12 +673,6 @@ export function testsForRpcMethodSupportingBlockParam(
),
response: { result: mockResults[0] },
});
// Note that the block-ref middleware will still allow the original
// request to go through.
comms.mockInfuraRpcCall({
request: requests[0],
response: { result: mockResults[0] },
});
const results = await withInfuraClient(({ makeRpcCallsInSeries }) =>
makeRpcCallsInSeries(requests),
@ -713,31 +707,15 @@ export function testsForRpcMethodSupportingBlockParam(
),
response: { result: mockResults[0] },
});
// Note that the block-ref middleware will still allow the original
// request to go through.
comms.mockInfuraRpcCall({
request: requests[0],
response: { result: mockResults[0] },
});
comms.mockNextBlockTrackerRequest({ blockNumber: '0x200' });
comms.mockInfuraRpcCall({
request: requests[1],
response: { result: mockResults[1] },
});
// The previous two requests will happen again, with a different block
// number, in the same order.
comms.mockInfuraRpcCall({
request: buildRequestWithReplacedBlockParam(
requests[0],
requests[1],
blockParamIndex,
'0x200',
),
response: { result: mockResults[1] },
});
comms.mockInfuraRpcCall({
request: requests[0],
response: { result: mockResults[1] },
});
const results = await withInfuraClient(async (client) => {
const firstResult = await client.makeRpcCall(requests[0]);
@ -780,25 +758,14 @@ export function testsForRpcMethodSupportingBlockParam(
),
response: { result: mockResults[0] },
});
// Note that the block-ref middleware will still allow the original
// request to go through.
comms.mockInfuraRpcCall({
request: requests[0],
response: { result: mockResults[0] },
});
// The previous two requests will happen again, in the same order.
comms.mockInfuraRpcCall({
request: buildRequestWithReplacedBlockParam(
requests[0],
requests[1],
blockParamIndex,
'0x100',
),
response: { result: mockResults[1] },
});
comms.mockInfuraRpcCall({
request: requests[0],
response: { result: mockResults[1] },
});
const results = await withInfuraClient(({ makeRpcCallsInSeries }) =>
makeRpcCallsInSeries(requests),
@ -823,8 +790,9 @@ export function testsForRpcMethodSupportingBlockParam(
comms.mockNextBlockTrackerRequest({ blockNumber: '0x100' });
// The block-ref middleware will make the request as specified
// except that the block param is replaced with the latest block
// number.
// number, and we delay it.
comms.mockInfuraRpcCall({
delay: 100,
request: buildRequestWithReplacedBlockParam(
requests[0],
blockParamIndex,
@ -832,13 +800,6 @@ export function testsForRpcMethodSupportingBlockParam(
),
response: { result: mockResults[0] },
});
// This is the original request as below, which the block-ref
// middleware will allow through, except that we delay it.
comms.mockInfuraRpcCall({
request: requests[0],
response: { result: mockResults[0] },
delay: 100,
});
// The previous two requests will happen again, in the same order.
comms.mockInfuraRpcCall({
request: buildRequestWithReplacedBlockParam(
@ -848,10 +809,6 @@ export function testsForRpcMethodSupportingBlockParam(
),
response: { result: mockResults[1] },
});
comms.mockInfuraRpcCall({
request: requests[1],
response: { result: mockResults[1] },
});
comms.mockInfuraRpcCall({
request: buildRequestWithReplacedBlockParam(
requests[2],
@ -860,10 +817,6 @@ export function testsForRpcMethodSupportingBlockParam(
),
response: { result: mockResults[2] },
});
comms.mockInfuraRpcCall({
request: requests[2],
response: { result: mockResults[2] },
});
const results = await withInfuraClient(async (client) => {
const resultPromises = [
@ -902,10 +855,6 @@ export function testsForRpcMethodSupportingBlockParam(
// The block-ref middleware will make the request as specified
// except that the block param is replaced with the latest block
// number.
//
// Note, however, that the block-ref middleware doesn't run the
// original request, as it fails before it gets to that point, so
// there is no need to mock the request again.
comms.mockInfuraRpcCall({
request: buildRequestWithReplacedBlockParam(
request,
@ -940,10 +889,6 @@ export function testsForRpcMethodSupportingBlockParam(
// The block-ref middleware will make the request as specified
// except that the block param is replaced with the latest block
// number.
//
// Note, however, that the block-ref middleware doesn't run the
// original request, as it fails before it gets to that point, so
// there is no need to mock the request again.
comms.mockInfuraRpcCall({
request: buildRequestWithReplacedBlockParam(
request,
@ -978,10 +923,6 @@ export function testsForRpcMethodSupportingBlockParam(
// The block-ref middleware will make the request as specified
// except that the block param is replaced with the latest block
// number.
//
// Note, however, that the block-ref middleware doesn't run the
// original request, as it fails before it gets to that point, so
// there is no need to mock the request again.
comms.mockInfuraRpcCall({
request: buildRequestWithReplacedBlockParam(
request,
@ -1046,15 +987,6 @@ export function testsForRpcMethodSupportingBlockParam(
httpStatus: 200,
},
});
// Note that the block-ref middleware will still allow the original
// request to go through.
comms.mockInfuraRpcCall({
request,
response: {
result: 'the result',
httpStatus: 200,
},
});
const result = await withInfuraClient(
async ({ makeRpcCall, clock }) => {
return await waitForPromiseToBeFulfilledAfterRunningAllTimers(
@ -1082,10 +1014,6 @@ export function testsForRpcMethodSupportingBlockParam(
// The block-ref middleware will make the request as specified
// except that the block param is replaced with the latest block
// number.
//
// Note, however, that the block-ref middleware doesn't run the
// original request, as it fails before it gets to that point, so
// there is no need to mock the request again.
comms.mockInfuraRpcCall({
request: buildRequestWithReplacedBlockParam(
request,
@ -1153,15 +1081,6 @@ export function testsForRpcMethodSupportingBlockParam(
httpStatus: 200,
},
});
// Note that the block-ref middleware will still allow the
// original request to go through.
comms.mockInfuraRpcCall({
request,
response: {
result: 'the result',
httpStatus: 200,
},
});
const result = await withInfuraClient(
async ({ makeRpcCall, clock }) => {
return await waitForPromiseToBeFulfilledAfterRunningAllTimers(
@ -1189,10 +1108,6 @@ export function testsForRpcMethodSupportingBlockParam(
// The block-ref middleware will make the request as specified
// except that the block param is replaced with the latest block
// number.
//
// Note, however, that the block-ref middleware doesn't run the
// original request, as it fails before it gets to that point, so
// there is no need to mock the request again.
comms.mockInfuraRpcCall({
request: buildRequestWithReplacedBlockParam(
request,
@ -1408,23 +1323,16 @@ export function testsForRpcMethodSupportingBlockParam(
// also happens within the retry-on-empty middleware (although the
// latest block is cached by now).
comms.mockNextBlockTrackerRequest({ blockNumber: '0x100' });
// The retry-on-empty middleware will make an explicit request.
comms.mockInfuraRpcCall({
request,
response: { result: 'this result gets overwritten' },
});
// Note that the retry-on-empty middleware will still allow the
// original request to go through.
comms.mockInfuraRpcCall({
request,
response: { result: 'the actual result' },
response: { result: 'the result' },
});
const result = await withInfuraClient(({ makeRpcCall }) =>
makeRpcCall(request),
);
expect(result).toStrictEqual('the actual result');
expect(result).toStrictEqual('the result');
});
});
@ -1440,23 +1348,16 @@ export function testsForRpcMethodSupportingBlockParam(
// also happens within the retry-on-empty middleware (although the
// latest block is cached by now).
comms.mockNextBlockTrackerRequest({ blockNumber: '0x100' });
// The retry-on-empty middleware will make an explicit request.
comms.mockInfuraRpcCall({
request,
response: { result: 'this result gets overwritten' },
});
// Note that the retry-on-empty middleware will still allow the
// original request to go through.
comms.mockInfuraRpcCall({
request,
response: { result: 'the actual result' },
response: { result: 'the result' },
});
const result = await withInfuraClient(({ makeRpcCall }) =>
makeRpcCall(request),
);
expect(result).toStrictEqual('the actual result');
expect(result).toStrictEqual('the result');
});
});
}

View File

@ -4551,7 +4551,7 @@
"packages": {
"browserify>browser-resolve": true,
"eth-block-tracker>@metamask/utils": true,
"eth-json-rpc-middleware>eth-sig-util": true,
"eth-json-rpc-middleware>@metamask/eth-sig-util": true,
"eth-json-rpc-middleware>pify": true,
"eth-rpc-errors": true,
"json-rpc-engine": true,
@ -4560,45 +4560,32 @@
"vinyl>clone": true
}
},
"eth-json-rpc-middleware>eth-sig-util": {
"eth-json-rpc-middleware>@metamask/eth-sig-util": {
"packages": {
"eth-json-rpc-middleware>eth-sig-util>ethereumjs-abi": true,
"eth-json-rpc-middleware>eth-sig-util>ethereumjs-util": true
}
},
"eth-json-rpc-middleware>eth-sig-util>ethereumjs-abi": {
"packages": {
"bn.js": true,
"3box>tweetnacl": true,
"3box>tweetnacl-util": true,
"browserify>buffer": true,
"eth-json-rpc-middleware>eth-sig-util>ethereumjs-abi>ethereumjs-util": true
"eth-json-rpc-middleware>@metamask/eth-sig-util>bn.js": true,
"eth-json-rpc-middleware>@metamask/eth-sig-util>ethereum-cryptography": true,
"eth-json-rpc-middleware>@metamask/eth-sig-util>ethjs-util": true,
"eth-lattice-keyring>@ethereumjs/util": true
}
},
"eth-json-rpc-middleware>eth-sig-util>ethereumjs-abi>ethereumjs-util": {
"eth-json-rpc-middleware>@metamask/eth-sig-util>bn.js": {
"packages": {
"3box>ethers>elliptic": true,
"bn.js": true,
"browserify>assert": true,
"browserify>buffer": true,
"eth-json-rpc-middleware>eth-sig-util>ethereumjs-util>ethjs-util": true,
"ethereumjs-util>create-hash": true,
"ethereumjs-util>ethereum-cryptography": true,
"ethereumjs-util>rlp": true
"browserify>browser-resolve": true
}
},
"eth-json-rpc-middleware>eth-sig-util>ethereumjs-util": {
"eth-json-rpc-middleware>@metamask/eth-sig-util>ethereum-cryptography": {
"globals": {
"TextDecoder": true,
"crypto": true
},
"packages": {
"3box>ethers>elliptic": true,
"bn.js": true,
"browserify>assert": true,
"browserify>buffer": true,
"eth-json-rpc-middleware>eth-sig-util>ethereumjs-util>ethjs-util": true,
"ethereumjs-util>create-hash": true,
"ethereumjs-util>ethereum-cryptography": true,
"ethereumjs-util>rlp": true,
"ethereumjs-wallet>safe-buffer": true
"@metamask/rpc-methods>@metamask/key-tree>@noble/hashes": true
}
},
"eth-json-rpc-middleware>eth-sig-util>ethereumjs-util>ethjs-util": {
"eth-json-rpc-middleware>@metamask/eth-sig-util>ethjs-util": {
"packages": {
"browserify>buffer": true,
"ethjs>ethjs-util>is-hex-prefixed": true,

View File

@ -5377,7 +5377,7 @@
"packages": {
"browserify>browser-resolve": true,
"eth-block-tracker>@metamask/utils": true,
"eth-json-rpc-middleware>eth-sig-util": true,
"eth-json-rpc-middleware>@metamask/eth-sig-util": true,
"eth-json-rpc-middleware>pify": true,
"eth-rpc-errors": true,
"json-rpc-engine": true,
@ -5386,45 +5386,32 @@
"vinyl>clone": true
}
},
"eth-json-rpc-middleware>eth-sig-util": {
"eth-json-rpc-middleware>@metamask/eth-sig-util": {
"packages": {
"eth-json-rpc-middleware>eth-sig-util>ethereumjs-abi": true,
"eth-json-rpc-middleware>eth-sig-util>ethereumjs-util": true
}
},
"eth-json-rpc-middleware>eth-sig-util>ethereumjs-abi": {
"packages": {
"bn.js": true,
"3box>tweetnacl": true,
"3box>tweetnacl-util": true,
"browserify>buffer": true,
"eth-json-rpc-middleware>eth-sig-util>ethereumjs-abi>ethereumjs-util": true
"eth-json-rpc-middleware>@metamask/eth-sig-util>bn.js": true,
"eth-json-rpc-middleware>@metamask/eth-sig-util>ethereum-cryptography": true,
"eth-json-rpc-middleware>@metamask/eth-sig-util>ethjs-util": true,
"eth-lattice-keyring>@ethereumjs/util": true
}
},
"eth-json-rpc-middleware>eth-sig-util>ethereumjs-abi>ethereumjs-util": {
"eth-json-rpc-middleware>@metamask/eth-sig-util>bn.js": {
"packages": {
"3box>ethers>elliptic": true,
"bn.js": true,
"browserify>assert": true,
"browserify>buffer": true,
"eth-json-rpc-middleware>eth-sig-util>ethereumjs-util>ethjs-util": true,
"ethereumjs-util>create-hash": true,
"ethereumjs-util>ethereum-cryptography": true,
"ethereumjs-util>rlp": true
"browserify>browser-resolve": true
}
},
"eth-json-rpc-middleware>eth-sig-util>ethereumjs-util": {
"eth-json-rpc-middleware>@metamask/eth-sig-util>ethereum-cryptography": {
"globals": {
"TextDecoder": true,
"crypto": true
},
"packages": {
"3box>ethers>elliptic": true,
"bn.js": true,
"browserify>assert": true,
"browserify>buffer": true,
"eth-json-rpc-middleware>eth-sig-util>ethereumjs-util>ethjs-util": true,
"ethereumjs-util>create-hash": true,
"ethereumjs-util>ethereum-cryptography": true,
"ethereumjs-util>rlp": true,
"ethereumjs-wallet>safe-buffer": true
"@metamask/rpc-methods>@metamask/key-tree>@noble/hashes": true
}
},
"eth-json-rpc-middleware>eth-sig-util>ethereumjs-util>ethjs-util": {
"eth-json-rpc-middleware>@metamask/eth-sig-util>ethjs-util": {
"packages": {
"browserify>buffer": true,
"ethjs>ethjs-util>is-hex-prefixed": true,

View File

@ -4551,7 +4551,7 @@
"packages": {
"browserify>browser-resolve": true,
"eth-block-tracker>@metamask/utils": true,
"eth-json-rpc-middleware>eth-sig-util": true,
"eth-json-rpc-middleware>@metamask/eth-sig-util": true,
"eth-json-rpc-middleware>pify": true,
"eth-rpc-errors": true,
"json-rpc-engine": true,
@ -4560,45 +4560,32 @@
"vinyl>clone": true
}
},
"eth-json-rpc-middleware>eth-sig-util": {
"eth-json-rpc-middleware>@metamask/eth-sig-util": {
"packages": {
"eth-json-rpc-middleware>eth-sig-util>ethereumjs-abi": true,
"eth-json-rpc-middleware>eth-sig-util>ethereumjs-util": true
}
},
"eth-json-rpc-middleware>eth-sig-util>ethereumjs-abi": {
"packages": {
"bn.js": true,
"3box>tweetnacl": true,
"3box>tweetnacl-util": true,
"browserify>buffer": true,
"eth-json-rpc-middleware>eth-sig-util>ethereumjs-abi>ethereumjs-util": true
"eth-json-rpc-middleware>@metamask/eth-sig-util>bn.js": true,
"eth-json-rpc-middleware>@metamask/eth-sig-util>ethereum-cryptography": true,
"eth-json-rpc-middleware>@metamask/eth-sig-util>ethjs-util": true,
"eth-lattice-keyring>@ethereumjs/util": true
}
},
"eth-json-rpc-middleware>eth-sig-util>ethereumjs-abi>ethereumjs-util": {
"eth-json-rpc-middleware>@metamask/eth-sig-util>bn.js": {
"packages": {
"3box>ethers>elliptic": true,
"bn.js": true,
"browserify>assert": true,
"browserify>buffer": true,
"eth-json-rpc-middleware>eth-sig-util>ethereumjs-util>ethjs-util": true,
"ethereumjs-util>create-hash": true,
"ethereumjs-util>ethereum-cryptography": true,
"ethereumjs-util>rlp": true
"browserify>browser-resolve": true
}
},
"eth-json-rpc-middleware>eth-sig-util>ethereumjs-util": {
"eth-json-rpc-middleware>@metamask/eth-sig-util>ethereum-cryptography": {
"globals": {
"TextDecoder": true,
"crypto": true
},
"packages": {
"3box>ethers>elliptic": true,
"bn.js": true,
"browserify>assert": true,
"browserify>buffer": true,
"eth-json-rpc-middleware>eth-sig-util>ethereumjs-util>ethjs-util": true,
"ethereumjs-util>create-hash": true,
"ethereumjs-util>ethereum-cryptography": true,
"ethereumjs-util>rlp": true,
"ethereumjs-wallet>safe-buffer": true
"@metamask/rpc-methods>@metamask/key-tree>@noble/hashes": true
}
},
"eth-json-rpc-middleware>eth-sig-util>ethereumjs-util>ethjs-util": {
"eth-json-rpc-middleware>@metamask/eth-sig-util>ethjs-util": {
"packages": {
"browserify>buffer": true,
"ethjs>ethjs-util>is-hex-prefixed": true,

View File

@ -2873,7 +2873,21 @@
},
"packages": {
"eslint>file-entry-cache>flat-cache>flatted": true,
"nyc>rimraf": true
"eslint>file-entry-cache>flat-cache>rimraf": true
}
},
"eslint>file-entry-cache>flat-cache>rimraf": {
"builtin": {
"assert": true,
"fs": true,
"path.join": true
},
"globals": {
"process.platform": true,
"setTimeout": true
},
"packages": {
"nyc>glob": true
}
},
"eslint>glob-parent": {
@ -5857,20 +5871,6 @@
"path.resolve": true
}
},
"nyc>rimraf": {
"builtin": {
"assert": true,
"fs": true,
"path.join": true
},
"globals": {
"process.platform": true,
"setTimeout": true
},
"packages": {
"nyc>glob": true
}
},
"nyc>signal-exit": {
"builtin": {
"assert.equal": true,

View File

@ -167,7 +167,7 @@
"eth-block-tracker": "^6.0.0",
"eth-ens-namehash": "^2.0.8",
"eth-json-rpc-filters": "^4.2.1",
"eth-json-rpc-middleware": "^9.0.0",
"eth-json-rpc-middleware": "^9.0.1",
"eth-keyring-controller": "^7.0.2",
"eth-lattice-keyring": "^0.12.3",
"eth-method-registry": "^2.0.0",

View File

@ -3299,6 +3299,18 @@
tweetnacl "^1.0.3"
tweetnacl-util "^0.15.1"
"@metamask/eth-sig-util@^5.0.0":
version "5.0.0"
resolved "https://registry.yarnpkg.com/@metamask/eth-sig-util/-/eth-sig-util-5.0.0.tgz#106364008029d30a231668a7133d6d0dae60adf6"
integrity sha512-wBOfkmPJoQG3c6kfxxJxQKfzxqSVtMxRjMD4C6xNtGU+TEuBacC3jIgjUUPlC5MTWu4XFo1Y8VWrmc1AlwAitA==
dependencies:
"@ethereumjs/util" "^8.0.0"
bn.js "4.11.8"
ethereum-cryptography "^1.1.2"
ethjs-util "^0.1.6"
tweetnacl "^1.0.3"
tweetnacl-util "^0.15.1"
"@metamask/eth-token-tracker@^4.0.0":
version "4.0.0"
resolved "https://registry.yarnpkg.com/@metamask/eth-token-tracker/-/eth-token-tracker-4.0.0.tgz#f3129855873a857ef675d4c28f532be684241b61"
@ -3555,7 +3567,7 @@
dependencies:
fast-deep-equal "^3.1.3"
"@metamask/utils@^3.0.1", "@metamask/utils@^3.1.0":
"@metamask/utils@^3.0.1", "@metamask/utils@^3.0.3", "@metamask/utils@^3.1.0":
version "3.1.0"
resolved "https://registry.yarnpkg.com/@metamask/utils/-/utils-3.1.0.tgz#ecfabe08e807bfcfb9ed1d7e727779a9382bee2c"
integrity sha512-zBGKgaqdKO9z2CoBSDzeE5KJUr5pM72YsumyUiklSyqMg/xL9vu7Z+E/pkRtwPmyi2YWXvq1rWfjugTt2+38nA==
@ -7855,6 +7867,11 @@ bn.js@4.11.6:
resolved "https://registry.yarnpkg.com/bn.js/-/bn.js-4.11.6.tgz#53344adb14617a13f6e8dd2ce28905d1c0ba3215"
integrity sha1-UzRK2xRhehP26N0s4okF0cC6MhU=
bn.js@4.11.8:
version "4.11.8"
resolved "https://registry.yarnpkg.com/bn.js/-/bn.js-4.11.8.tgz#2cde09eb5ee341f484746bb0309b3253b1b1442f"
integrity sha512-ItfYfPLkWHUjckQCk8xC+LwxgK8NYcXywGigJgSwOP8Y2iyWT4f2vsZnoOXTTbo+o5yXmIUJ4gn5538SO5S3gA==
bn.js@=2.0.4:
version "2.0.4"
resolved "https://registry.yarnpkg.com/bn.js/-/bn.js-2.0.4.tgz#220a7cd677f7f1bfa93627ff4193776fe7819480"
@ -12087,18 +12104,18 @@ eth-json-rpc-middleware@^8.1.0:
node-fetch "^2.6.7"
pify "^3.0.0"
eth-json-rpc-middleware@^9.0.0:
version "9.0.0"
resolved "https://registry.yarnpkg.com/eth-json-rpc-middleware/-/eth-json-rpc-middleware-9.0.0.tgz#8858713fa009e58758c34f7d8cdeb6179428ffd9"
integrity sha512-s/3BFGTjnby2CXAmWPXdNdWwmlygvRPsKRMYA3a5TJKCH8F/lVmVwGtckYRgfY3etpsEO8rMbkp6SQ+Ob1zCiQ==
eth-json-rpc-middleware@^9.0.1:
version "9.0.1"
resolved "https://registry.yarnpkg.com/eth-json-rpc-middleware/-/eth-json-rpc-middleware-9.0.1.tgz#193cb05174739fb736737bbbf992e13010c4b44e"
integrity sha512-5yLNjkedXA4LTIBzzU2f7aHFJqANPsc5qCdOZy6T2p7mlDLW+0q0YBQg6Lx4sHdamOWUnJwvm70qzPAqst5zSg==
dependencies:
"@metamask/eth-sig-util" "^5.0.0"
"@metamask/safe-event-emitter" "^2.0.0"
"@metamask/utils" "^3.0.1"
"@metamask/utils" "^3.0.3"
btoa "^1.2.1"
clone "^2.1.1"
eth-block-tracker "^5.0.1"
eth-rpc-errors "^4.0.3"
eth-sig-util "^1.4.2"
json-rpc-engine "^6.1.0"
json-stable-stringify "^1.0.1"
node-fetch "^2.6.7"