@metamask-previews/eth-json-rpc-middleware 21.0.0-preview-5a558267 → 21.0.0-preview-fe4c2215
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +0 -3
- package/dist/block-cache.cjs +32 -41
- package/dist/block-cache.cjs.map +1 -1
- package/dist/block-cache.d.cts +3 -12
- package/dist/block-cache.d.cts.map +1 -1
- package/dist/block-cache.d.mts +3 -12
- package/dist/block-cache.d.mts.map +1 -1
- package/dist/block-cache.mjs +32 -41
- package/dist/block-cache.mjs.map +1 -1
- package/dist/block-ref-rewrite.cjs +8 -12
- package/dist/block-ref-rewrite.cjs.map +1 -1
- package/dist/block-ref-rewrite.d.cts +3 -3
- package/dist/block-ref-rewrite.d.cts.map +1 -1
- package/dist/block-ref-rewrite.d.mts +3 -3
- package/dist/block-ref-rewrite.d.mts.map +1 -1
- package/dist/block-ref-rewrite.mjs +8 -12
- package/dist/block-ref-rewrite.mjs.map +1 -1
- package/dist/block-ref.cjs +10 -17
- package/dist/block-ref.cjs.map +1 -1
- package/dist/block-ref.d.cts +3 -12
- package/dist/block-ref.d.cts.map +1 -1
- package/dist/block-ref.d.mts +3 -12
- package/dist/block-ref.d.mts.map +1 -1
- package/dist/block-ref.mjs +10 -17
- package/dist/block-ref.mjs.map +1 -1
- package/dist/block-tracker-inspector.cjs +25 -28
- package/dist/block-tracker-inspector.cjs.map +1 -1
- package/dist/block-tracker-inspector.d.cts +3 -3
- package/dist/block-tracker-inspector.d.cts.map +1 -1
- package/dist/block-tracker-inspector.d.mts +3 -3
- package/dist/block-tracker-inspector.d.mts.map +1 -1
- package/dist/block-tracker-inspector.mjs +25 -28
- package/dist/block-tracker-inspector.mjs.map +1 -1
- package/dist/fetch.cjs +12 -8
- package/dist/fetch.cjs.map +1 -1
- package/dist/fetch.d.cts +3 -5
- package/dist/fetch.d.cts.map +1 -1
- package/dist/fetch.d.mts +3 -5
- package/dist/fetch.d.mts.map +1 -1
- package/dist/fetch.mjs +12 -8
- package/dist/fetch.mjs.map +1 -1
- package/dist/inflight-cache.cjs +45 -61
- package/dist/inflight-cache.cjs.map +1 -1
- package/dist/inflight-cache.d.cts +3 -12
- package/dist/inflight-cache.d.cts.map +1 -1
- package/dist/inflight-cache.d.mts +3 -12
- package/dist/inflight-cache.d.mts.map +1 -1
- package/dist/inflight-cache.mjs +45 -61
- package/dist/inflight-cache.mjs.map +1 -1
- package/dist/methods/wallet-request-execution-permissions.cjs +9 -20
- package/dist/methods/wallet-request-execution-permissions.cjs.map +1 -1
- package/dist/methods/wallet-request-execution-permissions.d.cts +3 -14
- package/dist/methods/wallet-request-execution-permissions.d.cts.map +1 -1
- package/dist/methods/wallet-request-execution-permissions.d.mts +3 -14
- package/dist/methods/wallet-request-execution-permissions.d.mts.map +1 -1
- package/dist/methods/wallet-request-execution-permissions.mjs +7 -18
- package/dist/methods/wallet-request-execution-permissions.mjs.map +1 -1
- package/dist/methods/wallet-revoke-execution-permission.cjs +11 -23
- package/dist/methods/wallet-revoke-execution-permission.cjs.map +1 -1
- package/dist/methods/wallet-revoke-execution-permission.d.cts +5 -19
- package/dist/methods/wallet-revoke-execution-permission.d.cts.map +1 -1
- package/dist/methods/wallet-revoke-execution-permission.d.mts +5 -19
- package/dist/methods/wallet-revoke-execution-permission.d.mts.map +1 -1
- package/dist/methods/wallet-revoke-execution-permission.mjs +8 -20
- package/dist/methods/wallet-revoke-execution-permission.mjs.map +1 -1
- package/dist/providerAsMiddleware.cjs +1 -18
- package/dist/providerAsMiddleware.cjs.map +1 -1
- package/dist/providerAsMiddleware.d.cts +3 -18
- package/dist/providerAsMiddleware.d.cts.map +1 -1
- package/dist/providerAsMiddleware.d.mts +3 -18
- package/dist/providerAsMiddleware.d.mts.map +1 -1
- package/dist/providerAsMiddleware.mjs +0 -16
- package/dist/providerAsMiddleware.mjs.map +1 -1
- package/dist/retryOnEmpty.cjs +11 -8
- package/dist/retryOnEmpty.cjs.map +1 -1
- package/dist/retryOnEmpty.d.cts +3 -3
- package/dist/retryOnEmpty.d.cts.map +1 -1
- package/dist/retryOnEmpty.d.mts +3 -3
- package/dist/retryOnEmpty.d.mts.map +1 -1
- package/dist/retryOnEmpty.mjs +11 -8
- package/dist/retryOnEmpty.mjs.map +1 -1
- package/dist/types.cjs.map +1 -1
- package/dist/types.d.cts +5 -0
- package/dist/types.d.cts.map +1 -1
- package/dist/types.d.mts +5 -0
- package/dist/types.d.mts.map +1 -1
- package/dist/types.mjs.map +1 -1
- package/dist/utils/error.cjs +0 -7
- package/dist/utils/error.cjs.map +1 -1
- package/dist/utils/error.d.cts +0 -7
- package/dist/utils/error.d.cts.map +1 -1
- package/dist/utils/error.d.mts +0 -7
- package/dist/utils/error.d.mts.map +1 -1
- package/dist/utils/error.mjs +0 -7
- package/dist/utils/error.mjs.map +1 -1
- package/dist/utils/normalize.cjs +2 -7
- package/dist/utils/normalize.cjs.map +1 -1
- package/dist/utils/normalize.d.cts.map +1 -1
- package/dist/utils/normalize.d.mts.map +1 -1
- package/dist/utils/normalize.mjs +2 -7
- package/dist/utils/normalize.mjs.map +1 -1
- package/dist/utils/validation.cjs +2 -34
- package/dist/utils/validation.cjs.map +1 -1
- package/dist/utils/validation.d.cts +3 -29
- package/dist/utils/validation.d.cts.map +1 -1
- package/dist/utils/validation.d.mts +3 -29
- package/dist/utils/validation.d.mts.map +1 -1
- package/dist/utils/validation.mjs +2 -34
- package/dist/utils/validation.mjs.map +1 -1
- package/dist/wallet.cjs +92 -199
- package/dist/wallet.cjs.map +1 -1
- package/dist/wallet.d.cts +13 -40
- package/dist/wallet.d.cts.map +1 -1
- package/dist/wallet.d.mts +13 -40
- package/dist/wallet.d.mts.map +1 -1
- package/dist/wallet.mjs +93 -200
- package/dist/wallet.mjs.map +1 -1
- package/package.json +1 -4
package/CHANGELOG.md
CHANGED
|
@@ -9,9 +9,6 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
9
9
|
|
|
10
10
|
### Changed
|
|
11
11
|
|
|
12
|
-
- **BREAKING:** Migrate to `JsonRpcEngineV2` ([#7065](https://github.com/MetaMask/core/pull/7065))
|
|
13
|
-
- Migrates all middleware from `JsonRpcEngine` to `JsonRpcEngineV2`.
|
|
14
|
-
- To continue using this package with the legacy `JsonRpcEngine`, use the `asLegacyMiddleware` backwards compatibility function.
|
|
15
12
|
- **BREAKING:** Use `InternalProvider` instead of `SafeEventEmitterProvider` ([#6796](https://github.com/MetaMask/core/pull/6796))
|
|
16
13
|
- Wherever a `SafeEventEmitterProvider` was expected, an `InternalProvider` is now expected instead.
|
|
17
14
|
- **BREAKING:** Stop retrying `undefined` results for methods that include a block tag parameter ([#7001](https://github.com/MetaMask/core/pull/7001))
|
package/dist/block-cache.cjs
CHANGED
|
@@ -1,18 +1,7 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
var __classPrivateFieldSet = (this && this.__classPrivateFieldSet) || function (receiver, state, value, kind, f) {
|
|
3
|
-
if (kind === "m") throw new TypeError("Private method is not writable");
|
|
4
|
-
if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a setter");
|
|
5
|
-
if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot write private member to an object whose class did not declare it");
|
|
6
|
-
return (kind === "a" ? f.call(receiver, value) : f ? f.value = value : state.set(receiver, value)), value;
|
|
7
|
-
};
|
|
8
|
-
var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (receiver, state, kind, f) {
|
|
9
|
-
if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a getter");
|
|
10
|
-
if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it");
|
|
11
|
-
return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
|
|
12
|
-
};
|
|
13
|
-
var _BlockCacheStrategy_cache;
|
|
14
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
15
3
|
exports.createBlockCacheMiddleware = void 0;
|
|
4
|
+
const json_rpc_engine_1 = require("@metamask/json-rpc-engine");
|
|
16
5
|
const logging_utils_1 = require("./logging-utils.cjs");
|
|
17
6
|
const cache_1 = require("./utils/cache.cjs");
|
|
18
7
|
const log = (0, logging_utils_1.createModuleLogger)(logging_utils_1.projectLogger, 'block-cache');
|
|
@@ -23,16 +12,15 @@ const emptyValues = [undefined, null, '\u003cnil\u003e'];
|
|
|
23
12
|
//
|
|
24
13
|
class BlockCacheStrategy {
|
|
25
14
|
constructor() {
|
|
26
|
-
|
|
27
|
-
__classPrivateFieldSet(this, _BlockCacheStrategy_cache, {}, "f");
|
|
15
|
+
this.cache = {};
|
|
28
16
|
}
|
|
29
17
|
getBlockCache(blockNumberHex) {
|
|
30
18
|
const blockNumber = Number.parseInt(blockNumberHex, 16);
|
|
31
|
-
let blockCache =
|
|
19
|
+
let blockCache = this.cache[blockNumber];
|
|
32
20
|
// create new cache if necesary
|
|
33
21
|
if (!blockCache) {
|
|
34
22
|
const newCache = {};
|
|
35
|
-
|
|
23
|
+
this.cache[blockNumber] = newCache;
|
|
36
24
|
blockCache = newCache;
|
|
37
25
|
}
|
|
38
26
|
return blockCache;
|
|
@@ -92,24 +80,18 @@ class BlockCacheStrategy {
|
|
|
92
80
|
clearBefore(oldBlockHex) {
|
|
93
81
|
const oldBlockNumber = Number.parseInt(oldBlockHex, 16);
|
|
94
82
|
// clear old caches
|
|
95
|
-
Object.keys(
|
|
83
|
+
Object.keys(this.cache)
|
|
96
84
|
.map(Number)
|
|
97
85
|
.filter((num) => num < oldBlockNumber)
|
|
98
|
-
.forEach((num) => delete
|
|
86
|
+
.forEach((num) => delete this.cache[num]);
|
|
99
87
|
}
|
|
100
88
|
}
|
|
101
|
-
_BlockCacheStrategy_cache = new WeakMap();
|
|
102
|
-
/**
|
|
103
|
-
* Creates a middleware that caches block-related requests.
|
|
104
|
-
*
|
|
105
|
-
* @param options - The options for the middleware.
|
|
106
|
-
* @param options.blockTracker - The block tracker to use.
|
|
107
|
-
* @returns The block cache middleware.
|
|
108
|
-
*/
|
|
109
89
|
function createBlockCacheMiddleware({ blockTracker, } = {}) {
|
|
90
|
+
// validate options
|
|
110
91
|
if (!blockTracker) {
|
|
111
92
|
throw new Error('createBlockCacheMiddleware - No PollingBlockTracker specified');
|
|
112
93
|
}
|
|
94
|
+
// create caching strategies
|
|
113
95
|
const blockCache = new BlockCacheStrategy();
|
|
114
96
|
const strategies = {
|
|
115
97
|
[cache_1.CacheStrategy.Permanent]: blockCache,
|
|
@@ -117,23 +99,28 @@ function createBlockCacheMiddleware({ blockTracker, } = {}) {
|
|
|
117
99
|
[cache_1.CacheStrategy.Fork]: blockCache,
|
|
118
100
|
[cache_1.CacheStrategy.Never]: undefined,
|
|
119
101
|
};
|
|
120
|
-
return async (
|
|
121
|
-
if
|
|
102
|
+
return (0, json_rpc_engine_1.createAsyncMiddleware)(async (req, res, next) => {
|
|
103
|
+
// allow cach to be skipped if so specified
|
|
104
|
+
if (req.skipCache) {
|
|
122
105
|
return next();
|
|
123
106
|
}
|
|
124
|
-
|
|
107
|
+
// check type and matching strategy
|
|
108
|
+
const type = (0, cache_1.cacheTypeForMethod)(req.method);
|
|
125
109
|
const strategy = strategies[type];
|
|
110
|
+
// If there's no strategy in place, pass it down the chain.
|
|
126
111
|
if (!strategy) {
|
|
127
112
|
return next();
|
|
128
113
|
}
|
|
129
|
-
|
|
114
|
+
// If the strategy can't cache this request, ignore it.
|
|
115
|
+
if (!strategy.canCacheRequest(req)) {
|
|
130
116
|
return next();
|
|
131
117
|
}
|
|
132
|
-
|
|
118
|
+
// get block reference (number or keyword)
|
|
119
|
+
const requestBlockTag = (0, cache_1.blockTagForRequest)(req);
|
|
133
120
|
const blockTag = requestBlockTag && typeof requestBlockTag === 'string'
|
|
134
121
|
? requestBlockTag
|
|
135
122
|
: 'latest';
|
|
136
|
-
log('blockTag = %o, req = %o', blockTag,
|
|
123
|
+
log('blockTag = %o, req = %o', blockTag, req);
|
|
137
124
|
// get exact block number
|
|
138
125
|
let requestedBlockNumber;
|
|
139
126
|
if (blockTag === 'earliest') {
|
|
@@ -141,6 +128,7 @@ function createBlockCacheMiddleware({ blockTracker, } = {}) {
|
|
|
141
128
|
requestedBlockNumber = '0x00';
|
|
142
129
|
}
|
|
143
130
|
else if (blockTag === 'latest') {
|
|
131
|
+
// fetch latest block number
|
|
144
132
|
log('Fetching latest block number to determine cache key');
|
|
145
133
|
const latestBlockNumber = await blockTracker.getLatestBlock();
|
|
146
134
|
// clear all cache before latest block
|
|
@@ -149,26 +137,29 @@ function createBlockCacheMiddleware({ blockTracker, } = {}) {
|
|
|
149
137
|
requestedBlockNumber = latestBlockNumber;
|
|
150
138
|
}
|
|
151
139
|
else {
|
|
152
|
-
//
|
|
140
|
+
// We have a hex number
|
|
153
141
|
requestedBlockNumber = blockTag;
|
|
154
142
|
}
|
|
155
143
|
// end on a hit, continue on a miss
|
|
156
|
-
const cacheResult = await strategy.get(
|
|
144
|
+
const cacheResult = await strategy.get(req, requestedBlockNumber);
|
|
157
145
|
if (cacheResult === undefined) {
|
|
158
146
|
// cache miss
|
|
159
147
|
// wait for other middleware to handle request
|
|
160
148
|
log('No cache stored under block number %o, carrying request forward', requestedBlockNumber);
|
|
161
|
-
|
|
149
|
+
await next();
|
|
162
150
|
// add result to cache
|
|
163
151
|
// it's safe to cast res.result as Block, due to runtime type checks
|
|
164
152
|
// performed when strategy.set is called
|
|
165
|
-
log('Populating cache with',
|
|
166
|
-
await strategy.set(
|
|
167
|
-
return result;
|
|
153
|
+
log('Populating cache with', res);
|
|
154
|
+
await strategy.set(req, requestedBlockNumber, res.result);
|
|
168
155
|
}
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
156
|
+
else {
|
|
157
|
+
// fill in result from cache
|
|
158
|
+
log('Cache hit, reusing cache result stored under block number %o', requestedBlockNumber);
|
|
159
|
+
res.result = cacheResult;
|
|
160
|
+
}
|
|
161
|
+
return undefined;
|
|
162
|
+
});
|
|
172
163
|
}
|
|
173
164
|
exports.createBlockCacheMiddleware = createBlockCacheMiddleware;
|
|
174
165
|
//# sourceMappingURL=block-cache.cjs.map
|
package/dist/block-cache.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"block-cache.cjs","sourceRoot":"","sources":["../src/block-cache.ts"],"names":[],"mappings":"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","sourcesContent":["import type { PollingBlockTracker } from '@metamask/eth-block-tracker';\nimport type {\n JsonRpcMiddleware,\n MiddlewareContext,\n} from '@metamask/json-rpc-engine/v2';\nimport type { Json, JsonRpcRequest } from '@metamask/utils';\n\nimport { projectLogger, createModuleLogger } from './logging-utils';\nimport type {\n Block,\n BlockCache,\n // eslint-disable-next-line @typescript-eslint/no-shadow\n Cache,\n} from './types';\nimport {\n cacheIdentifierForRequest,\n blockTagForRequest,\n cacheTypeForMethod,\n canCache,\n CacheStrategy,\n} from './utils/cache';\n\nconst log = createModuleLogger(projectLogger, 'block-cache');\n// `<nil>` comes from https://github.com/ethereum/go-ethereum/issues/16925\nconst emptyValues: unknown[] = [undefined, null, '\\u003cnil\\u003e'];\n\ntype BlockCacheMiddlewareOptions = {\n blockTracker?: PollingBlockTracker;\n};\n\n//\n// Cache Strategies\n//\n\nclass BlockCacheStrategy {\n #cache: Cache;\n\n constructor() {\n this.#cache = {};\n }\n\n getBlockCache(blockNumberHex: string): BlockCache {\n const blockNumber: number = Number.parseInt(blockNumberHex, 16);\n let blockCache: BlockCache = this.#cache[blockNumber];\n // create new cache if necesary\n if (!blockCache) {\n const newCache: BlockCache = {};\n this.#cache[blockNumber] = newCache;\n blockCache = newCache;\n }\n return blockCache;\n }\n\n async get(\n request: JsonRpcRequest,\n requestedBlockNumber: string,\n ): Promise<Block | undefined> {\n // lookup block cache\n const blockCache: BlockCache = this.getBlockCache(requestedBlockNumber);\n // lookup payload in block cache\n const identifier: string | null = cacheIdentifierForRequest(request, true);\n return identifier ? blockCache[identifier] : undefined;\n }\n\n async set(\n request: JsonRpcRequest,\n requestedBlockNumber: string,\n result: Block,\n ): Promise<void> {\n // check if we can cached this result\n const canCacheResult: boolean = this.canCacheResult(request, result);\n if (!canCacheResult) {\n return;\n }\n\n // set the value in the cache\n const identifier: string | null = cacheIdentifierForRequest(request, true);\n if (!identifier) {\n return;\n }\n const blockCache: BlockCache = this.getBlockCache(requestedBlockNumber);\n blockCache[identifier] = result;\n }\n\n canCacheRequest(request: JsonRpcRequest): boolean {\n // check request method\n if (!canCache(request.method)) {\n return false;\n }\n // check blockTag\n const blockTag = blockTagForRequest(request);\n\n if (blockTag === 'pending') {\n return false;\n }\n // can be cached\n return true;\n }\n\n canCacheResult(request: JsonRpcRequest, result: Block): boolean {\n // never cache empty values (e.g. undefined)\n if (emptyValues.includes(result)) {\n return false;\n }\n\n // check if transactions have block reference before caching\n if (\n request.method &&\n ['eth_getTransactionByHash', 'eth_getTransactionReceipt'].includes(\n request.method,\n )\n ) {\n if (\n !result?.blockHash ||\n result.blockHash ===\n '0x0000000000000000000000000000000000000000000000000000000000000000'\n ) {\n return false;\n }\n }\n // otherwise true\n return true;\n }\n\n // removes all block caches with block number lower than `oldBlockHex`\n clearBefore(oldBlockHex: string): void {\n const oldBlockNumber: number = Number.parseInt(oldBlockHex, 16);\n // clear old caches\n Object.keys(this.#cache)\n .map(Number)\n .filter((num) => num < oldBlockNumber)\n .forEach((num) => delete this.#cache[num]);\n }\n}\n\n/**\n * Creates a middleware that caches block-related requests.\n *\n * @param options - The options for the middleware.\n * @param options.blockTracker - The block tracker to use.\n * @returns The block cache middleware.\n */\nexport function createBlockCacheMiddleware({\n blockTracker,\n}: BlockCacheMiddlewareOptions = {}): JsonRpcMiddleware<\n JsonRpcRequest,\n Json,\n MiddlewareContext<{ skipCache?: boolean }>\n> {\n if (!blockTracker) {\n throw new Error(\n 'createBlockCacheMiddleware - No PollingBlockTracker specified',\n );\n }\n\n const blockCache: BlockCacheStrategy = new BlockCacheStrategy();\n const strategies: Record<CacheStrategy, BlockCacheStrategy | undefined> = {\n [CacheStrategy.Permanent]: blockCache,\n [CacheStrategy.Block]: blockCache,\n [CacheStrategy.Fork]: blockCache,\n [CacheStrategy.Never]: undefined,\n };\n\n return async ({ request, next, context }) => {\n if (context.get('skipCache')) {\n return next();\n }\n\n const type = cacheTypeForMethod(request.method);\n const strategy = strategies[type];\n if (!strategy) {\n return next();\n }\n\n if (!strategy.canCacheRequest(request)) {\n return next();\n }\n\n const requestBlockTag = blockTagForRequest(request);\n const blockTag =\n requestBlockTag && typeof requestBlockTag === 'string'\n ? requestBlockTag\n : 'latest';\n\n log('blockTag = %o, req = %o', blockTag, request);\n\n // get exact block number\n let requestedBlockNumber: string;\n if (blockTag === 'earliest') {\n // this just exists for symmetry with \"latest\"\n requestedBlockNumber = '0x00';\n } else if (blockTag === 'latest') {\n log('Fetching latest block number to determine cache key');\n const latestBlockNumber = await blockTracker.getLatestBlock();\n\n // clear all cache before latest block\n log(\n 'Clearing values stored under block numbers before %o',\n latestBlockNumber,\n );\n blockCache.clearBefore(latestBlockNumber);\n requestedBlockNumber = latestBlockNumber;\n } else {\n // we have a hex number\n requestedBlockNumber = blockTag;\n }\n\n // end on a hit, continue on a miss\n const cacheResult = await strategy.get(request, requestedBlockNumber);\n if (cacheResult === undefined) {\n // cache miss\n // wait for other middleware to handle request\n log(\n 'No cache stored under block number %o, carrying request forward',\n requestedBlockNumber,\n );\n const result = await next();\n\n // add result to cache\n // it's safe to cast res.result as Block, due to runtime type checks\n // performed when strategy.set is called\n log('Populating cache with', result);\n await strategy.set(request, requestedBlockNumber, result as Block);\n return result;\n }\n log(\n 'Cache hit, reusing cache result stored under block number %o',\n requestedBlockNumber,\n );\n return cacheResult;\n };\n}\n"]}
|
|
1
|
+
{"version":3,"file":"block-cache.cjs","sourceRoot":"","sources":["../src/block-cache.ts"],"names":[],"mappings":"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","sourcesContent":["import type { PollingBlockTracker } from '@metamask/eth-block-tracker';\nimport { createAsyncMiddleware } from '@metamask/json-rpc-engine';\nimport type { Json, JsonRpcParams, JsonRpcRequest } from '@metamask/utils';\n\nimport { projectLogger, createModuleLogger } from './logging-utils';\nimport type {\n Block,\n BlockCache,\n // eslint-disable-next-line @typescript-eslint/no-shadow\n Cache,\n JsonRpcCacheMiddleware,\n JsonRpcRequestToCache,\n} from './types';\nimport {\n cacheIdentifierForRequest,\n blockTagForRequest,\n cacheTypeForMethod,\n canCache,\n CacheStrategy,\n} from './utils/cache';\n\nconst log = createModuleLogger(projectLogger, 'block-cache');\n// `<nil>` comes from https://github.com/ethereum/go-ethereum/issues/16925\nconst emptyValues = [undefined, null, '\\u003cnil\\u003e'];\n\ntype BlockCacheMiddlewareOptions = {\n blockTracker?: PollingBlockTracker;\n};\n\n//\n// Cache Strategies\n//\n\nclass BlockCacheStrategy {\n private cache: Cache;\n\n constructor() {\n this.cache = {};\n }\n\n getBlockCache(blockNumberHex: string): BlockCache {\n const blockNumber: number = Number.parseInt(blockNumberHex, 16);\n let blockCache: BlockCache = this.cache[blockNumber];\n // create new cache if necesary\n if (!blockCache) {\n const newCache: BlockCache = {};\n this.cache[blockNumber] = newCache;\n blockCache = newCache;\n }\n return blockCache;\n }\n\n async get(\n request: JsonRpcRequest,\n requestedBlockNumber: string,\n ): Promise<Block | undefined> {\n // lookup block cache\n const blockCache: BlockCache = this.getBlockCache(requestedBlockNumber);\n // lookup payload in block cache\n const identifier: string | null = cacheIdentifierForRequest(request, true);\n return identifier ? blockCache[identifier] : undefined;\n }\n\n async set(\n request: JsonRpcRequest,\n requestedBlockNumber: string,\n result: Block,\n ): Promise<void> {\n // check if we can cached this result\n const canCacheResult: boolean = this.canCacheResult(request, result);\n if (!canCacheResult) {\n return;\n }\n\n // set the value in the cache\n const identifier: string | null = cacheIdentifierForRequest(request, true);\n if (!identifier) {\n return;\n }\n const blockCache: BlockCache = this.getBlockCache(requestedBlockNumber);\n blockCache[identifier] = result;\n }\n\n canCacheRequest(request: JsonRpcRequest): boolean {\n // check request method\n if (!canCache(request.method)) {\n return false;\n }\n // check blockTag\n const blockTag = blockTagForRequest(request);\n\n if (blockTag === 'pending') {\n return false;\n }\n // can be cached\n return true;\n }\n\n canCacheResult(request: JsonRpcRequest, result: Block): boolean {\n // never cache empty values (e.g. undefined)\n if (emptyValues.includes(result as any)) {\n return false;\n }\n\n // check if transactions have block reference before caching\n if (\n request.method &&\n ['eth_getTransactionByHash', 'eth_getTransactionReceipt'].includes(\n request.method,\n )\n ) {\n if (\n !result?.blockHash ||\n result.blockHash ===\n '0x0000000000000000000000000000000000000000000000000000000000000000'\n ) {\n return false;\n }\n }\n // otherwise true\n return true;\n }\n\n // removes all block caches with block number lower than `oldBlockHex`\n clearBefore(oldBlockHex: string): void {\n const oldBlockNumber: number = Number.parseInt(oldBlockHex, 16);\n // clear old caches\n Object.keys(this.cache)\n .map(Number)\n .filter((num) => num < oldBlockNumber)\n .forEach((num) => delete this.cache[num]);\n }\n}\n\nexport function createBlockCacheMiddleware({\n blockTracker,\n}: BlockCacheMiddlewareOptions = {}): JsonRpcCacheMiddleware<\n JsonRpcParams,\n Json\n> {\n // validate options\n if (!blockTracker) {\n throw new Error(\n 'createBlockCacheMiddleware - No PollingBlockTracker specified',\n );\n }\n\n // create caching strategies\n const blockCache: BlockCacheStrategy = new BlockCacheStrategy();\n const strategies: Record<CacheStrategy, BlockCacheStrategy | undefined> = {\n [CacheStrategy.Permanent]: blockCache,\n [CacheStrategy.Block]: blockCache,\n [CacheStrategy.Fork]: blockCache,\n [CacheStrategy.Never]: undefined,\n };\n\n return createAsyncMiddleware(\n async (req: JsonRpcRequestToCache<JsonRpcParams>, res, next) => {\n // allow cach to be skipped if so specified\n if (req.skipCache) {\n return next();\n }\n // check type and matching strategy\n const type = cacheTypeForMethod(req.method);\n const strategy = strategies[type];\n // If there's no strategy in place, pass it down the chain.\n if (!strategy) {\n return next();\n }\n\n // If the strategy can't cache this request, ignore it.\n if (!strategy.canCacheRequest(req)) {\n return next();\n }\n\n // get block reference (number or keyword)\n const requestBlockTag = blockTagForRequest(req);\n const blockTag =\n requestBlockTag && typeof requestBlockTag === 'string'\n ? requestBlockTag\n : 'latest';\n\n log('blockTag = %o, req = %o', blockTag, req);\n\n // get exact block number\n let requestedBlockNumber: string;\n if (blockTag === 'earliest') {\n // this just exists for symmetry with \"latest\"\n requestedBlockNumber = '0x00';\n } else if (blockTag === 'latest') {\n // fetch latest block number\n log('Fetching latest block number to determine cache key');\n const latestBlockNumber = await blockTracker.getLatestBlock();\n // clear all cache before latest block\n log(\n 'Clearing values stored under block numbers before %o',\n latestBlockNumber,\n );\n blockCache.clearBefore(latestBlockNumber);\n requestedBlockNumber = latestBlockNumber;\n } else {\n // We have a hex number\n requestedBlockNumber = blockTag;\n }\n // end on a hit, continue on a miss\n const cacheResult: Block | undefined = await strategy.get(\n req,\n requestedBlockNumber,\n );\n if (cacheResult === undefined) {\n // cache miss\n // wait for other middleware to handle request\n log(\n 'No cache stored under block number %o, carrying request forward',\n requestedBlockNumber,\n );\n await next();\n\n // add result to cache\n // it's safe to cast res.result as Block, due to runtime type checks\n // performed when strategy.set is called\n log('Populating cache with', res);\n await strategy.set(req, requestedBlockNumber, res.result as Block);\n } else {\n // fill in result from cache\n log(\n 'Cache hit, reusing cache result stored under block number %o',\n requestedBlockNumber,\n );\n res.result = cacheResult;\n }\n return undefined;\n },\n );\n}\n"]}
|
package/dist/block-cache.d.cts
CHANGED
|
@@ -1,18 +1,9 @@
|
|
|
1
1
|
import type { PollingBlockTracker } from "@metamask/eth-block-tracker";
|
|
2
|
-
import type {
|
|
3
|
-
import type {
|
|
2
|
+
import type { Json, JsonRpcParams } from "@metamask/utils";
|
|
3
|
+
import type { JsonRpcCacheMiddleware } from "./types.cjs";
|
|
4
4
|
type BlockCacheMiddlewareOptions = {
|
|
5
5
|
blockTracker?: PollingBlockTracker;
|
|
6
6
|
};
|
|
7
|
-
|
|
8
|
-
* Creates a middleware that caches block-related requests.
|
|
9
|
-
*
|
|
10
|
-
* @param options - The options for the middleware.
|
|
11
|
-
* @param options.blockTracker - The block tracker to use.
|
|
12
|
-
* @returns The block cache middleware.
|
|
13
|
-
*/
|
|
14
|
-
export declare function createBlockCacheMiddleware({ blockTracker, }?: BlockCacheMiddlewareOptions): JsonRpcMiddleware<JsonRpcRequest, Json, MiddlewareContext<{
|
|
15
|
-
skipCache?: boolean;
|
|
16
|
-
}>>;
|
|
7
|
+
export declare function createBlockCacheMiddleware({ blockTracker, }?: BlockCacheMiddlewareOptions): JsonRpcCacheMiddleware<JsonRpcParams, Json>;
|
|
17
8
|
export {};
|
|
18
9
|
//# sourceMappingURL=block-cache.d.cts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"block-cache.d.cts","sourceRoot":"","sources":["../src/block-cache.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,mBAAmB,EAAE,oCAAoC;
|
|
1
|
+
{"version":3,"file":"block-cache.d.cts","sourceRoot":"","sources":["../src/block-cache.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,mBAAmB,EAAE,oCAAoC;AAEvE,OAAO,KAAK,EAAE,IAAI,EAAE,aAAa,EAAkB,wBAAwB;AAG3E,OAAO,KAAK,EAKV,sBAAsB,EAEvB,oBAAgB;AAajB,KAAK,2BAA2B,GAAG;IACjC,YAAY,CAAC,EAAE,mBAAmB,CAAC;CACpC,CAAC;AA2GF,wBAAgB,0BAA0B,CAAC,EACzC,YAAY,GACb,GAAE,2BAAgC,GAAG,sBAAsB,CAC1D,aAAa,EACb,IAAI,CACL,CA+FA"}
|
package/dist/block-cache.d.mts
CHANGED
|
@@ -1,18 +1,9 @@
|
|
|
1
1
|
import type { PollingBlockTracker } from "@metamask/eth-block-tracker";
|
|
2
|
-
import type {
|
|
3
|
-
import type {
|
|
2
|
+
import type { Json, JsonRpcParams } from "@metamask/utils";
|
|
3
|
+
import type { JsonRpcCacheMiddleware } from "./types.mjs";
|
|
4
4
|
type BlockCacheMiddlewareOptions = {
|
|
5
5
|
blockTracker?: PollingBlockTracker;
|
|
6
6
|
};
|
|
7
|
-
|
|
8
|
-
* Creates a middleware that caches block-related requests.
|
|
9
|
-
*
|
|
10
|
-
* @param options - The options for the middleware.
|
|
11
|
-
* @param options.blockTracker - The block tracker to use.
|
|
12
|
-
* @returns The block cache middleware.
|
|
13
|
-
*/
|
|
14
|
-
export declare function createBlockCacheMiddleware({ blockTracker, }?: BlockCacheMiddlewareOptions): JsonRpcMiddleware<JsonRpcRequest, Json, MiddlewareContext<{
|
|
15
|
-
skipCache?: boolean;
|
|
16
|
-
}>>;
|
|
7
|
+
export declare function createBlockCacheMiddleware({ blockTracker, }?: BlockCacheMiddlewareOptions): JsonRpcCacheMiddleware<JsonRpcParams, Json>;
|
|
17
8
|
export {};
|
|
18
9
|
//# sourceMappingURL=block-cache.d.mts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"block-cache.d.mts","sourceRoot":"","sources":["../src/block-cache.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,mBAAmB,EAAE,oCAAoC;
|
|
1
|
+
{"version":3,"file":"block-cache.d.mts","sourceRoot":"","sources":["../src/block-cache.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,mBAAmB,EAAE,oCAAoC;AAEvE,OAAO,KAAK,EAAE,IAAI,EAAE,aAAa,EAAkB,wBAAwB;AAG3E,OAAO,KAAK,EAKV,sBAAsB,EAEvB,oBAAgB;AAajB,KAAK,2BAA2B,GAAG;IACjC,YAAY,CAAC,EAAE,mBAAmB,CAAC;CACpC,CAAC;AA2GF,wBAAgB,0BAA0B,CAAC,EACzC,YAAY,GACb,GAAE,2BAAgC,GAAG,sBAAsB,CAC1D,aAAa,EACb,IAAI,CACL,CA+FA"}
|
package/dist/block-cache.mjs
CHANGED
|
@@ -1,15 +1,4 @@
|
|
|
1
|
-
|
|
2
|
-
if (kind === "m") throw new TypeError("Private method is not writable");
|
|
3
|
-
if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a setter");
|
|
4
|
-
if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot write private member to an object whose class did not declare it");
|
|
5
|
-
return (kind === "a" ? f.call(receiver, value) : f ? f.value = value : state.set(receiver, value)), value;
|
|
6
|
-
};
|
|
7
|
-
var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (receiver, state, kind, f) {
|
|
8
|
-
if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a getter");
|
|
9
|
-
if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it");
|
|
10
|
-
return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
|
|
11
|
-
};
|
|
12
|
-
var _BlockCacheStrategy_cache;
|
|
1
|
+
import { createAsyncMiddleware } from "@metamask/json-rpc-engine";
|
|
13
2
|
import { projectLogger, createModuleLogger } from "./logging-utils.mjs";
|
|
14
3
|
import { cacheIdentifierForRequest, blockTagForRequest, cacheTypeForMethod, canCache, CacheStrategy } from "./utils/cache.mjs";
|
|
15
4
|
const log = createModuleLogger(projectLogger, 'block-cache');
|
|
@@ -20,16 +9,15 @@ const emptyValues = [undefined, null, '\u003cnil\u003e'];
|
|
|
20
9
|
//
|
|
21
10
|
class BlockCacheStrategy {
|
|
22
11
|
constructor() {
|
|
23
|
-
|
|
24
|
-
__classPrivateFieldSet(this, _BlockCacheStrategy_cache, {}, "f");
|
|
12
|
+
this.cache = {};
|
|
25
13
|
}
|
|
26
14
|
getBlockCache(blockNumberHex) {
|
|
27
15
|
const blockNumber = Number.parseInt(blockNumberHex, 16);
|
|
28
|
-
let blockCache =
|
|
16
|
+
let blockCache = this.cache[blockNumber];
|
|
29
17
|
// create new cache if necesary
|
|
30
18
|
if (!blockCache) {
|
|
31
19
|
const newCache = {};
|
|
32
|
-
|
|
20
|
+
this.cache[blockNumber] = newCache;
|
|
33
21
|
blockCache = newCache;
|
|
34
22
|
}
|
|
35
23
|
return blockCache;
|
|
@@ -89,24 +77,18 @@ class BlockCacheStrategy {
|
|
|
89
77
|
clearBefore(oldBlockHex) {
|
|
90
78
|
const oldBlockNumber = Number.parseInt(oldBlockHex, 16);
|
|
91
79
|
// clear old caches
|
|
92
|
-
Object.keys(
|
|
80
|
+
Object.keys(this.cache)
|
|
93
81
|
.map(Number)
|
|
94
82
|
.filter((num) => num < oldBlockNumber)
|
|
95
|
-
.forEach((num) => delete
|
|
83
|
+
.forEach((num) => delete this.cache[num]);
|
|
96
84
|
}
|
|
97
85
|
}
|
|
98
|
-
_BlockCacheStrategy_cache = new WeakMap();
|
|
99
|
-
/**
|
|
100
|
-
* Creates a middleware that caches block-related requests.
|
|
101
|
-
*
|
|
102
|
-
* @param options - The options for the middleware.
|
|
103
|
-
* @param options.blockTracker - The block tracker to use.
|
|
104
|
-
* @returns The block cache middleware.
|
|
105
|
-
*/
|
|
106
86
|
export function createBlockCacheMiddleware({ blockTracker, } = {}) {
|
|
87
|
+
// validate options
|
|
107
88
|
if (!blockTracker) {
|
|
108
89
|
throw new Error('createBlockCacheMiddleware - No PollingBlockTracker specified');
|
|
109
90
|
}
|
|
91
|
+
// create caching strategies
|
|
110
92
|
const blockCache = new BlockCacheStrategy();
|
|
111
93
|
const strategies = {
|
|
112
94
|
[CacheStrategy.Permanent]: blockCache,
|
|
@@ -114,23 +96,28 @@ export function createBlockCacheMiddleware({ blockTracker, } = {}) {
|
|
|
114
96
|
[CacheStrategy.Fork]: blockCache,
|
|
115
97
|
[CacheStrategy.Never]: undefined,
|
|
116
98
|
};
|
|
117
|
-
return async (
|
|
118
|
-
if
|
|
99
|
+
return createAsyncMiddleware(async (req, res, next) => {
|
|
100
|
+
// allow cach to be skipped if so specified
|
|
101
|
+
if (req.skipCache) {
|
|
119
102
|
return next();
|
|
120
103
|
}
|
|
121
|
-
|
|
104
|
+
// check type and matching strategy
|
|
105
|
+
const type = cacheTypeForMethod(req.method);
|
|
122
106
|
const strategy = strategies[type];
|
|
107
|
+
// If there's no strategy in place, pass it down the chain.
|
|
123
108
|
if (!strategy) {
|
|
124
109
|
return next();
|
|
125
110
|
}
|
|
126
|
-
|
|
111
|
+
// If the strategy can't cache this request, ignore it.
|
|
112
|
+
if (!strategy.canCacheRequest(req)) {
|
|
127
113
|
return next();
|
|
128
114
|
}
|
|
129
|
-
|
|
115
|
+
// get block reference (number or keyword)
|
|
116
|
+
const requestBlockTag = blockTagForRequest(req);
|
|
130
117
|
const blockTag = requestBlockTag && typeof requestBlockTag === 'string'
|
|
131
118
|
? requestBlockTag
|
|
132
119
|
: 'latest';
|
|
133
|
-
log('blockTag = %o, req = %o', blockTag,
|
|
120
|
+
log('blockTag = %o, req = %o', blockTag, req);
|
|
134
121
|
// get exact block number
|
|
135
122
|
let requestedBlockNumber;
|
|
136
123
|
if (blockTag === 'earliest') {
|
|
@@ -138,6 +125,7 @@ export function createBlockCacheMiddleware({ blockTracker, } = {}) {
|
|
|
138
125
|
requestedBlockNumber = '0x00';
|
|
139
126
|
}
|
|
140
127
|
else if (blockTag === 'latest') {
|
|
128
|
+
// fetch latest block number
|
|
141
129
|
log('Fetching latest block number to determine cache key');
|
|
142
130
|
const latestBlockNumber = await blockTracker.getLatestBlock();
|
|
143
131
|
// clear all cache before latest block
|
|
@@ -146,25 +134,28 @@ export function createBlockCacheMiddleware({ blockTracker, } = {}) {
|
|
|
146
134
|
requestedBlockNumber = latestBlockNumber;
|
|
147
135
|
}
|
|
148
136
|
else {
|
|
149
|
-
//
|
|
137
|
+
// We have a hex number
|
|
150
138
|
requestedBlockNumber = blockTag;
|
|
151
139
|
}
|
|
152
140
|
// end on a hit, continue on a miss
|
|
153
|
-
const cacheResult = await strategy.get(
|
|
141
|
+
const cacheResult = await strategy.get(req, requestedBlockNumber);
|
|
154
142
|
if (cacheResult === undefined) {
|
|
155
143
|
// cache miss
|
|
156
144
|
// wait for other middleware to handle request
|
|
157
145
|
log('No cache stored under block number %o, carrying request forward', requestedBlockNumber);
|
|
158
|
-
|
|
146
|
+
await next();
|
|
159
147
|
// add result to cache
|
|
160
148
|
// it's safe to cast res.result as Block, due to runtime type checks
|
|
161
149
|
// performed when strategy.set is called
|
|
162
|
-
log('Populating cache with',
|
|
163
|
-
await strategy.set(
|
|
164
|
-
return result;
|
|
150
|
+
log('Populating cache with', res);
|
|
151
|
+
await strategy.set(req, requestedBlockNumber, res.result);
|
|
165
152
|
}
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
153
|
+
else {
|
|
154
|
+
// fill in result from cache
|
|
155
|
+
log('Cache hit, reusing cache result stored under block number %o', requestedBlockNumber);
|
|
156
|
+
res.result = cacheResult;
|
|
157
|
+
}
|
|
158
|
+
return undefined;
|
|
159
|
+
});
|
|
169
160
|
}
|
|
170
161
|
//# sourceMappingURL=block-cache.mjs.map
|
package/dist/block-cache.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"block-cache.mjs","sourceRoot":"","sources":["../src/block-cache.ts"],"names":[],"mappings":"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","sourcesContent":["import type { PollingBlockTracker } from '@metamask/eth-block-tracker';\nimport type {\n JsonRpcMiddleware,\n MiddlewareContext,\n} from '@metamask/json-rpc-engine/v2';\nimport type { Json, JsonRpcRequest } from '@metamask/utils';\n\nimport { projectLogger, createModuleLogger } from './logging-utils';\nimport type {\n Block,\n BlockCache,\n // eslint-disable-next-line @typescript-eslint/no-shadow\n Cache,\n} from './types';\nimport {\n cacheIdentifierForRequest,\n blockTagForRequest,\n cacheTypeForMethod,\n canCache,\n CacheStrategy,\n} from './utils/cache';\n\nconst log = createModuleLogger(projectLogger, 'block-cache');\n// `<nil>` comes from https://github.com/ethereum/go-ethereum/issues/16925\nconst emptyValues: unknown[] = [undefined, null, '\\u003cnil\\u003e'];\n\ntype BlockCacheMiddlewareOptions = {\n blockTracker?: PollingBlockTracker;\n};\n\n//\n// Cache Strategies\n//\n\nclass BlockCacheStrategy {\n #cache: Cache;\n\n constructor() {\n this.#cache = {};\n }\n\n getBlockCache(blockNumberHex: string): BlockCache {\n const blockNumber: number = Number.parseInt(blockNumberHex, 16);\n let blockCache: BlockCache = this.#cache[blockNumber];\n // create new cache if necesary\n if (!blockCache) {\n const newCache: BlockCache = {};\n this.#cache[blockNumber] = newCache;\n blockCache = newCache;\n }\n return blockCache;\n }\n\n async get(\n request: JsonRpcRequest,\n requestedBlockNumber: string,\n ): Promise<Block | undefined> {\n // lookup block cache\n const blockCache: BlockCache = this.getBlockCache(requestedBlockNumber);\n // lookup payload in block cache\n const identifier: string | null = cacheIdentifierForRequest(request, true);\n return identifier ? blockCache[identifier] : undefined;\n }\n\n async set(\n request: JsonRpcRequest,\n requestedBlockNumber: string,\n result: Block,\n ): Promise<void> {\n // check if we can cached this result\n const canCacheResult: boolean = this.canCacheResult(request, result);\n if (!canCacheResult) {\n return;\n }\n\n // set the value in the cache\n const identifier: string | null = cacheIdentifierForRequest(request, true);\n if (!identifier) {\n return;\n }\n const blockCache: BlockCache = this.getBlockCache(requestedBlockNumber);\n blockCache[identifier] = result;\n }\n\n canCacheRequest(request: JsonRpcRequest): boolean {\n // check request method\n if (!canCache(request.method)) {\n return false;\n }\n // check blockTag\n const blockTag = blockTagForRequest(request);\n\n if (blockTag === 'pending') {\n return false;\n }\n // can be cached\n return true;\n }\n\n canCacheResult(request: JsonRpcRequest, result: Block): boolean {\n // never cache empty values (e.g. undefined)\n if (emptyValues.includes(result)) {\n return false;\n }\n\n // check if transactions have block reference before caching\n if (\n request.method &&\n ['eth_getTransactionByHash', 'eth_getTransactionReceipt'].includes(\n request.method,\n )\n ) {\n if (\n !result?.blockHash ||\n result.blockHash ===\n '0x0000000000000000000000000000000000000000000000000000000000000000'\n ) {\n return false;\n }\n }\n // otherwise true\n return true;\n }\n\n // removes all block caches with block number lower than `oldBlockHex`\n clearBefore(oldBlockHex: string): void {\n const oldBlockNumber: number = Number.parseInt(oldBlockHex, 16);\n // clear old caches\n Object.keys(this.#cache)\n .map(Number)\n .filter((num) => num < oldBlockNumber)\n .forEach((num) => delete this.#cache[num]);\n }\n}\n\n/**\n * Creates a middleware that caches block-related requests.\n *\n * @param options - The options for the middleware.\n * @param options.blockTracker - The block tracker to use.\n * @returns The block cache middleware.\n */\nexport function createBlockCacheMiddleware({\n blockTracker,\n}: BlockCacheMiddlewareOptions = {}): JsonRpcMiddleware<\n JsonRpcRequest,\n Json,\n MiddlewareContext<{ skipCache?: boolean }>\n> {\n if (!blockTracker) {\n throw new Error(\n 'createBlockCacheMiddleware - No PollingBlockTracker specified',\n );\n }\n\n const blockCache: BlockCacheStrategy = new BlockCacheStrategy();\n const strategies: Record<CacheStrategy, BlockCacheStrategy | undefined> = {\n [CacheStrategy.Permanent]: blockCache,\n [CacheStrategy.Block]: blockCache,\n [CacheStrategy.Fork]: blockCache,\n [CacheStrategy.Never]: undefined,\n };\n\n return async ({ request, next, context }) => {\n if (context.get('skipCache')) {\n return next();\n }\n\n const type = cacheTypeForMethod(request.method);\n const strategy = strategies[type];\n if (!strategy) {\n return next();\n }\n\n if (!strategy.canCacheRequest(request)) {\n return next();\n }\n\n const requestBlockTag = blockTagForRequest(request);\n const blockTag =\n requestBlockTag && typeof requestBlockTag === 'string'\n ? requestBlockTag\n : 'latest';\n\n log('blockTag = %o, req = %o', blockTag, request);\n\n // get exact block number\n let requestedBlockNumber: string;\n if (blockTag === 'earliest') {\n // this just exists for symmetry with \"latest\"\n requestedBlockNumber = '0x00';\n } else if (blockTag === 'latest') {\n log('Fetching latest block number to determine cache key');\n const latestBlockNumber = await blockTracker.getLatestBlock();\n\n // clear all cache before latest block\n log(\n 'Clearing values stored under block numbers before %o',\n latestBlockNumber,\n );\n blockCache.clearBefore(latestBlockNumber);\n requestedBlockNumber = latestBlockNumber;\n } else {\n // we have a hex number\n requestedBlockNumber = blockTag;\n }\n\n // end on a hit, continue on a miss\n const cacheResult = await strategy.get(request, requestedBlockNumber);\n if (cacheResult === undefined) {\n // cache miss\n // wait for other middleware to handle request\n log(\n 'No cache stored under block number %o, carrying request forward',\n requestedBlockNumber,\n );\n const result = await next();\n\n // add result to cache\n // it's safe to cast res.result as Block, due to runtime type checks\n // performed when strategy.set is called\n log('Populating cache with', result);\n await strategy.set(request, requestedBlockNumber, result as Block);\n return result;\n }\n log(\n 'Cache hit, reusing cache result stored under block number %o',\n requestedBlockNumber,\n );\n return cacheResult;\n };\n}\n"]}
|
|
1
|
+
{"version":3,"file":"block-cache.mjs","sourceRoot":"","sources":["../src/block-cache.ts"],"names":[],"mappings":"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","sourcesContent":["import type { PollingBlockTracker } from '@metamask/eth-block-tracker';\nimport { createAsyncMiddleware } from '@metamask/json-rpc-engine';\nimport type { Json, JsonRpcParams, JsonRpcRequest } from '@metamask/utils';\n\nimport { projectLogger, createModuleLogger } from './logging-utils';\nimport type {\n Block,\n BlockCache,\n // eslint-disable-next-line @typescript-eslint/no-shadow\n Cache,\n JsonRpcCacheMiddleware,\n JsonRpcRequestToCache,\n} from './types';\nimport {\n cacheIdentifierForRequest,\n blockTagForRequest,\n cacheTypeForMethod,\n canCache,\n CacheStrategy,\n} from './utils/cache';\n\nconst log = createModuleLogger(projectLogger, 'block-cache');\n// `<nil>` comes from https://github.com/ethereum/go-ethereum/issues/16925\nconst emptyValues = [undefined, null, '\\u003cnil\\u003e'];\n\ntype BlockCacheMiddlewareOptions = {\n blockTracker?: PollingBlockTracker;\n};\n\n//\n// Cache Strategies\n//\n\nclass BlockCacheStrategy {\n private cache: Cache;\n\n constructor() {\n this.cache = {};\n }\n\n getBlockCache(blockNumberHex: string): BlockCache {\n const blockNumber: number = Number.parseInt(blockNumberHex, 16);\n let blockCache: BlockCache = this.cache[blockNumber];\n // create new cache if necesary\n if (!blockCache) {\n const newCache: BlockCache = {};\n this.cache[blockNumber] = newCache;\n blockCache = newCache;\n }\n return blockCache;\n }\n\n async get(\n request: JsonRpcRequest,\n requestedBlockNumber: string,\n ): Promise<Block | undefined> {\n // lookup block cache\n const blockCache: BlockCache = this.getBlockCache(requestedBlockNumber);\n // lookup payload in block cache\n const identifier: string | null = cacheIdentifierForRequest(request, true);\n return identifier ? blockCache[identifier] : undefined;\n }\n\n async set(\n request: JsonRpcRequest,\n requestedBlockNumber: string,\n result: Block,\n ): Promise<void> {\n // check if we can cached this result\n const canCacheResult: boolean = this.canCacheResult(request, result);\n if (!canCacheResult) {\n return;\n }\n\n // set the value in the cache\n const identifier: string | null = cacheIdentifierForRequest(request, true);\n if (!identifier) {\n return;\n }\n const blockCache: BlockCache = this.getBlockCache(requestedBlockNumber);\n blockCache[identifier] = result;\n }\n\n canCacheRequest(request: JsonRpcRequest): boolean {\n // check request method\n if (!canCache(request.method)) {\n return false;\n }\n // check blockTag\n const blockTag = blockTagForRequest(request);\n\n if (blockTag === 'pending') {\n return false;\n }\n // can be cached\n return true;\n }\n\n canCacheResult(request: JsonRpcRequest, result: Block): boolean {\n // never cache empty values (e.g. undefined)\n if (emptyValues.includes(result as any)) {\n return false;\n }\n\n // check if transactions have block reference before caching\n if (\n request.method &&\n ['eth_getTransactionByHash', 'eth_getTransactionReceipt'].includes(\n request.method,\n )\n ) {\n if (\n !result?.blockHash ||\n result.blockHash ===\n '0x0000000000000000000000000000000000000000000000000000000000000000'\n ) {\n return false;\n }\n }\n // otherwise true\n return true;\n }\n\n // removes all block caches with block number lower than `oldBlockHex`\n clearBefore(oldBlockHex: string): void {\n const oldBlockNumber: number = Number.parseInt(oldBlockHex, 16);\n // clear old caches\n Object.keys(this.cache)\n .map(Number)\n .filter((num) => num < oldBlockNumber)\n .forEach((num) => delete this.cache[num]);\n }\n}\n\nexport function createBlockCacheMiddleware({\n blockTracker,\n}: BlockCacheMiddlewareOptions = {}): JsonRpcCacheMiddleware<\n JsonRpcParams,\n Json\n> {\n // validate options\n if (!blockTracker) {\n throw new Error(\n 'createBlockCacheMiddleware - No PollingBlockTracker specified',\n );\n }\n\n // create caching strategies\n const blockCache: BlockCacheStrategy = new BlockCacheStrategy();\n const strategies: Record<CacheStrategy, BlockCacheStrategy | undefined> = {\n [CacheStrategy.Permanent]: blockCache,\n [CacheStrategy.Block]: blockCache,\n [CacheStrategy.Fork]: blockCache,\n [CacheStrategy.Never]: undefined,\n };\n\n return createAsyncMiddleware(\n async (req: JsonRpcRequestToCache<JsonRpcParams>, res, next) => {\n // allow cach to be skipped if so specified\n if (req.skipCache) {\n return next();\n }\n // check type and matching strategy\n const type = cacheTypeForMethod(req.method);\n const strategy = strategies[type];\n // If there's no strategy in place, pass it down the chain.\n if (!strategy) {\n return next();\n }\n\n // If the strategy can't cache this request, ignore it.\n if (!strategy.canCacheRequest(req)) {\n return next();\n }\n\n // get block reference (number or keyword)\n const requestBlockTag = blockTagForRequest(req);\n const blockTag =\n requestBlockTag && typeof requestBlockTag === 'string'\n ? requestBlockTag\n : 'latest';\n\n log('blockTag = %o, req = %o', blockTag, req);\n\n // get exact block number\n let requestedBlockNumber: string;\n if (blockTag === 'earliest') {\n // this just exists for symmetry with \"latest\"\n requestedBlockNumber = '0x00';\n } else if (blockTag === 'latest') {\n // fetch latest block number\n log('Fetching latest block number to determine cache key');\n const latestBlockNumber = await blockTracker.getLatestBlock();\n // clear all cache before latest block\n log(\n 'Clearing values stored under block numbers before %o',\n latestBlockNumber,\n );\n blockCache.clearBefore(latestBlockNumber);\n requestedBlockNumber = latestBlockNumber;\n } else {\n // We have a hex number\n requestedBlockNumber = blockTag;\n }\n // end on a hit, continue on a miss\n const cacheResult: Block | undefined = await strategy.get(\n req,\n requestedBlockNumber,\n );\n if (cacheResult === undefined) {\n // cache miss\n // wait for other middleware to handle request\n log(\n 'No cache stored under block number %o, carrying request forward',\n requestedBlockNumber,\n );\n await next();\n\n // add result to cache\n // it's safe to cast res.result as Block, due to runtime type checks\n // performed when strategy.set is called\n log('Populating cache with', res);\n await strategy.set(req, requestedBlockNumber, res.result as Block);\n } else {\n // fill in result from cache\n log(\n 'Cache hit, reusing cache result stored under block number %o',\n requestedBlockNumber,\n );\n res.result = cacheResult;\n }\n return undefined;\n },\n );\n}\n"]}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.createBlockRefRewriteMiddleware = void 0;
|
|
4
|
+
const json_rpc_engine_1 = require("@metamask/json-rpc-engine");
|
|
4
5
|
const cache_1 = require("./utils/cache.cjs");
|
|
5
6
|
/**
|
|
6
7
|
* Creates a middleware that rewrites "latest" block references to the known
|
|
@@ -14,13 +15,13 @@ function createBlockRefRewriteMiddleware({ blockTracker, } = {}) {
|
|
|
14
15
|
if (!blockTracker) {
|
|
15
16
|
throw Error('BlockRefRewriteMiddleware - mandatory "blockTracker" option is missing.');
|
|
16
17
|
}
|
|
17
|
-
return async (
|
|
18
|
-
const blockRefIndex = (0, cache_1.blockTagParamIndex)(
|
|
18
|
+
return (0, json_rpc_engine_1.createAsyncMiddleware)(async (req, _res, next) => {
|
|
19
|
+
const blockRefIndex = (0, cache_1.blockTagParamIndex)(req.method);
|
|
19
20
|
if (blockRefIndex === undefined) {
|
|
20
21
|
return next();
|
|
21
22
|
}
|
|
22
|
-
const blockRef = Array.isArray(
|
|
23
|
-
?
|
|
23
|
+
const blockRef = Array.isArray(req.params) && req.params[blockRefIndex]
|
|
24
|
+
? req.params[blockRefIndex]
|
|
24
25
|
: // omitted blockRef implies "latest"
|
|
25
26
|
'latest';
|
|
26
27
|
if (blockRef !== 'latest') {
|
|
@@ -28,16 +29,11 @@ function createBlockRefRewriteMiddleware({ blockTracker, } = {}) {
|
|
|
28
29
|
}
|
|
29
30
|
// rewrite blockRef to block-tracker's block number
|
|
30
31
|
const latestBlockNumber = await blockTracker.getLatestBlock();
|
|
31
|
-
if (Array.isArray(
|
|
32
|
-
|
|
33
|
-
params[blockRefIndex] = latestBlockNumber;
|
|
34
|
-
return next({
|
|
35
|
-
...request,
|
|
36
|
-
params,
|
|
37
|
-
});
|
|
32
|
+
if (Array.isArray(req.params)) {
|
|
33
|
+
req.params[blockRefIndex] = latestBlockNumber;
|
|
38
34
|
}
|
|
39
35
|
return next();
|
|
40
|
-
};
|
|
36
|
+
});
|
|
41
37
|
}
|
|
42
38
|
exports.createBlockRefRewriteMiddleware = createBlockRefRewriteMiddleware;
|
|
43
39
|
//# sourceMappingURL=block-ref-rewrite.cjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"block-ref-rewrite.cjs","sourceRoot":"","sources":["../src/block-ref-rewrite.ts"],"names":[],"mappings":";;;
|
|
1
|
+
{"version":3,"file":"block-ref-rewrite.cjs","sourceRoot":"","sources":["../src/block-ref-rewrite.ts"],"names":[],"mappings":";;;AAEA,+DAAkE;AAGlE,6CAAmD;AAMnD;;;;;;;GAOG;AACH,SAAgB,+BAA+B,CAAC,EAC9C,YAAY,MACwB,EAAE;IAItC,IAAI,CAAC,YAAY,EAAE;QACjB,MAAM,KAAK,CACT,yEAAyE,CAC1E,CAAC;KACH;IAED,OAAO,IAAA,uCAAqB,EAAC,KAAK,EAAE,GAAG,EAAE,IAAI,EAAE,IAAI,EAAE,EAAE;QACrD,MAAM,aAAa,GAAuB,IAAA,0BAAkB,EAAC,GAAG,CAAC,MAAM,CAAC,CAAC;QACzE,IAAI,aAAa,KAAK,SAAS,EAAE;YAC/B,OAAO,IAAI,EAAE,CAAC;SACf;QAED,MAAM,QAAQ,GACZ,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,IAAI,GAAG,CAAC,MAAM,CAAC,aAAa,CAAC;YACpD,CAAC,CAAE,GAAG,CAAC,MAAM,CAAC,aAAa,CAAY;YACvC,CAAC,CAAC,oCAAoC;gBACpC,QAAQ,CAAC;QAEf,IAAI,QAAQ,KAAK,QAAQ,EAAE;YACzB,OAAO,IAAI,EAAE,CAAC;SACf;QAED,mDAAmD;QACnD,MAAM,iBAAiB,GAAG,MAAM,YAAY,CAAC,cAAc,EAAE,CAAC;QAC9D,IAAI,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE;YAC7B,GAAG,CAAC,MAAM,CAAC,aAAa,CAAC,GAAG,iBAAiB,CAAC;SAC/C;QACD,OAAO,IAAI,EAAE,CAAC;IAChB,CAAC,CAAC,CAAC;AACL,CAAC;AAnCD,0EAmCC","sourcesContent":["import type { PollingBlockTracker } from '@metamask/eth-block-tracker';\nimport type { JsonRpcMiddleware } from '@metamask/json-rpc-engine';\nimport { createAsyncMiddleware } from '@metamask/json-rpc-engine';\nimport type { Json, JsonRpcParams } from '@metamask/utils';\n\nimport { blockTagParamIndex } from './utils/cache';\n\ntype BlockRefRewriteMiddlewareOptions = {\n blockTracker?: PollingBlockTracker;\n};\n\n/**\n * Creates a middleware that rewrites \"latest\" block references to the known\n * latest block number from a block tracker.\n *\n * @param options - The options for the middleware.\n * @param options.blockTracker - The block tracker to use.\n * @returns The middleware.\n */\nexport function createBlockRefRewriteMiddleware({\n blockTracker,\n}: BlockRefRewriteMiddlewareOptions = {}): JsonRpcMiddleware<\n JsonRpcParams,\n Json\n> {\n if (!blockTracker) {\n throw Error(\n 'BlockRefRewriteMiddleware - mandatory \"blockTracker\" option is missing.',\n );\n }\n\n return createAsyncMiddleware(async (req, _res, next) => {\n const blockRefIndex: number | undefined = blockTagParamIndex(req.method);\n if (blockRefIndex === undefined) {\n return next();\n }\n\n const blockRef: string | undefined =\n Array.isArray(req.params) && req.params[blockRefIndex]\n ? (req.params[blockRefIndex] as string)\n : // omitted blockRef implies \"latest\"\n 'latest';\n\n if (blockRef !== 'latest') {\n return next();\n }\n\n // rewrite blockRef to block-tracker's block number\n const latestBlockNumber = await blockTracker.getLatestBlock();\n if (Array.isArray(req.params)) {\n req.params[blockRefIndex] = latestBlockNumber;\n }\n return next();\n });\n}\n"]}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type { PollingBlockTracker } from "@metamask/eth-block-tracker";
|
|
2
|
-
import type { JsonRpcMiddleware } from "@metamask/json-rpc-engine
|
|
3
|
-
import type { Json,
|
|
2
|
+
import type { JsonRpcMiddleware } from "@metamask/json-rpc-engine";
|
|
3
|
+
import type { Json, JsonRpcParams } from "@metamask/utils";
|
|
4
4
|
type BlockRefRewriteMiddlewareOptions = {
|
|
5
5
|
blockTracker?: PollingBlockTracker;
|
|
6
6
|
};
|
|
@@ -12,6 +12,6 @@ type BlockRefRewriteMiddlewareOptions = {
|
|
|
12
12
|
* @param options.blockTracker - The block tracker to use.
|
|
13
13
|
* @returns The middleware.
|
|
14
14
|
*/
|
|
15
|
-
export declare function createBlockRefRewriteMiddleware({ blockTracker, }?: BlockRefRewriteMiddlewareOptions): JsonRpcMiddleware<
|
|
15
|
+
export declare function createBlockRefRewriteMiddleware({ blockTracker, }?: BlockRefRewriteMiddlewareOptions): JsonRpcMiddleware<JsonRpcParams, Json>;
|
|
16
16
|
export {};
|
|
17
17
|
//# sourceMappingURL=block-ref-rewrite.d.cts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"block-ref-rewrite.d.cts","sourceRoot":"","sources":["../src/block-ref-rewrite.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,mBAAmB,EAAE,oCAAoC;AACvE,OAAO,KAAK,EAAE,iBAAiB,EAAE,
|
|
1
|
+
{"version":3,"file":"block-ref-rewrite.d.cts","sourceRoot":"","sources":["../src/block-ref-rewrite.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,mBAAmB,EAAE,oCAAoC;AACvE,OAAO,KAAK,EAAE,iBAAiB,EAAE,kCAAkC;AAEnE,OAAO,KAAK,EAAE,IAAI,EAAE,aAAa,EAAE,wBAAwB;AAI3D,KAAK,gCAAgC,GAAG;IACtC,YAAY,CAAC,EAAE,mBAAmB,CAAC;CACpC,CAAC;AAEF;;;;;;;GAOG;AACH,wBAAgB,+BAA+B,CAAC,EAC9C,YAAY,GACb,GAAE,gCAAqC,GAAG,iBAAiB,CAC1D,aAAa,EACb,IAAI,CACL,CA8BA"}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type { PollingBlockTracker } from "@metamask/eth-block-tracker";
|
|
2
|
-
import type { JsonRpcMiddleware } from "@metamask/json-rpc-engine
|
|
3
|
-
import type { Json,
|
|
2
|
+
import type { JsonRpcMiddleware } from "@metamask/json-rpc-engine";
|
|
3
|
+
import type { Json, JsonRpcParams } from "@metamask/utils";
|
|
4
4
|
type BlockRefRewriteMiddlewareOptions = {
|
|
5
5
|
blockTracker?: PollingBlockTracker;
|
|
6
6
|
};
|
|
@@ -12,6 +12,6 @@ type BlockRefRewriteMiddlewareOptions = {
|
|
|
12
12
|
* @param options.blockTracker - The block tracker to use.
|
|
13
13
|
* @returns The middleware.
|
|
14
14
|
*/
|
|
15
|
-
export declare function createBlockRefRewriteMiddleware({ blockTracker, }?: BlockRefRewriteMiddlewareOptions): JsonRpcMiddleware<
|
|
15
|
+
export declare function createBlockRefRewriteMiddleware({ blockTracker, }?: BlockRefRewriteMiddlewareOptions): JsonRpcMiddleware<JsonRpcParams, Json>;
|
|
16
16
|
export {};
|
|
17
17
|
//# sourceMappingURL=block-ref-rewrite.d.mts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"block-ref-rewrite.d.mts","sourceRoot":"","sources":["../src/block-ref-rewrite.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,mBAAmB,EAAE,oCAAoC;AACvE,OAAO,KAAK,EAAE,iBAAiB,EAAE,
|
|
1
|
+
{"version":3,"file":"block-ref-rewrite.d.mts","sourceRoot":"","sources":["../src/block-ref-rewrite.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,mBAAmB,EAAE,oCAAoC;AACvE,OAAO,KAAK,EAAE,iBAAiB,EAAE,kCAAkC;AAEnE,OAAO,KAAK,EAAE,IAAI,EAAE,aAAa,EAAE,wBAAwB;AAI3D,KAAK,gCAAgC,GAAG;IACtC,YAAY,CAAC,EAAE,mBAAmB,CAAC;CACpC,CAAC;AAEF;;;;;;;GAOG;AACH,wBAAgB,+BAA+B,CAAC,EAC9C,YAAY,GACb,GAAE,gCAAqC,GAAG,iBAAiB,CAC1D,aAAa,EACb,IAAI,CACL,CA8BA"}
|