Commit a8763df7 authored by Mark Tyneway's avatar Mark Tyneway Committed by GitHub

Merge pull request #2024 from indeavr/develop

Split OVMMulticall.sol into Multicall.sol & OVMContext.sol in integration tests
parents b64c2721 a7fbafa8
---
'@eth-optimism/integration-tests': patch
---
Split OVMMulticall.sol into Multicall.sol & OVMContext.sol
// SPDX-License-Identifier: MIT
pragma solidity >=0.5.0;
pragma experimental ABIEncoderV2;
// https://github.com/makerdao/multicall/blob/master/src/Multicall.sol
/// @title Multicall - Aggregate results from multiple read-only function calls
/// @author Michael Elliot <mike@makerdao.com>
/// @author Joshua Levine <joshua@makerdao.com>
/// @author Nick Johnson <arachnid@notdot.net>
contract Multicall {
struct Call {
address target;
bytes callData;
}
function aggregate(Call[] memory calls) public returns (uint256 blockNumber, bytes[] memory returnData) {
blockNumber = block.number;
returnData = new bytes[](calls.length);
for (uint256 i = 0; i < calls.length; i++) {
(bool success, bytes memory ret) = calls[i].target.call(calls[i].callData);
require(success);
returnData[i] = ret;
}
}
// Helper functions
function getEthBalance(address addr) public view returns (uint256 balance) {
balance = addr.balance;
}
function getBlockHash(uint256 blockNumber) public view returns (bytes32 blockHash) {
blockHash = blockhash(blockNumber);
}
function getLastBlockHash() public view returns (bytes32 blockHash) {
blockHash = blockhash(block.number - 1);
}
function getCurrentBlockTimestamp() public view returns (uint256 timestamp) {
timestamp = block.timestamp;
}
function getCurrentBlockDifficulty() public view returns (uint256 difficulty) {
difficulty = block.difficulty;
}
function getCurrentBlockGasLimit() public view returns (uint256 gaslimit) {
gaslimit = block.gaslimit;
}
function getCurrentBlockCoinbase() public view returns (address coinbase) {
coinbase = block.coinbase;
}
}
......@@ -22,26 +22,13 @@ pragma solidity ^0.8.9;
// Can't do this until the package is published.
//import { iOVM_L1BlockNumber } from "@eth-optimism/contracts/iOVM_L1BlockNumber";
import { iOVM_L1BlockNumber } from "./OVMContextStorage.sol";
/// @title OVMMulticall - Aggregate results from multiple read-only function calls
contract OVMMulticall {
struct Call {
address target;
bytes callData;
}
function aggregate(Call[] memory calls) public returns (uint256 blockNumber, bytes[] memory returnData) {
blockNumber = block.number;
returnData = new bytes[](calls.length);
for (uint256 i = 0; i < calls.length; i++) {
(bool success, bytes memory ret) = calls[i].target.call(calls[i].callData);
require(success);
returnData[i] = ret;
}
}
interface iOVM_L1BlockNumber {
function getL1BlockNumber() external view returns (uint256);
}
// Helper functions
/// @title OVMContext - Helper Functions
contract OVMContext {
function getCurrentBlockTimestamp() public view returns (uint256 timestamp) {
timestamp = block.timestamp;
}
......
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.9;
// Can't do this until the package is published.
//import { iOVM_L1BlockNumber } from "@eth-optimism/contracts/iOVM_L1BlockNumber";
interface iOVM_L1BlockNumber {
function getL1BlockNumber() external view returns (uint256);
}
import {OVMContext} from "./OVMContext.sol";
contract OVMContextStorage {
mapping (uint256 => uint256) public l1BlockNumbers;
mapping (uint256 => uint256) public blockNumbers;
mapping (uint256 => uint256) public timestamps;
mapping (uint256 => uint256) public difficulty;
mapping (uint256 => address) public coinbases;
contract OVMContextStorage is OVMContext {
mapping(uint256 => uint256) public l1BlockNumbers;
mapping(uint256 => uint256) public blockNumbers;
mapping(uint256 => uint256) public timestamps;
mapping(uint256 => uint256) public difficulty;
mapping(uint256 => address) public coinbases;
uint256 public index = 0;
fallback() external {
l1BlockNumbers[index] = iOVM_L1BlockNumber(
0x4200000000000000000000000000000000000013
).getL1BlockNumber();
blockNumbers[index] = block.number;
timestamps[index] = block.timestamp;
l1BlockNumbers[index] = getCurrentL1BlockNumber();
blockNumbers[index] = getCurrentBlockNumber();
timestamps[index] = getCurrentBlockTimestamp();
difficulty[index] = block.difficulty;
coinbases[index] = block.coinbase;
index++;
......
......@@ -23,22 +23,22 @@ describe('OVM Context: Layer 2 EVM Context', () => {
env = await OptimismEnv.new()
})
let OVMMulticall: Contract
let Multicall: Contract
let OVMContextStorage: Contract
beforeEach(async () => {
const OVMContextStorageFactory = await ethers.getContractFactory(
'OVMContextStorage',
env.l2Wallet
)
const OVMMulticallFactory = await ethers.getContractFactory(
'OVMMulticall',
const MulticallFactory = await ethers.getContractFactory(
'Multicall',
env.l2Wallet
)
OVMContextStorage = await OVMContextStorageFactory.deploy()
await OVMContextStorage.deployTransaction.wait()
OVMMulticall = await OVMMulticallFactory.deploy()
await OVMMulticall.deployTransaction.wait()
Multicall = await MulticallFactory.deploy()
await Multicall.deployTransaction.wait()
})
let numTxs = 5
......@@ -101,21 +101,23 @@ describe('OVM Context: Layer 2 EVM Context', () => {
await dummyTx.wait()
const block = await L2Provider.getBlockWithTransactions('latest')
const [, returnData] = await OVMMulticall.callStatic.aggregate(
const [, returnData] = await Multicall.callStatic.aggregate(
[
[
OVMMulticall.address,
OVMMulticall.interface.encodeFunctionData(
OVMContextStorage.address,
OVMContextStorage.interface.encodeFunctionData(
'getCurrentBlockTimestamp'
),
],
[
OVMMulticall.address,
OVMMulticall.interface.encodeFunctionData('getCurrentBlockNumber'),
OVMContextStorage.address,
OVMContextStorage.interface.encodeFunctionData(
'getCurrentBlockNumber'
),
],
[
OVMMulticall.address,
OVMMulticall.interface.encodeFunctionData(
OVMContextStorage.address,
OVMContextStorage.interface.encodeFunctionData(
'getCurrentL1BlockNumber'
),
],
......@@ -141,19 +143,23 @@ describe('OVM Context: Layer 2 EVM Context', () => {
*/
it('should return same timestamp and blocknumbers between `eth_call` and `rollup_getInfo`', async () => {
// As atomically as possible, call `rollup_getInfo` and OVMMulticall for the
// As atomically as possible, call `rollup_getInfo` and Multicall for the
// blocknumber and timestamp. If this is not atomic, then the sequencer can
// happend to update the timestamp between the `eth_call` and the `rollup_getInfo`
const [info, [, returnData]] = await Promise.all([
L2Provider.send('rollup_getInfo', []),
OVMMulticall.callStatic.aggregate([
Multicall.callStatic.aggregate([
[
OVMMulticall.address,
OVMMulticall.interface.encodeFunctionData('getCurrentBlockTimestamp'),
OVMContextStorage.address,
OVMContextStorage.interface.encodeFunctionData(
'getCurrentBlockTimestamp'
),
],
[
OVMMulticall.address,
OVMMulticall.interface.encodeFunctionData('getCurrentL1BlockNumber'),
OVMContextStorage.address,
OVMContextStorage.interface.encodeFunctionData(
'getCurrentL1BlockNumber'
),
],
]),
])
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment