Skip to content

Commit

Permalink
Remove enableTransientStorage custom logic & throw an error if pre-ca…
Browse files Browse the repository at this point in the history
…ncun
  • Loading branch information
schaable committed Feb 13, 2024
1 parent 45b8290 commit 8000aad
Show file tree
Hide file tree
Showing 3 changed files with 45 additions and 143 deletions.
@@ -1,7 +1,6 @@
import { Block, HeaderData } from "@nomicfoundation/ethereumjs-block";
import {
Common,
CustomCommonOpts,
EVMStateManagerInterface,
} from "@nomicfoundation/ethereumjs-common";
import { ERROR } from "@nomicfoundation/ethereumjs-evm/dist/cjs/exceptions";
Expand Down Expand Up @@ -2555,6 +2554,11 @@ Hardhat Network's forking functionality only works with blocks from at least spu

originalCommon = (this._vm as any).common;

assertTransientStorageCompatibility(
this._enableTransientStorage,
this._vm.common.hardfork() as HardforkName
);

(this._vm as any).common = Common.custom(
{
chainId:
Expand All @@ -2566,7 +2570,6 @@ Hardhat Network's forking functionality only works with blocks from at least spu
},
{
hardfork: this._selectHardfork(blockContext.header.number),
...this._getTransientStorageSettings(),
}
);

Expand Down Expand Up @@ -2947,6 +2950,11 @@ Hardhat Network's forking functionality only works with blocks from at least spu
}

private _getCommonForTracing(networkId: number, blockNumber: bigint): Common {
assertTransientStorageCompatibility(
this._enableTransientStorage,
this._vm.common.hardfork() as HardforkName
);

try {
const common = Common.custom(
{
Expand All @@ -2955,7 +2963,6 @@ Hardhat Network's forking functionality only works with blocks from at least spu
},
{
hardfork: this._selectHardfork(BigInt(blockNumber)),
...this._getTransientStorageSettings(),
}
);

Expand All @@ -2966,12 +2973,15 @@ Hardhat Network's forking functionality only works with blocks from at least spu
);
}
}
}

private _getTransientStorageSettings(): Partial<CustomCommonOpts> {
if (this._enableTransientStorage) {
return { eips: [1153] };
}

return {};
export function assertTransientStorageCompatibility(
enableTransientStorage: boolean,
hardfork: HardforkName
) {
if (enableTransientStorage && !hardforkGte(hardfork, HardforkName.CANCUN)) {
throw new InternalError(
`Transient storage is not compatible with hardfork "${hardfork}". To use transient storage, set the hardfork to "cancun" or later.`
);
}
}
@@ -1,14 +1,19 @@
import { Common } from "@nomicfoundation/ethereumjs-common";

import { LocalNodeConfig } from "../node-types";
import { HardforkName } from "../../../util/hardforks";
import { assertTransientStorageCompatibility } from "../node";

export function makeCommon({
chainId,
networkId,
hardfork,
enableTransientStorage,
}: LocalNodeConfig) {
const otherSettings = enableTransientStorage ? { eips: [1153] } : {};
assertTransientStorageCompatibility(
enableTransientStorage,
hardfork as HardforkName
);

const common = Common.custom(
{
Expand All @@ -17,8 +22,8 @@ export function makeCommon({
},
{
// ethereumjs uses this name for the merge hardfork
hardfork: hardfork === "merge" ? "mergeForkIdTransition" : hardfork,
...otherSettings,
hardfork:
hardfork === HardforkName.MERGE ? "mergeForkIdTransition" : hardfork,
}
);

Expand Down
149 changes: 18 additions & 131 deletions packages/hardhat-core/test/internal/hardhat-network/provider/node.ts
Expand Up @@ -1101,148 +1101,35 @@ describe("HardhatNode", () => {
automine: true,
chainId: 1,
networkId: 1,
hardfork: "london",
hardfork: "",
blockGasLimit: 1_000_000,
minGasPrice: 0n,
genesisAccounts: DEFAULT_ACCOUNTS,
chains: defaultHardhatNetworkParams.chains,
mempoolOrder: "priority",
coinbase: "0x0000000000000000000000000000000000000000",
allowBlocksWithSameTimestamp: false,
enableTransientStorage: false,
enableTransientStorage: true,
};

describe("When not enabled and on a fork that doesn't support it", function () {
it("Should revert if trying to run TLOAD in a tx", async function () {
const [, hardhatNode] = await HardhatNode.create(nodeConfig);

const tx = createTestTransaction({
nonce: 0,
from: DEFAULT_ACCOUNTS_ADDRESSES[0],
to: undefined,
data: TLOAD_DEPLOYMENT_BYTECODE,
gasLimit: 1_000_000n,
gasPrice: 10n ** 9n,
});

const transactionResult = await hardhatNode.sendTransaction(tx);

if (
typeof transactionResult === "string" ||
Array.isArray(transactionResult)
) {
assert.fail("Expected a MineBlockResult");
}

const error = transactionResult.traces[0].error;
assert.isDefined(error);
assert.include(error!.message, "invalid opcode");
});

it("Should revert if trying to run TSTORE in a tx", async function () {
const [, hardhatNode] = await HardhatNode.create(nodeConfig);

const tx = createTestTransaction({
nonce: 0,
from: DEFAULT_ACCOUNTS_ADDRESSES[0],
to: undefined,
data: TSTORE_DEPLOYMENT_BYTECODE,
gasLimit: 1_000_000n,
gasPrice: 10n ** 9n,
});

const transactionResult = await hardhatNode.sendTransaction(tx);

if (
typeof transactionResult === "string" ||
Array.isArray(transactionResult)
) {
assert.fail("Expected a MineBlockResult");
}

const error = transactionResult.traces[0].error;
assert.isDefined(error);
assert.include(error!.message, "invalid opcode");
});

it("Should revert if trying to run TLOAD in a call", async function () {
const [, hardhatNode] = await HardhatNode.create(nodeConfig);

const callResult = await hardhatNode.runCall(
{
to: undefined,
from: toBuffer(DEFAULT_ACCOUNTS_ADDRESSES[0]),
data: toBuffer(TLOAD_DEPLOYMENT_BYTECODE),
value: 0n,
gasLimit: 1_000_000n,
},
0n
);

assert.isDefined(callResult.error);
assert.include(callResult.error!.message, "invalid opcode");
});

it("Should revert if trying to run TSTORE in a call", async function () {
const [, hardhatNode] = await HardhatNode.create(nodeConfig);

const callResult = await hardhatNode.runCall(
{
to: undefined,
from: toBuffer(DEFAULT_ACCOUNTS_ADDRESSES[0]),
data: toBuffer(TSTORE_DEPLOYMENT_BYTECODE),
value: 0n,
gasLimit: 1_000_000n,
},
0n
);

assert.isDefined(callResult.error);
assert.include(callResult.error!.message, "invalid opcode");
});

it("Should revert if trying to run TLOAD in a gasEstimate", async function () {
const [, hardhatNode] = await HardhatNode.create(nodeConfig);

const estimateGasResult = await hardhatNode.estimateGas(
{
to: undefined,
from: toBuffer(DEFAULT_ACCOUNTS_ADDRESSES[0]),
data: toBuffer(TLOAD_DEPLOYMENT_BYTECODE),
value: 0n,
gasLimit: 1_000_000n,
},
0n
);

assert.isDefined(estimateGasResult.error);
assert.include(estimateGasResult.error!.message, "invalid opcode");
});

it("Should revert if trying to run TSTORE in a gasEstimate", async function () {
const [, hardhatNode] = await HardhatNode.create(nodeConfig);

const estimateGasResult = await hardhatNode.estimateGas(
{
to: undefined,
from: toBuffer(DEFAULT_ACCOUNTS_ADDRESSES[0]),
data: toBuffer(TSTORE_DEPLOYMENT_BYTECODE),
value: 0n,
gasLimit: 1_000_000n,
},
0n
describe("When on a fork that doesn't support it", function () {
it("Should revert when trying to create the node", async function () {
await expectErrorAsync(
async () =>
HardhatNode.create({
...nodeConfig,
hardfork: "london",
}),
/Transient storage is not compatible with hardfork "london"./
);

assert.isDefined(estimateGasResult.error);
assert.include(estimateGasResult.error!.message, "invalid opcode");
});
});

describe("When enabled", function () {
describe("When on a fork that supports it", function () {
it("Should not revert if trying to run TLOAD in a tx", async function () {
const [, hardhatNode] = await HardhatNode.create({
...nodeConfig,
enableTransientStorage: true,
hardfork: "cancun",
});

const tx = createTestTransaction({
Expand Down Expand Up @@ -1270,7 +1157,7 @@ describe("HardhatNode", () => {
it("Should not revert if trying to run TSTORE in a tx", async function () {
const [, hardhatNode] = await HardhatNode.create({
...nodeConfig,
enableTransientStorage: true,
hardfork: "cancun",
});

const tx = createTestTransaction({
Expand Down Expand Up @@ -1298,7 +1185,7 @@ describe("HardhatNode", () => {
it("Should not revert if trying to run TLOAD in a call", async function () {
const [, hardhatNode] = await HardhatNode.create({
...nodeConfig,
enableTransientStorage: true,
hardfork: "cancun",
});

const callResult = await hardhatNode.runCall(
Expand All @@ -1318,7 +1205,7 @@ describe("HardhatNode", () => {
it("Should revert if trying to run TSTORE in a call", async function () {
const [, hardhatNode] = await HardhatNode.create({
...nodeConfig,
enableTransientStorage: true,
hardfork: "cancun",
});

const callResult = await hardhatNode.runCall(
Expand All @@ -1338,7 +1225,7 @@ describe("HardhatNode", () => {
it("Should not revert if trying to run TLOAD in a gasEstimate", async function () {
const [, hardhatNode] = await HardhatNode.create({
...nodeConfig,
enableTransientStorage: true,
hardfork: "cancun",
});

const estimateGasResult = await hardhatNode.estimateGas(
Expand All @@ -1358,7 +1245,7 @@ describe("HardhatNode", () => {
it("Should not revert if trying to run TSTORE in a gasEstimate", async function () {
const [, hardhatNode] = await HardhatNode.create({
...nodeConfig,
enableTransientStorage: true,
hardfork: "cancun",
});

const estimateGasResult = await hardhatNode.estimateGas(
Expand Down

0 comments on commit 8000aad

Please sign in to comment.