hardhat 2.22.3 → 2.22.5

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 (52) hide show
  1. package/internal/core/errors-list.d.ts +14 -0
  2. package/internal/core/errors-list.d.ts.map +1 -1
  3. package/internal/core/errors-list.js +16 -0
  4. package/internal/core/errors-list.js.map +1 -1
  5. package/internal/core/params/argumentTypes.d.ts +6 -0
  6. package/internal/core/params/argumentTypes.d.ts.map +1 -1
  7. package/internal/core/params/argumentTypes.js +40 -1
  8. package/internal/core/params/argumentTypes.js.map +1 -1
  9. package/internal/core/providers/http.d.ts.map +1 -1
  10. package/internal/core/providers/http.js +5 -0
  11. package/internal/core/providers/http.js.map +1 -1
  12. package/internal/hardhat-network/provider/provider.d.ts +1 -0
  13. package/internal/hardhat-network/provider/provider.d.ts.map +1 -1
  14. package/internal/hardhat-network/provider/provider.js +44 -23
  15. package/internal/hardhat-network/provider/provider.js.map +1 -1
  16. package/internal/hardhat-network/provider/utils/convertToEdr.d.ts.map +1 -1
  17. package/internal/hardhat-network/provider/utils/convertToEdr.js +30 -4
  18. package/internal/hardhat-network/provider/utils/convertToEdr.js.map +1 -1
  19. package/internal/hardhat-network/provider/vm/minimal-vm.d.ts +8 -1
  20. package/internal/hardhat-network/provider/vm/minimal-vm.d.ts.map +1 -1
  21. package/internal/hardhat-network/provider/vm/minimal-vm.js +6 -2
  22. package/internal/hardhat-network/provider/vm/minimal-vm.js.map +1 -1
  23. package/internal/hardhat-network/provider/vm/types.d.ts +8 -0
  24. package/internal/hardhat-network/provider/vm/types.d.ts.map +1 -1
  25. package/internal/hardhat-network/stack-traces/source-maps.d.ts.map +1 -1
  26. package/internal/hardhat-network/stack-traces/source-maps.js +7 -7
  27. package/internal/hardhat-network/stack-traces/source-maps.js.map +1 -1
  28. package/internal/solidity/compilation-job.js +3 -1
  29. package/internal/solidity/compilation-job.js.map +1 -1
  30. package/internal/solidity/compiler/index.d.ts +0 -9
  31. package/internal/solidity/compiler/index.d.ts.map +1 -1
  32. package/internal/solidity/compiler/index.js +19 -34
  33. package/internal/solidity/compiler/index.js.map +1 -1
  34. package/internal/solidity/compiler/solcjs-runner.js +34 -0
  35. package/package.json +4 -9
  36. package/sample-projects/typescript-viem/hardhat.config.ts +1 -1
  37. package/src/internal/core/errors-list.ts +18 -0
  38. package/src/internal/core/params/argumentTypes.ts +44 -0
  39. package/src/internal/core/providers/http.ts +6 -0
  40. package/src/internal/hardhat-network/provider/provider.ts +62 -33
  41. package/src/internal/hardhat-network/provider/utils/convertToEdr.ts +36 -4
  42. package/src/internal/hardhat-network/provider/vm/minimal-vm.ts +14 -3
  43. package/src/internal/hardhat-network/provider/vm/types.ts +7 -0
  44. package/src/internal/hardhat-network/stack-traces/source-maps.ts +7 -8
  45. package/src/internal/solidity/compilation-job.ts +3 -3
  46. package/src/internal/solidity/compiler/index.ts +27 -49
  47. package/src/internal/solidity/compiler/solcjs-runner.js +34 -0
  48. package/internal/hardhat-network/provider/MiningTimer.d.ts +0 -28
  49. package/internal/hardhat-network/provider/MiningTimer.d.ts.map +0 -1
  50. package/internal/hardhat-network/provider/MiningTimer.js +0 -96
  51. package/internal/hardhat-network/provider/MiningTimer.js.map +0 -1
  52. package/src/internal/hardhat-network/provider/MiningTimer.ts +0 -118
@@ -208,24 +208,55 @@ export function edrRpcDebugTraceToHardhat(
208
208
  export function edrTracingStepToMinimalInterpreterStep(
209
209
  step: TracingStep
210
210
  ): MinimalInterpreterStep {
211
- return {
211
+ const minimalInterpreterStep: MinimalInterpreterStep = {
212
212
  pc: Number(step.pc),
213
213
  depth: step.depth,
214
214
  opcode: {
215
215
  name: step.opcode,
216
216
  },
217
- stack: step.stackTop !== undefined ? [step.stackTop] : [],
217
+ stack: step.stack,
218
218
  };
219
+
220
+ if (step.memory !== undefined) {
221
+ minimalInterpreterStep.memory = step.memory;
222
+ }
223
+
224
+ return minimalInterpreterStep;
219
225
  }
220
226
 
221
227
  export function edrTracingMessageResultToMinimalEVMResult(
222
228
  tracingMessageResult: TracingMessageResult
223
229
  ): MinimalEVMResult {
224
- return {
230
+ const { result, contractAddress } = tracingMessageResult.executionResult;
231
+
232
+ // only SuccessResult has logs
233
+ const success = "logs" in result;
234
+
235
+ const minimalEVMResult: MinimalEVMResult = {
225
236
  execResult: {
226
- executionGasUsed: tracingMessageResult.executionResult.result.gasUsed,
237
+ executionGasUsed: result.gasUsed,
238
+ success,
227
239
  },
228
240
  };
241
+
242
+ // only success and exceptional halt have reason
243
+ if ("reason" in result) {
244
+ minimalEVMResult.execResult.reason = result.reason;
245
+ }
246
+ if ("output" in result) {
247
+ const { output } = result;
248
+ if (Buffer.isBuffer(output)) {
249
+ minimalEVMResult.execResult.output = output;
250
+ } else {
251
+ minimalEVMResult.execResult.output = output.returnValue;
252
+ }
253
+ }
254
+
255
+ if (contractAddress !== undefined) {
256
+ minimalEVMResult.execResult.contractAddress = new Address(contractAddress);
257
+ }
258
+
259
+ return minimalEVMResult;
229
260
  }
230
261
 
231
262
  export function edrTracingMessageToMinimalMessage(
@@ -241,5 +272,6 @@ export function edrTracingMessageToMinimalMessage(
241
272
  value: message.value,
242
273
  caller: new Address(message.caller),
243
274
  gasLimit: message.gasLimit,
275
+ isStaticCall: message.isStaticCall,
244
276
  };
245
277
  }
@@ -13,8 +13,9 @@ import { AsyncEventEmitter } from "@nomicfoundation/ethereumjs-util";
13
13
  * interface only has the things used by those plugins.
14
14
  */
15
15
  export interface MinimalEthereumJsVm {
16
+ events: AsyncEventEmitter<MinimalEthereumJsVmEvents>;
16
17
  evm: {
17
- events: AsyncEventEmitter<MinimalEthereumJsVmEvents>;
18
+ events: AsyncEventEmitter<MinimalEthereumJsEvmEvents>;
18
19
  };
19
20
  stateManager: {
20
21
  putContractCode: (address: Address, code: Buffer) => Promise<void>;
@@ -27,10 +28,18 @@ export interface MinimalEthereumJsVm {
27
28
  };
28
29
  }
29
30
 
30
- // we need to use a type instead of an interface to satisfy the type constarint
31
+ // we need to use a type instead of an interface to satisfy the type constraint
31
32
  // of the AsyncEventEmitter type param
32
33
  // eslint-disable-next-line @typescript-eslint/consistent-type-definitions
33
34
  type MinimalEthereumJsVmEvents = {
35
+ beforeTx: () => void;
36
+ afterTx: () => void;
37
+ };
38
+
39
+ // we need to use a type instead of an interface to satisfy the type constraint
40
+ // of the AsyncEventEmitter type param
41
+ // eslint-disable-next-line @typescript-eslint/consistent-type-definitions
42
+ type MinimalEthereumJsEvmEvents = {
34
43
  beforeMessage: (
35
44
  data: MinimalMessage,
36
45
  resolve?: (result?: any) => void
@@ -46,13 +55,15 @@ type MinimalEthereumJsVmEvents = {
46
55
  };
47
56
 
48
57
  export class MinimalEthereumJsVmEventEmitter extends AsyncEventEmitter<MinimalEthereumJsVmEvents> {}
58
+ export class MinimalEthereumJsEvmEventEmitter extends AsyncEventEmitter<MinimalEthereumJsEvmEvents> {}
49
59
 
50
60
  export function getMinimalEthereumJsVm(
51
61
  provider: EdrProviderT
52
62
  ): MinimalEthereumJsVm {
53
63
  const minimalEthereumJsVm: MinimalEthereumJsVm = {
64
+ events: new MinimalEthereumJsVmEventEmitter(),
54
65
  evm: {
55
- events: new MinimalEthereumJsVmEventEmitter(),
66
+ events: new MinimalEthereumJsEvmEventEmitter(),
56
67
  },
57
68
  stateManager: {
58
69
  putContractCode: async (address: Address, code: Buffer) => {
@@ -1,3 +1,4 @@
1
+ import type { ExceptionalHalt, SuccessReason } from "@nomicfoundation/edr";
1
2
  import type { Address } from "@nomicfoundation/ethereumjs-util";
2
3
 
3
4
  /**
@@ -12,10 +13,15 @@ export interface MinimalInterpreterStep {
12
13
  name: string;
13
14
  };
14
15
  stack: bigint[];
16
+ memory?: Uint8Array;
15
17
  }
16
18
 
17
19
  export interface MinimalExecResult {
20
+ success: boolean;
18
21
  executionGasUsed: bigint;
22
+ contractAddress?: Address;
23
+ reason?: SuccessReason | ExceptionalHalt;
24
+ output?: Buffer;
19
25
  }
20
26
 
21
27
  export interface MinimalEVMResult {
@@ -29,4 +35,5 @@ export interface MinimalMessage {
29
35
  data: Uint8Array;
30
36
  caller: Address;
31
37
  gasLimit: bigint;
38
+ isStaticCall: boolean;
32
39
  }
@@ -75,14 +75,13 @@ function uncompressSourcemaps(compressedSourcemap: string): SourceMap[] {
75
75
 
76
76
  function addUnmappedInstructions(
77
77
  instructions: Instruction[],
78
- bytecode: Buffer,
79
- bytesIndex: number
78
+ bytecode: Buffer
80
79
  ) {
81
80
  const lastInstrPc = instructions[instructions.length - 1].pc;
82
- let nextPc = lastInstrPc + 1;
81
+ let bytesIndex = lastInstrPc + 1;
83
82
 
84
- while (bytecode[nextPc] !== Opcode.INVALID) {
85
- const opcode = bytecode[nextPc];
83
+ while (bytecode[bytesIndex] !== Opcode.INVALID) {
84
+ const opcode = bytecode[bytesIndex];
86
85
  let pushData: Buffer | undefined;
87
86
 
88
87
  let pushDataLenth = 0;
@@ -95,10 +94,10 @@ function addUnmappedInstructions(
95
94
  ? JumpType.INTERNAL_JUMP
96
95
  : JumpType.NOT_JUMP;
97
96
 
98
- const instruction = new Instruction(nextPc, opcode, jumpType, pushData);
97
+ const instruction = new Instruction(bytesIndex, opcode, jumpType, pushData);
99
98
  instructions.push(instruction);
100
99
 
101
- nextPc += 1 + pushDataLenth;
100
+ bytesIndex += getOpcodeLength(opcode);
102
101
  }
103
102
  }
104
103
 
@@ -161,7 +160,7 @@ export function decodeInstructions(
161
160
 
162
161
  // See: https://github.com/ethereum/solidity/issues/9133
163
162
  if (isDeployment) {
164
- addUnmappedInstructions(instructions, bytecode, bytesIndex);
163
+ addUnmappedInstructions(instructions, bytecode);
165
164
  }
166
165
 
167
166
  return instructions;
@@ -234,9 +234,9 @@ function getCompilerConfigForFile(
234
234
  transitiveDependencies: taskTypes.TransitiveDependency[],
235
235
  solidityConfig: SolidityConfig
236
236
  ): SolcConfig | CompilationJobCreationError {
237
- const transitiveDependenciesVersionPragmas = transitiveDependencies.map(
238
- ({ dependency }) => dependency.content.versionPragmas
239
- );
237
+ const transitiveDependenciesVersionPragmas = transitiveDependencies
238
+ .map(({ dependency }) => dependency.content.versionPragmas)
239
+ .flat();
240
240
  const versionRange = Array.from(
241
241
  new Set([
242
242
  ...file.content.versionPragmas,
@@ -12,61 +12,39 @@ export interface ICompiler {
12
12
  }
13
13
 
14
14
  export class Compiler implements ICompiler {
15
- private _loadedSolc?: any;
16
-
17
15
  constructor(private _pathToSolcJs: string) {}
18
16
 
19
17
  public async compile(input: CompilerInput) {
20
- const solc = await this.getSolc();
21
-
22
- const jsonOutput = solc.compile(JSON.stringify(input));
23
- return JSON.parse(jsonOutput);
24
- }
25
-
26
- public async getSolc() {
27
- if (this._loadedSolc !== undefined) {
28
- return this._loadedSolc;
29
- }
30
-
31
- const solcWrapper = require("solc/wrapper");
32
- this._loadedSolc = solcWrapper(
33
- this._loadCompilerSources(this._pathToSolcJs)
34
- );
35
-
36
- return this._loadedSolc;
37
- }
18
+ const scriptPath = path.join(__dirname, "./solcjs-runner.js");
38
19
 
39
- /**
40
- * This function loads the compiler sources bypassing any require hook.
41
- *
42
- * The compiler is a huge asm.js file, and using a simple require may trigger
43
- * babel/register and hang the process.
44
- */
45
- private _loadCompilerSources(compilerPath: string) {
46
- const Module = module.constructor as any;
47
-
48
- // if Hardhat is bundled (for example, in the vscode extension), then
49
- // Module._extenions might be undefined. In that case, we just use a plain
50
- // require.
51
- if (Module._extensions === undefined) {
52
- return require(compilerPath);
53
- }
54
-
55
- const previousHook = Module._extensions[".js"];
56
-
57
- Module._extensions[".js"] = function (
58
- module: NodeJS.Module,
59
- filename: string
60
- ) {
61
- const content = fs.readFileSync(filename, "utf8");
62
- Object.getPrototypeOf(module)._compile.call(module, content, filename);
63
- };
64
-
65
- const loadedSolc = require(compilerPath);
20
+ const output: string = await new Promise((resolve, reject) => {
21
+ try {
22
+ const subprocess = execFile(
23
+ process.execPath,
24
+ [scriptPath, this._pathToSolcJs],
25
+ {
26
+ maxBuffer: 1024 * 1024 * 500,
27
+ },
28
+ (err, stdout) => {
29
+ if (err !== null) {
30
+ return reject(err);
31
+ }
32
+ resolve(stdout);
33
+ }
34
+ );
66
35
 
67
- Module._extensions[".js"] = previousHook;
36
+ subprocess.stdin!.write(JSON.stringify(input));
37
+ subprocess.stdin!.end();
38
+ } catch (e: any) {
39
+ throw new HardhatError(
40
+ ERRORS.SOLC.SOLCJS_ERROR,
41
+ { error: e.message },
42
+ e
43
+ );
44
+ }
45
+ });
68
46
 
69
- return loadedSolc;
47
+ return JSON.parse(output);
70
48
  }
71
49
  }
72
50
 
@@ -0,0 +1,34 @@
1
+ // @ts-check
2
+
3
+ async function readStream(stream, encoding = "utf8") {
4
+ stream.setEncoding(encoding);
5
+
6
+ return new Promise((resolve, reject) => {
7
+ let data = "";
8
+
9
+ stream.on("data", (chunk) => (data += chunk));
10
+ stream.on("end", () => resolve(data));
11
+ stream.on("error", (error) => reject(error));
12
+ });
13
+ }
14
+
15
+ function getSolcJs(solcJsPath) {
16
+ const solcWrapper = require("solc/wrapper");
17
+ return solcWrapper(require(solcJsPath));
18
+ }
19
+
20
+ async function main() {
21
+ const input = await readStream(process.stdin);
22
+
23
+ const solcjsPath = process.argv[2];
24
+ const solc = getSolcJs(solcjsPath);
25
+
26
+ const output = solc.compile(input);
27
+
28
+ console.log(output);
29
+ }
30
+
31
+ main().catch((error) => {
32
+ console.error(error);
33
+ process.exitCode = 1;
34
+ });
@@ -1,28 +0,0 @@
1
- import { IntervalMiningConfig } from "./node-types";
2
- /**
3
- * Timer used to periodically call the given mining function.
4
- *
5
- * `_blockTime` can be a number or a pair of numbers (of milliseconds). If it
6
- * is a number, it will call the given function repeatedly every `_blockTime`
7
- * milliseconds. If it is a pair of numbers, then after each call it will
8
- * randomly choose how much to wait until the next call.
9
- *
10
- * `_mineFunction` is the function to call. It can be async, and it is assumed
11
- * that it will never throw.
12
- */
13
- export declare class MiningTimer {
14
- private _blockTime;
15
- private readonly _mineFunction;
16
- private _state;
17
- private _timeout;
18
- constructor(_blockTime: IntervalMiningConfig, _mineFunction: () => Promise<any>);
19
- getBlockTime(): IntervalMiningConfig;
20
- enabled(): boolean;
21
- setBlockTime(blockTime: IntervalMiningConfig): void;
22
- start(): void;
23
- stop(): void;
24
- private _validateBlockTime;
25
- private _loop;
26
- private _getNextBlockTime;
27
- }
28
- //# sourceMappingURL=MiningTimer.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"MiningTimer.d.ts","sourceRoot":"","sources":["../../../src/internal/hardhat-network/provider/MiningTimer.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,oBAAoB,EAAE,MAAM,cAAc,CAAC;AASpD;;;;;;;;;;GAUG;AACH,qBAAa,WAAW;IAKpB,OAAO,CAAC,UAAU;IAClB,OAAO,CAAC,QAAQ,CAAC,aAAa;IALhC,OAAO,CAAC,MAAM,CAAyB;IACvC,OAAO,CAAC,QAAQ,CAA+B;gBAGrC,UAAU,EAAE,oBAAoB,EACvB,aAAa,EAAE,MAAM,OAAO,CAAC,GAAG,CAAC;IAK7C,YAAY,IAAI,oBAAoB;IAIpC,OAAO,IAAI,OAAO;IAIlB,YAAY,CAAC,SAAS,EAAE,oBAAoB,GAAG,IAAI;IAiBnD,KAAK,IAAI,IAAI;IAWb,IAAI,IAAI,IAAI;IAYnB,OAAO,CAAC,kBAAkB;YAaZ,KAAK;IAcnB,OAAO,CAAC,iBAAiB;CAW1B"}
@@ -1,96 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.MiningTimer = void 0;
4
- var MiningTimerState;
5
- (function (MiningTimerState) {
6
- MiningTimerState[MiningTimerState["STOP"] = 0] = "STOP";
7
- MiningTimerState[MiningTimerState["RUNNING"] = 1] = "RUNNING";
8
- })(MiningTimerState || (MiningTimerState = {}));
9
- /* eslint-disable @nomicfoundation/hardhat-internal-rules/only-hardhat-error */
10
- /**
11
- * Timer used to periodically call the given mining function.
12
- *
13
- * `_blockTime` can be a number or a pair of numbers (of milliseconds). If it
14
- * is a number, it will call the given function repeatedly every `_blockTime`
15
- * milliseconds. If it is a pair of numbers, then after each call it will
16
- * randomly choose how much to wait until the next call.
17
- *
18
- * `_mineFunction` is the function to call. It can be async, and it is assumed
19
- * that it will never throw.
20
- */
21
- class MiningTimer {
22
- constructor(_blockTime, _mineFunction) {
23
- this._blockTime = _blockTime;
24
- this._mineFunction = _mineFunction;
25
- this._state = MiningTimerState.STOP;
26
- this._timeout = null;
27
- this._validateBlockTime(_blockTime);
28
- }
29
- getBlockTime() {
30
- return this._blockTime;
31
- }
32
- enabled() {
33
- return this._blockTime !== 0;
34
- }
35
- setBlockTime(blockTime) {
36
- this._validateBlockTime(blockTime);
37
- if (blockTime === 0) {
38
- this.stop();
39
- return;
40
- }
41
- this._blockTime = blockTime;
42
- if (this._state === MiningTimerState.RUNNING) {
43
- this.stop();
44
- }
45
- this.start();
46
- }
47
- start() {
48
- if (this._state === MiningTimerState.RUNNING || !this.enabled()) {
49
- return;
50
- }
51
- const blockTime = this._getNextBlockTime();
52
- this._state = MiningTimerState.RUNNING;
53
- this._timeout = setTimeout(() => this._loop(), blockTime);
54
- }
55
- stop() {
56
- if (this._state === MiningTimerState.STOP) {
57
- return;
58
- }
59
- this._state = MiningTimerState.STOP;
60
- if (this._timeout !== null) {
61
- clearTimeout(this._timeout);
62
- }
63
- }
64
- _validateBlockTime(blockTime) {
65
- if (Array.isArray(blockTime)) {
66
- const [rangeStart, rangeEnd] = blockTime;
67
- if (rangeEnd < rangeStart) {
68
- throw new Error("Invalid block time range");
69
- }
70
- }
71
- else {
72
- if (blockTime < 0) {
73
- throw new Error("Block time cannot be negative");
74
- }
75
- }
76
- }
77
- async _loop() {
78
- if (this._state === MiningTimerState.STOP) {
79
- return;
80
- }
81
- await this._mineFunction();
82
- const blockTime = this._getNextBlockTime();
83
- this._timeout = setTimeout(() => {
84
- this._loop(); // eslint-disable-line @typescript-eslint/no-floating-promises
85
- }, blockTime);
86
- }
87
- _getNextBlockTime() {
88
- if (Array.isArray(this._blockTime)) {
89
- const [minBlockTime, maxBlockTime] = this._blockTime;
90
- return (minBlockTime + Math.floor(Math.random() * (maxBlockTime - minBlockTime)));
91
- }
92
- return this._blockTime;
93
- }
94
- }
95
- exports.MiningTimer = MiningTimer;
96
- //# sourceMappingURL=MiningTimer.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"MiningTimer.js","sourceRoot":"","sources":["../../../src/internal/hardhat-network/provider/MiningTimer.ts"],"names":[],"mappings":"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"}
@@ -1,118 +0,0 @@
1
- import { IntervalMiningConfig } from "./node-types";
2
-
3
- enum MiningTimerState {
4
- STOP,
5
- RUNNING,
6
- }
7
-
8
- /* eslint-disable @nomicfoundation/hardhat-internal-rules/only-hardhat-error */
9
-
10
- /**
11
- * Timer used to periodically call the given mining function.
12
- *
13
- * `_blockTime` can be a number or a pair of numbers (of milliseconds). If it
14
- * is a number, it will call the given function repeatedly every `_blockTime`
15
- * milliseconds. If it is a pair of numbers, then after each call it will
16
- * randomly choose how much to wait until the next call.
17
- *
18
- * `_mineFunction` is the function to call. It can be async, and it is assumed
19
- * that it will never throw.
20
- */
21
- export class MiningTimer {
22
- private _state = MiningTimerState.STOP;
23
- private _timeout: NodeJS.Timeout | null = null;
24
-
25
- constructor(
26
- private _blockTime: IntervalMiningConfig,
27
- private readonly _mineFunction: () => Promise<any>
28
- ) {
29
- this._validateBlockTime(_blockTime);
30
- }
31
-
32
- public getBlockTime(): IntervalMiningConfig {
33
- return this._blockTime;
34
- }
35
-
36
- public enabled(): boolean {
37
- return this._blockTime !== 0;
38
- }
39
-
40
- public setBlockTime(blockTime: IntervalMiningConfig): void {
41
- this._validateBlockTime(blockTime);
42
-
43
- if (blockTime === 0) {
44
- this.stop();
45
- return;
46
- }
47
-
48
- this._blockTime = blockTime;
49
-
50
- if (this._state === MiningTimerState.RUNNING) {
51
- this.stop();
52
- }
53
-
54
- this.start();
55
- }
56
-
57
- public start(): void {
58
- if (this._state === MiningTimerState.RUNNING || !this.enabled()) {
59
- return;
60
- }
61
-
62
- const blockTime = this._getNextBlockTime();
63
-
64
- this._state = MiningTimerState.RUNNING;
65
- this._timeout = setTimeout(() => this._loop(), blockTime);
66
- }
67
-
68
- public stop(): void {
69
- if (this._state === MiningTimerState.STOP) {
70
- return;
71
- }
72
-
73
- this._state = MiningTimerState.STOP;
74
-
75
- if (this._timeout !== null) {
76
- clearTimeout(this._timeout);
77
- }
78
- }
79
-
80
- private _validateBlockTime(blockTime: IntervalMiningConfig) {
81
- if (Array.isArray(blockTime)) {
82
- const [rangeStart, rangeEnd] = blockTime;
83
- if (rangeEnd < rangeStart) {
84
- throw new Error("Invalid block time range");
85
- }
86
- } else {
87
- if (blockTime < 0) {
88
- throw new Error("Block time cannot be negative");
89
- }
90
- }
91
- }
92
-
93
- private async _loop() {
94
- if (this._state === MiningTimerState.STOP) {
95
- return;
96
- }
97
-
98
- await this._mineFunction();
99
-
100
- const blockTime = this._getNextBlockTime();
101
-
102
- this._timeout = setTimeout(() => {
103
- this._loop(); // eslint-disable-line @typescript-eslint/no-floating-promises
104
- }, blockTime);
105
- }
106
-
107
- private _getNextBlockTime(): number {
108
- if (Array.isArray(this._blockTime)) {
109
- const [minBlockTime, maxBlockTime] = this._blockTime;
110
-
111
- return (
112
- minBlockTime + Math.floor(Math.random() * (maxBlockTime - minBlockTime))
113
- );
114
- }
115
-
116
- return this._blockTime;
117
- }
118
- }