Commit 1f554526 authored by mergify[bot]'s avatar mergify[bot] Committed by GitHub

Merge branch 'develop' into jg/multi_arch_images

parents fda74a69 34ce8dad
---
"@eth-optimism/l2geth-exporter": patch
---
build(deps): bump golang.org/x/crypto from 0.0.0-20220307211146-efcb8507fb70 to 0.1.0 in /l2geth-exporter
---
"@eth-optimism/gas-oracle": patch
---
build(deps): bump golang.org/x/net from 0.0.0-20211112202133-69e39bad7dc2 to 0.7.0 in /gas-oracle
---
"@eth-optimism/gas-oracle": patch
---
build(deps): bump golang.org/x/sys from 0.0.0-20220310020820-b874c991c1a5 to 0.1.0 in /gas-oracle
---
"@eth-optimism/l2geth-exporter": patch
---
build(deps): bump golang.org/x/sys from 0.0.0-20220310020820-b874c991c1a5 to 0.1.0 in /l2geth-exporter
---
'@eth-optimism/atst': patch
---
Add new atst package
---
"@eth-optimism/batch-submitter-service": patch
---
build(deps): bump golang.org/x/crypto from 0.0.0-20220307211146-efcb8507fb70 to 0.1.0 in /batch-submitter
---
'@eth-optimism/atst': patch
---
Release ATST
...@@ -536,8 +536,7 @@ jobs: ...@@ -536,8 +536,7 @@ jobs:
# constraint that gotestsum does not currently (nor likely will) accept files from different pacakges when building. # constraint that gotestsum does not currently (nor likely will) accept files from different pacakges when building.
OP_TESTLOG_DISABLE_COLOR=true OP_E2E_DISABLE_PARALLEL=true OP_E2E_USE_HTTP=<<parameters.use_http>> gotestsum \ OP_TESTLOG_DISABLE_COLOR=true OP_E2E_DISABLE_PARALLEL=true OP_E2E_USE_HTTP=<<parameters.use_http>> gotestsum \
--format=standard-verbose --junitfile=/tmp/test-results/<<parameters.module>>_http_<<parameters.use_http>>.xml \ --format=standard-verbose --junitfile=/tmp/test-results/<<parameters.module>>_http_<<parameters.use_http>>.xml \
./... \ -- -timeout=20m ./...
-- -timeout=20m
working_directory: <<parameters.module>> working_directory: <<parameters.module>>
- store_test_results: - store_test_results:
path: /tmp/test-results path: /tmp/test-results
......
...@@ -19,6 +19,7 @@ ...@@ -19,6 +19,7 @@
/packages/migration-data @ethereum-optimism/legacy-reviewers /packages/migration-data @ethereum-optimism/legacy-reviewers
/packages/replica-healthcheck @ethereum-optimism/legacy-reviewers /packages/replica-healthcheck @ethereum-optimism/legacy-reviewers
/packages/sdk @ethereum-optimism/ecopod /packages/sdk @ethereum-optimism/ecopod
/packages/atst @ethereum-optimism/ecopod
# Bedrock codebases # Bedrock codebases
/bedrock-devnet @ethereum-optimism/go-reviewers /bedrock-devnet @ethereum-optimism/go-reviewers
......
...@@ -19,6 +19,7 @@ jobs: ...@@ -19,6 +19,7 @@ jobs:
message-relayer: ${{ steps.packages.outputs.message-relayer }} message-relayer: ${{ steps.packages.outputs.message-relayer }}
fault-detector: ${{ steps.packages.outputs.fault-detector }} fault-detector: ${{ steps.packages.outputs.fault-detector }}
drippie-mon: ${{ steps.packages.outputs.drippie-mon }} drippie-mon: ${{ steps.packages.outputs.drippie-mon }}
wd-mon: ${{ steps.packages.outputs.wd-mon }}
data-transport-layer: ${{ steps.packages.outputs.data-transport-layer }} data-transport-layer: ${{ steps.packages.outputs.data-transport-layer }}
contracts: ${{ steps.packages.outputs.contracts }} contracts: ${{ steps.packages.outputs.contracts }}
contracts-bedrock: ${{ steps.packages.outputs.contracts-bedrock }} contracts-bedrock: ${{ steps.packages.outputs.contracts-bedrock }}
...@@ -256,6 +257,33 @@ jobs: ...@@ -256,6 +257,33 @@ jobs:
push: true push: true
tags: ethereumoptimism/drippie-mon:${{ needs.canary-publish.outputs.canary-docker-tag }} tags: ethereumoptimism/drippie-mon:${{ needs.canary-publish.outputs.canary-docker-tag }}
wd-mon:
name: Publish Withdrawal Monitor Version ${{ needs.canary-publish.outputs.canary-docker-tag }}
needs: canary-publish
if: needs.canary-publish.outputs.wd-mon != ''
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v2
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v1
- name: Login to Docker Hub
uses: docker/login-action@v1
with:
username: ${{ secrets.DOCKERHUB_ACCESS_TOKEN_USERNAME }}
password: ${{ secrets.DOCKERHUB_ACCESS_TOKEN_SECRET }}
- name: Build and push
uses: docker/build-push-action@v2
with:
context: .
file: ./ops/docker/Dockerfile.packages
target: wd-mon
push: true
tags: ethereumoptimism/wd-mon:${{ needs.canary-publish.outputs.canary-docker-tag }}
data-transport-layer: data-transport-layer:
name: Publish Data Transport Layer Version ${{ needs.canary-publish.outputs.canary-docker-tag }} name: Publish Data Transport Layer Version ${{ needs.canary-publish.outputs.canary-docker-tag }}
needs: canary-publish needs: canary-publish
......
...@@ -15,6 +15,7 @@ jobs: ...@@ -15,6 +15,7 @@ jobs:
message-relayer: ${{ steps.packages.outputs.message-relayer }} message-relayer: ${{ steps.packages.outputs.message-relayer }}
fault-detector: ${{ steps.packages.outputs.fault-detector }} fault-detector: ${{ steps.packages.outputs.fault-detector }}
drippie-mon: ${{ steps.packages.outputs.drippie-mon }} drippie-mon: ${{ steps.packages.outputs.drippie-mon }}
wd-mon: ${{ steps.packages.outputs.wd-mon }}
data-transport-layer: ${{ steps.packages.outputs.data-transport-layer }} data-transport-layer: ${{ steps.packages.outputs.data-transport-layer }}
contracts: ${{ steps.packages.outputs.contracts }} contracts: ${{ steps.packages.outputs.contracts }}
contracts-bedrock: ${{ steps.packages.outputs.contracts-bedrock }} contracts-bedrock: ${{ steps.packages.outputs.contracts-bedrock }}
...@@ -336,6 +337,33 @@ jobs: ...@@ -336,6 +337,33 @@ jobs:
push: true push: true
tags: ethereumoptimism/fault-detector:${{ needs.release.outputs.fault-detector }},ethereumoptimism/fault-detector:latest tags: ethereumoptimism/fault-detector:${{ needs.release.outputs.fault-detector }},ethereumoptimism/fault-detector:latest
wd-mon:
name: Publish Withdrawal Monitor Version ${{ needs.release.outputs.wd-mon }}
needs: release
if: needs.release.outputs.wd-mon != ''
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v2
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v1
- name: Login to Docker Hub
uses: docker/login-action@v1
with:
username: ${{ secrets.DOCKERHUB_ACCESS_TOKEN_USERNAME }}
password: ${{ secrets.DOCKERHUB_ACCESS_TOKEN_SECRET }}
- name: Build and push
uses: docker/build-push-action@v2
with:
context: .
file: ./ops/docker/Dockerfile.packages
target: wd-mon
push: true
tags: ethereumoptimism/wd-mon:${{ needs.release.outputs.wd-mon }},ethereumoptimism/wd-mon:latest
drippie-mon: drippie-mon:
name: Publish Drippie Monitor Version ${{ needs.release.outputs.drippie-mon }} name: Publish Drippie Monitor Version ${{ needs.release.outputs.drippie-mon }}
needs: release needs: release
......
...@@ -70,22 +70,27 @@ You'll need the following: ...@@ -70,22 +70,27 @@ You'll need the following:
### Setup ### Setup
Clone the repository, open it, and install nodejs packages with `yarn`: Clone the repository and open it:
```bash ```bash
git clone git@github.com:ethereum-optimism/optimism.git git clone git@github.com:ethereum-optimism/optimism.git
cd optimism cd optimism
yarn install
``` ```
### Install the Correct Version of NodeJS ### Install the Correct Version of NodeJS
Using `nvm`, install the correct version of NodeJS. Install node v16.16.0 with [nvm](https://github.com/nvm-sh/nvm)
``` ```bash
nvm use nvm use
``` ```
### Install node modules with Yarn
```bash
yarn install
```
### Building the TypeScript packages ### Building the TypeScript packages
[foundry](https://github.com/foundry-rs/foundry) is used for some smart contract [foundry](https://github.com/foundry-rs/foundry) is used for some smart contract
......
# @eth-optimism/batch-submitter-service # @eth-optimism/batch-submitter-service
## 0.1.15
### Patch Changes
- 1d8d50c42: build(deps): bump golang.org/x/crypto from 0.0.0-20220307211146-efcb8507fb70 to 0.1.0 in /batch-submitter
## 0.1.14 ## 0.1.14
### Patch Changes ### Patch Changes
......
{ {
"name": "@eth-optimism/batch-submitter-service", "name": "@eth-optimism/batch-submitter-service",
"version": "0.1.14", "version": "0.1.15",
"private": true, "private": true,
"devDependencies": {} "devDependencies": {}
} }
# @eth-optimism/gas-oracle # @eth-optimism/gas-oracle
## 0.1.13
### Patch Changes
- 9b61c84c9: build(deps): bump golang.org/x/net from 0.0.0-20211112202133-69e39bad7dc2 to 0.7.0 in /gas-oracle
- f13b31e04: build(deps): bump golang.org/x/sys from 0.0.0-20220310020820-b874c991c1a5 to 0.1.0 in /gas-oracle
## 0.1.12 ## 0.1.12
### Patch Changes ### Patch Changes
......
{ {
"name": "@eth-optimism/gas-oracle", "name": "@eth-optimism/gas-oracle",
"version": "0.1.12", "version": "0.1.13",
"private": true, "private": true,
"devDependencies": {} "devDependencies": {}
} }
...@@ -32,6 +32,7 @@ require ( ...@@ -32,6 +32,7 @@ require (
github.com/urfave/cli v1.22.9 github.com/urfave/cli v1.22.9
github.com/urfave/cli/v2 v2.17.2-0.20221006022127-8f469abc00aa github.com/urfave/cli/v2 v2.17.2-0.20221006022127-8f469abc00aa
golang.org/x/crypto v0.6.0 golang.org/x/crypto v0.6.0
golang.org/x/exp v0.0.0-20230213192124-5e25df0256eb
golang.org/x/term v0.5.0 golang.org/x/term v0.5.0
) )
...@@ -174,7 +175,6 @@ require ( ...@@ -174,7 +175,6 @@ require (
go.uber.org/fx v1.19.1 // indirect go.uber.org/fx v1.19.1 // indirect
go.uber.org/multierr v1.9.0 // indirect go.uber.org/multierr v1.9.0 // indirect
go.uber.org/zap v1.24.0 // indirect go.uber.org/zap v1.24.0 // indirect
golang.org/x/exp v0.0.0-20230213192124-5e25df0256eb // indirect
golang.org/x/mod v0.8.0 // indirect golang.org/x/mod v0.8.0 // indirect
golang.org/x/net v0.7.0 // indirect golang.org/x/net v0.7.0 // indirect
golang.org/x/sync v0.1.0 // indirect golang.org/x/sync v0.1.0 // indirect
...@@ -191,6 +191,6 @@ require ( ...@@ -191,6 +191,6 @@ require (
nhooyr.io/websocket v1.8.7 // indirect nhooyr.io/websocket v1.8.7 // indirect
) )
replace github.com/ethereum/go-ethereum v1.11.2 => github.com/ethereum-optimism/op-geth v1.11.2-aea0402.0.20230227230209-0705cf1b7df9 replace github.com/ethereum/go-ethereum v1.11.2 => github.com/ethereum-optimism/op-geth v1.11.2-aea0402.0.20230301232322-c407b2a217b7
//replace github.com/ethereum/go-ethereum v1.11.2 => ../go-ethereum //replace github.com/ethereum/go-ethereum v1.11.2 => ../go-ethereum
...@@ -217,8 +217,8 @@ github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7 ...@@ -217,8 +217,8 @@ github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7
github.com/etcd-io/bbolt v1.3.3/go.mod h1:ZF2nL25h33cCyBtcyWeZ2/I3HQOfTP+0PIEvHjkjCrw= github.com/etcd-io/bbolt v1.3.3/go.mod h1:ZF2nL25h33cCyBtcyWeZ2/I3HQOfTP+0PIEvHjkjCrw=
github.com/ethereum-optimism/go-ethereum-hdwallet v0.1.3 h1:RWHKLhCrQThMfch+QJ1Z8veEq5ZO3DfIhZ7xgRP9WTc= github.com/ethereum-optimism/go-ethereum-hdwallet v0.1.3 h1:RWHKLhCrQThMfch+QJ1Z8veEq5ZO3DfIhZ7xgRP9WTc=
github.com/ethereum-optimism/go-ethereum-hdwallet v0.1.3/go.mod h1:QziizLAiF0KqyLdNJYD7O5cpDlaFMNZzlxYNcWsJUxs= github.com/ethereum-optimism/go-ethereum-hdwallet v0.1.3/go.mod h1:QziizLAiF0KqyLdNJYD7O5cpDlaFMNZzlxYNcWsJUxs=
github.com/ethereum-optimism/op-geth v1.11.2-aea0402.0.20230227230209-0705cf1b7df9 h1:O13fqCZYW+HiGVs+UFKtMUHnCMpWR7XcyTPijm9IAiY= github.com/ethereum-optimism/op-geth v1.11.2-aea0402.0.20230301232322-c407b2a217b7 h1:bkttBXCRDv2Mp4VoGBglr4BjS7icIuN8HS5ZFpeKfvE=
github.com/ethereum-optimism/op-geth v1.11.2-aea0402.0.20230227230209-0705cf1b7df9/go.mod h1:/tjlXxOaovIyuF0l6+wCzr6AtDb3lYWTymmpQAQcqu8= github.com/ethereum-optimism/op-geth v1.11.2-aea0402.0.20230301232322-c407b2a217b7/go.mod h1:/tjlXxOaovIyuF0l6+wCzr6AtDb3lYWTymmpQAQcqu8=
github.com/fasthttp-contrib/websocket v0.0.0-20160511215533-1f3b11f56072/go.mod h1:duJ4Jxv5lDcvg4QuQr0oowTf7dz4/CR8NtyCooz9HL8= github.com/fasthttp-contrib/websocket v0.0.0-20160511215533-1f3b11f56072/go.mod h1:duJ4Jxv5lDcvg4QuQr0oowTf7dz4/CR8NtyCooz9HL8=
github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4= github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4=
github.com/fatih/structs v1.1.0/go.mod h1:9NiDSp5zOcgEDl+j00MP/WkGVPOlPRLejGD8Ga6PJ7M= github.com/fatih/structs v1.1.0/go.mod h1:9NiDSp5zOcgEDl+j00MP/WkGVPOlPRLejGD8Ga6PJ7M=
......
...@@ -4,7 +4,7 @@ go 1.17 ...@@ -4,7 +4,7 @@ go 1.17
replace ( replace (
github.com/ethereum/go-ethereum v1.10.26 => github.com/ethereum-optimism/op-geth v0.0.0-20230214215134-401b7fd3309b github.com/ethereum/go-ethereum v1.10.26 => github.com/ethereum-optimism/op-geth v0.0.0-20230214215134-401b7fd3309b
github.com/ethereum/go-ethereum v1.11.2 => github.com/ethereum-optimism/op-geth v1.11.2-aea0402.0.20230227230209-0705cf1b7df9 github.com/ethereum/go-ethereum v1.11.2 => github.com/ethereum-optimism/op-geth v1.11.2-aea0402.0.20230301232322-c407b2a217b7
) )
require ( require (
......
...@@ -30,10 +30,10 @@ ...@@ -30,10 +30,10 @@
"devDependencies": { "devDependencies": {
"@babel/eslint-parser": "^7.5.4", "@babel/eslint-parser": "^7.5.4",
"@eth-optimism/contracts": "^0.5.40", "@eth-optimism/contracts": "^0.5.40",
"@eth-optimism/contracts-bedrock": "0.12.1", "@eth-optimism/contracts-bedrock": "0.13.0",
"@eth-optimism/contracts-periphery": "^1.0.7", "@eth-optimism/contracts-periphery": "^1.0.7",
"@eth-optimism/core-utils": "0.12.0", "@eth-optimism/core-utils": "0.12.0",
"@eth-optimism/sdk": "1.10.4", "@eth-optimism/sdk": "2.0.0",
"@ethersproject/abstract-provider": "^5.7.0", "@ethersproject/abstract-provider": "^5.7.0",
"@ethersproject/providers": "^5.7.0", "@ethersproject/providers": "^5.7.0",
"@ethersproject/transactions": "^5.7.0", "@ethersproject/transactions": "^5.7.0",
......
# @eth-optimism/l2geth-exporter # @eth-optimism/l2geth-exporter
## 0.0.8
### Patch Changes
- e085354a8: build(deps): bump golang.org/x/crypto from 0.0.0-20220307211146-efcb8507fb70 to 0.1.0 in /l2geth-exporter
- 9bee5c8cc: build(deps): bump golang.org/x/sys from 0.0.0-20220310020820-b874c991c1a5 to 0.1.0 in /l2geth-exporter
## 0.0.7 ## 0.0.7
### Patch Changes ### Patch Changes
......
{ {
"name": "@eth-optimism/l2geth-exporter", "name": "@eth-optimism/l2geth-exporter",
"version": "0.0.7", "version": "0.0.8",
"private": true, "private": true,
"devDependencies": {} "devDependencies": {}
} }
...@@ -18,6 +18,15 @@ type ChannelConfig struct { ...@@ -18,6 +18,15 @@ type ChannelConfig struct {
// The maximum number of L1 blocks that the inclusion transactions of a // The maximum number of L1 blocks that the inclusion transactions of a
// channel's frames can span. // channel's frames can span.
ChannelTimeout uint64 ChannelTimeout uint64
// Builder Config
// MaxChannelDuration is the maximum duration (in #L1-blocks) to keep the
// channel open. This allows control over how long a channel is kept open
// during times of low transaction volume.
//
// If 0, duration checks are disabled.
MaxChannelDuration uint64
// The batcher tx submission safety margin (in #L1-blocks) to subtract from // The batcher tx submission safety margin (in #L1-blocks) to subtract from
// a channel's timeout and sequencing window, to guarantee safe inclusion of // a channel's timeout and sequencing window, to guarantee safe inclusion of
// a channel on L1. // a channel on L1.
...@@ -50,12 +59,17 @@ func (c ChannelConfig) InputThreshold() uint64 { ...@@ -50,12 +59,17 @@ func (c ChannelConfig) InputThreshold() uint64 {
type channelBuilder struct { type channelBuilder struct {
cfg ChannelConfig cfg ChannelConfig
// L1 block timestamp of combined channel & sequencing window timeout. 0 if // L1 block number timeout of combined
// no timeout set yet. // - channel duration timeout,
// - consensus channel timeout,
// - sequencing window timeout.
// 0 if no block number timeout set yet.
timeout uint64 timeout uint64
// reason for currently set timeout
timeoutReason error
// marked as full if a) max RLP input bytes, b) max num frames or c) max // Reason for the channel being full. Set by setFullErr so it's always
// allowed frame index (uint16) has been reached // guaranteed to be a ChannelFullError wrapping the specific reason.
fullErr error fullErr error
// current channel // current channel
co *derive.ChannelOut co *derive.ChannelOut
...@@ -102,28 +116,6 @@ func (c *channelBuilder) Reset() error { ...@@ -102,28 +116,6 @@ func (c *channelBuilder) Reset() error {
return c.co.Reset() return c.co.Reset()
} }
// FramePublished calculates the submission timeout of this channel from the
// given frame inclusion L1-block number. If an older frame tx has already been
// seen, the timeout is not updated.
func (c *channelBuilder) FramePublished(l1BlockNum uint64) {
timeout := l1BlockNum + c.cfg.ChannelTimeout - c.cfg.SubSafetyMargin
c.updateTimeout(timeout)
}
// TimedOut returns whether the passed block number is after the channel timeout
// block. If no block timeout is set yet, it returns false.
func (c *channelBuilder) TimedOut(blockNum uint64) bool {
return c.timeout != 0 && blockNum >= c.timeout
}
// CheckTimeout checks if the channel is timed out at the given block number and
// in this case marks the channel as full with reason ErrChannelTimedOut.
func (c *channelBuilder) CheckTimeout(blockNum uint64) {
if !c.IsFull() && c.TimedOut(blockNum) {
c.setFullErr(ErrChannelTimedOut)
}
}
// AddBlock adds a block to the channel compression pipeline. IsFull should be // AddBlock adds a block to the channel compression pipeline. IsFull should be
// called aftewards to test whether the channel is full. If full, a new channel // called aftewards to test whether the channel is full. If full, a new channel
// must be started. // must be started.
...@@ -151,7 +143,7 @@ func (c *channelBuilder) AddBlock(block *types.Block) error { ...@@ -151,7 +143,7 @@ func (c *channelBuilder) AddBlock(block *types.Block) error {
c.blocks = append(c.blocks, block) c.blocks = append(c.blocks, block)
c.updateSwTimeout(batch) c.updateSwTimeout(batch)
if c.InputTargetReached() { if c.inputTargetReached() {
c.setFullErr(ErrInputTargetReached) c.setFullErr(ErrInputTargetReached)
// Adding this block still worked, so don't return error, just mark as full // Adding this block still worked, so don't return error, just mark as full
} }
...@@ -159,25 +151,76 @@ func (c *channelBuilder) AddBlock(block *types.Block) error { ...@@ -159,25 +151,76 @@ func (c *channelBuilder) AddBlock(block *types.Block) error {
return nil return nil
} }
// Timeout management
// RegisterL1Block should be called whenever a new L1-block is seen.
//
// It ensures proper tracking of all possible timeouts (max channel duration,
// close to consensus channel timeout, close to end of sequencing window).
func (c *channelBuilder) RegisterL1Block(l1BlockNum uint64) {
c.updateDurationTimeout(l1BlockNum)
c.checkTimeout(l1BlockNum)
}
// FramePublished should be called whenever a frame of this channel got
// published with the L1-block number of the block that the frame got included
// in.
func (c *channelBuilder) FramePublished(l1BlockNum uint64) {
timeout := l1BlockNum + c.cfg.ChannelTimeout - c.cfg.SubSafetyMargin
c.updateTimeout(timeout, ErrChannelTimeoutClose)
}
// updateDurationTimeout updates the block timeout with the channel duration
// timeout derived from the given L1-block number. The timeout is only moved
// forward if the derived timeout is earlier than the currently set timeout.
//
// It does nothing if the max channel duration is set to 0.
func (c *channelBuilder) updateDurationTimeout(l1BlockNum uint64) {
if c.cfg.MaxChannelDuration == 0 {
return
}
timeout := l1BlockNum + c.cfg.MaxChannelDuration
c.updateTimeout(timeout, ErrMaxDurationReached)
}
// updateSwTimeout updates the block timeout with the sequencer window timeout // updateSwTimeout updates the block timeout with the sequencer window timeout
// derived from the batch's origin L1 block. The timeout is only moved forward // derived from the batch's origin L1 block. The timeout is only moved forward
// if the derived sequencer window timeout is earlier than the current. // if the derived sequencer window timeout is earlier than the currently set
// timeout.
func (c *channelBuilder) updateSwTimeout(batch *derive.BatchData) { func (c *channelBuilder) updateSwTimeout(batch *derive.BatchData) {
timeout := uint64(batch.EpochNum) + c.cfg.SeqWindowSize - c.cfg.SubSafetyMargin timeout := uint64(batch.EpochNum) + c.cfg.SeqWindowSize - c.cfg.SubSafetyMargin
c.updateTimeout(timeout) c.updateTimeout(timeout, ErrSeqWindowClose)
} }
// updateTimeout updates the timeout block to the given block number if it is // updateTimeout updates the timeout block to the given block number if it is
// earlier then the current block timeout, or if it still unset. // earlier than the current block timeout, or if it still unset.
func (c *channelBuilder) updateTimeout(timeoutBlockNum uint64) { //
// If the timeout is updated, the provided reason will be set as the channel
// full error reason in case the timeout is hit in the future.
func (c *channelBuilder) updateTimeout(timeoutBlockNum uint64, reason error) {
if c.timeout == 0 || c.timeout > timeoutBlockNum { if c.timeout == 0 || c.timeout > timeoutBlockNum {
c.timeout = timeoutBlockNum c.timeout = timeoutBlockNum
c.timeoutReason = reason
} }
} }
// InputTargetReached says whether the target amount of input data has been // checkTimeout checks if the channel is timed out at the given block number and
// in this case marks the channel as full, if it wasn't full alredy.
func (c *channelBuilder) checkTimeout(blockNum uint64) {
if !c.IsFull() && c.TimedOut(blockNum) {
c.setFullErr(c.timeoutReason)
}
}
// TimedOut returns whether the passed block number is after the timeout block
// number. If no block timeout is set yet, it returns false.
func (c *channelBuilder) TimedOut(blockNum uint64) bool {
return c.timeout != 0 && blockNum >= c.timeout
}
// inputTargetReached says whether the target amount of input data has been
// reached in this channel builder. No more blocks can be added afterwards. // reached in this channel builder. No more blocks can be added afterwards.
func (c *channelBuilder) InputTargetReached() bool { func (c *channelBuilder) inputTargetReached() bool {
return uint64(c.co.InputBytes()) >= c.cfg.InputThreshold() return uint64(c.co.InputBytes()) >= c.cfg.InputThreshold()
} }
...@@ -190,14 +233,16 @@ func (c *channelBuilder) IsFull() bool { ...@@ -190,14 +233,16 @@ func (c *channelBuilder) IsFull() bool {
// FullErr returns the reason why the channel is full. If not full yet, it // FullErr returns the reason why the channel is full. If not full yet, it
// returns nil. // returns nil.
// //
// It returns a ChannelFullError wrapping one of four possible reasons for the // It returns a ChannelFullError wrapping one of six possible reasons for the
// channel being full: // channel being full:
// - ErrInputTargetReached if the target amount of input data has been reached, // - ErrInputTargetReached if the target amount of input data has been reached,
// - derive.MaxRLPBytesPerChannel if the general maximum amount of input data // - derive.MaxRLPBytesPerChannel if the general maximum amount of input data
// would have been exceeded by the latest AddBlock call, // would have been exceeded by the latest AddBlock call,
// - ErrMaxFrameIndex if the maximum number of frames has been generated // - ErrMaxFrameIndex if the maximum number of frames has been generated
// (uint16), // (uint16),
// - ErrChannelTimedOut if the batcher channel timeout has been reached. // - ErrMaxDurationReached if the max channel duration got reached.
// - ErrChannelTimeoutClose if the consensus channel timeout got too close.
// - ErrSeqWindowClose if the end of the sequencer window got too close.
func (c *channelBuilder) FullErr() error { func (c *channelBuilder) FullErr() error {
return c.fullErr return c.fullErr
} }
...@@ -210,9 +255,9 @@ func (c *channelBuilder) setFullErr(err error) { ...@@ -210,9 +255,9 @@ func (c *channelBuilder) setFullErr(err error) {
// after AddBlock and before iterating over available frames with HasFrame and // after AddBlock and before iterating over available frames with HasFrame and
// NextFrame. // NextFrame.
// //
// If the input data target hasn't been reached yet, it will conservatively only // If the channel isn't full yet, it will conservatively only
// pull readily available frames from the compression output. // pull readily available frames from the compression output.
// If the target has been reached, the channel is closed and all remaining // If it is full, the channel is closed and all remaining
// frames will be created, possibly with a small leftover frame. // frames will be created, possibly with a small leftover frame.
func (c *channelBuilder) OutputFrames() error { func (c *channelBuilder) OutputFrames() error {
if c.IsFull() { if c.IsFull() {
...@@ -320,7 +365,9 @@ func (c *channelBuilder) PushFrame(id txID, frame []byte) { ...@@ -320,7 +365,9 @@ func (c *channelBuilder) PushFrame(id txID, frame []byte) {
var ( var (
ErrInputTargetReached = errors.New("target amount of input data reached") ErrInputTargetReached = errors.New("target amount of input data reached")
ErrMaxFrameIndex = errors.New("max frame index reached (uint16)") ErrMaxFrameIndex = errors.New("max frame index reached (uint16)")
ErrChannelTimedOut = errors.New("channel timed out") ErrMaxDurationReached = errors.New("max channel duration reached")
ErrChannelTimeoutClose = errors.New("close to channel timeout")
ErrSeqWindowClose = errors.New("close to sequencer window timeout")
) )
type ChannelFullError struct { type ChannelFullError struct {
......
...@@ -188,9 +188,6 @@ func (s *channelManager) nextTxData() ([]byte, txID, error) { ...@@ -188,9 +188,6 @@ func (s *channelManager) nextTxData() ([]byte, txID, error) {
// It currently only uses one frame per transaction. If the pending channel is // It currently only uses one frame per transaction. If the pending channel is
// full, it only returns the remaining frames of this channel until it got // full, it only returns the remaining frames of this channel until it got
// successfully fully sent to L1. It returns io.EOF if there's no pending frame. // successfully fully sent to L1. It returns io.EOF if there's no pending frame.
//
// It currently ignores the l1Head provided and doesn't track channel timeouts
// or the sequencer window span yet.
func (s *channelManager) TxData(l1Head eth.BlockID) ([]byte, txID, error) { func (s *channelManager) TxData(l1Head eth.BlockID) ([]byte, txID, error) {
dataPending := s.pendingChannel != nil && s.pendingChannel.HasFrame() dataPending := s.pendingChannel != nil && s.pendingChannel.HasFrame()
s.log.Debug("Requested tx data", "l1Head", l1Head, "data_pending", dataPending, "blocks_pending", len(s.blocks)) s.log.Debug("Requested tx data", "l1Head", l1Head, "data_pending", dataPending, "blocks_pending", len(s.blocks))
...@@ -211,12 +208,15 @@ func (s *channelManager) TxData(l1Head eth.BlockID) ([]byte, txID, error) { ...@@ -211,12 +208,15 @@ func (s *channelManager) TxData(l1Head eth.BlockID) ([]byte, txID, error) {
return nil, txID{}, err return nil, txID{}, err
} }
s.checkTimeout(l1Head)
if err := s.processBlocks(); err != nil { if err := s.processBlocks(); err != nil {
return nil, txID{}, err return nil, txID{}, err
} }
// Register current L1 head only after all pending blocks have been
// processed. Even if a timeout will be triggered now, it is better to have
// all pending blocks be included in this channel for submission.
s.registerL1Block(l1Head)
if err := s.pendingChannel.OutputFrames(); err != nil { if err := s.pendingChannel.OutputFrames(); err != nil {
return nil, txID{}, fmt.Errorf("creating frames with channel builder: %w", err) return nil, txID{}, fmt.Errorf("creating frames with channel builder: %w", err)
} }
...@@ -239,14 +239,13 @@ func (s *channelManager) ensurePendingChannel(l1Head eth.BlockID) error { ...@@ -239,14 +239,13 @@ func (s *channelManager) ensurePendingChannel(l1Head eth.BlockID) error {
return nil return nil
} }
// checkTimeout checks the block timeout on the pending channel. // registerL1Block registers the given block at the pending channel.
func (s *channelManager) checkTimeout(l1Head eth.BlockID) { func (s *channelManager) registerL1Block(l1Head eth.BlockID) {
s.pendingChannel.CheckTimeout(l1Head.Number) s.pendingChannel.RegisterL1Block(l1Head.Number)
ferr := s.pendingChannel.FullErr() s.log.Debug("new L1-block registered at channel builder",
s.log.Debug("timeout triggered",
"l1Head", l1Head, "l1Head", l1Head,
"timed_out", errors.Is(ferr, ErrChannelTimedOut), "channel_full", s.pendingChannel.IsFull(),
"full_reason", ferr, "full_reason", s.pendingChannel.FullErr(),
) )
} }
......
package batcher_test
import (
"io"
"math/big"
"testing"
"github.com/ethereum-optimism/optimism/op-batcher/batcher"
"github.com/ethereum-optimism/optimism/op-node/eth"
"github.com/ethereum-optimism/optimism/op-node/rollup/derive"
"github.com/ethereum-optimism/optimism/op-node/testlog"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/log"
"github.com/ethereum/go-ethereum/trie"
"github.com/stretchr/testify/require"
)
// TestChannelManagerReturnsErrReorg ensures that the channel manager
// detects a reorg when it has cached L1 blocks.
func TestChannelManagerReturnsErrReorg(t *testing.T) {
log := testlog.Logger(t, log.LvlCrit)
m := batcher.NewChannelManager(log, batcher.ChannelConfig{})
a := types.NewBlock(&types.Header{
Number: big.NewInt(0),
}, nil, nil, nil, nil)
b := types.NewBlock(&types.Header{
Number: big.NewInt(1),
ParentHash: a.Hash(),
}, nil, nil, nil, nil)
c := types.NewBlock(&types.Header{
Number: big.NewInt(2),
ParentHash: b.Hash(),
}, nil, nil, nil, nil)
x := types.NewBlock(&types.Header{
Number: big.NewInt(2),
ParentHash: common.Hash{0xff},
}, nil, nil, nil, nil)
err := m.AddL2Block(a)
require.NoError(t, err)
err = m.AddL2Block(b)
require.NoError(t, err)
err = m.AddL2Block(c)
require.NoError(t, err)
err = m.AddL2Block(x)
require.ErrorIs(t, err, batcher.ErrReorg)
}
// TestChannelManagerReturnsErrReorgWhenDrained ensures that the channel manager
// detects a reorg even if it does not have any blocks inside it.
func TestChannelManagerReturnsErrReorgWhenDrained(t *testing.T) {
log := testlog.Logger(t, log.LvlCrit)
m := batcher.NewChannelManager(log, batcher.ChannelConfig{
TargetFrameSize: 0,
MaxFrameSize: 100,
ApproxComprRatio: 1.0,
})
lBlock := types.NewBlock(&types.Header{
BaseFee: big.NewInt(10),
Difficulty: common.Big0,
Number: big.NewInt(100),
}, nil, nil, nil, trie.NewStackTrie(nil))
l1InfoTx, err := derive.L1InfoDeposit(0, lBlock, eth.SystemConfig{}, false)
require.NoError(t, err)
txs := []*types.Transaction{types.NewTx(l1InfoTx)}
a := types.NewBlock(&types.Header{
Number: big.NewInt(0),
}, txs, nil, nil, trie.NewStackTrie(nil))
x := types.NewBlock(&types.Header{
Number: big.NewInt(1),
ParentHash: common.Hash{0xff},
}, txs, nil, nil, trie.NewStackTrie(nil))
err = m.AddL2Block(a)
require.NoError(t, err)
_, _, err = m.TxData(eth.BlockID{})
require.NoError(t, err)
_, _, err = m.TxData(eth.BlockID{})
require.ErrorIs(t, err, io.EOF)
err = m.AddL2Block(x)
require.ErrorIs(t, err, batcher.ErrReorg)
}
...@@ -47,6 +47,16 @@ type CLIConfig struct { ...@@ -47,6 +47,16 @@ type CLIConfig struct {
// RollupRpc is the HTTP provider URL for the L2 rollup node. // RollupRpc is the HTTP provider URL for the L2 rollup node.
RollupRpc string RollupRpc string
// MaxChannelDuration is the maximum duration (in #L1-blocks) to keep a
// channel open. This allows to more eagerly send batcher transactions
// during times of low L2 transaction volume. Note that the effective
// L1-block distance between batcher transactions is then MaxChannelDuration
// + NumConfirmations because the batcher waits for NumConfirmations blocks
// after sending a batcher tx and only then starts a new channel.
//
// If 0, duration checks are disabled.
MaxChannelDuration uint64
// The batcher tx submission safety margin (in #L1-blocks) to subtract from // The batcher tx submission safety margin (in #L1-blocks) to subtract from
// a channel's timeout and sequencing window, to guarantee safe inclusion of // a channel's timeout and sequencing window, to guarantee safe inclusion of
// a channel on L1. // a channel on L1.
...@@ -143,6 +153,7 @@ func NewConfig(ctx *cli.Context) CLIConfig { ...@@ -143,6 +153,7 @@ func NewConfig(ctx *cli.Context) CLIConfig {
ResubmissionTimeout: ctx.GlobalDuration(flags.ResubmissionTimeoutFlag.Name), ResubmissionTimeout: ctx.GlobalDuration(flags.ResubmissionTimeoutFlag.Name),
/* Optional Flags */ /* Optional Flags */
MaxChannelDuration: ctx.GlobalUint64(flags.MaxChannelDurationFlag.Name),
MaxL1TxSize: ctx.GlobalUint64(flags.MaxL1TxSizeBytesFlag.Name), MaxL1TxSize: ctx.GlobalUint64(flags.MaxL1TxSizeBytesFlag.Name),
TargetL1TxSize: ctx.GlobalUint64(flags.TargetL1TxSizeBytesFlag.Name), TargetL1TxSize: ctx.GlobalUint64(flags.TargetL1TxSizeBytesFlag.Name),
TargetNumFrames: ctx.GlobalInt(flags.TargetNumFramesFlag.Name), TargetNumFrames: ctx.GlobalInt(flags.TargetNumFramesFlag.Name),
......
...@@ -90,6 +90,7 @@ func NewBatchSubmitterFromCLIConfig(cfg CLIConfig, l log.Logger) (*BatchSubmitte ...@@ -90,6 +90,7 @@ func NewBatchSubmitterFromCLIConfig(cfg CLIConfig, l log.Logger) (*BatchSubmitte
Channel: ChannelConfig{ Channel: ChannelConfig{
SeqWindowSize: rcfg.SeqWindowSize, SeqWindowSize: rcfg.SeqWindowSize,
ChannelTimeout: rcfg.ChannelTimeout, ChannelTimeout: rcfg.ChannelTimeout,
MaxChannelDuration: cfg.MaxChannelDuration,
SubSafetyMargin: cfg.SubSafetyMargin, SubSafetyMargin: cfg.SubSafetyMargin,
MaxFrameSize: cfg.MaxL1TxSize - 1, // subtract 1 byte for version MaxFrameSize: cfg.MaxL1TxSize - 1, // subtract 1 byte for version
TargetFrameSize: cfg.TargetL1TxSize - 1, // subtract 1 byte for version TargetFrameSize: cfg.TargetL1TxSize - 1, // subtract 1 byte for version
......
...@@ -75,6 +75,12 @@ var ( ...@@ -75,6 +75,12 @@ var (
/* Optional flags */ /* Optional flags */
MaxChannelDurationFlag = cli.Uint64Flag{
Name: "max-channel-duration",
Usage: "The maximum duration of L1-blocks to keep a channel open. 0 to disable.",
Value: 0,
EnvVar: opservice.PrefixEnvVar(envVarPrefix, "MAX_CHANNEL_DURATION"),
}
MaxL1TxSizeBytesFlag = cli.Uint64Flag{ MaxL1TxSizeBytesFlag = cli.Uint64Flag{
Name: "max-l1-tx-size-bytes", Name: "max-l1-tx-size-bytes",
Usage: "The maximum size of a batch tx submitted to L1.", Usage: "The maximum size of a batch tx submitted to L1.",
...@@ -96,7 +102,7 @@ var ( ...@@ -96,7 +102,7 @@ var (
ApproxComprRatioFlag = cli.Float64Flag{ ApproxComprRatioFlag = cli.Float64Flag{
Name: "approx-compr-ratio", Name: "approx-compr-ratio",
Usage: "The approximate compression ratio (<= 1.0)", Usage: "The approximate compression ratio (<= 1.0)",
Value: 1.0, Value: 0.4,
EnvVar: opservice.PrefixEnvVar(envVarPrefix, "APPROX_COMPR_RATIO"), EnvVar: opservice.PrefixEnvVar(envVarPrefix, "APPROX_COMPR_RATIO"),
} }
StoppedFlag = cli.BoolFlag{ StoppedFlag = cli.BoolFlag{
...@@ -135,6 +141,7 @@ var requiredFlags = []cli.Flag{ ...@@ -135,6 +141,7 @@ var requiredFlags = []cli.Flag{
} }
var optionalFlags = []cli.Flag{ var optionalFlags = []cli.Flag{
MaxChannelDurationFlag,
MaxL1TxSizeBytesFlag, MaxL1TxSizeBytesFlag,
TargetL1TxSizeBytesFlag, TargetL1TxSizeBytesFlag,
TargetNumFramesFlag, TargetNumFramesFlag,
......
...@@ -37,8 +37,8 @@ type TypesOutputProposal struct { ...@@ -37,8 +37,8 @@ type TypesOutputProposal 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\":\"uint256\",\"name\":\"_startingBlockNumber\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_startingTimestamp\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"_proposer\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_challenger\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint8\",\"name\":\"version\",\"type\":\"uint8\"}],\"name\":\"Initialized\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"outputRoot\",\"type\":\"bytes32\"},{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"l2OutputIndex\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"l2BlockNumber\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"l1Timestamp\",\"type\":\"uint256\"}],\"name\":\"OutputProposed\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"prevNextOutputIndex\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"newNextOutputIndex\",\"type\":\"uint256\"}],\"name\":\"OutputsDeleted\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"CHALLENGER\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"L2_BLOCK_TIME\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"PROPOSER\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"SUBMISSION_INTERVAL\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_l2BlockNumber\",\"type\":\"uint256\"}],\"name\":\"computeL2Timestamp\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_l2OutputIndex\",\"type\":\"uint256\"}],\"name\":\"deleteL2Outputs\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_l2OutputIndex\",\"type\":\"uint256\"}],\"name\":\"getL2Output\",\"outputs\":[{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"outputRoot\",\"type\":\"bytes32\"},{\"internalType\":\"uint128\",\"name\":\"timestamp\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"l2BlockNumber\",\"type\":\"uint128\"}],\"internalType\":\"structTypes.OutputProposal\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_l2BlockNumber\",\"type\":\"uint256\"}],\"name\":\"getL2OutputAfter\",\"outputs\":[{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"outputRoot\",\"type\":\"bytes32\"},{\"internalType\":\"uint128\",\"name\":\"timestamp\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"l2BlockNumber\",\"type\":\"uint128\"}],\"internalType\":\"structTypes.OutputProposal\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_l2BlockNumber\",\"type\":\"uint256\"}],\"name\":\"getL2OutputIndexAfter\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_startingBlockNumber\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_startingTimestamp\",\"type\":\"uint256\"}],\"name\":\"initialize\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"latestBlockNumber\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"latestOutputIndex\",\"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\":\"nextOutputIndex\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"_outputRoot\",\"type\":\"bytes32\"},{\"internalType\":\"uint256\",\"name\":\"_l2BlockNumber\",\"type\":\"uint256\"},{\"internalType\":\"bytes32\",\"name\":\"_l1BlockHash\",\"type\":\"bytes32\"},{\"internalType\":\"uint256\",\"name\":\"_l1BlockNumber\",\"type\":\"uint256\"}],\"name\":\"proposeL2Output\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"startingBlockNumber\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"startingTimestamp\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"version\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"}]", ABI: "[{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_submissionInterval\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_l2BlockTime\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_startingBlockNumber\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_startingTimestamp\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"_proposer\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_challenger\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"_finalizationPeriodSeconds\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint8\",\"name\":\"version\",\"type\":\"uint8\"}],\"name\":\"Initialized\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"outputRoot\",\"type\":\"bytes32\"},{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"l2OutputIndex\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"l2BlockNumber\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"l1Timestamp\",\"type\":\"uint256\"}],\"name\":\"OutputProposed\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"prevNextOutputIndex\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"newNextOutputIndex\",\"type\":\"uint256\"}],\"name\":\"OutputsDeleted\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"CHALLENGER\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"FINALIZATION_PERIOD_SECONDS\",\"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\":\"PROPOSER\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"SUBMISSION_INTERVAL\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_l2BlockNumber\",\"type\":\"uint256\"}],\"name\":\"computeL2Timestamp\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_l2OutputIndex\",\"type\":\"uint256\"}],\"name\":\"deleteL2Outputs\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_l2OutputIndex\",\"type\":\"uint256\"}],\"name\":\"getL2Output\",\"outputs\":[{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"outputRoot\",\"type\":\"bytes32\"},{\"internalType\":\"uint128\",\"name\":\"timestamp\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"l2BlockNumber\",\"type\":\"uint128\"}],\"internalType\":\"structTypes.OutputProposal\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_l2BlockNumber\",\"type\":\"uint256\"}],\"name\":\"getL2OutputAfter\",\"outputs\":[{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"outputRoot\",\"type\":\"bytes32\"},{\"internalType\":\"uint128\",\"name\":\"timestamp\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"l2BlockNumber\",\"type\":\"uint128\"}],\"internalType\":\"structTypes.OutputProposal\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_l2BlockNumber\",\"type\":\"uint256\"}],\"name\":\"getL2OutputIndexAfter\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_startingBlockNumber\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_startingTimestamp\",\"type\":\"uint256\"}],\"name\":\"initialize\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"latestBlockNumber\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"latestOutputIndex\",\"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\":\"nextOutputIndex\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"_outputRoot\",\"type\":\"bytes32\"},{\"internalType\":\"uint256\",\"name\":\"_l2BlockNumber\",\"type\":\"uint256\"},{\"internalType\":\"bytes32\",\"name\":\"_l1BlockHash\",\"type\":\"bytes32\"},{\"internalType\":\"uint256\",\"name\":\"_l1BlockNumber\",\"type\":\"uint256\"}],\"name\":\"proposeL2Output\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"startingBlockNumber\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"startingTimestamp\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"version\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"}]",
Bin: "0x6101606040523480156200001257600080fd5b50604051620019863803806200198683398101604081905262000035916200035d565b6001608081905260a052600060c05284620000bd5760405162461bcd60e51b815260206004820152603460248201527f4c324f75747075744f7261636c653a204c3220626c6f636b2074696d65206d7560448201527f73742062652067726561746572207468616e203000000000000000000000000060648201526084015b60405180910390fd5b848611620001435760405162461bcd60e51b815260206004820152604660248201527f4c324f75747075744f7261636c653a207375626d697373696f6e20696e74657260448201527f76616c206d7573742062652067726561746572207468616e204c3220626c6f636064820152656b2074696d6560d01b608482015260a401620000b4565b60e08690526101008590526001600160a01b03808316610140528116610120526200016f84846200017b565b505050505050620003ba565b600054610100900460ff16158080156200019c5750600054600160ff909116105b80620001cc5750620001b9306200033160201b620011031760201c565b158015620001cc575060005460ff166001145b620002315760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201526d191e481a5b9a5d1a585b1a5e995960921b6064820152608401620000b4565b6000805460ff19166001179055801562000255576000805461ff0019166101001790555b42821115620002db5760405162461bcd60e51b8152602060048201526044602482018190527f4c324f75747075744f7261636c653a207374617274696e67204c322074696d65908201527f7374616d70206d757374206265206c657373207468616e2063757272656e742060648201526374696d6560e01b608482015260a401620000b4565b6002829055600183905580156200032c576000805461ff0019169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b505050565b6001600160a01b03163b151590565b80516001600160a01b03811681146200035857600080fd5b919050565b60008060008060008060c087890312156200037757600080fd5b865195506020870151945060408701519350606087015192506200039e6080880162000340565b9150620003ae60a0880162000340565b90509295509295509295565b60805160a05160c05160e0516101005161012051610140516115556200043160003960008181610351015261090001526000818161021b015261074101526000818161013f0152610e3701526000818161019b0152610e85015260006104b40152600061048b0152600061046201526115556000f3fe6080604052600436106101285760003560e01c806388786272116100a5578063bffa7f0f11610074578063d1de856c11610059578063d1de856c14610393578063dcec3348146103b3578063e4a30116146103c857600080fd5b8063bffa7f0f1461033f578063cf8e5cf01461037357600080fd5b8063887862721461029857806389c44cbb146102ae5780639aaab648146102d0578063a25ae557146102e357600080fd5b806369f16eec116100fc5780636b4d98dd116100e15780636b4d98dd1461020957806370872aa5146102625780637f0064201461027857600080fd5b806369f16eec146101df5780636abcf563146101f457600080fd5b80622134cc1461012d5780634599c78814610174578063529933df1461018957806354fd4d50146101bd575b600080fd5b34801561013957600080fd5b506101617f000000000000000000000000000000000000000000000000000000000000000081565b6040519081526020015b60405180910390f35b34801561018057600080fd5b506101616103e8565b34801561019557600080fd5b506101617f000000000000000000000000000000000000000000000000000000000000000081565b3480156101c957600080fd5b506101d261045b565b60405161016b919061128c565b3480156101eb57600080fd5b506101616104fe565b34801561020057600080fd5b50600354610161565b34801561021557600080fd5b5061023d7f000000000000000000000000000000000000000000000000000000000000000081565b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200161016b565b34801561026e57600080fd5b5061016160015481565b34801561028457600080fd5b506101616102933660046112dd565b610510565b3480156102a457600080fd5b5061016160025481565b3480156102ba57600080fd5b506102ce6102c93660046112dd565b610729565b005b6102ce6102de3660046112f6565b6108e8565b3480156102ef57600080fd5b506103036102fe3660046112dd565b610d67565b60408051825181526020808401516fffffffffffffffffffffffffffffffff90811691830191909152928201519092169082015260600161016b565b34801561034b57600080fd5b5061023d7f000000000000000000000000000000000000000000000000000000000000000081565b34801561037f57600080fd5b5061030361038e3660046112dd565b610dfb565b34801561039f57600080fd5b506101616103ae3660046112dd565b610e33565b3480156103bf57600080fd5b50610161610e81565b3480156103d457600080fd5b506102ce6103e3366004611328565b610eb6565b60035460009015610452576003805461040390600190611379565b8154811061041357610413611390565b600091825260209091206002909102016001015470010000000000000000000000000000000090046fffffffffffffffffffffffffffffffff16919050565b6001545b905090565b60606104867f000000000000000000000000000000000000000000000000000000000000000061111f565b6104af7f000000000000000000000000000000000000000000000000000000000000000061111f565b6104d87f000000000000000000000000000000000000000000000000000000000000000061111f565b6040516020016104ea939291906113bf565b604051602081830303815290604052905090565b60035460009061045690600190611379565b600061051a6103e8565b8211156105d4576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604860248201527f4c324f75747075744f7261636c653a2063616e6e6f7420676574206f7574707560448201527f7420666f72206120626c6f636b207468617420686173206e6f74206265656e2060648201527f70726f706f736564000000000000000000000000000000000000000000000000608482015260a4015b60405180910390fd5b600354610689576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604660248201527f4c324f75747075744f7261636c653a2063616e6e6f7420676574206f7574707560448201527f74206173206e6f206f7574707574732068617665206265656e2070726f706f7360648201527f6564207965740000000000000000000000000000000000000000000000000000608482015260a4016105cb565b6003546000905b8082101561072257600060026106a68385611435565b6106b0919061147c565b905084600382815481106106c6576106c6611390565b600091825260209091206002909102016001015470010000000000000000000000000000000090046fffffffffffffffffffffffffffffffff16101561071857610711816001611435565b925061071c565b8091505b50610690565b5092915050565b3373ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000000000000000000000000000000000000000000016146107ee576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603e60248201527f4c324f75747075744f7261636c653a206f6e6c7920746865206368616c6c656e60448201527f67657220616464726573732063616e2064656c657465206f757470757473000060648201526084016105cb565b60035481106108a5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604360248201527f4c324f75747075744f7261636c653a2063616e6e6f742064656c657465206f7560448201527f747075747320616674657220746865206c6174657374206f757470757420696e60648201527f6465780000000000000000000000000000000000000000000000000000000000608482015260a4016105cb565b60006108b060035490565b90508160035581817f4ee37ac2c786ec85e87592d3c5c8a1dd66f8496dda3f125d9ea8ca5f657629b660405160405180910390a35050565b3373ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000000000000000000000000000000000000000000016146109d3576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604160248201527f4c324f75747075744f7261636c653a206f6e6c79207468652070726f706f736560448201527f7220616464726573732063616e2070726f706f7365206e6577206f757470757460648201527f7300000000000000000000000000000000000000000000000000000000000000608482015260a4016105cb565b6109db610e81565b8314610a8f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604860248201527f4c324f75747075744f7261636c653a20626c6f636b206e756d626572206d757360448201527f7420626520657175616c20746f206e65787420657870656374656420626c6f6360648201527f6b206e756d626572000000000000000000000000000000000000000000000000608482015260a4016105cb565b42610a9984610e33565b10610b26576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603660248201527f4c324f75747075744f7261636c653a2063616e6e6f742070726f706f7365204c60448201527f32206f757470757420696e20746865206675747572650000000000000000000060648201526084016105cb565b83610bb3576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603a60248201527f4c324f75747075744f7261636c653a204c32206f75747075742070726f706f7360448201527f616c2063616e6e6f7420626520746865207a65726f206861736800000000000060648201526084016105cb565b8115610c6f5781814014610c6f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604960248201527f4c324f75747075744f7261636c653a20626c6f636b206861736820646f65732060448201527f6e6f74206d61746368207468652068617368206174207468652065787065637460648201527f6564206865696768740000000000000000000000000000000000000000000000608482015260a4016105cb565b82610c7960035490565b857fa7aaf2512769da4e444e3de247be2564225c2e7a8f74cfe528e46e17d24868e242604051610cab91815260200190565b60405180910390a45050604080516060810182529283526fffffffffffffffffffffffffffffffff4281166020850190815292811691840191825260038054600181018255600091909152935160029094027fc2575a0e9e593c00f959f8c92f12db2869c3395a3b0502d05e2516446f71f85b810194909455915190518216700100000000000000000000000000000000029116177fc2575a0e9e593c00f959f8c92f12db2869c3395a3b0502d05e2516446f71f85c90910155565b604080516060810182526000808252602082018190529181019190915260038281548110610d9757610d97611390565b600091825260209182902060408051606081018252600290930290910180548352600101546fffffffffffffffffffffffffffffffff8082169484019490945270010000000000000000000000000000000090049092169181019190915292915050565b60408051606081018252600080825260208201819052918101919091526003610e2383610510565b81548110610d9757610d97611390565b60007f000000000000000000000000000000000000000000000000000000000000000060015483610e649190611379565b610e6e9190611490565b600254610e7b9190611435565b92915050565b60007f0000000000000000000000000000000000000000000000000000000000000000610eac6103e8565b6104569190611435565b600054610100900460ff1615808015610ed65750600054600160ff909116105b80610ef05750303b158015610ef0575060005460ff166001145b610f7c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a656400000000000000000000000000000000000060648201526084016105cb565b600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660011790558015610fda57600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff166101001790555b42821115611091576040517f08c379a0000000000000000000000000000000000000000000000000000000008152602060048201526044602482018190527f4c324f75747075744f7261636c653a207374617274696e67204c322074696d65908201527f7374616d70206d757374206265206c657373207468616e2063757272656e742060648201527f74696d6500000000000000000000000000000000000000000000000000000000608482015260a4016105cb565b6002829055600183905580156110fe57600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b505050565b73ffffffffffffffffffffffffffffffffffffffff163b151590565b60608160000361116257505060408051808201909152600181527f3000000000000000000000000000000000000000000000000000000000000000602082015290565b8160005b811561118c5780611176816114cd565b91506111859050600a8361147c565b9150611166565b60008167ffffffffffffffff8111156111a7576111a7611505565b6040519080825280601f01601f1916602001820160405280156111d1576020820181803683370190505b5090505b8415611254576111e6600183611379565b91506111f3600a86611534565b6111fe906030611435565b60f81b81838151811061121357611213611390565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a90535061124d600a8661147c565b94506111d5565b949350505050565b60005b8381101561127757818101518382015260200161125f565b83811115611286576000848401525b50505050565b60208152600082518060208401526112ab81604085016020870161125c565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169190910160400192915050565b6000602082840312156112ef57600080fd5b5035919050565b6000806000806080858703121561130c57600080fd5b5050823594602084013594506040840135936060013592509050565b6000806040838503121561133b57600080fd5b50508035926020909101359150565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60008282101561138b5761138b61134a565b500390565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b600084516113d181846020890161125c565b80830190507f2e00000000000000000000000000000000000000000000000000000000000000808252855161140d816001850160208a0161125c565b6001920191820152835161142881600284016020880161125c565b0160020195945050505050565b600082198211156114485761144861134a565b500190565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b60008261148b5761148b61144d565b500490565b6000817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff04831182151516156114c8576114c861134a565b500290565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82036114fe576114fe61134a565b5060010190565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6000826115435761154361144d565b50069056fea164736f6c634300080f000a", Bin: "0x6101806040523480156200001257600080fd5b5060405162001b1038038062001b10833981016040819052620000359162000364565b6001608052600260a052600060c05285620000bd5760405162461bcd60e51b815260206004820152603460248201527f4c324f75747075744f7261636c653a204c3220626c6f636b2074696d65206d7560448201527f73742062652067726561746572207468616e203000000000000000000000000060648201526084015b60405180910390fd5b858711620001435760405162461bcd60e51b815260206004820152604660248201527f4c324f75747075744f7261636c653a207375626d697373696f6e20696e74657260448201527f76616c206d7573742062652067726561746572207468616e204c3220626c6f636064820152656b2074696d6560d01b608482015260a401620000b4565b60e08790526101008690526001600160a01b038084166101405282166101205261016081905262000175858562000182565b50505050505050620003cc565b600054610100900460ff1615808015620001a35750600054600160ff909116105b80620001d35750620001c0306200033860201b620012691760201c565b158015620001d3575060005460ff166001145b620002385760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201526d191e481a5b9a5d1a585b1a5e995960921b6064820152608401620000b4565b6000805460ff1916600117905580156200025c576000805461ff0019166101001790555b42821115620002e25760405162461bcd60e51b8152602060048201526044602482018190527f4c324f75747075744f7261636c653a207374617274696e67204c322074696d65908201527f7374616d70206d757374206265206c657373207468616e2063757272656e742060648201526374696d6560e01b608482015260a401620000b4565b60028290556001839055801562000333576000805461ff0019169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b505050565b6001600160a01b03163b151590565b80516001600160a01b03811681146200035f57600080fd5b919050565b600080600080600080600060e0888a0312156200038057600080fd5b87519650602088015195506040880151945060608801519350620003a76080890162000347565b9250620003b760a0890162000347565b915060c0880151905092959891949750929550565b60805160a05160c05160e051610100516101205161014051610160516116bb620004556000396000818161041501526108f601526000818161036c0152610a66015260008181610236015261079001526000818161015a0152610f9d0152600081816101b60152610feb01526000610503015260006104da015260006104b101526116bb6000f3fe6080604052600436106101435760003560e01c806388786272116100c0578063cf8e5cf011610074578063dcec334811610059578063dcec3348146103ce578063e4a30116146103e3578063f4daa2911461040357600080fd5b8063cf8e5cf01461038e578063d1de856c146103ae57600080fd5b80639aaab648116100a55780639aaab648146102eb578063a25ae557146102fe578063bffa7f0f1461035a57600080fd5b806388786272146102b357806389c44cbb146102c957600080fd5b806369f16eec116101175780636b4d98dd116100fc5780636b4d98dd1461022457806370872aa51461027d5780637f0064201461029357600080fd5b806369f16eec146101fa5780636abcf5631461020f57600080fd5b80622134cc146101485780634599c7881461018f578063529933df146101a457806354fd4d50146101d8575b600080fd5b34801561015457600080fd5b5061017c7f000000000000000000000000000000000000000000000000000000000000000081565b6040519081526020015b60405180910390f35b34801561019b57600080fd5b5061017c610437565b3480156101b057600080fd5b5061017c7f000000000000000000000000000000000000000000000000000000000000000081565b3480156101e457600080fd5b506101ed6104aa565b60405161018691906113f2565b34801561020657600080fd5b5061017c61054d565b34801561021b57600080fd5b5060035461017c565b34801561023057600080fd5b506102587f000000000000000000000000000000000000000000000000000000000000000081565b60405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610186565b34801561028957600080fd5b5061017c60015481565b34801561029f57600080fd5b5061017c6102ae366004611443565b61055f565b3480156102bf57600080fd5b5061017c60025481565b3480156102d557600080fd5b506102e96102e4366004611443565b610778565b005b6102e96102f936600461145c565b610a4e565b34801561030a57600080fd5b5061031e610319366004611443565b610ecd565b60408051825181526020808401516fffffffffffffffffffffffffffffffff908116918301919091529282015190921690820152606001610186565b34801561036657600080fd5b506102587f000000000000000000000000000000000000000000000000000000000000000081565b34801561039a57600080fd5b5061031e6103a9366004611443565b610f61565b3480156103ba57600080fd5b5061017c6103c9366004611443565b610f99565b3480156103da57600080fd5b5061017c610fe7565b3480156103ef57600080fd5b506102e96103fe36600461148e565b61101c565b34801561040f57600080fd5b5061017c7f000000000000000000000000000000000000000000000000000000000000000081565b600354600090156104a15760038054610452906001906114df565b81548110610462576104626114f6565b600091825260209091206002909102016001015470010000000000000000000000000000000090046fffffffffffffffffffffffffffffffff16919050565b6001545b905090565b60606104d57f0000000000000000000000000000000000000000000000000000000000000000611285565b6104fe7f0000000000000000000000000000000000000000000000000000000000000000611285565b6105277f0000000000000000000000000000000000000000000000000000000000000000611285565b60405160200161053993929190611525565b604051602081830303815290604052905090565b6003546000906104a5906001906114df565b6000610569610437565b821115610623576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604860248201527f4c324f75747075744f7261636c653a2063616e6e6f7420676574206f7574707560448201527f7420666f72206120626c6f636b207468617420686173206e6f74206265656e2060648201527f70726f706f736564000000000000000000000000000000000000000000000000608482015260a4015b60405180910390fd5b6003546106d8576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604660248201527f4c324f75747075744f7261636c653a2063616e6e6f7420676574206f7574707560448201527f74206173206e6f206f7574707574732068617665206265656e2070726f706f7360648201527f6564207965740000000000000000000000000000000000000000000000000000608482015260a40161061a565b6003546000905b8082101561077157600060026106f5838561159b565b6106ff91906115e2565b90508460038281548110610715576107156114f6565b600091825260209091206002909102016001015470010000000000000000000000000000000090046fffffffffffffffffffffffffffffffff1610156107675761076081600161159b565b925061076b565b8091505b506106df565b5092915050565b3373ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000161461083d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603e60248201527f4c324f75747075744f7261636c653a206f6e6c7920746865206368616c6c656e60448201527f67657220616464726573732063616e2064656c657465206f7574707574730000606482015260840161061a565b60035481106108f4576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604360248201527f4c324f75747075744f7261636c653a2063616e6e6f742064656c657465206f7560448201527f747075747320616674657220746865206c6174657374206f757470757420696e60648201527f6465780000000000000000000000000000000000000000000000000000000000608482015260a40161061a565b7f000000000000000000000000000000000000000000000000000000000000000060038281548110610928576109286114f6565b6000918252602090912060016002909202010154610958906fffffffffffffffffffffffffffffffff16426114df565b10610a0b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604660248201527f4c324f75747075744f7261636c653a2063616e6e6f742064656c657465206f7560448201527f74707574732074686174206861766520616c7265616479206265656e2066696e60648201527f616c697a65640000000000000000000000000000000000000000000000000000608482015260a40161061a565b6000610a1660035490565b90508160035581817f4ee37ac2c786ec85e87592d3c5c8a1dd66f8496dda3f125d9ea8ca5f657629b660405160405180910390a35050565b3373ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000001614610b39576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604160248201527f4c324f75747075744f7261636c653a206f6e6c79207468652070726f706f736560448201527f7220616464726573732063616e2070726f706f7365206e6577206f757470757460648201527f7300000000000000000000000000000000000000000000000000000000000000608482015260a40161061a565b610b41610fe7565b8314610bf5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604860248201527f4c324f75747075744f7261636c653a20626c6f636b206e756d626572206d757360448201527f7420626520657175616c20746f206e65787420657870656374656420626c6f6360648201527f6b206e756d626572000000000000000000000000000000000000000000000000608482015260a40161061a565b42610bff84610f99565b10610c8c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603660248201527f4c324f75747075744f7261636c653a2063616e6e6f742070726f706f7365204c60448201527f32206f757470757420696e207468652066757475726500000000000000000000606482015260840161061a565b83610d19576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603a60248201527f4c324f75747075744f7261636c653a204c32206f75747075742070726f706f7360448201527f616c2063616e6e6f7420626520746865207a65726f2068617368000000000000606482015260840161061a565b8115610dd55781814014610dd5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604960248201527f4c324f75747075744f7261636c653a20626c6f636b206861736820646f65732060448201527f6e6f74206d61746368207468652068617368206174207468652065787065637460648201527f6564206865696768740000000000000000000000000000000000000000000000608482015260a40161061a565b82610ddf60035490565b857fa7aaf2512769da4e444e3de247be2564225c2e7a8f74cfe528e46e17d24868e242604051610e1191815260200190565b60405180910390a45050604080516060810182529283526fffffffffffffffffffffffffffffffff4281166020850190815292811691840191825260038054600181018255600091909152935160029094027fc2575a0e9e593c00f959f8c92f12db2869c3395a3b0502d05e2516446f71f85b810194909455915190518216700100000000000000000000000000000000029116177fc2575a0e9e593c00f959f8c92f12db2869c3395a3b0502d05e2516446f71f85c90910155565b604080516060810182526000808252602082018190529181019190915260038281548110610efd57610efd6114f6565b600091825260209182902060408051606081018252600290930290910180548352600101546fffffffffffffffffffffffffffffffff8082169484019490945270010000000000000000000000000000000090049092169181019190915292915050565b60408051606081018252600080825260208201819052918101919091526003610f898361055f565b81548110610efd57610efd6114f6565b60007f000000000000000000000000000000000000000000000000000000000000000060015483610fca91906114df565b610fd491906115f6565b600254610fe1919061159b565b92915050565b60007f0000000000000000000000000000000000000000000000000000000000000000611012610437565b6104a5919061159b565b600054610100900460ff161580801561103c5750600054600160ff909116105b806110565750303b158015611056575060005460ff166001145b6110e2576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a6564000000000000000000000000000000000000606482015260840161061a565b600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001179055801561114057600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff166101001790555b428211156111f7576040517f08c379a0000000000000000000000000000000000000000000000000000000008152602060048201526044602482018190527f4c324f75747075744f7261636c653a207374617274696e67204c322074696d65908201527f7374616d70206d757374206265206c657373207468616e2063757272656e742060648201527f74696d6500000000000000000000000000000000000000000000000000000000608482015260a40161061a565b60028290556001839055801561126457600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b505050565b73ffffffffffffffffffffffffffffffffffffffff163b151590565b6060816000036112c857505060408051808201909152600181527f3000000000000000000000000000000000000000000000000000000000000000602082015290565b8160005b81156112f257806112dc81611633565b91506112eb9050600a836115e2565b91506112cc565b60008167ffffffffffffffff81111561130d5761130d61166b565b6040519080825280601f01601f191660200182016040528015611337576020820181803683370190505b5090505b84156113ba5761134c6001836114df565b9150611359600a8661169a565b61136490603061159b565b60f81b818381518110611379576113796114f6565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053506113b3600a866115e2565b945061133b565b949350505050565b60005b838110156113dd5781810151838201526020016113c5565b838111156113ec576000848401525b50505050565b60208152600082518060208401526114118160408501602087016113c2565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169190910160400192915050565b60006020828403121561145557600080fd5b5035919050565b6000806000806080858703121561147257600080fd5b5050823594602084013594506040840135936060013592509050565b600080604083850312156114a157600080fd5b50508035926020909101359150565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b6000828210156114f1576114f16114b0565b500390565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b600084516115378184602089016113c2565b80830190507f2e000000000000000000000000000000000000000000000000000000000000008082528551611573816001850160208a016113c2565b6001920191820152835161158e8160028401602088016113c2565b0160020195945050505050565b600082198211156115ae576115ae6114b0565b500190565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b6000826115f1576115f16115b3565b500490565b6000817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff048311821515161561162e5761162e6114b0565b500290565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203611664576116646114b0565b5060010190565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6000826116a9576116a96115b3565b50069056fea164736f6c634300080f000a",
} }
// L2OutputOracleABI is the input ABI used to generate the binding from. // L2OutputOracleABI is the input ABI used to generate the binding from.
...@@ -50,7 +50,7 @@ var L2OutputOracleABI = L2OutputOracleMetaData.ABI ...@@ -50,7 +50,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, _startingBlockNumber *big.Int, _startingTimestamp *big.Int, _proposer common.Address, _challenger common.Address) (common.Address, *types.Transaction, *L2OutputOracle, error) { func DeployL2OutputOracle(auth *bind.TransactOpts, backend bind.ContractBackend, _submissionInterval *big.Int, _l2BlockTime *big.Int, _startingBlockNumber *big.Int, _startingTimestamp *big.Int, _proposer common.Address, _challenger common.Address, _finalizationPeriodSeconds *big.Int) (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
...@@ -59,7 +59,7 @@ func DeployL2OutputOracle(auth *bind.TransactOpts, backend bind.ContractBackend, ...@@ -59,7 +59,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, _startingBlockNumber, _startingTimestamp, _proposer, _challenger) address, tx, contract, err := bind.DeployContract(auth, *parsed, common.FromHex(L2OutputOracleBin), backend, _submissionInterval, _l2BlockTime, _startingBlockNumber, _startingTimestamp, _proposer, _challenger, _finalizationPeriodSeconds)
if err != nil { if err != nil {
return common.Address{}, nil, nil, err return common.Address{}, nil, nil, err
} }
...@@ -239,6 +239,37 @@ func (_L2OutputOracle *L2OutputOracleCallerSession) CHALLENGER() (common.Address ...@@ -239,6 +239,37 @@ func (_L2OutputOracle *L2OutputOracleCallerSession) CHALLENGER() (common.Address
return _L2OutputOracle.Contract.CHALLENGER(&_L2OutputOracle.CallOpts) return _L2OutputOracle.Contract.CHALLENGER(&_L2OutputOracle.CallOpts)
} }
// FINALIZATIONPERIODSECONDS is a free data retrieval call binding the contract method 0xf4daa291.
//
// Solidity: function FINALIZATION_PERIOD_SECONDS() view returns(uint256)
func (_L2OutputOracle *L2OutputOracleCaller) FINALIZATIONPERIODSECONDS(opts *bind.CallOpts) (*big.Int, error) {
var out []interface{}
err := _L2OutputOracle.contract.Call(opts, &out, "FINALIZATION_PERIOD_SECONDS")
if err != nil {
return *new(*big.Int), err
}
out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int)
return out0, err
}
// FINALIZATIONPERIODSECONDS is a free data retrieval call binding the contract method 0xf4daa291.
//
// Solidity: function FINALIZATION_PERIOD_SECONDS() view returns(uint256)
func (_L2OutputOracle *L2OutputOracleSession) FINALIZATIONPERIODSECONDS() (*big.Int, error) {
return _L2OutputOracle.Contract.FINALIZATIONPERIODSECONDS(&_L2OutputOracle.CallOpts)
}
// FINALIZATIONPERIODSECONDS is a free data retrieval call binding the contract method 0xf4daa291.
//
// Solidity: function FINALIZATION_PERIOD_SECONDS() view returns(uint256)
func (_L2OutputOracle *L2OutputOracleCallerSession) FINALIZATIONPERIODSECONDS() (*big.Int, error) {
return _L2OutputOracle.Contract.FINALIZATIONPERIODSECONDS(&_L2OutputOracle.CallOpts)
}
// L2BLOCKTIME is a free data retrieval call binding the contract method 0x002134cc. // L2BLOCKTIME is a free data retrieval call binding the contract method 0x002134cc.
// //
// Solidity: function L2_BLOCK_TIME() view returns(uint256) // Solidity: function L2_BLOCK_TIME() view returns(uint256)
......
This source diff could not be displayed because it is too large. You can view the blob instead.
...@@ -13,7 +13,7 @@ const OptimismPortalStorageLayoutJSON = "{\"storage\":[{\"astId\":1000,\"contrac ...@@ -13,7 +13,7 @@ const OptimismPortalStorageLayoutJSON = "{\"storage\":[{\"astId\":1000,\"contrac
var OptimismPortalStorageLayout = new(solc.StorageLayout) var OptimismPortalStorageLayout = new(solc.StorageLayout)
var OptimismPortalDeployedBin = "0x60806040526004361061018e5760003560e01c8063867ead13116100d6578063cd7c97891161007f578063e965084c11610059578063e965084c14610517578063e9e05c42146105a3578063f4daa291146105b657600080fd5b8063cd7c978914610441578063cff0ab9614610456578063d53a822f146104f757600080fd5b80639bf62d82116100b05780639bf62d82146103cf578063a14238e7146103fc578063ca3e99ba1461042c57600080fd5b8063867ead13146103995780638b4c40b0146101b35780638c3152e9146103af57600080fd5b80635c975abb116101385780636dbffb78116101125780636dbffb7814610330578063724c184c146103505780638456cb591461038457600080fd5b80635c975abb146102da57806364b79208146103045780636bb0291e1461031b57600080fd5b80634870496f116101695780634870496f1461026657806354fd4d50146102865780635c1f2827146102a857600080fd5b80621c2ff6146101ba57806313620abd146102185780633f4ba83a1461025157600080fd5b366101b5576101b33334620186a06000604051806020016040528060008152506105ea565b005b600080fd5b3480156101c657600080fd5b506101ee7f000000000000000000000000000000000000000000000000000000000000000081565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020015b60405180910390f35b34801561022457600080fd5b50610230633b9aca0081565b6040516fffffffffffffffffffffffffffffffff909116815260200161020f565b34801561025d57600080fd5b506101b3610afe565b34801561027257600080fd5b506101b3610281366004614c76565b610c21565b34801561029257600080fd5b5061029b611287565b60405161020f9190614dcc565b3480156102b457600080fd5b506102cc6fffffffffffffffffffffffffffffffff81565b60405190815260200161020f565b3480156102e657600080fd5b506035546102f49060ff1681565b604051901515815260200161020f565b34801561031057600080fd5b506102cc627a120081565b34801561032757600080fd5b506102cc600481565b34801561033c57600080fd5b506102f461034b366004614ddf565b61132a565b34801561035c57600080fd5b506101ee7f000000000000000000000000000000000000000000000000000000000000000081565b34801561039057600080fd5b506101b3611401565b3480156103a557600080fd5b506102cc61271081565b3480156103bb57600080fd5b506101b36103ca366004614df8565b611521565b3480156103db57600080fd5b506032546101ee9073ffffffffffffffffffffffffffffffffffffffff1681565b34801561040857600080fd5b506102f4610417366004614ddf565b60336020526000908152604090205460ff1681565b34801561043857600080fd5b506102cc611ea4565b34801561044d57600080fd5b506102cc600881565b34801561046257600080fd5b506001546104be906fffffffffffffffffffffffffffffffff81169067ffffffffffffffff7001000000000000000000000000000000008204811691780100000000000000000000000000000000000000000000000090041683565b604080516fffffffffffffffffffffffffffffffff909416845267ffffffffffffffff928316602085015291169082015260600161020f565b34801561050357600080fd5b506101b3610512366004614e3d565b611eb5565b34801561052357600080fd5b50610575610532366004614ddf565b603460205260009081526040902080546001909101546fffffffffffffffffffffffffffffffff8082169170010000000000000000000000000000000090041683565b604080519384526fffffffffffffffffffffffffffffffff928316602085015291169082015260600161020f565b6101b36105b1366004614e58565b6105ea565b3480156105c257600080fd5b506102cc7f000000000000000000000000000000000000000000000000000000000000000081565b8260005a905083156106a15773ffffffffffffffffffffffffffffffffffffffff8716156106a157604080517f08c379a00000000000000000000000000000000000000000000000000000000081526020600482015260248101919091527f4f7074696d69736d506f7274616c3a206d7573742073656e6420746f2061646460448201527f72657373283029207768656e206372656174696e67206120636f6e747261637460648201526084015b60405180910390fd5b6152088567ffffffffffffffff16101561073d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603860248201527f4f7074696d69736d506f7274616c3a20676173206c696d6974206d757374206360448201527f6f76657220696e737472696e7369632067617320636f737400000000000000006064820152608401610698565b3332811461075e575033731111000000000000000000000000000000001111015b60003488888888604051602001610779959493929190614edd565b604051602081830303815290604052905060008973ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff167fb3813568d9991fc951961fcb4c784893574240a28925604d09fc577c55bb7c32846040516107e99190614dcc565b60405180910390a45050600154600090610829907801000000000000000000000000000000000000000000000000900467ffffffffffffffff1643614f71565b9050801561095d5760006108416004627a1200614fb7565b60015461086c9190700100000000000000000000000000000000900467ffffffffffffffff1661501f565b9050600060086108806004627a1200614fb7565b61088a9190615093565b6001546108aa9084906fffffffffffffffffffffffffffffffff16615093565b6108b49190614fb7565b6001549091506000906108f7906108de9084906fffffffffffffffffffffffffffffffff1661514f565b6127106fffffffffffffffffffffffffffffffff6120be565b9050600184111561091e5761091b6108de826008610916600189614f71565b6120dd565b90505b6fffffffffffffffffffffffffffffffff16780100000000000000000000000000000000000000000000000067ffffffffffffffff4316021760015550505b60018054849190601090610990908490700100000000000000000000000000000000900467ffffffffffffffff166151c3565b92506101000a81548167ffffffffffffffff021916908367ffffffffffffffff160217905550627a1200600160000160109054906101000a900467ffffffffffffffff1667ffffffffffffffff161315610a6c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603e60248201527f5265736f757263654d65746572696e673a2063616e6e6f7420627579206d6f7260448201527f6520676173207468616e20617661696c61626c6520676173206c696d697400006064820152608401610698565b600154600090610a98906fffffffffffffffffffffffffffffffff1667ffffffffffffffff86166151ef565b6fffffffffffffffffffffffffffffffff1690506000610abc48633b9aca00612132565b610ac69083615227565b905060005a610ad59086614f71565b905080821115610af157610af1610aec8284614f71565b612149565b5050505050505050505050565b3373ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000001614610bc3576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602960248201527f4f7074696d69736d506f7274616c3a206f6e6c7920677561726469616e20636160448201527f6e20756e706175736500000000000000000000000000000000000000000000006064820152608401610698565b603580547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001690556040513381527f5db9ee0a495bf2e6ff9c91a7834c1ba4fdd244a5e8aa4e537bd38aeae4b073aa906020015b60405180910390a1565b60355460ff1615610c8e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4f7074696d69736d506f7274616c3a20706175736564000000000000000000006044820152606401610698565b3073ffffffffffffffffffffffffffffffffffffffff16856040015173ffffffffffffffffffffffffffffffffffffffff1603610d4d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603f60248201527f4f7074696d69736d506f7274616c3a20796f752063616e6e6f742073656e642060448201527f6d6573736167657320746f2074686520706f7274616c20636f6e7472616374006064820152608401610698565b6040517fa25ae557000000000000000000000000000000000000000000000000000000008152600481018590526000907f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff169063a25ae55790602401606060405180830381865afa158015610ddb573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610dff919061525b565b519050610e19610e14368690038601866152c0565b612177565b8114610ea7576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602960248201527f4f7074696d69736d506f7274616c3a20696e76616c6964206f7574707574207260448201527f6f6f742070726f6f6600000000000000000000000000000000000000000000006064820152608401610698565b6000610eb2876121d3565b6000818152603460209081526040918290208251606081018452815481526001909101546fffffffffffffffffffffffffffffffff8082169383018490527001000000000000000000000000000000009091041692810192909252919250901580610fe45750805160408083015190517fa25ae5570000000000000000000000000000000000000000000000000000000081526fffffffffffffffffffffffffffffffff90911660048201527f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff169063a25ae55790602401606060405180830381865afa158015610fbc573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610fe0919061525b565b5114155b611070576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603760248201527f4f7074696d69736d506f7274616c3a207769746864726177616c20686173682060448201527f68617320616c7265616479206265656e2070726f76656e0000000000000000006064820152608401610698565b60408051602081018490526000918101829052606001604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0818403018152828252805160209182012090830181905292506111399101604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0818403018152828201909152600182527f010000000000000000000000000000000000000000000000000000000000000060208301529061112f888a615326565b8a60400135612203565b6111c5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603260248201527f4f7074696d69736d506f7274616c3a20696e76616c696420776974686472617760448201527f616c20696e636c7573696f6e2070726f6f6600000000000000000000000000006064820152608401610698565b604080516060810182528581526fffffffffffffffffffffffffffffffff42811660208084019182528c831684860190815260008981526034835286812095518655925190518416700100000000000000000000000000000000029316929092176001909301929092558b830151908c0151925173ffffffffffffffffffffffffffffffffffffffff918216939091169186917f67a6208cfcc0801d50f6cbe764733f4fddf66ac0b04442061a8a8c0cb6b63f629190a4505050505050505050565b60606112b27f0000000000000000000000000000000000000000000000000000000000000000612227565b6112db7f0000000000000000000000000000000000000000000000000000000000000000612227565b6113047f0000000000000000000000000000000000000000000000000000000000000000612227565b604051602001611316939291906153aa565b604051602081830303815290604052905090565b6040517fa25ae557000000000000000000000000000000000000000000000000000000008152600481018290526000906113fb9073ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000169063a25ae55790602401606060405180830381865afa1580156113bc573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906113e0919061525b565b602001516fffffffffffffffffffffffffffffffff16612364565b92915050565b3373ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000000000000000000000000000000000000000000016146114c6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602760248201527f4f7074696d69736d506f7274616c3a206f6e6c7920677561726469616e20636160448201527f6e207061757365000000000000000000000000000000000000000000000000006064820152608401610698565b603580547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660011790556040513381527f62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a25890602001610c17565b60355460ff161561158e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4f7074696d69736d506f7274616c3a20706175736564000000000000000000006044820152606401610698565b60325473ffffffffffffffffffffffffffffffffffffffff1661dead14611637576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603f60248201527f4f7074696d69736d506f7274616c3a2063616e206f6e6c79207472696767657260448201527f206f6e65207769746864726177616c20706572207472616e73616374696f6e006064820152608401610698565b6000611642826121d3565b60008181526034602090815260408083208151606081018352815481526001909101546fffffffffffffffffffffffffffffffff8082169483018590527001000000000000000000000000000000009091041691810191909152929350900361172d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603260248201527f4f7074696d69736d506f7274616c3a207769746864726177616c20686173206e60448201527f6f74206265656e2070726f76656e2079657400000000000000000000000000006064820152608401610698565b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663887862726040518163ffffffff1660e01b8152600401602060405180830381865afa158015611798573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906117bc9190615420565b81602001516fffffffffffffffffffffffffffffffff161015611887576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604b60248201527f4f7074696d69736d506f7274616c3a207769746864726177616c2074696d657360448201527f74616d70206c657373207468616e204c32204f7261636c65207374617274696e60648201527f672074696d657374616d70000000000000000000000000000000000000000000608482015260a401610698565b6118a681602001516fffffffffffffffffffffffffffffffff16612364565b611958576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604560248201527f4f7074696d69736d506f7274616c3a2070726f76656e2077697468647261776160448201527f6c2066696e616c697a6174696f6e20706572696f6420686173206e6f7420656c60648201527f6170736564000000000000000000000000000000000000000000000000000000608482015260a401610698565b60408181015190517fa25ae5570000000000000000000000000000000000000000000000000000000081526fffffffffffffffffffffffffffffffff90911660048201526000907f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff169063a25ae55790602401606060405180830381865afa1580156119fd573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611a21919061525b565b8251815191925014611adb576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604960248201527f4f7074696d69736d506f7274616c3a206f757470757420726f6f742070726f7660448201527f656e206973206e6f74207468652073616d652061732063757272656e74206f7560648201527f7470757420726f6f740000000000000000000000000000000000000000000000608482015260a401610698565b611afa81602001516fffffffffffffffffffffffffffffffff16612364565b611bac576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604360248201527f4f7074696d69736d506f7274616c3a206f75747075742070726f706f73616c2060448201527f66696e616c697a6174696f6e20706572696f6420686173206e6f7420656c617060648201527f7365640000000000000000000000000000000000000000000000000000000000608482015260a401610698565b60008381526033602052604090205460ff1615611c4b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603560248201527f4f7074696d69736d506f7274616c3a207769746864726177616c20686173206160448201527f6c7265616479206265656e2066696e616c697a656400000000000000000000006064820152608401610698565b600083815260336020526040902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660011790556080840151611c9490614e2090615439565b5a1015611d23576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603760248201527f4f7074696d69736d506f7274616c3a20696e73756666696369656e742067617360448201527f20746f2066696e616c697a65207769746864726177616c0000000000000000006064820152608401610698565b6020840151603280547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff9092169190911790556040840151600090611d9590614e205a611d869190614f71565b87606001518860a00151612398565b603280547fffffffffffffffffffffffff00000000000000000000000000000000000000001661dead17905560405190915084907fdb5c7652857aa163daadd670e116628fb42e869d8ac4251ef8971d9e5727df1b90611dfa90841515815260200190565b60405180910390a280158015611e105750326001145b15611e9d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602160248201527f4f7074696d69736d506f7274616c3a207769746864726177616c206661696c6560448201527f64000000000000000000000000000000000000000000000000000000000000006064820152608401610698565b5050505050565b611eb26004627a1200614fb7565b81565b600054610100900460ff1615808015611ed55750600054600160ff909116105b80611eef5750303b158015611eef575060005460ff166001145b611f7b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a65640000000000000000000000000000000000006064820152608401610698565b600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660011790558015611fd957600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff166101001790555b603280547fffffffffffffffffffffffff00000000000000000000000000000000000000001661dead179055603580548315157fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0090911617905561203b6123b2565b801561209e57600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b5050565b73ffffffffffffffffffffffffffffffffffffffff163b151590565b60006120d36120cd8585612495565b836124a5565b90505b9392505050565b6000670de0b6b3a764000061211e6120f58583614fb7565b61210790670de0b6b3a764000061501f565b61211985670de0b6b3a7640000615093565b6124b4565b6121289086615093565b6120d39190614fb7565b60008183101561214257816120d6565b5090919050565b6000805a90505b825a61215c9083614f71565b10156121725761216b82615451565b9150612150565b505050565b600081600001518260200151836040015184606001516040516020016121b6949392919093845260208401929092526040830152606082015260800190565b604051602081830303815290604052805190602001209050919050565b80516020808301516040808501516060860151608087015160a088015193516000976121b6979096959101615489565b60008061220f866124e5565b905061221d81868686612517565b9695505050505050565b60608160000361226a57505060408051808201909152600181527f3000000000000000000000000000000000000000000000000000000000000000602082015290565b8160005b8115612294578061227e81615451565b915061228d9050600a83615227565b915061226e565b60008167ffffffffffffffff8111156122af576122af614a9c565b6040519080825280601f01601f1916602001820160405280156122d9576020820181803683370190505b5090505b841561235c576122ee600183614f71565b91506122fb600a866154e0565b612306906030615439565b60f81b81838151811061231b5761231b6154f4565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a905350612355600a86615227565b94506122dd565b949350505050565b60006123907f000000000000000000000000000000000000000000000000000000000000000083615439565b421192915050565b600080600080845160208601878a8af19695505050505050565b600054610100900460ff16612449576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e670000000000000000000000000000000000000000006064820152608401610698565b60408051606081018252633b9aca00808252600060208301524367ffffffffffffffff169190920181905278010000000000000000000000000000000000000000000000000217600155565b60008183121561214257816120d6565b600081831261214257816120d6565b60006120d6670de0b6b3a7640000836124cc86612547565b6124d69190615093565b6124e09190614fb7565b61278b565b6060818051906020012060405160200161250191815260200190565b6040516020818303038152906040529050919050565b600061253e846125288786866129ca565b8051602091820120825192909101919091201490565b95945050505050565b60008082136125b2576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600960248201527f554e444546494e454400000000000000000000000000000000000000000000006044820152606401610698565b600060606125bf84613452565b03609f8181039490941b90931c6c465772b2bbbb5f824b15207a3081018102606090811d6d0388eaa27412d5aca026815d636e018202811d6d0df99ac502031bf953eff472fdcc018202811d6d13cdffb29d51d99322bdff5f2211018202811d6d0a0f742023def783a307a986912e018202811d6d01920d8043ca89b5239253284e42018202811d6c0b7a86d7375468fac667a0a527016c29508e458543d8aa4df2abee7883018302821d6d0139601a2efabe717e604cbb4894018302821d6d02247f7a7b6594320649aa03aba1018302821d7fffffffffffffffffffffffffffffffffffffff73c0c716a594e00d54e3c4cbc9018302821d7ffffffffffffffffffffffffffffffffffffffdc7b88c420e53a9890533129f6f01830290911d7fffffffffffffffffffffffffffffffffffffff465fda27eb4d63ded474e5f832019091027ffffffffffffffff5f6af8f7b3396644f18e157960000000000000000000000000105711340daa0d5f769dba1915cef59f0815a5506027d0267a36c0c95b3975ab3ee5b203a7614a3f75373f047d803ae7b6687f2b393909302929092017d57115e47018c7177eebf7cd370a3356a1b7863008a5ae8028c72b88642840160ae1d92915050565b60007ffffffffffffffffffffffffffffffffffffffffffffffffdb731c958f34d94c182136127bc57506000919050565b680755bf798b4a1bf1e5821261282e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600c60248201527f4558505f4f564552464c4f5700000000000000000000000000000000000000006044820152606401610698565b6503782dace9d9604e83901b059150600060606bb17217f7d1cf79abc9e3b39884821b056b80000000000000000000000001901d6bb17217f7d1cf79abc9e3b39881029093037fffffffffffffffffffffffffffffffffffffffdbf3ccf1604d263450f02a550481018102606090811d6d0277594991cfc85f6e2461837cd9018202811d7fffffffffffffffffffffffffffffffffffffe5adedaa1cb095af9e4da10e363c018202811d6db1bbb201f443cf962f1a1d3db4a5018202811d7ffffffffffffffffffffffffffffffffffffd38dc772608b0ae56cce01296c0eb018202811d6e05180bb14799ab47a8a8cb2a527d57016d02d16720577bd19bf614176fe9ea6c10fe68e7fd37d0007b713f765084018402831d9081019084017ffffffffffffffffffffffffffffffffffffffe2c69812cf03b0763fd454a8f7e010290911d6e0587f503bb6ea29d25fcb7401964500190910279d835ebba824c98fb31b83b2ca45c000000000000000000000000010574029d9dc38563c32e5c2f6dc192ee70ef65f9978af30260c3939093039290921c92915050565b60606000845111612a37576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601560248201527f4d65726b6c65547269653a20656d707479206b657900000000000000000000006044820152606401610698565b6000612a4284613528565b90506000612a4f86613617565b9050600084604051602001612a6691815260200190565b60405160208183030381529060405290506000805b84518110156133c9576000858281518110612a9857612a986154f4565b602002602001015190508451831115612b33576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f4d65726b6c65547269653a206b657920696e646578206578636565647320746f60448201527f74616c206b6579206c656e6774680000000000000000000000000000000000006064820152608401610698565b82600003612bec5780518051602091820120604051612b8192612b5b92910190815260200190565b604051602081830303815290604052858051602091820120825192909101919091201490565b612be7576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f4d65726b6c65547269653a20696e76616c696420726f6f7420686173680000006044820152606401610698565b612d43565b805151602011612ca25780518051602091820120604051612c1692612b5b92910190815260200190565b612be7576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602760248201527f4d65726b6c65547269653a20696e76616c6964206c6172676520696e7465726e60448201527f616c2068617368000000000000000000000000000000000000000000000000006064820152608401610698565b805184516020808701919091208251919092012014612d43576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f4d65726b6c65547269653a20696e76616c696420696e7465726e616c206e6f6460448201527f65206861736800000000000000000000000000000000000000000000000000006064820152608401610698565b612d4f60106001615439565b81602001515103612f305784518303612ec8576000612d8b8260200151601081518110612d7e57612d7e6154f4565b60200260200101516137b2565b90506000815111612e1e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603b60248201527f4d65726b6c65547269653a2076616c7565206c656e677468206d75737420626560448201527f2067726561746572207468616e207a65726f20286272616e63682900000000006064820152608401610698565b60018751612e2c9190614f71565b8314612eba576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603a60248201527f4d65726b6c65547269653a2076616c7565206e6f6465206d757374206265206c60448201527f617374206e6f646520696e2070726f6f6620286272616e6368290000000000006064820152608401610698565b96506120d695505050505050565b6000858481518110612edc57612edc6154f4565b602001015160f81c60f81b60f81c9050600082602001518260ff1681518110612f0757612f076154f4565b60200260200101519050612f1a81613912565b9550612f27600186615439565b945050506133b6565b60028160200151510361332e576000612f4882613937565b9050600081600081518110612f5f57612f5f6154f4565b016020015160f81c90506000612f76600283615523565b612f81906002615545565b90506000612f92848360ff1661395b565b90506000612fa08a8961395b565b90506000612fae8383613991565b905080835114613040576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603a60248201527f4d65726b6c65547269653a20706174682072656d61696e646572206d7573742060448201527f736861726520616c6c206e6962626c65732077697468206b65790000000000006064820152608401610698565b60ff851660021480613055575060ff85166003145b1561324957808251146130ea576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603d60248201527f4d65726b6c65547269653a206b65792072656d61696e646572206d757374206260448201527f65206964656e746963616c20746f20706174682072656d61696e6465720000006064820152608401610698565b60006131068860200151600181518110612d7e57612d7e6154f4565b90506000815111613199576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603960248201527f4d65726b6c65547269653a2076616c7565206c656e677468206d75737420626560448201527f2067726561746572207468616e207a65726f20286c65616629000000000000006064820152608401610698565b60018d516131a79190614f71565b8914613235576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603860248201527f4d65726b6c65547269653a2076616c7565206e6f6465206d757374206265206c60448201527f617374206e6f646520696e2070726f6f6620286c6561662900000000000000006064820152608401610698565b9c506120d69b505050505050505050505050565b60ff8516158061325c575060ff85166001145b1561329b57613288876020015160018151811061327b5761327b6154f4565b6020026020010151613912565b9950613294818a615439565b9850613323565b6040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603260248201527f4d65726b6c65547269653a2072656365697665642061206e6f6465207769746860448201527f20616e20756e6b6e6f776e2070726566697800000000000000000000000000006064820152608401610698565b5050505050506133b6565b6040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602860248201527f4d65726b6c65547269653a20726563656976656420616e20756e70617273656160448201527f626c65206e6f64650000000000000000000000000000000000000000000000006064820152608401610698565b50806133c181615451565b915050612a7b565b506040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602560248201527f4d65726b6c65547269653a2072616e206f7574206f662070726f6f6620656c6560448201527f6d656e74730000000000000000000000000000000000000000000000000000006064820152608401610698565b60008082116134bd576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600960248201527f554e444546494e454400000000000000000000000000000000000000000000006044820152606401610698565b5060016fffffffffffffffffffffffffffffffff821160071b82811c67ffffffffffffffff1060061b1782811c63ffffffff1060051b1782811c61ffff1060041b1782811c60ff10600390811b90911783811c600f1060021b1783811c909110821b1791821c111790565b805160609060008167ffffffffffffffff81111561354857613548614a9c565b60405190808252806020026020018201604052801561358d57816020015b60408051808201909152606080825260208201528152602001906001900390816135665790505b50905060005b8281101561360f5760405180604001604052808683815181106135b8576135b86154f4565b602002602001015181526020016135e78784815181106135da576135da6154f4565b6020026020010151613a40565b8152508282815181106135fc576135fc6154f4565b6020908102919091010152600101613593565b509392505050565b80516060906000613629826002615568565b67ffffffffffffffff81111561364157613641614a9c565b6040519080825280601f01601f19166020018201604052801561366b576020820181803683370190505b5090506000805b838110156137a85785818151811061368c5761368c6154f4565b6020910101517fff000000000000000000000000000000000000000000000000000000000000008116925060041c7f0ff000000000000000000000000000000000000000000000000000000000000016836136e8836002615568565b815181106136f8576136f86154f4565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053507f0f00000000000000000000000000000000000000000000000000000000000000821683613756836002615568565b613761906001615439565b81518110613771576137716154f4565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a905350600101613672565b5090949350505050565b606060008060006137c285613a53565b9194509250905060008160018111156137dd576137dd6155a5565b1461386a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603960248201527f524c505265616465723a206465636f646564206974656d207479706520666f7260448201527f206279746573206973206e6f7420612064617461206974656d000000000000006064820152608401610698565b6138748284615439565b855114613903576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603460248201527f524c505265616465723a2062797465732076616c756520636f6e7461696e732060448201527f616e20696e76616c69642072656d61696e6465720000000000000000000000006064820152608401610698565b61253e856020015184846144c0565b6060602082600001511061392e57613929826137b2565b6113fb565b6113fb82614561565b60606113fb6139568360200151600081518110612d7e57612d7e6154f4565b613617565b60608251821061397a57506040805160208101909152600081526113fb565b6120d6838384865161398c9190614f71565b614577565b600080600083518551106139a65783516139a9565b84515b90505b8082108015613a3057508382815181106139c8576139c86154f4565b602001015160f81c60f81b7effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916858381518110613a0757613a076154f4565b01602001517fff0000000000000000000000000000000000000000000000000000000000000016145b1561360f578160010191506139ac565b60606113fb613a4e8361474f565b614838565b600080600080846000015111613b11576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604a60248201527f524c505265616465723a206c656e677468206f6620616e20524c50206974656d60448201527f206d7573742062652067726561746572207468616e207a65726f20746f20626560648201527f206465636f6461626c6500000000000000000000000000000000000000000000608482015260a401610698565b6020840151805160001a607f8111613b365760006001600094509450945050506144b9565b60b78111613d44576000613b4b608083614f71565b905080876000015111613c06576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604e60248201527f524c505265616465723a206c656e677468206f6620636f6e74656e74206d757360448201527f742062652067726561746572207468616e20737472696e67206c656e6774682060648201527f2873686f727420737472696e6729000000000000000000000000000000000000608482015260a401610698565b6001838101517fff00000000000000000000000000000000000000000000000000000000000000169082141580613c7f57507f80000000000000000000000000000000000000000000000000000000000000007fff00000000000000000000000000000000000000000000000000000000000000821610155b613d31576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604d60248201527f524c505265616465723a20696e76616c6964207072656669782c2073696e676c60448201527f652062797465203c203078383020617265206e6f74207072656669786564202860648201527f73686f727420737472696e672900000000000000000000000000000000000000608482015260a401610698565b50600195509350600092506144b9915050565b60bf8111614092576000613d5960b783614f71565b905080876000015111613e14576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152605160248201527f524c505265616465723a206c656e677468206f6620636f6e74656e74206d757360448201527f74206265203e207468616e206c656e677468206f6620737472696e67206c656e60648201527f67746820286c6f6e6720737472696e6729000000000000000000000000000000608482015260a401610698565b60018301517fff00000000000000000000000000000000000000000000000000000000000000166000819003613ef2576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604a60248201527f524c505265616465723a206c656e677468206f6620636f6e74656e74206d757360448201527f74206e6f74206861766520616e79206c656164696e67207a65726f7320286c6f60648201527f6e6720737472696e672900000000000000000000000000000000000000000000608482015260a401610698565b600184015160088302610100031c60378111613fb6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604860248201527f524c505265616465723a206c656e677468206f6620636f6e74656e74206d757360448201527f742062652067726561746572207468616e20353520627974657320286c6f6e6760648201527f20737472696e6729000000000000000000000000000000000000000000000000608482015260a401610698565b613fc08184615439565b895111614075576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604c60248201527f524c505265616465723a206c656e677468206f6620636f6e74656e74206d757360448201527f742062652067726561746572207468616e20746f74616c206c656e677468202860648201527f6c6f6e6720737472696e67290000000000000000000000000000000000000000608482015260a401610698565b614080836001615439565b97509550600094506144b99350505050565b60f781116141735760006140a760c083614f71565b905080876000015111614162576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604a60248201527f524c505265616465723a206c656e677468206f6620636f6e74656e74206d757360448201527f742062652067726561746572207468616e206c697374206c656e67746820287360648201527f686f7274206c6973742900000000000000000000000000000000000000000000608482015260a401610698565b6001955093508492506144b9915050565b600061418060f783614f71565b90508087600001511161423b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604d60248201527f524c505265616465723a206c656e677468206f6620636f6e74656e74206d757360448201527f74206265203e207468616e206c656e677468206f66206c697374206c656e677460648201527f6820286c6f6e67206c6973742900000000000000000000000000000000000000608482015260a401610698565b60018301517fff00000000000000000000000000000000000000000000000000000000000000166000819003614319576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604860248201527f524c505265616465723a206c656e677468206f6620636f6e74656e74206d757360448201527f74206e6f74206861766520616e79206c656164696e67207a65726f7320286c6f60648201527f6e67206c69737429000000000000000000000000000000000000000000000000608482015260a401610698565b600184015160088302610100031c603781116143dd576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604660248201527f524c505265616465723a206c656e677468206f6620636f6e74656e74206d757360448201527f742062652067726561746572207468616e20353520627974657320286c6f6e6760648201527f206c697374290000000000000000000000000000000000000000000000000000608482015260a401610698565b6143e78184615439565b89511161449c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604a60248201527f524c505265616465723a206c656e677468206f6620636f6e74656e74206d757360448201527f742062652067726561746572207468616e20746f74616c206c656e677468202860648201527f6c6f6e67206c6973742900000000000000000000000000000000000000000000608482015260a401610698565b6144a7836001615439565b97509550600194506144b99350505050565b9193909250565b606060008267ffffffffffffffff8111156144dd576144dd614a9c565b6040519080825280601f01601f191660200182016040528015614507576020820181803683370190505b509050826000036145195790506120d6565b60006145258587615439565b90506020820160005b8581101561454657828101518282015260200161452e565b85811115614555576000868301525b50919695505050505050565b60606113fb8260200151600084600001516144c0565b60608182601f0110156145e6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600e60248201527f736c6963655f6f766572666c6f770000000000000000000000000000000000006044820152606401610698565b828284011015614652576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600e60248201527f736c6963655f6f766572666c6f770000000000000000000000000000000000006044820152606401610698565b818301845110156146bf576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601160248201527f736c6963655f6f75744f66426f756e64730000000000000000000000000000006044820152606401610698565b6060821580156146de5760405191506000825260208201604052614746565b6040519150601f8416801560200281840101858101878315602002848b0101015b818310156147175780518352602092830192016146ff565b5050858452601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016604052505b50949350505050565b6040805180820190915260008082526020820152600082511161481a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604a60248201527f524c505265616465723a206c656e677468206f6620616e20524c50206974656d60448201527f206d7573742062652067726561746572207468616e207a65726f20746f20626560648201527f206465636f6461626c6500000000000000000000000000000000000000000000608482015260a401610698565b50604080518082019091528151815260209182019181019190915290565b6060600080600061484885613a53565b919450925090506001816001811115614863576148636155a5565b146148f0576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603860248201527f524c505265616465723a206465636f646564206974656d207479706520666f7260448201527f206c697374206973206e6f742061206c697374206974656d00000000000000006064820152608401610698565b84516148fc8385615439565b14614989576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603260248201527f524c505265616465723a206c697374206974656d2068617320616e20696e766160448201527f6c696420646174612072656d61696e64657200000000000000000000000000006064820152608401610698565b6040805160208082526104208201909252600091816020015b60408051808201909152600080825260208201528152602001906001900390816149a25790505090506000845b8751811015614a9057600080614a156040518060400160405280858d600001516149f99190614f71565b8152602001858d60200151614a0e9190615439565b9052613a53565b509150915060405180604001604052808383614a319190615439565b8152602001848c60200151614a469190615439565b815250858581518110614a5b57614a5b6154f4565b6020908102919091010152614a71600185615439565b9350614a7d8183615439565b614a879084615439565b925050506149cf565b50815295945050505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff81118282101715614b1257614b12614a9c565b604052919050565b803573ffffffffffffffffffffffffffffffffffffffff81168114614b3e57600080fd5b919050565b600082601f830112614b5457600080fd5b813567ffffffffffffffff811115614b6e57614b6e614a9c565b614b9f60207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f84011601614acb565b818152846020838601011115614bb457600080fd5b816020850160208301376000918101602001919091529392505050565b600060c08284031215614be357600080fd5b60405160c0810167ffffffffffffffff8282108183111715614c0757614c07614a9c565b8160405282935084358352614c1e60208601614b1a565b6020840152614c2f60408601614b1a565b6040840152606085013560608401526080850135608084015260a0850135915080821115614c5c57600080fd5b50614c6985828601614b43565b60a0830152505092915050565b600080600080600085870360e0811215614c8f57600080fd5b863567ffffffffffffffff80821115614ca757600080fd5b614cb38a838b01614bd1565b97506020890135965060807fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc084011215614cec57600080fd5b60408901955060c0890135925080831115614d0657600080fd5b828901925089601f840112614d1a57600080fd5b8235915080821115614d2b57600080fd5b508860208260051b8401011115614d4157600080fd5b959894975092955050506020019190565b60005b83811015614d6d578181015183820152602001614d55565b83811115614d7c576000848401525b50505050565b60008151808452614d9a816020860160208601614d52565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b6020815260006120d66020830184614d82565b600060208284031215614df157600080fd5b5035919050565b600060208284031215614e0a57600080fd5b813567ffffffffffffffff811115614e2157600080fd5b61235c84828501614bd1565b80358015158114614b3e57600080fd5b600060208284031215614e4f57600080fd5b6120d682614e2d565b600080600080600060a08688031215614e7057600080fd5b614e7986614b1a565b945060208601359350604086013567ffffffffffffffff8082168214614e9e57600080fd5b819450614ead60608901614e2d565b93506080880135915080821115614ec357600080fd5b50614ed088828901614b43565b9150509295509295909350565b8581528460208201527fffffffffffffffff0000000000000000000000000000000000000000000000008460c01b16604082015282151560f81b604882015260008251614f31816049850160208701614d52565b919091016049019695505050505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b600082821015614f8357614f83614f42565b500390565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b600082614fc657614fc6614f88565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff83147f80000000000000000000000000000000000000000000000000000000000000008314161561501a5761501a614f42565b500590565b6000808312837f80000000000000000000000000000000000000000000000000000000000000000183128115161561505957615059614f42565b837f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01831381161561508d5761508d614f42565b50500390565b60007f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff6000841360008413858304851182821616156150d4576150d4614f42565b7f8000000000000000000000000000000000000000000000000000000000000000600087128682058812818416161561510f5761510f614f42565b6000871292508782058712848416161561512b5761512b614f42565b8785058712818416161561514157615141614f42565b505050929093029392505050565b6000808212827f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0384138115161561518957615189614f42565b827f80000000000000000000000000000000000000000000000000000000000000000384128116156151bd576151bd614f42565b50500190565b600067ffffffffffffffff8083168185168083038211156151e6576151e6614f42565b01949350505050565b60006fffffffffffffffffffffffffffffffff8083168185168183048111821515161561521e5761521e614f42565b02949350505050565b60008261523657615236614f88565b500490565b80516fffffffffffffffffffffffffffffffff81168114614b3e57600080fd5b60006060828403121561526d57600080fd5b6040516060810181811067ffffffffffffffff8211171561529057615290614a9c565b604052825181526152a36020840161523b565b60208201526152b46040840161523b565b60408201529392505050565b6000608082840312156152d257600080fd5b6040516080810181811067ffffffffffffffff821117156152f5576152f5614a9c565b8060405250823581526020830135602082015260408301356040820152606083013560608201528091505092915050565b600067ffffffffffffffff8084111561534157615341614a9c565b8360051b6020615352818301614acb565b86815291850191818101903684111561536a57600080fd5b865b8481101561539e578035868111156153845760008081fd5b61539036828b01614b43565b84525091830191830161536c565b50979650505050505050565b600084516153bc818460208901614d52565b80830190507f2e0000000000000000000000000000000000000000000000000000000000000080825285516153f8816001850160208a01614d52565b60019201918201528351615413816002840160208801614d52565b0160020195945050505050565b60006020828403121561543257600080fd5b5051919050565b6000821982111561544c5761544c614f42565b500190565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff820361548257615482614f42565b5060010190565b868152600073ffffffffffffffffffffffffffffffffffffffff808816602084015280871660408401525084606083015283608083015260c060a08301526154d460c0830184614d82565b98975050505050505050565b6000826154ef576154ef614f88565b500690565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b600060ff83168061553657615536614f88565b8060ff84160691505092915050565b600060ff821660ff84168082101561555f5761555f614f42565b90039392505050565b6000817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff04831182151516156155a0576155a0614f42565b500290565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fdfea164736f6c634300080f000a" var OptimismPortalDeployedBin = "0x6080604052600436106101835760003560e01c80638456cb59116100d6578063ca3e99ba1161007f578063d53a822f11610059578063d53a822f146104ec578063e965084c1461050c578063e9e05c421461059857600080fd5b8063ca3e99ba14610421578063cd7c978914610436578063cff0ab961461044b57600080fd5b80638c3152e9116100b05780638c3152e9146103a45780639bf62d82146103c4578063a14238e7146103f157600080fd5b80638456cb5914610379578063867ead131461038e5780638b4c40b0146101a857600080fd5b80635c1f2827116101385780636bb0291e116101125780636bb0291e146103105780636dbffb7814610325578063724c184c1461034557600080fd5b80635c1f28271461029d5780635c975abb146102cf57806364b79208146102f957600080fd5b80633f4ba83a116101695780633f4ba83a146102465780634870496f1461025b57806354fd4d501461027b57600080fd5b80621c2ff6146101af57806313620abd1461020d57600080fd5b366101aa576101a83334620186a06000604051806020016040528060008152506105a6565b005b600080fd5b3480156101bb57600080fd5b506101e37f000000000000000000000000000000000000000000000000000000000000000081565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020015b60405180910390f35b34801561021957600080fd5b50610225633b9aca0081565b6040516fffffffffffffffffffffffffffffffff9091168152602001610204565b34801561025257600080fd5b506101a8610aba565b34801561026757600080fd5b506101a8610276366004614ca1565b610bdd565b34801561028757600080fd5b50610290611243565b6040516102049190614df7565b3480156102a957600080fd5b506102c16fffffffffffffffffffffffffffffffff81565b604051908152602001610204565b3480156102db57600080fd5b506035546102e99060ff1681565b6040519015158152602001610204565b34801561030557600080fd5b506102c1627a120081565b34801561031c57600080fd5b506102c1600481565b34801561033157600080fd5b506102e9610340366004614e0a565b6112e6565b34801561035157600080fd5b506101e37f000000000000000000000000000000000000000000000000000000000000000081565b34801561038557600080fd5b506101a86113bd565b34801561039a57600080fd5b506102c161271081565b3480156103b057600080fd5b506101a86103bf366004614e23565b6114dd565b3480156103d057600080fd5b506032546101e39073ffffffffffffffffffffffffffffffffffffffff1681565b3480156103fd57600080fd5b506102e961040c366004614e0a565b60336020526000908152604090205460ff1681565b34801561042d57600080fd5b506102c1611e60565b34801561044257600080fd5b506102c1600881565b34801561045757600080fd5b506001546104b3906fffffffffffffffffffffffffffffffff81169067ffffffffffffffff7001000000000000000000000000000000008204811691780100000000000000000000000000000000000000000000000090041683565b604080516fffffffffffffffffffffffffffffffff909416845267ffffffffffffffff9283166020850152911690820152606001610204565b3480156104f857600080fd5b506101a8610507366004614e68565b611e71565b34801561051857600080fd5b5061056a610527366004614e0a565b603460205260009081526040902080546001909101546fffffffffffffffffffffffffffffffff8082169170010000000000000000000000000000000090041683565b604080519384526fffffffffffffffffffffffffffffffff9283166020850152911690820152606001610204565b6101a86105a6366004614e83565b8260005a9050831561065d5773ffffffffffffffffffffffffffffffffffffffff87161561065d57604080517f08c379a00000000000000000000000000000000000000000000000000000000081526020600482015260248101919091527f4f7074696d69736d506f7274616c3a206d7573742073656e6420746f2061646460448201527f72657373283029207768656e206372656174696e67206120636f6e747261637460648201526084015b60405180910390fd5b6152088567ffffffffffffffff1610156106f9576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603860248201527f4f7074696d69736d506f7274616c3a20676173206c696d6974206d757374206360448201527f6f76657220696e737472696e7369632067617320636f737400000000000000006064820152608401610654565b3332811461071a575033731111000000000000000000000000000000001111015b60003488888888604051602001610735959493929190614f08565b604051602081830303815290604052905060008973ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff167fb3813568d9991fc951961fcb4c784893574240a28925604d09fc577c55bb7c32846040516107a59190614df7565b60405180910390a450506001546000906107e5907801000000000000000000000000000000000000000000000000900467ffffffffffffffff1643614f9c565b905080156109195760006107fd6004627a1200614fe2565b6001546108289190700100000000000000000000000000000000900467ffffffffffffffff1661504a565b90506000600861083c6004627a1200614fe2565b61084691906150be565b6001546108669084906fffffffffffffffffffffffffffffffff166150be565b6108709190614fe2565b6001549091506000906108b39061089a9084906fffffffffffffffffffffffffffffffff1661517a565b6127106fffffffffffffffffffffffffffffffff61207a565b905060018411156108da576108d761089a8260086108d2600189614f9c565b612099565b90505b6fffffffffffffffffffffffffffffffff16780100000000000000000000000000000000000000000000000067ffffffffffffffff4316021760015550505b6001805484919060109061094c908490700100000000000000000000000000000000900467ffffffffffffffff166151ee565b92506101000a81548167ffffffffffffffff021916908367ffffffffffffffff160217905550627a1200600160000160109054906101000a900467ffffffffffffffff1667ffffffffffffffff161315610a28576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603e60248201527f5265736f757263654d65746572696e673a2063616e6e6f7420627579206d6f7260448201527f6520676173207468616e20617661696c61626c6520676173206c696d697400006064820152608401610654565b600154600090610a54906fffffffffffffffffffffffffffffffff1667ffffffffffffffff861661521a565b6fffffffffffffffffffffffffffffffff1690506000610a7848633b9aca006120ee565b610a829083615252565b905060005a610a919086614f9c565b905080821115610aad57610aad610aa88284614f9c565b612105565b5050505050505050505050565b3373ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000001614610b7f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602960248201527f4f7074696d69736d506f7274616c3a206f6e6c7920677561726469616e20636160448201527f6e20756e706175736500000000000000000000000000000000000000000000006064820152608401610654565b603580547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001690556040513381527f5db9ee0a495bf2e6ff9c91a7834c1ba4fdd244a5e8aa4e537bd38aeae4b073aa906020015b60405180910390a1565b60355460ff1615610c4a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4f7074696d69736d506f7274616c3a20706175736564000000000000000000006044820152606401610654565b3073ffffffffffffffffffffffffffffffffffffffff16856040015173ffffffffffffffffffffffffffffffffffffffff1603610d09576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603f60248201527f4f7074696d69736d506f7274616c3a20796f752063616e6e6f742073656e642060448201527f6d6573736167657320746f2074686520706f7274616c20636f6e7472616374006064820152608401610654565b6040517fa25ae557000000000000000000000000000000000000000000000000000000008152600481018590526000907f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff169063a25ae55790602401606060405180830381865afa158015610d97573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610dbb9190615286565b519050610dd5610dd0368690038601866152eb565b612133565b8114610e63576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602960248201527f4f7074696d69736d506f7274616c3a20696e76616c6964206f7574707574207260448201527f6f6f742070726f6f6600000000000000000000000000000000000000000000006064820152608401610654565b6000610e6e8761218f565b6000818152603460209081526040918290208251606081018452815481526001909101546fffffffffffffffffffffffffffffffff8082169383018490527001000000000000000000000000000000009091041692810192909252919250901580610fa05750805160408083015190517fa25ae5570000000000000000000000000000000000000000000000000000000081526fffffffffffffffffffffffffffffffff90911660048201527f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff169063a25ae55790602401606060405180830381865afa158015610f78573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610f9c9190615286565b5114155b61102c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603760248201527f4f7074696d69736d506f7274616c3a207769746864726177616c20686173682060448201527f68617320616c7265616479206265656e2070726f76656e0000000000000000006064820152608401610654565b60408051602081018490526000918101829052606001604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0818403018152828252805160209182012090830181905292506110f59101604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0818403018152828201909152600182527f01000000000000000000000000000000000000000000000000000000000000006020830152906110eb888a615351565b8a604001356121bf565b611181576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603260248201527f4f7074696d69736d506f7274616c3a20696e76616c696420776974686472617760448201527f616c20696e636c7573696f6e2070726f6f6600000000000000000000000000006064820152608401610654565b604080516060810182528581526fffffffffffffffffffffffffffffffff42811660208084019182528c831684860190815260008981526034835286812095518655925190518416700100000000000000000000000000000000029316929092176001909301929092558b830151908c0151925173ffffffffffffffffffffffffffffffffffffffff918216939091169186917f67a6208cfcc0801d50f6cbe764733f4fddf66ac0b04442061a8a8c0cb6b63f629190a4505050505050505050565b606061126e7f00000000000000000000000000000000000000000000000000000000000000006121e3565b6112977f00000000000000000000000000000000000000000000000000000000000000006121e3565b6112c07f00000000000000000000000000000000000000000000000000000000000000006121e3565b6040516020016112d2939291906153d5565b604051602081830303815290604052905090565b6040517fa25ae557000000000000000000000000000000000000000000000000000000008152600481018290526000906113b79073ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000169063a25ae55790602401606060405180830381865afa158015611378573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061139c9190615286565b602001516fffffffffffffffffffffffffffffffff16612320565b92915050565b3373ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000001614611482576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602760248201527f4f7074696d69736d506f7274616c3a206f6e6c7920677561726469616e20636160448201527f6e207061757365000000000000000000000000000000000000000000000000006064820152608401610654565b603580547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660011790556040513381527f62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a25890602001610bd3565b60355460ff161561154a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4f7074696d69736d506f7274616c3a20706175736564000000000000000000006044820152606401610654565b60325473ffffffffffffffffffffffffffffffffffffffff1661dead146115f3576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603f60248201527f4f7074696d69736d506f7274616c3a2063616e206f6e6c79207472696767657260448201527f206f6e65207769746864726177616c20706572207472616e73616374696f6e006064820152608401610654565b60006115fe8261218f565b60008181526034602090815260408083208151606081018352815481526001909101546fffffffffffffffffffffffffffffffff808216948301859052700100000000000000000000000000000000909104169181019190915292935090036116e9576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603260248201527f4f7074696d69736d506f7274616c3a207769746864726177616c20686173206e60448201527f6f74206265656e2070726f76656e2079657400000000000000000000000000006064820152608401610654565b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663887862726040518163ffffffff1660e01b8152600401602060405180830381865afa158015611754573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611778919061544b565b81602001516fffffffffffffffffffffffffffffffff161015611843576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604b60248201527f4f7074696d69736d506f7274616c3a207769746864726177616c2074696d657360448201527f74616d70206c657373207468616e204c32204f7261636c65207374617274696e60648201527f672074696d657374616d70000000000000000000000000000000000000000000608482015260a401610654565b61186281602001516fffffffffffffffffffffffffffffffff16612320565b611914576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604560248201527f4f7074696d69736d506f7274616c3a2070726f76656e2077697468647261776160448201527f6c2066696e616c697a6174696f6e20706572696f6420686173206e6f7420656c60648201527f6170736564000000000000000000000000000000000000000000000000000000608482015260a401610654565b60408181015190517fa25ae5570000000000000000000000000000000000000000000000000000000081526fffffffffffffffffffffffffffffffff90911660048201526000907f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff169063a25ae55790602401606060405180830381865afa1580156119b9573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906119dd9190615286565b8251815191925014611a97576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604960248201527f4f7074696d69736d506f7274616c3a206f757470757420726f6f742070726f7660448201527f656e206973206e6f74207468652073616d652061732063757272656e74206f7560648201527f7470757420726f6f740000000000000000000000000000000000000000000000608482015260a401610654565b611ab681602001516fffffffffffffffffffffffffffffffff16612320565b611b68576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604360248201527f4f7074696d69736d506f7274616c3a206f75747075742070726f706f73616c2060448201527f66696e616c697a6174696f6e20706572696f6420686173206e6f7420656c617060648201527f7365640000000000000000000000000000000000000000000000000000000000608482015260a401610654565b60008381526033602052604090205460ff1615611c07576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603560248201527f4f7074696d69736d506f7274616c3a207769746864726177616c20686173206160448201527f6c7265616479206265656e2066696e616c697a656400000000000000000000006064820152608401610654565b600083815260336020526040902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660011790556080840151611c5090614e2090615464565b5a1015611cdf576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603760248201527f4f7074696d69736d506f7274616c3a20696e73756666696369656e742067617360448201527f20746f2066696e616c697a65207769746864726177616c0000000000000000006064820152608401610654565b6020840151603280547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff9092169190911790556040840151600090611d5190614e205a611d429190614f9c565b87606001518860a001516123c3565b603280547fffffffffffffffffffffffff00000000000000000000000000000000000000001661dead17905560405190915084907fdb5c7652857aa163daadd670e116628fb42e869d8ac4251ef8971d9e5727df1b90611db690841515815260200190565b60405180910390a280158015611dcc5750326001145b15611e59576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602160248201527f4f7074696d69736d506f7274616c3a207769746864726177616c206661696c6560448201527f64000000000000000000000000000000000000000000000000000000000000006064820152608401610654565b5050505050565b611e6e6004627a1200614fe2565b81565b600054610100900460ff1615808015611e915750600054600160ff909116105b80611eab5750303b158015611eab575060005460ff166001145b611f37576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a65640000000000000000000000000000000000006064820152608401610654565b600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660011790558015611f9557600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff166101001790555b603280547fffffffffffffffffffffffff00000000000000000000000000000000000000001661dead179055603580548315157fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00909116179055611ff76123dd565b801561205a57600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b5050565b73ffffffffffffffffffffffffffffffffffffffff163b151590565b600061208f61208985856124c0565b836124d0565b90505b9392505050565b6000670de0b6b3a76400006120da6120b18583614fe2565b6120c390670de0b6b3a764000061504a565b6120d585670de0b6b3a76400006150be565b6124df565b6120e490866150be565b61208f9190614fe2565b6000818310156120fe5781612092565b5090919050565b6000805a90505b825a6121189083614f9c565b101561212e576121278261547c565b915061210c565b505050565b60008160000151826020015183604001518460600151604051602001612172949392919093845260208401929092526040830152606082015260800190565b604051602081830303815290604052805190602001209050919050565b80516020808301516040808501516060860151608087015160a088015193516000976121729790969591016154b4565b6000806121cb86612510565b90506121d981868686612542565b9695505050505050565b60608160000361222657505060408051808201909152600181527f3000000000000000000000000000000000000000000000000000000000000000602082015290565b8160005b8115612250578061223a8161547c565b91506122499050600a83615252565b915061222a565b60008167ffffffffffffffff81111561226b5761226b614ac7565b6040519080825280601f01601f191660200182016040528015612295576020820181803683370190505b5090505b8415612318576122aa600183614f9c565b91506122b7600a8661550b565b6122c2906030615464565b60f81b8183815181106122d7576122d761551f565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a905350612311600a86615252565b9450612299565b949350505050565b60007f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663f4daa2916040518163ffffffff1660e01b8152600401602060405180830381865afa15801561238d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906123b1919061544b565b6123bb9083615464565b421192915050565b600080600080845160208601878a8af19695505050505050565b600054610100900460ff16612474576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e670000000000000000000000000000000000000000006064820152608401610654565b60408051606081018252633b9aca00808252600060208301524367ffffffffffffffff169190920181905278010000000000000000000000000000000000000000000000000217600155565b6000818312156120fe5781612092565b60008183126120fe5781612092565b6000612092670de0b6b3a7640000836124f786612572565b61250191906150be565b61250b9190614fe2565b6127b6565b6060818051906020012060405160200161252c91815260200190565b6040516020818303038152906040529050919050565b6000612569846125538786866129f5565b8051602091820120825192909101919091201490565b95945050505050565b60008082136125dd576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600960248201527f554e444546494e454400000000000000000000000000000000000000000000006044820152606401610654565b600060606125ea8461347d565b03609f8181039490941b90931c6c465772b2bbbb5f824b15207a3081018102606090811d6d0388eaa27412d5aca026815d636e018202811d6d0df99ac502031bf953eff472fdcc018202811d6d13cdffb29d51d99322bdff5f2211018202811d6d0a0f742023def783a307a986912e018202811d6d01920d8043ca89b5239253284e42018202811d6c0b7a86d7375468fac667a0a527016c29508e458543d8aa4df2abee7883018302821d6d0139601a2efabe717e604cbb4894018302821d6d02247f7a7b6594320649aa03aba1018302821d7fffffffffffffffffffffffffffffffffffffff73c0c716a594e00d54e3c4cbc9018302821d7ffffffffffffffffffffffffffffffffffffffdc7b88c420e53a9890533129f6f01830290911d7fffffffffffffffffffffffffffffffffffffff465fda27eb4d63ded474e5f832019091027ffffffffffffffff5f6af8f7b3396644f18e157960000000000000000000000000105711340daa0d5f769dba1915cef59f0815a5506027d0267a36c0c95b3975ab3ee5b203a7614a3f75373f047d803ae7b6687f2b393909302929092017d57115e47018c7177eebf7cd370a3356a1b7863008a5ae8028c72b88642840160ae1d92915050565b60007ffffffffffffffffffffffffffffffffffffffffffffffffdb731c958f34d94c182136127e757506000919050565b680755bf798b4a1bf1e58212612859576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600c60248201527f4558505f4f564552464c4f5700000000000000000000000000000000000000006044820152606401610654565b6503782dace9d9604e83901b059150600060606bb17217f7d1cf79abc9e3b39884821b056b80000000000000000000000001901d6bb17217f7d1cf79abc9e3b39881029093037fffffffffffffffffffffffffffffffffffffffdbf3ccf1604d263450f02a550481018102606090811d6d0277594991cfc85f6e2461837cd9018202811d7fffffffffffffffffffffffffffffffffffffe5adedaa1cb095af9e4da10e363c018202811d6db1bbb201f443cf962f1a1d3db4a5018202811d7ffffffffffffffffffffffffffffffffffffd38dc772608b0ae56cce01296c0eb018202811d6e05180bb14799ab47a8a8cb2a527d57016d02d16720577bd19bf614176fe9ea6c10fe68e7fd37d0007b713f765084018402831d9081019084017ffffffffffffffffffffffffffffffffffffffe2c69812cf03b0763fd454a8f7e010290911d6e0587f503bb6ea29d25fcb7401964500190910279d835ebba824c98fb31b83b2ca45c000000000000000000000000010574029d9dc38563c32e5c2f6dc192ee70ef65f9978af30260c3939093039290921c92915050565b60606000845111612a62576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601560248201527f4d65726b6c65547269653a20656d707479206b657900000000000000000000006044820152606401610654565b6000612a6d84613553565b90506000612a7a86613642565b9050600084604051602001612a9191815260200190565b60405160208183030381529060405290506000805b84518110156133f4576000858281518110612ac357612ac361551f565b602002602001015190508451831115612b5e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f4d65726b6c65547269653a206b657920696e646578206578636565647320746f60448201527f74616c206b6579206c656e6774680000000000000000000000000000000000006064820152608401610654565b82600003612c175780518051602091820120604051612bac92612b8692910190815260200190565b604051602081830303815290604052858051602091820120825192909101919091201490565b612c12576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f4d65726b6c65547269653a20696e76616c696420726f6f7420686173680000006044820152606401610654565b612d6e565b805151602011612ccd5780518051602091820120604051612c4192612b8692910190815260200190565b612c12576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602760248201527f4d65726b6c65547269653a20696e76616c6964206c6172676520696e7465726e60448201527f616c2068617368000000000000000000000000000000000000000000000000006064820152608401610654565b805184516020808701919091208251919092012014612d6e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f4d65726b6c65547269653a20696e76616c696420696e7465726e616c206e6f6460448201527f65206861736800000000000000000000000000000000000000000000000000006064820152608401610654565b612d7a60106001615464565b81602001515103612f5b5784518303612ef3576000612db68260200151601081518110612da957612da961551f565b60200260200101516137dd565b90506000815111612e49576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603b60248201527f4d65726b6c65547269653a2076616c7565206c656e677468206d75737420626560448201527f2067726561746572207468616e207a65726f20286272616e63682900000000006064820152608401610654565b60018751612e579190614f9c565b8314612ee5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603a60248201527f4d65726b6c65547269653a2076616c7565206e6f6465206d757374206265206c60448201527f617374206e6f646520696e2070726f6f6620286272616e6368290000000000006064820152608401610654565b965061209295505050505050565b6000858481518110612f0757612f0761551f565b602001015160f81c60f81b60f81c9050600082602001518260ff1681518110612f3257612f3261551f565b60200260200101519050612f458161393d565b9550612f52600186615464565b945050506133e1565b600281602001515103613359576000612f7382613962565b9050600081600081518110612f8a57612f8a61551f565b016020015160f81c90506000612fa160028361554e565b612fac906002615570565b90506000612fbd848360ff16613986565b90506000612fcb8a89613986565b90506000612fd983836139bc565b90508083511461306b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603a60248201527f4d65726b6c65547269653a20706174682072656d61696e646572206d7573742060448201527f736861726520616c6c206e6962626c65732077697468206b65790000000000006064820152608401610654565b60ff851660021480613080575060ff85166003145b156132745780825114613115576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603d60248201527f4d65726b6c65547269653a206b65792072656d61696e646572206d757374206260448201527f65206964656e746963616c20746f20706174682072656d61696e6465720000006064820152608401610654565b60006131318860200151600181518110612da957612da961551f565b905060008151116131c4576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603960248201527f4d65726b6c65547269653a2076616c7565206c656e677468206d75737420626560448201527f2067726561746572207468616e207a65726f20286c65616629000000000000006064820152608401610654565b60018d516131d29190614f9c565b8914613260576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603860248201527f4d65726b6c65547269653a2076616c7565206e6f6465206d757374206265206c60448201527f617374206e6f646520696e2070726f6f6620286c6561662900000000000000006064820152608401610654565b9c506120929b505050505050505050505050565b60ff85161580613287575060ff85166001145b156132c6576132b387602001516001815181106132a6576132a661551f565b602002602001015161393d565b99506132bf818a615464565b985061334e565b6040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603260248201527f4d65726b6c65547269653a2072656365697665642061206e6f6465207769746860448201527f20616e20756e6b6e6f776e2070726566697800000000000000000000000000006064820152608401610654565b5050505050506133e1565b6040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602860248201527f4d65726b6c65547269653a20726563656976656420616e20756e70617273656160448201527f626c65206e6f64650000000000000000000000000000000000000000000000006064820152608401610654565b50806133ec8161547c565b915050612aa6565b506040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602560248201527f4d65726b6c65547269653a2072616e206f7574206f662070726f6f6620656c6560448201527f6d656e74730000000000000000000000000000000000000000000000000000006064820152608401610654565b60008082116134e8576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600960248201527f554e444546494e454400000000000000000000000000000000000000000000006044820152606401610654565b5060016fffffffffffffffffffffffffffffffff821160071b82811c67ffffffffffffffff1060061b1782811c63ffffffff1060051b1782811c61ffff1060041b1782811c60ff10600390811b90911783811c600f1060021b1783811c909110821b1791821c111790565b805160609060008167ffffffffffffffff81111561357357613573614ac7565b6040519080825280602002602001820160405280156135b857816020015b60408051808201909152606080825260208201528152602001906001900390816135915790505b50905060005b8281101561363a5760405180604001604052808683815181106135e3576135e361551f565b602002602001015181526020016136128784815181106136055761360561551f565b6020026020010151613a6b565b8152508282815181106136275761362761551f565b60209081029190910101526001016135be565b509392505050565b80516060906000613654826002615593565b67ffffffffffffffff81111561366c5761366c614ac7565b6040519080825280601f01601f191660200182016040528015613696576020820181803683370190505b5090506000805b838110156137d3578581815181106136b7576136b761551f565b6020910101517fff000000000000000000000000000000000000000000000000000000000000008116925060041c7f0ff00000000000000000000000000000000000000000000000000000000000001683613713836002615593565b815181106137235761372361551f565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053507f0f00000000000000000000000000000000000000000000000000000000000000821683613781836002615593565b61378c906001615464565b8151811061379c5761379c61551f565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a90535060010161369d565b5090949350505050565b606060008060006137ed85613a7e565b919450925090506000816001811115613808576138086155d0565b14613895576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603960248201527f524c505265616465723a206465636f646564206974656d207479706520666f7260448201527f206279746573206973206e6f7420612064617461206974656d000000000000006064820152608401610654565b61389f8284615464565b85511461392e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603460248201527f524c505265616465723a2062797465732076616c756520636f6e7461696e732060448201527f616e20696e76616c69642072656d61696e6465720000000000000000000000006064820152608401610654565b612569856020015184846144eb565b6060602082600001511061395957613954826137dd565b6113b7565b6113b78261458c565b60606113b76139818360200151600081518110612da957612da961551f565b613642565b6060825182106139a557506040805160208101909152600081526113b7565b61209283838486516139b79190614f9c565b6145a2565b600080600083518551106139d15783516139d4565b84515b90505b8082108015613a5b57508382815181106139f3576139f361551f565b602001015160f81c60f81b7effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916858381518110613a3257613a3261551f565b01602001517fff0000000000000000000000000000000000000000000000000000000000000016145b1561363a578160010191506139d7565b60606113b7613a798361477a565b614863565b600080600080846000015111613b3c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604a60248201527f524c505265616465723a206c656e677468206f6620616e20524c50206974656d60448201527f206d7573742062652067726561746572207468616e207a65726f20746f20626560648201527f206465636f6461626c6500000000000000000000000000000000000000000000608482015260a401610654565b6020840151805160001a607f8111613b615760006001600094509450945050506144e4565b60b78111613d6f576000613b76608083614f9c565b905080876000015111613c31576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604e60248201527f524c505265616465723a206c656e677468206f6620636f6e74656e74206d757360448201527f742062652067726561746572207468616e20737472696e67206c656e6774682060648201527f2873686f727420737472696e6729000000000000000000000000000000000000608482015260a401610654565b6001838101517fff00000000000000000000000000000000000000000000000000000000000000169082141580613caa57507f80000000000000000000000000000000000000000000000000000000000000007fff00000000000000000000000000000000000000000000000000000000000000821610155b613d5c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604d60248201527f524c505265616465723a20696e76616c6964207072656669782c2073696e676c60448201527f652062797465203c203078383020617265206e6f74207072656669786564202860648201527f73686f727420737472696e672900000000000000000000000000000000000000608482015260a401610654565b50600195509350600092506144e4915050565b60bf81116140bd576000613d8460b783614f9c565b905080876000015111613e3f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152605160248201527f524c505265616465723a206c656e677468206f6620636f6e74656e74206d757360448201527f74206265203e207468616e206c656e677468206f6620737472696e67206c656e60648201527f67746820286c6f6e6720737472696e6729000000000000000000000000000000608482015260a401610654565b60018301517fff00000000000000000000000000000000000000000000000000000000000000166000819003613f1d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604a60248201527f524c505265616465723a206c656e677468206f6620636f6e74656e74206d757360448201527f74206e6f74206861766520616e79206c656164696e67207a65726f7320286c6f60648201527f6e6720737472696e672900000000000000000000000000000000000000000000608482015260a401610654565b600184015160088302610100031c60378111613fe1576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604860248201527f524c505265616465723a206c656e677468206f6620636f6e74656e74206d757360448201527f742062652067726561746572207468616e20353520627974657320286c6f6e6760648201527f20737472696e6729000000000000000000000000000000000000000000000000608482015260a401610654565b613feb8184615464565b8951116140a0576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604c60248201527f524c505265616465723a206c656e677468206f6620636f6e74656e74206d757360448201527f742062652067726561746572207468616e20746f74616c206c656e677468202860648201527f6c6f6e6720737472696e67290000000000000000000000000000000000000000608482015260a401610654565b6140ab836001615464565b97509550600094506144e49350505050565b60f7811161419e5760006140d260c083614f9c565b90508087600001511161418d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604a60248201527f524c505265616465723a206c656e677468206f6620636f6e74656e74206d757360448201527f742062652067726561746572207468616e206c697374206c656e67746820287360648201527f686f7274206c6973742900000000000000000000000000000000000000000000608482015260a401610654565b6001955093508492506144e4915050565b60006141ab60f783614f9c565b905080876000015111614266576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604d60248201527f524c505265616465723a206c656e677468206f6620636f6e74656e74206d757360448201527f74206265203e207468616e206c656e677468206f66206c697374206c656e677460648201527f6820286c6f6e67206c6973742900000000000000000000000000000000000000608482015260a401610654565b60018301517fff00000000000000000000000000000000000000000000000000000000000000166000819003614344576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604860248201527f524c505265616465723a206c656e677468206f6620636f6e74656e74206d757360448201527f74206e6f74206861766520616e79206c656164696e67207a65726f7320286c6f60648201527f6e67206c69737429000000000000000000000000000000000000000000000000608482015260a401610654565b600184015160088302610100031c60378111614408576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604660248201527f524c505265616465723a206c656e677468206f6620636f6e74656e74206d757360448201527f742062652067726561746572207468616e20353520627974657320286c6f6e6760648201527f206c697374290000000000000000000000000000000000000000000000000000608482015260a401610654565b6144128184615464565b8951116144c7576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604a60248201527f524c505265616465723a206c656e677468206f6620636f6e74656e74206d757360448201527f742062652067726561746572207468616e20746f74616c206c656e677468202860648201527f6c6f6e67206c6973742900000000000000000000000000000000000000000000608482015260a401610654565b6144d2836001615464565b97509550600194506144e49350505050565b9193909250565b606060008267ffffffffffffffff81111561450857614508614ac7565b6040519080825280601f01601f191660200182016040528015614532576020820181803683370190505b50905082600003614544579050612092565b60006145508587615464565b90506020820160005b85811015614571578281015182820152602001614559565b85811115614580576000868301525b50919695505050505050565b60606113b78260200151600084600001516144eb565b60608182601f011015614611576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600e60248201527f736c6963655f6f766572666c6f770000000000000000000000000000000000006044820152606401610654565b82828401101561467d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600e60248201527f736c6963655f6f766572666c6f770000000000000000000000000000000000006044820152606401610654565b818301845110156146ea576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601160248201527f736c6963655f6f75744f66426f756e64730000000000000000000000000000006044820152606401610654565b6060821580156147095760405191506000825260208201604052614771565b6040519150601f8416801560200281840101858101878315602002848b0101015b8183101561474257805183526020928301920161472a565b5050858452601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016604052505b50949350505050565b60408051808201909152600080825260208201526000825111614845576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604a60248201527f524c505265616465723a206c656e677468206f6620616e20524c50206974656d60448201527f206d7573742062652067726561746572207468616e207a65726f20746f20626560648201527f206465636f6461626c6500000000000000000000000000000000000000000000608482015260a401610654565b50604080518082019091528151815260209182019181019190915290565b6060600080600061487385613a7e565b91945092509050600181600181111561488e5761488e6155d0565b1461491b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603860248201527f524c505265616465723a206465636f646564206974656d207479706520666f7260448201527f206c697374206973206e6f742061206c697374206974656d00000000000000006064820152608401610654565b84516149278385615464565b146149b4576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603260248201527f524c505265616465723a206c697374206974656d2068617320616e20696e766160448201527f6c696420646174612072656d61696e64657200000000000000000000000000006064820152608401610654565b6040805160208082526104208201909252600091816020015b60408051808201909152600080825260208201528152602001906001900390816149cd5790505090506000845b8751811015614abb57600080614a406040518060400160405280858d60000151614a249190614f9c565b8152602001858d60200151614a399190615464565b9052613a7e565b509150915060405180604001604052808383614a5c9190615464565b8152602001848c60200151614a719190615464565b815250858581518110614a8657614a8661551f565b6020908102919091010152614a9c600185615464565b9350614aa88183615464565b614ab29084615464565b925050506149fa565b50815295945050505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff81118282101715614b3d57614b3d614ac7565b604052919050565b803573ffffffffffffffffffffffffffffffffffffffff81168114614b6957600080fd5b919050565b600082601f830112614b7f57600080fd5b813567ffffffffffffffff811115614b9957614b99614ac7565b614bca60207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f84011601614af6565b818152846020838601011115614bdf57600080fd5b816020850160208301376000918101602001919091529392505050565b600060c08284031215614c0e57600080fd5b60405160c0810167ffffffffffffffff8282108183111715614c3257614c32614ac7565b8160405282935084358352614c4960208601614b45565b6020840152614c5a60408601614b45565b6040840152606085013560608401526080850135608084015260a0850135915080821115614c8757600080fd5b50614c9485828601614b6e565b60a0830152505092915050565b600080600080600085870360e0811215614cba57600080fd5b863567ffffffffffffffff80821115614cd257600080fd5b614cde8a838b01614bfc565b97506020890135965060807fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc084011215614d1757600080fd5b60408901955060c0890135925080831115614d3157600080fd5b828901925089601f840112614d4557600080fd5b8235915080821115614d5657600080fd5b508860208260051b8401011115614d6c57600080fd5b959894975092955050506020019190565b60005b83811015614d98578181015183820152602001614d80565b83811115614da7576000848401525b50505050565b60008151808452614dc5816020860160208601614d7d565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b6020815260006120926020830184614dad565b600060208284031215614e1c57600080fd5b5035919050565b600060208284031215614e3557600080fd5b813567ffffffffffffffff811115614e4c57600080fd5b61231884828501614bfc565b80358015158114614b6957600080fd5b600060208284031215614e7a57600080fd5b61209282614e58565b600080600080600060a08688031215614e9b57600080fd5b614ea486614b45565b945060208601359350604086013567ffffffffffffffff8082168214614ec957600080fd5b819450614ed860608901614e58565b93506080880135915080821115614eee57600080fd5b50614efb88828901614b6e565b9150509295509295909350565b8581528460208201527fffffffffffffffff0000000000000000000000000000000000000000000000008460c01b16604082015282151560f81b604882015260008251614f5c816049850160208701614d7d565b919091016049019695505050505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b600082821015614fae57614fae614f6d565b500390565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b600082614ff157614ff1614fb3565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff83147f80000000000000000000000000000000000000000000000000000000000000008314161561504557615045614f6d565b500590565b6000808312837f80000000000000000000000000000000000000000000000000000000000000000183128115161561508457615084614f6d565b837f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0183138116156150b8576150b8614f6d565b50500390565b60007f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff6000841360008413858304851182821616156150ff576150ff614f6d565b7f8000000000000000000000000000000000000000000000000000000000000000600087128682058812818416161561513a5761513a614f6d565b6000871292508782058712848416161561515657615156614f6d565b8785058712818416161561516c5761516c614f6d565b505050929093029392505050565b6000808212827f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff038413811516156151b4576151b4614f6d565b827f80000000000000000000000000000000000000000000000000000000000000000384128116156151e8576151e8614f6d565b50500190565b600067ffffffffffffffff80831681851680830382111561521157615211614f6d565b01949350505050565b60006fffffffffffffffffffffffffffffffff8083168185168183048111821515161561524957615249614f6d565b02949350505050565b60008261526157615261614fb3565b500490565b80516fffffffffffffffffffffffffffffffff81168114614b6957600080fd5b60006060828403121561529857600080fd5b6040516060810181811067ffffffffffffffff821117156152bb576152bb614ac7565b604052825181526152ce60208401615266565b60208201526152df60408401615266565b60408201529392505050565b6000608082840312156152fd57600080fd5b6040516080810181811067ffffffffffffffff8211171561532057615320614ac7565b8060405250823581526020830135602082015260408301356040820152606083013560608201528091505092915050565b600067ffffffffffffffff8084111561536c5761536c614ac7565b8360051b602061537d818301614af6565b86815291850191818101903684111561539557600080fd5b865b848110156153c9578035868111156153af5760008081fd5b6153bb36828b01614b6e565b845250918301918301615397565b50979650505050505050565b600084516153e7818460208901614d7d565b80830190507f2e000000000000000000000000000000000000000000000000000000000000008082528551615423816001850160208a01614d7d565b6001920191820152835161543e816002840160208801614d7d565b0160020195945050505050565b60006020828403121561545d57600080fd5b5051919050565b6000821982111561547757615477614f6d565b500190565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82036154ad576154ad614f6d565b5060010190565b868152600073ffffffffffffffffffffffffffffffffffffffff808816602084015280871660408401525084606083015283608083015260c060a08301526154ff60c0830184614dad565b98975050505050505050565b60008261551a5761551a614fb3565b500690565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b600060ff83168061556157615561614fb3565b8060ff84160691505092915050565b600060ff821660ff84168082101561558a5761558a614f6d565b90039392505050565b6000817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff04831182151516156155cb576155cb614f6d565b500290565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fdfea164736f6c634300080f000a"
func init() { func init() {
if err := json.Unmarshal([]byte(OptimismPortalStorageLayoutJSON), OptimismPortalStorageLayout); err != nil { if err := json.Unmarshal([]byte(OptimismPortalStorageLayoutJSON), OptimismPortalStorageLayout); err != nil {
......
...@@ -140,7 +140,7 @@ func main() { ...@@ -140,7 +140,7 @@ func main() {
return err return err
} }
period, err := contracts.OptimismPortal.FINALIZATIONPERIODSECONDS(&bind.CallOpts{}) period, err := contracts.L2OutputOracle.FINALIZATIONPERIODSECONDS(&bind.CallOpts{})
if err != nil { if err != nil {
return err return err
} }
......
...@@ -285,6 +285,7 @@ func deployL1Contracts(config *DeployConfig, backend *backends.SimulatedBackend) ...@@ -285,6 +285,7 @@ func deployL1Contracts(config *DeployConfig, backend *backends.SimulatedBackend)
uint642Big(uint64(config.L1GenesisBlockTimestamp)), uint642Big(uint64(config.L1GenesisBlockTimestamp)),
config.L2OutputOracleProposer, config.L2OutputOracleProposer,
config.L2OutputOracleChallenger, config.L2OutputOracleChallenger,
uint642Big(config.FinalizationPeriodSeconds),
}, },
}, },
{ {
...@@ -295,7 +296,6 @@ func deployL1Contracts(config *DeployConfig, backend *backends.SimulatedBackend) ...@@ -295,7 +296,6 @@ func deployL1Contracts(config *DeployConfig, backend *backends.SimulatedBackend)
Args: []interface{}{ Args: []interface{}{
predeploys.DevL2OutputOracleAddr, predeploys.DevL2OutputOracleAddr,
config.FinalSystemOwner, config.FinalSystemOwner,
uint642Big(config.FinalizationPeriodSeconds),
true, // _paused true, // _paused
}, },
}, },
...@@ -353,15 +353,15 @@ func l1Deployer(backend *backends.SimulatedBackend, opts *bind.TransactOpts, dep ...@@ -353,15 +353,15 @@ func l1Deployer(backend *backends.SimulatedBackend, opts *bind.TransactOpts, dep
deployment.Args[3].(*big.Int), deployment.Args[3].(*big.Int),
deployment.Args[4].(common.Address), deployment.Args[4].(common.Address),
deployment.Args[5].(common.Address), deployment.Args[5].(common.Address),
deployment.Args[6].(*big.Int),
) )
case "OptimismPortal": case "OptimismPortal":
_, tx, _, err = bindings.DeployOptimismPortal( _, tx, _, err = bindings.DeployOptimismPortal(
opts, opts,
backend, backend,
deployment.Args[0].(common.Address), deployment.Args[0].(common.Address),
deployment.Args[2].(*big.Int),
deployment.Args[1].(common.Address), deployment.Args[1].(common.Address),
deployment.Args[3].(bool), deployment.Args[2].(bool),
) )
case "L1CrossDomainMessenger": case "L1CrossDomainMessenger":
_, tx, _, err = bindings.DeployL1CrossDomainMessenger( _, tx, _, err = bindings.DeployL1CrossDomainMessenger(
......
...@@ -155,3 +155,11 @@ func (s *L2Sequencer) ActBuildToL1HeadExclUnsafe(t Testing) { ...@@ -155,3 +155,11 @@ func (s *L2Sequencer) ActBuildToL1HeadExclUnsafe(t Testing) {
s.ActL2EndBlock(t) s.ActL2EndBlock(t)
} }
} }
func (s *L2Sequencer) ActBuildL2ToRegolith(t Testing) {
require.NotNil(t, s.rollupCfg.RegolithTime, "cannot activate Regolith when it is not scheduled")
for s.L2Unsafe().Time < *s.rollupCfg.RegolithTime {
s.ActL2StartBlock(t)
s.ActL2EndBlock(t)
}
}
...@@ -445,7 +445,7 @@ func (s *CrossLayerUser) ActCompleteWithdrawal(t Testing) { ...@@ -445,7 +445,7 @@ func (s *CrossLayerUser) ActCompleteWithdrawal(t Testing) {
// CompleteWithdrawal creates a L1 withdrawal finalization tx for the given L2 withdrawal tx, returning the tx hash. // CompleteWithdrawal creates a L1 withdrawal finalization tx for the given L2 withdrawal tx, returning the tx hash.
// It's an invalid action to attempt to complete a withdrawal that has not passed the L1 finalization period yet // It's an invalid action to attempt to complete a withdrawal that has not passed the L1 finalization period yet
func (s *CrossLayerUser) CompleteWithdrawal(t Testing, l2TxHash common.Hash) common.Hash { func (s *CrossLayerUser) CompleteWithdrawal(t Testing, l2TxHash common.Hash) common.Hash {
finalizationPeriod, err := s.L1.env.Bindings.OptimismPortal.FINALIZATIONPERIODSECONDS(&bind.CallOpts{}) finalizationPeriod, err := s.L1.env.Bindings.L2OutputOracle.FINALIZATIONPERIODSECONDS(&bind.CallOpts{})
require.NoError(t, err) require.NoError(t, err)
// Figure out when our withdrawal was included // Figure out when our withdrawal was included
......
...@@ -4,6 +4,7 @@ import ( ...@@ -4,6 +4,7 @@ import (
"math/rand" "math/rand"
"testing" "testing"
"github.com/ethereum/go-ethereum/common/hexutil"
"github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/log" "github.com/ethereum/go-ethereum/log"
"github.com/stretchr/testify/require" "github.com/stretchr/testify/require"
...@@ -12,7 +13,13 @@ import ( ...@@ -12,7 +13,13 @@ import (
"github.com/ethereum-optimism/optimism/op-node/testlog" "github.com/ethereum-optimism/optimism/op-node/testlog"
) )
// TestCrossLayerUser tests that common actions of the CrossLayerUser actor work: type regolithScheduledTest struct {
name string
regolithTime *hexutil.Uint64
activateRegolith bool
}
// TestCrossLayerUser tests that common actions of the CrossLayerUser actor work in various regolith configurations:
// - transact on L1 // - transact on L1
// - transact on L2 // - transact on L2
// - deposit on L1 // - deposit on L1
...@@ -20,9 +27,28 @@ import ( ...@@ -20,9 +27,28 @@ import (
// - prove tx on L1 // - prove tx on L1
// - wait 1 week + 1 second // - wait 1 week + 1 second
// - finalize withdrawal on L1 // - finalize withdrawal on L1
func TestCrossLayerUser(gt *testing.T) { func TestCrossLayerUser(t *testing.T) {
zeroTime := hexutil.Uint64(0)
futureTime := hexutil.Uint64(20)
farFutureTime := hexutil.Uint64(2000)
tests := []regolithScheduledTest{
{name: "NoRegolith", regolithTime: nil, activateRegolith: false},
{name: "NotYetRegolith", regolithTime: &farFutureTime, activateRegolith: false},
{name: "RegolithAtGenesis", regolithTime: &zeroTime, activateRegolith: true},
{name: "RegolithAfterGenesis", regolithTime: &futureTime, activateRegolith: true},
}
for _, test := range tests {
test := test // Use a fixed reference as the tests run in parallel
t.Run(test.name, func(gt *testing.T) {
runCrossLayerUserTest(gt, test)
})
}
}
func runCrossLayerUserTest(gt *testing.T, test regolithScheduledTest) {
t := NewDefaultTesting(gt) t := NewDefaultTesting(gt)
dp := e2eutils.MakeDeployParams(t, defaultRollupTestParams) dp := e2eutils.MakeDeployParams(t, defaultRollupTestParams)
dp.DeployConfig.L2GenesisRegolithTimeOffset = test.regolithTime
sd := e2eutils.Setup(t, dp, defaultAlloc) sd := e2eutils.Setup(t, dp, defaultAlloc)
log := testlog.Logger(t, log.LvlDebug) log := testlog.Logger(t, log.LvlDebug)
...@@ -64,6 +90,21 @@ func TestCrossLayerUser(gt *testing.T) { ...@@ -64,6 +90,21 @@ func TestCrossLayerUser(gt *testing.T) {
alice.L1.SetUserEnv(l1UserEnv) alice.L1.SetUserEnv(l1UserEnv)
alice.L2.SetUserEnv(l2UserEnv) alice.L2.SetUserEnv(l2UserEnv)
// Build at least one l2 block so we have an unsafe head with a deposit info tx (genesis block doesn't)
seq.ActL2StartBlock(t)
seq.ActL2EndBlock(t)
if test.activateRegolith {
// advance L2 enough to activate regolith fork
seq.ActBuildL2ToRegolith(t)
}
// Check Regolith is active or not by confirming the system info tx is not a system tx
infoTx, err := l2Cl.TransactionInBlock(t.Ctx(), seq.L2Unsafe().Hash, 0)
require.NoError(t, err)
require.True(t, infoTx.IsDepositTx())
// Should only be a system tx if regolith is not enabled
require.Equal(t, !test.activateRegolith, infoTx.IsSystemTx())
// regular L2 tx, in new L2 block // regular L2 tx, in new L2 block
alice.L2.ActResetTxOpts(t) alice.L2.ActResetTxOpts(t)
alice.L2.ActSetTxToAddr(&dp.Addresses.Bob)(t) alice.L2.ActSetTxToAddr(&dp.Addresses.Bob)(t)
...@@ -158,4 +199,11 @@ func TestCrossLayerUser(gt *testing.T) { ...@@ -158,4 +199,11 @@ func TestCrossLayerUser(gt *testing.T) {
miner.ActL1EndBlock(t) miner.ActL1EndBlock(t)
// check withdrawal succeeded // check withdrawal succeeded
alice.L1.ActCheckReceiptStatusOfLastTx(true)(t) alice.L1.ActCheckReceiptStatusOfLastTx(true)(t)
// Check Regolith wasn't activated during the test unintentionally
infoTx, err = l2Cl.TransactionInBlock(t.Ctx(), seq.L2Unsafe().Hash, 0)
require.NoError(t, err)
require.True(t, infoTx.IsDepositTx())
// Should only be a system tx if regolith is not enabled
require.Equal(t, !test.activateRegolith, infoTx.IsSystemTx())
} }
...@@ -323,11 +323,12 @@ func TestMigration(t *testing.T) { ...@@ -323,11 +323,12 @@ func TestMigration(t *testing.T) {
L1EthRpc: forkedL1URL, L1EthRpc: forkedL1URL,
L2EthRpc: gethNode.WSEndpoint(), L2EthRpc: gethNode.WSEndpoint(),
RollupRpc: rollupNode.HTTPEndpoint(), RollupRpc: rollupNode.HTTPEndpoint(),
MaxChannelDuration: 1,
MaxL1TxSize: 120_000, MaxL1TxSize: 120_000,
TargetL1TxSize: 624, TargetL1TxSize: 100_000,
TargetNumFrames: 1, TargetNumFrames: 1,
ApproxComprRatio: 1.0, ApproxComprRatio: 0.4,
SubSafetyMargin: testSafetyMargin(deployCfg), SubSafetyMargin: 4,
PollInterval: 50 * time.Millisecond, PollInterval: 50 * time.Millisecond,
NumConfirmations: 1, NumConfirmations: 1,
ResubmissionTimeout: 5 * time.Second, ResubmissionTimeout: 5 * time.Second,
......
...@@ -531,11 +531,12 @@ func (cfg SystemConfig) Start() (*System, error) { ...@@ -531,11 +531,12 @@ func (cfg SystemConfig) Start() (*System, error) {
L1EthRpc: sys.Nodes["l1"].WSEndpoint(), L1EthRpc: sys.Nodes["l1"].WSEndpoint(),
L2EthRpc: sys.Nodes["sequencer"].WSEndpoint(), L2EthRpc: sys.Nodes["sequencer"].WSEndpoint(),
RollupRpc: sys.RollupNodes["sequencer"].HTTPEndpoint(), RollupRpc: sys.RollupNodes["sequencer"].HTTPEndpoint(),
MaxChannelDuration: 1,
MaxL1TxSize: 120_000, MaxL1TxSize: 120_000,
TargetL1TxSize: 160, //624, TargetL1TxSize: 100_000,
TargetNumFrames: 1, TargetNumFrames: 1,
ApproxComprRatio: 1.0, ApproxComprRatio: 0.4,
SubSafetyMargin: testSafetyMargin(cfg.DeployConfig), SubSafetyMargin: 4,
PollInterval: 50 * time.Millisecond, PollInterval: 50 * time.Millisecond,
NumConfirmations: 1, NumConfirmations: 1,
ResubmissionTimeout: 5 * time.Second, ResubmissionTimeout: 5 * time.Second,
...@@ -575,24 +576,3 @@ func hexPriv(in *ecdsa.PrivateKey) string { ...@@ -575,24 +576,3 @@ func hexPriv(in *ecdsa.PrivateKey) string {
b := e2eutils.EncodePrivKey(in) b := e2eutils.EncodePrivKey(in)
return hexutil.Encode(b) return hexutil.Encode(b)
} }
// returns a safety margin that heuristically leads to a short channel lifetime
// of netChannelDuration. In current testing setups, we want channels to close
// quickly to have a low latency. We don't optimize for gas consumption.
func testSafetyMargin(cfg *genesis.DeployConfig) uint64 {
// target channel duration after first frame is included on L1
const netChannelDuration = 2
// The sequencing window timeout starts from the L1 origin, whereas the
// channel timeout starts from the first L1 inclusion block of any frame.
// So to have comparable values, the sws is converted to an effective
// sequencing window from the first L1 inclusion block, assuming that L2
// blocks are quickly included on L1.
// So we subtract 1 block distance from the origin block and 1 block for
// minging the first frame.
openChannelSeqWindow := cfg.SequencerWindowSize - 2
if openChannelSeqWindow > cfg.ChannelTimeout {
return cfg.ChannelTimeout - netChannelDuration
} else {
return openChannelSeqWindow - netChannelDuration
}
}
...@@ -367,9 +367,9 @@ func TestFinalize(t *testing.T) { ...@@ -367,9 +367,9 @@ func TestFinalize(t *testing.T) {
l2Seq := sys.Clients["sequencer"] l2Seq := sys.Clients["sequencer"]
// as configured in the extra geth lifecycle in testing setup // as configured in the extra geth lifecycle in testing setup
finalizedDistance := uint64(8) const finalizedDistance = 8
// Wait enough time for L1 to finalize and L2 to confirm its data in finalized L1 blocks // Wait enough time for L1 to finalize and L2 to confirm its data in finalized L1 blocks
<-time.After(time.Duration((finalizedDistance+4)*cfg.DeployConfig.L1BlockTime) * time.Second) time.Sleep(time.Duration((finalizedDistance+6)*cfg.DeployConfig.L1BlockTime) * time.Second)
// fetch the finalizes head of geth // fetch the finalizes head of geth
ctx, cancel := context.WithTimeout(context.Background(), 1*time.Second) ctx, cancel := context.WithTimeout(context.Background(), 1*time.Second)
...@@ -883,7 +883,7 @@ func TestWithdrawals(t *testing.T) { ...@@ -883,7 +883,7 @@ func TestWithdrawals(t *testing.T) {
require.Nil(t, err) require.Nil(t, err)
// Get l2BlockNumber for proof generation // Get l2BlockNumber for proof generation
ctx, cancel = context.WithTimeout(context.Background(), 30*time.Duration(cfg.DeployConfig.L1BlockTime)*time.Second) ctx, cancel = context.WithTimeout(context.Background(), 40*time.Duration(cfg.DeployConfig.L1BlockTime)*time.Second)
defer cancel() defer cancel()
blockNumber, err := withdrawals.WaitForFinalizationPeriod(ctx, l1Client, predeploys.DevOptimismPortalAddr, receipt.BlockNumber) blockNumber, err := withdrawals.WaitForFinalizationPeriod(ctx, l1Client, predeploys.DevOptimismPortalAddr, receipt.BlockNumber)
require.Nil(t, err) require.Nil(t, err)
......
...@@ -415,7 +415,6 @@ func TestMixedDepositValidity(t *testing.T) { ...@@ -415,7 +415,6 @@ func TestMixedDepositValidity(t *testing.T) {
// TestMixedWithdrawalValidity makes a number of withdrawal transactions and ensures ones with modified parameters are // TestMixedWithdrawalValidity makes a number of withdrawal transactions and ensures ones with modified parameters are
// rejected while unmodified ones are accepted. This runs test cases in different systems. // rejected while unmodified ones are accepted. This runs test cases in different systems.
func TestMixedWithdrawalValidity(t *testing.T) { func TestMixedWithdrawalValidity(t *testing.T) {
parallel(t)
// Setup our logger handler // Setup our logger handler
if !verboseGethNodes { if !verboseGethNodes {
log.Root().SetHandler(log.DiscardHandler()) log.Root().SetHandler(log.DiscardHandler())
...@@ -425,7 +424,7 @@ func TestMixedWithdrawalValidity(t *testing.T) { ...@@ -425,7 +424,7 @@ func TestMixedWithdrawalValidity(t *testing.T) {
for i := 0; i <= 8; i++ { for i := 0; i <= 8; i++ {
i := i // avoid loop var capture i := i // avoid loop var capture
t.Run(fmt.Sprintf("withdrawal test#%d", i+1), func(t *testing.T) { t.Run(fmt.Sprintf("withdrawal test#%d", i+1), func(t *testing.T) {
t.Parallel() parallel(t)
// Create our system configuration, funding all accounts we created for L1/L2, and start it // Create our system configuration, funding all accounts we created for L1/L2, and start it
cfg := DefaultSystemConfig(t) cfg := DefaultSystemConfig(t)
cfg.DeployConfig.FinalizationPeriodSeconds = 6 cfg.DeployConfig.FinalizationPeriodSeconds = 6
...@@ -528,7 +527,7 @@ func TestMixedWithdrawalValidity(t *testing.T) { ...@@ -528,7 +527,7 @@ func TestMixedWithdrawalValidity(t *testing.T) {
transactor.ExpectedL2Nonce = transactor.ExpectedL2Nonce + 1 transactor.ExpectedL2Nonce = transactor.ExpectedL2Nonce + 1
// Wait for the finalization period, then we can finalize this withdrawal. // Wait for the finalization period, then we can finalize this withdrawal.
ctx, cancel = context.WithTimeout(context.Background(), 25*time.Duration(cfg.DeployConfig.L1BlockTime)*time.Second) ctx, cancel = context.WithTimeout(context.Background(), 40*time.Duration(cfg.DeployConfig.L1BlockTime)*time.Second)
blockNumber, err := withdrawals.WaitForFinalizationPeriod(ctx, l1Client, predeploys.DevOptimismPortalAddr, receipt.BlockNumber) blockNumber, err := withdrawals.WaitForFinalizationPeriod(ctx, l1Client, predeploys.DevOptimismPortalAddr, receipt.BlockNumber)
cancel() cancel()
require.Nil(t, err) require.Nil(t, err)
...@@ -658,7 +657,7 @@ func TestMixedWithdrawalValidity(t *testing.T) { ...@@ -658,7 +657,7 @@ func TestMixedWithdrawalValidity(t *testing.T) {
require.Equal(t, types.ReceiptStatusSuccessful, proveReceipt.Status) require.Equal(t, types.ReceiptStatusSuccessful, proveReceipt.Status)
// Wait for finalization and then create the Finalized Withdrawal Transaction // Wait for finalization and then create the Finalized Withdrawal Transaction
ctx, cancel = context.WithTimeout(context.Background(), 40*time.Duration(cfg.DeployConfig.L1BlockTime)*time.Second) ctx, cancel = context.WithTimeout(context.Background(), 45*time.Duration(cfg.DeployConfig.L1BlockTime)*time.Second)
defer cancel() defer cancel()
_, err = withdrawals.WaitForFinalizationPeriod(ctx, l1Client, predeploys.DevOptimismPortalAddr, header.Number) _, err = withdrawals.WaitForFinalizationPeriod(ctx, l1Client, predeploys.DevOptimismPortalAddr, header.Number)
require.Nil(t, err) require.Nil(t, err)
......
...@@ -66,6 +66,7 @@ var Goerli = rollup.Config{ ...@@ -66,6 +66,7 @@ var Goerli = rollup.Config{
BatchInboxAddress: common.HexToAddress("0xff00000000000000000000000000000000000420"), BatchInboxAddress: common.HexToAddress("0xff00000000000000000000000000000000000420"),
DepositContractAddress: common.HexToAddress("0x5b47E1A08Ea6d985D6649300584e6722Ec4B1383"), DepositContractAddress: common.HexToAddress("0x5b47E1A08Ea6d985D6649300584e6722Ec4B1383"),
L1SystemConfigAddress: common.HexToAddress("0xAe851f927Ee40dE99aaBb7461C00f9622ab91d60"), L1SystemConfigAddress: common.HexToAddress("0xAe851f927Ee40dE99aaBb7461C00f9622ab91d60"),
RegolithTime: u64Ptr(1679079600),
} }
var NetworksByName = map[string]rollup.Config{ var NetworksByName = map[string]rollup.Config{
...@@ -97,3 +98,7 @@ func GetRollupConfig(name string) (rollup.Config, error) { ...@@ -97,3 +98,7 @@ func GetRollupConfig(name string) (rollup.Config, error) {
return network, nil return network, nil
} }
func u64Ptr(v uint64) *uint64 {
return &v
}
...@@ -19,6 +19,7 @@ import ( ...@@ -19,6 +19,7 @@ import (
mocknet "github.com/libp2p/go-libp2p/p2p/net/mock" mocknet "github.com/libp2p/go-libp2p/p2p/net/mock"
tswarm "github.com/libp2p/go-libp2p/p2p/net/swarm/testing" tswarm "github.com/libp2p/go-libp2p/p2p/net/swarm/testing"
"github.com/stretchr/testify/require" "github.com/stretchr/testify/require"
"golang.org/x/exp/slices"
"github.com/ethereum/go-ethereum/log" "github.com/ethereum/go-ethereum/log"
"github.com/ethereum/go-ethereum/p2p/enode" "github.com/ethereum/go-ethereum/p2p/enode"
...@@ -314,19 +315,22 @@ func TestDiscovery(t *testing.T) { ...@@ -314,19 +315,22 @@ func TestDiscovery(t *testing.T) {
// B and C don't know each other yet, but both have A as a bootnode. // B and C don't know each other yet, but both have A as a bootnode.
// It should only be a matter of time for them to connect, if they discover each other via A. // It should only be a matter of time for them to connect, if they discover each other via A.
var firstPeersOfB []peer.ID timeout := time.After(time.Second * 10)
for i := 0; i < 2; i++ { var peersOfB []peer.ID
// B should be connected to the bootnode (A) it used (it's a valid optimism node to connect to here)
// C should also be connected, although this one might take more time to discover
for !slices.Contains(peersOfB, hostA.ID()) || !slices.Contains(peersOfB, hostC.ID()) {
select { select {
case <-time.After(time.Second * 30): case <-timeout:
t.Fatal("failed to get connection to B in time") var peers []string
for _, id := range peersOfB {
peers = append(peers, id.String())
}
t.Fatalf("timeout reached - expected host A: %v and host C: %v to be in %v", hostA.ID().String(), hostC.ID().String(), peers)
case c := <-connsB: case c := <-connsB:
firstPeersOfB = append(firstPeersOfB, c.RemotePeer()) peersOfB = append(peersOfB, c.RemotePeer())
} }
} }
// B should be connected to the bootnode it used (it's a valid optimism node to connect to here)
require.Contains(t, firstPeersOfB, hostA.ID())
// C should be connected, although this one might take more time to discover
require.Contains(t, firstPeersOfB, hostC.ID())
} }
// Most tests should use mocknets instead of using the actual local host network // Most tests should use mocknets instead of using the actual local host network
......
...@@ -54,7 +54,7 @@ func WaitForFinalizationPeriod(ctx context.Context, client *ethclient.Client, po ...@@ -54,7 +54,7 @@ func WaitForFinalizationPeriod(ctx context.Context, client *ethclient.Client, po
} }
l2BlockNumber = l2BlockNumber.Mul(l2BlockNumber, submissionInterval) l2BlockNumber = l2BlockNumber.Mul(l2BlockNumber, submissionInterval)
finalizationPeriod, err := portal.FINALIZATIONPERIODSECONDS(opts) finalizationPeriod, err := l2OO.FINALIZATIONPERIODSECONDS(opts)
if err != nil { if err != nil {
return 0, err return 0, err
} }
......
FROM ethereum/client-go:v1.10.22 FROM ethereum/client-go:v1.11.2
RUN apk add --no-cache jq RUN apk add --no-cache jq
......
FROM ethereumoptimism/op-geth:optimism-history FROM ethereumoptimism/op-geth:optimism
RUN apk add --no-cache jq RUN apk add --no-cache jq
......
...@@ -17,6 +17,7 @@ services: ...@@ -17,6 +17,7 @@ services:
dockerfile: Dockerfile.l1 dockerfile: Dockerfile.l1
ports: ports:
- "8545:8545" - "8545:8545"
- "7060:6060"
volumes: volumes:
- "l1_data:/db" - "l1_data:/db"
- "${PWD}/../.devnet/genesis-l1.json:/genesis.json" - "${PWD}/../.devnet/genesis-l1.json:/genesis.json"
...@@ -28,6 +29,7 @@ services: ...@@ -28,6 +29,7 @@ services:
dockerfile: Dockerfile.l2 dockerfile: Dockerfile.l2
ports: ports:
- "9545:8545" - "9545:8545"
- "8060:6060"
volumes: volumes:
- "l2_data:/db" - "l2_data:/db"
- "${PWD}/../.devnet/genesis-l2.json:/genesis.json" - "${PWD}/../.devnet/genesis-l2.json:/genesis.json"
...@@ -120,11 +122,12 @@ services: ...@@ -120,11 +122,12 @@ services:
OP_BATCHER_L1_ETH_RPC: http://l1:8545 OP_BATCHER_L1_ETH_RPC: http://l1:8545
OP_BATCHER_L2_ETH_RPC: http://l2:8545 OP_BATCHER_L2_ETH_RPC: http://l2:8545
OP_BATCHER_ROLLUP_RPC: http://op-node:8545 OP_BATCHER_ROLLUP_RPC: http://op-node:8545
OP_BATCHER_MAX_CHANNEL_DURATION: 1
OP_BATCHER_MAX_L1_TX_SIZE_BYTES: 120000 OP_BATCHER_MAX_L1_TX_SIZE_BYTES: 120000
OP_BATCHER_TARGET_L1_TX_SIZE_BYTES: 624 OP_BATCHER_TARGET_L1_TX_SIZE_BYTES: 100000
OP_BATCHER_TARGET_NUM_FRAMES: 1 OP_BATCHER_TARGET_NUM_FRAMES: 1
OP_BATCHER_APPROX_COMPR_RATIO: 1.0 OP_BATCHER_APPROX_COMPR_RATIO: 0.4
OP_BATCHER_SUB_SAFETY_MARGIN: 6 # SWS is 15, ChannelTimeout is 40 OP_BATCHER_SUB_SAFETY_MARGIN: 4 # SWS is 15, ChannelTimeout is 40
OP_BATCHER_POLL_INTERVAL: 1s OP_BATCHER_POLL_INTERVAL: 1s
OP_BATCHER_NUM_CONFIRMATIONS: 1 OP_BATCHER_NUM_CONFIRMATIONS: 1
OP_BATCHER_SAFE_ABORT_NONCE_TOO_LOW_COUNT: 3 OP_BATCHER_SAFE_ABORT_NONCE_TOO_LOW_COUNT: 3
......
...@@ -65,4 +65,7 @@ exec geth \ ...@@ -65,4 +65,7 @@ exec geth \
--authrpc.vhosts="*" \ --authrpc.vhosts="*" \
--authrpc.jwtsecret=/config/jwt-secret.txt \ --authrpc.jwtsecret=/config/jwt-secret.txt \
--gcmode=archive \ --gcmode=archive \
--metrics \
--metrics.addr=0.0.0.0 \
--metrics.port=6060 \
"$@" "$@"
...@@ -125,6 +125,6 @@ FROM base as balance-monitor ...@@ -125,6 +125,6 @@ FROM base as balance-monitor
WORKDIR /opt/optimism/packages/balance-monitor WORKDIR /opt/optimism/packages/balance-monitor
ENTRYPOINT ["yarn", "run", "start:prod"] ENTRYPOINT ["yarn", "run", "start:prod"]
FROM base as two-step-monitor FROM base as wd-mon
WORKDIR /opt/optimism/packages/two-step-monitor WORKDIR /opt/optimism/packages/chain-mon
ENTRYPOINT ["yarn", "run", "start"] ENTRYPOINT ["yarn", "run", "start:wd-mon"]
# @eth-optimism/actor-tests # @eth-optimism/actor-tests
## 0.0.22
### Patch Changes
- Updated dependencies [cb19e2f9c]
- @eth-optimism/sdk@2.0.0
- @eth-optimism/contracts-bedrock@0.13.0
## 0.0.21 ## 0.0.21
### Patch Changes ### Patch Changes
......
{ {
"name": "@eth-optimism/actor-tests", "name": "@eth-optimism/actor-tests",
"version": "0.0.21", "version": "0.0.22",
"description": "A library and suite of tests to stress test Optimism Bedrock.", "description": "A library and suite of tests to stress test Optimism Bedrock.",
"license": "MIT", "license": "MIT",
"author": "", "author": "",
...@@ -18,9 +18,9 @@ ...@@ -18,9 +18,9 @@
"test:coverage": "yarn test" "test:coverage": "yarn test"
}, },
"dependencies": { "dependencies": {
"@eth-optimism/contracts-bedrock": "0.12.1", "@eth-optimism/contracts-bedrock": "0.13.0",
"@eth-optimism/core-utils": "^0.12.0", "@eth-optimism/core-utils": "^0.12.0",
"@eth-optimism/sdk": "^1.10.4", "@eth-optimism/sdk": "^2.0.0",
"@types/chai": "^4.2.18", "@types/chai": "^4.2.18",
"@types/chai-as-promised": "^7.1.4", "@types/chai-as-promised": "^7.1.4",
"async-mutex": "^0.3.2", "async-mutex": "^0.3.2",
......
# @eth-optimism/atst
## 0.1.0
### Minor Changes
- a312af15d: Make type parsing more intuitive
- 82a033fed: Fix string type that should be `0x${string}`
### Patch Changes
- 11bb01851: Add new atst package
- 7c37d262a: Release ATST
...@@ -32,7 +32,7 @@ npm install @eth-optimism/atst wagmi @wagmi/core ethers@5.7.0 ...@@ -32,7 +32,7 @@ npm install @eth-optimism/atst wagmi @wagmi/core ethers@5.7.0
The typescript sdk provides a clean [wagmi](https://wagmi.sh/) based interface for reading and writing to the attestation station The typescript sdk provides a clean [wagmi](https://wagmi.sh/) based interface for reading and writing to the attestation station
### See [sdk docs]() for usage instructions ### See [sdk docs](https://github.com/ethereum-optimism/optimism/blob/develop/packages/atst/docs/sdk.md) for usage instructions
## atst cli ## atst cli
...@@ -40,16 +40,28 @@ The cli provides a convenient cli for interacting with the attestation station c ...@@ -40,16 +40,28 @@ The cli provides a convenient cli for interacting with the attestation station c
TODO put a gif here of using it TODO put a gif here of using it
## React instructions ## React API
For react hooks we recomend using the [wagmi cli](https://wagmi.sh/cli/getting-started) with the [etherscan plugin](https://wagmi.sh/cli/plugins/etherscan) and [react plugin](https://wagmi.sh/cli/plugins/react) to automatically generate react hooks around the attestation station. See [example/react](http://todo.todo.todo) for an example. For react hooks we recomend using the [wagmi cli](https://wagmi.sh/cli/getting-started) with the [etherscan plugin](https://wagmi.sh/cli/plugins/etherscan) and [react plugin](https://wagmi.sh/cli/plugins/react) to automatically generate react hooks around the attestation station.
Use `parseAttestationBytes` and `stringifyAttestationBytes` to parse and stringify attestations before passing them into wagmi hooks. Use `parseAttestationBytes` and `stringifyAttestationBytes` to parse and stringify attestations before passing them into wagmi hooks.
For convenience we also export the hooks here.
`useAttestationStationAttestation` - Reads attestations with useContractRead
`useAttestationStationVersion` - Reads attestation version
`useAttestationStationAttest` - Wraps useContractWrite with attestation station abi calling attest
`usePrepareAttestationStationAttest` - Wraps usePrepare with attestation station abi calling attest
`useAttestationStationAttestationCreatedEvent` - Wraps useContractEvents for Created events
Also some more hooks exported by the cli but these are likely the only ones you need.
## Contributing ## Contributing
Please see our [contributing.md](/docs/contributing.md). No contribution is too small. Please see our [contributing.md](docs/contributing.md). No contribution is too small.
Having your contribution denied feels bad. Please consider opening an issue before adding any new features or apis Having your contribution denied feels bad. Please consider opening an issue before adding any new features or apis
## Check [Awesome ATST](https://todo.todo.todo) for awesome tools and examples around the attestation station
...@@ -30,6 +30,8 @@ yarn add @eth-optimism/atst @wagmi/core ethers@5.7.0 ...@@ -30,6 +30,8 @@ yarn add @eth-optimism/atst @wagmi/core ethers@5.7.0
## Basic usage ## Basic usage
Note: all functions are fully tested. The tests are a great example to see usage examples.
### Basic Setup ### Basic Setup
ATST uses `@wagmi/core` under the hood. See their documentation for more information. ATST uses `@wagmi/core` under the hood. See their documentation for more information.
...@@ -52,21 +54,26 @@ createClient({ ...@@ -52,21 +54,26 @@ createClient({
### Reading an attestation ### Reading an attestation
To read an attestation use `readString`, `readAddress`, `readNumber`, `readBool`
Use `readAttestationString` with `bytes` passed in for the types parameter to read raw bytes
Here is an example of reading an attestation used by the optimist nft Here is an example of reading an attestation used by the optimist nft
```typescript ```typescript
import { readAttestation } from '@eth-optimism/atst' import { readAttestationString } from '@eth-optimism/atst'
const creator = '0x60c5C9c98bcBd0b0F2fD89B24c16e533BaA8CdA3' const creator = '0x60c5C9c98bcBd0b0F2fD89B24c16e533BaA8CdA3'
const about = '0x2335022c740d17c2837f9C884Bfe4fFdbf0A95D5' const about = '0x2335022c740d17c2837f9C884Bfe4fFdbf0A95D5'
const key = 'optimist.base-uri' const key = 'optimist.base-uri'
const dataType = 'string' // note string is default
const attestation = await readAttestation(creator, about, key, dataType) const str = await readAttestationString(creator, about, key)
console.log(attestation) // https://assets.optimism.io/4a609661-6774-441f-9fdb-453fdbb89931-bucket/optimist-nft/attributes console.log(attestation) // https://assets.optimism.io/4a609661-6774-441f-9fdb-453fdbb89931-bucket/optimist-nft/attributes
``` ```
### Reading multiple Attestations
If reading more than one attestation you can use readAttestations to read them with multicall If reading more than one attestation you can use readAttestations to read them with multicall
### Writing an attestation ### Writing an attestation
...@@ -172,11 +179,16 @@ const attestation = await readAttestations({ ...@@ -172,11 +179,16 @@ const attestation = await readAttestations({
}) })
``` ```
### parseAttestationBytes ### Parsing bytes
Parses raw bytes from the attestation station based on the type. These utilities for parsing bytes are provided:
Note: `readAttestation` and `readAttestations` already parse the bytes so this is only necessary if reading attestations directly from chain instead of through this sdkA `parseAddress`
`parseNumber`
`parseBool`
`parseString`
Note: `readAttestation` and `readAttestations` already parse the bytes so this is only necessary if reading attestations directly from chain instead of through this utility
```typescript ```typescript
const attestation = parseAttestationBytes( const attestation = parseAttestationBytes(
...@@ -193,6 +205,21 @@ const attestation = parseAttestationBytes( ...@@ -193,6 +205,21 @@ const attestation = parseAttestationBytes(
) )
``` ```
### attestation keys
Attestation keys are limited to 32 bytes. To support keys longer than 32 bytes, you can use the `encodeRawKey` function
```typescript
const key = await encodeRawKey(
about,
key,
'i.am.a.key.much.longer.than.32.bytes.long'
)
await writeAttestation(preparedTx)
```
encodeRawKey will keep the key as is if it is shorter than 32 bytes and otherwise run it through kekkak256
### prepareWriteAttestation ### prepareWriteAttestation
[Prepares](https://wagmi.sh/core/actions/prepareWriteContract) an attestation to be written. [Prepares](https://wagmi.sh/core/actions/prepareWriteContract) an attestation to be written.
...@@ -225,3 +252,25 @@ const bigNumberAttestation = stringifyAttestationBytes( ...@@ -225,3 +252,25 @@ const bigNumberAttestation = stringifyAttestationBytes(
const preparedTx = await prepareWriteAttestation(about, key, 'hello world') const preparedTx = await prepareWriteAttestation(about, key, 'hello world')
await writeAttestation(preparedTx) await writeAttestation(preparedTx)
``` ```
### getEvents
To getEvents use getEvents with a provider and any filters to filter the event
```typescript
const events = await getEvents({
creator,
about,
key,
value,
provider: new ethers.providers.JsonRpcProvider('http://localhost:8545'),
fromBlockOrBlockhash,
toBlock,
})
```
Set key, about, creator, or value to `null` to not include that filter
## Tutorial
For a tutorial on using the attestation station in general, see out tutorial as well as other Optimism related tutorials in our [optimism-tutorial](https://github.com/ethereum-optimism/optimism-tutorial/tree/main/ecosystem/attestation-station#key-values) repo
{ {
"name": "@eth-optimism/atst", "name": "@eth-optimism/atst",
"version": "0.0.0", "version": "0.1.0",
"type": "module", "type": "module",
"main": "dist/index.js", "main": "dist/index.js",
"types": "src/index.ts", "types": "src/index.ts",
......
...@@ -26,6 +26,7 @@ cli ...@@ -26,6 +26,7 @@ cli
}) })
.example( .example(
() => () =>
// note: private key is just the first testing address when running anvil
`atst read --key "optimist.base-uri" --about 0x2335022c740d17c2837f9C884Bfe4fFdbf0A95D5 --creator 0x60c5C9c98bcBd0b0F2fD89B24c16e533BaA8CdA3` `atst read --key "optimist.base-uri" --about 0x2335022c740d17c2837f9C884Bfe4fFdbf0A95D5 --creator 0x60c5C9c98bcBd0b0F2fD89B24c16e533BaA8CdA3`
) )
.action(async (options: ReadOptions) => { .action(async (options: ReadOptions) => {
...@@ -72,6 +73,8 @@ cli ...@@ -72,6 +73,8 @@ cli
`atst write --key "optimist.base-uri" --about 0x2335022c740d17c2837f9C884Bfe4fFdbf0A95D5 --value "my attestation" --private-key 0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80 --rpc-url http://localhost:8545` `atst write --key "optimist.base-uri" --about 0x2335022c740d17c2837f9C884Bfe4fFdbf0A95D5 --value "my attestation" --private-key 0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80 --rpc-url http://localhost:8545`
) )
.action(async (options: WriteOptions) => { .action(async (options: WriteOptions) => {
const spinner = logger.spinner()
spinner.start('Writing attestation...')
const { write } = await import('./commands/write') const { write } = await import('./commands/write')
// TODO use the native api to do this instead of parsing the raw args // TODO use the native api to do this instead of parsing the raw args
...@@ -86,9 +89,16 @@ cli ...@@ -86,9 +89,16 @@ cli
: options.contract : options.contract
await write({ ...options, about, privateKey, contract }) await write({ ...options, about, privateKey, contract })
.then((res) => {
spinner.succeed('Attestation written!')
logger.info(`Attestation hash: ${res}`)
})
.catch((e) => {
logger.error(e)
spinner.fail('Attestation failed!')
})
}) })
cli.help()
cli.version(packageJson.version) cli.version(packageJson.version)
void (async () => { void (async () => {
......
...@@ -25,6 +25,7 @@ describe(`cli:${write.name}`, () => { ...@@ -25,6 +25,7 @@ describe(`cli:${write.name}`, () => {
value, value,
contract: ATTESTATION_STATION_ADDRESS, contract: ATTESTATION_STATION_ADDRESS,
rpcUrl, rpcUrl,
dataType: 'string',
}) })
expect(txHash.startsWith('0x')).toBe(true) expect(txHash.startsWith('0x')).toBe(true)
......
// constants // constants
export { ATTESTATION_STATION_ADDRESS } from './constants/attestationStationAddress' export { ATTESTATION_STATION_ADDRESS } from './constants/attestationStationAddress'
// lib // lib
export { readAttestation } from './lib/readAttestation' export { encodeRawKey } from './lib/encodeRawKey'
export {
readAttestation,
readAttestationAddress,
readAttestationBool,
readAttestationNumber,
readAttestationString,
} from './lib/readAttestation'
export { readAttestations } from './lib/readAttestations' export { readAttestations } from './lib/readAttestations'
export { getEvents } from './lib/getEvents'
export { prepareWriteAttestation } from './lib/prepareWriteAttestation' export { prepareWriteAttestation } from './lib/prepareWriteAttestation'
export { prepareWriteAttestations } from './lib/prepareWriteAttestations' export { prepareWriteAttestations } from './lib/prepareWriteAttestations'
export { writeAttestation } from './lib/writeAttestation' export { writeAttestation } from './lib/writeAttestation'
export { abi } from './lib/abi' export { abi } from './lib/abi'
export { parseAttestationBytes } from './lib/parseAttestationBytes'
export { stringifyAttestationBytes } from './lib/stringifyAttestationBytes' export { stringifyAttestationBytes } from './lib/stringifyAttestationBytes'
export {
parseAttestationBytes,
parseAddress,
parseNumber,
parseBool,
parseString,
} from './lib/parseAttestationBytes'
// types // types
export type { AttestationCreatedEvent } from './types/AttestationCreatedEvent'
export type { AttestationReadParams } from './types/AttestationReadParams' export type { AttestationReadParams } from './types/AttestationReadParams'
export type { WagmiBytes } from './types/WagmiBytes'
export type { DataTypeOption } from './types/DataTypeOption' export type { DataTypeOption } from './types/DataTypeOption'
export type { WagmiBytes } from './types/WagmiBytes'
// react
export * from './react'
import { describe, expect, it } from 'vitest'
import { encodeRawKey } from './encodeRawKey'
describe(encodeRawKey.name, () => {
it('should return just the raw key if it is less than 32 bytes', () => {
const rawKey = 'I am 32'
const encodedKey = encodeRawKey(rawKey)
expect(encodedKey).toMatchInlineSnapshot(
'"0x4920616d20333200000000000000000000000000000000000000000000000000"'
)
})
it('should return the keccak256 hash of the raw key if it is more than 32 bytes', () => {
const rawKey = 'I am way more than 32 bytes long I should be hashed'
const encodedKey = encodeRawKey(rawKey)
expect(encodedKey).toMatchInlineSnapshot(
'"0xc9d5d767710cc45f74c3a9a0c53dc44391a7951604c7ea3bd9116ccff406daff"'
)
})
})
import { ethers } from 'ethers'
import { WagmiBytes } from '../types/WagmiBytes'
export const encodeRawKey = (rawKey: string): WagmiBytes => {
if (rawKey.length < 32) {
return ethers.utils.formatBytes32String(rawKey) as WagmiBytes
}
const hash = ethers.utils.keccak256(ethers.utils.toUtf8Bytes(rawKey))
return (hash.slice(0, 64) + 'ff') as WagmiBytes
}
import { ethers } from 'ethers'
import { describe, it, expect } from 'vitest'
import { getEvents } from './getEvents'
describe(getEvents.name, () => {
it('should get events on goerli', async () => {
const key = 'animalfarm.school.attended'
const creator = '0xBCf86Fd70a0183433763ab0c14E7a760194f3a9F'
expect(
await getEvents({
creator,
about: '0x00000000000000000000000000000000000060A7',
key,
provider: new ethers.providers.JsonRpcProvider(
'https://goerli.optimism.io'
),
})
).toMatchInlineSnapshot(`
[
{
"address": "0xEE36eaaD94d1Cc1d0eccaDb55C38bFfB6Be06C77",
"args": [
"0xBCf86Fd70a0183433763ab0c14E7a760194f3a9F",
"0x00000000000000000000000000000000000060A7",
"0x616e696d616c6661726d2e7363686f6f6c2e617474656e646564000000000000",
"0x01",
],
"blockHash": "0x75feb3572d4b7d682cf632bf64df72c8d9c336dedcf8df1c88f755d529ec1b85",
"blockNumber": 3463240,
"data": "0x000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000010100000000000000000000000000000000000000000000000000000000000000",
"decode": [Function],
"event": "AttestationCreated",
"eventSignature": "AttestationCreated(address,address,bytes32,bytes)",
"getBlock": [Function],
"getTransaction": [Function],
"getTransactionReceipt": [Function],
"logIndex": 0,
"removeListener": [Function],
"removed": false,
"topics": [
"0x28710dfecab43d1e29e02aa56b2e1e610c0bae19135c9cf7a83a1adb6df96d85",
"0x000000000000000000000000bcf86fd70a0183433763ab0c14e7a760194f3a9f",
"0x00000000000000000000000000000000000000000000000000000000000060a7",
"0x616e696d616c6661726d2e7363686f6f6c2e617474656e646564000000000000",
],
"transactionHash": "0x0e77a32b2558f39e60c3e81bd6efd811cf4b3bd80a4f666d042a221ea63c93ab",
"transactionIndex": 0,
},
{
"address": "0xEE36eaaD94d1Cc1d0eccaDb55C38bFfB6Be06C77",
"args": [
"0xBCf86Fd70a0183433763ab0c14E7a760194f3a9F",
"0x00000000000000000000000000000000000060A7",
"0x616e696d616c6661726d2e7363686f6f6c2e617474656e646564000000000000",
"0x01",
],
"blockHash": "0xdb11b4b06e5866be931667b8c62dca182240b9256a3d8c64c1c247107aa33752",
"blockNumber": 4105095,
"data": "0x000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000010100000000000000000000000000000000000000000000000000000000000000",
"decode": [Function],
"event": "AttestationCreated",
"eventSignature": "AttestationCreated(address,address,bytes32,bytes)",
"getBlock": [Function],
"getTransaction": [Function],
"getTransactionReceipt": [Function],
"logIndex": 0,
"removeListener": [Function],
"removed": false,
"topics": [
"0x28710dfecab43d1e29e02aa56b2e1e610c0bae19135c9cf7a83a1adb6df96d85",
"0x000000000000000000000000bcf86fd70a0183433763ab0c14e7a760194f3a9f",
"0x00000000000000000000000000000000000000000000000000000000000060a7",
"0x616e696d616c6661726d2e7363686f6f6c2e617474656e646564000000000000",
],
"transactionHash": "0x61f59bd4dfe54272d9369effe3ae57a0ef2584161fcf2bbd55f5596002e759bd",
"transactionIndex": 1,
},
]
`)
})
it('should get events on mainnet', async () => {
const creator = '0x60c5C9c98bcBd0b0F2fD89B24c16e533BaA8CdA3'
const about = '0x2335022c740d17c2837f9C884Bfe4fFdbf0A95D5'
const key = 'optimist.base-uri'
expect(
await getEvents({
creator,
about,
key,
provider: new ethers.providers.JsonRpcProvider('http://localhost:8545'),
})
).toMatchInlineSnapshot(`
[
{
"address": "0xEE36eaaD94d1Cc1d0eccaDb55C38bFfB6Be06C77",
"args": [
"0x60c5C9c98bcBd0b0F2fD89B24c16e533BaA8CdA3",
"0x2335022c740d17c2837f9C884Bfe4fFdbf0A95D5",
"0x6f7074696d6973742e626173652d757269000000000000000000000000000000",
"0x68747470733a2f2f73746f726167656170692e666c65656b2e636f2f33336630633965392d666437392d343634622d613431642d3634343238313961316230352d6275636b65742f6f7074696d6973742d6e66742f61747472696275746573",
],
"blockHash": "0x5b5f34cb7a72eb6aaf6d8af873f210278738573386c88f85c605067c10d67ee3",
"blockNumber": 50135778,
"data": "0x0000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000005f68747470733a2f2f73746f726167656170692e666c65656b2e636f2f33336630633965392d666437392d343634622d613431642d3634343238313961316230352d6275636b65742f6f7074696d6973742d6e66742f6174747269627574657300",
"decode": [Function],
"event": "AttestationCreated",
"eventSignature": "AttestationCreated(address,address,bytes32,bytes)",
"getBlock": [Function],
"getTransaction": [Function],
"getTransactionReceipt": [Function],
"logIndex": 1,
"removeListener": [Function],
"removed": false,
"topics": [
"0x28710dfecab43d1e29e02aa56b2e1e610c0bae19135c9cf7a83a1adb6df96d85",
"0x00000000000000000000000060c5c9c98bcbd0b0f2fd89b24c16e533baa8cda3",
"0x0000000000000000000000002335022c740d17c2837f9c884bfe4ffdbf0a95d5",
"0x6f7074696d6973742e626173652d757269000000000000000000000000000000",
],
"transactionHash": "0x265c98ce12e0836616efd3ea2130df9647729574feb40d5607e4031ff9aace01",
"transactionIndex": 0,
},
{
"address": "0xEE36eaaD94d1Cc1d0eccaDb55C38bFfB6Be06C77",
"args": [
"0x60c5C9c98bcBd0b0F2fD89B24c16e533BaA8CdA3",
"0x2335022c740d17c2837f9C884Bfe4fFdbf0A95D5",
"0x6f7074696d6973742e626173652d757269000000000000000000000000000000",
"0x68747470733a2f2f6173736574732e6f7074696d69736d2e696f2f34613630393636312d363737342d343431662d396664622d3435336664626238393933312d6275636b65742f6f7074696d6973742d6e66742f61747472696275746573",
],
"blockHash": "0x889ad6bb2eb7aee0c095c1f6cc11f5a7a65917d7bc06500dad3213fb031f1e9c",
"blockNumber": 50141511,
"data": "0x0000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000005e68747470733a2f2f6173736574732e6f7074696d69736d2e696f2f34613630393636312d363737342d343431662d396664622d3435336664626238393933312d6275636b65742f6f7074696d6973742d6e66742f617474726962757465730000",
"decode": [Function],
"event": "AttestationCreated",
"eventSignature": "AttestationCreated(address,address,bytes32,bytes)",
"getBlock": [Function],
"getTransaction": [Function],
"getTransactionReceipt": [Function],
"logIndex": 1,
"removeListener": [Function],
"removed": false,
"topics": [
"0x28710dfecab43d1e29e02aa56b2e1e610c0bae19135c9cf7a83a1adb6df96d85",
"0x00000000000000000000000060c5c9c98bcbd0b0f2fd89b24c16e533baa8cda3",
"0x0000000000000000000000002335022c740d17c2837f9c884bfe4ffdbf0a95d5",
"0x6f7074696d6973742e626173652d757269000000000000000000000000000000",
],
"transactionHash": "0xf4c0fc1ceec42831252c90b7d5c1e7a5bd6d9642d07c80afc8b525211852ee03",
"transactionIndex": 0,
},
{
"address": "0xEE36eaaD94d1Cc1d0eccaDb55C38bFfB6Be06C77",
"args": [
"0x60c5C9c98bcBd0b0F2fD89B24c16e533BaA8CdA3",
"0x2335022c740d17c2837f9C884Bfe4fFdbf0A95D5",
"0x6f7074696d6973742e626173652d757269000000000000000000000000000000",
"0x68747470733a2f2f6173736574732e6f7074696d69736d2e696f2f34613630393636312d363737342d343431662d396664622d3435336664626238393933312d6275636b65742f6f7074696d6973742d6e66742f61747472696275746573",
],
"blockHash": "0x120931c24234d03af66b9b21fcaf3b97242ed8f0c0418a9b16fc5cc1a804e917",
"blockNumber": 50141837,
"data": "0x0000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000005e68747470733a2f2f6173736574732e6f7074696d69736d2e696f2f34613630393636312d363737342d343431662d396664622d3435336664626238393933312d6275636b65742f6f7074696d6973742d6e66742f617474726962757465730000",
"decode": [Function],
"event": "AttestationCreated",
"eventSignature": "AttestationCreated(address,address,bytes32,bytes)",
"getBlock": [Function],
"getTransaction": [Function],
"getTransactionReceipt": [Function],
"logIndex": 1,
"removeListener": [Function],
"removed": false,
"topics": [
"0x28710dfecab43d1e29e02aa56b2e1e610c0bae19135c9cf7a83a1adb6df96d85",
"0x00000000000000000000000060c5c9c98bcbd0b0f2fd89b24c16e533baa8cda3",
"0x0000000000000000000000002335022c740d17c2837f9c884bfe4ffdbf0a95d5",
"0x6f7074696d6973742e626173652d757269000000000000000000000000000000",
],
"transactionHash": "0xfaf727afe431a920448636b80864dfeeef690903756f9c3041eb625ffcc82f11",
"transactionIndex": 0,
},
]
`)
})
})
import { ethers } from 'ethers'
import { Address } from 'wagmi'
import { ATTESTATION_STATION_ADDRESS } from '../constants/attestationStationAddress'
import { abi } from '../lib/abi'
import { AttestationCreatedEvent } from '../types/AttestationCreatedEvent'
import { encodeRawKey } from './encodeRawKey'
export const getEvents = async ({
creator = null,
about = null,
key = null,
value = null,
provider,
fromBlockOrBlockhash,
toBlock,
}: {
creator?: Address | null
about?: Address | null
key?: string | null
value?: string | null
provider: ethers.providers.JsonRpcProvider
fromBlockOrBlockhash?: ethers.providers.BlockTag | undefined
toBlock?: ethers.providers.BlockTag | undefined
}) => {
const contract = new ethers.Contract(
ATTESTATION_STATION_ADDRESS,
abi,
provider
)
return contract.queryFilter(
contract.filters.AttestationCreated(
creator,
about,
key && encodeRawKey(key),
value
),
fromBlockOrBlockhash,
toBlock
) as Promise<AttestationCreatedEvent[]>
}
...@@ -3,7 +3,13 @@ import { toUtf8Bytes } from 'ethers/lib/utils.js' ...@@ -3,7 +3,13 @@ import { toUtf8Bytes } from 'ethers/lib/utils.js'
import { expect, describe, it } from 'vitest' import { expect, describe, it } from 'vitest'
import { WagmiBytes } from '../types/WagmiBytes' import { WagmiBytes } from '../types/WagmiBytes'
import { parseAttestationBytes } from './parseAttestationBytes' import {
parseNumber,
parseAddress,
parseBool,
parseString,
parseAttestationBytes,
} from './parseAttestationBytes'
describe(parseAttestationBytes.name, () => { describe(parseAttestationBytes.name, () => {
it('works for strings', () => { it('works for strings', () => {
...@@ -15,7 +21,12 @@ describe(parseAttestationBytes.name, () => { ...@@ -15,7 +21,12 @@ describe(parseAttestationBytes.name, () => {
it('works for numbers', () => { it('works for numbers', () => {
const num = 123 const num = 123
const bytes = BigNumber.from(num).toHexString() as WagmiBytes const bytes = BigNumber.from(num).toHexString() as WagmiBytes
expect(parseAttestationBytes(bytes, 'number')).toBe(num.toString()) expect(parseAttestationBytes(bytes, 'number')).toMatchInlineSnapshot(`
{
"hex": "0x7b",
"type": "BigNumber",
}
`)
}) })
it('works for addresses', () => { it('works for addresses', () => {
...@@ -26,12 +37,15 @@ describe(parseAttestationBytes.name, () => { ...@@ -26,12 +37,15 @@ describe(parseAttestationBytes.name, () => {
it('works for booleans', () => { it('works for booleans', () => {
const bytes = BigNumber.from(1).toHexString() as WagmiBytes const bytes = BigNumber.from(1).toHexString() as WagmiBytes
expect(parseAttestationBytes(bytes, 'bool')).toBe('true') expect(parseAttestationBytes(bytes, 'bool')).toBe(true)
}) })
it('should work for raw bytes', () => { it('should work for raw bytes', () => {
const bytes = '0x420' expect(parseAttestationBytes('0x420', 'bytes')).toMatchInlineSnapshot(
expect(parseAttestationBytes(bytes, 'bytes')).toBe(bytes) '"0x420"'
)
expect(parseAttestationBytes('0x', 'string')).toMatchInlineSnapshot('""')
expect(parseAttestationBytes('0x0', 'string')).toMatchInlineSnapshot('""')
}) })
it('should return raw bytes for invalid type', () => { it('should return raw bytes for invalid type', () => {
...@@ -40,3 +54,35 @@ describe(parseAttestationBytes.name, () => { ...@@ -40,3 +54,35 @@ describe(parseAttestationBytes.name, () => {
expect(parseAttestationBytes(bytes, 'foo')).toBe(bytes) expect(parseAttestationBytes(bytes, 'foo')).toBe(bytes)
}) })
}) })
describe('parseFoo', () => {
it('works for strings', () => {
const str = 'Hello World'
const bytes = BigNumber.from(toUtf8Bytes(str)).toHexString() as WagmiBytes
expect(parseString(bytes)).toBe(str)
expect(parseString('0x')).toMatchInlineSnapshot('""')
expect(parseString('0x0')).toMatchInlineSnapshot('""')
expect(parseString('0x0')).toMatchInlineSnapshot('""')
})
it('works for numbers', () => {
const num = 123
const bytes = BigNumber.from(num).toHexString() as WagmiBytes
expect(parseNumber(bytes)).toEqual(BigNumber.from(num))
expect(parseNumber('0x')).toEqual(BigNumber.from(0))
})
it('works for addresses', () => {
const addr = '0x1234567890123456789012345678901234567890'
const bytes = BigNumber.from(addr).toHexString() as WagmiBytes
expect(parseAddress(bytes)).toBe(addr)
})
it('works for booleans', () => {
const bytes = BigNumber.from(1).toHexString() as WagmiBytes
expect(parseBool(bytes)).toBe(true)
expect(parseBool('0x')).toBe(false)
expect(parseBool('0x0')).toBe(false)
expect(parseBool('0x00000')).toBe(false)
})
})
import { BigNumber } from 'ethers' import { BigNumber } from 'ethers'
import { toUtf8String } from 'ethers/lib/utils.js' import { toUtf8String } from 'ethers/lib/utils.js'
import type { Address } from '@wagmi/core'
import type { DataTypeOption } from '../types/DataTypeOption' import type { DataTypeOption } from '../types/DataTypeOption'
import type { WagmiBytes } from '../types/WagmiBytes' import type { WagmiBytes } from '../types/WagmiBytes'
import { ParseBytesReturn } from '../types/ParseBytesReturn'
export const parseAttestationBytes = ( /**
* Parses a string attestion
*/
export const parseString = (rawAttestation: WagmiBytes): string => {
rawAttestation = rawAttestation === '0x0' ? '0x' : rawAttestation
return rawAttestation ? toUtf8String(rawAttestation) : ''
}
/**
* Parses a boolean attestion
*/
export const parseBool = (rawAttestation: WagmiBytes): boolean => {
rawAttestation = rawAttestation === '0x' ? '0x0' : rawAttestation
return rawAttestation ? BigNumber.from(rawAttestation).gt(0) : false
}
/**
* Parses a number attestion
*/
export const parseNumber = (rawAttestation: WagmiBytes): BigNumber => {
rawAttestation = rawAttestation === '0x' ? '0x0' : rawAttestation
return rawAttestation ? BigNumber.from(rawAttestation) : BigNumber.from(0)
}
/**
* Parses a address attestion
*/
export const parseAddress = (rawAttestation: WagmiBytes): Address => {
rawAttestation = rawAttestation === '0x' ? '0x0' : rawAttestation
return rawAttestation
? (BigNumber.from(rawAttestation).toHexString() as Address)
: '0x0000000000000000000000000000000000000000'
}
/**
* Parses a raw attestation
*/
export const parseAttestationBytes = <TDataType extends DataTypeOption>(
attestationBytes: WagmiBytes, attestationBytes: WagmiBytes,
dataType: DataTypeOption dataType: TDataType
) => { ): ParseBytesReturn<TDataType> => {
if (dataType === 'bytes') { if (dataType === 'bytes') {
return attestationBytes return attestationBytes as ParseBytesReturn<TDataType>
} }
if (dataType === 'number') { if (dataType === 'number') {
return BigNumber.from(attestationBytes).toString() return parseNumber(attestationBytes) as ParseBytesReturn<TDataType>
} }
if (dataType === 'address') { if (dataType === 'address') {
return BigNumber.from(attestationBytes).toHexString() return parseAddress(attestationBytes) as ParseBytesReturn<TDataType>
} }
if (dataType === 'bool') { if (dataType === 'bool') {
return BigNumber.from(attestationBytes).gt(0) ? 'true' : 'false' return parseBool(attestationBytes) as ParseBytesReturn<TDataType>
} }
if (dataType === 'string') { if (dataType === 'string') {
return attestationBytes && toUtf8String(attestationBytes) return parseString(attestationBytes) as ParseBytesReturn<TDataType>
} }
console.warn(`unrecognized dataType ${dataType satisfies never}`) console.warn(`unrecognized dataType ${dataType satisfies never}`)
return attestationBytes return attestationBytes as never
} }
...@@ -13,7 +13,15 @@ export const prepareWriteAttestation = async ( ...@@ -13,7 +13,15 @@ export const prepareWriteAttestation = async (
chainId = 10, chainId = 10,
contractAddress: Address = ATTESTATION_STATION_ADDRESS contractAddress: Address = ATTESTATION_STATION_ADDRESS
) => { ) => {
const formattedKey = formatBytes32String(key) as WagmiBytes let formattedKey: WagmiBytes
try {
formattedKey = formatBytes32String(key) as WagmiBytes
} catch (e) {
console.error(e)
throw new Error(
`key is longer than 32 bytes: ${key}. Try using a shorter key or using 'encodeRawKey' to encode the key into 32 bytes first`
)
}
return prepareWriteContract({ return prepareWriteContract({
address: contractAddress, address: contractAddress,
abi, abi,
......
...@@ -18,7 +18,15 @@ export const prepareWriteAttestations = async ( ...@@ -18,7 +18,15 @@ export const prepareWriteAttestations = async (
contractAddress: Address = ATTESTATION_STATION_ADDRESS contractAddress: Address = ATTESTATION_STATION_ADDRESS
) => { ) => {
const formattedAttestations = attestations.map((attestation) => { const formattedAttestations = attestations.map((attestation) => {
const formattedKey = formatBytes32String(attestation.key) as WagmiBytes let formattedKey: WagmiBytes
try {
formattedKey = formatBytes32String(attestation.key) as WagmiBytes
} catch (e) {
console.error(e)
throw new Error(
`key is longer than 32 bytes: ${attestation.key}. Try using a shorter key or using 'encodeRawKey' to encode the key into 32 bytes first`
)
}
const formattedValue = stringifyAttestationBytes( const formattedValue = stringifyAttestationBytes(
attestation.value attestation.value
) as WagmiBytes ) as WagmiBytes
......
import type { Address } from '@wagmi/core' import type { Address } from '@wagmi/core'
import { BigNumber } from 'ethers'
import { DataTypeOption, DEFAULT_DATA_TYPE } from '../types/DataTypeOption' import { DataTypeOption } from '../types/DataTypeOption'
import { ParseBytesReturn } from '../types/ParseBytesReturn'
import { readAttestations } from './readAttestations' import { readAttestations } from './readAttestations'
/** /**
...@@ -17,19 +19,166 @@ import { readAttestations } from './readAttestations' ...@@ -17,19 +19,166 @@ import { readAttestations } from './readAttestations'
* key: 'my_key', * key: 'my_key',
* }, * },
*/ */
export const readAttestation = async ( export const readAttestation = async <TDataType extends DataTypeOption>(
/**
* Creator of the attestation
*/
creator: Address, creator: Address,
/**
* Address the attestation is about
*/
about: Address, about: Address,
/**
* Key of the attestation
*/
key: string, key: string,
dataType: DataTypeOption = DEFAULT_DATA_TYPE, /**
* Data type of the attestation
* string | bool | number | address | bytes
*
* @defaults 'string'
*/
dataType: TDataType,
/**
* Attestation address
* defaults to the official Optimism attestation station determistic deploy address
*
* @defaults '0xEE36eaaD94d1Cc1d0eccaDb55C38bFfB6Be06C77'
*/
contractAddress: Address = '0xEE36eaaD94d1Cc1d0eccaDb55C38bFfB6Be06C77' contractAddress: Address = '0xEE36eaaD94d1Cc1d0eccaDb55C38bFfB6Be06C77'
) => { ): Promise<ParseBytesReturn<TDataType>> => {
const [result] = await readAttestations({ const [result] = await readAttestations({
creator, creator,
about, about,
key, key,
dataType,
contractAddress, contractAddress,
dataType,
}) })
return result return result as ParseBytesReturn<TDataType>
}
/**
* Reads a string attestation
*/
export const readAttestationString = (
/**
* Creator of the attestation
*/
creator: Address,
/**
* Address the attestation is about
*/
about: Address,
/**
* Key of the attestation
*/
key: string,
/**
* Attestation address
* defaults to the official Optimism attestation station determistic deploy address
*
* @defaults '0xEE36eaaD94d1Cc1d0eccaDb55C38bFfB6Be06C77'
*/
contractAddress: Address = '0xEE36eaaD94d1Cc1d0eccaDb55C38bFfB6Be06C77'
) => {
return readAttestation(
creator,
about,
key,
'string',
contractAddress
) as Promise<string>
}
export const readAttestationBool = (
/**
* Creator of the attestation
*/
creator: Address,
/**
* Address the attestation is about
*/
about: Address,
/**
* Key of the attestation
*/
key: string,
/**
* Attestation address
* defaults to the official Optimism attestation station determistic deploy address
*
* @defaults '0xEE36eaaD94d1Cc1d0eccaDb55C38bFfB6Be06C77'
*/
contractAddress: Address = '0xEE36eaaD94d1Cc1d0eccaDb55C38bFfB6Be06C77'
) => {
return readAttestation(
/**
* Creator of the attestation
*/
creator,
about,
key,
'bool',
contractAddress
) as Promise<boolean>
}
export const readAttestationNumber = (
/**
* Creator of the attestation
*/
creator: Address,
/**
* Address the attestation is about
*/
about: Address,
/**
* Key of the attestation
*/
key: string,
/**
* Attestation address
* defaults to the official Optimism attestation station determistic deploy address
*
* @defaults '0xEE36eaaD94d1Cc1d0eccaDb55C38bFfB6Be06C77'
*/
contractAddress: Address = '0xEE36eaaD94d1Cc1d0eccaDb55C38bFfB6Be06C77'
) => {
return readAttestation(
creator,
about,
key,
'number',
contractAddress
) as Promise<BigNumber>
}
export const readAttestationAddress = (
/**
* Creator of the attestation
*/
creator: Address,
/**
* Address the attestation is about
*/
about: Address,
/**
* Key of the attestation
*/
key: string,
/**
* Attestation address
* defaults to the official Optimism attestation station determistic deploy address
*
* @defaults '0xEE36eaaD94d1Cc1d0eccaDb55C38bFfB6Be06C77'
*/
contractAddress: Address = '0xEE36eaaD94d1Cc1d0eccaDb55C38bFfB6Be06C77'
) => {
return readAttestation(
creator,
about,
key,
'address',
contractAddress
) as Promise<Address>
} }
...@@ -52,9 +52,12 @@ describe(readAttestation.name, () => { ...@@ -52,9 +52,12 @@ describe(readAttestation.name, () => {
` `
[ [
"https://assets.optimism.io/4a609661-6774-441f-9fdb-453fdbb89931-bucket/optimist-nft/attributes", "https://assets.optimism.io/4a609661-6774-441f-9fdb-453fdbb89931-bucket/optimist-nft/attributes",
"true", true,
"0x68747470733a2f2f6173736574732e6f7074696d69736d2e696f2f34613630393636312d363737342d343431662d396664622d3435336664626238393933312d6275636b65742f6f7074696d6973742d6e66742f61747472696275746573", "0x68747470733a2f2f6173736574732e6f7074696d69736d2e696f2f34613630393636312d363737342d343431662d396664622d3435336664626238393933312d6275636b65742f6f7074696d6973742d6e66742f61747472696275746573",
"9665973469795080068873111198635018086067645613429821071805084917303478255842407465257371959707311987533859075426222329066766033171696373249109388415320911537042272090516917683029511016473045453921068327933733922308146003731827", {
"hex": "0x68747470733a2f2f6173736574732e6f7074696d69736d2e696f2f34613630393636312d363737342d343431662d396664622d3435336664626238393933312d6275636b65742f6f7074696d6973742d6e66742f61747472696275746573",
"type": "BigNumber",
},
] ]
` `
) )
......
import { Address } from '@wagmi/core' import { Address } from '@wagmi/core'
import { BigNumber } from 'ethers' import { BigNumber } from 'ethers'
import { isAddress, isHexString, toUtf8Bytes } from 'ethers/lib/utils.js' import {
hexlify,
isAddress,
isHexString,
toUtf8Bytes,
} from 'ethers/lib/utils.js'
import { WagmiBytes } from '../types/WagmiBytes' import { WagmiBytes } from '../types/WagmiBytes'
export const stringifyAttestationBytes = ( export const stringifyAttestationBytes = (
bytes: WagmiBytes | string | Address | number | boolean | BigNumber bytes: WagmiBytes | string | Address | number | boolean | BigNumber
) => { ): WagmiBytes => {
bytes = bytes === '0x' ? '0x0' : bytes bytes = bytes === '0x' ? '0x0' : bytes
if (BigNumber.isBigNumber(bytes)) { if (BigNumber.isBigNumber(bytes)) {
return bytes.toHexString() return bytes.toHexString() as WagmiBytes
} }
if (typeof bytes === 'number') { if (typeof bytes === 'number') {
return BigNumber.from(bytes).toHexString() return BigNumber.from(bytes).toHexString() as WagmiBytes
} }
if (typeof bytes === 'boolean') { if (typeof bytes === 'boolean') {
return bytes ? '0x1' : '0x0' return bytes ? '0x1' : '0x0'
...@@ -21,10 +26,10 @@ export const stringifyAttestationBytes = ( ...@@ -21,10 +26,10 @@ export const stringifyAttestationBytes = (
return bytes return bytes
} }
if (isHexString(bytes)) { if (isHexString(bytes)) {
return bytes return bytes as WagmiBytes
} }
if (typeof bytes === 'string') { if (typeof bytes === 'string') {
return toUtf8Bytes(bytes) return hexlify(toUtf8Bytes(bytes)) as WagmiBytes
} }
throw new Error(`unrecognized bytes type ${bytes satisfies never}`) throw new Error(`unrecognized bytes type ${bytes satisfies never}`)
} }
/* eslint-disable prefer-arrow/prefer-arrow-functions */
// Generated by @wagmi/cli@0.1.10 on 2/26/2023 at 11:08:05 AM // Generated by @wagmi/cli@0.1.10 on 2/26/2023 at 11:08:05 AM
import { import {
useNetwork, useNetwork,
...@@ -177,11 +178,7 @@ export function useAttestationStationRead< ...@@ -177,11 +178,7 @@ export function useAttestationStationRead<
chainId as keyof typeof attestationStationAddress chainId as keyof typeof attestationStationAddress
], ],
...config, ...config,
} as UseContractReadConfig< } as UseContractReadConfig<typeof attestationStationABI, TFunctionName, TSelectData>)
typeof attestationStationABI,
TFunctionName,
TSelectData
>)
} }
/** /**
...@@ -213,11 +210,7 @@ export function useAttestationStationAttestations< ...@@ -213,11 +210,7 @@ export function useAttestationStationAttestations<
], ],
functionName: 'attestations', functionName: 'attestations',
...config, ...config,
} as UseContractReadConfig< } as UseContractReadConfig<typeof attestationStationABI, 'attestations', TSelectData>)
typeof attestationStationABI,
'attestations',
TSelectData
>)
} }
/** /**
...@@ -245,11 +238,7 @@ export function useAttestationStationVersion< ...@@ -245,11 +238,7 @@ export function useAttestationStationVersion<
], ],
functionName: 'version', functionName: 'version',
...config, ...config,
} as UseContractReadConfig< } as UseContractReadConfig<typeof attestationStationABI, 'version', TSelectData>)
typeof attestationStationABI,
'version',
TSelectData
>)
} }
/** /**
...@@ -358,10 +347,7 @@ export function usePrepareAttestationStationWrite<TFunctionName extends string>( ...@@ -358,10 +347,7 @@ export function usePrepareAttestationStationWrite<TFunctionName extends string>(
chainId as keyof typeof attestationStationAddress chainId as keyof typeof attestationStationAddress
], ],
...config, ...config,
} as UsePrepareContractWriteConfig< } as UsePrepareContractWriteConfig<typeof attestationStationABI, TFunctionName>)
typeof attestationStationABI,
TFunctionName
>)
} }
/** /**
...@@ -438,8 +424,5 @@ export function useAttestationStationAttestationCreatedEvent( ...@@ -438,8 +424,5 @@ export function useAttestationStationAttestationCreatedEvent(
], ],
eventName: 'AttestationCreated', eventName: 'AttestationCreated',
...config, ...config,
} as UseContractEventConfig< } as UseContractEventConfig<typeof attestationStationABI, 'AttestationCreated'>)
typeof attestationStationABI,
'AttestationCreated'
>)
} }
import type { Event } from 'ethers'
interface TypedEvent<TArgsArray extends Array<any> = any, TArgsObject = any>
extends Event {
args: TArgsArray & TArgsObject
}
export interface AttestationCreatedEventObject {
creator: string
about: string
key: string
val: string
}
export type AttestationCreatedEvent = TypedEvent<
[string, string, string, string],
AttestationCreatedEventObject
>
import { BigNumber } from 'ethers'
import { Address } from 'wagmi'
import { DataTypeOption } from './DataTypeOption'
import { WagmiBytes } from './WagmiBytes'
/**
* @internal
* Returns the correct typescript type of a DataOption
*/
export type ParseBytesReturn<T extends DataTypeOption> = T extends 'bytes'
? WagmiBytes
: T extends 'number'
? BigNumber
: T extends 'address'
? Address
: T extends 'bool'
? boolean
: T extends 'string'
? string
: never
import { defineConfig } from '@wagmi/cli' import { defineConfig } from '@wagmi/cli'
import { hardhat, react } from '@wagmi/cli/plugins' import { hardhat, react } from '@wagmi/cli/plugins'
import * as chains from 'wagmi/chains' import * as chains from 'wagmi/chains'
import {ATTESTATION_STATION_ADDRESS} from '@eth-optimism/atst'
export const ATTESTATION_STATION_ADDRESS =
'0xEE36eaaD94d1Cc1d0eccaDb55C38bFfB6Be06C77'
export default defineConfig({ export default defineConfig({
out: 'src/react.ts', out: 'src/react.ts',
...@@ -14,7 +16,7 @@ export default defineConfig({ ...@@ -14,7 +16,7 @@ export default defineConfig({
[chains.optimism.id]: ATTESTATION_STATION_ADDRESS, [chains.optimism.id]: ATTESTATION_STATION_ADDRESS,
[chains.optimismGoerli.id]: ATTESTATION_STATION_ADDRESS, [chains.optimismGoerli.id]: ATTESTATION_STATION_ADDRESS,
[chains.foundry.id]: ATTESTATION_STATION_ADDRESS, [chains.foundry.id]: ATTESTATION_STATION_ADDRESS,
} },
}, },
}), }),
react(), react(),
......
# @eth-optimism/drippie-mon # @eth-optimism/drippie-mon
## 0.2.0
### Minor Changes
- 282bda091: Added a withdrawal monitoring service
### Patch Changes
- Updated dependencies [cb19e2f9c]
- @eth-optimism/sdk@2.0.0
## 0.1.3 ## 0.1.3
### Patch Changes ### Patch Changes
......
{ {
"private": true, "private": true,
"name": "@eth-optimism/chain-mon", "name": "@eth-optimism/chain-mon",
"version": "0.1.3", "version": "0.2.0",
"description": "[Optimism] Chain monitoring services", "description": "[Optimism] Chain monitoring services",
"main": "dist/index", "main": "dist/index",
"types": "dist/index", "types": "dist/index",
...@@ -35,7 +35,7 @@ ...@@ -35,7 +35,7 @@
"@eth-optimism/common-ts": "0.8.0", "@eth-optimism/common-ts": "0.8.0",
"@eth-optimism/contracts-periphery": "1.0.7", "@eth-optimism/contracts-periphery": "1.0.7",
"@eth-optimism/core-utils": "0.12.0", "@eth-optimism/core-utils": "0.12.0",
"@eth-optimism/sdk": "1.10.4", "@eth-optimism/sdk": "2.0.0",
"ethers": "^5.7.0", "ethers": "^5.7.0",
"@types/dateformat": "^5.0.0", "@types/dateformat": "^5.0.0",
"chai-as-promised": "^7.1.1", "chai-as-promised": "^7.1.1",
......
...@@ -22,23 +22,23 @@ CrossDomainOwnable3_Test:test_transferOwnershipNoLocal_succeeds() (gas: 48610) ...@@ -22,23 +22,23 @@ CrossDomainOwnable3_Test:test_transferOwnershipNoLocal_succeeds() (gas: 48610)
CrossDomainOwnable3_Test:test_transferOwnership_noLocalZeroAddress_reverts() (gas: 12015) CrossDomainOwnable3_Test:test_transferOwnership_noLocalZeroAddress_reverts() (gas: 12015)
CrossDomainOwnable3_Test:test_transferOwnership_notOwner_reverts() (gas: 13437) CrossDomainOwnable3_Test:test_transferOwnership_notOwner_reverts() (gas: 13437)
CrossDomainOwnable3_Test:test_transferOwnership_zeroAddress_reverts() (gas: 12081) CrossDomainOwnable3_Test:test_transferOwnership_zeroAddress_reverts() (gas: 12081)
CrossDomainOwnableThroughPortal_Test:test_depositTransaction_crossDomainOwner_succeeds() (gas: 72494) CrossDomainOwnableThroughPortal_Test:test_depositTransaction_crossDomainOwner_succeeds() (gas: 72504)
CrossDomainOwnable_Test:test_onlyOwner_notOwner_reverts() (gas: 10597) CrossDomainOwnable_Test:test_onlyOwner_notOwner_reverts() (gas: 10597)
CrossDomainOwnable_Test:test_onlyOwner_succeeds() (gas: 34883) CrossDomainOwnable_Test:test_onlyOwner_succeeds() (gas: 34883)
DeployerWhitelist_Test:test_owner_succeeds() (gas: 7582) DeployerWhitelist_Test:test_owner_succeeds() (gas: 7582)
DeployerWhitelist_Test:test_storageSlots_succeeds() (gas: 33395) DeployerWhitelist_Test:test_storageSlots_succeeds() (gas: 33395)
FeeVault_Test:test_constructor_succeeds() (gas: 10736) FeeVault_Test:test_constructor_succeeds() (gas: 10736)
FeeVault_Test:test_minWithdrawalAmount_succeeds() (gas: 10713) FeeVault_Test:test_minWithdrawalAmount_succeeds() (gas: 10713)
GasBenchMark_L1CrossDomainMessenger:test_sendMessage_benchmark_0() (gas: 261340) GasBenchMark_L1CrossDomainMessenger:test_sendMessage_benchmark_0() (gas: 261350)
GasBenchMark_L1CrossDomainMessenger:test_sendMessage_benchmark_1() (gas: 76067) GasBenchMark_L1CrossDomainMessenger:test_sendMessage_benchmark_1() (gas: 76077)
GasBenchMark_L1StandardBridge_Deposit:test_depositERC20_benchmark_0() (gas: 348292) GasBenchMark_L1StandardBridge_Deposit:test_depositERC20_benchmark_0() (gas: 348302)
GasBenchMark_L1StandardBridge_Deposit:test_depositERC20_benchmark_1() (gas: 112945) GasBenchMark_L1StandardBridge_Deposit:test_depositERC20_benchmark_1() (gas: 112955)
GasBenchMark_L1StandardBridge_Deposit:test_depositETH_benchmark_0() (gas: 348314) GasBenchMark_L1StandardBridge_Deposit:test_depositETH_benchmark_0() (gas: 348324)
GasBenchMark_L1StandardBridge_Deposit:test_depositETH_benchmark_1() (gas: 112965) GasBenchMark_L1StandardBridge_Deposit:test_depositETH_benchmark_1() (gas: 112975)
GasBenchMark_L1StandardBridge_Finalize:test_finalizeETHWithdrawal_benchmark() (gas: 40409) GasBenchMark_L1StandardBridge_Finalize:test_finalizeETHWithdrawal_benchmark() (gas: 40409)
GasBenchMark_L2OutputOracle:test_proposeL2Output_benchmark() (gas: 88535) GasBenchMark_L2OutputOracle:test_proposeL2Output_benchmark() (gas: 88513)
GasBenchMark_OptimismPortal:test_depositTransaction_benchmark() (gas: 75075) GasBenchMark_OptimismPortal:test_depositTransaction_benchmark() (gas: 75085)
GasBenchMark_OptimismPortal:test_depositTransaction_benchmark_1() (gas: 36386) GasBenchMark_OptimismPortal:test_depositTransaction_benchmark_1() (gas: 36396)
GasBenchMark_OptimismPortal:test_proveWithdrawalTransaction_benchmark() (gas: 169229) GasBenchMark_OptimismPortal:test_proveWithdrawalTransaction_benchmark() (gas: 169229)
GasPriceOracle_Test:test_baseFee_succeeds() (gas: 8325) GasPriceOracle_Test:test_baseFee_succeeds() (gas: 8325)
GasPriceOracle_Test:test_decimals_succeeds() (gas: 6167) GasPriceOracle_Test:test_decimals_succeeds() (gas: 6167)
...@@ -70,43 +70,43 @@ L1BlockTest:test_timestamp_succeeds() (gas: 7640) ...@@ -70,43 +70,43 @@ L1BlockTest:test_timestamp_succeeds() (gas: 7640)
L1BlockTest:test_updateValues_succeeds() (gas: 60482) L1BlockTest:test_updateValues_succeeds() (gas: 60482)
L1CrossDomainMessenger_Test:test_messageVersion_succeeds() (gas: 24715) L1CrossDomainMessenger_Test:test_messageVersion_succeeds() (gas: 24715)
L1CrossDomainMessenger_Test:test_relayMessage_legacyOldReplay_reverts() (gas: 49394) L1CrossDomainMessenger_Test:test_relayMessage_legacyOldReplay_reverts() (gas: 49394)
L1CrossDomainMessenger_Test:test_relayMessage_legacyRetryAfterFailureThenSuccess_reverts() (gas: 228293) L1CrossDomainMessenger_Test:test_relayMessage_legacyRetryAfterFailureThenSuccess_reverts() (gas: 228315)
L1CrossDomainMessenger_Test:test_relayMessage_legacyRetryAfterFailure_succeeds() (gas: 201787) L1CrossDomainMessenger_Test:test_relayMessage_legacyRetryAfterFailure_succeeds() (gas: 201809)
L1CrossDomainMessenger_Test:test_relayMessage_legacyRetryAfterSuccess_reverts() (gas: 141987) L1CrossDomainMessenger_Test:test_relayMessage_legacyRetryAfterSuccess_reverts() (gas: 142009)
L1CrossDomainMessenger_Test:test_relayMessage_legacy_succeeds() (gas: 74897) L1CrossDomainMessenger_Test:test_relayMessage_legacy_succeeds() (gas: 74919)
L1CrossDomainMessenger_Test:test_relayMessage_reentrancyDiffMessage_succeeds() (gas: 720517) L1CrossDomainMessenger_Test:test_relayMessage_reentrancyDiffMessage_succeeds() (gas: 720561)
L1CrossDomainMessenger_Test:test_relayMessage_reentrancySameMessage_reverts() (gas: 657639) L1CrossDomainMessenger_Test:test_relayMessage_reentrancySameMessage_reverts() (gas: 657661)
L1CrossDomainMessenger_Test:test_relayMessage_retryAfterFailure_succeeds() (gas: 195694) L1CrossDomainMessenger_Test:test_relayMessage_retryAfterFailure_succeeds() (gas: 195716)
L1CrossDomainMessenger_Test:test_relayMessage_succeeds() (gas: 71833) L1CrossDomainMessenger_Test:test_relayMessage_succeeds() (gas: 71855)
L1CrossDomainMessenger_Test:test_relayMessage_toSystemContract_reverts() (gas: 96277) L1CrossDomainMessenger_Test:test_relayMessage_toSystemContract_reverts() (gas: 96299)
L1CrossDomainMessenger_Test:test_relayMessage_v2_reverts() (gas: 12365) L1CrossDomainMessenger_Test:test_relayMessage_v2_reverts() (gas: 12365)
L1CrossDomainMessenger_Test:test_replayMessage_withValue_reverts() (gas: 53445) L1CrossDomainMessenger_Test:test_replayMessage_withValue_reverts() (gas: 53445)
L1CrossDomainMessenger_Test:test_sendMessage_succeeds() (gas: 299694) L1CrossDomainMessenger_Test:test_sendMessage_succeeds() (gas: 299704)
L1CrossDomainMessenger_Test:test_sendMessage_twice_succeeds() (gas: 1490560) L1CrossDomainMessenger_Test:test_sendMessage_twice_succeeds() (gas: 1490580)
L1CrossDomainMessenger_Test:test_xDomainMessageSender_reset_succeeds() (gas: 82362) L1CrossDomainMessenger_Test:test_xDomainMessageSender_reset_succeeds() (gas: 82384)
L1CrossDomainMessenger_Test:test_xDomainSender_notSet_reverts() (gas: 24296) L1CrossDomainMessenger_Test:test_xDomainSender_notSet_reverts() (gas: 24296)
L1ERC721Bridge_Test:test_bridgeERC721To_localTokenZeroAddress_reverts() (gas: 52707) L1ERC721Bridge_Test:test_bridgeERC721To_localTokenZeroAddress_reverts() (gas: 52707)
L1ERC721Bridge_Test:test_bridgeERC721To_remoteTokenZeroAddress_reverts() (gas: 27310) L1ERC721Bridge_Test:test_bridgeERC721To_remoteTokenZeroAddress_reverts() (gas: 27310)
L1ERC721Bridge_Test:test_bridgeERC721To_succeeds() (gas: 354740) L1ERC721Bridge_Test:test_bridgeERC721To_succeeds() (gas: 354750)
L1ERC721Bridge_Test:test_bridgeERC721To_wrongOwner_reverts() (gas: 60934) L1ERC721Bridge_Test:test_bridgeERC721To_wrongOwner_reverts() (gas: 60934)
L1ERC721Bridge_Test:test_bridgeERC721_fromContract_reverts() (gas: 25666) L1ERC721Bridge_Test:test_bridgeERC721_fromContract_reverts() (gas: 25666)
L1ERC721Bridge_Test:test_bridgeERC721_localTokenZeroAddress_reverts() (gas: 50564) L1ERC721Bridge_Test:test_bridgeERC721_localTokenZeroAddress_reverts() (gas: 50564)
L1ERC721Bridge_Test:test_bridgeERC721_remoteTokenZeroAddress_reverts() (gas: 25124) L1ERC721Bridge_Test:test_bridgeERC721_remoteTokenZeroAddress_reverts() (gas: 25124)
L1ERC721Bridge_Test:test_bridgeERC721_succeeds() (gas: 352320) L1ERC721Bridge_Test:test_bridgeERC721_succeeds() (gas: 352330)
L1ERC721Bridge_Test:test_bridgeERC721_wrongOwner_reverts() (gas: 60830) L1ERC721Bridge_Test:test_bridgeERC721_wrongOwner_reverts() (gas: 60830)
L1ERC721Bridge_Test:test_constructor_succeeds() (gas: 10200) L1ERC721Bridge_Test:test_constructor_succeeds() (gas: 10200)
L1ERC721Bridge_Test:test_finalizeBridgeERC721_notEscrowed_reverts() (gas: 22119) L1ERC721Bridge_Test:test_finalizeBridgeERC721_notEscrowed_reverts() (gas: 22119)
L1ERC721Bridge_Test:test_finalizeBridgeERC721_notFromRemoteMessenger_reverts() (gas: 19797) L1ERC721Bridge_Test:test_finalizeBridgeERC721_notFromRemoteMessenger_reverts() (gas: 19797)
L1ERC721Bridge_Test:test_finalizeBridgeERC721_notViaLocalMessenger_reverts() (gas: 16049) L1ERC721Bridge_Test:test_finalizeBridgeERC721_notViaLocalMessenger_reverts() (gas: 16049)
L1ERC721Bridge_Test:test_finalizeBridgeERC721_selfToken_reverts() (gas: 17615) L1ERC721Bridge_Test:test_finalizeBridgeERC721_selfToken_reverts() (gas: 17615)
L1ERC721Bridge_Test:test_finalizeBridgeERC721_succeeds() (gas: 323832) L1ERC721Bridge_Test:test_finalizeBridgeERC721_succeeds() (gas: 323842)
L1StandardBridge_BridgeETHTo_Test:test_bridgeETHTo_succeeds() (gas: 419582) L1StandardBridge_BridgeETHTo_Test:test_bridgeETHTo_succeeds() (gas: 419592)
L1StandardBridge_BridgeETH_Test:test_bridgeETH_succeeds() (gas: 406803) L1StandardBridge_BridgeETH_Test:test_bridgeETH_succeeds() (gas: 406813)
L1StandardBridge_DepositERC20To_Test:test_depositERC20To_succeeds() (gas: 624879) L1StandardBridge_DepositERC20To_Test:test_depositERC20To_succeeds() (gas: 624889)
L1StandardBridge_DepositERC20_Test:test_depositERC20_succeeds() (gas: 622580) L1StandardBridge_DepositERC20_Test:test_depositERC20_succeeds() (gas: 622590)
L1StandardBridge_DepositERC20_TestFail:test_depositERC20_notEoa_reverts() (gas: 22320) L1StandardBridge_DepositERC20_TestFail:test_depositERC20_notEoa_reverts() (gas: 22320)
L1StandardBridge_DepositETHTo_Test:test_depositETHTo_succeeds() (gas: 419659) L1StandardBridge_DepositETHTo_Test:test_depositETHTo_succeeds() (gas: 419669)
L1StandardBridge_DepositETH_Test:test_depositETH_succeeds() (gas: 406897) L1StandardBridge_DepositETH_Test:test_depositETH_succeeds() (gas: 406907)
L1StandardBridge_DepositETH_TestFail:test_depositETH_notEoa_reverts() (gas: 40780) L1StandardBridge_DepositETH_TestFail:test_depositETH_notEoa_reverts() (gas: 40780)
L1StandardBridge_FinalizeBridgeETH_Test:test_finalizeBridgeETH_succeeds() (gas: 51674) L1StandardBridge_FinalizeBridgeETH_Test:test_finalizeBridgeETH_succeeds() (gas: 51674)
L1StandardBridge_FinalizeBridgeETH_TestFail:test_finalizeBridgeETH_incorrectValue_reverts() (gas: 34207) L1StandardBridge_FinalizeBridgeETH_TestFail:test_finalizeBridgeETH_incorrectValue_reverts() (gas: 34207)
...@@ -118,7 +118,7 @@ L1StandardBridge_FinalizeERC20Withdrawal_TestFail:test_finalizeERC20Withdrawal_n ...@@ -118,7 +118,7 @@ L1StandardBridge_FinalizeERC20Withdrawal_TestFail:test_finalizeERC20Withdrawal_n
L1StandardBridge_FinalizeETHWithdrawal_Test:test_finalizeETHWithdrawal_succeeds() (gas: 61722) L1StandardBridge_FinalizeETHWithdrawal_Test:test_finalizeETHWithdrawal_succeeds() (gas: 61722)
L1StandardBridge_Getter_Test:test_getters_succeeds() (gas: 32173) L1StandardBridge_Getter_Test:test_getters_succeeds() (gas: 32173)
L1StandardBridge_Initialize_Test:test_initialize_succeeds() (gas: 22050) L1StandardBridge_Initialize_Test:test_initialize_succeeds() (gas: 22050)
L1StandardBridge_Receive_Test:test_receive_succeeds() (gas: 520206) L1StandardBridge_Receive_Test:test_receive_succeeds() (gas: 520216)
L2CrossDomainMessenger_Test:test_messageVersion_succeeds() (gas: 8411) L2CrossDomainMessenger_Test:test_messageVersion_succeeds() (gas: 8411)
L2CrossDomainMessenger_Test:test_relayMessage_reentrancyDiffMessage_succeeds() (gas: 681087) L2CrossDomainMessenger_Test:test_relayMessage_reentrancyDiffMessage_succeeds() (gas: 681087)
L2CrossDomainMessenger_Test:test_relayMessage_reentrancySameMessage_reverts() (gas: 626802) L2CrossDomainMessenger_Test:test_relayMessage_reentrancySameMessage_reverts() (gas: 626802)
...@@ -145,33 +145,34 @@ L2ERC721Bridge_Test:test_finalizeBridgeERC721_notFromRemoteMessenger_reverts() ( ...@@ -145,33 +145,34 @@ L2ERC721Bridge_Test:test_finalizeBridgeERC721_notFromRemoteMessenger_reverts() (
L2ERC721Bridge_Test:test_finalizeBridgeERC721_notViaLocalMessenger_reverts() (gas: 16104) L2ERC721Bridge_Test:test_finalizeBridgeERC721_notViaLocalMessenger_reverts() (gas: 16104)
L2ERC721Bridge_Test:test_finalizeBridgeERC721_selfToken_reverts() (gas: 17659) L2ERC721Bridge_Test:test_finalizeBridgeERC721_selfToken_reverts() (gas: 17659)
L2ERC721Bridge_Test:test_finalizeBridgeERC721_succeeds() (gas: 168970) L2ERC721Bridge_Test:test_finalizeBridgeERC721_succeeds() (gas: 168970)
L2OutputOracleTest:test_computeL2Timestamp_succeeds() (gas: 37206) L2OutputOracleTest:test_computeL2Timestamp_succeeds() (gas: 37298)
L2OutputOracleTest:test_constructor_badTimestamp_reverts() (gas: 70812) L2OutputOracleTest:test_constructor_badTimestamp_reverts() (gas: 70947)
L2OutputOracleTest:test_constructor_l2BlockTimeZero_reverts() (gas: 45808) L2OutputOracleTest:test_constructor_l2BlockTimeZero_reverts() (gas: 45954)
L2OutputOracleTest:test_constructor_succeeds() (gas: 33695) L2OutputOracleTest:test_constructor_succeeds() (gas: 33827)
L2OutputOracleTest:test_deleteL2Outputs_afterLatest_reverts() (gas: 211900) L2OutputOracleTest:test_deleteL2Outputs_afterLatest_reverts() (gas: 212262)
L2OutputOracleTest:test_deleteL2Outputs_ifNotChallenger_reverts() (gas: 18894) L2OutputOracleTest:test_deleteL2Outputs_finalized_reverts() (gas: 108967)
L2OutputOracleTest:test_deleteL2Outputs_nonExistent_reverts() (gas: 107337) L2OutputOracleTest:test_deleteL2Outputs_ifNotChallenger_reverts() (gas: 18918)
L2OutputOracleTest:test_deleteOutputs_multipleOutputs_succeeds() (gas: 302143) L2OutputOracleTest:test_deleteL2Outputs_nonExistent_reverts() (gas: 107339)
L2OutputOracleTest:test_deleteOutputs_singleOutput_succeeds() (gas: 180722) L2OutputOracleTest:test_deleteOutputs_multipleOutputs_succeeds() (gas: 302439)
L2OutputOracleTest:test_getL2OutputIndexAfter_multipleOutputsExist_succeeds() (gas: 267204) L2OutputOracleTest:test_deleteOutputs_singleOutput_succeeds() (gas: 181038)
L2OutputOracleTest:test_getL2OutputIndexAfter_noOutputsExis_reverts() (gas: 17936) L2OutputOracleTest:test_getL2OutputIndexAfter_multipleOutputsExist_succeeds() (gas: 267120)
L2OutputOracleTest:test_getL2OutputIndexAfter_previousBlock_succeeds() (gas: 96064) L2OutputOracleTest:test_getL2OutputIndexAfter_noOutputsExis_reverts() (gas: 17959)
L2OutputOracleTest:test_getL2OutputIndexAfter_sameBlock_succeeds() (gas: 96038) L2OutputOracleTest:test_getL2OutputIndexAfter_previousBlock_succeeds() (gas: 96066)
L2OutputOracleTest:test_getL2Output_succeeds() (gas: 101721) L2OutputOracleTest:test_getL2OutputIndexAfter_sameBlock_succeeds() (gas: 95995)
L2OutputOracleTest:test_latestBlockNumber_succeeds() (gas: 96983) L2OutputOracleTest:test_getL2Output_succeeds() (gas: 101634)
L2OutputOracleTest:test_nextBlockNumber_succeeds() (gas: 17512) L2OutputOracleTest:test_latestBlockNumber_succeeds() (gas: 96962)
L2OutputOracleTest:test_proposeL2Output_emptyOutput_reverts() (gas: 26688) L2OutputOracleTest:test_nextBlockNumber_succeeds() (gas: 17490)
L2OutputOracleTest:test_proposeL2Output_futureTimetamp_reverts() (gas: 28646) L2OutputOracleTest:test_proposeL2Output_emptyOutput_reverts() (gas: 26690)
L2OutputOracleTest:test_proposeL2Output_notProposer_reverts() (gas: 25804) L2OutputOracleTest:test_proposeL2Output_futureTimetamp_reverts() (gas: 28669)
L2OutputOracleTest:test_proposeL2Output_proposeAnotherOutput_succeeds() (gas: 101071) L2OutputOracleTest:test_proposeL2Output_notProposer_reverts() (gas: 25783)
L2OutputOracleTest:test_proposeL2Output_unexpectedBlockNumber_reverts() (gas: 28402) L2OutputOracleTest:test_proposeL2Output_proposeAnotherOutput_succeeds() (gas: 101028)
L2OutputOracleTest:test_proposeL2Output_unmatchedBlockhash_reverts() (gas: 29424) L2OutputOracleTest:test_proposeL2Output_unexpectedBlockNumber_reverts() (gas: 28381)
L2OutputOracleTest:test_proposeL2Output_wrongFork_reverts() (gas: 29005) L2OutputOracleTest:test_proposeL2Output_unmatchedBlockhash_reverts() (gas: 29381)
L2OutputOracleTest:test_proposeWithBlockhashAndHeight_succeeds() (gas: 95274) L2OutputOracleTest:test_proposeL2Output_wrongFork_reverts() (gas: 28984)
L2OutputOracleUpgradeable_Test:test_initValuesOnProxy_succeeds() (gas: 26141) L2OutputOracleTest:test_proposeWithBlockhashAndHeight_succeeds() (gas: 95253)
L2OutputOracleUpgradeable_Test:test_initializeImpl_alreadyInitialized_reverts() (gas: 15171) L2OutputOracleUpgradeable_Test:test_initValuesOnProxy_succeeds() (gas: 26208)
L2OutputOracleUpgradeable_Test:test_initializeProxy_alreadyInitialized_reverts() (gas: 20197) L2OutputOracleUpgradeable_Test:test_initializeImpl_alreadyInitialized_reverts() (gas: 15149)
L2OutputOracleUpgradeable_Test:test_initializeProxy_alreadyInitialized_reverts() (gas: 20175)
L2OutputOracleUpgradeable_Test:test_upgrading_succeeds() (gas: 180481) L2OutputOracleUpgradeable_Test:test_upgrading_succeeds() (gas: 180481)
L2StandardBridge_BridgeERC20To_Test:test_bridgeERC20To_succeeds() (gas: 387833) L2StandardBridge_BridgeERC20To_Test:test_bridgeERC20To_succeeds() (gas: 387833)
L2StandardBridge_BridgeERC20To_Test:test_withdrawTo_withdrawingERC20_succeeds() (gas: 388064) L2StandardBridge_BridgeERC20To_Test:test_withdrawTo_withdrawingERC20_succeeds() (gas: 388064)
...@@ -255,48 +256,48 @@ OptimismMintableTokenFactory_Test:test_bridge_succeeds() (gas: 7580) ...@@ -255,48 +256,48 @@ OptimismMintableTokenFactory_Test:test_bridge_succeeds() (gas: 7580)
OptimismMintableTokenFactory_Test:test_createStandardL2Token_remoteIsZero_succeeds() (gas: 9390) OptimismMintableTokenFactory_Test:test_createStandardL2Token_remoteIsZero_succeeds() (gas: 9390)
OptimismMintableTokenFactory_Test:test_createStandardL2Token_sameTwice_succeeds() (gas: 2523203) OptimismMintableTokenFactory_Test:test_createStandardL2Token_sameTwice_succeeds() (gas: 2523203)
OptimismMintableTokenFactory_Test:test_createStandardL2Token_succeeds() (gas: 1268564) OptimismMintableTokenFactory_Test:test_createStandardL2Token_succeeds() (gas: 1268564)
OptimismPortalUpgradeable_Test:test_initialize_cannotInitImpl_reverts() (gas: 11016) OptimismPortalUpgradeable_Test:test_initialize_cannotInitImpl_reverts() (gas: 10971)
OptimismPortalUpgradeable_Test:test_initialize_cannotInitProxy_reverts() (gas: 15940) OptimismPortalUpgradeable_Test:test_initialize_cannotInitProxy_reverts() (gas: 15895)
OptimismPortalUpgradeable_Test:test_params_initValuesOnProxy_succeeds() (gas: 16056) OptimismPortalUpgradeable_Test:test_params_initValuesOnProxy_succeeds() (gas: 16078)
OptimismPortalUpgradeable_Test:test_upgradeToAndCall_upgrading_succeeds() (gas: 180547) OptimismPortalUpgradeable_Test:test_upgradeToAndCall_upgrading_succeeds() (gas: 180547)
OptimismPortal_FinalizeWithdrawal_Test:test_finalizeWithdrawalTransaction_ifOutputRootChanges_reverts() (gas: 201010) OptimismPortal_FinalizeWithdrawal_Test:test_finalizeWithdrawalTransaction_ifOutputRootChanges_reverts() (gas: 204067)
OptimismPortal_FinalizeWithdrawal_Test:test_finalizeWithdrawalTransaction_ifOutputTimestampIsNotFinalized_reverts() (gas: 203373) OptimismPortal_FinalizeWithdrawal_Test:test_finalizeWithdrawalTransaction_ifOutputTimestampIsNotFinalized_reverts() (gas: 207520)
OptimismPortal_FinalizeWithdrawal_Test:test_finalizeWithdrawalTransaction_ifWithdrawalNotProven_reverts() (gas: 41798) OptimismPortal_FinalizeWithdrawal_Test:test_finalizeWithdrawalTransaction_ifWithdrawalNotProven_reverts() (gas: 41753)
OptimismPortal_FinalizeWithdrawal_Test:test_finalizeWithdrawalTransaction_ifWithdrawalProofNotOldEnough_reverts() (gas: 198396) OptimismPortal_FinalizeWithdrawal_Test:test_finalizeWithdrawalTransaction_ifWithdrawalProofNotOldEnough_reverts() (gas: 199464)
OptimismPortal_FinalizeWithdrawal_Test:test_finalizeWithdrawalTransaction_onInsufficientGas_reverts() (gas: 199219) OptimismPortal_FinalizeWithdrawal_Test:test_finalizeWithdrawalTransaction_onInsufficientGas_reverts() (gas: 203388)
OptimismPortal_FinalizeWithdrawal_Test:test_finalizeWithdrawalTransaction_onRecentWithdrawal_reverts() (gas: 179139) OptimismPortal_FinalizeWithdrawal_Test:test_finalizeWithdrawalTransaction_onRecentWithdrawal_reverts() (gas: 180229)
OptimismPortal_FinalizeWithdrawal_Test:test_finalizeWithdrawalTransaction_onReentrancy_reverts() (gas: 237848) OptimismPortal_FinalizeWithdrawal_Test:test_finalizeWithdrawalTransaction_onReentrancy_reverts() (gas: 244483)
OptimismPortal_FinalizeWithdrawal_Test:test_finalizeWithdrawalTransaction_onReplay_reverts() (gas: 239372) OptimismPortal_FinalizeWithdrawal_Test:test_finalizeWithdrawalTransaction_onReplay_reverts() (gas: 245634)
OptimismPortal_FinalizeWithdrawal_Test:test_finalizeWithdrawalTransaction_paused_reverts() (gas: 53621) OptimismPortal_FinalizeWithdrawal_Test:test_finalizeWithdrawalTransaction_paused_reverts() (gas: 53555)
OptimismPortal_FinalizeWithdrawal_Test:test_finalizeWithdrawalTransaction_provenWithdrawalHash_succeeds() (gas: 230921) OptimismPortal_FinalizeWithdrawal_Test:test_finalizeWithdrawalTransaction_provenWithdrawalHash_succeeds() (gas: 235047)
OptimismPortal_FinalizeWithdrawal_Test:test_finalizeWithdrawalTransaction_targetFails_fails() (gas: 8797746687696163739) OptimismPortal_FinalizeWithdrawal_Test:test_finalizeWithdrawalTransaction_targetFails_fails() (gas: 8797746687696163866)
OptimismPortal_FinalizeWithdrawal_Test:test_finalizeWithdrawalTransaction_timestampLessThanL2OracleStart_reverts() (gas: 195098) OptimismPortal_FinalizeWithdrawal_Test:test_finalizeWithdrawalTransaction_timestampLessThanL2OracleStart_reverts() (gas: 197042)
OptimismPortal_FinalizeWithdrawal_Test:test_proveWithdrawalTransaction_onInvalidOutputRootProof_reverts() (gas: 85690) OptimismPortal_FinalizeWithdrawal_Test:test_proveWithdrawalTransaction_onInvalidOutputRootProof_reverts() (gas: 85690)
OptimismPortal_FinalizeWithdrawal_Test:test_proveWithdrawalTransaction_onInvalidWithdrawalProof_reverts() (gas: 137350) OptimismPortal_FinalizeWithdrawal_Test:test_proveWithdrawalTransaction_onInvalidWithdrawalProof_reverts() (gas: 137350)
OptimismPortal_FinalizeWithdrawal_Test:test_proveWithdrawalTransaction_onSelfCall_reverts() (gas: 52925) OptimismPortal_FinalizeWithdrawal_Test:test_proveWithdrawalTransaction_onSelfCall_reverts() (gas: 52947)
OptimismPortal_FinalizeWithdrawal_Test:test_proveWithdrawalTransaction_paused_reverts() (gas: 73695) OptimismPortal_FinalizeWithdrawal_Test:test_proveWithdrawalTransaction_paused_reverts() (gas: 73696)
OptimismPortal_FinalizeWithdrawal_Test:test_proveWithdrawalTransaction_replayProveChangedOutputRootAndOutputIndex_succeeds() (gas: 346875) OptimismPortal_FinalizeWithdrawal_Test:test_proveWithdrawalTransaction_replayProveChangedOutputRootAndOutputIndex_succeeds() (gas: 346853)
OptimismPortal_FinalizeWithdrawal_Test:test_proveWithdrawalTransaction_replayProveChangedOutputRoot_succeeds() (gas: 279593) OptimismPortal_FinalizeWithdrawal_Test:test_proveWithdrawalTransaction_replayProveChangedOutputRoot_succeeds() (gas: 279593)
OptimismPortal_FinalizeWithdrawal_Test:test_proveWithdrawalTransaction_replayProve_reverts() (gas: 192570) OptimismPortal_FinalizeWithdrawal_Test:test_proveWithdrawalTransaction_replayProve_reverts() (gas: 192548)
OptimismPortal_FinalizeWithdrawal_Test:test_proveWithdrawalTransaction_validWithdrawalProof_succeeds() (gas: 180486) OptimismPortal_FinalizeWithdrawal_Test:test_proveWithdrawalTransaction_validWithdrawalProof_succeeds() (gas: 180486)
OptimismPortal_Test:test_constructor_succeeds() (gas: 20672) OptimismPortal_Test:test_constructor_succeeds() (gas: 19440)
OptimismPortal_Test:test_depositTransaction_contractCreation_reverts() (gas: 14320) OptimismPortal_Test:test_depositTransaction_contractCreation_reverts() (gas: 14330)
OptimismPortal_Test:test_depositTransaction_createWithZeroValueForContract_succeeds() (gas: 76748) OptimismPortal_Test:test_depositTransaction_createWithZeroValueForContract_succeeds() (gas: 76758)
OptimismPortal_Test:test_depositTransaction_createWithZeroValueForEOA_succeeds() (gas: 77114) OptimismPortal_Test:test_depositTransaction_createWithZeroValueForEOA_succeeds() (gas: 77124)
OptimismPortal_Test:test_depositTransaction_noValueContract_succeeds() (gas: 76766) OptimismPortal_Test:test_depositTransaction_noValueContract_succeeds() (gas: 76776)
OptimismPortal_Test:test_depositTransaction_noValueEOA_succeeds() (gas: 77111) OptimismPortal_Test:test_depositTransaction_noValueEOA_succeeds() (gas: 77121)
OptimismPortal_Test:test_depositTransaction_smallGasLimit_reverts() (gas: 14266) OptimismPortal_Test:test_depositTransaction_smallGasLimit_reverts() (gas: 14276)
OptimismPortal_Test:test_depositTransaction_withEthValueAndContractContractCreation_succeeds() (gas: 83772) OptimismPortal_Test:test_depositTransaction_withEthValueAndContractContractCreation_succeeds() (gas: 83782)
OptimismPortal_Test:test_depositTransaction_withEthValueAndEOAContractCreation_succeeds() (gas: 75925) OptimismPortal_Test:test_depositTransaction_withEthValueAndEOAContractCreation_succeeds() (gas: 75935)
OptimismPortal_Test:test_depositTransaction_withEthValueFromContract_succeeds() (gas: 83452) OptimismPortal_Test:test_depositTransaction_withEthValueFromContract_succeeds() (gas: 83462)
OptimismPortal_Test:test_depositTransaction_withEthValueFromEOA_succeeds() (gas: 84068) OptimismPortal_Test:test_depositTransaction_withEthValueFromEOA_succeeds() (gas: 84078)
OptimismPortal_Test:test_isOutputFinalized_succeeds() (gas: 119519) OptimismPortal_Test:test_isOutputFinalized_succeeds() (gas: 121711)
OptimismPortal_Test:test_pause_onlyGuardian_reverts() (gas: 22182) OptimismPortal_Test:test_pause_onlyGuardian_reverts() (gas: 22205)
OptimismPortal_Test:test_pause_succeeds() (gas: 42161) OptimismPortal_Test:test_pause_succeeds() (gas: 42184)
OptimismPortal_Test:test_receive_succeeds() (gas: 127554) OptimismPortal_Test:test_receive_succeeds() (gas: 127554)
OptimismPortal_Test:test_simple_isOutputFinalized_succeeds() (gas: 24232) OptimismPortal_Test:test_simple_isOutputFinalized_succeeds() (gas: 32934)
OptimismPortal_Test:test_unpause_onlyGuardian_reverts() (gas: 46151) OptimismPortal_Test:test_unpause_onlyGuardian_reverts() (gas: 46151)
OptimismPortal_Test:test_unpause_succeeds() (gas: 31780) OptimismPortal_Test:test_unpause_succeeds() (gas: 31763)
ProxyAdmin_Test:test_chugsplashChangeProxyAdmin_succeeds() (gas: 35586) ProxyAdmin_Test:test_chugsplashChangeProxyAdmin_succeeds() (gas: 35586)
ProxyAdmin_Test:test_chugsplashGetProxyAdmin_succeeds() (gas: 15675) ProxyAdmin_Test:test_chugsplashGetProxyAdmin_succeeds() (gas: 15675)
ProxyAdmin_Test:test_chugsplashGetProxyImplementation_succeeds() (gas: 51084) ProxyAdmin_Test:test_chugsplashGetProxyImplementation_succeeds() (gas: 51084)
......
# @eth-optimism/contracts-bedrock # @eth-optimism/contracts-bedrock
## 0.13.0
### Minor Changes
- cb19e2f9c: Moves `FINALIZATION_PERIOD_SECONDS` from the `OptimismPortal` to the `L2OutputOracle` & ensures the `CHALLENGER` key cannot delete finalized outputs.
## 0.12.1 ## 0.12.1
### Patch Changes ### Patch Changes
......
...@@ -34,6 +34,11 @@ contract L2OutputOracle is Initializable, Semver { ...@@ -34,6 +34,11 @@ contract L2OutputOracle is Initializable, Semver {
*/ */
address public immutable PROPOSER; address public immutable PROPOSER;
/**
* @notice Minimum time (in seconds) that must elapse before a withdrawal can be finalized.
*/
uint256 public immutable FINALIZATION_PERIOD_SECONDS;
/** /**
* @notice The number of the first L2 block recorded in this contract. * @notice The number of the first L2 block recorded in this contract.
*/ */
...@@ -73,7 +78,7 @@ contract L2OutputOracle is Initializable, Semver { ...@@ -73,7 +78,7 @@ contract L2OutputOracle is Initializable, Semver {
event OutputsDeleted(uint256 indexed prevNextOutputIndex, uint256 indexed newNextOutputIndex); event OutputsDeleted(uint256 indexed prevNextOutputIndex, uint256 indexed newNextOutputIndex);
/** /**
* @custom:semver 1.1.0 * @custom:semver 1.2.0
* *
* @param _submissionInterval Interval in blocks at which checkpoints must be submitted. * @param _submissionInterval Interval in blocks at which checkpoints must be submitted.
* @param _l2BlockTime The time per L2 block, in seconds. * @param _l2BlockTime The time per L2 block, in seconds.
...@@ -88,8 +93,9 @@ contract L2OutputOracle is Initializable, Semver { ...@@ -88,8 +93,9 @@ contract L2OutputOracle is Initializable, Semver {
uint256 _startingBlockNumber, uint256 _startingBlockNumber,
uint256 _startingTimestamp, uint256 _startingTimestamp,
address _proposer, address _proposer,
address _challenger address _challenger,
) Semver(1, 1, 0) { uint256 _finalizationPeriodSeconds
) Semver(1, 2, 0) {
require(_l2BlockTime > 0, "L2OutputOracle: L2 block time must be greater than 0"); require(_l2BlockTime > 0, "L2OutputOracle: L2 block time must be greater than 0");
require( require(
_submissionInterval > _l2BlockTime, _submissionInterval > _l2BlockTime,
...@@ -100,6 +106,7 @@ contract L2OutputOracle is Initializable, Semver { ...@@ -100,6 +106,7 @@ contract L2OutputOracle is Initializable, Semver {
L2_BLOCK_TIME = _l2BlockTime; L2_BLOCK_TIME = _l2BlockTime;
PROPOSER = _proposer; PROPOSER = _proposer;
CHALLENGER = _challenger; CHALLENGER = _challenger;
FINALIZATION_PERIOD_SECONDS = _finalizationPeriodSeconds;
initialize(_startingBlockNumber, _startingTimestamp); initialize(_startingBlockNumber, _startingTimestamp);
} }
...@@ -143,6 +150,12 @@ contract L2OutputOracle is Initializable, Semver { ...@@ -143,6 +150,12 @@ contract L2OutputOracle is Initializable, Semver {
"L2OutputOracle: cannot delete outputs after the latest output index" "L2OutputOracle: cannot delete outputs after the latest output index"
); );
// Do not allow deleting any outputs that have already been finalized.
require(
block.timestamp - l2Outputs[_l2OutputIndex].timestamp < FINALIZATION_PERIOD_SECONDS,
"L2OutputOracle: cannot delete outputs that have already been finalized"
);
uint256 prevNextL2OutputIndex = nextOutputIndex(); uint256 prevNextL2OutputIndex = nextOutputIndex();
// Use assembly to delete the array elements because Solidity doesn't allow it. // Use assembly to delete the array elements because Solidity doesn't allow it.
......
...@@ -48,11 +48,6 @@ contract OptimismPortal is Initializable, ResourceMetering, Semver { ...@@ -48,11 +48,6 @@ contract OptimismPortal is Initializable, ResourceMetering, Semver {
*/ */
uint256 internal constant FINALIZE_GAS_BUFFER = 20_000; uint256 internal constant FINALIZE_GAS_BUFFER = 20_000;
/**
* @notice Minimum time (in seconds) that must elapse before a withdrawal can be finalized.
*/
uint256 public immutable FINALIZATION_PERIOD_SECONDS;
/** /**
* @notice Address of the L2OutputOracle. * @notice Address of the L2OutputOracle.
*/ */
...@@ -145,22 +140,19 @@ contract OptimismPortal is Initializable, ResourceMetering, Semver { ...@@ -145,22 +140,19 @@ contract OptimismPortal is Initializable, ResourceMetering, Semver {
} }
/** /**
* @custom:semver 1.1.0 * @custom:semver 1.2.0
* *
* @param _l2Oracle Address of the L2OutputOracle contract. * @param _l2Oracle Address of the L2OutputOracle contract.
* @param _guardian Address that can pause deposits and withdrawals. * @param _guardian Address that can pause deposits and withdrawals.
* @param _finalizationPeriodSeconds Output finalization time in seconds.
* @param _paused Sets the contract's pausability state. * @param _paused Sets the contract's pausability state.
*/ */
constructor( constructor(
L2OutputOracle _l2Oracle, L2OutputOracle _l2Oracle,
uint256 _finalizationPeriodSeconds,
address _guardian, address _guardian,
bool _paused bool _paused
) Semver(1, 1, 0) { ) Semver(1, 2, 0) {
L2_ORACLE = _l2Oracle; L2_ORACLE = _l2Oracle;
GUARDIAN = _guardian; GUARDIAN = _guardian;
FINALIZATION_PERIOD_SECONDS = _finalizationPeriodSeconds;
initialize(_paused); initialize(_paused);
} }
...@@ -480,6 +472,6 @@ contract OptimismPortal is Initializable, ResourceMetering, Semver { ...@@ -480,6 +472,6 @@ contract OptimismPortal is Initializable, ResourceMetering, Semver {
* @return Whether or not the finalization period has elapsed. * @return Whether or not the finalization period has elapsed.
*/ */
function _isFinalizationPeriodElapsed(uint256 _timestamp) internal view returns (bool) { function _isFinalizationPeriodElapsed(uint256 _timestamp) internal view returns (bool) {
return block.timestamp > _timestamp + FINALIZATION_PERIOD_SECONDS; return block.timestamp > _timestamp + L2_ORACLE.FINALIZATION_PERIOD_SECONDS();
} }
} }
...@@ -12,7 +12,6 @@ contract EchidnaFuzzOptimismPortal { ...@@ -12,7 +12,6 @@ contract EchidnaFuzzOptimismPortal {
portal = new OptimismPortal({ portal = new OptimismPortal({
_l2Oracle: L2OutputOracle(address(0)), _l2Oracle: L2OutputOracle(address(0)),
_guardian: address(0), _guardian: address(0),
_finalizationPeriodSeconds: 10,
_paused: false _paused: false
}); });
} }
......
...@@ -85,7 +85,7 @@ contract GasBenchMark_OptimismPortal is Portal_Initializer { ...@@ -85,7 +85,7 @@ contract GasBenchMark_OptimismPortal is Portal_Initializer {
// Warp beyond the finalization period for the block we've proposed. // Warp beyond the finalization period for the block we've proposed.
vm.warp( vm.warp(
oracle.getL2Output(_proposedOutputIndex).timestamp + oracle.getL2Output(_proposedOutputIndex).timestamp +
op.FINALIZATION_PERIOD_SECONDS() + oracle.FINALIZATION_PERIOD_SECONDS() +
1 1
); );
// Fund the portal so that we can withdraw ETH. // Fund the portal so that we can withdraw ETH.
......
...@@ -128,14 +128,15 @@ contract L2OutputOracle_Initializer is CommonTest { ...@@ -128,14 +128,15 @@ contract L2OutputOracle_Initializer is CommonTest {
vm.warp(initL1Time); vm.warp(initL1Time);
vm.roll(startingBlockNumber); vm.roll(startingBlockNumber);
// Deploy the L2OutputOracle and transfer owernship to the proposer // Deploy the L2OutputOracle and transfer owernship to the proposer
oracleImpl = new L2OutputOracle( oracleImpl = new L2OutputOracle({
submissionInterval, _submissionInterval: submissionInterval,
l2BlockTime, _l2BlockTime: l2BlockTime,
startingBlockNumber, _startingBlockNumber: startingBlockNumber,
startingTimestamp, _startingTimestamp: startingTimestamp,
proposer, _proposer: proposer,
owner _challenger: owner,
); _finalizationPeriodSeconds: 7 days
});
Proxy proxy = new Proxy(multisig); Proxy proxy = new Proxy(multisig);
vm.prank(multisig); vm.prank(multisig);
proxy.upgradeToAndCall( proxy.upgradeToAndCall(
...@@ -167,12 +168,7 @@ contract Portal_Initializer is L2OutputOracle_Initializer { ...@@ -167,12 +168,7 @@ contract Portal_Initializer is L2OutputOracle_Initializer {
function setUp() public virtual override { function setUp() public virtual override {
super.setUp(); super.setUp();
opImpl = new OptimismPortal({ opImpl = new OptimismPortal({ _l2Oracle: oracle, _guardian: guardian, _paused: true });
_l2Oracle: oracle,
_guardian: guardian,
_finalizationPeriodSeconds: 7 days,
_paused: true
});
Proxy proxy = new Proxy(multisig); Proxy proxy = new Proxy(multisig);
vm.prank(multisig); vm.prank(multisig);
proxy.upgradeToAndCall( proxy.upgradeToAndCall(
...@@ -231,12 +227,7 @@ contract Messenger_Initializer is L2OutputOracle_Initializer { ...@@ -231,12 +227,7 @@ contract Messenger_Initializer is L2OutputOracle_Initializer {
super.setUp(); super.setUp();
// Deploy the OptimismPortal // Deploy the OptimismPortal
op = new OptimismPortal({ op = new OptimismPortal({ _l2Oracle: oracle, _guardian: guardian, _paused: false });
_l2Oracle: oracle,
_guardian: guardian,
_finalizationPeriodSeconds: 7 days,
_paused: false
});
vm.label(address(op), "OptimismPortal"); vm.label(address(op), "OptimismPortal");
// Deploy the address manager // Deploy the address manager
......
...@@ -22,27 +22,29 @@ contract L2OutputOracleTest is L2OutputOracle_Initializer { ...@@ -22,27 +22,29 @@ contract L2OutputOracleTest is L2OutputOracle_Initializer {
function test_constructor_badTimestamp_reverts() external { function test_constructor_badTimestamp_reverts() external {
vm.expectRevert("L2OutputOracle: starting L2 timestamp must be less than current time"); vm.expectRevert("L2OutputOracle: starting L2 timestamp must be less than current time");
new L2OutputOracle(
submissionInterval,
l2BlockTime,
startingBlockNumber,
// startingTimestamp is in the future // startingTimestamp is in the future
block.timestamp + 1, new L2OutputOracle({
proposer, _submissionInterval: submissionInterval,
owner _l2BlockTime: l2BlockTime,
); _startingBlockNumber: startingBlockNumber,
_startingTimestamp: block.timestamp + 1,
_proposer: proposer,
_challenger: owner,
_finalizationPeriodSeconds: 7 days
});
} }
function test_constructor_l2BlockTimeZero_reverts() external { function test_constructor_l2BlockTimeZero_reverts() external {
vm.expectRevert("L2OutputOracle: L2 block time must be greater than 0"); vm.expectRevert("L2OutputOracle: L2 block time must be greater than 0");
new L2OutputOracle( new L2OutputOracle({
submissionInterval, _submissionInterval: submissionInterval,
0, _l2BlockTime: 0,
startingBlockNumber, _startingBlockNumber: startingBlockNumber,
block.timestamp, _startingTimestamp: block.timestamp,
proposer, _proposer: proposer,
owner _challenger: owner,
); _finalizationPeriodSeconds: 7 days
});
} }
function testFuzz_constructor_submissionIntervalLteL2BlockTime_reverts( function testFuzz_constructor_submissionIntervalLteL2BlockTime_reverts(
...@@ -57,14 +59,15 @@ contract L2OutputOracleTest is L2OutputOracle_Initializer { ...@@ -57,14 +59,15 @@ contract L2OutputOracleTest is L2OutputOracle_Initializer {
_submissionInterval = bound(_submissionInterval, 0, _l2BlockTime); _submissionInterval = bound(_submissionInterval, 0, _l2BlockTime);
vm.expectRevert("L2OutputOracle: submission interval must be greater than L2 block time"); vm.expectRevert("L2OutputOracle: submission interval must be greater than L2 block time");
new L2OutputOracle( new L2OutputOracle({
_submissionInterval, _submissionInterval: _submissionInterval,
_l2BlockTime, _l2BlockTime: _l2BlockTime,
startingBlockNumber, _startingBlockNumber: startingBlockNumber,
block.timestamp, _startingTimestamp: block.timestamp,
proposer, _proposer: proposer,
owner _challenger: owner,
); _finalizationPeriodSeconds: 7 days
});
} }
/**************** /****************
...@@ -411,6 +414,20 @@ contract L2OutputOracleTest is L2OutputOracle_Initializer { ...@@ -411,6 +414,20 @@ contract L2OutputOracleTest is L2OutputOracle_Initializer {
vm.expectRevert("L2OutputOracle: cannot delete outputs after the latest output index"); vm.expectRevert("L2OutputOracle: cannot delete outputs after the latest output index");
oracle.deleteL2Outputs(latestOutputIndex - 2); oracle.deleteL2Outputs(latestOutputIndex - 2);
} }
function test_deleteL2Outputs_finalized_reverts() external {
test_proposeL2Output_proposeAnotherOutput_succeeds();
// Warp past the finalization period + 1 second
vm.warp(block.timestamp + oracle.FINALIZATION_PERIOD_SECONDS() + 1);
uint256 latestOutputIndex = oracle.latestOutputIndex();
// Try to delete a finalized output
vm.prank(owner);
vm.expectRevert("L2OutputOracle: cannot delete outputs that have already been finalized");
oracle.deleteL2Outputs(latestOutputIndex);
}
} }
contract L2OutputOracleUpgradeable_Test is L2OutputOracle_Initializer { contract L2OutputOracleUpgradeable_Test is L2OutputOracle_Initializer {
......
...@@ -15,7 +15,6 @@ contract OptimismPortal_Test is Portal_Initializer { ...@@ -15,7 +15,6 @@ contract OptimismPortal_Test is Portal_Initializer {
event Unpaused(address); event Unpaused(address);
function test_constructor_succeeds() external { function test_constructor_succeeds() external {
assertEq(op.FINALIZATION_PERIOD_SECONDS(), 7 days);
assertEq(address(op.L2_ORACLE()), address(oracle)); assertEq(address(op.L2_ORACLE()), address(oracle));
assertEq(op.l2Sender(), 0x000000000000000000000000000000000000dEaD); assertEq(op.l2Sender(), 0x000000000000000000000000000000000000dEaD);
assertEq(op.paused(), false); assertEq(op.paused(), false);
...@@ -314,11 +313,11 @@ contract OptimismPortal_Test is Portal_Initializer { ...@@ -314,11 +313,11 @@ contract OptimismPortal_Test is Portal_Initializer {
); );
// warp to the finalization period // warp to the finalization period
vm.warp(ts + op.FINALIZATION_PERIOD_SECONDS()); vm.warp(ts + oracle.FINALIZATION_PERIOD_SECONDS());
assertEq(op.isOutputFinalized(0), false); assertEq(op.isOutputFinalized(0), false);
// warp past the finalization period // warp past the finalization period
vm.warp(ts + op.FINALIZATION_PERIOD_SECONDS() + 1); vm.warp(ts + oracle.FINALIZATION_PERIOD_SECONDS() + 1);
assertEq(op.isOutputFinalized(0), true); assertEq(op.isOutputFinalized(0), true);
} }
...@@ -331,7 +330,7 @@ contract OptimismPortal_Test is Portal_Initializer { ...@@ -331,7 +330,7 @@ contract OptimismPortal_Test is Portal_Initializer {
oracle.proposeL2Output(keccak256(abi.encode(2)), checkpoint, 0, 0); oracle.proposeL2Output(keccak256(abi.encode(2)), checkpoint, 0, 0);
// warp to the final second of the finalization period // warp to the final second of the finalization period
uint256 finalizationHorizon = block.timestamp + op.FINALIZATION_PERIOD_SECONDS(); uint256 finalizationHorizon = block.timestamp + oracle.FINALIZATION_PERIOD_SECONDS();
vm.warp(finalizationHorizon); vm.warp(finalizationHorizon);
// The checkpointed block should not be finalized until 1 second from now. // The checkpointed block should not be finalized until 1 second from now.
assertEq(op.isOutputFinalized(nextOutputIndex), false); assertEq(op.isOutputFinalized(nextOutputIndex), false);
...@@ -398,7 +397,7 @@ contract OptimismPortal_FinalizeWithdrawal_Test is Portal_Initializer { ...@@ -398,7 +397,7 @@ contract OptimismPortal_FinalizeWithdrawal_Test is Portal_Initializer {
// Warp beyond the finalization period for the block we've proposed. // Warp beyond the finalization period for the block we've proposed.
vm.warp( vm.warp(
oracle.getL2Output(_proposedOutputIndex).timestamp + oracle.getL2Output(_proposedOutputIndex).timestamp +
op.FINALIZATION_PERIOD_SECONDS() + oracle.FINALIZATION_PERIOD_SECONDS() +
1 1
); );
// Fund the portal so that we can withdraw ETH. // Fund the portal so that we can withdraw ETH.
...@@ -620,7 +619,7 @@ contract OptimismPortal_FinalizeWithdrawal_Test is Portal_Initializer { ...@@ -620,7 +619,7 @@ contract OptimismPortal_FinalizeWithdrawal_Test is Portal_Initializer {
_withdrawalProof _withdrawalProof
); );
vm.warp(block.timestamp + op.FINALIZATION_PERIOD_SECONDS() + 1); vm.warp(block.timestamp + oracle.FINALIZATION_PERIOD_SECONDS() + 1);
vm.expectEmit(true, true, false, true); vm.expectEmit(true, true, false, true);
emit WithdrawalFinalized(_withdrawalHash, true); emit WithdrawalFinalized(_withdrawalHash, true);
op.finalizeWithdrawalTransaction(_defaultTx); op.finalizeWithdrawalTransaction(_defaultTx);
...@@ -692,7 +691,7 @@ contract OptimismPortal_FinalizeWithdrawal_Test is Portal_Initializer { ...@@ -692,7 +691,7 @@ contract OptimismPortal_FinalizeWithdrawal_Test is Portal_Initializer {
); );
// Warp to after the finalization period // Warp to after the finalization period
vm.warp(block.timestamp + op.FINALIZATION_PERIOD_SECONDS() + 1); vm.warp(block.timestamp + oracle.FINALIZATION_PERIOD_SECONDS() + 1);
// Mock a startingTimestamp change on the L2 Oracle // Mock a startingTimestamp change on the L2 Oracle
vm.mockCall( vm.mockCall(
...@@ -727,7 +726,7 @@ contract OptimismPortal_FinalizeWithdrawal_Test is Portal_Initializer { ...@@ -727,7 +726,7 @@ contract OptimismPortal_FinalizeWithdrawal_Test is Portal_Initializer {
); );
// Warp to after the finalization period // Warp to after the finalization period
vm.warp(block.timestamp + op.FINALIZATION_PERIOD_SECONDS() + 1); vm.warp(block.timestamp + oracle.FINALIZATION_PERIOD_SECONDS() + 1);
// Mock an outputRoot change on the output proposal before attempting // Mock an outputRoot change on the output proposal before attempting
// to finalize the withdrawal. // to finalize the withdrawal.
...@@ -769,7 +768,7 @@ contract OptimismPortal_FinalizeWithdrawal_Test is Portal_Initializer { ...@@ -769,7 +768,7 @@ contract OptimismPortal_FinalizeWithdrawal_Test is Portal_Initializer {
); );
// Warp to after the finalization period // Warp to after the finalization period
vm.warp(block.timestamp + op.FINALIZATION_PERIOD_SECONDS() + 1); vm.warp(block.timestamp + oracle.FINALIZATION_PERIOD_SECONDS() + 1);
// Mock a timestamp change on the output proposal that has not passed the // Mock a timestamp change on the output proposal that has not passed the
// finalization period. // finalization period.
...@@ -808,7 +807,7 @@ contract OptimismPortal_FinalizeWithdrawal_Test is Portal_Initializer { ...@@ -808,7 +807,7 @@ contract OptimismPortal_FinalizeWithdrawal_Test is Portal_Initializer {
_withdrawalProof _withdrawalProof
); );
vm.warp(block.timestamp + op.FINALIZATION_PERIOD_SECONDS() + 1); vm.warp(block.timestamp + oracle.FINALIZATION_PERIOD_SECONDS() + 1);
vm.expectEmit(true, true, true, true); vm.expectEmit(true, true, true, true);
emit WithdrawalFinalized(_withdrawalHash, false); emit WithdrawalFinalized(_withdrawalHash, false);
op.finalizeWithdrawalTransaction(_defaultTx); op.finalizeWithdrawalTransaction(_defaultTx);
...@@ -854,7 +853,7 @@ contract OptimismPortal_FinalizeWithdrawal_Test is Portal_Initializer { ...@@ -854,7 +853,7 @@ contract OptimismPortal_FinalizeWithdrawal_Test is Portal_Initializer {
_withdrawalProof _withdrawalProof
); );
vm.warp(block.timestamp + op.FINALIZATION_PERIOD_SECONDS() + 1); vm.warp(block.timestamp + oracle.FINALIZATION_PERIOD_SECONDS() + 1);
vm.expectEmit(true, true, true, true); vm.expectEmit(true, true, true, true);
emit WithdrawalFinalized(_withdrawalHash, true); emit WithdrawalFinalized(_withdrawalHash, true);
op.finalizeWithdrawalTransaction(_defaultTx); op.finalizeWithdrawalTransaction(_defaultTx);
...@@ -905,7 +904,7 @@ contract OptimismPortal_FinalizeWithdrawal_Test is Portal_Initializer { ...@@ -905,7 +904,7 @@ contract OptimismPortal_FinalizeWithdrawal_Test is Portal_Initializer {
withdrawalProof withdrawalProof
); );
vm.warp(block.timestamp + op.FINALIZATION_PERIOD_SECONDS() + 1); vm.warp(block.timestamp + oracle.FINALIZATION_PERIOD_SECONDS() + 1);
vm.expectRevert("OptimismPortal: insufficient gas to finalize withdrawal"); vm.expectRevert("OptimismPortal: insufficient gas to finalize withdrawal");
op.finalizeWithdrawalTransaction{ gas: gasLimit }(insufficientGasTx); op.finalizeWithdrawalTransaction{ gas: gasLimit }(insufficientGasTx);
} }
...@@ -937,7 +936,7 @@ contract OptimismPortal_FinalizeWithdrawal_Test is Portal_Initializer { ...@@ -937,7 +936,7 @@ contract OptimismPortal_FinalizeWithdrawal_Test is Portal_Initializer {
}); });
// Setup the Oracle to return the outputRoot we want as well as a finalized timestamp. // Setup the Oracle to return the outputRoot we want as well as a finalized timestamp.
uint256 finalizedTimestamp = block.timestamp - op.FINALIZATION_PERIOD_SECONDS() - 1; uint256 finalizedTimestamp = block.timestamp - oracle.FINALIZATION_PERIOD_SECONDS() - 1;
vm.mockCall( vm.mockCall(
address(op.L2_ORACLE()), address(op.L2_ORACLE()),
abi.encodeWithSelector(L2OutputOracle.getL2Output.selector), abi.encodeWithSelector(L2OutputOracle.getL2Output.selector),
...@@ -959,7 +958,7 @@ contract OptimismPortal_FinalizeWithdrawal_Test is Portal_Initializer { ...@@ -959,7 +958,7 @@ contract OptimismPortal_FinalizeWithdrawal_Test is Portal_Initializer {
withdrawalProof withdrawalProof
); );
vm.warp(block.timestamp + op.FINALIZATION_PERIOD_SECONDS() + 1); vm.warp(block.timestamp + oracle.FINALIZATION_PERIOD_SECONDS() + 1);
vm.expectCall(address(this), _testTx.data); vm.expectCall(address(this), _testTx.data);
vm.expectEmit(true, true, true, true); vm.expectEmit(true, true, true, true);
emit WithdrawalFinalized(withdrawalHash, true); emit WithdrawalFinalized(withdrawalHash, true);
...@@ -1025,7 +1024,7 @@ contract OptimismPortal_FinalizeWithdrawal_Test is Portal_Initializer { ...@@ -1025,7 +1024,7 @@ contract OptimismPortal_FinalizeWithdrawal_Test is Portal_Initializer {
// Ensure that the sentMessages is correct // Ensure that the sentMessages is correct
assertEq(messagePasser.sentMessages(withdrawalHash), true); assertEq(messagePasser.sentMessages(withdrawalHash), true);
vm.warp(block.timestamp + op.FINALIZATION_PERIOD_SECONDS() + 1); vm.warp(block.timestamp + oracle.FINALIZATION_PERIOD_SECONDS() + 1);
op.proveWithdrawalTransaction( op.proveWithdrawalTransaction(
_tx, _tx,
100, // l2BlockNumber 100, // l2BlockNumber
......
...@@ -49,7 +49,7 @@ contract OptimismPortal_Invariant_Harness is Portal_Initializer { ...@@ -49,7 +49,7 @@ contract OptimismPortal_Invariant_Harness is Portal_Initializer {
// Warp beyond the finalization period for the block we've proposed. // Warp beyond the finalization period for the block we've proposed.
vm.warp( vm.warp(
oracle.getL2Output(_proposedOutputIndex).timestamp + oracle.getL2Output(_proposedOutputIndex).timestamp +
op.FINALIZATION_PERIOD_SECONDS() + oracle.FINALIZATION_PERIOD_SECONDS() +
1 1
); );
// Fund the portal so that we can withdraw ETH. // Fund the portal so that we can withdraw ETH.
...@@ -101,7 +101,7 @@ contract OptimismPortal_CannotFinalizeTwice is OptimismPortal_Invariant_Harness ...@@ -101,7 +101,7 @@ contract OptimismPortal_CannotFinalizeTwice is OptimismPortal_Invariant_Harness
); );
// Warp past the finalization period. // Warp past the finalization period.
vm.warp(block.timestamp + op.FINALIZATION_PERIOD_SECONDS() + 1); vm.warp(block.timestamp + oracle.FINALIZATION_PERIOD_SECONDS() + 1);
// Finalize the withdrawal transaction. // Finalize the withdrawal transaction.
op.finalizeWithdrawalTransaction(_defaultTx); op.finalizeWithdrawalTransaction(_defaultTx);
...@@ -138,7 +138,7 @@ contract OptimismPortal_CanAlwaysFinalizeAfterWindow is OptimismPortal_Invariant ...@@ -138,7 +138,7 @@ contract OptimismPortal_CanAlwaysFinalizeAfterWindow is OptimismPortal_Invariant
); );
// Warp past the finalization period. // Warp past the finalization period.
vm.warp(block.timestamp + op.FINALIZATION_PERIOD_SECONDS() + 1); vm.warp(block.timestamp + oracle.FINALIZATION_PERIOD_SECONDS() + 1);
// Set the target contract to the portal proxy // Set the target contract to the portal proxy
targetContract(address(op)); targetContract(address(op));
......
...@@ -28,6 +28,7 @@ const deployFn: DeployFunction = async (hre) => { ...@@ -28,6 +28,7 @@ const deployFn: DeployFunction = async (hre) => {
0, 0,
hre.deployConfig.l2OutputOracleProposer, hre.deployConfig.l2OutputOracleProposer,
hre.deployConfig.l2OutputOracleChallenger, hre.deployConfig.l2OutputOracleChallenger,
hre.deployConfig.finalizationPeriodSeconds,
], ],
postDeployAction: async (contract) => { postDeployAction: async (contract) => {
await assertContractVariable( await assertContractVariable(
...@@ -50,6 +51,11 @@ const deployFn: DeployFunction = async (hre) => { ...@@ -50,6 +51,11 @@ const deployFn: DeployFunction = async (hre) => {
'CHALLENGER', 'CHALLENGER',
hre.deployConfig.l2OutputOracleChallenger hre.deployConfig.l2OutputOracleChallenger
) )
await assertContractVariable(
contract,
'FINALIZATION_PERIOD_SECONDS',
hre.deployConfig.finalizationPeriodSeconds
)
}, },
}) })
} }
......
...@@ -41,7 +41,6 @@ const deployFn: DeployFunction = async (hre) => { ...@@ -41,7 +41,6 @@ const deployFn: DeployFunction = async (hre) => {
name: 'OptimismPortal', name: 'OptimismPortal',
args: [ args: [
L2OutputOracleProxy.address, L2OutputOracleProxy.address,
hre.deployConfig.finalizationPeriodSeconds,
finalSystemOwner, finalSystemOwner,
true, // paused true, // paused
], ],
...@@ -51,11 +50,6 @@ const deployFn: DeployFunction = async (hre) => { ...@@ -51,11 +50,6 @@ const deployFn: DeployFunction = async (hre) => {
'L2_ORACLE', 'L2_ORACLE',
L2OutputOracleProxy.address L2OutputOracleProxy.address
) )
await assertContractVariable(
contract,
'FINALIZATION_PERIOD_SECONDS',
hre.deployConfig.finalizationPeriodSeconds
)
await assertContractVariable( await assertContractVariable(
contract, contract,
'GUARDIAN', 'GUARDIAN',
......
...@@ -19,6 +19,6 @@ This invariant asserts that there is no chain of calls that can be made that wil ...@@ -19,6 +19,6 @@ This invariant asserts that there is no chain of calls that can be made that wil
## Deposits of any value should always succeed unless `_to` = `address(0)` or `_isCreation` = `true`. ## Deposits of any value should always succeed unless `_to` = `address(0)` or `_isCreation` = `true`.
**Test:** [`FuzzOptimismPortal.sol#L42`](../contracts/echidna/FuzzOptimismPortal.sol#L42) **Test:** [`FuzzOptimismPortal.sol#L41`](../contracts/echidna/FuzzOptimismPortal.sol#L41)
All deposits, barring creation transactions and transactions sent to `address(0)`, should always succeed. All deposits, barring creation transactions and transactions sent to `address(0)`, should always succeed.
{ {
"name": "@eth-optimism/contracts-bedrock", "name": "@eth-optimism/contracts-bedrock",
"version": "0.12.1", "version": "0.13.0",
"description": "Contracts for Optimism Specs", "description": "Contracts for Optimism Specs",
"main": "dist/index", "main": "dist/index",
"types": "dist/index", "types": "dist/index",
......
...@@ -53,7 +53,7 @@ ...@@ -53,7 +53,7 @@
"url": "https://github.com/ethereum-optimism/optimism.git" "url": "https://github.com/ethereum-optimism/optimism.git"
}, },
"devDependencies": { "devDependencies": {
"@eth-optimism/contracts-bedrock": "0.12.1", "@eth-optimism/contracts-bedrock": "0.13.0",
"@eth-optimism/core-utils": "^0.12.0", "@eth-optimism/core-utils": "^0.12.0",
"@eth-optimism/hardhat-deploy-config": "^0.2.5", "@eth-optimism/hardhat-deploy-config": "^0.2.5",
"@ethersproject/hardware-wallets": "^5.7.0", "@ethersproject/hardware-wallets": "^5.7.0",
......
# @eth-optimism/fault-detector # @eth-optimism/fault-detector
## 0.6.1
### Patch Changes
- Updated dependencies [cb19e2f9c]
- @eth-optimism/sdk@2.0.0
## 0.6.0 ## 0.6.0
### Minor Changes ### Minor Changes
......
{ {
"private": true, "private": true,
"name": "@eth-optimism/fault-detector", "name": "@eth-optimism/fault-detector",
"version": "0.6.0", "version": "0.6.1",
"description": "[Optimism] Service for detecting faulty L2 output proposals", "description": "[Optimism] Service for detecting faulty L2 output proposals",
"main": "dist/index", "main": "dist/index",
"types": "dist/index", "types": "dist/index",
...@@ -50,7 +50,7 @@ ...@@ -50,7 +50,7 @@
"@eth-optimism/common-ts": "^0.8.0", "@eth-optimism/common-ts": "^0.8.0",
"@eth-optimism/contracts": "^0.5.40", "@eth-optimism/contracts": "^0.5.40",
"@eth-optimism/core-utils": "^0.12.0", "@eth-optimism/core-utils": "^0.12.0",
"@eth-optimism/sdk": "^1.10.2", "@eth-optimism/sdk": "^2.0.0",
"@ethersproject/abstract-provider": "^5.7.0" "@ethersproject/abstract-provider": "^5.7.0"
} }
} }
# @eth-optimism/message-relayer # @eth-optimism/message-relayer
## 0.5.31
### Patch Changes
- Updated dependencies [cb19e2f9c]
- @eth-optimism/sdk@2.0.0
## 0.5.30 ## 0.5.30
### Patch Changes ### Patch Changes
......
{ {
"private": true, "private": true,
"name": "@eth-optimism/message-relayer", "name": "@eth-optimism/message-relayer",
"version": "0.5.30", "version": "0.5.31",
"description": "[Optimism] Service for automatically relaying L2 to L1 transactions", "description": "[Optimism] Service for automatically relaying L2 to L1 transactions",
"main": "dist/index", "main": "dist/index",
"types": "dist/index", "types": "dist/index",
...@@ -33,7 +33,7 @@ ...@@ -33,7 +33,7 @@
"dependencies": { "dependencies": {
"@eth-optimism/common-ts": "0.8.0", "@eth-optimism/common-ts": "0.8.0",
"@eth-optimism/core-utils": "0.12.0", "@eth-optimism/core-utils": "0.12.0",
"@eth-optimism/sdk": "1.10.4", "@eth-optimism/sdk": "2.0.0",
"ethers": "^5.7.0" "ethers": "^5.7.0"
}, },
"devDependencies": { "devDependencies": {
......
# @eth-optimism/sdk # @eth-optimism/sdk
## 2.0.0
### Major Changes
- cb19e2f9c: Moves `FINALIZATION_PERIOD_SECONDS` from the `OptimismPortal` to the `L2OutputOracle` & ensures the `CHALLENGER` key cannot delete finalized outputs.
### Patch Changes
- Updated dependencies [cb19e2f9c]
- @eth-optimism/contracts-bedrock@0.13.0
## 1.10.4 ## 1.10.4
### Patch Changes ### Patch Changes
......
{ {
"name": "@eth-optimism/sdk", "name": "@eth-optimism/sdk",
"version": "1.10.4", "version": "2.0.0",
"description": "[Optimism] Tools for working with Optimism", "description": "[Optimism] Tools for working with Optimism",
"main": "dist/index", "main": "dist/index",
"types": "dist/index", "types": "dist/index",
...@@ -50,7 +50,7 @@ ...@@ -50,7 +50,7 @@
"dependencies": { "dependencies": {
"@eth-optimism/contracts": "0.5.40", "@eth-optimism/contracts": "0.5.40",
"@eth-optimism/core-utils": "0.12.0", "@eth-optimism/core-utils": "0.12.0",
"@eth-optimism/contracts-bedrock": "0.12.1", "@eth-optimism/contracts-bedrock": "0.13.0",
"lodash": "^4.17.21", "lodash": "^4.17.21",
"merkletreejs": "^0.2.27", "merkletreejs": "^0.2.27",
"rlp": "^2.2.7" "rlp": "^2.2.7"
......
...@@ -1005,7 +1005,7 @@ export class CrossChainMessenger { ...@@ -1005,7 +1005,7 @@ export class CrossChainMessenger {
*/ */
public async getChallengePeriodSeconds(): Promise<number> { public async getChallengePeriodSeconds(): Promise<number> {
const challengePeriod = this.bedrock const challengePeriod = this.bedrock
? await this.contracts.l1.OptimismPortal.FINALIZATION_PERIOD_SECONDS() ? await this.contracts.l1.L2OutputOracle.FINALIZATION_PERIOD_SECONDS()
: await this.contracts.l1.StateCommitmentChain.FRAUD_PROOF_WINDOW() : await this.contracts.l1.StateCommitmentChain.FRAUD_PROOF_WINDOW()
return challengePeriod.toNumber() return challengePeriod.toNumber()
} }
......
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