Skip to content

Commit

Permalink
chore: do not expose edr types via user config
Browse files Browse the repository at this point in the history
  • Loading branch information
galargh committed Oct 28, 2024
1 parent 7743030 commit 1c5f1a1
Show file tree
Hide file tree
Showing 4 changed files with 230 additions and 59 deletions.
101 changes: 100 additions & 1 deletion v-next/hardhat/src/internal/builtin-plugins/solidity-test/helpers.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,109 @@
import type { RunOptions } from "./types.js";
import type { ArtifactsManager } from "../../../types/artifacts.js";
import type { Artifact } from "@ignored/edr";
import type { SolidityTestUserConfig } from "../../../types/config.js";
import type {
Artifact,
SolidityTestRunnerConfigArgs,
CachedChains,
CachedEndpoints,
PathPermission,
StorageCachingConfig,
AddressLabel,
} from "@ignored/edr";

import { HardhatError } from "@ignored/hardhat-vnext-errors";
import { exists } from "@ignored/hardhat-vnext-utils/fs";
import { hexStringToBytes } from "@ignored/hardhat-vnext-utils/hex";
import { resolveFromRoot } from "@ignored/hardhat-vnext-utils/path";

function hexStringToBuffer(hexString: string): Buffer {
return Buffer.from(hexStringToBytes(hexString));
}

export function solidityTestUserConfigToRunOptions(
config: SolidityTestUserConfig,
): RunOptions {
return config;
}

export function solidityTestUserConfigToSolidityTestRunnerConfigArgs(
projectRoot: string,
config: SolidityTestUserConfig,
): SolidityTestRunnerConfigArgs {
const fsPermissions: PathPermission[] | undefined = [
config.fsPermissions?.readWrite?.map((path) => ({ access: 0, path })) ?? [],
config.fsPermissions?.read?.map((path) => ({ access: 0, path })) ?? [],
config.fsPermissions?.write?.map((path) => ({ access: 0, path })) ?? [],
].flat(1);

const labels: AddressLabel[] | undefined = config.labels?.map(
({ address, label }) => ({
address: hexStringToBuffer(address),
label,
}),
);

let rpcStorageCaching: StorageCachingConfig | undefined;
if (config.rpcStorageCaching !== undefined) {
let chains: CachedChains | string[];
if (Array.isArray(config.rpcStorageCaching.chains)) {
chains = config.rpcStorageCaching.chains;
} else {
const rpcStorageCachingChains: "All" | "None" =
config.rpcStorageCaching.chains;
switch (rpcStorageCachingChains) {
case "All":
chains = 0;
break;
case "None":
chains = 1;
break;
}
}
let endpoints: CachedEndpoints | string;
if (config.rpcStorageCaching.endpoints instanceof RegExp) {
endpoints = config.rpcStorageCaching.endpoints.source;
} else {
const rpcStorageCachingEndpoints: "All" | "Remote" =
config.rpcStorageCaching.endpoints;
switch (rpcStorageCachingEndpoints) {
case "All":
endpoints = 0;
break;
case "Remote":
endpoints = 1;
break;
}
}
rpcStorageCaching = {
chains,
endpoints,
};
}

const sender: Buffer | undefined =
config.sender === undefined ? undefined : hexStringToBuffer(config.sender);
const txOrigin: Buffer | undefined =
config.txOrigin === undefined
? undefined
: hexStringToBuffer(config.txOrigin);
const blockCoinbase: Buffer | undefined =
config.blockCoinbase === undefined
? undefined
: hexStringToBuffer(config.blockCoinbase);

return {
projectRoot,
...config,
fsPermissions,
labels,
sender,
txOrigin,
blockCoinbase,
rpcStorageCaching,
};
}

export async function getArtifacts(
hardhatArtifacts: ArtifactsManager,
): Promise<Artifact[]> {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,12 @@ import type { SolidityTestRunnerConfigArgs } from "@ignored/edr";

import { finished } from "node:stream/promises";

import { getArtifacts, isTestArtifact } from "./helpers.js";
import {
getArtifacts,
isTestArtifact,
solidityTestUserConfigToRunOptions,
solidityTestUserConfigToSolidityTestRunnerConfigArgs,
} from "./helpers.js";
import { testReporter } from "./reporter.js";
import { run } from "./runner.js";

Expand All @@ -31,12 +36,12 @@ const runSolidityTests: NewTaskActionFunction = async (_taskArguments, hre) => {
const profile = hre.config.solidity.profiles[profileName];
const testOptions = profile.test;

const config: SolidityTestRunnerConfigArgs = {
projectRoot: hre.config.paths.root,
...testOptions,
};

const options: RunOptions = testOptions;
const config: SolidityTestRunnerConfigArgs =
solidityTestUserConfigToSolidityTestRunnerConfigArgs(
hre.config.paths.root,
testOptions,
);
const options: RunOptions = solidityTestUserConfigToRunOptions(testOptions);

const runStream = run(artifacts, testSuiteIds, config, options);

Expand Down
106 changes: 61 additions & 45 deletions v-next/hardhat/src/internal/builtin-plugins/solidity/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -36,67 +36,83 @@ const solcUserConfigType = z.object({
});

const solidityTestUserConfigType = z.object({
// RunOptions
timeout: z.number().optional(),
// Omit<SolidityTestRunnerConfigArgs, "projectRoot">
fsPermissions: z.array(z.object({
access: z.enum(["ReadWrite", "Read", "Write"]),
path: z.string(),
})).optional(),
fsPermissions: z
.object({
readWrite: z.array(z.string()).optional(),
read: z.array(z.string()).optional(),
write: z.array(z.string()).optional(),
})
.optional(),
trace: z.boolean().optional(),
testFail: z.boolean().optional(),
labels: z.array(z.object({
address: z.instanceof(Buffer),
label: z.string(),
})).optional(),
labels: z
.array(
z.object({
address: z.string().startsWith("0x"),
label: z.string(),
}),
)
.optional(),
isolate: z.boolean().optional(),
ffi: z.boolean().optional(),
sender: z.instanceof(Buffer).optional(),
txOrigin: z.instanceof(Buffer).optional(),
sender: z.string().startsWith("0x").optional(),
txOrigin: z.string().startsWith("0x").optional(),
initialBalance: z.bigint().optional(),
blockBaseFeePerGas: z.bigint().optional(),
blockCoinbase: z.instanceof(Buffer).optional(),
blockCoinbase: z.string().startsWith("0x").optional(),
blockTimestamp: z.bigint().optional(),
blockDifficulty: z.bigint().optional(),
blockGasLimit: z.bigint().optional(),
disableBlockGasLimit: z.boolean().optional(),
memoryLimit: z.bigint().optional(),
ethRpcUrl: z.string().optional(),
forkBlockNumber: z.number().optional(),
forkBlockNumber: z.bigint().optional(),
rpcEndpoints: z.record(z.string()).optional(),
rpcCachePath: z.string().optional(),
rpcStorageCaching: z.object({
chains: unionType([
z.array(z.string()),
z.enum(["All", "None"]),
], ""),
endpoints: unionType([
z.string(),
z.enum(["All", "Remote"]),
], ""),
}).optional(),
rpcStorageCaching: z
.object({
chains: unionType(
[z.enum(["All", "None"]), z.array(z.string())],
"Expected `All`, `None` or a list of chain names to cache",
),
endpoints: unionType(
[
z.enum(["All", "Remote"]),
z.object({
source: z.string(),
}),
],
"Expected `All`, `Remote` or a RegExp object matching endpoints to cacche",
),
})
.optional(),
promptTimeout: z.number().optional(),
fuzz: z.object({
failurePersistDir: z.string().optional(),
failurePersistFile: z.string().optional(),
runs: z.number().optional(),
maxTestRejects: z.number().optional(),
seed: z.string().optional(),
dictionaryWeight: z.number().optional(),
includeStorage: z.boolean().optional(),
includePushBytes: z.boolean().optional(),
}).optional(),
invariant: z.object({
failurePersistDir: z.string().optional(),
runs: z.number().optional(),
depth: z.number().optional(),
failOnRevert: z.boolean().optional(),
callOverride: z.boolean().optional(),
dictionaryWeight: z.number().optional(),
includeStorage: z.boolean().optional(),
includePushBytes: z.boolean().optional(),
shrinkRunLimit: z.number().optional(),
}).optional(),
fuzz: z
.object({
failurePersistDir: z.string().optional(),
failurePersistFile: z.string().optional(),
runs: z.number().optional(),
maxTestRejects: z.number().optional(),
seed: z.string().optional(),
dictionaryWeight: z.number().optional(),
includeStorage: z.boolean().optional(),
includePushBytes: z.boolean().optional(),
})
.optional(),
invariant: z
.object({
failurePersistDir: z.string().optional(),
runs: z.number().optional(),
depth: z.number().optional(),
failOnRevert: z.boolean().optional(),
callOverride: z.boolean().optional(),
dictionaryWeight: z.number().optional(),
includeStorage: z.boolean().optional(),
includePushBytes: z.boolean().optional(),
shrinkRunLimit: z.number().optional(),
})
.optional(),
});

const singleVersionSolcUserConfigType = solcUserConfigType.extend({
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,62 @@ declare module "../../../types/config.js" {
settings?: any;
}

export type SolidityTestUserConfig = RunOptions &
Omit<SolidityTestRunnerConfigArgs, "projectRoot">;
export interface SolidityTestUserConfig {
timeout?: number;
fsPermissions?: {
readWrite?: string[];
read?: string[];
write?: string[];
};
trace?: boolean;
testFail?: boolean;
labels?: Array<{
address: string; // 0x-prefixed hex string
label: string;
}>;
isolate?: boolean;
ffi?: boolean;
sender?: string; // 0x-prefixed hex string
txOrigin?: string; // 0x-prefixed hex string
initialBalance?: bigint;
blockBaseFeePerGas?: bigint;
blockCoinbase?: string; // 0x-prefixed hex string
blockTimestamp?: bigint;
blockDifficulty?: bigint;
blockGasLimit?: bigint;
disableBlockGasLimit?: boolean;
memoryLimit?: bigint;
ethRpcUrl?: string;
forkBlockNumber?: bigint;
rpcEndpoints?: Record<string, string>;
rpcCachePath?: string;
rpcStorageCaching?: {
chains: "All" | "None" | string[];
endpoints: "All" | "Remote" | RegExp;
};
promptTimeout?: number;
fuzz?: {
failurePersistDir?: string;
failurePersistFile?: string;
runs?: number;
maxTestRejects?: number;
seed?: string;
dictionaryWeight?: number;
includeStorage?: boolean;
includePushBytes?: boolean;
};
invariant?: {
failurePersistDir?: string;
runs?: number;
depth?: number;
failOnRevert?: boolean;
callOverride?: boolean;
dictionaryWeight?: number;
includeStorage?: boolean;
includePushBytes?: boolean;
shrinkRunLimit?: number;
};
}

export interface SingleVersionSolcUserConfig extends SolcUserConfig {
test?: SolidityTestUserConfig;
Expand Down Expand Up @@ -56,8 +110,7 @@ declare module "../../../types/config.js" {
settings: any;
}

export type SolidityTestConfig = RunOptions &
Omit<SolidityTestRunnerConfigArgs, "projectRoot">;
export type SolidityTestConfig = SolidityTestUserConfig;

export interface SolidityBuildProfileConfig {
compilers: SolcConfig[];
Expand Down Expand Up @@ -86,8 +139,6 @@ declare module "../../../types/config.js" {

import "../../../types/hre.js";
import type { SolidityBuildSystem } from "../../../types/solidity/build-system.js";
import type { RunOptions } from "../solidity-test/types.js";
import type { SolidityTestRunnerConfigArgs } from "@ignored/edr";

declare module "../../../types/hre.js" {
export interface HardhatRuntimeEnvironment {
Expand Down

0 comments on commit 1c5f1a1

Please sign in to comment.