hardhat 2.20.1 → 2.21.0-dev.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 (271) hide show
  1. package/internal/core/jsonrpc/types/input/blockTag.d.ts +3 -3
  2. package/internal/core/jsonrpc/types/input/filterRequest.d.ts +6 -6
  3. package/internal/core/providers/construction.d.ts.map +1 -1
  4. package/internal/core/providers/construction.js +28 -4
  5. package/internal/core/providers/construction.js.map +1 -1
  6. package/internal/core/providers/http.d.ts +2 -0
  7. package/internal/core/providers/http.d.ts.map +1 -1
  8. package/internal/core/providers/http.js +2 -1
  9. package/internal/core/providers/http.js.map +1 -1
  10. package/internal/core/runtime-environment.d.ts.map +1 -1
  11. package/internal/core/runtime-environment.js.map +1 -1
  12. package/internal/hardhat-network/jsonrpc/client.d.ts +0 -2
  13. package/internal/hardhat-network/jsonrpc/client.d.ts.map +1 -1
  14. package/internal/hardhat-network/jsonrpc/client.js +0 -16
  15. package/internal/hardhat-network/jsonrpc/client.js.map +1 -1
  16. package/internal/hardhat-network/jsonrpc/handler.js +9 -1
  17. package/internal/hardhat-network/jsonrpc/handler.js.map +1 -1
  18. package/internal/hardhat-network/provider/BlockchainData.d.ts +5 -5
  19. package/internal/hardhat-network/provider/BlockchainData.d.ts.map +1 -1
  20. package/internal/hardhat-network/provider/BlockchainData.js +10 -10
  21. package/internal/hardhat-network/provider/BlockchainData.js.map +1 -1
  22. package/internal/hardhat-network/provider/HardhatBlockchain.d.ts +0 -7
  23. package/internal/hardhat-network/provider/HardhatBlockchain.d.ts.map +1 -1
  24. package/internal/hardhat-network/provider/HardhatBlockchain.js +2 -14
  25. package/internal/hardhat-network/provider/HardhatBlockchain.js.map +1 -1
  26. package/internal/hardhat-network/provider/TxPool.d.ts +3 -2
  27. package/internal/hardhat-network/provider/TxPool.d.ts.map +1 -1
  28. package/internal/hardhat-network/provider/TxPool.js +16 -16
  29. package/internal/hardhat-network/provider/TxPool.js.map +1 -1
  30. package/internal/hardhat-network/provider/ethereumjs-workarounds.js +1 -1
  31. package/internal/hardhat-network/provider/ethereumjs-workarounds.js.map +1 -1
  32. package/internal/hardhat-network/provider/filter.d.ts +6 -5
  33. package/internal/hardhat-network/provider/filter.d.ts.map +1 -1
  34. package/internal/hardhat-network/provider/filter.js +2 -2
  35. package/internal/hardhat-network/provider/filter.js.map +1 -1
  36. package/internal/hardhat-network/provider/fork/ForkBlockchain.d.ts +0 -7
  37. package/internal/hardhat-network/provider/fork/ForkBlockchain.d.ts.map +1 -1
  38. package/internal/hardhat-network/provider/fork/ForkBlockchain.js +4 -21
  39. package/internal/hardhat-network/provider/fork/ForkBlockchain.js.map +1 -1
  40. package/internal/hardhat-network/provider/fork/ForkStateManager.d.ts +13 -19
  41. package/internal/hardhat-network/provider/fork/ForkStateManager.d.ts.map +1 -1
  42. package/internal/hardhat-network/provider/fork/ForkStateManager.js +61 -59
  43. package/internal/hardhat-network/provider/fork/ForkStateManager.js.map +1 -1
  44. package/internal/hardhat-network/provider/fork/rpcToBlockData.d.ts.map +1 -1
  45. package/internal/hardhat-network/provider/fork/rpcToBlockData.js +0 -3
  46. package/internal/hardhat-network/provider/fork/rpcToBlockData.js.map +1 -1
  47. package/internal/hardhat-network/provider/fork/rpcToTxData.d.ts +2 -2
  48. package/internal/hardhat-network/provider/fork/rpcToTxData.d.ts.map +1 -1
  49. package/internal/hardhat-network/provider/fork/rpcToTxData.js +1 -1
  50. package/internal/hardhat-network/provider/fork/rpcToTxData.js.map +1 -1
  51. package/internal/hardhat-network/provider/modules/base.js +4 -4
  52. package/internal/hardhat-network/provider/modules/base.js.map +1 -1
  53. package/internal/hardhat-network/provider/modules/eth.d.ts.map +1 -1
  54. package/internal/hardhat-network/provider/modules/eth.js +9 -16
  55. package/internal/hardhat-network/provider/modules/eth.js.map +1 -1
  56. package/internal/hardhat-network/provider/modules/logger.d.ts +6 -84
  57. package/internal/hardhat-network/provider/modules/logger.d.ts.map +1 -1
  58. package/internal/hardhat-network/provider/modules/logger.js +3 -530
  59. package/internal/hardhat-network/provider/modules/logger.js.map +1 -1
  60. package/internal/hardhat-network/provider/node-types.d.ts +2 -65
  61. package/internal/hardhat-network/provider/node-types.d.ts.map +1 -1
  62. package/internal/hardhat-network/provider/node-types.js +0 -5
  63. package/internal/hardhat-network/provider/node-types.js.map +1 -1
  64. package/internal/hardhat-network/provider/node.d.ts +2 -6
  65. package/internal/hardhat-network/provider/node.d.ts.map +1 -1
  66. package/internal/hardhat-network/provider/node.js +79 -153
  67. package/internal/hardhat-network/provider/node.js.map +1 -1
  68. package/internal/hardhat-network/provider/output.d.ts +0 -14
  69. package/internal/hardhat-network/provider/output.d.ts.map +1 -1
  70. package/internal/hardhat-network/provider/output.js +0 -264
  71. package/internal/hardhat-network/provider/output.js.map +1 -1
  72. package/internal/hardhat-network/provider/provider.d.ts +26 -25
  73. package/internal/hardhat-network/provider/provider.d.ts.map +1 -1
  74. package/internal/hardhat-network/provider/provider.js +342 -186
  75. package/internal/hardhat-network/provider/provider.js.map +1 -1
  76. package/internal/hardhat-network/provider/transactions/FakeSenderAccessListEIP2930Transaction.d.ts +10 -8
  77. package/internal/hardhat-network/provider/transactions/FakeSenderAccessListEIP2930Transaction.d.ts.map +1 -1
  78. package/internal/hardhat-network/provider/transactions/FakeSenderAccessListEIP2930Transaction.js +9 -9
  79. package/internal/hardhat-network/provider/transactions/FakeSenderAccessListEIP2930Transaction.js.map +1 -1
  80. package/internal/hardhat-network/provider/transactions/FakeSenderEIP1559Transaction.d.ts +10 -8
  81. package/internal/hardhat-network/provider/transactions/FakeSenderEIP1559Transaction.d.ts.map +1 -1
  82. package/internal/hardhat-network/provider/transactions/FakeSenderEIP1559Transaction.js +9 -9
  83. package/internal/hardhat-network/provider/transactions/FakeSenderEIP1559Transaction.js.map +1 -1
  84. package/internal/hardhat-network/provider/transactions/FakeSenderTransaction.d.ts +10 -9
  85. package/internal/hardhat-network/provider/transactions/FakeSenderTransaction.d.ts.map +1 -1
  86. package/internal/hardhat-network/provider/transactions/FakeSenderTransaction.js +7 -6
  87. package/internal/hardhat-network/provider/transactions/FakeSenderTransaction.js.map +1 -1
  88. package/internal/hardhat-network/provider/transactions/ReadOnlyValidEIP1559Transaction.d.ts +6 -5
  89. package/internal/hardhat-network/provider/transactions/ReadOnlyValidEIP1559Transaction.d.ts.map +1 -1
  90. package/internal/hardhat-network/provider/transactions/ReadOnlyValidEIP1559Transaction.js +1 -1
  91. package/internal/hardhat-network/provider/transactions/ReadOnlyValidEIP1559Transaction.js.map +1 -1
  92. package/internal/hardhat-network/provider/transactions/ReadOnlyValidEIP2930Transaction.d.ts +5 -4
  93. package/internal/hardhat-network/provider/transactions/ReadOnlyValidEIP2930Transaction.d.ts.map +1 -1
  94. package/internal/hardhat-network/provider/transactions/ReadOnlyValidEIP2930Transaction.js +1 -1
  95. package/internal/hardhat-network/provider/transactions/ReadOnlyValidEIP2930Transaction.js.map +1 -1
  96. package/internal/hardhat-network/provider/transactions/ReadOnlyValidTransaction.d.ts +8 -7
  97. package/internal/hardhat-network/provider/transactions/ReadOnlyValidTransaction.d.ts.map +1 -1
  98. package/internal/hardhat-network/provider/transactions/ReadOnlyValidTransaction.js +2 -2
  99. package/internal/hardhat-network/provider/transactions/ReadOnlyValidTransaction.js.map +1 -1
  100. package/internal/hardhat-network/provider/transactions/ReadOnlyValidUnknownTypeTransaction.d.ts +8 -7
  101. package/internal/hardhat-network/provider/transactions/ReadOnlyValidUnknownTypeTransaction.d.ts.map +1 -1
  102. package/internal/hardhat-network/provider/transactions/ReadOnlyValidUnknownTypeTransaction.js +2 -2
  103. package/internal/hardhat-network/provider/transactions/ReadOnlyValidUnknownTypeTransaction.js.map +1 -1
  104. package/internal/hardhat-network/provider/types/HardhatBlockchainInterface.d.ts +5 -4
  105. package/internal/hardhat-network/provider/types/HardhatBlockchainInterface.d.ts.map +1 -1
  106. package/internal/hardhat-network/provider/utils/convertToEdr.d.ts +14 -0
  107. package/internal/hardhat-network/provider/utils/convertToEdr.d.ts.map +1 -0
  108. package/internal/hardhat-network/provider/utils/convertToEdr.js +191 -0
  109. package/internal/hardhat-network/provider/utils/convertToEdr.js.map +1 -0
  110. package/internal/hardhat-network/provider/utils/getCurrentTimestamp.d.ts +0 -1
  111. package/internal/hardhat-network/provider/utils/getCurrentTimestamp.d.ts.map +1 -1
  112. package/internal/hardhat-network/provider/utils/getCurrentTimestamp.js +1 -5
  113. package/internal/hardhat-network/provider/utils/getCurrentTimestamp.js.map +1 -1
  114. package/internal/hardhat-network/provider/utils/makeCommon.d.ts +1 -1
  115. package/internal/hardhat-network/provider/utils/makeCommon.d.ts.map +1 -1
  116. package/internal/hardhat-network/provider/utils/makeCommon.js +1 -3
  117. package/internal/hardhat-network/provider/utils/makeCommon.js.map +1 -1
  118. package/internal/hardhat-network/provider/utils/makeFakeSignature.d.ts +2 -2
  119. package/internal/hardhat-network/provider/utils/makeFakeSignature.d.ts.map +1 -1
  120. package/internal/hardhat-network/provider/utils/makeFakeSignature.js +1 -15
  121. package/internal/hardhat-network/provider/utils/makeFakeSignature.js.map +1 -1
  122. package/internal/hardhat-network/provider/utils/makeForkClient.d.ts +10 -1
  123. package/internal/hardhat-network/provider/utils/makeForkClient.d.ts.map +1 -1
  124. package/internal/hardhat-network/provider/utils/makeForkClient.js +38 -18
  125. package/internal/hardhat-network/provider/utils/makeForkClient.js.map +1 -1
  126. package/internal/hardhat-network/provider/utils/makeStateTrie.js +2 -2
  127. package/internal/hardhat-network/provider/utils/makeStateTrie.js.map +1 -1
  128. package/internal/hardhat-network/provider/utils/putGenesisBlock.d.ts +3 -1
  129. package/internal/hardhat-network/provider/utils/putGenesisBlock.d.ts.map +1 -1
  130. package/internal/hardhat-network/provider/utils/putGenesisBlock.js +2 -6
  131. package/internal/hardhat-network/provider/utils/putGenesisBlock.js.map +1 -1
  132. package/internal/hardhat-network/provider/utils/random.d.ts +1 -0
  133. package/internal/hardhat-network/provider/utils/random.d.ts.map +1 -1
  134. package/internal/hardhat-network/provider/utils/random.js +7 -1
  135. package/internal/hardhat-network/provider/utils/random.js.map +1 -1
  136. package/internal/hardhat-network/provider/utils/reorgs-protection.d.ts +1 -1
  137. package/internal/hardhat-network/provider/utils/reorgs-protection.d.ts.map +1 -1
  138. package/internal/hardhat-network/provider/utils/reorgs-protection.js +5 -5
  139. package/internal/hardhat-network/provider/utils/reorgs-protection.js.map +1 -1
  140. package/internal/hardhat-network/provider/vm/exit.d.ts +22 -0
  141. package/internal/hardhat-network/provider/vm/exit.d.ts.map +1 -0
  142. package/internal/hardhat-network/provider/vm/exit.js +93 -0
  143. package/internal/hardhat-network/provider/vm/exit.js.map +1 -0
  144. package/internal/hardhat-network/provider/vm/minimal-vm.d.ts +29 -0
  145. package/internal/hardhat-network/provider/vm/minimal-vm.d.ts.map +1 -0
  146. package/internal/hardhat-network/provider/vm/minimal-vm.js +46 -0
  147. package/internal/hardhat-network/provider/vm/minimal-vm.js.map +1 -0
  148. package/internal/hardhat-network/provider/vm/proxy-vm.d.ts +36 -0
  149. package/internal/hardhat-network/provider/vm/proxy-vm.d.ts.map +1 -0
  150. package/internal/hardhat-network/provider/vm/proxy-vm.js +73 -0
  151. package/internal/hardhat-network/provider/vm/proxy-vm.js.map +1 -0
  152. package/internal/hardhat-network/provider/vm/types.d.ts +27 -0
  153. package/internal/hardhat-network/provider/vm/types.d.ts.map +1 -0
  154. package/internal/hardhat-network/provider/vm/types.js +3 -0
  155. package/internal/hardhat-network/provider/vm/types.js.map +1 -0
  156. package/internal/hardhat-network/stack-traces/consoleLogger.d.ts +6 -0
  157. package/internal/hardhat-network/stack-traces/consoleLogger.d.ts.map +1 -1
  158. package/internal/hardhat-network/stack-traces/consoleLogger.js +33 -16
  159. package/internal/hardhat-network/stack-traces/consoleLogger.js.map +1 -1
  160. package/internal/hardhat-network/stack-traces/contracts-identifier.d.ts +1 -2
  161. package/internal/hardhat-network/stack-traces/contracts-identifier.d.ts.map +1 -1
  162. package/internal/hardhat-network/stack-traces/contracts-identifier.js +6 -7
  163. package/internal/hardhat-network/stack-traces/contracts-identifier.js.map +1 -1
  164. package/internal/hardhat-network/stack-traces/debug.js +6 -6
  165. package/internal/hardhat-network/stack-traces/debug.js.map +1 -1
  166. package/internal/hardhat-network/stack-traces/error-inferrer.d.ts.map +1 -1
  167. package/internal/hardhat-network/stack-traces/error-inferrer.js +13 -7
  168. package/internal/hardhat-network/stack-traces/error-inferrer.js.map +1 -1
  169. package/internal/hardhat-network/stack-traces/message-trace.d.ts +8 -3
  170. package/internal/hardhat-network/stack-traces/message-trace.d.ts.map +1 -1
  171. package/internal/hardhat-network/stack-traces/message-trace.js +22 -1
  172. package/internal/hardhat-network/stack-traces/message-trace.js.map +1 -1
  173. package/internal/hardhat-network/stack-traces/model.d.ts +8 -0
  174. package/internal/hardhat-network/stack-traces/model.d.ts.map +1 -1
  175. package/internal/hardhat-network/stack-traces/model.js +52 -0
  176. package/internal/hardhat-network/stack-traces/model.js.map +1 -1
  177. package/internal/hardhat-network/stack-traces/opcodes.d.ts +1 -0
  178. package/internal/hardhat-network/stack-traces/opcodes.d.ts.map +1 -1
  179. package/internal/hardhat-network/stack-traces/opcodes.js +5 -1
  180. package/internal/hardhat-network/stack-traces/opcodes.js.map +1 -1
  181. package/internal/hardhat-network/stack-traces/solidity-errors.js +2 -2
  182. package/internal/hardhat-network/stack-traces/solidity-errors.js.map +1 -1
  183. package/internal/hardhat-network/stack-traces/solidityTracer.d.ts.map +1 -1
  184. package/internal/hardhat-network/stack-traces/solidityTracer.js +5 -5
  185. package/internal/hardhat-network/stack-traces/solidityTracer.js.map +1 -1
  186. package/internal/hardhat-network/stack-traces/vm-debug-tracer.d.ts.map +1 -1
  187. package/internal/hardhat-network/stack-traces/vm-debug-tracer.js +28 -34
  188. package/internal/hardhat-network/stack-traces/vm-debug-tracer.js.map +1 -1
  189. package/internal/hardhat-network/stack-traces/vm-trace-decoder.d.ts +7 -0
  190. package/internal/hardhat-network/stack-traces/vm-trace-decoder.d.ts.map +1 -1
  191. package/internal/hardhat-network/stack-traces/vm-trace-decoder.js +69 -2
  192. package/internal/hardhat-network/stack-traces/vm-trace-decoder.js.map +1 -1
  193. package/internal/hardhat-network/stack-traces/vm-tracer.d.ts +7 -12
  194. package/internal/hardhat-network/stack-traces/vm-tracer.d.ts.map +1 -1
  195. package/internal/hardhat-network/stack-traces/vm-tracer.js +46 -65
  196. package/internal/hardhat-network/stack-traces/vm-tracer.js.map +1 -1
  197. package/internal/util/date.d.ts +1 -0
  198. package/internal/util/date.d.ts.map +1 -1
  199. package/internal/util/date.js +5 -1
  200. package/internal/util/date.js.map +1 -1
  201. package/internal/util/hardforks.d.ts +2 -0
  202. package/internal/util/hardforks.d.ts.map +1 -1
  203. package/internal/util/hardforks.js +27 -1
  204. package/internal/util/hardforks.js.map +1 -1
  205. package/package.json +18 -16
  206. package/src/internal/core/providers/construction.ts +7 -9
  207. package/src/internal/core/providers/http.ts +3 -1
  208. package/src/internal/core/runtime-environment.ts +2 -1
  209. package/src/internal/hardhat-network/jsonrpc/client.ts +1 -28
  210. package/src/internal/hardhat-network/jsonrpc/handler.ts +9 -1
  211. package/src/internal/hardhat-network/provider/modules/logger.ts +6 -801
  212. package/src/internal/hardhat-network/provider/node-types.ts +2 -89
  213. package/src/internal/hardhat-network/provider/output.ts +0 -352
  214. package/src/internal/hardhat-network/provider/provider.ts +482 -263
  215. package/src/internal/hardhat-network/provider/utils/convertToEdr.ts +228 -0
  216. package/src/internal/hardhat-network/provider/utils/getCurrentTimestamp.ts +0 -4
  217. package/src/internal/hardhat-network/provider/utils/makeCommon.ts +1 -12
  218. package/src/internal/hardhat-network/provider/utils/makeForkClient.ts +63 -24
  219. package/src/internal/hardhat-network/provider/utils/random.ts +8 -1
  220. package/src/internal/hardhat-network/provider/utils/reorgs-protection.ts +5 -5
  221. package/src/internal/hardhat-network/provider/vm/exit.ts +101 -0
  222. package/src/internal/hardhat-network/provider/vm/minimal-vm.ts +101 -0
  223. package/src/internal/hardhat-network/provider/vm/types.ts +31 -0
  224. package/src/internal/hardhat-network/stack-traces/consoleLogger.ts +40 -21
  225. package/src/internal/hardhat-network/stack-traces/contracts-identifier.ts +10 -12
  226. package/src/internal/hardhat-network/stack-traces/debug.ts +6 -6
  227. package/src/internal/hardhat-network/stack-traces/error-inferrer.ts +15 -8
  228. package/src/internal/hardhat-network/stack-traces/message-trace.ts +40 -4
  229. package/src/internal/hardhat-network/stack-traces/model.ts +61 -0
  230. package/src/internal/hardhat-network/stack-traces/opcodes.ts +4 -0
  231. package/src/internal/hardhat-network/stack-traces/solidity-errors.ts +2 -2
  232. package/src/internal/hardhat-network/stack-traces/solidityTracer.ts +6 -5
  233. package/src/internal/hardhat-network/stack-traces/vm-trace-decoder.ts +113 -4
  234. package/src/internal/hardhat-network/stack-traces/vm-tracer.ts +67 -95
  235. package/src/internal/util/date.ts +4 -0
  236. package/src/internal/util/hardforks.ts +52 -0
  237. package/src/internal/hardhat-network/provider/BlockchainBase.ts +0 -185
  238. package/src/internal/hardhat-network/provider/BlockchainData.ts +0 -261
  239. package/src/internal/hardhat-network/provider/HardhatBlockchain.ts +0 -140
  240. package/src/internal/hardhat-network/provider/PoolState.ts +0 -48
  241. package/src/internal/hardhat-network/provider/TransactionQueue.ts +0 -158
  242. package/src/internal/hardhat-network/provider/TxPool.ts +0 -715
  243. package/src/internal/hardhat-network/provider/ethereumjs-workarounds.ts +0 -21
  244. package/src/internal/hardhat-network/provider/filter.ts +0 -142
  245. package/src/internal/hardhat-network/provider/fork/ForkBlockchain.ts +0 -433
  246. package/src/internal/hardhat-network/provider/fork/ForkStateManager.ts +0 -480
  247. package/src/internal/hardhat-network/provider/fork/rpcToBlockData.ts +0 -35
  248. package/src/internal/hardhat-network/provider/fork/rpcToTxData.ts +0 -44
  249. package/src/internal/hardhat-network/provider/modules/base.ts +0 -156
  250. package/src/internal/hardhat-network/provider/modules/debug.ts +0 -104
  251. package/src/internal/hardhat-network/provider/modules/eth.ts +0 -1781
  252. package/src/internal/hardhat-network/provider/modules/evm.ts +0 -249
  253. package/src/internal/hardhat-network/provider/modules/hardhat.ts +0 -481
  254. package/src/internal/hardhat-network/provider/modules/net.ts +0 -60
  255. package/src/internal/hardhat-network/provider/modules/personal.ts +0 -40
  256. package/src/internal/hardhat-network/provider/modules/web3.ts +0 -49
  257. package/src/internal/hardhat-network/provider/node.ts +0 -2999
  258. package/src/internal/hardhat-network/provider/transactions/FakeSenderAccessListEIP2930Transaction.ts +0 -226
  259. package/src/internal/hardhat-network/provider/transactions/FakeSenderEIP1559Transaction.ts +0 -224
  260. package/src/internal/hardhat-network/provider/transactions/FakeSenderTransaction.ts +0 -216
  261. package/src/internal/hardhat-network/provider/transactions/ReadOnlyValidEIP1559Transaction.ts +0 -143
  262. package/src/internal/hardhat-network/provider/transactions/ReadOnlyValidEIP2930Transaction.ts +0 -144
  263. package/src/internal/hardhat-network/provider/transactions/ReadOnlyValidTransaction.ts +0 -171
  264. package/src/internal/hardhat-network/provider/transactions/ReadOnlyValidUnknownTypeTransaction.ts +0 -169
  265. package/src/internal/hardhat-network/provider/types/HardhatBlockchainInterface.ts +0 -25
  266. package/src/internal/hardhat-network/provider/utils/makeFakeSignature.ts +0 -60
  267. package/src/internal/hardhat-network/provider/utils/makeStateTrie.ts +0 -29
  268. package/src/internal/hardhat-network/provider/utils/putGenesisBlock.ts +0 -61
  269. package/src/internal/hardhat-network/provider/utils/reorganizeTransactionsLists.ts +0 -45
  270. package/src/internal/hardhat-network/provider/utils/txMapToArray.ts +0 -7
  271. package/src/internal/hardhat-network/stack-traces/vm-debug-tracer.ts +0 -630
@@ -1,1781 +0,0 @@
1
- import { Block } from "@nomicfoundation/ethereumjs-block";
2
- import { Common } from "@nomicfoundation/ethereumjs-common";
3
- import {
4
- LegacyTransaction,
5
- TransactionFactory,
6
- TypedTransaction,
7
- } from "@nomicfoundation/ethereumjs-tx";
8
- import {
9
- Address,
10
- equalsBytes,
11
- toBytes,
12
- toRpcSig,
13
- } from "@nomicfoundation/ethereumjs-util";
14
- import * as t from "io-ts";
15
- import cloneDeep from "lodash/cloneDeep";
16
- import { BoundExperimentalHardhatNetworkMessageTraceHook } from "../../../../types";
17
- import {
18
- bufferToRpcData,
19
- numberToRpcQuantity,
20
- rpcAddress,
21
- rpcData,
22
- rpcFloat,
23
- rpcHash,
24
- rpcQuantity,
25
- rpcStorageSlot,
26
- } from "../../../core/jsonrpc/types/base-types";
27
- import {
28
- optionalRpcNewBlockTag,
29
- OptionalRpcNewBlockTag,
30
- OptionalRpcOldBlockTag,
31
- rpcNewBlockTag,
32
- RpcNewBlockTag,
33
- rpcOldBlockTag,
34
- RpcOldBlockTag,
35
- } from "../../../core/jsonrpc/types/input/blockTag";
36
- import {
37
- optionalStateOverrideSet,
38
- OptionalStateOverrideSet,
39
- rpcCallRequest,
40
- RpcCallRequest,
41
- } from "../../../core/jsonrpc/types/input/callRequest";
42
- import {
43
- optionalRpcFilterRequest,
44
- OptionalRpcFilterRequest,
45
- rpcFilterRequest,
46
- RpcFilterRequest,
47
- } from "../../../core/jsonrpc/types/input/filterRequest";
48
- import { OptionalRpcLogAddress } from "../../../core/jsonrpc/types/input/logAddress";
49
- import { OptionalRpcLogTopics } from "../../../core/jsonrpc/types/input/logTopics";
50
- import {
51
- rpcSubscribeRequest,
52
- RpcSubscribeRequest,
53
- } from "../../../core/jsonrpc/types/input/subscribeRequest";
54
- import {
55
- rpcTransactionRequest,
56
- RpcTransactionRequest,
57
- } from "../../../core/jsonrpc/types/input/transactionRequest";
58
- import { validateParams } from "../../../core/jsonrpc/types/input/validation";
59
- import {
60
- InvalidArgumentsError,
61
- InvalidInputError,
62
- MethodNotFoundError,
63
- MethodNotSupportedError,
64
- } from "../../../core/providers/errors";
65
- import { MessageTrace } from "../../stack-traces/message-trace";
66
- import { LATEST_BLOCK } from "../filter";
67
- import { HardhatNode } from "../node";
68
- import {
69
- FilterParams,
70
- GatherTracesResult,
71
- MineBlockResult,
72
- TransactionParams,
73
- } from "../node-types";
74
- import {
75
- getRpcBlock,
76
- getRpcTransaction,
77
- RpcBlockOutput,
78
- RpcLogOutput,
79
- RpcReceiptOutput,
80
- RpcTransactionOutput,
81
- shouldShowTransactionTypeForHardfork,
82
- } from "../output";
83
-
84
- import { assertHardhatNetworkInvariant } from "../utils/assertions";
85
- import { optional } from "../../../util/io-ts";
86
- import * as BigIntUtils from "../../../util/bigint";
87
- import { HardforkName } from "../../../util/hardforks";
88
- import { ModulesLogger } from "./logger";
89
- import { Base } from "./base";
90
-
91
- const EIP1559_MIN_HARDFORK = HardforkName.LONDON;
92
- const ACCESS_LIST_MIN_HARDFORK = HardforkName.BERLIN;
93
- const EIP155_MIN_HARDFORK = HardforkName.SPURIOUS_DRAGON;
94
- const EIP3860_MIN_HARDFORK = HardforkName.SHANGHAI;
95
-
96
- /* eslint-disable @nomicfoundation/hardhat-internal-rules/only-hardhat-error */
97
- export class EthModule extends Base {
98
- constructor(
99
- private readonly _common: Common,
100
- _node: HardhatNode,
101
- private readonly _throwOnTransactionFailures: boolean,
102
- private readonly _throwOnCallFailures: boolean,
103
- private readonly _logger: ModulesLogger,
104
- private readonly _experimentalHardhatNetworkMessageTraceHooks: BoundExperimentalHardhatNetworkMessageTraceHook[] = []
105
- ) {
106
- super(_node);
107
- }
108
-
109
- public async processRequest(
110
- method: string,
111
- params: any[] = []
112
- ): Promise<any> {
113
- switch (method) {
114
- case "eth_accounts":
115
- return this._accountsAction(...this._accountsParams(params));
116
-
117
- case "eth_blockNumber":
118
- return this._blockNumberAction(...this._blockNumberParams(params));
119
-
120
- case "eth_call":
121
- return this._callAction(...this._callParams(params));
122
-
123
- case "eth_chainId":
124
- return this._chainIdAction(...this._chainIdParams(params));
125
-
126
- case "eth_coinbase":
127
- return this._coinbaseAction(...this._coinbaseParams(params));
128
-
129
- case "eth_compileLLL":
130
- throw new MethodNotSupportedError(method);
131
-
132
- case "eth_compileSerpent":
133
- throw new MethodNotSupportedError(method);
134
-
135
- case "eth_compileSolidity":
136
- throw new MethodNotSupportedError(method);
137
-
138
- case "eth_estimateGas":
139
- return this._estimateGasAction(...this._estimateGasParams(params));
140
-
141
- case "eth_gasPrice":
142
- return this._gasPriceAction(...this._gasPriceParams(params));
143
-
144
- case "eth_getBalance":
145
- return this._getBalanceAction(...this._getBalanceParams(params));
146
-
147
- case "eth_getBlockByHash":
148
- return this._getBlockByHashAction(
149
- ...this._getBlockByHashParams(params)
150
- );
151
-
152
- case "eth_getBlockByNumber":
153
- return this._getBlockByNumberAction(
154
- ...this._getBlockByNumberParams(params)
155
- );
156
-
157
- case "eth_getBlockTransactionCountByHash":
158
- return this._getBlockTransactionCountByHashAction(
159
- ...this._getBlockTransactionCountByHashParams(params)
160
- );
161
-
162
- case "eth_getBlockTransactionCountByNumber":
163
- return this._getBlockTransactionCountByNumberAction(
164
- ...this._getBlockTransactionCountByNumberParams(params)
165
- );
166
-
167
- case "eth_getCode":
168
- return this._getCodeAction(...this._getCodeParams(params));
169
-
170
- case "eth_getCompilers":
171
- throw new MethodNotSupportedError(method);
172
-
173
- case "eth_getFilterChanges":
174
- return this._getFilterChangesAction(
175
- ...this._getFilterChangesParams(params)
176
- );
177
-
178
- case "eth_getFilterLogs":
179
- return this._getFilterLogsAction(...this._getFilterLogsParams(params));
180
-
181
- case "eth_getLogs":
182
- return this._getLogsAction(...this._getLogsParams(params));
183
-
184
- case "eth_getProof":
185
- throw new MethodNotSupportedError(method);
186
-
187
- case "eth_getStorageAt":
188
- return this._getStorageAtAction(...this._getStorageAtParams(params));
189
-
190
- case "eth_getTransactionByBlockHashAndIndex":
191
- return this._getTransactionByBlockHashAndIndexAction(
192
- ...this._getTransactionByBlockHashAndIndexParams(params)
193
- );
194
-
195
- case "eth_getTransactionByBlockNumberAndIndex":
196
- return this._getTransactionByBlockNumberAndIndexAction(
197
- ...this._getTransactionByBlockNumberAndIndexParams(params)
198
- );
199
-
200
- case "eth_getTransactionByHash":
201
- return this._getTransactionByHashAction(
202
- ...this._getTransactionByHashParams(params)
203
- );
204
-
205
- case "eth_getTransactionCount":
206
- return this._getTransactionCountAction(
207
- ...this._getTransactionCountParams(params)
208
- );
209
-
210
- case "eth_getTransactionReceipt":
211
- return this._getTransactionReceiptAction(
212
- ...this._getTransactionReceiptParams(params)
213
- );
214
-
215
- case "eth_getUncleByBlockHashAndIndex":
216
- throw new MethodNotSupportedError(method);
217
-
218
- case "eth_getUncleByBlockNumberAndIndex":
219
- throw new MethodNotSupportedError(method);
220
-
221
- case "eth_getUncleCountByBlockHash":
222
- throw new MethodNotSupportedError(method);
223
-
224
- case "eth_getUncleCountByBlockNumber":
225
- throw new MethodNotSupportedError(method);
226
-
227
- case "eth_getWork":
228
- throw new MethodNotSupportedError(method);
229
-
230
- case "eth_hashrate":
231
- throw new MethodNotSupportedError(method);
232
-
233
- case "eth_mining":
234
- return this._miningAction(...this._miningParams(params));
235
-
236
- case "eth_newBlockFilter":
237
- return this._newBlockFilterAction(
238
- ...this._newBlockFilterParams(params)
239
- );
240
-
241
- case "eth_newFilter":
242
- return this._newFilterAction(...this._newFilterParams(params));
243
-
244
- case "eth_newPendingTransactionFilter":
245
- return this._newPendingTransactionAction(
246
- ...this._newPendingTransactionParams(params)
247
- );
248
-
249
- case "eth_pendingTransactions":
250
- return this._pendingTransactionsAction(
251
- ...this._pendingTransactionsParams(params)
252
- );
253
-
254
- case "eth_protocolVersion":
255
- throw new MethodNotSupportedError(method);
256
-
257
- case "eth_sendRawTransaction":
258
- return this._sendRawTransactionAction(
259
- ...this._sendRawTransactionParams(params)
260
- );
261
-
262
- case "eth_sendTransaction":
263
- return this._sendTransactionAction(
264
- ...this._sendTransactionParams(params)
265
- );
266
-
267
- case "eth_sign":
268
- return this._signAction(...this._signParams(params));
269
-
270
- case "eth_signTransaction":
271
- throw new MethodNotSupportedError(method);
272
-
273
- case "eth_signTypedData":
274
- throw new MethodNotSupportedError(method);
275
-
276
- case "eth_signTypedData_v3":
277
- throw new MethodNotSupportedError(method);
278
-
279
- // TODO: we're currently mimicking the MetaMask implementation here.
280
- // The EIP 712 is still a draft. It doesn't actually distinguish different versions
281
- // of the eth_signTypedData API.
282
- // Also, note that go-ethereum implemented this in a clef JSON-RPC API: account_signTypedData.
283
- case "eth_signTypedData_v4":
284
- return this._signTypedDataV4Action(
285
- ...this._signTypedDataV4Params(params)
286
- );
287
-
288
- case "eth_submitHashrate":
289
- throw new MethodNotSupportedError(method);
290
-
291
- case "eth_submitWork":
292
- throw new MethodNotSupportedError(method);
293
-
294
- case "eth_subscribe":
295
- return this._subscribeAction(...this._subscribeParams(params));
296
-
297
- case "eth_syncing":
298
- return this._syncingAction(...this._syncingParams(params));
299
-
300
- case "eth_uninstallFilter":
301
- return this._uninstallFilterAction(
302
- ...this._uninstallFilterParams(params)
303
- );
304
-
305
- case "eth_unsubscribe":
306
- return this._unsubscribeAction(...this._unsubscribeParams(params));
307
-
308
- case "eth_feeHistory":
309
- return this._feeHistoryAction(...this._feeHistoryParams(params));
310
- }
311
-
312
- throw new MethodNotFoundError(`Method ${method} not found`);
313
- }
314
-
315
- // eth_accounts
316
-
317
- private _accountsParams(params: any[]): [] {
318
- return validateParams(params);
319
- }
320
-
321
- private async _accountsAction(): Promise<string[]> {
322
- return this._node.getLocalAccountAddresses();
323
- }
324
-
325
- // eth_blockNumber
326
-
327
- private _blockNumberParams(params: any[]): [] {
328
- return validateParams(params);
329
- }
330
-
331
- private async _blockNumberAction(): Promise<string> {
332
- const blockNumber = this._node.getLatestBlockNumber();
333
- return numberToRpcQuantity(blockNumber);
334
- }
335
-
336
- // eth_call
337
-
338
- private _callParams(
339
- params: any[]
340
- ): [RpcCallRequest, OptionalRpcNewBlockTag, OptionalStateOverrideSet] {
341
- return validateParams(
342
- params,
343
- rpcCallRequest,
344
- optionalRpcNewBlockTag,
345
- optionalStateOverrideSet
346
- );
347
- }
348
-
349
- private async _callAction(
350
- rpcCall: RpcCallRequest,
351
- blockTag: OptionalRpcNewBlockTag,
352
- stateOverrideSet: OptionalStateOverrideSet
353
- ): Promise<string> {
354
- this._validateTransactionAndCallRequest(rpcCall);
355
-
356
- const blockNumberOrPending = await this.resolveNewBlockTag(blockTag);
357
-
358
- const callParams = await this.rpcCallRequestToNodeCallParams(rpcCall);
359
-
360
- const {
361
- result: returnData,
362
- trace,
363
- error,
364
- consoleLogMessages,
365
- } = await this._node.runCall(
366
- callParams,
367
- blockNumberOrPending,
368
- stateOverrideSet
369
- );
370
-
371
- const code = await this._node.getCodeFromTrace(trace, blockNumberOrPending);
372
-
373
- this._logger.logCallTrace(
374
- callParams,
375
- code,
376
- trace,
377
- consoleLogMessages,
378
- error
379
- );
380
-
381
- await this._runHardhatNetworkMessageTraceHooks(trace, true);
382
-
383
- if (error !== undefined && this._throwOnCallFailures) {
384
- const callReturnData = Buffer.from(trace?.returnData ?? []).toString(
385
- "hex"
386
- );
387
- (error as any).data = `0x${callReturnData}`;
388
-
389
- throw error;
390
- }
391
-
392
- return bufferToRpcData(returnData.value);
393
- }
394
-
395
- // eth_chainId
396
-
397
- private _chainIdParams(params: any[]): [] {
398
- return validateParams(params);
399
- }
400
-
401
- private async _chainIdAction(): Promise<string> {
402
- return numberToRpcQuantity(this._common.chainId());
403
- }
404
-
405
- // eth_coinbase
406
-
407
- private _coinbaseParams(params: any[]): [] {
408
- return validateParams(params);
409
- }
410
-
411
- private async _coinbaseAction(): Promise<string> {
412
- return this._node.getCoinbaseAddress().toString();
413
- }
414
-
415
- // eth_compileLLL
416
-
417
- // eth_compileSerpent
418
-
419
- // eth_compileSolidity
420
-
421
- // eth_estimateGas
422
-
423
- private _estimateGasParams(
424
- params: any[]
425
- ): [RpcCallRequest, OptionalRpcNewBlockTag] {
426
- // Estimate gas uses a CallArgs in Geth, so we mimic it here
427
- return validateParams(params, rpcCallRequest, optionalRpcNewBlockTag);
428
- }
429
-
430
- private async _estimateGasAction(
431
- callRequest: RpcCallRequest,
432
- blockTag: OptionalRpcNewBlockTag
433
- ): Promise<string> {
434
- this._validateTransactionAndCallRequest(callRequest);
435
-
436
- // estimateGas behaves differently when there's no blockTag
437
- // it uses "pending" as default instead of "latest"
438
- const blockNumberOrPending = await this.resolveNewBlockTag(
439
- blockTag,
440
- "pending"
441
- );
442
-
443
- const callParams = await this.rpcCallRequestToNodeCallParams(callRequest);
444
-
445
- const { estimation, error, trace, consoleLogMessages } =
446
- await this._node.estimateGas(callParams, blockNumberOrPending);
447
-
448
- if (error !== undefined) {
449
- const code = await this._node.getCodeFromTrace(
450
- trace,
451
- blockNumberOrPending
452
- );
453
-
454
- this._logger.logEstimateGasTrace(
455
- callParams,
456
- code,
457
- trace,
458
- consoleLogMessages,
459
- error
460
- );
461
-
462
- const callReturnData = Buffer.from(trace?.returnData ?? []).toString(
463
- "hex"
464
- );
465
- (error as any).data = `0x${callReturnData}`;
466
-
467
- throw error;
468
- }
469
-
470
- return numberToRpcQuantity(estimation);
471
- }
472
-
473
- // eth_gasPrice
474
-
475
- private _gasPriceParams(params: any[]): [] {
476
- return validateParams(params);
477
- }
478
-
479
- private async _gasPriceAction(): Promise<string> {
480
- return numberToRpcQuantity(await this._node.getGasPrice());
481
- }
482
-
483
- // eth_getBalance
484
-
485
- private _getBalanceParams(params: any[]): [Buffer, OptionalRpcNewBlockTag] {
486
- return validateParams(params, rpcAddress, optionalRpcNewBlockTag);
487
- }
488
-
489
- private async _getBalanceAction(
490
- address: Buffer,
491
- blockTag: OptionalRpcNewBlockTag
492
- ): Promise<string> {
493
- const blockNumberOrPending = await this.resolveNewBlockTag(blockTag);
494
-
495
- return numberToRpcQuantity(
496
- await this._node.getAccountBalance(
497
- new Address(address),
498
- blockNumberOrPending
499
- )
500
- );
501
- }
502
-
503
- // eth_getBlockByHash
504
-
505
- private _getBlockByHashParams(params: any[]): [Buffer, boolean] {
506
- return validateParams(params, rpcHash, t.boolean);
507
- }
508
-
509
- private async _getBlockByHashAction(
510
- hash: Buffer,
511
- includeTransactions: boolean
512
- ): Promise<RpcBlockOutput | null> {
513
- const block = await this._node.getBlockByHash(hash);
514
- if (block === undefined) {
515
- return null;
516
- }
517
-
518
- const totalDifficulty = await this._node.getBlockTotalDifficulty(block);
519
-
520
- return getRpcBlock(
521
- block,
522
- totalDifficulty,
523
- shouldShowTransactionTypeForHardfork(this._common),
524
- includeTransactions
525
- );
526
- }
527
-
528
- // eth_getBlockByNumber
529
-
530
- private _getBlockByNumberParams(params: any[]): [RpcOldBlockTag, boolean] {
531
- return validateParams(params, rpcOldBlockTag, t.boolean);
532
- }
533
-
534
- private async _getBlockByNumberAction(
535
- oldBlockTag: RpcOldBlockTag,
536
- includeTransactions: boolean
537
- ): Promise<RpcBlockOutput | null> {
538
- const numberOrPending = await this._resolveOldBlockTag(oldBlockTag);
539
- if (numberOrPending === undefined) {
540
- return null;
541
- }
542
-
543
- let block: Block | undefined;
544
- let totalDifficulty: bigint | undefined;
545
-
546
- if (numberOrPending === "pending") {
547
- [block, totalDifficulty] =
548
- await this._node.getPendingBlockAndTotalDifficulty();
549
- } else {
550
- block = await this._node.getBlockByNumber(numberOrPending);
551
- if (block === undefined) {
552
- return null;
553
- }
554
-
555
- totalDifficulty = await this._node.getBlockTotalDifficulty(block);
556
- }
557
-
558
- return getRpcBlock(
559
- block,
560
- totalDifficulty,
561
- shouldShowTransactionTypeForHardfork(this._common),
562
- includeTransactions,
563
- numberOrPending === "pending"
564
- );
565
- }
566
-
567
- // eth_getBlockTransactionCountByHash
568
-
569
- private _getBlockTransactionCountByHashParams(params: any[]): [Buffer] {
570
- return validateParams(params, rpcHash);
571
- }
572
-
573
- private async _getBlockTransactionCountByHashAction(
574
- hash: Buffer
575
- ): Promise<string | null> {
576
- const block = await this._node.getBlockByHash(hash);
577
- if (block === undefined) {
578
- return null;
579
- }
580
-
581
- return numberToRpcQuantity(block.transactions.length);
582
- }
583
-
584
- // eth_getBlockTransactionCountByNumber
585
-
586
- private _getBlockTransactionCountByNumberParams(
587
- params: any[]
588
- ): [RpcOldBlockTag] {
589
- return validateParams(params, rpcOldBlockTag);
590
- }
591
-
592
- private async _getBlockTransactionCountByNumberAction(
593
- oldBlockTag: RpcOldBlockTag
594
- ): Promise<string | null> {
595
- const numberOrPending = await this._resolveOldBlockTag(oldBlockTag);
596
- if (numberOrPending === undefined) {
597
- return null;
598
- }
599
-
600
- const block = await this._node.getBlockByNumber(numberOrPending);
601
- if (block === undefined) {
602
- return null;
603
- }
604
-
605
- return numberToRpcQuantity(block.transactions.length);
606
- }
607
-
608
- // eth_getCode
609
-
610
- private _getCodeParams(params: any[]): [Buffer, OptionalRpcNewBlockTag] {
611
- return validateParams(params, rpcAddress, optionalRpcNewBlockTag);
612
- }
613
-
614
- private async _getCodeAction(
615
- address: Buffer,
616
- blockTag: OptionalRpcNewBlockTag
617
- ): Promise<string> {
618
- const blockNumberOrPending = await this.resolveNewBlockTag(blockTag);
619
-
620
- return bufferToRpcData(
621
- await this._node.getCode(new Address(address), blockNumberOrPending)
622
- );
623
- }
624
-
625
- // eth_getCompilers
626
-
627
- // eth_getFilterChanges
628
-
629
- private _getFilterChangesParams(params: any[]): [bigint] {
630
- return validateParams(params, rpcQuantity);
631
- }
632
-
633
- private async _getFilterChangesAction(
634
- filterId: bigint
635
- ): Promise<string[] | RpcLogOutput[] | null> {
636
- const changes = await this._node.getFilterChanges(filterId);
637
- if (changes === undefined) {
638
- return null;
639
- }
640
-
641
- return changes;
642
- }
643
-
644
- // eth_getFilterLogs
645
-
646
- private _getFilterLogsParams(params: any[]): [bigint] {
647
- return validateParams(params, rpcQuantity);
648
- }
649
-
650
- private async _getFilterLogsAction(
651
- filterId: bigint
652
- ): Promise<RpcLogOutput[] | null> {
653
- const changes = await this._node.getFilterLogs(filterId);
654
- if (changes === undefined) {
655
- return null;
656
- }
657
-
658
- return changes;
659
- }
660
-
661
- // eth_getLogs
662
-
663
- private _getLogsParams(params: any[]): [RpcFilterRequest] {
664
- return validateParams(params, rpcFilterRequest);
665
- }
666
-
667
- private async _rpcFilterRequestToGetLogsParams(
668
- filter: RpcFilterRequest
669
- ): Promise<FilterParams> {
670
- if (filter.blockHash !== undefined) {
671
- if (filter.fromBlock !== undefined || filter.toBlock !== undefined) {
672
- throw new InvalidArgumentsError(
673
- "blockHash is mutually exclusive with fromBlock/toBlock"
674
- );
675
- }
676
-
677
- const block = await this._node.getBlockByHash(filter.blockHash);
678
- if (block === undefined) {
679
- throw new InvalidArgumentsError("blockHash cannot be found");
680
- }
681
-
682
- filter.fromBlock = block.header.number;
683
- filter.toBlock = block.header.number;
684
- }
685
-
686
- const [fromBlock, toBlock] = await Promise.all([
687
- this._normalizeOldBlockTagForFilterRequest(filter.fromBlock),
688
- this._normalizeOldBlockTagForFilterRequest(filter.toBlock),
689
- ]);
690
-
691
- return {
692
- fromBlock,
693
- toBlock,
694
- normalizedTopics: this._extractNormalizedLogTopics(filter.topics),
695
- addresses: this._extractLogAddresses(filter.address),
696
- };
697
- }
698
-
699
- private async _getLogsAction(
700
- filter: RpcFilterRequest
701
- ): Promise<RpcLogOutput[]> {
702
- const filterParams = await this._rpcFilterRequestToGetLogsParams(filter);
703
- const logs = await this._node.getLogs(filterParams);
704
- return cloneDeep(logs);
705
- }
706
-
707
- // eth_getProof
708
-
709
- // eth_getStorageAt
710
-
711
- private _getStorageAtParams(
712
- params: any[]
713
- ): [Buffer, bigint, OptionalRpcNewBlockTag] {
714
- return validateParams(
715
- params,
716
- rpcAddress,
717
- rpcStorageSlot,
718
- optionalRpcNewBlockTag
719
- );
720
- }
721
-
722
- private async _getStorageAtAction(
723
- address: Buffer,
724
- slot: bigint,
725
- blockTag: OptionalRpcNewBlockTag
726
- ): Promise<string> {
727
- const blockNumberOrPending = await this.resolveNewBlockTag(blockTag);
728
-
729
- const data = await this._node.getStorageAt(
730
- new Address(address),
731
- slot,
732
- blockNumberOrPending
733
- );
734
-
735
- return bufferToRpcData(data);
736
- }
737
-
738
- // eth_getTransactionByBlockHashAndIndex
739
-
740
- private _getTransactionByBlockHashAndIndexParams(
741
- params: any[]
742
- ): [Buffer, bigint] {
743
- return validateParams(params, rpcHash, rpcQuantity);
744
- }
745
-
746
- private async _getTransactionByBlockHashAndIndexAction(
747
- hash: Buffer,
748
- index: bigint
749
- ): Promise<RpcTransactionOutput | null> {
750
- const i = Number(index);
751
- const block = await this._node.getBlockByHash(hash);
752
- if (block === undefined) {
753
- return null;
754
- }
755
-
756
- const tx = block.transactions[i];
757
- if (tx === undefined) {
758
- return null;
759
- }
760
-
761
- return getRpcTransaction(
762
- tx,
763
- shouldShowTransactionTypeForHardfork(this._common),
764
- block,
765
- i
766
- );
767
- }
768
-
769
- // eth_getTransactionByBlockNumberAndIndex
770
-
771
- private _getTransactionByBlockNumberAndIndexParams(
772
- params: any[]
773
- ): [RpcOldBlockTag, bigint] {
774
- return validateParams(params, rpcOldBlockTag, rpcQuantity);
775
- }
776
-
777
- private async _getTransactionByBlockNumberAndIndexAction(
778
- oldBlockTag: RpcOldBlockTag,
779
- index: bigint
780
- ): Promise<RpcTransactionOutput | null> {
781
- const numberOrPending = await this._resolveOldBlockTag(oldBlockTag);
782
- if (numberOrPending === undefined) {
783
- return null;
784
- }
785
-
786
- const block = await this._node.getBlockByNumber(numberOrPending);
787
- const i = Number(index);
788
-
789
- if (block === undefined) {
790
- return null;
791
- }
792
-
793
- const tx = block.transactions[i];
794
- if (tx === undefined) {
795
- return null;
796
- }
797
-
798
- const showTransactionType = shouldShowTransactionTypeForHardfork(
799
- this._common
800
- );
801
-
802
- return numberOrPending === "pending"
803
- ? getRpcTransaction(tx, showTransactionType, "pending")
804
- : getRpcTransaction(tx, showTransactionType, block, i);
805
- }
806
-
807
- // eth_getTransactionByHash
808
-
809
- private _getTransactionByHashParams(params: any[]): [Buffer] {
810
- return validateParams(params, rpcHash);
811
- }
812
-
813
- private async _getTransactionByHashAction(
814
- hash: Buffer
815
- ): Promise<RpcTransactionOutput | null> {
816
- const pendingTx = await this._node.getPendingTransaction(hash);
817
- if (pendingTx !== undefined) {
818
- return getRpcTransaction(
819
- pendingTx,
820
- shouldShowTransactionTypeForHardfork(this._common),
821
- "pending"
822
- );
823
- }
824
-
825
- const block = await this._node.getBlockByTransactionHash(hash);
826
- if (block === undefined) {
827
- return null;
828
- }
829
-
830
- const index = block.transactions.findIndex((btx) =>
831
- equalsBytes(btx.hash(), hash)
832
- );
833
- const tx = block.transactions[index];
834
- if (tx === undefined) {
835
- throw new Error(
836
- "Transaction not found in the saved block, this should never happen"
837
- );
838
- }
839
-
840
- return getRpcTransaction(
841
- tx,
842
- shouldShowTransactionTypeForHardfork(this._common),
843
- block,
844
- index
845
- );
846
- }
847
-
848
- // eth_getTransactionCount
849
-
850
- private _getTransactionCountParams(
851
- params: any[]
852
- ): [Buffer, OptionalRpcNewBlockTag] {
853
- return validateParams(params, rpcAddress, optionalRpcNewBlockTag);
854
- }
855
-
856
- private async _getTransactionCountAction(
857
- address: Buffer,
858
- blockTag: OptionalRpcNewBlockTag
859
- ): Promise<string> {
860
- const blockNumberOrPending = await this.resolveNewBlockTag(blockTag);
861
-
862
- return numberToRpcQuantity(
863
- await this._node.getNextConfirmedNonce(
864
- new Address(address),
865
- blockNumberOrPending
866
- )
867
- );
868
- }
869
-
870
- // eth_getTransactionReceipt
871
-
872
- private _getTransactionReceiptParams(params: any[]): [Buffer] {
873
- return validateParams(params, rpcHash);
874
- }
875
-
876
- private async _getTransactionReceiptAction(
877
- hash: Buffer
878
- ): Promise<RpcReceiptOutput | null> {
879
- const receipt = await this._node.getTransactionReceipt(hash);
880
- if (receipt === undefined) {
881
- return null;
882
- }
883
- return cloneDeep(receipt);
884
- }
885
-
886
- // eth_getUncleByBlockHashAndIndex
887
-
888
- // TODO: Implement
889
-
890
- // eth_getUncleByBlockNumberAndIndex
891
-
892
- // TODO: Implement
893
-
894
- // eth_getUncleCountByBlockHash
895
-
896
- // TODO: Implement
897
-
898
- // eth_getUncleCountByBlockNumber
899
-
900
- // TODO: Implement
901
-
902
- // eth_getWork
903
-
904
- // eth_hashrate
905
-
906
- // eth_mining
907
-
908
- private _miningParams(params: any[]): [] {
909
- return validateParams(params);
910
- }
911
-
912
- private async _miningAction(): Promise<boolean> {
913
- return false;
914
- }
915
-
916
- // eth_newBlockFilter
917
-
918
- private _newBlockFilterParams(_params: any[]): [] {
919
- return [];
920
- }
921
-
922
- private async _newBlockFilterAction(): Promise<string> {
923
- const filterId = await this._node.newBlockFilter(false);
924
- return numberToRpcQuantity(filterId);
925
- }
926
-
927
- // eth_newFilter
928
-
929
- private _newFilterParams(params: any[]): [RpcFilterRequest] {
930
- return validateParams(params, rpcFilterRequest);
931
- }
932
-
933
- private async _newFilterAction(filter: RpcFilterRequest): Promise<string> {
934
- const filterParams = await this._rpcFilterRequestToGetLogsParams(filter);
935
- const filterId = await this._node.newFilter(filterParams, false);
936
- return numberToRpcQuantity(filterId);
937
- }
938
-
939
- // eth_newPendingTransactionFilter
940
-
941
- private _newPendingTransactionParams(_params: any[]): [] {
942
- return [];
943
- }
944
-
945
- private async _newPendingTransactionAction(): Promise<string> {
946
- const filterId = await this._node.newPendingTransactionFilter(false);
947
- return numberToRpcQuantity(filterId);
948
- }
949
-
950
- // eth_pendingTransactions
951
-
952
- private _pendingTransactionsParams(_params: any[]): [] {
953
- return [];
954
- }
955
-
956
- private async _pendingTransactionsAction(): Promise<RpcTransactionOutput[]> {
957
- const txs = await this._node.getPendingTransactions();
958
- return txs.map((tx) =>
959
- getRpcTransaction(
960
- tx,
961
- shouldShowTransactionTypeForHardfork(this._common),
962
- "pending"
963
- )
964
- );
965
- }
966
-
967
- // eth_protocolVersion
968
-
969
- // eth_sendRawTransaction
970
-
971
- private _sendRawTransactionParams(params: any[]): [Buffer] {
972
- return validateParams(params, rpcData);
973
- }
974
-
975
- private async _sendRawTransactionAction(rawTx: Buffer): Promise<string> {
976
- this._validateRawTransactionHardforkRequirements(rawTx);
977
-
978
- let tx: TypedTransaction;
979
- try {
980
- tx = TransactionFactory.fromSerializedData(rawTx, {
981
- common: this._common,
982
- allowUnlimitedInitCodeSize: true,
983
- });
984
-
985
- this._validateEip3860MaxInitCodeSize(tx.to?.toBytes(), tx.data);
986
- } catch (error) {
987
- // This section of the code is incredibly dependant of TransactionFactory.fromSerializedData
988
- // AccessListEIP2930Transaction.fromSerializedTx and Transaction.fromSerializedTx
989
- // Please keep it updated.
990
-
991
- if (error instanceof Error) {
992
- if (error.message === "invalid RLP: remainder must be zero") {
993
- throw new InvalidArgumentsError("Invalid transaction", error);
994
- }
995
-
996
- if (error.message.includes("Incompatible EIP155")) {
997
- throw new InvalidArgumentsError(
998
- "Trying to send an incompatible EIP-155 transaction, signed for another chain.",
999
- error
1000
- );
1001
- }
1002
-
1003
- if (
1004
- error.message.includes("TypedTransaction with ID") &&
1005
- error.message.includes(" unknown")
1006
- ) {
1007
- throw new InvalidArgumentsError(`Invalid transaction`, error);
1008
- }
1009
-
1010
- if (error.message.includes("The chain ID does not match")) {
1011
- const chainId = this._common.chainId();
1012
- throw new InvalidArgumentsError(
1013
- `Trying to send a raw transaction with an invalid chainId. The expected chainId is ${chainId}`,
1014
- error
1015
- );
1016
- }
1017
- }
1018
-
1019
- throw error;
1020
- }
1021
-
1022
- if (!tx.isSigned()) {
1023
- throw new InvalidArgumentsError("Invalid Signature");
1024
- }
1025
-
1026
- if (tx instanceof LegacyTransaction) {
1027
- this._validateEip155HardforkRequirement(tx);
1028
- }
1029
-
1030
- return this._sendTransactionAndReturnHash(tx);
1031
- }
1032
-
1033
- // eth_sendTransaction
1034
-
1035
- private _sendTransactionParams(params: any[]): [RpcTransactionRequest] {
1036
- return validateParams(params, rpcTransactionRequest);
1037
- }
1038
-
1039
- private async _sendTransactionAction(
1040
- transactionRequest: RpcTransactionRequest
1041
- ): Promise<string> {
1042
- this._validateEip3860MaxInitCodeSize(
1043
- transactionRequest.to,
1044
- transactionRequest.data ?? Buffer.from([])
1045
- );
1046
-
1047
- const expectedChainId = this._common.chainId();
1048
- if (
1049
- transactionRequest.chainId !== undefined &&
1050
- transactionRequest.chainId !== expectedChainId
1051
- ) {
1052
- throw new InvalidArgumentsError(
1053
- `Invalid chainId ${transactionRequest.chainId.toString()} provided, expected ${expectedChainId.toString()} instead.`
1054
- );
1055
- }
1056
-
1057
- this._validateTransactionAndCallRequest(transactionRequest);
1058
-
1059
- const txParams = await this._rpcTransactionRequestToNodeTransactionParams(
1060
- transactionRequest
1061
- );
1062
-
1063
- const tx = await this._node.getSignedTransaction(txParams);
1064
-
1065
- return this._sendTransactionAndReturnHash(tx);
1066
- }
1067
-
1068
- // eth_sign
1069
-
1070
- private _signParams(params: any[]): [Buffer, Buffer] {
1071
- return validateParams(params, rpcAddress, rpcData);
1072
- }
1073
-
1074
- private async _signAction(address: Buffer, data: Buffer): Promise<string> {
1075
- const signature = await this._node.signPersonalMessage(
1076
- new Address(address),
1077
- data
1078
- );
1079
-
1080
- return toRpcSig(signature.v, signature.r, signature.s);
1081
- }
1082
-
1083
- // eth_signTransaction
1084
-
1085
- // eth_signTypedData_v4
1086
-
1087
- private _signTypedDataV4Params(params: any[]): [Buffer, any] {
1088
- // Validation of the TypedData parameter is handled by eth-sig-util
1089
- return validateParams(params, rpcAddress, t.any);
1090
- }
1091
-
1092
- private async _signTypedDataV4Action(
1093
- address: Buffer,
1094
- typedData: any
1095
- ): Promise<string> {
1096
- let typedMessage: any = typedData;
1097
-
1098
- // According to the MetaMask implementation,
1099
- // the message parameter may be JSON stringified in versions later than V1
1100
- // See https://github.com/MetaMask/metamask-extension/blob/0dfdd44ae7728ed02cbf32c564c75b74f37acf77/app/scripts/metamask-controller.js#L1736
1101
- // In fact, ethers.js JSON stringifies the message at the time of writing.
1102
- if (typeof typedData === "string") {
1103
- try {
1104
- typedMessage = JSON.parse(typedData);
1105
- } catch {
1106
- throw new InvalidInputError(
1107
- `The message parameter is an invalid JSON. Either pass a valid JSON or a plain object conforming to EIP712 TypedData schema.`
1108
- );
1109
- }
1110
- }
1111
-
1112
- return this._node.signTypedDataV4(new Address(address), typedMessage);
1113
- }
1114
-
1115
- // eth_submitHashrate
1116
-
1117
- // eth_submitWork
1118
-
1119
- private _subscribeParams(
1120
- params: any[]
1121
- ): [RpcSubscribeRequest, OptionalRpcFilterRequest] {
1122
- if (params.length === 0) {
1123
- throw new InvalidInputError(
1124
- "Expected subscription name as first argument"
1125
- );
1126
- }
1127
-
1128
- return validateParams(
1129
- params,
1130
- rpcSubscribeRequest,
1131
- optionalRpcFilterRequest
1132
- );
1133
- }
1134
-
1135
- private async _subscribeAction(
1136
- subscribeRequest: RpcSubscribeRequest,
1137
- optionalFilterRequest: OptionalRpcFilterRequest
1138
- ): Promise<string> {
1139
- switch (subscribeRequest) {
1140
- case "newHeads":
1141
- return numberToRpcQuantity(await this._node.newBlockFilter(true));
1142
- case "newPendingTransactions":
1143
- return numberToRpcQuantity(
1144
- await this._node.newPendingTransactionFilter(true)
1145
- );
1146
- case "logs":
1147
- if (optionalFilterRequest === undefined) {
1148
- throw new InvalidArgumentsError("missing params argument");
1149
- }
1150
-
1151
- const filterParams = await this._rpcFilterRequestToGetLogsParams(
1152
- optionalFilterRequest
1153
- );
1154
-
1155
- return numberToRpcQuantity(
1156
- await this._node.newFilter(filterParams, true)
1157
- );
1158
- }
1159
- }
1160
-
1161
- // eth_syncing
1162
-
1163
- private _syncingParams(params: any[]): [] {
1164
- return validateParams(params);
1165
- }
1166
-
1167
- private async _syncingAction(): Promise<boolean> {
1168
- return false;
1169
- }
1170
-
1171
- // eth_uninstallFilter
1172
-
1173
- private _uninstallFilterParams(params: any): [bigint] {
1174
- return validateParams(params, rpcQuantity);
1175
- }
1176
-
1177
- private async _uninstallFilterAction(filterId: bigint): Promise<boolean> {
1178
- return this._node.uninstallFilter(filterId, false);
1179
- }
1180
-
1181
- // eth_unsubscribe
1182
-
1183
- private _unsubscribeParams(params: any[]): [bigint] {
1184
- return validateParams(params, rpcQuantity);
1185
- }
1186
-
1187
- private async _unsubscribeAction(filterId: bigint): Promise<boolean> {
1188
- return this._node.uninstallFilter(filterId, true);
1189
- }
1190
-
1191
- // eth_feeHistory
1192
-
1193
- private _feeHistoryParams(
1194
- params: any[]
1195
- ): [bigint, RpcNewBlockTag, number[] | undefined] {
1196
- const [blockCount, newestBlock, rewardPercentiles] = validateParams(
1197
- params,
1198
- rpcQuantity,
1199
- rpcNewBlockTag,
1200
- optional(t.array(rpcFloat))
1201
- );
1202
-
1203
- if (blockCount < 1n) {
1204
- throw new InvalidInputError(`blockCount should be at least 1`);
1205
- }
1206
-
1207
- if (blockCount > 1024n) {
1208
- throw new InvalidInputError(`blockCount should be at most 1024`);
1209
- }
1210
-
1211
- if (rewardPercentiles !== undefined) {
1212
- for (const [i, p] of rewardPercentiles.entries()) {
1213
- if (p < 0 || p > 100) {
1214
- throw new InvalidInputError(
1215
- `The reward percentile number ${
1216
- i + 1
1217
- } is invalid. It must be a float between 0 and 100, but is ${p} instead.`
1218
- );
1219
- }
1220
-
1221
- if (i !== 0) {
1222
- const prev = rewardPercentiles[i - 1];
1223
- if (prev > p) {
1224
- throw new InvalidInputError(
1225
- `The reward percentiles should be in non-decreasing order, but the percentile number ${i} is greater than the next one`
1226
- );
1227
- }
1228
- }
1229
- }
1230
- }
1231
-
1232
- return [blockCount, newestBlock, rewardPercentiles];
1233
- }
1234
-
1235
- private async _feeHistoryAction(
1236
- blockCount: bigint,
1237
- newestBlock: RpcNewBlockTag,
1238
- rewardPercentiles?: number[]
1239
- ) {
1240
- if (!this._node.isEip1559Active()) {
1241
- throw new InvalidInputError(
1242
- `eth_feeHistory is disabled. It only works with the London hardfork or a later one.`
1243
- );
1244
- }
1245
-
1246
- const resolvedNewestBlock = await this.resolveNewBlockTag(newestBlock);
1247
-
1248
- const feeHistory = await this._node.getFeeHistory(
1249
- blockCount,
1250
- resolvedNewestBlock,
1251
- rewardPercentiles ?? []
1252
- );
1253
-
1254
- const oldestBlock = numberToRpcQuantity(feeHistory.oldestBlock);
1255
- const baseFeePerGas = feeHistory.baseFeePerGas.map(numberToRpcQuantity);
1256
- const gasUsedRatio = feeHistory.gasUsedRatio;
1257
- const reward = feeHistory.reward?.map((rs) => rs.map(numberToRpcQuantity));
1258
-
1259
- return {
1260
- oldestBlock,
1261
- baseFeePerGas,
1262
- gasUsedRatio,
1263
- reward,
1264
- };
1265
- }
1266
-
1267
- // Utility methods
1268
-
1269
- private async _rpcTransactionRequestToNodeTransactionParams(
1270
- rpcTx: RpcTransactionRequest
1271
- ): Promise<TransactionParams> {
1272
- const baseParams = {
1273
- to: rpcTx.to,
1274
- from: rpcTx.from,
1275
- gasLimit:
1276
- rpcTx.gas !== undefined ? rpcTx.gas : this._node.getBlockGasLimit(),
1277
- value: rpcTx.value !== undefined ? rpcTx.value : 0n,
1278
- data: rpcTx.data !== undefined ? rpcTx.data : toBytes([]),
1279
- nonce:
1280
- rpcTx.nonce !== undefined
1281
- ? rpcTx.nonce
1282
- : await this._node.getAccountNextPendingNonce(
1283
- new Address(rpcTx.from)
1284
- ),
1285
- };
1286
-
1287
- if (
1288
- this._node.isEip1559Active() &&
1289
- (rpcTx.maxFeePerGas !== undefined ||
1290
- rpcTx.maxPriorityFeePerGas !== undefined ||
1291
- rpcTx.gasPrice === undefined)
1292
- ) {
1293
- const accessList =
1294
- rpcTx.accessList !== undefined
1295
- ? this._rpcAccessListToNodeAccessList(rpcTx.accessList)
1296
- : [];
1297
-
1298
- if (rpcTx.maxPriorityFeePerGas === undefined) {
1299
- rpcTx.maxPriorityFeePerGas = await this._node.getMaxPriorityFeePerGas();
1300
-
1301
- // If you only provide a maxFeePerGas, and the suggested tip is higher
1302
- // than that, we adjust the tip to make the tx valid
1303
- if (
1304
- rpcTx.maxFeePerGas !== undefined &&
1305
- rpcTx.maxFeePerGas < rpcTx.maxPriorityFeePerGas
1306
- ) {
1307
- rpcTx.maxPriorityFeePerGas = rpcTx.maxFeePerGas;
1308
- }
1309
- }
1310
-
1311
- if (rpcTx.maxFeePerGas === undefined) {
1312
- const baseFeePerGas = await this._node.getNextBlockBaseFeePerGas();
1313
-
1314
- assertHardhatNetworkInvariant(
1315
- baseFeePerGas !== undefined,
1316
- "EIP-1559 transactions should only be sent if the next block has baseFeePerGas"
1317
- );
1318
-
1319
- rpcTx.maxFeePerGas = 2n * baseFeePerGas + rpcTx.maxPriorityFeePerGas;
1320
- }
1321
-
1322
- return {
1323
- ...baseParams,
1324
- maxFeePerGas: rpcTx.maxFeePerGas,
1325
- maxPriorityFeePerGas: rpcTx.maxPriorityFeePerGas,
1326
- accessList,
1327
- };
1328
- }
1329
-
1330
- const gasPrice = rpcTx.gasPrice ?? (await this._node.getGasPrice());
1331
-
1332
- // AccessList params
1333
- if (rpcTx.accessList !== undefined) {
1334
- return {
1335
- ...baseParams,
1336
- gasPrice,
1337
- accessList: this._rpcAccessListToNodeAccessList(rpcTx.accessList),
1338
- };
1339
- }
1340
-
1341
- // Legacy params
1342
- return {
1343
- ...baseParams,
1344
- gasPrice,
1345
- };
1346
- }
1347
-
1348
- private async _resolveOldBlockTag(
1349
- oldBlockTag: RpcOldBlockTag
1350
- ): Promise<bigint | "pending" | undefined> {
1351
- if (oldBlockTag === undefined || oldBlockTag === "latest") {
1352
- return this._node.getLatestBlockNumber();
1353
- }
1354
-
1355
- if (oldBlockTag === "pending") {
1356
- return "pending";
1357
- }
1358
-
1359
- if (oldBlockTag === "earliest") {
1360
- return 0n;
1361
- }
1362
-
1363
- if (oldBlockTag === "safe" || oldBlockTag === "finalized") {
1364
- this._checkPostMergeBlockTags(oldBlockTag);
1365
-
1366
- return this._node.getLatestBlockNumber();
1367
- }
1368
-
1369
- const block = await this._node.getBlockByNumber(oldBlockTag);
1370
- return block?.header.number;
1371
- }
1372
-
1373
- private async _resolveNewBlockTag(
1374
- newBlockTag: OptionalRpcNewBlockTag,
1375
- defaultValue: RpcNewBlockTag = "latest"
1376
- ): Promise<bigint | "pending"> {
1377
- if (newBlockTag === undefined) {
1378
- newBlockTag = defaultValue;
1379
- }
1380
-
1381
- if (newBlockTag === "pending") {
1382
- return "pending";
1383
- }
1384
-
1385
- if (newBlockTag === "latest") {
1386
- return this._node.getLatestBlockNumber();
1387
- }
1388
-
1389
- if (newBlockTag === "earliest") {
1390
- return 0n;
1391
- }
1392
-
1393
- if (newBlockTag === "safe" || newBlockTag === "finalized") {
1394
- this._checkPostMergeBlockTags(newBlockTag);
1395
-
1396
- return this._node.getLatestBlockNumber();
1397
- }
1398
-
1399
- if (!BigIntUtils.isBigInt(newBlockTag)) {
1400
- if ("blockNumber" in newBlockTag && "blockHash" in newBlockTag) {
1401
- throw new InvalidArgumentsError(
1402
- "Invalid block tag received. Only one of hash or block number can be used."
1403
- );
1404
- }
1405
-
1406
- if ("blockNumber" in newBlockTag && "requireCanonical" in newBlockTag) {
1407
- throw new InvalidArgumentsError(
1408
- "Invalid block tag received. requireCanonical only works with hashes."
1409
- );
1410
- }
1411
- }
1412
-
1413
- let block: Block | undefined;
1414
- if (BigIntUtils.isBigInt(newBlockTag)) {
1415
- block = await this._node.getBlockByNumber(newBlockTag);
1416
- } else if ("blockNumber" in newBlockTag) {
1417
- block = await this._node.getBlockByNumber(newBlockTag.blockNumber);
1418
- } else {
1419
- block = await this._node.getBlockByHash(newBlockTag.blockHash);
1420
- }
1421
-
1422
- if (block === undefined) {
1423
- const latestBlock = this._node.getLatestBlockNumber();
1424
-
1425
- throw new InvalidInputError(
1426
- `Received invalid block tag ${this._newBlockTagToString(
1427
- newBlockTag
1428
- )}. Latest block number is ${latestBlock.toString()}`
1429
- );
1430
- }
1431
-
1432
- return block.header.number;
1433
- }
1434
-
1435
- private async _normalizeOldBlockTagForFilterRequest(
1436
- blockTag: OptionalRpcOldBlockTag
1437
- ): Promise<bigint> {
1438
- if (
1439
- blockTag === undefined ||
1440
- blockTag === "latest" ||
1441
- blockTag === "pending"
1442
- ) {
1443
- return LATEST_BLOCK;
1444
- }
1445
-
1446
- if (blockTag === "safe" || blockTag === "finalized") {
1447
- this._checkPostMergeBlockTags(blockTag);
1448
-
1449
- return LATEST_BLOCK;
1450
- }
1451
-
1452
- if (blockTag === "earliest") {
1453
- return 0n;
1454
- }
1455
-
1456
- return blockTag;
1457
- }
1458
-
1459
- private _extractNormalizedLogTopics(
1460
- topics: OptionalRpcLogTopics
1461
- ): Array<Array<Buffer | null> | null> {
1462
- if (topics === undefined || topics.length === 0) {
1463
- return [];
1464
- }
1465
-
1466
- const normalizedTopics: Array<Array<Buffer | null> | null> = [];
1467
- for (const topic of topics) {
1468
- if (Buffer.isBuffer(topic)) {
1469
- normalizedTopics.push([topic]);
1470
- } else {
1471
- normalizedTopics.push(topic);
1472
- }
1473
- }
1474
-
1475
- return normalizedTopics;
1476
- }
1477
-
1478
- private _extractLogAddresses(address: OptionalRpcLogAddress): Buffer[] {
1479
- if (address === undefined) {
1480
- return [];
1481
- }
1482
-
1483
- if (Buffer.isBuffer(address)) {
1484
- return [address];
1485
- }
1486
-
1487
- return address;
1488
- }
1489
-
1490
- private async _sendTransactionAndReturnHash(tx: TypedTransaction) {
1491
- let result = await this._node.sendTransaction(tx);
1492
-
1493
- if (typeof result === "string") {
1494
- return result;
1495
- }
1496
-
1497
- if (Array.isArray(result)) {
1498
- if (result.length === 1 && result[0].block.transactions.length > 1) {
1499
- this._logger.logMultipleTransactionsWarning();
1500
- } else if (result.length > 1) {
1501
- this._logger.logMultipleBlocksWarning();
1502
- }
1503
- } else {
1504
- if (result.block.transactions.length > 1) {
1505
- this._logger.logMultipleTransactionsWarning();
1506
- }
1507
- result = [result];
1508
- }
1509
-
1510
- const trace = await this._handleMineBlockResults(result, tx);
1511
-
1512
- if (trace.error !== undefined && this._throwOnTransactionFailures) {
1513
- const e = trace.error;
1514
-
1515
- const returnData = Buffer.from(trace.trace?.returnData ?? []).toString(
1516
- "hex"
1517
- );
1518
- (e as any).data = `0x${returnData}`;
1519
- (e as any).transactionHash = bufferToRpcData(tx.hash());
1520
-
1521
- throw e;
1522
- }
1523
-
1524
- return bufferToRpcData(tx.hash());
1525
- }
1526
-
1527
- /**
1528
- * Returns the trace of the sent tx
1529
- */
1530
- private async _handleMineBlockResults(
1531
- results: MineBlockResult[],
1532
- sentTx: TypedTransaction
1533
- ): Promise<GatherTracesResult> {
1534
- const singleTransactionMined =
1535
- results.length === 1 && results[0].block.transactions.length === 1;
1536
-
1537
- if (singleTransactionMined) {
1538
- const block = results[0].block;
1539
- const tx = block.transactions[0];
1540
- const txGasUsed = results[0].blockResult.results[0].totalGasSpent;
1541
- const trace = results[0].traces[0];
1542
- await this._logSingleTransaction(tx, block, txGasUsed, trace);
1543
-
1544
- return trace;
1545
- } else {
1546
- // this happens when automine is enabled, a tx is sent, and there are
1547
- // pending txs in the mempool
1548
- for (const result of results) {
1549
- await this._logBlock(result, sentTx);
1550
- }
1551
-
1552
- const [sentTxResult, sentTxIndex] = this._getTransactionResultAndIndex(
1553
- sentTx,
1554
- results
1555
- );
1556
- const sentTxTrace = sentTxResult.traces[sentTxIndex];
1557
-
1558
- if (!singleTransactionMined) {
1559
- const blockNumber = sentTxResult.block.header.number;
1560
- const code = await this._node.getCodeFromTrace(
1561
- sentTxTrace.trace,
1562
- blockNumber
1563
- );
1564
-
1565
- const { block, blockResult } = sentTxResult;
1566
- const gasUsed = blockResult.results[sentTxIndex].totalGasSpent;
1567
- this._logger.logCurrentlySentTransaction(
1568
- sentTx,
1569
- gasUsed,
1570
- sentTxTrace,
1571
- code,
1572
- block
1573
- );
1574
- }
1575
-
1576
- return sentTxTrace;
1577
- }
1578
- }
1579
-
1580
- private async _logSingleTransaction(
1581
- tx: TypedTransaction,
1582
- block: Block,
1583
- txGasUsed: bigint,
1584
- txTrace: GatherTracesResult
1585
- ) {
1586
- const code = await this._node.getCodeFromTrace(
1587
- txTrace.trace,
1588
- block.header.number
1589
- );
1590
- this._logger.logSingleTransaction(tx, block, txGasUsed, txTrace, code);
1591
-
1592
- await this._runHardhatNetworkMessageTraceHooks(txTrace.trace, false);
1593
- }
1594
-
1595
- private async _logBlock(result: MineBlockResult, sentTx: TypedTransaction) {
1596
- const { block, traces } = result;
1597
-
1598
- const codes: Buffer[] = [];
1599
- for (const txTrace of traces) {
1600
- const code = await this._node.getCodeFromTrace(
1601
- txTrace.trace,
1602
- block.header.number
1603
- );
1604
-
1605
- codes.push(code);
1606
- }
1607
-
1608
- this._logger.logBlockFromAutomine(result, codes, sentTx.hash());
1609
-
1610
- this._logger.logEmptyLine();
1611
-
1612
- for (const txTrace of traces) {
1613
- await this._runHardhatNetworkMessageTraceHooks(txTrace.trace, false);
1614
- }
1615
- }
1616
-
1617
- private _getTransactionResultAndIndex(
1618
- tx: TypedTransaction,
1619
- results: MineBlockResult[]
1620
- ): [MineBlockResult, number] {
1621
- for (const result of results) {
1622
- const transactions = result.block.transactions;
1623
- for (let i = 0; i < transactions.length; i++) {
1624
- const blockTx = transactions[i];
1625
- if (equalsBytes(blockTx.hash(), tx.hash())) {
1626
- return [result, i];
1627
- }
1628
- }
1629
- }
1630
-
1631
- throw new Error(
1632
- "The sent transaction not found in sendTransaction result, this should never happen"
1633
- );
1634
- }
1635
-
1636
- private async _runHardhatNetworkMessageTraceHooks(
1637
- trace: MessageTrace | undefined,
1638
- isCall: boolean
1639
- ) {
1640
- if (trace === undefined) {
1641
- return;
1642
- }
1643
-
1644
- for (const hook of this._experimentalHardhatNetworkMessageTraceHooks) {
1645
- await hook(trace, isCall);
1646
- }
1647
- }
1648
-
1649
- private _validateTransactionAndCallRequest(
1650
- rpcRequest: RpcCallRequest | RpcTransactionRequest
1651
- ) {
1652
- if (
1653
- rpcRequest.blobs !== undefined ||
1654
- rpcRequest.blobVersionedHashes !== undefined
1655
- ) {
1656
- throw new InvalidInputError(
1657
- `An EIP-4844 (shard blob) transaction was received, but Hardhat doesn't have support for them yet.`
1658
- );
1659
- }
1660
-
1661
- if (
1662
- (rpcRequest.maxFeePerGas !== undefined ||
1663
- rpcRequest.maxPriorityFeePerGas !== undefined) &&
1664
- !this._common.gteHardfork(EIP1559_MIN_HARDFORK)
1665
- ) {
1666
- throw new InvalidArgumentsError(`EIP-1559 style fee params (maxFeePerGas or maxPriorityFeePerGas) received but they are not supported by the current hardfork.
1667
-
1668
- You can use them by running Hardhat Network with 'hardfork' ${EIP1559_MIN_HARDFORK} or later.`);
1669
- }
1670
-
1671
- // NOTE: This validation should go after the maxFeePerGas one, as EIP-1559
1672
- // also accepts access list.
1673
- if (
1674
- rpcRequest.accessList !== undefined &&
1675
- !this._common.gteHardfork(ACCESS_LIST_MIN_HARDFORK)
1676
- ) {
1677
- throw new InvalidArgumentsError(`Access list received but is not supported by the current hardfork.
1678
-
1679
- You can use them by running Hardhat Network with 'hardfork' ${ACCESS_LIST_MIN_HARDFORK} or later.`);
1680
- }
1681
-
1682
- if (
1683
- rpcRequest.gasPrice !== undefined &&
1684
- rpcRequest.maxFeePerGas !== undefined
1685
- ) {
1686
- throw new InvalidInputError(
1687
- "Cannot send both gasPrice and maxFeePerGas params"
1688
- );
1689
- }
1690
-
1691
- if (
1692
- rpcRequest.gasPrice !== undefined &&
1693
- rpcRequest.maxPriorityFeePerGas !== undefined
1694
- ) {
1695
- throw new InvalidInputError(
1696
- "Cannot send both gasPrice and maxPriorityFeePerGas"
1697
- );
1698
- }
1699
-
1700
- if (
1701
- rpcRequest.maxFeePerGas !== undefined &&
1702
- rpcRequest.maxPriorityFeePerGas !== undefined &&
1703
- rpcRequest.maxPriorityFeePerGas > rpcRequest.maxFeePerGas
1704
- ) {
1705
- throw new InvalidInputError(
1706
- `maxPriorityFeePerGas (${rpcRequest.maxPriorityFeePerGas.toString()}) is bigger than maxFeePerGas (${rpcRequest.maxFeePerGas.toString()})`
1707
- );
1708
- }
1709
- }
1710
-
1711
- // TODO: Find a better place for this
1712
- private _validateEip155HardforkRequirement(tx: LegacyTransaction) {
1713
- // 27 and 28 are only valid for non-EIP-155 legacy txs
1714
- if (tx.v === 27n || tx.v === 28n) {
1715
- return;
1716
- }
1717
-
1718
- if (!this._common.gteHardfork(EIP155_MIN_HARDFORK)) {
1719
- throw new InvalidArgumentsError(`Trying to send an EIP-155 transaction, but they are not supported by the current hardfork.
1720
-
1721
- You can use them by running Hardhat Network with 'hardfork' ${EIP155_MIN_HARDFORK} or later.`);
1722
- }
1723
- }
1724
-
1725
- private _validateEip3860MaxInitCodeSize(
1726
- to: Uint8Array | undefined,
1727
- data: Uint8Array
1728
- ) {
1729
- if (!this._common.gteHardfork(EIP3860_MIN_HARDFORK)) {
1730
- // this check is only relevant after shanghai
1731
- return;
1732
- }
1733
-
1734
- if (to !== undefined) {
1735
- // this check is only relevant for deployments
1736
- return;
1737
- }
1738
-
1739
- if (this._node.allowUnlimitedContractSize) {
1740
- // this check is not performed if allowUnlimitedContractSize is enabled
1741
- return;
1742
- }
1743
-
1744
- const maxInitCodeSize = this._common.param("vm", "maxInitCodeSize");
1745
- if (data.length > maxInitCodeSize) {
1746
- throw new InvalidArgumentsError(`Trying to send a deployment transaction whose init code length is ${data.length}. The max length allowed by EIP-3860 is ${maxInitCodeSize}.
1747
-
1748
- Enable the 'allowUnlimitedContractSize' option to allow init codes of any length.`);
1749
- }
1750
- }
1751
-
1752
- private _validateRawTransactionHardforkRequirements(rawTx: Buffer) {
1753
- if (rawTx[0] <= 0x7f && rawTx[0] === 3) {
1754
- throw new InvalidInputError(
1755
- `An EIP-4844 (shard blob) transaction was received, but Hardhat doesn't have support for them yet.`
1756
- );
1757
- }
1758
-
1759
- if (rawTx[0] <= 0x7f && rawTx[0] !== 1 && rawTx[0] !== 2) {
1760
- throw new InvalidArgumentsError(`Invalid transaction type ${rawTx[0]}.
1761
-
1762
- Your raw transaction is incorrectly formatted, or Hardhat Network doesn't support this transaction type yet.`);
1763
- }
1764
-
1765
- if (rawTx[0] === 1 && !this._common.gteHardfork(ACCESS_LIST_MIN_HARDFORK)) {
1766
- throw new InvalidArgumentsError(
1767
- `Trying to send an EIP-2930 transaction but they are not supported by the current hard fork.
1768
-
1769
- You can use them by running Hardhat Network with 'hardfork' ${ACCESS_LIST_MIN_HARDFORK} or later.`
1770
- );
1771
- }
1772
-
1773
- if (rawTx[0] === 2 && !this._common.gteHardfork(EIP1559_MIN_HARDFORK)) {
1774
- throw new InvalidArgumentsError(
1775
- `Trying to send an EIP-1559 transaction but they are not supported by the current hard fork.
1776
-
1777
- You can use them by running Hardhat Network with 'hardfork' ${EIP1559_MIN_HARDFORK} or later.`
1778
- );
1779
- }
1780
- }
1781
- }