diff --git a/.changeset/pretty-dogs-hope.md b/.changeset/pretty-dogs-hope.md new file mode 100644 index 0000000000000..753f968a2af3b --- /dev/null +++ b/.changeset/pretty-dogs-hope.md @@ -0,0 +1,5 @@ +--- +'@eth-optimism/integration-tests': patch +--- + +Enforce fees in docker-compose setup and test cases for fee too low and fee too high diff --git a/integration-tests/test/fee-payment.spec.ts b/integration-tests/test/fee-payment.spec.ts index 6282a5aa9801d..b284eeda1a7f5 100644 --- a/integration-tests/test/fee-payment.spec.ts +++ b/integration-tests/test/fee-payment.spec.ts @@ -8,7 +8,7 @@ import { serialize } from '@ethersproject/transactions' import { predeploys, getContractFactory } from '@eth-optimism/contracts' /* Imports: Internal */ -import { gasPriceForL2, isLiveNetwork } from './shared/utils' +import { isLiveNetwork } from './shared/utils' import { OptimismEnv } from './shared/env' import { Direction } from './shared/watcher-utils' @@ -173,10 +173,7 @@ describe('Fee Payment Integration Tests', async () => { env.sequencerFeeVault.address ) - // Submit the withdrawal. - const withdrawTx = await env.sequencerFeeVault.withdraw({ - gasPrice: await gasPriceForL2(env), // Will be zero on HH - }) + const withdrawTx = await env.sequencerFeeVault.withdraw() // Wait for the withdrawal to be relayed to L1. await withdrawTx.wait() diff --git a/integration-tests/test/rpc.spec.ts b/integration-tests/test/rpc.spec.ts index 240e87821c527..19936a2c7d296 100644 --- a/integration-tests/test/rpc.spec.ts +++ b/integration-tests/test/rpc.spec.ts @@ -140,6 +140,45 @@ describe('Basic RPC tests', () => { 'gas required exceeds allowance' ) }) + + it('should reject a transaction with too low of a fee', async () => { + if (isLiveNetwork()) { + console.log('Skipping too low of a fee test on live network') + return + } + + const gasPrice = await env.gasPriceOracle.gasPrice() + await env.gasPriceOracle.setGasPrice(1000) + + const tx = { + ...defaultTransactionFactory(), + gasPrice: 1, + } + + await expect(env.l2Wallet.sendTransaction(tx)).to.be.rejectedWith( + `gas price too low: 1 wei, use at least tx.gasPrice = 1000 wei` + ) + // Reset the gas price to its original price + await env.gasPriceOracle.setGasPrice(gasPrice) + }) + + it('should reject a transaction with too high of a fee', async () => { + if (isLiveNetwork()) { + console.log('Skpping too high of a fee test on live network') + return + } + + const gasPrice = await env.gasPriceOracle.gasPrice() + const largeGasPrice = gasPrice.mul(10) + const tx = { + ...defaultTransactionFactory(), + gasPrice: largeGasPrice, + } + await expect(env.l2Wallet.sendTransaction(tx)).to.be.rejectedWith( + `gas price too high: ${largeGasPrice.toString()} wei, use at most ` + + `tx.gasPrice = ${gasPrice.toString()} wei` + ) + }) }) describe('eth_call', () => { diff --git a/integration-tests/test/shared/env.ts b/integration-tests/test/shared/env.ts index 5c5a8b2134f9c..41caae00388c8 100644 --- a/integration-tests/test/shared/env.ts +++ b/integration-tests/test/shared/env.ts @@ -13,6 +13,7 @@ import { replicaProvider, l1Wallet, l2Wallet, + gasPriceOracleWallet, fundUser, getOvmEth, getL1Bridge, @@ -100,7 +101,7 @@ export class OptimismEnv { .attach(ctcAddress) const gasPriceOracle = getContractFactory('OVM_GasPriceOracle') - .connect(l2Wallet) + .connect(gasPriceOracleWallet) .attach(predeploys.OVM_GasPriceOracle) const sccAddress = await addressManager.getAddress('StateCommitmentChain') diff --git a/integration-tests/test/shared/utils.ts b/integration-tests/test/shared/utils.ts index 82f1f68e3068c..cbb9227b48e8a 100644 --- a/integration-tests/test/shared/utils.ts +++ b/integration-tests/test/shared/utils.ts @@ -47,6 +47,10 @@ const env = cleanEnv(process.env, { ADDRESS_MANAGER: str({ default: '0x5FbDB2315678afecb367f032d93F642f64180aa3', }), + GAS_PRICE_ORACLE_PRIVATE_KEY: str({ + default: + '0x8b3a350cf5c34c9194ca85829a2df0ec3153be0318b5e2d3348e872092edffba', + }), L2_CHAINID: num({ default: 420 }), IS_LIVE_NETWORK: bool({ default: false }), }) @@ -77,6 +81,12 @@ export const l1Wallet = new Wallet(env.PRIVATE_KEY, l1Provider) // if it's using non-0 gas price export const l2Wallet = l1Wallet.connect(l2Provider) +// The owner of the GasPriceOracle on L2 +export const gasPriceOracleWallet = new Wallet( + env.GAS_PRICE_ORACLE_PRIVATE_KEY, + l2Provider +) + // Predeploys export const PROXY_SEQUENCER_ENTRYPOINT_ADDRESS = '0x4200000000000000000000000000000000000004' @@ -182,14 +192,17 @@ export const waitForL2Geth = async ( // eslint-disable-next-line @typescript-eslint/no-shadow export const gasPriceForL2 = async (env: OptimismEnv) => { - if (await isMainnet(env)) { + // The integration tests enforce fees on L2 + // which run against hardhat on L1. Update if + // geth --dev is adopted for L1 + const chainId = await env.l1Wallet.getChainId() + if ((await isMainnet(env)) || chainId === 31337) { return env.l2Wallet.getGasPrice() } if (isLiveNetwork()) { return Promise.resolve(BigNumber.from(10000)) } - return Promise.resolve(BigNumber.from(0)) } diff --git a/ops/docker-compose.yml b/ops/docker-compose.yml index 828eef0b551bd..0cae361b498c3 100644 --- a/ops/docker-compose.yml +++ b/ops/docker-compose.yml @@ -26,12 +26,13 @@ services: DEPLOYER_PRIVATE_KEY: "0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80" SEQUENCER_PRIVATE_KEY: "0x59c6995e998f97a5a0044966f0945389dc9e86dae88c7a8412f4603b6b78690d" PROPOSER_PRIVATE_KEY: "0x5de4111afa1a4b94908f83103eb1f1706367c2e68ca870fc3fb9a804cdab365a" - GAS_PRICE_ORACLE_OWNER: "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266" + # Default hardhat account 5 + GAS_PRICE_ORACLE_OWNER: "0x9965507d1a55bcc2695c58ba16fb37d819b0a4dc" # setting the whitelist owner to address(0) disables the whitelist WHITELIST_OWNER: "0x0000000000000000000000000000000000000000" L1_FEE_WALLET_ADDRESS: "0x391716d440c151c42cdf1c95c1d83a5427bca52c" L2_CHAIN_ID: 420 - L2_BLOCK_GAS_LIMIT: 11000000 + L2_BLOCK_GAS_LIMIT: 15000000 BLOCK_SIGNER_ADDRESS: "0x00000398232E2064F896018496b4b44b3D62751F" GAS_PRICE_ORACLE_OVERHEAD: "2750" GAS_PRICE_ORACLE_SCALAR: "1500000" @@ -212,4 +213,5 @@ services: entrypoint: ./gas-oracle.sh environment: GAS_PRICE_ORACLE_ETHEREUM_HTTP_URL: http://l2geth:8545 - GAS_PRICE_ORACLE_PRIVATE_KEY: "0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80" + # Default hardhat account 5 + GAS_PRICE_ORACLE_PRIVATE_KEY: "0x8b3a350cf5c34c9194ca85829a2df0ec3153be0318b5e2d3348e872092edffba" diff --git a/ops/envs/geth.env b/ops/envs/geth.env index 710be0a39af32..d3863718f1cf7 100644 --- a/ops/envs/geth.env +++ b/ops/envs/geth.env @@ -6,7 +6,7 @@ ETH1_CONFIRMATION_DEPTH=0 ROLLUP_CLIENT_HTTP= ROLLUP_POLL_INTERVAL_FLAG=500ms ROLLUP_ENABLE_L2_GAS_POLLING=true -# ROLLUP_ENFORCE_FEES= +ROLLUP_ENFORCE_FEES=true RPC_ENABLE=true RPC_ADDR=0.0.0.0 @@ -36,3 +36,6 @@ BLOCK_SIGNER_KEY=6587ae678cf4fc9a33000cdbf9f35226b71dcc6a4684a31203241f9bcfd55d2 BLOCK_SIGNER_ADDRESS=0x00000398232E2064F896018496b4b44b3D62751F L2_BLOCK_GAS_LIMIT=15000000 + +ROLLUP_FEE_THRESHOLD_DOWN=0.9 +ROLLUP_FEE_THRESHOLD_UP=1.1