Skip to content

Add build info watcher to the hardhat node task #6040

@galargh

Description

@galargh

This is a follow-up task to #5615

It is about adding a build info (from artifact) watcher functionality. The idea is to watch for build info changes and adding compilation info to EDR when they happen.

We'll be able to work on this once EDR is ready to receive build info from us.

Below, you'll find a draft of the implementation.

Implementation:

import fsPromises from "node:fs/promises";

export interface WatcherEvent {
  eventType: "change" | "rename";
  filename: string | null;
}

export type WatcherEventHandler = (event: WatcherEvent) => Promise<void>;

export class Watcher {
  readonly #abortController: AbortController;
  readonly #eventLoop: Promise<void>;

  constructor(path: string, eventHandler: WatcherEventHandler) {
    this.#abortController = new AbortController();

    const events = fsPromises.watch(path, {
      recursive: true,
      signal: this.#abortController.signal,
    });

    this.#eventLoop = new Promise(async () => {
      for await (const event of events) {
        await eventHandler(event);
      }
    });
  }

  public close(): Promise<void> {
    this.#abortController.abort();
    return this.#eventLoop;
  }
}

Usage:

import type { WatcherEvent } from "./watcher.js";
import type { BuildInfo } from "../../../types/artifacts.js";

import path from "node:path";

import { exists, readJsonFile } from "@ignored/hardhat-vnext-utils/fs";

import { BUILD_INFO_DIR_NAME } from "../artifacts/artifacts-manager.js";

import { Watcher } from "./watcher.js";

...

  const watcher = new Watcher(
    path.join(hre.config.paths.artifacts, BUILD_INFO_DIR_NAME),
    async ({ eventType, filename }: WatcherEvent) => {
      log(`Detected ${eventType} in ${filename}`);

      if (
        filename === null ||
        filename.endsWith(".output.json") ||
        !(await exists(filename))
      ) {
        return;
      }

      const filenameOutput = filename.replace(".json", ".output.json");
      if (await exists(filenameOutput)) {
        return;
      }

      const buildInfo: BuildInfo = await readJsonFile(filename);
      const buildInfoOutput = await readJsonFile(filenameOutput);

      try {
        await provider.request({
          method: "hardhat_addCompilationResult",
          params: [buildInfo.solcVersion, buildInfo.input, buildInfoOutput],
        });
      } catch (error) {
        log(error);
      }
    },
  );
  
  ...
  
  await watcher.close();
  
...

Metadata

Metadata

Assignees

Labels

status:blockedBlocked by other issues or external reasonsv-nextA Hardhat v3 development task

Type

No type

Projects

Status

In Review

Relationships

None yet

Development

No branches or pull requests

Issue actions