Skip to content

Commit

Permalink
Merge pull request #94 from ethdebug/test-how
Browse files Browse the repository at this point in the history
Document and improve @ethdebug/pointers integration tests
  • Loading branch information
gnidan committed Jul 1, 2024
2 parents f2fa084 + 9963be6 commit f3e74ff
Show file tree
Hide file tree
Showing 27 changed files with 1,191 additions and 486 deletions.
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
],
"scripts": {
"test": "node --experimental-vm-modules ./node_modules/.bin/jest",
"test:debug": "open -a \"Brave Browser\" brave://inspect && node --experimental-vm-modules --nolazy --inspect-brk ./node_modules/jest/bin/jest.js --runInBand --colors --verbose",
"start": "./bin/start",
"postinstall": "lerna run prepare"
},
Expand Down
63 changes: 63 additions & 0 deletions packages/pointers/bin/run-example.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
import chalk from "chalk";
import { highlight } from "cli-highlight";
import { describeSchema } from "@ethdebug/format";

import {
type Cursor,
Data
} from "../src/index.js";

import { observeTrace } from "../test/index.js";

import { observeTraceTests } from "../src/test-cases.js";

export async function run() {
const {
pointer,
compileOptions,
observe
} = observeTraceTests["string storage"];

console.log(
chalk.bold(chalk.cyan(
"demo: run compiled solidity and watch a changing ethdebug/format pointer\n"
))
);

console.group(chalk.bold("ethdebug/format pointer used by demo"));
console.log(
highlight(
describeSchema({
schema: { id: "schema:ethdebug/format/pointer" },
pointer: "#/examples/4"
}).yaml,
{ language: "yaml" }
).trim()
);
console.groupEnd();
console.log("");

console.group(chalk.bold("solidity source code used by demo"));
console.log(
compileOptions.sources["StringStorage.sol"].content.trim()
);
console.groupEnd();
console.log("");

console.group(chalk.bold("observing deployment trace"));

const observedValues =
await observeTrace({ pointer, compileOptions, observe });

console.groupEnd();
console.log("");

console.group(chalk.bold("observed values:"));
for (const value of observedValues) {
console.log("- %o", value);
}
console.groupEnd();
console.log("");
}

await run();
1 change: 1 addition & 0 deletions packages/pointers/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
"type": "module",
"license": "MIT",
"scripts": {
"run-example": "node ./dist/bin/run-example.js",
"prepare": "tsc",
"watch": "yarn prepare --watch",
"test": "node --experimental-vm-modules $(yarn bin jest)"
Expand Down
39 changes: 38 additions & 1 deletion packages/pointers/src/data.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,12 @@
import { toHex } from "ethereum-cryptography/utils";

import type * as Util from "util";

let util: typeof Util | undefined;
try {
util = await import("util");
} catch {}

export class Data extends Uint8Array {
static zero(): Data {
return new Data([]);
Expand Down Expand Up @@ -33,7 +40,7 @@ export class Data extends Uint8Array {
if (!hex.startsWith('0x')) {
throw new Error('Invalid hex string format. Expected "0x" prefix.');
}
const bytes = new Uint8Array(hex.length / 2 - 1);
const bytes = new Uint8Array((hex.length - 2) / 2 + 0.5);
for (let i = 2; i < hex.length; i += 2) {
bytes[i / 2 - 1] = parseInt(hex.slice(i, i + 2), 16);
}
Expand Down Expand Up @@ -84,4 +91,34 @@ export class Data extends Uint8Array {

return Data.fromBytes(resized);
}

concat(...others: Data[]): Data {
// HACK concatenate via string representation
const concatenatedHex = [this, ...others]
.map(data => data.toHex().slice(2))
.reduce((accumulator, hex) => `${accumulator}${hex}`, "0x");

return Data.fromHex(concatenatedHex);
}

inspect(
depth: number,
options: Util.InspectOptionsStylized,
inspect: typeof Util.inspect
): string {
return `Data[${options.stylize(this.toHex(), "number")}]`;
}

[
util && "inspect" in util && typeof util.inspect === "object"
? util.inspect.custom
: "_inspect"
](
depth: number,
options: Util.InspectOptionsStylized,
inspect: typeof Util.inspect
): string {
return this.inspect(depth, options, inspect);
}

}
76 changes: 0 additions & 76 deletions packages/pointers/src/dereference/index.integration.test.ts

This file was deleted.

4 changes: 2 additions & 2 deletions packages/pointers/src/dereference/region.ts
Original file line number Diff line number Diff line change
Expand Up @@ -100,8 +100,8 @@ export function adjustStackLength<R extends Pointer.Region>(
const slot: Pointer.Expression = stackLengthChange === 0n
? region.slot
: stackLengthChange > 0n
? { $sum: [region.slot, `"0x${stackLengthChange.toString(16)}"`] }
: { $difference: [region.slot, `"0x${-stackLengthChange.toString(16)}"`] };
? { $sum: [region.slot, `0x${stackLengthChange.toString(16)}`] }
: { $difference: [region.slot, `0x${-stackLengthChange.toString(16)}`] };

return {
...region,
Expand Down
18 changes: 8 additions & 10 deletions packages/pointers/src/evaluate.ts
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,11 @@ export async function evaluate(
return evaluateRead(expression, options);
}

throw new Error("Unexpected runtime failure to recognize kind of expression");
throw new Error(
`Unexpected runtime failure to recognize kind of expression: ${
JSON.stringify(expression)
}`
);
}

async function evaluateLiteral(
Expand Down Expand Up @@ -209,16 +213,10 @@ async function evaluateKeccak256(
async expression => await evaluate(expression, options)
));

// HACK concatenate via string representation
const concatenatedData = operands.reduce(
(data, operand) => `${data}${operand.toHex().slice(2)}`,
""
);

const buffer = Buffer.from(concatenatedData, "hex");
const hash = keccak256(buffer);
const preimage = Data.zero().concat(...operands);
const hash = Data.fromBytes(keccak256(preimage));

return Data.fromBytes(hash);
return hash;
}

async function evaluateResize(
Expand Down
22 changes: 22 additions & 0 deletions packages/pointers/src/integration.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import { jest, expect, describe, it, beforeEach } from "@jest/globals";

import { observeTrace } from "../test/index.js";
import { observeTraceTests } from "./test-cases.js";

describe("dereference (integration)", () => {
describe("changing pointer values over the course of a trace", () => {
for (const [name, test] of Object.entries(observeTraceTests)) {
const { expectedValues, ...options } = test;

describe(`example pointer: ${name}`, () => {
it("resolves to values containing the expected sequence", async () => {
const observedValues =
await observeTrace(options as Parameters<typeof observeTrace>[0]);

expect(observedValues)
.toEqual(expect.arrayContaining(expectedValues));
});
});
}
});
});
Loading

0 comments on commit f3e74ff

Please sign in to comment.