Commit 35757456 authored by Maurelian's avatar Maurelian Committed by GitHub

bedrock: use block number for key in output oracle (#2707)

* bedrock: use block number for key in output oracle

* contracts: Apply seaport style to natspec comments

Inspo: https://github.com/ProjectOpenSea/seaport/blob/main/contracts/Seaport.sol

* bedrock: Improve oracle error messages

* bedrock: update node and proposer with new oracle interface

* bedrock: add tests for oracle reorg protection.

* Fix op-proposer & withdrawals logic

* Golang PR Fixes

* specs: use block number for key in output oracle

* bedrock: Fix CamelCase on oracle events

* bedrock: Update arg name in usage of getL2Output

* bedrock: Oracle add computeL2Timestamp and check on append
Co-authored-by: default avatarJoshua Gutow <jgutow@optimism.io>
parent b81eae57
---
'@eth-optimism/contracts-bedrock': minor
---
Replaces L2 timestamps with block numbers as the key in mapping(uint => OutputProposal).
...@@ -36,8 +36,8 @@ type L2OutputOracleOutputProposal struct { ...@@ -36,8 +36,8 @@ type L2OutputOracleOutputProposal struct {
// L2OutputOracleMetaData contains all meta data concerning the L2OutputOracle contract. // L2OutputOracleMetaData contains all meta data concerning the L2OutputOracle contract.
var L2OutputOracleMetaData = &bind.MetaData{ var L2OutputOracleMetaData = &bind.MetaData{
ABI: "[{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_submissionInterval\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_l2BlockTime\",\"type\":\"uint256\"},{\"internalType\":\"bytes32\",\"name\":\"_genesisL2Output\",\"type\":\"bytes32\"},{\"internalType\":\"uint256\",\"name\":\"_historicalTotalBlocks\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_startingBlockTimestamp\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"_sequencer\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"previousOwner\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"_l2Output\",\"type\":\"bytes32\"},{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"_l1Timestamp\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"_l2timestamp\",\"type\":\"uint256\"}],\"name\":\"l2OutputAppended\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"_l2Output\",\"type\":\"bytes32\"},{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"_l1Timestamp\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"_l2timestamp\",\"type\":\"uint256\"}],\"name\":\"l2OutputDeleted\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"HISTORICAL_TOTAL_BLOCKS\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"L2_BLOCK_TIME\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"STARTING_BLOCK_TIMESTAMP\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"SUBMISSION_INTERVAL\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"_l2Output\",\"type\":\"bytes32\"},{\"internalType\":\"uint256\",\"name\":\"_l2timestamp\",\"type\":\"uint256\"},{\"internalType\":\"bytes32\",\"name\":\"_l1Blockhash\",\"type\":\"bytes32\"},{\"internalType\":\"uint256\",\"name\":\"_l1Blocknumber\",\"type\":\"uint256\"}],\"name\":\"appendL2Output\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_l2timestamp\",\"type\":\"uint256\"}],\"name\":\"computeL2BlockNumber\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"outputRoot\",\"type\":\"bytes32\"},{\"internalType\":\"uint256\",\"name\":\"timestamp\",\"type\":\"uint256\"}],\"internalType\":\"structL2OutputOracle.OutputProposal\",\"name\":\"_proposal\",\"type\":\"tuple\"}],\"name\":\"deleteL2Output\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_l2Timestamp\",\"type\":\"uint256\"}],\"name\":\"getL2Output\",\"outputs\":[{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"outputRoot\",\"type\":\"bytes32\"},{\"internalType\":\"uint256\",\"name\":\"timestamp\",\"type\":\"uint256\"}],\"internalType\":\"structL2OutputOracle.OutputProposal\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"latestBlockTimestamp\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"nextTimestamp\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"renounceOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]", ABI: "[{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_submissionInterval\",\"type\":\"uint256\"},{\"internalType\":\"bytes32\",\"name\":\"_genesisL2Output\",\"type\":\"bytes32\"},{\"internalType\":\"uint256\",\"name\":\"_historicalTotalBlocks\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_startingBlockNumber\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_startingTimestamp\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_l2BlockTime\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"_sequencer\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"_l2Output\",\"type\":\"bytes32\"},{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"_l1Timestamp\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"_l2BlockNumber\",\"type\":\"uint256\"}],\"name\":\"L2OutputAppended\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"_l2Output\",\"type\":\"bytes32\"},{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"_l1Timestamp\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"_l2BlockNumber\",\"type\":\"uint256\"}],\"name\":\"L2OutputDeleted\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"previousOwner\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"HISTORICAL_TOTAL_BLOCKS\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"L2_BLOCK_TIME\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"STARTING_BLOCK_NUMBER\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"STARTING_TIMESTAMP\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"SUBMISSION_INTERVAL\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"_l2Output\",\"type\":\"bytes32\"},{\"internalType\":\"uint256\",\"name\":\"_l2BlockNumber\",\"type\":\"uint256\"},{\"internalType\":\"bytes32\",\"name\":\"_l1Blockhash\",\"type\":\"bytes32\"},{\"internalType\":\"uint256\",\"name\":\"_l1BlockNumber\",\"type\":\"uint256\"}],\"name\":\"appendL2Output\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_l2BlockNumber\",\"type\":\"uint256\"}],\"name\":\"computeL2Timestamp\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"outputRoot\",\"type\":\"bytes32\"},{\"internalType\":\"uint256\",\"name\":\"timestamp\",\"type\":\"uint256\"}],\"internalType\":\"structL2OutputOracle.OutputProposal\",\"name\":\"_proposal\",\"type\":\"tuple\"}],\"name\":\"deleteL2Output\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_l2BlockNumber\",\"type\":\"uint256\"}],\"name\":\"getL2Output\",\"outputs\":[{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"outputRoot\",\"type\":\"bytes32\"},{\"internalType\":\"uint256\",\"name\":\"timestamp\",\"type\":\"uint256\"}],\"internalType\":\"structL2OutputOracle.OutputProposal\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"latestBlockNumber\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"nextBlockNumber\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"renounceOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]",
Bin: "0x61010060405234801561001157600080fd5b50604051610f9e380380610f9e83398101604081905261003091610164565b61003933610114565b61004385876101c8565b156100ba5760405162461bcd60e51b815260206004820152603760248201527f5375626d697373696f6e20496e74657276616c206d7573742062652061206d7560448201527f6c7469706c65206f66204c3220426c6f636b2054696d65000000000000000000606482015260840160405180910390fd5b608086905260a0859052604080518082018252858152426020808301918252600086815260029091529290922090518155905160019182015560c084905282905560e082905261010981610114565b5050505050506101ea565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b60008060008060008060c0878903121561017d57600080fd5b86516020880151604089015160608a015160808b015160a08c0151949a50929850909650945092506001600160a01b03811681146101ba57600080fd5b809150509295509295509295565b6000826101e557634e487b7160e01b600052601260045260246000fd5b500690565b60805160a05160c05160e051610d5261024c600039600081816101af0152818161031b01526103f10152600081816102d5015261042201526000818160e801526103d00152600081816101e30152818161062201526109570152610d526000f3fe6080604052600436106100d15760003560e01c806341840fa61161007f5780638da5cb5b116100595780638da5cb5b1461021a578063a25ae5571461024f578063a4771aad146102c3578063f2fde38b146102f757600080fd5b806341840fa61461019d578063529933df146101d1578063715018a61461020557600080fd5b80630c1952d3116100b05780630c1952d31461015f5780632518810414610175578063357e951f1461018857600080fd5b80622134cc146100d657806302e513451461011d578063093b3d901461013d575b600080fd5b3480156100e257600080fd5b5061010a7f000000000000000000000000000000000000000000000000000000000000000081565b6040519081526020015b60405180910390f35b34801561012957600080fd5b5061010a610138366004610bba565b610317565b34801561014957600080fd5b5061015d610158366004610bd3565b610449565b005b34801561016b57600080fd5b5061010a60015481565b61015d610183366004610c49565b61064e565b34801561019457600080fd5b5061010a610953565b3480156101a957600080fd5b5061010a7f000000000000000000000000000000000000000000000000000000000000000081565b3480156101dd57600080fd5b5061010a7f000000000000000000000000000000000000000000000000000000000000000081565b34801561021157600080fd5b5061015d610988565b34801561022657600080fd5b5060005460405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610114565b34801561025b57600080fd5b506102a861026a366004610bba565b604080518082019091526000808252602082015250600090815260026020908152604091829020825180840190935280548352600101549082015290565b60408051825181526020928301519281019290925201610114565b3480156102cf57600080fd5b5061010a7f000000000000000000000000000000000000000000000000000000000000000081565b34801561030357600080fd5b5061015d610312366004610c7b565b610a15565b60007f00000000000000000000000000000000000000000000000000000000000000008210156103ce576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602960248201527f54696d657374616d70207072696f7220746f207374617274696e67426c6f636b60448201527f54696d657374616d70000000000000000000000000000000000000000000000060648201526084015b60405180910390fd5b7f00000000000000000000000000000000000000000000000000000000000000007f000000000000000000000000000000000000000000000000000000000000000083038161041f5761041f610cb8565b047f0000000000000000000000000000000000000000000000000000000000000000019050919050565b60005473ffffffffffffffffffffffffffffffffffffffff1633146104ca576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064016103c5565b6001805460009081526002602090815260409182902082518084019093528054808452930154908201528251909114610585576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602760248201527f43616e206f6e6c792064656c65746520746865206d6f737420726563656e742060448201527f6f75747075742e0000000000000000000000000000000000000000000000000060648201526084016103c5565b80602001518260200151146105d0576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600060248201526044016103c5565b600154602082015182516040517f6897e92e2fea3b89bf0d45ed867487716da71bfa624c6878569d227d736c700990600090a460018054600090815260026020526040812081815582015554610647907f000000000000000000000000000000000000000000000000000000000000000090610d16565b6001555050565b60005473ffffffffffffffffffffffffffffffffffffffff1633146106cf576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064016103c5565b42831061075e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602160248201527f43616e6e6f7420617070656e64204c32206f757470757420696e20667574757260448201527f650000000000000000000000000000000000000000000000000000000000000060648201526084016103c5565b610766610953565b83146107f4576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f54696d657374616d70206e6f7420657175616c20746f206e657874206578706560448201527f637465642074696d657374616d7000000000000000000000000000000000000060648201526084016103c5565b8361085b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f43616e6e6f74207375626d697420656d707479204c32206f757470757400000060448201526064016103c5565b81156108f157818140146108f1576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603960248201527f426c6f636b6861736820646f6573206e6f74206d61746368207468652068617360448201527f6820617420746865206578706563746564206865696768742e0000000000000060648201526084016103c5565b60408051808201825285815242602080830182815260008881526002909252848220935184555160019384015591869055915185929187917f54fbf9b58db0b6543a3a0cb9fbd4e98a7c7b88878978fa125b84a2c7f51d34ba9190a450505050565b60007f00000000000000000000000000000000000000000000000000000000000000006001546109839190610d2d565b905090565b60005473ffffffffffffffffffffffffffffffffffffffff163314610a09576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064016103c5565b610a136000610b45565b565b60005473ffffffffffffffffffffffffffffffffffffffff163314610a96576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064016103c5565b73ffffffffffffffffffffffffffffffffffffffff8116610b39576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201527f646472657373000000000000000000000000000000000000000000000000000060648201526084016103c5565b610b4281610b45565b50565b6000805473ffffffffffffffffffffffffffffffffffffffff8381167fffffffffffffffffffffffff0000000000000000000000000000000000000000831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b600060208284031215610bcc57600080fd5b5035919050565b600060408284031215610be557600080fd5b6040516040810181811067ffffffffffffffff82111715610c2f577f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b604052823581526020928301359281019290925250919050565b60008060008060808587031215610c5f57600080fd5b5050823594602084013594506040840135936060013592509050565b600060208284031215610c8d57600080fd5b813573ffffffffffffffffffffffffffffffffffffffff81168114610cb157600080fd5b9392505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b600082821015610d2857610d28610ce7565b500390565b60008219821115610d4057610d40610ce7565b50019056fea164736f6c634300080a000a", Bin: "0x61012060405234801561001157600080fd5b5060405161112c38038061112c8339810160408190526100309161016f565b6100393361011f565b4282106100be5760405162461bcd60e51b815260206004820152604360248201527f4f7574707574204f7261636c653a20496e697469616c204c3220626c6f636b2060448201527f74696d65206d757374206265206c657373207468616e2063757272656e742074606482015262696d6560e81b608482015260a40160405180910390fd5b608087905260a085905260c084905260e083905261010082905260408051808201825287815242602080830191825260008881526002909152929092209051815590516001918201558490556101138161011f565b505050505050506101de565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b600080600080600080600060e0888a03121561018a57600080fd5b8751602089015160408a015160608b015160808c015160a08d015160c08e0151959c50939a509198509650945092506001600160a01b03811681146101ce57600080fd5b8091505092959891949750929550565b60805160a05160c05160e05161010051610ee161024b600039600060f301526000818161015c0152610b370152600081816101b901528181610a080152610b02015260006102df0152600081816101ed015281816105cc01528181610ade0152610b650152610ee16000f3fe6080604052600436106100dc5760003560e01c8063715018a61161007f578063a4771aad11610059578063a4771aad146102cd578063d1de856c14610301578063dcec334814610321578063f2fde38b1461033657600080fd5b8063715018a61461020f5780638da5cb5b14610224578063a25ae5571461025957600080fd5b806325188104116100bb578063251881041461017e5780634599c788146101915780634ab65d73146101a7578063529933df146101db57600080fd5b80622134cc146100e1578063093b3d901461012857806320e9fcd41461014a575b600080fd5b3480156100ed57600080fd5b506101157f000000000000000000000000000000000000000000000000000000000000000081565b6040519081526020015b60405180910390f35b34801561013457600080fd5b50610148610143366004610d3b565b610356565b005b34801561015657600080fd5b506101157f000000000000000000000000000000000000000000000000000000000000000081565b61014861018c366004610db1565b6105f8565b34801561019d57600080fd5b5061011560015481565b3480156101b357600080fd5b506101157f000000000000000000000000000000000000000000000000000000000000000081565b3480156101e757600080fd5b506101157f000000000000000000000000000000000000000000000000000000000000000081565b34801561021b57600080fd5b50610148610977565b34801561023057600080fd5b5060005460405173ffffffffffffffffffffffffffffffffffffffff909116815260200161011f565b34801561026557600080fd5b506102b2610274366004610de3565b604080518082019091526000808252602082015250600090815260026020908152604091829020825180840190935280548352600101549082015290565b6040805182518152602092830151928101929092520161011f565b3480156102d957600080fd5b506101157f000000000000000000000000000000000000000000000000000000000000000081565b34801561030d57600080fd5b5061011561031c366004610de3565b610a04565b34801561032d57600080fd5b50610115610b61565b34801561034257600080fd5b50610148610351366004610dfc565b610b96565b60005473ffffffffffffffffffffffffffffffffffffffff1633146103dc576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064015b60405180910390fd5b60018054600090815260026020908152604091829020825180840190935280548084529301549082015282519091146104bd576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152605260248201527f4f75747075744f7261636c653a20546865206f757470757420726f6f7420746f60448201527f2064656c65746520646f6573206e6f74206d6174636820746865206c6174657360648201527f74206f75747075742070726f706f73616c2e0000000000000000000000000000608482015260a4016103d3565b806020015182602001511461057a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152605060248201527f4f75747075744f7261636c653a205468652074696d657374616d7020746f206460448201527f656c65746520646f6573206e6f74206d6174636820746865206c61746573742060648201527f6f75747075742070726f706f73616c2e00000000000000000000000000000000608482015260a4016103d3565b600154602082015182516040517f7320566fd5256cf8923648a5d9f560f1e92f1435a1bb32ddd1fe107f224ad35990600090a4600180546000908152600260205260408120818155820155546105f1907f000000000000000000000000000000000000000000000000000000000000000090610e68565b6001555050565b60005473ffffffffffffffffffffffffffffffffffffffff163314610679576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064016103d3565b610681610b61565b8314610735576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604760248201527f4f75747075744f7261636c653a20426c6f636b206e756d626572206d7573742060448201527f626520657175616c20746f206e65787420657870656374656420626c6f636b2060648201527f6e756d6265722e00000000000000000000000000000000000000000000000000608482015260a4016103d3565b4261073f84610a04565b106107cc576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603060248201527f4f75747075744f7261636c653a2043616e6e6f7420617070656e64204c32206f60448201527f757470757420696e206675747572652e0000000000000000000000000000000060648201526084016103d3565b83610859576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602c60248201527f4f75747075744f7261636c653a2043616e6e6f74207375626d697420656d707460448201527f79204c32206f75747075742e000000000000000000000000000000000000000060648201526084016103d3565b81156109155781814014610915576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604760248201527f4f75747075744f7261636c653a20426c6f636b6861736820646f6573206e6f7460448201527f206d61746368207468652068617368206174207468652065787065637465642060648201527f6865696768742e00000000000000000000000000000000000000000000000000608482015260a4016103d3565b60408051808201825285815242602080830182815260008881526002909252848220935184555160019384015591869055915185929187917fd6703ded1701060d9ae1793db76d594790a4e775781225f79b5aa8a77987c0809190a450505050565b60005473ffffffffffffffffffffffffffffffffffffffff1633146109f8576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064016103d3565b610a026000610cc6565b565b60007f0000000000000000000000000000000000000000000000000000000000000000821015610adc576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152605660248201527f4f75747075744f7261636c653a20426c6f636b206e756d626572206d7573742060448201527f62652067726561746572207468616e206f7220657175616c20746f207468652060648201527f7374617274696e6720626c6f636b206e756d6265722e00000000000000000000608482015260a4016103d3565b7f0000000000000000000000000000000000000000000000000000000000000000610b277f000000000000000000000000000000000000000000000000000000000000000084610e68565b610b319190610e7f565b610b5b907f0000000000000000000000000000000000000000000000000000000000000000610ebc565b92915050565b60007f0000000000000000000000000000000000000000000000000000000000000000600154610b919190610ebc565b905090565b60005473ffffffffffffffffffffffffffffffffffffffff163314610c17576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064016103d3565b73ffffffffffffffffffffffffffffffffffffffff8116610cba576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201527f646472657373000000000000000000000000000000000000000000000000000060648201526084016103d3565b610cc381610cc6565b50565b6000805473ffffffffffffffffffffffffffffffffffffffff8381167fffffffffffffffffffffffff0000000000000000000000000000000000000000831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b600060408284031215610d4d57600080fd5b6040516040810181811067ffffffffffffffff82111715610d97577f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b604052823581526020928301359281019290925250919050565b60008060008060808587031215610dc757600080fd5b5050823594602084013594506040840135936060013592509050565b600060208284031215610df557600080fd5b5035919050565b600060208284031215610e0e57600080fd5b813573ffffffffffffffffffffffffffffffffffffffff81168114610e3257600080fd5b9392505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b600082821015610e7a57610e7a610e39565b500390565b6000817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0483118215151615610eb757610eb7610e39565b500290565b60008219821115610ecf57610ecf610e39565b50019056fea164736f6c634300080a000a",
} }
// L2OutputOracleABI is the input ABI used to generate the binding from. // L2OutputOracleABI is the input ABI used to generate the binding from.
...@@ -49,7 +49,7 @@ var L2OutputOracleABI = L2OutputOracleMetaData.ABI ...@@ -49,7 +49,7 @@ var L2OutputOracleABI = L2OutputOracleMetaData.ABI
var L2OutputOracleBin = L2OutputOracleMetaData.Bin var L2OutputOracleBin = L2OutputOracleMetaData.Bin
// DeployL2OutputOracle deploys a new Ethereum contract, binding an instance of L2OutputOracle to it. // DeployL2OutputOracle deploys a new Ethereum contract, binding an instance of L2OutputOracle to it.
func DeployL2OutputOracle(auth *bind.TransactOpts, backend bind.ContractBackend, _submissionInterval *big.Int, _l2BlockTime *big.Int, _genesisL2Output [32]byte, _historicalTotalBlocks *big.Int, _startingBlockTimestamp *big.Int, _sequencer common.Address) (common.Address, *types.Transaction, *L2OutputOracle, error) { func DeployL2OutputOracle(auth *bind.TransactOpts, backend bind.ContractBackend, _submissionInterval *big.Int, _genesisL2Output [32]byte, _historicalTotalBlocks *big.Int, _startingBlockNumber *big.Int, _startingTimestamp *big.Int, _l2BlockTime *big.Int, _sequencer common.Address) (common.Address, *types.Transaction, *L2OutputOracle, error) {
parsed, err := L2OutputOracleMetaData.GetAbi() parsed, err := L2OutputOracleMetaData.GetAbi()
if err != nil { if err != nil {
return common.Address{}, nil, nil, err return common.Address{}, nil, nil, err
...@@ -58,7 +58,7 @@ func DeployL2OutputOracle(auth *bind.TransactOpts, backend bind.ContractBackend, ...@@ -58,7 +58,7 @@ func DeployL2OutputOracle(auth *bind.TransactOpts, backend bind.ContractBackend,
return common.Address{}, nil, nil, errors.New("GetABI returned nil") return common.Address{}, nil, nil, errors.New("GetABI returned nil")
} }
address, tx, contract, err := bind.DeployContract(auth, *parsed, common.FromHex(L2OutputOracleBin), backend, _submissionInterval, _l2BlockTime, _genesisL2Output, _historicalTotalBlocks, _startingBlockTimestamp, _sequencer) address, tx, contract, err := bind.DeployContract(auth, *parsed, common.FromHex(L2OutputOracleBin), backend, _submissionInterval, _genesisL2Output, _historicalTotalBlocks, _startingBlockNumber, _startingTimestamp, _l2BlockTime, _sequencer)
if err != nil { if err != nil {
return common.Address{}, nil, nil, err return common.Address{}, nil, nil, err
} }
...@@ -269,12 +269,12 @@ func (_L2OutputOracle *L2OutputOracleCallerSession) L2BLOCKTIME() (*big.Int, err ...@@ -269,12 +269,12 @@ func (_L2OutputOracle *L2OutputOracleCallerSession) L2BLOCKTIME() (*big.Int, err
return _L2OutputOracle.Contract.L2BLOCKTIME(&_L2OutputOracle.CallOpts) return _L2OutputOracle.Contract.L2BLOCKTIME(&_L2OutputOracle.CallOpts)
} }
// STARTINGBLOCKTIMESTAMP is a free data retrieval call binding the contract method 0x41840fa6. // STARTINGBLOCKNUMBER is a free data retrieval call binding the contract method 0x4ab65d73.
// //
// Solidity: function STARTING_BLOCK_TIMESTAMP() view returns(uint256) // Solidity: function STARTING_BLOCK_NUMBER() view returns(uint256)
func (_L2OutputOracle *L2OutputOracleCaller) STARTINGBLOCKTIMESTAMP(opts *bind.CallOpts) (*big.Int, error) { func (_L2OutputOracle *L2OutputOracleCaller) STARTINGBLOCKNUMBER(opts *bind.CallOpts) (*big.Int, error) {
var out []interface{} var out []interface{}
err := _L2OutputOracle.contract.Call(opts, &out, "STARTING_BLOCK_TIMESTAMP") err := _L2OutputOracle.contract.Call(opts, &out, "STARTING_BLOCK_NUMBER")
if err != nil { if err != nil {
return *new(*big.Int), err return *new(*big.Int), err
...@@ -286,18 +286,49 @@ func (_L2OutputOracle *L2OutputOracleCaller) STARTINGBLOCKTIMESTAMP(opts *bind.C ...@@ -286,18 +286,49 @@ func (_L2OutputOracle *L2OutputOracleCaller) STARTINGBLOCKTIMESTAMP(opts *bind.C
} }
// STARTINGBLOCKTIMESTAMP is a free data retrieval call binding the contract method 0x41840fa6. // STARTINGBLOCKNUMBER is a free data retrieval call binding the contract method 0x4ab65d73.
// //
// Solidity: function STARTING_BLOCK_TIMESTAMP() view returns(uint256) // Solidity: function STARTING_BLOCK_NUMBER() view returns(uint256)
func (_L2OutputOracle *L2OutputOracleSession) STARTINGBLOCKTIMESTAMP() (*big.Int, error) { func (_L2OutputOracle *L2OutputOracleSession) STARTINGBLOCKNUMBER() (*big.Int, error) {
return _L2OutputOracle.Contract.STARTINGBLOCKTIMESTAMP(&_L2OutputOracle.CallOpts) return _L2OutputOracle.Contract.STARTINGBLOCKNUMBER(&_L2OutputOracle.CallOpts)
} }
// STARTINGBLOCKTIMESTAMP is a free data retrieval call binding the contract method 0x41840fa6. // STARTINGBLOCKNUMBER is a free data retrieval call binding the contract method 0x4ab65d73.
// //
// Solidity: function STARTING_BLOCK_TIMESTAMP() view returns(uint256) // Solidity: function STARTING_BLOCK_NUMBER() view returns(uint256)
func (_L2OutputOracle *L2OutputOracleCallerSession) STARTINGBLOCKTIMESTAMP() (*big.Int, error) { func (_L2OutputOracle *L2OutputOracleCallerSession) STARTINGBLOCKNUMBER() (*big.Int, error) {
return _L2OutputOracle.Contract.STARTINGBLOCKTIMESTAMP(&_L2OutputOracle.CallOpts) return _L2OutputOracle.Contract.STARTINGBLOCKNUMBER(&_L2OutputOracle.CallOpts)
}
// STARTINGTIMESTAMP is a free data retrieval call binding the contract method 0x20e9fcd4.
//
// Solidity: function STARTING_TIMESTAMP() view returns(uint256)
func (_L2OutputOracle *L2OutputOracleCaller) STARTINGTIMESTAMP(opts *bind.CallOpts) (*big.Int, error) {
var out []interface{}
err := _L2OutputOracle.contract.Call(opts, &out, "STARTING_TIMESTAMP")
if err != nil {
return *new(*big.Int), err
}
out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int)
return out0, err
}
// STARTINGTIMESTAMP is a free data retrieval call binding the contract method 0x20e9fcd4.
//
// Solidity: function STARTING_TIMESTAMP() view returns(uint256)
func (_L2OutputOracle *L2OutputOracleSession) STARTINGTIMESTAMP() (*big.Int, error) {
return _L2OutputOracle.Contract.STARTINGTIMESTAMP(&_L2OutputOracle.CallOpts)
}
// STARTINGTIMESTAMP is a free data retrieval call binding the contract method 0x20e9fcd4.
//
// Solidity: function STARTING_TIMESTAMP() view returns(uint256)
func (_L2OutputOracle *L2OutputOracleCallerSession) STARTINGTIMESTAMP() (*big.Int, error) {
return _L2OutputOracle.Contract.STARTINGTIMESTAMP(&_L2OutputOracle.CallOpts)
} }
// SUBMISSIONINTERVAL is a free data retrieval call binding the contract method 0x529933df. // SUBMISSIONINTERVAL is a free data retrieval call binding the contract method 0x529933df.
...@@ -331,12 +362,12 @@ func (_L2OutputOracle *L2OutputOracleCallerSession) SUBMISSIONINTERVAL() (*big.I ...@@ -331,12 +362,12 @@ func (_L2OutputOracle *L2OutputOracleCallerSession) SUBMISSIONINTERVAL() (*big.I
return _L2OutputOracle.Contract.SUBMISSIONINTERVAL(&_L2OutputOracle.CallOpts) return _L2OutputOracle.Contract.SUBMISSIONINTERVAL(&_L2OutputOracle.CallOpts)
} }
// ComputeL2BlockNumber is a free data retrieval call binding the contract method 0x02e51345. // ComputeL2Timestamp is a free data retrieval call binding the contract method 0xd1de856c.
// //
// Solidity: function computeL2BlockNumber(uint256 _l2timestamp) view returns(uint256) // Solidity: function computeL2Timestamp(uint256 _l2BlockNumber) view returns(uint256)
func (_L2OutputOracle *L2OutputOracleCaller) ComputeL2BlockNumber(opts *bind.CallOpts, _l2timestamp *big.Int) (*big.Int, error) { func (_L2OutputOracle *L2OutputOracleCaller) ComputeL2Timestamp(opts *bind.CallOpts, _l2BlockNumber *big.Int) (*big.Int, error) {
var out []interface{} var out []interface{}
err := _L2OutputOracle.contract.Call(opts, &out, "computeL2BlockNumber", _l2timestamp) err := _L2OutputOracle.contract.Call(opts, &out, "computeL2Timestamp", _l2BlockNumber)
if err != nil { if err != nil {
return *new(*big.Int), err return *new(*big.Int), err
...@@ -348,26 +379,26 @@ func (_L2OutputOracle *L2OutputOracleCaller) ComputeL2BlockNumber(opts *bind.Cal ...@@ -348,26 +379,26 @@ func (_L2OutputOracle *L2OutputOracleCaller) ComputeL2BlockNumber(opts *bind.Cal
} }
// ComputeL2BlockNumber is a free data retrieval call binding the contract method 0x02e51345. // ComputeL2Timestamp is a free data retrieval call binding the contract method 0xd1de856c.
// //
// Solidity: function computeL2BlockNumber(uint256 _l2timestamp) view returns(uint256) // Solidity: function computeL2Timestamp(uint256 _l2BlockNumber) view returns(uint256)
func (_L2OutputOracle *L2OutputOracleSession) ComputeL2BlockNumber(_l2timestamp *big.Int) (*big.Int, error) { func (_L2OutputOracle *L2OutputOracleSession) ComputeL2Timestamp(_l2BlockNumber *big.Int) (*big.Int, error) {
return _L2OutputOracle.Contract.ComputeL2BlockNumber(&_L2OutputOracle.CallOpts, _l2timestamp) return _L2OutputOracle.Contract.ComputeL2Timestamp(&_L2OutputOracle.CallOpts, _l2BlockNumber)
} }
// ComputeL2BlockNumber is a free data retrieval call binding the contract method 0x02e51345. // ComputeL2Timestamp is a free data retrieval call binding the contract method 0xd1de856c.
// //
// Solidity: function computeL2BlockNumber(uint256 _l2timestamp) view returns(uint256) // Solidity: function computeL2Timestamp(uint256 _l2BlockNumber) view returns(uint256)
func (_L2OutputOracle *L2OutputOracleCallerSession) ComputeL2BlockNumber(_l2timestamp *big.Int) (*big.Int, error) { func (_L2OutputOracle *L2OutputOracleCallerSession) ComputeL2Timestamp(_l2BlockNumber *big.Int) (*big.Int, error) {
return _L2OutputOracle.Contract.ComputeL2BlockNumber(&_L2OutputOracle.CallOpts, _l2timestamp) return _L2OutputOracle.Contract.ComputeL2Timestamp(&_L2OutputOracle.CallOpts, _l2BlockNumber)
} }
// GetL2Output is a free data retrieval call binding the contract method 0xa25ae557. // GetL2Output is a free data retrieval call binding the contract method 0xa25ae557.
// //
// Solidity: function getL2Output(uint256 _l2Timestamp) view returns((bytes32,uint256)) // Solidity: function getL2Output(uint256 _l2BlockNumber) view returns((bytes32,uint256))
func (_L2OutputOracle *L2OutputOracleCaller) GetL2Output(opts *bind.CallOpts, _l2Timestamp *big.Int) (L2OutputOracleOutputProposal, error) { func (_L2OutputOracle *L2OutputOracleCaller) GetL2Output(opts *bind.CallOpts, _l2BlockNumber *big.Int) (L2OutputOracleOutputProposal, error) {
var out []interface{} var out []interface{}
err := _L2OutputOracle.contract.Call(opts, &out, "getL2Output", _l2Timestamp) err := _L2OutputOracle.contract.Call(opts, &out, "getL2Output", _l2BlockNumber)
if err != nil { if err != nil {
return *new(L2OutputOracleOutputProposal), err return *new(L2OutputOracleOutputProposal), err
...@@ -381,24 +412,24 @@ func (_L2OutputOracle *L2OutputOracleCaller) GetL2Output(opts *bind.CallOpts, _l ...@@ -381,24 +412,24 @@ func (_L2OutputOracle *L2OutputOracleCaller) GetL2Output(opts *bind.CallOpts, _l
// GetL2Output is a free data retrieval call binding the contract method 0xa25ae557. // GetL2Output is a free data retrieval call binding the contract method 0xa25ae557.
// //
// Solidity: function getL2Output(uint256 _l2Timestamp) view returns((bytes32,uint256)) // Solidity: function getL2Output(uint256 _l2BlockNumber) view returns((bytes32,uint256))
func (_L2OutputOracle *L2OutputOracleSession) GetL2Output(_l2Timestamp *big.Int) (L2OutputOracleOutputProposal, error) { func (_L2OutputOracle *L2OutputOracleSession) GetL2Output(_l2BlockNumber *big.Int) (L2OutputOracleOutputProposal, error) {
return _L2OutputOracle.Contract.GetL2Output(&_L2OutputOracle.CallOpts, _l2Timestamp) return _L2OutputOracle.Contract.GetL2Output(&_L2OutputOracle.CallOpts, _l2BlockNumber)
} }
// GetL2Output is a free data retrieval call binding the contract method 0xa25ae557. // GetL2Output is a free data retrieval call binding the contract method 0xa25ae557.
// //
// Solidity: function getL2Output(uint256 _l2Timestamp) view returns((bytes32,uint256)) // Solidity: function getL2Output(uint256 _l2BlockNumber) view returns((bytes32,uint256))
func (_L2OutputOracle *L2OutputOracleCallerSession) GetL2Output(_l2Timestamp *big.Int) (L2OutputOracleOutputProposal, error) { func (_L2OutputOracle *L2OutputOracleCallerSession) GetL2Output(_l2BlockNumber *big.Int) (L2OutputOracleOutputProposal, error) {
return _L2OutputOracle.Contract.GetL2Output(&_L2OutputOracle.CallOpts, _l2Timestamp) return _L2OutputOracle.Contract.GetL2Output(&_L2OutputOracle.CallOpts, _l2BlockNumber)
} }
// LatestBlockTimestamp is a free data retrieval call binding the contract method 0x0c1952d3. // LatestBlockNumber is a free data retrieval call binding the contract method 0x4599c788.
// //
// Solidity: function latestBlockTimestamp() view returns(uint256) // Solidity: function latestBlockNumber() view returns(uint256)
func (_L2OutputOracle *L2OutputOracleCaller) LatestBlockTimestamp(opts *bind.CallOpts) (*big.Int, error) { func (_L2OutputOracle *L2OutputOracleCaller) LatestBlockNumber(opts *bind.CallOpts) (*big.Int, error) {
var out []interface{} var out []interface{}
err := _L2OutputOracle.contract.Call(opts, &out, "latestBlockTimestamp") err := _L2OutputOracle.contract.Call(opts, &out, "latestBlockNumber")
if err != nil { if err != nil {
return *new(*big.Int), err return *new(*big.Int), err
...@@ -410,26 +441,26 @@ func (_L2OutputOracle *L2OutputOracleCaller) LatestBlockTimestamp(opts *bind.Cal ...@@ -410,26 +441,26 @@ func (_L2OutputOracle *L2OutputOracleCaller) LatestBlockTimestamp(opts *bind.Cal
} }
// LatestBlockTimestamp is a free data retrieval call binding the contract method 0x0c1952d3. // LatestBlockNumber is a free data retrieval call binding the contract method 0x4599c788.
// //
// Solidity: function latestBlockTimestamp() view returns(uint256) // Solidity: function latestBlockNumber() view returns(uint256)
func (_L2OutputOracle *L2OutputOracleSession) LatestBlockTimestamp() (*big.Int, error) { func (_L2OutputOracle *L2OutputOracleSession) LatestBlockNumber() (*big.Int, error) {
return _L2OutputOracle.Contract.LatestBlockTimestamp(&_L2OutputOracle.CallOpts) return _L2OutputOracle.Contract.LatestBlockNumber(&_L2OutputOracle.CallOpts)
} }
// LatestBlockTimestamp is a free data retrieval call binding the contract method 0x0c1952d3. // LatestBlockNumber is a free data retrieval call binding the contract method 0x4599c788.
// //
// Solidity: function latestBlockTimestamp() view returns(uint256) // Solidity: function latestBlockNumber() view returns(uint256)
func (_L2OutputOracle *L2OutputOracleCallerSession) LatestBlockTimestamp() (*big.Int, error) { func (_L2OutputOracle *L2OutputOracleCallerSession) LatestBlockNumber() (*big.Int, error) {
return _L2OutputOracle.Contract.LatestBlockTimestamp(&_L2OutputOracle.CallOpts) return _L2OutputOracle.Contract.LatestBlockNumber(&_L2OutputOracle.CallOpts)
} }
// NextTimestamp is a free data retrieval call binding the contract method 0x357e951f. // NextBlockNumber is a free data retrieval call binding the contract method 0xdcec3348.
// //
// Solidity: function nextTimestamp() view returns(uint256) // Solidity: function nextBlockNumber() view returns(uint256)
func (_L2OutputOracle *L2OutputOracleCaller) NextTimestamp(opts *bind.CallOpts) (*big.Int, error) { func (_L2OutputOracle *L2OutputOracleCaller) NextBlockNumber(opts *bind.CallOpts) (*big.Int, error) {
var out []interface{} var out []interface{}
err := _L2OutputOracle.contract.Call(opts, &out, "nextTimestamp") err := _L2OutputOracle.contract.Call(opts, &out, "nextBlockNumber")
if err != nil { if err != nil {
return *new(*big.Int), err return *new(*big.Int), err
...@@ -441,18 +472,18 @@ func (_L2OutputOracle *L2OutputOracleCaller) NextTimestamp(opts *bind.CallOpts) ...@@ -441,18 +472,18 @@ func (_L2OutputOracle *L2OutputOracleCaller) NextTimestamp(opts *bind.CallOpts)
} }
// NextTimestamp is a free data retrieval call binding the contract method 0x357e951f. // NextBlockNumber is a free data retrieval call binding the contract method 0xdcec3348.
// //
// Solidity: function nextTimestamp() view returns(uint256) // Solidity: function nextBlockNumber() view returns(uint256)
func (_L2OutputOracle *L2OutputOracleSession) NextTimestamp() (*big.Int, error) { func (_L2OutputOracle *L2OutputOracleSession) NextBlockNumber() (*big.Int, error) {
return _L2OutputOracle.Contract.NextTimestamp(&_L2OutputOracle.CallOpts) return _L2OutputOracle.Contract.NextBlockNumber(&_L2OutputOracle.CallOpts)
} }
// NextTimestamp is a free data retrieval call binding the contract method 0x357e951f. // NextBlockNumber is a free data retrieval call binding the contract method 0xdcec3348.
// //
// Solidity: function nextTimestamp() view returns(uint256) // Solidity: function nextBlockNumber() view returns(uint256)
func (_L2OutputOracle *L2OutputOracleCallerSession) NextTimestamp() (*big.Int, error) { func (_L2OutputOracle *L2OutputOracleCallerSession) NextBlockNumber() (*big.Int, error) {
return _L2OutputOracle.Contract.NextTimestamp(&_L2OutputOracle.CallOpts) return _L2OutputOracle.Contract.NextBlockNumber(&_L2OutputOracle.CallOpts)
} }
// Owner is a free data retrieval call binding the contract method 0x8da5cb5b. // Owner is a free data retrieval call binding the contract method 0x8da5cb5b.
...@@ -488,23 +519,23 @@ func (_L2OutputOracle *L2OutputOracleCallerSession) Owner() (common.Address, err ...@@ -488,23 +519,23 @@ func (_L2OutputOracle *L2OutputOracleCallerSession) Owner() (common.Address, err
// AppendL2Output is a paid mutator transaction binding the contract method 0x25188104. // AppendL2Output is a paid mutator transaction binding the contract method 0x25188104.
// //
// Solidity: function appendL2Output(bytes32 _l2Output, uint256 _l2timestamp, bytes32 _l1Blockhash, uint256 _l1Blocknumber) payable returns() // Solidity: function appendL2Output(bytes32 _l2Output, uint256 _l2BlockNumber, bytes32 _l1Blockhash, uint256 _l1BlockNumber) payable returns()
func (_L2OutputOracle *L2OutputOracleTransactor) AppendL2Output(opts *bind.TransactOpts, _l2Output [32]byte, _l2timestamp *big.Int, _l1Blockhash [32]byte, _l1Blocknumber *big.Int) (*types.Transaction, error) { func (_L2OutputOracle *L2OutputOracleTransactor) AppendL2Output(opts *bind.TransactOpts, _l2Output [32]byte, _l2BlockNumber *big.Int, _l1Blockhash [32]byte, _l1BlockNumber *big.Int) (*types.Transaction, error) {
return _L2OutputOracle.contract.Transact(opts, "appendL2Output", _l2Output, _l2timestamp, _l1Blockhash, _l1Blocknumber) return _L2OutputOracle.contract.Transact(opts, "appendL2Output", _l2Output, _l2BlockNumber, _l1Blockhash, _l1BlockNumber)
} }
// AppendL2Output is a paid mutator transaction binding the contract method 0x25188104. // AppendL2Output is a paid mutator transaction binding the contract method 0x25188104.
// //
// Solidity: function appendL2Output(bytes32 _l2Output, uint256 _l2timestamp, bytes32 _l1Blockhash, uint256 _l1Blocknumber) payable returns() // Solidity: function appendL2Output(bytes32 _l2Output, uint256 _l2BlockNumber, bytes32 _l1Blockhash, uint256 _l1BlockNumber) payable returns()
func (_L2OutputOracle *L2OutputOracleSession) AppendL2Output(_l2Output [32]byte, _l2timestamp *big.Int, _l1Blockhash [32]byte, _l1Blocknumber *big.Int) (*types.Transaction, error) { func (_L2OutputOracle *L2OutputOracleSession) AppendL2Output(_l2Output [32]byte, _l2BlockNumber *big.Int, _l1Blockhash [32]byte, _l1BlockNumber *big.Int) (*types.Transaction, error) {
return _L2OutputOracle.Contract.AppendL2Output(&_L2OutputOracle.TransactOpts, _l2Output, _l2timestamp, _l1Blockhash, _l1Blocknumber) return _L2OutputOracle.Contract.AppendL2Output(&_L2OutputOracle.TransactOpts, _l2Output, _l2BlockNumber, _l1Blockhash, _l1BlockNumber)
} }
// AppendL2Output is a paid mutator transaction binding the contract method 0x25188104. // AppendL2Output is a paid mutator transaction binding the contract method 0x25188104.
// //
// Solidity: function appendL2Output(bytes32 _l2Output, uint256 _l2timestamp, bytes32 _l1Blockhash, uint256 _l1Blocknumber) payable returns() // Solidity: function appendL2Output(bytes32 _l2Output, uint256 _l2BlockNumber, bytes32 _l1Blockhash, uint256 _l1BlockNumber) payable returns()
func (_L2OutputOracle *L2OutputOracleTransactorSession) AppendL2Output(_l2Output [32]byte, _l2timestamp *big.Int, _l1Blockhash [32]byte, _l1Blocknumber *big.Int) (*types.Transaction, error) { func (_L2OutputOracle *L2OutputOracleTransactorSession) AppendL2Output(_l2Output [32]byte, _l2BlockNumber *big.Int, _l1Blockhash [32]byte, _l1BlockNumber *big.Int) (*types.Transaction, error) {
return _L2OutputOracle.Contract.AppendL2Output(&_L2OutputOracle.TransactOpts, _l2Output, _l2timestamp, _l1Blockhash, _l1Blocknumber) return _L2OutputOracle.Contract.AppendL2Output(&_L2OutputOracle.TransactOpts, _l2Output, _l2BlockNumber, _l1Blockhash, _l1BlockNumber)
} }
// DeleteL2Output is a paid mutator transaction binding the contract method 0x093b3d90. // DeleteL2Output is a paid mutator transaction binding the contract method 0x093b3d90.
...@@ -570,9 +601,9 @@ func (_L2OutputOracle *L2OutputOracleTransactorSession) TransferOwnership(newOwn ...@@ -570,9 +601,9 @@ func (_L2OutputOracle *L2OutputOracleTransactorSession) TransferOwnership(newOwn
return _L2OutputOracle.Contract.TransferOwnership(&_L2OutputOracle.TransactOpts, newOwner) return _L2OutputOracle.Contract.TransferOwnership(&_L2OutputOracle.TransactOpts, newOwner)
} }
// L2OutputOracleOwnershipTransferredIterator is returned from FilterOwnershipTransferred and is used to iterate over the raw logs and unpacked data for OwnershipTransferred events raised by the L2OutputOracle contract. // L2OutputOracleL2OutputAppendedIterator is returned from FilterL2OutputAppended and is used to iterate over the raw logs and unpacked data for L2OutputAppended events raised by the L2OutputOracle contract.
type L2OutputOracleOwnershipTransferredIterator struct { type L2OutputOracleL2OutputAppendedIterator struct {
Event *L2OutputOracleOwnershipTransferred // Event containing the contract specifics and raw log Event *L2OutputOracleL2OutputAppended // Event containing the contract specifics and raw log
contract *bind.BoundContract // Generic contract to use for unpacking event data contract *bind.BoundContract // Generic contract to use for unpacking event data
event string // Event name to use for unpacking event data event string // Event name to use for unpacking event data
...@@ -586,7 +617,7 @@ type L2OutputOracleOwnershipTransferredIterator struct { ...@@ -586,7 +617,7 @@ type L2OutputOracleOwnershipTransferredIterator struct {
// Next advances the iterator to the subsequent event, returning whether there // Next advances the iterator to the subsequent event, returning whether there
// are any more events found. In case of a retrieval or parsing error, false is // are any more events found. In case of a retrieval or parsing error, false is
// returned and Error() can be queried for the exact failure. // returned and Error() can be queried for the exact failure.
func (it *L2OutputOracleOwnershipTransferredIterator) Next() bool { func (it *L2OutputOracleL2OutputAppendedIterator) Next() bool {
// If the iterator failed, stop iterating // If the iterator failed, stop iterating
if it.fail != nil { if it.fail != nil {
return false return false
...@@ -595,7 +626,7 @@ func (it *L2OutputOracleOwnershipTransferredIterator) Next() bool { ...@@ -595,7 +626,7 @@ func (it *L2OutputOracleOwnershipTransferredIterator) Next() bool {
if it.done { if it.done {
select { select {
case log := <-it.logs: case log := <-it.logs:
it.Event = new(L2OutputOracleOwnershipTransferred) it.Event = new(L2OutputOracleL2OutputAppended)
if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil {
it.fail = err it.fail = err
return false return false
...@@ -610,7 +641,7 @@ func (it *L2OutputOracleOwnershipTransferredIterator) Next() bool { ...@@ -610,7 +641,7 @@ func (it *L2OutputOracleOwnershipTransferredIterator) Next() bool {
// Iterator still in progress, wait for either a data or an error event // Iterator still in progress, wait for either a data or an error event
select { select {
case log := <-it.logs: case log := <-it.logs:
it.Event = new(L2OutputOracleOwnershipTransferred) it.Event = new(L2OutputOracleL2OutputAppended)
if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil {
it.fail = err it.fail = err
return false return false
...@@ -626,60 +657,69 @@ func (it *L2OutputOracleOwnershipTransferredIterator) Next() bool { ...@@ -626,60 +657,69 @@ func (it *L2OutputOracleOwnershipTransferredIterator) Next() bool {
} }
// Error returns any retrieval or parsing error occurred during filtering. // Error returns any retrieval or parsing error occurred during filtering.
func (it *L2OutputOracleOwnershipTransferredIterator) Error() error { func (it *L2OutputOracleL2OutputAppendedIterator) Error() error {
return it.fail return it.fail
} }
// Close terminates the iteration process, releasing any pending underlying // Close terminates the iteration process, releasing any pending underlying
// resources. // resources.
func (it *L2OutputOracleOwnershipTransferredIterator) Close() error { func (it *L2OutputOracleL2OutputAppendedIterator) Close() error {
it.sub.Unsubscribe() it.sub.Unsubscribe()
return nil return nil
} }
// L2OutputOracleOwnershipTransferred represents a OwnershipTransferred event raised by the L2OutputOracle contract. // L2OutputOracleL2OutputAppended represents a L2OutputAppended event raised by the L2OutputOracle contract.
type L2OutputOracleOwnershipTransferred struct { type L2OutputOracleL2OutputAppended struct {
PreviousOwner common.Address L2Output [32]byte
NewOwner common.Address L1Timestamp *big.Int
L2BlockNumber *big.Int
Raw types.Log // Blockchain specific contextual infos Raw types.Log // Blockchain specific contextual infos
} }
// FilterOwnershipTransferred is a free log retrieval operation binding the contract event 0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0. // FilterL2OutputAppended is a free log retrieval operation binding the contract event 0xd6703ded1701060d9ae1793db76d594790a4e775781225f79b5aa8a77987c080.
// //
// Solidity: event OwnershipTransferred(address indexed previousOwner, address indexed newOwner) // Solidity: event L2OutputAppended(bytes32 indexed _l2Output, uint256 indexed _l1Timestamp, uint256 indexed _l2BlockNumber)
func (_L2OutputOracle *L2OutputOracleFilterer) FilterOwnershipTransferred(opts *bind.FilterOpts, previousOwner []common.Address, newOwner []common.Address) (*L2OutputOracleOwnershipTransferredIterator, error) { func (_L2OutputOracle *L2OutputOracleFilterer) FilterL2OutputAppended(opts *bind.FilterOpts, _l2Output [][32]byte, _l1Timestamp []*big.Int, _l2BlockNumber []*big.Int) (*L2OutputOracleL2OutputAppendedIterator, error) {
var previousOwnerRule []interface{} var _l2OutputRule []interface{}
for _, previousOwnerItem := range previousOwner { for _, _l2OutputItem := range _l2Output {
previousOwnerRule = append(previousOwnerRule, previousOwnerItem) _l2OutputRule = append(_l2OutputRule, _l2OutputItem)
} }
var newOwnerRule []interface{} var _l1TimestampRule []interface{}
for _, newOwnerItem := range newOwner { for _, _l1TimestampItem := range _l1Timestamp {
newOwnerRule = append(newOwnerRule, newOwnerItem) _l1TimestampRule = append(_l1TimestampRule, _l1TimestampItem)
}
var _l2BlockNumberRule []interface{}
for _, _l2BlockNumberItem := range _l2BlockNumber {
_l2BlockNumberRule = append(_l2BlockNumberRule, _l2BlockNumberItem)
} }
logs, sub, err := _L2OutputOracle.contract.FilterLogs(opts, "OwnershipTransferred", previousOwnerRule, newOwnerRule) logs, sub, err := _L2OutputOracle.contract.FilterLogs(opts, "L2OutputAppended", _l2OutputRule, _l1TimestampRule, _l2BlockNumberRule)
if err != nil { if err != nil {
return nil, err return nil, err
} }
return &L2OutputOracleOwnershipTransferredIterator{contract: _L2OutputOracle.contract, event: "OwnershipTransferred", logs: logs, sub: sub}, nil return &L2OutputOracleL2OutputAppendedIterator{contract: _L2OutputOracle.contract, event: "L2OutputAppended", logs: logs, sub: sub}, nil
} }
// WatchOwnershipTransferred is a free log subscription operation binding the contract event 0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0. // WatchL2OutputAppended is a free log subscription operation binding the contract event 0xd6703ded1701060d9ae1793db76d594790a4e775781225f79b5aa8a77987c080.
// //
// Solidity: event OwnershipTransferred(address indexed previousOwner, address indexed newOwner) // Solidity: event L2OutputAppended(bytes32 indexed _l2Output, uint256 indexed _l1Timestamp, uint256 indexed _l2BlockNumber)
func (_L2OutputOracle *L2OutputOracleFilterer) WatchOwnershipTransferred(opts *bind.WatchOpts, sink chan<- *L2OutputOracleOwnershipTransferred, previousOwner []common.Address, newOwner []common.Address) (event.Subscription, error) { func (_L2OutputOracle *L2OutputOracleFilterer) WatchL2OutputAppended(opts *bind.WatchOpts, sink chan<- *L2OutputOracleL2OutputAppended, _l2Output [][32]byte, _l1Timestamp []*big.Int, _l2BlockNumber []*big.Int) (event.Subscription, error) {
var previousOwnerRule []interface{} var _l2OutputRule []interface{}
for _, previousOwnerItem := range previousOwner { for _, _l2OutputItem := range _l2Output {
previousOwnerRule = append(previousOwnerRule, previousOwnerItem) _l2OutputRule = append(_l2OutputRule, _l2OutputItem)
} }
var newOwnerRule []interface{} var _l1TimestampRule []interface{}
for _, newOwnerItem := range newOwner { for _, _l1TimestampItem := range _l1Timestamp {
newOwnerRule = append(newOwnerRule, newOwnerItem) _l1TimestampRule = append(_l1TimestampRule, _l1TimestampItem)
}
var _l2BlockNumberRule []interface{}
for _, _l2BlockNumberItem := range _l2BlockNumber {
_l2BlockNumberRule = append(_l2BlockNumberRule, _l2BlockNumberItem)
} }
logs, sub, err := _L2OutputOracle.contract.WatchLogs(opts, "OwnershipTransferred", previousOwnerRule, newOwnerRule) logs, sub, err := _L2OutputOracle.contract.WatchLogs(opts, "L2OutputAppended", _l2OutputRule, _l1TimestampRule, _l2BlockNumberRule)
if err != nil { if err != nil {
return nil, err return nil, err
} }
...@@ -689,8 +729,8 @@ func (_L2OutputOracle *L2OutputOracleFilterer) WatchOwnershipTransferred(opts *b ...@@ -689,8 +729,8 @@ func (_L2OutputOracle *L2OutputOracleFilterer) WatchOwnershipTransferred(opts *b
select { select {
case log := <-logs: case log := <-logs:
// New log arrived, parse the event and forward to the user // New log arrived, parse the event and forward to the user
event := new(L2OutputOracleOwnershipTransferred) event := new(L2OutputOracleL2OutputAppended)
if err := _L2OutputOracle.contract.UnpackLog(event, "OwnershipTransferred", log); err != nil { if err := _L2OutputOracle.contract.UnpackLog(event, "L2OutputAppended", log); err != nil {
return err return err
} }
event.Raw = log event.Raw = log
...@@ -711,21 +751,21 @@ func (_L2OutputOracle *L2OutputOracleFilterer) WatchOwnershipTransferred(opts *b ...@@ -711,21 +751,21 @@ func (_L2OutputOracle *L2OutputOracleFilterer) WatchOwnershipTransferred(opts *b
}), nil }), nil
} }
// ParseOwnershipTransferred is a log parse operation binding the contract event 0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0. // ParseL2OutputAppended is a log parse operation binding the contract event 0xd6703ded1701060d9ae1793db76d594790a4e775781225f79b5aa8a77987c080.
// //
// Solidity: event OwnershipTransferred(address indexed previousOwner, address indexed newOwner) // Solidity: event L2OutputAppended(bytes32 indexed _l2Output, uint256 indexed _l1Timestamp, uint256 indexed _l2BlockNumber)
func (_L2OutputOracle *L2OutputOracleFilterer) ParseOwnershipTransferred(log types.Log) (*L2OutputOracleOwnershipTransferred, error) { func (_L2OutputOracle *L2OutputOracleFilterer) ParseL2OutputAppended(log types.Log) (*L2OutputOracleL2OutputAppended, error) {
event := new(L2OutputOracleOwnershipTransferred) event := new(L2OutputOracleL2OutputAppended)
if err := _L2OutputOracle.contract.UnpackLog(event, "OwnershipTransferred", log); err != nil { if err := _L2OutputOracle.contract.UnpackLog(event, "L2OutputAppended", log); err != nil {
return nil, err return nil, err
} }
event.Raw = log event.Raw = log
return event, nil return event, nil
} }
// L2OutputOracleL2OutputAppendedIterator is returned from FilterL2OutputAppended and is used to iterate over the raw logs and unpacked data for L2OutputAppended events raised by the L2OutputOracle contract. // L2OutputOracleL2OutputDeletedIterator is returned from FilterL2OutputDeleted and is used to iterate over the raw logs and unpacked data for L2OutputDeleted events raised by the L2OutputOracle contract.
type L2OutputOracleL2OutputAppendedIterator struct { type L2OutputOracleL2OutputDeletedIterator struct {
Event *L2OutputOracleL2OutputAppended // Event containing the contract specifics and raw log Event *L2OutputOracleL2OutputDeleted // Event containing the contract specifics and raw log
contract *bind.BoundContract // Generic contract to use for unpacking event data contract *bind.BoundContract // Generic contract to use for unpacking event data
event string // Event name to use for unpacking event data event string // Event name to use for unpacking event data
...@@ -739,7 +779,7 @@ type L2OutputOracleL2OutputAppendedIterator struct { ...@@ -739,7 +779,7 @@ type L2OutputOracleL2OutputAppendedIterator struct {
// Next advances the iterator to the subsequent event, returning whether there // Next advances the iterator to the subsequent event, returning whether there
// are any more events found. In case of a retrieval or parsing error, false is // are any more events found. In case of a retrieval or parsing error, false is
// returned and Error() can be queried for the exact failure. // returned and Error() can be queried for the exact failure.
func (it *L2OutputOracleL2OutputAppendedIterator) Next() bool { func (it *L2OutputOracleL2OutputDeletedIterator) Next() bool {
// If the iterator failed, stop iterating // If the iterator failed, stop iterating
if it.fail != nil { if it.fail != nil {
return false return false
...@@ -748,7 +788,7 @@ func (it *L2OutputOracleL2OutputAppendedIterator) Next() bool { ...@@ -748,7 +788,7 @@ func (it *L2OutputOracleL2OutputAppendedIterator) Next() bool {
if it.done { if it.done {
select { select {
case log := <-it.logs: case log := <-it.logs:
it.Event = new(L2OutputOracleL2OutputAppended) it.Event = new(L2OutputOracleL2OutputDeleted)
if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil {
it.fail = err it.fail = err
return false return false
...@@ -763,7 +803,7 @@ func (it *L2OutputOracleL2OutputAppendedIterator) Next() bool { ...@@ -763,7 +803,7 @@ func (it *L2OutputOracleL2OutputAppendedIterator) Next() bool {
// Iterator still in progress, wait for either a data or an error event // Iterator still in progress, wait for either a data or an error event
select { select {
case log := <-it.logs: case log := <-it.logs:
it.Event = new(L2OutputOracleL2OutputAppended) it.Event = new(L2OutputOracleL2OutputDeleted)
if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil {
it.fail = err it.fail = err
return false return false
...@@ -779,29 +819,29 @@ func (it *L2OutputOracleL2OutputAppendedIterator) Next() bool { ...@@ -779,29 +819,29 @@ func (it *L2OutputOracleL2OutputAppendedIterator) Next() bool {
} }
// Error returns any retrieval or parsing error occurred during filtering. // Error returns any retrieval or parsing error occurred during filtering.
func (it *L2OutputOracleL2OutputAppendedIterator) Error() error { func (it *L2OutputOracleL2OutputDeletedIterator) Error() error {
return it.fail return it.fail
} }
// Close terminates the iteration process, releasing any pending underlying // Close terminates the iteration process, releasing any pending underlying
// resources. // resources.
func (it *L2OutputOracleL2OutputAppendedIterator) Close() error { func (it *L2OutputOracleL2OutputDeletedIterator) Close() error {
it.sub.Unsubscribe() it.sub.Unsubscribe()
return nil return nil
} }
// L2OutputOracleL2OutputAppended represents a L2OutputAppended event raised by the L2OutputOracle contract. // L2OutputOracleL2OutputDeleted represents a L2OutputDeleted event raised by the L2OutputOracle contract.
type L2OutputOracleL2OutputAppended struct { type L2OutputOracleL2OutputDeleted struct {
L2Output [32]byte L2Output [32]byte
L1Timestamp *big.Int L1Timestamp *big.Int
L2timestamp *big.Int L2BlockNumber *big.Int
Raw types.Log // Blockchain specific contextual infos Raw types.Log // Blockchain specific contextual infos
} }
// FilterL2OutputAppended is a free log retrieval operation binding the contract event 0x54fbf9b58db0b6543a3a0cb9fbd4e98a7c7b88878978fa125b84a2c7f51d34ba. // FilterL2OutputDeleted is a free log retrieval operation binding the contract event 0x7320566fd5256cf8923648a5d9f560f1e92f1435a1bb32ddd1fe107f224ad359.
// //
// Solidity: event l2OutputAppended(bytes32 indexed _l2Output, uint256 indexed _l1Timestamp, uint256 indexed _l2timestamp) // Solidity: event L2OutputDeleted(bytes32 indexed _l2Output, uint256 indexed _l1Timestamp, uint256 indexed _l2BlockNumber)
func (_L2OutputOracle *L2OutputOracleFilterer) FilterL2OutputAppended(opts *bind.FilterOpts, _l2Output [][32]byte, _l1Timestamp []*big.Int, _l2timestamp []*big.Int) (*L2OutputOracleL2OutputAppendedIterator, error) { func (_L2OutputOracle *L2OutputOracleFilterer) FilterL2OutputDeleted(opts *bind.FilterOpts, _l2Output [][32]byte, _l1Timestamp []*big.Int, _l2BlockNumber []*big.Int) (*L2OutputOracleL2OutputDeletedIterator, error) {
var _l2OutputRule []interface{} var _l2OutputRule []interface{}
for _, _l2OutputItem := range _l2Output { for _, _l2OutputItem := range _l2Output {
...@@ -811,22 +851,22 @@ func (_L2OutputOracle *L2OutputOracleFilterer) FilterL2OutputAppended(opts *bind ...@@ -811,22 +851,22 @@ func (_L2OutputOracle *L2OutputOracleFilterer) FilterL2OutputAppended(opts *bind
for _, _l1TimestampItem := range _l1Timestamp { for _, _l1TimestampItem := range _l1Timestamp {
_l1TimestampRule = append(_l1TimestampRule, _l1TimestampItem) _l1TimestampRule = append(_l1TimestampRule, _l1TimestampItem)
} }
var _l2timestampRule []interface{} var _l2BlockNumberRule []interface{}
for _, _l2timestampItem := range _l2timestamp { for _, _l2BlockNumberItem := range _l2BlockNumber {
_l2timestampRule = append(_l2timestampRule, _l2timestampItem) _l2BlockNumberRule = append(_l2BlockNumberRule, _l2BlockNumberItem)
} }
logs, sub, err := _L2OutputOracle.contract.FilterLogs(opts, "l2OutputAppended", _l2OutputRule, _l1TimestampRule, _l2timestampRule) logs, sub, err := _L2OutputOracle.contract.FilterLogs(opts, "L2OutputDeleted", _l2OutputRule, _l1TimestampRule, _l2BlockNumberRule)
if err != nil { if err != nil {
return nil, err return nil, err
} }
return &L2OutputOracleL2OutputAppendedIterator{contract: _L2OutputOracle.contract, event: "l2OutputAppended", logs: logs, sub: sub}, nil return &L2OutputOracleL2OutputDeletedIterator{contract: _L2OutputOracle.contract, event: "L2OutputDeleted", logs: logs, sub: sub}, nil
} }
// WatchL2OutputAppended is a free log subscription operation binding the contract event 0x54fbf9b58db0b6543a3a0cb9fbd4e98a7c7b88878978fa125b84a2c7f51d34ba. // WatchL2OutputDeleted is a free log subscription operation binding the contract event 0x7320566fd5256cf8923648a5d9f560f1e92f1435a1bb32ddd1fe107f224ad359.
// //
// Solidity: event l2OutputAppended(bytes32 indexed _l2Output, uint256 indexed _l1Timestamp, uint256 indexed _l2timestamp) // Solidity: event L2OutputDeleted(bytes32 indexed _l2Output, uint256 indexed _l1Timestamp, uint256 indexed _l2BlockNumber)
func (_L2OutputOracle *L2OutputOracleFilterer) WatchL2OutputAppended(opts *bind.WatchOpts, sink chan<- *L2OutputOracleL2OutputAppended, _l2Output [][32]byte, _l1Timestamp []*big.Int, _l2timestamp []*big.Int) (event.Subscription, error) { func (_L2OutputOracle *L2OutputOracleFilterer) WatchL2OutputDeleted(opts *bind.WatchOpts, sink chan<- *L2OutputOracleL2OutputDeleted, _l2Output [][32]byte, _l1Timestamp []*big.Int, _l2BlockNumber []*big.Int) (event.Subscription, error) {
var _l2OutputRule []interface{} var _l2OutputRule []interface{}
for _, _l2OutputItem := range _l2Output { for _, _l2OutputItem := range _l2Output {
...@@ -836,12 +876,12 @@ func (_L2OutputOracle *L2OutputOracleFilterer) WatchL2OutputAppended(opts *bind. ...@@ -836,12 +876,12 @@ func (_L2OutputOracle *L2OutputOracleFilterer) WatchL2OutputAppended(opts *bind.
for _, _l1TimestampItem := range _l1Timestamp { for _, _l1TimestampItem := range _l1Timestamp {
_l1TimestampRule = append(_l1TimestampRule, _l1TimestampItem) _l1TimestampRule = append(_l1TimestampRule, _l1TimestampItem)
} }
var _l2timestampRule []interface{} var _l2BlockNumberRule []interface{}
for _, _l2timestampItem := range _l2timestamp { for _, _l2BlockNumberItem := range _l2BlockNumber {
_l2timestampRule = append(_l2timestampRule, _l2timestampItem) _l2BlockNumberRule = append(_l2BlockNumberRule, _l2BlockNumberItem)
} }
logs, sub, err := _L2OutputOracle.contract.WatchLogs(opts, "l2OutputAppended", _l2OutputRule, _l1TimestampRule, _l2timestampRule) logs, sub, err := _L2OutputOracle.contract.WatchLogs(opts, "L2OutputDeleted", _l2OutputRule, _l1TimestampRule, _l2BlockNumberRule)
if err != nil { if err != nil {
return nil, err return nil, err
} }
...@@ -851,8 +891,8 @@ func (_L2OutputOracle *L2OutputOracleFilterer) WatchL2OutputAppended(opts *bind. ...@@ -851,8 +891,8 @@ func (_L2OutputOracle *L2OutputOracleFilterer) WatchL2OutputAppended(opts *bind.
select { select {
case log := <-logs: case log := <-logs:
// New log arrived, parse the event and forward to the user // New log arrived, parse the event and forward to the user
event := new(L2OutputOracleL2OutputAppended) event := new(L2OutputOracleL2OutputDeleted)
if err := _L2OutputOracle.contract.UnpackLog(event, "l2OutputAppended", log); err != nil { if err := _L2OutputOracle.contract.UnpackLog(event, "L2OutputDeleted", log); err != nil {
return err return err
} }
event.Raw = log event.Raw = log
...@@ -873,21 +913,21 @@ func (_L2OutputOracle *L2OutputOracleFilterer) WatchL2OutputAppended(opts *bind. ...@@ -873,21 +913,21 @@ func (_L2OutputOracle *L2OutputOracleFilterer) WatchL2OutputAppended(opts *bind.
}), nil }), nil
} }
// ParseL2OutputAppended is a log parse operation binding the contract event 0x54fbf9b58db0b6543a3a0cb9fbd4e98a7c7b88878978fa125b84a2c7f51d34ba. // ParseL2OutputDeleted is a log parse operation binding the contract event 0x7320566fd5256cf8923648a5d9f560f1e92f1435a1bb32ddd1fe107f224ad359.
// //
// Solidity: event l2OutputAppended(bytes32 indexed _l2Output, uint256 indexed _l1Timestamp, uint256 indexed _l2timestamp) // Solidity: event L2OutputDeleted(bytes32 indexed _l2Output, uint256 indexed _l1Timestamp, uint256 indexed _l2BlockNumber)
func (_L2OutputOracle *L2OutputOracleFilterer) ParseL2OutputAppended(log types.Log) (*L2OutputOracleL2OutputAppended, error) { func (_L2OutputOracle *L2OutputOracleFilterer) ParseL2OutputDeleted(log types.Log) (*L2OutputOracleL2OutputDeleted, error) {
event := new(L2OutputOracleL2OutputAppended) event := new(L2OutputOracleL2OutputDeleted)
if err := _L2OutputOracle.contract.UnpackLog(event, "l2OutputAppended", log); err != nil { if err := _L2OutputOracle.contract.UnpackLog(event, "L2OutputDeleted", log); err != nil {
return nil, err return nil, err
} }
event.Raw = log event.Raw = log
return event, nil return event, nil
} }
// L2OutputOracleL2OutputDeletedIterator is returned from FilterL2OutputDeleted and is used to iterate over the raw logs and unpacked data for L2OutputDeleted events raised by the L2OutputOracle contract. // L2OutputOracleOwnershipTransferredIterator is returned from FilterOwnershipTransferred and is used to iterate over the raw logs and unpacked data for OwnershipTransferred events raised by the L2OutputOracle contract.
type L2OutputOracleL2OutputDeletedIterator struct { type L2OutputOracleOwnershipTransferredIterator struct {
Event *L2OutputOracleL2OutputDeleted // Event containing the contract specifics and raw log Event *L2OutputOracleOwnershipTransferred // Event containing the contract specifics and raw log
contract *bind.BoundContract // Generic contract to use for unpacking event data contract *bind.BoundContract // Generic contract to use for unpacking event data
event string // Event name to use for unpacking event data event string // Event name to use for unpacking event data
...@@ -901,7 +941,7 @@ type L2OutputOracleL2OutputDeletedIterator struct { ...@@ -901,7 +941,7 @@ type L2OutputOracleL2OutputDeletedIterator struct {
// Next advances the iterator to the subsequent event, returning whether there // Next advances the iterator to the subsequent event, returning whether there
// are any more events found. In case of a retrieval or parsing error, false is // are any more events found. In case of a retrieval or parsing error, false is
// returned and Error() can be queried for the exact failure. // returned and Error() can be queried for the exact failure.
func (it *L2OutputOracleL2OutputDeletedIterator) Next() bool { func (it *L2OutputOracleOwnershipTransferredIterator) Next() bool {
// If the iterator failed, stop iterating // If the iterator failed, stop iterating
if it.fail != nil { if it.fail != nil {
return false return false
...@@ -910,7 +950,7 @@ func (it *L2OutputOracleL2OutputDeletedIterator) Next() bool { ...@@ -910,7 +950,7 @@ func (it *L2OutputOracleL2OutputDeletedIterator) Next() bool {
if it.done { if it.done {
select { select {
case log := <-it.logs: case log := <-it.logs:
it.Event = new(L2OutputOracleL2OutputDeleted) it.Event = new(L2OutputOracleOwnershipTransferred)
if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil {
it.fail = err it.fail = err
return false return false
...@@ -925,7 +965,7 @@ func (it *L2OutputOracleL2OutputDeletedIterator) Next() bool { ...@@ -925,7 +965,7 @@ func (it *L2OutputOracleL2OutputDeletedIterator) Next() bool {
// Iterator still in progress, wait for either a data or an error event // Iterator still in progress, wait for either a data or an error event
select { select {
case log := <-it.logs: case log := <-it.logs:
it.Event = new(L2OutputOracleL2OutputDeleted) it.Event = new(L2OutputOracleOwnershipTransferred)
if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil {
it.fail = err it.fail = err
return false return false
...@@ -941,69 +981,60 @@ func (it *L2OutputOracleL2OutputDeletedIterator) Next() bool { ...@@ -941,69 +981,60 @@ func (it *L2OutputOracleL2OutputDeletedIterator) Next() bool {
} }
// Error returns any retrieval or parsing error occurred during filtering. // Error returns any retrieval or parsing error occurred during filtering.
func (it *L2OutputOracleL2OutputDeletedIterator) Error() error { func (it *L2OutputOracleOwnershipTransferredIterator) Error() error {
return it.fail return it.fail
} }
// Close terminates the iteration process, releasing any pending underlying // Close terminates the iteration process, releasing any pending underlying
// resources. // resources.
func (it *L2OutputOracleL2OutputDeletedIterator) Close() error { func (it *L2OutputOracleOwnershipTransferredIterator) Close() error {
it.sub.Unsubscribe() it.sub.Unsubscribe()
return nil return nil
} }
// L2OutputOracleL2OutputDeleted represents a L2OutputDeleted event raised by the L2OutputOracle contract. // L2OutputOracleOwnershipTransferred represents a OwnershipTransferred event raised by the L2OutputOracle contract.
type L2OutputOracleL2OutputDeleted struct { type L2OutputOracleOwnershipTransferred struct {
L2Output [32]byte PreviousOwner common.Address
L1Timestamp *big.Int NewOwner common.Address
L2timestamp *big.Int Raw types.Log // Blockchain specific contextual infos
Raw types.Log // Blockchain specific contextual infos
} }
// FilterL2OutputDeleted is a free log retrieval operation binding the contract event 0x6897e92e2fea3b89bf0d45ed867487716da71bfa624c6878569d227d736c7009. // FilterOwnershipTransferred is a free log retrieval operation binding the contract event 0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0.
// //
// Solidity: event l2OutputDeleted(bytes32 indexed _l2Output, uint256 indexed _l1Timestamp, uint256 indexed _l2timestamp) // Solidity: event OwnershipTransferred(address indexed previousOwner, address indexed newOwner)
func (_L2OutputOracle *L2OutputOracleFilterer) FilterL2OutputDeleted(opts *bind.FilterOpts, _l2Output [][32]byte, _l1Timestamp []*big.Int, _l2timestamp []*big.Int) (*L2OutputOracleL2OutputDeletedIterator, error) { func (_L2OutputOracle *L2OutputOracleFilterer) FilterOwnershipTransferred(opts *bind.FilterOpts, previousOwner []common.Address, newOwner []common.Address) (*L2OutputOracleOwnershipTransferredIterator, error) {
var _l2OutputRule []interface{} var previousOwnerRule []interface{}
for _, _l2OutputItem := range _l2Output { for _, previousOwnerItem := range previousOwner {
_l2OutputRule = append(_l2OutputRule, _l2OutputItem) previousOwnerRule = append(previousOwnerRule, previousOwnerItem)
}
var _l1TimestampRule []interface{}
for _, _l1TimestampItem := range _l1Timestamp {
_l1TimestampRule = append(_l1TimestampRule, _l1TimestampItem)
} }
var _l2timestampRule []interface{} var newOwnerRule []interface{}
for _, _l2timestampItem := range _l2timestamp { for _, newOwnerItem := range newOwner {
_l2timestampRule = append(_l2timestampRule, _l2timestampItem) newOwnerRule = append(newOwnerRule, newOwnerItem)
} }
logs, sub, err := _L2OutputOracle.contract.FilterLogs(opts, "l2OutputDeleted", _l2OutputRule, _l1TimestampRule, _l2timestampRule) logs, sub, err := _L2OutputOracle.contract.FilterLogs(opts, "OwnershipTransferred", previousOwnerRule, newOwnerRule)
if err != nil { if err != nil {
return nil, err return nil, err
} }
return &L2OutputOracleL2OutputDeletedIterator{contract: _L2OutputOracle.contract, event: "l2OutputDeleted", logs: logs, sub: sub}, nil return &L2OutputOracleOwnershipTransferredIterator{contract: _L2OutputOracle.contract, event: "OwnershipTransferred", logs: logs, sub: sub}, nil
} }
// WatchL2OutputDeleted is a free log subscription operation binding the contract event 0x6897e92e2fea3b89bf0d45ed867487716da71bfa624c6878569d227d736c7009. // WatchOwnershipTransferred is a free log subscription operation binding the contract event 0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0.
// //
// Solidity: event l2OutputDeleted(bytes32 indexed _l2Output, uint256 indexed _l1Timestamp, uint256 indexed _l2timestamp) // Solidity: event OwnershipTransferred(address indexed previousOwner, address indexed newOwner)
func (_L2OutputOracle *L2OutputOracleFilterer) WatchL2OutputDeleted(opts *bind.WatchOpts, sink chan<- *L2OutputOracleL2OutputDeleted, _l2Output [][32]byte, _l1Timestamp []*big.Int, _l2timestamp []*big.Int) (event.Subscription, error) { func (_L2OutputOracle *L2OutputOracleFilterer) WatchOwnershipTransferred(opts *bind.WatchOpts, sink chan<- *L2OutputOracleOwnershipTransferred, previousOwner []common.Address, newOwner []common.Address) (event.Subscription, error) {
var _l2OutputRule []interface{} var previousOwnerRule []interface{}
for _, _l2OutputItem := range _l2Output { for _, previousOwnerItem := range previousOwner {
_l2OutputRule = append(_l2OutputRule, _l2OutputItem) previousOwnerRule = append(previousOwnerRule, previousOwnerItem)
}
var _l1TimestampRule []interface{}
for _, _l1TimestampItem := range _l1Timestamp {
_l1TimestampRule = append(_l1TimestampRule, _l1TimestampItem)
} }
var _l2timestampRule []interface{} var newOwnerRule []interface{}
for _, _l2timestampItem := range _l2timestamp { for _, newOwnerItem := range newOwner {
_l2timestampRule = append(_l2timestampRule, _l2timestampItem) newOwnerRule = append(newOwnerRule, newOwnerItem)
} }
logs, sub, err := _L2OutputOracle.contract.WatchLogs(opts, "l2OutputDeleted", _l2OutputRule, _l1TimestampRule, _l2timestampRule) logs, sub, err := _L2OutputOracle.contract.WatchLogs(opts, "OwnershipTransferred", previousOwnerRule, newOwnerRule)
if err != nil { if err != nil {
return nil, err return nil, err
} }
...@@ -1013,8 +1044,8 @@ func (_L2OutputOracle *L2OutputOracleFilterer) WatchL2OutputDeleted(opts *bind.W ...@@ -1013,8 +1044,8 @@ func (_L2OutputOracle *L2OutputOracleFilterer) WatchL2OutputDeleted(opts *bind.W
select { select {
case log := <-logs: case log := <-logs:
// New log arrived, parse the event and forward to the user // New log arrived, parse the event and forward to the user
event := new(L2OutputOracleL2OutputDeleted) event := new(L2OutputOracleOwnershipTransferred)
if err := _L2OutputOracle.contract.UnpackLog(event, "l2OutputDeleted", log); err != nil { if err := _L2OutputOracle.contract.UnpackLog(event, "OwnershipTransferred", log); err != nil {
return err return err
} }
event.Raw = log event.Raw = log
...@@ -1035,12 +1066,12 @@ func (_L2OutputOracle *L2OutputOracleFilterer) WatchL2OutputDeleted(opts *bind.W ...@@ -1035,12 +1066,12 @@ func (_L2OutputOracle *L2OutputOracleFilterer) WatchL2OutputDeleted(opts *bind.W
}), nil }), nil
} }
// ParseL2OutputDeleted is a log parse operation binding the contract event 0x6897e92e2fea3b89bf0d45ed867487716da71bfa624c6878569d227d736c7009. // ParseOwnershipTransferred is a log parse operation binding the contract event 0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0.
// //
// Solidity: event l2OutputDeleted(bytes32 indexed _l2Output, uint256 indexed _l1Timestamp, uint256 indexed _l2timestamp) // Solidity: event OwnershipTransferred(address indexed previousOwner, address indexed newOwner)
func (_L2OutputOracle *L2OutputOracleFilterer) ParseL2OutputDeleted(log types.Log) (*L2OutputOracleL2OutputDeleted, error) { func (_L2OutputOracle *L2OutputOracleFilterer) ParseOwnershipTransferred(log types.Log) (*L2OutputOracleOwnershipTransferred, error) {
event := new(L2OutputOracleL2OutputDeleted) event := new(L2OutputOracleOwnershipTransferred)
if err := _L2OutputOracle.contract.UnpackLog(event, "l2OutputDeleted", log); err != nil { if err := _L2OutputOracle.contract.UnpackLog(event, "OwnershipTransferred", log); err != nil {
return nil, err return nil, err
} }
event.Raw = log event.Raw = log
......
...@@ -38,7 +38,7 @@ type WithdrawalVerifierOutputRootProof struct { ...@@ -38,7 +38,7 @@ type WithdrawalVerifierOutputRootProof struct {
// OptimismPortalMetaData contains all meta data concerning the OptimismPortal contract. // OptimismPortalMetaData contains all meta data concerning the OptimismPortal contract.
var OptimismPortalMetaData = &bind.MetaData{ var OptimismPortalMetaData = &bind.MetaData{
ABI: "[{\"inputs\":[{\"internalType\":\"contractL2OutputOracle\",\"name\":\"_l2Oracle\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"_finalizationPeriodSeconds\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"mint\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"gasLimit\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"bool\",\"name\":\"isCreation\",\"type\":\"bool\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"}],\"name\":\"TransactionDeposited\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"withdrawalHash\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"bool\",\"name\":\"success\",\"type\":\"bool\"}],\"name\":\"WithdrawalFinalized\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"BASE_FEE_MAX_CHANGE_DENOMINATOR\",\"outputs\":[{\"internalType\":\"int256\",\"name\":\"\",\"type\":\"int256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"ELASTICITY_MULTIPLIER\",\"outputs\":[{\"internalType\":\"int256\",\"name\":\"\",\"type\":\"int256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"FINALIZATION_PERIOD_SECONDS\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"INITIAL_BASE_FEE\",\"outputs\":[{\"internalType\":\"uint128\",\"name\":\"\",\"type\":\"uint128\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"L2_ORACLE\",\"outputs\":[{\"internalType\":\"contractL2OutputOracle\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"MAX_RESOURCE_LIMIT\",\"outputs\":[{\"internalType\":\"int256\",\"name\":\"\",\"type\":\"int256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"MINIMUM_BASE_FEE\",\"outputs\":[{\"internalType\":\"int256\",\"name\":\"\",\"type\":\"int256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"TARGET_RESOURCE_LIMIT\",\"outputs\":[{\"internalType\":\"int256\",\"name\":\"\",\"type\":\"int256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"_value\",\"type\":\"uint256\"},{\"internalType\":\"uint64\",\"name\":\"_gasLimit\",\"type\":\"uint64\"},{\"internalType\":\"bool\",\"name\":\"_isCreation\",\"type\":\"bool\"},{\"internalType\":\"bytes\",\"name\":\"_data\",\"type\":\"bytes\"}],\"name\":\"depositTransaction\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_nonce\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"_sender\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_target\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"_value\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_gasLimit\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"_data\",\"type\":\"bytes\"},{\"internalType\":\"uint256\",\"name\":\"_l2Timestamp\",\"type\":\"uint256\"},{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"version\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"stateRoot\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"withdrawerStorageRoot\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"latestBlockhash\",\"type\":\"bytes32\"}],\"internalType\":\"structWithdrawalVerifier.OutputRootProof\",\"name\":\"_outputRootProof\",\"type\":\"tuple\"},{\"internalType\":\"bytes\",\"name\":\"_withdrawalProof\",\"type\":\"bytes\"}],\"name\":\"finalizeWithdrawalTransaction\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"name\":\"finalizedWithdrawals\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"l2Sender\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"params\",\"outputs\":[{\"internalType\":\"uint128\",\"name\":\"prevBaseFee\",\"type\":\"uint128\"},{\"internalType\":\"uint64\",\"name\":\"prevBoughtGas\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"prevBlockNum\",\"type\":\"uint64\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"stateMutability\":\"payable\",\"type\":\"receive\"}]", ABI: "[{\"inputs\":[{\"internalType\":\"contractL2OutputOracle\",\"name\":\"_l2Oracle\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"_finalizationPeriodSeconds\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"mint\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"gasLimit\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"bool\",\"name\":\"isCreation\",\"type\":\"bool\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"}],\"name\":\"TransactionDeposited\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"withdrawalHash\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"bool\",\"name\":\"success\",\"type\":\"bool\"}],\"name\":\"WithdrawalFinalized\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"BASE_FEE_MAX_CHANGE_DENOMINATOR\",\"outputs\":[{\"internalType\":\"int256\",\"name\":\"\",\"type\":\"int256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"ELASTICITY_MULTIPLIER\",\"outputs\":[{\"internalType\":\"int256\",\"name\":\"\",\"type\":\"int256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"FINALIZATION_PERIOD_SECONDS\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"INITIAL_BASE_FEE\",\"outputs\":[{\"internalType\":\"uint128\",\"name\":\"\",\"type\":\"uint128\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"L2_ORACLE\",\"outputs\":[{\"internalType\":\"contractL2OutputOracle\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"MAX_RESOURCE_LIMIT\",\"outputs\":[{\"internalType\":\"int256\",\"name\":\"\",\"type\":\"int256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"MINIMUM_BASE_FEE\",\"outputs\":[{\"internalType\":\"int256\",\"name\":\"\",\"type\":\"int256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"TARGET_RESOURCE_LIMIT\",\"outputs\":[{\"internalType\":\"int256\",\"name\":\"\",\"type\":\"int256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"_value\",\"type\":\"uint256\"},{\"internalType\":\"uint64\",\"name\":\"_gasLimit\",\"type\":\"uint64\"},{\"internalType\":\"bool\",\"name\":\"_isCreation\",\"type\":\"bool\"},{\"internalType\":\"bytes\",\"name\":\"_data\",\"type\":\"bytes\"}],\"name\":\"depositTransaction\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_nonce\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"_sender\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_target\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"_value\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_gasLimit\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"_data\",\"type\":\"bytes\"},{\"internalType\":\"uint256\",\"name\":\"_l2BlockNumber\",\"type\":\"uint256\"},{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"version\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"stateRoot\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"withdrawerStorageRoot\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"latestBlockhash\",\"type\":\"bytes32\"}],\"internalType\":\"structWithdrawalVerifier.OutputRootProof\",\"name\":\"_outputRootProof\",\"type\":\"tuple\"},{\"internalType\":\"bytes\",\"name\":\"_withdrawalProof\",\"type\":\"bytes\"}],\"name\":\"finalizeWithdrawalTransaction\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"name\":\"finalizedWithdrawals\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"l2Sender\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"params\",\"outputs\":[{\"internalType\":\"uint128\",\"name\":\"prevBaseFee\",\"type\":\"uint128\"},{\"internalType\":\"uint64\",\"name\":\"prevBoughtGas\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"prevBlockNum\",\"type\":\"uint64\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"stateMutability\":\"payable\",\"type\":\"receive\"}]",
Bin: "0x60c0604052600180546001600160a01b03191661dead1790553480156200002557600080fd5b50604051620035c6380380620035c6833981016040819052620000489162000096565b60408051606081018252633b9aca00808252600060208301819052436001600160401b031692909301829052600160c01b9091021790556001600160a01b0390911660a052608052620000d2565b60008060408385031215620000aa57600080fd5b82516001600160a01b0381168114620000c257600080fd5b6020939093015192949293505050565b60805160a0516134c0620001066000396000818161011301526109ac0152600081816103580152610a2f01526134c06000f3fe6080604052600436106100d55760003560e01c8063a14238e71161007f578063cff0ab9611610059578063cff0ab961461027f578063e9e05c4214610320578063eecf1c3614610333578063f4daa2911461034657600080fd5b8063a14238e714610215578063ca3e99ba14610255578063cd7c97891461026a57600080fd5b80636bb0291e116100b05780636bb0291e146101bd578063867ead13146101d25780639bf62d82146101e857600080fd5b80621c2ff61461010157806313620abd1461015f57806364b792081461019857600080fd5b366100fc576100fa3334620186a060006040518060200160405280600081525061037a565b005b600080fd5b34801561010d57600080fd5b506101357f000000000000000000000000000000000000000000000000000000000000000081565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020015b60405180910390f35b34801561016b57600080fd5b50610177633b9aca0081565b6040516fffffffffffffffffffffffffffffffff9091168152602001610156565b3480156101a457600080fd5b506101af627a120081565b604051908152602001610156565b3480156101c957600080fd5b506101af600481565b3480156101de57600080fd5b506101af61271081565b3480156101f457600080fd5b506001546101359073ffffffffffffffffffffffffffffffffffffffff1681565b34801561022157600080fd5b50610245610230366004612bb8565b60026020526000908152604090205460ff1681565b6040519015158152602001610156565b34801561026157600080fd5b506101af61081a565b34801561027657600080fd5b506101af600881565b34801561028b57600080fd5b506000546102e7906fffffffffffffffffffffffffffffffff81169067ffffffffffffffff7001000000000000000000000000000000008204811691780100000000000000000000000000000000000000000000000090041683565b604080516fffffffffffffffffffffffffffffffff909416845267ffffffffffffffff9283166020850152911690820152606001610156565b6100fa61032e366004612c78565b61037a565b6100fa610341366004612dc2565b61082b565b34801561035257600080fd5b506101af7f000000000000000000000000000000000000000000000000000000000000000081565b8260005a905083156104315773ffffffffffffffffffffffffffffffffffffffff87161561043157604080517f08c379a00000000000000000000000000000000000000000000000000000000081526020600482015260248101919091527f4f7074696d69736d506f7274616c3a206d7573742073656e6420746f2061646460448201527f72657373283029207768656e206372656174696e67206120636f6e747261637460648201526084015b60405180910390fd5b33328114610452575033731111000000000000000000000000000000001111015b8773ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f78231ae6eb73366f912bb1d64351601fb76344c537bbab635ce14d0f376f0195348a8a8a8a6040516104b7959493929190612f2d565b60405180910390a350600080546104f4907801000000000000000000000000000000000000000000000000900467ffffffffffffffff1643612f93565b9050801561067c57600061050c6004627a1200612fd9565b6000546105379190700100000000000000000000000000000000900467ffffffffffffffff16613041565b90506000600861054b6004627a1200612fd9565b60005461056b9085906fffffffffffffffffffffffffffffffff166130b5565b6105759190612fd9565b61057f9190612fd9565b60008054919250906105ca906105b4906105ac9085906fffffffffffffffffffffffffffffffff16613171565b612710610f22565b6fffffffffffffffffffffffffffffffff610f3d565b9050600184111561063d5761063a6105b4670de0b6b3a76400006106266105f2600883612fd9565b61060490670de0b6b3a7640000613041565b61060f60018a612f93565b61062190670de0b6b3a76400006131e5565b610f4c565b61063090856130b5565b6105ac9190612fd9565b90505b6fffffffffffffffffffffffffffffffff16780100000000000000000000000000000000000000000000000067ffffffffffffffff4316021760005550505b600080548491906010906106af908490700100000000000000000000000000000000900467ffffffffffffffff16613222565b92506101000a81548167ffffffffffffffff021916908367ffffffffffffffff160217905550627a12006000800160109054906101000a900467ffffffffffffffff1667ffffffffffffffff16131561078a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603c60248201527f4f7074696d69736d506f7274616c3a2063616e6e6f7420627579206d6f72652060448201527f676173207468616e20617661696c61626c6520676173206c696d6974000000006064820152608401610428565b600080546107b4906fffffffffffffffffffffffffffffffff1667ffffffffffffffff861661324e565b6fffffffffffffffffffffffffffffffff16905060006107d848633b9aca00610f7d565b6107e29083613286565b905060005a6107f19086612f93565b90508082111561080d5761080d6108088284612f93565b610f8d565b5050505050505050505050565b6108286004627a1200612fd9565b81565b60015473ffffffffffffffffffffffffffffffffffffffff1661dead146108d4576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603f60248201527f4f7074696d69736d506f7274616c3a2063616e206f6e6c79207472696767657260448201527f206f6e65207769746864726177616c20706572207472616e73616374696f6e006064820152608401610428565b73ffffffffffffffffffffffffffffffffffffffff891630141561097a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603f60248201527f4f7074696d69736d506f7274616c3a20796f752063616e6e6f742073656e642060448201527f6d6573736167657320746f2074686520706f7274616c20636f6e7472616374006064820152608401610428565b6040517fa25ae557000000000000000000000000000000000000000000000000000000008152600481018590526000907f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff169063a25ae557906024016040805180830381865afa158015610a07573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a2b919061329a565b90507f00000000000000000000000000000000000000000000000000000000000000008160200151610a5d91906132e9565b4211610aeb576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602d60248201527f4f7074696d69736d506f7274616c3a2070726f706f73616c206973206e6f742060448201527f7965742066696e616c697a6564000000000000000000000000000000000000006064820152608401610428565b610b02610afd36869003860186613301565b610fbb565b815114610b91576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602960248201527f4f7074696d69736d506f7274616c3a20696e76616c6964206f7574707574207260448201527f6f6f742070726f6f6600000000000000000000000000000000000000000000006064820152608401610428565b6000610bd78d8d8d8d8d8d8d8080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061101792505050565b9050610c1e81866040013586868080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061105692505050565b610caa576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603260248201527f4f7074696d69736d506f7274616c3a20696e76616c696420776974686472617760448201527f616c20696e636c7573696f6e2070726f6f6600000000000000000000000000006064820152608401610428565b60008181526002602052604090205460ff1615610d49576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603560248201527f4f7074696d69736d506f7274616c3a207769746864726177616c20686173206160448201527f6c7265616479206265656e2066696e616c697a656400000000000000000000006064820152608401610428565b600081815260026020526040902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001179055610d8c614e208a6132e9565b5a1015610e1b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603760248201527f4f7074696d69736d506f7274616c3a20696e73756666696369656e742067617360448201527f20746f2066696e616c697a65207769746864726177616c0000000000000000006064820152608401610428565b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff8e16179055604080516020601f8a01819004810282018101909252888152600091610ea4918e918d918f918691908f908f908190840183828082843760009201919091525061111f92505050565b50600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001661dead17905560405190915082907fdb5c7652857aa163daadd670e116628fb42e869d8ac4251ef8971d9e5727df1b90610f0a90841515815260200190565b60405180910390a25050505050505050505050505050565b600081831215610f325781610f34565b825b90505b92915050565b6000818312610f325781610f34565b6000610f34670de0b6b3a764000083610f64866111aa565b610f6e91906130b5565b610f789190612fd9565b6113ee565b600081831015610f325781610f34565b6000805a90505b825a610fa09083612f93565b1015610fb657610faf82613367565b9150610f94565b505050565b60008160000151826020015183604001518460600151604051602001610ffa949392919093845260208401929092526040830152606082015260800190565b604051602081830303815290604052805190602001209050919050565b6000868686868686604051602001611034969594939291906133a0565b6040516020818303038152906040528051906020012090509695505050505050565b604080516020810185905260009181018290528190606001604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0818403018152828252805160209182012090830181905292506111149101604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0818403018152828201909152600182527f0100000000000000000000000000000000000000000000000000000000000000602083015290858761162d565b9150505b9392505050565b6000606060008060008661ffff1667ffffffffffffffff81111561114557611145612bfa565b6040519080825280601f01601f19166020018201604052801561116f576020820181803683370190505b5090506000808751602089018b8e8ef191503d925086831115611190578692505b828152826000602083013e90999098509650505050505050565b6000808213611215576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600960248201527f554e444546494e454400000000000000000000000000000000000000000000006044820152606401610428565b6000606061122284611651565b03609f8181039490941b90931c6c465772b2bbbb5f824b15207a3081018102606090811d6d0388eaa27412d5aca026815d636e018202811d6d0df99ac502031bf953eff472fdcc018202811d6d13cdffb29d51d99322bdff5f2211018202811d6d0a0f742023def783a307a986912e018202811d6d01920d8043ca89b5239253284e42018202811d6c0b7a86d7375468fac667a0a527016c29508e458543d8aa4df2abee7883018302821d6d0139601a2efabe717e604cbb4894018302821d6d02247f7a7b6594320649aa03aba1018302821d7fffffffffffffffffffffffffffffffffffffff73c0c716a594e00d54e3c4cbc9018302821d7ffffffffffffffffffffffffffffffffffffffdc7b88c420e53a9890533129f6f01830290911d7fffffffffffffffffffffffffffffffffffffff465fda27eb4d63ded474e5f832019091027ffffffffffffffff5f6af8f7b3396644f18e157960000000000000000000000000105711340daa0d5f769dba1915cef59f0815a5506027d0267a36c0c95b3975ab3ee5b203a7614a3f75373f047d803ae7b6687f2b393909302929092017d57115e47018c7177eebf7cd370a3356a1b7863008a5ae8028c72b88642840160ae1d92915050565b60007ffffffffffffffffffffffffffffffffffffffffffffffffdb731c958f34d94c1821361141f57506000919050565b680755bf798b4a1bf1e58212611491576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600c60248201527f4558505f4f564552464c4f5700000000000000000000000000000000000000006044820152606401610428565b6503782dace9d9604e83901b059150600060606bb17217f7d1cf79abc9e3b39884821b056b80000000000000000000000001901d6bb17217f7d1cf79abc9e3b39881029093037fffffffffffffffffffffffffffffffffffffffdbf3ccf1604d263450f02a550481018102606090811d6d0277594991cfc85f6e2461837cd9018202811d7fffffffffffffffffffffffffffffffffffffe5adedaa1cb095af9e4da10e363c018202811d6db1bbb201f443cf962f1a1d3db4a5018202811d7ffffffffffffffffffffffffffffffffffffd38dc772608b0ae56cce01296c0eb018202811d6e05180bb14799ab47a8a8cb2a527d57016d02d16720577bd19bf614176fe9ea6c10fe68e7fd37d0007b713f765084018402831d9081019084017ffffffffffffffffffffffffffffffffffffffe2c69812cf03b0763fd454a8f7e010290911d6e0587f503bb6ea29d25fcb7401964500190910279d835ebba824c98fb31b83b2ca45c000000000000000000000000010574029d9dc38563c32e5c2f6dc192ee70ef65f9978af30260c3939093039290921c92915050565b60008061163986611727565b905061164781868686611759565b9695505050505050565b60008082116116bc576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600960248201527f554e444546494e454400000000000000000000000000000000000000000000006044820152606401610428565b5060016fffffffffffffffffffffffffffffffff821160071b82811c67ffffffffffffffff1060061b1782811c63ffffffff1060051b1782811c61ffff1060041b1782811c60ff10600390811b90911783811c600f1060021b1783811c909110821b1791821c111790565b6060818051906020012060405160200161174391815260200190565b6040516020818303038152906040529050919050565b6000806000611769878686611796565b9150915081801561178b57508051602080830191909120875191880191909120145b979650505050505050565b6000606060006117a58561188b565b905060008060006117b7848a89611986565b815192955090935091501580806117cb5750815b611831576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601a60248201527f50726f76696465642070726f6f6620697320696e76616c69642e0000000000006044820152606401610428565b60008161184d5760405180602001604052806000815250611879565b6118798661185c600188612f93565b8151811061186c5761186c6133f7565b6020026020010151611ea3565b919b919a509098505050505050505050565b6060600061189883611ecd565b90506000815167ffffffffffffffff8111156118b6576118b6612bfa565b6040519080825280602002602001820160405280156118fb57816020015b60408051808201909152606080825260208201528152602001906001900390816118d45790505b50905060005b825181101561197e57600061192e848381518110611921576119216133f7565b6020026020010151611f00565b9050604051806040016040528082815260200161194a83611ecd565b81525083838151811061195f5761195f6133f7565b602002602001018190525050808061197690613367565b915050611901565b509392505050565b6000606081808061199687611faa565b905060008690506000806119bd604051806040016040528060608152602001606081525090565b60005b8c51811015611e5f578c81815181106119db576119db6133f7565b6020026020010151915082846119f191906132e9565b93506119fe6001886132e9565b965083611a7c57815180516020909101208514611a77576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601160248201527f496e76616c696420726f6f7420686173680000000000000000000000000000006044820152606401610428565b611b6d565b815151602011611af857815180516020909101208514611a77576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601b60248201527f496e76616c6964206c6172676520696e7465726e616c206861736800000000006044820152606401610428565b84611b06836000015161212d565b14611b6d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601a60248201527f496e76616c696420696e7465726e616c206e6f646520686173680000000000006044820152606401610428565b611b79601060016132e9565b8260200151511415611bf2578551841415611b9357611e5f565b6000868581518110611ba757611ba76133f7565b602001015160f81c60f81b60f81c9050600083602001518260ff1681518110611bd257611bd26133f7565b60200260200101519050611be581612155565b9650600194505050611e4d565b60028260200151511415611deb576000611c0b8361218b565b9050600081600081518110611c2257611c226133f7565b016020015160f81c90506000611c39600283613426565b611c44906002613448565b90506000611c55848360ff166121af565b90506000611c638b8a6121af565b90506000611c7183836121e5565b905060ff851660021480611c88575060ff85166003145b15611cde57808351148015611c9d5750808251145b15611caf57611cac818b6132e9565b99505b507f80000000000000000000000000000000000000000000000000000000000000009950611e5f945050505050565b60ff85161580611cf1575060ff85166001145b15611d635782518114611d2d57507f80000000000000000000000000000000000000000000000000000000000000009950611e5f945050505050565b611d548860200151600181518110611d4757611d476133f7565b6020026020010151612155565b9a509750611e4d945050505050565b6040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f52656365697665642061206e6f6465207769746820616e20756e6b6e6f776e2060448201527f70726566697800000000000000000000000000000000000000000000000000006064820152608401610428565b6040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f526563656976656420616e20756e706172736561626c65206e6f64652e0000006044820152606401610428565b80611e5781613367565b9150506119c0565b507f8000000000000000000000000000000000000000000000000000000000000000841486611e8e87866121af565b909e909d50909b509950505050505050505050565b60208101518051606091610f3791611ebd90600190612f93565b81518110611921576119216133f7565b604080518082018252600080825260209182015281518083019092528251825280830190820152606090610f3790612291565b60606000806000611f10856124c4565b919450925090506000816001811115611f2b57611f2b61346b565b14611f92576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601860248201527f496e76616c696420524c502062797465732076616c75652e00000000000000006044820152606401610428565b611fa1856020015184846128cb565b95945050505050565b6060600082516002611fbc91906131e5565b67ffffffffffffffff811115611fd457611fd4612bfa565b6040519080825280601f01601f191660200182016040528015611ffe576020820181803683370190505b50905060005b8351811015612126576004848281518110612021576120216133f7565b01602001517fff0000000000000000000000000000000000000000000000000000000000000016901c826120568360026131e5565b81518110612066576120666133f7565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a90535060108482815181106120a9576120a96133f7565b01602001516120bb919060f81c613426565b60f81b826120ca8360026131e5565b6120d59060016132e9565b815181106120e5576120e56133f7565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053508061211e81613367565b915050612004565b5092915050565b600060208251101561214157506020015190565b81806020019051810190610f37919061349a565b600060606020836000015110156121765761216f836129aa565b9050612182565b61217f83611f00565b90505b6111188161212d565b6060610f376121aa8360200151600081518110611921576119216133f7565b611faa565b6060825182106121ce5750604080516020810190915260008152610f37565b610f3483838486516121e09190612f93565b6129b5565b6000805b8084511180156121f95750808351115b801561227a5750828181518110612212576122126133f7565b602001015160f81c60f81b7effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916848281518110612251576122516133f7565b01602001517fff0000000000000000000000000000000000000000000000000000000000000016145b15610f34578061228981613367565b9150506121e9565b606060008061229f846124c4565b919350909150600190508160018111156122bb576122bb61346b565b14612322576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f496e76616c696420524c50206c6973742076616c75652e0000000000000000006044820152606401610428565b6040805160208082526104208201909252600091816020015b604080518082019091526000808252602082015281526020019060019003908161233b5790505090506000835b86518110156124b95760208210612401576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f50726f766964656420524c50206c6973742065786365656473206d6178206c6960448201527f7374206c656e6774682e000000000000000000000000000000000000000000006064820152608401610428565b60008061243e6040518060400160405280858c600001516124229190612f93565b8152602001858c6020015161243791906132e9565b90526124c4565b50915091506040518060400160405280838361245a91906132e9565b8152602001848b6020015161246f91906132e9565b815250858581518110612484576124846133f7565b602090810291909101015261249a6001856132e9565b93506124a681836132e9565b6124b090846132e9565b92505050612368565b508152949350505050565b600080600080846000015111612536576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601860248201527f524c50206974656d2063616e6e6f74206265206e756c6c2e00000000000000006044820152606401610428565b6020840151805160001a607f811161255b5760006001600094509450945050506128c4565b60b781116125f1576000612570608083612f93565b9050808760000151116125df576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601960248201527f496e76616c696420524c502073686f727420737472696e672e000000000000006044820152606401610428565b600195509350600092506128c4915050565b60bf811161271457600061260660b783612f93565b905080876000015111612675576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601f60248201527f496e76616c696420524c50206c6f6e6720737472696e67206c656e6774682e006044820152606401610428565b600183015160208290036101000a900461268f81836132e9565b8851116126f8576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601860248201527f496e76616c696420524c50206c6f6e6720737472696e672e00000000000000006044820152606401610428565b6127038260016132e9565b96509450600093506128c492505050565b60f781116127a957600061272960c083612f93565b905080876000015111612798576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f496e76616c696420524c502073686f7274206c6973742e0000000000000000006044820152606401610428565b6001955093508492506128c4915050565b60006127b660f783612f93565b905080876000015111612825576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f496e76616c696420524c50206c6f6e67206c697374206c656e6774682e0000006044820152606401610428565b600183015160208290036101000a900461283f81836132e9565b8851116128a8576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f496e76616c696420524c50206c6f6e67206c6973742e000000000000000000006044820152606401610428565b6128b38260016132e9565b96509450600193506128c492505050565b9193909250565b606060008267ffffffffffffffff8111156128e8576128e8612bfa565b6040519080825280601f01601f191660200182016040528015612912576020820181803683370190505b509050805160001415612926579050611118565b600061293285876132e9565b90506020820160005b612946602087613286565b81101561297d578251825261295c6020846132e9565b92506129696020836132e9565b91508061297581613367565b91505061293b565b5060006001602087066020036101000a039050808251168119845116178252839450505050509392505050565b6060610f3782612ba2565b6060816129c381601f6132e9565b1015612a2b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600e60248201527f736c6963655f6f766572666c6f770000000000000000000000000000000000006044820152606401610428565b82612a3683826132e9565b1015612a9e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600e60248201527f736c6963655f6f766572666c6f770000000000000000000000000000000000006044820152606401610428565b612aa882846132e9565b84511015612b12576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601160248201527f736c6963655f6f75744f66426f756e64730000000000000000000000000000006044820152606401610428565b606082158015612b315760405191506000825260208201604052612b99565b6040519150601f8416801560200281840101858101878315602002848b0101015b81831015612b6a578051835260209283019201612b52565b5050858452601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016604052505b50949350505050565b6060610f378260200151600084600001516128cb565b600060208284031215612bca57600080fd5b5035919050565b803573ffffffffffffffffffffffffffffffffffffffff81168114612bf557600080fd5b919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff81118282101715612c7057612c70612bfa565b604052919050565b600080600080600060a08688031215612c9057600080fd5b612c9986612bd1565b94506020808701359450604087013567ffffffffffffffff8082168214612cbf57600080fd5b9094506060880135908115158214612cd657600080fd5b90935060808801359080821115612cec57600080fd5b818901915089601f830112612d0057600080fd5b813581811115612d1257612d12612bfa565b612d42847fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f84011601612c29565b91508082528a84828501011115612d5857600080fd5b80848401858401376000848284010152508093505050509295509295909350565b60008083601f840112612d8b57600080fd5b50813567ffffffffffffffff811115612da357600080fd5b602083019150836020828501011115612dbb57600080fd5b9250929050565b60008060008060008060008060008060006101808c8e031215612de457600080fd5b8b359a50612df460208d01612bd1565b9950612e0260408d01612bd1565b985060608c0135975060808c0135965067ffffffffffffffff60a08d01351115612e2b57600080fd5b612e3b8d60a08e01358e01612d79565b909650945060c08c0135935060808c8e037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff20011215612e7957600080fd5b60e08c01925067ffffffffffffffff6101608d01351115612e9957600080fd5b612eaa8d6101608e01358e01612d79565b81935080925050509295989b509295989b9093969950565b6000815180845260005b81811015612ee857602081850181015186830182015201612ecc565b81811115612efa576000602083870101525b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b85815284602082015267ffffffffffffffff84166040820152821515606082015260a06080820152600061178b60a0830184612ec2565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b600082821015612fa557612fa5612f64565b500390565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b600082612fe857612fe8612faa565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff83147f80000000000000000000000000000000000000000000000000000000000000008314161561303c5761303c612f64565b500590565b6000808312837f80000000000000000000000000000000000000000000000000000000000000000183128115161561307b5761307b612f64565b837f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0183138116156130af576130af612f64565b50500390565b60007f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff6000841360008413858304851182821616156130f6576130f6612f64565b7f8000000000000000000000000000000000000000000000000000000000000000600087128682058812818416161561313157613131612f64565b6000871292508782058712848416161561314d5761314d612f64565b8785058712818416161561316357613163612f64565b505050929093029392505050565b6000808212827f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff038413811516156131ab576131ab612f64565b827f80000000000000000000000000000000000000000000000000000000000000000384128116156131df576131df612f64565b50500190565b6000817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff048311821515161561321d5761321d612f64565b500290565b600067ffffffffffffffff80831681851680830382111561324557613245612f64565b01949350505050565b60006fffffffffffffffffffffffffffffffff8083168185168183048111821515161561327d5761327d612f64565b02949350505050565b60008261329557613295612faa565b500490565b6000604082840312156132ac57600080fd5b6040516040810181811067ffffffffffffffff821117156132cf576132cf612bfa565b604052825181526020928301519281019290925250919050565b600082198211156132fc576132fc612f64565b500190565b60006080828403121561331357600080fd5b6040516080810181811067ffffffffffffffff8211171561333657613336612bfa565b8060405250823581526020830135602082015260408301356040820152606083013560608201528091505092915050565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82141561339957613399612f64565b5060010190565b868152600073ffffffffffffffffffffffffffffffffffffffff808816602084015280871660408401525084606083015283608083015260c060a08301526133eb60c0830184612ec2565b98975050505050505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b600060ff83168061343957613439612faa565b8060ff84160691505092915050565b600060ff821660ff84168082101561346257613462612f64565b90039392505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b6000602082840312156134ac57600080fd5b505191905056fea164736f6c634300080a000a", Bin: "0x60c0604052600180546001600160a01b03191661dead1790553480156200002557600080fd5b50604051620035c6380380620035c6833981016040819052620000489162000096565b60408051606081018252633b9aca00808252600060208301819052436001600160401b031692909301829052600160c01b9091021790556001600160a01b0390911660a052608052620000d2565b60008060408385031215620000aa57600080fd5b82516001600160a01b0381168114620000c257600080fd5b6020939093015192949293505050565b60805160a0516134c0620001066000396000818161011301526109ac0152600081816103580152610a2f01526134c06000f3fe6080604052600436106100d55760003560e01c8063a14238e71161007f578063cff0ab9611610059578063cff0ab961461027f578063e9e05c4214610320578063eecf1c3614610333578063f4daa2911461034657600080fd5b8063a14238e714610215578063ca3e99ba14610255578063cd7c97891461026a57600080fd5b80636bb0291e116100b05780636bb0291e146101bd578063867ead13146101d25780639bf62d82146101e857600080fd5b80621c2ff61461010157806313620abd1461015f57806364b792081461019857600080fd5b366100fc576100fa3334620186a060006040518060200160405280600081525061037a565b005b600080fd5b34801561010d57600080fd5b506101357f000000000000000000000000000000000000000000000000000000000000000081565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020015b60405180910390f35b34801561016b57600080fd5b50610177633b9aca0081565b6040516fffffffffffffffffffffffffffffffff9091168152602001610156565b3480156101a457600080fd5b506101af627a120081565b604051908152602001610156565b3480156101c957600080fd5b506101af600481565b3480156101de57600080fd5b506101af61271081565b3480156101f457600080fd5b506001546101359073ffffffffffffffffffffffffffffffffffffffff1681565b34801561022157600080fd5b50610245610230366004612bb8565b60026020526000908152604090205460ff1681565b6040519015158152602001610156565b34801561026157600080fd5b506101af61081a565b34801561027657600080fd5b506101af600881565b34801561028b57600080fd5b506000546102e7906fffffffffffffffffffffffffffffffff81169067ffffffffffffffff7001000000000000000000000000000000008204811691780100000000000000000000000000000000000000000000000090041683565b604080516fffffffffffffffffffffffffffffffff909416845267ffffffffffffffff9283166020850152911690820152606001610156565b6100fa61032e366004612c78565b61037a565b6100fa610341366004612dc2565b61082b565b34801561035257600080fd5b506101af7f000000000000000000000000000000000000000000000000000000000000000081565b8260005a905083156104315773ffffffffffffffffffffffffffffffffffffffff87161561043157604080517f08c379a00000000000000000000000000000000000000000000000000000000081526020600482015260248101919091527f4f7074696d69736d506f7274616c3a206d7573742073656e6420746f2061646460448201527f72657373283029207768656e206372656174696e67206120636f6e747261637460648201526084015b60405180910390fd5b33328114610452575033731111000000000000000000000000000000001111015b8773ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f78231ae6eb73366f912bb1d64351601fb76344c537bbab635ce14d0f376f0195348a8a8a8a6040516104b7959493929190612f2d565b60405180910390a350600080546104f4907801000000000000000000000000000000000000000000000000900467ffffffffffffffff1643612f93565b9050801561067c57600061050c6004627a1200612fd9565b6000546105379190700100000000000000000000000000000000900467ffffffffffffffff16613041565b90506000600861054b6004627a1200612fd9565b60005461056b9085906fffffffffffffffffffffffffffffffff166130b5565b6105759190612fd9565b61057f9190612fd9565b60008054919250906105ca906105b4906105ac9085906fffffffffffffffffffffffffffffffff16613171565b612710610f22565b6fffffffffffffffffffffffffffffffff610f3d565b9050600184111561063d5761063a6105b4670de0b6b3a76400006106266105f2600883612fd9565b61060490670de0b6b3a7640000613041565b61060f60018a612f93565b61062190670de0b6b3a76400006131e5565b610f4c565b61063090856130b5565b6105ac9190612fd9565b90505b6fffffffffffffffffffffffffffffffff16780100000000000000000000000000000000000000000000000067ffffffffffffffff4316021760005550505b600080548491906010906106af908490700100000000000000000000000000000000900467ffffffffffffffff16613222565b92506101000a81548167ffffffffffffffff021916908367ffffffffffffffff160217905550627a12006000800160109054906101000a900467ffffffffffffffff1667ffffffffffffffff16131561078a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603c60248201527f4f7074696d69736d506f7274616c3a2063616e6e6f7420627579206d6f72652060448201527f676173207468616e20617661696c61626c6520676173206c696d6974000000006064820152608401610428565b600080546107b4906fffffffffffffffffffffffffffffffff1667ffffffffffffffff861661324e565b6fffffffffffffffffffffffffffffffff16905060006107d848633b9aca00610f7d565b6107e29083613286565b905060005a6107f19086612f93565b90508082111561080d5761080d6108088284612f93565b610f8d565b5050505050505050505050565b6108286004627a1200612fd9565b81565b60015473ffffffffffffffffffffffffffffffffffffffff1661dead146108d4576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603f60248201527f4f7074696d69736d506f7274616c3a2063616e206f6e6c79207472696767657260448201527f206f6e65207769746864726177616c20706572207472616e73616374696f6e006064820152608401610428565b73ffffffffffffffffffffffffffffffffffffffff891630141561097a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603f60248201527f4f7074696d69736d506f7274616c3a20796f752063616e6e6f742073656e642060448201527f6d6573736167657320746f2074686520706f7274616c20636f6e7472616374006064820152608401610428565b6040517fa25ae557000000000000000000000000000000000000000000000000000000008152600481018590526000907f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff169063a25ae557906024016040805180830381865afa158015610a07573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a2b919061329a565b90507f00000000000000000000000000000000000000000000000000000000000000008160200151610a5d91906132e9565b4211610aeb576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602d60248201527f4f7074696d69736d506f7274616c3a2070726f706f73616c206973206e6f742060448201527f7965742066696e616c697a6564000000000000000000000000000000000000006064820152608401610428565b610b02610afd36869003860186613301565b610fbb565b815114610b91576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602960248201527f4f7074696d69736d506f7274616c3a20696e76616c6964206f7574707574207260448201527f6f6f742070726f6f6600000000000000000000000000000000000000000000006064820152608401610428565b6000610bd78d8d8d8d8d8d8d8080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061101792505050565b9050610c1e81866040013586868080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061105692505050565b610caa576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603260248201527f4f7074696d69736d506f7274616c3a20696e76616c696420776974686472617760448201527f616c20696e636c7573696f6e2070726f6f6600000000000000000000000000006064820152608401610428565b60008181526002602052604090205460ff1615610d49576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603560248201527f4f7074696d69736d506f7274616c3a207769746864726177616c20686173206160448201527f6c7265616479206265656e2066696e616c697a656400000000000000000000006064820152608401610428565b600081815260026020526040902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001179055610d8c614e208a6132e9565b5a1015610e1b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603760248201527f4f7074696d69736d506f7274616c3a20696e73756666696369656e742067617360448201527f20746f2066696e616c697a65207769746864726177616c0000000000000000006064820152608401610428565b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff8e16179055604080516020601f8a01819004810282018101909252888152600091610ea4918e918d918f918691908f908f908190840183828082843760009201919091525061111f92505050565b50600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001661dead17905560405190915082907fdb5c7652857aa163daadd670e116628fb42e869d8ac4251ef8971d9e5727df1b90610f0a90841515815260200190565b60405180910390a25050505050505050505050505050565b600081831215610f325781610f34565b825b90505b92915050565b6000818312610f325781610f34565b6000610f34670de0b6b3a764000083610f64866111aa565b610f6e91906130b5565b610f789190612fd9565b6113ee565b600081831015610f325781610f34565b6000805a90505b825a610fa09083612f93565b1015610fb657610faf82613367565b9150610f94565b505050565b60008160000151826020015183604001518460600151604051602001610ffa949392919093845260208401929092526040830152606082015260800190565b604051602081830303815290604052805190602001209050919050565b6000868686868686604051602001611034969594939291906133a0565b6040516020818303038152906040528051906020012090509695505050505050565b604080516020810185905260009181018290528190606001604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0818403018152828252805160209182012090830181905292506111149101604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0818403018152828201909152600182527f0100000000000000000000000000000000000000000000000000000000000000602083015290858761162d565b9150505b9392505050565b6000606060008060008661ffff1667ffffffffffffffff81111561114557611145612bfa565b6040519080825280601f01601f19166020018201604052801561116f576020820181803683370190505b5090506000808751602089018b8e8ef191503d925086831115611190578692505b828152826000602083013e90999098509650505050505050565b6000808213611215576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600960248201527f554e444546494e454400000000000000000000000000000000000000000000006044820152606401610428565b6000606061122284611651565b03609f8181039490941b90931c6c465772b2bbbb5f824b15207a3081018102606090811d6d0388eaa27412d5aca026815d636e018202811d6d0df99ac502031bf953eff472fdcc018202811d6d13cdffb29d51d99322bdff5f2211018202811d6d0a0f742023def783a307a986912e018202811d6d01920d8043ca89b5239253284e42018202811d6c0b7a86d7375468fac667a0a527016c29508e458543d8aa4df2abee7883018302821d6d0139601a2efabe717e604cbb4894018302821d6d02247f7a7b6594320649aa03aba1018302821d7fffffffffffffffffffffffffffffffffffffff73c0c716a594e00d54e3c4cbc9018302821d7ffffffffffffffffffffffffffffffffffffffdc7b88c420e53a9890533129f6f01830290911d7fffffffffffffffffffffffffffffffffffffff465fda27eb4d63ded474e5f832019091027ffffffffffffffff5f6af8f7b3396644f18e157960000000000000000000000000105711340daa0d5f769dba1915cef59f0815a5506027d0267a36c0c95b3975ab3ee5b203a7614a3f75373f047d803ae7b6687f2b393909302929092017d57115e47018c7177eebf7cd370a3356a1b7863008a5ae8028c72b88642840160ae1d92915050565b60007ffffffffffffffffffffffffffffffffffffffffffffffffdb731c958f34d94c1821361141f57506000919050565b680755bf798b4a1bf1e58212611491576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600c60248201527f4558505f4f564552464c4f5700000000000000000000000000000000000000006044820152606401610428565b6503782dace9d9604e83901b059150600060606bb17217f7d1cf79abc9e3b39884821b056b80000000000000000000000001901d6bb17217f7d1cf79abc9e3b39881029093037fffffffffffffffffffffffffffffffffffffffdbf3ccf1604d263450f02a550481018102606090811d6d0277594991cfc85f6e2461837cd9018202811d7fffffffffffffffffffffffffffffffffffffe5adedaa1cb095af9e4da10e363c018202811d6db1bbb201f443cf962f1a1d3db4a5018202811d7ffffffffffffffffffffffffffffffffffffd38dc772608b0ae56cce01296c0eb018202811d6e05180bb14799ab47a8a8cb2a527d57016d02d16720577bd19bf614176fe9ea6c10fe68e7fd37d0007b713f765084018402831d9081019084017ffffffffffffffffffffffffffffffffffffffe2c69812cf03b0763fd454a8f7e010290911d6e0587f503bb6ea29d25fcb7401964500190910279d835ebba824c98fb31b83b2ca45c000000000000000000000000010574029d9dc38563c32e5c2f6dc192ee70ef65f9978af30260c3939093039290921c92915050565b60008061163986611727565b905061164781868686611759565b9695505050505050565b60008082116116bc576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600960248201527f554e444546494e454400000000000000000000000000000000000000000000006044820152606401610428565b5060016fffffffffffffffffffffffffffffffff821160071b82811c67ffffffffffffffff1060061b1782811c63ffffffff1060051b1782811c61ffff1060041b1782811c60ff10600390811b90911783811c600f1060021b1783811c909110821b1791821c111790565b6060818051906020012060405160200161174391815260200190565b6040516020818303038152906040529050919050565b6000806000611769878686611796565b9150915081801561178b57508051602080830191909120875191880191909120145b979650505050505050565b6000606060006117a58561188b565b905060008060006117b7848a89611986565b815192955090935091501580806117cb5750815b611831576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601a60248201527f50726f76696465642070726f6f6620697320696e76616c69642e0000000000006044820152606401610428565b60008161184d5760405180602001604052806000815250611879565b6118798661185c600188612f93565b8151811061186c5761186c6133f7565b6020026020010151611ea3565b919b919a509098505050505050505050565b6060600061189883611ecd565b90506000815167ffffffffffffffff8111156118b6576118b6612bfa565b6040519080825280602002602001820160405280156118fb57816020015b60408051808201909152606080825260208201528152602001906001900390816118d45790505b50905060005b825181101561197e57600061192e848381518110611921576119216133f7565b6020026020010151611f00565b9050604051806040016040528082815260200161194a83611ecd565b81525083838151811061195f5761195f6133f7565b602002602001018190525050808061197690613367565b915050611901565b509392505050565b6000606081808061199687611faa565b905060008690506000806119bd604051806040016040528060608152602001606081525090565b60005b8c51811015611e5f578c81815181106119db576119db6133f7565b6020026020010151915082846119f191906132e9565b93506119fe6001886132e9565b965083611a7c57815180516020909101208514611a77576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601160248201527f496e76616c696420726f6f7420686173680000000000000000000000000000006044820152606401610428565b611b6d565b815151602011611af857815180516020909101208514611a77576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601b60248201527f496e76616c6964206c6172676520696e7465726e616c206861736800000000006044820152606401610428565b84611b06836000015161212d565b14611b6d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601a60248201527f496e76616c696420696e7465726e616c206e6f646520686173680000000000006044820152606401610428565b611b79601060016132e9565b8260200151511415611bf2578551841415611b9357611e5f565b6000868581518110611ba757611ba76133f7565b602001015160f81c60f81b60f81c9050600083602001518260ff1681518110611bd257611bd26133f7565b60200260200101519050611be581612155565b9650600194505050611e4d565b60028260200151511415611deb576000611c0b8361218b565b9050600081600081518110611c2257611c226133f7565b016020015160f81c90506000611c39600283613426565b611c44906002613448565b90506000611c55848360ff166121af565b90506000611c638b8a6121af565b90506000611c7183836121e5565b905060ff851660021480611c88575060ff85166003145b15611cde57808351148015611c9d5750808251145b15611caf57611cac818b6132e9565b99505b507f80000000000000000000000000000000000000000000000000000000000000009950611e5f945050505050565b60ff85161580611cf1575060ff85166001145b15611d635782518114611d2d57507f80000000000000000000000000000000000000000000000000000000000000009950611e5f945050505050565b611d548860200151600181518110611d4757611d476133f7565b6020026020010151612155565b9a509750611e4d945050505050565b6040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f52656365697665642061206e6f6465207769746820616e20756e6b6e6f776e2060448201527f70726566697800000000000000000000000000000000000000000000000000006064820152608401610428565b6040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f526563656976656420616e20756e706172736561626c65206e6f64652e0000006044820152606401610428565b80611e5781613367565b9150506119c0565b507f8000000000000000000000000000000000000000000000000000000000000000841486611e8e87866121af565b909e909d50909b509950505050505050505050565b60208101518051606091610f3791611ebd90600190612f93565b81518110611921576119216133f7565b604080518082018252600080825260209182015281518083019092528251825280830190820152606090610f3790612291565b60606000806000611f10856124c4565b919450925090506000816001811115611f2b57611f2b61346b565b14611f92576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601860248201527f496e76616c696420524c502062797465732076616c75652e00000000000000006044820152606401610428565b611fa1856020015184846128cb565b95945050505050565b6060600082516002611fbc91906131e5565b67ffffffffffffffff811115611fd457611fd4612bfa565b6040519080825280601f01601f191660200182016040528015611ffe576020820181803683370190505b50905060005b8351811015612126576004848281518110612021576120216133f7565b01602001517fff0000000000000000000000000000000000000000000000000000000000000016901c826120568360026131e5565b81518110612066576120666133f7565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a90535060108482815181106120a9576120a96133f7565b01602001516120bb919060f81c613426565b60f81b826120ca8360026131e5565b6120d59060016132e9565b815181106120e5576120e56133f7565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053508061211e81613367565b915050612004565b5092915050565b600060208251101561214157506020015190565b81806020019051810190610f37919061349a565b600060606020836000015110156121765761216f836129aa565b9050612182565b61217f83611f00565b90505b6111188161212d565b6060610f376121aa8360200151600081518110611921576119216133f7565b611faa565b6060825182106121ce5750604080516020810190915260008152610f37565b610f3483838486516121e09190612f93565b6129b5565b6000805b8084511180156121f95750808351115b801561227a5750828181518110612212576122126133f7565b602001015160f81c60f81b7effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916848281518110612251576122516133f7565b01602001517fff0000000000000000000000000000000000000000000000000000000000000016145b15610f34578061228981613367565b9150506121e9565b606060008061229f846124c4565b919350909150600190508160018111156122bb576122bb61346b565b14612322576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f496e76616c696420524c50206c6973742076616c75652e0000000000000000006044820152606401610428565b6040805160208082526104208201909252600091816020015b604080518082019091526000808252602082015281526020019060019003908161233b5790505090506000835b86518110156124b95760208210612401576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f50726f766964656420524c50206c6973742065786365656473206d6178206c6960448201527f7374206c656e6774682e000000000000000000000000000000000000000000006064820152608401610428565b60008061243e6040518060400160405280858c600001516124229190612f93565b8152602001858c6020015161243791906132e9565b90526124c4565b50915091506040518060400160405280838361245a91906132e9565b8152602001848b6020015161246f91906132e9565b815250858581518110612484576124846133f7565b602090810291909101015261249a6001856132e9565b93506124a681836132e9565b6124b090846132e9565b92505050612368565b508152949350505050565b600080600080846000015111612536576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601860248201527f524c50206974656d2063616e6e6f74206265206e756c6c2e00000000000000006044820152606401610428565b6020840151805160001a607f811161255b5760006001600094509450945050506128c4565b60b781116125f1576000612570608083612f93565b9050808760000151116125df576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601960248201527f496e76616c696420524c502073686f727420737472696e672e000000000000006044820152606401610428565b600195509350600092506128c4915050565b60bf811161271457600061260660b783612f93565b905080876000015111612675576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601f60248201527f496e76616c696420524c50206c6f6e6720737472696e67206c656e6774682e006044820152606401610428565b600183015160208290036101000a900461268f81836132e9565b8851116126f8576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601860248201527f496e76616c696420524c50206c6f6e6720737472696e672e00000000000000006044820152606401610428565b6127038260016132e9565b96509450600093506128c492505050565b60f781116127a957600061272960c083612f93565b905080876000015111612798576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f496e76616c696420524c502073686f7274206c6973742e0000000000000000006044820152606401610428565b6001955093508492506128c4915050565b60006127b660f783612f93565b905080876000015111612825576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f496e76616c696420524c50206c6f6e67206c697374206c656e6774682e0000006044820152606401610428565b600183015160208290036101000a900461283f81836132e9565b8851116128a8576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f496e76616c696420524c50206c6f6e67206c6973742e000000000000000000006044820152606401610428565b6128b38260016132e9565b96509450600193506128c492505050565b9193909250565b606060008267ffffffffffffffff8111156128e8576128e8612bfa565b6040519080825280601f01601f191660200182016040528015612912576020820181803683370190505b509050805160001415612926579050611118565b600061293285876132e9565b90506020820160005b612946602087613286565b81101561297d578251825261295c6020846132e9565b92506129696020836132e9565b91508061297581613367565b91505061293b565b5060006001602087066020036101000a039050808251168119845116178252839450505050509392505050565b6060610f3782612ba2565b6060816129c381601f6132e9565b1015612a2b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600e60248201527f736c6963655f6f766572666c6f770000000000000000000000000000000000006044820152606401610428565b82612a3683826132e9565b1015612a9e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600e60248201527f736c6963655f6f766572666c6f770000000000000000000000000000000000006044820152606401610428565b612aa882846132e9565b84511015612b12576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601160248201527f736c6963655f6f75744f66426f756e64730000000000000000000000000000006044820152606401610428565b606082158015612b315760405191506000825260208201604052612b99565b6040519150601f8416801560200281840101858101878315602002848b0101015b81831015612b6a578051835260209283019201612b52565b5050858452601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016604052505b50949350505050565b6060610f378260200151600084600001516128cb565b600060208284031215612bca57600080fd5b5035919050565b803573ffffffffffffffffffffffffffffffffffffffff81168114612bf557600080fd5b919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff81118282101715612c7057612c70612bfa565b604052919050565b600080600080600060a08688031215612c9057600080fd5b612c9986612bd1565b94506020808701359450604087013567ffffffffffffffff8082168214612cbf57600080fd5b9094506060880135908115158214612cd657600080fd5b90935060808801359080821115612cec57600080fd5b818901915089601f830112612d0057600080fd5b813581811115612d1257612d12612bfa565b612d42847fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f84011601612c29565b91508082528a84828501011115612d5857600080fd5b80848401858401376000848284010152508093505050509295509295909350565b60008083601f840112612d8b57600080fd5b50813567ffffffffffffffff811115612da357600080fd5b602083019150836020828501011115612dbb57600080fd5b9250929050565b60008060008060008060008060008060006101808c8e031215612de457600080fd5b8b359a50612df460208d01612bd1565b9950612e0260408d01612bd1565b985060608c0135975060808c0135965067ffffffffffffffff60a08d01351115612e2b57600080fd5b612e3b8d60a08e01358e01612d79565b909650945060c08c0135935060808c8e037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff20011215612e7957600080fd5b60e08c01925067ffffffffffffffff6101608d01351115612e9957600080fd5b612eaa8d6101608e01358e01612d79565b81935080925050509295989b509295989b9093969950565b6000815180845260005b81811015612ee857602081850181015186830182015201612ecc565b81811115612efa576000602083870101525b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b85815284602082015267ffffffffffffffff84166040820152821515606082015260a06080820152600061178b60a0830184612ec2565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b600082821015612fa557612fa5612f64565b500390565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b600082612fe857612fe8612faa565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff83147f80000000000000000000000000000000000000000000000000000000000000008314161561303c5761303c612f64565b500590565b6000808312837f80000000000000000000000000000000000000000000000000000000000000000183128115161561307b5761307b612f64565b837f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0183138116156130af576130af612f64565b50500390565b60007f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff6000841360008413858304851182821616156130f6576130f6612f64565b7f8000000000000000000000000000000000000000000000000000000000000000600087128682058812818416161561313157613131612f64565b6000871292508782058712848416161561314d5761314d612f64565b8785058712818416161561316357613163612f64565b505050929093029392505050565b6000808212827f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff038413811516156131ab576131ab612f64565b827f80000000000000000000000000000000000000000000000000000000000000000384128116156131df576131df612f64565b50500190565b6000817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff048311821515161561321d5761321d612f64565b500290565b600067ffffffffffffffff80831681851680830382111561324557613245612f64565b01949350505050565b60006fffffffffffffffffffffffffffffffff8083168185168183048111821515161561327d5761327d612f64565b02949350505050565b60008261329557613295612faa565b500490565b6000604082840312156132ac57600080fd5b6040516040810181811067ffffffffffffffff821117156132cf576132cf612bfa565b604052825181526020928301519281019290925250919050565b600082198211156132fc576132fc612f64565b500190565b60006080828403121561331357600080fd5b6040516080810181811067ffffffffffffffff8211171561333657613336612bfa565b8060405250823581526020830135602082015260408301356040820152606083013560608201528091505092915050565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82141561339957613399612f64565b5060010190565b868152600073ffffffffffffffffffffffffffffffffffffffff808816602084015280871660408401525084606083015283608083015260c060a08301526133eb60c0830184612ec2565b98975050505050505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b600060ff83168061343957613439612faa565b8060ff84160691505092915050565b600060ff821660ff84168082101561346257613462612f64565b90039392505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b6000602082840312156134ac57600080fd5b505191905056fea164736f6c634300080a000a",
} }
...@@ -592,23 +592,23 @@ func (_OptimismPortal *OptimismPortalTransactorSession) DepositTransaction(_to c ...@@ -592,23 +592,23 @@ func (_OptimismPortal *OptimismPortalTransactorSession) DepositTransaction(_to c
// FinalizeWithdrawalTransaction is a paid mutator transaction binding the contract method 0xeecf1c36. // FinalizeWithdrawalTransaction is a paid mutator transaction binding the contract method 0xeecf1c36.
// //
// Solidity: function finalizeWithdrawalTransaction(uint256 _nonce, address _sender, address _target, uint256 _value, uint256 _gasLimit, bytes _data, uint256 _l2Timestamp, (bytes32,bytes32,bytes32,bytes32) _outputRootProof, bytes _withdrawalProof) payable returns() // Solidity: function finalizeWithdrawalTransaction(uint256 _nonce, address _sender, address _target, uint256 _value, uint256 _gasLimit, bytes _data, uint256 _l2BlockNumber, (bytes32,bytes32,bytes32,bytes32) _outputRootProof, bytes _withdrawalProof) payable returns()
func (_OptimismPortal *OptimismPortalTransactor) FinalizeWithdrawalTransaction(opts *bind.TransactOpts, _nonce *big.Int, _sender common.Address, _target common.Address, _value *big.Int, _gasLimit *big.Int, _data []byte, _l2Timestamp *big.Int, _outputRootProof WithdrawalVerifierOutputRootProof, _withdrawalProof []byte) (*types.Transaction, error) { func (_OptimismPortal *OptimismPortalTransactor) FinalizeWithdrawalTransaction(opts *bind.TransactOpts, _nonce *big.Int, _sender common.Address, _target common.Address, _value *big.Int, _gasLimit *big.Int, _data []byte, _l2BlockNumber *big.Int, _outputRootProof WithdrawalVerifierOutputRootProof, _withdrawalProof []byte) (*types.Transaction, error) {
return _OptimismPortal.contract.Transact(opts, "finalizeWithdrawalTransaction", _nonce, _sender, _target, _value, _gasLimit, _data, _l2Timestamp, _outputRootProof, _withdrawalProof) return _OptimismPortal.contract.Transact(opts, "finalizeWithdrawalTransaction", _nonce, _sender, _target, _value, _gasLimit, _data, _l2BlockNumber, _outputRootProof, _withdrawalProof)
} }
// FinalizeWithdrawalTransaction is a paid mutator transaction binding the contract method 0xeecf1c36. // FinalizeWithdrawalTransaction is a paid mutator transaction binding the contract method 0xeecf1c36.
// //
// Solidity: function finalizeWithdrawalTransaction(uint256 _nonce, address _sender, address _target, uint256 _value, uint256 _gasLimit, bytes _data, uint256 _l2Timestamp, (bytes32,bytes32,bytes32,bytes32) _outputRootProof, bytes _withdrawalProof) payable returns() // Solidity: function finalizeWithdrawalTransaction(uint256 _nonce, address _sender, address _target, uint256 _value, uint256 _gasLimit, bytes _data, uint256 _l2BlockNumber, (bytes32,bytes32,bytes32,bytes32) _outputRootProof, bytes _withdrawalProof) payable returns()
func (_OptimismPortal *OptimismPortalSession) FinalizeWithdrawalTransaction(_nonce *big.Int, _sender common.Address, _target common.Address, _value *big.Int, _gasLimit *big.Int, _data []byte, _l2Timestamp *big.Int, _outputRootProof WithdrawalVerifierOutputRootProof, _withdrawalProof []byte) (*types.Transaction, error) { func (_OptimismPortal *OptimismPortalSession) FinalizeWithdrawalTransaction(_nonce *big.Int, _sender common.Address, _target common.Address, _value *big.Int, _gasLimit *big.Int, _data []byte, _l2BlockNumber *big.Int, _outputRootProof WithdrawalVerifierOutputRootProof, _withdrawalProof []byte) (*types.Transaction, error) {
return _OptimismPortal.Contract.FinalizeWithdrawalTransaction(&_OptimismPortal.TransactOpts, _nonce, _sender, _target, _value, _gasLimit, _data, _l2Timestamp, _outputRootProof, _withdrawalProof) return _OptimismPortal.Contract.FinalizeWithdrawalTransaction(&_OptimismPortal.TransactOpts, _nonce, _sender, _target, _value, _gasLimit, _data, _l2BlockNumber, _outputRootProof, _withdrawalProof)
} }
// FinalizeWithdrawalTransaction is a paid mutator transaction binding the contract method 0xeecf1c36. // FinalizeWithdrawalTransaction is a paid mutator transaction binding the contract method 0xeecf1c36.
// //
// Solidity: function finalizeWithdrawalTransaction(uint256 _nonce, address _sender, address _target, uint256 _value, uint256 _gasLimit, bytes _data, uint256 _l2Timestamp, (bytes32,bytes32,bytes32,bytes32) _outputRootProof, bytes _withdrawalProof) payable returns() // Solidity: function finalizeWithdrawalTransaction(uint256 _nonce, address _sender, address _target, uint256 _value, uint256 _gasLimit, bytes _data, uint256 _l2BlockNumber, (bytes32,bytes32,bytes32,bytes32) _outputRootProof, bytes _withdrawalProof) payable returns()
func (_OptimismPortal *OptimismPortalTransactorSession) FinalizeWithdrawalTransaction(_nonce *big.Int, _sender common.Address, _target common.Address, _value *big.Int, _gasLimit *big.Int, _data []byte, _l2Timestamp *big.Int, _outputRootProof WithdrawalVerifierOutputRootProof, _withdrawalProof []byte) (*types.Transaction, error) { func (_OptimismPortal *OptimismPortalTransactorSession) FinalizeWithdrawalTransaction(_nonce *big.Int, _sender common.Address, _target common.Address, _value *big.Int, _gasLimit *big.Int, _data []byte, _l2BlockNumber *big.Int, _outputRootProof WithdrawalVerifierOutputRootProof, _withdrawalProof []byte) (*types.Transaction, error) {
return _OptimismPortal.Contract.FinalizeWithdrawalTransaction(&_OptimismPortal.TransactOpts, _nonce, _sender, _target, _value, _gasLimit, _data, _l2Timestamp, _outputRootProof, _withdrawalProof) return _OptimismPortal.Contract.FinalizeWithdrawalTransaction(&_OptimismPortal.TransactOpts, _nonce, _sender, _target, _value, _gasLimit, _data, _l2BlockNumber, _outputRootProof, _withdrawalProof)
} }
// Receive is a paid mutator transaction binding the contract receive function. // Receive is a paid mutator transaction binding the contract receive function.
......
...@@ -52,10 +52,11 @@ func deriveAccount(w accounts.Wallet, path string) accounts.Account { ...@@ -52,10 +52,11 @@ func deriveAccount(w accounts.Wallet, path string) accounts.Account {
type L2OOContractConfig struct { type L2OOContractConfig struct {
SubmissionFrequency *big.Int SubmissionFrequency *big.Int
L2StartTime *big.Int L2StartingBlock *big.Int
L2BlockTime *big.Int
GenesisL2Output [32]byte GenesisL2Output [32]byte
HistoricalTotalBlocks *big.Int HistoricalTotalBlocks *big.Int
L2StartingTimeStamp *big.Int
L2BlockTime *big.Int
} }
type DepositContractConfig struct { type DepositContractConfig struct {
...@@ -82,9 +83,11 @@ type SystemConfig struct { ...@@ -82,9 +83,11 @@ type SystemConfig struct {
JWTFilePath string JWTFilePath string
JWTSecret [32]byte JWTSecret [32]byte
Nodes map[string]*rollupNode.Config // Per node config. Don't use populate rollup.Config Nodes map[string]*rollupNode.Config // Per node config. Don't use populate rollup.Config
Loggers map[string]log.Logger Loggers map[string]log.Logger
RollupConfig rollup.Config // Shared rollup configs ProposerLogger log.Logger
BatcherLogger log.Logger
RollupConfig rollup.Config // Shared rollup configs
L1BlockTime uint64 L1BlockTime uint64
...@@ -392,7 +395,9 @@ func (cfg SystemConfig) start() (*System, error) { ...@@ -392,7 +395,9 @@ func (cfg SystemConfig) start() (*System, error) {
sys.cfg.RollupConfig.Genesis = sys.RolupGenesis sys.cfg.RollupConfig.Genesis = sys.RolupGenesis
sys.cfg.RollupConfig.BatchSenderAddress = batchSubmitterAddr sys.cfg.RollupConfig.BatchSenderAddress = batchSubmitterAddr
sys.cfg.RollupConfig.P2PSequencerAddress = p2pSignerAddr sys.cfg.RollupConfig.P2PSequencerAddress = p2pSignerAddr
sys.cfg.L2OOCfg.L2StartTime = new(big.Int).SetUint64(l2GenesisTime) sys.cfg.L2OOCfg.L2StartingBlock = new(big.Int).SetUint64(l2GenesisID.Number)
sys.cfg.L2OOCfg.L2StartingTimeStamp = new(big.Int).SetUint64(l2Genesis.Timestamp)
sys.cfg.L2OOCfg.L2BlockTime = new(big.Int).SetUint64(2)
// Deploy Deposit Contract // Deploy Deposit Contract
deployerPrivKey, err := sys.wallet.PrivateKey(accounts.Account{ deployerPrivKey, err := sys.wallet.PrivateKey(accounts.Account{
...@@ -414,10 +419,11 @@ func (cfg SystemConfig) start() (*System, error) { ...@@ -414,10 +419,11 @@ func (cfg SystemConfig) start() (*System, error) {
opts, opts,
l1Client, l1Client,
sys.cfg.L2OOCfg.SubmissionFrequency, sys.cfg.L2OOCfg.SubmissionFrequency,
sys.cfg.L2OOCfg.L2BlockTime,
sys.cfg.L2OOCfg.GenesisL2Output, sys.cfg.L2OOCfg.GenesisL2Output,
sys.cfg.L2OOCfg.HistoricalTotalBlocks, sys.cfg.L2OOCfg.HistoricalTotalBlocks,
sys.cfg.L2OOCfg.L2StartTime, sys.cfg.L2OOCfg.L2StartingBlock,
sys.cfg.L2OOCfg.L2StartingTimeStamp,
sys.cfg.L2OOCfg.L2BlockTime,
l2OutputSubmitterAddr, l2OutputSubmitterAddr,
) )
sys.cfg.DepositCFG.L2Oracle = sys.L2OOContractAddr sys.cfg.DepositCFG.L2Oracle = sys.L2OOContractAddr
...@@ -554,7 +560,7 @@ func (cfg SystemConfig) start() (*System, error) { ...@@ -554,7 +560,7 @@ func (cfg SystemConfig) start() (*System, error) {
LogTerminal: true, LogTerminal: true,
Mnemonic: sys.cfg.Mnemonic, Mnemonic: sys.cfg.Mnemonic,
L2OutputHDPath: sys.cfg.L2OutputHDPath, L2OutputHDPath: sys.cfg.L2OutputHDPath,
}, "", log.New()) }, "", cfg.ProposerLogger)
if err != nil { if err != nil {
return nil, fmt.Errorf("unable to setup l2 output submitter: %w", err) return nil, fmt.Errorf("unable to setup l2 output submitter: %w", err)
} }
...@@ -590,7 +596,7 @@ func (cfg SystemConfig) start() (*System, error) { ...@@ -590,7 +596,7 @@ func (cfg SystemConfig) start() (*System, error) {
SequencerHistoryDBFilename: sys.sequencerHistoryDBFileName, SequencerHistoryDBFilename: sys.sequencerHistoryDBFileName,
SequencerGenesisHash: sys.RolupGenesis.L2.Hash.String(), SequencerGenesisHash: sys.RolupGenesis.L2.Hash.String(),
SequencerBatchInboxAddress: sys.cfg.RollupConfig.BatchInboxAddress.String(), SequencerBatchInboxAddress: sys.cfg.RollupConfig.BatchInboxAddress.String(),
}, "", log.New()) }, "", cfg.BatcherLogger)
if err != nil { if err != nil {
return nil, fmt.Errorf("failed to setup batch submitter: %w", err) return nil, fmt.Errorf("failed to setup batch submitter: %w", err)
} }
......
...@@ -88,7 +88,6 @@ func defaultSystemConfig(t *testing.T) SystemConfig { ...@@ -88,7 +88,6 @@ func defaultSystemConfig(t *testing.T) SystemConfig {
L2OOCfg: L2OOContractConfig{ L2OOCfg: L2OOContractConfig{
// L2 Start time is set based off of the L2 Genesis time // L2 Start time is set based off of the L2 Genesis time
SubmissionFrequency: big.NewInt(2), SubmissionFrequency: big.NewInt(2),
L2BlockTime: big.NewInt(1),
HistoricalTotalBlocks: big.NewInt(0), HistoricalTotalBlocks: big.NewInt(0),
}, },
L2OutputHDPath: l2OutputHDPath, L2OutputHDPath: l2OutputHDPath,
...@@ -117,6 +116,8 @@ func defaultSystemConfig(t *testing.T) SystemConfig { ...@@ -117,6 +116,8 @@ func defaultSystemConfig(t *testing.T) SystemConfig {
"verifier": testlog.Logger(t, log.LvlError).New("role", "verifier"), "verifier": testlog.Logger(t, log.LvlError).New("role", "verifier"),
"sequencer": testlog.Logger(t, log.LvlError).New("role", "sequencer"), "sequencer": testlog.Logger(t, log.LvlError).New("role", "sequencer"),
}, },
ProposerLogger: testlog.Logger(t, log.LvlCrit).New("role", "proposer"), // Proposer is noisy on shutdown
BatcherLogger: testlog.Logger(t, log.LvlCrit).New("role", "batcher"), // Batcher (txmgr really) is noisy on shutdown
RollupConfig: rollup.Config{ RollupConfig: rollup.Config{
BlockTime: 1, BlockTime: 1,
MaxSequencerDrift: 10, MaxSequencerDrift: 10,
...@@ -153,11 +154,11 @@ func TestL2OutputSubmitter(t *testing.T) { ...@@ -153,11 +154,11 @@ func TestL2OutputSubmitter(t *testing.T) {
require.Nil(t, err) require.Nil(t, err)
rollupClient := rollupclient.NewRollupClient(rollupRPCClient) rollupClient := rollupclient.NewRollupClient(rollupRPCClient)
// StateRootOracle is already deployed // OutputOracle is already deployed
l2OutputOracle, err := bindings.NewL2OutputOracleCaller(sys.L2OOContractAddr, l1Client) l2OutputOracle, err := bindings.NewL2OutputOracleCaller(sys.L2OOContractAddr, l1Client)
require.Nil(t, err) require.Nil(t, err)
initialSroTimestamp, err := l2OutputOracle.LatestBlockTimestamp(&bind.CallOpts{}) initialOutputBlockNumber, err := l2OutputOracle.LatestBlockNumber(&bind.CallOpts{})
require.Nil(t, err) require.Nil(t, err)
// Wait until the second output submission from L2. The output submitter submits outputs from the // Wait until the second output submission from L2. The output submitter submits outputs from the
...@@ -174,20 +175,15 @@ func TestL2OutputSubmitter(t *testing.T) { ...@@ -174,20 +175,15 @@ func TestL2OutputSubmitter(t *testing.T) {
ticker := time.NewTicker(1 * time.Second) ticker := time.NewTicker(1 * time.Second)
defer ticker.Stop() defer ticker.Stop()
for { for {
l2ooTimestamp, err := l2OutputOracle.LatestBlockTimestamp(&bind.CallOpts{}) l2ooBlockNumber, err := l2OutputOracle.LatestBlockNumber(&bind.CallOpts{})
require.Nil(t, err) require.Nil(t, err)
// Wait for the L2 output oracle to have been changed from the initial // Wait for the L2 output oracle to have been changed from the initial
// timestamp set in the contract constructor. // timestamp set in the contract constructor.
if l2ooTimestamp.Cmp(initialSroTimestamp) > 0 { if l2ooBlockNumber.Cmp(initialOutputBlockNumber) > 0 {
// Retrieve the l2 output committed at this updated timestamp. // Retrieve the l2 output committed at this updated timestamp.
committedL2Output, err := l2OutputOracle.GetL2Output(&bind.CallOpts{}, l2ooTimestamp) committedL2Output, err := l2OutputOracle.GetL2Output(&bind.CallOpts{}, l2ooBlockNumber)
require.Nil(t, err) require.NotEqual(t, [32]byte{}, committedL2Output.OutputRoot, "Empty L2 Output")
// Compute the committed L2 output's L2 block number.
l2ooBlockNumber, err := l2OutputOracle.ComputeL2BlockNumber(
&bind.CallOpts{}, l2ooTimestamp,
)
require.Nil(t, err) require.Nil(t, err)
// Fetch the corresponding L2 block and assert the committed L2 // Fetch the corresponding L2 block and assert the committed L2
...@@ -765,19 +761,19 @@ func TestWithdrawals(t *testing.T) { ...@@ -765,19 +761,19 @@ func TestWithdrawals(t *testing.T) {
tx, err = l2withdrawer.InitiateWithdrawal(l2opts, fromAddr, big.NewInt(21000), nil) tx, err = l2withdrawer.InitiateWithdrawal(l2opts, fromAddr, big.NewInt(21000), nil)
require.Nil(t, err, "sending initiate withdraw tx") require.Nil(t, err, "sending initiate withdraw tx")
receipt, err = waitForTransaction(tx.Hash(), l2Seq, 3*time.Duration(cfg.L1BlockTime)*time.Second) receipt, err = waitForTransaction(tx.Hash(), l2Verif, 5*time.Duration(cfg.L1BlockTime)*time.Second)
require.Nil(t, err, "withdrawal initiated on L2 sequencer") require.Nil(t, err, "withdrawal initiated on L2 sequencer")
require.Equal(t, receipt.Status, types.ReceiptStatusSuccessful, "transaction failed") require.Equal(t, receipt.Status, types.ReceiptStatusSuccessful, "transaction failed")
// Verify L2 balance after withdrawal // Verify L2 balance after withdrawal
ctx, cancel = context.WithTimeout(context.Background(), 1*time.Second) ctx, cancel = context.WithTimeout(context.Background(), 1*time.Second)
defer cancel() defer cancel()
header, err := l2Seq.HeaderByNumber(ctx, receipt.BlockNumber) header, err := l2Verif.HeaderByNumber(ctx, receipt.BlockNumber)
require.Nil(t, err) require.Nil(t, err)
ctx, cancel = context.WithTimeout(context.Background(), 1*time.Second) ctx, cancel = context.WithTimeout(context.Background(), 1*time.Second)
defer cancel() defer cancel()
endBalance, err = l2Seq.BalanceAt(ctx, fromAddr, nil) endBalance, err = l2Verif.BalanceAt(ctx, fromAddr, nil)
require.Nil(t, err) require.Nil(t, err)
// Take fee into account // Take fee into account
...@@ -793,25 +789,17 @@ func TestWithdrawals(t *testing.T) { ...@@ -793,25 +789,17 @@ func TestWithdrawals(t *testing.T) {
require.Nil(t, err) require.Nil(t, err)
// Wait for finalization and then create the Finalized Withdrawal Transaction // Wait for finalization and then create the Finalized Withdrawal Transaction
l2OutputOracle, err := bindings.NewL2OutputOracleCaller(sys.L2OOContractAddr, l1Client)
require.Nil(t, err)
ctx, cancel = context.WithTimeout(context.Background(), 10*time.Duration(cfg.L1BlockTime)*time.Second) ctx, cancel = context.WithTimeout(context.Background(), 10*time.Duration(cfg.L1BlockTime)*time.Second)
defer cancel() defer cancel()
timestamp, err := withdrawals.WaitForFinalizationPeriod(ctx, l1Client, sys.DepositContractAddr, header.Time) blockNumber, err := withdrawals.WaitForFinalizationPeriod(ctx, l1Client, sys.DepositContractAddr, receipt.BlockNumber)
require.Nil(t, err)
ctx, cancel = context.WithTimeout(context.Background(), 1*time.Second)
defer cancel()
blockNumber, err := l2OutputOracle.ComputeL2BlockNumber(&bind.CallOpts{Context: ctx}, new(big.Int).SetUint64(timestamp))
require.Nil(t, err) require.Nil(t, err)
ctx, cancel = context.WithTimeout(context.Background(), 1*time.Second) ctx, cancel = context.WithTimeout(context.Background(), 1*time.Second)
defer cancel() defer cancel()
header, err = l2Seq.HeaderByNumber(ctx, blockNumber) header, err = l2Verif.HeaderByNumber(ctx, new(big.Int).SetUint64(blockNumber))
require.Nil(t, err) require.Nil(t, err)
rpc, err := rpc.Dial(sys.nodes["sequencer"].WSEndpoint()) rpc, err := rpc.Dial(sys.nodes["verifier"].WSEndpoint())
require.Nil(t, err) require.Nil(t, err)
l2client := withdrawals.NewClient(rpc) l2client := withdrawals.NewClient(rpc)
...@@ -831,7 +819,7 @@ func TestWithdrawals(t *testing.T) { ...@@ -831,7 +819,7 @@ func TestWithdrawals(t *testing.T) {
params.Value, params.Value,
params.GasLimit, params.GasLimit,
params.Data, params.Data,
params.Timestamp, params.BlockNumber,
params.OutputRootProof, params.OutputRootProof,
params.WithdrawalProof, params.WithdrawalProof,
) )
......
...@@ -20,13 +20,13 @@ import ( ...@@ -20,13 +20,13 @@ import (
"github.com/ethereum/go-ethereum/rpc" "github.com/ethereum/go-ethereum/rpc"
) )
// WaitForFinalizationPeriod waits until the timestamp has been submitted to the L2 Output Oracle on L1 and // WaitForFinalizationPeriod waits until there is OutputProof for an L2 block number larger than the supplied l2BlockNumber
// then waits for the finalization period to be up. // and that the output is finalized.
// This functions polls and can block for a very long time if used on mainnet. // This functions polls and can block for a very long time if used on mainnet.
// This returns the timestamp to use for the proof generation. // This returns the block number to use for the proof generation.
func WaitForFinalizationPeriod(ctx context.Context, client *ethclient.Client, portalAddr common.Address, timestamp uint64) (uint64, error) { func WaitForFinalizationPeriod(ctx context.Context, client *ethclient.Client, portalAddr common.Address, l2BlockNumber *big.Int) (uint64, error) {
l2BlockNumber = new(big.Int).Set(l2BlockNumber) // Don't clobber caller owned l2BlockNumber
opts := &bind.CallOpts{Context: ctx} opts := &bind.CallOpts{Context: ctx}
timestampBig := new(big.Int).SetUint64(timestamp)
portal, err := bindings.NewOptimismPortalCaller(portalAddr, client) portal, err := bindings.NewOptimismPortalCaller(portalAddr, client)
if err != nil { if err != nil {
...@@ -40,21 +40,32 @@ func WaitForFinalizationPeriod(ctx context.Context, client *ethclient.Client, po ...@@ -40,21 +40,32 @@ func WaitForFinalizationPeriod(ctx context.Context, client *ethclient.Client, po
if err != nil { if err != nil {
return 0, err return 0, err
} }
submissionInterval, err := l2OO.SUBMISSIONINTERVAL(opts)
if err != nil {
return 0, err
}
// Convert blockNumber to submission interval boundary
rem := new(big.Int)
l2BlockNumber, rem = l2BlockNumber.DivMod(l2BlockNumber, submissionInterval, rem)
if rem.Cmp(common.Big0) != 0 {
l2BlockNumber = l2BlockNumber.Add(l2BlockNumber, common.Big1)
}
l2BlockNumber = l2BlockNumber.Mul(l2BlockNumber, submissionInterval)
finalizationPeriod, err := portal.FINALIZATIONPERIODSECONDS(opts) finalizationPeriod, err := portal.FINALIZATIONPERIODSECONDS(opts)
if err != nil { if err != nil {
return 0, err return 0, err
} }
next, err := l2OO.LatestBlockTimestamp(opts) latest, err := l2OO.LatestBlockNumber(opts)
if err != nil { if err != nil {
return 0, err return 0, err
} }
// Now poll // Now poll for the output to be submitted on chain
var ticker *time.Ticker var ticker *time.Ticker
diff := new(big.Int).Sub(timestampBig, next) diff := new(big.Int).Sub(l2BlockNumber, latest)
if diff.Cmp(big.NewInt(60)) > 0 { if diff.Cmp(big.NewInt(10)) > 0 {
ticker = time.NewTicker(time.Minute) ticker = time.NewTicker(time.Minute)
} else { } else {
ticker = time.NewTicker(time.Second) ticker = time.NewTicker(time.Second)
...@@ -64,12 +75,12 @@ loop: ...@@ -64,12 +75,12 @@ loop:
for { for {
select { select {
case <-ticker.C: case <-ticker.C:
next, err = l2OO.LatestBlockTimestamp(opts) latest, err = l2OO.LatestBlockNumber(opts)
if err != nil { if err != nil {
return 0, err return 0, err
} }
// Already passed next // Already passed the submitted block (likely just equals rather than >= here).
if next.Cmp(timestampBig) > 0 { if latest.Cmp(l2BlockNumber) >= 0 {
break loop break loop
} }
case <-ctx.Done(): case <-ctx.Done():
...@@ -78,10 +89,13 @@ loop: ...@@ -78,10 +89,13 @@ loop:
} }
// Now wait for it to be finalized // Now wait for it to be finalized
output, err := l2OO.GetL2Output(opts, next) output, err := l2OO.GetL2Output(opts, l2BlockNumber)
if err != nil { if err != nil {
return 0, err return 0, err
} }
if output.OutputRoot == [32]byte{} {
return 0, errors.New("empty output root. likely no proposal at timestamp")
}
targetTimestamp := new(big.Int).Add(output.Timestamp, finalizationPeriod) targetTimestamp := new(big.Int).Add(output.Timestamp, finalizationPeriod)
targetTime := time.Unix(targetTimestamp.Int64(), 0) targetTime := time.Unix(targetTimestamp.Int64(), 0)
// Assume clock is relatively correct // Assume clock is relatively correct
...@@ -96,7 +110,7 @@ loop: ...@@ -96,7 +110,7 @@ loop:
return 0, err return 0, err
} }
if header.Time > targetTimestamp.Uint64() { if header.Time > targetTimestamp.Uint64() {
return next.Uint64(), nil return l2BlockNumber.Uint64(), nil
} }
case <-ctx.Done(): case <-ctx.Done():
return 0, ctx.Err() return 0, ctx.Err()
...@@ -131,21 +145,21 @@ func NewClient(client *rpc.Client) *Client { ...@@ -131,21 +145,21 @@ func NewClient(client *rpc.Client) *Client {
} }
// FinalizedWithdrawalParameters is the set of paramets to pass to the FinalizedWithdrawal function // FinalizedWithdrawalParameters is the set of parameters to pass to the FinalizedWithdrawal function
type FinalizedWithdrawalParameters struct { type FinalizedWithdrawalParameters struct {
Nonce *big.Int Nonce *big.Int
Sender common.Address Sender common.Address
Target common.Address Target common.Address
Value *big.Int Value *big.Int
GasLimit *big.Int GasLimit *big.Int
Timestamp *big.Int BlockNumber *big.Int
Data []byte Data []byte
OutputRootProof bindings.WithdrawalVerifierOutputRootProof OutputRootProof bindings.WithdrawalVerifierOutputRootProof
WithdrawalProof []byte // RLP Encoded list of trie nodes to prove L2 storage WithdrawalProof []byte // RLP Encoded list of trie nodes to prove L2 storage
} }
// FinalizeWithdrawalParameters queries L2 to generate all withdrawal parameters and proof necessary to finalize an withdrawal on L1. // FinalizeWithdrawalParameters queries L2 to generate all withdrawal parameters and proof necessary to finalize an withdrawal on L1.
// The header provided is very imporant. It should be a block (timestamp) for which there is a submitted output in the L2 Output Oracle // The header provided is very important. It should be a block (timestamp) for which there is a submitted output in the L2 Output Oracle
// contract. If not, the withdrawal will fail as it the storage proof cannot be verified if there is no submitted state root. // contract. If not, the withdrawal will fail as it the storage proof cannot be verified if there is no submitted state root.
func FinalizeWithdrawalParameters(ctx context.Context, l2client ProofClient, txHash common.Hash, header *types.Header) (FinalizedWithdrawalParameters, error) { func FinalizeWithdrawalParameters(ctx context.Context, l2client ProofClient, txHash common.Hash, header *types.Header) (FinalizedWithdrawalParameters, error) {
// Transaction receipt // Transaction receipt
...@@ -189,13 +203,13 @@ func FinalizeWithdrawalParameters(ctx context.Context, l2client ProofClient, txH ...@@ -189,13 +203,13 @@ func FinalizeWithdrawalParameters(ctx context.Context, l2client ProofClient, txH
} }
return FinalizedWithdrawalParameters{ return FinalizedWithdrawalParameters{
Nonce: ev.Nonce, Nonce: ev.Nonce,
Sender: ev.Sender, Sender: ev.Sender,
Target: ev.Target, Target: ev.Target,
Value: ev.Value, Value: ev.Value,
GasLimit: ev.GasLimit, GasLimit: ev.GasLimit,
Timestamp: new(big.Int).SetUint64(header.Time), BlockNumber: new(big.Int).Set(header.Number),
Data: ev.Data, Data: ev.Data,
OutputRootProof: bindings.WithdrawalVerifierOutputRootProof{ OutputRootProof: bindings.WithdrawalVerifierOutputRootProof{
Version: [32]byte{}, // Empty for version 1 Version: [32]byte{}, // Empty for version 1
StateRoot: header.Root, StateRoot: header.Root,
......
...@@ -95,58 +95,41 @@ func (d *Driver) GetBlockRange( ...@@ -95,58 +95,41 @@ func (d *Driver) GetBlockRange(
Context: ctx, Context: ctx,
} }
// Determine the next uncommitted L2 block number. We do so by transforming // Determine the last committed L2 Block Number
// the timestamp of the latest committed L2 block into its block number and start, err := d.l2ooContract.LatestBlockNumber(callOpts)
// adding one.
l2ooTimestamp, err := d.l2ooContract.LatestBlockTimestamp(callOpts)
if err != nil { if err != nil {
d.l.Error(name+" unable to get latest block timestamp", "err", err) d.l.Error(name+" unable to get latest block number", "err", err)
return nil, nil, err
}
start, err := d.l2ooContract.ComputeL2BlockNumber(callOpts, l2ooTimestamp)
if err != nil {
d.l.Error(name+" unable to compute latest l2 block number", "err", err)
return nil, nil, err return nil, nil, err
} }
start.Add(start, bigOne) start.Add(start, bigOne)
// Next we need to obtain the current timestamp and the next timestamp at // Next determine the L2 block that we need to commit
// which we will need to submit an L2 output. The former is done by simply nextBlockNumber, err := d.l2ooContract.NextBlockNumber(callOpts)
// adding the submission interval to the latest committed block's timestamp;
// the latter inspects the timestamp of the latest block.
nextTimestamp, err := d.l2ooContract.NextTimestamp(callOpts)
if err != nil { if err != nil {
d.l.Error(name+" unable to get next block timestamp", "err", err) d.l.Error(name+" unable to get next block number", "err", err)
return nil, nil, err return nil, nil, err
} }
latestHeader, err := d.cfg.L1Client.HeaderByNumber(ctx, nil) latestHeader, err := d.cfg.L2Client.HeaderByNumber(ctx, nil)
if err != nil { if err != nil {
d.l.Error(name+" unable to retrieve latest header", "err", err) d.l.Error(name+" unable to retrieve latest header", "err", err)
return nil, nil, err return nil, nil, err
} }
currentTimestamp := big.NewInt(int64(latestHeader.Time)) currentBlockNumber := big.NewInt(latestHeader.Number.Int64())
// If the submission window has yet to elapsed, we must wait before // If we do not have the new L2 Block number
// submitting our L2 output commitment. Return start as the end value which if currentBlockNumber.Cmp(nextBlockNumber) < 0 {
// will signal that there is no work to be done.
if currentTimestamp.Cmp(nextTimestamp) < 0 {
d.l.Info(name+" submission interval has not elapsed", d.l.Info(name+" submission interval has not elapsed",
"currentTimestamp", currentTimestamp, "nextTimestamp", nextTimestamp) "currentBlockNumber", currentBlockNumber, "nextBlockNumber", nextBlockNumber)
return start, start, nil return start, start, nil
} }
d.l.Info(name+" submission interval has elapsed", d.l.Info(name+" submission interval has elapsed",
"currentTimestamp", currentTimestamp, "nextTimestamp", nextTimestamp) "currentBlockNumber", currentBlockNumber, "nextBlockNumber", nextBlockNumber)
// Otherwise the submission interval has elapsed. Transform the next // Otherwise the submission interval has elapsed. Transform the next
// expected timestamp into its L2 block number, and add one since end is // expected timestamp into its L2 block number, and add one since end is
// exclusive. // exclusive.
end, err := d.l2ooContract.ComputeL2BlockNumber(callOpts, nextTimestamp) end := new(big.Int).Add(nextBlockNumber, bigOne)
if err != nil {
d.l.Error(name+" unable to compute next l2 block number", "err", err)
return nil, nil, err
}
end.Add(end, bigOne)
return start, end, nil return start, end, nil
} }
...@@ -174,35 +157,11 @@ func (d *Driver) CraftTx( ...@@ -174,35 +157,11 @@ func (d *Driver) CraftTx(
return nil, err return nil, err
} }
// Fetch the next expected timestamp that we will submit along with the
// L2Output.
callOpts := &bind.CallOpts{
Pending: false,
Context: ctx,
}
timestamp, err := d.l2ooContract.NextTimestamp(callOpts)
if err != nil {
return nil, err
}
// Sanity check that we are submitting against the same expected timestamp.
expCheckpointBlock, err := d.l2ooContract.ComputeL2BlockNumber(
callOpts, timestamp,
)
if err != nil {
return nil, err
}
if nextCheckpointBlock.Cmp(expCheckpointBlock) != 0 {
return nil, fmt.Errorf("expected next checkpoint block to be %d, "+
"found %d", nextCheckpointBlock.Uint64(),
expCheckpointBlock.Uint64())
}
numElements := new(big.Int).Sub(start, end).Uint64() numElements := new(big.Int).Sub(start, end).Uint64()
d.l.Info(name+" checkpoint constructed", "start", start, "end", end, d.l.Info(name+" checkpoint constructed", "start", start, "end", end,
"nonce", nonce, "blocks_committed", numElements, "checkpoint_block", nextCheckpointBlock) "nonce", nonce, "blocks_committed", numElements, "checkpoint_block", nextCheckpointBlock)
header, err := d.cfg.L1Client.HeaderByNumber(ctx, nil) l1Header, err := d.cfg.L1Client.HeaderByNumber(ctx, nil)
if err != nil { if err != nil {
return nil, fmt.Errorf("error resolving checkpoint block: %v", err) return nil, fmt.Errorf("error resolving checkpoint block: %v", err)
} }
...@@ -212,8 +171,8 @@ func (d *Driver) CraftTx( ...@@ -212,8 +171,8 @@ func (d *Driver) CraftTx(
return nil, fmt.Errorf("error resolving checkpoint block: %v", err) return nil, fmt.Errorf("error resolving checkpoint block: %v", err)
} }
if l2Header.Time != timestamp.Uint64() { if l2Header.Number.Cmp(nextCheckpointBlock) != 0 {
return nil, fmt.Errorf("invalid timestamp: next timestamp is %v, timestamp of block is %v", timestamp, l2Header.Time) return nil, fmt.Errorf("invalid blockNumber: next blockNumber is %v, blockNumber of block is %v", nextCheckpointBlock, l2Header.Number)
} }
opts, err := bind.NewKeyedTransactorWithChainID( opts, err := bind.NewKeyedTransactorWithChainID(
...@@ -226,7 +185,7 @@ func (d *Driver) CraftTx( ...@@ -226,7 +185,7 @@ func (d *Driver) CraftTx(
opts.Nonce = nonce opts.Nonce = nonce
opts.NoSend = true opts.NoSend = true
return d.l2ooContract.AppendL2Output(opts, l2OutputRoot, timestamp, header.Hash(), header.Number) return d.l2ooContract.AppendL2Output(opts, l2OutputRoot, nextCheckpointBlock, l1Header.Hash(), l1Header.Number)
} }
// UpdateGasPrice signs an otherwise identical txn to the one provided but with // UpdateGasPrice signs an otherwise identical txn to the one provided but with
......
...@@ -38,7 +38,7 @@ L1StandardBridge_Test:test_depositERC20To() (gas: 454650) ...@@ -38,7 +38,7 @@ L1StandardBridge_Test:test_depositERC20To() (gas: 454650)
L1StandardBridge_Test:test_depositETH() (gas: 247054) L1StandardBridge_Test:test_depositETH() (gas: 247054)
L1StandardBridge_Test:test_depositETHTo() (gas: 204938) L1StandardBridge_Test:test_depositETHTo() (gas: 204938)
L1StandardBridge_Test:test_donateETH() (gas: 17545) L1StandardBridge_Test:test_donateETH() (gas: 17545)
L1StandardBridge_Test:test_finalizeERC20Withdrawal() (gas: 438817) L1StandardBridge_Test:test_finalizeERC20Withdrawal() (gas: 438824)
L1StandardBridge_Test:test_finalizeETHWithdrawal() (gas: 48005) L1StandardBridge_Test:test_finalizeETHWithdrawal() (gas: 48005)
L1StandardBridge_Test:test_initialize() (gas: 14885) L1StandardBridge_Test:test_initialize() (gas: 14885)
L1StandardBridge_Test:test_onlyEOADepositERC20() (gas: 12085) L1StandardBridge_Test:test_onlyEOADepositERC20() (gas: 12085)
...@@ -56,21 +56,21 @@ L2CrossDomainMessenger_Test:test_L2MessengerSendMessage() (gas: 119659) ...@@ -56,21 +56,21 @@ L2CrossDomainMessenger_Test:test_L2MessengerSendMessage() (gas: 119659)
L2CrossDomainMessenger_Test:test_L2MessengerTwiceSendMessage() (gas: 133096) L2CrossDomainMessenger_Test:test_L2MessengerTwiceSendMessage() (gas: 133096)
L2CrossDomainMessenger_Test:test_L2MessengerXDomainSenderReverts() (gas: 10588) L2CrossDomainMessenger_Test:test_L2MessengerXDomainSenderReverts() (gas: 10588)
L2CrossDomainMessenger_Test:test_L2MessengerxDomainMessageSenderResets() (gas: 54859) L2CrossDomainMessenger_Test:test_L2MessengerxDomainMessageSenderResets() (gas: 54859)
L2OutputOracleTest:testCannot_appendCurrentTimestamp() (gas: 18627) L2OutputOracleTest:testCannot_appendEmptyOutput() (gas: 18442)
L2OutputOracleTest:testCannot_appendEmptyOutput() (gas: 16756) L2OutputOracleTest:testCannot_appendFutureTimetamp() (gas: 20072)
L2OutputOracleTest:testCannot_appendFutureTimestamp() (gas: 18708) L2OutputOracleTest:testCannot_appendOnWrongFork() (gas: 20710)
L2OutputOracleTest:testCannot_appendOutputIfNotSequencer() (gas: 16458) L2OutputOracleTest:testCannot_appendOutputIfNotSequencer() (gas: 17829)
L2OutputOracleTest:testCannot_appendUnexpectedTimestamp() (gas: 18893) L2OutputOracleTest:testCannot_appendUnexpectedBlockNumber() (gas: 20313)
L2OutputOracleTest:testCannot_computePreHistoricalL2BlockNumber() (gas: 11093) L2OutputOracleTest:testCannot_deleteL2Output_ifNotSequencer() (gas: 18805)
L2OutputOracleTest:testCannot_deleteL2Output_ifNotSequencer() (gas: 18793) L2OutputOracleTest:testCannot_deleteWrongL2Output() (gas: 79498)
L2OutputOracleTest:testCannot_deleteWrongL2Output() (gas: 77352) L2OutputOracleTest:test_appendWithBlockhashAndHeight() (gas: 69365)
L2OutputOracleTest:test_appendingAnotherOutput() (gas: 68582) L2OutputOracleTest:test_appendingAnotherOutput() (gas: 70714)
L2OutputOracleTest:test_computeL2BlockNumber() (gas: 14755) L2OutputOracleTest:test_computeL2Timestamp() (gas: 19230)
L2OutputOracleTest:test_constructor() (gas: 33752) L2OutputOracleTest:test_constructor() (gas: 33908)
L2OutputOracleTest:test_deleteL2Output() (gas: 64338) L2OutputOracleTest:test_deleteL2Output() (gas: 66081)
L2OutputOracleTest:test_getL2Output() (gas: 74601) L2OutputOracleTest:test_getL2Output() (gas: 76274)
L2OutputOracleTest:test_latestBlockTimestamp() (gas: 68377) L2OutputOracleTest:test_latestBlockNumber() (gas: 70075)
L2OutputOracleTest:test_nextTimestamp() (gas: 9236) L2OutputOracleTest:test_nextBlockNumber() (gas: 9279)
L2StandardBridge_Test:test_cannotWithdrawEthWithoutSendingIt() (gas: 21578) L2StandardBridge_Test:test_cannotWithdrawEthWithoutSendingIt() (gas: 21578)
L2StandardBridge_Test:test_finalizeDeposit() (gas: 93165) L2StandardBridge_Test:test_finalizeDeposit() (gas: 93165)
L2StandardBridge_Test:test_finalizeDeposit_failsToCompleteOutboundTransfer() (gas: 140106) L2StandardBridge_Test:test_finalizeDeposit_failsToCompleteOutboundTransfer() (gas: 140106)
...@@ -108,7 +108,7 @@ OptimismMintableTokenFactory_Test:test_initializeShouldRevert() (gas: 12696) ...@@ -108,7 +108,7 @@ OptimismMintableTokenFactory_Test:test_initializeShouldRevert() (gas: 12696)
OptimismPortal_Test:test_OptimismPortalConstructor() (gas: 11413) OptimismPortal_Test:test_OptimismPortalConstructor() (gas: 11413)
OptimismPortal_Test:test_OptimismPortalContractCreationReverts() (gas: 9214) OptimismPortal_Test:test_OptimismPortalContractCreationReverts() (gas: 9214)
OptimismPortal_Test:test_OptimismPortalReceiveEth() (gas: 121706) OptimismPortal_Test:test_OptimismPortalReceiveEth() (gas: 121706)
OptimismPortal_Test:test_cannotVerifyRecentWithdrawal() (gas: 21863) OptimismPortal_Test:test_cannotVerifyRecentWithdrawal() (gas: 21886)
OptimismPortal_Test:test_depositTransaction_NoValueContract() (gas: 70746) OptimismPortal_Test:test_depositTransaction_NoValueContract() (gas: 70746)
OptimismPortal_Test:test_depositTransaction_NoValueEOA() (gas: 71114) OptimismPortal_Test:test_depositTransaction_NoValueEOA() (gas: 71114)
OptimismPortal_Test:test_depositTransaction_createWithZeroValueForContract() (gas: 70773) OptimismPortal_Test:test_depositTransaction_createWithZeroValueForContract() (gas: 70773)
...@@ -117,7 +117,7 @@ OptimismPortal_Test:test_depositTransaction_withEthValueAndContractContractCreat ...@@ -117,7 +117,7 @@ OptimismPortal_Test:test_depositTransaction_withEthValueAndContractContractCreat
OptimismPortal_Test:test_depositTransaction_withEthValueAndEOAContractCreation() (gas: 69947) OptimismPortal_Test:test_depositTransaction_withEthValueAndEOAContractCreation() (gas: 69947)
OptimismPortal_Test:test_depositTransaction_withEthValueFromContract() (gas: 77478) OptimismPortal_Test:test_depositTransaction_withEthValueFromContract() (gas: 77478)
OptimismPortal_Test:test_depositTransaction_withEthValueFromEOA() (gas: 78049) OptimismPortal_Test:test_depositTransaction_withEthValueFromEOA() (gas: 78049)
OptimismPortal_Test:test_invalidWithdrawalProof() (gas: 28541) OptimismPortal_Test:test_invalidWithdrawalProof() (gas: 33702)
Proxy_Test:test_clashingFunctionSignatures() (gas: 101427) Proxy_Test:test_clashingFunctionSignatures() (gas: 101427)
Proxy_Test:test_implementationKey() (gas: 20942) Proxy_Test:test_implementationKey() (gas: 20942)
Proxy_Test:test_implementationProxyCallIfNotAdmin() (gas: 30021) Proxy_Test:test_implementationProxyCallIfNotAdmin() (gas: 30021)
...@@ -163,5 +163,5 @@ ResourceMetering_Test:test_useMoreThanMaxReverts() (gas: 16024) ...@@ -163,5 +163,5 @@ ResourceMetering_Test:test_useMoreThanMaxReverts() (gas: 16024)
SequencerFeeVault_Test:test_constructor() (gas: 7611) SequencerFeeVault_Test:test_constructor() (gas: 7611)
SequencerFeeVault_Test:test_minWithdrawalAmount() (gas: 5429) SequencerFeeVault_Test:test_minWithdrawalAmount() (gas: 5429)
SequencerFeeVault_Test:test_receive() (gas: 17280) SequencerFeeVault_Test:test_receive() (gas: 17280)
SequencerFeeVault_Test:test_revertWithdraw() (gas: 9245) SequencerFeeVault_Test:test_revertWithdraw() (gas: 9266)
SequencerFeeVault_Test:test_withdraw() (gas: 147297) SequencerFeeVault_Test:test_withdraw() (gas: 147300)
...@@ -6,124 +6,149 @@ import { Ownable } from "@openzeppelin/contracts/access/Ownable.sol"; ...@@ -6,124 +6,149 @@ import { Ownable } from "@openzeppelin/contracts/access/Ownable.sol";
/** /**
* @title L2OutputOracle * @title L2OutputOracle
* @notice The L2 state is committed to in this contract * @notice The L2 state is committed to in this contract
* The payable keyword is used on appendL2Output to save gas on the msg.value check. * The payable keyword is used on appendL2Output to save gas on the msg.value check.
* This contract should be deployed behind an upgradable proxy * This contract should be deployed behind an upgradable proxy
*/ */
// slither-disable-next-line locked-ether // slither-disable-next-line locked-ether
contract L2OutputOracle is Ownable { contract L2OutputOracle is Ownable {
/********** /**
* Events * * @notice OutputProposal represents a commitment to the L2 state.
**********/ * The timestamp is the L1 timestamp that the output root is posted.
* This timestamp is used to verify that the finalization period
* has passed since the output root was submitted.
*/
struct OutputProposal {
bytes32 outputRoot;
uint256 timestamp;
}
/// @notice Emitted when an output is appended. /**
event l2OutputAppended( * @notice Emitted when an output is appended.
*
* @param _l2Output The output root.
* @param _l1Timestamp The L1 timestamp when appended.
* @param _l2BlockNumber The L2 block number of the output root.
*/
event L2OutputAppended(
bytes32 indexed _l2Output, bytes32 indexed _l2Output,
uint256 indexed _l1Timestamp, uint256 indexed _l1Timestamp,
uint256 indexed _l2timestamp uint256 indexed _l2BlockNumber
); );
/// @notice Emitted when an output is deleted. /**
event l2OutputDeleted( * @notice Emitted when an output is deleted.
*
* @param _l2Output The output root.
* @param _l1Timestamp The L1 timestamp when appended.
* @param _l2BlockNumber The L2 block number of the output root.
*/
event L2OutputDeleted(
bytes32 indexed _l2Output, bytes32 indexed _l2Output,
uint256 indexed _l1Timestamp, uint256 indexed _l1Timestamp,
uint256 indexed _l2timestamp uint256 indexed _l2BlockNumber
); );
/********************** /**
* Contract Variables * * @notice The interval in L2 blocks at which checkpoints must be submitted.
**********************/ */
/// @notice The interval in seconds at which checkpoints must be submitted.
uint256 public immutable SUBMISSION_INTERVAL; uint256 public immutable SUBMISSION_INTERVAL;
/// @notice The time between blocks on L2. /**
uint256 public immutable L2_BLOCK_TIME; * @notice The number of blocks in the chain before the first block in this contract.
*/
/// @notice The number of blocks in the chain before the first block in this contract.
uint256 public immutable HISTORICAL_TOTAL_BLOCKS; uint256 public immutable HISTORICAL_TOTAL_BLOCKS;
/// @notice The timestamp of the first L2 block recorded in this contract. /**
uint256 public immutable STARTING_BLOCK_TIMESTAMP; * @notice The number of the first L2 block recorded in this contract.
*/
uint256 public immutable STARTING_BLOCK_NUMBER;
/// @notice The timestamp of the most recent L2 block recorded in this contract. /**
uint256 public latestBlockTimestamp; * @notice The timestamp of the first L2 block recorded in this contract.
*/
uint256 public immutable STARTING_TIMESTAMP;
/// @notice A mapping from L2 timestamps to the output root for the block with that timestamp. /**
mapping(uint256 => OutputProposal) internal l2Outputs; * @notice The time between L2 blocks in seconds.
*/
uint256 public immutable L2_BLOCK_TIME;
/// @notice OutputProposal represents a commitment to the L2 state. /**
/// The timestamp is the L1 timestamp that the output root is posted. * @notice The number of the most recent L2 block recorded in this contract.
/// This timestamp is used to verify that the finalization period */
/// has passed since the output root was submitted. uint256 public latestBlockNumber;
struct OutputProposal {
bytes32 outputRoot;
uint256 timestamp;
}
/*************** /**
* Constructor * * @notice A mapping from L2 block numbers to the respective output root. Note that these
***************/ * outputs should not be considered finalized until the finalization period (as defined
* in the Optimism Portal) has passed.
*/
mapping(uint256 => OutputProposal) internal l2Outputs;
/** /**
* @notice Initialize the L2OutputOracle contract. * @notice Initialize the L2OutputOracle contract.
* @param _submissionInterval The desired interval in seconds at which *
* checkpoints must be submitted. * @param _submissionInterval The desired interval in seconds at which
* @param _l2BlockTime The desired L2 inter-block time in seconds. * checkpoints must be submitted.
* @param _genesisL2Output The initial L2 output of the L2 chain. * @param _genesisL2Output The initial L2 output of the L2 chain.
* @param _historicalTotalBlocks The number of blocks that preceding the * @param _historicalTotalBlocks The number of blocks that preceding the
* initialization of the L2 chain. * initialization of the L2 chain.
* @param _startingBlockTimestamp The timestamp to start L2 block at. * @param _startingBlockNumber The number of the first L2 block.
* @param _sequencer The address of the _sequencer. * @param _startingTimestamp The timestamp of the first L2 block.
* @param _l2BlockTime The timestamp of the first L2 block.
* @param _sequencer The address of the sequencer.
*/ */
constructor( constructor(
uint256 _submissionInterval, uint256 _submissionInterval,
uint256 _l2BlockTime,
bytes32 _genesisL2Output, bytes32 _genesisL2Output,
uint256 _historicalTotalBlocks, uint256 _historicalTotalBlocks,
uint256 _startingBlockTimestamp, uint256 _startingBlockNumber,
uint256 _startingTimestamp,
uint256 _l2BlockTime,
address _sequencer address _sequencer
) { ) {
require( require(
_submissionInterval % _l2BlockTime == 0, _l2BlockTime < block.timestamp,
"Submission Interval must be a multiple of L2 Block Time" "Output Oracle: Initial L2 block time must be less than current time"
); );
SUBMISSION_INTERVAL = _submissionInterval; SUBMISSION_INTERVAL = _submissionInterval;
L2_BLOCK_TIME = _l2BlockTime;
// solhint-disable-next-line not-rely-on-time
l2Outputs[_startingBlockTimestamp] = OutputProposal(_genesisL2Output, block.timestamp);
HISTORICAL_TOTAL_BLOCKS = _historicalTotalBlocks; HISTORICAL_TOTAL_BLOCKS = _historicalTotalBlocks;
// solhint-disable-next-line not-rely-on-time STARTING_BLOCK_NUMBER = _startingBlockNumber;
latestBlockTimestamp = _startingBlockTimestamp; STARTING_TIMESTAMP = _startingTimestamp;
// solhint-disable-next-line not-rely-on-time L2_BLOCK_TIME = _l2BlockTime;
STARTING_BLOCK_TIMESTAMP = _startingBlockTimestamp;
l2Outputs[_startingBlockNumber] = OutputProposal(_genesisL2Output, block.timestamp);
latestBlockNumber = _startingBlockNumber;
_transferOwnership(_sequencer); _transferOwnership(_sequencer);
} }
/*********************************
* External and Public Functions *
*********************************/
/** /**
* @notice Accepts an L2 outputRoot and the timestamp of the corresponding L2 block. The * @notice Accepts an L2 outputRoot and the timestamp of the corresponding L2 block. The
* timestamp must be equal to the current value returned by `nextTimestamp()` in order to be * timestamp must be equal to the current value returned by `nextTimestamp()` in order
* accepted. * to be accepted.
* This function may only be called by the Sequencer. * This function may only be called by the Sequencer.
* @param _l2Output The L2 output of the checkpoint block. *
* @param _l2timestamp The L2 block timestamp that resulted in _l2Output. * @param _l2Output The L2 output of the checkpoint block.
* @param _l1Blockhash A block hash which must be included in the current chain. * @param _l2BlockNumber The L2 block number that resulted in _l2Output.
* @param _l1Blocknumber The block number with the specified block hash. * @param _l1Blockhash A block hash which must be included in the current chain.
* @param _l1BlockNumber The block number with the specified block hash.
*/ */
function appendL2Output( function appendL2Output(
bytes32 _l2Output, bytes32 _l2Output,
uint256 _l2timestamp, uint256 _l2BlockNumber,
bytes32 _l1Blockhash, bytes32 _l1Blockhash,
uint256 _l1Blocknumber uint256 _l1BlockNumber
) external payable onlyOwner { ) external payable onlyOwner {
require(_l2timestamp < block.timestamp, "Cannot append L2 output in future"); require(
require(_l2timestamp == nextTimestamp(), "Timestamp not equal to next expected timestamp"); _l2BlockNumber == nextBlockNumber(),
require(_l2Output != bytes32(0), "Cannot submit empty L2 output"); "OutputOracle: Block number must be equal to next expected block number."
);
require(
computeL2Timestamp(_l2BlockNumber) < block.timestamp,
"OutputOracle: Cannot append L2 output in future."
);
require(_l2Output != bytes32(0), "OutputOracle: Cannot submit empty L2 output.");
if (_l1Blockhash != bytes32(0)) { if (_l1Blockhash != bytes32(0)) {
// This check allows the sequencer to append an output based on a given L1 block, // This check allows the sequencer to append an output based on a given L1 block,
...@@ -135,71 +160,74 @@ contract L2OutputOracle is Ownable { ...@@ -135,71 +160,74 @@ contract L2OutputOracle is Ownable {
// blockhash value, and delay submission until it is confident that the L1 block is // blockhash value, and delay submission until it is confident that the L1 block is
// finalized. // finalized.
require( require(
blockhash(_l1Blocknumber) == _l1Blockhash, blockhash(_l1BlockNumber) == _l1Blockhash,
"Blockhash does not match the hash at the expected height." "OutputOracle: Blockhash does not match the hash at the expected height."
); );
} }
l2Outputs[_l2timestamp] = OutputProposal(_l2Output, block.timestamp); l2Outputs[_l2BlockNumber] = OutputProposal(_l2Output, block.timestamp);
latestBlockTimestamp = _l2timestamp; latestBlockNumber = _l2BlockNumber;
emit l2OutputAppended(_l2Output, block.timestamp, _l2timestamp); emit L2OutputAppended(_l2Output, block.timestamp, _l2BlockNumber);
} }
/** /**
* @notice Deletes the most recent output. * @notice Deletes the most recent output.
*
* @param _proposal Represents the output proposal to delete * @param _proposal Represents the output proposal to delete
*/ */
function deleteL2Output(OutputProposal memory _proposal) external onlyOwner { function deleteL2Output(OutputProposal memory _proposal) external onlyOwner {
OutputProposal memory outputToDelete = l2Outputs[latestBlockTimestamp]; OutputProposal memory outputToDelete = l2Outputs[latestBlockNumber];
require( require(
_proposal.outputRoot == outputToDelete.outputRoot, _proposal.outputRoot == outputToDelete.outputRoot,
"Can only delete the most recent output." "OutputOracle: The output root to delete does not match the latest output proposal."
);
require(
_proposal.timestamp == outputToDelete.timestamp,
"OutputOracle: The timestamp to delete does not match the latest output proposal."
); );
require(_proposal.timestamp == outputToDelete.timestamp, "");
emit l2OutputDeleted( emit L2OutputDeleted(
outputToDelete.outputRoot, outputToDelete.outputRoot,
outputToDelete.timestamp, outputToDelete.timestamp,
latestBlockTimestamp latestBlockNumber
); );
delete l2Outputs[latestBlockTimestamp]; delete l2Outputs[latestBlockNumber];
latestBlockTimestamp = latestBlockTimestamp - SUBMISSION_INTERVAL; latestBlockNumber = latestBlockNumber - SUBMISSION_INTERVAL;
} }
/** /**
* @notice Computes the timestamp of the next L2 block that needs to be checkpointed. * @notice Computes the block number of the next L2 block that needs to be checkpointed.
*/ */
function nextTimestamp() public view returns (uint256) { function nextBlockNumber() public view returns (uint256) {
return latestBlockTimestamp + SUBMISSION_INTERVAL; return latestBlockNumber + SUBMISSION_INTERVAL;
} }
/** /**
* @notice Returns the L2 output proposal given a target L2 block timestamp. * @notice Returns the L2 output proposal given a target L2 block number.
* Returns a null output proposal if none is found. * Returns a null output proposal if none is found.
* @param _l2Timestamp The L2 block timestamp of the target block. *
* @param _l2BlockNumber The L2 block number of the target block.
*/ */
function getL2Output(uint256 _l2Timestamp) external view returns (OutputProposal memory) { function getL2Output(uint256 _l2BlockNumber) external view returns (OutputProposal memory) {
return l2Outputs[_l2Timestamp]; return l2Outputs[_l2BlockNumber];
} }
/** /**
* @notice Computes the L2 block number given a target L2 block timestamp. * @notice Returns the L2 timestamp corresponding to a given L2 block number.
* @param _l2timestamp The L2 block timestamp of the target block. * Returns a null output proposal if none is found.
*
* @param _l2BlockNumber The L2 block number of the target block.
*/ */
function computeL2BlockNumber(uint256 _l2timestamp) external view returns (uint256) { function computeL2Timestamp(uint256 _l2BlockNumber) public view returns (uint256) {
require( require(
_l2timestamp >= STARTING_BLOCK_TIMESTAMP, _l2BlockNumber >= STARTING_BLOCK_NUMBER,
"Timestamp prior to startingBlockTimestamp" "OutputOracle: Block number must be greater than or equal to the starting block number."
); );
// For the first block recorded (ie. _l2timestamp = STARTING_BLOCK_TIMESTAMP), the
// L2BlockNumber should be HISTORICAL_TOTAL_BLOCKS + 1. return
unchecked { STARTING_TIMESTAMP + ((_l2BlockNumber - STARTING_BLOCK_NUMBER) * SUBMISSION_INTERVAL);
return
HISTORICAL_TOTAL_BLOCKS +
((_l2timestamp - STARTING_BLOCK_TIMESTAMP) / L2_BLOCK_TIME);
}
} }
} }
...@@ -150,7 +150,7 @@ contract OptimismPortal is ResourceMetering { ...@@ -150,7 +150,7 @@ contract OptimismPortal is ResourceMetering {
* @param _value ETH to send to the target. * @param _value ETH to send to the target.
* @param _gasLimit Minumum gas to be forwarded to the target. * @param _gasLimit Minumum gas to be forwarded to the target.
* @param _data Data to send to the target. * @param _data Data to send to the target.
* @param _l2Timestamp L2 timestamp of the outputRoot. * @param _l2BlockNumber L2 block number of the outputRoot.
* @param _outputRootProof Inclusion proof of the withdrawer contracts storage root. * @param _outputRootProof Inclusion proof of the withdrawer contracts storage root.
* @param _withdrawalProof Inclusion proof for the given withdrawal in the withdrawer contract. * @param _withdrawalProof Inclusion proof for the given withdrawal in the withdrawer contract.
*/ */
...@@ -161,7 +161,7 @@ contract OptimismPortal is ResourceMetering { ...@@ -161,7 +161,7 @@ contract OptimismPortal is ResourceMetering {
uint256 _value, uint256 _value,
uint256 _gasLimit, uint256 _gasLimit,
bytes calldata _data, bytes calldata _data,
uint256 _l2Timestamp, uint256 _l2BlockNumber,
WithdrawalVerifier.OutputRootProof calldata _outputRootProof, WithdrawalVerifier.OutputRootProof calldata _outputRootProof,
bytes calldata _withdrawalProof bytes calldata _withdrawalProof
) external payable { ) external payable {
...@@ -179,7 +179,7 @@ contract OptimismPortal is ResourceMetering { ...@@ -179,7 +179,7 @@ contract OptimismPortal is ResourceMetering {
); );
// Get the output root. // Get the output root.
L2OutputOracle.OutputProposal memory proposal = L2_ORACLE.getL2Output(_l2Timestamp); L2OutputOracle.OutputProposal memory proposal = L2_ORACLE.getL2Output(_l2BlockNumber);
// Ensure that enough time has passed since the proposal was submitted before allowing a // Ensure that enough time has passed since the proposal was submitted before allowing a
// withdrawal. Under the assumption that the fault proof mechanism is operating correctly, // withdrawal. Under the assumption that the fault proof mechanism is operating correctly,
......
...@@ -47,33 +47,35 @@ contract L2OutputOracle_Initializer is CommonTest { ...@@ -47,33 +47,35 @@ contract L2OutputOracle_Initializer is CommonTest {
L2OutputOracle oracle; L2OutputOracle oracle;
// Constructor arguments // Constructor arguments
address sequencer = 0x000000000000000000000000000000000000AbBa; uint256 submissionInterval = 42;
uint256 submissionInterval = 1800;
uint256 l2BlockTime = 2;
bytes32 genesisL2Output = keccak256(abi.encode(0)); bytes32 genesisL2Output = keccak256(abi.encode(0));
uint256 historicalTotalBlocks = 100; uint256 historicalTotalBlocks = 199;
uint256 startingBlockNumber = 200;
// Cache of the initial L2 timestamp uint256 startingTimestamp = 1000;
uint256 startingBlockTimestamp; uint256 l2BlockTime = 2;
address sequencer = 0x000000000000000000000000000000000000AbBa;
// By default the first block has timestamp zero, which will cause underflows in the tests // Test data
uint256 initTime = 1000; uint256 initL1Time;
function setUp() public virtual { function setUp() public virtual {
_setUp(); _setUp();
// Move time forward so we have a non-zero starting timestamp // By default the first block has timestamp and number zero, which will cause underflows in the
vm.warp(initTime); // tests, so we'll move forward to these block values.
initL1Time = startingTimestamp + 1;
vm.warp(initL1Time);
vm.roll(startingBlockNumber);
// Deploy the L2OutputOracle and transfer owernship to the sequencer // Deploy the L2OutputOracle and transfer owernship to the sequencer
oracle = new L2OutputOracle( oracle = new L2OutputOracle(
submissionInterval, submissionInterval,
l2BlockTime,
genesisL2Output, genesisL2Output,
historicalTotalBlocks, historicalTotalBlocks,
initTime, startingBlockNumber,
startingTimestamp,
l2BlockTime,
sequencer sequencer
); );
startingBlockTimestamp = block.timestamp;
} }
} }
......
...@@ -11,85 +11,79 @@ contract L2OutputOracleTest is L2OutputOracle_Initializer { ...@@ -11,85 +11,79 @@ contract L2OutputOracleTest is L2OutputOracle_Initializer {
super.setUp(); super.setUp();
} }
// advance the evm state to meet the L2OutputOracle's requirements for appendL2Output
function oracleWarpRoll(uint256 _nextBlockNumber) public {
vm.roll(_nextBlockNumber);
vm.warp(oracle.computeL2Timestamp(_nextBlockNumber) + 1);
}
function test_constructor() external { function test_constructor() external {
assertEq(oracle.owner(), sequencer); assertEq(oracle.owner(), sequencer);
assertEq(oracle.SUBMISSION_INTERVAL(), submissionInterval); assertEq(oracle.SUBMISSION_INTERVAL(), submissionInterval);
assertEq(oracle.L2_BLOCK_TIME(), l2BlockTime);
assertEq(oracle.HISTORICAL_TOTAL_BLOCKS(), historicalTotalBlocks); assertEq(oracle.HISTORICAL_TOTAL_BLOCKS(), historicalTotalBlocks);
assertEq(oracle.latestBlockTimestamp(), startingBlockTimestamp); assertEq(oracle.latestBlockNumber(), startingBlockNumber);
assertEq(oracle.STARTING_BLOCK_TIMESTAMP(), startingBlockTimestamp); assertEq(oracle.STARTING_BLOCK_NUMBER(), startingBlockNumber);
assertEq(oracle.STARTING_TIMESTAMP(), startingTimestamp);
L2OutputOracle.OutputProposal memory proposal = oracle.getL2Output(startingBlockTimestamp); L2OutputOracle.OutputProposal memory proposal = oracle.getL2Output(startingBlockNumber);
assertEq(proposal.outputRoot, genesisL2Output); assertEq(proposal.outputRoot, genesisL2Output);
assertEq(proposal.timestamp, initTime); assertEq(proposal.timestamp, initL1Time);
} }
/**************** /****************
* Getter Tests * * Getter Tests *
****************/ ****************/
// Test: latestBlockTimestamp() should return the correct value // Test: latestBlockNumber() should return the correct value
function test_latestBlockTimestamp() external { function test_latestBlockNumber() external {
uint256 appendedTimestamp = oracle.nextTimestamp(); uint256 appendedNumber = oracle.nextBlockNumber();
// Warp to after the timestamp we'll append // Roll to after the block number we'll append
vm.warp(appendedTimestamp + 1); oracleWarpRoll(appendedNumber);
vm.prank(sequencer); vm.prank(sequencer);
oracle.appendL2Output(appendedOutput1, appendedTimestamp, 0, 0); oracle.appendL2Output(appendedOutput1, appendedNumber, 0, 0);
assertEq(oracle.latestBlockTimestamp(), appendedTimestamp); assertEq(oracle.latestBlockNumber(), appendedNumber);
} }
// Test: getL2Output() should return the correct value // Test: getL2Output() should return the correct value
function test_getL2Output() external { function test_getL2Output() external {
uint256 nextTimestamp = oracle.nextTimestamp(); uint256 nextBlockNumber = oracle.nextBlockNumber();
oracleWarpRoll(nextBlockNumber);
vm.warp(nextTimestamp + 1);
vm.prank(sequencer); vm.prank(sequencer);
oracle.appendL2Output(appendedOutput1, nextTimestamp, 0, 0); oracle.appendL2Output(appendedOutput1, nextBlockNumber, 0, 0);
L2OutputOracle.OutputProposal memory proposal = oracle.getL2Output(nextTimestamp); L2OutputOracle.OutputProposal memory proposal = oracle.getL2Output(nextBlockNumber);
assertEq(proposal.outputRoot, appendedOutput1); assertEq(proposal.outputRoot, appendedOutput1);
assertEq(proposal.timestamp, nextTimestamp + 1); assertEq(proposal.timestamp, block.timestamp);
L2OutputOracle.OutputProposal memory proposal2 = oracle.getL2Output(0); L2OutputOracle.OutputProposal memory proposal2 = oracle.getL2Output(0);
assertEq(proposal2.outputRoot, bytes32(0)); assertEq(proposal2.outputRoot, bytes32(0));
assertEq(proposal2.timestamp, 0); assertEq(proposal2.timestamp, 0);
} }
// Test: nextTimestamp() should return the correct value // Test: nextBlockNumber() should return the correct value
function test_nextTimestamp() external { function test_nextBlockNumber() external {
assertEq( assertEq(
oracle.nextTimestamp(), oracle.nextBlockNumber(),
// The return value should match this arithmetic // The return value should match this arithmetic
oracle.latestBlockTimestamp() + oracle.SUBMISSION_INTERVAL() oracle.latestBlockNumber() + oracle.SUBMISSION_INTERVAL()
); );
} }
// Test: computeL2BlockNumber() should return the correct value function test_computeL2Timestamp() external {
function test_computeL2BlockNumber() external { // reverts if timestamp is too low
// Test with the timestamp of the very first appended block vm.expectRevert("OutputOracle: Block number must be greater than or equal to the starting block number.");
uint256 argTimestamp = startingBlockTimestamp; oracle.computeL2Timestamp(startingBlockNumber - 1);
uint256 expected = historicalTotalBlocks;
assertEq(oracle.computeL2BlockNumber(argTimestamp), expected);
// Test with an integer multiple of the l2BlockTime
argTimestamp = startingBlockTimestamp + 20;
expected = historicalTotalBlocks + (20 / l2BlockTime);
assertEq(oracle.computeL2BlockNumber(argTimestamp), expected);
// Test with a remainder
argTimestamp = startingBlockTimestamp + 33;
expected = historicalTotalBlocks + (33 / l2BlockTime);
assertEq(oracle.computeL2BlockNumber(argTimestamp), expected);
}
// Test: computeL2BlockNumber() fails with a blockNumber from before the startingBlockTimestamp // returns the correct value...
function testCannot_computePreHistoricalL2BlockNumber() external { // ... for the very first block
bytes memory expectedError = "Timestamp prior to startingBlockTimestamp"; assertEq(oracle.computeL2Timestamp(startingBlockNumber), startingTimestamp);
uint256 argTimestamp = startingBlockTimestamp - 1;
vm.expectRevert(expectedError); // ... for the first block after the starting block
oracle.computeL2BlockNumber(argTimestamp); assertEq(oracle.computeL2Timestamp(startingBlockNumber + 1), startingTimestamp + submissionInterval);
// ... for some other block number
assertEq(oracle.computeL2Timestamp(startingBlockNumber + 96024), startingTimestamp + submissionInterval * 96024);
} }
/***************************** /*****************************
...@@ -100,37 +94,29 @@ contract L2OutputOracleTest is L2OutputOracle_Initializer { ...@@ -100,37 +94,29 @@ contract L2OutputOracleTest is L2OutputOracle_Initializer {
// specified. // specified.
function test_appendingAnotherOutput() public { function test_appendingAnotherOutput() public {
bytes32 appendedOutput2 = keccak256(abi.encode(2)); bytes32 appendedOutput2 = keccak256(abi.encode(2));
uint256 nextTimestamp = oracle.nextTimestamp(); uint256 nextBlockNumber = oracle.nextBlockNumber();
oracleWarpRoll(nextBlockNumber);
uint256 appendedTimestamp = oracle.latestBlockTimestamp(); uint256 appendedNumber = oracle.latestBlockNumber();
// Ensure the submissionInterval is enforced // Ensure the submissionInterval is enforced
assertEq(nextTimestamp, appendedTimestamp + submissionInterval); assertEq(nextBlockNumber, appendedNumber + submissionInterval);
vm.warp(nextTimestamp + 1); vm.roll(nextBlockNumber + 1);
vm.prank(sequencer); vm.prank(sequencer);
oracle.appendL2Output(appendedOutput2, nextTimestamp, 0, 0); oracle.appendL2Output(appendedOutput2, nextBlockNumber, 0, 0);
} }
// Test: appendL2Output succeeds when given valid input, and when a block hash and number are // Test: appendL2Output succeeds when given valid input, and when a block hash and number are
// specified for reorg protection. // specified for reorg protection.
// This tests is disabled (w/ skip_ prefix) because all blocks in Foundry currently have a function test_appendWithBlockhashAndHeight() external {
// blockhash of zero.
function skip_test_appendWithBlockhashAndHeight() external {
// Move ahead to block 100 so that we can reference historical blocks
vm.roll(100);
// Get the number and hash of a previous block in the chain // Get the number and hash of a previous block in the chain
uint256 l1BlockNumber = block.number - 1; uint256 prevL1BlockNumber = block.number - 1;
bytes32 l1BlockHash = blockhash(l1BlockNumber); bytes32 prevL1BlockHash = blockhash(prevL1BlockNumber);
uint256 nextTimestamp = oracle.nextTimestamp(); uint256 nextBlockNumber = oracle.nextBlockNumber();
vm.warp(nextTimestamp + 1); oracleWarpRoll(nextBlockNumber);
vm.prank(sequencer); vm.prank(sequencer);
oracle.appendL2Output(nonZeroHash, nextBlockNumber, prevL1BlockHash, prevL1BlockNumber);
// Changing the l1BlockNumber argument should break this tests, however it does not
// per the comment preceding this test.
oracle.appendL2Output(nonZeroHash, nextTimestamp, l1BlockHash, l1BlockNumber);
} }
/*************************** /***************************
...@@ -139,49 +125,55 @@ contract L2OutputOracleTest is L2OutputOracle_Initializer { ...@@ -139,49 +125,55 @@ contract L2OutputOracleTest is L2OutputOracle_Initializer {
// Test: appendL2Output fails if called by a party that is not the sequencer. // Test: appendL2Output fails if called by a party that is not the sequencer.
function testCannot_appendOutputIfNotSequencer() external { function testCannot_appendOutputIfNotSequencer() external {
uint256 nextTimestamp = oracle.nextTimestamp(); uint256 nextBlockNumber = oracle.nextBlockNumber();
oracleWarpRoll(nextBlockNumber);
vm.prank(address(128)); vm.prank(address(128));
vm.warp(nextTimestamp + 1);
vm.expectRevert("Ownable: caller is not the owner"); vm.expectRevert("Ownable: caller is not the owner");
oracle.appendL2Output(nonZeroHash, nextTimestamp, 0, 0); oracle.appendL2Output(nonZeroHash, nextBlockNumber, 0, 0);
} }
// Test: appendL2Output fails given a zero blockhash. // Test: appendL2Output fails given a zero blockhash.
function testCannot_appendEmptyOutput() external { function testCannot_appendEmptyOutput() external {
bytes32 outputToAppend = bytes32(0); bytes32 outputToAppend = bytes32(0);
uint256 nextTimestamp = oracle.nextTimestamp(); uint256 nextBlockNumber = oracle.nextBlockNumber();
vm.warp(nextTimestamp + 1); oracleWarpRoll(nextBlockNumber);
vm.prank(sequencer); vm.prank(sequencer);
vm.expectRevert("Cannot submit empty L2 output"); vm.expectRevert("OutputOracle: Cannot submit empty L2 output.");
oracle.appendL2Output(outputToAppend, nextTimestamp, 0, 0); oracle.appendL2Output(outputToAppend, nextBlockNumber, 0, 0);
} }
// Test: appendL2Output fails if the timestamp doesn't match the next expected timestamp. // Test: appendL2Output fails if the block number doesn't match the next expected number.
function testCannot_appendUnexpectedTimestamp() external { function testCannot_appendUnexpectedBlockNumber() external {
uint256 nextTimestamp = oracle.nextTimestamp(); uint256 nextBlockNumber = oracle.nextBlockNumber();
vm.warp(nextTimestamp + 1); oracleWarpRoll(nextBlockNumber);
vm.prank(sequencer); vm.prank(sequencer);
vm.expectRevert("Timestamp not equal to next expected timestamp"); vm.expectRevert("OutputOracle: Block number must be equal to next expected block number.");
oracle.appendL2Output(nonZeroHash, nextTimestamp - 1, 0, 0); oracle.appendL2Output(nonZeroHash, nextBlockNumber - 1, 0, 0);
} }
// Test: appendL2Output fails if it would have a timestamp in the future.
// Test: appendL2Output fails if the timestamp is equal to the current L1 timestamp. function testCannot_appendFutureTimetamp() external {
function testCannot_appendCurrentTimestamp() external { uint256 nextBlockNumber = oracle.nextBlockNumber();
uint256 nextTimestamp = oracle.nextTimestamp(); uint256 nextTimestamp = oracle.computeL2Timestamp(nextBlockNumber);
vm.warp(nextTimestamp + 1); vm.warp(nextTimestamp);
vm.prank(sequencer); vm.prank(sequencer);
vm.expectRevert("Cannot append L2 output in future"); vm.expectRevert("OutputOracle: Cannot append L2 output in future.");
oracle.appendL2Output(nonZeroHash, block.timestamp, 0, 0); oracle.appendL2Output(nonZeroHash, nextBlockNumber, 0, 0);
} }
// Test: appendL2Output fails if the timestamp is in the future. // Test: appendL2Output fails if a non-existent L1 block hash and number are provided for reorg
function testCannot_appendFutureTimestamp() external { // protection.
uint256 nextTimestamp = oracle.nextTimestamp(); function testCannot_appendOnWrongFork() external {
vm.warp(nextTimestamp + 1); uint256 nextBlockNumber = oracle.nextBlockNumber();
oracleWarpRoll(nextBlockNumber);
vm.prank(sequencer); vm.prank(sequencer);
vm.expectRevert("Cannot append L2 output in future"); vm.expectRevert("OutputOracle: Blockhash does not match the hash at the expected height.");
oracle.appendL2Output(nonZeroHash, block.timestamp + 1, 0, 0); oracle.appendL2Output(
nonZeroHash,
nextBlockNumber,
bytes32(uint256(0x01)),
block.number - 1
);
} }
// Test: appendL2Output fails when given valid input, but the block hash and number do not // Test: appendL2Output fails when given valid input, but the block hash and number do not
...@@ -196,56 +188,57 @@ contract L2OutputOracleTest is L2OutputOracle_Initializer { ...@@ -196,56 +188,57 @@ contract L2OutputOracleTest is L2OutputOracle_Initializer {
uint256 l1BlockNumber = block.number - 1; uint256 l1BlockNumber = block.number - 1;
bytes32 l1BlockHash = blockhash(l1BlockNumber); bytes32 l1BlockHash = blockhash(l1BlockNumber);
uint256 nextTimestamp = oracle.nextTimestamp(); uint256 nextBlockNumber = oracle.nextBlockNumber();
vm.warp(nextTimestamp + 1); oracleWarpRoll(nextBlockNumber);
vm.prank(sequencer); vm.prank(sequencer);
// This will fail when foundry no longer returns zerod block hashes // This will fail when foundry no longer returns zerod block hashes
oracle.appendL2Output(nonZeroHash, nextTimestamp, l1BlockHash, l1BlockNumber - 1); oracle.appendL2Output(nonZeroHash, nextBlockNumber, l1BlockHash, l1BlockNumber - 1);
} }
/**************** /****************
* Delete Tests * * Delete Tests *
****************/ ****************/
event l2OutputDeleted( event L2OutputDeleted(
bytes32 indexed _l2Output, bytes32 indexed _l2Output,
uint256 indexed _l1Timestamp, uint256 indexed _l1Timestamp,
uint256 indexed _l2timestamp uint256 indexed _l2BlockNumber
); );
function test_deleteL2Output() external { function test_deleteL2Output() external {
test_appendingAnotherOutput(); test_appendingAnotherOutput();
uint256 latestBlockTimestamp = oracle.latestBlockTimestamp(); uint256 latestBlockNumber = oracle.latestBlockNumber();
L2OutputOracle.OutputProposal memory proposalToDelete = oracle.getL2Output(latestBlockTimestamp); L2OutputOracle.OutputProposal memory proposalToDelete = oracle.getL2Output(latestBlockNumber);
L2OutputOracle.OutputProposal memory newLatestOutput = oracle.getL2Output(latestBlockTimestamp - submissionInterval); L2OutputOracle.OutputProposal memory newLatestOutput = oracle.getL2Output(latestBlockNumber - submissionInterval);
vm.prank(sequencer); vm.prank(sequencer);
vm.expectEmit(true, true, false, false); vm.expectEmit(true, true, false, false);
emit l2OutputDeleted( emit L2OutputDeleted(
proposalToDelete.outputRoot, proposalToDelete.outputRoot,
proposalToDelete.timestamp, proposalToDelete.timestamp,
latestBlockTimestamp latestBlockNumber
); );
oracle.deleteL2Output(proposalToDelete); oracle.deleteL2Output(proposalToDelete);
// validate latestBlockTimestamp has been reduced // validate latestBlockNumber has been reduced
uint256 latestBlockTimestampAfter = oracle.latestBlockTimestamp(); uint256 latestBlockNumberAfter = oracle.latestBlockNumber();
assertEq( assertEq(
latestBlockTimestamp - submissionInterval, latestBlockNumber - submissionInterval,
latestBlockTimestampAfter latestBlockNumberAfter
); );
L2OutputOracle.OutputProposal memory proposal = oracle.getL2Output(latestBlockTimestampAfter); L2OutputOracle.OutputProposal memory proposal = oracle.getL2Output(latestBlockNumberAfter);
// validate that the new latest output is as expected. // validate that the new latest output is as expected.
assertEq(newLatestOutput.outputRoot, proposal.outputRoot); assertEq(newLatestOutput.outputRoot, proposal.outputRoot);
assertEq(newLatestOutput.timestamp, proposal.timestamp); assertEq(newLatestOutput.timestamp, proposal.timestamp);
} }
function testCannot_deleteL2Output_ifNotSequencer() external { function testCannot_deleteL2Output_ifNotSequencer() external {
uint256 latestBlockTimestamp = oracle.latestBlockTimestamp(); uint256 latestBlockNumber = oracle.latestBlockNumber();
L2OutputOracle.OutputProposal memory proposal = oracle.getL2Output(latestBlockTimestamp); L2OutputOracle.OutputProposal memory proposal = oracle.getL2Output(latestBlockNumber);
vm.expectRevert("Ownable: caller is not the owner"); vm.expectRevert("Ownable: caller is not the owner");
oracle.deleteL2Output(proposal); oracle.deleteL2Output(proposal);
...@@ -254,11 +247,11 @@ contract L2OutputOracleTest is L2OutputOracle_Initializer { ...@@ -254,11 +247,11 @@ contract L2OutputOracleTest is L2OutputOracle_Initializer {
function testCannot_deleteWrongL2Output() external { function testCannot_deleteWrongL2Output() external {
test_appendingAnotherOutput(); test_appendingAnotherOutput();
uint256 previousBlockTimestamp = oracle.latestBlockTimestamp() - submissionInterval; uint256 previousBlockNumber = oracle.latestBlockNumber() - submissionInterval;
L2OutputOracle.OutputProposal memory proposalToDelete = oracle.getL2Output(previousBlockTimestamp); L2OutputOracle.OutputProposal memory proposalToDelete = oracle.getL2Output(previousBlockNumber);
vm.prank(sequencer); vm.prank(sequencer);
vm.expectRevert("Can only delete the most recent output."); vm.expectRevert("OutputOracle: The output root to delete does not match the latest output proposal.");
oracle.deleteL2Output(proposalToDelete); oracle.deleteL2Output(proposalToDelete);
} }
} }
//SPDX-License-Identifier: MIT //SPDX-License-Identifier: MIT
pragma solidity 0.8.10; pragma solidity 0.8.10;
import { CommonTest } from "./CommonTest.t.sol"; import { L2OutputOracle_Initializer } from "./CommonTest.t.sol";
import { AddressAliasHelper } from "../libraries/AddressAliasHelper.sol"; import { AddressAliasHelper } from "../libraries/AddressAliasHelper.sol";
import { L2OutputOracle } from "../L1/L2OutputOracle.sol"; import { L2OutputOracle } from "../L1/L2OutputOracle.sol";
import { OptimismPortal } from "../L1/OptimismPortal.sol"; import { OptimismPortal } from "../L1/OptimismPortal.sol";
import { WithdrawalVerifier } from "../libraries/Lib_WithdrawalVerifier.sol"; import { WithdrawalVerifier } from "../libraries/Lib_WithdrawalVerifier.sol";
contract OptimismPortal_Test is CommonTest { contract OptimismPortal_Test is L2OutputOracle_Initializer {
event TransactionDeposited( event TransactionDeposited(
address indexed from, address indexed from,
address indexed to, address indexed to,
...@@ -20,19 +20,11 @@ contract OptimismPortal_Test is CommonTest { ...@@ -20,19 +20,11 @@ contract OptimismPortal_Test is CommonTest {
); );
// Dependencies // Dependencies
L2OutputOracle oracle; // L2OutputOracle oracle;
OptimismPortal op; OptimismPortal op;
function setUp() external { function setUp() public override {
_setUp(); L2OutputOracle_Initializer.setUp();
oracle = new L2OutputOracle(
1800,
2,
keccak256(abi.encode(0)),
100,
1,
address(666)
);
op = new OptimismPortal(oracle, 7 days); op = new OptimismPortal(oracle, 7 days);
} }
...@@ -44,15 +36,7 @@ contract OptimismPortal_Test is CommonTest { ...@@ -44,15 +36,7 @@ contract OptimismPortal_Test is CommonTest {
function test_OptimismPortalReceiveEth() external { function test_OptimismPortalReceiveEth() external {
vm.expectEmit(true, true, false, true); vm.expectEmit(true, true, false, true);
emit TransactionDeposited( emit TransactionDeposited(alice, alice, 100, 100, 100_000, false, hex"");
alice,
alice,
100,
100,
100_000,
false,
hex""
);
// give alice money and send as an eoa // give alice money and send as an eoa
vm.deal(alice, 2**64); vm.deal(alice, 2**64);
...@@ -254,47 +238,35 @@ contract OptimismPortal_Test is CommonTest { ...@@ -254,47 +238,35 @@ contract OptimismPortal_Test is CommonTest {
// function test_verifyWithdrawal() external {} // function test_verifyWithdrawal() external {}
function test_cannotVerifyRecentWithdrawal() external { function test_cannotVerifyRecentWithdrawal() external {
WithdrawalVerifier.OutputRootProof memory outputRootProof = WithdrawalVerifier.OutputRootProof({ WithdrawalVerifier.OutputRootProof memory outputRootProof = WithdrawalVerifier
version: bytes32(0), .OutputRootProof({
stateRoot: bytes32(0), version: bytes32(0),
withdrawerStorageRoot: bytes32(0), stateRoot: bytes32(0),
latestBlockhash: bytes32(0) withdrawerStorageRoot: bytes32(0),
}); latestBlockhash: bytes32(0)
});
vm.expectRevert("OptimismPortal: proposal is not yet finalized"); vm.expectRevert("OptimismPortal: proposal is not yet finalized");
op.finalizeWithdrawalTransaction( op.finalizeWithdrawalTransaction(0, alice, alice, 0, 0, hex"", 0, outputRootProof, hex"");
0,
alice,
alice,
0,
0,
hex"",
0,
outputRootProof,
hex""
);
} }
function test_invalidWithdrawalProof() external { function test_invalidWithdrawalProof() external {
WithdrawalVerifier.OutputRootProof memory outputRootProof = WithdrawalVerifier.OutputRootProof({ WithdrawalVerifier.OutputRootProof memory outputRootProof = WithdrawalVerifier
version: bytes32(0), .OutputRootProof({
stateRoot: bytes32(0), version: bytes32(0),
withdrawerStorageRoot: bytes32(0), stateRoot: bytes32(0),
latestBlockhash: bytes32(0) withdrawerStorageRoot: bytes32(0),
}); latestBlockhash: bytes32(0)
});
vm.warp(oracle.nextTimestamp() + op.FINALIZATION_PERIOD_SECONDS());
vm.expectRevert("OptimismPortal: invalid output root proof"); vm.warp(
op.finalizeWithdrawalTransaction( oracle.getL2Output(
0, oracle.latestBlockNumber()
alice, ).timestamp
alice, + op.FINALIZATION_PERIOD_SECONDS()
0,
0,
hex"",
0,
outputRootProof,
hex""
); );
vm.expectRevert("OptimismPortal: invalid output root proof");
op.finalizeWithdrawalTransaction(0, alice, alice, 0, 0, hex"", 0, outputRootProof, hex"");
} }
} }
...@@ -91,28 +91,28 @@ where: ...@@ -91,28 +91,28 @@ where:
## L2 Output Oracle Smart Contract ## L2 Output Oracle Smart Contract
L2 blocks are produced at a constant rate of `L2_BLOCK_TIME` (2 seconds). L2 blocks are produced at a constant rate of `L2_BLOCK_TIME` (2 seconds).
A new L2 output MUST be appended to the chain once per `SUBMISSION_INTERVAL` (1800 seconds). Note that this interval is\ A new L2 output MUST be appended to the chain once per `SUBMISSION_INTERVAL` which is based on a number of blocks.
based on L2 time. It is OK to have L2 outputs submitted at larger or small intervals. The exact number is yet to be determined, and will depend on the design of the fault proving game.
The L2 Output Oracle contract implements the following interface: The L2 Output Oracle contract implements the following interface:
```js ```js
/** /**
* Accepts an L2 output checkpoint and the timestamp of the corresponding L2 * @notice Accepts an L2 outputRoot and the timestamp of the corresponding L2 block. The
* block. The timestamp must be equal to the current value returned by * timestamp must be equal to the current value returned by `nextTimestamp()` in order to be
* `nextTimestamp()` in order to be accepted. * accepted.
* This function may only be called by the Sequencer. * This function may only be called by the Sequencer.
* @param _l2Output The L2 output of the checkpoint block. * @param _l2Output The L2 output of the checkpoint block.
* @param _l2timestamp The L2 block timestamp that resulted in _l2Output. * @param _l2BlockNumber The L2 block number that resulted in _l2Output.
* @param _l1Blockhash A block hash which must be included in the current chain. * @param _l1Blockhash A block hash which must be included in the current chain.
* @param _l1Blocknumber The block number with the specified block hash. * @param _l1BlockNumber The block number with the specified block hash.
*/ */
function appendL2Output( function appendL2Output(
bytes32 _l2Output, bytes32 _l2Output,
uint256 _l2timestamp, uint256 _l2BlockNumber,
bytes32 _l1Blockhash, bytes32 _l1Blockhash,
uint256 _l1Blocknumber uint256 _l1BlockNumber
) )
/** /**
* @notice Deletes the most recent output. * @notice Deletes the most recent output.
...@@ -122,15 +122,9 @@ function appendL2Output( ...@@ -122,15 +122,9 @@ function appendL2Output(
function deleteL2Output(bytes32 _l2Output) external function deleteL2Output(bytes32 _l2Output) external
/** /**
* Computes the timestamp of the next L2 block that needs to be checkpointed. * @notice Computes the block number of the next L2 block that needs to be checkpointed.
*/
function nextTimestamp() public view returns (uint256)
/**
* Computes the L2 block number given a target L2 block timestamp.
* @param _timestamp The L2 block timestamp of the target block.
*/ */
function computeL2BlockNumber(uint256 _timestamp) public view returns (uint256) function nextBlockNumber() public view returns (uint256) {
``` ```
## Security Considerations ## Security Considerations
......
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