@feelyourprotocol/statemanager 8141.0.0

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.
Files changed (169) hide show
  1. package/LICENSE +373 -0
  2. package/README.md +331 -0
  3. package/dist/cjs/cache/account.d.ts +85 -0
  4. package/dist/cjs/cache/account.d.ts.map +1 -0
  5. package/dist/cjs/cache/account.js +252 -0
  6. package/dist/cjs/cache/account.js.map +1 -0
  7. package/dist/cjs/cache/cache.d.ts +23 -0
  8. package/dist/cjs/cache/cache.d.ts.map +1 -0
  9. package/dist/cjs/cache/cache.js +31 -0
  10. package/dist/cjs/cache/cache.js.map +1 -0
  11. package/dist/cjs/cache/caches.d.ts +19 -0
  12. package/dist/cjs/cache/caches.d.ts.map +1 -0
  13. package/dist/cjs/cache/caches.js +107 -0
  14. package/dist/cjs/cache/caches.js.map +1 -0
  15. package/dist/cjs/cache/code.d.ts +87 -0
  16. package/dist/cjs/cache/code.d.ts.map +1 -0
  17. package/dist/cjs/cache/code.js +258 -0
  18. package/dist/cjs/cache/code.js.map +1 -0
  19. package/dist/cjs/cache/index.d.ts +7 -0
  20. package/dist/cjs/cache/index.d.ts.map +1 -0
  21. package/dist/cjs/cache/index.js +23 -0
  22. package/dist/cjs/cache/index.js.map +1 -0
  23. package/dist/cjs/cache/originalStorageCache.d.ts +21 -0
  24. package/dist/cjs/cache/originalStorageCache.d.ts.map +1 -0
  25. package/dist/cjs/cache/originalStorageCache.js +52 -0
  26. package/dist/cjs/cache/originalStorageCache.js.map +1 -0
  27. package/dist/cjs/cache/storage.d.ts +101 -0
  28. package/dist/cjs/cache/storage.d.ts.map +1 -0
  29. package/dist/cjs/cache/storage.js +337 -0
  30. package/dist/cjs/cache/storage.js.map +1 -0
  31. package/dist/cjs/cache/types.d.ts +36 -0
  32. package/dist/cjs/cache/types.d.ts.map +1 -0
  33. package/dist/cjs/cache/types.js +8 -0
  34. package/dist/cjs/cache/types.js.map +1 -0
  35. package/dist/cjs/index.d.ts +8 -0
  36. package/dist/cjs/index.d.ts.map +1 -0
  37. package/dist/cjs/index.js +24 -0
  38. package/dist/cjs/index.js.map +1 -0
  39. package/dist/cjs/merkleStateManager.d.ts +260 -0
  40. package/dist/cjs/merkleStateManager.d.ts.map +1 -0
  41. package/dist/cjs/merkleStateManager.js +616 -0
  42. package/dist/cjs/merkleStateManager.js.map +1 -0
  43. package/dist/cjs/package.json +3 -0
  44. package/dist/cjs/proof/index.d.ts +3 -0
  45. package/dist/cjs/proof/index.d.ts.map +1 -0
  46. package/dist/cjs/proof/index.js +19 -0
  47. package/dist/cjs/proof/index.js.map +1 -0
  48. package/dist/cjs/proof/merkle.d.ts +40 -0
  49. package/dist/cjs/proof/merkle.d.ts.map +1 -0
  50. package/dist/cjs/proof/merkle.js +182 -0
  51. package/dist/cjs/proof/merkle.js.map +1 -0
  52. package/dist/cjs/proof/rpc.d.ts +10 -0
  53. package/dist/cjs/proof/rpc.d.ts.map +1 -0
  54. package/dist/cjs/proof/rpc.js +20 -0
  55. package/dist/cjs/proof/rpc.js.map +1 -0
  56. package/dist/cjs/rpcStateManager.d.ts +162 -0
  57. package/dist/cjs/rpcStateManager.d.ts.map +1 -0
  58. package/dist/cjs/rpcStateManager.js +313 -0
  59. package/dist/cjs/rpcStateManager.js.map +1 -0
  60. package/dist/cjs/simpleStateManager.d.ts +54 -0
  61. package/dist/cjs/simpleStateManager.d.ts.map +1 -0
  62. package/dist/cjs/simpleStateManager.js +125 -0
  63. package/dist/cjs/simpleStateManager.js.map +1 -0
  64. package/dist/cjs/statefulBinaryTreeStateManager.d.ts +69 -0
  65. package/dist/cjs/statefulBinaryTreeStateManager.d.ts.map +1 -0
  66. package/dist/cjs/statefulBinaryTreeStateManager.js +576 -0
  67. package/dist/cjs/statefulBinaryTreeStateManager.js.map +1 -0
  68. package/dist/cjs/types.d.ts +92 -0
  69. package/dist/cjs/types.d.ts.map +1 -0
  70. package/dist/cjs/types.js +3 -0
  71. package/dist/cjs/types.js.map +1 -0
  72. package/dist/cjs/util.d.ts +4 -0
  73. package/dist/cjs/util.d.ts.map +1 -0
  74. package/dist/cjs/util.js +21 -0
  75. package/dist/cjs/util.js.map +1 -0
  76. package/dist/esm/cache/account.d.ts +85 -0
  77. package/dist/esm/cache/account.d.ts.map +1 -0
  78. package/dist/esm/cache/account.js +248 -0
  79. package/dist/esm/cache/account.js.map +1 -0
  80. package/dist/esm/cache/cache.d.ts +23 -0
  81. package/dist/esm/cache/cache.d.ts.map +1 -0
  82. package/dist/esm/cache/cache.js +27 -0
  83. package/dist/esm/cache/cache.js.map +1 -0
  84. package/dist/esm/cache/caches.d.ts +19 -0
  85. package/dist/esm/cache/caches.d.ts.map +1 -0
  86. package/dist/esm/cache/caches.js +103 -0
  87. package/dist/esm/cache/caches.js.map +1 -0
  88. package/dist/esm/cache/code.d.ts +87 -0
  89. package/dist/esm/cache/code.d.ts.map +1 -0
  90. package/dist/esm/cache/code.js +254 -0
  91. package/dist/esm/cache/code.js.map +1 -0
  92. package/dist/esm/cache/index.d.ts +7 -0
  93. package/dist/esm/cache/index.d.ts.map +1 -0
  94. package/dist/esm/cache/index.js +7 -0
  95. package/dist/esm/cache/index.js.map +1 -0
  96. package/dist/esm/cache/originalStorageCache.d.ts +21 -0
  97. package/dist/esm/cache/originalStorageCache.d.ts.map +1 -0
  98. package/dist/esm/cache/originalStorageCache.js +48 -0
  99. package/dist/esm/cache/originalStorageCache.js.map +1 -0
  100. package/dist/esm/cache/storage.d.ts +101 -0
  101. package/dist/esm/cache/storage.d.ts.map +1 -0
  102. package/dist/esm/cache/storage.js +333 -0
  103. package/dist/esm/cache/storage.js.map +1 -0
  104. package/dist/esm/cache/types.d.ts +36 -0
  105. package/dist/esm/cache/types.d.ts.map +1 -0
  106. package/dist/esm/cache/types.js +5 -0
  107. package/dist/esm/cache/types.js.map +1 -0
  108. package/dist/esm/index.d.ts +8 -0
  109. package/dist/esm/index.d.ts.map +1 -0
  110. package/dist/esm/index.js +8 -0
  111. package/dist/esm/index.js.map +1 -0
  112. package/dist/esm/merkleStateManager.d.ts +260 -0
  113. package/dist/esm/merkleStateManager.d.ts.map +1 -0
  114. package/dist/esm/merkleStateManager.js +612 -0
  115. package/dist/esm/merkleStateManager.js.map +1 -0
  116. package/dist/esm/package.json +3 -0
  117. package/dist/esm/proof/index.d.ts +3 -0
  118. package/dist/esm/proof/index.d.ts.map +1 -0
  119. package/dist/esm/proof/index.js +3 -0
  120. package/dist/esm/proof/index.js.map +1 -0
  121. package/dist/esm/proof/merkle.d.ts +40 -0
  122. package/dist/esm/proof/merkle.d.ts.map +1 -0
  123. package/dist/esm/proof/merkle.js +175 -0
  124. package/dist/esm/proof/merkle.js.map +1 -0
  125. package/dist/esm/proof/rpc.d.ts +10 -0
  126. package/dist/esm/proof/rpc.d.ts.map +1 -0
  127. package/dist/esm/proof/rpc.js +17 -0
  128. package/dist/esm/proof/rpc.js.map +1 -0
  129. package/dist/esm/rpcStateManager.d.ts +162 -0
  130. package/dist/esm/rpcStateManager.d.ts.map +1 -0
  131. package/dist/esm/rpcStateManager.js +308 -0
  132. package/dist/esm/rpcStateManager.js.map +1 -0
  133. package/dist/esm/simpleStateManager.d.ts +54 -0
  134. package/dist/esm/simpleStateManager.d.ts.map +1 -0
  135. package/dist/esm/simpleStateManager.js +121 -0
  136. package/dist/esm/simpleStateManager.js.map +1 -0
  137. package/dist/esm/statefulBinaryTreeStateManager.d.ts +69 -0
  138. package/dist/esm/statefulBinaryTreeStateManager.d.ts.map +1 -0
  139. package/dist/esm/statefulBinaryTreeStateManager.js +572 -0
  140. package/dist/esm/statefulBinaryTreeStateManager.js.map +1 -0
  141. package/dist/esm/types.d.ts +92 -0
  142. package/dist/esm/types.d.ts.map +1 -0
  143. package/dist/esm/types.js +2 -0
  144. package/dist/esm/types.js.map +1 -0
  145. package/dist/esm/util.d.ts +4 -0
  146. package/dist/esm/util.d.ts.map +1 -0
  147. package/dist/esm/util.js +18 -0
  148. package/dist/esm/util.js.map +1 -0
  149. package/dist/tsconfig.prod.cjs.tsbuildinfo +1 -0
  150. package/dist/tsconfig.prod.esm.tsbuildinfo +1 -0
  151. package/package.json +74 -0
  152. package/src/cache/account.ts +277 -0
  153. package/src/cache/cache.ts +35 -0
  154. package/src/cache/caches.ts +125 -0
  155. package/src/cache/code.ts +277 -0
  156. package/src/cache/index.ts +6 -0
  157. package/src/cache/originalStorageCache.ts +57 -0
  158. package/src/cache/storage.ts +369 -0
  159. package/src/cache/types.ts +38 -0
  160. package/src/index.ts +7 -0
  161. package/src/merkleStateManager.ts +737 -0
  162. package/src/proof/index.ts +2 -0
  163. package/src/proof/merkle.ts +264 -0
  164. package/src/proof/rpc.ts +24 -0
  165. package/src/rpcStateManager.ts +381 -0
  166. package/src/simpleStateManager.ts +154 -0
  167. package/src/statefulBinaryTreeStateManager.ts +789 -0
  168. package/src/types.ts +103 -0
  169. package/src/util.ts +28 -0
@@ -0,0 +1,57 @@
1
+ import { bytesToUnprefixedHex } from '@feelyourprotocol/util'
2
+
3
+ import type { Address } from '@feelyourprotocol/util'
4
+
5
+ type getStorage = (address: Address, key: Uint8Array) => Promise<Uint8Array>
6
+
7
+ /**
8
+ * Helper class to cache original storage values (so values already being present in
9
+ * the pre-state of a call), mainly for correct gas cost calculation in EVM/VM.
10
+ *
11
+ * TODO: Usage of this class is very implicit through the injected `getStorage()`
12
+ * method bound to the calling state manager. It should be examined if there are alternative
13
+ * designs being more transparent and direct along the next breaking release round.
14
+ *
15
+ */
16
+ export class OriginalStorageCache {
17
+ private map: Map<string, Map<string, Uint8Array>>
18
+ private getStorage: getStorage
19
+ constructor(getStorage: getStorage) {
20
+ this.map = new Map()
21
+ this.getStorage = getStorage
22
+ }
23
+
24
+ async get(address: Address, key: Uint8Array): Promise<Uint8Array> {
25
+ // Using deprecated bytesToUnprefixedHex for performance: used as Map keys for cache lookups.
26
+ const addressHex = bytesToUnprefixedHex(address.bytes)
27
+ const map = this.map.get(addressHex)
28
+ if (map !== undefined) {
29
+ const keyHex = bytesToUnprefixedHex(key)
30
+ const value = map.get(keyHex)
31
+ if (value !== undefined) {
32
+ return value
33
+ }
34
+ }
35
+ const value = await this.getStorage(address, key)
36
+ this.put(address, key, value)
37
+ return value
38
+ }
39
+
40
+ put(address: Address, key: Uint8Array, value: Uint8Array) {
41
+ // Using deprecated bytesToUnprefixedHex for performance: used as Map keys for cache lookups.
42
+ const addressHex = bytesToUnprefixedHex(address.bytes)
43
+ let map = this.map.get(addressHex)
44
+ if (map === undefined) {
45
+ map = new Map()
46
+ this.map.set(addressHex, map)
47
+ }
48
+ const keyHex = bytesToUnprefixedHex(key)
49
+ if (map!.has(keyHex) === false) {
50
+ map!.set(keyHex, value)
51
+ }
52
+ }
53
+
54
+ clear(): void {
55
+ this.map = new Map()
56
+ }
57
+ }
@@ -0,0 +1,369 @@
1
+ import { EthereumJSErrorWithoutCode, bytesToUnprefixedHex, hexToBytes } from '@feelyourprotocol/util'
2
+ import { OrderedMap } from '@js-sdsl/ordered-map'
3
+ import debugDefault from 'debug'
4
+ import { LRUCache } from 'lru-cache'
5
+
6
+ import { Cache } from './cache.ts'
7
+ import { CacheType } from './types.ts'
8
+
9
+ import type { Address } from '@feelyourprotocol/util'
10
+ import type { CacheOpts } from './types.ts'
11
+
12
+ /**
13
+ * key -> storage mapping
14
+ *
15
+ * undefined: storage value is known not to exist in the cache
16
+ */
17
+ type DiffStorageCacheMap = Map<string, Uint8Array | undefined>
18
+ type StorageCacheMap = Map<string, Uint8Array>
19
+
20
+ export class StorageCache extends Cache {
21
+ _lruCache: LRUCache<string, StorageCacheMap> | undefined
22
+ _orderedMapCache: OrderedMap<string, StorageCacheMap> | undefined
23
+
24
+ /**
25
+ * Diff cache collecting the state of the cache
26
+ * at the beginning of checkpoint height
27
+ * (respectively: before a first modification)
28
+ *
29
+ * If the whole cache element is undefined (in contrast
30
+ * to the account), the element didn't exist in the cache
31
+ * before.
32
+ */
33
+ _diffCache: Map<string, DiffStorageCacheMap>[] = []
34
+
35
+ constructor(opts: CacheOpts) {
36
+ super()
37
+ if (opts.type === CacheType.LRU) {
38
+ this._lruCache = new LRUCache({
39
+ max: opts.size,
40
+ updateAgeOnGet: true,
41
+ })
42
+ } else {
43
+ this._orderedMapCache = new OrderedMap()
44
+ }
45
+
46
+ this._diffCache.push(new Map())
47
+
48
+ if (this.DEBUG) {
49
+ this._debug = debugDefault('statemanager:cache:storage')
50
+ }
51
+ }
52
+
53
+ _saveCachePreState(addressHex: string, keyHex: string) {
54
+ const addressStoragePreState = this._diffCache[this._checkpoints].get(addressHex)
55
+ const diffStorageMap: DiffStorageCacheMap = addressStoragePreState ?? new Map()
56
+
57
+ if (!diffStorageMap.has(keyHex)) {
58
+ let oldStorageMap: StorageCacheMap | undefined
59
+ let oldStorage: Uint8Array | undefined = undefined
60
+ if (this._lruCache) {
61
+ oldStorageMap = this._lruCache!.get(addressHex)
62
+ if (oldStorageMap) {
63
+ oldStorage = oldStorageMap.get(keyHex)
64
+ }
65
+ } else {
66
+ oldStorageMap = this._orderedMapCache!.getElementByKey(addressHex)
67
+ if (oldStorageMap) {
68
+ oldStorage = oldStorageMap.get(keyHex)
69
+ }
70
+ }
71
+ diffStorageMap.set(keyHex, oldStorage)
72
+ this._diffCache[this._checkpoints].set(addressHex, diffStorageMap)
73
+ }
74
+ }
75
+
76
+ /**
77
+ * Puts storage value to cache under address_key cache key.
78
+ * @param address - Account address
79
+ * @param key - Storage key
80
+ * @param val - RLP-encoded storage value
81
+ */
82
+ put(address: Address, key: Uint8Array, value: Uint8Array): void {
83
+ // Using deprecated bytesToUnprefixedHex for performance: used as Map keys for cache lookups.
84
+ const addressHex = bytesToUnprefixedHex(address.bytes)
85
+ const keyHex = bytesToUnprefixedHex(key)
86
+ this._saveCachePreState(addressHex, keyHex)
87
+
88
+ if (this.DEBUG) {
89
+ this._debug(
90
+ `Put storage for ${addressHex}: ${keyHex} -> ${
91
+ value !== undefined ? bytesToUnprefixedHex(value) : ''
92
+ }`,
93
+ )
94
+ }
95
+ if (this._lruCache) {
96
+ let storageMap = this._lruCache!.get(addressHex)
97
+ if (!storageMap) {
98
+ storageMap = new Map()
99
+ }
100
+ storageMap.set(keyHex, value)
101
+ this._lruCache!.set(addressHex, storageMap)
102
+ } else {
103
+ let storageMap = this._orderedMapCache!.getElementByKey(addressHex)
104
+ if (!storageMap) {
105
+ storageMap = new Map()
106
+ }
107
+ storageMap.set(keyHex, value)
108
+ this._orderedMapCache!.setElement(addressHex, storageMap)
109
+ }
110
+ this._stats.writes += 1
111
+ }
112
+
113
+ /**
114
+ * Returns the queried slot as the RLP encoded storage value
115
+ * hexToBytes('0x80'): slot is known to be empty
116
+ * undefined: slot is not in cache
117
+ * @param address - Address of account
118
+ * @param key - Storage key
119
+ * @returns Storage value or undefined
120
+ */
121
+ get(address: Address, key: Uint8Array): Uint8Array | undefined {
122
+ const addressHex = bytesToUnprefixedHex(address.bytes)
123
+ const keyHex = bytesToUnprefixedHex(key)
124
+ if (this.DEBUG) {
125
+ this._debug(`Get storage for ${addressHex}`)
126
+ }
127
+
128
+ let storageMap: StorageCacheMap | undefined
129
+ if (this._lruCache) {
130
+ storageMap = this._lruCache!.get(addressHex)
131
+ } else {
132
+ storageMap = this._orderedMapCache!.getElementByKey(addressHex)
133
+ }
134
+ this._stats.reads += 1
135
+ if (storageMap) {
136
+ this._stats.hits += 1
137
+ return storageMap.get(keyHex)
138
+ }
139
+ }
140
+
141
+ /**
142
+ * Marks storage key for address as deleted in cache.
143
+ * @param address - Address
144
+ * @param key - Storage key
145
+ */
146
+ del(address: Address, key: Uint8Array): void {
147
+ const addressHex = bytesToUnprefixedHex(address.bytes)
148
+ const keyHex = bytesToUnprefixedHex(key)
149
+ this._saveCachePreState(addressHex, keyHex)
150
+ if (this.DEBUG) {
151
+ this._debug(`Delete storage for ${addressHex}: ${keyHex}`)
152
+ }
153
+ if (this._lruCache) {
154
+ let storageMap = this._lruCache!.get(addressHex)
155
+ if (!storageMap) {
156
+ storageMap = new Map()
157
+ }
158
+ storageMap.set(keyHex, hexToBytes('0x80'))
159
+ this._lruCache!.set(addressHex, storageMap)
160
+ } else {
161
+ let storageMap = this._orderedMapCache!.getElementByKey(addressHex)
162
+ if (!storageMap) {
163
+ storageMap = new Map()
164
+ }
165
+ storageMap.set(keyHex, hexToBytes('0x80'))
166
+ this._orderedMapCache!.setElement(addressHex, storageMap)
167
+ }
168
+
169
+ this._stats.deletions += 1
170
+ }
171
+
172
+ /**
173
+ * Deletes all storage slots for address from the cache
174
+ * @param address
175
+ */
176
+ clearStorage(address: Address): void {
177
+ const addressHex = bytesToUnprefixedHex(address.bytes)
178
+ if (this._lruCache) {
179
+ this._lruCache!.set(addressHex, new Map())
180
+ } else {
181
+ this._orderedMapCache!.setElement(addressHex, new Map())
182
+ }
183
+ }
184
+
185
+ /**
186
+ * Flushes cache by returning storage slots that have been modified
187
+ * or deleted and resetting the diff cache (at checkpoint height).
188
+ */
189
+ flush(): [string, string, Uint8Array | undefined][] {
190
+ if (this.DEBUG) {
191
+ this._debug(`Flushing cache on checkpoint ${this._checkpoints}`)
192
+ }
193
+
194
+ const diffMap = this._diffCache[this._checkpoints]!
195
+
196
+ const items: [string, string, Uint8Array | undefined][] = []
197
+
198
+ for (const entry of diffMap.entries()) {
199
+ const addressHex = entry[0]
200
+ const diffStorageMap = entry[1]
201
+ let storageMap: StorageCacheMap | undefined
202
+ if (this._lruCache) {
203
+ storageMap = this._lruCache!.get(addressHex)
204
+ } else {
205
+ storageMap = this._orderedMapCache!.getElementByKey(addressHex)
206
+ }
207
+
208
+ if (storageMap !== undefined) {
209
+ for (const entry of diffStorageMap.entries()) {
210
+ const keyHex = entry[0]
211
+ const value = storageMap.get(keyHex)
212
+ items.push([addressHex, keyHex, value])
213
+ }
214
+ } else {
215
+ throw EthereumJSErrorWithoutCode(
216
+ 'internal error: storage cache map for account should be defined',
217
+ )
218
+ }
219
+ }
220
+ this._diffCache[this._checkpoints] = new Map()
221
+ return items
222
+ }
223
+
224
+ /**
225
+ * Revert changes to cache last checkpoint (no effect on trie).
226
+ */
227
+ revert(): void {
228
+ this._checkpoints -= 1
229
+ if (this.DEBUG) {
230
+ this._debug(`Revert to checkpoint ${this._checkpoints}`)
231
+ }
232
+ const diffMap = this._diffCache.pop()!
233
+
234
+ for (const entry of diffMap.entries()) {
235
+ const addressHex = entry[0]
236
+ const diffStorageMap = entry[1]
237
+
238
+ for (const entry of diffStorageMap.entries()) {
239
+ const keyHex = entry[0]
240
+ const value = entry[1]
241
+ if (this._lruCache) {
242
+ const storageMap = this._lruCache.get(addressHex) ?? new Map()
243
+ if (value === undefined) {
244
+ // Value is known not to be in the cache before
245
+ // -> delete from cache
246
+ storageMap.delete(keyHex)
247
+ } else {
248
+ // Value is known to be in the cache before
249
+ // (being either some storage value or the RLP-encoded empty Uint8Array)
250
+ storageMap.set(keyHex, value)
251
+ }
252
+ this._lruCache.set(addressHex, storageMap)
253
+ } else {
254
+ const storageMap = this._orderedMapCache!.getElementByKey(addressHex) ?? new Map()
255
+ if (!value) {
256
+ storageMap.delete(keyHex)
257
+ } else {
258
+ storageMap.set(keyHex, value)
259
+ }
260
+ this._orderedMapCache!.setElement(addressHex, storageMap)
261
+ }
262
+ }
263
+ }
264
+ }
265
+
266
+ /**
267
+ * Commits to current state of cache (no effect on trie).
268
+ */
269
+ commit(): void {
270
+ this._checkpoints -= 1
271
+ if (this.DEBUG) {
272
+ this._debug(`Commit to checkpoint ${this._checkpoints}`)
273
+ }
274
+ const higherHeightDiffMap = this._diffCache.pop()!
275
+ const lowerHeightDiffMap = this._diffCache[this._checkpoints]
276
+
277
+ // Go through diffMap from the pre-commit checkpoint height.
278
+ // 1. Iterate through all state pre states
279
+ // 2. If state pre-state is not in the new (lower) height diff map, take pre commit pre state value
280
+ // 3. If state is in new map, take this one, since this supersedes subsequent changes
281
+ for (const entry of higherHeightDiffMap.entries()) {
282
+ const addressHex = entry[0]
283
+ const higherHeightStorageDiff = entry[1]
284
+
285
+ const lowerHeightStorageDiff = lowerHeightDiffMap.get(addressHex) ?? new Map()
286
+
287
+ for (const entry of higherHeightStorageDiff.entries()) {
288
+ const keyHex = entry[0]
289
+ if (!lowerHeightStorageDiff.has(keyHex)) {
290
+ const elem = entry[1]
291
+ lowerHeightStorageDiff.set(keyHex, elem)
292
+ }
293
+ }
294
+ lowerHeightDiffMap.set(addressHex, lowerHeightStorageDiff)
295
+ }
296
+ }
297
+
298
+ /**
299
+ * Marks current state of cache as checkpoint, which can
300
+ * later on be reverted or committed.
301
+ */
302
+ checkpoint(): void {
303
+ this._checkpoints += 1
304
+ if (this.DEBUG) {
305
+ this._debug(`New checkpoint ${this._checkpoints}`)
306
+ }
307
+ this._diffCache.push(new Map())
308
+ }
309
+
310
+ /**
311
+ * Returns the size of the cache
312
+ * @returns
313
+ */
314
+ size() {
315
+ if (this._lruCache) {
316
+ return this._lruCache!.size
317
+ } else {
318
+ return this._orderedMapCache!.size()
319
+ }
320
+ }
321
+
322
+ /**
323
+ * Returns a dict with cache stats
324
+ * @param reset
325
+ */
326
+ stats(reset = true) {
327
+ const stats = { ...this._stats }
328
+ stats.size = this.size()
329
+ if (reset) {
330
+ this._stats = {
331
+ size: 0,
332
+ reads: 0,
333
+ hits: 0,
334
+ writes: 0,
335
+ deletions: 0,
336
+ }
337
+ }
338
+ return stats
339
+ }
340
+
341
+ /**
342
+ * Clears cache.
343
+ */
344
+ clear(): void {
345
+ if (this.DEBUG) {
346
+ this._debug(`Clear cache`)
347
+ }
348
+ if (this._lruCache) {
349
+ this._lruCache!.clear()
350
+ } else {
351
+ this._orderedMapCache!.clear()
352
+ }
353
+ }
354
+
355
+ /**
356
+ * Dumps the RLP-encoded storage values for an `account` specified by `address`.
357
+ * @param address - The address of the `account` to return storage for
358
+ * @returns {StorageCacheMap | undefined} - The storage values for the `account` or undefined if the `account` is not in the cache
359
+ */
360
+ dump(address: Address): StorageCacheMap | undefined {
361
+ let storageMap
362
+ if (this._lruCache) {
363
+ storageMap = this._lruCache!.get(bytesToUnprefixedHex(address.bytes))
364
+ } else {
365
+ storageMap = this._orderedMapCache?.getElementByKey(bytesToUnprefixedHex(address.bytes))
366
+ }
367
+ return storageMap
368
+ }
369
+ }
@@ -0,0 +1,38 @@
1
+ export type CacheType = (typeof CacheType)[keyof typeof CacheType]
2
+
3
+ export const CacheType = {
4
+ LRU: 'lru',
5
+ ORDERED_MAP: 'ordered_map',
6
+ } as const
7
+
8
+ export interface CacheOpts {
9
+ /**
10
+ * Size of the cache (only for LRU cache)
11
+ *
12
+ * Default: 100000 (account cache) / 20000 (storage cache) / 20000 (code cache)
13
+ *
14
+ * Note: the cache/trie interplay mechanism is designed in a way that
15
+ * the theoretical number of max modified accounts between two flush operations
16
+ * should be smaller than the cache size, otherwise the cache will "forget" the
17
+ * old modifications resulting in an incomplete set of trie-flushed accounts.
18
+ */
19
+ size: number
20
+ /**
21
+ * Cache type to use.
22
+ *
23
+ * Available options:
24
+ *
25
+ * ORDERED_MAP: Cache with no fixed upper bound and dynamic allocation,
26
+ * use for dynamic setups like testing or similar.
27
+ *
28
+ * LRU: LRU cache with pre-allocation of memory and a fixed size.
29
+ * Use for larger and more persistent caches.
30
+ */
31
+ type: CacheType
32
+ }
33
+
34
+ export interface CachesStateManagerOpts {
35
+ account?: Partial<CacheOpts>
36
+ code?: Partial<CacheOpts>
37
+ storage?: Partial<CacheOpts>
38
+ }
package/src/index.ts ADDED
@@ -0,0 +1,7 @@
1
+ export * from './cache/index.ts'
2
+ export * from './merkleStateManager.ts'
3
+ export * from './proof/index.ts'
4
+ export * from './rpcStateManager.ts'
5
+ export * from './simpleStateManager.ts'
6
+ export * from './statefulBinaryTreeStateManager.ts'
7
+ export * from './types.ts'