Commit 98291fbc authored by Joshua Gutow's avatar Joshua Gutow Committed by GitHub

Merge branch 'develop' into jg/flags

parents d35c733f af19faea
---
'@eth-optimism/sdk': patch
---
Update the migrated withdrawal gas limit for non goerli networks
......@@ -364,6 +364,13 @@ jobs:
environment:
FOUNDRY_PROFILE: ci
working_directory: packages/contracts-bedrock
- run:
name: validate deploy configs
command: |
yarn validate-deploy-configs || echo "export DEPLOY_CONFIG_STATUS=1" >> "$BASH_ENV"
environment:
FOUNDRY_PROFILE: ci
working_directory: packages/contracts-bedrock
- run:
name: storage snapshot
command: |
......@@ -387,6 +394,10 @@ jobs:
FAILED=1
echo "Gas snapshot failed, see job output for details."
fi
if [[ "$DEPLOY_CONFIG_STATUS" -ne 0 ]]; then
FAILED=1
echo "Deploy configs invalid, see job output for details."
fi
if [[ "$STORAGE_SNAPSHOT_STATUS" -ne 0 ]]; then
echo "Storage snapshot failed, see job output for details."
FAILED=1
......@@ -561,11 +572,11 @@ jobs:
- run:
name: build
command: yarn build
working_directory: packages/atst
working_directory: packages/sdk
- run:
name: lint
command: yarn lint:check
working_directory: packages/atst
working_directory: packages/sdk
- run:
name: make sure anvil l1 is up
command: npx wait-on tcp:8545 && cast block-number --rpc-url http://localhost:8545
......@@ -660,6 +671,47 @@ jobs:
command: npx depcheck
working_directory: integration-tests
atst-tests:
docker:
- image: ethereumoptimism/ci-builder:latest
resource_class: large
steps:
- checkout
- attach_workspace: { at: '.' }
- check-changed:
patterns: atst,contracts-periphery
- restore_cache:
name: Restore Yarn Package Cache
keys:
- yarn-packages-v2-{{ checksum "yarn.lock" }}
- run:
name: anvil
background: true
command: anvil --fork-url $ANVIL_L2_FORK_URL_MAINNET --fork-block-number 92093723
- run:
name: build
command: yarn build
working_directory: packages/atst
- run:
name: typecheck
command: yarn typecheck
working_directory: packages/atst
- run:
name: lint
command: yarn lint:check
working_directory: packages/atst
- run:
name: make sure anvil is up
command: npx wait-on tcp:8545 && cast block-number --rpc-url http://localhost:8545
- run:
name: test
command: yarn test
no_output_timeout: 5m
working_directory: packages/atst
environment:
CI: true
go-lint:
parameters:
module:
......@@ -1094,6 +1146,9 @@ workflows:
- op-bindings-build:
requires:
- yarn-monorepo
- atst-tests:
requires:
- yarn-monorepo
- js-lint-test:
name: actor-tests-tests
coverage_flag: actor-tests-tests
......@@ -1306,6 +1361,20 @@ workflows:
context:
- oplabs-gcr
platforms: "linux/amd64,linux/arm64"
- docker-build:
name: op-program-docker-build
docker_file: op-program/Dockerfile
docker_name: op-program
docker_tags: <<pipeline.git.revision>>,<<pipeline.git.branch>>
docker_context: .
- docker-publish:
name: op-program-docker-publish
docker_file: op-program/Dockerfile
docker_name: op-program
docker_tags: <<pipeline.git.revision>>,<<pipeline.git.branch>>
context:
- oplabs-gcr
platforms: "linux/amd64,linux/arm64"
- docker-build:
name: op-proposer-docker-build
docker_file: op-proposer/Dockerfile
......@@ -1464,4 +1533,4 @@ workflows:
docker_tags: <<pipeline.git.revision>>,latest
docker_context: ./ops/docker/ci-builder
context:
- oplabs-gcr
\ No newline at end of file
- oplabs-gcr
......@@ -187,7 +187,8 @@ module.exports = {
children: [
'/docs/security/faq.md',
'/docs/security/policy.md',
'/docs/security/pause.md'
'/docs/security/pause.md',
'/docs/security/forced-withdrawal.md',
]
},
], // end of sidebar
......
---
title: Forced withdrawal from an OP Stack blockchain
lang: en-US
---
## What is this?
Any assets you own on an OP Stack blockchain are backed by equivalent assets on the underlying L1, locked in a bridge.
In this article you learn how to withdraw these assets directly from L1.
Note that the steps here do require access to an L2 endpoint.
However, that L2 endpoint can be a read-only replica.
## Setup
The code to go along with this article is available at [our tutorials repository](https://github.com/ethereum-optimism/optimism-tutorial/tree/main/op-stack/forced-withdrawal).
1. Clone the repository, move to the correct directory, and install the required dependencies.
```sh
git clone https://github.com/ethereum-optimism/optimism-tutorial.git
cd optimism-tutorial/op-stack/forced-withdrawal
npm install
```
1. Copy the environment setup variables.
```sh
cp .env.example .env
```
1. Edit `.env` to set these variables:
| Variable | Meaning |
| -------------------- | ------- |
| L1URL | URL to L1 (Goerli if you followed the directions on this site)
| L2URL | URL to the L2 from which you are withdrawing
| PRIV_KEY | Private key for an account that has ETH on L2. It also needs ETH on L1 to submit transactions
| OPTIMISM_PORTAL_ADDR | Address of the `OptimismPortalProxy` on L1.
## Withdrawal
### ETH withdrawals
The easiest way to withdraw ETH is to send it to the bridge, or the cross domain messenger, on L2.
1. Enter the Hardhat console.
```sh
npx hardhat console --network l1
```
1. Specify the amount of ETH you want to transfer.
This code transfers one hundred'th of an ETH.
```js
transferAmt = BigInt(0.01 * 1e18)
```
1. Create a contract object for the [`OptimismPortal`](https://github.com/ethereum-optimism/optimism/blob/develop/packages/contracts-bedrock/contracts/L1/OptimismPortal.sol) contract.
```js
optimismContracts = require("@eth-optimism/contracts-bedrock")
optimismPortalData = optimismContracts.getContractDefinition("OptimismPortal")
optimismPortal = new ethers.Contract(process.env.OPTIMISM_PORTAL_ADDR, optimismPortalData.abi, await ethers.getSigner())
```
1. Send the transaction.
```js
txn = await optimismPortal.depositTransaction(
optimismContracts.predeploys.L2StandardBridge,
transferAmt,
1e6, false, []
)
rcpt = await txn.wait()
```
1. To [prove](https://sdk.optimism.io/classes/crosschainmessenger#proveMessage-2) and [finalize](https://sdk.optimism.io/classes/crosschainmessenger#finalizeMessage-2) the message we need the hash.
Optimism's [core-utils package](https://www.npmjs.com/package/@eth-optimism/core-utils) has the necessary function.
```js
optimismCoreUtils = require("@eth-optimism/core-utils")
withdrawalData = new optimismCoreUtils.DepositTx({
from: (await ethers.getSigner()).address,
to: optimismContracts.predeploys.L2StandardBridge,
mint: 0,
value: ethers.BigNumber.from(transferAmt),
gas: 1e6,
isSystemTransaction: false,
data: "",
domain: optimismCoreUtils.SourceHashDomain.UserDeposit,
l1BlockHash: rcpt.blockHash,
logIndex: rcpt.logs[0].logIndex,
})
withdrawalHash = withdrawalData.hash()
```
1. Create the object for the L1 contracts, [as explained in the documentation](../build/sdk.md).
You will create an object similar to this one:
```js
L1Contracts = {
StateCommitmentChain: '0x0000000000000000000000000000000000000000',
CanonicalTransactionChain: '0x0000000000000000000000000000000000000000',
BondManager: '0x0000000000000000000000000000000000000000',
AddressManager: '0x432d810484AdD7454ddb3b5311f0Ac2E95CeceA8',
L1CrossDomainMessenger: '0x27E8cBC25C0Aa2C831a356bbCcc91f4e7c48EeeE',
L1StandardBridge: '0x154EaA56f8cB658bcD5d4b9701e1483A414A14Df',
OptimismPortal: '0x4AD19e14C1FD57986dae669BE4ee9C904431572C',
L2OutputOracle: '0x65B41B7A2550140f57b603472686D743B4b940dB'
}
```
1. Create the data structure for the standard bridge.
```js
bridges = {
Standard: {
l1Bridge: l1Contracts.L1StandardBridge,
l2Bridge: "0x4200000000000000000000000000000000000010",
Adapter: optimismSDK.StandardBridgeAdapter
},
ETH: {
l1Bridge: l1Contracts.L1StandardBridge,
l2Bridge: "0x4200000000000000000000000000000000000010",
Adapter: optimismSDK.ETHBridgeAdapter
}
}
```
1. Create [a cross domain messenger](https://sdk.optimism.io/classes/crosschainmessenger).
This step, and subsequent ETH withdrawal steps, are explained in [this tutorial](https://github.com/ethereum-optimism/optimism-tutorial/tree/main/cross-dom-bridge-eth).
```js
optimismSDK = require("@eth-optimism/sdk")
l2Provider = new ethers.providers.JsonRpcProvider(process.env.L2URL)
await l2Provider._networkPromise
crossChainMessenger = new optimismSDK.CrossChainMessenger({
l1ChainId: ethers.provider.network.chainId,
l2ChainId: l2Provider.network.chainId,
l1SignerOrProvider: await ethers.getSigner(),
l2SignerOrProvider: l2Provider,
bedrock: true,
contracts: {
l1: l1Contracts
},
bridges: bridges
})
```
1. Wait for the message status for the withdrawal to become `READY_TO_PROVE`.
By default the state root is written every four minutes, so you're likely to need to need to wait.
```js
await crossChainMessenger.waitForMessageStatus(withdrawalHash,
optimismSDK.MessageStatus.READY_TO_PROVE)
```
1. Submit the withdrawal proof.
```js
await crossChainMessenger.proveMessage(withdrawalHash)
```
1. Wait for the message status for the withdrawal to become `READY_FOR_RELAY`.
This waits the challenge period (7 days in production, but a lot less on test networks).
```js
await crossChainMessenger.waitForMessageStatus(withdrawalHash,
optimismSDK.MessageStatus.READY_FOR_RELAY)
```
1. Finalize the withdrawal.
See that your balance changes by the withdrawal amount.
```js
myAddr = (await ethers.getSigner()).address
balance0 = await ethers.provider.getBalance(myAddr)
finalTxn = await crossChainMessenger.finalizeMessage(withdrawalHash)
finalRcpt = await finalTxn.wait()
balance1 = await ethers.provider.getBalance(myAddr)
withdrawnAmt = BigInt(balance1)-BigInt(balance0)
```
::: tip transferAmt > withdrawnAmt
Your L1 balance doesn't increase by the entire `transferAmt` because of the cost of `crossChainMessenger.finalizeMessage`, which submits a transaction.
:::
\ No newline at end of file
......@@ -34,6 +34,7 @@ require (
github.com/urfave/cli/v2 v2.17.2-0.20221006022127-8f469abc00aa
golang.org/x/crypto v0.6.0
golang.org/x/exp v0.0.0-20230213192124-5e25df0256eb
golang.org/x/sync v0.1.0
golang.org/x/term v0.5.0
golang.org/x/time v0.0.0-20220922220347-f3bd1da661af
)
......@@ -176,7 +177,6 @@ require (
go.uber.org/zap v1.24.0 // indirect
golang.org/x/mod v0.8.0 // indirect
golang.org/x/net v0.7.0 // indirect
golang.org/x/sync v0.1.0 // indirect
golang.org/x/sys v0.5.0 // indirect
golang.org/x/text v0.7.0 // indirect
golang.org/x/tools v0.6.0 // indirect
......@@ -189,6 +189,6 @@ require (
nhooyr.io/websocket v1.8.7 // indirect
)
replace github.com/ethereum/go-ethereum v1.11.5 => github.com/ethereum-optimism/op-geth v1.11.2-de8c5df46.0.20230324105532-555b76f39878
replace github.com/ethereum/go-ethereum v1.11.5 => github.com/ethereum-optimism/op-geth v1.101105.1-0.20230420183214-24ae687be390
//replace github.com/ethereum/go-ethereum v1.11.5 => ../go-ethereum
......@@ -184,8 +184,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/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/op-geth v1.11.2-de8c5df46.0.20230324105532-555b76f39878 h1:pk3lFrP6zay7+jT+yoFAWxvGbP1Z/5lsorimXGrQoxE=
github.com/ethereum-optimism/op-geth v1.11.2-de8c5df46.0.20230324105532-555b76f39878/go.mod h1:SGLXBOtu2JlKrNoUG76EatI2uJX/WZRY4nmEyvE9Q38=
github.com/ethereum-optimism/op-geth v1.101105.1-0.20230420183214-24ae687be390 h1:8Ijv72z/XSpb3ep/hiOEdRKwStGsV8Ve9knU1Ck8Mf8=
github.com/ethereum-optimism/op-geth v1.101105.1-0.20230420183214-24ae687be390/go.mod h1:SGLXBOtu2JlKrNoUG76EatI2uJX/WZRY4nmEyvE9Q38=
github.com/fasthttp-contrib/websocket v0.0.0-20160511215533-1f3b11f56072/go.mod h1:duJ4Jxv5lDcvg4QuQr0oowTf7dz4/CR8NtyCooz9HL8=
github.com/fatih/structs v1.1.0/go.mod h1:9NiDSp5zOcgEDl+j00MP/WkGVPOlPRLejGD8Ga6PJ7M=
github.com/fjl/memsize v0.0.1 h1:+zhkb+dhUgx0/e+M8sF0QqiouvMQUiKR+QYvdxIOKcQ=
......
......@@ -199,6 +199,11 @@ func (s *channelManager) TxData(l1Head eth.BlockID) (txData, error) {
return txData{}, io.EOF
}
// we have blocks, but we cannot add them to the channel right now
if s.pendingChannel != nil && s.pendingChannel.IsFull() {
return txData{}, io.EOF
}
if err := s.ensurePendingChannel(l1Head); err != nil {
return txData{}, err
}
......
......@@ -26,8 +26,9 @@ type Config struct {
RollupNode *sources.RollupClient
TxManager txmgr.TxManager
NetworkTimeout time.Duration
PollInterval time.Duration
NetworkTimeout time.Duration
PollInterval time.Duration
MaxPendingTransactions uint64
// RollupConfig is queried at startup
Rollup *rollup.Config
......@@ -76,6 +77,10 @@ type CLIConfig struct {
// and creating a new batch.
PollInterval time.Duration
// MaxPendingTransactions is the maximum number of concurrent pending
// transactions sent to the transaction manager.
MaxPendingTransactions uint64
// MaxL1TxSize is the maximum size of a batch tx submitted to L1.
MaxL1TxSize uint64
......@@ -128,16 +133,17 @@ func NewConfig(ctx *cli.Context) CLIConfig {
PollInterval: ctx.GlobalDuration(flags.PollIntervalFlag.Name),
/* Optional Flags */
MaxChannelDuration: ctx.GlobalUint64(flags.MaxChannelDurationFlag.Name),
MaxL1TxSize: ctx.GlobalUint64(flags.MaxL1TxSizeBytesFlag.Name),
TargetL1TxSize: ctx.GlobalUint64(flags.TargetL1TxSizeBytesFlag.Name),
TargetNumFrames: ctx.GlobalInt(flags.TargetNumFramesFlag.Name),
ApproxComprRatio: ctx.GlobalFloat64(flags.ApproxComprRatioFlag.Name),
Stopped: ctx.GlobalBool(flags.StoppedFlag.Name),
TxMgrConfig: txmgr.ReadCLIConfig(ctx),
RPCConfig: rpc.ReadCLIConfig(ctx),
LogConfig: oplog.ReadCLIConfig(ctx),
MetricsConfig: opmetrics.ReadCLIConfig(ctx),
PprofConfig: oppprof.ReadCLIConfig(ctx),
MaxPendingTransactions: ctx.GlobalUint64(flags.MaxPendingTransactionsFlag.Name),
MaxChannelDuration: ctx.GlobalUint64(flags.MaxChannelDurationFlag.Name),
MaxL1TxSize: ctx.GlobalUint64(flags.MaxL1TxSizeBytesFlag.Name),
TargetL1TxSize: ctx.GlobalUint64(flags.TargetL1TxSizeBytesFlag.Name),
TargetNumFrames: ctx.GlobalInt(flags.TargetNumFramesFlag.Name),
ApproxComprRatio: ctx.GlobalFloat64(flags.ApproxComprRatioFlag.Name),
Stopped: ctx.GlobalBool(flags.StoppedFlag.Name),
TxMgrConfig: txmgr.ReadCLIConfig(ctx),
RPCConfig: rpc.ReadCLIConfig(ctx),
LogConfig: oplog.ReadCLIConfig(ctx),
MetricsConfig: opmetrics.ReadCLIConfig(ctx),
PprofConfig: oppprof.ReadCLIConfig(ctx),
}
}
......@@ -75,13 +75,14 @@ func NewBatchSubmitterFromCLIConfig(cfg CLIConfig, l log.Logger, m metrics.Metri
}
batcherCfg := Config{
L1Client: l1Client,
L2Client: l2Client,
RollupNode: rollupClient,
PollInterval: cfg.PollInterval,
NetworkTimeout: cfg.TxMgrConfig.NetworkTimeout,
TxManager: txManager,
Rollup: rcfg,
L1Client: l1Client,
L2Client: l2Client,
RollupNode: rollupClient,
PollInterval: cfg.PollInterval,
MaxPendingTransactions: cfg.MaxPendingTransactions,
NetworkTimeout: cfg.TxMgrConfig.NetworkTimeout,
TxManager: txManager,
Rollup: rcfg,
Channel: ChannelConfig{
SeqWindowSize: rcfg.SeqWindowSize,
ChannelTimeout: rcfg.ChannelTimeout,
......@@ -286,13 +287,23 @@ func (l *BatchSubmitter) loop() {
ticker := time.NewTicker(l.PollInterval)
defer ticker.Stop()
receiptsCh := make(chan txmgr.TxReceipt[txData])
queue := txmgr.NewQueue[txData](l.killCtx, l.txMgr, l.MaxPendingTransactions)
for {
select {
case <-ticker.C:
l.loadBlocksIntoState(l.shutdownCtx)
l.publishStateToL1(l.killCtx)
l.publishStateToL1(queue, receiptsCh, false)
case r := <-receiptsCh:
l.handleReceipt(r)
case <-l.shutdownCtx.Done():
l.publishStateToL1(l.killCtx)
err := l.state.Close()
if err != nil {
l.log.Error("error closing the channel manager", "err", err)
}
l.publishStateToL1(queue, receiptsCh, true)
return
}
}
......@@ -300,70 +311,90 @@ func (l *BatchSubmitter) loop() {
// publishStateToL1 loops through the block data loaded into `state` and
// submits the associated data to the L1 in the form of channel frames.
func (l *BatchSubmitter) publishStateToL1(ctx context.Context) {
for {
// Attempt to gracefully terminate the current channel, ensuring that no new frames will be
// produced. Any remaining frames must still be published to the L1 to prevent stalling.
select {
case <-ctx.Done():
err := l.state.Close()
if err != nil {
l.log.Error("error closing the channel manager", "err", err)
func (l *BatchSubmitter) publishStateToL1(queue *txmgr.Queue[txData], receiptsCh chan txmgr.TxReceipt[txData], drain bool) {
txDone := make(chan struct{})
// send/wait and receipt reading must be on a separate goroutines to avoid deadlocks
go func() {
defer func() {
if drain {
// if draining, we wait for all transactions to complete
queue.Wait()
}
case <-l.shutdownCtx.Done():
err := l.state.Close()
close(txDone)
}()
for {
err := l.publishTxToL1(l.killCtx, queue, receiptsCh)
if err != nil {
l.log.Error("error closing the channel manager", "err", err)
if drain && err != io.EOF {
l.log.Error("error sending tx while draining state", "err", err)
}
return
}
default:
}
}()
l1tip, err := l.l1Tip(ctx)
if err != nil {
l.log.Error("Failed to query L1 tip", "error", err)
for {
select {
case r := <-receiptsCh:
l.handleReceipt(r)
case <-txDone:
return
}
l.recordL1Tip(l1tip)
}
}
// Collect next transaction data
txdata, err := l.state.TxData(l1tip.ID())
if err == io.EOF {
l.log.Trace("no transaction data available")
break
} else if err != nil {
l.log.Error("unable to get tx data", "err", err)
break
}
// Record TX Status
if receipt, err := l.sendTransaction(ctx, txdata.Bytes()); err != nil {
l.recordFailedTx(txdata.ID(), err)
} else {
l.recordConfirmedTx(txdata.ID(), receipt)
}
// publishTxToL1 submits a single state tx to the L1
func (l *BatchSubmitter) publishTxToL1(ctx context.Context, queue *txmgr.Queue[txData], receiptsCh chan txmgr.TxReceipt[txData]) error {
// send all available transactions
l1tip, err := l.l1Tip(ctx)
if err != nil {
l.log.Error("Failed to query L1 tip", "error", err)
return err
}
l.recordL1Tip(l1tip)
// Collect next transaction data
txdata, err := l.state.TxData(l1tip.ID())
if err == io.EOF {
l.log.Trace("no transaction data available")
return err
} else if err != nil {
l.log.Error("unable to get tx data", "err", err)
return err
}
l.sendTransaction(txdata, queue, receiptsCh)
return nil
}
// sendTransaction creates & submits a transaction to the batch inbox address with the given `data`.
// It currently uses the underlying `txmgr` to handle transaction sending & price management.
// This is a blocking method. It should not be called concurrently.
func (l *BatchSubmitter) sendTransaction(ctx context.Context, data []byte) (*types.Receipt, error) {
func (l *BatchSubmitter) sendTransaction(txdata txData, queue *txmgr.Queue[txData], receiptsCh chan txmgr.TxReceipt[txData]) {
// Do the gas estimation offline. A value of 0 will cause the [txmgr] to estimate the gas limit.
data := txdata.Bytes()
intrinsicGas, err := core.IntrinsicGas(data, nil, false, true, true, false)
if err != nil {
return nil, fmt.Errorf("failed to calculate intrinsic gas: %w", err)
l.log.Error("Failed to calculate intrinsic gas", "error", err)
return
}
// Send the transaction through the txmgr
if receipt, err := l.txMgr.Send(ctx, txmgr.TxCandidate{
candidate := txmgr.TxCandidate{
To: &l.Rollup.BatchInboxAddress,
TxData: data,
GasLimit: intrinsicGas,
}); err != nil {
l.log.Warn("unable to publish tx", "err", err, "data_size", len(data))
return nil, err
}
queue.Send(txdata, candidate, receiptsCh)
}
func (l *BatchSubmitter) handleReceipt(r txmgr.TxReceipt[txData]) {
// Record TX Status
if r.Err != nil {
l.log.Warn("unable to publish tx", "err", r.Err, "data_size", r.ID.Len())
l.recordFailedTx(r.ID.ID(), r.Err)
} else {
l.log.Info("tx successfully published", "tx_hash", receipt.TxHash, "data_size", len(data))
return receipt, nil
l.log.Info("tx successfully published", "tx_hash", r.Receipt.TxHash, "data_size", r.ID.Len())
l.recordConfirmedTx(r.ID.ID(), r.Receipt)
}
}
......
......@@ -26,6 +26,10 @@ func (td *txData) Bytes() []byte {
return append([]byte{derive.DerivationVersion0}, td.frame.data...)
}
func (td *txData) Len() int {
return 1 + len(td.frame.data)
}
// Frame returns the single frame of this tx data.
//
// Note: when the batcher is changed to possibly send multiple frames per tx,
......
......@@ -49,6 +49,12 @@ var (
Value: 6 * time.Second,
EnvVar: opservice.PrefixEnvVar(envVarPrefix, "POLL_INTERVAL"),
}
MaxPendingTransactionsFlag = cli.Uint64Flag{
Name: "max-pending-tx",
Usage: "The maximum number of pending transactions. 0 for no limit.",
Value: 1,
EnvVar: opservice.PrefixEnvVar(envVarPrefix, "MAX_PENDING_TX"),
}
MaxChannelDurationFlag = cli.Uint64Flag{
Name: "max-channel-duration",
Usage: "The maximum duration of L1-blocks to keep a channel open. 0 to disable.",
......@@ -97,6 +103,7 @@ var requiredFlags = []cli.Flag{
var optionalFlags = []cli.Flag{
SubSafetyMarginFlag,
PollIntervalFlag,
MaxPendingTransactionsFlag,
MaxChannelDurationFlag,
MaxL1TxSizeBytesFlag,
TargetL1TxSizeBytesFlag,
......
......@@ -30,8 +30,8 @@ var (
// L1CrossDomainMessengerMetaData contains all meta data concerning the L1CrossDomainMessenger contract.
var L1CrossDomainMessengerMetaData = &bind.MetaData{
ABI: "[{\"inputs\":[{\"internalType\":\"contractOptimismPortal\",\"name\":\"_portal\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"msgHash\",\"type\":\"bytes32\"}],\"name\":\"FailedRelayedMessage\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint8\",\"name\":\"version\",\"type\":\"uint8\"}],\"name\":\"Initialized\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"msgHash\",\"type\":\"bytes32\"}],\"name\":\"RelayedMessage\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"target\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"message\",\"type\":\"bytes\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"messageNonce\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"gasLimit\",\"type\":\"uint256\"}],\"name\":\"SentMessage\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"}],\"name\":\"SentMessageExtension1\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"MESSAGE_VERSION\",\"outputs\":[{\"internalType\":\"uint16\",\"name\":\"\",\"type\":\"uint16\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"MIN_GAS_CALLDATA_OVERHEAD\",\"outputs\":[{\"internalType\":\"uint64\",\"name\":\"\",\"type\":\"uint64\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"MIN_GAS_CONSTANT_OVERHEAD\",\"outputs\":[{\"internalType\":\"uint64\",\"name\":\"\",\"type\":\"uint64\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"MIN_GAS_DYNAMIC_OVERHEAD_DENOMINATOR\",\"outputs\":[{\"internalType\":\"uint64\",\"name\":\"\",\"type\":\"uint64\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"MIN_GAS_DYNAMIC_OVERHEAD_NUMERATOR\",\"outputs\":[{\"internalType\":\"uint64\",\"name\":\"\",\"type\":\"uint64\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"OTHER_MESSENGER\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"PORTAL\",\"outputs\":[{\"internalType\":\"contractOptimismPortal\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"_message\",\"type\":\"bytes\"},{\"internalType\":\"uint32\",\"name\":\"_minGasLimit\",\"type\":\"uint32\"}],\"name\":\"baseGas\",\"outputs\":[{\"internalType\":\"uint64\",\"name\":\"\",\"type\":\"uint64\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"name\":\"failedMessages\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"initialize\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"messageNonce\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_nonce\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"_sender\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_target\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"_value\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_minGasLimit\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"_message\",\"type\":\"bytes\"}],\"name\":\"relayMessage\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_target\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"_message\",\"type\":\"bytes\"},{\"internalType\":\"uint32\",\"name\":\"_minGasLimit\",\"type\":\"uint32\"}],\"name\":\"sendMessage\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"name\":\"successfulMessages\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"version\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"xDomainMessageSender\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"}]",
Bin: "0x6101206040523480156200001257600080fd5b50604051620021b8380380620021b883398101604081905262000035916200025c565b734200000000000000000000000000000000000007608052600160a052600260c052600060e0526001600160a01b03811661010052620000746200007b565b506200028e565b600054600160a81b900460ff1615808015620000a457506000546001600160a01b90910460ff16105b80620000db5750620000c130620001c860201b6200116f1760201c565b158015620000db5750600054600160a01b900460ff166001145b620001445760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201526d191e481a5b9a5d1a585b1a5e995960921b60648201526084015b60405180910390fd5b6000805460ff60a01b1916600160a01b179055801562000172576000805460ff60a81b1916600160a81b1790555b6200017c620001d7565b8015620001c5576000805460ff60a81b19169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b50565b6001600160a01b03163b151590565b600054600160a81b900460ff16620002465760405162461bcd60e51b815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201526a6e697469616c697a696e6760a81b60648201526084016200013b565b60cc80546001600160a01b03191661dead179055565b6000602082840312156200026f57600080fd5b81516001600160a01b03811681146200028757600080fd5b9392505050565b60805160a05160c05160e05161010051611ebb620002fd60003960008181610153015281816111c8015281816114aa0152818161150b01526115d70152600061064901526000610620015260006105f70152600081816102620152818161039101526114d40152611ebb6000f3fe6080604052600436106100f35760003560e01c80637dea7cc31161008a578063b1b1b20911610059578063b1b1b209146102c4578063b28ade25146102f4578063d764ad0b14610314578063ecc704281461032757600080fd5b80637dea7cc3146102245780638129fc1c1461023b5780639fce812c14610250578063a4e7f8bd1461028457600080fd5b80633dbb202b116100c65780633dbb202b146101b05780633f827a5a146101c557806354fd4d50146101ed5780636e296e451461020f57600080fd5b8063028f85f7146100f85780630c5684981461012b5780630ff754ea146101415780632828d7e81461019a575b600080fd5b34801561010457600080fd5b5061010d601081565b60405167ffffffffffffffff90911681526020015b60405180910390f35b34801561013757600080fd5b5061010d6103e881565b34801561014d57600080fd5b506101757f000000000000000000000000000000000000000000000000000000000000000081565b60405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610122565b3480156101a657600080fd5b5061010d6103f881565b6101c36101be366004611841565b61038c565b005b3480156101d157600080fd5b506101da600181565b60405161ffff9091168152602001610122565b3480156101f957600080fd5b506102026105f0565b6040516101229190611922565b34801561021b57600080fd5b50610175610693565b34801561023057600080fd5b5061010d62030d4081565b34801561024757600080fd5b506101c361077f565b34801561025c57600080fd5b506101757f000000000000000000000000000000000000000000000000000000000000000081565b34801561029057600080fd5b506102b461029f36600461193c565b60ce6020526000908152604090205460ff1681565b6040519015158152602001610122565b3480156102d057600080fd5b506102b46102df36600461193c565b60cb6020526000908152604090205460ff1681565b34801561030057600080fd5b5061010d61030f366004611955565b61097c565b6101c36103223660046119a9565b6109c8565b34801561033357600080fd5b5061037e60cd547dffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff167e010000000000000000000000000000000000000000000000000000000000001790565b604051908152602001610122565b6104c57f00000000000000000000000000000000000000000000000000000000000000006103bb85858561097c565b347fd764ad0b0000000000000000000000000000000000000000000000000000000061042760cd547dffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff167e010000000000000000000000000000000000000000000000000000000000001790565b338a34898c8c6040516024016104439796959493929190611a78565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff000000000000000000000000000000000000000000000000000000009093169290921790915261118b565b8373ffffffffffffffffffffffffffffffffffffffff167fcb0f7ffd78f9aee47a248fae8db181db6eee833039123e026dcbff529522e52a33858561054a60cd547dffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff167e010000000000000000000000000000000000000000000000000000000000001790565b8660405161055c959493929190611ad7565b60405180910390a260405134815233907f8ebb2ec2465bdb2a06a66fc37a0963af8a2a6a1479d81d56fdb8cbb98096d5469060200160405180910390a2505060cd80547dffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff808216600101167fffff0000000000000000000000000000000000000000000000000000000000009091161790555050565b606061061b7f0000000000000000000000000000000000000000000000000000000000000000611240565b6106447f0000000000000000000000000000000000000000000000000000000000000000611240565b61066d7f0000000000000000000000000000000000000000000000000000000000000000611240565b60405160200161067f93929190611b25565b604051602081830303815290604052905090565b60cc5460009073ffffffffffffffffffffffffffffffffffffffff167fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff215301610762576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603560248201527f43726f7373446f6d61696e4d657373656e6765723a2078446f6d61696e4d657360448201527f7361676553656e646572206973206e6f7420736574000000000000000000000060648201526084015b60405180910390fd5b5060cc5473ffffffffffffffffffffffffffffffffffffffff1690565b6000547501000000000000000000000000000000000000000000900460ff16158080156107ca575060005460017401000000000000000000000000000000000000000090910460ff16105b806107fc5750303b1580156107fc575060005474010000000000000000000000000000000000000000900460ff166001145b610888576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a65640000000000000000000000000000000000006064820152608401610759565b600080547fffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffff1674010000000000000000000000000000000000000000179055801561090e57600080547fffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffffff1675010000000000000000000000000000000000000000001790555b610916611375565b801561097957600080547fffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffffff169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b50565b600062030d4061098d601085611bca565b6103e86109a26103f863ffffffff8716611bca565b6109ac9190611c29565b6109b69190611c50565b6109c09190611c50565b949350505050565b60f087901c60028110610a83576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604d60248201527f43726f7373446f6d61696e4d657373656e6765723a206f6e6c7920766572736960448201527f6f6e2030206f722031206d657373616765732061726520737570706f7274656460648201527f20617420746869732074696d6500000000000000000000000000000000000000608482015260a401610759565b8061ffff16600003610b78576000610ad4878986868080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152508f925061144e915050565b600081815260cb602052604090205490915060ff1615610b76576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603760248201527f43726f7373446f6d61696e4d657373656e6765723a206c65676163792077697460448201527f6864726177616c20616c72656164792072656c617965640000000000000000006064820152608401610759565b505b6000610bbe898989898989898080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061146d92505050565b9050610bc8611490565b15610c0057853414610bdc57610bdc611c7c565b600081815260ce602052604090205460ff1615610bfb57610bfb611c7c565b610d52565b3415610cb4576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152605060248201527f43726f7373446f6d61696e4d657373656e6765723a2076616c7565206d75737460448201527f206265207a65726f20756e6c657373206d6573736167652069732066726f6d2060648201527f612073797374656d206164647265737300000000000000000000000000000000608482015260a401610759565b600081815260ce602052604090205460ff16610d52576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603060248201527f43726f7373446f6d61696e4d657373656e6765723a206d65737361676520636160448201527f6e6e6f74206265207265706c61796564000000000000000000000000000000006064820152608401610759565b610d5b876115b4565b15610e0e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604360248201527f43726f7373446f6d61696e4d657373656e6765723a2063616e6e6f742073656e60448201527f64206d65737361676520746f20626c6f636b65642073797374656d206164647260648201527f6573730000000000000000000000000000000000000000000000000000000000608482015260a401610759565b600081815260cb602052604090205460ff1615610ead576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603660248201527f43726f7373446f6d61696e4d657373656e6765723a206d65737361676520686160448201527f7320616c7265616479206265656e2072656c61796564000000000000000000006064820152608401610759565b60cc5473ffffffffffffffffffffffffffffffffffffffff1661dead14610f3357600081815260ce602052604080822080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660011790555182917f99d0e048484baa1b1540b1367cb128acd7ab2946d1ed91ec10e3c85e4bf51b8f91a25050611161565b60cc80547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff8a16179055604080516020601f8601819004810282018101909252848152600091610fb9918a9189918b918a908a908190840183828082843760009201919091525061162b92505050565b60cc80547fffffffffffffffffffffffff00000000000000000000000000000000000000001661dead1790559050801561105057600082815260cb602052604080822080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660011790555183917f4641df4a962071e12719d8c8c8e5ac7fc4d97b927346a3d7a335b1f7517e133c91a261115d565b600082815260ce602052604080822080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660011790555183917f99d0e048484baa1b1540b1367cb128acd7ab2946d1ed91ec10e3c85e4bf51b8f91a27fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff320161115d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602d60248201527f43726f7373446f6d61696e4d657373656e6765723a206661696c656420746f2060448201527f72656c6179206d657373616765000000000000000000000000000000000000006064820152608401610759565b5050505b50505050505050565b905090565b73ffffffffffffffffffffffffffffffffffffffff163b151590565b6040517fe9e05c4200000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000169063e9e05c42908490611208908890839089906000908990600401611cab565b6000604051808303818588803b15801561122157600080fd5b505af1158015611235573d6000803e3d6000fd5b505050505050505050565b60608160000361128357505060408051808201909152600181527f3000000000000000000000000000000000000000000000000000000000000000602082015290565b8160005b81156112ad578061129781611d03565b91506112a69050600a83611d3b565b9150611287565b60008167ffffffffffffffff8111156112c8576112c8611d4f565b6040519080825280601f01601f1916602001820160405280156112f2576020820181803683370190505b5090505b84156109c057611307600183611d7e565b9150611314600a86611d95565b61131f906030611da9565b60f81b81838151811061133457611334611dc1565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a90535061136e600a86611d3b565b94506112f6565b6000547501000000000000000000000000000000000000000000900460ff16611420576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e670000000000000000000000000000000000000000006064820152608401610759565b60cc80547fffffffffffffffffffffffff00000000000000000000000000000000000000001661dead179055565b600061145c85858585611685565b805190602001209050949350505050565b600061147d87878787878761171e565b8051906020012090509695505050505050565b60003373ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000001614801561116a57507f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff167f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16639bf62d826040518163ffffffff1660e01b8152600401602060405180830381865afa158015611574573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906115989190611df0565b73ffffffffffffffffffffffffffffffffffffffff1614905090565b600073ffffffffffffffffffffffffffffffffffffffff821630148061162557507f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16145b92915050565b600080603f60c88601604002045a101561166e576308c379a06000526020805278185361666543616c6c3a204e6f7420656e6f756768206761736058526064601cfd5b600080845160208601878a5af19695505050505050565b60608484848460405160240161169e9493929190611e0d565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fcbd4ece9000000000000000000000000000000000000000000000000000000001790529050949350505050565b606086868686868660405160240161173b96959493929190611e57565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fd764ad0b0000000000000000000000000000000000000000000000000000000017905290509695505050505050565b73ffffffffffffffffffffffffffffffffffffffff8116811461097957600080fd5b60008083601f8401126117f157600080fd5b50813567ffffffffffffffff81111561180957600080fd5b60208301915083602082850101111561182157600080fd5b9250929050565b803563ffffffff8116811461183c57600080fd5b919050565b6000806000806060858703121561185757600080fd5b8435611862816117bd565b9350602085013567ffffffffffffffff81111561187e57600080fd5b61188a878288016117df565b909450925061189d905060408601611828565b905092959194509250565b60005b838110156118c35781810151838201526020016118ab565b838111156118d2576000848401525b50505050565b600081518084526118f08160208601602086016118a8565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b60208152600061193560208301846118d8565b9392505050565b60006020828403121561194e57600080fd5b5035919050565b60008060006040848603121561196a57600080fd5b833567ffffffffffffffff81111561198157600080fd5b61198d868287016117df565b90945092506119a0905060208501611828565b90509250925092565b600080600080600080600060c0888a0312156119c457600080fd5b8735965060208801356119d6816117bd565b955060408801356119e6816117bd565b9450606088013593506080880135925060a088013567ffffffffffffffff811115611a1057600080fd5b611a1c8a828b016117df565b989b979a50959850939692959293505050565b8183528181602085013750600060208284010152600060207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f840116840101905092915050565b878152600073ffffffffffffffffffffffffffffffffffffffff808916602084015280881660408401525085606083015263ffffffff8516608083015260c060a0830152611aca60c083018486611a2f565b9998505050505050505050565b73ffffffffffffffffffffffffffffffffffffffff86168152608060208201526000611b07608083018688611a2f565b905083604083015263ffffffff831660608301529695505050505050565b60008451611b378184602089016118a8565b80830190507f2e000000000000000000000000000000000000000000000000000000000000008082528551611b73816001850160208a016118a8565b60019201918201528351611b8e8160028401602088016118a8565b0160020195945050505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b600067ffffffffffffffff80831681851681830481118215151615611bf157611bf1611b9b565b02949350505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b600067ffffffffffffffff80841680611c4457611c44611bfa565b92169190910492915050565b600067ffffffffffffffff808316818516808303821115611c7357611c73611b9b565b01949350505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052600160045260246000fd5b73ffffffffffffffffffffffffffffffffffffffff8616815284602082015267ffffffffffffffff84166040820152821515606082015260a060808201526000611cf860a08301846118d8565b979650505050505050565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203611d3457611d34611b9b565b5060010190565b600082611d4a57611d4a611bfa565b500490565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b600082821015611d9057611d90611b9b565b500390565b600082611da457611da4611bfa565b500690565b60008219821115611dbc57611dbc611b9b565b500190565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b600060208284031215611e0257600080fd5b8151611935816117bd565b600073ffffffffffffffffffffffffffffffffffffffff808716835280861660208401525060806040830152611e4660808301856118d8565b905082606083015295945050505050565b868152600073ffffffffffffffffffffffffffffffffffffffff808816602084015280871660408401525084606083015283608083015260c060a0830152611ea260c08301846118d8565b9897505050505050505056fea164736f6c634300080f000a",
ABI: "[{\"inputs\":[{\"internalType\":\"contractOptimismPortal\",\"name\":\"_portal\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"msgHash\",\"type\":\"bytes32\"}],\"name\":\"FailedRelayedMessage\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint8\",\"name\":\"version\",\"type\":\"uint8\"}],\"name\":\"Initialized\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"msgHash\",\"type\":\"bytes32\"}],\"name\":\"RelayedMessage\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"target\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"message\",\"type\":\"bytes\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"messageNonce\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"gasLimit\",\"type\":\"uint256\"}],\"name\":\"SentMessage\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"}],\"name\":\"SentMessageExtension1\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"MESSAGE_VERSION\",\"outputs\":[{\"internalType\":\"uint16\",\"name\":\"\",\"type\":\"uint16\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"MIN_GAS_CALLDATA_OVERHEAD\",\"outputs\":[{\"internalType\":\"uint64\",\"name\":\"\",\"type\":\"uint64\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"MIN_GAS_DYNAMIC_OVERHEAD_DENOMINATOR\",\"outputs\":[{\"internalType\":\"uint64\",\"name\":\"\",\"type\":\"uint64\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"MIN_GAS_DYNAMIC_OVERHEAD_NUMERATOR\",\"outputs\":[{\"internalType\":\"uint64\",\"name\":\"\",\"type\":\"uint64\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"OTHER_MESSENGER\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"PORTAL\",\"outputs\":[{\"internalType\":\"contractOptimismPortal\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"RELAY_CALL_OVERHEAD\",\"outputs\":[{\"internalType\":\"uint64\",\"name\":\"\",\"type\":\"uint64\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"RELAY_CONSTANT_OVERHEAD\",\"outputs\":[{\"internalType\":\"uint64\",\"name\":\"\",\"type\":\"uint64\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"RELAY_GAS_CHECK_BUFFER\",\"outputs\":[{\"internalType\":\"uint64\",\"name\":\"\",\"type\":\"uint64\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"RELAY_RESERVED_GAS\",\"outputs\":[{\"internalType\":\"uint64\",\"name\":\"\",\"type\":\"uint64\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"_message\",\"type\":\"bytes\"},{\"internalType\":\"uint32\",\"name\":\"_minGasLimit\",\"type\":\"uint32\"}],\"name\":\"baseGas\",\"outputs\":[{\"internalType\":\"uint64\",\"name\":\"\",\"type\":\"uint64\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"name\":\"failedMessages\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"initialize\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"messageNonce\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_nonce\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"_sender\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_target\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"_value\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_minGasLimit\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"_message\",\"type\":\"bytes\"}],\"name\":\"relayMessage\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_target\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"_message\",\"type\":\"bytes\"},{\"internalType\":\"uint32\",\"name\":\"_minGasLimit\",\"type\":\"uint32\"}],\"name\":\"sendMessage\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"name\":\"successfulMessages\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"version\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"xDomainMessageSender\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"}]",
Bin: "0x6101206040523480156200001257600080fd5b50604051620023153803806200231583398101604081905262000035916200025c565b734200000000000000000000000000000000000007608052600160a052600360c052600060e0526001600160a01b03811661010052620000746200007b565b506200028e565b600054600160a81b900460ff1615808015620000a457506000546001600160a01b90910460ff16105b80620000db5750620000c130620001c860201b620012f11760201c565b158015620000db5750600054600160a01b900460ff166001145b620001445760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201526d191e481a5b9a5d1a585b1a5e995960921b60648201526084015b60405180910390fd5b6000805460ff60a01b1916600160a01b179055801562000172576000805460ff60a81b1916600160a81b1790555b6200017c620001d7565b8015620001c5576000805460ff60a81b19169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b50565b6001600160a01b03163b151590565b600054600160a81b900460ff16620002465760405162461bcd60e51b815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201526a6e697469616c697a696e6760a81b60648201526084016200013b565b60cc80546001600160a01b03191661dead179055565b6000602082840312156200026f57600080fd5b81516001600160a01b03811681146200028757600080fd5b9392505050565b60805160a05160c05160e05161010051612018620002fd600039600081816101a30152818161134a0152818161162c0152818161168d0152611759015260006106c40152600061069b015260006106720152600081816102dd0152818161040c015261165601526120186000f3fe6080604052600436106101445760003560e01c80636e296e45116100c0578063a4e7f8bd11610074578063b28ade2511610059578063b28ade251461036f578063d764ad0b1461038f578063ecc70428146103a257600080fd5b8063a4e7f8bd146102ff578063b1b1b2091461033f57600080fd5b806383a74074116100a557806383a74074146102b45780638cbeeef21461023c5780639fce812c146102cb57600080fd5b80636e296e451461028a5780638129fc1c1461029f57600080fd5b80633dbb202b116101175780634c1d6a69116100fc5780634c1d6a691461023c57806354fd4d50146102525780635644cfdf1461027457600080fd5b80633dbb202b146101ff5780633f827a5a1461021457600080fd5b8063028f85f7146101495780630c5684981461017c5780630ff754ea146101915780632828d7e8146101ea575b600080fd5b34801561015557600080fd5b5061015e601081565b60405167ffffffffffffffff90911681526020015b60405180910390f35b34801561018857600080fd5b5061015e603f81565b34801561019d57600080fd5b506101c57f000000000000000000000000000000000000000000000000000000000000000081565b60405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610173565b3480156101f657600080fd5b5061015e604081565b61021261020d36600461199e565b610407565b005b34801561022057600080fd5b50610229600181565b60405161ffff9091168152602001610173565b34801561024857600080fd5b5061015e619c4081565b34801561025e57600080fd5b5061026761066b565b6040516101739190611a7f565b34801561028057600080fd5b5061015e61138881565b34801561029657600080fd5b506101c561070e565b3480156102ab57600080fd5b506102126107fa565b3480156102c057600080fd5b5061015e62030d4081565b3480156102d757600080fd5b506101c57f000000000000000000000000000000000000000000000000000000000000000081565b34801561030b57600080fd5b5061032f61031a366004611a99565b60ce6020526000908152604090205460ff1681565b6040519015158152602001610173565b34801561034b57600080fd5b5061032f61035a366004611a99565b60cb6020526000908152604090205460ff1681565b34801561037b57600080fd5b5061015e61038a366004611ab2565b6109f7565b61021261039d366004611b06565b610a65565b3480156103ae57600080fd5b506103f960cd547dffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff167e010000000000000000000000000000000000000000000000000000000000001790565b604051908152602001610173565b6105407f00000000000000000000000000000000000000000000000000000000000000006104368585856109f7565b347fd764ad0b000000000000000000000000000000000000000000000000000000006104a260cd547dffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff167e010000000000000000000000000000000000000000000000000000000000001790565b338a34898c8c6040516024016104be9796959493929190611bd5565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff000000000000000000000000000000000000000000000000000000009093169290921790915261130d565b8373ffffffffffffffffffffffffffffffffffffffff167fcb0f7ffd78f9aee47a248fae8db181db6eee833039123e026dcbff529522e52a3385856105c560cd547dffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff167e010000000000000000000000000000000000000000000000000000000000001790565b866040516105d7959493929190611c34565b60405180910390a260405134815233907f8ebb2ec2465bdb2a06a66fc37a0963af8a2a6a1479d81d56fdb8cbb98096d5469060200160405180910390a2505060cd80547dffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff808216600101167fffff0000000000000000000000000000000000000000000000000000000000009091161790555050565b60606106967f00000000000000000000000000000000000000000000000000000000000000006113c2565b6106bf7f00000000000000000000000000000000000000000000000000000000000000006113c2565b6106e87f00000000000000000000000000000000000000000000000000000000000000006113c2565b6040516020016106fa93929190611c82565b604051602081830303815290604052905090565b60cc5460009073ffffffffffffffffffffffffffffffffffffffff167fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff2153016107dd576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603560248201527f43726f7373446f6d61696e4d657373656e6765723a2078446f6d61696e4d657360448201527f7361676553656e646572206973206e6f7420736574000000000000000000000060648201526084015b60405180910390fd5b5060cc5473ffffffffffffffffffffffffffffffffffffffff1690565b6000547501000000000000000000000000000000000000000000900460ff1615808015610845575060005460017401000000000000000000000000000000000000000090910460ff16105b806108775750303b158015610877575060005474010000000000000000000000000000000000000000900460ff166001145b610903576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a656400000000000000000000000000000000000060648201526084016107d4565b600080547fffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffff1674010000000000000000000000000000000000000000179055801561098957600080547fffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffffff1675010000000000000000000000000000000000000000001790555b6109916114f7565b80156109f457600080547fffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffffff169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b50565b6000611388619c4080603f610a13604063ffffffff8816611d27565b610a1d9190611d86565b610a28601088611d27565b610a359062030d40611dad565b610a3f9190611dad565b610a499190611dad565b610a539190611dad565b610a5d9190611dad565b949350505050565b60f087901c60028110610b20576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604d60248201527f43726f7373446f6d61696e4d657373656e6765723a206f6e6c7920766572736960448201527f6f6e2030206f722031206d657373616765732061726520737570706f7274656460648201527f20617420746869732074696d6500000000000000000000000000000000000000608482015260a4016107d4565b8061ffff16600003610c15576000610b71878986868080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152508f92506115d0915050565b600081815260cb602052604090205490915060ff1615610c13576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603760248201527f43726f7373446f6d61696e4d657373656e6765723a206c65676163792077697460448201527f6864726177616c20616c72656164792072656c6179656400000000000000000060648201526084016107d4565b505b6000610c5b898989898989898080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152506115ef92505050565b9050610c65611612565b15610c9d57853414610c7957610c79611dd9565b600081815260ce602052604090205460ff1615610c9857610c98611dd9565b610def565b3415610d51576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152605060248201527f43726f7373446f6d61696e4d657373656e6765723a2076616c7565206d75737460448201527f206265207a65726f20756e6c657373206d6573736167652069732066726f6d2060648201527f612073797374656d206164647265737300000000000000000000000000000000608482015260a4016107d4565b600081815260ce602052604090205460ff16610def576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603060248201527f43726f7373446f6d61696e4d657373656e6765723a206d65737361676520636160448201527f6e6e6f74206265207265706c617965640000000000000000000000000000000060648201526084016107d4565b610df887611736565b15610eab576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604360248201527f43726f7373446f6d61696e4d657373656e6765723a2063616e6e6f742073656e60448201527f64206d65737361676520746f20626c6f636b65642073797374656d206164647260648201527f6573730000000000000000000000000000000000000000000000000000000000608482015260a4016107d4565b600081815260cb602052604090205460ff1615610f4a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603660248201527f43726f7373446f6d61696e4d657373656e6765723a206d65737361676520686160448201527f7320616c7265616479206265656e2072656c617965640000000000000000000060648201526084016107d4565b610f6b85610f5c611388619c40611dad565b67ffffffffffffffff166117ad565b1580610f91575060cc5473ffffffffffffffffffffffffffffffffffffffff1661dead14155b156110aa57600081815260ce602052604080822080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660011790555182917f99d0e048484baa1b1540b1367cb128acd7ab2946d1ed91ec10e3c85e4bf51b8f91a27fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff32016110a3576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602d60248201527f43726f7373446f6d61696e4d657373656e6765723a206661696c656420746f2060448201527f72656c6179206d6573736167650000000000000000000000000000000000000060648201526084016107d4565b50506112e3565b60cc80547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff8a16179055600061113b88619c405a6110fe9190611e08565b8988888080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152506117c892505050565b60cc80547fffffffffffffffffffffffff00000000000000000000000000000000000000001661dead179055905080156111d257600082815260cb602052604080822080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660011790555183917f4641df4a962071e12719d8c8c8e5ac7fc4d97b927346a3d7a335b1f7517e133c91a26112df565b600082815260ce602052604080822080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660011790555183917f99d0e048484baa1b1540b1367cb128acd7ab2946d1ed91ec10e3c85e4bf51b8f91a27fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff32016112df576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602d60248201527f43726f7373446f6d61696e4d657373656e6765723a206661696c656420746f2060448201527f72656c6179206d6573736167650000000000000000000000000000000000000060648201526084016107d4565b5050505b50505050505050565b905090565b73ffffffffffffffffffffffffffffffffffffffff163b151590565b6040517fe9e05c4200000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000169063e9e05c4290849061138a908890839089906000908990600401611e1f565b6000604051808303818588803b1580156113a357600080fd5b505af11580156113b7573d6000803e3d6000fd5b505050505050505050565b60608160000361140557505060408051808201909152600181527f3000000000000000000000000000000000000000000000000000000000000000602082015290565b8160005b811561142f578061141981611e77565b91506114289050600a83611eaf565b9150611409565b60008167ffffffffffffffff81111561144a5761144a611ec3565b6040519080825280601f01601f191660200182016040528015611474576020820181803683370190505b5090505b8415610a5d57611489600183611e08565b9150611496600a86611ef2565b6114a1906030611f06565b60f81b8183815181106114b6576114b6611f1e565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053506114f0600a86611eaf565b9450611478565b6000547501000000000000000000000000000000000000000000900460ff166115a2576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e6700000000000000000000000000000000000000000060648201526084016107d4565b60cc80547fffffffffffffffffffffffff00000000000000000000000000000000000000001661dead179055565b60006115de858585856117e2565b805190602001209050949350505050565b60006115ff87878787878761187b565b8051906020012090509695505050505050565b60003373ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000161480156112ec57507f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff167f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16639bf62d826040518163ffffffff1660e01b8152600401602060405180830381865afa1580156116f6573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061171a9190611f4d565b73ffffffffffffffffffffffffffffffffffffffff1614905090565b600073ffffffffffffffffffffffffffffffffffffffff82163014806117a757507f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16145b92915050565b60008082619c4001603f6040860204015a1015949350505050565b600080600080845160208601878a8af19695505050505050565b6060848484846040516024016117fb9493929190611f6a565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fcbd4ece9000000000000000000000000000000000000000000000000000000001790529050949350505050565b606086868686868660405160240161189896959493929190611fb4565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fd764ad0b0000000000000000000000000000000000000000000000000000000017905290509695505050505050565b73ffffffffffffffffffffffffffffffffffffffff811681146109f457600080fd5b60008083601f84011261194e57600080fd5b50813567ffffffffffffffff81111561196657600080fd5b60208301915083602082850101111561197e57600080fd5b9250929050565b803563ffffffff8116811461199957600080fd5b919050565b600080600080606085870312156119b457600080fd5b84356119bf8161191a565b9350602085013567ffffffffffffffff8111156119db57600080fd5b6119e78782880161193c565b90945092506119fa905060408601611985565b905092959194509250565b60005b83811015611a20578181015183820152602001611a08565b83811115611a2f576000848401525b50505050565b60008151808452611a4d816020860160208601611a05565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b602081526000611a926020830184611a35565b9392505050565b600060208284031215611aab57600080fd5b5035919050565b600080600060408486031215611ac757600080fd5b833567ffffffffffffffff811115611ade57600080fd5b611aea8682870161193c565b9094509250611afd905060208501611985565b90509250925092565b600080600080600080600060c0888a031215611b2157600080fd5b873596506020880135611b338161191a565b95506040880135611b438161191a565b9450606088013593506080880135925060a088013567ffffffffffffffff811115611b6d57600080fd5b611b798a828b0161193c565b989b979a50959850939692959293505050565b8183528181602085013750600060208284010152600060207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f840116840101905092915050565b878152600073ffffffffffffffffffffffffffffffffffffffff808916602084015280881660408401525085606083015263ffffffff8516608083015260c060a0830152611c2760c083018486611b8c565b9998505050505050505050565b73ffffffffffffffffffffffffffffffffffffffff86168152608060208201526000611c64608083018688611b8c565b905083604083015263ffffffff831660608301529695505050505050565b60008451611c94818460208901611a05565b80830190507f2e000000000000000000000000000000000000000000000000000000000000008082528551611cd0816001850160208a01611a05565b60019201918201528351611ceb816002840160208801611a05565b0160020195945050505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b600067ffffffffffffffff80831681851681830481118215151615611d4e57611d4e611cf8565b02949350505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b600067ffffffffffffffff80841680611da157611da1611d57565b92169190910492915050565b600067ffffffffffffffff808316818516808303821115611dd057611dd0611cf8565b01949350505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052600160045260246000fd5b600082821015611e1a57611e1a611cf8565b500390565b73ffffffffffffffffffffffffffffffffffffffff8616815284602082015267ffffffffffffffff84166040820152821515606082015260a060808201526000611e6c60a0830184611a35565b979650505050505050565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203611ea857611ea8611cf8565b5060010190565b600082611ebe57611ebe611d57565b500490565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b600082611f0157611f01611d57565b500690565b60008219821115611f1957611f19611cf8565b500190565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b600060208284031215611f5f57600080fd5b8151611a928161191a565b600073ffffffffffffffffffffffffffffffffffffffff808716835280861660208401525060806040830152611fa36080830185611a35565b905082606083015295945050505050565b868152600073ffffffffffffffffffffffffffffffffffffffff808816602084015280871660408401525084606083015283608083015260c060a0830152611fff60c0830184611a35565b9897505050505050505056fea164736f6c634300080f000a",
}
// L1CrossDomainMessengerABI is the input ABI used to generate the binding from.
......@@ -263,37 +263,6 @@ func (_L1CrossDomainMessenger *L1CrossDomainMessengerCallerSession) MINGASCALLDA
return _L1CrossDomainMessenger.Contract.MINGASCALLDATAOVERHEAD(&_L1CrossDomainMessenger.CallOpts)
}
// MINGASCONSTANTOVERHEAD is a free data retrieval call binding the contract method 0x7dea7cc3.
//
// Solidity: function MIN_GAS_CONSTANT_OVERHEAD() view returns(uint64)
func (_L1CrossDomainMessenger *L1CrossDomainMessengerCaller) MINGASCONSTANTOVERHEAD(opts *bind.CallOpts) (uint64, error) {
var out []interface{}
err := _L1CrossDomainMessenger.contract.Call(opts, &out, "MIN_GAS_CONSTANT_OVERHEAD")
if err != nil {
return *new(uint64), err
}
out0 := *abi.ConvertType(out[0], new(uint64)).(*uint64)
return out0, err
}
// MINGASCONSTANTOVERHEAD is a free data retrieval call binding the contract method 0x7dea7cc3.
//
// Solidity: function MIN_GAS_CONSTANT_OVERHEAD() view returns(uint64)
func (_L1CrossDomainMessenger *L1CrossDomainMessengerSession) MINGASCONSTANTOVERHEAD() (uint64, error) {
return _L1CrossDomainMessenger.Contract.MINGASCONSTANTOVERHEAD(&_L1CrossDomainMessenger.CallOpts)
}
// MINGASCONSTANTOVERHEAD is a free data retrieval call binding the contract method 0x7dea7cc3.
//
// Solidity: function MIN_GAS_CONSTANT_OVERHEAD() view returns(uint64)
func (_L1CrossDomainMessenger *L1CrossDomainMessengerCallerSession) MINGASCONSTANTOVERHEAD() (uint64, error) {
return _L1CrossDomainMessenger.Contract.MINGASCONSTANTOVERHEAD(&_L1CrossDomainMessenger.CallOpts)
}
// MINGASDYNAMICOVERHEADDENOMINATOR is a free data retrieval call binding the contract method 0x0c568498.
//
// Solidity: function MIN_GAS_DYNAMIC_OVERHEAD_DENOMINATOR() view returns(uint64)
......@@ -418,6 +387,130 @@ func (_L1CrossDomainMessenger *L1CrossDomainMessengerCallerSession) PORTAL() (co
return _L1CrossDomainMessenger.Contract.PORTAL(&_L1CrossDomainMessenger.CallOpts)
}
// RELAYCALLOVERHEAD is a free data retrieval call binding the contract method 0x4c1d6a69.
//
// Solidity: function RELAY_CALL_OVERHEAD() view returns(uint64)
func (_L1CrossDomainMessenger *L1CrossDomainMessengerCaller) RELAYCALLOVERHEAD(opts *bind.CallOpts) (uint64, error) {
var out []interface{}
err := _L1CrossDomainMessenger.contract.Call(opts, &out, "RELAY_CALL_OVERHEAD")
if err != nil {
return *new(uint64), err
}
out0 := *abi.ConvertType(out[0], new(uint64)).(*uint64)
return out0, err
}
// RELAYCALLOVERHEAD is a free data retrieval call binding the contract method 0x4c1d6a69.
//
// Solidity: function RELAY_CALL_OVERHEAD() view returns(uint64)
func (_L1CrossDomainMessenger *L1CrossDomainMessengerSession) RELAYCALLOVERHEAD() (uint64, error) {
return _L1CrossDomainMessenger.Contract.RELAYCALLOVERHEAD(&_L1CrossDomainMessenger.CallOpts)
}
// RELAYCALLOVERHEAD is a free data retrieval call binding the contract method 0x4c1d6a69.
//
// Solidity: function RELAY_CALL_OVERHEAD() view returns(uint64)
func (_L1CrossDomainMessenger *L1CrossDomainMessengerCallerSession) RELAYCALLOVERHEAD() (uint64, error) {
return _L1CrossDomainMessenger.Contract.RELAYCALLOVERHEAD(&_L1CrossDomainMessenger.CallOpts)
}
// RELAYCONSTANTOVERHEAD is a free data retrieval call binding the contract method 0x83a74074.
//
// Solidity: function RELAY_CONSTANT_OVERHEAD() view returns(uint64)
func (_L1CrossDomainMessenger *L1CrossDomainMessengerCaller) RELAYCONSTANTOVERHEAD(opts *bind.CallOpts) (uint64, error) {
var out []interface{}
err := _L1CrossDomainMessenger.contract.Call(opts, &out, "RELAY_CONSTANT_OVERHEAD")
if err != nil {
return *new(uint64), err
}
out0 := *abi.ConvertType(out[0], new(uint64)).(*uint64)
return out0, err
}
// RELAYCONSTANTOVERHEAD is a free data retrieval call binding the contract method 0x83a74074.
//
// Solidity: function RELAY_CONSTANT_OVERHEAD() view returns(uint64)
func (_L1CrossDomainMessenger *L1CrossDomainMessengerSession) RELAYCONSTANTOVERHEAD() (uint64, error) {
return _L1CrossDomainMessenger.Contract.RELAYCONSTANTOVERHEAD(&_L1CrossDomainMessenger.CallOpts)
}
// RELAYCONSTANTOVERHEAD is a free data retrieval call binding the contract method 0x83a74074.
//
// Solidity: function RELAY_CONSTANT_OVERHEAD() view returns(uint64)
func (_L1CrossDomainMessenger *L1CrossDomainMessengerCallerSession) RELAYCONSTANTOVERHEAD() (uint64, error) {
return _L1CrossDomainMessenger.Contract.RELAYCONSTANTOVERHEAD(&_L1CrossDomainMessenger.CallOpts)
}
// RELAYGASCHECKBUFFER is a free data retrieval call binding the contract method 0x5644cfdf.
//
// Solidity: function RELAY_GAS_CHECK_BUFFER() view returns(uint64)
func (_L1CrossDomainMessenger *L1CrossDomainMessengerCaller) RELAYGASCHECKBUFFER(opts *bind.CallOpts) (uint64, error) {
var out []interface{}
err := _L1CrossDomainMessenger.contract.Call(opts, &out, "RELAY_GAS_CHECK_BUFFER")
if err != nil {
return *new(uint64), err
}
out0 := *abi.ConvertType(out[0], new(uint64)).(*uint64)
return out0, err
}
// RELAYGASCHECKBUFFER is a free data retrieval call binding the contract method 0x5644cfdf.
//
// Solidity: function RELAY_GAS_CHECK_BUFFER() view returns(uint64)
func (_L1CrossDomainMessenger *L1CrossDomainMessengerSession) RELAYGASCHECKBUFFER() (uint64, error) {
return _L1CrossDomainMessenger.Contract.RELAYGASCHECKBUFFER(&_L1CrossDomainMessenger.CallOpts)
}
// RELAYGASCHECKBUFFER is a free data retrieval call binding the contract method 0x5644cfdf.
//
// Solidity: function RELAY_GAS_CHECK_BUFFER() view returns(uint64)
func (_L1CrossDomainMessenger *L1CrossDomainMessengerCallerSession) RELAYGASCHECKBUFFER() (uint64, error) {
return _L1CrossDomainMessenger.Contract.RELAYGASCHECKBUFFER(&_L1CrossDomainMessenger.CallOpts)
}
// RELAYRESERVEDGAS is a free data retrieval call binding the contract method 0x8cbeeef2.
//
// Solidity: function RELAY_RESERVED_GAS() view returns(uint64)
func (_L1CrossDomainMessenger *L1CrossDomainMessengerCaller) RELAYRESERVEDGAS(opts *bind.CallOpts) (uint64, error) {
var out []interface{}
err := _L1CrossDomainMessenger.contract.Call(opts, &out, "RELAY_RESERVED_GAS")
if err != nil {
return *new(uint64), err
}
out0 := *abi.ConvertType(out[0], new(uint64)).(*uint64)
return out0, err
}
// RELAYRESERVEDGAS is a free data retrieval call binding the contract method 0x8cbeeef2.
//
// Solidity: function RELAY_RESERVED_GAS() view returns(uint64)
func (_L1CrossDomainMessenger *L1CrossDomainMessengerSession) RELAYRESERVEDGAS() (uint64, error) {
return _L1CrossDomainMessenger.Contract.RELAYRESERVEDGAS(&_L1CrossDomainMessenger.CallOpts)
}
// RELAYRESERVEDGAS is a free data retrieval call binding the contract method 0x8cbeeef2.
//
// Solidity: function RELAY_RESERVED_GAS() view returns(uint64)
func (_L1CrossDomainMessenger *L1CrossDomainMessengerCallerSession) RELAYRESERVEDGAS() (uint64, error) {
return _L1CrossDomainMessenger.Contract.RELAYRESERVEDGAS(&_L1CrossDomainMessenger.CallOpts)
}
// BaseGas is a free data retrieval call binding the contract method 0xb28ade25.
//
// Solidity: function baseGas(bytes _message, uint32 _minGasLimit) pure returns(uint64)
......
......@@ -13,7 +13,7 @@ const L1CrossDomainMessengerStorageLayoutJSON = "{\"storage\":[{\"astId\":1000,\
var L1CrossDomainMessengerStorageLayout = new(solc.StorageLayout)
var L1CrossDomainMessengerDeployedBin = "0x6080604052600436106100f35760003560e01c80637dea7cc31161008a578063b1b1b20911610059578063b1b1b209146102c4578063b28ade25146102f4578063d764ad0b14610314578063ecc704281461032757600080fd5b80637dea7cc3146102245780638129fc1c1461023b5780639fce812c14610250578063a4e7f8bd1461028457600080fd5b80633dbb202b116100c65780633dbb202b146101b05780633f827a5a146101c557806354fd4d50146101ed5780636e296e451461020f57600080fd5b8063028f85f7146100f85780630c5684981461012b5780630ff754ea146101415780632828d7e81461019a575b600080fd5b34801561010457600080fd5b5061010d601081565b60405167ffffffffffffffff90911681526020015b60405180910390f35b34801561013757600080fd5b5061010d6103e881565b34801561014d57600080fd5b506101757f000000000000000000000000000000000000000000000000000000000000000081565b60405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610122565b3480156101a657600080fd5b5061010d6103f881565b6101c36101be366004611841565b61038c565b005b3480156101d157600080fd5b506101da600181565b60405161ffff9091168152602001610122565b3480156101f957600080fd5b506102026105f0565b6040516101229190611922565b34801561021b57600080fd5b50610175610693565b34801561023057600080fd5b5061010d62030d4081565b34801561024757600080fd5b506101c361077f565b34801561025c57600080fd5b506101757f000000000000000000000000000000000000000000000000000000000000000081565b34801561029057600080fd5b506102b461029f36600461193c565b60ce6020526000908152604090205460ff1681565b6040519015158152602001610122565b3480156102d057600080fd5b506102b46102df36600461193c565b60cb6020526000908152604090205460ff1681565b34801561030057600080fd5b5061010d61030f366004611955565b61097c565b6101c36103223660046119a9565b6109c8565b34801561033357600080fd5b5061037e60cd547dffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff167e010000000000000000000000000000000000000000000000000000000000001790565b604051908152602001610122565b6104c57f00000000000000000000000000000000000000000000000000000000000000006103bb85858561097c565b347fd764ad0b0000000000000000000000000000000000000000000000000000000061042760cd547dffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff167e010000000000000000000000000000000000000000000000000000000000001790565b338a34898c8c6040516024016104439796959493929190611a78565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff000000000000000000000000000000000000000000000000000000009093169290921790915261118b565b8373ffffffffffffffffffffffffffffffffffffffff167fcb0f7ffd78f9aee47a248fae8db181db6eee833039123e026dcbff529522e52a33858561054a60cd547dffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff167e010000000000000000000000000000000000000000000000000000000000001790565b8660405161055c959493929190611ad7565b60405180910390a260405134815233907f8ebb2ec2465bdb2a06a66fc37a0963af8a2a6a1479d81d56fdb8cbb98096d5469060200160405180910390a2505060cd80547dffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff808216600101167fffff0000000000000000000000000000000000000000000000000000000000009091161790555050565b606061061b7f0000000000000000000000000000000000000000000000000000000000000000611240565b6106447f0000000000000000000000000000000000000000000000000000000000000000611240565b61066d7f0000000000000000000000000000000000000000000000000000000000000000611240565b60405160200161067f93929190611b25565b604051602081830303815290604052905090565b60cc5460009073ffffffffffffffffffffffffffffffffffffffff167fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff215301610762576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603560248201527f43726f7373446f6d61696e4d657373656e6765723a2078446f6d61696e4d657360448201527f7361676553656e646572206973206e6f7420736574000000000000000000000060648201526084015b60405180910390fd5b5060cc5473ffffffffffffffffffffffffffffffffffffffff1690565b6000547501000000000000000000000000000000000000000000900460ff16158080156107ca575060005460017401000000000000000000000000000000000000000090910460ff16105b806107fc5750303b1580156107fc575060005474010000000000000000000000000000000000000000900460ff166001145b610888576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a65640000000000000000000000000000000000006064820152608401610759565b600080547fffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffff1674010000000000000000000000000000000000000000179055801561090e57600080547fffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffffff1675010000000000000000000000000000000000000000001790555b610916611375565b801561097957600080547fffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffffff169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b50565b600062030d4061098d601085611bca565b6103e86109a26103f863ffffffff8716611bca565b6109ac9190611c29565b6109b69190611c50565b6109c09190611c50565b949350505050565b60f087901c60028110610a83576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604d60248201527f43726f7373446f6d61696e4d657373656e6765723a206f6e6c7920766572736960448201527f6f6e2030206f722031206d657373616765732061726520737570706f7274656460648201527f20617420746869732074696d6500000000000000000000000000000000000000608482015260a401610759565b8061ffff16600003610b78576000610ad4878986868080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152508f925061144e915050565b600081815260cb602052604090205490915060ff1615610b76576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603760248201527f43726f7373446f6d61696e4d657373656e6765723a206c65676163792077697460448201527f6864726177616c20616c72656164792072656c617965640000000000000000006064820152608401610759565b505b6000610bbe898989898989898080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061146d92505050565b9050610bc8611490565b15610c0057853414610bdc57610bdc611c7c565b600081815260ce602052604090205460ff1615610bfb57610bfb611c7c565b610d52565b3415610cb4576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152605060248201527f43726f7373446f6d61696e4d657373656e6765723a2076616c7565206d75737460448201527f206265207a65726f20756e6c657373206d6573736167652069732066726f6d2060648201527f612073797374656d206164647265737300000000000000000000000000000000608482015260a401610759565b600081815260ce602052604090205460ff16610d52576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603060248201527f43726f7373446f6d61696e4d657373656e6765723a206d65737361676520636160448201527f6e6e6f74206265207265706c61796564000000000000000000000000000000006064820152608401610759565b610d5b876115b4565b15610e0e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604360248201527f43726f7373446f6d61696e4d657373656e6765723a2063616e6e6f742073656e60448201527f64206d65737361676520746f20626c6f636b65642073797374656d206164647260648201527f6573730000000000000000000000000000000000000000000000000000000000608482015260a401610759565b600081815260cb602052604090205460ff1615610ead576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603660248201527f43726f7373446f6d61696e4d657373656e6765723a206d65737361676520686160448201527f7320616c7265616479206265656e2072656c61796564000000000000000000006064820152608401610759565b60cc5473ffffffffffffffffffffffffffffffffffffffff1661dead14610f3357600081815260ce602052604080822080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660011790555182917f99d0e048484baa1b1540b1367cb128acd7ab2946d1ed91ec10e3c85e4bf51b8f91a25050611161565b60cc80547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff8a16179055604080516020601f8601819004810282018101909252848152600091610fb9918a9189918b918a908a908190840183828082843760009201919091525061162b92505050565b60cc80547fffffffffffffffffffffffff00000000000000000000000000000000000000001661dead1790559050801561105057600082815260cb602052604080822080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660011790555183917f4641df4a962071e12719d8c8c8e5ac7fc4d97b927346a3d7a335b1f7517e133c91a261115d565b600082815260ce602052604080822080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660011790555183917f99d0e048484baa1b1540b1367cb128acd7ab2946d1ed91ec10e3c85e4bf51b8f91a27fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff320161115d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602d60248201527f43726f7373446f6d61696e4d657373656e6765723a206661696c656420746f2060448201527f72656c6179206d657373616765000000000000000000000000000000000000006064820152608401610759565b5050505b50505050505050565b905090565b73ffffffffffffffffffffffffffffffffffffffff163b151590565b6040517fe9e05c4200000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000169063e9e05c42908490611208908890839089906000908990600401611cab565b6000604051808303818588803b15801561122157600080fd5b505af1158015611235573d6000803e3d6000fd5b505050505050505050565b60608160000361128357505060408051808201909152600181527f3000000000000000000000000000000000000000000000000000000000000000602082015290565b8160005b81156112ad578061129781611d03565b91506112a69050600a83611d3b565b9150611287565b60008167ffffffffffffffff8111156112c8576112c8611d4f565b6040519080825280601f01601f1916602001820160405280156112f2576020820181803683370190505b5090505b84156109c057611307600183611d7e565b9150611314600a86611d95565b61131f906030611da9565b60f81b81838151811061133457611334611dc1565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a90535061136e600a86611d3b565b94506112f6565b6000547501000000000000000000000000000000000000000000900460ff16611420576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e670000000000000000000000000000000000000000006064820152608401610759565b60cc80547fffffffffffffffffffffffff00000000000000000000000000000000000000001661dead179055565b600061145c85858585611685565b805190602001209050949350505050565b600061147d87878787878761171e565b8051906020012090509695505050505050565b60003373ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000001614801561116a57507f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff167f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16639bf62d826040518163ffffffff1660e01b8152600401602060405180830381865afa158015611574573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906115989190611df0565b73ffffffffffffffffffffffffffffffffffffffff1614905090565b600073ffffffffffffffffffffffffffffffffffffffff821630148061162557507f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16145b92915050565b600080603f60c88601604002045a101561166e576308c379a06000526020805278185361666543616c6c3a204e6f7420656e6f756768206761736058526064601cfd5b600080845160208601878a5af19695505050505050565b60608484848460405160240161169e9493929190611e0d565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fcbd4ece9000000000000000000000000000000000000000000000000000000001790529050949350505050565b606086868686868660405160240161173b96959493929190611e57565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fd764ad0b0000000000000000000000000000000000000000000000000000000017905290509695505050505050565b73ffffffffffffffffffffffffffffffffffffffff8116811461097957600080fd5b60008083601f8401126117f157600080fd5b50813567ffffffffffffffff81111561180957600080fd5b60208301915083602082850101111561182157600080fd5b9250929050565b803563ffffffff8116811461183c57600080fd5b919050565b6000806000806060858703121561185757600080fd5b8435611862816117bd565b9350602085013567ffffffffffffffff81111561187e57600080fd5b61188a878288016117df565b909450925061189d905060408601611828565b905092959194509250565b60005b838110156118c35781810151838201526020016118ab565b838111156118d2576000848401525b50505050565b600081518084526118f08160208601602086016118a8565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b60208152600061193560208301846118d8565b9392505050565b60006020828403121561194e57600080fd5b5035919050565b60008060006040848603121561196a57600080fd5b833567ffffffffffffffff81111561198157600080fd5b61198d868287016117df565b90945092506119a0905060208501611828565b90509250925092565b600080600080600080600060c0888a0312156119c457600080fd5b8735965060208801356119d6816117bd565b955060408801356119e6816117bd565b9450606088013593506080880135925060a088013567ffffffffffffffff811115611a1057600080fd5b611a1c8a828b016117df565b989b979a50959850939692959293505050565b8183528181602085013750600060208284010152600060207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f840116840101905092915050565b878152600073ffffffffffffffffffffffffffffffffffffffff808916602084015280881660408401525085606083015263ffffffff8516608083015260c060a0830152611aca60c083018486611a2f565b9998505050505050505050565b73ffffffffffffffffffffffffffffffffffffffff86168152608060208201526000611b07608083018688611a2f565b905083604083015263ffffffff831660608301529695505050505050565b60008451611b378184602089016118a8565b80830190507f2e000000000000000000000000000000000000000000000000000000000000008082528551611b73816001850160208a016118a8565b60019201918201528351611b8e8160028401602088016118a8565b0160020195945050505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b600067ffffffffffffffff80831681851681830481118215151615611bf157611bf1611b9b565b02949350505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b600067ffffffffffffffff80841680611c4457611c44611bfa565b92169190910492915050565b600067ffffffffffffffff808316818516808303821115611c7357611c73611b9b565b01949350505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052600160045260246000fd5b73ffffffffffffffffffffffffffffffffffffffff8616815284602082015267ffffffffffffffff84166040820152821515606082015260a060808201526000611cf860a08301846118d8565b979650505050505050565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203611d3457611d34611b9b565b5060010190565b600082611d4a57611d4a611bfa565b500490565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b600082821015611d9057611d90611b9b565b500390565b600082611da457611da4611bfa565b500690565b60008219821115611dbc57611dbc611b9b565b500190565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b600060208284031215611e0257600080fd5b8151611935816117bd565b600073ffffffffffffffffffffffffffffffffffffffff808716835280861660208401525060806040830152611e4660808301856118d8565b905082606083015295945050505050565b868152600073ffffffffffffffffffffffffffffffffffffffff808816602084015280871660408401525084606083015283608083015260c060a0830152611ea260c08301846118d8565b9897505050505050505056fea164736f6c634300080f000a"
var L1CrossDomainMessengerDeployedBin = "0x6080604052600436106101445760003560e01c80636e296e45116100c0578063a4e7f8bd11610074578063b28ade2511610059578063b28ade251461036f578063d764ad0b1461038f578063ecc70428146103a257600080fd5b8063a4e7f8bd146102ff578063b1b1b2091461033f57600080fd5b806383a74074116100a557806383a74074146102b45780638cbeeef21461023c5780639fce812c146102cb57600080fd5b80636e296e451461028a5780638129fc1c1461029f57600080fd5b80633dbb202b116101175780634c1d6a69116100fc5780634c1d6a691461023c57806354fd4d50146102525780635644cfdf1461027457600080fd5b80633dbb202b146101ff5780633f827a5a1461021457600080fd5b8063028f85f7146101495780630c5684981461017c5780630ff754ea146101915780632828d7e8146101ea575b600080fd5b34801561015557600080fd5b5061015e601081565b60405167ffffffffffffffff90911681526020015b60405180910390f35b34801561018857600080fd5b5061015e603f81565b34801561019d57600080fd5b506101c57f000000000000000000000000000000000000000000000000000000000000000081565b60405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610173565b3480156101f657600080fd5b5061015e604081565b61021261020d36600461199e565b610407565b005b34801561022057600080fd5b50610229600181565b60405161ffff9091168152602001610173565b34801561024857600080fd5b5061015e619c4081565b34801561025e57600080fd5b5061026761066b565b6040516101739190611a7f565b34801561028057600080fd5b5061015e61138881565b34801561029657600080fd5b506101c561070e565b3480156102ab57600080fd5b506102126107fa565b3480156102c057600080fd5b5061015e62030d4081565b3480156102d757600080fd5b506101c57f000000000000000000000000000000000000000000000000000000000000000081565b34801561030b57600080fd5b5061032f61031a366004611a99565b60ce6020526000908152604090205460ff1681565b6040519015158152602001610173565b34801561034b57600080fd5b5061032f61035a366004611a99565b60cb6020526000908152604090205460ff1681565b34801561037b57600080fd5b5061015e61038a366004611ab2565b6109f7565b61021261039d366004611b06565b610a65565b3480156103ae57600080fd5b506103f960cd547dffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff167e010000000000000000000000000000000000000000000000000000000000001790565b604051908152602001610173565b6105407f00000000000000000000000000000000000000000000000000000000000000006104368585856109f7565b347fd764ad0b000000000000000000000000000000000000000000000000000000006104a260cd547dffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff167e010000000000000000000000000000000000000000000000000000000000001790565b338a34898c8c6040516024016104be9796959493929190611bd5565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff000000000000000000000000000000000000000000000000000000009093169290921790915261130d565b8373ffffffffffffffffffffffffffffffffffffffff167fcb0f7ffd78f9aee47a248fae8db181db6eee833039123e026dcbff529522e52a3385856105c560cd547dffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff167e010000000000000000000000000000000000000000000000000000000000001790565b866040516105d7959493929190611c34565b60405180910390a260405134815233907f8ebb2ec2465bdb2a06a66fc37a0963af8a2a6a1479d81d56fdb8cbb98096d5469060200160405180910390a2505060cd80547dffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff808216600101167fffff0000000000000000000000000000000000000000000000000000000000009091161790555050565b60606106967f00000000000000000000000000000000000000000000000000000000000000006113c2565b6106bf7f00000000000000000000000000000000000000000000000000000000000000006113c2565b6106e87f00000000000000000000000000000000000000000000000000000000000000006113c2565b6040516020016106fa93929190611c82565b604051602081830303815290604052905090565b60cc5460009073ffffffffffffffffffffffffffffffffffffffff167fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff2153016107dd576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603560248201527f43726f7373446f6d61696e4d657373656e6765723a2078446f6d61696e4d657360448201527f7361676553656e646572206973206e6f7420736574000000000000000000000060648201526084015b60405180910390fd5b5060cc5473ffffffffffffffffffffffffffffffffffffffff1690565b6000547501000000000000000000000000000000000000000000900460ff1615808015610845575060005460017401000000000000000000000000000000000000000090910460ff16105b806108775750303b158015610877575060005474010000000000000000000000000000000000000000900460ff166001145b610903576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a656400000000000000000000000000000000000060648201526084016107d4565b600080547fffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffff1674010000000000000000000000000000000000000000179055801561098957600080547fffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffffff1675010000000000000000000000000000000000000000001790555b6109916114f7565b80156109f457600080547fffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffffff169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b50565b6000611388619c4080603f610a13604063ffffffff8816611d27565b610a1d9190611d86565b610a28601088611d27565b610a359062030d40611dad565b610a3f9190611dad565b610a499190611dad565b610a539190611dad565b610a5d9190611dad565b949350505050565b60f087901c60028110610b20576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604d60248201527f43726f7373446f6d61696e4d657373656e6765723a206f6e6c7920766572736960448201527f6f6e2030206f722031206d657373616765732061726520737570706f7274656460648201527f20617420746869732074696d6500000000000000000000000000000000000000608482015260a4016107d4565b8061ffff16600003610c15576000610b71878986868080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152508f92506115d0915050565b600081815260cb602052604090205490915060ff1615610c13576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603760248201527f43726f7373446f6d61696e4d657373656e6765723a206c65676163792077697460448201527f6864726177616c20616c72656164792072656c6179656400000000000000000060648201526084016107d4565b505b6000610c5b898989898989898080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152506115ef92505050565b9050610c65611612565b15610c9d57853414610c7957610c79611dd9565b600081815260ce602052604090205460ff1615610c9857610c98611dd9565b610def565b3415610d51576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152605060248201527f43726f7373446f6d61696e4d657373656e6765723a2076616c7565206d75737460448201527f206265207a65726f20756e6c657373206d6573736167652069732066726f6d2060648201527f612073797374656d206164647265737300000000000000000000000000000000608482015260a4016107d4565b600081815260ce602052604090205460ff16610def576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603060248201527f43726f7373446f6d61696e4d657373656e6765723a206d65737361676520636160448201527f6e6e6f74206265207265706c617965640000000000000000000000000000000060648201526084016107d4565b610df887611736565b15610eab576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604360248201527f43726f7373446f6d61696e4d657373656e6765723a2063616e6e6f742073656e60448201527f64206d65737361676520746f20626c6f636b65642073797374656d206164647260648201527f6573730000000000000000000000000000000000000000000000000000000000608482015260a4016107d4565b600081815260cb602052604090205460ff1615610f4a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603660248201527f43726f7373446f6d61696e4d657373656e6765723a206d65737361676520686160448201527f7320616c7265616479206265656e2072656c617965640000000000000000000060648201526084016107d4565b610f6b85610f5c611388619c40611dad565b67ffffffffffffffff166117ad565b1580610f91575060cc5473ffffffffffffffffffffffffffffffffffffffff1661dead14155b156110aa57600081815260ce602052604080822080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660011790555182917f99d0e048484baa1b1540b1367cb128acd7ab2946d1ed91ec10e3c85e4bf51b8f91a27fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff32016110a3576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602d60248201527f43726f7373446f6d61696e4d657373656e6765723a206661696c656420746f2060448201527f72656c6179206d6573736167650000000000000000000000000000000000000060648201526084016107d4565b50506112e3565b60cc80547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff8a16179055600061113b88619c405a6110fe9190611e08565b8988888080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152506117c892505050565b60cc80547fffffffffffffffffffffffff00000000000000000000000000000000000000001661dead179055905080156111d257600082815260cb602052604080822080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660011790555183917f4641df4a962071e12719d8c8c8e5ac7fc4d97b927346a3d7a335b1f7517e133c91a26112df565b600082815260ce602052604080822080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660011790555183917f99d0e048484baa1b1540b1367cb128acd7ab2946d1ed91ec10e3c85e4bf51b8f91a27fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff32016112df576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602d60248201527f43726f7373446f6d61696e4d657373656e6765723a206661696c656420746f2060448201527f72656c6179206d6573736167650000000000000000000000000000000000000060648201526084016107d4565b5050505b50505050505050565b905090565b73ffffffffffffffffffffffffffffffffffffffff163b151590565b6040517fe9e05c4200000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000169063e9e05c4290849061138a908890839089906000908990600401611e1f565b6000604051808303818588803b1580156113a357600080fd5b505af11580156113b7573d6000803e3d6000fd5b505050505050505050565b60608160000361140557505060408051808201909152600181527f3000000000000000000000000000000000000000000000000000000000000000602082015290565b8160005b811561142f578061141981611e77565b91506114289050600a83611eaf565b9150611409565b60008167ffffffffffffffff81111561144a5761144a611ec3565b6040519080825280601f01601f191660200182016040528015611474576020820181803683370190505b5090505b8415610a5d57611489600183611e08565b9150611496600a86611ef2565b6114a1906030611f06565b60f81b8183815181106114b6576114b6611f1e565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053506114f0600a86611eaf565b9450611478565b6000547501000000000000000000000000000000000000000000900460ff166115a2576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e6700000000000000000000000000000000000000000060648201526084016107d4565b60cc80547fffffffffffffffffffffffff00000000000000000000000000000000000000001661dead179055565b60006115de858585856117e2565b805190602001209050949350505050565b60006115ff87878787878761187b565b8051906020012090509695505050505050565b60003373ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000161480156112ec57507f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff167f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16639bf62d826040518163ffffffff1660e01b8152600401602060405180830381865afa1580156116f6573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061171a9190611f4d565b73ffffffffffffffffffffffffffffffffffffffff1614905090565b600073ffffffffffffffffffffffffffffffffffffffff82163014806117a757507f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16145b92915050565b60008082619c4001603f6040860204015a1015949350505050565b600080600080845160208601878a8af19695505050505050565b6060848484846040516024016117fb9493929190611f6a565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fcbd4ece9000000000000000000000000000000000000000000000000000000001790529050949350505050565b606086868686868660405160240161189896959493929190611fb4565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fd764ad0b0000000000000000000000000000000000000000000000000000000017905290509695505050505050565b73ffffffffffffffffffffffffffffffffffffffff811681146109f457600080fd5b60008083601f84011261194e57600080fd5b50813567ffffffffffffffff81111561196657600080fd5b60208301915083602082850101111561197e57600080fd5b9250929050565b803563ffffffff8116811461199957600080fd5b919050565b600080600080606085870312156119b457600080fd5b84356119bf8161191a565b9350602085013567ffffffffffffffff8111156119db57600080fd5b6119e78782880161193c565b90945092506119fa905060408601611985565b905092959194509250565b60005b83811015611a20578181015183820152602001611a08565b83811115611a2f576000848401525b50505050565b60008151808452611a4d816020860160208601611a05565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b602081526000611a926020830184611a35565b9392505050565b600060208284031215611aab57600080fd5b5035919050565b600080600060408486031215611ac757600080fd5b833567ffffffffffffffff811115611ade57600080fd5b611aea8682870161193c565b9094509250611afd905060208501611985565b90509250925092565b600080600080600080600060c0888a031215611b2157600080fd5b873596506020880135611b338161191a565b95506040880135611b438161191a565b9450606088013593506080880135925060a088013567ffffffffffffffff811115611b6d57600080fd5b611b798a828b0161193c565b989b979a50959850939692959293505050565b8183528181602085013750600060208284010152600060207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f840116840101905092915050565b878152600073ffffffffffffffffffffffffffffffffffffffff808916602084015280881660408401525085606083015263ffffffff8516608083015260c060a0830152611c2760c083018486611b8c565b9998505050505050505050565b73ffffffffffffffffffffffffffffffffffffffff86168152608060208201526000611c64608083018688611b8c565b905083604083015263ffffffff831660608301529695505050505050565b60008451611c94818460208901611a05565b80830190507f2e000000000000000000000000000000000000000000000000000000000000008082528551611cd0816001850160208a01611a05565b60019201918201528351611ceb816002840160208801611a05565b0160020195945050505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b600067ffffffffffffffff80831681851681830481118215151615611d4e57611d4e611cf8565b02949350505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b600067ffffffffffffffff80841680611da157611da1611d57565b92169190910492915050565b600067ffffffffffffffff808316818516808303821115611dd057611dd0611cf8565b01949350505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052600160045260246000fd5b600082821015611e1a57611e1a611cf8565b500390565b73ffffffffffffffffffffffffffffffffffffffff8616815284602082015267ffffffffffffffff84166040820152821515606082015260a060808201526000611e6c60a0830184611a35565b979650505050505050565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203611ea857611ea8611cf8565b5060010190565b600082611ebe57611ebe611d57565b500490565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b600082611f0157611f01611d57565b500690565b60008219821115611f1957611f19611cf8565b500190565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b600060208284031215611f5f57600080fd5b8151611a928161191a565b600073ffffffffffffffffffffffffffffffffffffffff808716835280861660208401525060806040830152611fa36080830185611a35565b905082606083015295945050505050565b868152600073ffffffffffffffffffffffffffffffffffffffff808816602084015280871660408401525084606083015283608083015260c060a0830152611fff60c0830184611a35565b9897505050505050505056fea164736f6c634300080f000a"
func init() {
if err := json.Unmarshal([]byte(L1CrossDomainMessengerStorageLayoutJSON), L1CrossDomainMessengerStorageLayout); err != nil {
......
......@@ -30,8 +30,8 @@ var (
// L2CrossDomainMessengerMetaData contains all meta data concerning the L2CrossDomainMessenger contract.
var L2CrossDomainMessengerMetaData = &bind.MetaData{
ABI: "[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_l1CrossDomainMessenger\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"msgHash\",\"type\":\"bytes32\"}],\"name\":\"FailedRelayedMessage\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint8\",\"name\":\"version\",\"type\":\"uint8\"}],\"name\":\"Initialized\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"msgHash\",\"type\":\"bytes32\"}],\"name\":\"RelayedMessage\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"target\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"message\",\"type\":\"bytes\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"messageNonce\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"gasLimit\",\"type\":\"uint256\"}],\"name\":\"SentMessage\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"}],\"name\":\"SentMessageExtension1\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"MESSAGE_VERSION\",\"outputs\":[{\"internalType\":\"uint16\",\"name\":\"\",\"type\":\"uint16\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"MIN_GAS_CALLDATA_OVERHEAD\",\"outputs\":[{\"internalType\":\"uint64\",\"name\":\"\",\"type\":\"uint64\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"MIN_GAS_CONSTANT_OVERHEAD\",\"outputs\":[{\"internalType\":\"uint64\",\"name\":\"\",\"type\":\"uint64\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"MIN_GAS_DYNAMIC_OVERHEAD_DENOMINATOR\",\"outputs\":[{\"internalType\":\"uint64\",\"name\":\"\",\"type\":\"uint64\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"MIN_GAS_DYNAMIC_OVERHEAD_NUMERATOR\",\"outputs\":[{\"internalType\":\"uint64\",\"name\":\"\",\"type\":\"uint64\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"OTHER_MESSENGER\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"_message\",\"type\":\"bytes\"},{\"internalType\":\"uint32\",\"name\":\"_minGasLimit\",\"type\":\"uint32\"}],\"name\":\"baseGas\",\"outputs\":[{\"internalType\":\"uint64\",\"name\":\"\",\"type\":\"uint64\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"name\":\"failedMessages\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"initialize\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"l1CrossDomainMessenger\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"messageNonce\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_nonce\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"_sender\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_target\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"_value\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_minGasLimit\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"_message\",\"type\":\"bytes\"}],\"name\":\"relayMessage\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_target\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"_message\",\"type\":\"bytes\"},{\"internalType\":\"uint32\",\"name\":\"_minGasLimit\",\"type\":\"uint32\"}],\"name\":\"sendMessage\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"name\":\"successfulMessages\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"version\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"xDomainMessageSender\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"}]",
Bin: "0x6101006040523480156200001257600080fd5b506040516200203138038062002031833981016040819052620000359162000243565b6001600160a01b038116608052600160a052600260c052600060e0526200005b62000062565b5062000275565b600054600160a81b900460ff16158080156200008b57506000546001600160a01b90910460ff16105b80620000c25750620000a830620001af60201b620011bf1760201c565b158015620000c25750600054600160a01b900460ff166001145b6200012b5760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201526d191e481a5b9a5d1a585b1a5e995960921b60648201526084015b60405180910390fd5b6000805460ff60a01b1916600160a01b179055801562000159576000805460ff60a81b1916600160a81b1790555b62000163620001be565b8015620001ac576000805460ff60a81b19169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b50565b6001600160a01b03163b151590565b600054600160a81b900460ff166200022d5760405162461bcd60e51b815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201526a6e697469616c697a696e6760a81b606482015260840162000122565b60cc80546001600160a01b03191661dead179055565b6000602082840312156200025657600080fd5b81516001600160a01b03811681146200026e57600080fd5b9392505050565b60805160a05160c05160e051611d6d620002c460003960006106480152600061061f015260006105f601526000818161022e0152818161029f015281816103900152610bfb0152611d6d6000f3fe6080604052600436106100f35760003560e01c80638129fc1c1161008a578063b1b1b20911610059578063b1b1b209146102c3578063b28ade25146102f3578063d764ad0b14610313578063ecc704281461032657600080fd5b80638129fc1c146102075780639fce812c1461021c578063a4e7f8bd14610250578063a71198691461029057600080fd5b80633f827a5a116100c65780633f827a5a1461016c57806354fd4d50146101945780636e296e45146101b65780637dea7cc3146101f057600080fd5b8063028f85f7146100f85780630c5684981461012b5780632828d7e8146101415780633dbb202b14610157575b600080fd5b34801561010457600080fd5b5061010d601081565b60405167ffffffffffffffff90911681526020015b60405180910390f35b34801561013757600080fd5b5061010d6103e881565b34801561014d57600080fd5b5061010d6103f881565b61016a610165366004611726565b61038b565b005b34801561017857600080fd5b50610181600181565b60405161ffff9091168152602001610122565b3480156101a057600080fd5b506101a96105ef565b6040516101229190611805565b3480156101c257600080fd5b506101cb610692565b60405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610122565b3480156101fc57600080fd5b5061010d62030d4081565b34801561021357600080fd5b5061016a61077e565b34801561022857600080fd5b506101cb7f000000000000000000000000000000000000000000000000000000000000000081565b34801561025c57600080fd5b5061028061026b36600461181f565b60ce6020526000908152604090205460ff1681565b6040519015158152602001610122565b34801561029c57600080fd5b507f00000000000000000000000000000000000000000000000000000000000000006101cb565b3480156102cf57600080fd5b506102806102de36600461181f565b60cb6020526000908152604090205460ff1681565b3480156102ff57600080fd5b5061010d61030e366004611838565b61097b565b61016a61032136600461188c565b6109c7565b34801561033257600080fd5b5061037d60cd547dffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff167e010000000000000000000000000000000000000000000000000000000000001790565b604051908152602001610122565b6104c47f00000000000000000000000000000000000000000000000000000000000000006103ba85858561097b565b347fd764ad0b0000000000000000000000000000000000000000000000000000000061042660cd547dffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff167e010000000000000000000000000000000000000000000000000000000000001790565b338a34898c8c6040516024016104429796959493929190611957565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff00000000000000000000000000000000000000000000000000000000909316929092179091526111db565b8373ffffffffffffffffffffffffffffffffffffffff167fcb0f7ffd78f9aee47a248fae8db181db6eee833039123e026dcbff529522e52a33858561054960cd547dffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff167e010000000000000000000000000000000000000000000000000000000000001790565b8660405161055b9594939291906119b6565b60405180910390a260405134815233907f8ebb2ec2465bdb2a06a66fc37a0963af8a2a6a1479d81d56fdb8cbb98096d5469060200160405180910390a2505060cd80547dffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff808216600101167fffff0000000000000000000000000000000000000000000000000000000000009091161790555050565b606061061a7f0000000000000000000000000000000000000000000000000000000000000000611269565b6106437f0000000000000000000000000000000000000000000000000000000000000000611269565b61066c7f0000000000000000000000000000000000000000000000000000000000000000611269565b60405160200161067e93929190611a04565b604051602081830303815290604052905090565b60cc5460009073ffffffffffffffffffffffffffffffffffffffff167fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff215301610761576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603560248201527f43726f7373446f6d61696e4d657373656e6765723a2078446f6d61696e4d657360448201527f7361676553656e646572206973206e6f7420736574000000000000000000000060648201526084015b60405180910390fd5b5060cc5473ffffffffffffffffffffffffffffffffffffffff1690565b6000547501000000000000000000000000000000000000000000900460ff16158080156107c9575060005460017401000000000000000000000000000000000000000090910460ff16105b806107fb5750303b1580156107fb575060005474010000000000000000000000000000000000000000900460ff166001145b610887576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a65640000000000000000000000000000000000006064820152608401610758565b600080547fffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffff1674010000000000000000000000000000000000000000179055801561090d57600080547fffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffffff1675010000000000000000000000000000000000000000001790555b61091561139e565b801561097857600080547fffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffffff169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b50565b600062030d4061098c601085611aa9565b6103e86109a16103f863ffffffff8716611aa9565b6109ab9190611b08565b6109b59190611b2f565b6109bf9190611b2f565b949350505050565b60f087901c60028110610a82576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604d60248201527f43726f7373446f6d61696e4d657373656e6765723a206f6e6c7920766572736960448201527f6f6e2030206f722031206d657373616765732061726520737570706f7274656460648201527f20617420746869732074696d6500000000000000000000000000000000000000608482015260a401610758565b8061ffff16600003610b77576000610ad3878986868080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152508f9250611477915050565b600081815260cb602052604090205490915060ff1615610b75576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603760248201527f43726f7373446f6d61696e4d657373656e6765723a206c65676163792077697460448201527f6864726177616c20616c72656164792072656c617965640000000000000000006064820152608401610758565b505b6000610bbd898989898989898080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061149692505050565b905073ffffffffffffffffffffffffffffffffffffffff7fffffffffffffffffffffffffeeeeffffffffffffffffffffffffffffffffeeef330181167f000000000000000000000000000000000000000000000000000000000000000090911603610c5557853414610c3157610c31611b5b565b600081815260ce602052604090205460ff1615610c5057610c50611b5b565b610da7565b3415610d09576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152605060248201527f43726f7373446f6d61696e4d657373656e6765723a2076616c7565206d75737460448201527f206265207a65726f20756e6c657373206d6573736167652069732066726f6d2060648201527f612073797374656d206164647265737300000000000000000000000000000000608482015260a401610758565b600081815260ce602052604090205460ff16610da7576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603060248201527f43726f7373446f6d61696e4d657373656e6765723a206d65737361676520636160448201527f6e6e6f74206265207265706c61796564000000000000000000000000000000006064820152608401610758565b610db0876114b9565b15610e63576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604360248201527f43726f7373446f6d61696e4d657373656e6765723a2063616e6e6f742073656e60448201527f64206d65737361676520746f20626c6f636b65642073797374656d206164647260648201527f6573730000000000000000000000000000000000000000000000000000000000608482015260a401610758565b600081815260cb602052604090205460ff1615610f02576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603660248201527f43726f7373446f6d61696e4d657373656e6765723a206d65737361676520686160448201527f7320616c7265616479206265656e2072656c61796564000000000000000000006064820152608401610758565b60cc5473ffffffffffffffffffffffffffffffffffffffff1661dead14610f8857600081815260ce602052604080822080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660011790555182917f99d0e048484baa1b1540b1367cb128acd7ab2946d1ed91ec10e3c85e4bf51b8f91a250506111b6565b60cc80547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff8a16179055604080516020601f860181900481028201810190925284815260009161100e918a9189918b918a908a908190840183828082843760009201919091525061150e92505050565b60cc80547fffffffffffffffffffffffff00000000000000000000000000000000000000001661dead179055905080156110a557600082815260cb602052604080822080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660011790555183917f4641df4a962071e12719d8c8c8e5ac7fc4d97b927346a3d7a335b1f7517e133c91a26111b2565b600082815260ce602052604080822080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660011790555183917f99d0e048484baa1b1540b1367cb128acd7ab2946d1ed91ec10e3c85e4bf51b8f91a27fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff32016111b2576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602d60248201527f43726f7373446f6d61696e4d657373656e6765723a206661696c656420746f2060448201527f72656c6179206d657373616765000000000000000000000000000000000000006064820152608401610758565b5050505b50505050505050565b73ffffffffffffffffffffffffffffffffffffffff163b151590565b6040517fc2b3e5ac0000000000000000000000000000000000000000000000000000000081527342000000000000000000000000000000000000169063c2b3e5ac90849061123190889088908790600401611b8a565b6000604051808303818588803b15801561124a57600080fd5b505af115801561125e573d6000803e3d6000fd5b505050505050505050565b6060816000036112ac57505060408051808201909152600181527f3000000000000000000000000000000000000000000000000000000000000000602082015290565b8160005b81156112d657806112c081611bd2565b91506112cf9050600a83611c0a565b91506112b0565b60008167ffffffffffffffff8111156112f1576112f1611c1e565b6040519080825280601f01601f19166020018201604052801561131b576020820181803683370190505b5090505b84156109bf57611330600183611c4d565b915061133d600a86611c64565b611348906030611c78565b60f81b81838151811061135d5761135d611c90565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a905350611397600a86611c0a565b945061131f565b6000547501000000000000000000000000000000000000000000900460ff16611449576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e670000000000000000000000000000000000000000006064820152608401610758565b60cc80547fffffffffffffffffffffffff00000000000000000000000000000000000000001661dead179055565b600061148585858585611568565b805190602001209050949350505050565b60006114a6878787878787611601565b8051906020012090509695505050505050565b600073ffffffffffffffffffffffffffffffffffffffff8216301480611508575073ffffffffffffffffffffffffffffffffffffffff8216734200000000000000000000000000000000000016145b92915050565b600080603f60c88601604002045a1015611551576308c379a06000526020805278185361666543616c6c3a204e6f7420656e6f756768206761736058526064601cfd5b600080845160208601878a5af19695505050505050565b6060848484846040516024016115819493929190611cbf565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fcbd4ece9000000000000000000000000000000000000000000000000000000001790529050949350505050565b606086868686868660405160240161161e96959493929190611d09565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fd764ad0b0000000000000000000000000000000000000000000000000000000017905290509695505050505050565b803573ffffffffffffffffffffffffffffffffffffffff811681146116c457600080fd5b919050565b60008083601f8401126116db57600080fd5b50813567ffffffffffffffff8111156116f357600080fd5b60208301915083602082850101111561170b57600080fd5b9250929050565b803563ffffffff811681146116c457600080fd5b6000806000806060858703121561173c57600080fd5b611745856116a0565b9350602085013567ffffffffffffffff81111561176157600080fd5b61176d878288016116c9565b9094509250611780905060408601611712565b905092959194509250565b60005b838110156117a657818101518382015260200161178e565b838111156117b5576000848401525b50505050565b600081518084526117d381602086016020860161178b565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b60208152600061181860208301846117bb565b9392505050565b60006020828403121561183157600080fd5b5035919050565b60008060006040848603121561184d57600080fd5b833567ffffffffffffffff81111561186457600080fd5b611870868287016116c9565b9094509250611883905060208501611712565b90509250925092565b600080600080600080600060c0888a0312156118a757600080fd5b873596506118b7602089016116a0565b95506118c5604089016116a0565b9450606088013593506080880135925060a088013567ffffffffffffffff8111156118ef57600080fd5b6118fb8a828b016116c9565b989b979a50959850939692959293505050565b8183528181602085013750600060208284010152600060207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f840116840101905092915050565b878152600073ffffffffffffffffffffffffffffffffffffffff808916602084015280881660408401525085606083015263ffffffff8516608083015260c060a08301526119a960c08301848661190e565b9998505050505050505050565b73ffffffffffffffffffffffffffffffffffffffff861681526080602082015260006119e660808301868861190e565b905083604083015263ffffffff831660608301529695505050505050565b60008451611a1681846020890161178b565b80830190507f2e000000000000000000000000000000000000000000000000000000000000008082528551611a52816001850160208a0161178b565b60019201918201528351611a6d81600284016020880161178b565b0160020195945050505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b600067ffffffffffffffff80831681851681830481118215151615611ad057611ad0611a7a565b02949350505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b600067ffffffffffffffff80841680611b2357611b23611ad9565b92169190910492915050565b600067ffffffffffffffff808316818516808303821115611b5257611b52611a7a565b01949350505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052600160045260246000fd5b73ffffffffffffffffffffffffffffffffffffffff8416815267ffffffffffffffff83166020820152606060408201526000611bc960608301846117bb565b95945050505050565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203611c0357611c03611a7a565b5060010190565b600082611c1957611c19611ad9565b500490565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b600082821015611c5f57611c5f611a7a565b500390565b600082611c7357611c73611ad9565b500690565b60008219821115611c8b57611c8b611a7a565b500190565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b600073ffffffffffffffffffffffffffffffffffffffff808716835280861660208401525060806040830152611cf860808301856117bb565b905082606083015295945050505050565b868152600073ffffffffffffffffffffffffffffffffffffffff808816602084015280871660408401525084606083015283608083015260c060a0830152611d5460c08301846117bb565b9897505050505050505056fea164736f6c634300080f000a",
ABI: "[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_l1CrossDomainMessenger\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"msgHash\",\"type\":\"bytes32\"}],\"name\":\"FailedRelayedMessage\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint8\",\"name\":\"version\",\"type\":\"uint8\"}],\"name\":\"Initialized\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"msgHash\",\"type\":\"bytes32\"}],\"name\":\"RelayedMessage\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"target\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"message\",\"type\":\"bytes\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"messageNonce\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"gasLimit\",\"type\":\"uint256\"}],\"name\":\"SentMessage\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"}],\"name\":\"SentMessageExtension1\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"MESSAGE_VERSION\",\"outputs\":[{\"internalType\":\"uint16\",\"name\":\"\",\"type\":\"uint16\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"MIN_GAS_CALLDATA_OVERHEAD\",\"outputs\":[{\"internalType\":\"uint64\",\"name\":\"\",\"type\":\"uint64\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"MIN_GAS_DYNAMIC_OVERHEAD_DENOMINATOR\",\"outputs\":[{\"internalType\":\"uint64\",\"name\":\"\",\"type\":\"uint64\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"MIN_GAS_DYNAMIC_OVERHEAD_NUMERATOR\",\"outputs\":[{\"internalType\":\"uint64\",\"name\":\"\",\"type\":\"uint64\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"OTHER_MESSENGER\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"RELAY_CALL_OVERHEAD\",\"outputs\":[{\"internalType\":\"uint64\",\"name\":\"\",\"type\":\"uint64\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"RELAY_CONSTANT_OVERHEAD\",\"outputs\":[{\"internalType\":\"uint64\",\"name\":\"\",\"type\":\"uint64\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"RELAY_GAS_CHECK_BUFFER\",\"outputs\":[{\"internalType\":\"uint64\",\"name\":\"\",\"type\":\"uint64\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"RELAY_RESERVED_GAS\",\"outputs\":[{\"internalType\":\"uint64\",\"name\":\"\",\"type\":\"uint64\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"_message\",\"type\":\"bytes\"},{\"internalType\":\"uint32\",\"name\":\"_minGasLimit\",\"type\":\"uint32\"}],\"name\":\"baseGas\",\"outputs\":[{\"internalType\":\"uint64\",\"name\":\"\",\"type\":\"uint64\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"name\":\"failedMessages\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"initialize\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"l1CrossDomainMessenger\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"messageNonce\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_nonce\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"_sender\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_target\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"_value\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_minGasLimit\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"_message\",\"type\":\"bytes\"}],\"name\":\"relayMessage\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_target\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"_message\",\"type\":\"bytes\"},{\"internalType\":\"uint32\",\"name\":\"_minGasLimit\",\"type\":\"uint32\"}],\"name\":\"sendMessage\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"name\":\"successfulMessages\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"version\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"xDomainMessageSender\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"}]",
Bin: "0x6101006040523480156200001257600080fd5b506040516200218e3803806200218e833981016040819052620000359162000243565b6001600160a01b038116608052600160a052600360c052600060e0526200005b62000062565b5062000275565b600054600160a81b900460ff16158080156200008b57506000546001600160a01b90910460ff16105b80620000c25750620000a830620001af60201b620013411760201c565b158015620000c25750600054600160a01b900460ff166001145b6200012b5760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201526d191e481a5b9a5d1a585b1a5e995960921b60648201526084015b60405180910390fd5b6000805460ff60a01b1916600160a01b179055801562000159576000805460ff60a81b1916600160a81b1790555b62000163620001be565b8015620001ac576000805460ff60a81b19169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b50565b6001600160a01b03163b151590565b600054600160a81b900460ff166200022d5760405162461bcd60e51b815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201526a6e697469616c697a696e6760a81b606482015260840162000122565b60cc80546001600160a01b03191661dead179055565b6000602082840312156200025657600080fd5b81516001600160a01b03811681146200026e57600080fd5b9392505050565b60805160a05160c05160e051611eca620002c460003960006106c30152600061069a015260006106710152600081816102a90152818161031a0152818161040b0152610c980152611eca6000f3fe6080604052600436106101445760003560e01c80638129fc1c116100c0578063a711986911610074578063b28ade2511610059578063b28ade251461036e578063d764ad0b1461038e578063ecc70428146103a157600080fd5b8063a71198691461030b578063b1b1b2091461033e57600080fd5b80638cbeeef2116100a55780638cbeeef2146101e35780639fce812c14610297578063a4e7f8bd146102cb57600080fd5b80638129fc1c1461026b57806383a740741461028057600080fd5b80633f827a5a1161011757806354fd4d50116100fc57806354fd4d50146101f95780635644cfdf1461021b5780636e296e451461023157600080fd5b80633f827a5a146101bb5780634c1d6a69146101e357600080fd5b8063028f85f7146101495780630c5684981461017c5780632828d7e8146101915780633dbb202b146101a6575b600080fd5b34801561015557600080fd5b5061015e601081565b60405167ffffffffffffffff90911681526020015b60405180910390f35b34801561018857600080fd5b5061015e603f81565b34801561019d57600080fd5b5061015e604081565b6101b96101b4366004611883565b610406565b005b3480156101c757600080fd5b506101d0600181565b60405161ffff9091168152602001610173565b3480156101ef57600080fd5b5061015e619c4081565b34801561020557600080fd5b5061020e61066a565b6040516101739190611962565b34801561022757600080fd5b5061015e61138881565b34801561023d57600080fd5b5061024661070d565b60405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610173565b34801561027757600080fd5b506101b96107f9565b34801561028c57600080fd5b5061015e62030d4081565b3480156102a357600080fd5b506102467f000000000000000000000000000000000000000000000000000000000000000081565b3480156102d757600080fd5b506102fb6102e636600461197c565b60ce6020526000908152604090205460ff1681565b6040519015158152602001610173565b34801561031757600080fd5b507f0000000000000000000000000000000000000000000000000000000000000000610246565b34801561034a57600080fd5b506102fb61035936600461197c565b60cb6020526000908152604090205460ff1681565b34801561037a57600080fd5b5061015e610389366004611995565b6109f6565b6101b961039c3660046119e9565b610a64565b3480156103ad57600080fd5b506103f860cd547dffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff167e010000000000000000000000000000000000000000000000000000000000001790565b604051908152602001610173565b61053f7f00000000000000000000000000000000000000000000000000000000000000006104358585856109f6565b347fd764ad0b000000000000000000000000000000000000000000000000000000006104a160cd547dffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff167e010000000000000000000000000000000000000000000000000000000000001790565b338a34898c8c6040516024016104bd9796959493929190611ab4565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff000000000000000000000000000000000000000000000000000000009093169290921790915261135d565b8373ffffffffffffffffffffffffffffffffffffffff167fcb0f7ffd78f9aee47a248fae8db181db6eee833039123e026dcbff529522e52a3385856105c460cd547dffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff167e010000000000000000000000000000000000000000000000000000000000001790565b866040516105d6959493929190611b13565b60405180910390a260405134815233907f8ebb2ec2465bdb2a06a66fc37a0963af8a2a6a1479d81d56fdb8cbb98096d5469060200160405180910390a2505060cd80547dffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff808216600101167fffff0000000000000000000000000000000000000000000000000000000000009091161790555050565b60606106957f00000000000000000000000000000000000000000000000000000000000000006113eb565b6106be7f00000000000000000000000000000000000000000000000000000000000000006113eb565b6106e77f00000000000000000000000000000000000000000000000000000000000000006113eb565b6040516020016106f993929190611b61565b604051602081830303815290604052905090565b60cc5460009073ffffffffffffffffffffffffffffffffffffffff167fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff2153016107dc576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603560248201527f43726f7373446f6d61696e4d657373656e6765723a2078446f6d61696e4d657360448201527f7361676553656e646572206973206e6f7420736574000000000000000000000060648201526084015b60405180910390fd5b5060cc5473ffffffffffffffffffffffffffffffffffffffff1690565b6000547501000000000000000000000000000000000000000000900460ff1615808015610844575060005460017401000000000000000000000000000000000000000090910460ff16105b806108765750303b158015610876575060005474010000000000000000000000000000000000000000900460ff166001145b610902576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a656400000000000000000000000000000000000060648201526084016107d3565b600080547fffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffff1674010000000000000000000000000000000000000000179055801561098857600080547fffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffffff1675010000000000000000000000000000000000000000001790555b610990611520565b80156109f357600080547fffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffffff169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b50565b6000611388619c4080603f610a12604063ffffffff8816611c06565b610a1c9190611c65565b610a27601088611c06565b610a349062030d40611c8c565b610a3e9190611c8c565b610a489190611c8c565b610a529190611c8c565b610a5c9190611c8c565b949350505050565b60f087901c60028110610b1f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604d60248201527f43726f7373446f6d61696e4d657373656e6765723a206f6e6c7920766572736960448201527f6f6e2030206f722031206d657373616765732061726520737570706f7274656460648201527f20617420746869732074696d6500000000000000000000000000000000000000608482015260a4016107d3565b8061ffff16600003610c14576000610b70878986868080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152508f92506115f9915050565b600081815260cb602052604090205490915060ff1615610c12576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603760248201527f43726f7373446f6d61696e4d657373656e6765723a206c65676163792077697460448201527f6864726177616c20616c72656164792072656c6179656400000000000000000060648201526084016107d3565b505b6000610c5a898989898989898080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061161892505050565b905073ffffffffffffffffffffffffffffffffffffffff7fffffffffffffffffffffffffeeeeffffffffffffffffffffffffffffffffeeef330181167f000000000000000000000000000000000000000000000000000000000000000090911603610cf257853414610cce57610cce611cb8565b600081815260ce602052604090205460ff1615610ced57610ced611cb8565b610e44565b3415610da6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152605060248201527f43726f7373446f6d61696e4d657373656e6765723a2076616c7565206d75737460448201527f206265207a65726f20756e6c657373206d6573736167652069732066726f6d2060648201527f612073797374656d206164647265737300000000000000000000000000000000608482015260a4016107d3565b600081815260ce602052604090205460ff16610e44576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603060248201527f43726f7373446f6d61696e4d657373656e6765723a206d65737361676520636160448201527f6e6e6f74206265207265706c617965640000000000000000000000000000000060648201526084016107d3565b610e4d8761163b565b15610f00576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604360248201527f43726f7373446f6d61696e4d657373656e6765723a2063616e6e6f742073656e60448201527f64206d65737361676520746f20626c6f636b65642073797374656d206164647260648201527f6573730000000000000000000000000000000000000000000000000000000000608482015260a4016107d3565b600081815260cb602052604090205460ff1615610f9f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603660248201527f43726f7373446f6d61696e4d657373656e6765723a206d65737361676520686160448201527f7320616c7265616479206265656e2072656c617965640000000000000000000060648201526084016107d3565b610fc085610fb1611388619c40611c8c565b67ffffffffffffffff16611690565b1580610fe6575060cc5473ffffffffffffffffffffffffffffffffffffffff1661dead14155b156110ff57600081815260ce602052604080822080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660011790555182917f99d0e048484baa1b1540b1367cb128acd7ab2946d1ed91ec10e3c85e4bf51b8f91a27fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff32016110f8576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602d60248201527f43726f7373446f6d61696e4d657373656e6765723a206661696c656420746f2060448201527f72656c6179206d6573736167650000000000000000000000000000000000000060648201526084016107d3565b5050611338565b60cc80547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff8a16179055600061119088619c405a6111539190611ce7565b8988888080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152506116ab92505050565b60cc80547fffffffffffffffffffffffff00000000000000000000000000000000000000001661dead1790559050801561122757600082815260cb602052604080822080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660011790555183917f4641df4a962071e12719d8c8c8e5ac7fc4d97b927346a3d7a335b1f7517e133c91a2611334565b600082815260ce602052604080822080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660011790555183917f99d0e048484baa1b1540b1367cb128acd7ab2946d1ed91ec10e3c85e4bf51b8f91a27fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff3201611334576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602d60248201527f43726f7373446f6d61696e4d657373656e6765723a206661696c656420746f2060448201527f72656c6179206d6573736167650000000000000000000000000000000000000060648201526084016107d3565b5050505b50505050505050565b73ffffffffffffffffffffffffffffffffffffffff163b151590565b6040517fc2b3e5ac0000000000000000000000000000000000000000000000000000000081527342000000000000000000000000000000000000169063c2b3e5ac9084906113b390889088908790600401611cfe565b6000604051808303818588803b1580156113cc57600080fd5b505af11580156113e0573d6000803e3d6000fd5b505050505050505050565b60608160000361142e57505060408051808201909152600181527f3000000000000000000000000000000000000000000000000000000000000000602082015290565b8160005b8115611458578061144281611d46565b91506114519050600a83611d7e565b9150611432565b60008167ffffffffffffffff81111561147357611473611d92565b6040519080825280601f01601f19166020018201604052801561149d576020820181803683370190505b5090505b8415610a5c576114b2600183611ce7565b91506114bf600a86611dc1565b6114ca906030611dd5565b60f81b8183815181106114df576114df611ded565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a905350611519600a86611d7e565b94506114a1565b6000547501000000000000000000000000000000000000000000900460ff166115cb576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e6700000000000000000000000000000000000000000060648201526084016107d3565b60cc80547fffffffffffffffffffffffff00000000000000000000000000000000000000001661dead179055565b6000611607858585856116c5565b805190602001209050949350505050565b600061162887878787878761175e565b8051906020012090509695505050505050565b600073ffffffffffffffffffffffffffffffffffffffff821630148061168a575073ffffffffffffffffffffffffffffffffffffffff8216734200000000000000000000000000000000000016145b92915050565b60008082619c4001603f6040860204015a1015949350505050565b600080600080845160208601878a8af19695505050505050565b6060848484846040516024016116de9493929190611e1c565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fcbd4ece9000000000000000000000000000000000000000000000000000000001790529050949350505050565b606086868686868660405160240161177b96959493929190611e66565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fd764ad0b0000000000000000000000000000000000000000000000000000000017905290509695505050505050565b803573ffffffffffffffffffffffffffffffffffffffff8116811461182157600080fd5b919050565b60008083601f84011261183857600080fd5b50813567ffffffffffffffff81111561185057600080fd5b60208301915083602082850101111561186857600080fd5b9250929050565b803563ffffffff8116811461182157600080fd5b6000806000806060858703121561189957600080fd5b6118a2856117fd565b9350602085013567ffffffffffffffff8111156118be57600080fd5b6118ca87828801611826565b90945092506118dd90506040860161186f565b905092959194509250565b60005b838110156119035781810151838201526020016118eb565b83811115611912576000848401525b50505050565b600081518084526119308160208601602086016118e8565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b6020815260006119756020830184611918565b9392505050565b60006020828403121561198e57600080fd5b5035919050565b6000806000604084860312156119aa57600080fd5b833567ffffffffffffffff8111156119c157600080fd5b6119cd86828701611826565b90945092506119e090506020850161186f565b90509250925092565b600080600080600080600060c0888a031215611a0457600080fd5b87359650611a14602089016117fd565b9550611a22604089016117fd565b9450606088013593506080880135925060a088013567ffffffffffffffff811115611a4c57600080fd5b611a588a828b01611826565b989b979a50959850939692959293505050565b8183528181602085013750600060208284010152600060207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f840116840101905092915050565b878152600073ffffffffffffffffffffffffffffffffffffffff808916602084015280881660408401525085606083015263ffffffff8516608083015260c060a0830152611b0660c083018486611a6b565b9998505050505050505050565b73ffffffffffffffffffffffffffffffffffffffff86168152608060208201526000611b43608083018688611a6b565b905083604083015263ffffffff831660608301529695505050505050565b60008451611b738184602089016118e8565b80830190507f2e000000000000000000000000000000000000000000000000000000000000008082528551611baf816001850160208a016118e8565b60019201918201528351611bca8160028401602088016118e8565b0160020195945050505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b600067ffffffffffffffff80831681851681830481118215151615611c2d57611c2d611bd7565b02949350505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b600067ffffffffffffffff80841680611c8057611c80611c36565b92169190910492915050565b600067ffffffffffffffff808316818516808303821115611caf57611caf611bd7565b01949350505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052600160045260246000fd5b600082821015611cf957611cf9611bd7565b500390565b73ffffffffffffffffffffffffffffffffffffffff8416815267ffffffffffffffff83166020820152606060408201526000611d3d6060830184611918565b95945050505050565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203611d7757611d77611bd7565b5060010190565b600082611d8d57611d8d611c36565b500490565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b600082611dd057611dd0611c36565b500690565b60008219821115611de857611de8611bd7565b500190565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b600073ffffffffffffffffffffffffffffffffffffffff808716835280861660208401525060806040830152611e556080830185611918565b905082606083015295945050505050565b868152600073ffffffffffffffffffffffffffffffffffffffff808816602084015280871660408401525084606083015283608083015260c060a0830152611eb160c0830184611918565b9897505050505050505056fea164736f6c634300080f000a",
}
// L2CrossDomainMessengerABI is the input ABI used to generate the binding from.
......@@ -263,37 +263,6 @@ func (_L2CrossDomainMessenger *L2CrossDomainMessengerCallerSession) MINGASCALLDA
return _L2CrossDomainMessenger.Contract.MINGASCALLDATAOVERHEAD(&_L2CrossDomainMessenger.CallOpts)
}
// MINGASCONSTANTOVERHEAD is a free data retrieval call binding the contract method 0x7dea7cc3.
//
// Solidity: function MIN_GAS_CONSTANT_OVERHEAD() view returns(uint64)
func (_L2CrossDomainMessenger *L2CrossDomainMessengerCaller) MINGASCONSTANTOVERHEAD(opts *bind.CallOpts) (uint64, error) {
var out []interface{}
err := _L2CrossDomainMessenger.contract.Call(opts, &out, "MIN_GAS_CONSTANT_OVERHEAD")
if err != nil {
return *new(uint64), err
}
out0 := *abi.ConvertType(out[0], new(uint64)).(*uint64)
return out0, err
}
// MINGASCONSTANTOVERHEAD is a free data retrieval call binding the contract method 0x7dea7cc3.
//
// Solidity: function MIN_GAS_CONSTANT_OVERHEAD() view returns(uint64)
func (_L2CrossDomainMessenger *L2CrossDomainMessengerSession) MINGASCONSTANTOVERHEAD() (uint64, error) {
return _L2CrossDomainMessenger.Contract.MINGASCONSTANTOVERHEAD(&_L2CrossDomainMessenger.CallOpts)
}
// MINGASCONSTANTOVERHEAD is a free data retrieval call binding the contract method 0x7dea7cc3.
//
// Solidity: function MIN_GAS_CONSTANT_OVERHEAD() view returns(uint64)
func (_L2CrossDomainMessenger *L2CrossDomainMessengerCallerSession) MINGASCONSTANTOVERHEAD() (uint64, error) {
return _L2CrossDomainMessenger.Contract.MINGASCONSTANTOVERHEAD(&_L2CrossDomainMessenger.CallOpts)
}
// MINGASDYNAMICOVERHEADDENOMINATOR is a free data retrieval call binding the contract method 0x0c568498.
//
// Solidity: function MIN_GAS_DYNAMIC_OVERHEAD_DENOMINATOR() view returns(uint64)
......@@ -387,6 +356,130 @@ func (_L2CrossDomainMessenger *L2CrossDomainMessengerCallerSession) OTHERMESSENG
return _L2CrossDomainMessenger.Contract.OTHERMESSENGER(&_L2CrossDomainMessenger.CallOpts)
}
// RELAYCALLOVERHEAD is a free data retrieval call binding the contract method 0x4c1d6a69.
//
// Solidity: function RELAY_CALL_OVERHEAD() view returns(uint64)
func (_L2CrossDomainMessenger *L2CrossDomainMessengerCaller) RELAYCALLOVERHEAD(opts *bind.CallOpts) (uint64, error) {
var out []interface{}
err := _L2CrossDomainMessenger.contract.Call(opts, &out, "RELAY_CALL_OVERHEAD")
if err != nil {
return *new(uint64), err
}
out0 := *abi.ConvertType(out[0], new(uint64)).(*uint64)
return out0, err
}
// RELAYCALLOVERHEAD is a free data retrieval call binding the contract method 0x4c1d6a69.
//
// Solidity: function RELAY_CALL_OVERHEAD() view returns(uint64)
func (_L2CrossDomainMessenger *L2CrossDomainMessengerSession) RELAYCALLOVERHEAD() (uint64, error) {
return _L2CrossDomainMessenger.Contract.RELAYCALLOVERHEAD(&_L2CrossDomainMessenger.CallOpts)
}
// RELAYCALLOVERHEAD is a free data retrieval call binding the contract method 0x4c1d6a69.
//
// Solidity: function RELAY_CALL_OVERHEAD() view returns(uint64)
func (_L2CrossDomainMessenger *L2CrossDomainMessengerCallerSession) RELAYCALLOVERHEAD() (uint64, error) {
return _L2CrossDomainMessenger.Contract.RELAYCALLOVERHEAD(&_L2CrossDomainMessenger.CallOpts)
}
// RELAYCONSTANTOVERHEAD is a free data retrieval call binding the contract method 0x83a74074.
//
// Solidity: function RELAY_CONSTANT_OVERHEAD() view returns(uint64)
func (_L2CrossDomainMessenger *L2CrossDomainMessengerCaller) RELAYCONSTANTOVERHEAD(opts *bind.CallOpts) (uint64, error) {
var out []interface{}
err := _L2CrossDomainMessenger.contract.Call(opts, &out, "RELAY_CONSTANT_OVERHEAD")
if err != nil {
return *new(uint64), err
}
out0 := *abi.ConvertType(out[0], new(uint64)).(*uint64)
return out0, err
}
// RELAYCONSTANTOVERHEAD is a free data retrieval call binding the contract method 0x83a74074.
//
// Solidity: function RELAY_CONSTANT_OVERHEAD() view returns(uint64)
func (_L2CrossDomainMessenger *L2CrossDomainMessengerSession) RELAYCONSTANTOVERHEAD() (uint64, error) {
return _L2CrossDomainMessenger.Contract.RELAYCONSTANTOVERHEAD(&_L2CrossDomainMessenger.CallOpts)
}
// RELAYCONSTANTOVERHEAD is a free data retrieval call binding the contract method 0x83a74074.
//
// Solidity: function RELAY_CONSTANT_OVERHEAD() view returns(uint64)
func (_L2CrossDomainMessenger *L2CrossDomainMessengerCallerSession) RELAYCONSTANTOVERHEAD() (uint64, error) {
return _L2CrossDomainMessenger.Contract.RELAYCONSTANTOVERHEAD(&_L2CrossDomainMessenger.CallOpts)
}
// RELAYGASCHECKBUFFER is a free data retrieval call binding the contract method 0x5644cfdf.
//
// Solidity: function RELAY_GAS_CHECK_BUFFER() view returns(uint64)
func (_L2CrossDomainMessenger *L2CrossDomainMessengerCaller) RELAYGASCHECKBUFFER(opts *bind.CallOpts) (uint64, error) {
var out []interface{}
err := _L2CrossDomainMessenger.contract.Call(opts, &out, "RELAY_GAS_CHECK_BUFFER")
if err != nil {
return *new(uint64), err
}
out0 := *abi.ConvertType(out[0], new(uint64)).(*uint64)
return out0, err
}
// RELAYGASCHECKBUFFER is a free data retrieval call binding the contract method 0x5644cfdf.
//
// Solidity: function RELAY_GAS_CHECK_BUFFER() view returns(uint64)
func (_L2CrossDomainMessenger *L2CrossDomainMessengerSession) RELAYGASCHECKBUFFER() (uint64, error) {
return _L2CrossDomainMessenger.Contract.RELAYGASCHECKBUFFER(&_L2CrossDomainMessenger.CallOpts)
}
// RELAYGASCHECKBUFFER is a free data retrieval call binding the contract method 0x5644cfdf.
//
// Solidity: function RELAY_GAS_CHECK_BUFFER() view returns(uint64)
func (_L2CrossDomainMessenger *L2CrossDomainMessengerCallerSession) RELAYGASCHECKBUFFER() (uint64, error) {
return _L2CrossDomainMessenger.Contract.RELAYGASCHECKBUFFER(&_L2CrossDomainMessenger.CallOpts)
}
// RELAYRESERVEDGAS is a free data retrieval call binding the contract method 0x8cbeeef2.
//
// Solidity: function RELAY_RESERVED_GAS() view returns(uint64)
func (_L2CrossDomainMessenger *L2CrossDomainMessengerCaller) RELAYRESERVEDGAS(opts *bind.CallOpts) (uint64, error) {
var out []interface{}
err := _L2CrossDomainMessenger.contract.Call(opts, &out, "RELAY_RESERVED_GAS")
if err != nil {
return *new(uint64), err
}
out0 := *abi.ConvertType(out[0], new(uint64)).(*uint64)
return out0, err
}
// RELAYRESERVEDGAS is a free data retrieval call binding the contract method 0x8cbeeef2.
//
// Solidity: function RELAY_RESERVED_GAS() view returns(uint64)
func (_L2CrossDomainMessenger *L2CrossDomainMessengerSession) RELAYRESERVEDGAS() (uint64, error) {
return _L2CrossDomainMessenger.Contract.RELAYRESERVEDGAS(&_L2CrossDomainMessenger.CallOpts)
}
// RELAYRESERVEDGAS is a free data retrieval call binding the contract method 0x8cbeeef2.
//
// Solidity: function RELAY_RESERVED_GAS() view returns(uint64)
func (_L2CrossDomainMessenger *L2CrossDomainMessengerCallerSession) RELAYRESERVEDGAS() (uint64, error) {
return _L2CrossDomainMessenger.Contract.RELAYRESERVEDGAS(&_L2CrossDomainMessenger.CallOpts)
}
// BaseGas is a free data retrieval call binding the contract method 0xb28ade25.
//
// Solidity: function baseGas(bytes _message, uint32 _minGasLimit) pure returns(uint64)
......
......@@ -13,7 +13,7 @@ const L2CrossDomainMessengerStorageLayoutJSON = "{\"storage\":[{\"astId\":1000,\
var L2CrossDomainMessengerStorageLayout = new(solc.StorageLayout)
var L2CrossDomainMessengerDeployedBin = "0x6080604052600436106100f35760003560e01c80638129fc1c1161008a578063b1b1b20911610059578063b1b1b209146102c3578063b28ade25146102f3578063d764ad0b14610313578063ecc704281461032657600080fd5b80638129fc1c146102075780639fce812c1461021c578063a4e7f8bd14610250578063a71198691461029057600080fd5b80633f827a5a116100c65780633f827a5a1461016c57806354fd4d50146101945780636e296e45146101b65780637dea7cc3146101f057600080fd5b8063028f85f7146100f85780630c5684981461012b5780632828d7e8146101415780633dbb202b14610157575b600080fd5b34801561010457600080fd5b5061010d601081565b60405167ffffffffffffffff90911681526020015b60405180910390f35b34801561013757600080fd5b5061010d6103e881565b34801561014d57600080fd5b5061010d6103f881565b61016a610165366004611726565b61038b565b005b34801561017857600080fd5b50610181600181565b60405161ffff9091168152602001610122565b3480156101a057600080fd5b506101a96105ef565b6040516101229190611805565b3480156101c257600080fd5b506101cb610692565b60405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610122565b3480156101fc57600080fd5b5061010d62030d4081565b34801561021357600080fd5b5061016a61077e565b34801561022857600080fd5b506101cb7f000000000000000000000000000000000000000000000000000000000000000081565b34801561025c57600080fd5b5061028061026b36600461181f565b60ce6020526000908152604090205460ff1681565b6040519015158152602001610122565b34801561029c57600080fd5b507f00000000000000000000000000000000000000000000000000000000000000006101cb565b3480156102cf57600080fd5b506102806102de36600461181f565b60cb6020526000908152604090205460ff1681565b3480156102ff57600080fd5b5061010d61030e366004611838565b61097b565b61016a61032136600461188c565b6109c7565b34801561033257600080fd5b5061037d60cd547dffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff167e010000000000000000000000000000000000000000000000000000000000001790565b604051908152602001610122565b6104c47f00000000000000000000000000000000000000000000000000000000000000006103ba85858561097b565b347fd764ad0b0000000000000000000000000000000000000000000000000000000061042660cd547dffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff167e010000000000000000000000000000000000000000000000000000000000001790565b338a34898c8c6040516024016104429796959493929190611957565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff00000000000000000000000000000000000000000000000000000000909316929092179091526111db565b8373ffffffffffffffffffffffffffffffffffffffff167fcb0f7ffd78f9aee47a248fae8db181db6eee833039123e026dcbff529522e52a33858561054960cd547dffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff167e010000000000000000000000000000000000000000000000000000000000001790565b8660405161055b9594939291906119b6565b60405180910390a260405134815233907f8ebb2ec2465bdb2a06a66fc37a0963af8a2a6a1479d81d56fdb8cbb98096d5469060200160405180910390a2505060cd80547dffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff808216600101167fffff0000000000000000000000000000000000000000000000000000000000009091161790555050565b606061061a7f0000000000000000000000000000000000000000000000000000000000000000611269565b6106437f0000000000000000000000000000000000000000000000000000000000000000611269565b61066c7f0000000000000000000000000000000000000000000000000000000000000000611269565b60405160200161067e93929190611a04565b604051602081830303815290604052905090565b60cc5460009073ffffffffffffffffffffffffffffffffffffffff167fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff215301610761576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603560248201527f43726f7373446f6d61696e4d657373656e6765723a2078446f6d61696e4d657360448201527f7361676553656e646572206973206e6f7420736574000000000000000000000060648201526084015b60405180910390fd5b5060cc5473ffffffffffffffffffffffffffffffffffffffff1690565b6000547501000000000000000000000000000000000000000000900460ff16158080156107c9575060005460017401000000000000000000000000000000000000000090910460ff16105b806107fb5750303b1580156107fb575060005474010000000000000000000000000000000000000000900460ff166001145b610887576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a65640000000000000000000000000000000000006064820152608401610758565b600080547fffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffff1674010000000000000000000000000000000000000000179055801561090d57600080547fffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffffff1675010000000000000000000000000000000000000000001790555b61091561139e565b801561097857600080547fffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffffff169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b50565b600062030d4061098c601085611aa9565b6103e86109a16103f863ffffffff8716611aa9565b6109ab9190611b08565b6109b59190611b2f565b6109bf9190611b2f565b949350505050565b60f087901c60028110610a82576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604d60248201527f43726f7373446f6d61696e4d657373656e6765723a206f6e6c7920766572736960448201527f6f6e2030206f722031206d657373616765732061726520737570706f7274656460648201527f20617420746869732074696d6500000000000000000000000000000000000000608482015260a401610758565b8061ffff16600003610b77576000610ad3878986868080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152508f9250611477915050565b600081815260cb602052604090205490915060ff1615610b75576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603760248201527f43726f7373446f6d61696e4d657373656e6765723a206c65676163792077697460448201527f6864726177616c20616c72656164792072656c617965640000000000000000006064820152608401610758565b505b6000610bbd898989898989898080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061149692505050565b905073ffffffffffffffffffffffffffffffffffffffff7fffffffffffffffffffffffffeeeeffffffffffffffffffffffffffffffffeeef330181167f000000000000000000000000000000000000000000000000000000000000000090911603610c5557853414610c3157610c31611b5b565b600081815260ce602052604090205460ff1615610c5057610c50611b5b565b610da7565b3415610d09576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152605060248201527f43726f7373446f6d61696e4d657373656e6765723a2076616c7565206d75737460448201527f206265207a65726f20756e6c657373206d6573736167652069732066726f6d2060648201527f612073797374656d206164647265737300000000000000000000000000000000608482015260a401610758565b600081815260ce602052604090205460ff16610da7576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603060248201527f43726f7373446f6d61696e4d657373656e6765723a206d65737361676520636160448201527f6e6e6f74206265207265706c61796564000000000000000000000000000000006064820152608401610758565b610db0876114b9565b15610e63576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604360248201527f43726f7373446f6d61696e4d657373656e6765723a2063616e6e6f742073656e60448201527f64206d65737361676520746f20626c6f636b65642073797374656d206164647260648201527f6573730000000000000000000000000000000000000000000000000000000000608482015260a401610758565b600081815260cb602052604090205460ff1615610f02576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603660248201527f43726f7373446f6d61696e4d657373656e6765723a206d65737361676520686160448201527f7320616c7265616479206265656e2072656c61796564000000000000000000006064820152608401610758565b60cc5473ffffffffffffffffffffffffffffffffffffffff1661dead14610f8857600081815260ce602052604080822080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660011790555182917f99d0e048484baa1b1540b1367cb128acd7ab2946d1ed91ec10e3c85e4bf51b8f91a250506111b6565b60cc80547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff8a16179055604080516020601f860181900481028201810190925284815260009161100e918a9189918b918a908a908190840183828082843760009201919091525061150e92505050565b60cc80547fffffffffffffffffffffffff00000000000000000000000000000000000000001661dead179055905080156110a557600082815260cb602052604080822080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660011790555183917f4641df4a962071e12719d8c8c8e5ac7fc4d97b927346a3d7a335b1f7517e133c91a26111b2565b600082815260ce602052604080822080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660011790555183917f99d0e048484baa1b1540b1367cb128acd7ab2946d1ed91ec10e3c85e4bf51b8f91a27fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff32016111b2576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602d60248201527f43726f7373446f6d61696e4d657373656e6765723a206661696c656420746f2060448201527f72656c6179206d657373616765000000000000000000000000000000000000006064820152608401610758565b5050505b50505050505050565b73ffffffffffffffffffffffffffffffffffffffff163b151590565b6040517fc2b3e5ac0000000000000000000000000000000000000000000000000000000081527342000000000000000000000000000000000000169063c2b3e5ac90849061123190889088908790600401611b8a565b6000604051808303818588803b15801561124a57600080fd5b505af115801561125e573d6000803e3d6000fd5b505050505050505050565b6060816000036112ac57505060408051808201909152600181527f3000000000000000000000000000000000000000000000000000000000000000602082015290565b8160005b81156112d657806112c081611bd2565b91506112cf9050600a83611c0a565b91506112b0565b60008167ffffffffffffffff8111156112f1576112f1611c1e565b6040519080825280601f01601f19166020018201604052801561131b576020820181803683370190505b5090505b84156109bf57611330600183611c4d565b915061133d600a86611c64565b611348906030611c78565b60f81b81838151811061135d5761135d611c90565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a905350611397600a86611c0a565b945061131f565b6000547501000000000000000000000000000000000000000000900460ff16611449576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e670000000000000000000000000000000000000000006064820152608401610758565b60cc80547fffffffffffffffffffffffff00000000000000000000000000000000000000001661dead179055565b600061148585858585611568565b805190602001209050949350505050565b60006114a6878787878787611601565b8051906020012090509695505050505050565b600073ffffffffffffffffffffffffffffffffffffffff8216301480611508575073ffffffffffffffffffffffffffffffffffffffff8216734200000000000000000000000000000000000016145b92915050565b600080603f60c88601604002045a1015611551576308c379a06000526020805278185361666543616c6c3a204e6f7420656e6f756768206761736058526064601cfd5b600080845160208601878a5af19695505050505050565b6060848484846040516024016115819493929190611cbf565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fcbd4ece9000000000000000000000000000000000000000000000000000000001790529050949350505050565b606086868686868660405160240161161e96959493929190611d09565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fd764ad0b0000000000000000000000000000000000000000000000000000000017905290509695505050505050565b803573ffffffffffffffffffffffffffffffffffffffff811681146116c457600080fd5b919050565b60008083601f8401126116db57600080fd5b50813567ffffffffffffffff8111156116f357600080fd5b60208301915083602082850101111561170b57600080fd5b9250929050565b803563ffffffff811681146116c457600080fd5b6000806000806060858703121561173c57600080fd5b611745856116a0565b9350602085013567ffffffffffffffff81111561176157600080fd5b61176d878288016116c9565b9094509250611780905060408601611712565b905092959194509250565b60005b838110156117a657818101518382015260200161178e565b838111156117b5576000848401525b50505050565b600081518084526117d381602086016020860161178b565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b60208152600061181860208301846117bb565b9392505050565b60006020828403121561183157600080fd5b5035919050565b60008060006040848603121561184d57600080fd5b833567ffffffffffffffff81111561186457600080fd5b611870868287016116c9565b9094509250611883905060208501611712565b90509250925092565b600080600080600080600060c0888a0312156118a757600080fd5b873596506118b7602089016116a0565b95506118c5604089016116a0565b9450606088013593506080880135925060a088013567ffffffffffffffff8111156118ef57600080fd5b6118fb8a828b016116c9565b989b979a50959850939692959293505050565b8183528181602085013750600060208284010152600060207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f840116840101905092915050565b878152600073ffffffffffffffffffffffffffffffffffffffff808916602084015280881660408401525085606083015263ffffffff8516608083015260c060a08301526119a960c08301848661190e565b9998505050505050505050565b73ffffffffffffffffffffffffffffffffffffffff861681526080602082015260006119e660808301868861190e565b905083604083015263ffffffff831660608301529695505050505050565b60008451611a1681846020890161178b565b80830190507f2e000000000000000000000000000000000000000000000000000000000000008082528551611a52816001850160208a0161178b565b60019201918201528351611a6d81600284016020880161178b565b0160020195945050505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b600067ffffffffffffffff80831681851681830481118215151615611ad057611ad0611a7a565b02949350505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b600067ffffffffffffffff80841680611b2357611b23611ad9565b92169190910492915050565b600067ffffffffffffffff808316818516808303821115611b5257611b52611a7a565b01949350505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052600160045260246000fd5b73ffffffffffffffffffffffffffffffffffffffff8416815267ffffffffffffffff83166020820152606060408201526000611bc960608301846117bb565b95945050505050565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203611c0357611c03611a7a565b5060010190565b600082611c1957611c19611ad9565b500490565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b600082821015611c5f57611c5f611a7a565b500390565b600082611c7357611c73611ad9565b500690565b60008219821115611c8b57611c8b611a7a565b500190565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b600073ffffffffffffffffffffffffffffffffffffffff808716835280861660208401525060806040830152611cf860808301856117bb565b905082606083015295945050505050565b868152600073ffffffffffffffffffffffffffffffffffffffff808816602084015280871660408401525084606083015283608083015260c060a0830152611d5460c08301846117bb565b9897505050505050505056fea164736f6c634300080f000a"
var L2CrossDomainMessengerDeployedBin = "0x6080604052600436106101445760003560e01c80638129fc1c116100c0578063a711986911610074578063b28ade2511610059578063b28ade251461036e578063d764ad0b1461038e578063ecc70428146103a157600080fd5b8063a71198691461030b578063b1b1b2091461033e57600080fd5b80638cbeeef2116100a55780638cbeeef2146101e35780639fce812c14610297578063a4e7f8bd146102cb57600080fd5b80638129fc1c1461026b57806383a740741461028057600080fd5b80633f827a5a1161011757806354fd4d50116100fc57806354fd4d50146101f95780635644cfdf1461021b5780636e296e451461023157600080fd5b80633f827a5a146101bb5780634c1d6a69146101e357600080fd5b8063028f85f7146101495780630c5684981461017c5780632828d7e8146101915780633dbb202b146101a6575b600080fd5b34801561015557600080fd5b5061015e601081565b60405167ffffffffffffffff90911681526020015b60405180910390f35b34801561018857600080fd5b5061015e603f81565b34801561019d57600080fd5b5061015e604081565b6101b96101b4366004611883565b610406565b005b3480156101c757600080fd5b506101d0600181565b60405161ffff9091168152602001610173565b3480156101ef57600080fd5b5061015e619c4081565b34801561020557600080fd5b5061020e61066a565b6040516101739190611962565b34801561022757600080fd5b5061015e61138881565b34801561023d57600080fd5b5061024661070d565b60405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610173565b34801561027757600080fd5b506101b96107f9565b34801561028c57600080fd5b5061015e62030d4081565b3480156102a357600080fd5b506102467f000000000000000000000000000000000000000000000000000000000000000081565b3480156102d757600080fd5b506102fb6102e636600461197c565b60ce6020526000908152604090205460ff1681565b6040519015158152602001610173565b34801561031757600080fd5b507f0000000000000000000000000000000000000000000000000000000000000000610246565b34801561034a57600080fd5b506102fb61035936600461197c565b60cb6020526000908152604090205460ff1681565b34801561037a57600080fd5b5061015e610389366004611995565b6109f6565b6101b961039c3660046119e9565b610a64565b3480156103ad57600080fd5b506103f860cd547dffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff167e010000000000000000000000000000000000000000000000000000000000001790565b604051908152602001610173565b61053f7f00000000000000000000000000000000000000000000000000000000000000006104358585856109f6565b347fd764ad0b000000000000000000000000000000000000000000000000000000006104a160cd547dffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff167e010000000000000000000000000000000000000000000000000000000000001790565b338a34898c8c6040516024016104bd9796959493929190611ab4565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff000000000000000000000000000000000000000000000000000000009093169290921790915261135d565b8373ffffffffffffffffffffffffffffffffffffffff167fcb0f7ffd78f9aee47a248fae8db181db6eee833039123e026dcbff529522e52a3385856105c460cd547dffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff167e010000000000000000000000000000000000000000000000000000000000001790565b866040516105d6959493929190611b13565b60405180910390a260405134815233907f8ebb2ec2465bdb2a06a66fc37a0963af8a2a6a1479d81d56fdb8cbb98096d5469060200160405180910390a2505060cd80547dffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff808216600101167fffff0000000000000000000000000000000000000000000000000000000000009091161790555050565b60606106957f00000000000000000000000000000000000000000000000000000000000000006113eb565b6106be7f00000000000000000000000000000000000000000000000000000000000000006113eb565b6106e77f00000000000000000000000000000000000000000000000000000000000000006113eb565b6040516020016106f993929190611b61565b604051602081830303815290604052905090565b60cc5460009073ffffffffffffffffffffffffffffffffffffffff167fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff2153016107dc576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603560248201527f43726f7373446f6d61696e4d657373656e6765723a2078446f6d61696e4d657360448201527f7361676553656e646572206973206e6f7420736574000000000000000000000060648201526084015b60405180910390fd5b5060cc5473ffffffffffffffffffffffffffffffffffffffff1690565b6000547501000000000000000000000000000000000000000000900460ff1615808015610844575060005460017401000000000000000000000000000000000000000090910460ff16105b806108765750303b158015610876575060005474010000000000000000000000000000000000000000900460ff166001145b610902576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a656400000000000000000000000000000000000060648201526084016107d3565b600080547fffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffff1674010000000000000000000000000000000000000000179055801561098857600080547fffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffffff1675010000000000000000000000000000000000000000001790555b610990611520565b80156109f357600080547fffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffffff169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b50565b6000611388619c4080603f610a12604063ffffffff8816611c06565b610a1c9190611c65565b610a27601088611c06565b610a349062030d40611c8c565b610a3e9190611c8c565b610a489190611c8c565b610a529190611c8c565b610a5c9190611c8c565b949350505050565b60f087901c60028110610b1f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604d60248201527f43726f7373446f6d61696e4d657373656e6765723a206f6e6c7920766572736960448201527f6f6e2030206f722031206d657373616765732061726520737570706f7274656460648201527f20617420746869732074696d6500000000000000000000000000000000000000608482015260a4016107d3565b8061ffff16600003610c14576000610b70878986868080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152508f92506115f9915050565b600081815260cb602052604090205490915060ff1615610c12576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603760248201527f43726f7373446f6d61696e4d657373656e6765723a206c65676163792077697460448201527f6864726177616c20616c72656164792072656c6179656400000000000000000060648201526084016107d3565b505b6000610c5a898989898989898080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061161892505050565b905073ffffffffffffffffffffffffffffffffffffffff7fffffffffffffffffffffffffeeeeffffffffffffffffffffffffffffffffeeef330181167f000000000000000000000000000000000000000000000000000000000000000090911603610cf257853414610cce57610cce611cb8565b600081815260ce602052604090205460ff1615610ced57610ced611cb8565b610e44565b3415610da6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152605060248201527f43726f7373446f6d61696e4d657373656e6765723a2076616c7565206d75737460448201527f206265207a65726f20756e6c657373206d6573736167652069732066726f6d2060648201527f612073797374656d206164647265737300000000000000000000000000000000608482015260a4016107d3565b600081815260ce602052604090205460ff16610e44576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603060248201527f43726f7373446f6d61696e4d657373656e6765723a206d65737361676520636160448201527f6e6e6f74206265207265706c617965640000000000000000000000000000000060648201526084016107d3565b610e4d8761163b565b15610f00576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604360248201527f43726f7373446f6d61696e4d657373656e6765723a2063616e6e6f742073656e60448201527f64206d65737361676520746f20626c6f636b65642073797374656d206164647260648201527f6573730000000000000000000000000000000000000000000000000000000000608482015260a4016107d3565b600081815260cb602052604090205460ff1615610f9f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603660248201527f43726f7373446f6d61696e4d657373656e6765723a206d65737361676520686160448201527f7320616c7265616479206265656e2072656c617965640000000000000000000060648201526084016107d3565b610fc085610fb1611388619c40611c8c565b67ffffffffffffffff16611690565b1580610fe6575060cc5473ffffffffffffffffffffffffffffffffffffffff1661dead14155b156110ff57600081815260ce602052604080822080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660011790555182917f99d0e048484baa1b1540b1367cb128acd7ab2946d1ed91ec10e3c85e4bf51b8f91a27fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff32016110f8576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602d60248201527f43726f7373446f6d61696e4d657373656e6765723a206661696c656420746f2060448201527f72656c6179206d6573736167650000000000000000000000000000000000000060648201526084016107d3565b5050611338565b60cc80547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff8a16179055600061119088619c405a6111539190611ce7565b8988888080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152506116ab92505050565b60cc80547fffffffffffffffffffffffff00000000000000000000000000000000000000001661dead1790559050801561122757600082815260cb602052604080822080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660011790555183917f4641df4a962071e12719d8c8c8e5ac7fc4d97b927346a3d7a335b1f7517e133c91a2611334565b600082815260ce602052604080822080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660011790555183917f99d0e048484baa1b1540b1367cb128acd7ab2946d1ed91ec10e3c85e4bf51b8f91a27fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff3201611334576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602d60248201527f43726f7373446f6d61696e4d657373656e6765723a206661696c656420746f2060448201527f72656c6179206d6573736167650000000000000000000000000000000000000060648201526084016107d3565b5050505b50505050505050565b73ffffffffffffffffffffffffffffffffffffffff163b151590565b6040517fc2b3e5ac0000000000000000000000000000000000000000000000000000000081527342000000000000000000000000000000000000169063c2b3e5ac9084906113b390889088908790600401611cfe565b6000604051808303818588803b1580156113cc57600080fd5b505af11580156113e0573d6000803e3d6000fd5b505050505050505050565b60608160000361142e57505060408051808201909152600181527f3000000000000000000000000000000000000000000000000000000000000000602082015290565b8160005b8115611458578061144281611d46565b91506114519050600a83611d7e565b9150611432565b60008167ffffffffffffffff81111561147357611473611d92565b6040519080825280601f01601f19166020018201604052801561149d576020820181803683370190505b5090505b8415610a5c576114b2600183611ce7565b91506114bf600a86611dc1565b6114ca906030611dd5565b60f81b8183815181106114df576114df611ded565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a905350611519600a86611d7e565b94506114a1565b6000547501000000000000000000000000000000000000000000900460ff166115cb576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e6700000000000000000000000000000000000000000060648201526084016107d3565b60cc80547fffffffffffffffffffffffff00000000000000000000000000000000000000001661dead179055565b6000611607858585856116c5565b805190602001209050949350505050565b600061162887878787878761175e565b8051906020012090509695505050505050565b600073ffffffffffffffffffffffffffffffffffffffff821630148061168a575073ffffffffffffffffffffffffffffffffffffffff8216734200000000000000000000000000000000000016145b92915050565b60008082619c4001603f6040860204015a1015949350505050565b600080600080845160208601878a8af19695505050505050565b6060848484846040516024016116de9493929190611e1c565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fcbd4ece9000000000000000000000000000000000000000000000000000000001790529050949350505050565b606086868686868660405160240161177b96959493929190611e66565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fd764ad0b0000000000000000000000000000000000000000000000000000000017905290509695505050505050565b803573ffffffffffffffffffffffffffffffffffffffff8116811461182157600080fd5b919050565b60008083601f84011261183857600080fd5b50813567ffffffffffffffff81111561185057600080fd5b60208301915083602082850101111561186857600080fd5b9250929050565b803563ffffffff8116811461182157600080fd5b6000806000806060858703121561189957600080fd5b6118a2856117fd565b9350602085013567ffffffffffffffff8111156118be57600080fd5b6118ca87828801611826565b90945092506118dd90506040860161186f565b905092959194509250565b60005b838110156119035781810151838201526020016118eb565b83811115611912576000848401525b50505050565b600081518084526119308160208601602086016118e8565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b6020815260006119756020830184611918565b9392505050565b60006020828403121561198e57600080fd5b5035919050565b6000806000604084860312156119aa57600080fd5b833567ffffffffffffffff8111156119c157600080fd5b6119cd86828701611826565b90945092506119e090506020850161186f565b90509250925092565b600080600080600080600060c0888a031215611a0457600080fd5b87359650611a14602089016117fd565b9550611a22604089016117fd565b9450606088013593506080880135925060a088013567ffffffffffffffff811115611a4c57600080fd5b611a588a828b01611826565b989b979a50959850939692959293505050565b8183528181602085013750600060208284010152600060207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f840116840101905092915050565b878152600073ffffffffffffffffffffffffffffffffffffffff808916602084015280881660408401525085606083015263ffffffff8516608083015260c060a0830152611b0660c083018486611a6b565b9998505050505050505050565b73ffffffffffffffffffffffffffffffffffffffff86168152608060208201526000611b43608083018688611a6b565b905083604083015263ffffffff831660608301529695505050505050565b60008451611b738184602089016118e8565b80830190507f2e000000000000000000000000000000000000000000000000000000000000008082528551611baf816001850160208a016118e8565b60019201918201528351611bca8160028401602088016118e8565b0160020195945050505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b600067ffffffffffffffff80831681851681830481118215151615611c2d57611c2d611bd7565b02949350505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b600067ffffffffffffffff80841680611c8057611c80611c36565b92169190910492915050565b600067ffffffffffffffff808316818516808303821115611caf57611caf611bd7565b01949350505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052600160045260246000fd5b600082821015611cf957611cf9611bd7565b500390565b73ffffffffffffffffffffffffffffffffffffffff8416815267ffffffffffffffff83166020820152606060408201526000611d3d6060830184611918565b95945050505050565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203611d7757611d77611bd7565b5060010190565b600082611d8d57611d8d611c36565b500490565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b600082611dd057611dd0611c36565b500690565b60008219821115611de857611de8611bd7565b500190565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b600073ffffffffffffffffffffffffffffffffffffffff808716835280861660208401525060806040830152611e556080830185611918565b905082606083015295945050505050565b868152600073ffffffffffffffffffffffffffffffffffffffff808816602084015280871660408401525084606083015283608083015260c060a0830152611eb160c0830184611918565b9897505050505050505056fea164736f6c634300080f000a"
func init() {
if err := json.Unmarshal([]byte(L2CrossDomainMessengerStorageLayoutJSON), L2CrossDomainMessengerStorageLayout); err != nil {
......
......@@ -49,7 +49,7 @@ type TypesWithdrawalTransaction struct {
// OptimismPortalMetaData contains all meta data concerning the OptimismPortal contract.
var OptimismPortalMetaData = &bind.MetaData{
ABI: "[{\"inputs\":[{\"internalType\":\"contractL2OutputOracle\",\"name\":\"_l2Oracle\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_guardian\",\"type\":\"address\"},{\"internalType\":\"bool\",\"name\":\"_paused\",\"type\":\"bool\"},{\"internalType\":\"contractSystemConfig\",\"name\":\"_config\",\"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\":false,\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"}],\"name\":\"Paused\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"version\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"opaqueData\",\"type\":\"bytes\"}],\"name\":\"TransactionDeposited\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"}],\"name\":\"Unpaused\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"withdrawalHash\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"bool\",\"name\":\"success\",\"type\":\"bool\"}],\"name\":\"WithdrawalFinalized\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"withdrawalHash\",\"type\":\"bytes32\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"WithdrawalProven\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"GUARDIAN\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"L2_ORACLE\",\"outputs\":[{\"internalType\":\"contractL2OutputOracle\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"SYSTEM_CONFIG\",\"outputs\":[{\"internalType\":\"contractSystemConfig\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"_value\",\"type\":\"uint256\"},{\"internalType\":\"uint64\",\"name\":\"_gasLimit\",\"type\":\"uint64\"},{\"internalType\":\"bool\",\"name\":\"_isCreation\",\"type\":\"bool\"},{\"internalType\":\"bytes\",\"name\":\"_data\",\"type\":\"bytes\"}],\"name\":\"depositTransaction\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"donateETH\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"uint256\",\"name\":\"nonce\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"target\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"gasLimit\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"}],\"internalType\":\"structTypes.WithdrawalTransaction\",\"name\":\"_tx\",\"type\":\"tuple\"}],\"name\":\"finalizeWithdrawalTransaction\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"name\":\"finalizedWithdrawals\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bool\",\"name\":\"_paused\",\"type\":\"bool\"}],\"name\":\"initialize\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_l2OutputIndex\",\"type\":\"uint256\"}],\"name\":\"isOutputFinalized\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"l2Sender\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"params\",\"outputs\":[{\"internalType\":\"uint128\",\"name\":\"prevBaseFee\",\"type\":\"uint128\"},{\"internalType\":\"uint64\",\"name\":\"prevBoughtGas\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"prevBlockNum\",\"type\":\"uint64\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"pause\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"paused\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"uint256\",\"name\":\"nonce\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"target\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"gasLimit\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"}],\"internalType\":\"structTypes.WithdrawalTransaction\",\"name\":\"_tx\",\"type\":\"tuple\"},{\"internalType\":\"uint256\",\"name\":\"_l2OutputIndex\",\"type\":\"uint256\"},{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"version\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"stateRoot\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"messagePasserStorageRoot\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"latestBlockhash\",\"type\":\"bytes32\"}],\"internalType\":\"structTypes.OutputRootProof\",\"name\":\"_outputRootProof\",\"type\":\"tuple\"},{\"internalType\":\"bytes[]\",\"name\":\"_withdrawalProof\",\"type\":\"bytes[]\"}],\"name\":\"proveWithdrawalTransaction\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"name\":\"provenWithdrawals\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"outputRoot\",\"type\":\"bytes32\"},{\"internalType\":\"uint128\",\"name\":\"timestamp\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"l2OutputIndex\",\"type\":\"uint128\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"unpause\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"version\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"stateMutability\":\"payable\",\"type\":\"receive\"}]",
Bin: "0x6101406040523480156200001257600080fd5b506040516200599b3803806200599b833981016040819052620000359162000296565b60016080819052600360a05260c0526001600160a01b0380851660e052838116610120528116610100526200006a8262000074565b5050505062000302565b600054610100900460ff1615808015620000955750600054600160ff909116105b80620000c55750620000b230620001cb60201b62001b9d1760201c565b158015620000c5575060005460ff166001145b6200012e5760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201526d191e481a5b9a5d1a585b1a5e995960921b60648201526084015b60405180910390fd5b6000805460ff19166001179055801562000152576000805461ff0019166101001790555b603280546001600160a01b03191661dead1790556035805483151560ff1990911617905562000180620001da565b8015620001c7576000805461ff0019169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b5050565b6001600160a01b03163b151590565b600054610100900460ff16620002475760405162461bcd60e51b815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201526a6e697469616c697a696e6760a81b606482015260840162000125565b60408051606081018252633b9aca0080825260006020830152436001600160401b031691909201819052600160c01b0217600155565b6001600160a01b03811681146200029357600080fd5b50565b60008060008060808587031215620002ad57600080fd5b8451620002ba816200027d565b6020860151909450620002cd816200027d565b60408601519093508015158114620002e457600080fd5b6060860151909250620002f7816200027d565b939692955090935050565b60805160a05160c05160e051610100516101205161560a620003916000396000818161024e015281816106ca0152610fcd01526000818161047401526122e701526000818161014f0152818161093301528181610b1401528181610f29015281816112e30152818161155501526120d701526000610e9401526000610e6b01526000610e42015261560a6000f3fe6080604052600436106101115760003560e01c80638b4c40b0116100a5578063cff0ab9611610074578063e965084c11610059578063e965084c146103c3578063e9e05c421461044f578063f04987501461046257600080fd5b8063cff0ab9614610302578063d53a822f146103a357600080fd5b80638b4c40b0146101365780638c3152e9146102855780639bf62d82146102a5578063a14238e7146102d257600080fd5b80635c975abb116100e15780635c975abb146101f25780636dbffb781461021c578063724c184c1461023c5780638456cb591461027057600080fd5b80621c2ff61461013d5780633f4ba83a1461019b5780634870496f146101b057806354fd4d50146101d057600080fd5b36610138576101363334620186a0600060405180602001604052806000815250610496565b005b600080fd5b34801561014957600080fd5b506101717f000000000000000000000000000000000000000000000000000000000000000081565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020015b60405180910390f35b3480156101a757600080fd5b506101366106b2565b3480156101bc57600080fd5b506101366101cb366004614c13565b6107d5565b3480156101dc57600080fd5b506101e5610e3b565b6040516101929190614d69565b3480156101fe57600080fd5b5060355461020c9060ff1681565b6040519015158152602001610192565b34801561022857600080fd5b5061020c610237366004614d7c565b610ede565b34801561024857600080fd5b506101717f000000000000000000000000000000000000000000000000000000000000000081565b34801561027c57600080fd5b50610136610fb5565b34801561029157600080fd5b506101366102a0366004614d95565b6110d5565b3480156102b157600080fd5b506032546101719073ffffffffffffffffffffffffffffffffffffffff1681565b3480156102de57600080fd5b5061020c6102ed366004614d7c565b60336020526000908152604090205460ff1681565b34801561030e57600080fd5b5060015461036a906fffffffffffffffffffffffffffffffff81169067ffffffffffffffff7001000000000000000000000000000000008204811691780100000000000000000000000000000000000000000000000090041683565b604080516fffffffffffffffffffffffffffffffff909416845267ffffffffffffffff9283166020850152911690820152606001610192565b3480156103af57600080fd5b506101366103be366004614dda565b6119b0565b3480156103cf57600080fd5b506104216103de366004614d7c565b603460205260009081526040902080546001909101546fffffffffffffffffffffffffffffffff8082169170010000000000000000000000000000000090041683565b604080519384526fffffffffffffffffffffffffffffffff9283166020850152911690820152606001610192565b61013661045d366004614df5565b610496565b34801561046e57600080fd5b506101717f000000000000000000000000000000000000000000000000000000000000000081565b8260005a9050831561054d5773ffffffffffffffffffffffffffffffffffffffff87161561054d57604080517f08c379a00000000000000000000000000000000000000000000000000000000081526020600482015260248101919091527f4f7074696d69736d506f7274616c3a206d7573742073656e6420746f2061646460448201527f72657373283029207768656e206372656174696e67206120636f6e747261637460648201526084015b60405180910390fd5b6152088567ffffffffffffffff1610156105e9576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603860248201527f4f7074696d69736d506f7274616c3a20676173206c696d6974206d757374206360448201527f6f76657220696e737472696e7369632067617320636f737400000000000000006064820152608401610544565b3332811461060a575033731111000000000000000000000000000000001111015b60003488888888604051602001610625959493929190614e7a565b604051602081830303815290604052905060008973ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff167fb3813568d9991fc951961fcb4c784893574240a28925604d09fc577c55bb7c32846040516106959190614d69565b60405180910390a450506106a98282611bb9565b50505050505050565b3373ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000001614610777576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602960248201527f4f7074696d69736d506f7274616c3a206f6e6c7920677561726469616e20636160448201527f6e20756e706175736500000000000000000000000000000000000000000000006064820152608401610544565b603580547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001690556040513381527f5db9ee0a495bf2e6ff9c91a7834c1ba4fdd244a5e8aa4e537bd38aeae4b073aa906020015b60405180910390a1565b60355460ff1615610842576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4f7074696d69736d506f7274616c3a20706175736564000000000000000000006044820152606401610544565b3073ffffffffffffffffffffffffffffffffffffffff16856040015173ffffffffffffffffffffffffffffffffffffffff1603610901576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603f60248201527f4f7074696d69736d506f7274616c3a20796f752063616e6e6f742073656e642060448201527f6d6573736167657320746f2074686520706f7274616c20636f6e7472616374006064820152608401610544565b6040517fa25ae557000000000000000000000000000000000000000000000000000000008152600481018590526000907f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff169063a25ae55790602401606060405180830381865afa15801561098f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906109b39190614eff565b5190506109cd6109c836869003860186614f64565b611ee6565b8114610a5b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602960248201527f4f7074696d69736d506f7274616c3a20696e76616c6964206f7574707574207260448201527f6f6f742070726f6f6600000000000000000000000000000000000000000000006064820152608401610544565b6000610a6687611f42565b6000818152603460209081526040918290208251606081018452815481526001909101546fffffffffffffffffffffffffffffffff8082169383018490527001000000000000000000000000000000009091041692810192909252919250901580610b985750805160408083015190517fa25ae5570000000000000000000000000000000000000000000000000000000081526fffffffffffffffffffffffffffffffff90911660048201527f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff169063a25ae55790602401606060405180830381865afa158015610b70573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610b949190614eff565b5114155b610c24576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603760248201527f4f7074696d69736d506f7274616c3a207769746864726177616c20686173682060448201527f68617320616c7265616479206265656e2070726f76656e0000000000000000006064820152608401610544565b60408051602081018490526000918101829052606001604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe081840301815282825280516020918201209083018190529250610ced9101604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0818403018152828201909152600182527f0100000000000000000000000000000000000000000000000000000000000000602083015290610ce3888a614fca565b8a60400135611f72565b610d79576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603260248201527f4f7074696d69736d506f7274616c3a20696e76616c696420776974686472617760448201527f616c20696e636c7573696f6e2070726f6f6600000000000000000000000000006064820152608401610544565b604080516060810182528581526fffffffffffffffffffffffffffffffff42811660208084019182528c831684860190815260008981526034835286812095518655925190518416700100000000000000000000000000000000029316929092176001909301929092558b830151908c0151925173ffffffffffffffffffffffffffffffffffffffff918216939091169186917f67a6208cfcc0801d50f6cbe764733f4fddf66ac0b04442061a8a8c0cb6b63f629190a4505050505050505050565b6060610e667f0000000000000000000000000000000000000000000000000000000000000000611f96565b610e8f7f0000000000000000000000000000000000000000000000000000000000000000611f96565b610eb87f0000000000000000000000000000000000000000000000000000000000000000611f96565b604051602001610eca9392919061504e565b604051602081830303815290604052905090565b6040517fa25ae55700000000000000000000000000000000000000000000000000000000815260048101829052600090610faf9073ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000169063a25ae55790602401606060405180830381865afa158015610f70573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610f949190614eff565b602001516fffffffffffffffffffffffffffffffff166120d3565b92915050565b3373ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000161461107a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602760248201527f4f7074696d69736d506f7274616c3a206f6e6c7920677561726469616e20636160448201527f6e207061757365000000000000000000000000000000000000000000000000006064820152608401610544565b603580547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660011790556040513381527f62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a258906020016107cb565b60355460ff1615611142576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4f7074696d69736d506f7274616c3a20706175736564000000000000000000006044820152606401610544565b60325473ffffffffffffffffffffffffffffffffffffffff1661dead146111eb576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603f60248201527f4f7074696d69736d506f7274616c3a2063616e206f6e6c79207472696767657260448201527f206f6e65207769746864726177616c20706572207472616e73616374696f6e006064820152608401610544565b60006111f682611f42565b60008181526034602090815260408083208151606081018352815481526001909101546fffffffffffffffffffffffffffffffff808216948301859052700100000000000000000000000000000000909104169181019190915292935090036112e1576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603260248201527f4f7074696d69736d506f7274616c3a207769746864726177616c20686173206e60448201527f6f74206265656e2070726f76656e2079657400000000000000000000000000006064820152608401610544565b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663887862726040518163ffffffff1660e01b8152600401602060405180830381865afa15801561134c573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061137091906150c4565b81602001516fffffffffffffffffffffffffffffffff16101561143b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604b60248201527f4f7074696d69736d506f7274616c3a207769746864726177616c2074696d657360448201527f74616d70206c657373207468616e204c32204f7261636c65207374617274696e60648201527f672074696d657374616d70000000000000000000000000000000000000000000608482015260a401610544565b61145a81602001516fffffffffffffffffffffffffffffffff166120d3565b61150c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604560248201527f4f7074696d69736d506f7274616c3a2070726f76656e2077697468647261776160448201527f6c2066696e616c697a6174696f6e20706572696f6420686173206e6f7420656c60648201527f6170736564000000000000000000000000000000000000000000000000000000608482015260a401610544565b60408181015190517fa25ae5570000000000000000000000000000000000000000000000000000000081526fffffffffffffffffffffffffffffffff90911660048201526000907f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff169063a25ae55790602401606060405180830381865afa1580156115b1573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906115d59190614eff565b825181519192501461168f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604960248201527f4f7074696d69736d506f7274616c3a206f757470757420726f6f742070726f7660448201527f656e206973206e6f74207468652073616d652061732063757272656e74206f7560648201527f7470757420726f6f740000000000000000000000000000000000000000000000608482015260a401610544565b6116ae81602001516fffffffffffffffffffffffffffffffff166120d3565b611760576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604360248201527f4f7074696d69736d506f7274616c3a206f75747075742070726f706f73616c2060448201527f66696e616c697a6174696f6e20706572696f6420686173206e6f7420656c617060648201527f7365640000000000000000000000000000000000000000000000000000000000608482015260a401610544565b60008381526033602052604090205460ff16156117ff576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603560248201527f4f7074696d69736d506f7274616c3a207769746864726177616c20686173206160448201527f6c7265616479206265656e2066696e616c697a656400000000000000000000006064820152608401610544565b600083815260336020908152604080832080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001179055908601516032805473ffffffffffffffffffffffffffffffffffffffff9092167fffffffffffffffffffffffff00000000000000000000000000000000000000009092169190911790558501516080860151606087015160a08801516118a193929190612176565b603280547fffffffffffffffffffffffff00000000000000000000000000000000000000001661dead17905560405190915084907fdb5c7652857aa163daadd670e116628fb42e869d8ac4251ef8971d9e5727df1b9061190690841515815260200190565b60405180910390a28015801561191c5750326001145b156119a9576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602160248201527f4f7074696d69736d506f7274616c3a207769746864726177616c206661696c6560448201527f64000000000000000000000000000000000000000000000000000000000000006064820152608401610544565b5050505050565b600054610100900460ff16158080156119d05750600054600160ff909116105b806119ea5750303b1580156119ea575060005460ff166001145b611a76576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a65640000000000000000000000000000000000006064820152608401610544565b600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660011790558015611ad457600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff166101001790555b603280547fffffffffffffffffffffffff00000000000000000000000000000000000000001661dead179055603580548315157fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00909116179055611b366121d0565b8015611b9957600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b5050565b73ffffffffffffffffffffffffffffffffffffffff163b151590565b600154600090611bef907801000000000000000000000000000000000000000000000000900467ffffffffffffffff164361510c565b90506000611bfb6122b3565b90506000816020015160ff16826000015163ffffffff16611c1c9190615152565b90508215611d5357600154600090611c53908390700100000000000000000000000000000000900467ffffffffffffffff166151ba565b90506000836040015160ff1683611c6a919061522e565b600154611c8a9084906fffffffffffffffffffffffffffffffff1661522e565b611c949190615152565b600154909150600090611ce590611cbe9084906fffffffffffffffffffffffffffffffff166152ea565b866060015163ffffffff168760a001516fffffffffffffffffffffffffffffffff16612379565b90506001861115611d1457611d11611cbe82876040015160ff1660018a611d0c919061510c565b612398565b90505b6fffffffffffffffffffffffffffffffff16780100000000000000000000000000000000000000000000000067ffffffffffffffff4316021760015550505b60018054869190601090611d86908490700100000000000000000000000000000000900467ffffffffffffffff1661535e565b92506101000a81548167ffffffffffffffff021916908367ffffffffffffffff160217905550816000015163ffffffff16600160000160109054906101000a900467ffffffffffffffff1667ffffffffffffffff161315611e69576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603e60248201527f5265736f757263654d65746572696e673a2063616e6e6f7420627579206d6f7260448201527f6520676173207468616e20617661696c61626c6520676173206c696d697400006064820152608401610544565b600154600090611e95906fffffffffffffffffffffffffffffffff1667ffffffffffffffff881661538a565b90506000611ea748633b9aca006123ed565b611eb190836153c7565b905060005a611ec0908861510c565b905080821115611edc57611edc611ed7828461510c565b612404565b5050505050505050565b60008160000151826020015183604001518460600151604051602001611f25949392919093845260208401929092526040830152606082015260800190565b604051602081830303815290604052805190602001209050919050565b80516020808301516040808501516060860151608087015160a08801519351600097611f259790969591016153db565b600080611f7e86612432565b9050611f8c81868686612464565b9695505050505050565b606081600003611fd957505060408051808201909152600181527f3000000000000000000000000000000000000000000000000000000000000000602082015290565b8160005b81156120035780611fed81615432565b9150611ffc9050600a836153c7565b9150611fdd565b60008167ffffffffffffffff81111561201e5761201e614a39565b6040519080825280601f01601f191660200182016040528015612048576020820181803683370190505b5090505b84156120cb5761205d60018361510c565b915061206a600a8661546a565b61207590603061547e565b60f81b81838151811061208a5761208a615496565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053506120c4600a866153c7565b945061204c565b949350505050565b60007f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663f4daa2916040518163ffffffff1660e01b8152600401602060405180830381865afa158015612140573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061216491906150c4565b61216e908361547e565b421192915050565b600080603f60c88601604002045a10156121b9576308c379a06000526020805278185361666543616c6c3a204e6f7420656e6f756768206761736058526064601cfd5b600080845160208601878a5af19695505050505050565b600054610100900460ff16612267576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e670000000000000000000000000000000000000000006064820152608401610544565b60408051606081018252633b9aca00808252600060208301524367ffffffffffffffff169190920181905278010000000000000000000000000000000000000000000000000217600155565b6040805160c081018252600080825260208201819052918101829052606081018290526080810182905260a08101919091527f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663cc731b026040518163ffffffff1660e01b815260040160c060405180830381865afa158015612350573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061237491906154ea565b905090565b600061238e6123888585612494565b836124a4565b90505b9392505050565b6000670de0b6b3a76400006123d96123b08583615152565b6123c290670de0b6b3a76400006151ba565b6123d485670de0b6b3a764000061522e565b6124b3565b6123e3908661522e565b61238e9190615152565b6000818310156123fd5781612391565b5090919050565b6000805a90505b825a612417908361510c565b101561242d5761242682615432565b915061240b565b505050565b6060818051906020012060405160200161244e91815260200190565b6040516020818303038152906040529050919050565b600061248b846124758786866124e4565b8051602091820120825192909101919091201490565b95945050505050565b6000818312156123fd5781612391565b60008183126123fd5781612391565b6000612391670de0b6b3a7640000836124cb86612f6c565b6124d5919061522e565b6124df9190615152565b6131b0565b60606000845111612551576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601560248201527f4d65726b6c65547269653a20656d707479206b657900000000000000000000006044820152606401610544565b600061255c846133ef565b90506000612569866134de565b905060008460405160200161258091815260200190565b60405160208183030381529060405290506000805b8451811015612ee35760008582815181106125b2576125b2615496565b60200260200101519050845183111561264d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f4d65726b6c65547269653a206b657920696e646578206578636565647320746f60448201527f74616c206b6579206c656e6774680000000000000000000000000000000000006064820152608401610544565b82600003612706578051805160209182012060405161269b9261267592910190815260200190565b604051602081830303815290604052858051602091820120825192909101919091201490565b612701576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f4d65726b6c65547269653a20696e76616c696420726f6f7420686173680000006044820152606401610544565b61285d565b8051516020116127bc57805180516020918201206040516127309261267592910190815260200190565b612701576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602760248201527f4d65726b6c65547269653a20696e76616c6964206c6172676520696e7465726e60448201527f616c2068617368000000000000000000000000000000000000000000000000006064820152608401610544565b80518451602080870191909120825191909201201461285d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f4d65726b6c65547269653a20696e76616c696420696e7465726e616c206e6f6460448201527f65206861736800000000000000000000000000000000000000000000000000006064820152608401610544565b6128696010600161547e565b81602001515103612a4a57845183036129e25760006128a5826020015160108151811061289857612898615496565b6020026020010151613679565b90506000815111612938576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603b60248201527f4d65726b6c65547269653a2076616c7565206c656e677468206d75737420626560448201527f2067726561746572207468616e207a65726f20286272616e63682900000000006064820152608401610544565b60018751612946919061510c565b83146129d4576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603a60248201527f4d65726b6c65547269653a2076616c7565206e6f6465206d757374206265206c60448201527f617374206e6f646520696e2070726f6f6620286272616e6368290000000000006064820152608401610544565b965061239195505050505050565b60008584815181106129f6576129f6615496565b602001015160f81c60f81b60f81c9050600082602001518260ff1681518110612a2157612a21615496565b60200260200101519050612a34816137d9565b9550612a4160018661547e565b94505050612ed0565b600281602001515103612e48576000612a62826137fe565b9050600081600081518110612a7957612a79615496565b016020015160f81c90506000612a90600283615589565b612a9b9060026155ab565b90506000612aac848360ff16613822565b90506000612aba8a89613822565b90506000612ac88383613858565b905080835114612b5a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603a60248201527f4d65726b6c65547269653a20706174682072656d61696e646572206d7573742060448201527f736861726520616c6c206e6962626c65732077697468206b65790000000000006064820152608401610544565b60ff851660021480612b6f575060ff85166003145b15612d635780825114612c04576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603d60248201527f4d65726b6c65547269653a206b65792072656d61696e646572206d757374206260448201527f65206964656e746963616c20746f20706174682072656d61696e6465720000006064820152608401610544565b6000612c20886020015160018151811061289857612898615496565b90506000815111612cb3576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603960248201527f4d65726b6c65547269653a2076616c7565206c656e677468206d75737420626560448201527f2067726561746572207468616e207a65726f20286c65616629000000000000006064820152608401610544565b60018d51612cc1919061510c565b8914612d4f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603860248201527f4d65726b6c65547269653a2076616c7565206e6f6465206d757374206265206c60448201527f617374206e6f646520696e2070726f6f6620286c6561662900000000000000006064820152608401610544565b9c506123919b505050505050505050505050565b60ff85161580612d76575060ff85166001145b15612db557612da28760200151600181518110612d9557612d95615496565b60200260200101516137d9565b9950612dae818a61547e565b9850612e3d565b6040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603260248201527f4d65726b6c65547269653a2072656365697665642061206e6f6465207769746860448201527f20616e20756e6b6e6f776e2070726566697800000000000000000000000000006064820152608401610544565b505050505050612ed0565b6040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602860248201527f4d65726b6c65547269653a20726563656976656420616e20756e70617273656160448201527f626c65206e6f64650000000000000000000000000000000000000000000000006064820152608401610544565b5080612edb81615432565b915050612595565b506040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602560248201527f4d65726b6c65547269653a2072616e206f7574206f662070726f6f6620656c6560448201527f6d656e74730000000000000000000000000000000000000000000000000000006064820152608401610544565b6000808213612fd7576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600960248201527f554e444546494e454400000000000000000000000000000000000000000000006044820152606401610544565b60006060612fe484613907565b03609f8181039490941b90931c6c465772b2bbbb5f824b15207a3081018102606090811d6d0388eaa27412d5aca026815d636e018202811d6d0df99ac502031bf953eff472fdcc018202811d6d13cdffb29d51d99322bdff5f2211018202811d6d0a0f742023def783a307a986912e018202811d6d01920d8043ca89b5239253284e42018202811d6c0b7a86d7375468fac667a0a527016c29508e458543d8aa4df2abee7883018302821d6d0139601a2efabe717e604cbb4894018302821d6d02247f7a7b6594320649aa03aba1018302821d7fffffffffffffffffffffffffffffffffffffff73c0c716a594e00d54e3c4cbc9018302821d7ffffffffffffffffffffffffffffffffffffffdc7b88c420e53a9890533129f6f01830290911d7fffffffffffffffffffffffffffffffffffffff465fda27eb4d63ded474e5f832019091027ffffffffffffffff5f6af8f7b3396644f18e157960000000000000000000000000105711340daa0d5f769dba1915cef59f0815a5506027d0267a36c0c95b3975ab3ee5b203a7614a3f75373f047d803ae7b6687f2b393909302929092017d57115e47018c7177eebf7cd370a3356a1b7863008a5ae8028c72b88642840160ae1d92915050565b60007ffffffffffffffffffffffffffffffffffffffffffffffffdb731c958f34d94c182136131e157506000919050565b680755bf798b4a1bf1e58212613253576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600c60248201527f4558505f4f564552464c4f5700000000000000000000000000000000000000006044820152606401610544565b6503782dace9d9604e83901b059150600060606bb17217f7d1cf79abc9e3b39884821b056b80000000000000000000000001901d6bb17217f7d1cf79abc9e3b39881029093037fffffffffffffffffffffffffffffffffffffffdbf3ccf1604d263450f02a550481018102606090811d6d0277594991cfc85f6e2461837cd9018202811d7fffffffffffffffffffffffffffffffffffffe5adedaa1cb095af9e4da10e363c018202811d6db1bbb201f443cf962f1a1d3db4a5018202811d7ffffffffffffffffffffffffffffffffffffd38dc772608b0ae56cce01296c0eb018202811d6e05180bb14799ab47a8a8cb2a527d57016d02d16720577bd19bf614176fe9ea6c10fe68e7fd37d0007b713f765084018402831d9081019084017ffffffffffffffffffffffffffffffffffffffe2c69812cf03b0763fd454a8f7e010290911d6e0587f503bb6ea29d25fcb7401964500190910279d835ebba824c98fb31b83b2ca45c000000000000000000000000010574029d9dc38563c32e5c2f6dc192ee70ef65f9978af30260c3939093039290921c92915050565b805160609060008167ffffffffffffffff81111561340f5761340f614a39565b60405190808252806020026020018201604052801561345457816020015b604080518082019091526060808252602082015281526020019060019003908161342d5790505b50905060005b828110156134d657604051806040016040528086838151811061347f5761347f615496565b602002602001015181526020016134ae8784815181106134a1576134a1615496565b60200260200101516139dd565b8152508282815181106134c3576134c3615496565b602090810291909101015260010161345a565b509392505050565b805160609060006134f082600261538a565b67ffffffffffffffff81111561350857613508614a39565b6040519080825280601f01601f191660200182016040528015613532576020820181803683370190505b5090506000805b8381101561366f5785818151811061355357613553615496565b6020910101517fff000000000000000000000000000000000000000000000000000000000000008116925060041c7f0ff000000000000000000000000000000000000000000000000000000000000016836135af83600261538a565b815181106135bf576135bf615496565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053507f0f0000000000000000000000000000000000000000000000000000000000000082168361361d83600261538a565b61362890600161547e565b8151811061363857613638615496565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a905350600101613539565b5090949350505050565b60606000806000613689856139f0565b9194509250905060008160018111156136a4576136a46155ce565b14613731576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603960248201527f524c505265616465723a206465636f646564206974656d207479706520666f7260448201527f206279746573206973206e6f7420612064617461206974656d000000000000006064820152608401610544565b61373b828461547e565b8551146137ca576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603460248201527f524c505265616465723a2062797465732076616c756520636f6e7461696e732060448201527f616e20696e76616c69642072656d61696e6465720000000000000000000000006064820152608401610544565b61248b8560200151848461445d565b606060208260000151106137f5576137f082613679565b610faf565b610faf826144fe565b6060610faf61381d836020015160008151811061289857612898615496565b6134de565b6060825182106138415750604080516020810190915260008152610faf565b6123918383848651613853919061510c565b614514565b6000806000835185511061386d578351613870565b84515b90505b80821080156138f7575083828151811061388f5761388f615496565b602001015160f81c60f81b7effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff19168583815181106138ce576138ce615496565b01602001517fff0000000000000000000000000000000000000000000000000000000000000016145b156134d657816001019150613873565b6000808211613972576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600960248201527f554e444546494e454400000000000000000000000000000000000000000000006044820152606401610544565b5060016fffffffffffffffffffffffffffffffff821160071b82811c67ffffffffffffffff1060061b1782811c63ffffffff1060051b1782811c61ffff1060041b1782811c60ff10600390811b90911783811c600f1060021b1783811c909110821b1791821c111790565b6060610faf6139eb836146ec565b6147d5565b600080600080846000015111613aae576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604a60248201527f524c505265616465723a206c656e677468206f6620616e20524c50206974656d60448201527f206d7573742062652067726561746572207468616e207a65726f20746f20626560648201527f206465636f6461626c6500000000000000000000000000000000000000000000608482015260a401610544565b6020840151805160001a607f8111613ad3576000600160009450945094505050614456565b60b78111613ce1576000613ae860808361510c565b905080876000015111613ba3576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604e60248201527f524c505265616465723a206c656e677468206f6620636f6e74656e74206d757360448201527f742062652067726561746572207468616e20737472696e67206c656e6774682060648201527f2873686f727420737472696e6729000000000000000000000000000000000000608482015260a401610544565b6001838101517fff00000000000000000000000000000000000000000000000000000000000000169082141580613c1c57507f80000000000000000000000000000000000000000000000000000000000000007fff00000000000000000000000000000000000000000000000000000000000000821610155b613cce576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604d60248201527f524c505265616465723a20696e76616c6964207072656669782c2073696e676c60448201527f652062797465203c203078383020617265206e6f74207072656669786564202860648201527f73686f727420737472696e672900000000000000000000000000000000000000608482015260a401610544565b5060019550935060009250614456915050565b60bf811161402f576000613cf660b78361510c565b905080876000015111613db1576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152605160248201527f524c505265616465723a206c656e677468206f6620636f6e74656e74206d757360448201527f74206265203e207468616e206c656e677468206f6620737472696e67206c656e60648201527f67746820286c6f6e6720737472696e6729000000000000000000000000000000608482015260a401610544565b60018301517fff00000000000000000000000000000000000000000000000000000000000000166000819003613e8f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604a60248201527f524c505265616465723a206c656e677468206f6620636f6e74656e74206d757360448201527f74206e6f74206861766520616e79206c656164696e67207a65726f7320286c6f60648201527f6e6720737472696e672900000000000000000000000000000000000000000000608482015260a401610544565b600184015160088302610100031c60378111613f53576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604860248201527f524c505265616465723a206c656e677468206f6620636f6e74656e74206d757360448201527f742062652067726561746572207468616e20353520627974657320286c6f6e6760648201527f20737472696e6729000000000000000000000000000000000000000000000000608482015260a401610544565b613f5d818461547e565b895111614012576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604c60248201527f524c505265616465723a206c656e677468206f6620636f6e74656e74206d757360448201527f742062652067726561746572207468616e20746f74616c206c656e677468202860648201527f6c6f6e6720737472696e67290000000000000000000000000000000000000000608482015260a401610544565b61401d83600161547e565b97509550600094506144569350505050565b60f7811161411057600061404460c08361510c565b9050808760000151116140ff576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604a60248201527f524c505265616465723a206c656e677468206f6620636f6e74656e74206d757360448201527f742062652067726561746572207468616e206c697374206c656e67746820287360648201527f686f7274206c6973742900000000000000000000000000000000000000000000608482015260a401610544565b600195509350849250614456915050565b600061411d60f78361510c565b9050808760000151116141d8576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604d60248201527f524c505265616465723a206c656e677468206f6620636f6e74656e74206d757360448201527f74206265203e207468616e206c656e677468206f66206c697374206c656e677460648201527f6820286c6f6e67206c6973742900000000000000000000000000000000000000608482015260a401610544565b60018301517fff000000000000000000000000000000000000000000000000000000000000001660008190036142b6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604860248201527f524c505265616465723a206c656e677468206f6620636f6e74656e74206d757360448201527f74206e6f74206861766520616e79206c656164696e67207a65726f7320286c6f60648201527f6e67206c69737429000000000000000000000000000000000000000000000000608482015260a401610544565b600184015160088302610100031c6037811161437a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604660248201527f524c505265616465723a206c656e677468206f6620636f6e74656e74206d757360448201527f742062652067726561746572207468616e20353520627974657320286c6f6e6760648201527f206c697374290000000000000000000000000000000000000000000000000000608482015260a401610544565b614384818461547e565b895111614439576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604a60248201527f524c505265616465723a206c656e677468206f6620636f6e74656e74206d757360448201527f742062652067726561746572207468616e20746f74616c206c656e677468202860648201527f6c6f6e67206c6973742900000000000000000000000000000000000000000000608482015260a401610544565b61444483600161547e565b97509550600194506144569350505050565b9193909250565b606060008267ffffffffffffffff81111561447a5761447a614a39565b6040519080825280601f01601f1916602001820160405280156144a4576020820181803683370190505b509050826000036144b6579050612391565b60006144c2858761547e565b90506020820160005b858110156144e35782810151828201526020016144cb565b858111156144f2576000868301525b50919695505050505050565b6060610faf82602001516000846000015161445d565b60608182601f011015614583576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600e60248201527f736c6963655f6f766572666c6f770000000000000000000000000000000000006044820152606401610544565b8282840110156145ef576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600e60248201527f736c6963655f6f766572666c6f770000000000000000000000000000000000006044820152606401610544565b8183018451101561465c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601160248201527f736c6963655f6f75744f66426f756e64730000000000000000000000000000006044820152606401610544565b60608215801561467b57604051915060008252602082016040526146e3565b6040519150601f8416801560200281840101858101878315602002848b0101015b818310156146b457805183526020928301920161469c565b5050858452601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016604052505b50949350505050565b604080518082019091526000808252602082015260008251116147b7576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604a60248201527f524c505265616465723a206c656e677468206f6620616e20524c50206974656d60448201527f206d7573742062652067726561746572207468616e207a65726f20746f20626560648201527f206465636f6461626c6500000000000000000000000000000000000000000000608482015260a401610544565b50604080518082019091528151815260209182019181019190915290565b606060008060006147e5856139f0565b919450925090506001816001811115614800576148006155ce565b1461488d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603860248201527f524c505265616465723a206465636f646564206974656d207479706520666f7260448201527f206c697374206973206e6f742061206c697374206974656d00000000000000006064820152608401610544565b8451614899838561547e565b14614926576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603260248201527f524c505265616465723a206c697374206974656d2068617320616e20696e766160448201527f6c696420646174612072656d61696e64657200000000000000000000000000006064820152608401610544565b6040805160208082526104208201909252600091816020015b604080518082019091526000808252602082015281526020019060019003908161493f5790505090506000845b8751811015614a2d576000806149b26040518060400160405280858d60000151614996919061510c565b8152602001858d602001516149ab919061547e565b90526139f0565b5091509150604051806040016040528083836149ce919061547e565b8152602001848c602001516149e3919061547e565b8152508585815181106149f8576149f8615496565b6020908102919091010152614a0e60018561547e565b9350614a1a818361547e565b614a24908461547e565b9250505061496c565b50815295945050505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff81118282101715614aaf57614aaf614a39565b604052919050565b803573ffffffffffffffffffffffffffffffffffffffff81168114614adb57600080fd5b919050565b600082601f830112614af157600080fd5b813567ffffffffffffffff811115614b0b57614b0b614a39565b614b3c60207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f84011601614a68565b818152846020838601011115614b5157600080fd5b816020850160208301376000918101602001919091529392505050565b600060c08284031215614b8057600080fd5b60405160c0810167ffffffffffffffff8282108183111715614ba457614ba4614a39565b8160405282935084358352614bbb60208601614ab7565b6020840152614bcc60408601614ab7565b6040840152606085013560608401526080850135608084015260a0850135915080821115614bf957600080fd5b50614c0685828601614ae0565b60a0830152505092915050565b600080600080600085870360e0811215614c2c57600080fd5b863567ffffffffffffffff80821115614c4457600080fd5b614c508a838b01614b6e565b97506020890135965060807fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc084011215614c8957600080fd5b60408901955060c0890135925080831115614ca357600080fd5b828901925089601f840112614cb757600080fd5b8235915080821115614cc857600080fd5b508860208260051b8401011115614cde57600080fd5b959894975092955050506020019190565b60005b83811015614d0a578181015183820152602001614cf2565b83811115614d19576000848401525b50505050565b60008151808452614d37816020860160208601614cef565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b6020815260006123916020830184614d1f565b600060208284031215614d8e57600080fd5b5035919050565b600060208284031215614da757600080fd5b813567ffffffffffffffff811115614dbe57600080fd5b6120cb84828501614b6e565b80358015158114614adb57600080fd5b600060208284031215614dec57600080fd5b61239182614dca565b600080600080600060a08688031215614e0d57600080fd5b614e1686614ab7565b945060208601359350604086013567ffffffffffffffff8082168214614e3b57600080fd5b819450614e4a60608901614dca565b93506080880135915080821115614e6057600080fd5b50614e6d88828901614ae0565b9150509295509295909350565b8581528460208201527fffffffffffffffff0000000000000000000000000000000000000000000000008460c01b16604082015282151560f81b604882015260008251614ece816049850160208701614cef565b919091016049019695505050505050565b80516fffffffffffffffffffffffffffffffff81168114614adb57600080fd5b600060608284031215614f1157600080fd5b6040516060810181811067ffffffffffffffff82111715614f3457614f34614a39565b60405282518152614f4760208401614edf565b6020820152614f5860408401614edf565b60408201529392505050565b600060808284031215614f7657600080fd5b6040516080810181811067ffffffffffffffff82111715614f9957614f99614a39565b8060405250823581526020830135602082015260408301356040820152606083013560608201528091505092915050565b600067ffffffffffffffff80841115614fe557614fe5614a39565b8360051b6020614ff6818301614a68565b86815291850191818101903684111561500e57600080fd5b865b84811015615042578035868111156150285760008081fd5b61503436828b01614ae0565b845250918301918301615010565b50979650505050505050565b60008451615060818460208901614cef565b80830190507f2e00000000000000000000000000000000000000000000000000000000000000808252855161509c816001850160208a01614cef565b600192019182015283516150b7816002840160208801614cef565b0160020195945050505050565b6000602082840312156150d657600080fd5b5051919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60008282101561511e5761511e6150dd565b500390565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b60008261516157615161615123565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff83147f8000000000000000000000000000000000000000000000000000000000000000831416156151b5576151b56150dd565b500590565b6000808312837f8000000000000000000000000000000000000000000000000000000000000000018312811516156151f4576151f46150dd565b837f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff018313811615615228576152286150dd565b50500390565b60007f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff60008413600084138583048511828216161561526f5761526f6150dd565b7f800000000000000000000000000000000000000000000000000000000000000060008712868205881281841616156152aa576152aa6150dd565b600087129250878205871284841616156152c6576152c66150dd565b878505871281841616156152dc576152dc6150dd565b505050929093029392505050565b6000808212827f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff03841381151615615324576153246150dd565b827f8000000000000000000000000000000000000000000000000000000000000000038412811615615358576153586150dd565b50500190565b600067ffffffffffffffff808316818516808303821115615381576153816150dd565b01949350505050565b6000817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff04831182151516156153c2576153c26150dd565b500290565b6000826153d6576153d6615123565b500490565b868152600073ffffffffffffffffffffffffffffffffffffffff808816602084015280871660408401525084606083015283608083015260c060a083015261542660c0830184614d1f565b98975050505050505050565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203615463576154636150dd565b5060010190565b60008261547957615479615123565b500690565b60008219821115615491576154916150dd565b500190565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b805163ffffffff81168114614adb57600080fd5b805160ff81168114614adb57600080fd5b600060c082840312156154fc57600080fd5b60405160c0810181811067ffffffffffffffff8211171561551f5761551f614a39565b60405261552b836154c5565b8152615539602084016154d9565b602082015261554a604084016154d9565b604082015261555b606084016154c5565b606082015261556c608084016154c5565b608082015261557d60a08401614edf565b60a08201529392505050565b600060ff83168061559c5761559c615123565b8060ff84160691505092915050565b600060ff821660ff8416808210156155c5576155c56150dd565b90039392505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fdfea164736f6c634300080f000a",
Bin: "0x6101406040523480156200001257600080fd5b50604051620059ba380380620059ba833981016040819052620000359162000296565b6001608052600460a052600060c0526001600160a01b0380851660e052838116610120528116610100526200006a8262000074565b5050505062000302565b600054610100900460ff1615808015620000955750600054600160ff909116105b80620000c55750620000b230620001cb60201b62001b9d1760201c565b158015620000c5575060005460ff166001145b6200012e5760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201526d191e481a5b9a5d1a585b1a5e995960921b60648201526084015b60405180910390fd5b6000805460ff19166001179055801562000152576000805461ff0019166101001790555b603280546001600160a01b03191661dead1790556035805483151560ff1990911617905562000180620001da565b8015620001c7576000805461ff0019169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b5050565b6001600160a01b03163b151590565b600054610100900460ff16620002475760405162461bcd60e51b815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201526a6e697469616c697a696e6760a81b606482015260840162000125565b60408051606081018252633b9aca0080825260006020830152436001600160401b031691909201819052600160c01b0217600155565b6001600160a01b03811681146200029357600080fd5b50565b60008060008060808587031215620002ad57600080fd5b8451620002ba816200027d565b6020860151909450620002cd816200027d565b60408601519093508015158114620002e457600080fd5b6060860151909250620002f7816200027d565b939692955090935050565b60805160a05160c05160e0516101005161012051615629620003916000396000818161024e015281816106ca0152610fcd01526000818161047401526122eb01526000818161014f0152818161093301528181610b1401528181610f29015281816112e30152818161155501526120d701526000610e9401526000610e6b01526000610e4201526156296000f3fe6080604052600436106101115760003560e01c80638b4c40b0116100a5578063cff0ab9611610074578063e965084c11610059578063e965084c146103c3578063e9e05c421461044f578063f04987501461046257600080fd5b8063cff0ab9614610302578063d53a822f146103a357600080fd5b80638b4c40b0146101365780638c3152e9146102855780639bf62d82146102a5578063a14238e7146102d257600080fd5b80635c975abb116100e15780635c975abb146101f25780636dbffb781461021c578063724c184c1461023c5780638456cb591461027057600080fd5b80621c2ff61461013d5780633f4ba83a1461019b5780634870496f146101b057806354fd4d50146101d057600080fd5b36610138576101363334620186a0600060405180602001604052806000815250610496565b005b600080fd5b34801561014957600080fd5b506101717f000000000000000000000000000000000000000000000000000000000000000081565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020015b60405180910390f35b3480156101a757600080fd5b506101366106b2565b3480156101bc57600080fd5b506101366101cb366004614c32565b6107d5565b3480156101dc57600080fd5b506101e5610e3b565b6040516101929190614d88565b3480156101fe57600080fd5b5060355461020c9060ff1681565b6040519015158152602001610192565b34801561022857600080fd5b5061020c610237366004614d9b565b610ede565b34801561024857600080fd5b506101717f000000000000000000000000000000000000000000000000000000000000000081565b34801561027c57600080fd5b50610136610fb5565b34801561029157600080fd5b506101366102a0366004614db4565b6110d5565b3480156102b157600080fd5b506032546101719073ffffffffffffffffffffffffffffffffffffffff1681565b3480156102de57600080fd5b5061020c6102ed366004614d9b565b60336020526000908152604090205460ff1681565b34801561030e57600080fd5b5060015461036a906fffffffffffffffffffffffffffffffff81169067ffffffffffffffff7001000000000000000000000000000000008204811691780100000000000000000000000000000000000000000000000090041683565b604080516fffffffffffffffffffffffffffffffff909416845267ffffffffffffffff9283166020850152911690820152606001610192565b3480156103af57600080fd5b506101366103be366004614df9565b6119b0565b3480156103cf57600080fd5b506104216103de366004614d9b565b603460205260009081526040902080546001909101546fffffffffffffffffffffffffffffffff8082169170010000000000000000000000000000000090041683565b604080519384526fffffffffffffffffffffffffffffffff9283166020850152911690820152606001610192565b61013661045d366004614e14565b610496565b34801561046e57600080fd5b506101717f000000000000000000000000000000000000000000000000000000000000000081565b8260005a9050831561054d5773ffffffffffffffffffffffffffffffffffffffff87161561054d57604080517f08c379a00000000000000000000000000000000000000000000000000000000081526020600482015260248101919091527f4f7074696d69736d506f7274616c3a206d7573742073656e6420746f2061646460448201527f72657373283029207768656e206372656174696e67206120636f6e747261637460648201526084015b60405180910390fd5b6152088567ffffffffffffffff1610156105e9576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603860248201527f4f7074696d69736d506f7274616c3a20676173206c696d6974206d757374206360448201527f6f76657220696e737472696e7369632067617320636f737400000000000000006064820152608401610544565b3332811461060a575033731111000000000000000000000000000000001111015b60003488888888604051602001610625959493929190614e99565b604051602081830303815290604052905060008973ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff167fb3813568d9991fc951961fcb4c784893574240a28925604d09fc577c55bb7c32846040516106959190614d88565b60405180910390a450506106a98282611bb9565b50505050505050565b3373ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000001614610777576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602960248201527f4f7074696d69736d506f7274616c3a206f6e6c7920677561726469616e20636160448201527f6e20756e706175736500000000000000000000000000000000000000000000006064820152608401610544565b603580547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001690556040513381527f5db9ee0a495bf2e6ff9c91a7834c1ba4fdd244a5e8aa4e537bd38aeae4b073aa906020015b60405180910390a1565b60355460ff1615610842576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4f7074696d69736d506f7274616c3a20706175736564000000000000000000006044820152606401610544565b3073ffffffffffffffffffffffffffffffffffffffff16856040015173ffffffffffffffffffffffffffffffffffffffff1603610901576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603f60248201527f4f7074696d69736d506f7274616c3a20796f752063616e6e6f742073656e642060448201527f6d6573736167657320746f2074686520706f7274616c20636f6e7472616374006064820152608401610544565b6040517fa25ae557000000000000000000000000000000000000000000000000000000008152600481018590526000907f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff169063a25ae55790602401606060405180830381865afa15801561098f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906109b39190614f1e565b5190506109cd6109c836869003860186614f83565b611ee6565b8114610a5b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602960248201527f4f7074696d69736d506f7274616c3a20696e76616c6964206f7574707574207260448201527f6f6f742070726f6f6600000000000000000000000000000000000000000000006064820152608401610544565b6000610a6687611f42565b6000818152603460209081526040918290208251606081018452815481526001909101546fffffffffffffffffffffffffffffffff8082169383018490527001000000000000000000000000000000009091041692810192909252919250901580610b985750805160408083015190517fa25ae5570000000000000000000000000000000000000000000000000000000081526fffffffffffffffffffffffffffffffff90911660048201527f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff169063a25ae55790602401606060405180830381865afa158015610b70573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610b949190614f1e565b5114155b610c24576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603760248201527f4f7074696d69736d506f7274616c3a207769746864726177616c20686173682060448201527f68617320616c7265616479206265656e2070726f76656e0000000000000000006064820152608401610544565b60408051602081018490526000918101829052606001604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe081840301815282825280516020918201209083018190529250610ced9101604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0818403018152828201909152600182527f0100000000000000000000000000000000000000000000000000000000000000602083015290610ce3888a614fe9565b8a60400135611f72565b610d79576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603260248201527f4f7074696d69736d506f7274616c3a20696e76616c696420776974686472617760448201527f616c20696e636c7573696f6e2070726f6f6600000000000000000000000000006064820152608401610544565b604080516060810182528581526fffffffffffffffffffffffffffffffff42811660208084019182528c831684860190815260008981526034835286812095518655925190518416700100000000000000000000000000000000029316929092176001909301929092558b830151908c0151925173ffffffffffffffffffffffffffffffffffffffff918216939091169186917f67a6208cfcc0801d50f6cbe764733f4fddf66ac0b04442061a8a8c0cb6b63f629190a4505050505050505050565b6060610e667f0000000000000000000000000000000000000000000000000000000000000000611f96565b610e8f7f0000000000000000000000000000000000000000000000000000000000000000611f96565b610eb87f0000000000000000000000000000000000000000000000000000000000000000611f96565b604051602001610eca9392919061506d565b604051602081830303815290604052905090565b6040517fa25ae55700000000000000000000000000000000000000000000000000000000815260048101829052600090610faf9073ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000169063a25ae55790602401606060405180830381865afa158015610f70573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610f949190614f1e565b602001516fffffffffffffffffffffffffffffffff166120d3565b92915050565b3373ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000161461107a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602760248201527f4f7074696d69736d506f7274616c3a206f6e6c7920677561726469616e20636160448201527f6e207061757365000000000000000000000000000000000000000000000000006064820152608401610544565b603580547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660011790556040513381527f62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a258906020016107cb565b60355460ff1615611142576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4f7074696d69736d506f7274616c3a20706175736564000000000000000000006044820152606401610544565b60325473ffffffffffffffffffffffffffffffffffffffff1661dead146111eb576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603f60248201527f4f7074696d69736d506f7274616c3a2063616e206f6e6c79207472696767657260448201527f206f6e65207769746864726177616c20706572207472616e73616374696f6e006064820152608401610544565b60006111f682611f42565b60008181526034602090815260408083208151606081018352815481526001909101546fffffffffffffffffffffffffffffffff808216948301859052700100000000000000000000000000000000909104169181019190915292935090036112e1576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603260248201527f4f7074696d69736d506f7274616c3a207769746864726177616c20686173206e60448201527f6f74206265656e2070726f76656e2079657400000000000000000000000000006064820152608401610544565b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663887862726040518163ffffffff1660e01b8152600401602060405180830381865afa15801561134c573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061137091906150e3565b81602001516fffffffffffffffffffffffffffffffff16101561143b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604b60248201527f4f7074696d69736d506f7274616c3a207769746864726177616c2074696d657360448201527f74616d70206c657373207468616e204c32204f7261636c65207374617274696e60648201527f672074696d657374616d70000000000000000000000000000000000000000000608482015260a401610544565b61145a81602001516fffffffffffffffffffffffffffffffff166120d3565b61150c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604560248201527f4f7074696d69736d506f7274616c3a2070726f76656e2077697468647261776160448201527f6c2066696e616c697a6174696f6e20706572696f6420686173206e6f7420656c60648201527f6170736564000000000000000000000000000000000000000000000000000000608482015260a401610544565b60408181015190517fa25ae5570000000000000000000000000000000000000000000000000000000081526fffffffffffffffffffffffffffffffff90911660048201526000907f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff169063a25ae55790602401606060405180830381865afa1580156115b1573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906115d59190614f1e565b825181519192501461168f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604960248201527f4f7074696d69736d506f7274616c3a206f757470757420726f6f742070726f7660448201527f656e206973206e6f74207468652073616d652061732063757272656e74206f7560648201527f7470757420726f6f740000000000000000000000000000000000000000000000608482015260a401610544565b6116ae81602001516fffffffffffffffffffffffffffffffff166120d3565b611760576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604360248201527f4f7074696d69736d506f7274616c3a206f75747075742070726f706f73616c2060448201527f66696e616c697a6174696f6e20706572696f6420686173206e6f7420656c617060648201527f7365640000000000000000000000000000000000000000000000000000000000608482015260a401610544565b60008381526033602052604090205460ff16156117ff576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603560248201527f4f7074696d69736d506f7274616c3a207769746864726177616c20686173206160448201527f6c7265616479206265656e2066696e616c697a656400000000000000000000006064820152608401610544565b600083815260336020908152604080832080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001179055908601516032805473ffffffffffffffffffffffffffffffffffffffff9092167fffffffffffffffffffffffff00000000000000000000000000000000000000009092169190911790558501516080860151606087015160a08801516118a193929190612176565b603280547fffffffffffffffffffffffff00000000000000000000000000000000000000001661dead17905560405190915084907fdb5c7652857aa163daadd670e116628fb42e869d8ac4251ef8971d9e5727df1b9061190690841515815260200190565b60405180910390a28015801561191c5750326001145b156119a9576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602160248201527f4f7074696d69736d506f7274616c3a207769746864726177616c206661696c6560448201527f64000000000000000000000000000000000000000000000000000000000000006064820152608401610544565b5050505050565b600054610100900460ff16158080156119d05750600054600160ff909116105b806119ea5750303b1580156119ea575060005460ff166001145b611a76576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a65640000000000000000000000000000000000006064820152608401610544565b600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660011790558015611ad457600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff166101001790555b603280547fffffffffffffffffffffffff00000000000000000000000000000000000000001661dead179055603580548315157fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00909116179055611b366121d4565b8015611b9957600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b5050565b73ffffffffffffffffffffffffffffffffffffffff163b151590565b600154600090611bef907801000000000000000000000000000000000000000000000000900467ffffffffffffffff164361512b565b90506000611bfb6122b7565b90506000816020015160ff16826000015163ffffffff16611c1c9190615171565b90508215611d5357600154600090611c53908390700100000000000000000000000000000000900467ffffffffffffffff166151d9565b90506000836040015160ff1683611c6a919061524d565b600154611c8a9084906fffffffffffffffffffffffffffffffff1661524d565b611c949190615171565b600154909150600090611ce590611cbe9084906fffffffffffffffffffffffffffffffff16615309565b866060015163ffffffff168760a001516fffffffffffffffffffffffffffffffff1661237d565b90506001861115611d1457611d11611cbe82876040015160ff1660018a611d0c919061512b565b61239c565b90505b6fffffffffffffffffffffffffffffffff16780100000000000000000000000000000000000000000000000067ffffffffffffffff4316021760015550505b60018054869190601090611d86908490700100000000000000000000000000000000900467ffffffffffffffff1661537d565b92506101000a81548167ffffffffffffffff021916908367ffffffffffffffff160217905550816000015163ffffffff16600160000160109054906101000a900467ffffffffffffffff1667ffffffffffffffff161315611e69576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603e60248201527f5265736f757263654d65746572696e673a2063616e6e6f7420627579206d6f7260448201527f6520676173207468616e20617661696c61626c6520676173206c696d697400006064820152608401610544565b600154600090611e95906fffffffffffffffffffffffffffffffff1667ffffffffffffffff88166153a9565b90506000611ea748633b9aca006123f1565b611eb190836153e6565b905060005a611ec0908861512b565b905080821115611edc57611edc611ed7828461512b565b612408565b5050505050505050565b60008160000151826020015183604001518460600151604051602001611f25949392919093845260208401929092526040830152606082015260800190565b604051602081830303815290604052805190602001209050919050565b80516020808301516040808501516060860151608087015160a08801519351600097611f259790969591016153fa565b600080611f7e86612436565b9050611f8c81868686612468565b9695505050505050565b606081600003611fd957505060408051808201909152600181527f3000000000000000000000000000000000000000000000000000000000000000602082015290565b8160005b81156120035780611fed81615451565b9150611ffc9050600a836153e6565b9150611fdd565b60008167ffffffffffffffff81111561201e5761201e614a58565b6040519080825280601f01601f191660200182016040528015612048576020820181803683370190505b5090505b84156120cb5761205d60018361512b565b915061206a600a86615489565b61207590603061549d565b60f81b81838151811061208a5761208a6154b5565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053506120c4600a866153e6565b945061204c565b949350505050565b60007f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663f4daa2916040518163ffffffff1660e01b8152600401602060405180830381865afa158015612140573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061216491906150e3565b61216e908361549d565b421192915050565b6000806000612186866000612498565b9050806121bc576308c379a06000526020805278185361666543616c6c3a204e6f7420656e6f756768206761736058526064601cfd5b600080855160208701888b5af1979650505050505050565b600054610100900460ff1661226b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e670000000000000000000000000000000000000000006064820152608401610544565b60408051606081018252633b9aca00808252600060208301524367ffffffffffffffff169190920181905278010000000000000000000000000000000000000000000000000217600155565b6040805160c081018252600080825260208201819052918101829052606081018290526080810182905260a08101919091527f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663cc731b026040518163ffffffff1660e01b815260040160c060405180830381865afa158015612354573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906123789190615509565b905090565b600061239261238c85856124b3565b836124c3565b90505b9392505050565b6000670de0b6b3a76400006123dd6123b48583615171565b6123c690670de0b6b3a76400006151d9565b6123d885670de0b6b3a764000061524d565b6124d2565b6123e7908661524d565b6123929190615171565b6000818310156124015781612395565b5090919050565b6000805a90505b825a61241b908361512b565b10156124315761242a82615451565b915061240f565b505050565b6060818051906020012060405160200161245291815260200190565b6040516020818303038152906040529050919050565b600061248f84612479878686612503565b8051602091820120825192909101919091201490565b95945050505050565b60008082619c4001603f6040860204015a1015949350505050565b6000818312156124015781612395565b60008183126124015781612395565b6000612395670de0b6b3a7640000836124ea86612f8b565b6124f4919061524d565b6124fe9190615171565b6131cf565b60606000845111612570576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601560248201527f4d65726b6c65547269653a20656d707479206b657900000000000000000000006044820152606401610544565b600061257b8461340e565b90506000612588866134fd565b905060008460405160200161259f91815260200190565b60405160208183030381529060405290506000805b8451811015612f025760008582815181106125d1576125d16154b5565b60200260200101519050845183111561266c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f4d65726b6c65547269653a206b657920696e646578206578636565647320746f60448201527f74616c206b6579206c656e6774680000000000000000000000000000000000006064820152608401610544565b8260000361272557805180516020918201206040516126ba9261269492910190815260200190565b604051602081830303815290604052858051602091820120825192909101919091201490565b612720576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f4d65726b6c65547269653a20696e76616c696420726f6f7420686173680000006044820152606401610544565b61287c565b8051516020116127db578051805160209182012060405161274f9261269492910190815260200190565b612720576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602760248201527f4d65726b6c65547269653a20696e76616c6964206c6172676520696e7465726e60448201527f616c2068617368000000000000000000000000000000000000000000000000006064820152608401610544565b80518451602080870191909120825191909201201461287c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f4d65726b6c65547269653a20696e76616c696420696e7465726e616c206e6f6460448201527f65206861736800000000000000000000000000000000000000000000000000006064820152608401610544565b6128886010600161549d565b81602001515103612a695784518303612a015760006128c482602001516010815181106128b7576128b76154b5565b6020026020010151613698565b90506000815111612957576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603b60248201527f4d65726b6c65547269653a2076616c7565206c656e677468206d75737420626560448201527f2067726561746572207468616e207a65726f20286272616e63682900000000006064820152608401610544565b60018751612965919061512b565b83146129f3576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603a60248201527f4d65726b6c65547269653a2076616c7565206e6f6465206d757374206265206c60448201527f617374206e6f646520696e2070726f6f6620286272616e6368290000000000006064820152608401610544565b965061239595505050505050565b6000858481518110612a1557612a156154b5565b602001015160f81c60f81b60f81c9050600082602001518260ff1681518110612a4057612a406154b5565b60200260200101519050612a53816137f8565b9550612a6060018661549d565b94505050612eef565b600281602001515103612e67576000612a818261381d565b9050600081600081518110612a9857612a986154b5565b016020015160f81c90506000612aaf6002836155a8565b612aba9060026155ca565b90506000612acb848360ff16613841565b90506000612ad98a89613841565b90506000612ae78383613877565b905080835114612b79576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603a60248201527f4d65726b6c65547269653a20706174682072656d61696e646572206d7573742060448201527f736861726520616c6c206e6962626c65732077697468206b65790000000000006064820152608401610544565b60ff851660021480612b8e575060ff85166003145b15612d825780825114612c23576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603d60248201527f4d65726b6c65547269653a206b65792072656d61696e646572206d757374206260448201527f65206964656e746963616c20746f20706174682072656d61696e6465720000006064820152608401610544565b6000612c3f88602001516001815181106128b7576128b76154b5565b90506000815111612cd2576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603960248201527f4d65726b6c65547269653a2076616c7565206c656e677468206d75737420626560448201527f2067726561746572207468616e207a65726f20286c65616629000000000000006064820152608401610544565b60018d51612ce0919061512b565b8914612d6e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603860248201527f4d65726b6c65547269653a2076616c7565206e6f6465206d757374206265206c60448201527f617374206e6f646520696e2070726f6f6620286c6561662900000000000000006064820152608401610544565b9c506123959b505050505050505050505050565b60ff85161580612d95575060ff85166001145b15612dd457612dc18760200151600181518110612db457612db46154b5565b60200260200101516137f8565b9950612dcd818a61549d565b9850612e5c565b6040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603260248201527f4d65726b6c65547269653a2072656365697665642061206e6f6465207769746860448201527f20616e20756e6b6e6f776e2070726566697800000000000000000000000000006064820152608401610544565b505050505050612eef565b6040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602860248201527f4d65726b6c65547269653a20726563656976656420616e20756e70617273656160448201527f626c65206e6f64650000000000000000000000000000000000000000000000006064820152608401610544565b5080612efa81615451565b9150506125b4565b506040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602560248201527f4d65726b6c65547269653a2072616e206f7574206f662070726f6f6620656c6560448201527f6d656e74730000000000000000000000000000000000000000000000000000006064820152608401610544565b6000808213612ff6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600960248201527f554e444546494e454400000000000000000000000000000000000000000000006044820152606401610544565b6000606061300384613926565b03609f8181039490941b90931c6c465772b2bbbb5f824b15207a3081018102606090811d6d0388eaa27412d5aca026815d636e018202811d6d0df99ac502031bf953eff472fdcc018202811d6d13cdffb29d51d99322bdff5f2211018202811d6d0a0f742023def783a307a986912e018202811d6d01920d8043ca89b5239253284e42018202811d6c0b7a86d7375468fac667a0a527016c29508e458543d8aa4df2abee7883018302821d6d0139601a2efabe717e604cbb4894018302821d6d02247f7a7b6594320649aa03aba1018302821d7fffffffffffffffffffffffffffffffffffffff73c0c716a594e00d54e3c4cbc9018302821d7ffffffffffffffffffffffffffffffffffffffdc7b88c420e53a9890533129f6f01830290911d7fffffffffffffffffffffffffffffffffffffff465fda27eb4d63ded474e5f832019091027ffffffffffffffff5f6af8f7b3396644f18e157960000000000000000000000000105711340daa0d5f769dba1915cef59f0815a5506027d0267a36c0c95b3975ab3ee5b203a7614a3f75373f047d803ae7b6687f2b393909302929092017d57115e47018c7177eebf7cd370a3356a1b7863008a5ae8028c72b88642840160ae1d92915050565b60007ffffffffffffffffffffffffffffffffffffffffffffffffdb731c958f34d94c1821361320057506000919050565b680755bf798b4a1bf1e58212613272576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600c60248201527f4558505f4f564552464c4f5700000000000000000000000000000000000000006044820152606401610544565b6503782dace9d9604e83901b059150600060606bb17217f7d1cf79abc9e3b39884821b056b80000000000000000000000001901d6bb17217f7d1cf79abc9e3b39881029093037fffffffffffffffffffffffffffffffffffffffdbf3ccf1604d263450f02a550481018102606090811d6d0277594991cfc85f6e2461837cd9018202811d7fffffffffffffffffffffffffffffffffffffe5adedaa1cb095af9e4da10e363c018202811d6db1bbb201f443cf962f1a1d3db4a5018202811d7ffffffffffffffffffffffffffffffffffffd38dc772608b0ae56cce01296c0eb018202811d6e05180bb14799ab47a8a8cb2a527d57016d02d16720577bd19bf614176fe9ea6c10fe68e7fd37d0007b713f765084018402831d9081019084017ffffffffffffffffffffffffffffffffffffffe2c69812cf03b0763fd454a8f7e010290911d6e0587f503bb6ea29d25fcb7401964500190910279d835ebba824c98fb31b83b2ca45c000000000000000000000000010574029d9dc38563c32e5c2f6dc192ee70ef65f9978af30260c3939093039290921c92915050565b805160609060008167ffffffffffffffff81111561342e5761342e614a58565b60405190808252806020026020018201604052801561347357816020015b604080518082019091526060808252602082015281526020019060019003908161344c5790505b50905060005b828110156134f557604051806040016040528086838151811061349e5761349e6154b5565b602002602001015181526020016134cd8784815181106134c0576134c06154b5565b60200260200101516139fc565b8152508282815181106134e2576134e26154b5565b6020908102919091010152600101613479565b509392505050565b8051606090600061350f8260026153a9565b67ffffffffffffffff81111561352757613527614a58565b6040519080825280601f01601f191660200182016040528015613551576020820181803683370190505b5090506000805b8381101561368e57858181518110613572576135726154b5565b6020910101517fff000000000000000000000000000000000000000000000000000000000000008116925060041c7f0ff000000000000000000000000000000000000000000000000000000000000016836135ce8360026153a9565b815181106135de576135de6154b5565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053507f0f0000000000000000000000000000000000000000000000000000000000000082168361363c8360026153a9565b61364790600161549d565b81518110613657576136576154b5565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a905350600101613558565b5090949350505050565b606060008060006136a885613a0f565b9194509250905060008160018111156136c3576136c36155ed565b14613750576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603960248201527f524c505265616465723a206465636f646564206974656d207479706520666f7260448201527f206279746573206973206e6f7420612064617461206974656d000000000000006064820152608401610544565b61375a828461549d565b8551146137e9576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603460248201527f524c505265616465723a2062797465732076616c756520636f6e7461696e732060448201527f616e20696e76616c69642072656d61696e6465720000000000000000000000006064820152608401610544565b61248f8560200151848461447c565b606060208260000151106138145761380f82613698565b610faf565b610faf8261451d565b6060610faf61383c83602001516000815181106128b7576128b76154b5565b6134fd565b6060825182106138605750604080516020810190915260008152610faf565b6123958383848651613872919061512b565b614533565b6000806000835185511061388c57835161388f565b84515b90505b808210801561391657508382815181106138ae576138ae6154b5565b602001015160f81c60f81b7effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff19168583815181106138ed576138ed6154b5565b01602001517fff0000000000000000000000000000000000000000000000000000000000000016145b156134f557816001019150613892565b6000808211613991576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600960248201527f554e444546494e454400000000000000000000000000000000000000000000006044820152606401610544565b5060016fffffffffffffffffffffffffffffffff821160071b82811c67ffffffffffffffff1060061b1782811c63ffffffff1060051b1782811c61ffff1060041b1782811c60ff10600390811b90911783811c600f1060021b1783811c909110821b1791821c111790565b6060610faf613a0a8361470b565b6147f4565b600080600080846000015111613acd576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604a60248201527f524c505265616465723a206c656e677468206f6620616e20524c50206974656d60448201527f206d7573742062652067726561746572207468616e207a65726f20746f20626560648201527f206465636f6461626c6500000000000000000000000000000000000000000000608482015260a401610544565b6020840151805160001a607f8111613af2576000600160009450945094505050614475565b60b78111613d00576000613b0760808361512b565b905080876000015111613bc2576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604e60248201527f524c505265616465723a206c656e677468206f6620636f6e74656e74206d757360448201527f742062652067726561746572207468616e20737472696e67206c656e6774682060648201527f2873686f727420737472696e6729000000000000000000000000000000000000608482015260a401610544565b6001838101517fff00000000000000000000000000000000000000000000000000000000000000169082141580613c3b57507f80000000000000000000000000000000000000000000000000000000000000007fff00000000000000000000000000000000000000000000000000000000000000821610155b613ced576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604d60248201527f524c505265616465723a20696e76616c6964207072656669782c2073696e676c60448201527f652062797465203c203078383020617265206e6f74207072656669786564202860648201527f73686f727420737472696e672900000000000000000000000000000000000000608482015260a401610544565b5060019550935060009250614475915050565b60bf811161404e576000613d1560b78361512b565b905080876000015111613dd0576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152605160248201527f524c505265616465723a206c656e677468206f6620636f6e74656e74206d757360448201527f74206265203e207468616e206c656e677468206f6620737472696e67206c656e60648201527f67746820286c6f6e6720737472696e6729000000000000000000000000000000608482015260a401610544565b60018301517fff00000000000000000000000000000000000000000000000000000000000000166000819003613eae576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604a60248201527f524c505265616465723a206c656e677468206f6620636f6e74656e74206d757360448201527f74206e6f74206861766520616e79206c656164696e67207a65726f7320286c6f60648201527f6e6720737472696e672900000000000000000000000000000000000000000000608482015260a401610544565b600184015160088302610100031c60378111613f72576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604860248201527f524c505265616465723a206c656e677468206f6620636f6e74656e74206d757360448201527f742062652067726561746572207468616e20353520627974657320286c6f6e6760648201527f20737472696e6729000000000000000000000000000000000000000000000000608482015260a401610544565b613f7c818461549d565b895111614031576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604c60248201527f524c505265616465723a206c656e677468206f6620636f6e74656e74206d757360448201527f742062652067726561746572207468616e20746f74616c206c656e677468202860648201527f6c6f6e6720737472696e67290000000000000000000000000000000000000000608482015260a401610544565b61403c83600161549d565b97509550600094506144759350505050565b60f7811161412f57600061406360c08361512b565b90508087600001511161411e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604a60248201527f524c505265616465723a206c656e677468206f6620636f6e74656e74206d757360448201527f742062652067726561746572207468616e206c697374206c656e67746820287360648201527f686f7274206c6973742900000000000000000000000000000000000000000000608482015260a401610544565b600195509350849250614475915050565b600061413c60f78361512b565b9050808760000151116141f7576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604d60248201527f524c505265616465723a206c656e677468206f6620636f6e74656e74206d757360448201527f74206265203e207468616e206c656e677468206f66206c697374206c656e677460648201527f6820286c6f6e67206c6973742900000000000000000000000000000000000000608482015260a401610544565b60018301517fff000000000000000000000000000000000000000000000000000000000000001660008190036142d5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604860248201527f524c505265616465723a206c656e677468206f6620636f6e74656e74206d757360448201527f74206e6f74206861766520616e79206c656164696e67207a65726f7320286c6f60648201527f6e67206c69737429000000000000000000000000000000000000000000000000608482015260a401610544565b600184015160088302610100031c60378111614399576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604660248201527f524c505265616465723a206c656e677468206f6620636f6e74656e74206d757360448201527f742062652067726561746572207468616e20353520627974657320286c6f6e6760648201527f206c697374290000000000000000000000000000000000000000000000000000608482015260a401610544565b6143a3818461549d565b895111614458576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604a60248201527f524c505265616465723a206c656e677468206f6620636f6e74656e74206d757360448201527f742062652067726561746572207468616e20746f74616c206c656e677468202860648201527f6c6f6e67206c6973742900000000000000000000000000000000000000000000608482015260a401610544565b61446383600161549d565b97509550600194506144759350505050565b9193909250565b606060008267ffffffffffffffff81111561449957614499614a58565b6040519080825280601f01601f1916602001820160405280156144c3576020820181803683370190505b509050826000036144d5579050612395565b60006144e1858761549d565b90506020820160005b858110156145025782810151828201526020016144ea565b85811115614511576000868301525b50919695505050505050565b6060610faf82602001516000846000015161447c565b60608182601f0110156145a2576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600e60248201527f736c6963655f6f766572666c6f770000000000000000000000000000000000006044820152606401610544565b82828401101561460e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600e60248201527f736c6963655f6f766572666c6f770000000000000000000000000000000000006044820152606401610544565b8183018451101561467b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601160248201527f736c6963655f6f75744f66426f756e64730000000000000000000000000000006044820152606401610544565b60608215801561469a5760405191506000825260208201604052614702565b6040519150601f8416801560200281840101858101878315602002848b0101015b818310156146d35780518352602092830192016146bb565b5050858452601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016604052505b50949350505050565b604080518082019091526000808252602082015260008251116147d6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604a60248201527f524c505265616465723a206c656e677468206f6620616e20524c50206974656d60448201527f206d7573742062652067726561746572207468616e207a65726f20746f20626560648201527f206465636f6461626c6500000000000000000000000000000000000000000000608482015260a401610544565b50604080518082019091528151815260209182019181019190915290565b6060600080600061480485613a0f565b91945092509050600181600181111561481f5761481f6155ed565b146148ac576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603860248201527f524c505265616465723a206465636f646564206974656d207479706520666f7260448201527f206c697374206973206e6f742061206c697374206974656d00000000000000006064820152608401610544565b84516148b8838561549d565b14614945576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603260248201527f524c505265616465723a206c697374206974656d2068617320616e20696e766160448201527f6c696420646174612072656d61696e64657200000000000000000000000000006064820152608401610544565b6040805160208082526104208201909252600091816020015b604080518082019091526000808252602082015281526020019060019003908161495e5790505090506000845b8751811015614a4c576000806149d16040518060400160405280858d600001516149b5919061512b565b8152602001858d602001516149ca919061549d565b9052613a0f565b5091509150604051806040016040528083836149ed919061549d565b8152602001848c60200151614a02919061549d565b815250858581518110614a1757614a176154b5565b6020908102919091010152614a2d60018561549d565b9350614a39818361549d565b614a43908461549d565b9250505061498b565b50815295945050505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff81118282101715614ace57614ace614a58565b604052919050565b803573ffffffffffffffffffffffffffffffffffffffff81168114614afa57600080fd5b919050565b600082601f830112614b1057600080fd5b813567ffffffffffffffff811115614b2a57614b2a614a58565b614b5b60207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f84011601614a87565b818152846020838601011115614b7057600080fd5b816020850160208301376000918101602001919091529392505050565b600060c08284031215614b9f57600080fd5b60405160c0810167ffffffffffffffff8282108183111715614bc357614bc3614a58565b8160405282935084358352614bda60208601614ad6565b6020840152614beb60408601614ad6565b6040840152606085013560608401526080850135608084015260a0850135915080821115614c1857600080fd5b50614c2585828601614aff565b60a0830152505092915050565b600080600080600085870360e0811215614c4b57600080fd5b863567ffffffffffffffff80821115614c6357600080fd5b614c6f8a838b01614b8d565b97506020890135965060807fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc084011215614ca857600080fd5b60408901955060c0890135925080831115614cc257600080fd5b828901925089601f840112614cd657600080fd5b8235915080821115614ce757600080fd5b508860208260051b8401011115614cfd57600080fd5b959894975092955050506020019190565b60005b83811015614d29578181015183820152602001614d11565b83811115614d38576000848401525b50505050565b60008151808452614d56816020860160208601614d0e565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b6020815260006123956020830184614d3e565b600060208284031215614dad57600080fd5b5035919050565b600060208284031215614dc657600080fd5b813567ffffffffffffffff811115614ddd57600080fd5b6120cb84828501614b8d565b80358015158114614afa57600080fd5b600060208284031215614e0b57600080fd5b61239582614de9565b600080600080600060a08688031215614e2c57600080fd5b614e3586614ad6565b945060208601359350604086013567ffffffffffffffff8082168214614e5a57600080fd5b819450614e6960608901614de9565b93506080880135915080821115614e7f57600080fd5b50614e8c88828901614aff565b9150509295509295909350565b8581528460208201527fffffffffffffffff0000000000000000000000000000000000000000000000008460c01b16604082015282151560f81b604882015260008251614eed816049850160208701614d0e565b919091016049019695505050505050565b80516fffffffffffffffffffffffffffffffff81168114614afa57600080fd5b600060608284031215614f3057600080fd5b6040516060810181811067ffffffffffffffff82111715614f5357614f53614a58565b60405282518152614f6660208401614efe565b6020820152614f7760408401614efe565b60408201529392505050565b600060808284031215614f9557600080fd5b6040516080810181811067ffffffffffffffff82111715614fb857614fb8614a58565b8060405250823581526020830135602082015260408301356040820152606083013560608201528091505092915050565b600067ffffffffffffffff8084111561500457615004614a58565b8360051b6020615015818301614a87565b86815291850191818101903684111561502d57600080fd5b865b84811015615061578035868111156150475760008081fd5b61505336828b01614aff565b84525091830191830161502f565b50979650505050505050565b6000845161507f818460208901614d0e565b80830190507f2e0000000000000000000000000000000000000000000000000000000000000080825285516150bb816001850160208a01614d0e565b600192019182015283516150d6816002840160208801614d0e565b0160020195945050505050565b6000602082840312156150f557600080fd5b5051919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60008282101561513d5761513d6150fc565b500390565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b60008261518057615180615142565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff83147f8000000000000000000000000000000000000000000000000000000000000000831416156151d4576151d46150fc565b500590565b6000808312837f800000000000000000000000000000000000000000000000000000000000000001831281151615615213576152136150fc565b837f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff018313811615615247576152476150fc565b50500390565b60007f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff60008413600084138583048511828216161561528e5761528e6150fc565b7f800000000000000000000000000000000000000000000000000000000000000060008712868205881281841616156152c9576152c96150fc565b600087129250878205871284841616156152e5576152e56150fc565b878505871281841616156152fb576152fb6150fc565b505050929093029392505050565b6000808212827f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff03841381151615615343576153436150fc565b827f8000000000000000000000000000000000000000000000000000000000000000038412811615615377576153776150fc565b50500190565b600067ffffffffffffffff8083168185168083038211156153a0576153a06150fc565b01949350505050565b6000817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff04831182151516156153e1576153e16150fc565b500290565b6000826153f5576153f5615142565b500490565b868152600073ffffffffffffffffffffffffffffffffffffffff808816602084015280871660408401525084606083015283608083015260c060a083015261544560c0830184614d3e565b98975050505050505050565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203615482576154826150fc565b5060010190565b60008261549857615498615142565b500690565b600082198211156154b0576154b06150fc565b500190565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b805163ffffffff81168114614afa57600080fd5b805160ff81168114614afa57600080fd5b600060c0828403121561551b57600080fd5b60405160c0810181811067ffffffffffffffff8211171561553e5761553e614a58565b60405261554a836154e4565b8152615558602084016154f8565b6020820152615569604084016154f8565b604082015261557a606084016154e4565b606082015261558b608084016154e4565b608082015261559c60a08401614efe565b60a08201529392505050565b600060ff8316806155bb576155bb615142565b8060ff84160691505092915050565b600060ff821660ff8416808210156155e4576155e46150fc565b90039392505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fdfea164736f6c634300080f000a",
}
// OptimismPortalABI is the input ABI used to generate the binding from.
......
......@@ -13,7 +13,7 @@ const OptimismPortalStorageLayoutJSON = "{\"storage\":[{\"astId\":1000,\"contrac
var OptimismPortalStorageLayout = new(solc.StorageLayout)
var OptimismPortalDeployedBin = "0x6080604052600436106101115760003560e01c80638b4c40b0116100a5578063cff0ab9611610074578063e965084c11610059578063e965084c146103c3578063e9e05c421461044f578063f04987501461046257600080fd5b8063cff0ab9614610302578063d53a822f146103a357600080fd5b80638b4c40b0146101365780638c3152e9146102855780639bf62d82146102a5578063a14238e7146102d257600080fd5b80635c975abb116100e15780635c975abb146101f25780636dbffb781461021c578063724c184c1461023c5780638456cb591461027057600080fd5b80621c2ff61461013d5780633f4ba83a1461019b5780634870496f146101b057806354fd4d50146101d057600080fd5b36610138576101363334620186a0600060405180602001604052806000815250610496565b005b600080fd5b34801561014957600080fd5b506101717f000000000000000000000000000000000000000000000000000000000000000081565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020015b60405180910390f35b3480156101a757600080fd5b506101366106b2565b3480156101bc57600080fd5b506101366101cb366004614c13565b6107d5565b3480156101dc57600080fd5b506101e5610e3b565b6040516101929190614d69565b3480156101fe57600080fd5b5060355461020c9060ff1681565b6040519015158152602001610192565b34801561022857600080fd5b5061020c610237366004614d7c565b610ede565b34801561024857600080fd5b506101717f000000000000000000000000000000000000000000000000000000000000000081565b34801561027c57600080fd5b50610136610fb5565b34801561029157600080fd5b506101366102a0366004614d95565b6110d5565b3480156102b157600080fd5b506032546101719073ffffffffffffffffffffffffffffffffffffffff1681565b3480156102de57600080fd5b5061020c6102ed366004614d7c565b60336020526000908152604090205460ff1681565b34801561030e57600080fd5b5060015461036a906fffffffffffffffffffffffffffffffff81169067ffffffffffffffff7001000000000000000000000000000000008204811691780100000000000000000000000000000000000000000000000090041683565b604080516fffffffffffffffffffffffffffffffff909416845267ffffffffffffffff9283166020850152911690820152606001610192565b3480156103af57600080fd5b506101366103be366004614dda565b6119b0565b3480156103cf57600080fd5b506104216103de366004614d7c565b603460205260009081526040902080546001909101546fffffffffffffffffffffffffffffffff8082169170010000000000000000000000000000000090041683565b604080519384526fffffffffffffffffffffffffffffffff9283166020850152911690820152606001610192565b61013661045d366004614df5565b610496565b34801561046e57600080fd5b506101717f000000000000000000000000000000000000000000000000000000000000000081565b8260005a9050831561054d5773ffffffffffffffffffffffffffffffffffffffff87161561054d57604080517f08c379a00000000000000000000000000000000000000000000000000000000081526020600482015260248101919091527f4f7074696d69736d506f7274616c3a206d7573742073656e6420746f2061646460448201527f72657373283029207768656e206372656174696e67206120636f6e747261637460648201526084015b60405180910390fd5b6152088567ffffffffffffffff1610156105e9576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603860248201527f4f7074696d69736d506f7274616c3a20676173206c696d6974206d757374206360448201527f6f76657220696e737472696e7369632067617320636f737400000000000000006064820152608401610544565b3332811461060a575033731111000000000000000000000000000000001111015b60003488888888604051602001610625959493929190614e7a565b604051602081830303815290604052905060008973ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff167fb3813568d9991fc951961fcb4c784893574240a28925604d09fc577c55bb7c32846040516106959190614d69565b60405180910390a450506106a98282611bb9565b50505050505050565b3373ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000001614610777576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602960248201527f4f7074696d69736d506f7274616c3a206f6e6c7920677561726469616e20636160448201527f6e20756e706175736500000000000000000000000000000000000000000000006064820152608401610544565b603580547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001690556040513381527f5db9ee0a495bf2e6ff9c91a7834c1ba4fdd244a5e8aa4e537bd38aeae4b073aa906020015b60405180910390a1565b60355460ff1615610842576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4f7074696d69736d506f7274616c3a20706175736564000000000000000000006044820152606401610544565b3073ffffffffffffffffffffffffffffffffffffffff16856040015173ffffffffffffffffffffffffffffffffffffffff1603610901576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603f60248201527f4f7074696d69736d506f7274616c3a20796f752063616e6e6f742073656e642060448201527f6d6573736167657320746f2074686520706f7274616c20636f6e7472616374006064820152608401610544565b6040517fa25ae557000000000000000000000000000000000000000000000000000000008152600481018590526000907f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff169063a25ae55790602401606060405180830381865afa15801561098f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906109b39190614eff565b5190506109cd6109c836869003860186614f64565b611ee6565b8114610a5b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602960248201527f4f7074696d69736d506f7274616c3a20696e76616c6964206f7574707574207260448201527f6f6f742070726f6f6600000000000000000000000000000000000000000000006064820152608401610544565b6000610a6687611f42565b6000818152603460209081526040918290208251606081018452815481526001909101546fffffffffffffffffffffffffffffffff8082169383018490527001000000000000000000000000000000009091041692810192909252919250901580610b985750805160408083015190517fa25ae5570000000000000000000000000000000000000000000000000000000081526fffffffffffffffffffffffffffffffff90911660048201527f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff169063a25ae55790602401606060405180830381865afa158015610b70573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610b949190614eff565b5114155b610c24576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603760248201527f4f7074696d69736d506f7274616c3a207769746864726177616c20686173682060448201527f68617320616c7265616479206265656e2070726f76656e0000000000000000006064820152608401610544565b60408051602081018490526000918101829052606001604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe081840301815282825280516020918201209083018190529250610ced9101604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0818403018152828201909152600182527f0100000000000000000000000000000000000000000000000000000000000000602083015290610ce3888a614fca565b8a60400135611f72565b610d79576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603260248201527f4f7074696d69736d506f7274616c3a20696e76616c696420776974686472617760448201527f616c20696e636c7573696f6e2070726f6f6600000000000000000000000000006064820152608401610544565b604080516060810182528581526fffffffffffffffffffffffffffffffff42811660208084019182528c831684860190815260008981526034835286812095518655925190518416700100000000000000000000000000000000029316929092176001909301929092558b830151908c0151925173ffffffffffffffffffffffffffffffffffffffff918216939091169186917f67a6208cfcc0801d50f6cbe764733f4fddf66ac0b04442061a8a8c0cb6b63f629190a4505050505050505050565b6060610e667f0000000000000000000000000000000000000000000000000000000000000000611f96565b610e8f7f0000000000000000000000000000000000000000000000000000000000000000611f96565b610eb87f0000000000000000000000000000000000000000000000000000000000000000611f96565b604051602001610eca9392919061504e565b604051602081830303815290604052905090565b6040517fa25ae55700000000000000000000000000000000000000000000000000000000815260048101829052600090610faf9073ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000169063a25ae55790602401606060405180830381865afa158015610f70573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610f949190614eff565b602001516fffffffffffffffffffffffffffffffff166120d3565b92915050565b3373ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000161461107a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602760248201527f4f7074696d69736d506f7274616c3a206f6e6c7920677561726469616e20636160448201527f6e207061757365000000000000000000000000000000000000000000000000006064820152608401610544565b603580547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660011790556040513381527f62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a258906020016107cb565b60355460ff1615611142576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4f7074696d69736d506f7274616c3a20706175736564000000000000000000006044820152606401610544565b60325473ffffffffffffffffffffffffffffffffffffffff1661dead146111eb576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603f60248201527f4f7074696d69736d506f7274616c3a2063616e206f6e6c79207472696767657260448201527f206f6e65207769746864726177616c20706572207472616e73616374696f6e006064820152608401610544565b60006111f682611f42565b60008181526034602090815260408083208151606081018352815481526001909101546fffffffffffffffffffffffffffffffff808216948301859052700100000000000000000000000000000000909104169181019190915292935090036112e1576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603260248201527f4f7074696d69736d506f7274616c3a207769746864726177616c20686173206e60448201527f6f74206265656e2070726f76656e2079657400000000000000000000000000006064820152608401610544565b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663887862726040518163ffffffff1660e01b8152600401602060405180830381865afa15801561134c573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061137091906150c4565b81602001516fffffffffffffffffffffffffffffffff16101561143b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604b60248201527f4f7074696d69736d506f7274616c3a207769746864726177616c2074696d657360448201527f74616d70206c657373207468616e204c32204f7261636c65207374617274696e60648201527f672074696d657374616d70000000000000000000000000000000000000000000608482015260a401610544565b61145a81602001516fffffffffffffffffffffffffffffffff166120d3565b61150c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604560248201527f4f7074696d69736d506f7274616c3a2070726f76656e2077697468647261776160448201527f6c2066696e616c697a6174696f6e20706572696f6420686173206e6f7420656c60648201527f6170736564000000000000000000000000000000000000000000000000000000608482015260a401610544565b60408181015190517fa25ae5570000000000000000000000000000000000000000000000000000000081526fffffffffffffffffffffffffffffffff90911660048201526000907f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff169063a25ae55790602401606060405180830381865afa1580156115b1573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906115d59190614eff565b825181519192501461168f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604960248201527f4f7074696d69736d506f7274616c3a206f757470757420726f6f742070726f7660448201527f656e206973206e6f74207468652073616d652061732063757272656e74206f7560648201527f7470757420726f6f740000000000000000000000000000000000000000000000608482015260a401610544565b6116ae81602001516fffffffffffffffffffffffffffffffff166120d3565b611760576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604360248201527f4f7074696d69736d506f7274616c3a206f75747075742070726f706f73616c2060448201527f66696e616c697a6174696f6e20706572696f6420686173206e6f7420656c617060648201527f7365640000000000000000000000000000000000000000000000000000000000608482015260a401610544565b60008381526033602052604090205460ff16156117ff576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603560248201527f4f7074696d69736d506f7274616c3a207769746864726177616c20686173206160448201527f6c7265616479206265656e2066696e616c697a656400000000000000000000006064820152608401610544565b600083815260336020908152604080832080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001179055908601516032805473ffffffffffffffffffffffffffffffffffffffff9092167fffffffffffffffffffffffff00000000000000000000000000000000000000009092169190911790558501516080860151606087015160a08801516118a193929190612176565b603280547fffffffffffffffffffffffff00000000000000000000000000000000000000001661dead17905560405190915084907fdb5c7652857aa163daadd670e116628fb42e869d8ac4251ef8971d9e5727df1b9061190690841515815260200190565b60405180910390a28015801561191c5750326001145b156119a9576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602160248201527f4f7074696d69736d506f7274616c3a207769746864726177616c206661696c6560448201527f64000000000000000000000000000000000000000000000000000000000000006064820152608401610544565b5050505050565b600054610100900460ff16158080156119d05750600054600160ff909116105b806119ea5750303b1580156119ea575060005460ff166001145b611a76576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a65640000000000000000000000000000000000006064820152608401610544565b600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660011790558015611ad457600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff166101001790555b603280547fffffffffffffffffffffffff00000000000000000000000000000000000000001661dead179055603580548315157fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00909116179055611b366121d0565b8015611b9957600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b5050565b73ffffffffffffffffffffffffffffffffffffffff163b151590565b600154600090611bef907801000000000000000000000000000000000000000000000000900467ffffffffffffffff164361510c565b90506000611bfb6122b3565b90506000816020015160ff16826000015163ffffffff16611c1c9190615152565b90508215611d5357600154600090611c53908390700100000000000000000000000000000000900467ffffffffffffffff166151ba565b90506000836040015160ff1683611c6a919061522e565b600154611c8a9084906fffffffffffffffffffffffffffffffff1661522e565b611c949190615152565b600154909150600090611ce590611cbe9084906fffffffffffffffffffffffffffffffff166152ea565b866060015163ffffffff168760a001516fffffffffffffffffffffffffffffffff16612379565b90506001861115611d1457611d11611cbe82876040015160ff1660018a611d0c919061510c565b612398565b90505b6fffffffffffffffffffffffffffffffff16780100000000000000000000000000000000000000000000000067ffffffffffffffff4316021760015550505b60018054869190601090611d86908490700100000000000000000000000000000000900467ffffffffffffffff1661535e565b92506101000a81548167ffffffffffffffff021916908367ffffffffffffffff160217905550816000015163ffffffff16600160000160109054906101000a900467ffffffffffffffff1667ffffffffffffffff161315611e69576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603e60248201527f5265736f757263654d65746572696e673a2063616e6e6f7420627579206d6f7260448201527f6520676173207468616e20617661696c61626c6520676173206c696d697400006064820152608401610544565b600154600090611e95906fffffffffffffffffffffffffffffffff1667ffffffffffffffff881661538a565b90506000611ea748633b9aca006123ed565b611eb190836153c7565b905060005a611ec0908861510c565b905080821115611edc57611edc611ed7828461510c565b612404565b5050505050505050565b60008160000151826020015183604001518460600151604051602001611f25949392919093845260208401929092526040830152606082015260800190565b604051602081830303815290604052805190602001209050919050565b80516020808301516040808501516060860151608087015160a08801519351600097611f259790969591016153db565b600080611f7e86612432565b9050611f8c81868686612464565b9695505050505050565b606081600003611fd957505060408051808201909152600181527f3000000000000000000000000000000000000000000000000000000000000000602082015290565b8160005b81156120035780611fed81615432565b9150611ffc9050600a836153c7565b9150611fdd565b60008167ffffffffffffffff81111561201e5761201e614a39565b6040519080825280601f01601f191660200182016040528015612048576020820181803683370190505b5090505b84156120cb5761205d60018361510c565b915061206a600a8661546a565b61207590603061547e565b60f81b81838151811061208a5761208a615496565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053506120c4600a866153c7565b945061204c565b949350505050565b60007f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663f4daa2916040518163ffffffff1660e01b8152600401602060405180830381865afa158015612140573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061216491906150c4565b61216e908361547e565b421192915050565b600080603f60c88601604002045a10156121b9576308c379a06000526020805278185361666543616c6c3a204e6f7420656e6f756768206761736058526064601cfd5b600080845160208601878a5af19695505050505050565b600054610100900460ff16612267576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e670000000000000000000000000000000000000000006064820152608401610544565b60408051606081018252633b9aca00808252600060208301524367ffffffffffffffff169190920181905278010000000000000000000000000000000000000000000000000217600155565b6040805160c081018252600080825260208201819052918101829052606081018290526080810182905260a08101919091527f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663cc731b026040518163ffffffff1660e01b815260040160c060405180830381865afa158015612350573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061237491906154ea565b905090565b600061238e6123888585612494565b836124a4565b90505b9392505050565b6000670de0b6b3a76400006123d96123b08583615152565b6123c290670de0b6b3a76400006151ba565b6123d485670de0b6b3a764000061522e565b6124b3565b6123e3908661522e565b61238e9190615152565b6000818310156123fd5781612391565b5090919050565b6000805a90505b825a612417908361510c565b101561242d5761242682615432565b915061240b565b505050565b6060818051906020012060405160200161244e91815260200190565b6040516020818303038152906040529050919050565b600061248b846124758786866124e4565b8051602091820120825192909101919091201490565b95945050505050565b6000818312156123fd5781612391565b60008183126123fd5781612391565b6000612391670de0b6b3a7640000836124cb86612f6c565b6124d5919061522e565b6124df9190615152565b6131b0565b60606000845111612551576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601560248201527f4d65726b6c65547269653a20656d707479206b657900000000000000000000006044820152606401610544565b600061255c846133ef565b90506000612569866134de565b905060008460405160200161258091815260200190565b60405160208183030381529060405290506000805b8451811015612ee35760008582815181106125b2576125b2615496565b60200260200101519050845183111561264d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f4d65726b6c65547269653a206b657920696e646578206578636565647320746f60448201527f74616c206b6579206c656e6774680000000000000000000000000000000000006064820152608401610544565b82600003612706578051805160209182012060405161269b9261267592910190815260200190565b604051602081830303815290604052858051602091820120825192909101919091201490565b612701576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f4d65726b6c65547269653a20696e76616c696420726f6f7420686173680000006044820152606401610544565b61285d565b8051516020116127bc57805180516020918201206040516127309261267592910190815260200190565b612701576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602760248201527f4d65726b6c65547269653a20696e76616c6964206c6172676520696e7465726e60448201527f616c2068617368000000000000000000000000000000000000000000000000006064820152608401610544565b80518451602080870191909120825191909201201461285d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f4d65726b6c65547269653a20696e76616c696420696e7465726e616c206e6f6460448201527f65206861736800000000000000000000000000000000000000000000000000006064820152608401610544565b6128696010600161547e565b81602001515103612a4a57845183036129e25760006128a5826020015160108151811061289857612898615496565b6020026020010151613679565b90506000815111612938576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603b60248201527f4d65726b6c65547269653a2076616c7565206c656e677468206d75737420626560448201527f2067726561746572207468616e207a65726f20286272616e63682900000000006064820152608401610544565b60018751612946919061510c565b83146129d4576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603a60248201527f4d65726b6c65547269653a2076616c7565206e6f6465206d757374206265206c60448201527f617374206e6f646520696e2070726f6f6620286272616e6368290000000000006064820152608401610544565b965061239195505050505050565b60008584815181106129f6576129f6615496565b602001015160f81c60f81b60f81c9050600082602001518260ff1681518110612a2157612a21615496565b60200260200101519050612a34816137d9565b9550612a4160018661547e565b94505050612ed0565b600281602001515103612e48576000612a62826137fe565b9050600081600081518110612a7957612a79615496565b016020015160f81c90506000612a90600283615589565b612a9b9060026155ab565b90506000612aac848360ff16613822565b90506000612aba8a89613822565b90506000612ac88383613858565b905080835114612b5a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603a60248201527f4d65726b6c65547269653a20706174682072656d61696e646572206d7573742060448201527f736861726520616c6c206e6962626c65732077697468206b65790000000000006064820152608401610544565b60ff851660021480612b6f575060ff85166003145b15612d635780825114612c04576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603d60248201527f4d65726b6c65547269653a206b65792072656d61696e646572206d757374206260448201527f65206964656e746963616c20746f20706174682072656d61696e6465720000006064820152608401610544565b6000612c20886020015160018151811061289857612898615496565b90506000815111612cb3576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603960248201527f4d65726b6c65547269653a2076616c7565206c656e677468206d75737420626560448201527f2067726561746572207468616e207a65726f20286c65616629000000000000006064820152608401610544565b60018d51612cc1919061510c565b8914612d4f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603860248201527f4d65726b6c65547269653a2076616c7565206e6f6465206d757374206265206c60448201527f617374206e6f646520696e2070726f6f6620286c6561662900000000000000006064820152608401610544565b9c506123919b505050505050505050505050565b60ff85161580612d76575060ff85166001145b15612db557612da28760200151600181518110612d9557612d95615496565b60200260200101516137d9565b9950612dae818a61547e565b9850612e3d565b6040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603260248201527f4d65726b6c65547269653a2072656365697665642061206e6f6465207769746860448201527f20616e20756e6b6e6f776e2070726566697800000000000000000000000000006064820152608401610544565b505050505050612ed0565b6040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602860248201527f4d65726b6c65547269653a20726563656976656420616e20756e70617273656160448201527f626c65206e6f64650000000000000000000000000000000000000000000000006064820152608401610544565b5080612edb81615432565b915050612595565b506040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602560248201527f4d65726b6c65547269653a2072616e206f7574206f662070726f6f6620656c6560448201527f6d656e74730000000000000000000000000000000000000000000000000000006064820152608401610544565b6000808213612fd7576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600960248201527f554e444546494e454400000000000000000000000000000000000000000000006044820152606401610544565b60006060612fe484613907565b03609f8181039490941b90931c6c465772b2bbbb5f824b15207a3081018102606090811d6d0388eaa27412d5aca026815d636e018202811d6d0df99ac502031bf953eff472fdcc018202811d6d13cdffb29d51d99322bdff5f2211018202811d6d0a0f742023def783a307a986912e018202811d6d01920d8043ca89b5239253284e42018202811d6c0b7a86d7375468fac667a0a527016c29508e458543d8aa4df2abee7883018302821d6d0139601a2efabe717e604cbb4894018302821d6d02247f7a7b6594320649aa03aba1018302821d7fffffffffffffffffffffffffffffffffffffff73c0c716a594e00d54e3c4cbc9018302821d7ffffffffffffffffffffffffffffffffffffffdc7b88c420e53a9890533129f6f01830290911d7fffffffffffffffffffffffffffffffffffffff465fda27eb4d63ded474e5f832019091027ffffffffffffffff5f6af8f7b3396644f18e157960000000000000000000000000105711340daa0d5f769dba1915cef59f0815a5506027d0267a36c0c95b3975ab3ee5b203a7614a3f75373f047d803ae7b6687f2b393909302929092017d57115e47018c7177eebf7cd370a3356a1b7863008a5ae8028c72b88642840160ae1d92915050565b60007ffffffffffffffffffffffffffffffffffffffffffffffffdb731c958f34d94c182136131e157506000919050565b680755bf798b4a1bf1e58212613253576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600c60248201527f4558505f4f564552464c4f5700000000000000000000000000000000000000006044820152606401610544565b6503782dace9d9604e83901b059150600060606bb17217f7d1cf79abc9e3b39884821b056b80000000000000000000000001901d6bb17217f7d1cf79abc9e3b39881029093037fffffffffffffffffffffffffffffffffffffffdbf3ccf1604d263450f02a550481018102606090811d6d0277594991cfc85f6e2461837cd9018202811d7fffffffffffffffffffffffffffffffffffffe5adedaa1cb095af9e4da10e363c018202811d6db1bbb201f443cf962f1a1d3db4a5018202811d7ffffffffffffffffffffffffffffffffffffd38dc772608b0ae56cce01296c0eb018202811d6e05180bb14799ab47a8a8cb2a527d57016d02d16720577bd19bf614176fe9ea6c10fe68e7fd37d0007b713f765084018402831d9081019084017ffffffffffffffffffffffffffffffffffffffe2c69812cf03b0763fd454a8f7e010290911d6e0587f503bb6ea29d25fcb7401964500190910279d835ebba824c98fb31b83b2ca45c000000000000000000000000010574029d9dc38563c32e5c2f6dc192ee70ef65f9978af30260c3939093039290921c92915050565b805160609060008167ffffffffffffffff81111561340f5761340f614a39565b60405190808252806020026020018201604052801561345457816020015b604080518082019091526060808252602082015281526020019060019003908161342d5790505b50905060005b828110156134d657604051806040016040528086838151811061347f5761347f615496565b602002602001015181526020016134ae8784815181106134a1576134a1615496565b60200260200101516139dd565b8152508282815181106134c3576134c3615496565b602090810291909101015260010161345a565b509392505050565b805160609060006134f082600261538a565b67ffffffffffffffff81111561350857613508614a39565b6040519080825280601f01601f191660200182016040528015613532576020820181803683370190505b5090506000805b8381101561366f5785818151811061355357613553615496565b6020910101517fff000000000000000000000000000000000000000000000000000000000000008116925060041c7f0ff000000000000000000000000000000000000000000000000000000000000016836135af83600261538a565b815181106135bf576135bf615496565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053507f0f0000000000000000000000000000000000000000000000000000000000000082168361361d83600261538a565b61362890600161547e565b8151811061363857613638615496565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a905350600101613539565b5090949350505050565b60606000806000613689856139f0565b9194509250905060008160018111156136a4576136a46155ce565b14613731576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603960248201527f524c505265616465723a206465636f646564206974656d207479706520666f7260448201527f206279746573206973206e6f7420612064617461206974656d000000000000006064820152608401610544565b61373b828461547e565b8551146137ca576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603460248201527f524c505265616465723a2062797465732076616c756520636f6e7461696e732060448201527f616e20696e76616c69642072656d61696e6465720000000000000000000000006064820152608401610544565b61248b8560200151848461445d565b606060208260000151106137f5576137f082613679565b610faf565b610faf826144fe565b6060610faf61381d836020015160008151811061289857612898615496565b6134de565b6060825182106138415750604080516020810190915260008152610faf565b6123918383848651613853919061510c565b614514565b6000806000835185511061386d578351613870565b84515b90505b80821080156138f7575083828151811061388f5761388f615496565b602001015160f81c60f81b7effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff19168583815181106138ce576138ce615496565b01602001517fff0000000000000000000000000000000000000000000000000000000000000016145b156134d657816001019150613873565b6000808211613972576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600960248201527f554e444546494e454400000000000000000000000000000000000000000000006044820152606401610544565b5060016fffffffffffffffffffffffffffffffff821160071b82811c67ffffffffffffffff1060061b1782811c63ffffffff1060051b1782811c61ffff1060041b1782811c60ff10600390811b90911783811c600f1060021b1783811c909110821b1791821c111790565b6060610faf6139eb836146ec565b6147d5565b600080600080846000015111613aae576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604a60248201527f524c505265616465723a206c656e677468206f6620616e20524c50206974656d60448201527f206d7573742062652067726561746572207468616e207a65726f20746f20626560648201527f206465636f6461626c6500000000000000000000000000000000000000000000608482015260a401610544565b6020840151805160001a607f8111613ad3576000600160009450945094505050614456565b60b78111613ce1576000613ae860808361510c565b905080876000015111613ba3576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604e60248201527f524c505265616465723a206c656e677468206f6620636f6e74656e74206d757360448201527f742062652067726561746572207468616e20737472696e67206c656e6774682060648201527f2873686f727420737472696e6729000000000000000000000000000000000000608482015260a401610544565b6001838101517fff00000000000000000000000000000000000000000000000000000000000000169082141580613c1c57507f80000000000000000000000000000000000000000000000000000000000000007fff00000000000000000000000000000000000000000000000000000000000000821610155b613cce576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604d60248201527f524c505265616465723a20696e76616c6964207072656669782c2073696e676c60448201527f652062797465203c203078383020617265206e6f74207072656669786564202860648201527f73686f727420737472696e672900000000000000000000000000000000000000608482015260a401610544565b5060019550935060009250614456915050565b60bf811161402f576000613cf660b78361510c565b905080876000015111613db1576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152605160248201527f524c505265616465723a206c656e677468206f6620636f6e74656e74206d757360448201527f74206265203e207468616e206c656e677468206f6620737472696e67206c656e60648201527f67746820286c6f6e6720737472696e6729000000000000000000000000000000608482015260a401610544565b60018301517fff00000000000000000000000000000000000000000000000000000000000000166000819003613e8f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604a60248201527f524c505265616465723a206c656e677468206f6620636f6e74656e74206d757360448201527f74206e6f74206861766520616e79206c656164696e67207a65726f7320286c6f60648201527f6e6720737472696e672900000000000000000000000000000000000000000000608482015260a401610544565b600184015160088302610100031c60378111613f53576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604860248201527f524c505265616465723a206c656e677468206f6620636f6e74656e74206d757360448201527f742062652067726561746572207468616e20353520627974657320286c6f6e6760648201527f20737472696e6729000000000000000000000000000000000000000000000000608482015260a401610544565b613f5d818461547e565b895111614012576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604c60248201527f524c505265616465723a206c656e677468206f6620636f6e74656e74206d757360448201527f742062652067726561746572207468616e20746f74616c206c656e677468202860648201527f6c6f6e6720737472696e67290000000000000000000000000000000000000000608482015260a401610544565b61401d83600161547e565b97509550600094506144569350505050565b60f7811161411057600061404460c08361510c565b9050808760000151116140ff576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604a60248201527f524c505265616465723a206c656e677468206f6620636f6e74656e74206d757360448201527f742062652067726561746572207468616e206c697374206c656e67746820287360648201527f686f7274206c6973742900000000000000000000000000000000000000000000608482015260a401610544565b600195509350849250614456915050565b600061411d60f78361510c565b9050808760000151116141d8576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604d60248201527f524c505265616465723a206c656e677468206f6620636f6e74656e74206d757360448201527f74206265203e207468616e206c656e677468206f66206c697374206c656e677460648201527f6820286c6f6e67206c6973742900000000000000000000000000000000000000608482015260a401610544565b60018301517fff000000000000000000000000000000000000000000000000000000000000001660008190036142b6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604860248201527f524c505265616465723a206c656e677468206f6620636f6e74656e74206d757360448201527f74206e6f74206861766520616e79206c656164696e67207a65726f7320286c6f60648201527f6e67206c69737429000000000000000000000000000000000000000000000000608482015260a401610544565b600184015160088302610100031c6037811161437a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604660248201527f524c505265616465723a206c656e677468206f6620636f6e74656e74206d757360448201527f742062652067726561746572207468616e20353520627974657320286c6f6e6760648201527f206c697374290000000000000000000000000000000000000000000000000000608482015260a401610544565b614384818461547e565b895111614439576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604a60248201527f524c505265616465723a206c656e677468206f6620636f6e74656e74206d757360448201527f742062652067726561746572207468616e20746f74616c206c656e677468202860648201527f6c6f6e67206c6973742900000000000000000000000000000000000000000000608482015260a401610544565b61444483600161547e565b97509550600194506144569350505050565b9193909250565b606060008267ffffffffffffffff81111561447a5761447a614a39565b6040519080825280601f01601f1916602001820160405280156144a4576020820181803683370190505b509050826000036144b6579050612391565b60006144c2858761547e565b90506020820160005b858110156144e35782810151828201526020016144cb565b858111156144f2576000868301525b50919695505050505050565b6060610faf82602001516000846000015161445d565b60608182601f011015614583576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600e60248201527f736c6963655f6f766572666c6f770000000000000000000000000000000000006044820152606401610544565b8282840110156145ef576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600e60248201527f736c6963655f6f766572666c6f770000000000000000000000000000000000006044820152606401610544565b8183018451101561465c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601160248201527f736c6963655f6f75744f66426f756e64730000000000000000000000000000006044820152606401610544565b60608215801561467b57604051915060008252602082016040526146e3565b6040519150601f8416801560200281840101858101878315602002848b0101015b818310156146b457805183526020928301920161469c565b5050858452601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016604052505b50949350505050565b604080518082019091526000808252602082015260008251116147b7576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604a60248201527f524c505265616465723a206c656e677468206f6620616e20524c50206974656d60448201527f206d7573742062652067726561746572207468616e207a65726f20746f20626560648201527f206465636f6461626c6500000000000000000000000000000000000000000000608482015260a401610544565b50604080518082019091528151815260209182019181019190915290565b606060008060006147e5856139f0565b919450925090506001816001811115614800576148006155ce565b1461488d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603860248201527f524c505265616465723a206465636f646564206974656d207479706520666f7260448201527f206c697374206973206e6f742061206c697374206974656d00000000000000006064820152608401610544565b8451614899838561547e565b14614926576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603260248201527f524c505265616465723a206c697374206974656d2068617320616e20696e766160448201527f6c696420646174612072656d61696e64657200000000000000000000000000006064820152608401610544565b6040805160208082526104208201909252600091816020015b604080518082019091526000808252602082015281526020019060019003908161493f5790505090506000845b8751811015614a2d576000806149b26040518060400160405280858d60000151614996919061510c565b8152602001858d602001516149ab919061547e565b90526139f0565b5091509150604051806040016040528083836149ce919061547e565b8152602001848c602001516149e3919061547e565b8152508585815181106149f8576149f8615496565b6020908102919091010152614a0e60018561547e565b9350614a1a818361547e565b614a24908461547e565b9250505061496c565b50815295945050505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff81118282101715614aaf57614aaf614a39565b604052919050565b803573ffffffffffffffffffffffffffffffffffffffff81168114614adb57600080fd5b919050565b600082601f830112614af157600080fd5b813567ffffffffffffffff811115614b0b57614b0b614a39565b614b3c60207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f84011601614a68565b818152846020838601011115614b5157600080fd5b816020850160208301376000918101602001919091529392505050565b600060c08284031215614b8057600080fd5b60405160c0810167ffffffffffffffff8282108183111715614ba457614ba4614a39565b8160405282935084358352614bbb60208601614ab7565b6020840152614bcc60408601614ab7565b6040840152606085013560608401526080850135608084015260a0850135915080821115614bf957600080fd5b50614c0685828601614ae0565b60a0830152505092915050565b600080600080600085870360e0811215614c2c57600080fd5b863567ffffffffffffffff80821115614c4457600080fd5b614c508a838b01614b6e565b97506020890135965060807fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc084011215614c8957600080fd5b60408901955060c0890135925080831115614ca357600080fd5b828901925089601f840112614cb757600080fd5b8235915080821115614cc857600080fd5b508860208260051b8401011115614cde57600080fd5b959894975092955050506020019190565b60005b83811015614d0a578181015183820152602001614cf2565b83811115614d19576000848401525b50505050565b60008151808452614d37816020860160208601614cef565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b6020815260006123916020830184614d1f565b600060208284031215614d8e57600080fd5b5035919050565b600060208284031215614da757600080fd5b813567ffffffffffffffff811115614dbe57600080fd5b6120cb84828501614b6e565b80358015158114614adb57600080fd5b600060208284031215614dec57600080fd5b61239182614dca565b600080600080600060a08688031215614e0d57600080fd5b614e1686614ab7565b945060208601359350604086013567ffffffffffffffff8082168214614e3b57600080fd5b819450614e4a60608901614dca565b93506080880135915080821115614e6057600080fd5b50614e6d88828901614ae0565b9150509295509295909350565b8581528460208201527fffffffffffffffff0000000000000000000000000000000000000000000000008460c01b16604082015282151560f81b604882015260008251614ece816049850160208701614cef565b919091016049019695505050505050565b80516fffffffffffffffffffffffffffffffff81168114614adb57600080fd5b600060608284031215614f1157600080fd5b6040516060810181811067ffffffffffffffff82111715614f3457614f34614a39565b60405282518152614f4760208401614edf565b6020820152614f5860408401614edf565b60408201529392505050565b600060808284031215614f7657600080fd5b6040516080810181811067ffffffffffffffff82111715614f9957614f99614a39565b8060405250823581526020830135602082015260408301356040820152606083013560608201528091505092915050565b600067ffffffffffffffff80841115614fe557614fe5614a39565b8360051b6020614ff6818301614a68565b86815291850191818101903684111561500e57600080fd5b865b84811015615042578035868111156150285760008081fd5b61503436828b01614ae0565b845250918301918301615010565b50979650505050505050565b60008451615060818460208901614cef565b80830190507f2e00000000000000000000000000000000000000000000000000000000000000808252855161509c816001850160208a01614cef565b600192019182015283516150b7816002840160208801614cef565b0160020195945050505050565b6000602082840312156150d657600080fd5b5051919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60008282101561511e5761511e6150dd565b500390565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b60008261516157615161615123565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff83147f8000000000000000000000000000000000000000000000000000000000000000831416156151b5576151b56150dd565b500590565b6000808312837f8000000000000000000000000000000000000000000000000000000000000000018312811516156151f4576151f46150dd565b837f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff018313811615615228576152286150dd565b50500390565b60007f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff60008413600084138583048511828216161561526f5761526f6150dd565b7f800000000000000000000000000000000000000000000000000000000000000060008712868205881281841616156152aa576152aa6150dd565b600087129250878205871284841616156152c6576152c66150dd565b878505871281841616156152dc576152dc6150dd565b505050929093029392505050565b6000808212827f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff03841381151615615324576153246150dd565b827f8000000000000000000000000000000000000000000000000000000000000000038412811615615358576153586150dd565b50500190565b600067ffffffffffffffff808316818516808303821115615381576153816150dd565b01949350505050565b6000817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff04831182151516156153c2576153c26150dd565b500290565b6000826153d6576153d6615123565b500490565b868152600073ffffffffffffffffffffffffffffffffffffffff808816602084015280871660408401525084606083015283608083015260c060a083015261542660c0830184614d1f565b98975050505050505050565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203615463576154636150dd565b5060010190565b60008261547957615479615123565b500690565b60008219821115615491576154916150dd565b500190565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b805163ffffffff81168114614adb57600080fd5b805160ff81168114614adb57600080fd5b600060c082840312156154fc57600080fd5b60405160c0810181811067ffffffffffffffff8211171561551f5761551f614a39565b60405261552b836154c5565b8152615539602084016154d9565b602082015261554a604084016154d9565b604082015261555b606084016154c5565b606082015261556c608084016154c5565b608082015261557d60a08401614edf565b60a08201529392505050565b600060ff83168061559c5761559c615123565b8060ff84160691505092915050565b600060ff821660ff8416808210156155c5576155c56150dd565b90039392505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fdfea164736f6c634300080f000a"
var OptimismPortalDeployedBin = "0x6080604052600436106101115760003560e01c80638b4c40b0116100a5578063cff0ab9611610074578063e965084c11610059578063e965084c146103c3578063e9e05c421461044f578063f04987501461046257600080fd5b8063cff0ab9614610302578063d53a822f146103a357600080fd5b80638b4c40b0146101365780638c3152e9146102855780639bf62d82146102a5578063a14238e7146102d257600080fd5b80635c975abb116100e15780635c975abb146101f25780636dbffb781461021c578063724c184c1461023c5780638456cb591461027057600080fd5b80621c2ff61461013d5780633f4ba83a1461019b5780634870496f146101b057806354fd4d50146101d057600080fd5b36610138576101363334620186a0600060405180602001604052806000815250610496565b005b600080fd5b34801561014957600080fd5b506101717f000000000000000000000000000000000000000000000000000000000000000081565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020015b60405180910390f35b3480156101a757600080fd5b506101366106b2565b3480156101bc57600080fd5b506101366101cb366004614c32565b6107d5565b3480156101dc57600080fd5b506101e5610e3b565b6040516101929190614d88565b3480156101fe57600080fd5b5060355461020c9060ff1681565b6040519015158152602001610192565b34801561022857600080fd5b5061020c610237366004614d9b565b610ede565b34801561024857600080fd5b506101717f000000000000000000000000000000000000000000000000000000000000000081565b34801561027c57600080fd5b50610136610fb5565b34801561029157600080fd5b506101366102a0366004614db4565b6110d5565b3480156102b157600080fd5b506032546101719073ffffffffffffffffffffffffffffffffffffffff1681565b3480156102de57600080fd5b5061020c6102ed366004614d9b565b60336020526000908152604090205460ff1681565b34801561030e57600080fd5b5060015461036a906fffffffffffffffffffffffffffffffff81169067ffffffffffffffff7001000000000000000000000000000000008204811691780100000000000000000000000000000000000000000000000090041683565b604080516fffffffffffffffffffffffffffffffff909416845267ffffffffffffffff9283166020850152911690820152606001610192565b3480156103af57600080fd5b506101366103be366004614df9565b6119b0565b3480156103cf57600080fd5b506104216103de366004614d9b565b603460205260009081526040902080546001909101546fffffffffffffffffffffffffffffffff8082169170010000000000000000000000000000000090041683565b604080519384526fffffffffffffffffffffffffffffffff9283166020850152911690820152606001610192565b61013661045d366004614e14565b610496565b34801561046e57600080fd5b506101717f000000000000000000000000000000000000000000000000000000000000000081565b8260005a9050831561054d5773ffffffffffffffffffffffffffffffffffffffff87161561054d57604080517f08c379a00000000000000000000000000000000000000000000000000000000081526020600482015260248101919091527f4f7074696d69736d506f7274616c3a206d7573742073656e6420746f2061646460448201527f72657373283029207768656e206372656174696e67206120636f6e747261637460648201526084015b60405180910390fd5b6152088567ffffffffffffffff1610156105e9576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603860248201527f4f7074696d69736d506f7274616c3a20676173206c696d6974206d757374206360448201527f6f76657220696e737472696e7369632067617320636f737400000000000000006064820152608401610544565b3332811461060a575033731111000000000000000000000000000000001111015b60003488888888604051602001610625959493929190614e99565b604051602081830303815290604052905060008973ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff167fb3813568d9991fc951961fcb4c784893574240a28925604d09fc577c55bb7c32846040516106959190614d88565b60405180910390a450506106a98282611bb9565b50505050505050565b3373ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000001614610777576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602960248201527f4f7074696d69736d506f7274616c3a206f6e6c7920677561726469616e20636160448201527f6e20756e706175736500000000000000000000000000000000000000000000006064820152608401610544565b603580547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001690556040513381527f5db9ee0a495bf2e6ff9c91a7834c1ba4fdd244a5e8aa4e537bd38aeae4b073aa906020015b60405180910390a1565b60355460ff1615610842576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4f7074696d69736d506f7274616c3a20706175736564000000000000000000006044820152606401610544565b3073ffffffffffffffffffffffffffffffffffffffff16856040015173ffffffffffffffffffffffffffffffffffffffff1603610901576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603f60248201527f4f7074696d69736d506f7274616c3a20796f752063616e6e6f742073656e642060448201527f6d6573736167657320746f2074686520706f7274616c20636f6e7472616374006064820152608401610544565b6040517fa25ae557000000000000000000000000000000000000000000000000000000008152600481018590526000907f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff169063a25ae55790602401606060405180830381865afa15801561098f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906109b39190614f1e565b5190506109cd6109c836869003860186614f83565b611ee6565b8114610a5b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602960248201527f4f7074696d69736d506f7274616c3a20696e76616c6964206f7574707574207260448201527f6f6f742070726f6f6600000000000000000000000000000000000000000000006064820152608401610544565b6000610a6687611f42565b6000818152603460209081526040918290208251606081018452815481526001909101546fffffffffffffffffffffffffffffffff8082169383018490527001000000000000000000000000000000009091041692810192909252919250901580610b985750805160408083015190517fa25ae5570000000000000000000000000000000000000000000000000000000081526fffffffffffffffffffffffffffffffff90911660048201527f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff169063a25ae55790602401606060405180830381865afa158015610b70573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610b949190614f1e565b5114155b610c24576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603760248201527f4f7074696d69736d506f7274616c3a207769746864726177616c20686173682060448201527f68617320616c7265616479206265656e2070726f76656e0000000000000000006064820152608401610544565b60408051602081018490526000918101829052606001604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe081840301815282825280516020918201209083018190529250610ced9101604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0818403018152828201909152600182527f0100000000000000000000000000000000000000000000000000000000000000602083015290610ce3888a614fe9565b8a60400135611f72565b610d79576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603260248201527f4f7074696d69736d506f7274616c3a20696e76616c696420776974686472617760448201527f616c20696e636c7573696f6e2070726f6f6600000000000000000000000000006064820152608401610544565b604080516060810182528581526fffffffffffffffffffffffffffffffff42811660208084019182528c831684860190815260008981526034835286812095518655925190518416700100000000000000000000000000000000029316929092176001909301929092558b830151908c0151925173ffffffffffffffffffffffffffffffffffffffff918216939091169186917f67a6208cfcc0801d50f6cbe764733f4fddf66ac0b04442061a8a8c0cb6b63f629190a4505050505050505050565b6060610e667f0000000000000000000000000000000000000000000000000000000000000000611f96565b610e8f7f0000000000000000000000000000000000000000000000000000000000000000611f96565b610eb87f0000000000000000000000000000000000000000000000000000000000000000611f96565b604051602001610eca9392919061506d565b604051602081830303815290604052905090565b6040517fa25ae55700000000000000000000000000000000000000000000000000000000815260048101829052600090610faf9073ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000169063a25ae55790602401606060405180830381865afa158015610f70573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610f949190614f1e565b602001516fffffffffffffffffffffffffffffffff166120d3565b92915050565b3373ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000161461107a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602760248201527f4f7074696d69736d506f7274616c3a206f6e6c7920677561726469616e20636160448201527f6e207061757365000000000000000000000000000000000000000000000000006064820152608401610544565b603580547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660011790556040513381527f62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a258906020016107cb565b60355460ff1615611142576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4f7074696d69736d506f7274616c3a20706175736564000000000000000000006044820152606401610544565b60325473ffffffffffffffffffffffffffffffffffffffff1661dead146111eb576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603f60248201527f4f7074696d69736d506f7274616c3a2063616e206f6e6c79207472696767657260448201527f206f6e65207769746864726177616c20706572207472616e73616374696f6e006064820152608401610544565b60006111f682611f42565b60008181526034602090815260408083208151606081018352815481526001909101546fffffffffffffffffffffffffffffffff808216948301859052700100000000000000000000000000000000909104169181019190915292935090036112e1576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603260248201527f4f7074696d69736d506f7274616c3a207769746864726177616c20686173206e60448201527f6f74206265656e2070726f76656e2079657400000000000000000000000000006064820152608401610544565b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663887862726040518163ffffffff1660e01b8152600401602060405180830381865afa15801561134c573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061137091906150e3565b81602001516fffffffffffffffffffffffffffffffff16101561143b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604b60248201527f4f7074696d69736d506f7274616c3a207769746864726177616c2074696d657360448201527f74616d70206c657373207468616e204c32204f7261636c65207374617274696e60648201527f672074696d657374616d70000000000000000000000000000000000000000000608482015260a401610544565b61145a81602001516fffffffffffffffffffffffffffffffff166120d3565b61150c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604560248201527f4f7074696d69736d506f7274616c3a2070726f76656e2077697468647261776160448201527f6c2066696e616c697a6174696f6e20706572696f6420686173206e6f7420656c60648201527f6170736564000000000000000000000000000000000000000000000000000000608482015260a401610544565b60408181015190517fa25ae5570000000000000000000000000000000000000000000000000000000081526fffffffffffffffffffffffffffffffff90911660048201526000907f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff169063a25ae55790602401606060405180830381865afa1580156115b1573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906115d59190614f1e565b825181519192501461168f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604960248201527f4f7074696d69736d506f7274616c3a206f757470757420726f6f742070726f7660448201527f656e206973206e6f74207468652073616d652061732063757272656e74206f7560648201527f7470757420726f6f740000000000000000000000000000000000000000000000608482015260a401610544565b6116ae81602001516fffffffffffffffffffffffffffffffff166120d3565b611760576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604360248201527f4f7074696d69736d506f7274616c3a206f75747075742070726f706f73616c2060448201527f66696e616c697a6174696f6e20706572696f6420686173206e6f7420656c617060648201527f7365640000000000000000000000000000000000000000000000000000000000608482015260a401610544565b60008381526033602052604090205460ff16156117ff576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603560248201527f4f7074696d69736d506f7274616c3a207769746864726177616c20686173206160448201527f6c7265616479206265656e2066696e616c697a656400000000000000000000006064820152608401610544565b600083815260336020908152604080832080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001179055908601516032805473ffffffffffffffffffffffffffffffffffffffff9092167fffffffffffffffffffffffff00000000000000000000000000000000000000009092169190911790558501516080860151606087015160a08801516118a193929190612176565b603280547fffffffffffffffffffffffff00000000000000000000000000000000000000001661dead17905560405190915084907fdb5c7652857aa163daadd670e116628fb42e869d8ac4251ef8971d9e5727df1b9061190690841515815260200190565b60405180910390a28015801561191c5750326001145b156119a9576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602160248201527f4f7074696d69736d506f7274616c3a207769746864726177616c206661696c6560448201527f64000000000000000000000000000000000000000000000000000000000000006064820152608401610544565b5050505050565b600054610100900460ff16158080156119d05750600054600160ff909116105b806119ea5750303b1580156119ea575060005460ff166001145b611a76576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a65640000000000000000000000000000000000006064820152608401610544565b600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660011790558015611ad457600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff166101001790555b603280547fffffffffffffffffffffffff00000000000000000000000000000000000000001661dead179055603580548315157fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00909116179055611b366121d4565b8015611b9957600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b5050565b73ffffffffffffffffffffffffffffffffffffffff163b151590565b600154600090611bef907801000000000000000000000000000000000000000000000000900467ffffffffffffffff164361512b565b90506000611bfb6122b7565b90506000816020015160ff16826000015163ffffffff16611c1c9190615171565b90508215611d5357600154600090611c53908390700100000000000000000000000000000000900467ffffffffffffffff166151d9565b90506000836040015160ff1683611c6a919061524d565b600154611c8a9084906fffffffffffffffffffffffffffffffff1661524d565b611c949190615171565b600154909150600090611ce590611cbe9084906fffffffffffffffffffffffffffffffff16615309565b866060015163ffffffff168760a001516fffffffffffffffffffffffffffffffff1661237d565b90506001861115611d1457611d11611cbe82876040015160ff1660018a611d0c919061512b565b61239c565b90505b6fffffffffffffffffffffffffffffffff16780100000000000000000000000000000000000000000000000067ffffffffffffffff4316021760015550505b60018054869190601090611d86908490700100000000000000000000000000000000900467ffffffffffffffff1661537d565b92506101000a81548167ffffffffffffffff021916908367ffffffffffffffff160217905550816000015163ffffffff16600160000160109054906101000a900467ffffffffffffffff1667ffffffffffffffff161315611e69576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603e60248201527f5265736f757263654d65746572696e673a2063616e6e6f7420627579206d6f7260448201527f6520676173207468616e20617661696c61626c6520676173206c696d697400006064820152608401610544565b600154600090611e95906fffffffffffffffffffffffffffffffff1667ffffffffffffffff88166153a9565b90506000611ea748633b9aca006123f1565b611eb190836153e6565b905060005a611ec0908861512b565b905080821115611edc57611edc611ed7828461512b565b612408565b5050505050505050565b60008160000151826020015183604001518460600151604051602001611f25949392919093845260208401929092526040830152606082015260800190565b604051602081830303815290604052805190602001209050919050565b80516020808301516040808501516060860151608087015160a08801519351600097611f259790969591016153fa565b600080611f7e86612436565b9050611f8c81868686612468565b9695505050505050565b606081600003611fd957505060408051808201909152600181527f3000000000000000000000000000000000000000000000000000000000000000602082015290565b8160005b81156120035780611fed81615451565b9150611ffc9050600a836153e6565b9150611fdd565b60008167ffffffffffffffff81111561201e5761201e614a58565b6040519080825280601f01601f191660200182016040528015612048576020820181803683370190505b5090505b84156120cb5761205d60018361512b565b915061206a600a86615489565b61207590603061549d565b60f81b81838151811061208a5761208a6154b5565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053506120c4600a866153e6565b945061204c565b949350505050565b60007f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663f4daa2916040518163ffffffff1660e01b8152600401602060405180830381865afa158015612140573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061216491906150e3565b61216e908361549d565b421192915050565b6000806000612186866000612498565b9050806121bc576308c379a06000526020805278185361666543616c6c3a204e6f7420656e6f756768206761736058526064601cfd5b600080855160208701888b5af1979650505050505050565b600054610100900460ff1661226b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e670000000000000000000000000000000000000000006064820152608401610544565b60408051606081018252633b9aca00808252600060208301524367ffffffffffffffff169190920181905278010000000000000000000000000000000000000000000000000217600155565b6040805160c081018252600080825260208201819052918101829052606081018290526080810182905260a08101919091527f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663cc731b026040518163ffffffff1660e01b815260040160c060405180830381865afa158015612354573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906123789190615509565b905090565b600061239261238c85856124b3565b836124c3565b90505b9392505050565b6000670de0b6b3a76400006123dd6123b48583615171565b6123c690670de0b6b3a76400006151d9565b6123d885670de0b6b3a764000061524d565b6124d2565b6123e7908661524d565b6123929190615171565b6000818310156124015781612395565b5090919050565b6000805a90505b825a61241b908361512b565b10156124315761242a82615451565b915061240f565b505050565b6060818051906020012060405160200161245291815260200190565b6040516020818303038152906040529050919050565b600061248f84612479878686612503565b8051602091820120825192909101919091201490565b95945050505050565b60008082619c4001603f6040860204015a1015949350505050565b6000818312156124015781612395565b60008183126124015781612395565b6000612395670de0b6b3a7640000836124ea86612f8b565b6124f4919061524d565b6124fe9190615171565b6131cf565b60606000845111612570576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601560248201527f4d65726b6c65547269653a20656d707479206b657900000000000000000000006044820152606401610544565b600061257b8461340e565b90506000612588866134fd565b905060008460405160200161259f91815260200190565b60405160208183030381529060405290506000805b8451811015612f025760008582815181106125d1576125d16154b5565b60200260200101519050845183111561266c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f4d65726b6c65547269653a206b657920696e646578206578636565647320746f60448201527f74616c206b6579206c656e6774680000000000000000000000000000000000006064820152608401610544565b8260000361272557805180516020918201206040516126ba9261269492910190815260200190565b604051602081830303815290604052858051602091820120825192909101919091201490565b612720576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f4d65726b6c65547269653a20696e76616c696420726f6f7420686173680000006044820152606401610544565b61287c565b8051516020116127db578051805160209182012060405161274f9261269492910190815260200190565b612720576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602760248201527f4d65726b6c65547269653a20696e76616c6964206c6172676520696e7465726e60448201527f616c2068617368000000000000000000000000000000000000000000000000006064820152608401610544565b80518451602080870191909120825191909201201461287c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f4d65726b6c65547269653a20696e76616c696420696e7465726e616c206e6f6460448201527f65206861736800000000000000000000000000000000000000000000000000006064820152608401610544565b6128886010600161549d565b81602001515103612a695784518303612a015760006128c482602001516010815181106128b7576128b76154b5565b6020026020010151613698565b90506000815111612957576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603b60248201527f4d65726b6c65547269653a2076616c7565206c656e677468206d75737420626560448201527f2067726561746572207468616e207a65726f20286272616e63682900000000006064820152608401610544565b60018751612965919061512b565b83146129f3576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603a60248201527f4d65726b6c65547269653a2076616c7565206e6f6465206d757374206265206c60448201527f617374206e6f646520696e2070726f6f6620286272616e6368290000000000006064820152608401610544565b965061239595505050505050565b6000858481518110612a1557612a156154b5565b602001015160f81c60f81b60f81c9050600082602001518260ff1681518110612a4057612a406154b5565b60200260200101519050612a53816137f8565b9550612a6060018661549d565b94505050612eef565b600281602001515103612e67576000612a818261381d565b9050600081600081518110612a9857612a986154b5565b016020015160f81c90506000612aaf6002836155a8565b612aba9060026155ca565b90506000612acb848360ff16613841565b90506000612ad98a89613841565b90506000612ae78383613877565b905080835114612b79576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603a60248201527f4d65726b6c65547269653a20706174682072656d61696e646572206d7573742060448201527f736861726520616c6c206e6962626c65732077697468206b65790000000000006064820152608401610544565b60ff851660021480612b8e575060ff85166003145b15612d825780825114612c23576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603d60248201527f4d65726b6c65547269653a206b65792072656d61696e646572206d757374206260448201527f65206964656e746963616c20746f20706174682072656d61696e6465720000006064820152608401610544565b6000612c3f88602001516001815181106128b7576128b76154b5565b90506000815111612cd2576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603960248201527f4d65726b6c65547269653a2076616c7565206c656e677468206d75737420626560448201527f2067726561746572207468616e207a65726f20286c65616629000000000000006064820152608401610544565b60018d51612ce0919061512b565b8914612d6e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603860248201527f4d65726b6c65547269653a2076616c7565206e6f6465206d757374206265206c60448201527f617374206e6f646520696e2070726f6f6620286c6561662900000000000000006064820152608401610544565b9c506123959b505050505050505050505050565b60ff85161580612d95575060ff85166001145b15612dd457612dc18760200151600181518110612db457612db46154b5565b60200260200101516137f8565b9950612dcd818a61549d565b9850612e5c565b6040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603260248201527f4d65726b6c65547269653a2072656365697665642061206e6f6465207769746860448201527f20616e20756e6b6e6f776e2070726566697800000000000000000000000000006064820152608401610544565b505050505050612eef565b6040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602860248201527f4d65726b6c65547269653a20726563656976656420616e20756e70617273656160448201527f626c65206e6f64650000000000000000000000000000000000000000000000006064820152608401610544565b5080612efa81615451565b9150506125b4565b506040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602560248201527f4d65726b6c65547269653a2072616e206f7574206f662070726f6f6620656c6560448201527f6d656e74730000000000000000000000000000000000000000000000000000006064820152608401610544565b6000808213612ff6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600960248201527f554e444546494e454400000000000000000000000000000000000000000000006044820152606401610544565b6000606061300384613926565b03609f8181039490941b90931c6c465772b2bbbb5f824b15207a3081018102606090811d6d0388eaa27412d5aca026815d636e018202811d6d0df99ac502031bf953eff472fdcc018202811d6d13cdffb29d51d99322bdff5f2211018202811d6d0a0f742023def783a307a986912e018202811d6d01920d8043ca89b5239253284e42018202811d6c0b7a86d7375468fac667a0a527016c29508e458543d8aa4df2abee7883018302821d6d0139601a2efabe717e604cbb4894018302821d6d02247f7a7b6594320649aa03aba1018302821d7fffffffffffffffffffffffffffffffffffffff73c0c716a594e00d54e3c4cbc9018302821d7ffffffffffffffffffffffffffffffffffffffdc7b88c420e53a9890533129f6f01830290911d7fffffffffffffffffffffffffffffffffffffff465fda27eb4d63ded474e5f832019091027ffffffffffffffff5f6af8f7b3396644f18e157960000000000000000000000000105711340daa0d5f769dba1915cef59f0815a5506027d0267a36c0c95b3975ab3ee5b203a7614a3f75373f047d803ae7b6687f2b393909302929092017d57115e47018c7177eebf7cd370a3356a1b7863008a5ae8028c72b88642840160ae1d92915050565b60007ffffffffffffffffffffffffffffffffffffffffffffffffdb731c958f34d94c1821361320057506000919050565b680755bf798b4a1bf1e58212613272576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600c60248201527f4558505f4f564552464c4f5700000000000000000000000000000000000000006044820152606401610544565b6503782dace9d9604e83901b059150600060606bb17217f7d1cf79abc9e3b39884821b056b80000000000000000000000001901d6bb17217f7d1cf79abc9e3b39881029093037fffffffffffffffffffffffffffffffffffffffdbf3ccf1604d263450f02a550481018102606090811d6d0277594991cfc85f6e2461837cd9018202811d7fffffffffffffffffffffffffffffffffffffe5adedaa1cb095af9e4da10e363c018202811d6db1bbb201f443cf962f1a1d3db4a5018202811d7ffffffffffffffffffffffffffffffffffffd38dc772608b0ae56cce01296c0eb018202811d6e05180bb14799ab47a8a8cb2a527d57016d02d16720577bd19bf614176fe9ea6c10fe68e7fd37d0007b713f765084018402831d9081019084017ffffffffffffffffffffffffffffffffffffffe2c69812cf03b0763fd454a8f7e010290911d6e0587f503bb6ea29d25fcb7401964500190910279d835ebba824c98fb31b83b2ca45c000000000000000000000000010574029d9dc38563c32e5c2f6dc192ee70ef65f9978af30260c3939093039290921c92915050565b805160609060008167ffffffffffffffff81111561342e5761342e614a58565b60405190808252806020026020018201604052801561347357816020015b604080518082019091526060808252602082015281526020019060019003908161344c5790505b50905060005b828110156134f557604051806040016040528086838151811061349e5761349e6154b5565b602002602001015181526020016134cd8784815181106134c0576134c06154b5565b60200260200101516139fc565b8152508282815181106134e2576134e26154b5565b6020908102919091010152600101613479565b509392505050565b8051606090600061350f8260026153a9565b67ffffffffffffffff81111561352757613527614a58565b6040519080825280601f01601f191660200182016040528015613551576020820181803683370190505b5090506000805b8381101561368e57858181518110613572576135726154b5565b6020910101517fff000000000000000000000000000000000000000000000000000000000000008116925060041c7f0ff000000000000000000000000000000000000000000000000000000000000016836135ce8360026153a9565b815181106135de576135de6154b5565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053507f0f0000000000000000000000000000000000000000000000000000000000000082168361363c8360026153a9565b61364790600161549d565b81518110613657576136576154b5565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a905350600101613558565b5090949350505050565b606060008060006136a885613a0f565b9194509250905060008160018111156136c3576136c36155ed565b14613750576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603960248201527f524c505265616465723a206465636f646564206974656d207479706520666f7260448201527f206279746573206973206e6f7420612064617461206974656d000000000000006064820152608401610544565b61375a828461549d565b8551146137e9576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603460248201527f524c505265616465723a2062797465732076616c756520636f6e7461696e732060448201527f616e20696e76616c69642072656d61696e6465720000000000000000000000006064820152608401610544565b61248f8560200151848461447c565b606060208260000151106138145761380f82613698565b610faf565b610faf8261451d565b6060610faf61383c83602001516000815181106128b7576128b76154b5565b6134fd565b6060825182106138605750604080516020810190915260008152610faf565b6123958383848651613872919061512b565b614533565b6000806000835185511061388c57835161388f565b84515b90505b808210801561391657508382815181106138ae576138ae6154b5565b602001015160f81c60f81b7effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff19168583815181106138ed576138ed6154b5565b01602001517fff0000000000000000000000000000000000000000000000000000000000000016145b156134f557816001019150613892565b6000808211613991576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600960248201527f554e444546494e454400000000000000000000000000000000000000000000006044820152606401610544565b5060016fffffffffffffffffffffffffffffffff821160071b82811c67ffffffffffffffff1060061b1782811c63ffffffff1060051b1782811c61ffff1060041b1782811c60ff10600390811b90911783811c600f1060021b1783811c909110821b1791821c111790565b6060610faf613a0a8361470b565b6147f4565b600080600080846000015111613acd576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604a60248201527f524c505265616465723a206c656e677468206f6620616e20524c50206974656d60448201527f206d7573742062652067726561746572207468616e207a65726f20746f20626560648201527f206465636f6461626c6500000000000000000000000000000000000000000000608482015260a401610544565b6020840151805160001a607f8111613af2576000600160009450945094505050614475565b60b78111613d00576000613b0760808361512b565b905080876000015111613bc2576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604e60248201527f524c505265616465723a206c656e677468206f6620636f6e74656e74206d757360448201527f742062652067726561746572207468616e20737472696e67206c656e6774682060648201527f2873686f727420737472696e6729000000000000000000000000000000000000608482015260a401610544565b6001838101517fff00000000000000000000000000000000000000000000000000000000000000169082141580613c3b57507f80000000000000000000000000000000000000000000000000000000000000007fff00000000000000000000000000000000000000000000000000000000000000821610155b613ced576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604d60248201527f524c505265616465723a20696e76616c6964207072656669782c2073696e676c60448201527f652062797465203c203078383020617265206e6f74207072656669786564202860648201527f73686f727420737472696e672900000000000000000000000000000000000000608482015260a401610544565b5060019550935060009250614475915050565b60bf811161404e576000613d1560b78361512b565b905080876000015111613dd0576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152605160248201527f524c505265616465723a206c656e677468206f6620636f6e74656e74206d757360448201527f74206265203e207468616e206c656e677468206f6620737472696e67206c656e60648201527f67746820286c6f6e6720737472696e6729000000000000000000000000000000608482015260a401610544565b60018301517fff00000000000000000000000000000000000000000000000000000000000000166000819003613eae576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604a60248201527f524c505265616465723a206c656e677468206f6620636f6e74656e74206d757360448201527f74206e6f74206861766520616e79206c656164696e67207a65726f7320286c6f60648201527f6e6720737472696e672900000000000000000000000000000000000000000000608482015260a401610544565b600184015160088302610100031c60378111613f72576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604860248201527f524c505265616465723a206c656e677468206f6620636f6e74656e74206d757360448201527f742062652067726561746572207468616e20353520627974657320286c6f6e6760648201527f20737472696e6729000000000000000000000000000000000000000000000000608482015260a401610544565b613f7c818461549d565b895111614031576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604c60248201527f524c505265616465723a206c656e677468206f6620636f6e74656e74206d757360448201527f742062652067726561746572207468616e20746f74616c206c656e677468202860648201527f6c6f6e6720737472696e67290000000000000000000000000000000000000000608482015260a401610544565b61403c83600161549d565b97509550600094506144759350505050565b60f7811161412f57600061406360c08361512b565b90508087600001511161411e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604a60248201527f524c505265616465723a206c656e677468206f6620636f6e74656e74206d757360448201527f742062652067726561746572207468616e206c697374206c656e67746820287360648201527f686f7274206c6973742900000000000000000000000000000000000000000000608482015260a401610544565b600195509350849250614475915050565b600061413c60f78361512b565b9050808760000151116141f7576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604d60248201527f524c505265616465723a206c656e677468206f6620636f6e74656e74206d757360448201527f74206265203e207468616e206c656e677468206f66206c697374206c656e677460648201527f6820286c6f6e67206c6973742900000000000000000000000000000000000000608482015260a401610544565b60018301517fff000000000000000000000000000000000000000000000000000000000000001660008190036142d5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604860248201527f524c505265616465723a206c656e677468206f6620636f6e74656e74206d757360448201527f74206e6f74206861766520616e79206c656164696e67207a65726f7320286c6f60648201527f6e67206c69737429000000000000000000000000000000000000000000000000608482015260a401610544565b600184015160088302610100031c60378111614399576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604660248201527f524c505265616465723a206c656e677468206f6620636f6e74656e74206d757360448201527f742062652067726561746572207468616e20353520627974657320286c6f6e6760648201527f206c697374290000000000000000000000000000000000000000000000000000608482015260a401610544565b6143a3818461549d565b895111614458576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604a60248201527f524c505265616465723a206c656e677468206f6620636f6e74656e74206d757360448201527f742062652067726561746572207468616e20746f74616c206c656e677468202860648201527f6c6f6e67206c6973742900000000000000000000000000000000000000000000608482015260a401610544565b61446383600161549d565b97509550600194506144759350505050565b9193909250565b606060008267ffffffffffffffff81111561449957614499614a58565b6040519080825280601f01601f1916602001820160405280156144c3576020820181803683370190505b509050826000036144d5579050612395565b60006144e1858761549d565b90506020820160005b858110156145025782810151828201526020016144ea565b85811115614511576000868301525b50919695505050505050565b6060610faf82602001516000846000015161447c565b60608182601f0110156145a2576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600e60248201527f736c6963655f6f766572666c6f770000000000000000000000000000000000006044820152606401610544565b82828401101561460e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600e60248201527f736c6963655f6f766572666c6f770000000000000000000000000000000000006044820152606401610544565b8183018451101561467b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601160248201527f736c6963655f6f75744f66426f756e64730000000000000000000000000000006044820152606401610544565b60608215801561469a5760405191506000825260208201604052614702565b6040519150601f8416801560200281840101858101878315602002848b0101015b818310156146d35780518352602092830192016146bb565b5050858452601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016604052505b50949350505050565b604080518082019091526000808252602082015260008251116147d6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604a60248201527f524c505265616465723a206c656e677468206f6620616e20524c50206974656d60448201527f206d7573742062652067726561746572207468616e207a65726f20746f20626560648201527f206465636f6461626c6500000000000000000000000000000000000000000000608482015260a401610544565b50604080518082019091528151815260209182019181019190915290565b6060600080600061480485613a0f565b91945092509050600181600181111561481f5761481f6155ed565b146148ac576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603860248201527f524c505265616465723a206465636f646564206974656d207479706520666f7260448201527f206c697374206973206e6f742061206c697374206974656d00000000000000006064820152608401610544565b84516148b8838561549d565b14614945576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603260248201527f524c505265616465723a206c697374206974656d2068617320616e20696e766160448201527f6c696420646174612072656d61696e64657200000000000000000000000000006064820152608401610544565b6040805160208082526104208201909252600091816020015b604080518082019091526000808252602082015281526020019060019003908161495e5790505090506000845b8751811015614a4c576000806149d16040518060400160405280858d600001516149b5919061512b565b8152602001858d602001516149ca919061549d565b9052613a0f565b5091509150604051806040016040528083836149ed919061549d565b8152602001848c60200151614a02919061549d565b815250858581518110614a1757614a176154b5565b6020908102919091010152614a2d60018561549d565b9350614a39818361549d565b614a43908461549d565b9250505061498b565b50815295945050505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff81118282101715614ace57614ace614a58565b604052919050565b803573ffffffffffffffffffffffffffffffffffffffff81168114614afa57600080fd5b919050565b600082601f830112614b1057600080fd5b813567ffffffffffffffff811115614b2a57614b2a614a58565b614b5b60207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f84011601614a87565b818152846020838601011115614b7057600080fd5b816020850160208301376000918101602001919091529392505050565b600060c08284031215614b9f57600080fd5b60405160c0810167ffffffffffffffff8282108183111715614bc357614bc3614a58565b8160405282935084358352614bda60208601614ad6565b6020840152614beb60408601614ad6565b6040840152606085013560608401526080850135608084015260a0850135915080821115614c1857600080fd5b50614c2585828601614aff565b60a0830152505092915050565b600080600080600085870360e0811215614c4b57600080fd5b863567ffffffffffffffff80821115614c6357600080fd5b614c6f8a838b01614b8d565b97506020890135965060807fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc084011215614ca857600080fd5b60408901955060c0890135925080831115614cc257600080fd5b828901925089601f840112614cd657600080fd5b8235915080821115614ce757600080fd5b508860208260051b8401011115614cfd57600080fd5b959894975092955050506020019190565b60005b83811015614d29578181015183820152602001614d11565b83811115614d38576000848401525b50505050565b60008151808452614d56816020860160208601614d0e565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b6020815260006123956020830184614d3e565b600060208284031215614dad57600080fd5b5035919050565b600060208284031215614dc657600080fd5b813567ffffffffffffffff811115614ddd57600080fd5b6120cb84828501614b8d565b80358015158114614afa57600080fd5b600060208284031215614e0b57600080fd5b61239582614de9565b600080600080600060a08688031215614e2c57600080fd5b614e3586614ad6565b945060208601359350604086013567ffffffffffffffff8082168214614e5a57600080fd5b819450614e6960608901614de9565b93506080880135915080821115614e7f57600080fd5b50614e8c88828901614aff565b9150509295509295909350565b8581528460208201527fffffffffffffffff0000000000000000000000000000000000000000000000008460c01b16604082015282151560f81b604882015260008251614eed816049850160208701614d0e565b919091016049019695505050505050565b80516fffffffffffffffffffffffffffffffff81168114614afa57600080fd5b600060608284031215614f3057600080fd5b6040516060810181811067ffffffffffffffff82111715614f5357614f53614a58565b60405282518152614f6660208401614efe565b6020820152614f7760408401614efe565b60408201529392505050565b600060808284031215614f9557600080fd5b6040516080810181811067ffffffffffffffff82111715614fb857614fb8614a58565b8060405250823581526020830135602082015260408301356040820152606083013560608201528091505092915050565b600067ffffffffffffffff8084111561500457615004614a58565b8360051b6020615015818301614a87565b86815291850191818101903684111561502d57600080fd5b865b84811015615061578035868111156150475760008081fd5b61505336828b01614aff565b84525091830191830161502f565b50979650505050505050565b6000845161507f818460208901614d0e565b80830190507f2e0000000000000000000000000000000000000000000000000000000000000080825285516150bb816001850160208a01614d0e565b600192019182015283516150d6816002840160208801614d0e565b0160020195945050505050565b6000602082840312156150f557600080fd5b5051919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60008282101561513d5761513d6150fc565b500390565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b60008261518057615180615142565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff83147f8000000000000000000000000000000000000000000000000000000000000000831416156151d4576151d46150fc565b500590565b6000808312837f800000000000000000000000000000000000000000000000000000000000000001831281151615615213576152136150fc565b837f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff018313811615615247576152476150fc565b50500390565b60007f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff60008413600084138583048511828216161561528e5761528e6150fc565b7f800000000000000000000000000000000000000000000000000000000000000060008712868205881281841616156152c9576152c96150fc565b600087129250878205871284841616156152e5576152e56150fc565b878505871281841616156152fb576152fb6150fc565b505050929093029392505050565b6000808212827f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff03841381151615615343576153436150fc565b827f8000000000000000000000000000000000000000000000000000000000000000038412811615615377576153776150fc565b50500190565b600067ffffffffffffffff8083168185168083038211156153a0576153a06150fc565b01949350505050565b6000817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff04831182151516156153e1576153e16150fc565b500290565b6000826153f5576153f5615142565b500490565b868152600073ffffffffffffffffffffffffffffffffffffffff808816602084015280871660408401525084606083015283608083015260c060a083015261544560c0830184614d3e565b98975050505050505050565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203615482576154826150fc565b5060010190565b60008261549857615498615142565b500690565b600082198211156154b0576154b06150fc565b500190565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b805163ffffffff81168114614afa57600080fd5b805160ff81168114614afa57600080fd5b600060c0828403121561551b57600080fd5b60405160c0810181811067ffffffffffffffff8211171561553e5761553e614a58565b60405261554a836154e4565b8152615558602084016154f8565b6020820152615569604084016154f8565b604082015261557a606084016154e4565b606082015261558b608084016154e4565b608082015261559c60a08401614efe565b60a08201529392505050565b600060ff8316806155bb576155bb615142565b8060ff84160691505092915050565b600060ff821660ff8416808210156155e4576155e46150fc565b90039392505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fdfea164736f6c634300080f000a"
func init() {
if err := json.Unmarshal([]byte(OptimismPortalStorageLayoutJSON), OptimismPortalStorageLayout); err != nil {
......
......@@ -181,6 +181,7 @@ func main() {
migrationData,
&config.L1CrossDomainMessengerProxy,
config.L1ChainID,
config.L2ChainID,
config.FinalSystemOwner,
config.ProxyAdminOwner,
&derive.L1BlockInfo{
......
......@@ -223,6 +223,7 @@ func main() {
migrationData,
&config.L1CrossDomainMessengerProxy,
config.L1ChainID,
config.L2ChainID,
config.FinalSystemOwner,
config.ProxyAdminOwner,
&derive.L1BlockInfo{
......
......@@ -141,6 +141,10 @@ func main() {
if err != nil {
return err
}
l2ChainID, err := clients.L2Client.ChainID(context.Background())
if err != nil {
return err
}
// create the set of withdrawals
wds, err := newWithdrawals(ctx, l1ChainID)
......@@ -212,7 +216,7 @@ func main() {
log.Info("Processing withdrawal", "index", i)
// migrate the withdrawal
withdrawal, err := crossdomain.MigrateWithdrawal(wd, &l1xdmAddr)
withdrawal, err := crossdomain.MigrateWithdrawal(wd, &l1xdmAddr, l2ChainID)
if err != nil {
return err
}
......
......@@ -20,7 +20,13 @@ var (
)
// MigrateWithdrawals will migrate a list of pending withdrawals given a StateDB.
func MigrateWithdrawals(withdrawals SafeFilteredWithdrawals, db vm.StateDB, l1CrossDomainMessenger *common.Address, noCheck bool) error {
func MigrateWithdrawals(
withdrawals SafeFilteredWithdrawals,
db vm.StateDB,
l1CrossDomainMessenger *common.Address,
noCheck bool,
chainID *big.Int,
) error {
for i, legacy := range withdrawals {
legacySlot, err := legacy.StorageSlot()
if err != nil {
......@@ -34,7 +40,7 @@ func MigrateWithdrawals(withdrawals SafeFilteredWithdrawals, db vm.StateDB, l1Cr
}
}
withdrawal, err := MigrateWithdrawal(legacy, l1CrossDomainMessenger)
withdrawal, err := MigrateWithdrawal(legacy, l1CrossDomainMessenger, chainID)
if err != nil {
return err
}
......@@ -52,7 +58,11 @@ func MigrateWithdrawals(withdrawals SafeFilteredWithdrawals, db vm.StateDB, l1Cr
// MigrateWithdrawal will turn a LegacyWithdrawal into a bedrock
// style Withdrawal.
func MigrateWithdrawal(withdrawal *LegacyWithdrawal, l1CrossDomainMessenger *common.Address) (*Withdrawal, error) {
func MigrateWithdrawal(
withdrawal *LegacyWithdrawal,
l1CrossDomainMessenger *common.Address,
chainID *big.Int,
) (*Withdrawal, error) {
// Attempt to parse the value
value, err := withdrawal.Value()
if err != nil {
......@@ -83,7 +93,7 @@ func MigrateWithdrawal(withdrawal *LegacyWithdrawal, l1CrossDomainMessenger *com
return nil, fmt.Errorf("cannot abi encode relayMessage: %w", err)
}
gasLimit := MigrateWithdrawalGasLimit(data)
gasLimit := MigrateWithdrawalGasLimit(data, chainID)
w := NewWithdrawal(
versionedNonce,
......@@ -97,13 +107,21 @@ func MigrateWithdrawal(withdrawal *LegacyWithdrawal, l1CrossDomainMessenger *com
}
// MigrateWithdrawalGasLimit computes the gas limit for the migrated withdrawal.
func MigrateWithdrawalGasLimit(data []byte) uint64 {
// The chain id is used to determine the overhead.
func MigrateWithdrawalGasLimit(data []byte, chainID *big.Int) uint64 {
// Compute the upper bound on the gas limit. This could be more
// accurate if individual 0 bytes and non zero bytes were accounted
// for.
dataCost := uint64(len(data)) * params.TxDataNonZeroGasEIP2028
// Goerli has a lower gas limit than other chains.
overhead := uint64(200_000)
if chainID.Cmp(big.NewInt(420)) != 0 {
overhead = 1_000_000
}
// Set the outer gas limit. This cannot be zero
gasLimit := dataCost + 200_000
gasLimit := dataCost + overhead
// Cap the gas limit to be 25 million to prevent creating withdrawals
// that go over the block gas limit.
if gasLimit > 25_000_000 {
......
......@@ -12,7 +12,10 @@ import (
"github.com/stretchr/testify/require"
)
var big25Million = big.NewInt(25_000_000)
var (
big25Million = big.NewInt(25_000_000)
bigGoerliChainID = big.NewInt(420)
)
func TestMigrateWithdrawal(t *testing.T) {
withdrawals := make([]*crossdomain.LegacyWithdrawal, 0)
......@@ -27,7 +30,7 @@ func TestMigrateWithdrawal(t *testing.T) {
l1CrossDomainMessenger := common.HexToAddress("0x25ace71c97B33Cc4729CF772ae268934F7ab5fA1")
for i, legacy := range withdrawals {
t.Run(fmt.Sprintf("test%d", i), func(t *testing.T) {
withdrawal, err := crossdomain.MigrateWithdrawal(legacy, &l1CrossDomainMessenger)
withdrawal, err := crossdomain.MigrateWithdrawal(legacy, &l1CrossDomainMessenger, bigGoerliChainID)
require.Nil(t, err)
require.NotNil(t, withdrawal)
......@@ -50,7 +53,7 @@ func TestMigrateWithdrawalGasLimitMax(t *testing.T) {
data[i] = 0xff
}
result := crossdomain.MigrateWithdrawalGasLimit(data)
result := crossdomain.MigrateWithdrawalGasLimit(data, bigGoerliChainID)
require.Equal(t, result, big25Million.Uint64())
}
......@@ -84,7 +87,7 @@ func TestMigrateWithdrawalGasLimit(t *testing.T) {
}
for _, test := range tests {
result := crossdomain.MigrateWithdrawalGasLimit(test.input)
result := crossdomain.MigrateWithdrawalGasLimit(test.input, bigGoerliChainID)
require.Equal(t, test.output, result)
}
}
......@@ -101,6 +101,7 @@ func PostCheckMigratedDB(
migrationData crossdomain.MigrationData,
l1XDM *common.Address,
l1ChainID uint64,
l2ChainID uint64,
finalSystemOwner common.Address,
proxyAdminOwner common.Address,
info *derive.L1BlockInfo,
......@@ -163,7 +164,7 @@ func PostCheckMigratedDB(
}
log.Info("checked legacy eth")
if err := CheckWithdrawalsAfter(db, migrationData, l1XDM); err != nil {
if err := CheckWithdrawalsAfter(db, migrationData, l1XDM, new(big.Int).SetUint64(l2ChainID)); err != nil {
return err
}
log.Info("checked withdrawals")
......@@ -557,7 +558,7 @@ func PostCheckL1Block(db *state.StateDB, info *derive.L1BlockInfo) error {
return nil
}
func CheckWithdrawalsAfter(db *state.StateDB, data crossdomain.MigrationData, l1CrossDomainMessenger *common.Address) error {
func CheckWithdrawalsAfter(db *state.StateDB, data crossdomain.MigrationData, l1CrossDomainMessenger *common.Address, l2ChainID *big.Int) error {
wds, invalidMessages, err := data.ToWithdrawals()
if err != nil {
return err
......@@ -570,7 +571,7 @@ func CheckWithdrawalsAfter(db *state.StateDB, data crossdomain.MigrationData, l1
wdsByOldSlot := make(map[common.Hash]*crossdomain.LegacyWithdrawal)
invalidMessagesByOldSlot := make(map[common.Hash]crossdomain.InvalidMessage)
for _, wd := range wds {
migrated, err := crossdomain.MigrateWithdrawal(wd, l1CrossDomainMessenger)
migrated, err := crossdomain.MigrateWithdrawal(wd, l1CrossDomainMessenger, l2ChainID)
if err != nil {
return err
}
......
......@@ -186,7 +186,8 @@ func MigrateDB(ldb ethdb.Database, config *DeployConfig, l1Block *types.Block, m
// the LegacyMessagePasser contract. Here we operate on the list of withdrawals that we
// previously filtered and verified.
log.Info("Starting to migrate withdrawals", "no-check", noCheck)
err = crossdomain.MigrateWithdrawals(filteredWithdrawals, db, &config.L1CrossDomainMessengerProxy, noCheck)
l2ChainID := new(big.Int).SetUint64(config.L2ChainID)
err = crossdomain.MigrateWithdrawals(filteredWithdrawals, db, &config.L1CrossDomainMessengerProxy, noCheck, l2ChainID)
if err != nil {
return nil, fmt.Errorf("cannot migrate withdrawals: %w", err)
}
......
......@@ -11,6 +11,7 @@ import (
"github.com/ethereum/go-ethereum"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/common/hexutil"
"github.com/ethereum/go-ethereum/core/txpool"
"github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/core/vm"
"github.com/ethereum/go-ethereum/crypto"
......@@ -40,6 +41,28 @@ func TestMissingGasLimit(t *testing.T) {
require.Nil(t, res)
}
// TestTxGasSameAsBlockGasLimit tests that op-geth rejects transactions that attempt to use the full block gas limit.
// The L1 Info deposit always takes gas so the effective gas limit is lower than the full block gas limit.
func TestTxGasSameAsBlockGasLimit(t *testing.T) {
InitParallel(t)
cfg := DefaultSystemConfig(t)
sys, err := cfg.Start()
require.Nil(t, err, "Error starting up system")
defer sys.Close()
ethPrivKey := sys.cfg.Secrets.Alice
tx := types.MustSignNewTx(ethPrivKey, types.LatestSignerForChainID(cfg.L2ChainIDBig()), &types.DynamicFeeTx{
ChainID: cfg.L2ChainIDBig(),
Gas: 29_999_999,
})
ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second)
defer cancel()
l2Seq := sys.Clients["sequencer"]
err = l2Seq.SendTransaction(ctx, tx)
require.ErrorContains(t, err, txpool.ErrGasLimit.Error())
}
// TestInvalidDepositInFCU runs an invalid deposit through a FCU/GetPayload/NewPayload/FCU set of calls.
// This tests that deposits must always allow the block to be built even if they are invalid.
func TestInvalidDepositInFCU(t *testing.T) {
......
......@@ -593,17 +593,18 @@ func (cfg SystemConfig) Start(_opts ...SystemConfigOption) (*System, error) {
// Batch Submitter
sys.BatchSubmitter, err = bss.NewBatchSubmitterFromCLIConfig(bss.CLIConfig{
L1EthRpc: sys.Nodes["l1"].WSEndpoint(),
L2EthRpc: sys.Nodes["sequencer"].WSEndpoint(),
RollupRpc: sys.RollupNodes["sequencer"].HTTPEndpoint(),
MaxChannelDuration: 1,
MaxL1TxSize: 120_000,
TargetL1TxSize: 100_000,
TargetNumFrames: 1,
ApproxComprRatio: 0.4,
SubSafetyMargin: 4,
PollInterval: 50 * time.Millisecond,
TxMgrConfig: newTxMgrConfig(sys.Nodes["l1"].WSEndpoint(), cfg.Secrets.Batcher),
L1EthRpc: sys.Nodes["l1"].WSEndpoint(),
L2EthRpc: sys.Nodes["sequencer"].WSEndpoint(),
RollupRpc: sys.RollupNodes["sequencer"].HTTPEndpoint(),
MaxPendingTransactions: 1,
MaxChannelDuration: 1,
MaxL1TxSize: 120_000,
TargetL1TxSize: 100_000,
TargetNumFrames: 1,
ApproxComprRatio: 0.4,
SubSafetyMargin: 4,
PollInterval: 50 * time.Millisecond,
TxMgrConfig: newTxMgrConfig(sys.Nodes["l1"].WSEndpoint(), cfg.Secrets.Batcher),
LogConfig: oplog.CLIConfig{
Level: "info",
Format: "text",
......
......@@ -9,8 +9,11 @@ import (
"github.com/ethereum-optimism/optimism/op-node/client"
"github.com/ethereum-optimism/optimism/op-node/sources"
"github.com/ethereum-optimism/optimism/op-node/testlog"
oppcl "github.com/ethereum-optimism/optimism/op-program/client"
"github.com/ethereum-optimism/optimism/op-program/client/driver"
opp "github.com/ethereum-optimism/optimism/op-program/host"
oppconf "github.com/ethereum-optimism/optimism/op-program/host/config"
oplog "github.com/ethereum-optimism/optimism/op-service/log"
"github.com/ethereum/go-ethereum/accounts/abi/bind"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/log"
......@@ -18,7 +21,27 @@ import (
"github.com/stretchr/testify/require"
)
// bypass the test runnner if running client to execute the fpp directly
func init() {
if !opp.RunningProgramInClient() {
return
}
logger := oplog.NewLogger(oplog.CLIConfig{
Level: "debug",
Format: "text",
})
oppcl.Main(logger)
}
func TestVerifyL2OutputRoot(t *testing.T) {
testVerifyL2OutputRoot(t, false)
}
func TestVerifyL2OutputRootDetached(t *testing.T) {
testVerifyL2OutputRoot(t, true)
}
func testVerifyL2OutputRoot(t *testing.T, detached bool) {
InitParallel(t)
ctx := context.Background()
......@@ -92,6 +115,7 @@ func TestVerifyL2OutputRoot(t *testing.T) {
fppConfig.L1URL = sys.NodeEndpoint("l1")
fppConfig.L2URL = sys.NodeEndpoint("sequencer")
fppConfig.DataDir = preimageDir
fppConfig.Detached = detached
// Check the FPP confirms the expected output
t.Log("Running fault proof in fetching mode")
......@@ -118,7 +142,11 @@ func TestVerifyL2OutputRoot(t *testing.T) {
t.Log("Running fault proof with invalid claim")
fppConfig.L2Claim = common.Hash{0xaa}
err = opp.FaultProofProgram(log, fppConfig)
require.ErrorIs(t, err, opp.ErrClaimNotValid)
if detached {
require.Error(t, err, "exit status 1")
} else {
require.ErrorIs(t, err, driver.ErrClaimNotValid)
}
}
func waitForSafeHead(ctx context.Context, safeBlockNum uint64, rollupClient *sources.RollupClient) error {
......
FROM --platform=$BUILDPLATFORM golang:1.19.0-alpine3.15 as builder
ARG VERSION=v0.0.0
RUN apk add --no-cache make gcc musl-dev linux-headers git jq bash
# build op-program with the shared go.mod & go.sum files
COPY ./op-program /app/op-program
COPY ./op-node /app/op-node
COPY ./op-chain-ops /app/op-chain-ops
COPY ./op-service /app/op-service
COPY ./op-bindings /app/op-bindings
COPY ./go.mod /app/go.mod
COPY ./go.sum /app/go.sum
COPY ./.git /app/.git
WORKDIR /app/op-program
RUN go mod download
ARG TARGETOS TARGETARCH
RUN make op-program VERSION="$VERSION" GOOS=$TARGETOS GOARCH=$TARGETARCH
FROM alpine:3.15
COPY --from=builder /app/op-program/bin/op-program /usr/local/bin
CMD ["op-program"]
package client
import (
"encoding/binary"
"encoding/json"
"fmt"
"io"
"github.com/ethereum-optimism/optimism/op-node/rollup"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/params"
)
type BootInfo struct {
// TODO(CLI-XXX): The rollup config will be hardcoded. It's configurable for testing purposes.
Rollup *rollup.Config `json:"rollup"`
L2ChainConfig *params.ChainConfig `json:"l2_chain_config"`
L1Head common.Hash `json:"l1_head"`
L2Head common.Hash `json:"l2_head"`
L2Claim common.Hash `json:"l2_claim"`
L2ClaimBlockNumber uint64 `json:"l2_claim_block_number"`
}
type BootstrapOracleWriter struct {
w io.Writer
}
func NewBootstrapOracleWriter(w io.Writer) *BootstrapOracleWriter {
return &BootstrapOracleWriter{w: w}
}
func (bw *BootstrapOracleWriter) WriteBootInfo(info *BootInfo) error {
// TODO(CLI-3751): Bootstrap from local oracle
payload, err := json.Marshal(info)
if err != nil {
return err
}
var b []byte
b = binary.BigEndian.AppendUint32(b, uint32(len(payload)))
b = append(b, payload...)
_, err = bw.w.Write(b)
return err
}
type BootstrapOracleReader struct {
r io.Reader
}
func NewBootstrapOracleReader(r io.Reader) *BootstrapOracleReader {
return &BootstrapOracleReader{r: r}
}
func (br *BootstrapOracleReader) BootInfo() (*BootInfo, error) {
var length uint32
if err := binary.Read(br.r, binary.BigEndian, &length); err != nil {
if err == io.EOF {
return nil, io.EOF
}
return nil, fmt.Errorf("failed to read bootinfo length prefix: %w", err)
}
payload := make([]byte, length)
if length > 0 {
if _, err := io.ReadFull(br.r, payload); err != nil {
return nil, fmt.Errorf("failed to read bootinfo data (length %d): %w", length, err)
}
}
var bootInfo BootInfo
if err := json.Unmarshal(payload, &bootInfo); err != nil {
return nil, err
}
return &bootInfo, nil
}
package client
import (
"io"
"testing"
"time"
"github.com/ethereum-optimism/optimism/op-node/rollup"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/params"
"github.com/stretchr/testify/require"
)
func TestBootstrapOracle(t *testing.T) {
r, w := io.Pipe()
br := NewBootstrapOracleReader(r)
bw := NewBootstrapOracleWriter(w)
bootInfo := BootInfo{
Rollup: new(rollup.Config),
L2ChainConfig: new(params.ChainConfig),
L1Head: common.HexToHash("0xffffa"),
L2Head: common.HexToHash("0xffffb"),
L2Claim: common.HexToHash("0xffffc"),
L2ClaimBlockNumber: 1,
}
go func() {
err := bw.WriteBootInfo(&bootInfo)
require.NoError(t, err)
}()
type result struct {
bootInnfo *BootInfo
err error
}
read := make(chan result)
go func() {
readBootInfo, err := br.BootInfo()
read <- result{readBootInfo, err}
close(read)
}()
select {
case <-time.After(time.Second * 30):
t.Error("timeout waiting for bootstrap oracle")
case r := <-read:
require.NoError(t, r.err)
require.Equal(t, bootInfo, *r.bootInnfo)
}
}
......@@ -13,6 +13,10 @@ import (
"github.com/ethereum/go-ethereum/log"
)
var (
ErrClaimNotValid = errors.New("invalid claim")
)
type Derivation interface {
Step(ctx context.Context) error
SafeL2Head() eth.L2BlockRef
......@@ -47,11 +51,12 @@ func NewDriver(logger log.Logger, cfg *rollup.Config, l1Source derive.L1Fetcher,
// Returns a non-EOF error if the derivation failed
func (d *Driver) Step(ctx context.Context) error {
if err := d.pipeline.Step(ctx); errors.Is(err, io.EOF) {
d.logger.Info("Derivation complete: reached L1 head", "head", d.pipeline.SafeL2Head())
return io.EOF
} else if errors.Is(err, derive.NotEnoughData) {
head := d.pipeline.SafeL2Head()
if head.Number >= d.targetBlockNum {
d.logger.Info("Target L2 block reached", "head", head)
d.logger.Info("Derivation complete: reached L2 block", "head", head)
return io.EOF
}
d.logger.Debug("Data is lacking")
......@@ -66,12 +71,14 @@ func (d *Driver) SafeHead() eth.L2BlockRef {
return d.pipeline.SafeL2Head()
}
func (d *Driver) ValidateClaim(claimedOutputRoot eth.Bytes32) bool {
func (d *Driver) ValidateClaim(claimedOutputRoot eth.Bytes32) error {
outputRoot, err := d.l2OutputRoot()
if err != nil {
d.logger.Info("Failed to calculate L2 output root", "err", err)
return false
return fmt.Errorf("calculate L2 output root: %w", err)
}
d.logger.Info("Derivation complete", "head", d.SafeHead(), "output", outputRoot, "claim", claimedOutputRoot)
return claimedOutputRoot == outputRoot
d.logger.Info("Validating claim", "head", d.SafeHead(), "output", outputRoot, "claim", claimedOutputRoot)
if claimedOutputRoot != outputRoot {
return fmt.Errorf("%w: claim: %v actual: %v", ErrClaimNotValid, claimedOutputRoot, outputRoot)
}
return nil
}
......@@ -76,8 +76,8 @@ func TestValidateClaim(t *testing.T) {
driver.l2OutputRoot = func() (eth.Bytes32, error) {
return expected, nil
}
valid := driver.ValidateClaim(expected)
require.True(t, valid)
err := driver.ValidateClaim(expected)
require.NoError(t, err)
})
t.Run("Invalid", func(t *testing.T) {
......@@ -85,17 +85,18 @@ func TestValidateClaim(t *testing.T) {
driver.l2OutputRoot = func() (eth.Bytes32, error) {
return eth.Bytes32{0x22}, nil
}
valid := driver.ValidateClaim(eth.Bytes32{0x11})
require.False(t, valid)
err := driver.ValidateClaim(eth.Bytes32{0x11})
require.ErrorIs(t, err, ErrClaimNotValid)
})
t.Run("Error", func(t *testing.T) {
driver := createDriver(t, io.EOF)
expectedErr := errors.New("boom")
driver.l2OutputRoot = func() (eth.Bytes32, error) {
return eth.Bytes32{}, errors.New("boom")
return eth.Bytes32{}, expectedErr
}
valid := driver.ValidateClaim(eth.Bytes32{0x11})
require.False(t, valid)
err := driver.ValidateClaim(eth.Bytes32{0x11})
require.ErrorIs(t, err, expectedErr)
})
}
......
package client
const (
// 0,1,2 used for stdin,stdout,stderr
HClientRFd = iota + 3
HClientWFd
PClientRFd
PClientWFd
BootRFd // TODO(CLI-3751): remove
MaxFd
)
......@@ -18,16 +18,20 @@ var (
)
type OracleL1Client struct {
oracle Oracle
head eth.L1BlockRef
oracle Oracle
head eth.L1BlockRef
hashByNum map[uint64]common.Hash
earliestIndexedBlock eth.L1BlockRef
}
func NewOracleL1Client(logger log.Logger, oracle Oracle, l1Head common.Hash) *OracleL1Client {
head := eth.InfoToL1BlockRef(oracle.HeaderByBlockHash(l1Head))
logger.Info("L1 head loaded", "hash", head.Hash, "number", head.Number)
return &OracleL1Client{
oracle: oracle,
head: head,
oracle: oracle,
head: head,
hashByNum: map[uint64]common.Hash{head.Number: head.Hash},
earliestIndexedBlock: head,
}
}
......@@ -43,9 +47,15 @@ func (o *OracleL1Client) L1BlockRefByNumber(ctx context.Context, number uint64)
if number > o.head.Number {
return eth.L1BlockRef{}, fmt.Errorf("%w: block number %d", ErrNotFound, number)
}
block := o.head
hash, ok := o.hashByNum[number]
if ok {
return o.L1BlockRefByHash(ctx, hash)
}
block := o.earliestIndexedBlock
for block.Number > number {
block = eth.InfoToL1BlockRef(o.oracle.HeaderByBlockHash(block.ParentHash))
o.hashByNum[block.Number] = block.Hash
o.earliestIndexedBlock = block
}
return block, nil
}
......
......@@ -126,8 +126,7 @@ func TestL1BlockRefByNumber(t *testing.T) {
require.NoError(t, err)
require.Equal(t, eth.InfoToL1BlockRef(parent), ref)
})
t.Run("AncestorOfHead", func(t *testing.T) {
client, oracle := newClient(t)
createBlocks := func(oracle *test.StubOracle) []eth.BlockInfo {
block := head
blocks := []eth.BlockInfo{block}
for i := 0; i < 10; i++ {
......@@ -135,6 +134,11 @@ func TestL1BlockRefByNumber(t *testing.T) {
oracle.Blocks[block.Hash()] = block
blocks = append(blocks, block)
}
return blocks
}
t.Run("AncestorsAccessForwards", func(t *testing.T) {
client, oracle := newClient(t)
blocks := createBlocks(oracle)
for _, block := range blocks {
ref, err := client.L1BlockRefByNumber(context.Background(), block.NumberU64())
......@@ -142,6 +146,17 @@ func TestL1BlockRefByNumber(t *testing.T) {
require.Equal(t, eth.InfoToL1BlockRef(block), ref)
}
})
t.Run("AncestorsAccessReverse", func(t *testing.T) {
client, oracle := newClient(t)
blocks := createBlocks(oracle)
for i := len(blocks) - 1; i >= 0; i-- {
block := blocks[i]
ref, err := client.L1BlockRefByNumber(context.Background(), block.NumberU64())
require.NoError(t, err)
require.Equal(t, eth.InfoToL1BlockRef(block), ref)
}
})
}
func newClient(t *testing.T) (*OracleL1Client, *test.StubOracle) {
......
......@@ -28,6 +28,10 @@ type OracleBackedL2Chain struct {
finalized *types.Header
vmCfg vm.Config
// Block by number cache
hashByNum map[uint64]common.Hash
earliestIndexedBlock *types.Header
// Inserted blocks
blocks map[common.Hash]*types.Block
db ethdb.KeyValueStore
......@@ -44,6 +48,11 @@ func NewOracleBackedL2Chain(logger log.Logger, oracle Oracle, chainCfg *params.C
chainCfg: chainCfg,
engine: beacon.New(nil),
hashByNum: map[uint64]common.Hash{
head.NumberU64(): head.Hash(),
},
earliestIndexedBlock: head.Header(),
// Treat the agreed starting head as finalized - nothing before it can be disputed
head: head.Header(),
safe: head.Header(),
......@@ -59,14 +68,20 @@ func (o *OracleBackedL2Chain) CurrentHeader() *types.Header {
}
func (o *OracleBackedL2Chain) GetHeaderByNumber(n uint64) *types.Header {
// Walk back from current head to the requested block number
h := o.head
if h.Number.Uint64() < n {
if o.head.Number.Uint64() < n {
return nil
}
hash, ok := o.hashByNum[n]
if ok {
return o.GetHeaderByHash(hash)
}
// Walk back from current head to the requested block number
h := o.head
for h.Number.Uint64() > n {
h = o.GetHeaderByHash(h.ParentHash)
o.hashByNum[h.Number.Uint64()] = h.Hash()
}
o.earliestIndexedBlock = h
return h
}
......@@ -176,7 +191,28 @@ func (o *OracleBackedL2Chain) InsertBlockWithoutSetHead(block *types.Block) erro
}
func (o *OracleBackedL2Chain) SetCanonical(head *types.Block) (common.Hash, error) {
oldHead := o.head
o.head = head.Header()
// Remove canonical hashes after the new header
for n := head.NumberU64() + 1; n <= oldHead.Number.Uint64(); n++ {
delete(o.hashByNum, n)
}
// Add new canonical blocks to the block by number cache
// Since the original head is added to the block number cache and acts as the finalized block,
// at some point we must reach the existing canonical chain and can stop updating.
h := o.head
for {
newHash := h.Hash()
prevHash, ok := o.hashByNum[h.Number.Uint64()]
if ok && prevHash == newHash {
// Connected with the existing canonical chain so stop updating
break
}
o.hashByNum[h.Number.Uint64()] = newHash
h = o.GetHeaderByHash(h.ParentHash)
}
return head.Hash(), nil
}
......
......@@ -123,6 +123,66 @@ func TestRejectBlockWithStateRootMismatch(t *testing.T) {
require.ErrorContains(t, err, "block root mismatch")
}
func TestGetHeaderByNumber(t *testing.T) {
t.Run("Forwards", func(t *testing.T) {
blocks, chain := setupOracleBackedChain(t, 10)
for _, block := range blocks {
result := chain.GetHeaderByNumber(block.NumberU64())
require.Equal(t, block.Header(), result)
}
})
t.Run("Reverse", func(t *testing.T) {
blocks, chain := setupOracleBackedChain(t, 10)
for i := len(blocks) - 1; i >= 0; i-- {
block := blocks[i]
result := chain.GetHeaderByNumber(block.NumberU64())
require.Equal(t, block.Header(), result)
}
})
t.Run("AppendedBlock", func(t *testing.T) {
_, chain := setupOracleBackedChain(t, 10)
// Append a block
newBlock := createBlock(t, chain)
require.NoError(t, chain.InsertBlockWithoutSetHead(newBlock))
_, err := chain.SetCanonical(newBlock)
require.NoError(t, err)
require.Equal(t, newBlock.Header(), chain.GetHeaderByNumber(newBlock.NumberU64()))
})
t.Run("AppendedBlockAfterLookup", func(t *testing.T) {
blocks, chain := setupOracleBackedChain(t, 10)
// Look up an early block to prime the block cache
require.Equal(t, blocks[0].Header(), chain.GetHeaderByNumber(blocks[0].NumberU64()))
// Append a block
newBlock := createBlock(t, chain)
require.NoError(t, chain.InsertBlockWithoutSetHead(newBlock))
_, err := chain.SetCanonical(newBlock)
require.NoError(t, err)
require.Equal(t, newBlock.Header(), chain.GetHeaderByNumber(newBlock.NumberU64()))
})
t.Run("AppendedMultipleBlocks", func(t *testing.T) {
blocks, chain := setupOracleBackedChainWithLowerHead(t, 5, 2)
// Append a few blocks
newBlock1 := blocks[3]
newBlock2 := blocks[4]
newBlock3 := blocks[5]
require.NoError(t, chain.InsertBlockWithoutSetHead(newBlock1))
require.NoError(t, chain.InsertBlockWithoutSetHead(newBlock2))
require.NoError(t, chain.InsertBlockWithoutSetHead(newBlock3))
_, err := chain.SetCanonical(newBlock3)
require.NoError(t, err)
require.Equal(t, newBlock3.Header(), chain.GetHeaderByNumber(newBlock3.NumberU64()), "Lookup block3")
require.Equal(t, newBlock2.Header(), chain.GetHeaderByNumber(newBlock2.NumberU64()), "Lookup block2")
require.Equal(t, newBlock1.Header(), chain.GetHeaderByNumber(newBlock1.NumberU64()), "Lookup block1")
})
}
func assertBlockDataAvailable(t *testing.T, chain *OracleBackedL2Chain, block *types.Block, blockNumber uint64) {
require.Equal(t, block, chain.GetBlockByHash(block.Hash()), "get block %v by hash", blockNumber)
require.Equal(t, block.Header(), chain.GetHeaderByHash(block.Hash()), "get header %v by hash", blockNumber)
......
package client
import (
"context"
"errors"
"fmt"
"io"
"os"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/log"
"github.com/ethereum/go-ethereum/params"
"github.com/ethereum-optimism/optimism/op-node/eth"
"github.com/ethereum-optimism/optimism/op-node/rollup"
cldr "github.com/ethereum-optimism/optimism/op-program/client/driver"
"github.com/ethereum-optimism/optimism/op-program/client/l1"
"github.com/ethereum-optimism/optimism/op-program/client/l2"
oppio "github.com/ethereum-optimism/optimism/op-program/io"
"github.com/ethereum-optimism/optimism/op-program/preimage"
)
// Main executes the client program in a detached context and exits the current process.
// The client runtime environment must be preset before calling this function.
func Main(logger log.Logger) {
log.Info("Starting fault proof program client")
preimageOracle := CreatePreimageChannel()
preimageHinter := CreateHinterChannel()
bootOracle := os.NewFile(BootRFd, "bootR")
err := RunProgram(logger, bootOracle, preimageOracle, preimageHinter)
if err != nil {
log.Error("Program failed", "err", err)
os.Exit(1)
} else {
os.Exit(0)
}
}
// RunProgram executes the Program, while attached to an IO based pre-image oracle, to be served by a host.
func RunProgram(logger log.Logger, bootOracle io.Reader, preimageOracle io.ReadWriter, preimageHinter io.ReadWriter) error {
bootReader := NewBootstrapOracleReader(bootOracle)
bootInfo, err := bootReader.BootInfo()
if err != nil {
return fmt.Errorf("failed to read boot info: %w", err)
}
logger.Debug("Loaded boot info", "bootInfo", bootInfo)
pClient := preimage.NewOracleClient(preimageOracle)
hClient := preimage.NewHintWriter(preimageHinter)
l1PreimageOracle := l1.NewPreimageOracle(pClient, hClient)
l2PreimageOracle := l2.NewPreimageOracle(pClient, hClient)
return runDerivation(
logger,
bootInfo.Rollup,
bootInfo.L2ChainConfig,
bootInfo.L1Head,
bootInfo.L2Head,
bootInfo.L2Claim,
bootInfo.L2ClaimBlockNumber,
l1PreimageOracle,
l2PreimageOracle,
)
}
// runDerivation executes the L2 state transition, given a minimal interface to retrieve data.
func runDerivation(logger log.Logger, cfg *rollup.Config, l2Cfg *params.ChainConfig, l1Head common.Hash, l2Head common.Hash, l2Claim common.Hash, l2ClaimBlockNum uint64, l1Oracle l1.Oracle, l2Oracle l2.Oracle) error {
l1Source := l1.NewOracleL1Client(logger, l1Oracle, l1Head)
engineBackend, err := l2.NewOracleBackedL2Chain(logger, l2Oracle, l2Cfg, l2Head)
if err != nil {
return fmt.Errorf("failed to create oracle-backed L2 chain: %w", err)
}
l2Source := l2.NewOracleEngine(cfg, logger, engineBackend)
logger.Info("Starting derivation")
d := cldr.NewDriver(logger, cfg, l1Source, l2Source, l2ClaimBlockNum)
for {
if err = d.Step(context.Background()); errors.Is(err, io.EOF) {
break
} else if err != nil {
return err
}
}
return d.ValidateClaim(eth.Bytes32(l2Claim))
}
func CreateHinterChannel() oppio.FileChannel {
r := os.NewFile(HClientRFd, "preimage-hint-read")
w := os.NewFile(HClientWFd, "preimage-hint-write")
return oppio.NewReadWritePair(r, w)
}
// CreatePreimageChannel returns a FileChannel for the preimage oracle in a detached context
func CreatePreimageChannel() oppio.FileChannel {
r := os.NewFile(PClientRFd, "preimage-oracle-read")
w := os.NewFile(PClientWFd, "preimage-oracle-write")
return oppio.NewReadWritePair(r, w)
}
package main
import (
"errors"
"fmt"
"os"
"github.com/ethereum-optimism/optimism/op-program/client/driver"
"github.com/ethereum-optimism/optimism/op-program/host"
"github.com/ethereum-optimism/optimism/op-program/host/config"
"github.com/ethereum-optimism/optimism/op-program/host/flags"
......@@ -35,9 +37,10 @@ var VersionWithMeta = func() string {
func main() {
args := os.Args
err := run(args, host.FaultProofProgram)
if err != nil {
log.Crit("Application failed", "message", err)
if err := run(args, host.FaultProofProgram); errors.Is(err, driver.ErrClaimNotValid) {
log.Crit("Claim is invalid", "err", err)
} else if err != nil {
log.Crit("Application failed", "err", err)
} else {
log.Info("Claim successfully verified")
}
......
......@@ -214,6 +214,25 @@ func TestL2BlockNumber(t *testing.T) {
})
}
func TestDetached(t *testing.T) {
t.Run("DefaultFalse", func(t *testing.T) {
cfg := configForArgs(t, addRequiredArgs(t))
require.False(t, cfg.Detached)
})
t.Run("Enabled", func(t *testing.T) {
cfg := configForArgs(t, addRequiredArgs(t, "--detached"))
require.True(t, cfg.Detached)
})
t.Run("EnabledWithArg", func(t *testing.T) {
cfg := configForArgs(t, addRequiredArgs(t, "--detached=true"))
require.True(t, cfg.Detached)
})
t.Run("Disabled", func(t *testing.T) {
cfg := configForArgs(t, addRequiredArgs(t, "--detached=false"))
require.False(t, cfg.Detached)
})
}
func verifyArgsInvalid(t *testing.T, messageContains string, cliArgs []string) {
_, _, err := runWithArgs(cliArgs)
require.ErrorContains(t, err, messageContains)
......
......@@ -49,6 +49,8 @@ type Config struct {
L2ClaimBlockNumber uint64
// L2ChainConfig is the op-geth chain config for the L2 execution engine
L2ChainConfig *params.ChainConfig
// Detached indicates that the program runs as a separate process
Detached bool
}
func (c *Config) Check() error {
......@@ -137,6 +139,7 @@ func NewConfigFromCLI(ctx *cli.Context) (*Config, error) {
L1URL: ctx.GlobalString(flags.L1NodeAddr.Name),
L1TrustRPC: ctx.GlobalBool(flags.L1TrustRPC.Name),
L1RPCKind: sources.RPCProviderKind(ctx.GlobalString(flags.L1RPCProviderKind.Name)),
Detached: ctx.GlobalBool(flags.Detached.Name),
}, nil
}
......
......@@ -81,6 +81,11 @@ var (
return &out
}(),
}
Detached = cli.BoolFlag{
Name: "detached",
Usage: "Run the program as a separate process detached from the host",
EnvVar: service.PrefixEnvVar(envVarPrefix, "DETACHED"),
}
)
// Flags contains the list of configuration options available to the binary.
......@@ -101,6 +106,7 @@ var programFlags = []cli.Flag{
L1NodeAddr,
L1TrustRPC,
L1RPCProviderKind,
Detached,
}
func init() {
......
......@@ -5,34 +5,42 @@ import (
"errors"
"fmt"
"io"
"io/fs"
"os"
"os/exec"
"github.com/ethereum-optimism/optimism/op-node/chaincfg"
"github.com/ethereum-optimism/optimism/op-node/client"
"github.com/ethereum-optimism/optimism/op-node/eth"
"github.com/ethereum-optimism/optimism/op-node/sources"
cldr "github.com/ethereum-optimism/optimism/op-program/client/driver"
cl "github.com/ethereum-optimism/optimism/op-program/client"
"github.com/ethereum-optimism/optimism/op-program/host/config"
"github.com/ethereum-optimism/optimism/op-program/host/kvstore"
"github.com/ethereum-optimism/optimism/op-program/host/l1"
"github.com/ethereum-optimism/optimism/op-program/host/l2"
"github.com/ethereum-optimism/optimism/op-program/host/prefetcher"
oppio "github.com/ethereum-optimism/optimism/op-program/io"
"github.com/ethereum-optimism/optimism/op-program/preimage"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/log"
)
var (
ErrClaimNotValid = errors.New("invalid claim")
)
type L2Source struct {
*sources.L2Client
*sources.DebugClient
}
const opProgramChildEnvName = "OP_PROGRAM_CHILD"
func RunningProgramInClient() bool {
value, _ := os.LookupEnv(opProgramChildEnvName)
return value == "true"
}
// FaultProofProgram is the programmatic entry-point for the fault proof program
func FaultProofProgram(logger log.Logger, cfg *config.Config) error {
if RunningProgramInClient() {
cl.Main(logger)
panic("Client main should have exited process")
}
if err := cfg.Check(); err != nil {
return fmt.Errorf("invalid config: %w", err)
}
......@@ -51,83 +59,162 @@ func FaultProofProgram(logger log.Logger, cfg *config.Config) error {
kv = kvstore.NewDiskKV(cfg.DataDir)
}
var preimageOracle preimage.OracleFn
var hinter preimage.HinterFn
var (
getPreimage func(key common.Hash) ([]byte, error)
hinter func(hint string) error
)
if cfg.FetchingEnabled() {
logger.Info("Connecting to L1 node", "l1", cfg.L1URL)
l1RPC, err := client.NewRPC(ctx, logger, cfg.L1URL)
prefetch, err := makePrefetcher(ctx, logger, kv, cfg)
if err != nil {
return fmt.Errorf("failed to setup L1 RPC: %w", err)
return fmt.Errorf("failed to create prefetcher: %w", err)
}
logger.Info("Connecting to L2 node", "l2", cfg.L2URL)
l2RPC, err := client.NewRPC(ctx, logger, cfg.L2URL)
if err != nil {
return fmt.Errorf("failed to setup L2 RPC: %w", err)
getPreimage = func(key common.Hash) ([]byte, error) { return prefetch.GetPreimage(ctx, key) }
hinter = prefetch.Hint
} else {
logger.Info("Using offline mode. All required pre-images must be pre-populated.")
getPreimage = kv.Get
hinter = func(hint string) error {
logger.Debug("ignoring prefetch hint", "hint", hint)
return nil
}
}
// TODO(CLI-3751: Load local preimages
localPreimageSource := kvstore.NewLocalPreimageSource(cfg)
splitter := kvstore.NewPreimageSourceSplitter(localPreimageSource.Get, getPreimage)
// Setup client I/O for preimage oracle interaction
pClientRW, pHostRW, err := oppio.CreateBidirectionalChannel()
if err != nil {
return fmt.Errorf("failed to create preimage pipe: %w", err)
}
oracleServer := preimage.NewOracleServer(pHostRW)
launchOracleServer(logger, oracleServer, splitter.Get)
defer pHostRW.Close()
// Setup client I/O for hint comms
hClientRW, hHostRW, err := oppio.CreateBidirectionalChannel()
if err != nil {
return fmt.Errorf("failed to create hints pipe: %w", err)
}
defer hHostRW.Close()
hHost := preimage.NewHintReader(hHostRW)
routeHints(logger, hHost, hinter)
bootClientR, bootHostW, err := os.Pipe()
if err != nil {
return fmt.Errorf("failed to create boot info pipe: %w", err)
}
var cmd *exec.Cmd
if cfg.Detached {
cmd = exec.Command(os.Args[0], os.Args[1:]...)
cmd.ExtraFiles = make([]*os.File, cl.MaxFd-3) // not including stdin, stdout and stderr
cmd.ExtraFiles[cl.HClientRFd-3] = hClientRW.Reader()
cmd.ExtraFiles[cl.HClientWFd-3] = hClientRW.Writer()
cmd.ExtraFiles[cl.PClientRFd-3] = pClientRW.Reader()
cmd.ExtraFiles[cl.PClientWFd-3] = pClientRW.Writer()
cmd.ExtraFiles[cl.BootRFd-3] = bootClientR
cmd.Stdout = os.Stdout // for debugging
cmd.Stderr = os.Stderr // for debugging
cmd.Env = append(os.Environ(), fmt.Sprintf("%s=true", opProgramChildEnvName))
l1ClCfg := sources.L1ClientDefaultConfig(cfg.Rollup, cfg.L1TrustRPC, cfg.L1RPCKind)
l2ClCfg := sources.L2ClientDefaultConfig(cfg.Rollup, true)
l1Cl, err := sources.NewL1Client(l1RPC, logger, nil, l1ClCfg)
err := cmd.Start()
if err != nil {
return fmt.Errorf("failed to create L1 client: %w", err)
return fmt.Errorf("program cmd failed to start: %w", err)
}
l2Cl, err := sources.NewL2Client(l2RPC, logger, nil, l2ClCfg)
}
bootInfo := cl.BootInfo{
Rollup: cfg.Rollup,
L2ChainConfig: cfg.L2ChainConfig,
L1Head: cfg.L1Head,
L2Head: cfg.L2Head,
L2Claim: cfg.L2Claim,
L2ClaimBlockNumber: cfg.L2ClaimBlockNumber,
}
// Spawn a goroutine to write the boot info to avoid blocking this host's goroutine
// if we're running in detached mode
bootInitErrorCh := initializeBootInfoAsync(&bootInfo, bootHostW)
if !cfg.Detached {
return cl.RunProgram(logger, bootClientR, pClientRW, hClientRW)
}
if err := <-bootInitErrorCh; err != nil {
// return early as a detached client is blocked waiting for the boot info
return fmt.Errorf("failed to write boot info: %w", err)
}
if cfg.Detached {
err := cmd.Wait()
if err != nil {
return fmt.Errorf("failed to create L2 client: %w", err)
}
l2DebugCl := &L2Source{L2Client: l2Cl, DebugClient: sources.NewDebugClient(l2RPC.CallContext)}
logger.Info("Setting up pre-fetcher")
prefetch := prefetcher.NewPrefetcher(logger, l1Cl, l2DebugCl, kv)
preimageOracle = asOracleFn(func(key common.Hash) ([]byte, error) {
return prefetch.GetPreimage(ctx, key)
})
hinter = asHinter(prefetch.Hint)
} else {
logger.Info("Using offline mode. All required pre-images must be pre-populated.")
preimageOracle = asOracleFn(kv.Get)
hinter = func(v preimage.Hint) {
logger.Debug("ignoring prefetch hint", "hint", v)
return fmt.Errorf("failed to wait for child program: %w", err)
}
}
l1Source := l1.NewSource(logger, preimageOracle, hinter, cfg.L1Head)
return nil
}
l2Source, err := l2.NewEngine(logger, preimageOracle, hinter, cfg)
func makePrefetcher(ctx context.Context, logger log.Logger, kv kvstore.KV, cfg *config.Config) (*prefetcher.Prefetcher, error) {
logger.Info("Connecting to L1 node", "l1", cfg.L1URL)
l1RPC, err := client.NewRPC(ctx, logger, cfg.L1URL)
if err != nil {
return fmt.Errorf("connect l2 oracle: %w", err)
return nil, fmt.Errorf("failed to setup L1 RPC: %w", err)
}
logger.Info("Starting derivation")
d := cldr.NewDriver(logger, cfg.Rollup, l1Source, l2Source, cfg.L2ClaimBlockNumber)
for {
if err = d.Step(ctx); errors.Is(err, io.EOF) {
break
} else if err != nil {
return err
}
logger.Info("Connecting to L2 node", "l2", cfg.L2URL)
l2RPC, err := client.NewRPC(ctx, logger, cfg.L2URL)
if err != nil {
return nil, fmt.Errorf("failed to setup L2 RPC: %w", err)
}
if !d.ValidateClaim(eth.Bytes32(cfg.L2Claim)) {
return ErrClaimNotValid
l1ClCfg := sources.L1ClientDefaultConfig(cfg.Rollup, cfg.L1TrustRPC, cfg.L1RPCKind)
l2ClCfg := sources.L2ClientDefaultConfig(cfg.Rollup, true)
l1Cl, err := sources.NewL1Client(l1RPC, logger, nil, l1ClCfg)
if err != nil {
return nil, fmt.Errorf("failed to create L1 client: %w", err)
}
return nil
l2Cl, err := sources.NewL2Client(l2RPC, logger, nil, l2ClCfg)
if err != nil {
return nil, fmt.Errorf("failed to create L2 client: %w", err)
}
l2DebugCl := &L2Source{L2Client: l2Cl, DebugClient: sources.NewDebugClient(l2RPC.CallContext)}
return prefetcher.NewPrefetcher(logger, l1Cl, l2DebugCl, kv), nil
}
func asOracleFn(getter func(key common.Hash) ([]byte, error)) preimage.OracleFn {
return func(key preimage.Key) []byte {
pre, err := getter(key.PreimageKey())
if err != nil {
panic(fmt.Errorf("preimage unavailable for key %v: %w", key, err))
func initializeBootInfoAsync(bootInfo *cl.BootInfo, bootOracle *os.File) <-chan error {
bootWriteErr := make(chan error, 1)
go func() {
bootOracleWriter := cl.NewBootstrapOracleWriter(bootOracle)
bootWriteErr <- bootOracleWriter.WriteBootInfo(bootInfo)
close(bootWriteErr)
}()
return bootWriteErr
}
func routeHints(logger log.Logger, hintReader *preimage.HintReader, hinter func(hint string) error) {
go func() {
for {
if err := hintReader.NextHint(hinter); err != nil {
if err == io.EOF || errors.Is(err, fs.ErrClosed) {
logger.Debug("closing pre-image hint handler")
return
}
logger.Error("pre-image hint router error", "err", err)
return
}
}
return pre
}
}()
}
func asHinter(hint func(hint string) error) preimage.HinterFn {
return func(v preimage.Hint) {
err := hint(v.Hint())
if err != nil {
panic(fmt.Errorf("hint rejected %v: %w", v, err))
func launchOracleServer(logger log.Logger, server *preimage.OracleServer, getter func(key common.Hash) ([]byte, error)) {
go func() {
for {
if err := server.NextPreimageRequest(getter); err != nil {
if err == io.EOF || errors.Is(err, fs.ErrClosed) {
logger.Debug("closing pre-image server")
return
}
logger.Error("pre-image server error", "error", err)
return
}
}
}
}()
}
package kvstore
import (
"encoding/binary"
"encoding/json"
"github.com/ethereum-optimism/optimism/op-program/host/config"
"github.com/ethereum-optimism/optimism/op-program/preimage"
"github.com/ethereum/go-ethereum/common"
)
type LocalPreimageSource struct {
config *config.Config
}
func NewLocalPreimageSource(config *config.Config) *LocalPreimageSource {
return &LocalPreimageSource{config}
}
func localKey(num int64) common.Hash {
return preimage.LocalIndexKey(num).PreimageKey()
}
var (
L1HeadKey = localKey(1)
L2HeadKey = localKey(2)
L2ClaimKey = localKey(3)
L2ClaimBlockNumberKey = localKey(4)
L2ChainConfigKey = localKey(5)
RollupKey = localKey(6)
)
func (s *LocalPreimageSource) Get(key common.Hash) ([]byte, error) {
switch key {
case L1HeadKey:
return s.config.L1Head.Bytes(), nil
case L2HeadKey:
return s.config.L2Head.Bytes(), nil
case L2ClaimKey:
return s.config.L2Claim.Bytes(), nil
case L2ClaimBlockNumberKey:
return binary.BigEndian.AppendUint64(nil, s.config.L2ClaimBlockNumber), nil
case L2ChainConfigKey:
return json.Marshal(s.config.L2ChainConfig)
case RollupKey:
return json.Marshal(s.config.Rollup)
default:
return nil, ErrNotFound
}
}
package kvstore
import (
"encoding/binary"
"encoding/json"
"testing"
"github.com/ethereum-optimism/optimism/op-node/chaincfg"
"github.com/ethereum-optimism/optimism/op-program/host/config"
"github.com/ethereum-optimism/optimism/op-program/preimage"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/params"
"github.com/stretchr/testify/require"
)
func TestLocalPreimageSource(t *testing.T) {
cfg := &config.Config{
Rollup: &chaincfg.Goerli,
L1Head: common.HexToHash("0x1111"),
L2Head: common.HexToHash("0x2222"),
L2Claim: common.HexToHash("0x3333"),
L2ClaimBlockNumber: 1234,
L2ChainConfig: params.GoerliChainConfig,
}
source := NewLocalPreimageSource(cfg)
tests := []struct {
name string
key common.Hash
expected []byte
}{
{"L1Head", L1HeadKey, cfg.L1Head.Bytes()},
{"L2Head", L2HeadKey, cfg.L2Head.Bytes()},
{"L2Claim", L2ClaimKey, cfg.L2Claim.Bytes()},
{"L2ClaimBlockNumber", L2ClaimBlockNumberKey, binary.BigEndian.AppendUint64(nil, cfg.L2ClaimBlockNumber)},
{"Rollup", RollupKey, asJson(t, cfg.Rollup)},
{"ChainConfig", L2ChainConfigKey, asJson(t, cfg.L2ChainConfig)},
{"Unknown", preimage.LocalIndexKey(1000).PreimageKey(), nil},
}
for _, test := range tests {
t.Run(test.name, func(t *testing.T) {
result, err := source.Get(test.key)
if test.expected == nil {
require.ErrorIs(t, err, ErrNotFound)
} else {
require.NoError(t, err)
}
require.Equal(t, test.expected, result)
})
}
}
func asJson(t *testing.T, v any) []byte {
d, err := json.Marshal(v)
require.NoError(t, err)
return d
}
package kvstore
import (
"github.com/ethereum-optimism/optimism/op-program/preimage"
"github.com/ethereum/go-ethereum/common"
)
type PreimageSource func(key common.Hash) ([]byte, error)
type PreimageSourceSplitter struct {
local PreimageSource
global PreimageSource
}
func NewPreimageSourceSplitter(local PreimageSource, global PreimageSource) *PreimageSourceSplitter {
return &PreimageSourceSplitter{
local: local,
global: global,
}
}
func (s *PreimageSourceSplitter) Get(key common.Hash) ([]byte, error) {
if key[0] == byte(preimage.LocalKeyType) {
return s.local(key)
}
return s.global(key)
}
package kvstore
import (
"testing"
"github.com/ethereum-optimism/optimism/op-program/preimage"
"github.com/ethereum/go-ethereum/common"
"github.com/stretchr/testify/require"
)
func TestPreimageSourceSplitter(t *testing.T) {
localResult := []byte{1}
globalResult := []byte{2}
local := func(key common.Hash) ([]byte, error) { return localResult, nil }
global := func(key common.Hash) ([]byte, error) { return globalResult, nil }
splitter := NewPreimageSourceSplitter(local, global)
tests := []struct {
name string
keyPrefix byte
expected []byte
}{
{"Local", byte(preimage.LocalKeyType), localResult},
{"Keccak", byte(preimage.Keccak256KeyType), globalResult},
{"Generic", byte(3), globalResult},
{"Reserved", byte(4), globalResult},
{"Application", byte(255), globalResult},
}
for _, test := range tests {
t.Run(test.name, func(t *testing.T) {
key := common.Hash{0xff}
key[0] = test.keyPrefix
res, err := splitter.Get(key)
require.NoError(t, err)
require.Equal(t, test.expected, res)
})
}
}
......@@ -49,11 +49,13 @@ func NewPrefetcher(logger log.Logger, l1Fetcher L1Source, l2Fetcher L2Source, kv
}
func (p *Prefetcher) Hint(hint string) error {
p.logger.Trace("Received hint", "hint", hint)
p.lastHint = hint
return nil
}
func (p *Prefetcher) GetPreimage(ctx context.Context, key common.Hash) ([]byte, error) {
p.logger.Trace("Pre-image requested", "key", key)
pre, err := p.kvStore.Get(key)
if errors.Is(err, kvstore.ErrNotFound) && p.lastHint != "" {
hint := p.lastHint
......
package io
import (
"io"
"os"
)
// FileChannel is a unidirectional channel for file I/O
type FileChannel interface {
io.ReadWriteCloser
// Reader returns the file that is used for reading.
Reader() *os.File
// Writer returns the file that is used for writing.
Writer() *os.File
}
type ReadWritePair struct {
r *os.File
w *os.File
}
// NewReadWritePair creates a new FileChannel that uses the given files
func NewReadWritePair(r *os.File, w *os.File) *ReadWritePair {
return &ReadWritePair{r: r, w: w}
}
func (rw *ReadWritePair) Read(p []byte) (int, error) {
return rw.r.Read(p)
}
func (rw *ReadWritePair) Write(p []byte) (int, error) {
return rw.w.Write(p)
}
func (rw *ReadWritePair) Reader() *os.File {
return rw.r
}
func (rw *ReadWritePair) Writer() *os.File {
return rw.w
}
func (rw *ReadWritePair) Close() error {
if err := rw.r.Close(); err != nil {
return err
}
return rw.w.Close()
}
// CreateBidirectionalChannel creates a pair of FileChannels that are connected to each other.
func CreateBidirectionalChannel() (FileChannel, FileChannel, error) {
ar, bw, err := os.Pipe()
if err != nil {
return nil, nil, err
}
br, aw, err := os.Pipe()
if err != nil {
return nil, nil, err
}
return NewReadWritePair(ar, aw), NewReadWritePair(br, bw), nil
}
......@@ -9,13 +9,13 @@ import (
// HintWriter writes hints to an io.Writer (e.g. a special file descriptor, or a debug log),
// for a pre-image oracle service to prepare specific pre-images.
type HintWriter struct {
w io.Writer
rw io.ReadWriter
}
var _ Hinter = (*HintWriter)(nil)
func NewHintWriter(w io.Writer) *HintWriter {
return &HintWriter{w: w}
func NewHintWriter(rw io.ReadWriter) *HintWriter {
return &HintWriter{rw: rw}
}
func (hw *HintWriter) Hint(v Hint) {
......@@ -23,26 +23,29 @@ func (hw *HintWriter) Hint(v Hint) {
var hintBytes []byte
hintBytes = binary.BigEndian.AppendUint32(hintBytes, uint32(len(hint)))
hintBytes = append(hintBytes, []byte(hint)...)
hintBytes = append(hintBytes, 0) // to block writing on
_, err := hw.w.Write(hintBytes)
_, err := hw.rw.Write(hintBytes)
if err != nil {
panic(fmt.Errorf("failed to write pre-image hint: %w", err))
}
_, err = hw.rw.Read([]byte{0})
if err != nil {
panic(fmt.Errorf("failed to read pre-image hint ack: %w", err))
}
}
// HintReader reads the hints of HintWriter and passes them to a router for preparation of the requested pre-images.
// Onchain the written hints are no-op.
type HintReader struct {
r io.Reader
rw io.ReadWriter
}
func NewHintReader(r io.Reader) *HintReader {
return &HintReader{r: r}
func NewHintReader(rw io.ReadWriter) *HintReader {
return &HintReader{rw: rw}
}
func (hr *HintReader) NextHint(router func(hint string) error) error {
var length uint32
if err := binary.Read(hr.r, binary.BigEndian, &length); err != nil {
if err := binary.Read(hr.rw, binary.BigEndian, &length); err != nil {
if err == io.EOF {
return io.EOF
}
......@@ -50,17 +53,17 @@ func (hr *HintReader) NextHint(router func(hint string) error) error {
}
payload := make([]byte, length)
if length > 0 {
if _, err := io.ReadFull(hr.r, payload); err != nil {
if _, err := io.ReadFull(hr.rw, payload); err != nil {
return fmt.Errorf("failed to read hint payload (length %d): %w", length, err)
}
}
if err := router(string(payload)); err != nil {
// stream recovery
_, _ = hr.r.Read([]byte{0})
// write back on error to unblock the HintWriter
_, _ = hr.rw.Write([]byte{0})
return fmt.Errorf("failed to handle hint: %w", err)
}
if _, err := hr.r.Read([]byte{0}); err != nil {
return fmt.Errorf("failed to read trailing no-op byte to unblock hint writer: %w", err)
if _, err := hr.rw.Write([]byte{0}); err != nil {
return fmt.Errorf("failed to write trailing no-op byte to unblock hint writer: %w", err)
}
return nil
}
......@@ -5,7 +5,9 @@ import (
"crypto/rand"
"errors"
"io"
"sync"
"testing"
"time"
"github.com/stretchr/testify/require"
)
......@@ -20,26 +22,40 @@ func TestHints(t *testing.T) {
// Note: pretty much every string is valid communication:
// length, payload, 0. Worst case you run out of data, or allocate too much.
testHint := func(hints ...string) {
var buf bytes.Buffer
hw := NewHintWriter(&buf)
for _, h := range hints {
hw.Hint(rawHint(h))
}
hr := NewHintReader(&buf)
var got []string
for i := 0; i < 100; i++ { // sanity limit
err := hr.NextHint(func(hint string) error {
got = append(got, hint)
return nil
})
if err == io.EOF {
break
a, b := bidirectionalPipe()
var wg sync.WaitGroup
wg.Add(2)
go func() {
hw := NewHintWriter(a)
for _, h := range hints {
hw.Hint(rawHint(h))
}
require.NoError(t, err)
wg.Done()
}()
got := make(chan string, len(hints))
go func() {
defer wg.Done()
hr := NewHintReader(b)
for i := 0; i < len(hints); i++ {
err := hr.NextHint(func(hint string) error {
got <- hint
return nil
})
if err == io.EOF {
break
}
require.NoError(t, err)
}
}()
if waitTimeout(&wg) {
t.Error("hint read/write stuck")
}
require.Equal(t, len(hints), len(got), "got all hints")
for i, h := range hints {
require.Equal(t, h, got[i], "hints match")
for _, h := range hints {
require.Equal(t, h, <-got, "hints match")
}
}
......@@ -73,20 +89,47 @@ func TestHints(t *testing.T) {
require.ErrorIs(t, err, io.ErrUnexpectedEOF)
})
t.Run("cb error", func(t *testing.T) {
var buf bytes.Buffer
hw := NewHintWriter(&buf)
hw.Hint(rawHint("one"))
hw.Hint(rawHint("two"))
hr := NewHintReader(&buf)
cbErr := errors.New("fail")
err := hr.NextHint(func(hint string) error { return cbErr })
require.ErrorIs(t, err, cbErr)
var readHint string
err = hr.NextHint(func(hint string) error {
readHint = hint
return nil
})
require.NoError(t, err)
require.Equal(t, readHint, "two")
a, b := bidirectionalPipe()
var wg sync.WaitGroup
wg.Add(2)
go func() {
hw := NewHintWriter(a)
hw.Hint(rawHint("one"))
hw.Hint(rawHint("two"))
wg.Done()
}()
go func() {
defer wg.Done()
hr := NewHintReader(b)
cbErr := errors.New("fail")
err := hr.NextHint(func(hint string) error { return cbErr })
require.ErrorIs(t, err, cbErr)
var readHint string
err = hr.NextHint(func(hint string) error {
readHint = hint
return nil
})
require.NoError(t, err)
require.Equal(t, readHint, "two")
}()
if waitTimeout(&wg) {
t.Error("read/write hint stuck")
}
})
}
// waitTimeout returns true iff wg.Wait timed out
func waitTimeout(wg *sync.WaitGroup) bool {
done := make(chan struct{})
go func() {
wg.Wait()
close(done)
}()
select {
case <-time.After(time.Second * 30):
return true
case <-done:
return false
}
}
......@@ -33,8 +33,8 @@ const (
_ KeyType = 0
// LocalKeyType is for input-type pre-images, specific to the local program instance.
LocalKeyType KeyType = 1
// Keccak25Key6Type is for keccak256 pre-images, for any global shared pre-images.
Keccak25Key6Type KeyType = 2
// Keccak256KeyType is for keccak256 pre-images, for any global shared pre-images.
Keccak256KeyType KeyType = 2
)
// LocalIndexKey is a key local to the program, indexing a special program input.
......@@ -51,7 +51,7 @@ type Keccak256Key common.Hash
func (k Keccak256Key) PreimageKey() (out common.Hash) {
out = common.Hash(k) // copy the keccak hash
out[0] = byte(Keccak25Key6Type) // apply prefix
out[0] = byte(Keccak256KeyType) // apply prefix
return
}
......
......@@ -5,6 +5,7 @@ import "github.com/ethereum/go-ethereum/core/types"
type NoopTxMetrics struct{}
func (*NoopTxMetrics) RecordNonce(uint64) {}
func (*NoopTxMetrics) RecordPendingTx(int64) {}
func (*NoopTxMetrics) RecordGasBumpCount(int) {}
func (*NoopTxMetrics) RecordTxConfirmationLatency(int64) {}
func (*NoopTxMetrics) TxConfirmed(*types.Receipt) {}
......
......@@ -12,6 +12,7 @@ type TxMetricer interface {
RecordGasBumpCount(int)
RecordTxConfirmationLatency(int64)
RecordNonce(uint64)
RecordPendingTx(pending int64)
TxConfirmed(*types.Receipt)
TxPublished(string)
RPCError()
......@@ -24,6 +25,7 @@ type TxMetrics struct {
txFeeHistogram prometheus.Histogram
LatencyConfirmedTx prometheus.Gauge
currentNonce prometheus.Gauge
pendingTxs prometheus.Gauge
txPublishError *prometheus.CounterVec
publishEvent metrics.Event
confirmEvent metrics.EventVec
......@@ -82,6 +84,12 @@ func MakeTxMetrics(ns string, factory metrics.Factory) TxMetrics {
Help: "Current nonce of the from address",
Subsystem: "txmgr",
}),
pendingTxs: factory.NewGauge(prometheus.GaugeOpts{
Namespace: ns,
Name: "pending_txs",
Help: "Number of transactions pending receipts",
Subsystem: "txmgr",
}),
txPublishError: factory.NewCounterVec(prometheus.CounterOpts{
Namespace: ns,
Name: "tx_publish_error_count",
......@@ -103,6 +111,10 @@ func (t *TxMetrics) RecordNonce(nonce uint64) {
t.currentNonce.Set(float64(nonce))
}
func (t *TxMetrics) RecordPendingTx(pending int64) {
t.pendingTxs.Set(float64(pending))
}
// TxConfirmed records lots of information about the confirmed transaction
func (t *TxMetrics) TxConfirmed(receipt *types.Receipt) {
fee := float64(receipt.EffectiveGasPrice.Uint64() * receipt.GasUsed / params.GWei)
......
package txmgr
import (
"context"
"math"
"sync"
"github.com/ethereum/go-ethereum/core/types"
"golang.org/x/sync/errgroup"
)
type TxReceipt[T any] struct {
// ID can be used to identify unique tx receipts within the recept channel
ID T
// Receipt result from the transaction send
Receipt *types.Receipt
// Err contains any error that occurred during the tx send
Err error
}
type Queue[T any] struct {
ctx context.Context
txMgr TxManager
maxPending uint64
groupLock sync.Mutex
groupCtx context.Context
group *errgroup.Group
}
// NewQueue creates a new transaction sending Queue, with the following parameters:
// - maxPending: max number of pending txs at once (0 == no limit)
// - pendingChanged: called whenever a tx send starts or finishes. The
// number of currently pending txs is passed as a parameter.
func NewQueue[T any](ctx context.Context, txMgr TxManager, maxPending uint64) *Queue[T] {
if maxPending > math.MaxInt {
// ensure we don't overflow as errgroup only accepts int; in reality this will never be an issue
maxPending = math.MaxInt
}
return &Queue[T]{
ctx: ctx,
txMgr: txMgr,
maxPending: maxPending,
}
}
// Wait waits for all pending txs to complete (or fail).
func (q *Queue[T]) Wait() {
if q.group == nil {
return
}
_ = q.group.Wait()
}
// Send will wait until the number of pending txs is below the max pending,
// and then send the next tx.
//
// The actual tx sending is non-blocking, with the receipt returned on the
// provided receipt channel. If the channel is unbuffered, the goroutine is
// blocked from completing until the channel is read from.
func (q *Queue[T]) Send(id T, candidate TxCandidate, receiptCh chan TxReceipt[T]) {
group, ctx := q.groupContext()
group.Go(func() error {
return q.sendTx(ctx, id, candidate, receiptCh)
})
}
// TrySend sends the next tx, but only if the number of pending txs is below the
// max pending.
//
// Returns false if there is no room in the queue to send. Otherwise, the
// transaction is queued and this method returns true.
//
// The actual tx sending is non-blocking, with the receipt returned on the
// provided receipt channel. If the channel is unbuffered, the goroutine is
// blocked from completing until the channel is read from.
func (q *Queue[T]) TrySend(id T, candidate TxCandidate, receiptCh chan TxReceipt[T]) bool {
group, ctx := q.groupContext()
return group.TryGo(func() error {
return q.sendTx(ctx, id, candidate, receiptCh)
})
}
func (q *Queue[T]) sendTx(ctx context.Context, id T, candidate TxCandidate, receiptCh chan TxReceipt[T]) error {
receipt, err := q.txMgr.Send(ctx, candidate)
receiptCh <- TxReceipt[T]{
ID: id,
Receipt: receipt,
Err: err,
}
return err
}
// groupContext returns a Group and a Context to use when sending a tx.
//
// If any of the pending transactions returned an error, the queue's shared error Group is
// canceled. This method will wait on that Group for all pending transactions to return,
// and create a new Group with the queue's global context as its parent.
func (q *Queue[T]) groupContext() (*errgroup.Group, context.Context) {
q.groupLock.Lock()
defer q.groupLock.Unlock()
if q.groupCtx == nil || q.groupCtx.Err() != nil {
// no group exists, or the existing context has an error, so we need to wait
// for existing group threads to complete (if any) and create a new group
if q.group != nil {
_ = q.group.Wait()
}
q.group, q.groupCtx = errgroup.WithContext(q.ctx)
if q.maxPending > 0 {
q.group.SetLimit(int(q.maxPending))
}
}
return q.group, q.groupCtx
}
package txmgr
import (
"context"
"fmt"
"math/big"
"testing"
"time"
"github.com/ethereum-optimism/optimism/op-node/testlog"
"github.com/ethereum-optimism/optimism/op-service/txmgr/metrics"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/core"
"github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/log"
"github.com/stretchr/testify/require"
"golang.org/x/exp/slices"
)
type queueFunc func(id int, candidate TxCandidate, receiptCh chan TxReceipt[int], q *Queue[int]) bool
func sendQueueFunc(id int, candidate TxCandidate, receiptCh chan TxReceipt[int], q *Queue[int]) bool {
q.Send(id, candidate, receiptCh)
return true
}
func trySendQueueFunc(id int, candidate TxCandidate, receiptCh chan TxReceipt[int], q *Queue[int]) bool {
return q.TrySend(id, candidate, receiptCh)
}
type queueCall struct {
call queueFunc // queue call (either Send or TrySend, use function helpers above)
queued bool // true if the send was queued
txErr bool // true if the tx send should return an error
}
type testTx struct {
sendErr bool // error to return from send for this tx
}
type testCase struct {
name string // name of the test
max uint64 // max concurrency of the queue
calls []queueCall // calls to the queue
txs []testTx // txs to generate from the factory (and potentially error in send)
nonces []uint64 // expected sent tx nonces after all calls are made
total time.Duration // approx. total time it should take to complete all queue calls
}
type mockBackendWithNonce struct {
mockBackend
}
func newMockBackendWithNonce(g *gasPricer) *mockBackendWithNonce {
return &mockBackendWithNonce{
mockBackend: mockBackend{
g: g,
minedTxs: make(map[common.Hash]minedTxInfo),
},
}
}
func (b *mockBackendWithNonce) NonceAt(ctx context.Context, account common.Address, blockNumber *big.Int) (uint64, error) {
return uint64(len(b.minedTxs)), nil
}
func TestSend(t *testing.T) {
testCases := []testCase{
{
name: "success",
max: 5,
calls: []queueCall{
{call: trySendQueueFunc, queued: true},
{call: trySendQueueFunc, queued: true},
},
txs: []testTx{
{},
{},
},
nonces: []uint64{0, 1},
total: 1 * time.Second,
},
{
name: "no limit",
max: 0,
calls: []queueCall{
{call: trySendQueueFunc, queued: true},
{call: trySendQueueFunc, queued: true},
},
txs: []testTx{
{},
{},
},
nonces: []uint64{0, 1},
total: 1 * time.Second,
},
{
name: "single threaded",
max: 1,
calls: []queueCall{
{call: trySendQueueFunc, queued: true},
{call: trySendQueueFunc, queued: false},
{call: trySendQueueFunc, queued: false},
},
txs: []testTx{
{},
},
nonces: []uint64{0},
total: 1 * time.Second,
},
{
name: "single threaded blocking",
max: 1,
calls: []queueCall{
{call: trySendQueueFunc, queued: true},
{call: trySendQueueFunc, queued: false},
{call: sendQueueFunc, queued: true},
{call: sendQueueFunc, queued: true},
},
txs: []testTx{
{},
{},
{},
},
nonces: []uint64{0, 1, 2},
total: 3 * time.Second,
},
{
name: "dual threaded blocking",
max: 2,
calls: []queueCall{
{call: trySendQueueFunc, queued: true},
{call: trySendQueueFunc, queued: true},
{call: trySendQueueFunc, queued: false},
{call: sendQueueFunc, queued: true},
{call: sendQueueFunc, queued: true},
{call: sendQueueFunc, queued: true},
},
txs: []testTx{
{},
{},
{},
{},
{},
},
nonces: []uint64{0, 1, 2, 3, 4},
total: 3 * time.Second,
},
{
name: "subsequent txs fail after tx failure",
max: 1,
calls: []queueCall{
{call: sendQueueFunc, queued: true},
{call: sendQueueFunc, queued: true, txErr: true},
{call: sendQueueFunc, queued: true, txErr: true},
},
txs: []testTx{
{},
{sendErr: true},
{},
},
nonces: []uint64{0, 1, 1},
total: 3 * time.Second,
},
}
for _, test := range testCases {
test := test
t.Run(test.name, func(t *testing.T) {
t.Parallel()
conf := configWithNumConfs(1)
conf.ReceiptQueryInterval = 1 * time.Second // simulate a network send
conf.ResubmissionTimeout = 2 * time.Second // resubmit to detect errors
conf.SafeAbortNonceTooLowCount = 1
backend := newMockBackendWithNonce(newGasPricer(3))
mgr := &SimpleTxManager{
chainID: conf.ChainID,
name: "TEST",
cfg: conf,
backend: backend,
l: testlog.Logger(t, log.LvlCrit),
metr: &metrics.NoopTxMetrics{},
}
// track the nonces, and return any expected errors from tx sending
var nonces []uint64
sendTx := func(ctx context.Context, tx *types.Transaction) error {
index := int(tx.Data()[0])
nonces = append(nonces, tx.Nonce())
var testTx *testTx
if index < len(test.txs) {
testTx = &test.txs[index]
}
if testTx != nil && testTx.sendErr {
return core.ErrNonceTooLow
}
txHash := tx.Hash()
backend.mine(&txHash, tx.GasFeeCap())
return nil
}
backend.setTxSender(sendTx)
ctx, cancel := context.WithTimeout(context.Background(), 1*time.Minute)
defer cancel()
queue := NewQueue[int](ctx, mgr, test.max)
// make all the queue calls given in the test case
start := time.Now()
for i, c := range test.calls {
msg := fmt.Sprintf("Call %d", i)
c := c
receiptCh := make(chan TxReceipt[int], 1)
candidate := TxCandidate{
TxData: []byte{byte(i)},
To: &common.Address{},
}
queued := c.call(i, candidate, receiptCh, queue)
require.Equal(t, c.queued, queued, msg)
go func() {
r := <-receiptCh
if c.txErr {
require.Error(t, r.Err, msg)
} else {
require.NoError(t, r.Err, msg)
}
}()
}
// wait for the queue to drain (all txs complete or failed)
queue.Wait()
duration := time.Since(start)
// expect the execution time within a certain window
now := time.Now()
require.WithinDuration(t, now.Add(test.total), now.Add(duration), 500*time.Millisecond, "unexpected queue transaction timing")
// check that the nonces match
slices.Sort(nonces)
require.Equal(t, test.nonces, nonces, "expected nonces do not match")
})
}
}
......@@ -4,10 +4,10 @@ import (
"context"
"errors"
"fmt"
"math/big"
"strings"
"sync"
"sync/atomic"
"time"
"github.com/ethereum/go-ethereum"
......@@ -38,7 +38,7 @@ type TxManager interface {
// It can be stopped by cancelling the provided context; however, the transaction
// may be included on L1 even if the context is cancelled.
//
// NOTE: Send should be called by AT MOST one caller at a time.
// NOTE: Send can be called concurrently, the nonce will be managed internally.
Send(ctx context.Context, candidate TxCandidate) (*types.Receipt, error)
// From returns the sending address associated with the instance of the transaction manager.
......@@ -84,6 +84,11 @@ type SimpleTxManager struct {
backend ETHBackend
l log.Logger
metr metrics.TxMetricer
nonce *uint64
nonceLock sync.RWMutex
pending atomic.Int64
}
// NewSimpleTxManager initializes a new SimpleTxManager with the passed Config.
......@@ -126,8 +131,21 @@ type TxCandidate struct {
// The transaction manager handles all signing. If and only if the gas limit is 0, the
// transaction manager will do a gas estimation.
//
// NOTE: Send should be called by AT MOST one caller at a time.
// NOTE: Send can be called concurrently, the nonce will be managed internally.
func (m *SimpleTxManager) Send(ctx context.Context, candidate TxCandidate) (*types.Receipt, error) {
m.metr.RecordPendingTx(m.pending.Add(1))
defer func() {
m.metr.RecordPendingTx(m.pending.Add(-1))
}()
receipt, err := m.send(ctx, candidate)
if err != nil {
m.resetNonce()
}
return receipt, err
}
// send performs the actual transaction creation and sending.
func (m *SimpleTxManager) send(ctx context.Context, candidate TxCandidate) (*types.Receipt, error) {
if m.cfg.TxSendTimeout != 0 {
var cancel context.CancelFunc
ctx, cancel = context.WithTimeout(ctx, m.cfg.TxSendTimeout)
......@@ -137,7 +155,7 @@ func (m *SimpleTxManager) Send(ctx context.Context, candidate TxCandidate) (*typ
if err != nil {
return nil, fmt.Errorf("failed to create the tx: %w", err)
}
return m.send(ctx, tx)
return m.sendTx(ctx, tx)
}
// craftTx creates the signed transaction
......@@ -153,15 +171,10 @@ func (m *SimpleTxManager) craftTx(ctx context.Context, candidate TxCandidate) (*
}
gasFeeCap := calcGasFeeCap(basefee, gasTipCap)
// Fetch the sender's nonce from the latest known block (nil `blockNumber`)
childCtx, cancel := context.WithTimeout(ctx, m.cfg.NetworkTimeout)
defer cancel()
nonce, err := m.backend.NonceAt(childCtx, m.cfg.From, nil)
nonce, err := m.nextNonce(ctx)
if err != nil {
m.metr.RPCError()
return nil, fmt.Errorf("failed to get nonce: %w", err)
return nil, err
}
m.metr.RecordNonce(nonce)
rawTx := &types.DynamicFeeTx{
ChainID: m.chainID,
......@@ -192,14 +205,48 @@ func (m *SimpleTxManager) craftTx(ctx context.Context, candidate TxCandidate) (*
rawTx.Gas = gas
}
ctx, cancel = context.WithTimeout(ctx, m.cfg.NetworkTimeout)
ctx, cancel := context.WithTimeout(ctx, m.cfg.NetworkTimeout)
defer cancel()
return m.cfg.Signer(ctx, m.cfg.From, types.NewTx(rawTx))
}
// nextNonce returns a nonce to use for the next transaction. It uses
// eth_getTransactionCount with "latest" once, and then subsequent calls simply
// increment this number. If the transaction manager is reset, it will query the
// eth_getTransactionCount nonce again.
func (m *SimpleTxManager) nextNonce(ctx context.Context) (uint64, error) {
m.nonceLock.Lock()
defer m.nonceLock.Unlock()
if m.nonce == nil {
// Fetch the sender's nonce from the latest known block (nil `blockNumber`)
childCtx, cancel := context.WithTimeout(ctx, m.cfg.NetworkTimeout)
defer cancel()
nonce, err := m.backend.NonceAt(childCtx, m.cfg.From, nil)
if err != nil {
m.metr.RPCError()
return 0, fmt.Errorf("failed to get nonce: %w", err)
}
m.nonce = &nonce
} else {
*m.nonce++
}
m.metr.RecordNonce(*m.nonce)
return *m.nonce, nil
}
// resetNonce resets the internal nonce tracking. This is called if any pending send
// returns an error.
func (m *SimpleTxManager) resetNonce() {
m.nonceLock.Lock()
defer m.nonceLock.Unlock()
m.nonce = nil
}
// send submits the same transaction several times with increasing gas prices as necessary.
// It waits for the transaction to be confirmed on chain.
func (m *SimpleTxManager) send(ctx context.Context, tx *types.Transaction) (*types.Receipt, error) {
func (m *SimpleTxManager) sendTx(ctx context.Context, tx *types.Transaction) (*types.Receipt, error) {
var wg sync.WaitGroup
defer wg.Wait()
ctx, cancel := context.WithCancel(ctx)
......
......@@ -277,7 +277,7 @@ func TestTxMgrConfirmAtMinGasPrice(t *testing.T) {
ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
defer cancel()
receipt, err := h.mgr.send(ctx, tx)
receipt, err := h.mgr.sendTx(ctx, tx)
require.Nil(t, err)
require.NotNil(t, receipt)
require.Equal(t, gasPricer.expGasFeeCap().Uint64(), receipt.GasUsed)
......@@ -305,7 +305,7 @@ func TestTxMgrNeverConfirmCancel(t *testing.T) {
ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
defer cancel()
receipt, err := h.mgr.send(ctx, tx)
receipt, err := h.mgr.sendTx(ctx, tx)
require.Equal(t, err, context.DeadlineExceeded)
require.Nil(t, receipt)
}
......@@ -334,7 +334,7 @@ func TestTxMgrConfirmsAtHigherGasPrice(t *testing.T) {
ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
defer cancel()
receipt, err := h.mgr.send(ctx, tx)
receipt, err := h.mgr.sendTx(ctx, tx)
require.Nil(t, err)
require.NotNil(t, receipt)
require.Equal(t, h.gasPricer.expGasFeeCap().Uint64(), receipt.GasUsed)
......@@ -365,7 +365,7 @@ func TestTxMgrBlocksOnFailingRpcCalls(t *testing.T) {
ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
defer cancel()
receipt, err := h.mgr.send(ctx, tx)
receipt, err := h.mgr.sendTx(ctx, tx)
require.Equal(t, err, context.DeadlineExceeded)
require.Nil(t, receipt)
}
......@@ -443,7 +443,7 @@ func TestTxMgrOnlyOnePublicationSucceeds(t *testing.T) {
ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
defer cancel()
receipt, err := h.mgr.send(ctx, tx)
receipt, err := h.mgr.sendTx(ctx, tx)
require.Nil(t, err)
require.NotNil(t, receipt)
......@@ -478,7 +478,7 @@ func TestTxMgrConfirmsMinGasPriceAfterBumping(t *testing.T) {
ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
defer cancel()
receipt, err := h.mgr.send(ctx, tx)
receipt, err := h.mgr.sendTx(ctx, tx)
require.Nil(t, err)
require.NotNil(t, receipt)
require.Equal(t, h.gasPricer.expGasFeeCap().Uint64(), receipt.GasUsed)
......@@ -523,7 +523,7 @@ func TestTxMgrDoesntAbortNonceTooLowAfterMiningTx(t *testing.T) {
ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
defer cancel()
receipt, err := h.mgr.send(ctx, tx)
receipt, err := h.mgr.sendTx(ctx, tx)
require.Nil(t, err)
require.NotNil(t, receipt)
require.Equal(t, h.gasPricer.expGasFeeCap().Uint64(), receipt.GasUsed)
......@@ -870,3 +870,40 @@ func TestErrStringMatch(t *testing.T) {
})
}
}
func TestNonceReset(t *testing.T) {
conf := configWithNumConfs(1)
conf.SafeAbortNonceTooLowCount = 1
h := newTestHarnessWithConfig(t, conf)
index := -1
var nonces []uint64
sendTx := func(ctx context.Context, tx *types.Transaction) error {
index++
nonces = append(nonces, tx.Nonce())
// fail every 3rd tx
if index%3 == 0 {
return core.ErrNonceTooLow
}
txHash := tx.Hash()
h.backend.mine(&txHash, tx.GasFeeCap())
return nil
}
h.backend.setTxSender(sendTx)
ctx := context.Background()
for i := 0; i < 8; i++ {
_, err := h.mgr.Send(ctx, TxCandidate{
To: &common.Address{},
})
// expect every 3rd tx to fail
if i%3 == 0 {
require.Error(t, err)
} else {
require.NoError(t, err)
}
}
// internal nonce tracking should be reset every 3rd tx
require.Equal(t, []uint64{0, 0, 1, 2, 0, 1, 2, 0}, nonces)
}
......@@ -18,10 +18,14 @@ Vitest snapshots for the vitest tests
CLI implementations of atst read and write
## contants
## constants
Internal and external constants
## contracts
The attestation station contract
## lib
All library code for the sdk lives here
......@@ -32,4 +36,4 @@ Test helpers
## types
Zod and typscript types
\ No newline at end of file
Zod and typscript types
../../../contracts-periphery/contracts/universal/op-nft/AttestationStation.sol
\ No newline at end of file
......@@ -4,7 +4,9 @@ import { describe, it, expect } from 'vitest'
import { getEvents } from './getEvents'
describe(getEvents.name, () => {
it('should get events on goerli', async () => {
// sinc this test is using https://goerli.optimism.io it is currently skipped
// we should start anvil for goerli too and then we can remove this skip
it.skipIf(process.env.CI)('should get events on goerli', async () => {
const key = 'animalfarm.school.attended'
const creator = '0xBCf86Fd70a0183433763ab0c14E7a760194f3a9F'
expect(
......
......@@ -5,16 +5,16 @@ Bytes_slice_Test:test_slice_fromZeroIdx_works() (gas: 20826)
Bytes_toNibbles_Test:test_toNibbles_expectedResult128Bytes_works() (gas: 129874)
Bytes_toNibbles_Test:test_toNibbles_expectedResult5Bytes_works() (gas: 6132)
Bytes_toNibbles_Test:test_toNibbles_zeroLengthInput_works() (gas: 944)
CrossDomainMessenger_BaseGas_Test:test_baseGas_succeeds() (gas: 20097)
CrossDomainMessenger_BaseGas_Test:test_baseGas_succeeds() (gas: 20412)
CrossDomainOwnable2_Test:test_onlyOwner_notMessenger_reverts() (gas: 8416)
CrossDomainOwnable2_Test:test_onlyOwner_notOwner2_reverts() (gas: 57254)
CrossDomainOwnable2_Test:test_onlyOwner_notOwner_reverts() (gas: 16566)
CrossDomainOwnable2_Test:test_onlyOwner_succeeds() (gas: 73282)
CrossDomainOwnable2_Test:test_onlyOwner_notOwner2_reverts() (gas: 57507)
CrossDomainOwnable2_Test:test_onlyOwner_notOwner_reverts() (gas: 16588)
CrossDomainOwnable2_Test:test_onlyOwner_succeeds() (gas: 73535)
CrossDomainOwnable3_Test:test_constructor_succeeds() (gas: 10554)
CrossDomainOwnable3_Test:test_crossDomainOnlyOwner_notMessenger_reverts() (gas: 28334)
CrossDomainOwnable3_Test:test_crossDomainOnlyOwner_notOwner2_reverts() (gas: 73730)
CrossDomainOwnable3_Test:test_crossDomainOnlyOwner_notOwner_reverts() (gas: 31978)
CrossDomainOwnable3_Test:test_crossDomainTransferOwnership_succeeds() (gas: 91287)
CrossDomainOwnable3_Test:test_crossDomainOnlyOwner_notOwner2_reverts() (gas: 73983)
CrossDomainOwnable3_Test:test_crossDomainOnlyOwner_notOwner_reverts() (gas: 32000)
CrossDomainOwnable3_Test:test_crossDomainTransferOwnership_succeeds() (gas: 91540)
CrossDomainOwnable3_Test:test_localOnlyOwner_notOwner_reverts() (gas: 13193)
CrossDomainOwnable3_Test:test_localOnlyOwner_succeeds() (gas: 35220)
CrossDomainOwnable3_Test:test_localTransferOwnership_succeeds() (gas: 52128)
......@@ -29,12 +29,12 @@ DeployerWhitelist_Test:test_owner_succeeds() (gas: 7582)
DeployerWhitelist_Test:test_storageSlots_succeeds() (gas: 33395)
FeeVault_Test:test_constructor_succeeds() (gas: 10736)
FeeVault_Test:test_minWithdrawalAmount_succeeds() (gas: 10713)
GasBenchMark_L1CrossDomainMessenger:test_sendMessage_benchmark_0() (gas: 266854)
GasBenchMark_L1CrossDomainMessenger:test_sendMessage_benchmark_1() (gas: 2100005)
GasBenchMark_L1StandardBridge_Deposit:test_depositERC20_benchmark_0() (gas: 452633)
GasBenchMark_L1StandardBridge_Deposit:test_depositERC20_benchmark_1() (gas: 3199770)
GasBenchMark_L1StandardBridge_Deposit:test_depositETH_benchmark_0() (gas: 353890)
GasBenchMark_L1StandardBridge_Deposit:test_depositETH_benchmark_1() (gas: 2634733)
GasBenchMark_L1CrossDomainMessenger:test_sendMessage_benchmark_0() (gas: 352160)
GasBenchMark_L1CrossDomainMessenger:test_sendMessage_benchmark_1() (gas: 2950367)
GasBenchMark_L1StandardBridge_Deposit:test_depositERC20_benchmark_0() (gas: 537939)
GasBenchMark_L1StandardBridge_Deposit:test_depositERC20_benchmark_1() (gas: 4050132)
GasBenchMark_L1StandardBridge_Deposit:test_depositETH_benchmark_0() (gas: 439196)
GasBenchMark_L1StandardBridge_Deposit:test_depositETH_benchmark_1() (gas: 3485095)
GasBenchMark_L1StandardBridge_Finalize:test_finalizeETHWithdrawal_benchmark() (gas: 40409)
GasBenchMark_L2OutputOracle:test_proposeL2Output_benchmark() (gas: 88513)
GasBenchMark_OptimismPortal:test_depositTransaction_benchmark() (gas: 75078)
......@@ -68,43 +68,43 @@ L1BlockTest:test_number_succeeds() (gas: 7629)
L1BlockTest:test_sequenceNumber_succeeds() (gas: 7630)
L1BlockTest:test_timestamp_succeeds() (gas: 7640)
L1BlockTest:test_updateValues_succeeds() (gas: 60482)
L1CrossDomainMessenger_Test:test_messageVersion_succeeds() (gas: 24715)
L1CrossDomainMessenger_Test:test_relayMessage_legacyOldReplay_reverts() (gas: 49394)
L1CrossDomainMessenger_Test:test_relayMessage_legacyRetryAfterFailureThenSuccess_reverts() (gas: 209286)
L1CrossDomainMessenger_Test:test_relayMessage_legacyRetryAfterFailure_succeeds() (gas: 203184)
L1CrossDomainMessenger_Test:test_relayMessage_legacyRetryAfterSuccess_reverts() (gas: 123784)
L1CrossDomainMessenger_Test:test_relayMessage_legacy_succeeds() (gas: 77098)
L1CrossDomainMessenger_Test:test_relayMessage_retryAfterFailure_succeeds() (gas: 197091)
L1CrossDomainMessenger_Test:test_relayMessage_succeeds() (gas: 74034)
L1CrossDomainMessenger_Test:test_messageVersion_succeeds() (gas: 24738)
L1CrossDomainMessenger_Test:test_relayMessage_legacyOldReplay_reverts() (gas: 49395)
L1CrossDomainMessenger_Test:test_relayMessage_legacyRetryAfterFailureThenSuccess_reverts() (gas: 209750)
L1CrossDomainMessenger_Test:test_relayMessage_legacyRetryAfterFailure_succeeds() (gas: 203648)
L1CrossDomainMessenger_Test:test_relayMessage_legacyRetryAfterSuccess_reverts() (gas: 124016)
L1CrossDomainMessenger_Test:test_relayMessage_legacy_succeeds() (gas: 77330)
L1CrossDomainMessenger_Test:test_relayMessage_retryAfterFailure_succeeds() (gas: 197555)
L1CrossDomainMessenger_Test:test_relayMessage_succeeds() (gas: 74266)
L1CrossDomainMessenger_Test:test_relayMessage_toSystemContract_reverts() (gas: 56540)
L1CrossDomainMessenger_Test:test_relayMessage_v2_reverts() (gas: 12365)
L1CrossDomainMessenger_Test:test_replayMessage_withValue_reverts() (gas: 31063)
L1CrossDomainMessenger_Test:test_sendMessage_succeeds() (gas: 304740)
L1CrossDomainMessenger_Test:test_sendMessage_twice_succeeds() (gas: 1496124)
L1CrossDomainMessenger_Test:test_xDomainMessageSender_reset_succeeds() (gas: 84563)
L1CrossDomainMessenger_Test:test_xDomainSender_notSet_reverts() (gas: 24296)
L1CrossDomainMessenger_Test:test_sendMessage_succeeds() (gas: 390676)
L1CrossDomainMessenger_Test:test_sendMessage_twice_succeeds() (gas: 1666736)
L1CrossDomainMessenger_Test:test_xDomainMessageSender_reset_succeeds() (gas: 84708)
L1CrossDomainMessenger_Test:test_xDomainSender_notSet_reverts() (gas: 24253)
L1ERC721Bridge_Test:test_bridgeERC721To_localTokenZeroAddress_reverts() (gas: 52707)
L1ERC721Bridge_Test:test_bridgeERC721To_remoteTokenZeroAddress_reverts() (gas: 27310)
L1ERC721Bridge_Test:test_bridgeERC721To_succeeds() (gas: 359991)
L1ERC721Bridge_Test:test_bridgeERC721To_succeeds() (gas: 445297)
L1ERC721Bridge_Test:test_bridgeERC721To_wrongOwner_reverts() (gas: 60934)
L1ERC721Bridge_Test:test_bridgeERC721_fromContract_reverts() (gas: 25666)
L1ERC721Bridge_Test:test_bridgeERC721_localTokenZeroAddress_reverts() (gas: 50564)
L1ERC721Bridge_Test:test_bridgeERC721_remoteTokenZeroAddress_reverts() (gas: 25124)
L1ERC721Bridge_Test:test_bridgeERC721_succeeds() (gas: 357571)
L1ERC721Bridge_Test:test_bridgeERC721_succeeds() (gas: 442877)
L1ERC721Bridge_Test:test_bridgeERC721_wrongOwner_reverts() (gas: 60830)
L1ERC721Bridge_Test:test_constructor_succeeds() (gas: 10200)
L1ERC721Bridge_Test:test_finalizeBridgeERC721_notEscrowed_reverts() (gas: 22119)
L1ERC721Bridge_Test:test_finalizeBridgeERC721_notFromRemoteMessenger_reverts() (gas: 19797)
L1ERC721Bridge_Test:test_finalizeBridgeERC721_notViaLocalMessenger_reverts() (gas: 16049)
L1ERC721Bridge_Test:test_finalizeBridgeERC721_selfToken_reverts() (gas: 17615)
L1ERC721Bridge_Test:test_finalizeBridgeERC721_succeeds() (gas: 329083)
L1StandardBridge_BridgeETHTo_Test:test_bridgeETHTo_succeeds() (gas: 424648)
L1StandardBridge_BridgeETH_Test:test_bridgeETH_succeeds() (gas: 411869)
L1StandardBridge_DepositERC20To_Test:test_depositERC20To_succeeds() (gas: 630124)
L1StandardBridge_DepositERC20_Test:test_depositERC20_succeeds() (gas: 627825)
L1ERC721Bridge_Test:test_finalizeBridgeERC721_succeeds() (gas: 414389)
L1StandardBridge_BridgeETHTo_Test:test_bridgeETHTo_succeeds() (gas: 510269)
L1StandardBridge_BridgeETH_Test:test_bridgeETH_succeeds() (gas: 497490)
L1StandardBridge_DepositERC20To_Test:test_depositERC20To_succeeds() (gas: 715745)
L1StandardBridge_DepositERC20_Test:test_depositERC20_succeeds() (gas: 713446)
L1StandardBridge_DepositERC20_TestFail:test_depositERC20_notEoa_reverts() (gas: 22320)
L1StandardBridge_DepositETHTo_Test:test_depositETHTo_succeeds() (gas: 424725)
L1StandardBridge_DepositETH_Test:test_depositETH_succeeds() (gas: 411963)
L1StandardBridge_DepositETHTo_Test:test_depositETHTo_succeeds() (gas: 510346)
L1StandardBridge_DepositETH_Test:test_depositETH_succeeds() (gas: 497584)
L1StandardBridge_DepositETH_TestFail:test_depositETH_notEoa_reverts() (gas: 40780)
L1StandardBridge_FinalizeBridgeETH_Test:test_finalizeBridgeETH_succeeds() (gas: 51674)
L1StandardBridge_FinalizeBridgeETH_TestFail:test_finalizeBridgeETH_incorrectValue_reverts() (gas: 34204)
......@@ -116,32 +116,32 @@ L1StandardBridge_FinalizeERC20Withdrawal_TestFail:test_finalizeERC20Withdrawal_n
L1StandardBridge_FinalizeETHWithdrawal_Test:test_finalizeETHWithdrawal_succeeds() (gas: 61722)
L1StandardBridge_Getter_Test:test_getters_succeeds() (gas: 32173)
L1StandardBridge_Initialize_Test:test_initialize_succeeds() (gas: 22050)
L1StandardBridge_Receive_Test:test_receive_succeeds() (gas: 525438)
L2CrossDomainMessenger_Test:test_messageVersion_succeeds() (gas: 8411)
L2CrossDomainMessenger_Test:test_relayMessage_retry_succeeds() (gas: 163159)
L2CrossDomainMessenger_Test:test_relayMessage_succeeds() (gas: 48640)
L1StandardBridge_Receive_Test:test_receive_succeeds() (gas: 610744)
L2CrossDomainMessenger_Test:test_messageVersion_succeeds() (gas: 8434)
L2CrossDomainMessenger_Test:test_relayMessage_retry_succeeds() (gas: 163755)
L2CrossDomainMessenger_Test:test_relayMessage_succeeds() (gas: 48938)
L2CrossDomainMessenger_Test:test_relayMessage_toSystemContract_reverts() (gas: 29021)
L2CrossDomainMessenger_Test:test_relayMessage_v2_reverts() (gas: 11711)
L2CrossDomainMessenger_Test:test_sendMessage_succeeds() (gas: 122508)
L2CrossDomainMessenger_Test:test_sendMessage_twice_succeeds() (gas: 134826)
L2CrossDomainMessenger_Test:test_xDomainMessageSender_reset_succeeds() (gas: 48139)
L2CrossDomainMessenger_Test:test_xDomainSender_senderNotSet_reverts() (gas: 10590)
L2CrossDomainMessenger_Test:test_sendMessage_succeeds() (gas: 123768)
L2CrossDomainMessenger_Test:test_sendMessage_twice_succeeds() (gas: 135456)
L2CrossDomainMessenger_Test:test_xDomainMessageSender_reset_succeeds() (gas: 48414)
L2CrossDomainMessenger_Test:test_xDomainSender_senderNotSet_reverts() (gas: 10612)
L2ERC721Bridge_Test:test_bridgeERC721To_localTokenZeroAddress_reverts() (gas: 26431)
L2ERC721Bridge_Test:test_bridgeERC721To_remoteTokenZeroAddress_reverts() (gas: 21814)
L2ERC721Bridge_Test:test_bridgeERC721To_succeeds() (gas: 147041)
L2ERC721Bridge_Test:test_bridgeERC721To_succeeds() (gas: 147356)
L2ERC721Bridge_Test:test_bridgeERC721To_wrongOwner_reverts() (gas: 29449)
L2ERC721Bridge_Test:test_bridgeERC721_fromContract_reverts() (gas: 22148)
L2ERC721Bridge_Test:test_bridgeERC721_localTokenZeroAddress_reverts() (gas: 24310)
L2ERC721Bridge_Test:test_bridgeERC721_remoteTokenZeroAddress_reverts() (gas: 19628)
L2ERC721Bridge_Test:test_bridgeERC721_succeeds() (gas: 144643)
L2ERC721Bridge_Test:test_bridgeERC721_succeeds() (gas: 144958)
L2ERC721Bridge_Test:test_bridgeERC721_wrongOwner_reverts() (gas: 29258)
L2ERC721Bridge_Test:test_constructor_succeeds() (gas: 10110)
L2ERC721Bridge_Test:test_finalizeBridgeERC721_alreadyExists_reverts() (gas: 29128)
L2ERC721Bridge_Test:test_finalizeBridgeERC721_interfaceNotCompliant_reverts() (gas: 236012)
L2ERC721Bridge_Test:test_finalizeBridgeERC721_interfaceNotCompliant_reverts() (gas: 236327)
L2ERC721Bridge_Test:test_finalizeBridgeERC721_notFromRemoteMessenger_reverts() (gas: 19874)
L2ERC721Bridge_Test:test_finalizeBridgeERC721_notViaLocalMessenger_reverts() (gas: 16104)
L2ERC721Bridge_Test:test_finalizeBridgeERC721_selfToken_reverts() (gas: 17659)
L2ERC721Bridge_Test:test_finalizeBridgeERC721_succeeds() (gas: 168970)
L2ERC721Bridge_Test:test_finalizeBridgeERC721_succeeds() (gas: 169285)
L2OutputOracleTest:test_computeL2Timestamp_succeeds() (gas: 37298)
L2OutputOracleTest:test_constructor_badTimestamp_reverts() (gas: 70991)
L2OutputOracleTest:test_constructor_l2BlockTimeZero_reverts() (gas: 45954)
......@@ -172,13 +172,13 @@ L2OutputOracleUpgradeable_Test:test_initValuesOnProxy_succeeds() (gas: 26208)
L2OutputOracleUpgradeable_Test:test_initializeImpl_alreadyInitialized_reverts() (gas: 15149)
L2OutputOracleUpgradeable_Test:test_initializeProxy_alreadyInitialized_reverts() (gas: 20175)
L2OutputOracleUpgradeable_Test:test_upgrading_succeeds() (gas: 180481)
L2StandardBridge_BridgeERC20To_Test:test_bridgeERC20To_succeeds() (gas: 389773)
L2StandardBridge_BridgeERC20To_Test:test_withdrawTo_withdrawingERC20_succeeds() (gas: 390006)
L2StandardBridge_BridgeERC20_Test:test_bridgeERC20_succeeds() (gas: 385280)
L2StandardBridge_BridgeERC20_Test:test_bridgeLegacyERC20_succeeds() (gas: 393552)
L2StandardBridge_BridgeERC20_Test:test_withdrawLegacyERC20_succeeds() (gas: 393878)
L2StandardBridge_BridgeERC20To_Test:test_bridgeERC20To_succeeds() (gas: 390277)
L2StandardBridge_BridgeERC20To_Test:test_withdrawTo_withdrawingERC20_succeeds() (gas: 390510)
L2StandardBridge_BridgeERC20_Test:test_bridgeERC20_succeeds() (gas: 385784)
L2StandardBridge_BridgeERC20_Test:test_bridgeLegacyERC20_succeeds() (gas: 394056)
L2StandardBridge_BridgeERC20_Test:test_withdrawLegacyERC20_succeeds() (gas: 394382)
L2StandardBridge_BridgeERC20_Test:test_withdraw_notEOA_reverts() (gas: 251758)
L2StandardBridge_BridgeERC20_Test:test_withdraw_withdrawingERC20_succeeds() (gas: 385508)
L2StandardBridge_BridgeERC20_Test:test_withdraw_withdrawingERC20_succeeds() (gas: 386012)
L2StandardBridge_Bridge_Test:test_finalizeBridgeETH_incorrectValue_reverts() (gas: 23843)
L2StandardBridge_Bridge_Test:test_finalizeBridgeETH_sendToMessenger_reverts() (gas: 23982)
L2StandardBridge_Bridge_Test:test_finalizeBridgeETH_sendToSelf_reverts() (gas: 23870)
......@@ -186,8 +186,8 @@ L2StandardBridge_Bridge_Test:test_finalizeDeposit_depositingERC20_succeeds() (ga
L2StandardBridge_Bridge_Test:test_finalizeDeposit_depositingETH_succeeds() (gas: 92700)
L2StandardBridge_FinalizeBridgeETH_Test:test_finalizeBridgeETH_succeeds() (gas: 43155)
L2StandardBridge_Test:test_initialize_succeeds() (gas: 24292)
L2StandardBridge_Test:test_receive_succeeds() (gas: 174011)
L2StandardBridge_Test:test_withdraw_ether_succeeds() (gas: 140478)
L2StandardBridge_Test:test_receive_succeeds() (gas: 174641)
L2StandardBridge_Test:test_withdraw_ether_succeeds() (gas: 140793)
L2StandardBridge_Test:test_withdraw_insufficientValue_reverts() (gas: 16485)
L2ToL1MessagePasserTest:test_burn_succeeds() (gas: 112572)
L2ToL1MessagePasserTest:test_initiateWithdrawal_fromContract_succeeds() (gas: 70445)
......@@ -264,13 +264,13 @@ OptimismPortal_FinalizeWithdrawal_Test:test_finalizeWithdrawalTransaction_ifOutp
OptimismPortal_FinalizeWithdrawal_Test:test_finalizeWithdrawalTransaction_ifOutputTimestampIsNotFinalized_reverts() (gas: 207497)
OptimismPortal_FinalizeWithdrawal_Test:test_finalizeWithdrawalTransaction_ifWithdrawalNotProven_reverts() (gas: 41753)
OptimismPortal_FinalizeWithdrawal_Test:test_finalizeWithdrawalTransaction_ifWithdrawalProofNotOldEnough_reverts() (gas: 199441)
OptimismPortal_FinalizeWithdrawal_Test:test_finalizeWithdrawalTransaction_onInsufficientGas_reverts() (gas: 205795)
OptimismPortal_FinalizeWithdrawal_Test:test_finalizeWithdrawalTransaction_onInsufficientGas_reverts() (gas: 205862)
OptimismPortal_FinalizeWithdrawal_Test:test_finalizeWithdrawalTransaction_onRecentWithdrawal_reverts() (gas: 180206)
OptimismPortal_FinalizeWithdrawal_Test:test_finalizeWithdrawalTransaction_onReentrancy_reverts() (gas: 243812)
OptimismPortal_FinalizeWithdrawal_Test:test_finalizeWithdrawalTransaction_onReplay_reverts() (gas: 245528)
OptimismPortal_FinalizeWithdrawal_Test:test_finalizeWithdrawalTransaction_onReentrancy_reverts() (gas: 243881)
OptimismPortal_FinalizeWithdrawal_Test:test_finalizeWithdrawalTransaction_onReplay_reverts() (gas: 245597)
OptimismPortal_FinalizeWithdrawal_Test:test_finalizeWithdrawalTransaction_paused_reverts() (gas: 53576)
OptimismPortal_FinalizeWithdrawal_Test:test_finalizeWithdrawalTransaction_provenWithdrawalHash_succeeds() (gas: 234941)
OptimismPortal_FinalizeWithdrawal_Test:test_finalizeWithdrawalTransaction_targetFails_fails() (gas: 8797746687696163864)
OptimismPortal_FinalizeWithdrawal_Test:test_finalizeWithdrawalTransaction_provenWithdrawalHash_succeeds() (gas: 235010)
OptimismPortal_FinalizeWithdrawal_Test:test_finalizeWithdrawalTransaction_targetFails_fails() (gas: 8797746687696163867)
OptimismPortal_FinalizeWithdrawal_Test:test_finalizeWithdrawalTransaction_timestampLessThanL2OracleStart_reverts() (gas: 197019)
OptimismPortal_FinalizeWithdrawal_Test:test_proveWithdrawalTransaction_onInvalidOutputRootProof_reverts() (gas: 85690)
OptimismPortal_FinalizeWithdrawal_Test:test_proveWithdrawalTransaction_onInvalidWithdrawalProof_reverts() (gas: 137350)
......@@ -404,15 +404,15 @@ ResourceMetering_Test:test_meter_updateTenEmptyBlocks_succeeds() (gas: 23747)
ResourceMetering_Test:test_meter_updateTwoEmptyBlocks_succeeds() (gas: 23703)
ResourceMetering_Test:test_meter_useMax_succeeds() (gas: 20020816)
ResourceMetering_Test:test_meter_useMoreThanMax_reverts() (gas: 19549)
SafeCall_call_Test:test_callWithMinGas_noLeakageHigh_succeeds() (gas: 2075873614)
SafeCall_call_Test:test_callWithMinGas_noLeakageLow_succeeds() (gas: 753665282)
SafeCall_Test:test_callWithMinGas_noLeakageHigh_succeeds() (gas: 1020974534)
SafeCall_Test:test_callWithMinGas_noLeakageLow_succeeds() (gas: 1094812728)
Semver_Test:test_behindProxy_succeeds() (gas: 506748)
Semver_Test:test_version_succeeds() (gas: 9418)
SequencerFeeVault_Test:test_constructor_succeeds() (gas: 5526)
SequencerFeeVault_Test:test_minWithdrawalAmount_succeeds() (gas: 5442)
SequencerFeeVault_Test:test_receive_succeeds() (gas: 17373)
SequencerFeeVault_Test:test_withdraw_notEnough_reverts() (gas: 9331)
SequencerFeeVault_Test:test_withdraw_succeeds() (gas: 163228)
SequencerFeeVault_Test:test_withdraw_succeeds() (gas: 163543)
SetPrevBaseFee_Test:test_setPrevBaseFee_succeeds() (gas: 11515)
StandardBridge_Stateless_Test:test_isCorrectTokenPair_succeeds() (gas: 49936)
StandardBridge_Stateless_Test:test_isOptimismMintableERC20_succeeds() (gas: 33072)
......
......@@ -20,12 +20,12 @@ contract L1CrossDomainMessenger is CrossDomainMessenger, Semver {
OptimismPortal public immutable PORTAL;
/**
* @custom:semver 1.2.0
* @custom:semver 1.3.0
*
* @param _portal Address of the OptimismPortal contract on this network.
*/
constructor(OptimismPortal _portal)
Semver(1, 2, 0)
Semver(1, 3, 0)
CrossDomainMessenger(Predeploys.L2_CROSS_DOMAIN_MESSENGER)
{
PORTAL = _portal;
......
......@@ -140,7 +140,7 @@ contract OptimismPortal is Initializable, ResourceMetering, Semver {
}
/**
* @custom:semver 1.3.1
* @custom:semver 1.4.0
*
* @param _l2Oracle Address of the L2OutputOracle contract.
* @param _guardian Address that can pause deposits and withdrawals.
......@@ -152,7 +152,7 @@ contract OptimismPortal is Initializable, ResourceMetering, Semver {
address _guardian,
bool _paused,
SystemConfig _config
) Semver(1, 3, 1) {
) Semver(1, 4, 0) {
L2_ORACLE = _l2Oracle;
GUARDIAN = _guardian;
SYSTEM_CONFIG = _config;
......@@ -388,11 +388,9 @@ contract OptimismPortal is Initializable, ResourceMetering, Semver {
// SafeCall.callWithMinGas to ensure two key properties
// 1. Target contracts cannot force this call to run out of gas by returning a very large
// amount of data (and this is OK because we don't care about the returndata here).
// 2. The amount of gas provided to the call to the target contract is at least the gas
// limit specified by the user. If there is not enough gas in the callframe to
// accomplish this, `callWithMinGas` will revert.
// Additionally, if there is not enough gas remaining to complete the execution after the
// call returns, this function will revert.
// 2. The amount of gas provided to the execution context of the target is at least the
// gas limit specified by the user. If there is not enough gas in the current context
// to accomplish this, `callWithMinGas` will revert.
bool success = SafeCall.callWithMinGas(_tx.target, _tx.gasLimit, _tx.value, _tx.data);
// Reset the l2Sender back to the default value.
......
......@@ -17,12 +17,12 @@ import { L2ToL1MessagePasser } from "./L2ToL1MessagePasser.sol";
*/
contract L2CrossDomainMessenger is CrossDomainMessenger, Semver {
/**
* @custom:semver 1.2.0
* @custom:semver 1.3.0
*
* @param _l1CrossDomainMessenger Address of the L1CrossDomainMessenger contract.
*/
constructor(address _l1CrossDomainMessenger)
Semver(1, 2, 0)
Semver(1, 3, 0)
CrossDomainMessenger(_l1CrossDomainMessenger)
{
initialize();
......
......@@ -35,6 +35,41 @@ library SafeCall {
return _success;
}
/**
* @notice Helper function to determine if there is sufficient gas remaining within the context
* to guarantee that the minimum gas requirement for a call will be met as well as
* optionally reserving a specified amount of gas for after the call has concluded.
* @param _minGas The minimum amount of gas that may be passed to the target context.
* @param _reservedGas Optional amount of gas to reserve for the caller after the execution
* of the target context.
* @return `true` if there is enough gas remaining to safely supply `_minGas` to the target
* context as well as reserve `_reservedGas` for the caller after the execution of
* the target context.
* @dev !!!!! FOOTGUN ALERT !!!!!
* 1.) The 40_000 base buffer is to account for the worst case of the dynamic cost of the
* `CALL` opcode's `address_access_cost`, `positive_value_cost`, and
* `value_to_empty_account_cost` factors with an added buffer of 5,700 gas. It is
* still possible to self-rekt by initiating a withdrawal with a minimum gas limit
* that does not account for the `memory_expansion_cost` & `code_execution_cost`
* factors of the dynamic cost of the `CALL` opcode.
* 2.) This function should *directly* precede the external call if possible. There is an
* added buffer to account for gas consumed between this check and the call, but it
* is only 5,700 gas.
* 3.) Because EIP-150 ensures that a maximum of 63/64ths of the remaining gas in the call
* frame may be passed to a subcontext, we need to ensure that the gas will not be
* truncated.
* 4.) Use wisely. This function is not a silver bullet.
*/
function hasMinGas(uint256 _minGas, uint256 _reservedGas) internal view returns (bool) {
bool _hasMinGas;
assembly {
_hasMinGas := iszero(
lt(gas(), add(div(mul(_minGas, 64), 63), add(40000, _reservedGas)))
)
}
return _hasMinGas;
}
/**
* @notice Perform a low level call without copying any returndata. This function
* will revert if the call cannot be performed with the specified minimum
......@@ -52,16 +87,10 @@ library SafeCall {
bytes memory _calldata
) internal returns (bool) {
bool _success;
bool _hasMinGas = hasMinGas(_minGas, 0);
assembly {
// Assertion: gasleft() >= ((_minGas + 200) * 64) / 63
//
// Because EIP-150 ensures that, a maximum of 63/64ths of the remaining gas in the call
// frame may be passed to a subcontext, we need to ensure that the gas will not be
// truncated to hold this function's invariant: "If a call is performed by
// `callWithMinGas`, it must receive at least the specified minimum gas limit." In
// addition, exactly 51 gas is consumed between the below `GAS` opcode and the `CALL`
// opcode, so it is factored in with some extra room for error.
if lt(gas(), div(mul(64, add(_minGas, 200)), 63)) {
// Assertion: gasleft() >= (_minGas * 64) / 63 + 40_000
if iszero(_hasMinGas) {
// Store the "Error(string)" selector in scratch space.
mstore(0, 0x08c379a0)
// Store the pointer to the string length in scratch space.
......@@ -82,13 +111,11 @@ library SafeCall {
revert(28, 100)
}
// The call will be supplied at least (((_minGas + 200) * 64) / 63) - 49 gas due to the
// above assertion. This ensures that, in all circumstances, the call will
// receive at least the minimum amount of gas specified.
// We can prove this property by solving the inequalities:
// ((((_minGas + 200) * 64) / 63) - 49) >= _minGas
// ((((_minGas + 200) * 64) / 63) - 51) * (63 / 64) >= _minGas
// Both inequalities hold true for all possible values of `_minGas`.
// The call will be supplied at least ((_minGas * 64) / 63) gas due to the
// above assertion. This ensures that, in all circumstances (except for when the
// `_minGas` does not account for the `memory_expansion_cost` and `code_execution_cost`
// factors of the dynamic cost of the `CALL` opcode), the call will receive at least
// the minimum amount of gas specified.
_success := call(
gas(), // gas
_target, // recipient
......
......@@ -4,7 +4,7 @@ pragma solidity 0.8.15;
import { CommonTest } from "./CommonTest.t.sol";
import { SafeCall } from "../libraries/SafeCall.sol";
contract SafeCall_call_Test is CommonTest {
contract SafeCall_Test is CommonTest {
function testFuzz_call_succeeds(
address from,
address to,
......@@ -63,6 +63,8 @@ contract SafeCall_call_Test is CommonTest {
vm.assume(to != address(0x000000000000000000636F6e736F6c652e6c6f67));
// don't call the create2 deployer
vm.assume(to != address(0x4e59b44847b379578588920cA78FbF26c0B4956C));
// don't call the FFIInterface
vm.assume(to != address(0x5615dEB798BB3E4dFa0139dFa1b3D433Cc23b72f));
assertEq(from.balance, 0, "from balance is 0");
vm.deal(from, value);
......@@ -89,12 +91,12 @@ contract SafeCall_call_Test is CommonTest {
function test_callWithMinGas_noLeakageLow_succeeds() external {
SimpleSafeCaller caller = new SimpleSafeCaller();
for (uint64 i = 5000; i < 50_000; i++) {
for (uint64 i = 40_000; i < 100_000; i++) {
uint256 snapshot = vm.snapshot();
// 26,071 is the exact amount of gas required to make the safe call
// 65_903 is the exact amount of gas required to make the safe call
// successfully.
if (i < 26_071) {
if (i < 65_903) {
assertFalse(caller.makeSafeCall(i, 25_000));
} else {
vm.expectCallMinGas(
......@@ -116,9 +118,9 @@ contract SafeCall_call_Test is CommonTest {
for (uint64 i = 15_200_000; i < 15_300_000; i++) {
uint256 snapshot = vm.snapshot();
// 15,238,769 is the exact amount of gas required to make the safe call
// 15_278_602 is the exact amount of gas required to make the safe call
// successfully.
if (i < 15_238_769) {
if (i < 15_278_602) {
assertFalse(caller.makeSafeCall(i, 15_000_000));
} else {
vm.expectCallMinGas(
......
......@@ -7,6 +7,7 @@ import { L1CrossDomainMessenger } from "../../L1/L1CrossDomainMessenger.sol";
import { Messenger_Initializer } from "../CommonTest.t.sol";
import { Types } from "../../libraries/Types.sol";
import { Predeploys } from "../../libraries/Predeploys.sol";
import { Constants } from "../../libraries/Constants.sol";
import { Encoding } from "../../libraries/Encoding.sol";
import { Hashing } from "../../libraries/Hashing.sol";
......@@ -21,38 +22,53 @@ contract RelayActor is StdUtils {
OptimismPortal op;
L1CrossDomainMessenger xdm;
Vm vm;
bool doFail;
constructor(
OptimismPortal _op,
L1CrossDomainMessenger _xdm,
Vm _vm
Vm _vm,
bool _doFail
) {
op = _op;
xdm = _xdm;
vm = _vm;
doFail = _doFail;
}
/**
* Relays a message to the `L1CrossDomainMessenger` with a random `version`, `_minGasLimit`
* and `_message`.
* Relays a message to the `L1CrossDomainMessenger` with a random `version`, and `_message`.
*/
function relay(
uint16 _version,
uint32 _minGasLimit,
uint8 _version,
uint8 _value,
bytes memory _message
) external {
address target = address(0x04); // ID precompile
address sender = Predeploys.L2_CROSS_DOMAIN_MESSENGER;
// Set the minimum gas limit to the cost of the identity precompile's execution for
// the given message.
// ID Precompile cost can be determined by calculating: 15 + 3 * data_word_length
uint32 minGasLimit = uint32(15 + 3 * ((_message.length + 31) / 32));
// set the value of op.l2Sender() to be the L2 Cross Domain Messenger.
vm.store(address(op), bytes32(senderSlotIndex), bytes32(abi.encode(sender)));
// Restrict `_minGasLimit` to a number in the range of the block gas limit.
_minGasLimit = uint32(bound(_minGasLimit, 0, block.gaslimit));
// Restrict version to the range of [0, 1]
_version = _version % 2;
// Restrict the value to the range of [0, 1]
// This is just so we get variance of calls with and without value. The ID precompile
// will not reject value being sent to it.
_value = _value % 2;
// If the message should succeed, supply it `baseGas`. If not, supply it an amount of
// gas that is too low to complete the call.
uint256 gas = doFail
? bound(minGasLimit, 60_000, 80_000)
: xdm.baseGas(_message, minGasLimit);
// Compute the cross domain message hash and store it in `hashes`.
// The `relayMessage` function will always encode the message as a version 1
// message after checking that the V0 hash has not already been relayed.
......@@ -60,22 +76,29 @@ contract RelayActor is StdUtils {
Encoding.encodeVersionedNonce(0, _version),
sender,
target,
0, // value
_minGasLimit,
_value,
minGasLimit,
_message
);
hashes.push(_hash);
numHashes += 1;
// Make sure we've got a fresh message.
vm.assume(xdm.successfulMessages(_hash) == false && xdm.failedMessages(_hash) == false);
// Act as the optimism portal and call `relayMessage` on the `L1CrossDomainMessenger` with
// the outer min gas limit.
vm.startPrank(address(op));
vm.expectCall(target, _message);
if (!doFail) {
vm.expectCallMinGas(address(0x04), _value, minGasLimit, _message);
}
try
xdm.relayMessage{ gas: xdm.baseGas(_message, _minGasLimit) }(
xdm.relayMessage{ gas: gas, value: _value }(
Encoding.encodeVersionedNonce(0, _version),
sender,
target,
0, // value
_minGasLimit,
_value,
minGasLimit,
_message
)
{} catch {
......@@ -85,34 +108,81 @@ contract RelayActor is StdUtils {
reverted = true;
}
vm.stopPrank();
hashes.push(_hash);
numHashes += 1;
}
}
contract XDM_MinGasLimits is Messenger_Initializer {
RelayActor actor;
function setUp() public virtual override {
function init(bool doFail) public virtual {
// Set up the `L1CrossDomainMessenger` and `OptimismPortal` contracts.
super.setUp();
// Deploy a relay actor
actor = new RelayActor(op, L1Messenger, vm);
actor = new RelayActor(op, L1Messenger, vm, doFail);
// Give the portal some ether to send to `relayMessage`
vm.deal(address(op), type(uint128).max);
// Target the `RelayActor` contract
targetContract(address(actor));
// Don't allow the estimation address to be the sender
excludeSender(Constants.ESTIMATION_ADDRESS);
// Target the actor's `relay` function
bytes4[] memory selectors = new bytes4[](1);
selectors[0] = actor.relay.selector;
targetSelector(FuzzSelector({ addr: address(actor), selectors: selectors }));
}
}
contract XDM_MinGasLimits_Succeeds is XDM_MinGasLimits {
function setUp() public override {
// Don't fail
super.init(false);
}
/**
* @custom:invariant A call to `relayMessage` should succeed if at least the minimum gas limit
* can be supplied to the target context, there is enough gas to complete
* execution of `relayMessage` after the target context's execution is
* finished, and the target context did not revert.
*
* There are two minimum gas limits here:
*
* - The outer min gas limit is for the call from the `OptimismPortal` to the
* `L1CrossDomainMessenger`, and it can be retrieved by calling the xdm's `baseGas` function
* with the `message` and inner limit.
*
* - The inner min gas limit is for the call from the `L1CrossDomainMessenger` to the target
* contract.
*/
function invariant_minGasLimits() external {
uint256 length = actor.numHashes();
for (uint256 i = 0; i < length; ++i) {
bytes32 hash = actor.hashes(i);
// The message hash is set in the successfulMessages mapping
assertTrue(L1Messenger.successfulMessages(hash));
// The message hash is not set in the failedMessages mapping
assertFalse(L1Messenger.failedMessages(hash));
}
assertFalse(actor.reverted());
}
}
contract XDM_MinGasLimits_Reverts is XDM_MinGasLimits {
function setUp() public override {
// Do fail
super.init(true);
}
/**
* @custom:invariant A call to `relayMessage` should never revert if at least the proper minimum
* gas limits are supplied.
* @custom:invariant A call to `relayMessage` should assign the message hash to the
* `failedMessages` mapping if not enough gas is supplied to forward
* `minGasLimit` to the target context or if there is not enough gas to
* complete execution of `relayMessage` after the target context's execution
* is finished.
*
* There are two minimum gas limits here:
*
......@@ -123,19 +193,15 @@ contract XDM_MinGasLimits is Messenger_Initializer {
* - The inner min gas limit is for the call from the `L1CrossDomainMessenger` to the target
* contract.
*/
function invariant_minGasLimits() public {
///////////////////////////////////////////////////////////////////
// ~ DEV ~ //
// This test is temporarily disabled, it is being fixed in #5470 //
///////////////////////////////////////////////////////////////////
// uint256 length = actor.numHashes();
// for (uint256 i = 0; i < length; ++i) {
// bytes32 hash = actor.hashes(i);
// // the message hash is in the successfulMessages mapping
// assertTrue(L1Messenger.successfulMessages(hash));
// // it is not in the received messages mapping
// assertFalse(L1Messenger.failedMessages(hash));
// }
// assertFalse(actor.reverted());
function invariant_minGasLimits() external {
uint256 length = actor.numHashes();
for (uint256 i = 0; i < length; ++i) {
bytes32 hash = actor.hashes(i);
// The message hash is not set in the successfulMessages mapping
assertFalse(L1Messenger.successfulMessages(hash));
// The message hash is set in the failedMessages mapping
assertTrue(L1Messenger.failedMessages(hash));
}
assertFalse(actor.reverted());
}
}
......@@ -18,6 +18,9 @@ contract SafeCall_Succeeds_Invariants is Test {
// Target the safe caller actor.
targetContract(address(actor));
// Give the actor some ETH to work with
vm.deal(address(actor), type(uint128).max);
}
/**
......@@ -31,8 +34,8 @@ contract SafeCall_Succeeds_Invariants is Test {
assertEq(actor.numCalls(), 0, "no failed calls allowed");
}
function performSafeCallMinGas(uint64 minGas) external {
SafeCall.callWithMinGas(address(0), minGas, 0, hex"");
function performSafeCallMinGas(address to, uint64 minGas) external payable {
SafeCall.callWithMinGas(to, minGas, msg.value, hex"");
}
}
......@@ -48,6 +51,9 @@ contract SafeCall_Fails_Invariants is Test {
// Target the safe caller actor.
targetContract(address(actor));
// Give the actor some ETH to work with
vm.deal(address(actor), type(uint128).max);
}
/**
......@@ -62,8 +68,8 @@ contract SafeCall_Fails_Invariants is Test {
assertEq(actor.numCalls(), 0, "no successful calls allowed");
}
function performSafeCallMinGas(uint64 minGas) external {
SafeCall.callWithMinGas(address(0), minGas, 0, hex"");
function performSafeCallMinGas(address to, uint64 minGas) external payable {
SafeCall.callWithMinGas(to, minGas, msg.value, hex"");
}
}
......@@ -78,25 +84,39 @@ contract SafeCaller_Actor is StdUtils {
FAILS = _fails;
}
function performSafeCallMinGas(uint64 gas, uint64 minGas) external {
function performSafeCallMinGas(
uint64 gas,
uint64 minGas,
address to,
uint8 value
) external {
// Only send to EOAs - we exclude the console as it has no code but reverts when called
// with a selector that doesn't exist due to the foundry hook.
vm.assume(to.code.length == 0 && to != 0x000000000000000000636F6e736F6c652e6c6f67);
// Bound the minimum gas amount to [2500, type(uint48).max]
minGas = uint64(bound(minGas, 2500, type(uint48).max));
if (FAILS) {
// Bound the minimum gas amount to [2500, type(uint48).max]
minGas = uint64(bound(minGas, 2500, type(uint48).max));
// Bound the gas passed to [minGas, (((minGas + 200) * 64) / 63)]
gas = uint64(bound(gas, minGas, (((minGas + 200) * 64) / 63)));
// Bound the gas passed to [minGas, ((minGas * 64) / 63)]
gas = uint64(bound(gas, minGas, (minGas * 64) / 63));
} else {
// Bound the minimum gas amount to [2500, type(uint48).max]
minGas = uint64(bound(minGas, 2500, type(uint48).max));
// Bound the gas passed to [(((minGas + 200) * 64) / 63) + 500, type(uint64).max]
gas = uint64(bound(gas, (((minGas + 200) * 64) / 63) + 500, type(uint64).max));
// Bound the gas passed to
// [((minGas * 64) / 63) + 40_000 + 1000, type(uint64).max]
// The extra 1000 gas is to account for the gas used by the `SafeCall.call` call
// itself.
gas = uint64(bound(gas, ((minGas * 64) / 63) + 40_000 + 1000, type(uint64).max));
}
vm.expectCallMinGas(address(0x00), 0, minGas, hex"");
vm.expectCallMinGas(to, value, minGas, hex"");
bool success = SafeCall.call(
msg.sender,
gas,
0,
abi.encodeWithSelector(0x2ae57a41, minGas)
value,
abi.encodeWithSelector(
SafeCall_Succeeds_Invariants.performSafeCallMinGas.selector,
to,
minGas
)
);
if (success && FAILS) numCalls++;
......
......@@ -124,23 +124,39 @@ abstract contract CrossDomainMessenger is
/**
* @notice Constant overhead added to the base gas for a message.
*/
uint64 public constant MIN_GAS_CONSTANT_OVERHEAD = 200_000;
uint64 public constant RELAY_CONSTANT_OVERHEAD = 200_000;
/**
* @notice Numerator for dynamic overhead added to the base gas for a message.
*/
uint64 public constant MIN_GAS_DYNAMIC_OVERHEAD_NUMERATOR = 1016;
uint64 public constant MIN_GAS_DYNAMIC_OVERHEAD_NUMERATOR = 64;
/**
* @notice Denominator for dynamic overhead added to the base gas for a message.
*/
uint64 public constant MIN_GAS_DYNAMIC_OVERHEAD_DENOMINATOR = 1000;
uint64 public constant MIN_GAS_DYNAMIC_OVERHEAD_DENOMINATOR = 63;
/**
* @notice Extra gas added to base gas for each byte of calldata in a message.
*/
uint64 public constant MIN_GAS_CALLDATA_OVERHEAD = 16;
/**
* @notice Gas reserved for performing the external call in `relayMessage`.
*/
uint64 public constant RELAY_CALL_OVERHEAD = 40_000;
/**
* @notice Gas reserved for finalizing the execution of `relayMessage` after the safe call.
*/
uint64 public constant RELAY_RESERVED_GAS = 40_000;
/**
* @notice Gas reserved for the execution between the `hasMinGas` check and the external
* call in `relayMessage`.
*/
uint64 public constant RELAY_GAS_CHECK_BUFFER = 5_000;
/**
* @notice Address of the paired CrossDomainMessenger contract on the other chain.
*/
......@@ -345,17 +361,36 @@ abstract contract CrossDomainMessenger is
"CrossDomainMessenger: message has already been relayed"
);
// If there is not enough gas left to perform the external call and finish the execution,
// return early and assign the message to the failedMessages mapping.
// We are asserting that we have enough gas to:
// 1. Call the target contract (_minGasLimit + RELAY_CALL_OVERHEAD + RELAY_GAS_CHECK_BUFFER)
// 1.a. The RELAY_CALL_OVERHEAD is included in `hasMinGas`.
// 2. Finish the execution after the external call (RELAY_RESERVED_GAS).
//
// If `xDomainMsgSender` is not the default L2 sender, this function
// is being re-entered. This marks the message as failed to allow it
// to be replayed.
if (xDomainMsgSender != Constants.DEFAULT_L2_SENDER) {
// is being re-entered. This marks the message as failed to allow it to be replayed.
if (
!SafeCall.hasMinGas(_minGasLimit, RELAY_RESERVED_GAS + RELAY_GAS_CHECK_BUFFER) ||
xDomainMsgSender != Constants.DEFAULT_L2_SENDER
) {
failedMessages[versionedHash] = true;
emit FailedRelayedMessage(versionedHash);
// Revert in this case if the transaction was triggered by the estimation address. This
// should only be possible during gas estimation or we have bigger problems. Reverting
// here will make the behavior of gas estimation change such that the gas limit
// computed will be the amount required to relay the message, even if that amount is
// greater than the minimum gas limit specified by the user.
if (tx.origin == Constants.ESTIMATION_ADDRESS) {
revert("CrossDomainMessenger: failed to relay message");
}
return;
}
xDomainMsgSender = _sender;
bool success = SafeCall.callWithMinGas(_target, _minGasLimit, _value, _message);
bool success = SafeCall.call(_target, gasleft() - RELAY_RESERVED_GAS, _value, _message);
xDomainMsgSender = Constants.DEFAULT_L2_SENDER;
if (success) {
......@@ -415,17 +450,23 @@ abstract contract CrossDomainMessenger is
* @return Amount of gas required to guarantee message receipt.
*/
function baseGas(bytes calldata _message, uint32 _minGasLimit) public pure returns (uint64) {
// We peform the following math on uint64s to avoid overflow errors. Multiplying the
// by MIN_GAS_DYNAMIC_OVERHEAD_NUMERATOR would otherwise limit the _minGasLimit to
// type(uint32).max / MIN_GAS_DYNAMIC_OVERHEAD_NUMERATOR ~= 4.2m.
return
// Dynamic overhead
((uint64(_minGasLimit) * MIN_GAS_DYNAMIC_OVERHEAD_NUMERATOR) /
MIN_GAS_DYNAMIC_OVERHEAD_DENOMINATOR) +
// Constant overhead
RELAY_CONSTANT_OVERHEAD +
// Calldata overhead
(uint64(_message.length) * MIN_GAS_CALLDATA_OVERHEAD) +
// Constant overhead
MIN_GAS_CONSTANT_OVERHEAD;
// Dynamic overhead (EIP-150)
((_minGasLimit * MIN_GAS_DYNAMIC_OVERHEAD_NUMERATOR) /
MIN_GAS_DYNAMIC_OVERHEAD_DENOMINATOR) +
// Gas reserved for the worst-case cost of 3/5 of the `CALL` opcode's dynamic gas
// factors. (Conservative)
RELAY_CALL_OVERHEAD +
// Relay reserved gas (to ensure execution of `relayMessage` completes after the
// subcontext finishes executing) (Conservative)
RELAY_RESERVED_GAS +
// Gas reserved for the execution between the `hasMinGas` check and the `CALL`
// opcode. (Conservative)
RELAY_GAS_CHECK_BUFFER;
}
/**
......
......@@ -3,40 +3,29 @@
"portalGuardian": "0x9965507D1a55bcC2695C58ba16FB37d819B0A4dc",
"controller": "0xf39fd6e51aad88f6f4ce6ab8827279cfffb92266",
"proxyAdminOwner": "0x9965507D1a55bcC2695C58ba16FB37d819B0A4dc",
"l1StartingBlockTag": "earliest",
"l1ChainID": 900,
"l2ChainID": 901,
"l2BlockTime": 2,
"maxSequencerDrift": 300,
"sequencerWindowSize": 15,
"channelTimeout": 40,
"p2pSequencerAddress": "0x9965507D1a55bcC2695C58ba16FB37d819B0A4dc",
"batchInboxAddress": "0xff00000000000000000000000000000000000000",
"batchSenderAddress": "0x3C44CdDdB6a900fa2b585dd299e03d12FA4293BC",
"l2OutputOracleSubmissionInterval": 6,
"l2OutputOracleStartingTimestamp": 0,
"l2OutputOracleStartingBlockNumber": 0,
"l2OutputOracleProposer": "0x70997970C51812dc3A010C7d01b50e0d17dc79C8",
"l2OutputOracleChallenger": "0x6925B8704Ff96DEe942623d6FB5e946EF5884b63",
"l2GenesisBlockBaseFeePerGas": "0x3B9ACA00",
"l2GenesisBlockGasLimit": "0x17D7840",
"baseFeeVaultRecipient": "0x9965507D1a55bcC2695C58ba16FB37d819B0A4dc",
"l1FeeVaultRecipient": "0x9965507D1a55bcC2695C58ba16FB37d819B0A4dc",
"sequencerFeeVaultRecipient": "0x9965507D1a55bcC2695C58ba16FB37d819B0A4dc",
"l1FeeVaultRecipient": "0x71bE63f3384f5fb98995898A86B02Fb2426c5788",
"sequencerFeeVaultRecipient": "0xfabb0ac9d68b0b445fb7357272ff202c5651694a",
"governanceTokenName": "Optimism",
"governanceTokenSymbol": "OP",
"governanceTokenOwner": "0x9965507D1a55bcC2695C58ba16FB37d819B0A4dc",
"l1FeeVaultRecipient": "0x71bE63f3384f5fb98995898A86B02Fb2426c5788",
"sequencerFeeVaultRecipient": "0xfabb0ac9d68b0b445fb7357272ff202c5651694a",
"finalizationPeriodSeconds": 2,
"numDeployConfirmations": 1
}
}
\ No newline at end of file
# `CrossDomainMessenger` Invariants
## A call to `relayMessage` should never revert if at least the proper minimum gas limits are supplied.
**Test:** [`CrossDomainMessenger.t.sol#L126`](../contracts/test/invariants/CrossDomainMessenger.t.sol#L126)
## A call to `relayMessage` should succeed if at least the minimum gas limit can be supplied to the target context, there is enough gas to complete execution of `relayMessage` after the target context's execution is finished, and the target context did not revert.
**Test:** [`CrossDomainMessenger.t.sol#L161`](../contracts/test/invariants/CrossDomainMessenger.t.sol#L161)
There are two minimum gas limits here:
- The outer min gas limit is for the call from the `OptimismPortal` to the `L1CrossDomainMessenger`, and it can be retrieved by calling the xdm's `baseGas` function with the `message` and inner limit.
- The inner min gas limit is for the call from the `L1CrossDomainMessenger` to the target contract.
## A call to `relayMessage` should assign the message hash to the `failedMessages` mapping if not enough gas is supplied to forward `minGasLimit` to the target context or if there is not enough gas to complete execution of `relayMessage` after the target context's execution is finished.
**Test:** [`CrossDomainMessenger.t.sol#L196`](../contracts/test/invariants/CrossDomainMessenger.t.sol#L196)
There are two minimum gas limits here:
- The outer min gas limit is for the call from the `OptimismPortal` to the `L1CrossDomainMessenger`, and it can be retrieved by calling the xdm's `baseGas` function with the `message` and inner limit.
......
# `SafeCall` Invariants
## If `callWithMinGas` performs a call, then it must always provide at least the specified minimum gas limit to the subcontext.
**Test:** [`SafeCall.t.sol#L30`](../contracts/test/invariants/SafeCall.t.sol#L30)
**Test:** [`SafeCall.t.sol#L33`](../contracts/test/invariants/SafeCall.t.sol#L33)
If the check for remaining gas in `SafeCall.callWithMinGas` passes, the subcontext of the call below it must be provided at least `minGas` gas.
## `callWithMinGas` reverts if there is not enough gas to pass to the subcontext.
**Test:** [`SafeCall.t.sol#L61`](../contracts/test/invariants/SafeCall.t.sol#L61)
**Test:** [`SafeCall.t.sol#L67`](../contracts/test/invariants/SafeCall.t.sol#L67)
If there is not enough gas in the callframe to ensure that `callWithMinGas` can provide the specified minimum gas limit to the subcontext of the call, then `callWithMinGas` must revert.
......@@ -30,6 +30,7 @@
"coverage:lcov": "yarn build:differential && yarn build:fuzz && forge coverage --report lcov",
"gas-snapshot": "yarn build:differential && yarn build:fuzz && forge snapshot --no-match-test 'testDiff|testFuzz|invariant|generateArtifact'",
"storage-snapshot": "./scripts/storage-snapshot.sh",
"validate-deploy-configs": "hardhat compile && hardhat generate-deploy-config && ./scripts/validate-deploy-configs.sh",
"validate-spacers": "hardhat compile && hardhat validate-spacers",
"slither": "./scripts/slither.sh",
"slither:triage": "TRIAGE_MODE=1 ./scripts/slither.sh",
......
#!/usr/bin/env bash
set -e
dir=$(dirname "$0")
echo "Validating deployment configurations...\n"
for config in $dir/../deploy-config/*.json
do
echo "Found file: $config\n"
git diff --exit-code $config
done
echo "Deployment configs in $dir/../deploy-config validated!\n"
......@@ -245,7 +245,7 @@ const check = {
await assertSemver(
L2CrossDomainMessenger,
'L2CrossDomainMessenger',
'1.2.0'
'1.3.0'
)
const xDomainMessageSenderSlot = await signer.provider.getStorageAt(
......@@ -274,9 +274,9 @@ const check = {
const MIN_GAS_CALLDATA_OVERHEAD =
await L2CrossDomainMessenger.MIN_GAS_CALLDATA_OVERHEAD()
console.log(` - MIN_GAS_CALLDATA_OVERHEAD: ${MIN_GAS_CALLDATA_OVERHEAD}`)
const MIN_GAS_CONSTANT_OVERHEAD =
await L2CrossDomainMessenger.MIN_GAS_CONSTANT_OVERHEAD()
console.log(` - MIN_GAS_CONSTANT_OVERHEAD: ${MIN_GAS_CONSTANT_OVERHEAD}`)
const RELAY_CONSTANT_OVERHEAD =
await L2CrossDomainMessenger.RELAY_CONSTANT_OVERHEAD()
console.log(` - RELAY_CONSTANT_OVERHEAD: ${RELAY_CONSTANT_OVERHEAD}`)
const MIN_GAS_DYNAMIC_OVERHEAD_DENOMINATOR =
await L2CrossDomainMessenger.MIN_GAS_DYNAMIC_OVERHEAD_DENOMINATOR()
console.log(
......@@ -287,6 +287,14 @@ const check = {
console.log(
` - MIN_GAS_DYNAMIC_OVERHEAD_NUMERATOR: ${MIN_GAS_DYNAMIC_OVERHEAD_NUMERATOR}`
)
const RELAY_CALL_OVERHEAD =
await L2CrossDomainMessenger.RELAY_CALL_OVERHEAD()
console.log(` - RELAY_CALL_OVERHEAD: ${RELAY_CALL_OVERHEAD}`)
const RELAY_RESERVED_GAS = await L2CrossDomainMessenger.RELAY_RESERVED_GAS()
console.log(` - RELAY_RESERVED_GAS: ${RELAY_RESERVED_GAS}`)
const RELAY_GAS_CHECK_BUFFER =
await L2CrossDomainMessenger.RELAY_GAS_CHECK_BUFFER()
console.log(` - RELAY_GAS_CHECK_BUFFER: ${RELAY_GAS_CHECK_BUFFER}`)
const slot = await signer.provider.getStorageAt(
predeploys.L2CrossDomainMessenger,
......
......@@ -12,7 +12,7 @@ const config: DeployConfig = {
optimistAllowlistAllowlistAttestor:
'0x8F0EBDaA1cF7106bE861753B0f9F5c0250fE0819',
optimistAllowlistCoinbaseQuestAttestor:
'0x8F0EBDaA1cF7106bE861753B0f9F5c0250fE0819',
'0x9A75024c09b48B78205dfCf9D9FC5E026CD9A416',
}
export default config
{
"address": "0x29cc43964978c054b357E51E6949dDb1671DA408",
"address": "0x1EC6A94aee0Ff4BB21d4852da2D07b8Fd25914a0",
"abi": [
{
"inputs": [
......@@ -138,29 +138,29 @@
"type": "function"
}
],
"transactionHash": "0x94de4ffc0a27be2e084e59b3498218a77cf6db8cf053f8ed18e357ad01543c46",
"transactionHash": "0x5673e56b5a4f86f06bac8ed41f0f67ab12d1aaee313770d23d173f3736493be0",
"receipt": {
"to": "0x4e59b44847b379578588920cA78FbF26c0B4956C",
"from": "0x9C6373dE60c2D3297b18A8f964618ac46E011B58",
"from": "0x8F0EBDaA1cF7106bE861753B0f9F5c0250fE0819",
"contractAddress": null,
"transactionIndex": 1,
"transactionIndex": 3,
"gasUsed": "568770",
"logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
"blockHash": "0xc5342d9f4dfd1930ab03b5417bfd1b8c9c29be0c4fed56ca14e551681ca99d6f",
"transactionHash": "0x94de4ffc0a27be2e084e59b3498218a77cf6db8cf053f8ed18e357ad01543c46",
"blockHash": "0x6badea5d408ed78fae97b6620d71146646ab68889ad2a3cac3813af7cc9e6280",
"transactionHash": "0x5673e56b5a4f86f06bac8ed41f0f67ab12d1aaee313770d23d173f3736493be0",
"logs": [],
"blockNumber": 7691580,
"cumulativeGasUsed": "615683",
"blockNumber": 8253248,
"cumulativeGasUsed": "878505",
"status": 1,
"byzantium": true
},
"args": [
"0xEE36eaaD94d1Cc1d0eccaDb55C38bFfB6Be06C77",
"0x8F0EBDaA1cF7106bE861753B0f9F5c0250fE0819",
"0x8F0EBDaA1cF7106bE861753B0f9F5c0250fE0819",
"0x9A75024c09b48B78205dfCf9D9FC5E026CD9A416",
"0x073031A1E1b8F5458Ed41Ce56331F5fd7e1de929"
],
"numDeployments": 1,
"numDeployments": 2,
"solcInputHash": "d7155764d4bdb814f10e1bb45296292b",
"metadata": "{\"compiler\":{\"version\":\"0.8.15+commit.e14f2714\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"contract AttestationStation\",\"name\":\"_attestationStation\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_allowlistAttestor\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_coinbaseQuestAttestor\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_optimistInviter\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[],\"name\":\"ALLOWLIST_ATTESTOR\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"ATTESTATION_STATION\",\"outputs\":[{\"internalType\":\"contract AttestationStation\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"COINBASE_QUEST_ATTESTOR\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"COINBASE_QUEST_ELIGIBLE_ATTESTATION_KEY\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"OPTIMIST_CAN_MINT_ATTESTATION_KEY\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"OPTIMIST_INVITER\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_claimer\",\"type\":\"address\"}],\"name\":\"isAllowedToMint\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"version\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{\"constructor\":{\"custom:semver\":\"1.0.0\",\"params\":{\"_allowlistAttestor\":\"Address of the allowlist attestor.\",\"_attestationStation\":\"Address of the AttestationStation contract.\",\"_coinbaseQuestAttestor\":\"Address of the Coinbase Quest attestor.\",\"_optimistInviter\":\"Address of the OptimistInviter contract.\"}},\"isAllowedToMint(address)\":{\"params\":{\"_claimer\":\"Address to check.\"},\"returns\":{\"_0\":\"Whether or not the address is allowed to mint yet.\"}},\"version()\":{\"returns\":{\"_0\":\"Semver contract version as a string.\"}}},\"title\":\"OptimistAllowlist\",\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{\"ALLOWLIST_ATTESTOR()\":{\"notice\":\"Attestor that issues 'optimist.can-mint' attestations.\"},\"ATTESTATION_STATION()\":{\"notice\":\"Address of the AttestationStation contract.\"},\"COINBASE_QUEST_ATTESTOR()\":{\"notice\":\"Attestor that issues 'coinbase.quest-eligible' attestations.\"},\"COINBASE_QUEST_ELIGIBLE_ATTESTATION_KEY()\":{\"notice\":\"Attestation key used by Coinbase to issue attestations for Quest participants.\"},\"OPTIMIST_CAN_MINT_ATTESTATION_KEY()\":{\"notice\":\"Attestation key used by the AllowlistAttestor to manually add addresses to the allowlist.\"},\"OPTIMIST_INVITER()\":{\"notice\":\"Address of OptimistInviter contract that issues 'optimist.can-mint-from-invite' attestations.\"},\"isAllowedToMint(address)\":{\"notice\":\"Checks whether a given address is allowed to mint the Optimist NFT yet. Since the Optimist NFT will also be used as part of the Citizens House, mints are currently restricted. Eventually anyone will be able to mint. Currently, address is allowed to mint if it satisfies any of the following: 1) Has a valid 'optimist.can-mint' attestation from the allowlist attestor. 2) Has a valid 'coinbase.quest-eligible' attestation from Coinbase Quest attestor 3) Has a valid 'optimist.can-mint-from-invite' attestation from the OptimistInviter contract.\"},\"version()\":{\"notice\":\"Returns the full semver contract version.\"}},\"notice\":\"Source of truth for whether an address is able to mint an Optimist NFT. isAllowedToMint function checks various signals to return boolean value for whether an address is eligible or not.\",\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/universal/op-nft/OptimistAllowlist.sol\":\"OptimistAllowlist\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":10000},\"remappings\":[]},\"sources\":{\"@eth-optimism/contracts-bedrock/contracts/universal/Semver.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.0;\\n\\nimport { Strings } from \\\"@openzeppelin/contracts/utils/Strings.sol\\\";\\n\\n/**\\n * @title Semver\\n * @notice Semver is a simple contract for managing contract versions.\\n */\\ncontract Semver {\\n /**\\n * @notice Contract version number (major).\\n */\\n uint256 private immutable MAJOR_VERSION;\\n\\n /**\\n * @notice Contract version number (minor).\\n */\\n uint256 private immutable MINOR_VERSION;\\n\\n /**\\n * @notice Contract version number (patch).\\n */\\n uint256 private immutable PATCH_VERSION;\\n\\n /**\\n * @param _major Version number (major).\\n * @param _minor Version number (minor).\\n * @param _patch Version number (patch).\\n */\\n constructor(\\n uint256 _major,\\n uint256 _minor,\\n uint256 _patch\\n ) {\\n MAJOR_VERSION = _major;\\n MINOR_VERSION = _minor;\\n PATCH_VERSION = _patch;\\n }\\n\\n /**\\n * @notice Returns the full semver contract version.\\n *\\n * @return Semver contract version as a string.\\n */\\n function version() public view returns (string memory) {\\n return\\n string(\\n abi.encodePacked(\\n Strings.toString(MAJOR_VERSION),\\n \\\".\\\",\\n Strings.toString(MINOR_VERSION),\\n \\\".\\\",\\n Strings.toString(PATCH_VERSION)\\n )\\n );\\n }\\n}\\n\",\"keccak256\":\"0x400059d3edb9efc9c23e6fbc18de6710f9235a4ffba4ab23bdb9f825273f093b\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/Strings.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/Strings.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev String operations.\\n */\\nlibrary Strings {\\n bytes16 private constant _HEX_SYMBOLS = \\\"0123456789abcdef\\\";\\n uint8 private constant _ADDRESS_LENGTH = 20;\\n\\n /**\\n * @dev Converts a `uint256` to its ASCII `string` decimal representation.\\n */\\n function toString(uint256 value) internal pure returns (string memory) {\\n // Inspired by OraclizeAPI's implementation - MIT licence\\n // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol\\n\\n if (value == 0) {\\n return \\\"0\\\";\\n }\\n uint256 temp = value;\\n uint256 digits;\\n while (temp != 0) {\\n digits++;\\n temp /= 10;\\n }\\n bytes memory buffer = new bytes(digits);\\n while (value != 0) {\\n digits -= 1;\\n buffer[digits] = bytes1(uint8(48 + uint256(value % 10)));\\n value /= 10;\\n }\\n return string(buffer);\\n }\\n\\n /**\\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.\\n */\\n function toHexString(uint256 value) internal pure returns (string memory) {\\n if (value == 0) {\\n return \\\"0x00\\\";\\n }\\n uint256 temp = value;\\n uint256 length = 0;\\n while (temp != 0) {\\n length++;\\n temp >>= 8;\\n }\\n return toHexString(value, length);\\n }\\n\\n /**\\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.\\n */\\n function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {\\n bytes memory buffer = new bytes(2 * length + 2);\\n buffer[0] = \\\"0\\\";\\n buffer[1] = \\\"x\\\";\\n for (uint256 i = 2 * length + 1; i > 1; --i) {\\n buffer[i] = _HEX_SYMBOLS[value & 0xf];\\n value >>= 4;\\n }\\n require(value == 0, \\\"Strings: hex length insufficient\\\");\\n return string(buffer);\\n }\\n\\n /**\\n * @dev Converts an `address` with fixed length of 20 bytes to its not checksummed ASCII `string` hexadecimal representation.\\n */\\n function toHexString(address addr) internal pure returns (string memory) {\\n return toHexString(uint256(uint160(addr)), _ADDRESS_LENGTH);\\n }\\n}\\n\",\"keccak256\":\"0xaf159a8b1923ad2a26d516089bceca9bdeaeacd04be50983ea00ba63070f08a3\",\"license\":\"MIT\"},\"contracts/universal/op-nft/AttestationStation.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.8.15;\\n\\nimport { Semver } from \\\"@eth-optimism/contracts-bedrock/contracts/universal/Semver.sol\\\";\\n\\n/**\\n * @title AttestationStation\\n * @author Optimism Collective\\n * @author Gitcoin\\n * @notice Where attestations live.\\n */\\ncontract AttestationStation is Semver {\\n /**\\n * @notice Struct representing data that is being attested.\\n *\\n * @custom:field about Address for which the attestation is about.\\n * @custom:field key A bytes32 key for the attestation.\\n * @custom:field val The attestation as arbitrary bytes.\\n */\\n struct AttestationData {\\n address about;\\n bytes32 key;\\n bytes val;\\n }\\n\\n /**\\n * @notice Maps addresses to attestations. Creator => About => Key => Value.\\n */\\n mapping(address => mapping(address => mapping(bytes32 => bytes))) public attestations;\\n\\n /**\\n * @notice Emitted when Attestation is created.\\n *\\n * @param creator Address that made the attestation.\\n * @param about Address attestation is about.\\n * @param key Key of the attestation.\\n * @param val Value of the attestation.\\n */\\n event AttestationCreated(\\n address indexed creator,\\n address indexed about,\\n bytes32 indexed key,\\n bytes val\\n );\\n\\n /**\\n * @custom:semver 1.1.0\\n */\\n constructor() Semver(1, 1, 0) {}\\n\\n /**\\n * @notice Allows anyone to create an attestation.\\n *\\n * @param _about Address that the attestation is about.\\n * @param _key A key used to namespace the attestation.\\n * @param _val An arbitrary value stored as part of the attestation.\\n */\\n function attest(\\n address _about,\\n bytes32 _key,\\n bytes memory _val\\n ) public {\\n attestations[msg.sender][_about][_key] = _val;\\n\\n emit AttestationCreated(msg.sender, _about, _key, _val);\\n }\\n\\n /**\\n * @notice Allows anyone to create attestations.\\n *\\n * @param _attestations An array of AttestationData structs.\\n */\\n function attest(AttestationData[] calldata _attestations) external {\\n uint256 length = _attestations.length;\\n for (uint256 i = 0; i < length; ) {\\n AttestationData memory attestation = _attestations[i];\\n\\n attest(attestation.about, attestation.key, attestation.val);\\n\\n unchecked {\\n ++i;\\n }\\n }\\n }\\n}\\n\",\"keccak256\":\"0x421923e04df145353db12cd0352ccf516d9c29ab64b138733b4f7a6a450ce2be\",\"license\":\"MIT\"},\"contracts/universal/op-nft/OptimistAllowlist.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.8.15;\\n\\nimport { Semver } from \\\"@eth-optimism/contracts-bedrock/contracts/universal/Semver.sol\\\";\\nimport { AttestationStation } from \\\"./AttestationStation.sol\\\";\\nimport { OptimistConstants } from \\\"./libraries/OptimistConstants.sol\\\";\\n\\n/**\\n * @title OptimistAllowlist\\n * @notice Source of truth for whether an address is able to mint an Optimist NFT.\\n isAllowedToMint function checks various signals to return boolean value for whether an\\n address is eligible or not.\\n */\\ncontract OptimistAllowlist is Semver {\\n /**\\n * @notice Attestation key used by the AllowlistAttestor to manually add addresses to the\\n * allowlist.\\n */\\n bytes32 public constant OPTIMIST_CAN_MINT_ATTESTATION_KEY = bytes32(\\\"optimist.can-mint\\\");\\n\\n /**\\n * @notice Attestation key used by Coinbase to issue attestations for Quest participants.\\n */\\n bytes32 public constant COINBASE_QUEST_ELIGIBLE_ATTESTATION_KEY =\\n bytes32(\\\"coinbase.quest-eligible\\\");\\n\\n /**\\n * @notice Address of the AttestationStation contract.\\n */\\n AttestationStation public immutable ATTESTATION_STATION;\\n\\n /**\\n * @notice Attestor that issues 'optimist.can-mint' attestations.\\n */\\n address public immutable ALLOWLIST_ATTESTOR;\\n\\n /**\\n * @notice Attestor that issues 'coinbase.quest-eligible' attestations.\\n */\\n address public immutable COINBASE_QUEST_ATTESTOR;\\n\\n /**\\n * @notice Address of OptimistInviter contract that issues 'optimist.can-mint-from-invite'\\n * attestations.\\n */\\n address public immutable OPTIMIST_INVITER;\\n\\n /**\\n * @custom:semver 1.0.0\\n *\\n * @param _attestationStation Address of the AttestationStation contract.\\n * @param _allowlistAttestor Address of the allowlist attestor.\\n * @param _coinbaseQuestAttestor Address of the Coinbase Quest attestor.\\n * @param _optimistInviter Address of the OptimistInviter contract.\\n */\\n constructor(\\n AttestationStation _attestationStation,\\n address _allowlistAttestor,\\n address _coinbaseQuestAttestor,\\n address _optimistInviter\\n ) Semver(1, 0, 0) {\\n ATTESTATION_STATION = _attestationStation;\\n ALLOWLIST_ATTESTOR = _allowlistAttestor;\\n COINBASE_QUEST_ATTESTOR = _coinbaseQuestAttestor;\\n OPTIMIST_INVITER = _optimistInviter;\\n }\\n\\n /**\\n * @notice Checks whether a given address is allowed to mint the Optimist NFT yet. Since the\\n * Optimist NFT will also be used as part of the Citizens House, mints are currently\\n * restricted. Eventually anyone will be able to mint.\\n *\\n * Currently, address is allowed to mint if it satisfies any of the following:\\n * 1) Has a valid 'optimist.can-mint' attestation from the allowlist attestor.\\n * 2) Has a valid 'coinbase.quest-eligible' attestation from Coinbase Quest attestor\\n * 3) Has a valid 'optimist.can-mint-from-invite' attestation from the OptimistInviter\\n * contract.\\n *\\n * @param _claimer Address to check.\\n *\\n * @return Whether or not the address is allowed to mint yet.\\n */\\n function isAllowedToMint(address _claimer) public view returns (bool) {\\n return\\n _hasAttestationFromAllowlistAttestor(_claimer) ||\\n _hasAttestationFromCoinbaseQuestAttestor(_claimer) ||\\n _hasAttestationFromOptimistInviter(_claimer);\\n }\\n\\n /**\\n * @notice Checks whether an address has a valid 'optimist.can-mint' attestation from the\\n * allowlist attestor.\\n *\\n * @param _claimer Address to check.\\n *\\n * @return Whether or not the address has a valid attestation.\\n */\\n function _hasAttestationFromAllowlistAttestor(address _claimer) internal view returns (bool) {\\n // Expected attestation value is bytes32(\\\"true\\\")\\n return\\n _hasValidAttestation(ALLOWLIST_ATTESTOR, _claimer, OPTIMIST_CAN_MINT_ATTESTATION_KEY);\\n }\\n\\n /**\\n * @notice Checks whether an address has a valid attestation from the Coinbase attestor.\\n *\\n * @param _claimer Address to check.\\n *\\n * @return Whether or not the address has a valid attestation.\\n */\\n function _hasAttestationFromCoinbaseQuestAttestor(address _claimer)\\n internal\\n view\\n returns (bool)\\n {\\n // Expected attestation value is bytes32(\\\"true\\\")\\n return\\n _hasValidAttestation(\\n COINBASE_QUEST_ATTESTOR,\\n _claimer,\\n COINBASE_QUEST_ELIGIBLE_ATTESTATION_KEY\\n );\\n }\\n\\n /**\\n * @notice Checks whether an address has a valid attestation from the OptimistInviter contract.\\n *\\n * @param _claimer Address to check.\\n *\\n * @return Whether or not the address has a valid attestation.\\n */\\n function _hasAttestationFromOptimistInviter(address _claimer) internal view returns (bool) {\\n // Expected attestation value is the inviter's address\\n return\\n _hasValidAttestation(\\n OPTIMIST_INVITER,\\n _claimer,\\n OptimistConstants.OPTIMIST_CAN_MINT_FROM_INVITE_ATTESTATION_KEY\\n );\\n }\\n\\n /**\\n * @notice Checks whether an address has a valid truthy attestation.\\n * Any attestation val other than bytes32(\\\"\\\") is considered truthy.\\n *\\n * @param _creator Address that made the attestation.\\n * @param _about Address attestation is about.\\n * @param _key Key of the attestation.\\n *\\n * @return Whether or not the address has a valid truthy attestation.\\n */\\n function _hasValidAttestation(\\n address _creator,\\n address _about,\\n bytes32 _key\\n ) internal view returns (bool) {\\n return ATTESTATION_STATION.attestations(_creator, _about, _key).length > 0;\\n }\\n}\\n\",\"keccak256\":\"0xd36a677571450d2d9be832beb80e5c37481fcdfc355e6a9b929ac9c8d4966ca0\",\"license\":\"MIT\"},\"contracts/universal/op-nft/libraries/OptimistConstants.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.8.15;\\n\\n/**\\n * @title OptimistConstants\\n * @notice Library for storing Optimist related constants that are shared in multiple contracts.\\n */\\n\\nlibrary OptimistConstants {\\n /**\\n * @notice Attestation key issued by OptimistInviter allowing the attested account to mint.\\n */\\n bytes32 internal constant OPTIMIST_CAN_MINT_FROM_INVITE_ATTESTATION_KEY =\\n bytes32(\\\"optimist.can-mint-from-invite\\\");\\n}\\n\",\"keccak256\":\"0x6eebe1db87f8a5de79bf8af9120e5b0cc6a9b51d8d86e6461cdb6bc52a1dde21\",\"license\":\"MIT\"}},\"version\":1}",
"bytecode": "0x61016060405234801561001157600080fd5b50604051610a9d380380610a9d8339810160408190526100309161007c565b6001608052600060a081905260c0526001600160a01b0393841660e0529183166101005282166101205216610140526100db565b6001600160a01b038116811461007957600080fd5b50565b6000806000806080858703121561009257600080fd5b845161009d81610064565b60208601519094506100ae81610064565b60408601519093506100bf81610064565b60608601519092506100d081610064565b939692955090935050565b60805160a05160c05160e05161010051610120516101405161094d6101506000396000818161011b015261035a0152600081816092015261030d01526000818161019e01526102c001526000818161017701526105360152600061026f015260006102460152600061021d015261094d6000f3fe608060405234801561001057600080fd5b50600436106100885760003560e01c8063819f7e841161005b578063819f7e841461013d578063db083d7114610172578063db3c316314610199578063e7bd804e146101c057600080fd5b80633ac52df71461008d5780634813d8a6146100de57806354fd4d50146101015780635e4f489a14610116575b600080fd5b6100b47f000000000000000000000000000000000000000000000000000000000000000081565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020015b60405180910390f35b6100f16100ec3660046105cd565b6101e7565b60405190151581526020016100d5565b610109610216565b6040516100d5919061063a565b6100b47f000000000000000000000000000000000000000000000000000000000000000081565b6101647f636f696e626173652e71756573742d656c696769626c6500000000000000000081565b6040519081526020016100d5565b6100b47f000000000000000000000000000000000000000000000000000000000000000081565b6100b47f000000000000000000000000000000000000000000000000000000000000000081565b6101647f6f7074696d6973742e63616e2d6d696e7400000000000000000000000000000081565b60006101f2826102b9565b80610201575061020182610306565b80610210575061021082610353565b92915050565b60606102417f00000000000000000000000000000000000000000000000000000000000000006103a0565b61026a7f00000000000000000000000000000000000000000000000000000000000000006103a0565b6102937f00000000000000000000000000000000000000000000000000000000000000006103a0565b6040516020016102a59392919061068b565b604051602081830303815290604052905090565b60006102107f0000000000000000000000000000000000000000000000000000000000000000837f6f7074696d6973742e63616e2d6d696e740000000000000000000000000000006104dd565b60006102107f0000000000000000000000000000000000000000000000000000000000000000837f636f696e626173652e71756573742d656c696769626c650000000000000000006104dd565b60006102107f0000000000000000000000000000000000000000000000000000000000000000837f6f7074696d6973742e63616e2d6d696e742d66726f6d2d696e766974650000006104dd565b6060816000036103e357505060408051808201909152600181527f3000000000000000000000000000000000000000000000000000000000000000602082015290565b8160005b811561040d57806103f781610730565b91506104069050600a83610797565b91506103e7565b60008167ffffffffffffffff811115610428576104286107ab565b6040519080825280601f01601f191660200182016040528015610452576020820181803683370190505b5090505b84156104d5576104676001836107da565b9150610474600a866107f1565b61047f906030610805565b60f81b8183815181106104945761049461081d565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053506104ce600a86610797565b9450610456565b949350505050565b6040517f29b42cb500000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff848116600483015283811660248301526044820183905260009182917f000000000000000000000000000000000000000000000000000000000000000016906329b42cb590606401600060405180830381865afa15801561057d573d6000803e3d6000fd5b505050506040513d6000823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01682016040526105c3919081019061084c565b5111949350505050565b6000602082840312156105df57600080fd5b813573ffffffffffffffffffffffffffffffffffffffff8116811461060357600080fd5b9392505050565b60005b8381101561062557818101518382015260200161060d565b83811115610634576000848401525b50505050565b602081526000825180602084015261065981604085016020870161060a565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169190910160400192915050565b6000845161069d81846020890161060a565b80830190507f2e0000000000000000000000000000000000000000000000000000000000000080825285516106d9816001850160208a0161060a565b600192019182015283516106f481600284016020880161060a565b0160020195945050505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff820361076157610761610701565b5060010190565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b6000826107a6576107a6610768565b500490565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6000828210156107ec576107ec610701565b500390565b60008261080057610800610768565b500690565b6000821982111561081857610818610701565b500190565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60006020828403121561085e57600080fd5b815167ffffffffffffffff8082111561087657600080fd5b818401915084601f83011261088a57600080fd5b81518181111561089c5761089c6107ab565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f011681019083821181831017156108e2576108e26107ab565b816040528281528760208487010111156108fb57600080fd5b61090c83602083016020880161060a565b97965050505050505056fea2646970667358221220f7c9eee125b4662acd39871c7f71fd0d6635d58d3d0d2d059a8c8bb16ba6d74564736f6c634300080f0033",
......
......@@ -26,6 +26,7 @@ import {
BedrockCrossChainMessageProof,
decodeVersionedNonce,
encodeVersionedNonce,
getChainId,
} from '@eth-optimism/core-utils'
import { getContractInterface, predeploys } from '@eth-optimism/contracts'
import * as rlp from 'rlp'
......@@ -403,7 +404,8 @@ export class CrossChainMessenger {
let gasLimit: BigNumber
let messageNonce: BigNumber
if (version.eq(0)) {
gasLimit = migratedWithdrawalGasLimit(encoded)
const chainID = await getChainId(this.l2Provider)
gasLimit = migratedWithdrawalGasLimit(encoded, chainID)
messageNonce = resolved.messageNonce
} else {
const receipt = await this.l2Provider.getTransactionReceipt(
......
......@@ -41,10 +41,17 @@ export const hashMessageHash = (messageHash: string): string => {
/**
* Compute the min gas limit for a migrated withdrawal.
*/
export const migratedWithdrawalGasLimit = (data: string): BigNumber => {
export const migratedWithdrawalGasLimit = (
data: string,
chainID: number
): BigNumber => {
// Compute the gas limit and cap at 25 million
const dataCost = BigNumber.from(hexDataLength(data)).mul(16)
let minGasLimit = dataCost.add(200_000)
let overhead = 200_000
if (chainID !== 420) {
overhead = 1_000_000
}
let minGasLimit = dataCost.add(overhead)
if (minGasLimit.gt(25_000_000)) {
minGasLimit = BigNumber.from(25_000_000)
}
......
......@@ -7,11 +7,13 @@ import {
hashMessageHash,
} from '../../src/utils/message-utils'
const goerliChainID = 420
describe('Message Utils', () => {
describe('migratedWithdrawalGasLimit', () => {
it('should have a max of 25 million', () => {
const data = '0x' + 'ff'.repeat(15_000_000)
const result = migratedWithdrawalGasLimit(data)
const result = migratedWithdrawalGasLimit(data, goerliChainID)
expect(result).to.eq(BigNumber.from(25_000_000))
})
......@@ -25,7 +27,7 @@ describe('Message Utils', () => {
]
for (const test of tests) {
const result = migratedWithdrawalGasLimit(test.input)
const result = migratedWithdrawalGasLimit(test.input, goerliChainID)
expect(result).to.eq(test.result)
}
})
......
......@@ -365,6 +365,36 @@ func (b *Backend) setOffline() {
}
}
// ForwardRPC makes a call directly to a backend and populate the response into `res`
func (b *Backend) ForwardRPC(ctx context.Context, res *RPCRes, id string, method string, params ...any) error {
jsonParams, err := json.Marshal(params)
if err != nil {
return err
}
rpcReq := RPCReq{
JSONRPC: JSONRPCVersion,
Method: method,
Params: jsonParams,
ID: []byte(id),
}
slicedRes, err := b.doForward(ctx, []*RPCReq{&rpcReq}, false)
if err != nil {
return err
}
if len(slicedRes) != 1 {
return fmt.Errorf("unexpected response len for non-batched request (len != 1)")
}
if slicedRes[0].IsError() {
return fmt.Errorf(slicedRes[0].Error.Error())
}
*res = *(slicedRes[0])
return nil
}
func (b *Backend) doForward(ctx context.Context, rpcReqs []*RPCReq, isBatch bool) ([]*RPCRes, error) {
isSingleElementBatch := len(rpcReqs) == 1
......@@ -484,8 +514,9 @@ func sortBatchRPCResponse(req []*RPCReq, res []*RPCRes) {
}
type BackendGroup struct {
Name string
Backends []*Backend
Name string
Backends []*Backend
Consensus *ConsensusPoller
}
func (b *BackendGroup) Forward(ctx context.Context, rpcReqs []*RPCReq, isBatch bool) ([]*RPCRes, error) {
......
......@@ -52,7 +52,7 @@ func main() {
),
)
shutdown, err := proxyd.Start(config)
_, shutdown, err := proxyd.Start(config)
if err != nil {
log.Crit("error starting proxyd", "err", err)
}
......
......@@ -82,6 +82,7 @@ type BackendConfig struct {
Password string `toml:"password"`
RPCURL string `toml:"rpc_url"`
WSURL string `toml:"ws_url"`
WSPort int `toml:"ws_port"`
MaxRPS int `toml:"max_rps"`
MaxWSConns int `toml:"max_ws_conns"`
CAFile string `toml:"ca_file"`
......@@ -93,7 +94,9 @@ type BackendConfig struct {
type BackendsConfig map[string]*BackendConfig
type BackendGroupConfig struct {
Backends []string `toml:"backends"`
Backends []string `toml:"backends"`
ConsensusAware bool `toml:"consensus_aware"`
ConsensusAsyncHandler string `toml:"consensus_handler"`
}
type BackendGroupsConfig map[string]*BackendGroupConfig
......
package proxyd
import (
"context"
"fmt"
"strings"
"sync"
"time"
"github.com/ethereum/go-ethereum/common/hexutil"
"github.com/ethereum/go-ethereum/log"
)
const (
PollerInterval = 1 * time.Second
)
// ConsensusPoller checks the consensus state for each member of a BackendGroup
// resolves the highest common block for multiple nodes, and reconciles the consensus
// in case of block hash divergence to minimize re-orgs
type ConsensusPoller struct {
cancelFunc context.CancelFunc
backendGroup *BackendGroup
backendState map[*Backend]*backendState
consensusGroupMux sync.Mutex
consensusGroup []*Backend
tracker ConsensusTracker
asyncHandler ConsensusAsyncHandler
}
type backendState struct {
backendStateMux sync.Mutex
latestBlockNumber hexutil.Uint64
latestBlockHash string
lastUpdate time.Time
bannedUntil time.Time
}
// GetConsensusGroup returns the backend members that are agreeing in a consensus
func (cp *ConsensusPoller) GetConsensusGroup() []*Backend {
defer cp.consensusGroupMux.Unlock()
cp.consensusGroupMux.Lock()
g := make([]*Backend, len(cp.backendGroup.Backends))
copy(g, cp.consensusGroup)
return g
}
// GetConsensusBlockNumber returns the agreed block number in a consensus
func (ct *ConsensusPoller) GetConsensusBlockNumber() hexutil.Uint64 {
return ct.tracker.GetConsensusBlockNumber()
}
func (cp *ConsensusPoller) Shutdown() {
cp.asyncHandler.Shutdown()
}
// ConsensusAsyncHandler controls the asynchronous polling mechanism, interval and shutdown
type ConsensusAsyncHandler interface {
Init()
Shutdown()
}
// NoopAsyncHandler allows fine control updating the consensus
type NoopAsyncHandler struct{}
func NewNoopAsyncHandler() ConsensusAsyncHandler {
log.Warn("using NewNoopAsyncHandler")
return &NoopAsyncHandler{}
}
func (ah *NoopAsyncHandler) Init() {}
func (ah *NoopAsyncHandler) Shutdown() {}
// PollerAsyncHandler asynchronously updates each individual backend and the group consensus
type PollerAsyncHandler struct {
ctx context.Context
cp *ConsensusPoller
}
func NewPollerAsyncHandler(ctx context.Context, cp *ConsensusPoller) ConsensusAsyncHandler {
return &PollerAsyncHandler{
ctx: ctx,
cp: cp,
}
}
func (ah *PollerAsyncHandler) Init() {
// create the individual backend pollers
for _, be := range ah.cp.backendGroup.Backends {
go func(be *Backend) {
for {
timer := time.NewTimer(PollerInterval)
ah.cp.UpdateBackend(ah.ctx, be)
select {
case <-timer.C:
case <-ah.ctx.Done():
timer.Stop()
return
}
}
}(be)
}
// create the group consensus poller
go func() {
for {
timer := time.NewTimer(PollerInterval)
ah.cp.UpdateBackendGroupConsensus(ah.ctx)
select {
case <-timer.C:
case <-ah.ctx.Done():
timer.Stop()
return
}
}
}()
}
func (ah *PollerAsyncHandler) Shutdown() {
ah.cp.cancelFunc()
}
type ConsensusOpt func(cp *ConsensusPoller)
func WithTracker(tracker ConsensusTracker) ConsensusOpt {
return func(cp *ConsensusPoller) {
cp.tracker = tracker
}
}
func WithAsyncHandler(asyncHandler ConsensusAsyncHandler) ConsensusOpt {
return func(cp *ConsensusPoller) {
cp.asyncHandler = asyncHandler
}
}
func NewConsensusPoller(bg *BackendGroup, opts ...ConsensusOpt) *ConsensusPoller {
ctx, cancelFunc := context.WithCancel(context.Background())
state := make(map[*Backend]*backendState, len(bg.Backends))
for _, be := range bg.Backends {
state[be] = &backendState{}
}
cp := &ConsensusPoller{
cancelFunc: cancelFunc,
backendGroup: bg,
backendState: state,
}
for _, opt := range opts {
opt(cp)
}
if cp.tracker == nil {
cp.tracker = NewInMemoryConsensusTracker()
}
if cp.asyncHandler == nil {
cp.asyncHandler = NewPollerAsyncHandler(ctx, cp)
}
cp.asyncHandler.Init()
return cp
}
// UpdateBackend refreshes the consensus state of a single backend
func (cp *ConsensusPoller) UpdateBackend(ctx context.Context, be *Backend) {
bs := cp.backendState[be]
if time.Now().Before(bs.bannedUntil) {
log.Warn("skipping backend banned", "backend", be.Name, "bannedUntil", bs.bannedUntil)
return
}
if be.IsRateLimited() || !be.Online() {
return
}
// we'll introduce here checks to ban the backend
// i.e. node is syncing the chain
// then update backend consensus
latestBlockNumber, latestBlockHash, err := cp.fetchBlock(ctx, be, "latest")
if err != nil {
log.Warn("error updating backend", "name", be.Name, "err", err)
return
}
changed := cp.setBackendState(be, latestBlockNumber, latestBlockHash)
if changed {
RecordBackendLatestBlock(be, latestBlockNumber)
log.Info("backend state updated", "name", be.Name, "state", bs)
}
}
// UpdateBackendGroupConsensus resolves the current group consensus based on the state of the backends
func (cp *ConsensusPoller) UpdateBackendGroupConsensus(ctx context.Context) {
var lowestBlock hexutil.Uint64
var lowestBlockHash string
currentConsensusBlockNumber := cp.GetConsensusBlockNumber()
for _, be := range cp.backendGroup.Backends {
backendLatestBlockNumber, backendLatestBlockHash := cp.getBackendState(be)
if lowestBlock == 0 || backendLatestBlockNumber < lowestBlock {
lowestBlock = backendLatestBlockNumber
lowestBlockHash = backendLatestBlockHash
}
}
// no block to propose (i.e. initializing consensus)
if lowestBlock == 0 {
return
}
proposedBlock := lowestBlock
proposedBlockHash := lowestBlockHash
hasConsensus := false
// check if everybody agrees on the same block hash
consensusBackends := make([]*Backend, 0, len(cp.backendGroup.Backends))
consensusBackendsNames := make([]string, 0, len(cp.backendGroup.Backends))
filteredBackendsNames := make([]string, 0, len(cp.backendGroup.Backends))
if lowestBlock > currentConsensusBlockNumber {
log.Info("validating consensus on block", lowestBlock)
}
broken := false
for !hasConsensus {
allAgreed := true
consensusBackends = consensusBackends[:0]
filteredBackendsNames = filteredBackendsNames[:0]
for _, be := range cp.backendGroup.Backends {
if be.IsRateLimited() || !be.Online() || time.Now().Before(cp.backendState[be].bannedUntil) {
filteredBackendsNames = append(filteredBackendsNames, be.Name)
continue
}
actualBlockNumber, actualBlockHash, err := cp.fetchBlock(ctx, be, proposedBlock.String())
if err != nil {
log.Warn("error updating backend", "name", be.Name, "err", err)
continue
}
if proposedBlockHash == "" {
proposedBlockHash = actualBlockHash
}
blocksDontMatch := (actualBlockNumber != proposedBlock) || (actualBlockHash != proposedBlockHash)
if blocksDontMatch {
if currentConsensusBlockNumber >= actualBlockNumber {
log.Warn("backend broke consensus", "name", be.Name, "blockNum", actualBlockNumber, "proposedBlockNum", proposedBlock, "blockHash", actualBlockHash, "proposedBlockHash", proposedBlockHash)
broken = true
}
allAgreed = false
break
}
consensusBackends = append(consensusBackends, be)
consensusBackendsNames = append(consensusBackendsNames, be.Name)
}
if allAgreed {
hasConsensus = true
} else {
// walk one block behind and try again
proposedBlock -= 1
proposedBlockHash = ""
log.Info("no consensus, now trying", "block:", proposedBlock)
}
}
if broken {
// propagate event to other interested parts, such as cache invalidator
log.Info("consensus broken", "currentConsensusBlockNumber", currentConsensusBlockNumber, "proposedBlock", proposedBlock, "proposedBlockHash", proposedBlockHash)
}
cp.tracker.SetConsensusBlockNumber(proposedBlock)
RecordGroupConsensusLatestBlock(cp.backendGroup, proposedBlock)
cp.consensusGroupMux.Lock()
cp.consensusGroup = consensusBackends
cp.consensusGroupMux.Unlock()
log.Info("group state", "proposedBlock", proposedBlock, "consensusBackends", strings.Join(consensusBackendsNames, ", "), "filteredBackends", strings.Join(filteredBackendsNames, ", "))
}
// fetchBlock Convenient wrapper to make a request to get a block directly from the backend
func (cp *ConsensusPoller) fetchBlock(ctx context.Context, be *Backend, block string) (blockNumber hexutil.Uint64, blockHash string, err error) {
var rpcRes RPCRes
err = be.ForwardRPC(ctx, &rpcRes, "67", "eth_getBlockByNumber", block, false)
if err != nil {
return 0, "", err
}
jsonMap, ok := rpcRes.Result.(map[string]interface{})
if !ok {
return 0, "", fmt.Errorf("unexpected response type checking consensus on backend %s", be.Name)
}
blockNumber = hexutil.Uint64(hexutil.MustDecodeUint64(jsonMap["number"].(string)))
blockHash = jsonMap["hash"].(string)
return
}
func (cp *ConsensusPoller) getBackendState(be *Backend) (blockNumber hexutil.Uint64, blockHash string) {
bs := cp.backendState[be]
bs.backendStateMux.Lock()
blockNumber = bs.latestBlockNumber
blockHash = bs.latestBlockHash
bs.backendStateMux.Unlock()
return
}
func (cp *ConsensusPoller) setBackendState(be *Backend, blockNumber hexutil.Uint64, blockHash string) (changed bool) {
bs := cp.backendState[be]
bs.backendStateMux.Lock()
changed = bs.latestBlockHash != blockHash
bs.latestBlockNumber = blockNumber
bs.latestBlockHash = blockHash
bs.lastUpdate = time.Now()
bs.backendStateMux.Unlock()
return
}
package proxyd
import (
"context"
"fmt"
"sync"
"github.com/ethereum/go-ethereum/common/hexutil"
"github.com/go-redis/redis/v8"
)
// ConsensusTracker abstracts how we store and retrieve the current consensus
// allowing it to be stored locally in-memory or in a shared Redis cluster
type ConsensusTracker interface {
GetConsensusBlockNumber() hexutil.Uint64
SetConsensusBlockNumber(blockNumber hexutil.Uint64)
}
// InMemoryConsensusTracker store and retrieve in memory, async-safe
type InMemoryConsensusTracker struct {
consensusBlockNumber hexutil.Uint64
mutex sync.Mutex
}
func NewInMemoryConsensusTracker() ConsensusTracker {
return &InMemoryConsensusTracker{
consensusBlockNumber: 0,
mutex: sync.Mutex{},
}
}
func (ct *InMemoryConsensusTracker) GetConsensusBlockNumber() hexutil.Uint64 {
defer ct.mutex.Unlock()
ct.mutex.Lock()
return ct.consensusBlockNumber
}
func (ct *InMemoryConsensusTracker) SetConsensusBlockNumber(blockNumber hexutil.Uint64) {
defer ct.mutex.Unlock()
ct.mutex.Lock()
ct.consensusBlockNumber = blockNumber
}
// RedisConsensusTracker uses a Redis `client` to store and retrieve consensus, async-safe
type RedisConsensusTracker struct {
ctx context.Context
client *redis.Client
backendGroup string
}
func NewRedisConsensusTracker(ctx context.Context, r *redis.Client, namespace string) ConsensusTracker {
return &RedisConsensusTracker{
ctx: ctx,
client: r,
backendGroup: namespace,
}
}
func (ct *RedisConsensusTracker) key() string {
return fmt.Sprintf("consensus_latest_block:%s", ct.backendGroup)
}
func (ct *RedisConsensusTracker) GetConsensusBlockNumber() hexutil.Uint64 {
return hexutil.Uint64(hexutil.MustDecodeUint64(ct.client.Get(ct.ctx, ct.key()).Val()))
}
func (ct *RedisConsensusTracker) SetConsensusBlockNumber(blockNumber hexutil.Uint64) {
ct.client.Set(ct.ctx, ct.key(), blockNumber, 0)
}
......@@ -15,6 +15,7 @@ rpc_port = 8080
# Host for the proxyd WS server to listen on.
ws_host = "0.0.0.0"
# Port for the above
# Set the ws_port to 0 to disable WS
ws_port = 8085
# Maximum client body size, in bytes, that the server will accept.
max_body_size_bytes = 10485760
......
......@@ -11,10 +11,12 @@ require (
github.com/gorilla/mux v1.8.0
github.com/gorilla/websocket v1.5.0
github.com/hashicorp/golang-lru v0.5.5-0.20210104140557-80c98217689d
github.com/pkg/errors v0.9.1
github.com/prometheus/client_golang v1.11.1
github.com/rs/cors v1.8.2
github.com/stretchr/testify v1.7.0
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c
gopkg.in/yaml.v2 v2.4.0
)
require (
......@@ -29,6 +31,7 @@ require (
github.com/decred/dcrd/dcrec/secp256k1/v4 v4.0.1 // indirect
github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f // indirect
github.com/edsrzf/mmap-go v1.1.0 // indirect
github.com/emirpasic/gods v1.18.1 // indirect
github.com/fjl/memsize v0.0.1 // indirect
github.com/gballet/go-libpcsclite v0.0.0-20191108122812-4678299bea08 // indirect
github.com/go-ole/go-ole v1.2.6 // indirect
......
......@@ -140,6 +140,8 @@ github.com/eclipse/paho.mqtt.golang v1.2.0/go.mod h1:H9keYFcgq3Qr5OUJm/JZI/i6U7j
github.com/edsrzf/mmap-go v1.0.0/go.mod h1:YO35OhQPt3KJa3ryjFM5Bs14WD66h8eGKpfaBNrHW5M=
github.com/edsrzf/mmap-go v1.1.0 h1:6EUwBLQ/Mcr1EYLE4Tn1VdW1A4ckqCQWZBw8Hr0kjpQ=
github.com/edsrzf/mmap-go v1.1.0/go.mod h1:19H/e8pUPLicwkyNgOykDXkJ9F0MHE+Z52B8EIth78Q=
github.com/emirpasic/gods v1.18.1 h1:FXtiHYKDGKCW2KzwZKx0iC0PQmdlorYgdFG9jPXJ1Bc=
github.com/emirpasic/gods v1.18.1/go.mod h1:8tpGGwCnJ5H4r6BWwaV6OrWmMoPhUl5jm/FMNAnJvWQ=
github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98=
......
......@@ -22,7 +22,7 @@ func TestBatchTimeout(t *testing.T) {
config := ReadConfig("batch_timeout")
client := NewProxydClient("http://127.0.0.1:8545")
shutdown, err := proxyd.Start(config)
_, shutdown, err := proxyd.Start(config)
require.NoError(t, err)
defer shutdown()
......
......@@ -148,7 +148,7 @@ func TestBatching(t *testing.T) {
require.NoError(t, os.Setenv("GOOD_BACKEND_RPC_URL", goodBackend.URL()))
client := NewProxydClient("http://127.0.0.1:8545")
shutdown, err := proxyd.Start(config)
_, shutdown, err := proxyd.Start(config)
require.NoError(t, err)
defer shutdown()
......
......@@ -35,7 +35,7 @@ func TestCaching(t *testing.T) {
require.NoError(t, os.Setenv("REDIS_URL", fmt.Sprintf("redis://127.0.0.1:%s", redis.Port())))
config := ReadConfig("caching")
client := NewProxydClient("http://127.0.0.1:8545")
shutdown, err := proxyd.Start(config)
_, shutdown, err := proxyd.Start(config)
require.NoError(t, err)
defer shutdown()
......@@ -171,7 +171,7 @@ func TestBatchCaching(t *testing.T) {
config := ReadConfig("caching")
client := NewProxydClient("http://127.0.0.1:8545")
shutdown, err := proxyd.Start(config)
_, shutdown, err := proxyd.Start(config)
require.NoError(t, err)
defer shutdown()
......
package integration_tests
import (
"context"
"fmt"
"net/http"
"os"
"path"
"testing"
"github.com/ethereum-optimism/optimism/proxyd"
ms "github.com/ethereum-optimism/optimism/proxyd/tools/mockserver/handler"
"github.com/stretchr/testify/require"
)
func TestConsensus(t *testing.T) {
node1 := NewMockBackend(nil)
defer node1.Close()
node2 := NewMockBackend(nil)
defer node2.Close()
dir, err := os.Getwd()
require.NoError(t, err)
responses := path.Join(dir, "testdata/consensus_responses.yml")
h1 := ms.MockedHandler{
Overrides: []*ms.MethodTemplate{},
Autoload: true,
AutoloadFile: responses,
}
h2 := ms.MockedHandler{
Overrides: []*ms.MethodTemplate{},
Autoload: true,
AutoloadFile: responses,
}
require.NoError(t, os.Setenv("NODE1_URL", node1.URL()))
require.NoError(t, os.Setenv("NODE2_URL", node2.URL()))
node1.SetHandler(http.HandlerFunc(h1.Handler))
node2.SetHandler(http.HandlerFunc(h2.Handler))
config := ReadConfig("consensus")
ctx := context.Background()
svr, shutdown, err := proxyd.Start(config)
require.NoError(t, err)
defer shutdown()
bg := svr.BackendGroups["node"]
require.NotNil(t, bg)
require.NotNil(t, bg.Consensus)
t.Run("initial consensus", func(t *testing.T) {
h1.ResetOverrides()
h2.ResetOverrides()
// unknown consensus at init
require.Equal(t, "0x0", bg.Consensus.GetConsensusBlockNumber().String())
// first poll
for _, be := range bg.Backends {
bg.Consensus.UpdateBackend(ctx, be)
}
bg.Consensus.UpdateBackendGroupConsensus(ctx)
// consensus at block 0x1
require.Equal(t, "0x1", bg.Consensus.GetConsensusBlockNumber().String())
})
t.Run("advance consensus", func(t *testing.T) {
h1.ResetOverrides()
h2.ResetOverrides()
for _, be := range bg.Backends {
bg.Consensus.UpdateBackend(ctx, be)
}
bg.Consensus.UpdateBackendGroupConsensus(ctx)
// all nodes start at block 0x1
require.Equal(t, "0x1", bg.Consensus.GetConsensusBlockNumber().String())
// advance latest on node2 to 0x2
h2.AddOverride(&ms.MethodTemplate{
Method: "eth_getBlockByNumber",
Block: "latest",
Response: buildResponse("0x2", "hash2"),
})
// poll for group consensus
for _, be := range bg.Backends {
bg.Consensus.UpdateBackend(ctx, be)
}
bg.Consensus.UpdateBackendGroupConsensus(ctx)
// consensus should stick to 0x1, since node1 is still lagging there
bg.Consensus.UpdateBackendGroupConsensus(ctx)
require.Equal(t, "0x1", bg.Consensus.GetConsensusBlockNumber().String())
// advance latest on node1 to 0x2
h1.AddOverride(&ms.MethodTemplate{
Method: "eth_getBlockByNumber",
Block: "latest",
Response: buildResponse("0x2", "hash2"),
})
// poll for group consensus
for _, be := range bg.Backends {
bg.Consensus.UpdateBackend(ctx, be)
}
bg.Consensus.UpdateBackendGroupConsensus(ctx)
// should stick to 0x2, since now all nodes are at 0x2
require.Equal(t, "0x2", bg.Consensus.GetConsensusBlockNumber().String())
})
t.Run("broken consensus", func(t *testing.T) {
h1.ResetOverrides()
h2.ResetOverrides()
for _, be := range bg.Backends {
bg.Consensus.UpdateBackend(ctx, be)
}
bg.Consensus.UpdateBackendGroupConsensus(ctx)
// all nodes start at block 0x1
require.Equal(t, "0x1", bg.Consensus.GetConsensusBlockNumber().String())
// advance latest on both nodes to 0x2
h1.AddOverride(&ms.MethodTemplate{
Method: "eth_getBlockByNumber",
Block: "latest",
Response: buildResponse("0x2", "hash2"),
})
h2.AddOverride(&ms.MethodTemplate{
Method: "eth_getBlockByNumber",
Block: "latest",
Response: buildResponse("0x2", "hash2"),
})
// poll for group consensus
for _, be := range bg.Backends {
bg.Consensus.UpdateBackend(ctx, be)
}
bg.Consensus.UpdateBackendGroupConsensus(ctx)
// at 0x2
require.Equal(t, "0x2", bg.Consensus.GetConsensusBlockNumber().String())
// make node2 diverge on hash
h2.AddOverride(&ms.MethodTemplate{
Method: "eth_getBlockByNumber",
Block: "0x2",
Response: buildResponse("0x2", "wrong_hash"),
})
// poll for group consensus
for _, be := range bg.Backends {
bg.Consensus.UpdateBackend(ctx, be)
}
bg.Consensus.UpdateBackendGroupConsensus(ctx)
// should resolve to 0x1, since 0x2 is out of consensus at the moment
require.Equal(t, "0x1", bg.Consensus.GetConsensusBlockNumber().String())
// later, when impl events, listen to broken consensus event
})
t.Run("broken consensus with depth 2", func(t *testing.T) {
h1.ResetOverrides()
h2.ResetOverrides()
for _, be := range bg.Backends {
bg.Consensus.UpdateBackend(ctx, be)
}
bg.Consensus.UpdateBackendGroupConsensus(ctx)
// all nodes start at block 0x1
require.Equal(t, "0x1", bg.Consensus.GetConsensusBlockNumber().String())
// advance latest on both nodes to 0x2
h1.AddOverride(&ms.MethodTemplate{
Method: "eth_getBlockByNumber",
Block: "latest",
Response: buildResponse("0x2", "hash2"),
})
h2.AddOverride(&ms.MethodTemplate{
Method: "eth_getBlockByNumber",
Block: "latest",
Response: buildResponse("0x2", "hash2"),
})
// poll for group consensus
for _, be := range bg.Backends {
bg.Consensus.UpdateBackend(ctx, be)
}
bg.Consensus.UpdateBackendGroupConsensus(ctx)
// at 0x2
require.Equal(t, "0x2", bg.Consensus.GetConsensusBlockNumber().String())
// advance latest on both nodes to 0x3
h1.AddOverride(&ms.MethodTemplate{
Method: "eth_getBlockByNumber",
Block: "latest",
Response: buildResponse("0x3", "hash3"),
})
h2.AddOverride(&ms.MethodTemplate{
Method: "eth_getBlockByNumber",
Block: "latest",
Response: buildResponse("0x3", "hash3"),
})
// poll for group consensus
for _, be := range bg.Backends {
bg.Consensus.UpdateBackend(ctx, be)
}
bg.Consensus.UpdateBackendGroupConsensus(ctx)
// at 0x3
require.Equal(t, "0x3", bg.Consensus.GetConsensusBlockNumber().String())
// make node2 diverge on hash for blocks 0x2 and 0x3
h2.AddOverride(&ms.MethodTemplate{
Method: "eth_getBlockByNumber",
Block: "0x2",
Response: buildResponse("0x2", "wrong_hash2"),
})
h2.AddOverride(&ms.MethodTemplate{
Method: "eth_getBlockByNumber",
Block: "0x3",
Response: buildResponse("0x3", "wrong_hash3"),
})
// poll for group consensus
for _, be := range bg.Backends {
bg.Consensus.UpdateBackend(ctx, be)
}
bg.Consensus.UpdateBackendGroupConsensus(ctx)
// should resolve to 0x1
require.Equal(t, "0x1", bg.Consensus.GetConsensusBlockNumber().String())
})
t.Run("fork in advanced block", func(t *testing.T) {
h1.ResetOverrides()
h2.ResetOverrides()
for _, be := range bg.Backends {
bg.Consensus.UpdateBackend(ctx, be)
}
bg.Consensus.UpdateBackendGroupConsensus(ctx)
// all nodes start at block 0x1
require.Equal(t, "0x1", bg.Consensus.GetConsensusBlockNumber().String())
// make nodes 1 and 2 advance in forks
h1.AddOverride(&ms.MethodTemplate{
Method: "eth_getBlockByNumber",
Block: "0x2",
Response: buildResponse("0x2", "node1_0x2"),
})
h2.AddOverride(&ms.MethodTemplate{
Method: "eth_getBlockByNumber",
Block: "0x2",
Response: buildResponse("0x2", "node2_0x2"),
})
h1.AddOverride(&ms.MethodTemplate{
Method: "eth_getBlockByNumber",
Block: "0x3",
Response: buildResponse("0x3", "node1_0x3"),
})
h2.AddOverride(&ms.MethodTemplate{
Method: "eth_getBlockByNumber",
Block: "0x3",
Response: buildResponse("0x3", "node2_0x3"),
})
h1.AddOverride(&ms.MethodTemplate{
Method: "eth_getBlockByNumber",
Block: "latest",
Response: buildResponse("0x3", "node1_0x3"),
})
h2.AddOverride(&ms.MethodTemplate{
Method: "eth_getBlockByNumber",
Block: "latest",
Response: buildResponse("0x3", "node2_0x3"),
})
// poll for group consensus
for _, be := range bg.Backends {
bg.Consensus.UpdateBackend(ctx, be)
}
bg.Consensus.UpdateBackendGroupConsensus(ctx)
// should resolve to 0x1, the highest common ancestor
require.Equal(t, "0x1", bg.Consensus.GetConsensusBlockNumber().String())
})
}
func buildResponse(number string, hash string) string {
return fmt.Sprintf(`{
"jsonrpc": "2.0",
"id": 67,
"result": {
"number": "%s",
"hash": "%s"
}
}`, number, hash)
}
......@@ -30,7 +30,7 @@ func TestFailover(t *testing.T) {
config := ReadConfig("failover")
client := NewProxydClient("http://127.0.0.1:8545")
shutdown, err := proxyd.Start(config)
_, shutdown, err := proxyd.Start(config)
require.NoError(t, err)
defer shutdown()
......@@ -128,7 +128,7 @@ func TestRetries(t *testing.T) {
require.NoError(t, os.Setenv("GOOD_BACKEND_RPC_URL", backend.URL()))
config := ReadConfig("retries")
client := NewProxydClient("http://127.0.0.1:8545")
shutdown, err := proxyd.Start(config)
_, shutdown, err := proxyd.Start(config)
require.NoError(t, err)
defer shutdown()
......@@ -171,7 +171,7 @@ func TestOutOfServiceInterval(t *testing.T) {
config := ReadConfig("out_of_service_interval")
client := NewProxydClient("http://127.0.0.1:8545")
shutdown, err := proxyd.Start(config)
_, shutdown, err := proxyd.Start(config)
require.NoError(t, err)
defer shutdown()
......@@ -226,7 +226,7 @@ func TestBatchWithPartialFailover(t *testing.T) {
require.NoError(t, os.Setenv("BAD_BACKEND_RPC_URL", badBackend.URL()))
client := NewProxydClient("http://127.0.0.1:8545")
shutdown, err := proxyd.Start(config)
_, shutdown, err := proxyd.Start(config)
require.NoError(t, err)
defer shutdown()
......@@ -273,7 +273,7 @@ func TestInfuraFailoverOnUnexpectedResponse(t *testing.T) {
require.NoError(t, os.Setenv("BAD_BACKEND_RPC_URL", badBackend.URL()))
client := NewProxydClient("http://127.0.0.1:8545")
shutdown, err := proxyd.Start(config)
_, shutdown, err := proxyd.Start(config)
require.NoError(t, err)
defer shutdown()
......
......@@ -41,7 +41,7 @@ func TestMaxConcurrentRPCs(t *testing.T) {
config := ReadConfig("max_rpc_conns")
client := NewProxydClient("http://127.0.0.1:8545")
shutdown, err := proxyd.Start(config)
_, shutdown, err := proxyd.Start(config)
require.NoError(t, err)
defer shutdown()
......
......@@ -29,7 +29,7 @@ func TestBackendMaxRPSLimit(t *testing.T) {
config := ReadConfig("backend_rate_limit")
client := NewProxydClient("http://127.0.0.1:8545")
shutdown, err := proxyd.Start(config)
_, shutdown, err := proxyd.Start(config)
require.NoError(t, err)
defer shutdown()
limitedRes, codes := spamReqs(t, client, ethChainID, 503, 3)
......@@ -45,7 +45,7 @@ func TestFrontendMaxRPSLimit(t *testing.T) {
require.NoError(t, os.Setenv("GOOD_BACKEND_RPC_URL", goodBackend.URL()))
config := ReadConfig("frontend_rate_limit")
shutdown, err := proxyd.Start(config)
_, shutdown, err := proxyd.Start(config)
require.NoError(t, err)
defer shutdown()
......
......@@ -43,7 +43,7 @@ func TestSenderRateLimitValidation(t *testing.T) {
// validation.
config.SenderRateLimit.Limit = math.MaxInt
client := NewProxydClient("http://127.0.0.1:8545")
shutdown, err := proxyd.Start(config)
_, shutdown, err := proxyd.Start(config)
require.NoError(t, err)
defer shutdown()
......@@ -73,7 +73,7 @@ func TestSenderRateLimitLimiting(t *testing.T) {
config := ReadConfig("sender_rate_limit")
client := NewProxydClient("http://127.0.0.1:8545")
shutdown, err := proxyd.Start(config)
_, shutdown, err := proxyd.Start(config)
require.NoError(t, err)
defer shutdown()
......
[server]
rpc_port = 8080
[backend]
response_timeout_seconds = 1
[backends]
[backends.node1]
rpc_url = "$NODE1_URL"
[backends.node2]
rpc_url = "$NODE2_URL"
[backend_groups]
[backend_groups.node]
backends = ["node1", "node2"]
consensus_aware = true
consensus_handler = "noop" # allow more control over the consensus poller for tests
[rpc_method_mappings]
eth_call = "node"
eth_chainId = "node"
eth_blockNumber = "node"
eth_getBlockByNumber = "node"
- method: eth_getBlockByNumber
block: latest
response: >
{
"jsonrpc": "2.0",
"id": 67,
"result": {
"hash": "hash1",
"number": "0x1"
}
}
- method: eth_getBlockByNumber
block: 0x1
response: >
{
"jsonrpc": "2.0",
"id": 67,
"result": {
"hash": "hash1",
"number": "0x1"
}
}
- method: eth_getBlockByNumber
block: 0x2
response: >
{
"jsonrpc": "2.0",
"id": 67,
"result": {
"hash": "hash2",
"number": "0x2"
}
}
- method: eth_getBlockByNumber
block: 0x3
response: >
{
"jsonrpc": "2.0",
"id": 67,
"result": {
"hash": "hash3",
"number": "0x3"
}
}
......@@ -26,7 +26,7 @@ func TestSingleRPCValidation(t *testing.T) {
config := ReadConfig("whitelist")
client := NewProxydClient("http://127.0.0.1:8545")
shutdown, err := proxyd.Start(config)
_, shutdown, err := proxyd.Start(config)
require.NoError(t, err)
defer shutdown()
......@@ -110,7 +110,7 @@ func TestBatchRPCValidation(t *testing.T) {
config := ReadConfig("whitelist")
client := NewProxydClient("http://127.0.0.1:8545")
shutdown, err := proxyd.Start(config)
_, shutdown, err := proxyd.Start(config)
require.NoError(t, err)
defer shutdown()
......
......@@ -38,7 +38,7 @@ func TestConcurrentWSPanic(t *testing.T) {
require.NoError(t, os.Setenv("GOOD_BACKEND_RPC_URL", backend.URL()))
config := ReadConfig("ws")
shutdown, err := proxyd.Start(config)
_, shutdown, err := proxyd.Start(config)
require.NoError(t, err)
client, err := NewProxydWSClient("ws://127.0.0.1:8546", nil, nil)
require.NoError(t, err)
......@@ -147,7 +147,7 @@ func TestWS(t *testing.T) {
require.NoError(t, os.Setenv("GOOD_BACKEND_RPC_URL", backend.URL()))
config := ReadConfig("ws")
shutdown, err := proxyd.Start(config)
_, shutdown, err := proxyd.Start(config)
require.NoError(t, err)
client, err := NewProxydWSClient("ws://127.0.0.1:8546", func(msgType int, data []byte) {
clientHdlr.MsgCB(msgType, data)
......@@ -238,7 +238,7 @@ func TestWSClientClosure(t *testing.T) {
require.NoError(t, os.Setenv("GOOD_BACKEND_RPC_URL", backend.URL()))
config := ReadConfig("ws")
shutdown, err := proxyd.Start(config)
_, shutdown, err := proxyd.Start(config)
require.NoError(t, err)
defer shutdown()
......@@ -278,7 +278,7 @@ func TestWSClientMaxConns(t *testing.T) {
require.NoError(t, os.Setenv("GOOD_BACKEND_RPC_URL", backend.URL()))
config := ReadConfig("ws")
shutdown, err := proxyd.Start(config)
_, shutdown, err := proxyd.Start(config)
require.NoError(t, err)
defer shutdown()
......
......@@ -5,6 +5,8 @@ import (
"strconv"
"strings"
"github.com/ethereum/go-ethereum/common/hexutil"
"github.com/prometheus/client_golang/prometheus"
"github.com/prometheus/client_golang/prometheus/promauto"
)
......@@ -242,6 +244,22 @@ var (
Name: "rate_limit_take_errors",
Help: "Count of errors taking frontend rate limits",
})
consensusLatestBlock = promauto.NewGaugeVec(prometheus.GaugeOpts{
Namespace: MetricsNamespace,
Name: "group_consensus_latest_block",
Help: "Consensus latest block",
}, []string{
"backend_group_name",
})
backendLatestBlockBackend = promauto.NewGaugeVec(prometheus.GaugeOpts{
Namespace: MetricsNamespace,
Name: "backend_latest_block",
Help: "Current latest block observed per backend",
}, []string{
"backend_name",
})
)
func RecordRedisError(source string) {
......@@ -302,3 +320,11 @@ func RecordCacheMiss(method string) {
func RecordBatchSize(size int) {
batchSizeHistogram.Observe(float64(size))
}
func RecordBackendLatestBlock(be *Backend, blockNumber hexutil.Uint64) {
backendLatestBlockBackend.WithLabelValues(be.Name).Set(float64(blockNumber))
}
func RecordGroupConsensusLatestBlock(group *BackendGroup, blockNumber hexutil.Uint64) {
consensusLatestBlock.WithLabelValues(group.Name).Set(float64(blockNumber))
}
package avg_sliding_window
import (
"time"
lm "github.com/emirpasic/gods/maps/linkedhashmap"
)
type Clock interface {
Now() time.Time
}
// DefaultClock provides a clock that gets current time from the system time
type DefaultClock struct{}
func NewDefaultClock() *DefaultClock {
return &DefaultClock{}
}
func (c DefaultClock) Now() time.Time {
return time.Now()
}
// AdjustableClock provides a static clock to easily override the system time
type AdjustableClock struct {
now time.Time
}
func NewAdjustableClock(now time.Time) *AdjustableClock {
return &AdjustableClock{now: now}
}
func (c *AdjustableClock) Now() time.Time {
return c.now
}
func (c *AdjustableClock) Set(now time.Time) {
c.now = now
}
type bucket struct {
sum float64
qty uint
}
// AvgSlidingWindow calculates moving averages efficiently.
// Data points are rounded to nearest bucket of size `bucketSize`,
// and evicted when they are too old based on `windowLength`
type AvgSlidingWindow struct {
bucketSize time.Duration
windowLength time.Duration
clock Clock
buckets *lm.Map
qty uint
sum float64
}
type SlidingWindowOpts func(sw *AvgSlidingWindow)
func NewSlidingWindow(opts ...SlidingWindowOpts) *AvgSlidingWindow {
sw := &AvgSlidingWindow{
buckets: lm.New(),
}
for _, opt := range opts {
opt(sw)
}
if sw.bucketSize == 0 {
sw.bucketSize = time.Second
}
if sw.windowLength == 0 {
sw.windowLength = 5 * time.Minute
}
if sw.clock == nil {
sw.clock = NewDefaultClock()
}
return sw
}
func WithWindowLength(windowLength time.Duration) SlidingWindowOpts {
return func(sw *AvgSlidingWindow) {
sw.windowLength = windowLength
}
}
func WithBucketSize(bucketSize time.Duration) SlidingWindowOpts {
return func(sw *AvgSlidingWindow) {
sw.bucketSize = bucketSize
}
}
func WithClock(clock Clock) SlidingWindowOpts {
return func(sw *AvgSlidingWindow) {
sw.clock = clock
}
}
func (sw *AvgSlidingWindow) inWindow(t time.Time) bool {
now := sw.clock.Now().Round(sw.bucketSize)
windowStart := now.Add(-sw.windowLength)
return windowStart.Before(t) && !t.After(now)
}
// Add inserts a new data point into the window, with value `val` with the current time
func (sw *AvgSlidingWindow) Add(val float64) {
t := sw.clock.Now()
sw.AddWithTime(t, val)
}
// AddWithTime inserts a new data point into the window, with value `val` and time `t`
func (sw *AvgSlidingWindow) AddWithTime(t time.Time, val float64) {
sw.advance()
key := t.Round(sw.bucketSize)
if !sw.inWindow(key) {
return
}
var b *bucket
current, found := sw.buckets.Get(key)
if !found {
b = &bucket{}
} else {
b = current.(*bucket)
}
// update bucket
bsum := b.sum
b.qty += 1
b.sum = bsum + val
// update window
wsum := sw.sum
sw.qty += 1
sw.sum = wsum - bsum + b.sum
sw.buckets.Put(key, b)
}
// advance evicts old data points
func (sw *AvgSlidingWindow) advance() {
now := sw.clock.Now().Round(sw.bucketSize)
windowStart := now.Add(-sw.windowLength)
keys := sw.buckets.Keys()
for _, k := range keys {
if k.(time.Time).After(windowStart) {
break
}
val, _ := sw.buckets.Get(k)
b := val.(*bucket)
sw.buckets.Remove(k)
if sw.buckets.Size() > 0 {
sw.qty -= b.qty
sw.sum = sw.sum - b.sum
} else {
sw.qty = 0
sw.sum = 0.0
}
}
}
// Avg retrieves the current average for the sliding window
func (sw *AvgSlidingWindow) Avg() float64 {
sw.advance()
if sw.qty == 0 {
return 0
}
return sw.sum / float64(sw.qty)
}
// Sum retrieves the current sum for the sliding window
func (sw *AvgSlidingWindow) Sum() float64 {
sw.advance()
return sw.sum
}
// Count retrieves the data point count for the sliding window
func (sw *AvgSlidingWindow) Count() uint {
sw.advance()
return sw.qty
}
package avg_sliding_window
import (
"testing"
"time"
"github.com/stretchr/testify/require"
)
func TestSlidingWindow_AddWithTime_Single(t *testing.T) {
now := ts("2023-04-21 15:04:05")
clock := NewAdjustableClock(now)
sw := NewSlidingWindow(
WithWindowLength(10*time.Second),
WithBucketSize(time.Second),
WithClock(clock))
sw.AddWithTime(ts("2023-04-21 15:04:05"), 5)
require.Equal(t, 5.0, sw.Avg())
require.Equal(t, 5.0, sw.Sum())
require.Equal(t, 1, int(sw.Count()))
require.Equal(t, 1, sw.buckets.Size())
require.Equal(t, 1, int(sw.buckets.Values()[0].(*bucket).qty))
require.Equal(t, 5.0, sw.buckets.Values()[0].(*bucket).sum)
}
func TestSlidingWindow_AddWithTime_TwoValues_SameBucket(t *testing.T) {
now := ts("2023-04-21 15:04:05")
clock := NewAdjustableClock(now)
sw := NewSlidingWindow(
WithWindowLength(10*time.Second),
WithBucketSize(time.Second),
WithClock(clock))
sw.AddWithTime(ts("2023-04-21 15:04:05"), 5)
sw.AddWithTime(ts("2023-04-21 15:04:05"), 5)
require.Equal(t, 5.0, sw.Avg())
require.Equal(t, 10.0, sw.Sum())
require.Equal(t, 2, int(sw.Count()))
require.Equal(t, 1, sw.buckets.Size())
require.Equal(t, 2, int(sw.buckets.Values()[0].(*bucket).qty))
require.Equal(t, 10.0, sw.buckets.Values()[0].(*bucket).sum)
}
func TestSlidingWindow_AddWithTime_ThreeValues_SameBucket(t *testing.T) {
now := ts("2023-04-21 15:04:05")
clock := NewAdjustableClock(now)
sw := NewSlidingWindow(
WithWindowLength(10*time.Second),
WithBucketSize(time.Second),
WithClock(clock))
sw.AddWithTime(ts("2023-04-21 15:04:05"), 4)
sw.AddWithTime(ts("2023-04-21 15:04:05"), 5)
sw.AddWithTime(ts("2023-04-21 15:04:05"), 6)
require.Equal(t, 5.0, sw.Avg())
require.Equal(t, 15.0, sw.Sum())
require.Equal(t, 3, int(sw.Count()))
require.Equal(t, 1, sw.buckets.Size())
require.Equal(t, 15.0, sw.buckets.Values()[0].(*bucket).sum)
require.Equal(t, 3, int(sw.buckets.Values()[0].(*bucket).qty))
}
func TestSlidingWindow_AddWithTime_ThreeValues_ThreeBuckets(t *testing.T) {
now := ts("2023-04-21 15:04:05")
clock := NewAdjustableClock(now)
sw := NewSlidingWindow(
WithWindowLength(10*time.Second),
WithBucketSize(time.Second),
WithClock(clock))
sw.AddWithTime(ts("2023-04-21 15:04:01"), 4)
sw.AddWithTime(ts("2023-04-21 15:04:02"), 5)
sw.AddWithTime(ts("2023-04-21 15:04:05"), 6)
require.Equal(t, 5.0, sw.Avg())
require.Equal(t, 15.0, sw.Sum())
require.Equal(t, 3, int(sw.Count()))
require.Equal(t, 3, sw.buckets.Size())
require.Equal(t, 1, int(sw.buckets.Values()[0].(*bucket).qty))
require.Equal(t, 4.0, sw.buckets.Values()[0].(*bucket).sum)
require.Equal(t, 1, int(sw.buckets.Values()[1].(*bucket).qty))
require.Equal(t, 5.0, sw.buckets.Values()[1].(*bucket).sum)
require.Equal(t, 1, int(sw.buckets.Values()[2].(*bucket).qty))
require.Equal(t, 6.0, sw.buckets.Values()[2].(*bucket).sum)
}
func TestSlidingWindow_AddWithTime_OutWindow(t *testing.T) {
now := ts("2023-04-21 15:04:05")
clock := NewAdjustableClock(now)
sw := NewSlidingWindow(
WithWindowLength(10*time.Second),
WithBucketSize(time.Second),
WithClock(clock))
sw.AddWithTime(ts("2023-04-21 15:03:55"), 1000)
sw.AddWithTime(ts("2023-04-21 15:04:01"), 4)
sw.AddWithTime(ts("2023-04-21 15:04:02"), 5)
sw.AddWithTime(ts("2023-04-21 15:04:05"), 6)
require.Equal(t, 5.0, sw.Avg())
require.Equal(t, 15.0, sw.Sum())
require.Equal(t, 3, int(sw.Count()))
require.Equal(t, 3, sw.buckets.Size())
require.Equal(t, 1, int(sw.buckets.Values()[0].(*bucket).qty))
require.Equal(t, 4.0, sw.buckets.Values()[0].(*bucket).sum)
require.Equal(t, 1, int(sw.buckets.Values()[1].(*bucket).qty))
require.Equal(t, 5.0, sw.buckets.Values()[1].(*bucket).sum)
require.Equal(t, 1, int(sw.buckets.Values()[2].(*bucket).qty))
require.Equal(t, 6.0, sw.buckets.Values()[2].(*bucket).sum)
}
func TestSlidingWindow_AdvanceClock(t *testing.T) {
now := ts("2023-04-21 15:04:05")
clock := NewAdjustableClock(now)
sw := NewSlidingWindow(
WithWindowLength(10*time.Second),
WithBucketSize(time.Second),
WithClock(clock))
sw.AddWithTime(ts("2023-04-21 15:04:01"), 4)
sw.AddWithTime(ts("2023-04-21 15:04:02"), 5)
sw.AddWithTime(ts("2023-04-21 15:04:05"), 6)
require.Equal(t, 5.0, sw.Avg())
require.Equal(t, 15.0, sw.Sum())
require.Equal(t, 3, int(sw.Count()))
require.Equal(t, 3, sw.buckets.Size())
require.Equal(t, 1, int(sw.buckets.Values()[0].(*bucket).qty))
require.Equal(t, 4.0, sw.buckets.Values()[0].(*bucket).sum)
require.Equal(t, 1, int(sw.buckets.Values()[1].(*bucket).qty))
require.Equal(t, 5.0, sw.buckets.Values()[1].(*bucket).sum)
require.Equal(t, 1, int(sw.buckets.Values()[2].(*bucket).qty))
require.Equal(t, 6.0, sw.buckets.Values()[2].(*bucket).sum)
// up until 15:04:05 we had 3 buckets
// let's advance the clock to 15:04:11 and the first data point should be evicted
clock.Set(ts("2023-04-21 15:04:11"))
require.Equal(t, 5.5, sw.Avg())
require.Equal(t, 11.0, sw.Sum())
require.Equal(t, 2, int(sw.Count()))
require.Equal(t, 2, sw.buckets.Size())
require.Equal(t, 1, int(sw.buckets.Values()[0].(*bucket).qty))
require.Equal(t, 5.0, sw.buckets.Values()[0].(*bucket).sum)
require.Equal(t, 1, int(sw.buckets.Values()[1].(*bucket).qty))
require.Equal(t, 6.0, sw.buckets.Values()[1].(*bucket).sum)
// let's advance the clock to 15:04:12 and another data point should be evicted
clock.Set(ts("2023-04-21 15:04:12"))
require.Equal(t, 6.0, sw.Avg())
require.Equal(t, 6.0, sw.Sum())
require.Equal(t, 1, int(sw.Count()))
require.Equal(t, 1, sw.buckets.Size())
require.Equal(t, 1, int(sw.buckets.Values()[0].(*bucket).qty))
require.Equal(t, 6.0, sw.buckets.Values()[0].(*bucket).sum)
// let's advance the clock to 15:04:25 and all data point should be evicted
clock.Set(ts("2023-04-21 15:04:25"))
require.Equal(t, 0.0, sw.Avg())
require.Equal(t, 0.0, sw.Sum())
require.Equal(t, 0, int(sw.Count()))
require.Equal(t, 0, sw.buckets.Size())
}
func TestSlidingWindow_MultipleValPerBucket(t *testing.T) {
now := ts("2023-04-21 15:04:05")
clock := NewAdjustableClock(now)
sw := NewSlidingWindow(
WithWindowLength(10*time.Second),
WithBucketSize(time.Second),
WithClock(clock))
sw.AddWithTime(ts("2023-04-21 15:04:01"), 4)
sw.AddWithTime(ts("2023-04-21 15:04:01"), 12)
sw.AddWithTime(ts("2023-04-21 15:04:02"), 5)
sw.AddWithTime(ts("2023-04-21 15:04:02"), 15)
sw.AddWithTime(ts("2023-04-21 15:04:05"), 6)
sw.AddWithTime(ts("2023-04-21 15:04:05"), 3)
sw.AddWithTime(ts("2023-04-21 15:04:05"), 1)
sw.AddWithTime(ts("2023-04-21 15:04:05"), 3)
require.Equal(t, 6.125, sw.Avg())
require.Equal(t, 49.0, sw.Sum())
require.Equal(t, 8, int(sw.Count()))
require.Equal(t, 3, sw.buckets.Size())
require.Equal(t, 2, int(sw.buckets.Values()[0].(*bucket).qty))
require.Equal(t, 16.0, sw.buckets.Values()[0].(*bucket).sum)
require.Equal(t, 2, int(sw.buckets.Values()[1].(*bucket).qty))
require.Equal(t, 20.0, sw.buckets.Values()[1].(*bucket).sum)
require.Equal(t, 4, int(sw.buckets.Values()[2].(*bucket).qty))
require.Equal(t, 13.0, sw.buckets.Values()[2].(*bucket).sum)
// up until 15:04:05 we had 3 buckets
// let's advance the clock to 15:04:11 and the first data point should be evicted
clock.Set(ts("2023-04-21 15:04:11"))
require.Equal(t, 5.5, sw.Avg())
require.Equal(t, 33.0, sw.Sum())
require.Equal(t, 6, int(sw.Count()))
require.Equal(t, 2, sw.buckets.Size())
require.Equal(t, 2, int(sw.buckets.Values()[0].(*bucket).qty))
require.Equal(t, 20.0, sw.buckets.Values()[0].(*bucket).sum)
require.Equal(t, 4, int(sw.buckets.Values()[1].(*bucket).qty))
require.Equal(t, 13.0, sw.buckets.Values()[1].(*bucket).sum)
// let's advance the clock to 15:04:12 and another data point should be evicted
clock.Set(ts("2023-04-21 15:04:12"))
require.Equal(t, 3.25, sw.Avg())
require.Equal(t, 13.0, sw.Sum())
require.Equal(t, 4, int(sw.Count()))
require.Equal(t, 1, sw.buckets.Size())
require.Equal(t, 4, int(sw.buckets.Values()[0].(*bucket).qty))
require.Equal(t, 13.0, sw.buckets.Values()[0].(*bucket).sum)
// let's advance the clock to 15:04:25 and all data point should be evicted
clock.Set(ts("2023-04-21 15:04:25"))
require.Equal(t, 0.0, sw.Avg())
require.Equal(t, 0, sw.buckets.Size())
}
func TestSlidingWindow_CustomBucket(t *testing.T) {
now := ts("2023-04-21 15:04:05")
clock := NewAdjustableClock(now)
sw := NewSlidingWindow(
WithWindowLength(30*time.Second),
WithBucketSize(10*time.Second),
WithClock(clock))
sw.AddWithTime(ts("2023-04-21 15:03:49"), 5) // key: 03:50, sum: 5.0
sw.AddWithTime(ts("2023-04-21 15:04:02"), 15) // key: 04:00
sw.AddWithTime(ts("2023-04-21 15:04:03"), 5) // key: 04:00
sw.AddWithTime(ts("2023-04-21 15:04:04"), 1) // key: 04:00, sum: 21.0
sw.AddWithTime(ts("2023-04-21 15:04:05"), 3) // key: 04:10, sum: 3.0
require.Equal(t, 5.8, sw.Avg())
require.Equal(t, 29.0, sw.Sum())
require.Equal(t, 5, int(sw.Count()))
require.Equal(t, 3, sw.buckets.Size())
require.Equal(t, 5.0, sw.buckets.Values()[0].(*bucket).sum)
require.Equal(t, 1, int(sw.buckets.Values()[0].(*bucket).qty))
require.Equal(t, 21.0, sw.buckets.Values()[1].(*bucket).sum)
require.Equal(t, 3, int(sw.buckets.Values()[1].(*bucket).qty))
require.Equal(t, 3.0, sw.buckets.Values()[2].(*bucket).sum)
require.Equal(t, 1, int(sw.buckets.Values()[2].(*bucket).qty))
// up until 15:04:05 we had 3 buckets
// let's advance the clock to 15:04:21 and the first data point should be evicted
clock.Set(ts("2023-04-21 15:04:21"))
require.Equal(t, 6.0, sw.Avg())
require.Equal(t, 24.0, sw.Sum())
require.Equal(t, 4, int(sw.Count()))
require.Equal(t, 2, sw.buckets.Size())
require.Equal(t, 21.0, sw.buckets.Values()[0].(*bucket).sum)
require.Equal(t, 3, int(sw.buckets.Values()[0].(*bucket).qty))
require.Equal(t, 3.0, sw.buckets.Values()[1].(*bucket).sum)
require.Equal(t, 1, int(sw.buckets.Values()[1].(*bucket).qty))
// let's advance the clock to 15:04:32 and another data point should be evicted
clock.Set(ts("2023-04-21 15:04:32"))
require.Equal(t, 3.0, sw.Avg())
require.Equal(t, 3.0, sw.Sum())
require.Equal(t, 1, sw.buckets.Size())
require.Equal(t, 1, int(sw.Count()))
require.Equal(t, 3.0, sw.buckets.Values()[0].(*bucket).sum)
require.Equal(t, 1, int(sw.buckets.Values()[0].(*bucket).qty))
// let's advance the clock to 15:04:46 and all data point should be evicted
clock.Set(ts("2023-04-21 15:04:46"))
require.Equal(t, 0.0, sw.Avg())
require.Equal(t, 0.0, sw.Sum())
require.Equal(t, 0, int(sw.Count()))
require.Equal(t, 0, sw.buckets.Size())
}
// ts is a convenient method that must parse a time.Time from a string in format `"2006-01-02 15:04:05"`
func ts(s string) time.Time {
format := "2006-01-02 15:04:05"
t, err := time.Parse(format, s)
if err != nil {
panic(err)
}
return t
}
......@@ -18,20 +18,20 @@ import (
"golang.org/x/sync/semaphore"
)
func Start(config *Config) (func(), error) {
func Start(config *Config) (*Server, func(), error) {
if len(config.Backends) == 0 {
return nil, errors.New("must define at least one backend")
return nil, nil, errors.New("must define at least one backend")
}
if len(config.BackendGroups) == 0 {
return nil, errors.New("must define at least one backend group")
return nil, nil, errors.New("must define at least one backend group")
}
if len(config.RPCMethodMappings) == 0 {
return nil, errors.New("must define at least one RPC method mapping")
return nil, nil, errors.New("must define at least one RPC method mapping")
}
for authKey := range config.Authentication {
if authKey == "none" {
return nil, errors.New("cannot use none as an auth key")
return nil, nil, errors.New("cannot use none as an auth key")
}
}
......@@ -39,16 +39,16 @@ func Start(config *Config) (func(), error) {
if config.Redis.URL != "" {
rURL, err := ReadFromEnvOrConfig(config.Redis.URL)
if err != nil {
return nil, err
return nil, nil, err
}
redisClient, err = NewRedisClient(rURL)
if err != nil {
return nil, err
return nil, nil, err
}
}
if redisClient == nil && config.RateLimit.UseRedis {
return nil, errors.New("must specify a Redis URL if UseRedis is true in rate limit config")
return nil, nil, errors.New("must specify a Redis URL if UseRedis is true in rate limit config")
}
var lim BackendRateLimiter
......@@ -80,10 +80,10 @@ func Start(config *Config) (func(), error) {
if config.SenderRateLimit.Enabled {
if config.SenderRateLimit.Limit <= 0 {
return nil, errors.New("limit in sender_rate_limit must be > 0")
return nil, nil, errors.New("limit in sender_rate_limit must be > 0")
}
if time.Duration(config.SenderRateLimit.Interval) < time.Second {
return nil, errors.New("interval in sender_rate_limit must be >= 1s")
return nil, nil, errors.New("interval in sender_rate_limit must be >= 1s")
}
}
......@@ -100,17 +100,14 @@ func Start(config *Config) (func(), error) {
rpcURL, err := ReadFromEnvOrConfig(cfg.RPCURL)
if err != nil {
return nil, err
return nil, nil, err
}
wsURL, err := ReadFromEnvOrConfig(cfg.WSURL)
if err != nil {
return nil, err
return nil, nil, err
}
if rpcURL == "" {
return nil, fmt.Errorf("must define an RPC URL for backend %s", name)
}
if wsURL == "" {
return nil, fmt.Errorf("must define a WS URL for backend %s", name)
return nil, nil, fmt.Errorf("must define an RPC URL for backend %s", name)
}
if config.BackendOptions.ResponseTimeoutSeconds != 0 {
......@@ -135,13 +132,13 @@ func Start(config *Config) (func(), error) {
if cfg.Password != "" {
passwordVal, err := ReadFromEnvOrConfig(cfg.Password)
if err != nil {
return nil, err
return nil, nil, err
}
opts = append(opts, WithBasicAuth(cfg.Username, passwordVal))
}
tlsConfig, err := configureBackendTLS(cfg)
if err != nil {
return nil, err
return nil, nil, err
}
if tlsConfig != nil {
log.Info("using custom TLS config for backend", "name", name)
......@@ -162,7 +159,7 @@ func Start(config *Config) (func(), error) {
backends := make([]*Backend, 0)
for _, bName := range bg.Backends {
if backendsByName[bName] == nil {
return nil, fmt.Errorf("backend %s is not defined", bName)
return nil, nil, fmt.Errorf("backend %s is not defined", bName)
}
backends = append(backends, backendsByName[bName])
}
......@@ -177,17 +174,17 @@ func Start(config *Config) (func(), error) {
if config.WSBackendGroup != "" {
wsBackendGroup = backendGroups[config.WSBackendGroup]
if wsBackendGroup == nil {
return nil, fmt.Errorf("ws backend group %s does not exist", config.WSBackendGroup)
return nil, nil, fmt.Errorf("ws backend group %s does not exist", config.WSBackendGroup)
}
}
if wsBackendGroup == nil && config.Server.WSPort != 0 {
return nil, fmt.Errorf("a ws port was defined, but no ws group was defined")
return nil, nil, fmt.Errorf("a ws port was defined, but no ws group was defined")
}
for _, bg := range config.RPCMethodMappings {
if backendGroups[bg] == nil {
return nil, fmt.Errorf("undefined backend group %s", bg)
return nil, nil, fmt.Errorf("undefined backend group %s", bg)
}
}
......@@ -198,7 +195,7 @@ func Start(config *Config) (func(), error) {
for secret, alias := range config.Authentication {
resolvedSecret, err := ReadFromEnvOrConfig(secret)
if err != nil {
return nil, err
return nil, nil, err
}
resolvedAuth[resolvedSecret] = alias
}
......@@ -217,11 +214,11 @@ func Start(config *Config) (func(), error) {
)
if config.Cache.BlockSyncRPCURL == "" {
return nil, fmt.Errorf("block sync node required for caching")
return nil, nil, fmt.Errorf("block sync node required for caching")
}
blockSyncRPCURL, err := ReadFromEnvOrConfig(config.Cache.BlockSyncRPCURL)
if err != nil {
return nil, err
return nil, nil, err
}
if redisClient == nil {
......@@ -233,7 +230,7 @@ func Start(config *Config) (func(), error) {
// Ideally, the BlocKSyncRPCURL should be the sequencer or a HA replica that's not far behind
ethClient, err := ethclient.Dial(blockSyncRPCURL)
if err != nil {
return nil, err
return nil, nil, err
}
defer ethClient.Close()
......@@ -260,7 +257,7 @@ func Start(config *Config) (func(), error) {
redisClient,
)
if err != nil {
return nil, fmt.Errorf("error creating server: %w", err)
return nil, nil, fmt.Errorf("error creating server: %w", err)
}
if config.Metrics.Enabled {
......@@ -300,12 +297,28 @@ func Start(config *Config) (func(), error) {
log.Crit("error starting WS server", "err", err)
}
}()
} else {
log.Info("WS server not enabled (ws_port is set to 0)")
}
for bgName, bg := range backendGroups {
if config.BackendGroups[bgName].ConsensusAware {
log.Info("creating poller for consensus aware backend_group", "name", bgName)
copts := make([]ConsensusOpt, 0)
if config.BackendGroups[bgName].ConsensusAsyncHandler == "noop" {
copts = append(copts, WithAsyncHandler(NewNoopAsyncHandler()))
}
cp := NewConsensusPoller(bg, copts...)
bg.Consensus = cp
}
}
<-errTimer.C
log.Info("started proxyd")
return func() {
shutdownFunc := func() {
log.Info("shutting down proxyd")
if blockNumLVC != nil {
blockNumLVC.Stop()
......@@ -318,7 +331,9 @@ func Start(config *Config) (func(), error) {
log.Error("error flushing backend ws conns", "err", err)
}
log.Info("goodbye")
}, nil
}
return srv, shutdownFunc, nil
}
func secondsToDuration(seconds int) time.Duration {
......
......@@ -39,7 +39,7 @@ const (
var emptyArrayResponse = json.RawMessage("[]")
type Server struct {
backendGroups map[string]*BackendGroup
BackendGroups map[string]*BackendGroup
wsBackendGroup *BackendGroup
wsMethodWhitelist *StringSet
rpcMethodMappings map[string]string
......@@ -152,7 +152,7 @@ func NewServer(
}
return &Server{
backendGroups: backendGroups,
BackendGroups: backendGroups,
wsBackendGroup: wsBackendGroup,
wsMethodWhitelist: wsMethodWhitelist,
rpcMethodMappings: rpcMethodMappings,
......@@ -476,7 +476,7 @@ func (s *Server) handleBatchRPC(ctx context.Context, reqs []json.RawMessage, isL
start := i * s.maxUpstreamBatchSize
end := int(math.Min(float64(start+s.maxUpstreamBatchSize), float64(len(cacheMisses))))
elems := cacheMisses[start:end]
res, err := s.backendGroups[group.backendGroup].Forward(ctx, createBatchRequest(elems), isBatch)
res, err := s.BackendGroups[group.backendGroup].Forward(ctx, createBatchRequest(elems), isBatch)
if err != nil {
log.Error(
"error forwarding RPC batch",
......@@ -559,7 +559,7 @@ func (s *Server) populateContext(w http.ResponseWriter, r *http.Request) context
}
ctx := context.WithValue(r.Context(), ContextKeyXForwardedFor, xff) // nolint:staticcheck
if s.authenticatedPaths == nil {
if len(s.authenticatedPaths) == 0 {
// handle the edge case where auth is disabled
// but someone sends in an auth key anyway
if authorization != "" {
......
package handler
import (
"encoding/json"
"fmt"
"io"
"net/http"
"os"
"github.com/gorilla/mux"
"github.com/pkg/errors"
"gopkg.in/yaml.v3"
)
type MethodTemplate struct {
Method string `yaml:"method"`
Block string `yaml:"block"`
Response string `yaml:"response"`
}
type MockedHandler struct {
Overrides []*MethodTemplate
Autoload bool
AutoloadFile string
}
func (mh *MockedHandler) Serve(port int) error {
r := mux.NewRouter()
r.HandleFunc("/", mh.Handler)
http.Handle("/", r)
fmt.Printf("starting server up on :%d serving MockedResponsesFile %s\n", port, mh.AutoloadFile)
err := http.ListenAndServe(fmt.Sprintf(":%d", port), nil)
if errors.Is(err, http.ErrServerClosed) {
fmt.Printf("server closed\n")
} else if err != nil {
fmt.Printf("error starting server: %s\n", err)
return err
}
return nil
}
func (mh *MockedHandler) Handler(w http.ResponseWriter, req *http.Request) {
body, err := io.ReadAll(req.Body)
if err != nil {
fmt.Printf("error reading request: %v\n", err)
}
var j map[string]interface{}
err = json.Unmarshal(body, &j)
if err != nil {
fmt.Printf("error reading request: %v\n", err)
}
var template []*MethodTemplate
if mh.Autoload {
template = append(template, mh.LoadFromFile(mh.AutoloadFile)...)
}
if mh.Overrides != nil {
template = append(template, mh.Overrides...)
}
method := j["method"]
block := ""
if method == "eth_getBlockByNumber" {
block = (j["params"].([]interface{})[0]).(string)
}
var selectedResponse *string
for _, r := range template {
if r.Method == method && r.Block == block {
selectedResponse = &r.Response
}
}
if selectedResponse != nil {
_, err := fmt.Fprintf(w, *selectedResponse)
if err != nil {
fmt.Printf("error writing response: %v\n", err)
}
}
}
func (mh *MockedHandler) LoadFromFile(file string) []*MethodTemplate {
contents, err := os.ReadFile(file)
if err != nil {
fmt.Printf("error reading MockedResponsesFile: %v\n", err)
}
var template []*MethodTemplate
err = yaml.Unmarshal(contents, &template)
if err != nil {
fmt.Printf("error reading MockedResponsesFile: %v\n", err)
}
return template
}
func (mh *MockedHandler) AddOverride(template *MethodTemplate) {
mh.Overrides = append(mh.Overrides, template)
}
func (mh *MockedHandler) ResetOverrides() {
mh.Overrides = make([]*MethodTemplate, 0)
}
package main
import (
"fmt"
"os"
"path"
"strconv"
"github.com/ethereum-optimism/optimism/proxyd/tools/mockserver/handler"
)
func main() {
if len(os.Args) < 3 {
fmt.Printf("simply mock a response based on an external text MockedResponsesFile\n")
fmt.Printf("usage: mockserver <port> <MockedResponsesFile.yml>\n")
os.Exit(1)
}
port, _ := strconv.ParseInt(os.Args[1], 10, 32)
dir, _ := os.Getwd()
h := handler.MockedHandler{
Autoload: true,
AutoloadFile: path.Join(dir, os.Args[2]),
}
err := h.Serve(int(port))
if err != nil {
fmt.Printf("error starting mockserver: %v\n", err)
}
}
- method: eth_getBlockByNumber
block: latest
response: >
{
"jsonrpc": "2.0",
"id": 67,
"result": {
"hash": "hash2",
"number": "0x2"
}
}
- method: eth_getBlockByNumber
block: 0x1
response: >
{
"jsonrpc": "2.0",
"id": 67,
"result": {
"hash": "hash1",
"number": "0x1"
}
}
- method: eth_getBlockByNumber
block: 0x2
response: >
{
"jsonrpc": "2.0",
"id": 67,
"result": {
"hash": "hash2",
"number": "0x2"
}
}
- method: eth_getBlockByNumber
block: 0x3
response: >
{
"jsonrpc": "2.0",
"id": 67,
"result": {
"hash": "hash34",
"number": "0x3"
}
}
\ No newline at end of file
- method: eth_getBlockByNumber
block: latest
response: >
{
"jsonrpc": "2.0",
"id": 67,
"result": {
"hash": "hash2",
"number": "0x2"
}
}
- method: eth_getBlockByNumber
block: 0x1
response: >
{
"jsonrpc": "2.0",
"id": 67,
"result": {
"hash": "hash1",
"number": "0x1"
}
}
- method: eth_getBlockByNumber
block: 0x2
response: >
{
"jsonrpc": "2.0",
"id": 67,
"result": {
"hash": "hash2",
"number": "0x2"
}
}
- method: eth_getBlockByNumber
block: 0x3
response: >
{
"jsonrpc": "2.0",
"id": 67,
"result": {
"hash": "hash3",
"number": "0x3"
}
}
\ No newline at end of file
# Bond Manager Interface
<!-- START doctoc generated TOC please keep comment here to allow auto update -->
<!-- DON'T EDIT THIS SECTION, INSTEAD RE-RUN doctoc TO UPDATE -->
**Table of Contents**
- [Overview](#overview)
- [The Bond Problem](#the-bond-problem)
- [Simple Bond](#simple-bond)
- [Variable Bond](#variable-bond)
- [Contract Interface](#contract-interface)
- [Bond Manager Implementation](#bond-manager-implementation)
<!-- END doctoc generated TOC please keep comment here to allow auto update -->
## Overview
In the context of permissionless output proposals, bonds are a value that must
be attached to an output proposal. In this case, the bond will be paid in ether.
By requiring a bond to be posted with an output proposal, spam and invalid outputs
are disincentivized. Explicitly, if invalid outputs are proposed, challenge agents
can delete the invalid output via a [dispute-game](./dispute-game.md) and seize the
proposer's bond. So, posting invalid outputs is directly disincentivized in this way
since the proposer would lose their bond if the challenge agents seize it.
Concretely, outputs will be permissionlessly proposed to the `L2OutputOracle` contract.
When submitting an output proposal, the ether value is sent as the bond. This bond is
then held by a bond manager contract. The bond manager contract is responsible for
both the [dispute-games](./dispute-game.md) and the `L2OutputOracle` (further detailed
in [proposals](./proposals.md)).
The bond manager will need to handle bond logic for a variety of different
[dispute-games](./dispute-game-interface.md). In the simplest "attestation" dispute game,
bonds will not be required since the attestors are a permissioned set of trusted entities.
But in more complex games, such as the fault dispute game, challengers and defenders
perform a series of alternating onchain transactions requiring bonds at each step.
## The Bond Problem
At its core, the bond manager is straightforward - it escrows or holds ether and can be claimed
at maturity or seized if forfeited. But the uncertainty of introducing bonds lies in the
bond _sizing_, i.e. how much should a bond be? Sizing bonds correctly is a function of
the bond invariant: the bond must be greater than or equal to the cost of the next step.
If bonds are priced too low, then the bond invariant is violated and there isn't an economic
incentive to execute the next step. If bonds are priced too high, then the actors posting
bonds can be priced out.
Below, we outline two different approaches to sizing bonds and the tradeoffs of each.
### Simple Bond
The _Simple Bond_ is a very conservative approach to bond management, establishing a **fixed** bond
size. The idea behind simple bond pricing is to establish the worst case gas cost for
the next step in the dispute game.
With this approach, the size of the bond is computed up-front when a dispute game is created.
For example, in an attestation dispute game, this bond size can be computed as such:
```md
bond_size = (signer_threshold * (challenge_gas + security overhead)) + resolution_gas(signer_threshold)
```
Notice that since the bond size is linearly proportional to the number of signers, the economic
security a given bond size provides decreases as the number of signers increases. Also note, the
`resolution_gas` function is split out from the `challenge_gas` cost because only the _last_ challenger
will pay for the gas cost to resolve the game in the attestation dispute game.
Working backwards, if we assume the number of signers to be `5`, a negligible resolution gas cost, and
a `100,000` gas cost to progress the game, then the bond size should cover `500,000` gas. Meaning, a bond
of `1 ether` would cover the cost of progressing the game for `5` signers as long as the gas price
(base fee) does not exceed `2,000 gwei` for the entire finalization window. It would be prohibitively
expensive to keep the settlement layer base fee this high.
### Variable Bond
Better bond heuristics can be used to establish a bond price that accounts for
the time-weighted gas price. One instance of this called _Varable Bonds_ use a
separate oracle contract, `GasPriceFluctuationTracker`, that tracks gas fluctuations
within a pre-determined bounds. This replaces the ideal solution of tracking
challenge costs over all L1 blocks, but provides a reasonable bounds. The initial
actors posting this bond are responsible for funding this contract.
## Contract Interface
Below is a minimal interface for the bond manager contract.
```solidity
/**
* @title IBondManager
* @notice The IBondManager is an interface for a contract that handles bond management.
*/
interface IBondManager {
/**
* @notice Post a bond with a given id and owner.
* @dev This function will revert if the provided bondId is already in use.
* @param bondId is the id of the bond.
* @param owner is the address that owns the bond.
* @param minClaimHold is the minimum amount of time the owner must wait before reclaiming their bond.
*/
function post(bytes32 bondId, address owner, uint64 minClaimHold) external payable;
/**
* @notice Seizes the bond with the given id.
* @dev This function will revert if there is no bond at the given id.
* @param bondId is the id of the bond.
*/
function seize(bytes32 bondId) external;
/**
* @notice Seizes the bond with the given id and distributes it to recipients.
* @dev This function will revert if there is no bond at the given id.
* @param bondId is the id of the bond.
* @param recipients is a set of addresses to split the bond amongst.
*/
function seizeAndSplit(bytes32 bondId, address[] calldata recipients) external;
/**
* @notice Reclaims the bond of the bond owner.
* @dev This function will revert if there is no bond at the given id.
* @param bondId is the id of the bond.
*/
function reclaim(bytes32 bondId) external;
}
```
**Note**
The `bytes32 bondId` can be constructed using the `keccak256` hash of a given identifier.
For example, the `L2OutputOracle` can create a `bondId` by taking the `keccak256` hash of
the `l2BlockNumber` associated with the output proposal since there will only ever be one
outstanding output proposal for a given `l2BlockNumber`.
This also avoids the issue where an output proposer can have multiple bonds if bonds were
instead tied to the address of the output proposer.
## Bond Manager Implementation
Initially, the bond manager will only be used by the `L2OutputOracle` contract
for output proposals in the attestation [dispute game](./dispute-game.md). Since
the attestation dispute game has a permissioned set of attestors, there are no
intermediate steps in the game that would require bonds.
In the future however, Fault-based dispute games will be introduced and will
require bond management. In addition to the bond posted by the output proposer,
bonds will be posted at each step of the dispute game. Once the game is resolved,
bonds are dispersed to either the output challengers or defenders
(including the proposer).
......@@ -178,17 +178,21 @@ Note that hints may produce multiple pre-images:
e.g. a hint for an ethereum block with transaction list may prepare pre-images for the header,
each of the transactions, and the intermediate merkle-nodes that form the transactions-list Merkle Patricia Trie.
Hinting is implemented with a minimal wire-protocol over a blocking one-way stream:
Hinting is implemented with a request-acknowledgement wire-protocol over a blocking two-way stream:
```text
<request> := <length prefix> <hint bytes> <end>
<request> := <length prefix> <hint bytes>
<repsonse> := <ack>
<length prefix> := big-endian uint32 # length of <hint bytes>
<hint bytes> := byte sequence
<end> := 0 byte
<ack> := 1-byte zero value
```
The `<end>` trailing zero byte allows the server to block the program
(since the communication is blocking) until the hint is processed.
The ack informs the client that the hint has been processed. Servers may respond to hints and pre-image (see below)
requests asynchronously as they are on separate streams. To avoid requesting pre-images that are not yet fetched,
clients should request the pre-image only after it has observed the hint acknowledgement.
### Pre-image communication
......@@ -201,7 +205,6 @@ This protocol can be implemented with blocking read/write syscalls.
<response> := <length prefix> <pre-image bytes>
<length prefix> := big-endian uint64 # length of <pre-image bytes>, note: uint64
<hint bytes> := byte sequence #
```
The `<length prefix>` here may be arbitrarily high:
......
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