forked from ethereum-optimism/optimism
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
45 changed files
with
1,800 additions
and
140 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
--- | ||
'@eth-optimism/integration-tests': patch | ||
--- | ||
|
||
Add in berlin hardfork tests |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
--- | ||
'@eth-optimism/l2geth': patch | ||
--- | ||
|
||
Implement berlin hardfork |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
--- | ||
'@eth-optimism/contracts': patch | ||
--- | ||
|
||
Add berlin hardfork config to genesis creation |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
// SPDX-License-Identifier: MIT | ||
pragma solidity ^0.8.9; | ||
|
||
contract Precompiles { | ||
function expmod(uint256 base, uint256 e, uint256 m) public returns (uint256 o) { | ||
assembly { | ||
// define pointer | ||
let p := mload(0x40) | ||
// store data assembly-favouring ways | ||
mstore(p, 0x20) // Length of Base | ||
mstore(add(p, 0x20), 0x20) // Length of Exponent | ||
mstore(add(p, 0x40), 0x20) // Length of Modulus | ||
mstore(add(p, 0x60), base) // Base | ||
mstore(add(p, 0x80), e) // Exponent | ||
mstore(add(p, 0xa0), m) // Modulus | ||
if iszero(staticcall(sub(gas(), 2000), 0x05, p, 0xc0, p, 0x20)) { | ||
revert(0, 0) | ||
} | ||
// data | ||
o := mload(p) | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
// SPDX-License-Identifier: MIT | ||
pragma solidity ^0.8.9; | ||
|
||
contract SelfDestruction { | ||
bytes32 public data = 0x0000000000000000000000000000000000000000000000000000000061626364; | ||
|
||
function setData(bytes32 _data) public { | ||
data = _data; | ||
} | ||
|
||
function destruct() public { | ||
address payable self = payable(address(this)); | ||
selfdestruct(self); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,58 @@ | ||
import { task } from 'hardhat/config' | ||
import { providers } from 'ethers' | ||
|
||
import { die, logStderr } from '../test/shared/utils' | ||
|
||
task( | ||
'check-block-hashes', | ||
'Compares the block hashes of two different replicas.' | ||
) | ||
.addPositionalParam('replicaA', 'The first replica') | ||
.addPositionalParam('replicaB', 'The second replica') | ||
.setAction(async ({ replicaA, replicaB }) => { | ||
const providerA = new providers.JsonRpcProvider(replicaA) | ||
const providerB = new providers.JsonRpcProvider(replicaB) | ||
|
||
let netA | ||
let netB | ||
try { | ||
netA = await providerA.getNetwork() | ||
} catch (e) { | ||
console.error(`Error getting network from ${replicaA}:`) | ||
die(e) | ||
} | ||
try { | ||
netB = await providerA.getNetwork() | ||
} catch (e) { | ||
console.error(`Error getting network from ${replicaB}:`) | ||
die(e) | ||
} | ||
|
||
if (netA.chainId !== netB.chainId) { | ||
die('Chain IDs do not match') | ||
return | ||
} | ||
|
||
logStderr('Getting block height.') | ||
const heightA = await providerA.getBlockNumber() | ||
const heightB = await providerB.getBlockNumber() | ||
const endHeight = Math.min(heightA, heightB) | ||
logStderr(`Chose block height: ${endHeight}`) | ||
|
||
for (let n = endHeight; n >= 1; n--) { | ||
const blocks = await Promise.all([ | ||
providerA.getBlock(n), | ||
providerB.getBlock(n), | ||
]) | ||
|
||
const hashA = blocks[0].hash | ||
const hashB = blocks[1].hash | ||
if (hashA !== hashB) { | ||
console.log(`HASH MISMATCH! block=${n} a=${hashA} b=${hashB}`) | ||
continue | ||
} | ||
|
||
console.log(`HASHES OK! block=${n} hash=${hashA}`) | ||
return | ||
} | ||
}) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,109 @@ | ||
import { Contract } from 'ethers' | ||
import { ethers } from 'hardhat' | ||
|
||
import { OptimismEnv } from '../shared/env' | ||
import { expect } from '../shared/setup' | ||
import { traceToGasByOpcode } from '../hardfork.spec' | ||
import { envConfig } from '../shared/utils' | ||
|
||
describe('Nightly', () => { | ||
before(async function () { | ||
if (!envConfig.RUN_NIGHTLY_TESTS) { | ||
this.skip() | ||
} | ||
}) | ||
|
||
describe('Berlin Hardfork', () => { | ||
let env: OptimismEnv | ||
let SimpleStorage: Contract | ||
let Precompiles: Contract | ||
|
||
before(async () => { | ||
env = await OptimismEnv.new() | ||
SimpleStorage = await ethers.getContractAt( | ||
'SimpleStorage', | ||
'0xE08fFE40748367ddc29B5A154331C73B7FCC13bD', | ||
env.l2Wallet | ||
) | ||
|
||
Precompiles = await ethers.getContractAt( | ||
'Precompiles', | ||
'0x32E8Fbfd0C0bd1117112b249e997C27b0EC7cba2', | ||
env.l2Wallet | ||
) | ||
}) | ||
|
||
describe('EIP-2929', () => { | ||
it('should update the gas schedule', async () => { | ||
const tx = await SimpleStorage.setValueNotXDomain( | ||
`0x${'77'.repeat(32)}` | ||
) | ||
await tx.wait() | ||
|
||
const berlinTrace = await env.l2Provider.send( | ||
'debug_traceTransaction', | ||
[tx.hash] | ||
) | ||
const preBerlinTrace = await env.l2Provider.send( | ||
'debug_traceTransaction', | ||
['0x2bb346f53544c5711502fbcbd1d78dc4fb61ca5f9390b9d6d67f1a3a77de7c39'] | ||
) | ||
|
||
const berlinSstoreCosts = traceToGasByOpcode( | ||
berlinTrace.structLogs, | ||
'SSTORE' | ||
) | ||
const preBerlinSstoreCosts = traceToGasByOpcode( | ||
preBerlinTrace.structLogs, | ||
'SSTORE' | ||
) | ||
expect(preBerlinSstoreCosts).to.eq(80000) | ||
expect(berlinSstoreCosts).to.eq(5300) | ||
}) | ||
}) | ||
|
||
describe('EIP-2565', () => { | ||
it('should become cheaper', async () => { | ||
const tx = await Precompiles.expmod(64, 1, 64, { gasLimit: 5_000_000 }) | ||
await tx.wait() | ||
|
||
const berlinTrace = await env.l2Provider.send( | ||
'debug_traceTransaction', | ||
[tx.hash] | ||
) | ||
const preBerlinTrace = await env.l2Provider.send( | ||
'debug_traceTransaction', | ||
['0x7ba7d273449b0062448fe5e7426bb169a032ce189d0e3781eb21079e85c2d7d5'] | ||
) | ||
expect(berlinTrace.gas).to.be.lt(preBerlinTrace.gas) | ||
}) | ||
}) | ||
|
||
describe('Berlin Additional (L1 London)', () => { | ||
describe('EIP-3529', () => { | ||
it('should remove the refund for selfdestruct', async () => { | ||
const Factory__SelfDestruction = await ethers.getContractFactory( | ||
'SelfDestruction', | ||
env.l2Wallet | ||
) | ||
|
||
const SelfDestruction = await Factory__SelfDestruction.deploy() | ||
const tx = await SelfDestruction.destruct({ gasLimit: 5_000_000 }) | ||
await tx.wait() | ||
|
||
const berlinTrace = await env.l2Provider.send( | ||
'debug_traceTransaction', | ||
[tx.hash] | ||
) | ||
const preBerlinTrace = await env.l2Provider.send( | ||
'debug_traceTransaction', | ||
[ | ||
'0x948667349f00e996d9267e5c30d72fe7202a0ecdb88bab191e9a022bba6e4cb3', | ||
] | ||
) | ||
expect(berlinTrace.gas).to.be.gt(preBerlinTrace.gas) | ||
}) | ||
}) | ||
}) | ||
}) | ||
}) |
Oops, something went wrong.