Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support ignoring Hardhat compile errors when extracting detailed namespaced storage layouts for validations #1090

Merged
merged 10 commits into from
Oct 10, 2024
Merged
4 changes: 4 additions & 0 deletions packages/core/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
# Changelog

## Unreleased

- Support ignoring Hardhat compile errors when extracting detailed namespaced storage layouts for validations. ([#1090](https://github.com/OpenZeppelin/openzeppelin-upgrades/pull/1090))

## 1.39.0 (2024-10-02)

- Fix Hardhat compile error when library or interface has struct with namespace annotation. ([#1086](https://github.com/OpenZeppelin/openzeppelin-upgrades/pull/1086))
Expand Down
2 changes: 1 addition & 1 deletion packages/core/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@openzeppelin/upgrades-core",
"version": "1.39.0",
"version": "1.40.0",
"description": "",
"repository": "https://github.com/OpenZeppelin/openzeppelin-upgrades/tree/master/packages/core",
"license": "MIT",
Expand Down
1 change: 1 addition & 0 deletions packages/core/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -63,3 +63,4 @@ export { getUpgradeInterfaceVersion } from './upgrade-interface-version';
export { makeNamespacedInput } from './utils/make-namespaced';
export { isNamespaceSupported } from './storage/namespace';
export { inferProxyAdmin } from './infer-proxy-admin';
export { assertUnreachable } from './utils/assert';
4 changes: 4 additions & 0 deletions packages/plugin-hardhat/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
# Changelog

## Unreleased

- Support ignoring Hardhat compile errors when extracting detailed namespaced storage layouts for validations. ([#1090](https://github.com/OpenZeppelin/openzeppelin-upgrades/pull/1090))

## 3.4.0 (2024-09-23)

### Potentially breaking changes
Expand Down
2 changes: 1 addition & 1 deletion packages/plugin-hardhat/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@
"@openzeppelin/defender-sdk-base-client": "^1.14.4",
"@openzeppelin/defender-sdk-deploy-client": "^1.14.4",
"@openzeppelin/defender-sdk-network-client": "^1.14.4",
"@openzeppelin/upgrades-core": "^1.38.0",
"@openzeppelin/upgrades-core": "^1.40.0",
"chalk": "^4.1.0",
"debug": "^4.1.1",
"ethereumjs-util": "^7.1.5",
Expand Down
58 changes: 43 additions & 15 deletions packages/plugin-hardhat/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import { subtask, extendEnvironment, extendConfig } from 'hardhat/config';
import { TASK_COMPILE_SOLIDITY, TASK_COMPILE_SOLIDITY_COMPILE } from 'hardhat/builtin-tasks/task-names';
import { lazyObject } from 'hardhat/plugins';
import { HardhatConfig, HardhatRuntimeEnvironment } from 'hardhat/types';
import type { silenceWarnings, SolcInput, SolcOutput } from '@openzeppelin/upgrades-core';
import { assertUnreachable, type silenceWarnings, type SolcInput, type SolcOutput } from '@openzeppelin/upgrades-core';
import type { DeployFunction } from './deploy-proxy';
import type { PrepareUpgradeFunction } from './prepare-upgrade';
import type { UpgradeFunction } from './upgrade-proxy';
Expand Down Expand Up @@ -101,7 +101,46 @@ subtask(TASK_COMPILE_SOLIDITY_COMPILE, async (args: RunCompilerArgs, hre, runSup
if (isNamespaceSupported(args.solcVersion)) {
const namespacedInput = makeNamespacedInput(args.input, output, args.solcVersion);
namespacedOutput = (await runSuper({ ...args, quiet: true, input: namespacedInput })).output;
await checkNamespacedCompileErrors(namespacedOutput);

const namespacedCompileErrors = getNamespacedCompileErrors(namespacedOutput);
if (namespacedCompileErrors.length > 0) {
// If there are compile errors in the namespaced output, show error or warning if needed, then only use the original output

const msg = `Failed to compile modified contracts for namespaced storage layout validations:\n\n${namespacedCompileErrors.join('\n')}`;
const preamble = [
'Please report this at https://zpl.in/upgrades/report. If possible, include the source code for the contracts mentioned in the errors above.',
'This step allows for advanced storage modifications such as tight varible packing when performing upgrades with namespaced storage layouts.',
];

switch (hre.config.namespacedCompileErrors) {
case undefined:
case 'error': {
const { UpgradesError } = await import('@openzeppelin/upgrades-core');
const details = [
...preamble,
'If you are not using namespaced storage, or if you do not anticipate making advanced modifications to namespaces during upgrades,',
"you can set namespacedCompileErrors: 'warn' or namespacedCompileErrors: 'ignore' in your hardhat config to convert this to a warning or to ignore this.",
];
throw new UpgradesError(msg, () => details.join('\n'));
}
case 'warn': {
const { logWarning } = await import('@openzeppelin/upgrades-core');
const details = [
...preamble,
'If you are not using namespaced storage, or if you do not anticipate making advanced modifications to namespaces during upgrades,',
"you can set namespacedCompileErrors: 'ignore' in your hardhat config to ignore this.",
];
logWarning(msg, details);
break;
}
case 'ignore':
break;
default:
assertUnreachable(hre.config.namespacedCompileErrors);
}

namespacedOutput = undefined;
}
}

const validations = validate(output, decodeSrc, args.solcVersion, args.input, namespacedOutput);
Expand All @@ -111,11 +150,7 @@ subtask(TASK_COMPILE_SOLIDITY_COMPILE, async (args: RunCompilerArgs, hre, runSup
return { output, solcBuild };
});

/**
* Checks for compile errors in the modified contracts for namespaced storage.
* If errors are found, throws an error with the compile error messages.
*/
async function checkNamespacedCompileErrors(namespacedOutput: SolcOutput) {
function getNamespacedCompileErrors(namespacedOutput: SolcOutput) {
const errors = [];
if (namespacedOutput.errors !== undefined) {
for (const error of namespacedOutput.errors) {
Expand All @@ -124,14 +159,7 @@ async function checkNamespacedCompileErrors(namespacedOutput: SolcOutput) {
}
}
}
if (errors.length > 0) {
const { UpgradesError } = await import('@openzeppelin/upgrades-core');
throw new UpgradesError(
`Failed to compile modified contracts for namespaced storage:\n\n${errors.join('\n')}`,
() =>
'Please report this at https://zpl.in/upgrades/report. If possible, include the source code for the contracts mentioned in the errors above.',
);
}
return errors;
}

extendEnvironment(hre => {
Expand Down
4 changes: 4 additions & 0 deletions packages/plugin-hardhat/src/type-extensions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,12 +17,16 @@ export interface HardhatDefenderConfig {
network?: string;
}

export type NamespacedCompileErrorsRule = 'error' | 'warn' | 'ignore';

declare module 'hardhat/types/config' {
export interface HardhatUserConfig {
defender?: HardhatDefenderConfig;
namespacedCompileErrors?: NamespacedCompileErrorsRule;
}

export interface HardhatConfig {
defender?: HardhatDefenderConfig;
namespacedCompileErrors?: NamespacedCompileErrorsRule;
}
}
Loading