diff --git a/cmd/evm/internal/t8ntool/execution.go b/cmd/evm/internal/t8ntool/execution.go index ff4d50810bc..749bac9dbad 100644 --- a/cmd/evm/internal/t8ntool/execution.go +++ b/cmd/evm/internal/t8ntool/execution.go @@ -156,6 +156,10 @@ func (pre *Prestate) Apply(vmConfig vm.Config, chainConfig *params.ChainConfig, if chainConfig.IsFeynmanTransitionBlock(pre.Env.Timestamp, pre.Env.ParentTimestamp) { misc.ApplyFeynmanHardFork(statedb) } + // Apply GalileoV2 hard fork + if chainConfig.IsGalileoV2TransitionBlock(pre.Env.Timestamp, pre.Env.ParentTimestamp) { + misc.ApplyGalileoV2HardFork(statedb) + } // Apply EIP-2935 if pre.Env.BlockHashes != nil && chainConfig.IsFeynman(pre.Env.Timestamp) { var ( diff --git a/consensus/misc/galileoV2.go b/consensus/misc/galileoV2.go new file mode 100644 index 00000000000..87ffec19833 --- /dev/null +++ b/consensus/misc/galileoV2.go @@ -0,0 +1,20 @@ +package misc + +import ( + "github.com/scroll-tech/go-ethereum/common" + "github.com/scroll-tech/go-ethereum/core/state" + "github.com/scroll-tech/go-ethereum/log" + "github.com/scroll-tech/go-ethereum/rollup/rcfg" +) + +// ApplyGalileoV2HardFork modifies the state database according to the GalileoV2 hard-fork rules, +// updating the bytecode and storage of the L1GasPriceOracle contract. +func ApplyGalileoV2HardFork(statedb *state.StateDB) { + log.Info("Applying GalileoV2 hard fork") + + // update contract byte code + statedb.SetCode(rcfg.L1GasPriceOracleAddress, rcfg.GalileoV2L1GasPriceOracleBytecode) + + // initialize new storage slots + statedb.SetState(rcfg.L1GasPriceOracleAddress, rcfg.IsGalileoSlot, common.BytesToHash([]byte{1})) +} diff --git a/core/chain_makers.go b/core/chain_makers.go index f4b9418111e..025b8fbc471 100644 --- a/core/chain_makers.go +++ b/core/chain_makers.go @@ -252,6 +252,9 @@ func GenerateChain(config *params.ChainConfig, parent *types.Block, engine conse if config.IsFeynmanTransitionBlock(b.Time(), parent.Time()) { misc.ApplyFeynmanHardFork(statedb) } + if config.IsGalileoV2TransitionBlock(b.Time(), parent.Time()) { + misc.ApplyGalileoV2HardFork(statedb) + } // Execute any user modifications to the block if gen != nil { gen(i, b) diff --git a/core/state_processor.go b/core/state_processor.go index aea19a4e04c..2523ac75bd8 100644 --- a/core/state_processor.go +++ b/core/state_processor.go @@ -97,6 +97,10 @@ func (p *StateProcessor) Process(block *types.Block, statedb *state.StateDB, cfg if p.config.IsFeynmanTransitionBlock(block.Time(), parent.Time) { misc.ApplyFeynmanHardFork(statedb) } + // Apply GalileoV2 hard fork + if p.config.IsGalileoV2TransitionBlock(block.Time(), parent.Time) { + misc.ApplyGalileoV2HardFork(statedb) + } blockContext := NewEVMBlockContext(header, p.bc, p.config, nil) vmenv := vm.NewEVM(blockContext, vm.TxContext{}, statedb, p.config, cfg) processorBlockTransactionGauge.Update(int64(block.Transactions().Len())) diff --git a/eth/api.go b/eth/api.go index 06326d65b73..f4a9e9b08ad 100644 --- a/eth/api.go +++ b/eth/api.go @@ -362,10 +362,11 @@ func generateWitness(blockchain *core.BlockChain, block *types.Block) (*stateles // Collect storage locations that prover needs but sequencer might not touch necessarily statedb.GetState(rcfg.L2MessageQueueAddress, rcfg.WithdrawTrieRootSlot) - // Note: scroll-revm detects the Feynman transition block using this storage slot, + // Note: scroll-revm detects the Feynman and GalileoV2 transition blocks using these storage slots, // since it does not have access to the parent block timestamp. We need to make // sure that this is always present in the execution witness. statedb.GetState(rcfg.L1GasPriceOracleAddress, rcfg.IsFeynmanSlot) + statedb.GetState(rcfg.L1GasPriceOracleAddress, rcfg.IsGalileoSlot) // Ensure that all access list entries are included in the witness, // as these are always loaded by revm. diff --git a/miner/scroll_worker.go b/miner/scroll_worker.go index ffd7b7890bf..06d015b70c6 100644 --- a/miner/scroll_worker.go +++ b/miner/scroll_worker.go @@ -641,6 +641,11 @@ func (w *worker) handleForks(parent *types.Block) (bool, error) { misc.ApplyFeynmanHardFork(w.current.state) } + // Apply GalileoV2 hard fork + if w.chainConfig.IsGalileoV2TransitionBlock(w.current.header.Time, parent.Time()) { + misc.ApplyGalileoV2HardFork(w.current.state) + } + // Apply EIP-2935 if w.chainConfig.IsFeynman(w.current.header.Time) { context := core.NewEVMBlockContext(w.current.header, w.chain, w.chainConfig, nil) diff --git a/params/config.go b/params/config.go index a131a6ff09b..8a0784c09ea 100644 --- a/params/config.go +++ b/params/config.go @@ -334,6 +334,7 @@ var ( EuclidV2Time: newUint64(1741852800), FeynmanTime: newUint64(1753167600), GalileoTime: newUint64(1764054000), + GalileoV2Time: nil, Clique: &CliqueConfig{ Period: 3, Epoch: 30000, @@ -387,6 +388,8 @@ var ( EuclidTime: newUint64(1744815600), EuclidV2Time: newUint64(1745305200), FeynmanTime: newUint64(1755576000), + GalileoTime: nil, + GalileoV2Time: nil, Clique: &CliqueConfig{ Period: 3, Epoch: 30000, @@ -672,6 +675,7 @@ type ChainConfig struct { EuclidV2Time *uint64 `json:"euclidv2Time,omitempty"` // EuclidV2 switch time (nil = no fork, 0 = already on euclidv2) FeynmanTime *uint64 `json:"feynmanTime,omitempty"` // Feynman switch time (nil = no fork, 0 = already on feynman) GalileoTime *uint64 `json:"galileoTime,omitempty"` // Galileo switch time (nil = no fork, 0 = already on galileo) + GalileoV2Time *uint64 `json:"galileov2Time,omitempty"` // GalileoV2 switch time (nil = no fork, 0 = already on galileoV2) // TerminalTotalDifficulty is the amount of total difficulty reached by // the network that triggers the consensus upgrade. @@ -878,7 +882,11 @@ func (c *ChainConfig) String() string { if c.GalileoTime != nil { galileoTime = fmt.Sprintf("@%v", *c.GalileoTime) } - return fmt.Sprintf("{ChainID: %v Homestead: %v DAO: %v DAOSupport: %v EIP150: %v EIP155: %v EIP158: %v Byzantium: %v Constantinople: %v Petersburg: %v Istanbul: %v, Muir Glacier: %v, Berlin: %v, London: %v, Arrow Glacier: %v, Archimedes: %v, Shanghai: %v, Bernoulli: %v, Curie: %v, Darwin: %v, DarwinV2: %v, Euclid: %v, EuclidV2: %v, Feynman: %v, Galileo: %v, Engine: %v, Scroll config: %v}", + galileoV2Time := "" + if c.GalileoV2Time != nil { + galileoV2Time = fmt.Sprintf("@%v", *c.GalileoV2Time) + } + return fmt.Sprintf("{ChainID: %v Homestead: %v DAO: %v DAOSupport: %v EIP150: %v EIP155: %v EIP158: %v Byzantium: %v Constantinople: %v Petersburg: %v Istanbul: %v, Muir Glacier: %v, Berlin: %v, London: %v, Arrow Glacier: %v, Archimedes: %v, Shanghai: %v, Bernoulli: %v, Curie: %v, Darwin: %v, DarwinV2: %v, Euclid: %v, EuclidV2: %v, Feynman: %v, Galileo: %v, GalileoV2: %v, Engine: %v, Scroll config: %v}", c.ChainID, c.HomesteadBlock, c.DAOForkBlock, @@ -904,6 +912,7 @@ func (c *ChainConfig) String() string { euclidV2Time, feynmanTime, galileoTime, + galileoV2Time, engine, c.Scroll, ) @@ -1021,13 +1030,24 @@ func (c *ChainConfig) IsFeynman(now uint64) bool { return isForkedTime(now, c.FeynmanTime) } +// IsFeynmanTransitionBlock returns whether the given block timestamp corresponds to the first Feynman block. +func (c *ChainConfig) IsFeynmanTransitionBlock(blockTimestamp uint64, parentTimestamp uint64) bool { + return isForkedTime(blockTimestamp, c.FeynmanTime) && !isForkedTime(parentTimestamp, c.FeynmanTime) +} + +// IsGalileo returns whether time is either equal to the Galileo fork time or greater. func (c *ChainConfig) IsGalileo(now uint64) bool { return isForkedTime(now, c.GalileoTime) } -// IsFeynmanTransitionBlock returns whether the given block timestamp corresponds to the first Feynman block. -func (c *ChainConfig) IsFeynmanTransitionBlock(blockTimestamp uint64, parentTimestamp uint64) bool { - return isForkedTime(blockTimestamp, c.FeynmanTime) && !isForkedTime(parentTimestamp, c.FeynmanTime) +// IsGalileoV2 returns whether time is either equal to the GalileoV2 fork time or greater. +func (c *ChainConfig) IsGalileoV2(now uint64) bool { + return isForkedTime(now, c.GalileoV2Time) +} + +// IsGalileoV2TransitionBlock returns whether the given block timestamp corresponds to the first GalileoV2 block. +func (c *ChainConfig) IsGalileoV2TransitionBlock(blockTimestamp uint64, parentTimestamp uint64) bool { + return isForkedTime(blockTimestamp, c.GalileoV2Time) && !isForkedTime(parentTimestamp, c.GalileoV2Time) } // IsScroll returns whether the node is an scroll node or not. @@ -1258,7 +1278,7 @@ type Rules struct { IsByzantium, IsConstantinople, IsPetersburg, IsIstanbul bool IsBerlin, IsLondon, IsArchimedes, IsShanghai bool IsBernoulli, IsCurie, IsDarwin, IsEuclid, IsEuclidV2 bool - IsFeynman, IsGalileo bool + IsFeynman, IsGalileo, IsGalileoV2 bool } // Rules ensures c's ChainID is not nil. @@ -1288,5 +1308,6 @@ func (c *ChainConfig) Rules(num *big.Int, time uint64) Rules { IsEuclidV2: c.IsEuclidV2(time), IsFeynman: c.IsFeynman(time), IsGalileo: c.IsGalileo(time), + IsGalileoV2: c.IsGalileoV2(time), } } diff --git a/params/version.go b/params/version.go index 2034aada3f1..9e933658893 100644 --- a/params/version.go +++ b/params/version.go @@ -24,7 +24,7 @@ import ( const ( VersionMajor = 5 // Major version component of the current release VersionMinor = 9 // Minor version component of the current release - VersionPatch = 15 // Patch version component of the current release + VersionPatch = 16 // Patch version component of the current release VersionMeta = "mainnet" // Version metadata to append to the version string ) diff --git a/rollup/rcfg/config.go b/rollup/rcfg/config.go index 68626f4f865..64d01c9cf4a 100644 --- a/rollup/rcfg/config.go +++ b/rollup/rcfg/config.go @@ -48,6 +48,10 @@ var ( // | penaltyFactor | uint256 | 10 | 0 | 32 | // |------------------+---------------------+------+--------+-------+ // | isFeynman | bool | 11 | 0 | 1 | + // |------------------+---------------------+------+--------+-------+ + // | __gap | uint248 | 11 | 1 | 31 | + // |------------------+---------------------+------+--------+-------+ + // | isGalileo | bool | 12 | 0 | 1 | // ╰------------------+---------------------+------+--------+-------╯ L1GasPriceOracleAddress = common.HexToAddress("0x5300000000000000000000000000000000000002") @@ -64,6 +68,7 @@ var ( PenaltyThresholdSlot = common.BigToHash(big.NewInt(9)) // added in Feynman upgrade PenaltyFactorSlot = common.BigToHash(big.NewInt(10)) // added in Feynman upgrade IsFeynmanSlot = common.BigToHash(big.NewInt(11)) // added in Feynman upgrade + IsGalileoSlot = common.BigToHash(big.NewInt(12)) // added in GalileoV2 upgrade InitialCommitScalar = big.NewInt(230759955285) InitialBlobScalar = big.NewInt(417565260) @@ -88,6 +93,15 @@ var ( // forge build // cat artifacts/src/L1GasPriceOracle.sol/L1GasPriceOracle.json | jq -r .deployedBytecode.object FeynmanL1GasPriceOracleBytecode = common.Hex2Bytes("608060405234801561000f575f80fd5b50600436106101a1575f3560e01c806384189161116100f3578063c63b9e2d11610093578063e88a60ad1161006e578063e88a60ad1461032e578063f2fde38b14610341578063f45e65d814610354578063fe5b04151461035d575f80fd5b8063c63b9e2d146102ff578063c91e514914610312578063de26c4a11461031b575f80fd5b8063944b247f116100ce578063944b247f146102be578063a911d77f146102d1578063aa5e9334146102d9578063bede39b5146102ec575f80fd5b806384189161146102785780638da5cb5b1461028157806393e59dc1146102ab575f80fd5b80633d0f963e1161015e5780636112d6db116101395780636112d6db1461024b5780636a5e67e514610254578063704655971461025d578063715018a614610270575f80fd5b80633d0f963e1461021c57806349948e0e1461022f578063519b4bd314610242575f80fd5b80630c18c162146101a557806313dad5be146101c157806323e524ac146101de5780633577afc5146101e757806339455d3a146101fc5780633b7656bb1461020f575b5f80fd5b6101ae60025481565b6040519081526020015b60405180910390f35b6008546101ce9060ff1681565b60405190151581526020016101b8565b6101ae60065481565b6101fa6101f5366004610c73565b610365565b005b6101fa61020a366004610c8a565b6103f7565b600b546101ce9060ff1681565b6101fa61022a366004610caa565b6104f4565b6101ae61023d366004610ceb565b610577565b6101ae60015481565b6101ae600a5481565b6101ae60075481565b6101fa61026b366004610c73565b6105b0565b6101fa61063e565b6101ae60055481565b5f54610293906001600160a01b031681565b6040516001600160a01b0390911681526020016101b8565b600454610293906001600160a01b031681565b6101fa6102cc366004610c73565b610672565b6101fa6106fe565b6101fa6102e7366004610c73565b61075a565b6101fa6102fa366004610c73565b6107f4565b6101fa61030d366004610c73565b6108b1565b6101ae60095481565b6101ae610329366004610ceb565b61094a565b6101fa61033c366004610c73565b610974565b6101fa61034f366004610caa565b610a00565b6101ae60035481565b6101fa610a8b565b5f546001600160a01b031633146103975760405162461bcd60e51b815260040161038e90610d96565b60405180910390fd5b621c9c388111156103bb57604051635742c80560e11b815260040160405180910390fd5b60028190556040518181527f32740b35c0ea213650f60d44366b4fb211c9033b50714e4a1d34e65d5beb9bb4906020015b60405180910390a150565b6004805460405163efc7840160e01b815233928101929092526001600160a01b03169063efc7840190602401602060405180830381865afa15801561043e573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906104629190610dcd565b61047f576040516326b3506d60e11b815260040160405180910390fd5b600182905560058190556040518281527f351fb23757bb5ea0546c85b7996ddd7155f96b939ebaa5ff7bc49c75f27f2c449060200160405180910390a16040518181527f9a14bfb5d18c4c3cf14cae19c23d7cf1bcede357ea40ca1f75cd49542c71c214906020015b60405180910390a15050565b5f546001600160a01b0316331461051d5760405162461bcd60e51b815260040161038e90610d96565b600480546001600160a01b038381166001600160a01b031983168117909355604080519190921680825260208201939093527f22d1c35fe072d2e42c3c8f9bd4a0d34aa84a0101d020a62517b33fdb3174e5f791016104e8565b600b545f9060ff16156105935761058d82610ae7565b92915050565b60085460ff16156105a75761058d82610b45565b61058d82610b81565b5f546001600160a01b031633146105d95760405162461bcd60e51b815260040161038e90610d96565b6105e9633b9aca006103e8610e00565b81111561060957604051631e44fdeb60e11b815260040160405180910390fd5b60038190556040518181527f3336cd9708eaf2769a0f0dc0679f30e80f15dcd88d1921b5a16858e8b85c591a906020016103ec565b5f546001600160a01b031633146106675760405162461bcd60e51b815260040161038e90610d96565b6106705f610bc4565b565b5f546001600160a01b0316331461069b5760405162461bcd60e51b815260040161038e90610d96565b6106a9633b9aca0080610e00565b8111156106c95760405163874f603160e01b815260040160405180910390fd5b60068190556040518181527f2ab3f5a4ebbcbf3c24f62f5454f52f10e1a8c9dcc5acac8f19199ce881a6a108906020016103ec565b5f546001600160a01b031633146107275760405162461bcd60e51b815260040161038e90610d96565b60085460ff161561074b576040516379f9c57560e01b815260040160405180910390fd5b6008805460ff19166001179055565b5f546001600160a01b031633146107835760405162461bcd60e51b815260040161038e90610d96565b633b9aca008110806107a1575061079e633b9aca0080610e00565b81115b156107bf5760405163d9b5dcdf60e01b815260040160405180910390fd5b60098190556040518181527fd50d3079c77df569cd58d55d4e5614bfe7066449009425d22bde8e75242f50bb906020016103ec565b6004805460405163efc7840160e01b815233928101929092526001600160a01b03169063efc7840190602401602060405180830381865afa15801561083b573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061085f9190610dcd565b61087c576040516326b3506d60e11b815260040160405180910390fd5b60018190556040518181527f351fb23757bb5ea0546c85b7996ddd7155f96b939ebaa5ff7bc49c75f27f2c44906020016103ec565b5f546001600160a01b031633146108da5760405162461bcd60e51b815260040161038e90610d96565b633b9aca008110806108f857506108f5633b9aca0080610e00565b81115b156109155760405162ae184360e01b815260040160405180910390fd5b600a8190556040518181527f8647cebb7e57360673a28415c0bed2f68c42a86c5035f1c9b2eda2b09509288a906020016103ec565b600b545f9060ff168061095f575060085460ff165b1561096b57505f919050565b61058d82610c13565b5f546001600160a01b0316331461099d5760405162461bcd60e51b815260040161038e90610d96565b6109ab633b9aca0080610e00565b8111156109cb5760405163f37ec21560e01b815260040160405180910390fd5b60078190556040518181527f6b332a036d8c3ead57dcb06c87243bd7a2aed015ddf2d0528c2501dae56331aa906020016103ec565b5f546001600160a01b03163314610a295760405162461bcd60e51b815260040161038e90610d96565b6001600160a01b038116610a7f5760405162461bcd60e51b815260206004820152601d60248201527f6e6577206f776e657220697320746865207a65726f2061646472657373000000604482015260640161038e565b610a8881610bc4565b50565b5f546001600160a01b03163314610ab45760405162461bcd60e51b815260040161038e90610d96565b600b5460ff1615610ad857604051631a7c228b60e21b815260040160405180910390fd5b600b805460ff19166001179055565b5f633b9aca0080600a548451600554600754610b039190610e00565b600154600654610b139190610e00565b610b1d9190610e17565b610b279190610e00565b610b319190610e00565b610b3b9190610e2a565b61058d9190610e2a565b5f633b9aca006005548351600754610b5d9190610e00565b610b679190610e00565b600154600654610b779190610e00565b610b3b9190610e17565b5f80610b8c83610c13565b90505f60015482610b9d9190610e00565b9050633b9aca0060035482610bb29190610e00565b610bbc9190610e2a565b949350505050565b5f80546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b80515f908190815b81811015610c6457848181518110610c3557610c35610e49565b01602001516001600160f81b0319165f03610c5557600483019250610c5c565b6010830192505b600101610c1b565b50506002540160400192915050565b5f60208284031215610c83575f80fd5b5035919050565b5f8060408385031215610c9b575f80fd5b50508035926020909101359150565b5f60208284031215610cba575f80fd5b81356001600160a01b0381168114610cd0575f80fd5b9392505050565b634e487b7160e01b5f52604160045260245ffd5b5f60208284031215610cfb575f80fd5b813567ffffffffffffffff80821115610d12575f80fd5b818401915084601f830112610d25575f80fd5b813581811115610d3757610d37610cd7565b604051601f8201601f19908116603f01168101908382118183101715610d5f57610d5f610cd7565b81604052828152876020848701011115610d77575f80fd5b826020860160208301375f928101602001929092525095945050505050565b60208082526017908201527f63616c6c6572206973206e6f7420746865206f776e6572000000000000000000604082015260600190565b5f60208284031215610ddd575f80fd5b81518015158114610cd0575f80fd5b634e487b7160e01b5f52601160045260245ffd5b808202811582820484141761058d5761058d610dec565b8082018082111561058d5761058d610dec565b5f82610e4457634e487b7160e01b5f52601260045260245ffd5b500490565b634e487b7160e01b5f52603260045260245ffdfea164736f6c6343000818000a") + + // GalileoV2L1GasPriceOracleBytecode is the new gas price oracle after the GalileoV2 hard fork. + // Run these commands in the scroll-contracts repo to verify this bytecode: + // + // git checkout dfffa0f04bbd1de31ef342e1642a2f9ad9a620fe + // yarn + // forge build + // cat artifacts/src/L1GasPriceOracle.sol/L1GasPriceOracle.json | jq -r .deployedBytecode.object + GalileoV2L1GasPriceOracleBytecode = common.Hex2Bytes("608060405234801561000f575f80fd5b50600436106101c6575f3560e01c8063715018a6116100fe578063bede39b51161009e578063e88a60ad1161006e578063e88a60ad1461035d578063f2fde38b14610370578063f45e65d814610383578063fe5b04151461038c575f80fd5b8063bede39b51461031c578063c63b9e2d1461032f578063c91e514914610342578063de26c4a11461034a575f80fd5b80638da5cb5b116100d95780638da5cb5b146102c457806393e59dc1146102ee578063944b247f14610301578063a911d77f14610314575f80fd5b8063715018a6146102ab5780637f977cbf146102b357806384189161146102bb575f80fd5b80633d0f963e116101695780635471db39116101445780635471db391461027d5780636112d6db146102865780636a5e67e51461028f5780637046559714610298575f80fd5b80633d0f963e1461024e57806349948e0e14610261578063519b4bd314610274575f80fd5b806323e524ac116101a457806323e524ac146102105780633577afc51461021957806339455d3a1461022e5780633b7656bb14610241575f80fd5b80630c18c162146101ca5780630f337f6d146101e657806313dad5be14610203575b5f80fd5b6101d360025481565b6040519081526020015b60405180910390f35b600c546101f39060ff1681565b60405190151581526020016101dd565b6008546101f39060ff1681565b6101d360065481565b61022c610227366004610ccf565b610394565b005b61022c61023c366004610ce6565b610426565b600b546101f39060ff1681565b61022c61025c366004610d06565b610523565b6101d361026f366004610d47565b6105a6565b6101d360015481565b6101d360095481565b6101d3600a5481565b6101d360075481565b61022c6102a6366004610ccf565b6105f3565b61022c610681565b61022c6106b5565b6101d360055481565b5f546102d6906001600160a01b031681565b6040516001600160a01b0390911681526020016101dd565b6004546102d6906001600160a01b031681565b61022c61030f366004610ccf565b610711565b61022c61079d565b61022c61032a366004610ccf565b6107f9565b61022c61033d366004610ccf565b6108b6565b6009546101d3565b6101d3610358366004610d47565b610933565b61022c61036b366004610ccf565b61096a565b61022c61037e366004610d06565b6109f6565b6101d360035481565b61022c610a81565b5f546001600160a01b031633146103c65760405162461bcd60e51b81526004016103bd90610df2565b60405180910390fd5b621c9c388111156103ea57604051635742c80560e11b815260040160405180910390fd5b60028190556040518181527f32740b35c0ea213650f60d44366b4fb211c9033b50714e4a1d34e65d5beb9bb4906020015b60405180910390a150565b6004805460405163efc7840160e01b815233928101929092526001600160a01b03169063efc7840190602401602060405180830381865afa15801561046d573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906104919190610e29565b6104ae576040516326b3506d60e11b815260040160405180910390fd5b600182905560058190556040518281527f351fb23757bb5ea0546c85b7996ddd7155f96b939ebaa5ff7bc49c75f27f2c449060200160405180910390a16040518181527f9a14bfb5d18c4c3cf14cae19c23d7cf1bcede357ea40ca1f75cd49542c71c214906020015b60405180910390a15050565b5f546001600160a01b0316331461054c5760405162461bcd60e51b81526004016103bd90610df2565b600480546001600160a01b038381166001600160a01b031983168117909355604080519190921680825260208201939093527f22d1c35fe072d2e42c3c8f9bd4a0d34aa84a0101d020a62517b33fdb3174e5f79101610517565b600c545f9060ff16156105c2576105bc82610add565b92915050565b600b5460ff16156105d6576105bc82610b55565b60085460ff16156105ea576105bc82610bb3565b6105bc82610bef565b5f546001600160a01b0316331461061c5760405162461bcd60e51b81526004016103bd90610df2565b61062c633b9aca006103e8610e5c565b81111561064c57604051631e44fdeb60e11b815260040160405180910390fd5b60038190556040518181527f3336cd9708eaf2769a0f0dc0679f30e80f15dcd88d1921b5a16858e8b85c591a9060200161041b565b5f546001600160a01b031633146106aa5760405162461bcd60e51b81526004016103bd90610df2565b6106b35f610c20565b565b5f546001600160a01b031633146106de5760405162461bcd60e51b81526004016103bd90610df2565b600c5460ff16156107025760405163182389a760e01b815260040160405180910390fd5b600c805460ff19166001179055565b5f546001600160a01b0316331461073a5760405162461bcd60e51b81526004016103bd90610df2565b610748633b9aca0080610e5c565b8111156107685760405163874f603160e01b815260040160405180910390fd5b60068190556040518181527f2ab3f5a4ebbcbf3c24f62f5454f52f10e1a8c9dcc5acac8f19199ce881a6a1089060200161041b565b5f546001600160a01b031633146107c65760405162461bcd60e51b81526004016103bd90610df2565b60085460ff16156107ea576040516379f9c57560e01b815260040160405180910390fd5b6008805460ff19166001179055565b6004805460405163efc7840160e01b815233928101929092526001600160a01b03169063efc7840190602401602060405180830381865afa158015610840573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906108649190610e29565b610881576040516326b3506d60e11b815260040160405180910390fd5b60018190556040518181527f351fb23757bb5ea0546c85b7996ddd7155f96b939ebaa5ff7bc49c75f27f2c449060200161041b565b5f546001600160a01b031633146108df5760405162461bcd60e51b81526004016103bd90610df2565b805f036108fe5760405162ae184360e01b815260040160405180910390fd5b600a8190556040518181527f8647cebb7e57360673a28415c0bed2f68c42a86c5035f1c9b2eda2b09509288a9060200161041b565b600c545f9060ff16806109485750600b5460ff165b80610955575060085460ff165b1561096157505f919050565b6105bc82610c6f565b5f546001600160a01b031633146109935760405162461bcd60e51b81526004016103bd90610df2565b6109a1633b9aca0080610e5c565b8111156109c15760405163f37ec21560e01b815260040160405180910390fd5b60078190556040518181527f6b332a036d8c3ead57dcb06c87243bd7a2aed015ddf2d0528c2501dae56331aa9060200161041b565b5f546001600160a01b03163314610a1f5760405162461bcd60e51b81526004016103bd90610df2565b6001600160a01b038116610a755760405162461bcd60e51b815260206004820152601d60248201527f6e6577206f776e657220697320746865207a65726f206164647265737300000060448201526064016103bd565b610a7e81610c20565b50565b5f546001600160a01b03163314610aaa5760405162461bcd60e51b81526004016103bd90610df2565b600b5460ff1615610ace57604051631a7c228b60e21b815260040160405180910390fd5b600b805460ff19166001179055565b5f808251600554600754610af19190610e5c565b600154600654610b019190610e5c565b610b0b9190610e73565b610b159190610e5c565b90505f600a54845183610b289190610e5c565b610b329190610e86565b9050633b9aca00610b438284610e73565b610b4d9190610e86565b949350505050565b5f633b9aca0080600a548451600554600754610b719190610e5c565b600154600654610b819190610e5c565b610b8b9190610e73565b610b959190610e5c565b610b9f9190610e5c565b610ba99190610e86565b6105bc9190610e86565b5f633b9aca006005548351600754610bcb9190610e5c565b610bd59190610e5c565b600154600654610be59190610e5c565b610ba99190610e73565b5f80610bfa83610c6f565b90505f60015482610c0b9190610e5c565b9050633b9aca0060035482610b439190610e5c565b5f80546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b80515f908190815b81811015610cc057848181518110610c9157610c91610ea5565b01602001516001600160f81b0319165f03610cb157600483019250610cb8565b6010830192505b600101610c77565b50506002540160400192915050565b5f60208284031215610cdf575f80fd5b5035919050565b5f8060408385031215610cf7575f80fd5b50508035926020909101359150565b5f60208284031215610d16575f80fd5b81356001600160a01b0381168114610d2c575f80fd5b9392505050565b634e487b7160e01b5f52604160045260245ffd5b5f60208284031215610d57575f80fd5b813567ffffffffffffffff80821115610d6e575f80fd5b818401915084601f830112610d81575f80fd5b813581811115610d9357610d93610d33565b604051601f8201601f19908116603f01168101908382118183101715610dbb57610dbb610d33565b81604052828152876020848701011115610dd3575f80fd5b826020860160208301375f928101602001929092525095945050505050565b60208082526017908201527f63616c6c6572206973206e6f7420746865206f776e6572000000000000000000604082015260600190565b5f60208284031215610e39575f80fd5b81518015158114610d2c575f80fd5b634e487b7160e01b5f52601160045260245ffd5b80820281158282048414176105bc576105bc610e48565b808201808211156105bc576105bc610e48565b5f82610ea057634e487b7160e01b5f52601260045260245ffd5b500490565b634e487b7160e01b5f52603260045260245ffdfea164736f6c6343000818000a") ) // L2SystemConfig constants.