Skip to content

Commit

Permalink
Merge pull request #5762 from NomicFoundation/network-manager-m1-cleanup
Browse files Browse the repository at this point in the history
Network Manager M1 remaining tasks
  • Loading branch information
schaable authored Sep 28, 2024
2 parents 57f9e87 + ae00903 commit ce77ee9
Show file tree
Hide file tree
Showing 11 changed files with 1,286 additions and 112 deletions.
22 changes: 12 additions & 10 deletions v-next/hardhat-zod-utils/src/index.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import type { ZodTypeDef, ZodType } from "zod";

import { isObject } from "@ignored/hardhat-vnext-utils/lang";
import { z } from "zod";

/**
Expand Down Expand Up @@ -138,29 +137,32 @@ export const incompatibleFieldType = (errorMessage = "Unexpected field") =>
/**
* A Zod type to validate Hardhat's ConfigurationVariable objects.
*/
export const configurationVariableType = z.object({
export const configurationVariableSchema = z.object({
_type: z.literal("ConfigurationVariable"),
name: z.string(),
});

/**
* A Zod type to validate Hardhat's SensitiveString values.
*/
export const sensitiveStringType = conditionalUnionType(
[
[(data) => typeof data === "string", z.string()],
[isObject, configurationVariableType],
],
export const sensitiveStringSchema = unionType(
[z.string(), configurationVariableSchema],
"Expected a string or a Configuration Variable",
);

/**
* A Zod type to validate Hardhat's SensitiveString values that expect a URL.
*
* TODO: The custom error message in the unionType function doesn't work
* correctly when using string().url() for validation, see:
* https://github.com/colinhacks/zod/issues/2940
* As a workaround, we provide the error message directly in the url() call.
* We should remove this when the issue is fixed.
*/
export const sensitiveUrlType = conditionalUnionType(
export const sensitiveUrlSchema = unionType(
[
[(data) => typeof data === "string", z.string().url()],
[isObject, configurationVariableType],
z.string().url("Expected a URL or a Configuration Variable"),
configurationVariableSchema,
],
"Expected a URL or a Configuration Variable",
);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,78 +1,94 @@
import type {
ConfigurationVariable,
GasConfig,
GasUserConfig,
HardhatConfig,
HardhatUserConfig,
HttpNetworkConfig,
NetworkConfig,
NetworkUserConfig,
ResolvedConfigurationVariable,
} from "../../../../types/config.js";
import type { ConfigHooks } from "../../../../types/hooks.js";

import { validateUserConfig } from "../type-validation.js";

function resolveBigIntOrAuto(
value: number | bigint | "auto" | undefined,
): bigint | "auto" {
if (value === undefined || value === "auto") {
return "auto";
}

// TODO: Validate that it's a valid BigInt
return BigInt(value);
}

export default async (): Promise<Partial<ConfigHooks>> => ({
extendUserConfig: async (config, next) => {
const extendedConfig = await next(config);
extendUserConfig,
validateUserConfig,
resolveUserConfig,
});

const networks: Record<string, NetworkUserConfig> =
extendedConfig.networks ?? {};
export async function extendUserConfig(
config: HardhatUserConfig,
next: (nextConfig: HardhatUserConfig) => Promise<HardhatUserConfig>,
): Promise<HardhatUserConfig> {
const extendedConfig = await next(config);

return {
...extendedConfig,
networks: {
...networks,
localhost: {
url: "http://localhost:8545",
...networks.localhost,
type: "http",
},
},
};
},
validateUserConfig,
resolveUserConfig: async (userConfig, resolveConfigurationVariable, next) => {
const resolvedConfig = await next(userConfig, resolveConfigurationVariable);
const networks: Record<string, NetworkUserConfig> =
extendedConfig.networks ?? {};

const networks: Record<string, NetworkUserConfig> =
userConfig.networks ?? {};
return {
...extendedConfig,
networks: {
...networks,
localhost: {
url: "http://localhost:8545",
...networks.localhost,
type: "http",
},
},
};
}

const resolvedNetworks: Record<string, NetworkConfig> = {};
export async function resolveUserConfig(
userConfig: HardhatUserConfig,
resolveConfigurationVariable: (
variableOrString: ConfigurationVariable | string,
) => ResolvedConfigurationVariable,
next: (
nextUserConfig: HardhatUserConfig,
nextResolveConfigurationVariable: (
variableOrString: ConfigurationVariable | string,
) => ResolvedConfigurationVariable,
) => Promise<HardhatConfig>,
): Promise<HardhatConfig> {
const resolvedConfig = await next(userConfig, resolveConfigurationVariable);

for (const [networkName, networkConfig] of Object.entries(networks)) {
if (networkConfig.type !== "http") {
// eslint-disable-next-line no-restricted-syntax -- TODO
throw new Error("Only HTTP network is supported for now");
}
const networks: Record<string, NetworkUserConfig> = userConfig.networks ?? {};

const resolvedNetworkConfig: HttpNetworkConfig = {
type: "http",
chainId: networkConfig.chainId,
chainType: networkConfig.chainType,
from: networkConfig.from,
gas: resolveBigIntOrAuto(networkConfig.gas),
gasMultiplier: networkConfig.gasMultiplier ?? 1,
gasPrice: resolveBigIntOrAuto(networkConfig.gasPrice),
url: networkConfig.url,
timeout: networkConfig.timeout ?? 20_000,
httpHeaders: networkConfig.httpHeaders ?? {},
};
const resolvedNetworks: Record<string, NetworkConfig> = {};

resolvedNetworks[networkName] = resolvedNetworkConfig;
for (const [networkName, networkConfig] of Object.entries(networks)) {
if (networkConfig.type !== "http") {
// eslint-disable-next-line no-restricted-syntax -- TODO
throw new Error("Only HTTP network is supported for now");
}

return {
...resolvedConfig,
defaultNetwork: resolvedConfig.defaultNetwork ?? "localhost",
defaultChainType: resolvedConfig.defaultChainType ?? "unknown",
networks: resolvedNetworks,
const resolvedNetworkConfig: HttpNetworkConfig = {
type: "http",
chainId: networkConfig.chainId,
chainType: networkConfig.chainType,
from: networkConfig.from,
gas: resolveGasConfig(networkConfig.gas),
gasMultiplier: networkConfig.gasMultiplier ?? 1,
gasPrice: resolveGasConfig(networkConfig.gasPrice),
url: networkConfig.url,
timeout: networkConfig.timeout ?? 20_000,
httpHeaders: networkConfig.httpHeaders ?? {},
};
},
});

resolvedNetworks[networkName] = resolvedNetworkConfig;
}

return {
...resolvedConfig,
defaultChainType: resolvedConfig.defaultChainType ?? "unknown",
defaultNetwork: resolvedConfig.defaultNetwork ?? "localhost",
networks: resolvedNetworks,
};
}

function resolveGasConfig(value: GasUserConfig = "auto"): GasConfig {
return value === "auto" ? value : BigInt(value);
}
Original file line number Diff line number Diff line change
Expand Up @@ -112,7 +112,6 @@ export class HttpProvider extends EventEmitter implements EthereumProvider {
this.#jsonRpcRequestWrapper = jsonRpcRequestWrapper;
}

// TODO: We should test that the request is actually wrapped
public async request(
requestArguments: RequestArguments,
): Promise<SuccessfulJsonRpcResponse["result"]> {
Expand Down Expand Up @@ -151,7 +150,6 @@ export class HttpProvider extends EventEmitter implements EthereumProvider {
return jsonRpcResponse.result;
}

// TODO: This should be tested
public async close(): Promise<void> {
// See https://github.com/nodejs/undici/discussions/3522#discussioncomment-10498734
await this.#dispatcher.close();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,7 @@ export class NetworkManagerImplementation {

if (
networkConfigOverride !== undefined &&
"type" in networkConfigOverride &&
networkConfigOverride.type !==
this.#networkConfigs[resolvedNetworkName].type
) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -48,14 +48,16 @@ declare module "../../../../types/config.js" {

export type NetworkUserConfig = HttpNetworkUserConfig | EdrNetworkUserConfig;

export type GasUserConfig = "auto" | number | bigint;

export interface HttpNetworkUserConfig {
type: "http";
chainId?: number;
chainType?: ChainType;
from?: string;
gas?: "auto" | number | bigint;
gas?: GasUserConfig;
gasMultiplier?: number;
gasPrice?: "auto" | number | bigint;
gasPrice?: GasUserConfig;

// HTTP network specific
url: string;
Expand All @@ -68,23 +70,25 @@ declare module "../../../../types/config.js" {
chainId: number;
chainType?: ChainType;
from?: string;
gas: "auto" | number | bigint;
gas: GasUserConfig;
gasMultiplier: number;
gasPrice: "auto" | number | bigint;
gasPrice: GasUserConfig;

// EDR network specific
}

export type NetworkConfig = HttpNetworkConfig | EdrNetworkConfig;

export type GasConfig = "auto" | bigint;

export interface HttpNetworkConfig {
type: "http";
chainId?: number;
chainType?: ChainType;
from?: string;
gas: "auto" | bigint;
gas: GasConfig;
gasMultiplier: number;
gasPrice: "auto" | bigint;
gasPrice: GasConfig;

// HTTP network specific
url: string;
Expand All @@ -97,9 +101,9 @@ declare module "../../../../types/config.js" {
chainId: number;
chainType?: ChainType;
from: string;
gas: "auto" | bigint;
gas: GasConfig;
gasMultiplier: number;
gasPrice: "auto" | bigint;
gasPrice: GasConfig;

// EDR network specific
}
Expand Down
Loading

0 comments on commit ce77ee9

Please sign in to comment.