|
1 | 1 | import { Block } from "@nomicfoundation/ethereumjs-block";
|
2 | 2 | import { Common } from "@nomicfoundation/ethereumjs-common";
|
| 3 | +import { InterpreterStep } from "@nomicfoundation/ethereumjs-evm"; |
3 | 4 | import {
|
4 | 5 | Account,
|
5 | 6 | Address,
|
| 7 | + AsyncEventEmitter, |
6 | 8 | KECCAK256_NULL,
|
7 | 9 | } from "@nomicfoundation/ethereumjs-util";
|
8 | 10 | import { TypedTransaction } from "@nomicfoundation/ethereumjs-tx";
|
@@ -59,7 +61,9 @@ export class RethnetAdapter implements VMAdapter {
|
59 | 61 | private readonly _common: Common,
|
60 | 62 | private readonly _limitContractCodeSize: bigint | undefined,
|
61 | 63 | private readonly _limitInitcodeSize: bigint | undefined,
|
62 |
| - private readonly _enableTransientStorage: boolean |
| 64 | + private readonly _enableTransientStorage: boolean, |
| 65 | + // For solidity-coverage compatibility. Name cannot be changed. |
| 66 | + private _vm: VMStub |
63 | 67 | ) {
|
64 | 68 | this._vmTracer = new VMTracer(_common, false);
|
65 | 69 | }
|
@@ -93,13 +97,20 @@ export class RethnetAdapter implements VMAdapter {
|
93 | 97 | ? UNLIMITED_CONTRACT_SIZE_VALUE
|
94 | 98 | : undefined;
|
95 | 99 |
|
| 100 | + const vmStub: VMStub = { |
| 101 | + evm: { |
| 102 | + events: new AsyncEventEmitter(), |
| 103 | + }, |
| 104 | + }; |
| 105 | + |
96 | 106 | return new RethnetAdapter(
|
97 | 107 | blockchain,
|
98 | 108 | state,
|
99 | 109 | common,
|
100 | 110 | limitContractCodeSize,
|
101 | 111 | limitInitcodeSize,
|
102 |
| - config.enableTransientStorage |
| 112 | + config.enableTransientStorage, |
| 113 | + vmStub |
103 | 114 | );
|
104 | 115 | }
|
105 | 116 |
|
@@ -184,6 +195,16 @@ export class RethnetAdapter implements VMAdapter {
|
184 | 195 | }
|
185 | 196 | }
|
186 | 197 |
|
| 198 | + // For solidity-coverage compatibility |
| 199 | + for (const step of this._vmTracer.tracingSteps) { |
| 200 | + this._vm.evm.events.emit("step", { |
| 201 | + pc: Number(step.pc), |
| 202 | + depth: step.depth, |
| 203 | + opcode: { name: step.opcode }, |
| 204 | + stackTop: step.stackTop, |
| 205 | + }); |
| 206 | + } |
| 207 | + |
187 | 208 | try {
|
188 | 209 | const result = rethnetResultToRunTxResult(
|
189 | 210 | rethnetResult.result,
|
@@ -415,6 +436,16 @@ export class RethnetAdapter implements VMAdapter {
|
415 | 436 | }
|
416 | 437 | }
|
417 | 438 |
|
| 439 | + // For solidity-coverage compatibility |
| 440 | + for (const step of this._vmTracer.tracingSteps) { |
| 441 | + this._vm.evm.events.emit("step", { |
| 442 | + pc: Number(step.pc), |
| 443 | + depth: step.depth, |
| 444 | + opcode: { name: step.opcode }, |
| 445 | + stackTop: step.stackTop, |
| 446 | + }); |
| 447 | + } |
| 448 | + |
418 | 449 | try {
|
419 | 450 | const result = rethnetResultToRunTxResult(
|
420 | 451 | rethnetResult.result,
|
@@ -623,3 +654,19 @@ export class RethnetAdapter implements VMAdapter {
|
623 | 654 | return undefined;
|
624 | 655 | }
|
625 | 656 | }
|
| 657 | + |
| 658 | +type InterpreterStepStub = Pick<InterpreterStep, "pc" | "depth"> & { |
| 659 | + opcode: { name: string }; |
| 660 | + stackTop?: bigint; |
| 661 | +}; |
| 662 | + |
| 663 | +interface EVMStub { |
| 664 | + events: AsyncEventEmitter<{ |
| 665 | + step: (data: InterpreterStepStub, resolve?: (result?: any) => void) => void; |
| 666 | + }>; |
| 667 | +} |
| 668 | + |
| 669 | +// For compatibility with solidity-coverage that attaches a listener to the step event. |
| 670 | +export interface VMStub { |
| 671 | + evm: EVMStub; |
| 672 | +} |
0 commit comments