Skip to content

Commit

Permalink
Implement VersionCompatibilityChecker and implement the call to it in…
Browse files Browse the repository at this point in the history
… the setup.ts functions (#218)
  • Loading branch information
dule-git authored Sep 25, 2024
1 parent 9201bfe commit 2dd490f
Show file tree
Hide file tree
Showing 4 changed files with 105 additions and 8 deletions.
25 changes: 21 additions & 4 deletions packages/hre-extender-v1/src/setup.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ import{ TenderlyNetwork as TenderlyNetworkInterface } from "@tenderly/api-client

import { logger } from "./logger";
import { TenderlyService } from "@tenderly/api-client";
import { Tenderly, TenderlyNetwork } from "@tenderly/hardhat-integration";
import { Tenderly, TenderlyNetwork, VersionCompatibilityChecker } from "@tenderly/hardhat-integration";
import { extendEthers } from "./extenders/extend-ethers";
import { extendHardhatDeploy } from "./extenders/extend-hardhat-deploy";
import { isTenderlyNetworkConfig } from "./extenders/tenderly-network-resolver";
Expand All @@ -26,12 +26,12 @@ export function setup(cfg: { automaticVerifications: boolean } = { automaticVeri
extendEnvironment(async (hre: HardhatRuntimeEnvironment) => {
process.env.TENDERLY_AUTOMATIC_VERIFICATION = cfg.automaticVerifications ? "true": "false"
process.env.AUTOMATIC_VERIFICATION_ENABLED = cfg.automaticVerifications ? "true": "false"
process.env.HARDHAT_TENDERLY_VERSION = require("../package.json").version;
const hardhatTenderlyVersion = require("../package.json").version;
process.env.HARDHAT_TENDERLY_VERSION = hardhatTenderlyVersion;

hre.tenderly = lazyObject(() => new Tenderly(hre));

const pjson = require("../package.json");
logger.info("@tenderly/hardhat-tenderly version:", pjson.version);
logger.info("@tenderly/hardhat-tenderly version:", hardhatTenderlyVersion);

logger.info("Tenderly running configuration: ", {
username: hre.config.tenderly?.username,
Expand All @@ -40,6 +40,23 @@ export function setup(cfg: { automaticVerifications: boolean } = { automaticVeri
privateVerification: hre.config.tenderly?.privateVerification,
networkName: hre.network.name,
});

// check if the ethers and hardhat-tenderly versions are compatible
const versionCompatibilityChecker = new VersionCompatibilityChecker();
const [areCompatible, ethersVersion] = versionCompatibilityChecker.areEthersAndHardhatTenderlyVersionsCompatible(
hre,
hardhatTenderlyVersion,
);
if (!areCompatible) {
const compatibleHardhatTenderlyVersion = versionCompatibilityChecker.compatibleHardhatTenderlyVersionForEthersVersion(
ethersVersion,
);
console.log(
"\x1b[31m%s%s\x1b[0m",
`Wrong '@tenderly/hardhat-tenderly' version '${hardhatTenderlyVersion}' used with ethers version '${ethersVersion}'.\n`,
`Please use the correct version of latest '@tenderly/hardhat-tenderly@${compatibleHardhatTenderlyVersion}' plugin.\n`
);
}

extendProvider(hre);
populateNetworks();
Expand Down
26 changes: 22 additions & 4 deletions packages/hre-extender-v2/src/setup.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ import{ TenderlyNetwork as TenderlyNetworkInterface } from "@tenderly/api-client

import { logger } from "./logger";
import { TenderlyService } from"@tenderly/api-client";
import { Tenderly, TenderlyNetwork } from "@tenderly/hardhat-integration";
import { Tenderly, TenderlyNetwork, VersionCompatibilityChecker } from "@tenderly/hardhat-integration";
import { extendEthers } from "./extenders/extend-ethers";
import { extendUpgrades } from "./extenders/extend-upgrades";
import { extendHardhatDeploy } from "./extenders/extend-hardhat-deploy";
Expand All @@ -33,12 +33,13 @@ export function setup(cfg: { automaticVerifications: boolean } = { automaticVeri
extendEnvironment(async (hre: HardhatRuntimeEnvironment) => {
process.env.TENDERLY_AUTOMATIC_VERIFICATION = cfg.automaticVerifications ? "true": "false"
process.env.AUTOMATIC_VERIFICATION_ENABLED = cfg.automaticVerifications ? "true": "false"
process.env.HARDHAT_TENDERLY_VERSION = require("../package.json").version;

const hardhatTenderlyVersion = require("../package.json").version;
process.env.HARDHAT_TENDERLY_VERSION = hardhatTenderlyVersion;

hre.tenderly = lazyObject(() => new Tenderly(hre));

const pjson = require("../package.json");
logger.info("@tenderly/hardhat-tenderly version:", pjson.version);
logger.info("@tenderly/hardhat-tenderly version:", hardhatTenderlyVersion);

logger.info("Tenderly running configuration: ", {
username: hre.config.tenderly?.username,
Expand All @@ -47,6 +48,23 @@ export function setup(cfg: { automaticVerifications: boolean } = { automaticVeri
privateVerification: hre.config.tenderly?.privateVerification,
networkName: hre.network.name,
});

// check if the ethers and hardhat-tenderly versions are compatible
const versionCompatibilityChecker = new VersionCompatibilityChecker();
const [areCompatible, ethersVersion] = versionCompatibilityChecker.areEthersAndHardhatTenderlyVersionsCompatible(
hre,
hardhatTenderlyVersion,
);
if (!areCompatible) {
const compatibleHardhatTenderlyVersion = versionCompatibilityChecker.compatibleHardhatTenderlyVersionForEthersVersion(
ethersVersion,
);
console.log(
"\x1b[31m%s%s\x1b[0m",
`Wrong '@tenderly/hardhat-tenderly' version '${hardhatTenderlyVersion}' used with ethers version '${ethersVersion}'.\n`,
`Please use the correct version of latest '@tenderly/hardhat-tenderly@${compatibleHardhatTenderlyVersion}' plugin.\n`
);
}

extendProvider(hre);
populateNetworks();
Expand Down
61 changes: 61 additions & 0 deletions packages/tenderly-hardhat/src/VersionCompatibilityChecker.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
import { HardhatRuntimeEnvironment } from "hardhat/types";

export class VersionCompatibilityChecker {
public areEthersAndHardhatTenderlyVersionsCompatible(
hre: HardhatRuntimeEnvironment,
hardhatTenderlyVersion: string
): [boolean, string, string] {
// todo: there should be an interface VersionProvider from this tenderly-hardhat package.
// the hre-extender-v1 and hre-extender-v2 packages should implement that interface on their own
// for both EthersVersionProvider and TenderlyVersionProvider.
// I am casting this to `any` just for the sake of time.
// With this approach, this can easily be tested as well.
let ethersVersion = (hre as any).ethers.version as string;
ethersVersion = this._trimVersion(ethersVersion, "ethers/");
const ethersMajorVersion = this._majorVersion(ethersVersion);

const hardhatTenderlyMajorVersion = this._majorVersion(hardhatTenderlyVersion);

return [this._areCompatible(ethersMajorVersion, hardhatTenderlyMajorVersion), ethersVersion, hardhatTenderlyVersion];
}

// todo: change this function once we have the available data of which hardhat-tenderly version is the newest.
// Then,
// the function will call the API to get the newest hardhat-tenderly version
// and we can use that to print out the command to upgrade the plugin.
public compatibleHardhatTenderlyVersionForEthersVersion(ethersVersion: string): string {
ethersVersion = this._trimVersion(ethersVersion, "ethers/");
const ethersMajorVersion = this._majorVersion(ethersVersion);

if (ethersMajorVersion === 5) {
return "1.x.x.";
}
if (ethersMajorVersion === 6) {
return "2.x.x";
}

throw new Error(`Unsupported ethers version: ${ethersVersion}`);
}

private _trimVersion(version: string, toTrim: string): string {
if (version.startsWith(toTrim)) {
return version.slice(toTrim.length);
}
return version;
}

private _majorVersion(version: string): number {
return parseInt(version.split(".")[0], 10);
}

private _areCompatible(ethersMajorVersion: number, hardhatTenderlyMajorVersion: number): boolean {
if (ethersMajorVersion === 5 && hardhatTenderlyMajorVersion === 1) {
return true;
}
if (ethersMajorVersion === 6 && hardhatTenderlyMajorVersion === 2) {
return true;
}

return false;
}
}
1 change: 1 addition & 0 deletions packages/tenderly-hardhat/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import "./utils/logger";
export { Tenderly } from "./Tenderly";
export { TenderlyNetwork } from "./TenderlyNetwork";
export * from "./type-extensions";
export { VersionCompatibilityChecker } from "./VersionCompatibilityChecker";

// ProxyPlaceholderName is used for the `name` parameter in the `tenderly.verify` method because the name is actually not important.
// Beneath we use `@nomicfoundation/hardhat-verify` task in order to verify the proxy, and it doesn't need a name.
Expand Down

0 comments on commit 2dd490f

Please sign in to comment.