diff --git a/CHANGELOG.md b/CHANGELOG.md index 37d75695b8..274176f3e0 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,4 +1,37 @@ # Changelog +## v1.5.9 +### FEATURE +[\#2932](https://github.com/bnb-chain/bsc/pull/2932) BEP-520: Short Block Interval Phase One: 1.5 seconds +[\#2991](https://github.com/bnb-chain/bsc/pull/2991) config: update BSC Testnet hardfork time: Lorentz + +### BUGFIX +[\#2990](https://github.com/bnb-chain/bsc/pull/2990) core/state: fix concurrent map read and write for stateUpdate.accounts + +### IMPROVEMENT +[\#2933](https://github.com/bnb-chain/bsc/pull/2933) metrics: add more peer, block/vote metrics +[\#2938](https://github.com/bnb-chain/bsc/pull/2938) cmd/geth: add example for geth bls account generate-proof +[\#2949](https://github.com/bnb-chain/bsc/pull/2949) metrics: add more block/vote stats; +[\#2948](https://github.com/bnb-chain/bsc/pull/2948) go.mod: update crypto to solve CVE-2025-22869 +[\#2960](https://github.com/bnb-chain/bsc/pull/2960) pool: debug log instead of warn +[\#2961](https://github.com/bnb-chain/bsc/pull/2961) metric: add more block monitor metrics; +[\#2992](https://github.com/bnb-chain/bsc/pull/2992) core/systemcontracts: update url for lorentz hardfork +[\#2993](https://github.com/bnb-chain/bsc/pull/2993) cmd/jsutils: add tool GetMevStatus + +## v1.5.8 +### FEATURE +* [\#2955](https://github.com/bnb-chain/bsc/pull/2955) pbs: enable GreedyMergeTx by default + +### BUGFIX +* [\#2967](https://github.com/bnb-chain/bsc/pull/2967) fix: gas compare in bid simulator + +### IMPROVEMENT +* [\#2951](https://github.com/bnb-chain/bsc/pull/2951) bump golang.org/x/net from 0.34.0 to 0.36.0 +* [\#0000](https://github.com/bnb-chain/bsc/pull/0000) golang: upgrade toolchain to v1.23.0 (commit:3be156eec) +* [\#2957](https://github.com/bnb-chain/bsc/pull/2957) miner: stop GreedyMergeTx before worker picking bids +* [\#2959](https://github.com/bnb-chain/bsc/pull/2959) pbs: fix a inaccurate bid result log +* [\#2971](https://github.com/bnb-chain/bsc/pull/2971) mev: no interrupt if it is too later +* [\#2974](https://github.com/bnb-chain/bsc/pull/2974) miner: add metrics for bid simulation + ## v1.5.7 v1.5.7 conduct small upstream code merge to follow the latest pectra hard fork and apply some bug fix. There are two PR for the code merge: * [\#2897](https://github.com/bnb-chain/bsc/pull/2897) upstream: merge tag 'geth-v1.15.1' into bsc-develop diff --git a/cmd/geth/config.go b/cmd/geth/config.go index eb9c0208f2..69a6f31102 100644 --- a/cmd/geth/config.go +++ b/cmd/geth/config.go @@ -227,6 +227,7 @@ func makeFullNode(ctx *cli.Context) (*node.Node, ethapi.Backend) { } if ctx.IsSet(utils.OverrideMinBlocksForBlobRequests.Name) { params.MinBlocksForBlobRequests = ctx.Uint64(utils.OverrideMinBlocksForBlobRequests.Name) + params.MinTimeDurationForBlobRequests = uint64(float64(params.MinBlocksForBlobRequests) * 1.5 /*lorentzBlockInterval*/) } if ctx.IsSet(utils.OverrideDefaultExtraReserveForBlobRequests.Name) { params.DefaultExtraReserveForBlobRequests = ctx.Uint64(utils.OverrideDefaultExtraReserveForBlobRequests.Name) diff --git a/cmd/geth/testdata/bls-account-usage-demo.sh b/cmd/geth/testdata/bls-account-usage-demo.sh index ef4966c46d..b2b354d630 100644 --- a/cmd/geth/testdata/bls-account-usage-demo.sh +++ b/cmd/geth/testdata/bls-account-usage-demo.sh @@ -23,10 +23,13 @@ ${workspace}/build/bin/geth bls account list --blspassword ./bls-password.txt - echo "4. import a bls account by passing a keystore file------------------------------------------" keystoreFile=`ls bls1/bls/keystore` -${workspace}/build/bin/geth bls account import --importedaccountpassword ./bls-password1.txt --blspassword ./bls-password.txt --datadir ./bls ./bls1/bls/keystore/${keystoreFile} -${workspace}/build/bin/geth bls account list --blspassword ./bls-password.txt --datadir ./bls +${workspace}/build/bin/geth bls account import --importedaccountpassword ./bls-password1.txt --blspassword ./bls-password.txt --datadir ./bls ./bls1/bls/keystore/${keystoreFile} +publicKey=`${workspace}/build/bin/geth bls account list --blspassword ./bls-password.txt --datadir ./bls |grep public | tail -1 | awk '{print $NF}'` + +echo "5. generate ownership proof for the selected BLS account from the BLS wallet----------------" +${workspace}/build/bin/geth bls account generate-proof --blspassword ./bls-password.txt --datadir ./bls --chain-id 56 0x04d63aBCd2b9b1baa327f2Dda0f873F197ccd186 ${publicKey} -echo "5. clearup----------------------------------------------------------------------------------" +echo "6. clearup----------------------------------------------------------------------------------" rm -rf bls rm -rf bls1 rm -rf bls-password.txt diff --git a/cmd/jsutils/getchainstatus.js b/cmd/jsutils/getchainstatus.js index cad7cd0508..672041a3f8 100644 --- a/cmd/jsutils/getchainstatus.js +++ b/cmd/jsutils/getchainstatus.js @@ -24,6 +24,7 @@ function printUsage() { console.log(" GetBlobTxs: get BlobTxs of a block range"); console.log(" GetFaucetStatus: get faucet status of BSC testnet"); console.log(" GetKeyParameters: dump some key governance parameter"); + console.log(" GetMevStatus: get mev blocks of a block range"); console.log("\nOptions:"); console.log(" --rpc specify the url of RPC endpoint"); console.log(" --startNum the start block number"); @@ -43,6 +44,7 @@ function printUsage() { console.log(" node getchainstatus.js GetFaucetStatus --rpc https://bsc-testnet-dataseed.bnbchain.org --startNum 40000001 --endNum 40000010") console.log(" node getchainstatus.js GetKeyParameters --rpc https://bsc-testnet-dataseed.bnbchain.org") // default: latest block console.log(" node getchainstatus.js GetEip7623 --rpc https://bsc-testnet-dataseed.bnbchain.org --startNum 40000001 --endNum 40000010") + console.log(" node getchainstatus.js GetMevStatus --rpc https://bsc-testnet-dataseed.bnbchain.org --startNum 40000001 --endNum 40000010") } program.usage = printUsage; @@ -162,7 +164,38 @@ const validatorMap = new Map([ ["0xfA4d592F9B152f7a10B5DE9bE24C27a74BCE431A","MyTWFMM"] ]); - +const builderMap = new Map([ + // BSC mainnet + // blockrazor + ["0x5532CdB3c0c4278f9848fc4560b495b70bA67455", "blockrazor dublin"], + ["0xBA4233f6e478DB76698b0A5000972Af0196b7bE1", "blockrazor frankfurt"], + ["0x539E24781f616F0d912B60813aB75B7b80b75C53", "blockrazor nyc"], + ["0x49D91b1Ab0CC6A1591c2e5863E602d7159d36149", "blockrazor relay"], + ["0x50061047B9c7150f0Dc105f79588D1B07D2be250", "blockrazor tokyo"], + ["0x0557E8CB169F90F6eF421a54e29d7dd0629Ca597", "blockrazor virginia"], + ["0x488e37fcB2024A5B2F4342c7dE636f0825dE6448", "blockrazor x"], + // puissant + ["0x48a5Ed9abC1a8FBe86ceC4900483f43a7f2dBB48", "puissant ap"], + ["0x487e5Dfe70119C1b320B8219B190a6fa95a5BB48", "puissant eu"], + ["0x48FeE1BB3823D72fdF80671ebaD5646Ae397BB48", "puissant us"], + ["0x48B4bBEbF0655557A461e91B8905b85864B8BB48", "puissant x"], + ["0x4827b423D03a349b7519Dda537e9A28d31ecBB48", "puissant y"], + ["0x48B2665E5E9a343409199D70F7495c8aB660BB48", "puissant:z"], + // blockroute + ["0xD4376FdC9b49d90e6526dAa929f2766a33BFFD52", "blockroute dublin"], + ["0x2873fc7aD9122933BECB384f5856f0E87918388d", "blockroute frankfurt"], + ["0x432101856a330aafdeB049dD5fA03a756B3f1c66", "blockroute japan"], + ["0x2B217a4158933AAdE6D6494e3791D454B4D13AE7", "blockroute nyc"], + ["0x0da52E9673529b6E06F444FbBED2904A37f66415", "blockroute relay"], + ["0xE1ec1AeCE7953ecB4539749B9AA2eEF63354860a", "blockroute singapore"], + ["0x89434FC3a09e583F2cb4e47A8B8fe58De8BE6a15", "blockroute virginia"], + ["0x10353562E662E333C0c2007400284e0e21cF74fF", "blockroute x"], + // txboost + ["0x6Dddf681C908705472D09B1D7036B2241B50e5c7", "puissant ap"], + ["0x76736159984AE865a9b9Cc0Df61484A49dA68191", "puissant eu"], + ["0x5054b21D8baea3d602dca8761B235ee10bc0231E", "puissant us"], + // Chapel + ]); // 1.cmd: "GetMaxTxCountInBlockRange", usage: // node getchainstatus.js GetMaxTxCountInBlockRange --rpc https://bsc-testnet-dataseed.bnbchain.org \ @@ -347,7 +380,7 @@ async function getPerformanceData() { if (difficulty == 2) { inturnBlocks += 1 } - let timestamp = eval(eval(header.timestamp).toString(10)) + let timestamp = eval(eval(header.milliTimestamp).toString(10)) if (parliaEnabled) { let justifiedNumber = await provider.send("parlia_getJustifiedNumber", [ethers.toQuantity(i)]); if (justifiedNumber + 1 == i) { @@ -363,11 +396,11 @@ async function getPerformanceData() { let startHeader = await provider.send("eth_getHeaderByNumber", [ ethers.toQuantity(program.startNum)]); - let startTime = eval(eval(startHeader.timestamp).toString(10)) + let startTime = eval(eval(startHeader.milliTimestamp).toString(10)) let endHeader = await provider.send("eth_getHeaderByNumber", [ ethers.toQuantity(program.endNum)]); - let endTime = eval(eval(endHeader.timestamp).toString(10)) - let timeCost = endTime - startTime + let endTime = eval(eval(endHeader.milliTimestamp).toString(10)) + let timeCost = (endTime - startTime)/1000 let avgBlockTime = timeCost/blockCount let inturnBlocksRatio = inturnBlocks/blockCount let justifiedBlocksRatio = justifiedBlocks/blockCount @@ -550,6 +583,71 @@ async function getEip7623() { console.log(`Script executed in: ${duration} seconds`); } +// 10.cmd: "getMevStatus", usage: +// node getchainstatus.js GetMeVStatus \ +// --rpc https://bsc-testnet-dataseed.bnbchain.org \ +// --startNum 40000001 --endNum 40000005 +async function getMevStatus() { + let localCount = 0 + let blockrazorCount = 0 + let puissantCount = 0 + let blockrouteCount = 0 + let txboostCount = 0 + var startBlock = parseInt(program.startNum) + var endBlock = parseInt(program.endNum) + if (isNaN(endBlock) || isNaN(startBlock) || startBlock == 0) { + console.error("invalid input, --startNum", program.startNum, "--end", program.endNum) + return + } + // if --endNum is not specified, set it to the latest block number. + if (endBlock == 0) { + endBlock = await provider.getBlockNumber(); + } + if (startBlock > endBlock) { + console.error("invalid input, startBlock:", startBlock, " endBlock:", endBlock); + return + } + + for (let i = startBlock; i <= endBlock; i++) { + let blockData = await provider.getBlock(i); + let miner = validatorMap.get(blockData.miner) + const payBidTxReverseIdxMax = 3 + let mevBlock = false + for (let idx = 0; idx <= payBidTxReverseIdxMax && blockData.transactions.length - 1 - idx >= 0; idx++) { + var txIndex = blockData.transactions.length - 1 - idx + let txHash = blockData.transactions[txIndex] + let txData = await provider.getTransaction(txHash); + if (builderMap.has(txData.to)) { + let builder = builderMap.get(txData.to) + if (builder.search("blockrazor") != -1) { + blockrazorCount++ + } else if (builder.search("puissant") != -1) { + puissantCount++ + } else if (builder.search("blockroute") != -1) { + blockrouteCount++ + } else if (builder.search("txboost") != -1) { + txboostCount++ + } + mevBlock = true + console.log("blockNum:", i, " miner:", miner, " builder:("+builderMap.get(txData.to)+")", txData.to); + break + } + } + if (!mevBlock) { + localCount++ + console.log("blockNum:", i, " miner:", miner, " builder:local"); + } + } + console.log("Get Mev Status between [", program.startNum, ",", program.endNum, "]"); + let total = program.endNum - program.startNum + 1 + console.log("total =", total) + console.log("local =", localCount, " ratio =", (localCount / total).toFixed(2)) + console.log("blockrazor =", blockrazorCount, " ratio =", (blockrazorCount / total).toFixed(2)) + console.log("puissant =", puissantCount, " ratio =", (puissantCount / total).toFixed(2)) + console.log("blockroute =", blockrouteCount, " ratio =", (blockrouteCount / total).toFixed(2)) + console.log("txboost =", txboostCount, " ratio =", (txboostCount / total).toFixed(2)) + }; + const main = async () => { if (process.argv.length <= 2) { console.error('invalid process.argv.length', process.argv.length); @@ -579,6 +677,8 @@ const main = async () => { await getKeyParameters() } else if (cmd === "GetEip7623"){ await getEip7623() + } else if (cmd === "GetMevStatus"){ + await getMevStatus() } else { console.log("unsupported cmd", cmd); printUsage() diff --git a/common/bidutil/bidutil.go b/common/bidutil/bidutil.go index d2735808c6..22b3891d1f 100644 --- a/common/bidutil/bidutil.go +++ b/common/bidutil/bidutil.go @@ -17,7 +17,7 @@ func BidBetterBefore(parentHeader *types.Header, blockPeriod uint64, delayLeftOv // BidMustBefore returns the time when the next bid must be received, // only considering the consensus delay but not bid simulation duration. func BidMustBefore(parentHeader *types.Header, blockPeriod uint64, delayLeftOver time.Duration) time.Time { - nextHeaderTime := time.Unix(int64(parentHeader.Time+blockPeriod), 0) + nextHeaderTime := time.UnixMilli(int64(parentHeader.MilliTimestamp() + blockPeriod)) nextHeaderTime = nextHeaderTime.Add(-delayLeftOver) return nextHeaderTime } diff --git a/common/format.go b/common/format.go index 7af41f52d5..f8d2808846 100644 --- a/common/format.go +++ b/common/format.go @@ -80,3 +80,13 @@ func (t PrettyAge) String() string { } return result } + +func FormatMilliTime(n int64) string { + if n < 0 { + return "invalid" + } + if n == 0 { + return "" + } + return time.UnixMilli(n).Format("2006-01-02 15:04:05.000") +} diff --git a/consensus/consensus.go b/consensus/consensus.go index a58287f5e8..711646a8b0 100644 --- a/consensus/consensus.go +++ b/consensus/consensus.go @@ -162,6 +162,5 @@ type PoSA interface { GetFinalizedHeader(chain ChainHeaderReader, header *types.Header) *types.Header VerifyVote(chain ChainHeaderReader, vote *types.VoteEnvelope) error IsActiveValidatorAt(chain ChainHeaderReader, header *types.Header, checkVoteKeyFn func(bLSPublicKey *types.BLSPublicKey) bool) bool - BlockInterval() uint64 NextProposalBlock(chain ChainHeaderReader, header *types.Header, proposer common.Address) (uint64, uint64, error) } diff --git a/consensus/misc/eip1559/eip1559_test.go b/consensus/misc/eip1559/eip1559_test.go index 54f91046e3..0f68c6e860 100644 --- a/consensus/misc/eip1559/eip1559_test.go +++ b/consensus/misc/eip1559/eip1559_test.go @@ -52,10 +52,7 @@ func copyConfig(original *params.ChainConfig) *params.ChainConfig { func config() *params.ChainConfig { config := copyConfig(params.TestChainConfig) config.Ethash = nil - config.Parlia = ¶ms.ParliaConfig{ - Period: 3, - Epoch: 200, - } + config.Parlia = ¶ms.ParliaConfig{} config.LondonBlock = big.NewInt(5) return config } diff --git a/consensus/misc/eip4844/eip4844.go b/consensus/misc/eip4844/eip4844.go index 5d72563221..c077090287 100644 --- a/consensus/misc/eip4844/eip4844.go +++ b/consensus/misc/eip4844/eip4844.go @@ -83,7 +83,7 @@ func CalcExcessBlobGas(config *params.ChainConfig, parent *types.Header, headTim func CalcBlobFee(config *params.ChainConfig, header *types.Header) *big.Int { var frac uint64 switch config.LatestFork(header.Time) { - case forks.Prague: + case forks.Lorentz, forks.Prague: frac = config.BlobScheduleConfig.Prague.UpdateFraction case forks.Cancun: frac = config.BlobScheduleConfig.Cancun.UpdateFraction diff --git a/consensus/parlia/abi.go b/consensus/parlia/abi.go index 804dcdf7e0..7b08edaa0d 100644 --- a/consensus/parlia/abi.go +++ b/consensus/parlia/abi.go @@ -1501,19 +1501,6 @@ const validatorSetABI = ` ], "stateMutability": "view" }, - { - "type": "function", - "name": "EPOCH", - "inputs": [], - "outputs": [ - { - "name": "", - "type": "uint256", - "internalType": "uint256" - } - ], - "stateMutability": "view" - }, { "type": "function", "name": "ERROR_FAIL_CHECK_VALIDATORS", diff --git a/consensus/parlia/parlia.go b/consensus/parlia/parlia.go index 815946597a..21d7761b00 100644 --- a/consensus/parlia/parlia.go +++ b/consensus/parlia/parlia.go @@ -49,13 +49,18 @@ import ( ) const ( - inMemorySnapshots = 256 // Number of recent snapshots to keep in memory + inMemorySnapshots = 1280 // Number of recent snapshots to keep in memory; a buffer exceeding the EpochLength inMemorySignatures = 4096 // Number of recent block signatures to keep in memory inMemoryHeaders = 86400 // Number of recent headers to keep in memory for double sign detection, - checkpointInterval = 1024 // Number of blocks after which to save the snapshot to the database - defaultEpochLength = uint64(200) // Default number of blocks of checkpoint to update validatorSet from contract - defaultTurnLength = uint8(1) // Default consecutive number of blocks a validator receives priority for block production + checkpointInterval = 1024 // Number of blocks after which to save the snapshot to the database + + defaultEpochLength uint64 = 200 // Default number of blocks of checkpoint to update validatorSet from contract + lorentzEpochLength uint64 = 500 // Epoch length starting from the Lorentz hard fork + maxwellEpochLength uint64 = 1000 // Epoch length starting from the Maxwell hard fork + defaultBlockInterval uint64 = 3000 // Default block interval in milliseconds + lorentzBlockInterval uint64 = 1500 // Block interval starting from the Lorentz hard fork + defaultTurnLength uint8 = 1 // Default consecutive number of blocks a validator receives priority for block production extraVanity = 32 // Fixed number of extra-data prefix bytes reserved for signer vanity extraSeal = 65 // Fixed number of extra-data suffix bytes reserved for signer seal @@ -66,12 +71,18 @@ const ( validatorBytesLength = common.AddressLength + types.BLSPublicKeyLength validatorNumberSize = 1 // Fixed number of extra prefix bytes reserved for validator number after Luban - wiggleTime = uint64(1) // second, Random delay (per signer) to allow concurrent signers - initialBackOffTime = uint64(1) // second + wiggleTime uint64 = 1000 // milliseconds, Random delay (per signer) to allow concurrent signers + defaultInitialBackOffTime uint64 = 1000 // milliseconds, Default backoff time for the second validator permitted to produce blocks + lorentzInitialBackOffTime uint64 = 2000 // milliseconds, Backoff time for the second validator permitted to produce blocks from the Lorentz hard fork systemRewardPercent = 4 // it means 1/2^4 = 1/16 percentage of gas fee incoming will be distributed to system collectAdditionalVotesRewardRatio = 100 // ratio of additional reward for collecting more votes than needed, the denominator is 100 + + gasLimitBoundDivisorBeforeLorentz uint64 = 256 // The bound divisor of the gas limit, used in update calculations before lorentz hard fork. + + // `finalityRewardInterval` should be smaller than `inMemorySnapshots`, otherwise, it will result in excessive computation. + finalityRewardInterval = 200 ) var ( @@ -83,6 +94,7 @@ var ( updateAttestationErrorCounter = metrics.NewRegisteredCounter("parlia/updateAttestation/error", nil) validVotesfromSelfCounter = metrics.NewRegisteredCounter("parlia/VerifyVote/self", nil) doubleSignCounter = metrics.NewRegisteredCounter("parlia/doublesign", nil) + intentionalDelayMiningCounter = metrics.NewRegisteredCounter("parlia/intentionalDelayMining", nil) systemContracts = map[common.Address]bool{ common.HexToAddress(systemcontracts.ValidatorContract): true, @@ -263,11 +275,6 @@ func New( parliaConfig := chainConfig.Parlia log.Info("Parlia", "chainConfig", chainConfig) - // Set any missing consensus parameters to their defaults - if parliaConfig != nil && parliaConfig.Epoch == 0 { - parliaConfig.Epoch = defaultEpochLength - } - // Allocate the snapshot caches and create the engine recentSnaps, err := lru.NewARC(inMemorySnapshots) if err != nil { @@ -316,10 +323,6 @@ func New( return c } -func (p *Parlia) Period() uint64 { - return p.config.Period -} - func (p *Parlia) IsSystemTransaction(tx *types.Transaction, header *types.Header) (bool, error) { if tx.To() == nil || !isToSystemContract(*tx.To()) { return false, nil @@ -377,20 +380,20 @@ func (p *Parlia) VerifyHeaders(chain consensus.ChainHeaderReader, headers []*typ // On luban fork, we introduce vote attestation into the header's extra field, so extra format is different from before. // Before luban fork: |---Extra Vanity---|---Validators Bytes (or Empty)---|---Extra Seal---| // After luban fork: |---Extra Vanity---|---Validators Number and Validators Bytes (or Empty)---|---Vote Attestation (or Empty)---|---Extra Seal---| -// After bohr fork: |---Extra Vanity---|---Validators Number and Validators Bytes (or Empty)---|---Turn Length (or Empty)---|---Vote Attestation (or Empty)---|---Extra Seal---| -func getValidatorBytesFromHeader(header *types.Header, chainConfig *params.ChainConfig, parliaConfig *params.ParliaConfig) []byte { +// After bohr fork: |---Extra Vanity---|---Validators Number, Validators Bytes and Turn Length (or Empty)---|---Vote Attestation (or Empty)---|---Extra Seal---| +func getValidatorBytesFromHeader(header *types.Header, chainConfig *params.ChainConfig, epochLength uint64) []byte { if len(header.Extra) <= extraVanity+extraSeal { return nil } if !chainConfig.IsLuban(header.Number) { - if header.Number.Uint64()%parliaConfig.Epoch == 0 && (len(header.Extra)-extraSeal-extraVanity)%validatorBytesLengthBeforeLuban != 0 { + if header.Number.Uint64()%epochLength == 0 && (len(header.Extra)-extraSeal-extraVanity)%validatorBytesLengthBeforeLuban != 0 { return nil } return header.Extra[extraVanity : len(header.Extra)-extraSeal] } - if header.Number.Uint64()%parliaConfig.Epoch != 0 { + if header.Number.Uint64()%epochLength != 0 { return nil } num := int(header.Extra[extraVanity]) @@ -407,7 +410,7 @@ func getValidatorBytesFromHeader(header *types.Header, chainConfig *params.Chain } // getVoteAttestationFromHeader returns the vote attestation extracted from the header's extra field if exists. -func getVoteAttestationFromHeader(header *types.Header, chainConfig *params.ChainConfig, parliaConfig *params.ParliaConfig) (*types.VoteAttestation, error) { +func getVoteAttestationFromHeader(header *types.Header, chainConfig *params.ChainConfig, epochLength uint64) (*types.VoteAttestation, error) { if len(header.Extra) <= extraVanity+extraSeal { return nil, nil } @@ -417,7 +420,7 @@ func getVoteAttestationFromHeader(header *types.Header, chainConfig *params.Chai } var attestationBytes []byte - if header.Number.Uint64()%parliaConfig.Epoch != 0 { + if header.Number.Uint64()%epochLength != 0 { attestationBytes = header.Extra[extraVanity : len(header.Extra)-extraSeal] } else { num := int(header.Extra[extraVanity]) @@ -457,7 +460,11 @@ func (p *Parlia) getParent(chain consensus.ChainHeaderReader, header *types.Head // verifyVoteAttestation checks whether the vote attestation in the header is valid. func (p *Parlia) verifyVoteAttestation(chain consensus.ChainHeaderReader, header *types.Header, parents []*types.Header) error { - attestation, err := getVoteAttestationFromHeader(header, p.chainConfig, p.config) + epochLength, err := p.epochLength(chain, header, parents) + if err != nil { + return err + } + attestation, err := getVoteAttestationFromHeader(header, chain.Config(), epochLength) if err != nil { return err } @@ -571,10 +578,13 @@ func (p *Parlia) verifyHeader(chain consensus.ChainHeaderReader, header *types.H // check extra data number := header.Number.Uint64() - isEpoch := number%p.config.Epoch == 0 - + epochLength, err := p.epochLength(chain, header, parents) + if err != nil { + return err + } // Ensure that the extra-data contains a signer list on checkpoint, but none otherwise - signersBytes := getValidatorBytesFromHeader(header, p.chainConfig, p.config) + signersBytes := getValidatorBytesFromHeader(header, p.chainConfig, epochLength) + isEpoch := number%epochLength == 0 if !isEpoch && len(signersBytes) != 0 { return errExtraValidators } @@ -582,9 +592,15 @@ func (p *Parlia) verifyHeader(chain consensus.ChainHeaderReader, header *types.H return errInvalidSpanValidators } - // Ensure that the mix digest is zero as we don't have fork protection currently - if header.MixDigest != (common.Hash{}) { - return errInvalidMixDigest + lorentz := chain.Config().IsLorentz(header.Number, header.Time) + if !lorentz { + if header.MixDigest != (common.Hash{}) { + return errInvalidMixDigest + } + } else { + if header.MilliTimestamp()/1000 != header.Time { + return fmt.Errorf("invalid MixDigest, have %#x, expected the last two bytes to represent milliseconds", header.MixDigest) + } } // Ensure that the block doesn't contain any uncles which are meaningless in PoA if header.UncleHash != types.EmptyUncleHash { @@ -700,7 +716,11 @@ func (p *Parlia) verifyCascadingFields(chain consensus.ChainHeaderReader, header if diff < 0 { diff *= -1 } - limit := parent.GasLimit / params.GasLimitBoundDivisor + gasLimitBoundDivisor := gasLimitBoundDivisorBeforeLorentz + if p.chainConfig.IsLorentz(header.Number, header.Time) { + gasLimitBoundDivisor = params.GasLimitBoundDivisor + } + limit := parent.GasLimit / gasLimitBoundDivisor if uint64(diff) >= limit || header.GasLimit < params.MinGasLimit { return fmt.Errorf("invalid gas limit: have %d, want %d += %d", header.GasLimit, parent.GasLimit, limit-1) @@ -750,11 +770,20 @@ func (p *Parlia) snapshot(chain consensus.ChainHeaderReader, number uint64, hash // If we're at the genesis, snapshot the initial state. Alternatively if we have // piled up more headers than allowed to be reorged (chain reinit from a freezer), // consider the checkpoint trusted and snapshot it. - // An offset `p.config.Epoch - 1` can ensure getting the right validators. - if number == 0 || ((number+1)%p.config.Epoch == 0 && (len(headers) > int(params.FullImmutabilityThreshold))) { + + // Unable to retrieve the exact EpochLength here. + // As known + // defaultEpochLength = 200 && turnLength = 1 or 4 + // lorentzEpochLength = 500 && turnLength = 8 + // maxwellEpochLength = 1000 && turnLength = 16 + // So just select block number like 1200, 2200, 3200, we can always get the right validators from `number - 200` + offset := uint64(200) + if number == 0 || (number%maxwellEpochLength == offset && (len(headers) > int(params.FullImmutabilityThreshold))) { var ( - checkpoint *types.Header - blockHash common.Hash + checkpoint *types.Header + blockHash common.Hash + blockInterval = defaultBlockInterval + epochLength = defaultEpochLength ) if number == 0 { checkpoint = chain.GetHeaderByNumber(0) @@ -762,15 +791,26 @@ func (p *Parlia) snapshot(chain consensus.ChainHeaderReader, number uint64, hash blockHash = checkpoint.Hash() } } else { - checkpoint = chain.GetHeaderByNumber(number + 1 - p.config.Epoch) + checkpoint = chain.GetHeaderByNumber(number - offset) blockHeader := chain.GetHeaderByNumber(number) if blockHeader != nil { blockHash = blockHeader.Hash() + if p.chainConfig.IsLorentz(blockHeader.Number, blockHeader.Time) { + blockInterval = lorentzBlockInterval + } + } + if number > offset { // exclude `number == 200` + blockBeforeCheckpoint := chain.GetHeaderByNumber(number - offset - 1) + if blockBeforeCheckpoint != nil { + if p.chainConfig.IsLorentz(blockBeforeCheckpoint.Number, blockBeforeCheckpoint.Time) { + epochLength = lorentzEpochLength + } + } } } if checkpoint != nil && blockHash != (common.Hash{}) { // get validators from headers - validators, voteAddrs, err := parseValidators(checkpoint, p.chainConfig, p.config) + validators, voteAddrs, err := parseValidators(checkpoint, p.chainConfig, epochLength) if err != nil { return nil, err } @@ -779,13 +819,15 @@ func (p *Parlia) snapshot(chain consensus.ChainHeaderReader, number uint64, hash snap = newSnapshot(p.config, p.signatures, number, blockHash, validators, voteAddrs, p.ethAPI) // get turnLength from headers and use that for new turnLength - turnLength, err := parseTurnLength(checkpoint, p.chainConfig, p.config) + turnLength, err := parseTurnLength(checkpoint, p.chainConfig, epochLength) if err != nil { return nil, err } if turnLength != nil { snap.TurnLength = *turnLength } + snap.BlockInterval = blockInterval + snap.EpochLength = epochLength // snap.Recents is currently empty, which affects the following: // a. The function SignRecently - This is acceptable since an empty snap.Recents results in a more lenient check. @@ -925,8 +967,12 @@ func (p *Parlia) verifySeal(chain consensus.ChainHeaderReader, header *types.Hea return nil } -func (p *Parlia) prepareValidators(header *types.Header) error { - if header.Number.Uint64()%p.config.Epoch != 0 { +func (p *Parlia) prepareValidators(chain consensus.ChainHeaderReader, header *types.Header) error { + epochLength, err := p.epochLength(chain, header, nil) + if err != nil { + return err + } + if header.Number.Uint64()%epochLength != 0 { return nil } @@ -958,7 +1004,11 @@ func (p *Parlia) prepareValidators(header *types.Header) error { } func (p *Parlia) prepareTurnLength(chain consensus.ChainHeaderReader, header *types.Header) error { - if header.Number.Uint64()%p.config.Epoch != 0 || + epochLength, err := p.epochLength(chain, header, nil) + if err != nil { + return err + } + if header.Number.Uint64()%epochLength != 0 || !p.chainConfig.IsBohr(header.Number, header.Time) { return nil } @@ -1093,16 +1143,19 @@ func (p *Parlia) Prepare(chain consensus.ChainHeaderReader, header *types.Header if parent == nil { return consensus.ErrUnknownAncestor } - header.Time = p.blockTimeForRamanujanFork(snap, header, parent) - if header.Time < uint64(time.Now().Unix()) { - header.Time = uint64(time.Now().Unix()) + blockTime := p.blockTimeForRamanujanFork(snap, header, parent) + header.Time = blockTime / 1000 // get seconds + if p.chainConfig.IsLorentz(header.Number, header.Time) { + header.SetMilliseconds(blockTime % 1000) + } else { + header.MixDigest = common.Hash{} } header.Extra = header.Extra[:extraVanity-nextForkHashSize] nextForkHash := forkid.NextForkHash(p.chainConfig, p.genesisHash, chain.GenesisHeader().Time, number, header.Time) header.Extra = append(header.Extra, nextForkHash[:]...) - if err := p.prepareValidators(header); err != nil { + if err := p.prepareValidators(chain, header); err != nil { return err } @@ -1112,14 +1165,15 @@ func (p *Parlia) Prepare(chain consensus.ChainHeaderReader, header *types.Header // add extra seal space header.Extra = append(header.Extra, make([]byte, extraSeal)...) - // Mix digest is reserved for now, set to empty - header.MixDigest = common.Hash{} - return nil } -func (p *Parlia) verifyValidators(header *types.Header) error { - if header.Number.Uint64()%p.config.Epoch != 0 { +func (p *Parlia) verifyValidators(chain consensus.ChainHeaderReader, header *types.Header) error { + epochLength, err := p.epochLength(chain, header, nil) + if err != nil { + return err + } + if header.Number.Uint64()%epochLength != 0 { return nil } @@ -1153,19 +1207,23 @@ func (p *Parlia) verifyValidators(header *types.Header) error { copy(validatorsBytes[i*validatorBytesLength+common.AddressLength:], voteAddressMap[validator].Bytes()) } } - if !bytes.Equal(getValidatorBytesFromHeader(header, p.chainConfig, p.config), validatorsBytes) { + if !bytes.Equal(getValidatorBytesFromHeader(header, p.chainConfig, epochLength), validatorsBytes) { return errMismatchingEpochValidators } return nil } func (p *Parlia) verifyTurnLength(chain consensus.ChainHeaderReader, header *types.Header) error { - if header.Number.Uint64()%p.config.Epoch != 0 || + epochLength, err := p.epochLength(chain, header, nil) + if err != nil { + return err + } + if header.Number.Uint64()%epochLength != 0 || !p.chainConfig.IsBohr(header.Number, header.Time) { return nil } - turnLengthFromHeader, err := parseTurnLength(header, p.chainConfig, p.config) + turnLengthFromHeader, err := parseTurnLength(header, p.chainConfig, epochLength) if err != nil { return err } @@ -1187,20 +1245,22 @@ func (p *Parlia) distributeFinalityReward(chain consensus.ChainHeaderReader, sta cx core.ChainContext, txs *[]*types.Transaction, receipts *[]*types.Receipt, systemTxs *[]*types.Transaction, usedGas *uint64, mining bool, tracer *tracing.Hooks) error { currentHeight := header.Number.Uint64() - epoch := p.config.Epoch - chainConfig := chain.Config() - if currentHeight%epoch != 0 { + if currentHeight%finalityRewardInterval != 0 { return nil } head := header accumulatedWeights := make(map[common.Address]uint64) - for height := currentHeight - 1; height+epoch >= currentHeight && height >= 1; height-- { + for height := currentHeight - 1; height+finalityRewardInterval >= currentHeight && height >= 1; height-- { head = chain.GetHeaderByHash(head.ParentHash) if head == nil { return fmt.Errorf("header is nil at height %d", height) } - voteAttestation, err := getVoteAttestationFromHeader(head, chainConfig, p.config) + epochLength, err := p.epochLength(chain, head, nil) + if err != nil { + return err + } + voteAttestation, err := getVoteAttestationFromHeader(head, chain.Config(), epochLength) if err != nil { return err } @@ -1311,7 +1371,7 @@ func (p *Parlia) Finalize(chain consensus.ChainHeaderReader, header *types.Heade } // If the block is an epoch end block, verify the validator list // The verification can only be done when the state is ready, it can't be done in VerifyHeader. - if err := p.verifyValidators(header); err != nil { + if err := p.verifyValidators(chain, header); err != nil { return err } @@ -1365,7 +1425,16 @@ func (p *Parlia) Finalize(chain consensus.ChainHeaderReader, header *types.Heade } } } + val := header.Coinbase + PenalizeForDelayMining, err := p.isIntentionalDelayMining(chain, header) + if err != nil { + log.Debug("unexpected error happened when detecting intentional delay mining", "err", err) + } + if PenalizeForDelayMining { + intentionalDelayMiningCounter.Inc(1) + log.Warn("intentional delay mining detected", "validator", val, "number", header.Number, "hash", header.Hash()) + } err = p.distributeIncoming(val, state, header, cx, txs, receipts, systemTxs, usedGas, false, tracer) if err != nil { return err @@ -1576,9 +1645,9 @@ func (p *Parlia) Delay(chain consensus.ChainReader, header *types.Header, leftOv } delay := p.delayForRamanujanFork(snap, header) - if *leftOver >= time.Duration(p.config.Period)*time.Second { + if *leftOver >= time.Duration(snap.BlockInterval)*time.Millisecond { // ignore invalid leftOver - log.Error("Delay invalid argument", "leftOver", leftOver.String(), "Period", p.config.Period) + log.Error("Delay invalid argument", "leftOver", leftOver.String(), "Period", snap.BlockInterval) } else if *leftOver >= delay { delay = time.Duration(0) return &delay @@ -1587,9 +1656,9 @@ func (p *Parlia) Delay(chain consensus.ChainReader, header *types.Header, leftOv } // The blocking time should be no more than half of period when snap.TurnLength == 1 - timeForMining := time.Duration(p.config.Period) * time.Second / 2 + timeForMining := time.Duration(snap.BlockInterval) * time.Millisecond / 2 if !snap.lastBlockInOneTurn(header.Number.Uint64()) { - timeForMining = time.Duration(p.config.Period) * time.Second * 2 / 3 + timeForMining = time.Duration(snap.BlockInterval) * time.Millisecond * 2 / 3 } if delay > timeForMining { delay = timeForMining @@ -1607,11 +1676,6 @@ func (p *Parlia) Seal(chain consensus.ChainHeaderReader, block *types.Block, res if number == 0 { return errUnknownBlock } - // For 0-period chains, refuse to seal empty blocks (no reward but would spin sealing) - if p.config.Period == 0 && len(block.Transactions()) == 0 { - log.Info("Sealing paused, waiting for transactions") - return nil - } // Don't hold the val fields for the entire sealing procedure p.lock.RLock() val, signFn := p.val, p.signFn @@ -1850,6 +1914,21 @@ func (p *Parlia) getCurrentValidators(blockHash common.Hash, blockNum *big.Int) return valSet, voteAddrMap, nil } +func (p *Parlia) isIntentionalDelayMining(chain consensus.ChainHeaderReader, header *types.Header) (bool, error) { + parent := chain.GetHeader(header.ParentHash, header.Number.Uint64()-1) + if parent == nil { + return false, errors.New("parent not found") + } + blockInterval, err := p.BlockInterval(chain, header) + if err != nil { + return false, err + } + isIntentional := header.Coinbase == parent.Coinbase && + header.Difficulty == diffInTurn && parent.Difficulty == diffInTurn && + parent.MilliTimestamp()+blockInterval < header.MilliTimestamp() + return isIntentional, nil +} + // distributeIncoming distributes system incoming of the block func (p *Parlia) distributeIncoming(val common.Address, state vm.StateDB, header *types.Header, chain core.ChainContext, txs *[]*types.Transaction, receipts *[]*types.Receipt, receivedTxs *[]*types.Transaction, usedGas *uint64, mining bool, tracer *tracing.Hooks) error { @@ -2121,17 +2200,26 @@ func (p *Parlia) GetFinalizedHeader(chain consensus.ChainHeaderReader, header *t } // =========================== utility function ========================== -func (p *Parlia) backOffTime(snap *Snapshot, header *types.Header, val common.Address) uint64 { +func (p *Parlia) backOffTime(snap *Snapshot, parent, header *types.Header, val common.Address) uint64 { if snap.inturn(val) { log.Debug("backOffTime", "blockNumber", header.Number, "in turn validator", val) return 0 } else { - delay := initialBackOffTime + delay := defaultInitialBackOffTime + // When mining blocks, `header.Time` is temporarily set to time.Now() + 1. + // Therefore, using `header.Time` to determine whether a hard fork has occurred is incorrect. + // As a result, during the Bohr and Lorentz hard forks, the network may experience some instability, + // So use `parent.Time` instead. + isParerntLorentz := p.chainConfig.IsLorentz(parent.Number, parent.Time) + if isParerntLorentz { + // If the in-turn validator has not signed recently, the expected backoff times are [2, 3, 4, ...]. + delay = lorentzInitialBackOffTime + } validators := snap.validators() if p.chainConfig.IsPlanck(header.Number) { counts := snap.countRecents() for addr, seenTimes := range counts { - log.Debug("backOffTime", "blockNumber", header.Number, "validator", addr, "seenTimes", seenTimes) + log.Trace("backOffTime", "blockNumber", header.Number, "validator", addr, "seenTimes", seenTimes) } // The backOffTime does not matter when a validator has signed recently. @@ -2191,13 +2279,46 @@ func (p *Parlia) backOffTime(snap *Snapshot, header *types.Header, val common.Ad backOffSteps[i], backOffSteps[j] = backOffSteps[j], backOffSteps[i] }) + if delay == 0 && isParerntLorentz { + // If the in-turn validator has signed recently, the expected backoff times are [0, 2, 3, ...]. + if backOffSteps[idx] == 0 { + return 0 + } + return lorentzInitialBackOffTime + (backOffSteps[idx]-1)*wiggleTime + } delay += backOffSteps[idx] * wiggleTime return delay } } -func (p *Parlia) BlockInterval() uint64 { - return p.config.Period +// BlockInterval returns number of blocks in one epoch for the given header +func (p *Parlia) epochLength(chain consensus.ChainHeaderReader, header *types.Header, parents []*types.Header) (uint64, error) { + if header == nil { + return defaultEpochLength, errUnknownBlock + } + if header.Number.Uint64() == 0 { + return defaultEpochLength, nil + } + snap, err := p.snapshot(chain, header.Number.Uint64()-1, header.ParentHash, parents) + if err != nil { + return defaultEpochLength, err + } + return snap.EpochLength, nil +} + +// BlockInterval returns the block interval in milliseconds for the given header +func (p *Parlia) BlockInterval(chain consensus.ChainHeaderReader, header *types.Header) (uint64, error) { + if header == nil { + return defaultBlockInterval, errUnknownBlock + } + if header.Number.Uint64() == 0 { + return defaultBlockInterval, nil + } + snap, err := p.snapshot(chain, header.Number.Uint64()-1, header.ParentHash, nil) + if err != nil { + return defaultBlockInterval, err + } + return snap.BlockInterval, nil } func (p *Parlia) NextProposalBlock(chain consensus.ChainHeaderReader, header *types.Header, proposer common.Address) (uint64, uint64, error) { diff --git a/consensus/parlia/parlia_test.go b/consensus/parlia/parlia_test.go index 07705b3a6b..44d422402d 100644 --- a/consensus/parlia/parlia_test.go +++ b/consensus/parlia/parlia_test.go @@ -178,7 +178,7 @@ func producerBlockDelay(candidates map[int]bool, height, numOfValidators int) (i minCandidate = c } } - delay := initialBackOffTime + uint64(minDelay)*wiggleTime + delay := defaultInitialBackOffTime + uint64(minDelay)*wiggleTime return minCandidate, delay } diff --git a/consensus/parlia/ramanujanfork.go b/consensus/parlia/ramanujanfork.go index ce9089debc..64d149bf28 100644 --- a/consensus/parlia/ramanujanfork.go +++ b/consensus/parlia/ramanujanfork.go @@ -4,6 +4,7 @@ import ( "math/rand" "time" + cmath "github.com/ethereum/go-ethereum/common/math" "github.com/ethereum/go-ethereum/consensus" "github.com/ethereum/go-ethereum/core/types" ) @@ -11,10 +12,11 @@ import ( const ( wiggleTimeBeforeFork = 500 * time.Millisecond // Random delay (per signer) to allow concurrent signers fixedBackOffTimeBeforeFork = 200 * time.Millisecond + millisecondsUnit = 500 // Set to 250 if block interval is 750ms; not enforced at the consensus level ) func (p *Parlia) delayForRamanujanFork(snap *Snapshot, header *types.Header) time.Duration { - delay := time.Until(time.Unix(int64(header.Time), 0)) // nolint: gosimple + delay := time.Until(time.UnixMilli(int64(header.MilliTimestamp()))) // nolint: gosimple if p.chainConfig.IsRamanujan(header.Number) { return delay } @@ -27,16 +29,20 @@ func (p *Parlia) delayForRamanujanFork(snap *Snapshot, header *types.Header) tim } func (p *Parlia) blockTimeForRamanujanFork(snap *Snapshot, header, parent *types.Header) uint64 { - blockTime := parent.Time + p.config.Period + blockTime := parent.MilliTimestamp() + snap.BlockInterval if p.chainConfig.IsRamanujan(header.Number) { - blockTime = blockTime + p.backOffTime(snap, header, p.val) + blockTime = blockTime + p.backOffTime(snap, parent, header, p.val) + } + if now := uint64(time.Now().UnixMilli()); blockTime < now { + // Just to make the millisecond part of the time look more aligned. + blockTime = uint64(cmath.CeilDiv(int(now), millisecondsUnit)) * millisecondsUnit } return blockTime } func (p *Parlia) blockTimeVerifyForRamanujanFork(snap *Snapshot, header, parent *types.Header) error { if p.chainConfig.IsRamanujan(header.Number) { - if header.Time < parent.Time+p.config.Period+p.backOffTime(snap, header, header.Coinbase) { + if header.MilliTimestamp() < parent.MilliTimestamp()+snap.BlockInterval+p.backOffTime(snap, parent, header, header.Coinbase) { return consensus.ErrFutureBlock } } diff --git a/consensus/parlia/snapshot.go b/consensus/parlia/snapshot.go index d474c06041..ebdbcbe1ed 100644 --- a/consensus/parlia/snapshot.go +++ b/consensus/parlia/snapshot.go @@ -44,6 +44,8 @@ type Snapshot struct { Number uint64 `json:"number"` // Block number where the snapshot was created Hash common.Hash `json:"hash"` // Block hash where the snapshot was created + EpochLength uint64 `json:"epoch_length"` // Number of Blocks in one epoch + BlockInterval uint64 `json:"block_interval"` // Block Interval in milliseconds TurnLength uint8 `json:"turn_length"` // Length of `turn`, meaning the consecutive number of blocks a validator receives priority for block production Validators map[common.Address]*ValidatorInfo `json:"validators"` // Set of authorized validators at this moment Recents map[uint64]common.Address `json:"recents"` // Set of recent validators for spam protections @@ -74,6 +76,8 @@ func newSnapshot( sigCache: sigCache, Number: number, Hash: hash, + EpochLength: defaultEpochLength, + BlockInterval: defaultBlockInterval, TurnLength: defaultTurnLength, Recents: make(map[uint64]common.Address), RecentForkHashes: make(map[uint64]string), @@ -117,6 +121,12 @@ func loadSnapshot(config *params.ParliaConfig, sigCache *lru.ARCCache, db ethdb. if err := json.Unmarshal(blob, snap); err != nil { return nil, err } + if snap.EpochLength == 0 { // no EpochLength field in old snapshots + snap.EpochLength = defaultEpochLength + } + if snap.BlockInterval == 0 { // no BlockInterval field in old snapshots + snap.BlockInterval = defaultBlockInterval + } if snap.TurnLength == 0 { // no TurnLength field in old snapshots snap.TurnLength = defaultTurnLength } @@ -145,6 +155,8 @@ func (s *Snapshot) copy() *Snapshot { sigCache: s.sigCache, Number: s.Number, Hash: s.Hash, + EpochLength: s.EpochLength, + BlockInterval: s.BlockInterval, TurnLength: s.TurnLength, Validators: make(map[common.Address]*ValidatorInfo), Recents: make(map[uint64]common.Address), @@ -184,13 +196,13 @@ func (s *Snapshot) isMajorityFork(forkHash string) bool { return ally > len(s.RecentForkHashes)/2 } -func (s *Snapshot) updateAttestation(header *types.Header, chainConfig *params.ChainConfig, parliaConfig *params.ParliaConfig) { +func (s *Snapshot) updateAttestation(header *types.Header, chainConfig *params.ChainConfig, epochLength uint64) { if !chainConfig.IsLuban(header.Number) { return } // The attestation should have been checked in verify header, update directly - attestation, _ := getVoteAttestationFromHeader(header, chainConfig, parliaConfig) + attestation, _ := getVoteAttestationFromHeader(header, chainConfig, epochLength) if attestation == nil { return } @@ -310,10 +322,18 @@ func (s *Snapshot) apply(headers []*types.Header, chain consensus.ChainHeaderRea } snap.Recents[number] = validator snap.RecentForkHashes[number] = hex.EncodeToString(header.Extra[extraVanity-nextForkHashSize : extraVanity]) - snap.updateAttestation(header, chainConfig, s.config) + epochLength := snap.EpochLength + snap.updateAttestation(header, chainConfig, epochLength) + if chainConfig.IsLorentz(header.Number, header.Time) { + // Without this condition, an incorrect block might be used to parse validators for certain blocks after the Lorentz hard fork. + if (header.Number.Uint64()+1)%lorentzEpochLength == 0 { + snap.EpochLength = lorentzEpochLength + } + snap.BlockInterval = lorentzBlockInterval + } // change validator set - if number > 0 && number%s.config.Epoch == snap.minerHistoryCheckLen() { - epochKey := math.MaxUint64 - header.Number.Uint64()/s.config.Epoch // impossible used as a block number + if number > 0 && number%epochLength == snap.minerHistoryCheckLen() { + epochKey := math.MaxUint64 - header.Number.Uint64()/epochLength // impossible used as a block number if chainConfig.IsBohr(header.Number, header.Time) { // after switching the validator set, snap.Validators may become larger, // then the unexpected second switch will happen, just skip it. @@ -329,7 +349,7 @@ func (s *Snapshot) apply(headers []*types.Header, chain consensus.ChainHeaderRea oldVersionsLen := snap.versionHistoryCheckLen() // get turnLength from headers and use that for new turnLength - turnLength, err := parseTurnLength(checkpointHeader, chainConfig, s.config) + turnLength, err := parseTurnLength(checkpointHeader, chainConfig, epochLength) if err != nil { return nil, err } @@ -339,7 +359,7 @@ func (s *Snapshot) apply(headers []*types.Header, chain consensus.ChainHeaderRea } // get validators from headers and use that for new validator set - newValArr, voteAddrs, err := parseValidators(checkpointHeader, chainConfig, s.config) + newValArr, voteAddrs, err := parseValidators(checkpointHeader, chainConfig, epochLength) if err != nil { return nil, err } @@ -412,12 +432,13 @@ func (s *Snapshot) inturnValidator() common.Address { } func (s *Snapshot) nexValidatorsChangeBlock() uint64 { - currentEpoch := s.Number - s.Number%s.config.Epoch + epochLength := s.EpochLength + currentEpoch := s.Number - s.Number%epochLength checkLen := s.minerHistoryCheckLen() - if s.Number%s.config.Epoch < checkLen { + if s.Number%epochLength < checkLen { return currentEpoch + checkLen } - return currentEpoch + s.config.Epoch + checkLen + return currentEpoch + epochLength + checkLen } // nextProposalBlock returns the validator next proposal block. @@ -476,8 +497,8 @@ func (s *Snapshot) indexOfVal(validator common.Address) int { return -1 } -func parseValidators(header *types.Header, chainConfig *params.ChainConfig, parliaConfig *params.ParliaConfig) ([]common.Address, []types.BLSPublicKey, error) { - validatorsBytes := getValidatorBytesFromHeader(header, chainConfig, parliaConfig) +func parseValidators(header *types.Header, chainConfig *params.ChainConfig, epochLength uint64) ([]common.Address, []types.BLSPublicKey, error) { + validatorsBytes := getValidatorBytesFromHeader(header, chainConfig, epochLength) if len(validatorsBytes) == 0 { return nil, nil, errors.New("invalid validators bytes") } @@ -501,8 +522,8 @@ func parseValidators(header *types.Header, chainConfig *params.ChainConfig, parl return cnsAddrs, voteAddrs, nil } -func parseTurnLength(header *types.Header, chainConfig *params.ChainConfig, parliaConfig *params.ParliaConfig) (*uint8, error) { - if header.Number.Uint64()%parliaConfig.Epoch != 0 || +func parseTurnLength(header *types.Header, chainConfig *params.ChainConfig, epochLength uint64) (*uint8, error) { + if header.Number.Uint64()%epochLength != 0 || !chainConfig.IsBohr(header.Number, header.Time) { return nil, nil } diff --git a/core/block_validator.go b/core/block_validator.go index aea4a5bfd6..066b2111af 100644 --- a/core/block_validator.go +++ b/core/block_validator.go @@ -228,6 +228,7 @@ func (v *BlockValidator) RemoteVerifyManager() *remoteVerifyManager { // to keep the baseline gas close to the provided target, and increase it towards // the target if the baseline gas is lower. func CalcGasLimit(parentGasLimit, desiredLimit uint64) uint64 { + // change GasLimitBoundDivisor to 1024 from 256 from lorentz hard fork, but no need hard fork control here. delta := parentGasLimit/params.GasLimitBoundDivisor - 1 limit := parentGasLimit if desiredLimit < params.MinGasLimit { diff --git a/core/block_validator_test.go b/core/block_validator_test.go index 3b2015efa7..429cdb3cf3 100644 --- a/core/block_validator_test.go +++ b/core/block_validator_test.go @@ -240,8 +240,8 @@ func TestCalcGasLimit(t *testing.T) { max uint64 min uint64 }{ - {20000000, 20078124, 19921876}, - {40000000, 40156249, 39843751}, + {20000000, 20019530, 19980470}, + {40000000, 40039061, 39960939}, } { // Increase if have, want := CalcGasLimit(tc.pGasLimit, 2*tc.pGasLimit), tc.max; have != want { diff --git a/core/blockchain.go b/core/blockchain.go index 6a39dcad42..6f68a261e4 100644 --- a/core/blockchain.go +++ b/core/blockchain.go @@ -72,7 +72,9 @@ var ( justifiedBlockGauge = metrics.NewRegisteredGauge("chain/head/justified", nil) finalizedBlockGauge = metrics.NewRegisteredGauge("chain/head/finalized", nil) - blockInsertMgaspsGauge = metrics.NewRegisteredGauge("chain/insert/mgasps", nil) + blockInsertMgaspsGauge = metrics.NewRegisteredGauge("chain/insert/mgasps", nil) + blockInsertTxSizeGauge = metrics.NewRegisteredGauge("chain/insert/txsize", nil) + blockInsertGasUsedGauge = metrics.NewRegisteredGauge("chain/insert/gasused", nil) chainInfoGauge = metrics.NewRegisteredGaugeInfo("chain/info", nil) @@ -236,6 +238,21 @@ type txLookup struct { transaction *types.Transaction } +type BlockStats struct { + SendBlockTime atomic.Int64 + StartImportBlockTime atomic.Int64 + RecvNewBlockTime atomic.Int64 + RecvNewBlockFrom atomic.Value + RecvNewBlockHashTime atomic.Int64 + RecvNewBlockHashFrom atomic.Value + StartMiningTime atomic.Int64 + ImportedBlockTime atomic.Int64 + + SendVoteTime atomic.Int64 + FirstRecvVoteTime atomic.Int64 + RecvMajorityVoteTime atomic.Int64 +} + // BlockChain represents the canonical chain given a database with a genesis // block. The Blockchain manages chain imports, reverts, chain reorganisations. // @@ -288,10 +305,11 @@ type BlockChain struct { currentFinalBlock atomic.Pointer[types.Header] // Latest (consensus) finalized block chasingHead atomic.Pointer[types.Header] - bodyCache *lru.Cache[common.Hash, *types.Body] - bodyRLPCache *lru.Cache[common.Hash, rlp.RawValue] - receiptsCache *lru.Cache[common.Hash, []*types.Receipt] - blockCache *lru.Cache[common.Hash, *types.Block] + bodyCache *lru.Cache[common.Hash, *types.Body] + bodyRLPCache *lru.Cache[common.Hash, rlp.RawValue] + receiptsCache *lru.Cache[common.Hash, []*types.Receipt] + blockCache *lru.Cache[common.Hash, *types.Block] + blockStatsCache *lru.Cache[common.Hash, *BlockStats] txLookupLock sync.RWMutex txLookupCache *lru.Cache[common.Hash, txLookup] @@ -383,6 +401,7 @@ func NewBlockChain(db ethdb.Database, cacheConfig *CacheConfig, genesis *Genesis receiptsCache: lru.NewCache[common.Hash, []*types.Receipt](receiptsCacheLimit), sidecarsCache: lru.NewCache[common.Hash, types.BlobSidecars](sidecarsCacheLimit), blockCache: lru.NewCache[common.Hash, *types.Block](blockCacheLimit), + blockStatsCache: lru.NewCache[common.Hash, *BlockStats](blockCacheLimit), txLookupCache: lru.NewCache[common.Hash, txLookup](txLookupCacheLimit), futureBlocks: lru.NewCache[common.Hash, *types.Block](maxFutureBlocks), diffLayerCache: diffLayerCache, @@ -1140,6 +1159,7 @@ func (bc *BlockChain) setHeadBeyondRoot(head uint64, time uint64, root common.Ha bc.receiptsCache.Purge() bc.sidecarsCache.Purge() bc.blockCache.Purge() + bc.blockStatsCache.Purge() bc.txLookupCache.Purge() bc.futureBlocks.Purge() @@ -2072,6 +2092,7 @@ func (bc *BlockChain) insertChain(chain types.Blocks, setHead bool, makeWitness // Start the parallel header verifier headers := make([]*types.Header, len(chain)) for i, block := range chain { + bc.GetBlockStats(block.Hash()).StartImportBlockTime.Store(time.Now().UnixMilli()) headers[i] = block.Header() } abort, results := bc.engine.VerifyHeaders(bc, headers) @@ -2275,6 +2296,8 @@ func (bc *BlockChain) insertChain(chain types.Blocks, setHead bool, makeWitness if err != nil { return nil, it.index, err } + bc.GetBlockStats(block.Hash()).ImportedBlockTime.Store(time.Now().UnixMilli()) + // Report the import stats before returning the various results stats.processed++ stats.usedGas += res.usedGas @@ -2477,6 +2500,8 @@ func (bc *BlockChain) processBlock(block *types.Block, statedb *state.StateDB, s } blockWriteTimer.Update(time.Since(wstart) - max(statedb.AccountCommits, statedb.StorageCommits) /* concurrent */ - statedb.SnapshotCommits - statedb.TrieDBCommits) blockInsertTimer.UpdateSince(start) + blockInsertTxSizeGauge.Update(int64(len(block.Transactions()))) + blockInsertGasUsedGauge.Update(int64(block.GasUsed())) return &blockProcessingResult{usedGas: res.GasUsed, procTime: proctime, status: status}, nil } @@ -3322,3 +3347,12 @@ func (bc *BlockChain) SetTrieFlushInterval(interval time.Duration) { func (bc *BlockChain) GetTrieFlushInterval() time.Duration { return time.Duration(bc.flushInterval.Load()) } + +func (bc *BlockChain) GetBlockStats(hash common.Hash) *BlockStats { + if v, ok := bc.blockStatsCache.Get(hash); ok { + return v + } + n := &BlockStats{} + bc.blockStatsCache.Add(hash, n) + return n +} diff --git a/core/data_availability.go b/core/data_availability.go index 8f0bf580ac..6ec552d7a7 100644 --- a/core/data_availability.go +++ b/core/data_availability.go @@ -66,13 +66,13 @@ func IsDataAvailable(chain consensus.ChainHeaderReader, block *types.Block) (err return nil } - // only required to check within MinBlocksForBlobRequests block's DA + // only required to check within MinTimeDurationForBlobRequests seconds's DA highest := chain.ChasingHead() current := chain.CurrentHeader() if highest == nil || highest.Number.Cmp(current.Number) < 0 { highest = current } - if block.NumberU64()+params.MinBlocksForBlobRequests < highest.Number.Uint64() { + if block.Time()+params.MinTimeDurationForBlobRequests < highest.Time { // if we needn't check DA of this block, just clean it block.CleanSidecars() return nil diff --git a/core/data_availability_test.go b/core/data_availability_test.go index 4ed71d4b55..c0cd40220f 100644 --- a/core/data_availability_test.go +++ b/core/data_availability_test.go @@ -24,10 +24,11 @@ var ( func TestIsDataAvailable(t *testing.T) { hr := NewMockDAHeaderReader(params.ParliaTestChainConfig) tests := []struct { - block *types.Block - chasingHead uint64 - withSidecar bool - err bool + block *types.Block + chasingHeadNumber uint64 + chasingHeadTime uint64 + withSidecar bool + err bool }{ { block: types.NewBlockWithHeader(&types.Header{ @@ -40,9 +41,10 @@ func TestIsDataAvailable(t *testing.T) { Proofs: []kzg4844.Proof{emptyBlobProof}, }), }}), - chasingHead: 1, - withSidecar: true, - err: false, + chasingHeadNumber: 1, + chasingHeadTime: params.MinTimeDurationForBlobRequests - 1, + withSidecar: true, + err: false, }, { block: types.NewBlockWithHeader(&types.Header{ @@ -51,9 +53,10 @@ func TestIsDataAvailable(t *testing.T) { createMockDATx(hr.Config(), nil), createMockDATx(hr.Config(), nil), }}), - chasingHead: 1, - withSidecar: true, - err: false, + chasingHeadNumber: 1, + chasingHeadTime: params.MinTimeDurationForBlobRequests - 1, + withSidecar: true, + err: false, }, { block: types.NewBlockWithHeader(&types.Header{ @@ -66,9 +69,10 @@ func TestIsDataAvailable(t *testing.T) { Proofs: []kzg4844.Proof{emptyBlobProof}, }), }}), - chasingHead: 1, - withSidecar: false, - err: true, + chasingHeadNumber: 1, + chasingHeadTime: params.MinTimeDurationForBlobRequests - 1, + withSidecar: false, + err: true, }, { block: types.NewBlockWithHeader(&types.Header{ @@ -86,9 +90,10 @@ func TestIsDataAvailable(t *testing.T) { Proofs: []kzg4844.Proof{emptyBlobProof, emptyBlobProof}, }), }}), - chasingHead: 1, - withSidecar: true, - err: false, + chasingHeadNumber: 1, + chasingHeadTime: params.MinTimeDurationForBlobRequests - 1, + withSidecar: true, + err: false, }, { @@ -107,13 +112,14 @@ func TestIsDataAvailable(t *testing.T) { Proofs: []kzg4844.Proof{emptyBlobProof, emptyBlobProof, emptyBlobProof, emptyBlobProof}, }), }}), - chasingHead: params.MinBlocksForBlobRequests + 1, - withSidecar: true, - err: true, + chasingHeadNumber: params.MinBlocksForBlobRequests + 1, + chasingHeadTime: params.MinTimeDurationForBlobRequests, + withSidecar: true, + err: true, }, { block: types.NewBlockWithHeader(&types.Header{ - Number: big.NewInt(0), + Number: big.NewInt(1), }).WithBody(types.Body{Transactions: types.Transactions{ createMockDATx(hr.Config(), nil), createMockDATx(hr.Config(), &types.BlobTxSidecar{ @@ -122,9 +128,10 @@ func TestIsDataAvailable(t *testing.T) { Proofs: []kzg4844.Proof{emptyBlobProof}, }), }}), - chasingHead: params.MinBlocksForBlobRequests + 1, - withSidecar: false, - err: false, + chasingHeadNumber: params.MinBlocksForBlobRequests + 1, + chasingHeadTime: params.MinTimeDurationForBlobRequests + 1, + withSidecar: false, + err: false, }, } @@ -132,7 +139,7 @@ func TestIsDataAvailable(t *testing.T) { if item.withSidecar { item.block = item.block.WithSidecars(collectBlobsFromTxs(item.block.Header(), item.block.Transactions())) } - hr.setChasingHead(item.chasingHead) + hr.setChasingHead(item.chasingHeadNumber, item.chasingHeadTime) err := IsDataAvailable(hr, item.block) if item.err { require.Error(t, err, i) @@ -310,19 +317,20 @@ func collectBlobsFromTxs(header *types.Header, txs types.Transactions) types.Blo } type mockDAHeaderReader struct { - config *params.ChainConfig - chasingHead uint64 + config *params.ChainConfig + chasingHeadNumber uint64 + chasingHeadTime uint64 } func NewMockDAHeaderReader(config *params.ChainConfig) *mockDAHeaderReader { return &mockDAHeaderReader{ - config: config, - chasingHead: 0, + config: config, } } -func (r *mockDAHeaderReader) setChasingHead(h uint64) { - r.chasingHead = h +func (r *mockDAHeaderReader) setChasingHead(number, time uint64) { + r.chasingHeadNumber = number + r.chasingHeadTime = time } func (r *mockDAHeaderReader) Config() *params.ChainConfig { @@ -331,13 +339,15 @@ func (r *mockDAHeaderReader) Config() *params.ChainConfig { func (r *mockDAHeaderReader) CurrentHeader() *types.Header { return &types.Header{ - Number: new(big.Int).SetUint64(r.chasingHead), + Number: new(big.Int).SetUint64(r.chasingHeadNumber), + Time: r.chasingHeadTime, } } func (r *mockDAHeaderReader) ChasingHead() *types.Header { return &types.Header{ - Number: new(big.Int).SetUint64(r.chasingHead), + Number: new(big.Int).SetUint64(r.chasingHeadNumber), + Time: r.chasingHeadTime, } } diff --git a/core/headerchain.go b/core/headerchain.go index dfd6124b5e..310dc57501 100644 --- a/core/headerchain.go +++ b/core/headerchain.go @@ -35,8 +35,8 @@ import ( ) const ( - headerCacheLimit = 512 - tdCacheLimit = 1024 + headerCacheLimit = 1280 // a buffer exceeding the EpochLength + tdCacheLimit = 1280 // a buffer exceeding the EpochLength numberCacheLimit = 2048 ) diff --git a/core/rawdb/freezer.go b/core/rawdb/freezer.go index 36cc4bae2b..4854e0adb0 100644 --- a/core/rawdb/freezer.go +++ b/core/rawdb/freezer.go @@ -22,12 +22,11 @@ import ( "math" "os" "path/filepath" + "slices" "sync" "sync/atomic" "time" - "golang.org/x/exp/slices" - "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/ethdb" "github.com/ethereum/go-ethereum/log" diff --git a/core/rawdb/freezer_batch.go b/core/rawdb/freezer_batch.go index 35a8e9ed90..911da9a32c 100644 --- a/core/rawdb/freezer_batch.go +++ b/core/rawdb/freezer_batch.go @@ -19,12 +19,10 @@ package rawdb import ( "fmt" "math" + "slices" "sync/atomic" - "time" - "golang.org/x/exp/slices" - "github.com/ethereum/go-ethereum/rlp" "github.com/golang/snappy" ) diff --git a/core/rawdb/prunedfreezer.go b/core/rawdb/prunedfreezer.go index 122f8fe267..86856ff7ad 100644 --- a/core/rawdb/prunedfreezer.go +++ b/core/rawdb/prunedfreezer.go @@ -4,12 +4,11 @@ import ( "math" "os" "path/filepath" + "slices" "sync" "sync/atomic" "time" - "golang.org/x/exp/slices" - "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/ethdb" "github.com/ethereum/go-ethereum/log" diff --git a/core/state/statedb.go b/core/state/statedb.go index 42639477d0..97fc8dcb1d 100644 --- a/core/state/statedb.go +++ b/core/state/statedb.go @@ -1488,11 +1488,9 @@ func (s *StateDB) commitAndFlush(block uint64, deleteEmptyObjects bool, noStorag // - head layer is paired with HEAD state // - head-1 layer is paired with HEAD-1 state // - head-127 layer(bottom-most diff layer) is paired with HEAD-127 state - go func() { - if err := snap.Cap(ret.root, snap.CapLimit()); err != nil { - log.Warn("Failed to cap snapshot tree", "root", ret.root, "layers", TriesInMemory, "err", err) - } - }() + if err := snap.Cap(ret.root, snap.CapLimit()); err != nil { + log.Warn("Failed to cap snapshot tree", "root", ret.root, "layers", TriesInMemory, "err", err) + } if metrics.EnabledExpensive() { s.SnapshotCommits += time.Since(start) } diff --git a/core/systemcontracts/lorentz/chapel/ValidatorContract b/core/systemcontracts/lorentz/chapel/ValidatorContract new file mode 100644 index 0000000000..4acd3e094a --- /dev/null +++ b/core/systemcontracts/lorentz/chapel/ValidatorContract @@ -0,0 +1 @@ +6080604052600436106104405760003560e01c80638b5ad0c911610234578063c81b16621161012e578063e1c7392a116100b6578063f92eb86b1161007a578063f92eb86b14610b3f578063f9a2bbc714610b54578063fccc281314610b69578063fd4ad81f14610b7e578063fd6a687914610bad57610447565b8063e1c7392a14610ac2578063e40716a114610ad7578063ea321e4914610aec578063eb57e20214610b0c578063f340fa0114610b2c57610447565b8063d58918ae116100fd578063d58918ae14610a59578063d68fb56a14610a6e578063daacdb6614610a83578063dc927faf14610a98578063df8079e914610aad57610447565b8063c81b166214610a0f578063c8509d81146107e6578063cb75a59214610a24578063ce910b0c14610a3957610447565b8063aa82dce1116101bc578063aef198a911610180578063aef198a914610999578063b7ab4db5146109ae578063b8cf4ef1146109d0578063c466689d146109e5578063c6d33945146109fa57610447565b8063aa82dce11461090d578063aad5606314610922578063ab51bb9614610937578063ac43175114610959578063ad3c9da61461097957610447565b80639dc09262116102035780639dc09262146108a45780639fe0f816146108b9578063a1a11bf5146108ce578063a5422d5c146108e3578063a78abc16146108f857610447565b80638b5ad0c9146108455780638c5d749d1461085a5780638d19a4101461086f5780639369d7de1461088f57610447565b80634df6e0c3116103455780636e47b482116102cd578063820dcaa811610291578063820dcaa8146107d1578063831d65d1146107e6578063862498821461080657806388b32f111461081b5780638a7beb011461083057610447565b80636e47b4821461076857806375d47a0a1461077d57806378dfed4a146107925780637a84ca2a146107a75780637e434d54146107bc57610447565b806355614fcc1161031457806355614fcc146106c1578063565c56b3146106e157806360eba4fe1461070157806362b72cf5146107215780636969a25c1461073657610447565b80634df6e0c31461066d5780635192c82c1461068257806351b4dce31461069757806351e80672146106ac57610447565b80632a0ffb6e116103c857806335409f7f1161039757806335409f7f146105de5780633b071dcc146105fe57806343756e5c1461062157806345cf9daf14610636578063493279b11461064b57610447565b80632a0ffb6e1461055e578063300c35671461057e578063321d398a1461059e5780633365af3a146105be57610447565b8063152ad3b81161040f578063152ad3b8146104dd5780631bd14ed8146104ff5780631e4c1524146105145780631ff1806914610534578063280870281461054957610447565b806304c4fec61461044c57806307a56847146104635780630e2374a51461048e5780631182b875146104b057610447565b3661044757005b600080fd5b34801561045857600080fd5b50610461610bc2565b005b34801561046f57600080fd5b50610478610c36565b6040516104859190616d89565b60405180910390f35b34801561049a57600080fd5b506104a3610c3c565b604051610485919061613e565b3480156104bc57600080fd5b506104d06104cb366004616024565b610c42565b604051610485919061625e565b3480156104e957600080fd5b506104f2610d5e565b6040516104859190616253565b34801561050b57600080fd5b50610478610d67565b34801561052057600080fd5b5061046161052f366004615e52565b610d6d565b34801561054057600080fd5b506104786110a1565b34801561055557600080fd5b506104a36110a7565b34801561056a57600080fd5b50610461610579366004615db2565b6110ad565b34801561058a57600080fd5b50610461610599366004615dea565b6110ce565b3480156105aa57600080fd5b506104f26105b9366004615fd1565b611417565b3480156105ca57600080fd5b506104f26105d9366004615fd1565b6114e6565b3480156105ea57600080fd5b506104616105f9366004615db2565b611597565b34801561060a57600080fd5b506106136116fc565b6040516104859291906161e3565b34801561062d57600080fd5b506104a36119d8565b34801561064257600080fd5b506104786119de565b34801561065757600080fd5b506106606119e4565b6040516104859190616d7a565b34801561067957600080fd5b506106136119e9565b34801561068e57600080fd5b50610478611b83565b3480156106a357600080fd5b506104a3611b89565b3480156106b857600080fd5b506104a3611b8f565b3480156106cd57600080fd5b506104f26106dc366004615db2565b611b95565b3480156106ed57600080fd5b506104786106fc366004615db2565b611bd1565b34801561070d57600080fd5b506104d061071c366004615fd1565b611c22565b34801561072d57600080fd5b50610478611cc8565b34801561074257600080fd5b50610756610751366004615fd1565b611cce565b6040516104859695949392919061616b565b34801561077457600080fd5b506104a3611d32565b34801561078957600080fd5b506104a3611d38565b34801561079e57600080fd5b50610478611d3e565b3480156107b357600080fd5b50610478611d44565b3480156107c857600080fd5b506104a3611d4a565b3480156107dd57600080fd5b50610478611d50565b3480156107f257600080fd5b50610461610801366004616024565b611d56565b34801561081257600080fd5b50610478611d77565b34801561082757600080fd5b50610478611d7d565b34801561083c57600080fd5b506104f2611d83565b34801561085157600080fd5b50610478611d8c565b34801561086657600080fd5b50610478611d92565b34801561087b57600080fd5b5061047861088a366004615db2565b611daf565b34801561089b57600080fd5b50610461611def565b3480156108b057600080fd5b506104a3611f03565b3480156108c557600080fd5b50610478611f09565b3480156108da57600080fd5b506104a3611f0e565b3480156108ef57600080fd5b506104d0611f14565b34801561090457600080fd5b506104f2611f33565b34801561091957600080fd5b506104a3611f3c565b34801561092e57600080fd5b506104a3611f42565b34801561094357600080fd5b5061094c611f48565b6040516104859190616dbc565b34801561096557600080fd5b50610461610974366004615f75565b611f4d565b34801561098557600080fd5b50610478610994366004615db2565b6129b6565b3480156109a557600080fd5b506104786129c8565b3480156109ba57600080fd5b506109c36129d5565b60405161048591906161d0565b3480156109dc57600080fd5b50610478612ac0565b3480156109f157600080fd5b50610478612ac5565b348015610a0657600080fd5b50610478612acb565b348015610a1b57600080fd5b506104a3612ad0565b348015610a3057600080fd5b50610478612ad6565b348015610a4557600080fd5b506104d0610a54366004615fd1565b612adc565b348015610a6557600080fd5b50610478612ae9565b348015610a7a57600080fd5b50610478612aef565b348015610a8f57600080fd5b50610478612b2e565b348015610aa457600080fd5b506104a3612b34565b348015610ab957600080fd5b506104a3612b3a565b348015610ace57600080fd5b50610461612b40565b348015610ae357600080fd5b50610478612ce9565b348015610af857600080fd5b506104f2610b07366004615f36565b612cef565b348015610b1857600080fd5b50610461610b27366004615db2565b612e75565b610461610b3a366004615db2565b612f7d565b348015610b4b57600080fd5b50610478613333565b348015610b6057600080fd5b506104a3613339565b348015610b7557600080fd5b506104a361333f565b348015610b8a57600080fd5b50610b9e610b99366004615fd1565b613345565b60405161048593929190616d92565b348015610bb957600080fd5b506104a3613407565b6000610bcd33611daf565b9050600b8181548110610bdc57fe5b600091825260209091206001601690920201015460ff16610c185760405162461bcd60e51b8152600401610c0f90616a30565b60405180910390fd5b6000610c22612aef565b9050610c31338383600161340d565b505050565b60095481565b61200181565b60005460609060ff16610c675760405162461bcd60e51b8152600401610c0f90616443565b3361200014610c885760405162461bcd60e51b8152600401610c0f90616b42565b600b54610d4657610c9761595e565b60015460005b81811015610d4257600b80546001810182556000919091528351600080516020616fff833981519152601690920291820190815560208086015160008051602061703f8339815191528401805460ff1916911515919091179055604086015180518794610d1e9360008051602061701f83398151915290910192019061598d565b506060820151610d349060038301906013615a07565b505050806001019050610c9d565b5050505b60405162461bcd60e51b8152600401610c0f90616695565b60075460ff1681565b600f5481565b334114610d8c5760405162461bcd60e51b8152600401610c0f90616b91565b3a15610daa5760405162461bcd60e51b8152600401610c0f9061696f565b8251604080518281526020808402820101909152606090828015610de857816020015b610dd5615a34565b815260200190600190039081610dcd5790505b50905060005b82811015610e92576040518060c00160405280878381518110610e0d57fe5b60200260200101516001600160a01b0316815260200160006001600160a01b0316815260200160006001600160a01b03168152602001868381518110610e4f57fe5b60200260200101516001600160401b031681526020016000151581526020016000815250828281518110610e7f57fe5b6020908102919091010152600101610dee565b50606080610ea083866135ff565b9150915060005b600154811015610f9657600060018281548110610ec057fe5b906000526020600020906004020160030154905080600014610f8d57600060018381548110610eeb57fe5b9060005260206000209060040201600301819055506120026001600160a01b031663092193ab8260018581548110610f1f57fe5b60009182526020909120600491820201546040516001600160e01b031960e086901b168152610f5a926001600160a01b03909216910161613e565b6000604051808303818588803b158015610f7357600080fd5b505af1158015610f87573d6000803e3d6000fd5b50505050505b50600101610ea7565b504715611004577f6ecc855f9440a9282c90913bbc91619fd44f5ec0b462af28d127b116f130aa4d47604051610fcc9190616d89565b60405180910390a1604051611002904780156108fc02916000818181858888f19350505050158015611002573d6000803e3d6000fd5b505b600060035581511561101a5761101a8282613ae9565b6110016001600160a01b031663fc4333cd6040518163ffffffff1660e01b8152600401600060405180830381600087803b15801561105757600080fd5b505af115801561106b573d6000803e3d6000fd5b50506040517fedd8d7296956dd970ab4de3f2fc03be2b0ffc615d20cd4c72c6e44f928630ebf925060009150a150505050505050565b60035481565b61200581565b3361200214610d465760405162461bcd60e51b8152600401610c0f90616d43565b3341146110ed5760405162461bcd60e51b8152600401610c0f90616b91565b601054431161110e5760405162461bcd60e51b8152600401610c0f906165bf565b3a1561112c5760405162461bcd60e51b8152600401610c0f9061696f565b60005460ff1661114e5760405162461bcd60e51b8152600401610c0f90616443565b60006110023168056bc75e2d631000008111156111855761117e8168056bc75e2d6310000063ffffffff6142d816565b915061118c565b505061140d565b6040516309a99b4f60e41b815261100290639a99b4f0906111b39030908690600401616152565b602060405180830381600087803b1580156111cd57600080fd5b505af11580156111e1573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906112059190615fe9565b91508161121357505061140d565b6000805b848110156112415785858281811061122b57fe5b9050602002013582019150806001019050611217565b508061124f5750505061140d565b6000806000805b89811015611405578489898381811061126b57fe5b9050602002013588028161127b57fe5b0493508a8a8281811061128a57fe5b905060200201602081019061129f9190615db2565b6001600160a01b038116600090815260046020526040902054909350915081156113bb5760006001808403815481106112d457fe5b9060005260206000209060040201905080600201601c9054906101000a900460ff161561134157836001600160a01b03167fb9c75cbbfde137c4281689580799ef5f52144e78858f776a5979b2b212137d85866040516113349190616d89565b60405180910390a26113b5565b600354611354908663ffffffff61431a16565b600390815581015461136c908663ffffffff61431a16565b60038201556040516001600160a01b038516907fcb0aad6cf9cd03bdf6137e359f541c42f38b39f007cae8e89e88aa7d8c6617b2906113ac908890616d89565b60405180910390a25b506113fd565b826001600160a01b03167fb9c75cbbfde137c4281689580799ef5f52144e78858f776a5979b2b212137d85856040516113f49190616d89565b60405180910390a25b600101611256565b505050505050505b5050436010555050565b600154600090821061142b575060006114e1565b60006001600160a01b03166001838154811061144357fe5b60009182526020909120600490910201546001600160a01b03161480611473575060085415806114735750600a54155b80611482575060085460095410155b806114935750611491826114e6565b155b806114bc57506000600b83815481106114a857fe5b906000526020600020906016020160000154115b806114d0575060016114cc6129d5565b5111155b156114dd575060006114e1565b5060015b919050565b60015460009082106114fa575060006114e1565b600b548210611537576001828154811061151057fe5b9060005260206000209060040201600201601c9054906101000a900460ff161590506114e1565b6001828154811061154457fe5b9060005260206000209060040201600201601c9054906101000a900460ff161580156115915750600b828154811061157857fe5b600091825260209091206001601690920201015460ff16155b92915050565b600b54611655576115a661595e565b60015460005b8181101561165157600b80546001810182556000919091528351600080516020616fff833981519152601690920291820190815560208086015160008051602061703f8339815191528401805460ff191691151591909117905560408601518051879461162d9360008051602061701f83398151915290910192019061598d565b5060608201516116439060038301906013615a07565b5050508060010190506115ac565b5050505b336110011480611666575033612002145b6116825760405162461bcd60e51b8152600401610c0f9061647a565b6001600160a01b038116600090815260046020526040902054806116a657506116f9565b6001810390506000600b82815481106116bb57fe5b600091825260209091206001601690920201015460ff1690506116de838361433f565b80156116e75750805b15610c31576009805460001901905550505b50565b60015460609081906000805b8281101561174f576001818154811061171d57fe5b9060005260206000209060040201600201601c9054906101000a900460ff16611747576001909101905b600101611708565b5060608160405190808252806020026020018201604052801561177c578160200160208202803683370190505b5090506060826040519080825280602002602001820160405280156117b557816020015b60608152602001906001900390816117a05790505b50600b54600094509091508414156119305760005b8481101561192a57600181815481106117df57fe5b9060005260206000209060040201600201601c9054906101000a900460ff16611922576001818154811061180f57fe5b600091825260209091206004909102015483516001600160a01b039091169084908690811061183a57fe5b60200260200101906001600160a01b031690816001600160a01b031681525050600b818154811061186757fe5b600091825260209182902060026016909202018101805460408051601f6000196101006001861615020190931694909404918201859004850284018501905280835291929091908301828280156118ff5780601f106118d4576101008083540402835291602001916118ff565b820191906000526020600020905b8154815290600101906020018083116118e257829003601f168201915b505050505082858151811061191057fe5b60209081029190910101526001909301925b6001016117ca565b506119cc565b60005b848110156119ca576001818154811061194857fe5b9060005260206000209060040201600201601c9054906101000a900460ff166119c2576001818154811061197857fe5b600091825260209091206004909102015483516001600160a01b03909116908490869081106119a357fe5b6001600160a01b03909216602092830291909101909101526001909301925b600101611933565b505b909450925050505b9091565b61100181565b60085481565b606181565b6060806000600e549050600080600c5411611a05576015611a09565b600c545b905060c86060611a176129d5565b90506060611a2482614702565b905083825111611a3c5790955093506119d492505050565b84848351031015611a4e578382510394505b8415611a8e576000834381611a5f57fe5b049050611a7483838389890360008b8b614870565b611a8c8383838989038a8a038b8c8c8b510301614870565b505b606084604051908082528060200260200182016040528015611aba578160200160208202803683370190505b509050606085604051908082528060200260200182016040528015611af357816020015b6060815260200190600190039081611ade5790505b50905060005b86811015611b7457848181518110611b0d57fe5b6020026020010151838281518110611b2157fe5b60200260200101906001600160a01b031690816001600160a01b031681525050838181518110611b4d57fe5b6020026020010151828281518110611b6157fe5b6020908102919091010152600101611af9565b50909750955050505050509091565b60065481565b61200681565b61200081565b6001600160a01b03811660009081526004602052604081205480611bbd5760009150506114e1565b60001901611bca816114e6565b9392505050565b6001600160a01b03811660009081526004602052604081205480611bf95760009150506114e1565b600180820381548110611c0857fe5b906000526020600020906004020160030154915050919050565b60128181548110611c2f57fe5b600091825260209182902001805460408051601f6002600019610100600187161502019094169390930492830185900485028101850190915281815293509091830182828015611cc05780601f10611c9557610100808354040283529160200191611cc0565b820191906000526020600020905b815481529060010190602001808311611ca357829003601f168201915b505050505081565b60105481565b60018181548110611cdb57fe5b600091825260209091206004909102018054600182015460028301546003909301546001600160a01b0392831694509082169291821691600160a01b81046001600160401b031691600160e01b90910460ff169086565b61100581565b61100881565b6103e881565b600c5481565b61200381565b61271081565b3361200014610d465760405162461bcd60e51b8152600401610c0f90616b42565b60025481565b60115481565b60145460ff1681565b600a5481565b600060175460001415611da757506001611dac565b506017545b90565b6001600160a01b03811660009081526004602052604081205480611de55760405162461bcd60e51b8152600401610c0f90616aca565b6000190192915050565b600b54611ead57611dfe61595e565b60015460005b81811015611ea957600b80546001810182556000919091528351600080516020616fff833981519152601690920291820190815560208086015160008051602061703f8339815191528401805460ff1916911515919091179055604086015180518794611e859360008051602061701f83398151915290910192019061598d565b506060820151611e9b9060038301906013615a07565b505050806001019050611e04565b5050505b600854611eba5760036008555b600a54611ec7576002600a555b6000611ed233611daf565b9050611edd81611417565b611ef95760405162461bcd60e51b8152600401610c0f906168eb565b6116f933826149c7565b61100781565b600381565b61100681565b604051806101e001604052806101ab8152602001616e546101ab913981565b60005460ff1681565b61200281565b61300081565b600081565b60005460ff16611f6f5760405162461bcd60e51b8152600401610c0f90616443565b3361100714611f905760405162461bcd60e51b8152600401610c0f9061699d565b611ff084848080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250506040805180820190915260098152686275726e526174696f60b81b60208201529150614a5f9050565b156120a557602081146120155760405162461bcd60e51b8152600401610c0f906162a3565b604080516020601f840181900481028201810190925282815260009161205391858580838501838280828437600092019190915250614ab892505050565b905061271061207f601854612073600f548561431a90919063ffffffff16565b9063ffffffff61431a16565b111561209d5760405162461bcd60e51b8152600401610c0f906166b9565b600655612973565b61210f84848080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250506040805180820190915260138152726d61784e756d4f664d61696e7461696e696e6760681b60208201529150614a5f9050565b156121a957602081146121345760405162461bcd60e51b8152600401610c0f906162da565b604080516020601f840181900481028201810190925282815260009161217291858580838501838280828437600092019190915250614ab892505050565b600c5490915080612181575060155b8082106121a05760405162461bcd60e51b8152600401610c0f90616601565b50600855612973565b61221284848080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250506040805180820190915260128152716d61696e7461696e536c6173685363616c6560701b60208201529150614a5f9050565b156122ab57602081146122375760405162461bcd60e51b8152600401610c0f906163c9565b604080516020601f840181900481028201810190925282815260009161227591858580838501838280828437600092019190915250614ab892505050565b90506000811180156122875750600a81105b6122a35760405162461bcd60e51b8152600401610c0f90616c26565b600a55612973565b61231f84848080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152505060408051808201909152601981527f6d61784e756d4f66576f726b696e6743616e646964617465730000000000000060208201529150614a5f9050565b156123ae57602081146123445760405162461bcd60e51b8152600401610c0f9061637d565b604080516020601f840181900481028201810190925282815260009161238291858580838501838280828437600092019190915250614ab892505050565b9050600d548111156123a65760405162461bcd60e51b8152600401610c0f906167c2565b600e55612973565b61241784848080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250506040805180820190915260128152716d61784e756d4f6643616e6469646174657360701b60208201529150614a5f9050565b15612499576020811461243c5760405162461bcd60e51b8152600401610c0f906169eb565b604080516020601f840181900481028201810190925282815260009161247a91858580838501838280828437600092019190915250614ab892505050565b600d819055600e5490915081101561249357600d54600e555b50612973565b6124fd84848080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152505060408051808201909152600d81526c6e756d4f66436162696e65747360981b60208201529150614a5f9050565b1561262257602081146125225760405162461bcd60e51b8152600401610c0f9061640e565b604080516020601f840181900481028201810190925282815260009161256091858580838501838280828437600092019190915250614ab892505050565b9050600081116125825760405162461bcd60e51b8152600401610c0f90616577565b60006120026001600160a01b031663c473318f6040518163ffffffff1660e01b815260040160206040518083038186803b1580156125bf57600080fd5b505afa1580156125d3573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906125f79190615fe9565b9050808211156126195760405162461bcd60e51b8152600401610c0f90616320565b50600c55612973565b61268e84848080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152505060408051808201909152601581527473797374656d52657761726442617365526174696f60581b60208201529150614a5f9050565b1561273757602081146126b35760405162461bcd60e51b8152600401610c0f90616bde565b604080516020601f84018190048102820181019092528281526000916126f191858580838501838280828437600092019190915250614ab892505050565b90506127106127116018546120736006548561431a90919063ffffffff16565b111561272f5760405162461bcd60e51b8152600401610c0f906164e8565b600f55612973565b6127ab84848080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152505060408051808201909152601881527f73797374656d526577617264416e74694d4556526174696f000000000000000060208201529150614a5f9050565b1561285457602081146127d05760405162461bcd60e51b8152600401610c0f90616748565b604080516020601f840181900481028201810190925282815260009161280e91858580838501838280828437600092019190915250614ab892505050565b905061271061282e600f546120736006548561431a90919063ffffffff16565b111561284c5760405162461bcd60e51b8152600401610c0f9061685c565b601855612973565b6128b584848080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152505060408051808201909152600a8152690e8eae4dc98cadccee8d60b31b60208201529150614a5f9050565b1561295b57602081146128da5760405162461bcd60e51b8152600401610c0f9061665e565b604080516020601f840181900481028201810190925282815260009161291891858580838501838280828437600092019190915250614ab892505050565b90506003811015801561292c575060408111155b806129375750806001145b6129535760405162461bcd60e51b8152600401610c0f90616c83565b601755612973565b60405162461bcd60e51b8152600401610c0f90616cd3565b7f6cdb0ac70ab7f2e2d035cca5be60d89906f2dede7648ddbd7402189c1eeed17a848484846040516129a89493929190616271565b60405180910390a150505050565b60046020526000908152604090205481565b68056bc75e2d6310000081565b6001546060906000805b82811015612a04576129f0816114e6565b156129fc578160010191505b6001016129df565b50606081604051908082528060200260200182016040528015612a31578160200160208202803683370190505b5090506000915060005b83811015612ab857612a4c816114e6565b15612ab05760018181548110612a5e57fe5b600091825260209091206004909102015482516001600160a01b0390911690839085908110612a8957fe5b60200260200101906001600160a01b031690816001600160a01b0316815250508260010192505b600101612a3b565b509250505090565b601581565b61027181565b600281565b61100281565b60175481565b60138181548110611c2f57fe5b60185481565b6000612af96129d5565b519050600080600c5411612b0e576015612b12565b600c545b905080821115612b20578091505b81612b2a57600191505b5090565b60055481565b61100381565b61200481565b60005460ff1615612b635760405162461bcd60e51b8152600401610c0f90616a5c565b612b6b615a69565b6000612b91604051806101e001604052806101ab8152602001616e546101ab9139614abd565b9150915080612bb25760405162461bcd60e51b8152600401610c0f90616b01565b60005b826020015151811015612cd757600183602001518281518110612bd457fe5b60209081029190910181015182546001818101855560009485528385208351600493840290910180546001600160a01b039283166001600160a01b03199182161782558587015182850180549185169183169190911790556040860151600283018054606089015160808a01511515600160e01b0260ff60e01b196001600160401b03909216600160a01b0267ffffffffffffffff60a01b199590981692909516919091179290921694909417161790915560a090930151600390930192909255918601518051918501939185908110612caa57fe5b602090810291909101810151516001600160a01b0316825281019190915260400160002055600101612bb5565b50506000805460ff1916600117905550565b600d5481565b601354600090815b81811015612df857612de085858080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525050601380549092508591508110612d4857fe5b600091825260209182902001805460408051601f6002600019610100600187161502019094169390930492830185900485028101850190915281815292830182828015612dd65780601f10612dab57610100808354040283529160200191612dd6565b820191906000526020600020905b815481529060010190602001808311612db957829003601f168201915b5050505050614c79565b15612df057600192505050611591565b600101612cf7565b5060125460005b81811015612e6957612e5086868080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525050601280549092508591508110612d4857fe5b15612e615760019350505050611591565b600101612dff565b50600095945050505050565b3361100114612e965760405162461bcd60e51b8152600401610c0f90616cfa565b600b54612f5457612ea561595e565b60015460005b81811015612f5057600b80546001810182556000919091528351600080516020616fff833981519152601690920291820190815560208086015160008051602061703f8339815191528401805460ff1916911515919091179055604086015180518794612f2c9360008051602061701f83398151915290910192019061598d565b506060820151612f429060038301906013615a07565b505050806001019050612eab565b5050505b6000612f5f82614cdd565b9050612f6a81611417565b15612f7957612f7982826149c7565b5050565b334114612f9c5760405162461bcd60e51b8152600401610c0f90616b91565b60005460ff16612fbe5760405162461bcd60e51b8152600401610c0f90616443565b60003411612fde5760405162461bcd60e51b8152600401610c0f90616793565b3a15612ffc5760405162461bcd60e51b8152600401610c0f9061696f565b6001600160a01b03811660009081526004602052604090205460145434919060ff1661303c57610271600f556103e86006556014805460ff191660011790555b600f54601754600110801561305357506000601854115b1561307857600160175403601754438161306957fe5b06601854028161307557fe5b04015b6000831180156130885750600081115b156131355760006130b16127106130a5348563ffffffff614e6016565b9063ffffffff614e9a16565b90508015613133576040516110029082156108fc029083906000818181858888f193505050501580156130e8573d6000803e3d6000fd5b507f6ecc855f9440a9282c90913bbc91619fd44f5ec0b462af28d127b116f130aa4d816040516131189190616d89565b60405180910390a1613130848263ffffffff6142d816565b93505b505b60008311801561314757506000600654115b156131ed5760006131696127106130a560065434614e6090919063ffffffff16565b905080156131eb5760405161dead9082156108fc029083906000818181858888f193505050501580156131a0573d6000803e3d6000fd5b507f627059660ea01c4733a328effb2294d2f86905bf806da763a89cee254de8bee5816040516131d09190616d89565b60405180910390a16131e8848263ffffffff6142d816565b93505b505b81156132eb57600060018084038154811061320457fe5b9060005260206000209060040201905080600201601c9054906101000a900460ff161561327157846001600160a01b03167ff177e5d6c5764d79c32883ed824111d9b13f5668cf6ab1cc12dd36791dd955b4856040516132649190616d89565b60405180910390a26132e5565b600354613284908563ffffffff61431a16565b600390815581015461329c908563ffffffff61431a16565b60038201556040516001600160a01b038616907f93a090ecc682c002995fad3c85b30c5651d7fd29b0be5da9d784a3302aedc055906132dc908790616d89565b60405180910390a25b5061332d565b836001600160a01b03167ff177e5d6c5764d79c32883ed824111d9b13f5668cf6ab1cc12dd36791dd955b4846040516133249190616d89565b60405180910390a25b50505050565b600e5481565b61100081565b61dead81565b600b818154811061335257fe5b6000918252602091829020601691909102018054600180830154600280850180546040805161010096831615969096026000190190911692909204601f810188900488028501880190925281845293965060ff909116949192918301828280156133fd5780601f106133d2576101008083540402835291602001916133fd565b820191906000526020600020905b8154815290600101906020018083116133e057829003601f168201915b5050505050905083565b61100481565b6000600a546000148061341e575082155b806134295750600954155b15613436575060006135f7565b60096000815460019003919050819055506000613481600a546130a5866130a5600b8a8154811061346357fe5b6000918252602090912060169091020154439063ffffffff6142d816565b90506000600b868154811061349257fe5b906000526020600020906016020160010160006101000a81548160ff0219169083151502179055506000806110016001600160a01b0316638256ace66040518163ffffffff1660e01b8152600401604080518083038186803b1580156134f757600080fd5b505afa15801561350b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061352f9190616001565b91509150600093508083106135ad57613548888861433f565b506040516328aa02b160e01b8152611001906328aa02b190613572908b9087908a906004016161ad565b600060405180830381600087803b15801561358c57600080fd5b505af11580156135a0573d6000803e3d6000fd5b50505050600193506135bf565b8183106135bf576135bd88614cdd565b505b6040516001600160a01b038916907fb9d38178dc641ff1817967a63c9078cbcd955a9f1fcd75e0e3636de615d44d3b90600090a25050505b949350505050565b606080600080808080613610612aef565b6001549091505b801561384257600181039250600b838154811061363057fe5b600091825260209091206001601690920201015460ff1661365057613839565b6001838154811061365d57fe5b600091825260208220600490910201546001600160a01b031695506136879086908590859061340d565b93508361369357613839565b60405163436aa28360e11b81526000908190612002906386d54506906136bd908a9060040161613e565b60206040518083038186803b1580156136d557600080fd5b505afa1580156136e9573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061370d9190615dce565b90506001600160a01b03811615613796576040516302ceee9160e11b81526120029063059ddd229061374390849060040161613e565b60206040518083038186803b15801561375b57600080fd5b505afa15801561376f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906137939190615dce565b91505b60005b8c5181101561383557876001600160a01b03168d82815181106137b857fe5b6020026020010151600001516001600160a01b031614806138015750826001600160a01b03168d82815181106137ea57fe5b6020026020010151600001516001600160a01b0316145b1561382d5760018d828151811061381457fe5b6020908102919091010151901515608090910152613835565b600101613799565b5050505b60001901613617565b5060005b89518110156138af5789818151811061385b57fe5b6020026020010151608001518061389b575060006001600160a01b03168a828151811061388457fe5b6020026020010151600001516001600160a01b0316145b156138a7578560010195505b600101613846565b50885185106139975760408051600180825281830190925290816020015b6138d5615a34565b8152602001906001900390816138cd575050604080516001808252818301909252919850602082015b60608152602001906001900390816138fe5790505095508860008151811061392257fe5b60200260200101518760008151811061393757fe5b60200260200101819052508760008151811061394f57fe5b60200260200101518660008151811061396457fe5b602002602001018190525060008760008151811061397e57fe5b6020908102919091010151901515608090910152613adc565b848951036040519080825280602002602001820160405280156139d457816020015b6139c1615a34565b8152602001906001900390816139b95790505b50965084895103604051908082528060200260200182016040528015613a0e57816020015b60608152602001906001900390816139f95790505b5095506000915060005b8951811015613ada57898181518110613a2d57fe5b602002602001015160800151158015613a70575060006001600160a01b03168a8281518110613a5857fe5b6020026020010151600001516001600160a01b031614155b15613ad257898181518110613a8157fe5b6020026020010151888481518110613a9557fe5b6020026020010181905250888181518110613aac57fe5b6020026020010151878481518110613ac057fe5b60200260200101819052508260010192505b600101613a18565b505b50505050505b9250929050565b600154825160005b82811015613c06576001613b03615a34565b60018381548110613b1057fe5b600091825260208083206040805160c08101825260049490940290910180546001600160a01b0390811685526001820154811693850193909352600281015492831691840191909152600160a01b82046001600160401b03166060840152600160e01b90910460ff16151560808301526003015460a082015291505b84811015613bda57878181518110613ba057fe5b6020026020010151600001516001600160a01b031682600001516001600160a01b03161415613bd25760009250613bda565b600101613b8c565b508115613bfc5780516001600160a01b03166000908152600460205260408120555b5050600101613af1565b5080821115613cc557805b82811015613cc3576001805480613c2457fe5b60008281526020812060046000199093019283020180546001600160a01b0319908116825560018201805490911690556002810180546001600160e81b0319169055600301559055600b805480613c7757fe5b60008281526020812060166000199093019283020181815560018101805460ff1916905590613ca96002830182615a8d565b613cb7600383016000615ad1565b50509055600101613c11565b505b6000818310613cd45781613cd6565b825b905060005b8181101561407a57613d88868281518110613cf257fe5b602002602001015160018381548110613d0757fe5b60009182526020918290206040805160c08101825260049390930290910180546001600160a01b0390811684526001820154811694840194909452600281015493841691830191909152600160a01b83046001600160401b03166060830152600160e01b90920460ff161515608082015260039091015460a0820152614edc565b613f3c578060010160046000888481518110613da057fe5b6020026020010151600001516001600160a01b03166001600160a01b0316815260200190815260200160002081905550858181518110613ddc57fe5b602002602001015160018281548110613df157fe5b6000918252602091829020835160049092020180546001600160a01b039283166001600160a01b0319918216178255928401516001820180549184169185169190911790556040840151600282018054606087015160808801511515600160e01b0260ff60e01b196001600160401b03909216600160a01b0267ffffffffffffffff60a01b1995909716929097169190911792909216939093171692909217905560a0909101516003909101558451859082908110613eac57fe5b6020026020010151600b8281548110613ec157fe5b90600052602060002090601602016002019080519060200190613ee592919061598d565b506000600b8281548110613ef557fe5b60009182526020822060169190910201600101805460ff191692151592909217909155600b805483908110613f2657fe5b6000918252602090912060169091020155614072565b858181518110613f4857fe5b60200260200101516060015160018281548110613f6157fe5b906000526020600020906004020160020160146101000a8154816001600160401b0302191690836001600160401b03160217905550614027858281518110613fa557fe5b6020026020010151600b8381548110613fba57fe5b600091825260209182902060026016909202018101805460408051601f600019610100600186161502019093169490940491820185900485028401850190528083529192909190830182828015612dd65780601f10612dab57610100808354040283529160200191612dd6565b6140725784818151811061403757fe5b6020026020010151600b828154811061404c57fe5b9060005260206000209060160201600201908051906020019061407092919061598d565b505b600101613cdb565b50828211156142525761408b61595e565b835b8381101561424f578581815181106140a157fe5b6020026020010151826040018190525060018782815181106140bf57fe5b6020908102919091018101518254600181810185556000948552838520835160049093020180546001600160a01b039384166001600160a01b0319918216178255848601518284018054918616918316919091179055604080860151600284018054606089015160808a01511515600160e01b0260ff60e01b196001600160401b03909216600160a01b0267ffffffffffffffff60a01b1995909a1692909616919091179290921696909617169190911790935560a090930151600390930192909255600b8054928301815590935284516016909102600080516020616fff83398151915281019182558583015160008051602061703f8339815191528201805491151560ff19909216919091179055928501518051869492936141f59360008051602061701f8339815191520192019061598d565b50606082015161420b9060038301906013615a07565b505050806001016004600089848151811061422257fe5b602090810291909101810151516001600160a01b031682528101919091526040016000205560010161408d565b50505b61425a614f38565b61426261511a565b6000600981905560015493505b838110156142d0576000600b828154811061428657fe5b60009182526020822060169190910201600101805460ff191692151592909217909155600b8054839081106142b757fe5b600091825260209091206016909102015560010161426f565b505050505050565b6000611bca83836040518060400160405280601e81526020017f536166654d6174683a207375627472616374696f6e206f766572666c6f770000815250615308565b600082820183811015611bca5760405162461bcd60e51b8152600401610c0f906164b1565b6000806001838154811061434f57fe5b906000526020600020906004020160030154905060006001808054905003905060016143796129d5565b51116143ae5760006001858154811061438e57fe5b906000526020600020906004020160030181905550600092505050611591565b846001600160a01b03167f3b6f9ef90462b512a1293ecec018670bf7b7f1876fb727590a8a6d7643130a70836040516143e79190616d89565b60405180910390a26001600160a01b038516600090815260046020526040812055835b600154600019018110156145d4576001816001018154811061442857fe5b90600052602060002090600402016001828154811061444357fe5b60009182526020909120825460049092020180546001600160a01b03199081166001600160a01b0393841617825560018085015481840180548416918616919091179055600280860180549185018054909416919095161780835584546001600160401b03600160a01b91829004160267ffffffffffffffff60a01b1990911617808355935460ff600160e01b918290041615150260ff60e01b19909416939093179055600392830154920191909155600b80549091830190811061450457fe5b9060005260206000209060160201600b828154811061451f57fe5b600091825260209091208254601690920201908155600180830154818301805460ff909216151560ff1990921691909117905560028084018054614576938386019390821615610100026000190190911604615ae0565b5061458960038281019084016013615b55565b509050508060010160046000600184815481106145a257fe5b600091825260208083206004909202909101546001600160a01b0316835282019290925260400190205560010161440a565b5060018054806145e057fe5b60008281526020812060046000199093019283020180546001600160a01b0319908116825560018201805490911690556002810180546001600160e81b0319169055600301559055600b80548061463357fe5b60008281526020812060166000199093019283020181815560018101805460ff19169055906146656002830182615a8d565b614673600383016000615ad1565b50509055600081838161468257fe5b04905080156146f65760015460005b818110156146f3576146ca83600183815481106146aa57fe5b90600052602060002090600402016003015461431a90919063ffffffff16565b600182815481106146d757fe5b6000918252602090912060036004909202010155600101614691565b50505b50600195945050505050565b60015481516040805182815260208084028201019091526060929190839082801561474157816020015b606081526020019060019003908161472c5790505b50600b5490915083146147585792506114e1915050565b60005b8281101561486757600b60016004600089858151811061477757fe5b60200260200101516001600160a01b03166001600160a01b031681526020019081526020016000205403815481106147ab57fe5b600091825260209182902060026016909202018101805460408051601f6000196101006001861615020190931694909404918201859004850284018501905280835291929091908301828280156148435780601f1061481857610100808354040283529160200191614843565b820191906000526020600020905b81548152906001019060200180831161482657829003601f168201915b505050505082828151811061485457fe5b602090810291909101015260010161475b565b50949350505050565b60005b828110156149bd5760008287838801604051602001614893929190616130565b6040516020818303038152906040528051906020012060001c816148b357fe5b069050808501828701146149b457600089838801815181106148d157fe5b60200260200101519050606089848901815181106148eb57fe5b602002602001015190508a8388018151811061490357fe5b60200260200101518b858a018151811061491957fe5b60200260200101906001600160a01b031690816001600160a01b031681525050818b8489018151811061494857fe5b60200260200101906001600160a01b031690816001600160a01b031681525050898388018151811061497657fe5b60200260200101518a858a018151811061498c57fe5b6020026020010181905250808a848901815181106149a657fe5b602002602001018190525050505b50600101614873565b5050505050505050565b600980546001908101909155600b8054839081106149e157fe5b906000526020600020906016020160010160006101000a81548160ff02191690831515021790555043600b8281548110614a1757fe5b600091825260208220601690910201919091556040516001600160a01b038416917ff62981a567ec3cec866c6fa93c55bcdf841d6292d18b8d522ececa769375d82d91a25050565b600081604051602001614a729190616114565b6040516020818303038152906040528051906020012083604051602001614a999190616114565b6040516020818303038152906040528051906020012014905092915050565b015190565b614ac5615a69565b6000614acf615a69565b614ad7615b7f565b614ae8614ae386615334565b615359565b90506000805b614af7836153a3565b15614c6b5780614b1c57614b12614b0d846153c4565b615412565b60ff168452614c63565b8060011415614c5e576060614b38614b33856153c4565b615492565b90508051604051908082528060200260200182016040528015614b7557816020015b614b62615a34565b815260200190600190039081614b5a5790505b5085602001819052508051604051908082528060200260200182016040528015614bb357816020015b6060815260200190600190039081614b9e5790505b50604086015260005b8151811015614c5357614bcd615a34565b60606000614bed858581518110614be057fe5b6020026020010151615563565b92509250925080614c0d578860009a509a50505050505050505050614c74565b8289602001518581518110614c1e57fe5b60200260200101819052508189604001518581518110614c3a57fe5b6020026020010181905250505050806001019050614bbc565b506001925050614c63565b614c6b565b600101614aee565b50919350909150505b915091565b815181516000916001918114808314614c955760009250614cd3565b600160208701838101602088015b600284838510011415614cce578051835114614cc25760009650600093505b60209283019201614ca3565b505050505b5090949350505050565b6001600160a01b03811660009081526004602052604081205480614d06575060001990506114e1565b600181039050600060018281548110614d1b57fe5b9060005260206000209060040201600301549050600060018381548110614d3e57fe5b6000918252602090912060036004909202010155600154604051600019909101906001600160a01b038616907f8cd4e147d8af98a9e3b6724021b8bf6aed2e5dac71c38f2dce8161b82585b25d90614d97908590616d89565b60405180910390a280614daf578293505050506114e1565b6000818381614dba57fe5b0490508015614e565760005b84811015614e0857614ddf82600183815481106146aa57fe5b60018281548110614dec57fe5b6000918252602090912060036004909202010155600101614dc6565b50600180549085015b81811015614e5357614e2a83600183815481106146aa57fe5b60018281548110614e3757fe5b6000918252602090912060036004909202010155600101614e11565b50505b5091949350505050565b600082614e6f57506000611591565b82820282848281614e7c57fe5b0414611bca5760405162461bcd60e51b8152600401610c0f9061692e565b6000611bca83836040518060400160405280601a81526020017f536166654d6174683a206469766973696f6e206279207a65726f00000000000081525061567d565b805182516000916001600160a01b039182169116148015614f16575081602001516001600160a01b031683602001516001600160a01b0316145b8015611bca5750506040908101519101516001600160a01b0390811691161490565b60125460135480821115614f8357805b82811015614f81576012805480614f5b57fe5b600190038181906000526020600020016000614f779190615a8d565b9055600101614f48565b505b6000818310614f925781614f94565b825b905060005b818110156150ac5761505160128281548110614fb157fe5b600091825260209182902001805460408051601f600260001961010060018716150201909416939093049283018590048502810185019091528181529283018282801561503f5780601f106150145761010080835404028352916020019161503f565b820191906000526020600020905b81548152906001019060200180831161502257829003601f168201915b505050505060138381548110612d4857fe5b6150a4576013818154811061506257fe5b906000526020600020016012828154811061507957fe5b9060005260206000200190805460018160011615610100020316600290046150a2929190615ae0565b505b600101614f99565b5082821115610c3157825b8281101561332d576012601382815481106150ce57fe5b6000918252602080832084546001818101875595855291909320929091018054615111949390920192909160026101009282161592909202600019011604615ae0565b506001016150b7565b601354600b548082111561516557805b8281101561516357601380548061513d57fe5b6001900381819060005260206000200160006151599190615a8d565b905560010161512a565b505b60008183106151745781615176565b825b905060005b81811015615295576152336013828154811061519357fe5b600091825260209182902001805460408051601f60026000196101006001871615020190941693909304928301859004850281018501909152818152928301828280156152215780601f106151f657610100808354040283529160200191615221565b820191906000526020600020905b81548152906001019060200180831161520457829003601f168201915b5050505050600b8381548110613fba57fe5b61528d57600b818154811061524457fe5b90600052602060002090601602016002016013828154811061526257fe5b90600052602060002001908054600181600116156101000203166002900461528b929190615ae0565b505b60010161517b565b5082821115610c3157825b8281101561332d576013600b82815481106152b757fe5b6000918252602080832084546001808201875595855291909320601692909202909201600290810180546152ff95939094019390926000199082161561010002011604615ae0565b506001016152a0565b6000818484111561532c5760405162461bcd60e51b8152600401610c0f919061625e565b505050900390565b61533c615b9f565b506040805180820190915281518152602082810190820152919050565b615361615b7f565b61536a826156b4565b61537357600080fd5b600061538283602001516156ee565b60208085015160408051808201909152868152920190820152915050919050565b60006153ad615b9f565b505080518051602091820151919092015191011190565b6153cc615b9f565b6153d5826153a3565b6153de57600080fd5b602082015160006153ee82615751565b80830160209586015260408051808201909152908152938401919091525090919050565b80516000901580159061542757508151602110155b61543057600080fd5b600061543f83602001516156ee565b905080836000015110156154655760405162461bcd60e51b8152600401610c0f90616a93565b82516020808501518301805192849003929183101561486757506020919091036101000a90049392505050565b606061549d826156b4565b6154a657600080fd5b60006154b183615832565b90506060816040519080825280602002602001820160405280156154ef57816020015b6154dc615b9f565b8152602001906001900390816154d45790505b509050600061550185602001516156ee565b60208601510190506000805b848110156155585761551e83615751565b915060405180604001604052808381526020018481525084828151811061554157fe5b60209081029190910101529181019160010161550d565b509195945050505050565b61556b615a34565b60606000615577615a34565b6060615581615b7f565b61558a87615359565b90506000805b615599836153a3565b1561566e57806155c4576155b46155af846153c4565b61588e565b6001600160a01b03168552615666565b80600114156155ec576155d96155af846153c4565b6001600160a01b03166020860152615666565b8060021415615614576156016155af846153c4565b6001600160a01b03166040860152615666565b806003141561564057615629614b0d846153c4565b6001600160401b0316606086015260019150615666565b80600414156156615761565a615655846153c4565b6158a8565b9350615666565b61566e565b600101615590565b50929791965091945092505050565b6000818361569e5760405162461bcd60e51b8152600401610c0f919061625e565b5060008385816156aa57fe5b0495945050505050565b80516000906156c5575060006114e1565b6020820151805160001a9060c08210156156e4576000925050506114e1565b5060019392505050565b8051600090811a60808110156157085760009150506114e1565b60b8811080615723575060c08110801590615723575060f881105b156157325760019150506114e1565b60c08110156157465760b5190190506114e1565b60f5190190506114e1565b80516000908190811a608081101561576c576001915061582b565b60b881101561578157607e198101915061582b565b60c08110156157d257600060b78203600186019550806020036101000a8651049150600181018201935050808310156157cc5760405162461bcd60e51b8152600401610c0f90616831565b5061582b565b60f88110156157e75760be198101915061582b565b600060f78203600186019550806020036101000a8651049150600181018201935050808310156158295760405162461bcd60e51b8152600401610c0f90616831565b505b5092915050565b8051600090615843575060006114e1565b6000809050600061585784602001516156ee565b602085015185519181019250015b808210156158855761587682615751565b82019150826001019250615865565b50909392505050565b805160009060151461589f57600080fd5b61159182615412565b80516060906158b657600080fd5b60006158c583602001516156ee565b83516040805191839003808352601f19601f82011683016020019091529192506060908280156158fc576020820181803683370190505b50905060008160200190506148678487602001510182858061591d57610c31565b5b6020811061593d578251825260209283019290910190601f190161591e565b915181516020939093036101000a6000190180199091169216919091179052565b60405180608001604052806000815260200160001515815260200160608152602001615988615bb9565b905290565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f106159ce57805160ff19168380011785556159fb565b828001600101855582156159fb579182015b828111156159fb5782518255916020019190600101906159e0565b50612b2a929150615bd8565b82601381019282156159fb57916020028201828111156159fb5782518255916020019190600101906159e0565b6040805160c081018252600080825260208201819052918101829052606081018290526080810182905260a081019190915290565b6040518060600160405280600060ff16815260200160608152602001606081525090565b50805460018160011615610100020316600290046000825580601f10615ab357506116f9565b601f0160209004906000526020600020908101906116f99190615bd8565b506116f9906013810190615bd8565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f10615b1957805485556159fb565b828001600101855582156159fb57600052602060002091601f016020900482015b828111156159fb578254825591600101919060010190615b3a565b82601381019282156159fb57918201828111156159fb578254825591600101919060010190615b3a565b6040518060400160405280615b92615b9f565b8152602001600081525090565b604051806040016040528060008152602001600081525090565b6040518061026001604052806013906020820280368337509192915050565b611dac91905b80821115612b2a5760008155600101615bde565b803561159181616e3e565b60008083601f840112615c0e578182fd5b5081356001600160401b03811115615c24578182fd5b6020830191508360208083028501011115613ae257600080fd5b6000601f8381840112615c4f578182fd5b8235615c62615c5d82616df3565b616dcd565b818152925060208084019085810160005b84811015615cf4578135880189603f820112615c8e57600080fd5b838101356001600160401b03811115615ca657600080fd5b615cb7818901601f19168601616dcd565b81815260408c81848601011115615ccd57600080fd5b82818501888401375060009181018601919091528552509282019290820190600101615c73565b50505050505092915050565b600082601f830112615d10578081fd5b8135615d1e615c5d82616df3565b818152915060208083019084810181840286018201871015615d3f57600080fd5b6000805b85811015615cf45782356001600160401b0381168114615d61578283fd5b85529383019391830191600101615d43565b60008083601f840112615d84578182fd5b5081356001600160401b03811115615d9a578182fd5b602083019150836020828501011115613ae257600080fd5b600060208284031215615dc3578081fd5b8135611bca81616e3e565b600060208284031215615ddf578081fd5b8151611bca81616e3e565b60008060008060408587031215615dff578283fd5b84356001600160401b0380821115615e15578485fd5b615e2188838901615bfd565b90965094506020870135915080821115615e39578384fd5b50615e4687828801615bfd565b95989497509550505050565b600080600060608486031215615e66578283fd5b83356001600160401b0380821115615e7c578485fd5b81860187601f820112615e8d578586fd5b80359250615e9d615c5d84616df3565b80848252602080830192508084018b828389028701011115615ebd57898afd5b8994505b86851015615ee757615ed38c82615bf2565b845260019490940193928101928101615ec1565b509097508801359350505080821115615efe578384fd5b615f0a87838801615d00565b93506040860135915080821115615f1f578283fd5b50615f2c86828701615c3e565b9150509250925092565b60008060208385031215615f48578182fd5b82356001600160401b03811115615f5d578283fd5b615f6985828601615d73565b90969095509350505050565b60008060008060408587031215615f8a578384fd5b84356001600160401b0380821115615fa0578586fd5b615fac88838901615d73565b90965094506020870135915080821115615fc4578384fd5b50615e4687828801615d73565b600060208284031215615fe2578081fd5b5035919050565b600060208284031215615ffa578081fd5b5051919050565b60008060408385031215616013578182fd5b505080516020909101519092909150565b600080600060408486031215616038578081fd5b833560ff81168114616048578182fd5b925060208401356001600160401b03811115616062578182fd5b61606e86828701615d73565b9497909650939450505050565b6000815180845260208085019450808401835b838110156160b35781516001600160a01b03168752958201959082019060010161608e565b509495945050505050565b60008284528282602086013780602084860101526020601f19601f85011685010190509392505050565b60008151808452616100816020860160208601616e12565b601f01601f19169290920160200192915050565b60008251616126818460208701616e12565b9190910192915050565b918252602082015260400190565b6001600160a01b0391909116815260200190565b6001600160a01b03929092168252602082015260400190565b6001600160a01b03968716815294861660208601529290941660408401526001600160401b03166060830152911515608082015260a081019190915260c00190565b6001600160a01b0393909316835260208301919091521515604082015260600190565b600060208252611bca602083018461607b565b6000604082526161f6604083018561607b565b602083820381850152818551808452828401915082838202850101838801865b8381101561624457601f198784030185526162328383516160e8565b94860194925090850190600101616216565b50909998505050505050505050565b901515815260200190565b600060208252611bca60208301846160e8565b6000604082526162856040830186886160be565b82810360208401526162988185876160be565b979650505050505050565b6020808252601c908201527f6c656e677468206f66206275726e526174696f206d69736d6174636800000000604082015260600190565b60208082526026908201527f6c656e677468206f66206d61784e756d4f664d61696e7461696e696e67206d696040820152650e6dac2e8c6d60d31b606082015260800190565b60208082526038908201527f746865206e756d4f66436162696e657473206d757374206265206c657373207460408201527f68616e206d6178456c656374656456616c696461746f72730000000000000000606082015260800190565b6020808252602c908201527f6c656e677468206f66206d61784e756d4f66576f726b696e6743616e6469646160408201526b0e8cae640dad2e6dac2e8c6d60a31b606082015260800190565b60208082526025908201527f6c656e677468206f66206d61696e7461696e536c6173685363616c65206d69736040820152640dac2e8c6d60db1b606082015260800190565b6020808252818101527f6c656e677468206f66206e756d4f66436162696e657473206d69736d61746368604082015260600190565b60208082526019908201527f74686520636f6e7472616374206e6f7420696e69742079657400000000000000604082015260600190565b6020808252601f908201527f6f6e6c7920736c617368206f72207374616b6548756220636f6e747261637400604082015260600190565b6020808252601b908201527f536166654d6174683a206164646974696f6e206f766572666c6f770000000000604082015260600190565b60208082526063908201527f7468652073797374656d52657761726442617365526174696f20706c7573206260408201527f75726e526174696f20616e642073797374656d526577617264416e74694d455660608201527f526174696f206d757374206265206e6f2067726561746572207468616e20313060808201526203030360ec1b60a082015260c00190565b60208082526028908201527f746865206e756d4f66436162696e657473206d75737420626520677265617465604082015267072207468616e20360c41b606082015260800190565b60208082526022908201527f63616e206e6f7420646f207468697320747769636520696e206f6e6520626c6f604082015261636b60f01b606082015260800190565b60208082526037908201527f746865206d61784e756d4f664d61696e7461696e696e67206d7573742062652060408201527f6c657373207468616e206e756d4f66436162696e657473000000000000000000606082015260800190565b6020808252601d908201527f6c656e677468206f66207475726e4c656e677468206d69736d61746368000000604082015260600190565b6020808252600a908201526919195c1c9958d85d195960b21b604082015260600190565b60208082526063908201527f746865206275726e526174696f20706c75732073797374656d5265776172644260408201527f617365526174696f20616e642073797374656d526577617264416e74694d455660608201527f526174696f206d757374206265206e6f2067726561746572207468616e20313060808201526203030360ec1b60a082015260c00190565b6020808252602b908201527f6c656e677468206f662073797374656d526577617264416e74694d455652617460408201526a0d2de40dad2e6dac2e8c6d60ab1b606082015260800190565b6020808252601590820152746465706f7369742076616c7565206973207a65726f60581b604082015260600190565b60208082526049908201527f746865206d61784e756d4f66576f726b696e6743616e64696461746573206d7560408201527f7374206265206e6f742067726561746572207468616e206d61784e756d4f6643606082015268616e6469646174657360b81b608082015260a00190565b6020808252601190820152706164646974696f6e206f766572666c6f7760781b604082015260600190565b60208082526063908201527f7468652073797374656d526577617264416e74694d4556526174696f20706c7560408201527f73206275726e526174696f20616e642073797374656d5265776172644261736560608201527f526174696f206d757374206265206e6f2067726561746572207468616e20313060808201526203030360ec1b60a082015260c00190565b60208082526023908201527f63616e206e6f7420656e7465722054656d706f72617279204d61696e74656e616040820152626e636560e81b606082015260800190565b60208082526021908201527f536166654d6174683a206d756c7469706c69636174696f6e206f766572666c6f6040820152607760f81b606082015260800190565b6020808252601490820152736761737072696365206973206e6f74207a65726f60601b604082015260600190565b6020808252602e908201527f746865206d6573736167652073656e646572206d75737420626520676f76657260408201526d1b985b98d94818dbdb9d1c9858dd60921b606082015260800190565b60208082526025908201527f6c656e677468206f66206d61784e756d4f6643616e64696461746573206d69736040820152640dac2e8c6d60db1b606082015260800190565b6020808252601290820152716e6f7420696e206d61696e74656e616e636560701b604082015260600190565b60208082526019908201527f74686520636f6e747261637420616c726561647920696e697400000000000000604082015260600190565b6020808252601a908201527f6c656e677468206973206c657373207468616e206f6666736574000000000000604082015260600190565b60208082526017908201527f6f6e6c792063757272656e742076616c696461746f7273000000000000000000604082015260600190565b60208082526021908201527f6661696c656420746f20706172736520696e69742076616c696461746f7253656040820152601d60fa1b606082015260800190565b6020808252602f908201527f746865206d6573736167652073656e646572206d7573742062652063726f737360408201526e0818da185a5b8818dbdb9d1c9858dd608a1b606082015260800190565b6020808252602d908201527f746865206d6573736167652073656e646572206d75737420626520746865206260408201526c3637b1b590383937b23ab1b2b960991b606082015260800190565b60208082526028908201527f6c656e677468206f662073797374656d52657761726442617365526174696f206040820152670dad2e6dac2e8c6d60c31b606082015260800190565b6020808252603e908201527f746865206d61696e7461696e536c6173685363616c65206d757374206265206760408201527f726561746572207468616e203020616e64206c657373207468616e2031300000606082015260800190565b60208082526030908201527f746865207475726e4c656e6774682073686f756c6420626520696e205b332c3660408201526f345d206f7220657175616c20746f203160801b606082015260800190565b6020808252600d908201526c756e6b6e6f776e20706172616d60981b604082015260600190565b60208082526029908201527f746865206d6573736167652073656e646572206d75737420626520736c6173686040820152680818dbdb9d1c9858dd60ba1b606082015260800190565b6020808252601f908201527f746865206d73672073656e646572206d757374206265207374616b6548756200604082015260600190565b61ffff91909116815260200190565b90815260200190565b6000848252831515602083015260606040830152616db360608301846160e8565b95945050505050565b63ffffffff91909116815260200190565b6040518181016001600160401b0381118282101715616deb57600080fd5b604052919050565b60006001600160401b03821115616e08578081fd5b5060209081020190565b60005b83811015616e2d578181015183820152602001616e15565b8381111561332d5750506000910152565b6001600160a01b03811681146116f957600080fdfef901a880f901a4f844941284214b9b9c85549ab3d2b972df0deef66ac2c9946ddf42a51534fc98d0c0a3b42c963cace8441ddf946ddf42a51534fc98d0c0a3b42c963cace8441ddf8410000000f84494a2959d3f95eae5dc7d70144ce1b73b403b7eb6e0948081ef03f1d9e0bb4a5bf38f16285c879299f07f948081ef03f1d9e0bb4a5bf38f16285c879299f07f8410000000f8449435552c16704d214347f29fa77f77da6d75d7c75294dc4973e838e3949c77aced16ac2315dc2d7ab11194dc4973e838e3949c77aced16ac2315dc2d7ab1118410000000f84494980a75ecd1309ea12fa2ed87a8744fbfc9b863d594cc6ac05c95a99c1f7b5f88de0e3486c82293b27094cc6ac05c95a99c1f7b5f88de0e3486c82293b2708410000000f84494f474cf03cceff28abc65c9cbae594f725c80e12d94e61a183325a18a173319dd8e19c8d069459e217594e61a183325a18a173319dd8e19c8d069459e21758410000000f84494b71b214cb885500844365e95cd9942c7276e7fd894d22ca3ba2141d23adab65ce4940eb7665ea2b6a794d22ca3ba2141d23adab65ce4940eb7665ea2b6a784100000000175b7a638427703f0dbe7bb9bbf987a2551717b34e79f33b5b1008d1fa01db90175b7a638427703f0dbe7bb9bbf987a2551717b34e79f33b5b1008d1fa01dbb0175b7a638427703f0dbe7bb9bbf987a2551717b34e79f33b5b1008d1fa01dbaa164736f6c6343000604000a \ No newline at end of file diff --git a/core/systemcontracts/lorentz/mainnet/ValidatorContract b/core/systemcontracts/lorentz/mainnet/ValidatorContract new file mode 100644 index 0000000000..09eb9602d5 --- /dev/null +++ b/core/systemcontracts/lorentz/mainnet/ValidatorContract @@ -0,0 +1 @@ +6080604052600436106104405760003560e01c80638b5ad0c911610234578063c81b16621161012e578063e1c7392a116100b6578063f92eb86b1161007a578063f92eb86b14610b3f578063f9a2bbc714610b54578063fccc281314610b69578063fd4ad81f14610b7e578063fd6a687914610bad57610447565b8063e1c7392a14610ac2578063e40716a114610ad7578063ea321e4914610aec578063eb57e20214610b0c578063f340fa0114610b2c57610447565b8063d58918ae116100fd578063d58918ae14610a59578063d68fb56a14610a6e578063daacdb6614610a83578063dc927faf14610a98578063df8079e914610aad57610447565b8063c81b166214610a0f578063c8509d81146107e6578063cb75a59214610a24578063ce910b0c14610a3957610447565b8063aa82dce1116101bc578063aef198a911610180578063aef198a914610999578063b7ab4db5146109ae578063b8cf4ef1146109d0578063c466689d146109e5578063c6d33945146109fa57610447565b8063aa82dce11461090d578063aad5606314610922578063ab51bb9614610937578063ac43175114610959578063ad3c9da61461097957610447565b80639dc09262116102035780639dc09262146108a45780639fe0f816146108b9578063a1a11bf5146108ce578063a5422d5c146108e3578063a78abc16146108f857610447565b80638b5ad0c9146108455780638c5d749d1461085a5780638d19a4101461086f5780639369d7de1461088f57610447565b80634df6e0c3116103455780636e47b482116102cd578063820dcaa811610291578063820dcaa8146107d1578063831d65d1146107e6578063862498821461080657806388b32f111461081b5780638a7beb011461083057610447565b80636e47b4821461076857806375d47a0a1461077d57806378dfed4a146107925780637a84ca2a146107a75780637e434d54146107bc57610447565b806355614fcc1161031457806355614fcc146106c1578063565c56b3146106e157806360eba4fe1461070157806362b72cf5146107215780636969a25c1461073657610447565b80634df6e0c31461066d5780635192c82c1461068257806351b4dce31461069757806351e80672146106ac57610447565b80632a0ffb6e116103c857806335409f7f1161039757806335409f7f146105de5780633b071dcc146105fe57806343756e5c1461062157806345cf9daf14610636578063493279b11461064b57610447565b80632a0ffb6e1461055e578063300c35671461057e578063321d398a1461059e5780633365af3a146105be57610447565b8063152ad3b81161040f578063152ad3b8146104dd5780631bd14ed8146104ff5780631e4c1524146105145780631ff1806914610534578063280870281461054957610447565b806304c4fec61461044c57806307a56847146104635780630e2374a51461048e5780631182b875146104b057610447565b3661044757005b600080fd5b34801561045857600080fd5b50610461610bc2565b005b34801561046f57600080fd5b50610478610c36565b6040516104859190616d89565b60405180910390f35b34801561049a57600080fd5b506104a3610c3c565b604051610485919061613e565b3480156104bc57600080fd5b506104d06104cb366004616024565b610c42565b604051610485919061625e565b3480156104e957600080fd5b506104f2610d5e565b6040516104859190616253565b34801561050b57600080fd5b50610478610d67565b34801561052057600080fd5b5061046161052f366004615e52565b610d6d565b34801561054057600080fd5b506104786110a1565b34801561055557600080fd5b506104a36110a7565b34801561056a57600080fd5b50610461610579366004615db2565b6110ad565b34801561058a57600080fd5b50610461610599366004615dea565b6110ce565b3480156105aa57600080fd5b506104f26105b9366004615fd1565b611417565b3480156105ca57600080fd5b506104f26105d9366004615fd1565b6114e6565b3480156105ea57600080fd5b506104616105f9366004615db2565b611597565b34801561060a57600080fd5b506106136116fc565b6040516104859291906161e3565b34801561062d57600080fd5b506104a36119d8565b34801561064257600080fd5b506104786119de565b34801561065757600080fd5b506106606119e4565b6040516104859190616d7a565b34801561067957600080fd5b506106136119e9565b34801561068e57600080fd5b50610478611b83565b3480156106a357600080fd5b506104a3611b89565b3480156106b857600080fd5b506104a3611b8f565b3480156106cd57600080fd5b506104f26106dc366004615db2565b611b95565b3480156106ed57600080fd5b506104786106fc366004615db2565b611bd1565b34801561070d57600080fd5b506104d061071c366004615fd1565b611c22565b34801561072d57600080fd5b50610478611cc8565b34801561074257600080fd5b50610756610751366004615fd1565b611cce565b6040516104859695949392919061616b565b34801561077457600080fd5b506104a3611d32565b34801561078957600080fd5b506104a3611d38565b34801561079e57600080fd5b50610478611d3e565b3480156107b357600080fd5b50610478611d44565b3480156107c857600080fd5b506104a3611d4a565b3480156107dd57600080fd5b50610478611d50565b3480156107f257600080fd5b50610461610801366004616024565b611d56565b34801561081257600080fd5b50610478611d77565b34801561082757600080fd5b50610478611d7d565b34801561083c57600080fd5b506104f2611d83565b34801561085157600080fd5b50610478611d8c565b34801561086657600080fd5b50610478611d92565b34801561087b57600080fd5b5061047861088a366004615db2565b611daf565b34801561089b57600080fd5b50610461611def565b3480156108b057600080fd5b506104a3611f03565b3480156108c557600080fd5b50610478611f09565b3480156108da57600080fd5b506104a3611f0e565b3480156108ef57600080fd5b506104d0611f14565b34801561090457600080fd5b506104f2611f33565b34801561091957600080fd5b506104a3611f3c565b34801561092e57600080fd5b506104a3611f42565b34801561094357600080fd5b5061094c611f48565b6040516104859190616dbc565b34801561096557600080fd5b50610461610974366004615f75565b611f4d565b34801561098557600080fd5b50610478610994366004615db2565b6129b6565b3480156109a557600080fd5b506104786129c8565b3480156109ba57600080fd5b506109c36129d5565b60405161048591906161d0565b3480156109dc57600080fd5b50610478612ac0565b3480156109f157600080fd5b50610478612ac5565b348015610a0657600080fd5b50610478612acb565b348015610a1b57600080fd5b506104a3612ad0565b348015610a3057600080fd5b50610478612ad6565b348015610a4557600080fd5b506104d0610a54366004615fd1565b612adc565b348015610a6557600080fd5b50610478612ae9565b348015610a7a57600080fd5b50610478612aef565b348015610a8f57600080fd5b50610478612b2e565b348015610aa457600080fd5b506104a3612b34565b348015610ab957600080fd5b506104a3612b3a565b348015610ace57600080fd5b50610461612b40565b348015610ae357600080fd5b50610478612ce9565b348015610af857600080fd5b506104f2610b07366004615f36565b612cef565b348015610b1857600080fd5b50610461610b27366004615db2565b612e75565b610461610b3a366004615db2565b612f7d565b348015610b4b57600080fd5b50610478613333565b348015610b6057600080fd5b506104a3613339565b348015610b7557600080fd5b506104a361333f565b348015610b8a57600080fd5b50610b9e610b99366004615fd1565b613345565b60405161048593929190616d92565b348015610bb957600080fd5b506104a3613407565b6000610bcd33611daf565b9050600b8181548110610bdc57fe5b600091825260209091206001601690920201015460ff16610c185760405162461bcd60e51b8152600401610c0f90616a30565b60405180910390fd5b6000610c22612aef565b9050610c31338383600161340d565b505050565b60095481565b61200181565b60005460609060ff16610c675760405162461bcd60e51b8152600401610c0f90616443565b3361200014610c885760405162461bcd60e51b8152600401610c0f90616b42565b600b54610d4657610c9761595e565b60015460005b81811015610d4257600b80546001810182556000919091528351600080516020616e5483398151915260169092029182019081556020808601516000805160206174838339815191528401805460ff1916911515919091179055604086015180518794610d1e93600080516020616e7483398151915290910192019061598d565b506060820151610d349060038301906013615a07565b505050806001019050610c9d565b5050505b60405162461bcd60e51b8152600401610c0f90616695565b60075460ff1681565b600f5481565b334114610d8c5760405162461bcd60e51b8152600401610c0f90616b91565b3a15610daa5760405162461bcd60e51b8152600401610c0f9061696f565b8251604080518281526020808402820101909152606090828015610de857816020015b610dd5615a34565b815260200190600190039081610dcd5790505b50905060005b82811015610e92576040518060c00160405280878381518110610e0d57fe5b60200260200101516001600160a01b0316815260200160006001600160a01b0316815260200160006001600160a01b03168152602001868381518110610e4f57fe5b60200260200101516001600160401b031681526020016000151581526020016000815250828281518110610e7f57fe5b6020908102919091010152600101610dee565b50606080610ea083866135ff565b9150915060005b600154811015610f9657600060018281548110610ec057fe5b906000526020600020906004020160030154905080600014610f8d57600060018381548110610eeb57fe5b9060005260206000209060040201600301819055506120026001600160a01b031663092193ab8260018581548110610f1f57fe5b60009182526020909120600491820201546040516001600160e01b031960e086901b168152610f5a926001600160a01b03909216910161613e565b6000604051808303818588803b158015610f7357600080fd5b505af1158015610f87573d6000803e3d6000fd5b50505050505b50600101610ea7565b504715611004577f6ecc855f9440a9282c90913bbc91619fd44f5ec0b462af28d127b116f130aa4d47604051610fcc9190616d89565b60405180910390a1604051611002904780156108fc02916000818181858888f19350505050158015611002573d6000803e3d6000fd5b505b600060035581511561101a5761101a8282613ae9565b6110016001600160a01b031663fc4333cd6040518163ffffffff1660e01b8152600401600060405180830381600087803b15801561105757600080fd5b505af115801561106b573d6000803e3d6000fd5b50506040517fedd8d7296956dd970ab4de3f2fc03be2b0ffc615d20cd4c72c6e44f928630ebf925060009150a150505050505050565b60035481565b61200581565b3361200214610d465760405162461bcd60e51b8152600401610c0f90616d43565b3341146110ed5760405162461bcd60e51b8152600401610c0f90616b91565b601054431161110e5760405162461bcd60e51b8152600401610c0f906165bf565b3a1561112c5760405162461bcd60e51b8152600401610c0f9061696f565b60005460ff1661114e5760405162461bcd60e51b8152600401610c0f90616443565b60006110023168056bc75e2d631000008111156111855761117e8168056bc75e2d6310000063ffffffff6142d816565b915061118c565b505061140d565b6040516309a99b4f60e41b815261100290639a99b4f0906111b39030908690600401616152565b602060405180830381600087803b1580156111cd57600080fd5b505af11580156111e1573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906112059190615fe9565b91508161121357505061140d565b6000805b848110156112415785858281811061122b57fe5b9050602002013582019150806001019050611217565b508061124f5750505061140d565b6000806000805b89811015611405578489898381811061126b57fe5b9050602002013588028161127b57fe5b0493508a8a8281811061128a57fe5b905060200201602081019061129f9190615db2565b6001600160a01b038116600090815260046020526040902054909350915081156113bb5760006001808403815481106112d457fe5b9060005260206000209060040201905080600201601c9054906101000a900460ff161561134157836001600160a01b03167fb9c75cbbfde137c4281689580799ef5f52144e78858f776a5979b2b212137d85866040516113349190616d89565b60405180910390a26113b5565b600354611354908663ffffffff61431a16565b600390815581015461136c908663ffffffff61431a16565b60038201556040516001600160a01b038516907fcb0aad6cf9cd03bdf6137e359f541c42f38b39f007cae8e89e88aa7d8c6617b2906113ac908890616d89565b60405180910390a25b506113fd565b826001600160a01b03167fb9c75cbbfde137c4281689580799ef5f52144e78858f776a5979b2b212137d85856040516113f49190616d89565b60405180910390a25b600101611256565b505050505050505b5050436010555050565b600154600090821061142b575060006114e1565b60006001600160a01b03166001838154811061144357fe5b60009182526020909120600490910201546001600160a01b03161480611473575060085415806114735750600a54155b80611482575060085460095410155b806114935750611491826114e6565b155b806114bc57506000600b83815481106114a857fe5b906000526020600020906016020160000154115b806114d0575060016114cc6129d5565b5111155b156114dd575060006114e1565b5060015b919050565b60015460009082106114fa575060006114e1565b600b548210611537576001828154811061151057fe5b9060005260206000209060040201600201601c9054906101000a900460ff161590506114e1565b6001828154811061154457fe5b9060005260206000209060040201600201601c9054906101000a900460ff161580156115915750600b828154811061157857fe5b600091825260209091206001601690920201015460ff16155b92915050565b600b54611655576115a661595e565b60015460005b8181101561165157600b80546001810182556000919091528351600080516020616e5483398151915260169092029182019081556020808601516000805160206174838339815191528401805460ff191691151591909117905560408601518051879461162d93600080516020616e7483398151915290910192019061598d565b5060608201516116439060038301906013615a07565b5050508060010190506115ac565b5050505b336110011480611666575033612002145b6116825760405162461bcd60e51b8152600401610c0f9061647a565b6001600160a01b038116600090815260046020526040902054806116a657506116f9565b6001810390506000600b82815481106116bb57fe5b600091825260209091206001601690920201015460ff1690506116de838361433f565b80156116e75750805b15610c31576009805460001901905550505b50565b60015460609081906000805b8281101561174f576001818154811061171d57fe5b9060005260206000209060040201600201601c9054906101000a900460ff16611747576001909101905b600101611708565b5060608160405190808252806020026020018201604052801561177c578160200160208202803683370190505b5090506060826040519080825280602002602001820160405280156117b557816020015b60608152602001906001900390816117a05790505b50600b54600094509091508414156119305760005b8481101561192a57600181815481106117df57fe5b9060005260206000209060040201600201601c9054906101000a900460ff16611922576001818154811061180f57fe5b600091825260209091206004909102015483516001600160a01b039091169084908690811061183a57fe5b60200260200101906001600160a01b031690816001600160a01b031681525050600b818154811061186757fe5b600091825260209182902060026016909202018101805460408051601f6000196101006001861615020190931694909404918201859004850284018501905280835291929091908301828280156118ff5780601f106118d4576101008083540402835291602001916118ff565b820191906000526020600020905b8154815290600101906020018083116118e257829003601f168201915b505050505082858151811061191057fe5b60209081029190910101526001909301925b6001016117ca565b506119cc565b60005b848110156119ca576001818154811061194857fe5b9060005260206000209060040201600201601c9054906101000a900460ff166119c2576001818154811061197857fe5b600091825260209091206004909102015483516001600160a01b03909116908490869081106119a357fe5b6001600160a01b03909216602092830291909101909101526001909301925b600101611933565b505b909450925050505b9091565b61100181565b60085481565b603881565b6060806000600e549050600080600c5411611a05576015611a09565b600c545b905060c86060611a176129d5565b90506060611a2482614702565b905083825111611a3c5790955093506119d492505050565b84848351031015611a4e578382510394505b8415611a8e576000834381611a5f57fe5b049050611a7483838389890360008b8b614870565b611a8c8383838989038a8a038b8c8c8b510301614870565b505b606084604051908082528060200260200182016040528015611aba578160200160208202803683370190505b509050606085604051908082528060200260200182016040528015611af357816020015b6060815260200190600190039081611ade5790505b50905060005b86811015611b7457848181518110611b0d57fe5b6020026020010151838281518110611b2157fe5b60200260200101906001600160a01b031690816001600160a01b031681525050838181518110611b4d57fe5b6020026020010151828281518110611b6157fe5b6020908102919091010152600101611af9565b50909750955050505050509091565b60065481565b61200681565b61200081565b6001600160a01b03811660009081526004602052604081205480611bbd5760009150506114e1565b60001901611bca816114e6565b9392505050565b6001600160a01b03811660009081526004602052604081205480611bf95760009150506114e1565b600180820381548110611c0857fe5b906000526020600020906004020160030154915050919050565b60128181548110611c2f57fe5b600091825260209182902001805460408051601f6002600019610100600187161502019094169390930492830185900485028101850190915281815293509091830182828015611cc05780601f10611c9557610100808354040283529160200191611cc0565b820191906000526020600020905b815481529060010190602001808311611ca357829003601f168201915b505050505081565b60105481565b60018181548110611cdb57fe5b600091825260209091206004909102018054600182015460028301546003909301546001600160a01b0392831694509082169291821691600160a01b81046001600160401b031691600160e01b90910460ff169086565b61100581565b61100881565b6103e881565b600c5481565b61200381565b61271081565b3361200014610d465760405162461bcd60e51b8152600401610c0f90616b42565b60025481565b60115481565b60145460ff1681565b600a5481565b600060175460001415611da757506001611dac565b506017545b90565b6001600160a01b03811660009081526004602052604081205480611de55760405162461bcd60e51b8152600401610c0f90616aca565b6000190192915050565b600b54611ead57611dfe61595e565b60015460005b81811015611ea957600b80546001810182556000919091528351600080516020616e5483398151915260169092029182019081556020808601516000805160206174838339815191528401805460ff1916911515919091179055604086015180518794611e8593600080516020616e7483398151915290910192019061598d565b506060820151611e9b9060038301906013615a07565b505050806001019050611e04565b5050505b600854611eba5760036008555b600a54611ec7576002600a555b6000611ed233611daf565b9050611edd81611417565b611ef95760405162461bcd60e51b8152600401610c0f906168eb565b6116f933826149c7565b61100781565b600381565b61100681565b6040518061062001604052806105ef8152602001616e946105ef913981565b60005460ff1681565b61200281565b61300081565b600081565b60005460ff16611f6f5760405162461bcd60e51b8152600401610c0f90616443565b3361100714611f905760405162461bcd60e51b8152600401610c0f9061699d565b611ff084848080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250506040805180820190915260098152686275726e526174696f60b81b60208201529150614a5f9050565b156120a557602081146120155760405162461bcd60e51b8152600401610c0f906162a3565b604080516020601f840181900481028201810190925282815260009161205391858580838501838280828437600092019190915250614ab892505050565b905061271061207f601854612073600f548561431a90919063ffffffff16565b9063ffffffff61431a16565b111561209d5760405162461bcd60e51b8152600401610c0f906166b9565b600655612973565b61210f84848080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250506040805180820190915260138152726d61784e756d4f664d61696e7461696e696e6760681b60208201529150614a5f9050565b156121a957602081146121345760405162461bcd60e51b8152600401610c0f906162da565b604080516020601f840181900481028201810190925282815260009161217291858580838501838280828437600092019190915250614ab892505050565b600c5490915080612181575060155b8082106121a05760405162461bcd60e51b8152600401610c0f90616601565b50600855612973565b61221284848080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250506040805180820190915260128152716d61696e7461696e536c6173685363616c6560701b60208201529150614a5f9050565b156122ab57602081146122375760405162461bcd60e51b8152600401610c0f906163c9565b604080516020601f840181900481028201810190925282815260009161227591858580838501838280828437600092019190915250614ab892505050565b90506000811180156122875750600a81105b6122a35760405162461bcd60e51b8152600401610c0f90616c26565b600a55612973565b61231f84848080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152505060408051808201909152601981527f6d61784e756d4f66576f726b696e6743616e646964617465730000000000000060208201529150614a5f9050565b156123ae57602081146123445760405162461bcd60e51b8152600401610c0f9061637d565b604080516020601f840181900481028201810190925282815260009161238291858580838501838280828437600092019190915250614ab892505050565b9050600d548111156123a65760405162461bcd60e51b8152600401610c0f906167c2565b600e55612973565b61241784848080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250506040805180820190915260128152716d61784e756d4f6643616e6469646174657360701b60208201529150614a5f9050565b15612499576020811461243c5760405162461bcd60e51b8152600401610c0f906169eb565b604080516020601f840181900481028201810190925282815260009161247a91858580838501838280828437600092019190915250614ab892505050565b600d819055600e5490915081101561249357600d54600e555b50612973565b6124fd84848080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152505060408051808201909152600d81526c6e756d4f66436162696e65747360981b60208201529150614a5f9050565b1561262257602081146125225760405162461bcd60e51b8152600401610c0f9061640e565b604080516020601f840181900481028201810190925282815260009161256091858580838501838280828437600092019190915250614ab892505050565b9050600081116125825760405162461bcd60e51b8152600401610c0f90616577565b60006120026001600160a01b031663c473318f6040518163ffffffff1660e01b815260040160206040518083038186803b1580156125bf57600080fd5b505afa1580156125d3573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906125f79190615fe9565b9050808211156126195760405162461bcd60e51b8152600401610c0f90616320565b50600c55612973565b61268e84848080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152505060408051808201909152601581527473797374656d52657761726442617365526174696f60581b60208201529150614a5f9050565b1561273757602081146126b35760405162461bcd60e51b8152600401610c0f90616bde565b604080516020601f84018190048102820181019092528281526000916126f191858580838501838280828437600092019190915250614ab892505050565b90506127106127116018546120736006548561431a90919063ffffffff16565b111561272f5760405162461bcd60e51b8152600401610c0f906164e8565b600f55612973565b6127ab84848080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152505060408051808201909152601881527f73797374656d526577617264416e74694d4556526174696f000000000000000060208201529150614a5f9050565b1561285457602081146127d05760405162461bcd60e51b8152600401610c0f90616748565b604080516020601f840181900481028201810190925282815260009161280e91858580838501838280828437600092019190915250614ab892505050565b905061271061282e600f546120736006548561431a90919063ffffffff16565b111561284c5760405162461bcd60e51b8152600401610c0f9061685c565b601855612973565b6128b584848080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152505060408051808201909152600a8152690e8eae4dc98cadccee8d60b31b60208201529150614a5f9050565b1561295b57602081146128da5760405162461bcd60e51b8152600401610c0f9061665e565b604080516020601f840181900481028201810190925282815260009161291891858580838501838280828437600092019190915250614ab892505050565b90506003811015801561292c575060408111155b806129375750806001145b6129535760405162461bcd60e51b8152600401610c0f90616c83565b601755612973565b60405162461bcd60e51b8152600401610c0f90616cd3565b7f6cdb0ac70ab7f2e2d035cca5be60d89906f2dede7648ddbd7402189c1eeed17a848484846040516129a89493929190616271565b60405180910390a150505050565b60046020526000908152604090205481565b68056bc75e2d6310000081565b6001546060906000805b82811015612a04576129f0816114e6565b156129fc578160010191505b6001016129df565b50606081604051908082528060200260200182016040528015612a31578160200160208202803683370190505b5090506000915060005b83811015612ab857612a4c816114e6565b15612ab05760018181548110612a5e57fe5b600091825260209091206004909102015482516001600160a01b0390911690839085908110612a8957fe5b60200260200101906001600160a01b031690816001600160a01b0316815250508260010192505b600101612a3b565b509250505090565b601581565b61027181565b600281565b61100281565b60175481565b60138181548110611c2f57fe5b60185481565b6000612af96129d5565b519050600080600c5411612b0e576015612b12565b600c545b905080821115612b20578091505b81612b2a57600191505b5090565b60055481565b61100381565b61200481565b60005460ff1615612b635760405162461bcd60e51b8152600401610c0f90616a5c565b612b6b615a69565b6000612b916040518061062001604052806105ef8152602001616e946105ef9139614abd565b9150915080612bb25760405162461bcd60e51b8152600401610c0f90616b01565b60005b826020015151811015612cd757600183602001518281518110612bd457fe5b60209081029190910181015182546001818101855560009485528385208351600493840290910180546001600160a01b039283166001600160a01b03199182161782558587015182850180549185169183169190911790556040860151600283018054606089015160808a01511515600160e01b0260ff60e01b196001600160401b03909216600160a01b0267ffffffffffffffff60a01b199590981692909516919091179290921694909417161790915560a090930151600390930192909255918601518051918501939185908110612caa57fe5b602090810291909101810151516001600160a01b0316825281019190915260400160002055600101612bb5565b50506000805460ff1916600117905550565b600d5481565b601354600090815b81811015612df857612de085858080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525050601380549092508591508110612d4857fe5b600091825260209182902001805460408051601f6002600019610100600187161502019094169390930492830185900485028101850190915281815292830182828015612dd65780601f10612dab57610100808354040283529160200191612dd6565b820191906000526020600020905b815481529060010190602001808311612db957829003601f168201915b5050505050614c79565b15612df057600192505050611591565b600101612cf7565b5060125460005b81811015612e6957612e5086868080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525050601280549092508591508110612d4857fe5b15612e615760019350505050611591565b600101612dff565b50600095945050505050565b3361100114612e965760405162461bcd60e51b8152600401610c0f90616cfa565b600b54612f5457612ea561595e565b60015460005b81811015612f5057600b80546001810182556000919091528351600080516020616e5483398151915260169092029182019081556020808601516000805160206174838339815191528401805460ff1916911515919091179055604086015180518794612f2c93600080516020616e7483398151915290910192019061598d565b506060820151612f429060038301906013615a07565b505050806001019050612eab565b5050505b6000612f5f82614cdd565b9050612f6a81611417565b15612f7957612f7982826149c7565b5050565b334114612f9c5760405162461bcd60e51b8152600401610c0f90616b91565b60005460ff16612fbe5760405162461bcd60e51b8152600401610c0f90616443565b60003411612fde5760405162461bcd60e51b8152600401610c0f90616793565b3a15612ffc5760405162461bcd60e51b8152600401610c0f9061696f565b6001600160a01b03811660009081526004602052604090205460145434919060ff1661303c57610271600f556103e86006556014805460ff191660011790555b600f54601754600110801561305357506000601854115b1561307857600160175403601754438161306957fe5b06601854028161307557fe5b04015b6000831180156130885750600081115b156131355760006130b16127106130a5348563ffffffff614e6016565b9063ffffffff614e9a16565b90508015613133576040516110029082156108fc029083906000818181858888f193505050501580156130e8573d6000803e3d6000fd5b507f6ecc855f9440a9282c90913bbc91619fd44f5ec0b462af28d127b116f130aa4d816040516131189190616d89565b60405180910390a1613130848263ffffffff6142d816565b93505b505b60008311801561314757506000600654115b156131ed5760006131696127106130a560065434614e6090919063ffffffff16565b905080156131eb5760405161dead9082156108fc029083906000818181858888f193505050501580156131a0573d6000803e3d6000fd5b507f627059660ea01c4733a328effb2294d2f86905bf806da763a89cee254de8bee5816040516131d09190616d89565b60405180910390a16131e8848263ffffffff6142d816565b93505b505b81156132eb57600060018084038154811061320457fe5b9060005260206000209060040201905080600201601c9054906101000a900460ff161561327157846001600160a01b03167ff177e5d6c5764d79c32883ed824111d9b13f5668cf6ab1cc12dd36791dd955b4856040516132649190616d89565b60405180910390a26132e5565b600354613284908563ffffffff61431a16565b600390815581015461329c908563ffffffff61431a16565b60038201556040516001600160a01b038616907f93a090ecc682c002995fad3c85b30c5651d7fd29b0be5da9d784a3302aedc055906132dc908790616d89565b60405180910390a25b5061332d565b836001600160a01b03167ff177e5d6c5764d79c32883ed824111d9b13f5668cf6ab1cc12dd36791dd955b4846040516133249190616d89565b60405180910390a25b50505050565b600e5481565b61100081565b61dead81565b600b818154811061335257fe5b6000918252602091829020601691909102018054600180830154600280850180546040805161010096831615969096026000190190911692909204601f810188900488028501880190925281845293965060ff909116949192918301828280156133fd5780601f106133d2576101008083540402835291602001916133fd565b820191906000526020600020905b8154815290600101906020018083116133e057829003601f168201915b5050505050905083565b61100481565b6000600a546000148061341e575082155b806134295750600954155b15613436575060006135f7565b60096000815460019003919050819055506000613481600a546130a5866130a5600b8a8154811061346357fe5b6000918252602090912060169091020154439063ffffffff6142d816565b90506000600b868154811061349257fe5b906000526020600020906016020160010160006101000a81548160ff0219169083151502179055506000806110016001600160a01b0316638256ace66040518163ffffffff1660e01b8152600401604080518083038186803b1580156134f757600080fd5b505afa15801561350b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061352f9190616001565b91509150600093508083106135ad57613548888861433f565b506040516328aa02b160e01b8152611001906328aa02b190613572908b9087908a906004016161ad565b600060405180830381600087803b15801561358c57600080fd5b505af11580156135a0573d6000803e3d6000fd5b50505050600193506135bf565b8183106135bf576135bd88614cdd565b505b6040516001600160a01b038916907fb9d38178dc641ff1817967a63c9078cbcd955a9f1fcd75e0e3636de615d44d3b90600090a25050505b949350505050565b606080600080808080613610612aef565b6001549091505b801561384257600181039250600b838154811061363057fe5b600091825260209091206001601690920201015460ff1661365057613839565b6001838154811061365d57fe5b600091825260208220600490910201546001600160a01b031695506136879086908590859061340d565b93508361369357613839565b60405163436aa28360e11b81526000908190612002906386d54506906136bd908a9060040161613e565b60206040518083038186803b1580156136d557600080fd5b505afa1580156136e9573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061370d9190615dce565b90506001600160a01b03811615613796576040516302ceee9160e11b81526120029063059ddd229061374390849060040161613e565b60206040518083038186803b15801561375b57600080fd5b505afa15801561376f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906137939190615dce565b91505b60005b8c5181101561383557876001600160a01b03168d82815181106137b857fe5b6020026020010151600001516001600160a01b031614806138015750826001600160a01b03168d82815181106137ea57fe5b6020026020010151600001516001600160a01b0316145b1561382d5760018d828151811061381457fe5b6020908102919091010151901515608090910152613835565b600101613799565b5050505b60001901613617565b5060005b89518110156138af5789818151811061385b57fe5b6020026020010151608001518061389b575060006001600160a01b03168a828151811061388457fe5b6020026020010151600001516001600160a01b0316145b156138a7578560010195505b600101613846565b50885185106139975760408051600180825281830190925290816020015b6138d5615a34565b8152602001906001900390816138cd575050604080516001808252818301909252919850602082015b60608152602001906001900390816138fe5790505095508860008151811061392257fe5b60200260200101518760008151811061393757fe5b60200260200101819052508760008151811061394f57fe5b60200260200101518660008151811061396457fe5b602002602001018190525060008760008151811061397e57fe5b6020908102919091010151901515608090910152613adc565b848951036040519080825280602002602001820160405280156139d457816020015b6139c1615a34565b8152602001906001900390816139b95790505b50965084895103604051908082528060200260200182016040528015613a0e57816020015b60608152602001906001900390816139f95790505b5095506000915060005b8951811015613ada57898181518110613a2d57fe5b602002602001015160800151158015613a70575060006001600160a01b03168a8281518110613a5857fe5b6020026020010151600001516001600160a01b031614155b15613ad257898181518110613a8157fe5b6020026020010151888481518110613a9557fe5b6020026020010181905250888181518110613aac57fe5b6020026020010151878481518110613ac057fe5b60200260200101819052508260010192505b600101613a18565b505b50505050505b9250929050565b600154825160005b82811015613c06576001613b03615a34565b60018381548110613b1057fe5b600091825260208083206040805160c08101825260049490940290910180546001600160a01b0390811685526001820154811693850193909352600281015492831691840191909152600160a01b82046001600160401b03166060840152600160e01b90910460ff16151560808301526003015460a082015291505b84811015613bda57878181518110613ba057fe5b6020026020010151600001516001600160a01b031682600001516001600160a01b03161415613bd25760009250613bda565b600101613b8c565b508115613bfc5780516001600160a01b03166000908152600460205260408120555b5050600101613af1565b5080821115613cc557805b82811015613cc3576001805480613c2457fe5b60008281526020812060046000199093019283020180546001600160a01b0319908116825560018201805490911690556002810180546001600160e81b0319169055600301559055600b805480613c7757fe5b60008281526020812060166000199093019283020181815560018101805460ff1916905590613ca96002830182615a8d565b613cb7600383016000615ad1565b50509055600101613c11565b505b6000818310613cd45781613cd6565b825b905060005b8181101561407a57613d88868281518110613cf257fe5b602002602001015160018381548110613d0757fe5b60009182526020918290206040805160c08101825260049390930290910180546001600160a01b0390811684526001820154811694840194909452600281015493841691830191909152600160a01b83046001600160401b03166060830152600160e01b90920460ff161515608082015260039091015460a0820152614edc565b613f3c578060010160046000888481518110613da057fe5b6020026020010151600001516001600160a01b03166001600160a01b0316815260200190815260200160002081905550858181518110613ddc57fe5b602002602001015160018281548110613df157fe5b6000918252602091829020835160049092020180546001600160a01b039283166001600160a01b0319918216178255928401516001820180549184169185169190911790556040840151600282018054606087015160808801511515600160e01b0260ff60e01b196001600160401b03909216600160a01b0267ffffffffffffffff60a01b1995909716929097169190911792909216939093171692909217905560a0909101516003909101558451859082908110613eac57fe5b6020026020010151600b8281548110613ec157fe5b90600052602060002090601602016002019080519060200190613ee592919061598d565b506000600b8281548110613ef557fe5b60009182526020822060169190910201600101805460ff191692151592909217909155600b805483908110613f2657fe5b6000918252602090912060169091020155614072565b858181518110613f4857fe5b60200260200101516060015160018281548110613f6157fe5b906000526020600020906004020160020160146101000a8154816001600160401b0302191690836001600160401b03160217905550614027858281518110613fa557fe5b6020026020010151600b8381548110613fba57fe5b600091825260209182902060026016909202018101805460408051601f600019610100600186161502019093169490940491820185900485028401850190528083529192909190830182828015612dd65780601f10612dab57610100808354040283529160200191612dd6565b6140725784818151811061403757fe5b6020026020010151600b828154811061404c57fe5b9060005260206000209060160201600201908051906020019061407092919061598d565b505b600101613cdb565b50828211156142525761408b61595e565b835b8381101561424f578581815181106140a157fe5b6020026020010151826040018190525060018782815181106140bf57fe5b6020908102919091018101518254600181810185556000948552838520835160049093020180546001600160a01b039384166001600160a01b0319918216178255848601518284018054918616918316919091179055604080860151600284018054606089015160808a01511515600160e01b0260ff60e01b196001600160401b03909216600160a01b0267ffffffffffffffff60a01b1995909a1692909616919091179290921696909617169190911790935560a090930151600390930192909255600b8054928301815590935284516016909102600080516020616e548339815191528101918255858301516000805160206174838339815191528201805491151560ff19909216919091179055928501518051869492936141f593600080516020616e748339815191520192019061598d565b50606082015161420b9060038301906013615a07565b505050806001016004600089848151811061422257fe5b602090810291909101810151516001600160a01b031682528101919091526040016000205560010161408d565b50505b61425a614f38565b61426261511a565b6000600981905560015493505b838110156142d0576000600b828154811061428657fe5b60009182526020822060169190910201600101805460ff191692151592909217909155600b8054839081106142b757fe5b600091825260209091206016909102015560010161426f565b505050505050565b6000611bca83836040518060400160405280601e81526020017f536166654d6174683a207375627472616374696f6e206f766572666c6f770000815250615308565b600082820183811015611bca5760405162461bcd60e51b8152600401610c0f906164b1565b6000806001838154811061434f57fe5b906000526020600020906004020160030154905060006001808054905003905060016143796129d5565b51116143ae5760006001858154811061438e57fe5b906000526020600020906004020160030181905550600092505050611591565b846001600160a01b03167f3b6f9ef90462b512a1293ecec018670bf7b7f1876fb727590a8a6d7643130a70836040516143e79190616d89565b60405180910390a26001600160a01b038516600090815260046020526040812055835b600154600019018110156145d4576001816001018154811061442857fe5b90600052602060002090600402016001828154811061444357fe5b60009182526020909120825460049092020180546001600160a01b03199081166001600160a01b0393841617825560018085015481840180548416918616919091179055600280860180549185018054909416919095161780835584546001600160401b03600160a01b91829004160267ffffffffffffffff60a01b1990911617808355935460ff600160e01b918290041615150260ff60e01b19909416939093179055600392830154920191909155600b80549091830190811061450457fe5b9060005260206000209060160201600b828154811061451f57fe5b600091825260209091208254601690920201908155600180830154818301805460ff909216151560ff1990921691909117905560028084018054614576938386019390821615610100026000190190911604615ae0565b5061458960038281019084016013615b55565b509050508060010160046000600184815481106145a257fe5b600091825260208083206004909202909101546001600160a01b0316835282019290925260400190205560010161440a565b5060018054806145e057fe5b60008281526020812060046000199093019283020180546001600160a01b0319908116825560018201805490911690556002810180546001600160e81b0319169055600301559055600b80548061463357fe5b60008281526020812060166000199093019283020181815560018101805460ff19169055906146656002830182615a8d565b614673600383016000615ad1565b50509055600081838161468257fe5b04905080156146f65760015460005b818110156146f3576146ca83600183815481106146aa57fe5b90600052602060002090600402016003015461431a90919063ffffffff16565b600182815481106146d757fe5b6000918252602090912060036004909202010155600101614691565b50505b50600195945050505050565b60015481516040805182815260208084028201019091526060929190839082801561474157816020015b606081526020019060019003908161472c5790505b50600b5490915083146147585792506114e1915050565b60005b8281101561486757600b60016004600089858151811061477757fe5b60200260200101516001600160a01b03166001600160a01b031681526020019081526020016000205403815481106147ab57fe5b600091825260209182902060026016909202018101805460408051601f6000196101006001861615020190931694909404918201859004850284018501905280835291929091908301828280156148435780601f1061481857610100808354040283529160200191614843565b820191906000526020600020905b81548152906001019060200180831161482657829003601f168201915b505050505082828151811061485457fe5b602090810291909101015260010161475b565b50949350505050565b60005b828110156149bd5760008287838801604051602001614893929190616130565b6040516020818303038152906040528051906020012060001c816148b357fe5b069050808501828701146149b457600089838801815181106148d157fe5b60200260200101519050606089848901815181106148eb57fe5b602002602001015190508a8388018151811061490357fe5b60200260200101518b858a018151811061491957fe5b60200260200101906001600160a01b031690816001600160a01b031681525050818b8489018151811061494857fe5b60200260200101906001600160a01b031690816001600160a01b031681525050898388018151811061497657fe5b60200260200101518a858a018151811061498c57fe5b6020026020010181905250808a848901815181106149a657fe5b602002602001018190525050505b50600101614873565b5050505050505050565b600980546001908101909155600b8054839081106149e157fe5b906000526020600020906016020160010160006101000a81548160ff02191690831515021790555043600b8281548110614a1757fe5b600091825260208220601690910201919091556040516001600160a01b038416917ff62981a567ec3cec866c6fa93c55bcdf841d6292d18b8d522ececa769375d82d91a25050565b600081604051602001614a729190616114565b6040516020818303038152906040528051906020012083604051602001614a999190616114565b6040516020818303038152906040528051906020012014905092915050565b015190565b614ac5615a69565b6000614acf615a69565b614ad7615b7f565b614ae8614ae386615334565b615359565b90506000805b614af7836153a3565b15614c6b5780614b1c57614b12614b0d846153c4565b615412565b60ff168452614c63565b8060011415614c5e576060614b38614b33856153c4565b615492565b90508051604051908082528060200260200182016040528015614b7557816020015b614b62615a34565b815260200190600190039081614b5a5790505b5085602001819052508051604051908082528060200260200182016040528015614bb357816020015b6060815260200190600190039081614b9e5790505b50604086015260005b8151811015614c5357614bcd615a34565b60606000614bed858581518110614be057fe5b6020026020010151615563565b92509250925080614c0d578860009a509a50505050505050505050614c74565b8289602001518581518110614c1e57fe5b60200260200101819052508189604001518581518110614c3a57fe5b6020026020010181905250505050806001019050614bbc565b506001925050614c63565b614c6b565b600101614aee565b50919350909150505b915091565b815181516000916001918114808314614c955760009250614cd3565b600160208701838101602088015b600284838510011415614cce578051835114614cc25760009650600093505b60209283019201614ca3565b505050505b5090949350505050565b6001600160a01b03811660009081526004602052604081205480614d06575060001990506114e1565b600181039050600060018281548110614d1b57fe5b9060005260206000209060040201600301549050600060018381548110614d3e57fe5b6000918252602090912060036004909202010155600154604051600019909101906001600160a01b038616907f8cd4e147d8af98a9e3b6724021b8bf6aed2e5dac71c38f2dce8161b82585b25d90614d97908590616d89565b60405180910390a280614daf578293505050506114e1565b6000818381614dba57fe5b0490508015614e565760005b84811015614e0857614ddf82600183815481106146aa57fe5b60018281548110614dec57fe5b6000918252602090912060036004909202010155600101614dc6565b50600180549085015b81811015614e5357614e2a83600183815481106146aa57fe5b60018281548110614e3757fe5b6000918252602090912060036004909202010155600101614e11565b50505b5091949350505050565b600082614e6f57506000611591565b82820282848281614e7c57fe5b0414611bca5760405162461bcd60e51b8152600401610c0f9061692e565b6000611bca83836040518060400160405280601a81526020017f536166654d6174683a206469766973696f6e206279207a65726f00000000000081525061567d565b805182516000916001600160a01b039182169116148015614f16575081602001516001600160a01b031683602001516001600160a01b0316145b8015611bca5750506040908101519101516001600160a01b0390811691161490565b60125460135480821115614f8357805b82811015614f81576012805480614f5b57fe5b600190038181906000526020600020016000614f779190615a8d565b9055600101614f48565b505b6000818310614f925781614f94565b825b905060005b818110156150ac5761505160128281548110614fb157fe5b600091825260209182902001805460408051601f600260001961010060018716150201909416939093049283018590048502810185019091528181529283018282801561503f5780601f106150145761010080835404028352916020019161503f565b820191906000526020600020905b81548152906001019060200180831161502257829003601f168201915b505050505060138381548110612d4857fe5b6150a4576013818154811061506257fe5b906000526020600020016012828154811061507957fe5b9060005260206000200190805460018160011615610100020316600290046150a2929190615ae0565b505b600101614f99565b5082821115610c3157825b8281101561332d576012601382815481106150ce57fe5b6000918252602080832084546001818101875595855291909320929091018054615111949390920192909160026101009282161592909202600019011604615ae0565b506001016150b7565b601354600b548082111561516557805b8281101561516357601380548061513d57fe5b6001900381819060005260206000200160006151599190615a8d565b905560010161512a565b505b60008183106151745781615176565b825b905060005b81811015615295576152336013828154811061519357fe5b600091825260209182902001805460408051601f60026000196101006001871615020190941693909304928301859004850281018501909152818152928301828280156152215780601f106151f657610100808354040283529160200191615221565b820191906000526020600020905b81548152906001019060200180831161520457829003601f168201915b5050505050600b8381548110613fba57fe5b61528d57600b818154811061524457fe5b90600052602060002090601602016002016013828154811061526257fe5b90600052602060002001908054600181600116156101000203166002900461528b929190615ae0565b505b60010161517b565b5082821115610c3157825b8281101561332d576013600b82815481106152b757fe5b6000918252602080832084546001808201875595855291909320601692909202909201600290810180546152ff95939094019390926000199082161561010002011604615ae0565b506001016152a0565b6000818484111561532c5760405162461bcd60e51b8152600401610c0f919061625e565b505050900390565b61533c615b9f565b506040805180820190915281518152602082810190820152919050565b615361615b7f565b61536a826156b4565b61537357600080fd5b600061538283602001516156ee565b60208085015160408051808201909152868152920190820152915050919050565b60006153ad615b9f565b505080518051602091820151919092015191011190565b6153cc615b9f565b6153d5826153a3565b6153de57600080fd5b602082015160006153ee82615751565b80830160209586015260408051808201909152908152938401919091525090919050565b80516000901580159061542757508151602110155b61543057600080fd5b600061543f83602001516156ee565b905080836000015110156154655760405162461bcd60e51b8152600401610c0f90616a93565b82516020808501518301805192849003929183101561486757506020919091036101000a90049392505050565b606061549d826156b4565b6154a657600080fd5b60006154b183615832565b90506060816040519080825280602002602001820160405280156154ef57816020015b6154dc615b9f565b8152602001906001900390816154d45790505b509050600061550185602001516156ee565b60208601510190506000805b848110156155585761551e83615751565b915060405180604001604052808381526020018481525084828151811061554157fe5b60209081029190910101529181019160010161550d565b509195945050505050565b61556b615a34565b60606000615577615a34565b6060615581615b7f565b61558a87615359565b90506000805b615599836153a3565b1561566e57806155c4576155b46155af846153c4565b61588e565b6001600160a01b03168552615666565b80600114156155ec576155d96155af846153c4565b6001600160a01b03166020860152615666565b8060021415615614576156016155af846153c4565b6001600160a01b03166040860152615666565b806003141561564057615629614b0d846153c4565b6001600160401b0316606086015260019150615666565b80600414156156615761565a615655846153c4565b6158a8565b9350615666565b61566e565b600101615590565b50929791965091945092505050565b6000818361569e5760405162461bcd60e51b8152600401610c0f919061625e565b5060008385816156aa57fe5b0495945050505050565b80516000906156c5575060006114e1565b6020820151805160001a9060c08210156156e4576000925050506114e1565b5060019392505050565b8051600090811a60808110156157085760009150506114e1565b60b8811080615723575060c08110801590615723575060f881105b156157325760019150506114e1565b60c08110156157465760b5190190506114e1565b60f5190190506114e1565b80516000908190811a608081101561576c576001915061582b565b60b881101561578157607e198101915061582b565b60c08110156157d257600060b78203600186019550806020036101000a8651049150600181018201935050808310156157cc5760405162461bcd60e51b8152600401610c0f90616831565b5061582b565b60f88110156157e75760be198101915061582b565b600060f78203600186019550806020036101000a8651049150600181018201935050808310156158295760405162461bcd60e51b8152600401610c0f90616831565b505b5092915050565b8051600090615843575060006114e1565b6000809050600061585784602001516156ee565b602085015185519181019250015b808210156158855761587682615751565b82019150826001019250615865565b50909392505050565b805160009060151461589f57600080fd5b61159182615412565b80516060906158b657600080fd5b60006158c583602001516156ee565b83516040805191839003808352601f19601f82011683016020019091529192506060908280156158fc576020820181803683370190505b50905060008160200190506148678487602001510182858061591d57610c31565b5b6020811061593d578251825260209283019290910190601f190161591e565b915181516020939093036101000a6000190180199091169216919091179052565b60405180608001604052806000815260200160001515815260200160608152602001615988615bb9565b905290565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f106159ce57805160ff19168380011785556159fb565b828001600101855582156159fb579182015b828111156159fb5782518255916020019190600101906159e0565b50612b2a929150615bd8565b82601381019282156159fb57916020028201828111156159fb5782518255916020019190600101906159e0565b6040805160c081018252600080825260208201819052918101829052606081018290526080810182905260a081019190915290565b6040518060600160405280600060ff16815260200160608152602001606081525090565b50805460018160011615610100020316600290046000825580601f10615ab357506116f9565b601f0160209004906000526020600020908101906116f99190615bd8565b506116f9906013810190615bd8565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f10615b1957805485556159fb565b828001600101855582156159fb57600052602060002091601f016020900482015b828111156159fb578254825591600101919060010190615b3a565b82601381019282156159fb57918201828111156159fb578254825591600101919060010190615b3a565b6040518060400160405280615b92615b9f565b8152602001600081525090565b604051806040016040528060008152602001600081525090565b6040518061026001604052806013906020820280368337509192915050565b611dac91905b80821115612b2a5760008155600101615bde565b803561159181616e3e565b60008083601f840112615c0e578182fd5b5081356001600160401b03811115615c24578182fd5b6020830191508360208083028501011115613ae257600080fd5b6000601f8381840112615c4f578182fd5b8235615c62615c5d82616df3565b616dcd565b818152925060208084019085810160005b84811015615cf4578135880189603f820112615c8e57600080fd5b838101356001600160401b03811115615ca657600080fd5b615cb7818901601f19168601616dcd565b81815260408c81848601011115615ccd57600080fd5b82818501888401375060009181018601919091528552509282019290820190600101615c73565b50505050505092915050565b600082601f830112615d10578081fd5b8135615d1e615c5d82616df3565b818152915060208083019084810181840286018201871015615d3f57600080fd5b6000805b85811015615cf45782356001600160401b0381168114615d61578283fd5b85529383019391830191600101615d43565b60008083601f840112615d84578182fd5b5081356001600160401b03811115615d9a578182fd5b602083019150836020828501011115613ae257600080fd5b600060208284031215615dc3578081fd5b8135611bca81616e3e565b600060208284031215615ddf578081fd5b8151611bca81616e3e565b60008060008060408587031215615dff578283fd5b84356001600160401b0380821115615e15578485fd5b615e2188838901615bfd565b90965094506020870135915080821115615e39578384fd5b50615e4687828801615bfd565b95989497509550505050565b600080600060608486031215615e66578283fd5b83356001600160401b0380821115615e7c578485fd5b81860187601f820112615e8d578586fd5b80359250615e9d615c5d84616df3565b80848252602080830192508084018b828389028701011115615ebd57898afd5b8994505b86851015615ee757615ed38c82615bf2565b845260019490940193928101928101615ec1565b509097508801359350505080821115615efe578384fd5b615f0a87838801615d00565b93506040860135915080821115615f1f578283fd5b50615f2c86828701615c3e565b9150509250925092565b60008060208385031215615f48578182fd5b82356001600160401b03811115615f5d578283fd5b615f6985828601615d73565b90969095509350505050565b60008060008060408587031215615f8a578384fd5b84356001600160401b0380821115615fa0578586fd5b615fac88838901615d73565b90965094506020870135915080821115615fc4578384fd5b50615e4687828801615d73565b600060208284031215615fe2578081fd5b5035919050565b600060208284031215615ffa578081fd5b5051919050565b60008060408385031215616013578182fd5b505080516020909101519092909150565b600080600060408486031215616038578081fd5b833560ff81168114616048578182fd5b925060208401356001600160401b03811115616062578182fd5b61606e86828701615d73565b9497909650939450505050565b6000815180845260208085019450808401835b838110156160b35781516001600160a01b03168752958201959082019060010161608e565b509495945050505050565b60008284528282602086013780602084860101526020601f19601f85011685010190509392505050565b60008151808452616100816020860160208601616e12565b601f01601f19169290920160200192915050565b60008251616126818460208701616e12565b9190910192915050565b918252602082015260400190565b6001600160a01b0391909116815260200190565b6001600160a01b03929092168252602082015260400190565b6001600160a01b03968716815294861660208601529290941660408401526001600160401b03166060830152911515608082015260a081019190915260c00190565b6001600160a01b0393909316835260208301919091521515604082015260600190565b600060208252611bca602083018461607b565b6000604082526161f6604083018561607b565b602083820381850152818551808452828401915082838202850101838801865b8381101561624457601f198784030185526162328383516160e8565b94860194925090850190600101616216565b50909998505050505050505050565b901515815260200190565b600060208252611bca60208301846160e8565b6000604082526162856040830186886160be565b82810360208401526162988185876160be565b979650505050505050565b6020808252601c908201527f6c656e677468206f66206275726e526174696f206d69736d6174636800000000604082015260600190565b60208082526026908201527f6c656e677468206f66206d61784e756d4f664d61696e7461696e696e67206d696040820152650e6dac2e8c6d60d31b606082015260800190565b60208082526038908201527f746865206e756d4f66436162696e657473206d757374206265206c657373207460408201527f68616e206d6178456c656374656456616c696461746f72730000000000000000606082015260800190565b6020808252602c908201527f6c656e677468206f66206d61784e756d4f66576f726b696e6743616e6469646160408201526b0e8cae640dad2e6dac2e8c6d60a31b606082015260800190565b60208082526025908201527f6c656e677468206f66206d61696e7461696e536c6173685363616c65206d69736040820152640dac2e8c6d60db1b606082015260800190565b6020808252818101527f6c656e677468206f66206e756d4f66436162696e657473206d69736d61746368604082015260600190565b60208082526019908201527f74686520636f6e7472616374206e6f7420696e69742079657400000000000000604082015260600190565b6020808252601f908201527f6f6e6c7920736c617368206f72207374616b6548756220636f6e747261637400604082015260600190565b6020808252601b908201527f536166654d6174683a206164646974696f6e206f766572666c6f770000000000604082015260600190565b60208082526063908201527f7468652073797374656d52657761726442617365526174696f20706c7573206260408201527f75726e526174696f20616e642073797374656d526577617264416e74694d455660608201527f526174696f206d757374206265206e6f2067726561746572207468616e20313060808201526203030360ec1b60a082015260c00190565b60208082526028908201527f746865206e756d4f66436162696e657473206d75737420626520677265617465604082015267072207468616e20360c41b606082015260800190565b60208082526022908201527f63616e206e6f7420646f207468697320747769636520696e206f6e6520626c6f604082015261636b60f01b606082015260800190565b60208082526037908201527f746865206d61784e756d4f664d61696e7461696e696e67206d7573742062652060408201527f6c657373207468616e206e756d4f66436162696e657473000000000000000000606082015260800190565b6020808252601d908201527f6c656e677468206f66207475726e4c656e677468206d69736d61746368000000604082015260600190565b6020808252600a908201526919195c1c9958d85d195960b21b604082015260600190565b60208082526063908201527f746865206275726e526174696f20706c75732073797374656d5265776172644260408201527f617365526174696f20616e642073797374656d526577617264416e74694d455660608201527f526174696f206d757374206265206e6f2067726561746572207468616e20313060808201526203030360ec1b60a082015260c00190565b6020808252602b908201527f6c656e677468206f662073797374656d526577617264416e74694d455652617460408201526a0d2de40dad2e6dac2e8c6d60ab1b606082015260800190565b6020808252601590820152746465706f7369742076616c7565206973207a65726f60581b604082015260600190565b60208082526049908201527f746865206d61784e756d4f66576f726b696e6743616e64696461746573206d7560408201527f7374206265206e6f742067726561746572207468616e206d61784e756d4f6643606082015268616e6469646174657360b81b608082015260a00190565b6020808252601190820152706164646974696f6e206f766572666c6f7760781b604082015260600190565b60208082526063908201527f7468652073797374656d526577617264416e74694d4556526174696f20706c7560408201527f73206275726e526174696f20616e642073797374656d5265776172644261736560608201527f526174696f206d757374206265206e6f2067726561746572207468616e20313060808201526203030360ec1b60a082015260c00190565b60208082526023908201527f63616e206e6f7420656e7465722054656d706f72617279204d61696e74656e616040820152626e636560e81b606082015260800190565b60208082526021908201527f536166654d6174683a206d756c7469706c69636174696f6e206f766572666c6f6040820152607760f81b606082015260800190565b6020808252601490820152736761737072696365206973206e6f74207a65726f60601b604082015260600190565b6020808252602e908201527f746865206d6573736167652073656e646572206d75737420626520676f76657260408201526d1b985b98d94818dbdb9d1c9858dd60921b606082015260800190565b60208082526025908201527f6c656e677468206f66206d61784e756d4f6643616e64696461746573206d69736040820152640dac2e8c6d60db1b606082015260800190565b6020808252601290820152716e6f7420696e206d61696e74656e616e636560701b604082015260600190565b60208082526019908201527f74686520636f6e747261637420616c726561647920696e697400000000000000604082015260600190565b6020808252601a908201527f6c656e677468206973206c657373207468616e206f6666736574000000000000604082015260600190565b60208082526017908201527f6f6e6c792063757272656e742076616c696461746f7273000000000000000000604082015260600190565b60208082526021908201527f6661696c656420746f20706172736520696e69742076616c696461746f7253656040820152601d60fa1b606082015260800190565b6020808252602f908201527f746865206d6573736167652073656e646572206d7573742062652063726f737360408201526e0818da185a5b8818dbdb9d1c9858dd608a1b606082015260800190565b6020808252602d908201527f746865206d6573736167652073656e646572206d75737420626520746865206260408201526c3637b1b590383937b23ab1b2b960991b606082015260800190565b60208082526028908201527f6c656e677468206f662073797374656d52657761726442617365526174696f206040820152670dad2e6dac2e8c6d60c31b606082015260800190565b6020808252603e908201527f746865206d61696e7461696e536c6173685363616c65206d757374206265206760408201527f726561746572207468616e203020616e64206c657373207468616e2031300000606082015260800190565b60208082526030908201527f746865207475726e4c656e6774682073686f756c6420626520696e205b332c3660408201526f345d206f7220657175616c20746f203160801b606082015260800190565b6020808252600d908201526c756e6b6e6f776e20706172616d60981b604082015260600190565b60208082526029908201527f746865206d6573736167652073656e646572206d75737420626520736c6173686040820152680818dbdb9d1c9858dd60ba1b606082015260800190565b6020808252601f908201527f746865206d73672073656e646572206d757374206265207374616b6548756200604082015260600190565b61ffff91909116815260200190565b90815260200190565b6000848252831515602083015260606040830152616db360608301846160e8565b95945050505050565b63ffffffff91909116815260200190565b6040518181016001600160401b0381118282101715616deb57600080fd5b604052919050565b60006001600160401b03821115616e08578081fd5b5060209081020190565b60005b83811015616e2d578181015183820152602001616e15565b8381111561332d5750506000910152565b6001600160a01b03811681146116f957600080fdfe0175b7a638427703f0dbe7bb9bbf987a2551717b34e79f33b5b1008d1fa01db90175b7a638427703f0dbe7bb9bbf987a2551717b34e79f33b5b1008d1fa01dbbf905ec80f905e8f846942a7cdd959bfe8d9487b2a43b33565295a698f7e294b6a7edd747c0554875d3fc531d19ba1497992c5e941ff80f3f7f110ffd8920a3ac38fdef318fe94a3f86048c27395000f846946488aa4d1955ee33403f8ccb1d4de5fb97c7ade294220f003d8bdfaadf52aa1e55ae4cc485e6794875941a87e90e440a39c99aa9cb5cea0ad6a3f0b2407b86048c27395000f846949ef9f4360c606c7ab4db26b016007d3ad0ab86a0946103af86a874b705854033438383c82575f25bc29418e2db06cbff3e3c5f856410a1838649e760175786048c27395000f84694ee01c3b1283aa067c58eab4709f85e99d46de5fe94ee4b9bfb1871c64e2bcabb1dc382dc8b7c4218a29415904ab26ab0e99d70b51c220ccdcccabee6e29786048c27395000f84694685b1ded8013785d6623cc18d214320b6bb6475994a20ef4e5e4e7e36258dbf51f4d905114cb1b34bc9413e39085dc88704f4394d35209a02b1a9520320c86048c27395000f8469478f3adfc719c99674c072166708589033e2d9afe9448a30d5eaa7b64492a160f139e2da2800ec3834e94055838358c29edf4dcc1ba1985ad58aedbb6be2b86048c27395000f84694c2be4ec20253b8642161bc3f444f53679c1f3d479466f50c616d737e60d7ca6311ff0d9c434197898a94d1d678a2506eeaa365056fe565df8bc8659f28b086048c27395000f846942f7be8361c80a4c1e7e9aaf001d0877f1cfde218945f93992ac37f3e61db2ef8a587a436a161fd210b94ecbc4fb1a97861344dad0867ca3cba2b860411f086048c27395000f84694ce2fd7544e0b2cc94692d4a704debef7bcb613289444abc67b4b2fba283c582387f54c9cba7c34bafa948acc2ab395ded08bb75ce85bf0f95ad2abc51ad586048c27395000f84694b8f7166496996a7da21cf1f1b04d9b3e26a3d077946770572763289aac606e4f327c2f6cc1aa3b3e3b94882d745ed97d4422ca8da1c22ec49d880c4c097286048c27395000f846942d4c407bbe49438ed859fe965b140dcf1aab71a9943ad0939e120f33518fbba04631afe7a3ed6327b194b2bbb170ca4e499a2b0f3cc85ebfa6e8c4dfcbea86048c27395000f846946bbad7cf34b5fa511d8e963dbba288b1960e75d694853b0f6c324d1f4e76c8266942337ac1b0af1a229442498946a51ca5924552ead6fc2af08b94fcba648601d1a94a2000f846944430b3230294d12c6ab2aac5c2cd68e80b16b581947b107f4976a252a6939b771202c28e64e03f52d694795811a7f214084116949fc4f53cedbf189eeab28601d1a94a2000f84694ea0a6e3c511bbd10f4519ece37dc24887e11b55d946811ca77acfb221a49393c193f3a22db829fcc8e9464feb7c04830dd9ace164fc5c52b3f5a29e5018a8601d1a94a2000f846947ae2f5b9e386cd1b50a4550696d957cb4900f03a94e83bcc5077e6b873995c24bac871b5ad856047e19464e48d4057a90b233e026c1041e6012ada897fe88601d1a94a2000f8469482012708dafc9e1b880fd083b32182b869be8e09948e5adc73a2d233a1b496ed3115464dd6c7b887509428b383d324bc9a37f4e276190796ba5a8947f5ed8601d1a94a2000f8469422b81f8e175ffde54d797fe11eb03f9e3bf75f1d94a1c3ef7ca38d8ba80cce3bfc53ebd2903ed21658942767f7447f7b9b70313d4147b795414aecea54718601d1a94a2000f8469468bf0b8b6fb4e317a0f9d6f03eaf8ce6675bc60d94675cfe570b7902623f47e7f59c9664b5f5065dcf94d84f0d2e50bcf00f2fc476e1c57f5ca2d57f625b8601d1a94a2000f846948c4d90829ce8f72d0163c1d5cf348a862d5506309485c42a7b34309bee2ed6a235f86d16f059deec5894cc2cedc53f0fa6d376336efb67e43d167169f3b78601d1a94a2000f8469435e7a025f4da968de7e4d7e4004197917f4070f194b1182abaeeb3b4d8eba7e6a4162eac7ace23d57394c4fd0d870da52e73de2dd8ded19fe3d26f43a1138601d1a94a2000f84694d6caa02bbebaebb5d7e581e4b66559e635f805ff94c07335cf083c1c46a487f0325769d88e163b653694efaff03b42e41f953a925fc43720e45fb61a19938601d1a94a20000175b7a638427703f0dbe7bb9bbf987a2551717b34e79f33b5b1008d1fa01dbaa164736f6c6343000604000a \ No newline at end of file diff --git a/core/systemcontracts/lorentz/rialto/ValidatorContract b/core/systemcontracts/lorentz/rialto/ValidatorContract new file mode 100644 index 0000000000..0705dd92a0 --- /dev/null +++ b/core/systemcontracts/lorentz/rialto/ValidatorContract @@ -0,0 +1 @@ +6080604052600436106104405760003560e01c80638b5ad0c911610234578063c81b16621161012e578063e1c7392a116100b6578063f92eb86b1161007a578063f92eb86b14610b3f578063f9a2bbc714610b54578063fccc281314610b69578063fd4ad81f14610b7e578063fd6a687914610bad57610447565b8063e1c7392a14610ac2578063e40716a114610ad7578063ea321e4914610aec578063eb57e20214610b0c578063f340fa0114610b2c57610447565b8063d58918ae116100fd578063d58918ae14610a59578063d68fb56a14610a6e578063daacdb6614610a83578063dc927faf14610a98578063df8079e914610aad57610447565b8063c81b166214610a0f578063c8509d81146107e6578063cb75a59214610a24578063ce910b0c14610a3957610447565b8063aa82dce1116101bc578063aef198a911610180578063aef198a914610999578063b7ab4db5146109ae578063b8cf4ef1146109d0578063c466689d146109e5578063c6d33945146109fa57610447565b8063aa82dce11461090d578063aad5606314610922578063ab51bb9614610937578063ac43175114610959578063ad3c9da61461097957610447565b80639dc09262116102035780639dc09262146108a45780639fe0f816146108b9578063a1a11bf5146108ce578063a5422d5c146108e3578063a78abc16146108f857610447565b80638b5ad0c9146108455780638c5d749d1461085a5780638d19a4101461086f5780639369d7de1461088f57610447565b80634df6e0c3116103455780636e47b482116102cd578063820dcaa811610291578063820dcaa8146107d1578063831d65d1146107e6578063862498821461080657806388b32f111461081b5780638a7beb011461083057610447565b80636e47b4821461076857806375d47a0a1461077d57806378dfed4a146107925780637a84ca2a146107a75780637e434d54146107bc57610447565b806355614fcc1161031457806355614fcc146106c1578063565c56b3146106e157806360eba4fe1461070157806362b72cf5146107215780636969a25c1461073657610447565b80634df6e0c31461066d5780635192c82c1461068257806351b4dce31461069757806351e80672146106ac57610447565b80632a0ffb6e116103c857806335409f7f1161039757806335409f7f146105de5780633b071dcc146105fe57806343756e5c1461062157806345cf9daf14610636578063493279b11461064b57610447565b80632a0ffb6e1461055e578063300c35671461057e578063321d398a1461059e5780633365af3a146105be57610447565b8063152ad3b81161040f578063152ad3b8146104dd5780631bd14ed8146104ff5780631e4c1524146105145780631ff1806914610534578063280870281461054957610447565b806304c4fec61461044c57806307a56847146104635780630e2374a51461048e5780631182b875146104b057610447565b3661044757005b600080fd5b34801561045857600080fd5b50610461610bc2565b005b34801561046f57600080fd5b50610478610c36565b6040516104859190616e48565b60405180910390f35b34801561049a57600080fd5b506104a3610c3c565b60405161048591906161fd565b3480156104bc57600080fd5b506104d06104cb3660046160e3565b610c42565b604051610485919061631d565b3480156104e957600080fd5b506104f2610d3d565b6040516104859190616312565b34801561050b57600080fd5b50610478610d46565b34801561052057600080fd5b5061046161052f366004615f11565b610d4c565b34801561054057600080fd5b50610478611080565b34801561055557600080fd5b506104a3611086565b34801561056a57600080fd5b50610461610579366004615e71565b61108c565b34801561058a57600080fd5b50610461610599366004615ea9565b6110ad565b3480156105aa57600080fd5b506104f26105b9366004616090565b6113f6565b3480156105ca57600080fd5b506104f26105d9366004616090565b6114c5565b3480156105ea57600080fd5b506104616105f9366004615e71565b611576565b34801561060a57600080fd5b506106136116db565b6040516104859291906162a2565b34801561062d57600080fd5b506104a36119b7565b34801561064257600080fd5b506104786119bd565b34801561065757600080fd5b506106606119c3565b6040516104859190616e39565b34801561067957600080fd5b506106136119c9565b34801561068e57600080fd5b50610478611b63565b3480156106a357600080fd5b506104a3611b69565b3480156106b857600080fd5b506104a3611b6f565b3480156106cd57600080fd5b506104f26106dc366004615e71565b611b75565b3480156106ed57600080fd5b506104786106fc366004615e71565b611bb1565b34801561070d57600080fd5b506104d061071c366004616090565b611c02565b34801561072d57600080fd5b50610478611ca8565b34801561074257600080fd5b50610756610751366004616090565b611cae565b6040516104859695949392919061622a565b34801561077457600080fd5b506104a3611d12565b34801561078957600080fd5b506104a3611d18565b34801561079e57600080fd5b50610478611d1e565b3480156107b357600080fd5b50610478611d24565b3480156107c857600080fd5b506104a3611d2a565b3480156107dd57600080fd5b50610478611d30565b3480156107f257600080fd5b506104616108013660046160e3565b611d36565b34801561081257600080fd5b50610478611d57565b34801561082757600080fd5b50610478611d5d565b34801561083c57600080fd5b506104f2611d63565b34801561085157600080fd5b50610478611d6c565b34801561086657600080fd5b50610478611d72565b34801561087b57600080fd5b5061047861088a366004615e71565b611d8f565b34801561089b57600080fd5b50610461611dcf565b3480156108b057600080fd5b506104a3611ee3565b3480156108c557600080fd5b50610478611ee9565b3480156108da57600080fd5b506104a3611eee565b3480156108ef57600080fd5b506104d0611ef4565b34801561090457600080fd5b506104f2611f10565b34801561091957600080fd5b506104a3611f19565b34801561092e57600080fd5b506104a3611f1f565b34801561094357600080fd5b5061094c611f25565b6040516104859190616e7b565b34801561096557600080fd5b50610461610974366004616034565b611f2a565b34801561098557600080fd5b50610478610994366004615e71565b612993565b3480156109a557600080fd5b506104786129a5565b3480156109ba57600080fd5b506109c36129b2565b604051610485919061628f565b3480156109dc57600080fd5b50610478612a9d565b3480156109f157600080fd5b50610478612aa2565b348015610a0657600080fd5b50610478612aa8565b348015610a1b57600080fd5b506104a3612aad565b348015610a3057600080fd5b50610478612ab3565b348015610a4557600080fd5b506104d0610a54366004616090565b612ab9565b348015610a6557600080fd5b50610478612ac6565b348015610a7a57600080fd5b50610478612acc565b348015610a8f57600080fd5b50610478612b0b565b348015610aa457600080fd5b506104a3612b11565b348015610ab957600080fd5b506104a3612b17565b348015610ace57600080fd5b50610461612b1d565b348015610ae357600080fd5b50610478612da8565b348015610af857600080fd5b506104f2610b07366004615ff5565b612dae565b348015610b1857600080fd5b50610461610b27366004615e71565b612f34565b610461610b3a366004615e71565b61303c565b348015610b4b57600080fd5b506104786133f2565b348015610b6057600080fd5b506104a36133f8565b348015610b7557600080fd5b506104a36133fe565b348015610b8a57600080fd5b50610b9e610b99366004616090565b613404565b60405161048593929190616e51565b348015610bb957600080fd5b506104a36134c6565b6000610bcd33611d8f565b9050600b8181548110610bdc57fe5b600091825260209091206001601690920201015460ff16610c185760405162461bcd60e51b8152600401610c0f90616aef565b60405180910390fd5b6000610c22612acc565b9050610c3133838360016134cc565b505050565b60095481565b61200181565b60005460609060ff16610c675760405162461bcd60e51b8152600401610c0f90616502565b600b54610d2557610c76615a1d565b60015460005b81811015610d2157600b80546001810182556000919091528351600080516020616f138339815191526016909202918201908155602080860151600080516020616f538339815191528401805460ff1916911515919091179055604086015180518794610cfd93600080516020616f33833981519152909101920190615a4c565b506060820151610d139060038301906013615ac6565b505050806001019050610c7c565b5050505b60405162461bcd60e51b8152600401610c0f90616754565b60075460ff1681565b600f5481565b334114610d6b5760405162461bcd60e51b8152600401610c0f90616c50565b3a15610d895760405162461bcd60e51b8152600401610c0f90616a2e565b8251604080518281526020808402820101909152606090828015610dc757816020015b610db4615af3565b815260200190600190039081610dac5790505b50905060005b82811015610e71576040518060c00160405280878381518110610dec57fe5b60200260200101516001600160a01b0316815260200160006001600160a01b0316815260200160006001600160a01b03168152602001868381518110610e2e57fe5b60200260200101516001600160401b031681526020016000151581526020016000815250828281518110610e5e57fe5b6020908102919091010152600101610dcd565b50606080610e7f83866136be565b9150915060005b600154811015610f7557600060018281548110610e9f57fe5b906000526020600020906004020160030154905080600014610f6c57600060018381548110610eca57fe5b9060005260206000209060040201600301819055506120026001600160a01b031663092193ab8260018581548110610efe57fe5b60009182526020909120600491820201546040516001600160e01b031960e086901b168152610f39926001600160a01b0390921691016161fd565b6000604051808303818588803b158015610f5257600080fd5b505af1158015610f66573d6000803e3d6000fd5b50505050505b50600101610e86565b504715610fe3577f6ecc855f9440a9282c90913bbc91619fd44f5ec0b462af28d127b116f130aa4d47604051610fab9190616e48565b60405180910390a1604051611002904780156108fc02916000818181858888f19350505050158015610fe1573d6000803e3d6000fd5b505b6000600355815115610ff957610ff98282613ba8565b6110016001600160a01b031663fc4333cd6040518163ffffffff1660e01b8152600401600060405180830381600087803b15801561103657600080fd5b505af115801561104a573d6000803e3d6000fd5b50506040517fedd8d7296956dd970ab4de3f2fc03be2b0ffc615d20cd4c72c6e44f928630ebf925060009150a150505050505050565b60035481565b61200581565b3361200214610d255760405162461bcd60e51b8152600401610c0f90616e02565b3341146110cc5760405162461bcd60e51b8152600401610c0f90616c50565b60105443116110ed5760405162461bcd60e51b8152600401610c0f9061667e565b3a1561110b5760405162461bcd60e51b8152600401610c0f90616a2e565b60005460ff1661112d5760405162461bcd60e51b8152600401610c0f90616502565b60006110023168056bc75e2d631000008111156111645761115d8168056bc75e2d6310000063ffffffff61439716565b915061116b565b50506113ec565b6040516309a99b4f60e41b815261100290639a99b4f0906111929030908690600401616211565b602060405180830381600087803b1580156111ac57600080fd5b505af11580156111c0573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906111e491906160a8565b9150816111f25750506113ec565b6000805b848110156112205785858281811061120a57fe5b90506020020135820191508060010190506111f6565b508061122e575050506113ec565b6000806000805b898110156113e4578489898381811061124a57fe5b9050602002013588028161125a57fe5b0493508a8a8281811061126957fe5b905060200201602081019061127e9190615e71565b6001600160a01b0381166000908152600460205260409020549093509150811561139a5760006001808403815481106112b357fe5b9060005260206000209060040201905080600201601c9054906101000a900460ff161561132057836001600160a01b03167fb9c75cbbfde137c4281689580799ef5f52144e78858f776a5979b2b212137d85866040516113139190616e48565b60405180910390a2611394565b600354611333908663ffffffff6143d916565b600390815581015461134b908663ffffffff6143d916565b60038201556040516001600160a01b038516907fcb0aad6cf9cd03bdf6137e359f541c42f38b39f007cae8e89e88aa7d8c6617b29061138b908890616e48565b60405180910390a25b506113dc565b826001600160a01b03167fb9c75cbbfde137c4281689580799ef5f52144e78858f776a5979b2b212137d85856040516113d39190616e48565b60405180910390a25b600101611235565b505050505050505b5050436010555050565b600154600090821061140a575060006114c0565b60006001600160a01b03166001838154811061142257fe5b60009182526020909120600490910201546001600160a01b03161480611452575060085415806114525750600a54155b80611461575060085460095410155b806114725750611470826114c5565b155b8061149b57506000600b838154811061148757fe5b906000526020600020906016020160000154115b806114af575060016114ab6129b2565b5111155b156114bc575060006114c0565b5060015b919050565b60015460009082106114d9575060006114c0565b600b54821061151657600182815481106114ef57fe5b9060005260206000209060040201600201601c9054906101000a900460ff161590506114c0565b6001828154811061152357fe5b9060005260206000209060040201600201601c9054906101000a900460ff161580156115705750600b828154811061155757fe5b600091825260209091206001601690920201015460ff16155b92915050565b600b5461163457611585615a1d565b60015460005b8181101561163057600b80546001810182556000919091528351600080516020616f138339815191526016909202918201908155602080860151600080516020616f538339815191528401805460ff191691151591909117905560408601518051879461160c93600080516020616f33833981519152909101920190615a4c565b5060608201516116229060038301906013615ac6565b50505080600101905061158b565b5050505b336110011480611645575033612002145b6116615760405162461bcd60e51b8152600401610c0f90616539565b6001600160a01b0381166000908152600460205260409020548061168557506116d8565b6001810390506000600b828154811061169a57fe5b600091825260209091206001601690920201015460ff1690506116bd83836143fe565b80156116c65750805b15610c31576009805460001901905550505b50565b60015460609081906000805b8281101561172e57600181815481106116fc57fe5b9060005260206000209060040201600201601c9054906101000a900460ff16611726576001909101905b6001016116e7565b5060608160405190808252806020026020018201604052801561175b578160200160208202803683370190505b50905060608260405190808252806020026020018201604052801561179457816020015b606081526020019060019003908161177f5790505b50600b546000945090915084141561190f5760005b8481101561190957600181815481106117be57fe5b9060005260206000209060040201600201601c9054906101000a900460ff1661190157600181815481106117ee57fe5b600091825260209091206004909102015483516001600160a01b039091169084908690811061181957fe5b60200260200101906001600160a01b031690816001600160a01b031681525050600b818154811061184657fe5b600091825260209182902060026016909202018101805460408051601f6000196101006001861615020190931694909404918201859004850284018501905280835291929091908301828280156118de5780601f106118b3576101008083540402835291602001916118de565b820191906000526020600020905b8154815290600101906020018083116118c157829003601f168201915b50505050508285815181106118ef57fe5b60209081029190910101526001909301925b6001016117a9565b506119ab565b60005b848110156119a9576001818154811061192757fe5b9060005260206000209060040201600201601c9054906101000a900460ff166119a1576001818154811061195757fe5b600091825260209091206004909102015483516001600160a01b039091169084908690811061198257fe5b6001600160a01b03909216602092830291909101909101526001909301925b600101611912565b505b909450925050505b9091565b61100181565b60085481565b6102ca81565b6060806000600e549050600080600c54116119e55760156119e9565b600c545b905060c860606119f76129b2565b90506060611a04826147c1565b905083825111611a1c5790955093506119b392505050565b84848351031015611a2e578382510394505b8415611a6e576000834381611a3f57fe5b049050611a5483838389890360008b8b61492f565b611a6c8383838989038a8a038b8c8c8b51030161492f565b505b606084604051908082528060200260200182016040528015611a9a578160200160208202803683370190505b509050606085604051908082528060200260200182016040528015611ad357816020015b6060815260200190600190039081611abe5790505b50905060005b86811015611b5457848181518110611aed57fe5b6020026020010151838281518110611b0157fe5b60200260200101906001600160a01b031690816001600160a01b031681525050838181518110611b2d57fe5b6020026020010151828281518110611b4157fe5b6020908102919091010152600101611ad9565b50909750955050505050509091565b60065481565b61200681565b61200081565b6001600160a01b03811660009081526004602052604081205480611b9d5760009150506114c0565b60001901611baa816114c5565b9392505050565b6001600160a01b03811660009081526004602052604081205480611bd95760009150506114c0565b600180820381548110611be857fe5b906000526020600020906004020160030154915050919050565b60128181548110611c0f57fe5b600091825260209182902001805460408051601f6002600019610100600187161502019094169390930492830185900485028101850190915281815293509091830182828015611ca05780601f10611c7557610100808354040283529160200191611ca0565b820191906000526020600020905b815481529060010190602001808311611c8357829003601f168201915b505050505081565b60105481565b60018181548110611cbb57fe5b600091825260209091206004909102018054600182015460028301546003909301546001600160a01b0392831694509082169291821691600160a01b81046001600160401b031691600160e01b90910460ff169086565b61100581565b61100881565b6103e881565b600c5481565b61200381565b61271081565b3361200014610d255760405162461bcd60e51b8152600401610c0f90616c01565b60025481565b60115481565b60145460ff1681565b600a5481565b600060175460001415611d8757506001611d8c565b506017545b90565b6001600160a01b03811660009081526004602052604081205480611dc55760405162461bcd60e51b8152600401610c0f90616b89565b6000190192915050565b600b54611e8d57611dde615a1d565b60015460005b81811015611e8957600b80546001810182556000919091528351600080516020616f138339815191526016909202918201908155602080860151600080516020616f538339815191528401805460ff1916911515919091179055604086015180518794611e6593600080516020616f33833981519152909101920190615a4c565b506060820151611e7b9060038301906013615ac6565b505050806001019050611de4565b5050505b600854611e9a5760036008555b600a54611ea7576002600a555b6000611eb233611d8f565b9050611ebd816113f6565b611ed95760405162461bcd60e51b8152600401610c0f906169aa565b6116d83382614a86565b61100781565b600381565b61100681565b6040518060a0016040528060788152602001616f736078913981565b60005460ff1681565b61200281565b61300081565b600081565b60005460ff16611f4c5760405162461bcd60e51b8152600401610c0f90616502565b3361100714611f6d5760405162461bcd60e51b8152600401610c0f90616a5c565b611fcd84848080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250506040805180820190915260098152686275726e526174696f60b81b60208201529150614b1e9050565b156120825760208114611ff25760405162461bcd60e51b8152600401610c0f90616362565b604080516020601f840181900481028201810190925282815260009161203091858580838501838280828437600092019190915250614b7792505050565b905061271061205c601854612050600f54856143d990919063ffffffff16565b9063ffffffff6143d916565b111561207a5760405162461bcd60e51b8152600401610c0f90616778565b600655612950565b6120ec84848080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250506040805180820190915260138152726d61784e756d4f664d61696e7461696e696e6760681b60208201529150614b1e9050565b1561218657602081146121115760405162461bcd60e51b8152600401610c0f90616399565b604080516020601f840181900481028201810190925282815260009161214f91858580838501838280828437600092019190915250614b7792505050565b600c549091508061215e575060155b80821061217d5760405162461bcd60e51b8152600401610c0f906166c0565b50600855612950565b6121ef84848080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250506040805180820190915260128152716d61696e7461696e536c6173685363616c6560701b60208201529150614b1e9050565b1561228857602081146122145760405162461bcd60e51b8152600401610c0f90616488565b604080516020601f840181900481028201810190925282815260009161225291858580838501838280828437600092019190915250614b7792505050565b90506000811180156122645750600a81105b6122805760405162461bcd60e51b8152600401610c0f90616ce5565b600a55612950565b6122fc84848080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152505060408051808201909152601981527f6d61784e756d4f66576f726b696e6743616e646964617465730000000000000060208201529150614b1e9050565b1561238b57602081146123215760405162461bcd60e51b8152600401610c0f9061643c565b604080516020601f840181900481028201810190925282815260009161235f91858580838501838280828437600092019190915250614b7792505050565b9050600d548111156123835760405162461bcd60e51b8152600401610c0f90616881565b600e55612950565b6123f484848080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250506040805180820190915260128152716d61784e756d4f6643616e6469646174657360701b60208201529150614b1e9050565b1561247657602081146124195760405162461bcd60e51b8152600401610c0f90616aaa565b604080516020601f840181900481028201810190925282815260009161245791858580838501838280828437600092019190915250614b7792505050565b600d819055600e5490915081101561247057600d54600e555b50612950565b6124da84848080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152505060408051808201909152600d81526c6e756d4f66436162696e65747360981b60208201529150614b1e9050565b156125ff57602081146124ff5760405162461bcd60e51b8152600401610c0f906164cd565b604080516020601f840181900481028201810190925282815260009161253d91858580838501838280828437600092019190915250614b7792505050565b90506000811161255f5760405162461bcd60e51b8152600401610c0f90616636565b60006120026001600160a01b031663c473318f6040518163ffffffff1660e01b815260040160206040518083038186803b15801561259c57600080fd5b505afa1580156125b0573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906125d491906160a8565b9050808211156125f65760405162461bcd60e51b8152600401610c0f906163df565b50600c55612950565b61266b84848080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152505060408051808201909152601581527473797374656d52657761726442617365526174696f60581b60208201529150614b1e9050565b1561271457602081146126905760405162461bcd60e51b8152600401610c0f90616c9d565b604080516020601f84018190048102820181019092528281526000916126ce91858580838501838280828437600092019190915250614b7792505050565b90506127106126ee601854612050600654856143d990919063ffffffff16565b111561270c5760405162461bcd60e51b8152600401610c0f906165a7565b600f55612950565b61278884848080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152505060408051808201909152601881527f73797374656d526577617264416e74694d4556526174696f000000000000000060208201529150614b1e9050565b1561283157602081146127ad5760405162461bcd60e51b8152600401610c0f90616807565b604080516020601f84018190048102820181019092528281526000916127eb91858580838501838280828437600092019190915250614b7792505050565b905061271061280b600f54612050600654856143d990919063ffffffff16565b11156128295760405162461bcd60e51b8152600401610c0f9061691b565b601855612950565b61289284848080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152505060408051808201909152600a8152690e8eae4dc98cadccee8d60b31b60208201529150614b1e9050565b1561293857602081146128b75760405162461bcd60e51b8152600401610c0f9061671d565b604080516020601f84018190048102820181019092528281526000916128f591858580838501838280828437600092019190915250614b7792505050565b905060038110158015612909575060408111155b806129145750806001145b6129305760405162461bcd60e51b8152600401610c0f90616d42565b601755612950565b60405162461bcd60e51b8152600401610c0f90616d92565b7f6cdb0ac70ab7f2e2d035cca5be60d89906f2dede7648ddbd7402189c1eeed17a848484846040516129859493929190616330565b60405180910390a150505050565b60046020526000908152604090205481565b68056bc75e2d6310000081565b6001546060906000805b828110156129e1576129cd816114c5565b156129d9578160010191505b6001016129bc565b50606081604051908082528060200260200182016040528015612a0e578160200160208202803683370190505b5090506000915060005b83811015612a9557612a29816114c5565b15612a8d5760018181548110612a3b57fe5b600091825260209091206004909102015482516001600160a01b0390911690839085908110612a6657fe5b60200260200101906001600160a01b031690816001600160a01b0316815250508260010192505b600101612a18565b509250505090565b601581565b61027181565b600281565b61100281565b60175481565b60138181548110611c0f57fe5b60185481565b6000612ad66129b2565b519050600080600c5411612aeb576015612aef565b600c545b905080821115612afd578091505b81612b0757600191505b5090565b60055481565b61100381565b61200481565b60005460ff1615612b405760405162461bcd60e51b8152600401610c0f90616b1b565b612b48615b28565b6000612b6b6040518060a0016040528060788152602001616f7360789139614b7c565b9150915080612b8c5760405162461bcd60e51b8152600401610c0f90616bc0565b612b94615a1d565b60005b836020015151811015612d9557600b80546001810182556000919091528251600080516020616f138339815191526016909202918201908155602080850151600080516020616f538339815191528401805460ff1916911515919091179055604085015180518694612c1d93600080516020616f33833981519152909101920190615a4c565b506060820151612c339060038301906013615ac6565b50505083604001518181518110612c4657fe5b6020026020010151600b8281548110612c5b57fe5b90600052602060002090601602016002019080519060200190612c7f929190615a4c565b50600184602001518281518110612c9257fe5b60209081029190910181015182546001818101855560009485528385208351600493840290910180546001600160a01b039283166001600160a01b03199182161782558587015182850180549185169183169190911790556040860151600283018054606089015160808a01511515600160e01b0260ff60e01b196001600160401b03909216600160a01b0267ffffffffffffffff60a01b199590981692909516919091179290921694909417161790915560a090930151600390930192909255918701518051918501939185908110612d6857fe5b602090810291909101810151516001600160a01b0316825281019190915260400160002055600101612b97565b50506000805460ff191660011790555050565b600d5481565b601354600090815b81811015612eb757612e9f85858080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525050601380549092508591508110612e0757fe5b600091825260209182902001805460408051601f6002600019610100600187161502019094169390930492830185900485028101850190915281815292830182828015612e955780601f10612e6a57610100808354040283529160200191612e95565b820191906000526020600020905b815481529060010190602001808311612e7857829003601f168201915b5050505050614d38565b15612eaf57600192505050611570565b600101612db6565b5060125460005b81811015612f2857612f0f86868080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525050601280549092508591508110612e0757fe5b15612f205760019350505050611570565b600101612ebe565b50600095945050505050565b3361100114612f555760405162461bcd60e51b8152600401610c0f90616db9565b600b5461301357612f64615a1d565b60015460005b8181101561300f57600b80546001810182556000919091528351600080516020616f138339815191526016909202918201908155602080860151600080516020616f538339815191528401805460ff1916911515919091179055604086015180518794612feb93600080516020616f33833981519152909101920190615a4c565b5060608201516130019060038301906013615ac6565b505050806001019050612f6a565b5050505b600061301e82614d9c565b9050613029816113f6565b15613038576130388282614a86565b5050565b33411461305b5760405162461bcd60e51b8152600401610c0f90616c50565b60005460ff1661307d5760405162461bcd60e51b8152600401610c0f90616502565b6000341161309d5760405162461bcd60e51b8152600401610c0f90616852565b3a156130bb5760405162461bcd60e51b8152600401610c0f90616a2e565b6001600160a01b03811660009081526004602052604090205460145434919060ff166130fb57610271600f556103e86006556014805460ff191660011790555b600f54601754600110801561311257506000601854115b1561313757600160175403601754438161312857fe5b06601854028161313457fe5b04015b6000831180156131475750600081115b156131f4576000613170612710613164348563ffffffff614f1f16565b9063ffffffff614f5916565b905080156131f2576040516110029082156108fc029083906000818181858888f193505050501580156131a7573d6000803e3d6000fd5b507f6ecc855f9440a9282c90913bbc91619fd44f5ec0b462af28d127b116f130aa4d816040516131d79190616e48565b60405180910390a16131ef848263ffffffff61439716565b93505b505b60008311801561320657506000600654115b156132ac57600061322861271061316460065434614f1f90919063ffffffff16565b905080156132aa5760405161dead9082156108fc029083906000818181858888f1935050505015801561325f573d6000803e3d6000fd5b507f627059660ea01c4733a328effb2294d2f86905bf806da763a89cee254de8bee58160405161328f9190616e48565b60405180910390a16132a7848263ffffffff61439716565b93505b505b81156133aa5760006001808403815481106132c357fe5b9060005260206000209060040201905080600201601c9054906101000a900460ff161561333057846001600160a01b03167ff177e5d6c5764d79c32883ed824111d9b13f5668cf6ab1cc12dd36791dd955b4856040516133239190616e48565b60405180910390a26133a4565b600354613343908563ffffffff6143d916565b600390815581015461335b908563ffffffff6143d916565b60038201556040516001600160a01b038616907f93a090ecc682c002995fad3c85b30c5651d7fd29b0be5da9d784a3302aedc0559061339b908790616e48565b60405180910390a25b506133ec565b836001600160a01b03167ff177e5d6c5764d79c32883ed824111d9b13f5668cf6ab1cc12dd36791dd955b4846040516133e39190616e48565b60405180910390a25b50505050565b600e5481565b61100081565b61dead81565b600b818154811061341157fe5b6000918252602091829020601691909102018054600180830154600280850180546040805161010096831615969096026000190190911692909204601f810188900488028501880190925281845293965060ff909116949192918301828280156134bc5780601f10613491576101008083540402835291602001916134bc565b820191906000526020600020905b81548152906001019060200180831161349f57829003601f168201915b5050505050905083565b61100481565b6000600a54600014806134dd575082155b806134e85750600954155b156134f5575060006136b6565b60096000815460019003919050819055506000613540600a5461316486613164600b8a8154811061352257fe5b6000918252602090912060169091020154439063ffffffff61439716565b90506000600b868154811061355157fe5b906000526020600020906016020160010160006101000a81548160ff0219169083151502179055506000806110016001600160a01b0316638256ace66040518163ffffffff1660e01b8152600401604080518083038186803b1580156135b657600080fd5b505afa1580156135ca573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906135ee91906160c0565b915091506000935080831061366c5761360788886143fe565b506040516328aa02b160e01b8152611001906328aa02b190613631908b9087908a9060040161626c565b600060405180830381600087803b15801561364b57600080fd5b505af115801561365f573d6000803e3d6000fd5b505050506001935061367e565b81831061367e5761367c88614d9c565b505b6040516001600160a01b038916907fb9d38178dc641ff1817967a63c9078cbcd955a9f1fcd75e0e3636de615d44d3b90600090a25050505b949350505050565b6060806000808080806136cf612acc565b6001549091505b801561390157600181039250600b83815481106136ef57fe5b600091825260209091206001601690920201015460ff1661370f576138f8565b6001838154811061371c57fe5b600091825260208220600490910201546001600160a01b03169550613746908690859085906134cc565b935083613752576138f8565b60405163436aa28360e11b81526000908190612002906386d545069061377c908a906004016161fd565b60206040518083038186803b15801561379457600080fd5b505afa1580156137a8573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906137cc9190615e8d565b90506001600160a01b03811615613855576040516302ceee9160e11b81526120029063059ddd22906138029084906004016161fd565b60206040518083038186803b15801561381a57600080fd5b505afa15801561382e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906138529190615e8d565b91505b60005b8c518110156138f457876001600160a01b03168d828151811061387757fe5b6020026020010151600001516001600160a01b031614806138c05750826001600160a01b03168d82815181106138a957fe5b6020026020010151600001516001600160a01b0316145b156138ec5760018d82815181106138d357fe5b60209081029190910101519015156080909101526138f4565b600101613858565b5050505b600019016136d6565b5060005b895181101561396e5789818151811061391a57fe5b6020026020010151608001518061395a575060006001600160a01b03168a828151811061394357fe5b6020026020010151600001516001600160a01b0316145b15613966578560010195505b600101613905565b5088518510613a565760408051600180825281830190925290816020015b613994615af3565b81526020019060019003908161398c575050604080516001808252818301909252919850602082015b60608152602001906001900390816139bd579050509550886000815181106139e157fe5b6020026020010151876000815181106139f657fe5b602002602001018190525087600081518110613a0e57fe5b602002602001015186600081518110613a2357fe5b6020026020010181905250600087600081518110613a3d57fe5b6020908102919091010151901515608090910152613b9b565b84895103604051908082528060200260200182016040528015613a9357816020015b613a80615af3565b815260200190600190039081613a785790505b50965084895103604051908082528060200260200182016040528015613acd57816020015b6060815260200190600190039081613ab85790505b5095506000915060005b8951811015613b9957898181518110613aec57fe5b602002602001015160800151158015613b2f575060006001600160a01b03168a8281518110613b1757fe5b6020026020010151600001516001600160a01b031614155b15613b9157898181518110613b4057fe5b6020026020010151888481518110613b5457fe5b6020026020010181905250888181518110613b6b57fe5b6020026020010151878481518110613b7f57fe5b60200260200101819052508260010192505b600101613ad7565b505b50505050505b9250929050565b600154825160005b82811015613cc5576001613bc2615af3565b60018381548110613bcf57fe5b600091825260208083206040805160c08101825260049490940290910180546001600160a01b0390811685526001820154811693850193909352600281015492831691840191909152600160a01b82046001600160401b03166060840152600160e01b90910460ff16151560808301526003015460a082015291505b84811015613c9957878181518110613c5f57fe5b6020026020010151600001516001600160a01b031682600001516001600160a01b03161415613c915760009250613c99565b600101613c4b565b508115613cbb5780516001600160a01b03166000908152600460205260408120555b5050600101613bb0565b5080821115613d8457805b82811015613d82576001805480613ce357fe5b60008281526020812060046000199093019283020180546001600160a01b0319908116825560018201805490911690556002810180546001600160e81b0319169055600301559055600b805480613d3657fe5b60008281526020812060166000199093019283020181815560018101805460ff1916905590613d686002830182615b4c565b613d76600383016000615b90565b50509055600101613cd0565b505b6000818310613d935781613d95565b825b905060005b8181101561413957613e47868281518110613db157fe5b602002602001015160018381548110613dc657fe5b60009182526020918290206040805160c08101825260049390930290910180546001600160a01b0390811684526001820154811694840194909452600281015493841691830191909152600160a01b83046001600160401b03166060830152600160e01b90920460ff161515608082015260039091015460a0820152614f9b565b613ffb578060010160046000888481518110613e5f57fe5b6020026020010151600001516001600160a01b03166001600160a01b0316815260200190815260200160002081905550858181518110613e9b57fe5b602002602001015160018281548110613eb057fe5b6000918252602091829020835160049092020180546001600160a01b039283166001600160a01b0319918216178255928401516001820180549184169185169190911790556040840151600282018054606087015160808801511515600160e01b0260ff60e01b196001600160401b03909216600160a01b0267ffffffffffffffff60a01b1995909716929097169190911792909216939093171692909217905560a0909101516003909101558451859082908110613f6b57fe5b6020026020010151600b8281548110613f8057fe5b90600052602060002090601602016002019080519060200190613fa4929190615a4c565b506000600b8281548110613fb457fe5b60009182526020822060169190910201600101805460ff191692151592909217909155600b805483908110613fe557fe5b6000918252602090912060169091020155614131565b85818151811061400757fe5b6020026020010151606001516001828154811061402057fe5b906000526020600020906004020160020160146101000a8154816001600160401b0302191690836001600160401b031602179055506140e685828151811061406457fe5b6020026020010151600b838154811061407957fe5b600091825260209182902060026016909202018101805460408051601f600019610100600186161502019093169490940491820185900485028401850190528083529192909190830182828015612e955780601f10612e6a57610100808354040283529160200191612e95565b614131578481815181106140f657fe5b6020026020010151600b828154811061410b57fe5b9060005260206000209060160201600201908051906020019061412f929190615a4c565b505b600101613d9a565b50828211156143115761414a615a1d565b835b8381101561430e5785818151811061416057fe5b60200260200101518260400181905250600187828151811061417e57fe5b6020908102919091018101518254600181810185556000948552838520835160049093020180546001600160a01b039384166001600160a01b0319918216178255848601518284018054918616918316919091179055604080860151600284018054606089015160808a01511515600160e01b0260ff60e01b196001600160401b03909216600160a01b0267ffffffffffffffff60a01b1995909a1692909616919091179290921696909617169190911790935560a090930151600390930192909255600b8054928301815590935284516016909102600080516020616f13833981519152810191825585830151600080516020616f538339815191528201805491151560ff19909216919091179055928501518051869492936142b493600080516020616f3383398151915201920190615a4c565b5060608201516142ca9060038301906013615ac6565b50505080600101600460008984815181106142e157fe5b602090810291909101810151516001600160a01b031682528101919091526040016000205560010161414c565b50505b614319614ff7565b6143216151d9565b6000600981905560015493505b8381101561438f576000600b828154811061434557fe5b60009182526020822060169190910201600101805460ff191692151592909217909155600b80548390811061437657fe5b600091825260209091206016909102015560010161432e565b505050505050565b6000611baa83836040518060400160405280601e81526020017f536166654d6174683a207375627472616374696f6e206f766572666c6f7700008152506153c7565b600082820183811015611baa5760405162461bcd60e51b8152600401610c0f90616570565b6000806001838154811061440e57fe5b906000526020600020906004020160030154905060006001808054905003905060016144386129b2565b511161446d5760006001858154811061444d57fe5b906000526020600020906004020160030181905550600092505050611570565b846001600160a01b03167f3b6f9ef90462b512a1293ecec018670bf7b7f1876fb727590a8a6d7643130a70836040516144a69190616e48565b60405180910390a26001600160a01b038516600090815260046020526040812055835b6001546000190181101561469357600181600101815481106144e757fe5b90600052602060002090600402016001828154811061450257fe5b60009182526020909120825460049092020180546001600160a01b03199081166001600160a01b0393841617825560018085015481840180548416918616919091179055600280860180549185018054909416919095161780835584546001600160401b03600160a01b91829004160267ffffffffffffffff60a01b1990911617808355935460ff600160e01b918290041615150260ff60e01b19909416939093179055600392830154920191909155600b8054909183019081106145c357fe5b9060005260206000209060160201600b82815481106145de57fe5b600091825260209091208254601690920201908155600180830154818301805460ff909216151560ff1990921691909117905560028084018054614635938386019390821615610100026000190190911604615b9f565b5061464860038281019084016013615c14565b5090505080600101600460006001848154811061466157fe5b600091825260208083206004909202909101546001600160a01b031683528201929092526040019020556001016144c9565b50600180548061469f57fe5b60008281526020812060046000199093019283020180546001600160a01b0319908116825560018201805490911690556002810180546001600160e81b0319169055600301559055600b8054806146f257fe5b60008281526020812060166000199093019283020181815560018101805460ff19169055906147246002830182615b4c565b614732600383016000615b90565b50509055600081838161474157fe5b04905080156147b55760015460005b818110156147b257614789836001838154811061476957fe5b9060005260206000209060040201600301546143d990919063ffffffff16565b6001828154811061479657fe5b6000918252602090912060036004909202010155600101614750565b50505b50600195945050505050565b60015481516040805182815260208084028201019091526060929190839082801561480057816020015b60608152602001906001900390816147eb5790505b50600b5490915083146148175792506114c0915050565b60005b8281101561492657600b60016004600089858151811061483657fe5b60200260200101516001600160a01b03166001600160a01b0316815260200190815260200160002054038154811061486a57fe5b600091825260209182902060026016909202018101805460408051601f6000196101006001861615020190931694909404918201859004850284018501905280835291929091908301828280156149025780601f106148d757610100808354040283529160200191614902565b820191906000526020600020905b8154815290600101906020018083116148e557829003601f168201915b505050505082828151811061491357fe5b602090810291909101015260010161481a565b50949350505050565b60005b82811015614a7c57600082878388016040516020016149529291906161ef565b6040516020818303038152906040528051906020012060001c8161497257fe5b06905080850182870114614a73576000898388018151811061499057fe5b60200260200101519050606089848901815181106149aa57fe5b602002602001015190508a838801815181106149c257fe5b60200260200101518b858a01815181106149d857fe5b60200260200101906001600160a01b031690816001600160a01b031681525050818b84890181518110614a0757fe5b60200260200101906001600160a01b031690816001600160a01b0316815250508983880181518110614a3557fe5b60200260200101518a858a0181518110614a4b57fe5b6020026020010181905250808a84890181518110614a6557fe5b602002602001018190525050505b50600101614932565b5050505050505050565b600980546001908101909155600b805483908110614aa057fe5b906000526020600020906016020160010160006101000a81548160ff02191690831515021790555043600b8281548110614ad657fe5b600091825260208220601690910201919091556040516001600160a01b038416917ff62981a567ec3cec866c6fa93c55bcdf841d6292d18b8d522ececa769375d82d91a25050565b600081604051602001614b3191906161d3565b6040516020818303038152906040528051906020012083604051602001614b5891906161d3565b6040516020818303038152906040528051906020012014905092915050565b015190565b614b84615b28565b6000614b8e615b28565b614b96615c3e565b614ba7614ba2866153f3565b615418565b90506000805b614bb683615462565b15614d2a5780614bdb57614bd1614bcc84615483565b6154d1565b60ff168452614d22565b8060011415614d1d576060614bf7614bf285615483565b615551565b90508051604051908082528060200260200182016040528015614c3457816020015b614c21615af3565b815260200190600190039081614c195790505b5085602001819052508051604051908082528060200260200182016040528015614c7257816020015b6060815260200190600190039081614c5d5790505b50604086015260005b8151811015614d1257614c8c615af3565b60606000614cac858581518110614c9f57fe5b6020026020010151615622565b92509250925080614ccc578860009a509a50505050505050505050614d33565b8289602001518581518110614cdd57fe5b60200260200101819052508189604001518581518110614cf957fe5b6020026020010181905250505050806001019050614c7b565b506001925050614d22565b614d2a565b600101614bad565b50919350909150505b915091565b815181516000916001918114808314614d545760009250614d92565b600160208701838101602088015b600284838510011415614d8d578051835114614d815760009650600093505b60209283019201614d62565b505050505b5090949350505050565b6001600160a01b03811660009081526004602052604081205480614dc5575060001990506114c0565b600181039050600060018281548110614dda57fe5b9060005260206000209060040201600301549050600060018381548110614dfd57fe5b6000918252602090912060036004909202010155600154604051600019909101906001600160a01b038616907f8cd4e147d8af98a9e3b6724021b8bf6aed2e5dac71c38f2dce8161b82585b25d90614e56908590616e48565b60405180910390a280614e6e578293505050506114c0565b6000818381614e7957fe5b0490508015614f155760005b84811015614ec757614e9e826001838154811061476957fe5b60018281548110614eab57fe5b6000918252602090912060036004909202010155600101614e85565b50600180549085015b81811015614f1257614ee9836001838154811061476957fe5b60018281548110614ef657fe5b6000918252602090912060036004909202010155600101614ed0565b50505b5091949350505050565b600082614f2e57506000611570565b82820282848281614f3b57fe5b0414611baa5760405162461bcd60e51b8152600401610c0f906169ed565b6000611baa83836040518060400160405280601a81526020017f536166654d6174683a206469766973696f6e206279207a65726f00000000000081525061573c565b805182516000916001600160a01b039182169116148015614fd5575081602001516001600160a01b031683602001516001600160a01b0316145b8015611baa5750506040908101519101516001600160a01b0390811691161490565b6012546013548082111561504257805b8281101561504057601280548061501a57fe5b6001900381819060005260206000200160006150369190615b4c565b9055600101615007565b505b60008183106150515781615053565b825b905060005b8181101561516b576151106012828154811061507057fe5b600091825260209182902001805460408051601f60026000196101006001871615020190941693909304928301859004850281018501909152818152928301828280156150fe5780601f106150d3576101008083540402835291602001916150fe565b820191906000526020600020905b8154815290600101906020018083116150e157829003601f168201915b505050505060138381548110612e0757fe5b615163576013818154811061512157fe5b906000526020600020016012828154811061513857fe5b906000526020600020019080546001816001161561010002031660029004615161929190615b9f565b505b600101615058565b5082821115610c3157825b828110156133ec5760126013828154811061518d57fe5b60009182526020808320845460018181018755958552919093209290910180546151d0949390920192909160026101009282161592909202600019011604615b9f565b50600101615176565b601354600b548082111561522457805b828110156152225760138054806151fc57fe5b6001900381819060005260206000200160006152189190615b4c565b90556001016151e9565b505b60008183106152335781615235565b825b905060005b81811015615354576152f26013828154811061525257fe5b600091825260209182902001805460408051601f60026000196101006001871615020190941693909304928301859004850281018501909152818152928301828280156152e05780601f106152b5576101008083540402835291602001916152e0565b820191906000526020600020905b8154815290600101906020018083116152c357829003601f168201915b5050505050600b838154811061407957fe5b61534c57600b818154811061530357fe5b90600052602060002090601602016002016013828154811061532157fe5b90600052602060002001908054600181600116156101000203166002900461534a929190615b9f565b505b60010161523a565b5082821115610c3157825b828110156133ec576013600b828154811061537657fe5b6000918252602080832084546001808201875595855291909320601692909202909201600290810180546153be95939094019390926000199082161561010002011604615b9f565b5060010161535f565b600081848411156153eb5760405162461bcd60e51b8152600401610c0f919061631d565b505050900390565b6153fb615c5e565b506040805180820190915281518152602082810190820152919050565b615420615c3e565b61542982615773565b61543257600080fd5b600061544183602001516157ad565b60208085015160408051808201909152868152920190820152915050919050565b600061546c615c5e565b505080518051602091820151919092015191011190565b61548b615c5e565b61549482615462565b61549d57600080fd5b602082015160006154ad82615810565b80830160209586015260408051808201909152908152938401919091525090919050565b8051600090158015906154e657508151602110155b6154ef57600080fd5b60006154fe83602001516157ad565b905080836000015110156155245760405162461bcd60e51b8152600401610c0f90616b52565b82516020808501518301805192849003929183101561492657506020919091036101000a90049392505050565b606061555c82615773565b61556557600080fd5b6000615570836158f1565b90506060816040519080825280602002602001820160405280156155ae57816020015b61559b615c5e565b8152602001906001900390816155935790505b50905060006155c085602001516157ad565b60208601510190506000805b84811015615617576155dd83615810565b915060405180604001604052808381526020018481525084828151811061560057fe5b6020908102919091010152918101916001016155cc565b509195945050505050565b61562a615af3565b60606000615636615af3565b6060615640615c3e565b61564987615418565b90506000805b61565883615462565b1561572d57806156835761567361566e84615483565b61594d565b6001600160a01b03168552615725565b80600114156156ab5761569861566e84615483565b6001600160a01b03166020860152615725565b80600214156156d3576156c061566e84615483565b6001600160a01b03166040860152615725565b80600314156156ff576156e8614bcc84615483565b6001600160401b0316606086015260019150615725565b80600414156157205761571961571484615483565b615967565b9350615725565b61572d565b60010161564f565b50929791965091945092505050565b6000818361575d5760405162461bcd60e51b8152600401610c0f919061631d565b50600083858161576957fe5b0495945050505050565b8051600090615784575060006114c0565b6020820151805160001a9060c08210156157a3576000925050506114c0565b5060019392505050565b8051600090811a60808110156157c75760009150506114c0565b60b88110806157e2575060c081108015906157e2575060f881105b156157f15760019150506114c0565b60c08110156158055760b5190190506114c0565b60f5190190506114c0565b80516000908190811a608081101561582b57600191506158ea565b60b881101561584057607e19810191506158ea565b60c081101561589157600060b78203600186019550806020036101000a86510491506001810182019350508083101561588b5760405162461bcd60e51b8152600401610c0f906168f0565b506158ea565b60f88110156158a65760be19810191506158ea565b600060f78203600186019550806020036101000a8651049150600181018201935050808310156158e85760405162461bcd60e51b8152600401610c0f906168f0565b505b5092915050565b8051600090615902575060006114c0565b6000809050600061591684602001516157ad565b602085015185519181019250015b808210156159445761593582615810565b82019150826001019250615924565b50909392505050565b805160009060151461595e57600080fd5b611570826154d1565b805160609061597557600080fd5b600061598483602001516157ad565b83516040805191839003808352601f19601f82011683016020019091529192506060908280156159bb576020820181803683370190505b5090506000816020019050614926848760200151018285806159dc57610c31565b5b602081106159fc578251825260209283019290910190601f19016159dd565b915181516020939093036101000a6000190180199091169216919091179052565b60405180608001604052806000815260200160001515815260200160608152602001615a47615c78565b905290565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f10615a8d57805160ff1916838001178555615aba565b82800160010185558215615aba579182015b82811115615aba578251825591602001919060010190615a9f565b50612b07929150615c97565b8260138101928215615aba5791602002820182811115615aba578251825591602001919060010190615a9f565b6040805160c081018252600080825260208201819052918101829052606081018290526080810182905260a081019190915290565b6040518060600160405280600060ff16815260200160608152602001606081525090565b50805460018160011615610100020316600290046000825580601f10615b7257506116d8565b601f0160209004906000526020600020908101906116d89190615c97565b506116d8906013810190615c97565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f10615bd85780548555615aba565b82800160010185558215615aba57600052602060002091601f016020900482015b82811115615aba578254825591600101919060010190615bf9565b8260138101928215615aba5791820182811115615aba578254825591600101919060010190615bf9565b6040518060400160405280615c51615c5e565b8152602001600081525090565b604051806040016040528060008152602001600081525090565b6040518061026001604052806013906020820280368337509192915050565b611d8c91905b80821115612b075760008155600101615c9d565b803561157081616efd565b60008083601f840112615ccd578182fd5b5081356001600160401b03811115615ce3578182fd5b6020830191508360208083028501011115613ba157600080fd5b6000601f8381840112615d0e578182fd5b8235615d21615d1c82616eb2565b616e8c565b818152925060208084019085810160005b84811015615db3578135880189603f820112615d4d57600080fd5b838101356001600160401b03811115615d6557600080fd5b615d76818901601f19168601616e8c565b81815260408c81848601011115615d8c57600080fd5b82818501888401375060009181018601919091528552509282019290820190600101615d32565b50505050505092915050565b600082601f830112615dcf578081fd5b8135615ddd615d1c82616eb2565b818152915060208083019084810181840286018201871015615dfe57600080fd5b6000805b85811015615db35782356001600160401b0381168114615e20578283fd5b85529383019391830191600101615e02565b60008083601f840112615e43578182fd5b5081356001600160401b03811115615e59578182fd5b602083019150836020828501011115613ba157600080fd5b600060208284031215615e82578081fd5b8135611baa81616efd565b600060208284031215615e9e578081fd5b8151611baa81616efd565b60008060008060408587031215615ebe578283fd5b84356001600160401b0380821115615ed4578485fd5b615ee088838901615cbc565b90965094506020870135915080821115615ef8578384fd5b50615f0587828801615cbc565b95989497509550505050565b600080600060608486031215615f25578283fd5b83356001600160401b0380821115615f3b578485fd5b81860187601f820112615f4c578586fd5b80359250615f5c615d1c84616eb2565b80848252602080830192508084018b828389028701011115615f7c57898afd5b8994505b86851015615fa657615f928c82615cb1565b845260019490940193928101928101615f80565b509097508801359350505080821115615fbd578384fd5b615fc987838801615dbf565b93506040860135915080821115615fde578283fd5b50615feb86828701615cfd565b9150509250925092565b60008060208385031215616007578182fd5b82356001600160401b0381111561601c578283fd5b61602885828601615e32565b90969095509350505050565b60008060008060408587031215616049578384fd5b84356001600160401b038082111561605f578586fd5b61606b88838901615e32565b90965094506020870135915080821115616083578384fd5b50615f0587828801615e32565b6000602082840312156160a1578081fd5b5035919050565b6000602082840312156160b9578081fd5b5051919050565b600080604083850312156160d2578182fd5b505080516020909101519092909150565b6000806000604084860312156160f7578081fd5b833560ff81168114616107578182fd5b925060208401356001600160401b03811115616121578182fd5b61612d86828701615e32565b9497909650939450505050565b6000815180845260208085019450808401835b838110156161725781516001600160a01b03168752958201959082019060010161614d565b509495945050505050565b60008284528282602086013780602084860101526020601f19601f85011685010190509392505050565b600081518084526161bf816020860160208601616ed1565b601f01601f19169290920160200192915050565b600082516161e5818460208701616ed1565b9190910192915050565b918252602082015260400190565b6001600160a01b0391909116815260200190565b6001600160a01b03929092168252602082015260400190565b6001600160a01b03968716815294861660208601529290941660408401526001600160401b03166060830152911515608082015260a081019190915260c00190565b6001600160a01b0393909316835260208301919091521515604082015260600190565b600060208252611baa602083018461613a565b6000604082526162b5604083018561613a565b602083820381850152818551808452828401915082838202850101838801865b8381101561630357601f198784030185526162f18383516161a7565b948601949250908501906001016162d5565b50909998505050505050505050565b901515815260200190565b600060208252611baa60208301846161a7565b60006040825261634460408301868861617d565b828103602084015261635781858761617d565b979650505050505050565b6020808252601c908201527f6c656e677468206f66206275726e526174696f206d69736d6174636800000000604082015260600190565b60208082526026908201527f6c656e677468206f66206d61784e756d4f664d61696e7461696e696e67206d696040820152650e6dac2e8c6d60d31b606082015260800190565b60208082526038908201527f746865206e756d4f66436162696e657473206d757374206265206c657373207460408201527f68616e206d6178456c656374656456616c696461746f72730000000000000000606082015260800190565b6020808252602c908201527f6c656e677468206f66206d61784e756d4f66576f726b696e6743616e6469646160408201526b0e8cae640dad2e6dac2e8c6d60a31b606082015260800190565b60208082526025908201527f6c656e677468206f66206d61696e7461696e536c6173685363616c65206d69736040820152640dac2e8c6d60db1b606082015260800190565b6020808252818101527f6c656e677468206f66206e756d4f66436162696e657473206d69736d61746368604082015260600190565b60208082526019908201527f74686520636f6e7472616374206e6f7420696e69742079657400000000000000604082015260600190565b6020808252601f908201527f6f6e6c7920736c617368206f72207374616b6548756220636f6e747261637400604082015260600190565b6020808252601b908201527f536166654d6174683a206164646974696f6e206f766572666c6f770000000000604082015260600190565b60208082526063908201527f7468652073797374656d52657761726442617365526174696f20706c7573206260408201527f75726e526174696f20616e642073797374656d526577617264416e74694d455660608201527f526174696f206d757374206265206e6f2067726561746572207468616e20313060808201526203030360ec1b60a082015260c00190565b60208082526028908201527f746865206e756d4f66436162696e657473206d75737420626520677265617465604082015267072207468616e20360c41b606082015260800190565b60208082526022908201527f63616e206e6f7420646f207468697320747769636520696e206f6e6520626c6f604082015261636b60f01b606082015260800190565b60208082526037908201527f746865206d61784e756d4f664d61696e7461696e696e67206d7573742062652060408201527f6c657373207468616e206e756d4f66436162696e657473000000000000000000606082015260800190565b6020808252601d908201527f6c656e677468206f66207475726e4c656e677468206d69736d61746368000000604082015260600190565b6020808252600a908201526919195c1c9958d85d195960b21b604082015260600190565b60208082526063908201527f746865206275726e526174696f20706c75732073797374656d5265776172644260408201527f617365526174696f20616e642073797374656d526577617264416e74694d455660608201527f526174696f206d757374206265206e6f2067726561746572207468616e20313060808201526203030360ec1b60a082015260c00190565b6020808252602b908201527f6c656e677468206f662073797374656d526577617264416e74694d455652617460408201526a0d2de40dad2e6dac2e8c6d60ab1b606082015260800190565b6020808252601590820152746465706f7369742076616c7565206973207a65726f60581b604082015260600190565b60208082526049908201527f746865206d61784e756d4f66576f726b696e6743616e64696461746573206d7560408201527f7374206265206e6f742067726561746572207468616e206d61784e756d4f6643606082015268616e6469646174657360b81b608082015260a00190565b6020808252601190820152706164646974696f6e206f766572666c6f7760781b604082015260600190565b60208082526063908201527f7468652073797374656d526577617264416e74694d4556526174696f20706c7560408201527f73206275726e526174696f20616e642073797374656d5265776172644261736560608201527f526174696f206d757374206265206e6f2067726561746572207468616e20313060808201526203030360ec1b60a082015260c00190565b60208082526023908201527f63616e206e6f7420656e7465722054656d706f72617279204d61696e74656e616040820152626e636560e81b606082015260800190565b60208082526021908201527f536166654d6174683a206d756c7469706c69636174696f6e206f766572666c6f6040820152607760f81b606082015260800190565b6020808252601490820152736761737072696365206973206e6f74207a65726f60601b604082015260600190565b6020808252602e908201527f746865206d6573736167652073656e646572206d75737420626520676f76657260408201526d1b985b98d94818dbdb9d1c9858dd60921b606082015260800190565b60208082526025908201527f6c656e677468206f66206d61784e756d4f6643616e64696461746573206d69736040820152640dac2e8c6d60db1b606082015260800190565b6020808252601290820152716e6f7420696e206d61696e74656e616e636560701b604082015260600190565b60208082526019908201527f74686520636f6e747261637420616c726561647920696e697400000000000000604082015260600190565b6020808252601a908201527f6c656e677468206973206c657373207468616e206f6666736574000000000000604082015260600190565b60208082526017908201527f6f6e6c792063757272656e742076616c696461746f7273000000000000000000604082015260600190565b60208082526021908201527f6661696c656420746f20706172736520696e69742076616c696461746f7253656040820152601d60fa1b606082015260800190565b6020808252602f908201527f746865206d6573736167652073656e646572206d7573742062652063726f737360408201526e0818da185a5b8818dbdb9d1c9858dd608a1b606082015260800190565b6020808252602d908201527f746865206d6573736167652073656e646572206d75737420626520746865206260408201526c3637b1b590383937b23ab1b2b960991b606082015260800190565b60208082526028908201527f6c656e677468206f662073797374656d52657761726442617365526174696f206040820152670dad2e6dac2e8c6d60c31b606082015260800190565b6020808252603e908201527f746865206d61696e7461696e536c6173685363616c65206d757374206265206760408201527f726561746572207468616e203020616e64206c657373207468616e2031300000606082015260800190565b60208082526030908201527f746865207475726e4c656e6774682073686f756c6420626520696e205b332c3660408201526f345d206f7220657175616c20746f203160801b606082015260800190565b6020808252600d908201526c756e6b6e6f776e20706172616d60981b604082015260600190565b60208082526029908201527f746865206d6573736167652073656e646572206d75737420626520736c6173686040820152680818dbdb9d1c9858dd60ba1b606082015260800190565b6020808252601f908201527f746865206d73672073656e646572206d757374206265207374616b6548756200604082015260600190565b61ffff91909116815260200190565b90815260200190565b6000848252831515602083015260606040830152616e7260608301846161a7565b95945050505050565b63ffffffff91909116815260200190565b6040518181016001600160401b0381118282101715616eaa57600080fd5b604052919050565b60006001600160401b03821115616ec7578081fd5b5060209081020190565b60005b83811015616eec578181015183820152602001616ed4565b838111156133ec5750506000910152565b6001600160a01b03811681146116d857600080fdfe0175b7a638427703f0dbe7bb9bbf987a2551717b34e79f33b5b1008d1fa01db90175b7a638427703f0dbe7bb9bbf987a2551717b34e79f33b5b1008d1fa01dbb0175b7a638427703f0dbe7bb9bbf987a2551717b34e79f33b5b1008d1fa01dbaf87680f873f871949fb29aac15b9a4b7f17c3385939b007540f4d791949fb29aac15b9a4b7f17c3385939b007540f4d791949fb29aac15b9a4b7f17c3385939b007540f4d79164b085e6972fc98cd3c81d64d40e325acfed44365b97a7567a27939c14dbc7512ddcf54cb1284eb637cfa308ae4e00cb5588a164736f6c6343000604000a \ No newline at end of file diff --git a/core/systemcontracts/lorentz/types.go b/core/systemcontracts/lorentz/types.go new file mode 100644 index 0000000000..4ae56835e7 --- /dev/null +++ b/core/systemcontracts/lorentz/types.go @@ -0,0 +1,21 @@ +package lorentz + +import _ "embed" + +// contract codes for Mainnet upgrade +var ( + //go:embed mainnet/ValidatorContract + MainnetValidatorContract string +) + +// contract codes for Chapel upgrade +var ( + //go:embed chapel/ValidatorContract + ChapelValidatorContract string +) + +// contract codes for Rialto upgrade +var ( + //go:embed rialto/ValidatorContract + RialtoValidatorContract string +) diff --git a/core/systemcontracts/upgrade.go b/core/systemcontracts/upgrade.go index 57de667889..9dc92de03b 100644 --- a/core/systemcontracts/upgrade.go +++ b/core/systemcontracts/upgrade.go @@ -16,6 +16,7 @@ import ( "github.com/ethereum/go-ethereum/core/systemcontracts/gibbs" haberFix "github.com/ethereum/go-ethereum/core/systemcontracts/haber_fix" "github.com/ethereum/go-ethereum/core/systemcontracts/kepler" + "github.com/ethereum/go-ethereum/core/systemcontracts/lorentz" "github.com/ethereum/go-ethereum/core/systemcontracts/luban" "github.com/ethereum/go-ethereum/core/systemcontracts/mirror" "github.com/ethereum/go-ethereum/core/systemcontracts/moran" @@ -86,6 +87,8 @@ var ( bohrUpgrade = make(map[string]*Upgrade) pascalUpgrade = make(map[string]*Upgrade) + + lorentzUpgrade = make(map[string]*Upgrade) ) func init() { @@ -1049,6 +1052,39 @@ func init() { }, }, } + + lorentzUpgrade[mainNet] = &Upgrade{ + UpgradeName: "lorentz", + Configs: []*UpgradeConfig{ + { + ContractAddr: common.HexToAddress(ValidatorContract), + CommitUrl: "https://github.com/bnb-chain/bsc-genesis-contract/commit/44ebc6c17a00bd24db3240141a78091528dcebbb", + Code: lorentz.MainnetValidatorContract, + }, + }, + } + + lorentzUpgrade[chapelNet] = &Upgrade{ + UpgradeName: "lorentz", + Configs: []*UpgradeConfig{ + { + ContractAddr: common.HexToAddress(ValidatorContract), + CommitUrl: "https://github.com/bnb-chain/bsc-genesis-contract/commit/44ebc6c17a00bd24db3240141a78091528dcebbb", + Code: lorentz.ChapelValidatorContract, + }, + }, + } + + lorentzUpgrade[rialtoNet] = &Upgrade{ + UpgradeName: "lorentz", + Configs: []*UpgradeConfig{ + { + ContractAddr: common.HexToAddress(ValidatorContract), + CommitUrl: "https://github.com/bnb-chain/bsc-genesis-contract/commit/44ebc6c17a00bd24db3240141a78091528dcebbb", + Code: lorentz.RialtoValidatorContract, + }, + }, + } } func TryUpdateBuildInSystemContract(config *params.ChainConfig, blockNumber *big.Int, lastBlockTime uint64, blockTime uint64, statedb vm.StateDB, atBlockBegin bool) { @@ -1156,6 +1192,10 @@ func upgradeBuildInSystemContract(config *params.ChainConfig, blockNumber *big.I applySystemContractUpgrade(pascalUpgrade[network], blockNumber, statedb, logger) } + if config.IsOnLorentz(blockNumber, lastBlockTime, blockTime) { + applySystemContractUpgrade(lorentzUpgrade[network], blockNumber, statedb, logger) + } + /* apply other upgrades */ diff --git a/core/txpool/blobpool/blobpool_test.go b/core/txpool/blobpool/blobpool_test.go index 8589e5c01d..a1c4c8d5f5 100644 --- a/core/txpool/blobpool/blobpool_test.go +++ b/core/txpool/blobpool/blobpool_test.go @@ -1067,7 +1067,7 @@ func TestChangingSlotterSize(t *testing.T) { // Write the two safely sized txs to store. note: although the store is // configured for a blob count of 6, it can also support around ~1mb of call - // data - all this to say that we aren't using the the absolute largest shelf + // data - all this to say that we aren't using the absolute largest shelf // available. store.Put(blob1) store.Put(blob2) diff --git a/core/txpool/legacypool/tx_overflowpool.go b/core/txpool/legacypool/tx_overflowpool.go index 7d1c56bd1f..ee6a924e03 100644 --- a/core/txpool/legacypool/tx_overflowpool.go +++ b/core/txpool/legacypool/tx_overflowpool.go @@ -91,7 +91,7 @@ func (tp *TxOverflowPool) Add(tx *types.Transaction) bool { // If the transaction is too big to ever fit (and the pool isn't empty right now), reject it if (txSlots > tp.maxSize) || (txSlots == tp.maxSize && tp.totalSize != 0) { - log.Warn("Transaction too large to fit in OverflowPool", "transaction", tx.Hash().String(), "requiredSlots", txSlots, "maxSlots", tp.maxSize) + log.Debug("Transaction too large to fit in OverflowPool", "transaction", tx.Hash().String(), "requiredSlots", txSlots, "maxSlots", tp.maxSize) return false } diff --git a/core/txpool/locals/tx_tracker.go b/core/txpool/locals/tx_tracker.go index a24fcb1f4e..0113646669 100644 --- a/core/txpool/locals/tx_tracker.go +++ b/core/txpool/locals/tx_tracker.go @@ -18,6 +18,7 @@ package locals import ( + "slices" "sync" "time" @@ -28,7 +29,6 @@ import ( "github.com/ethereum/go-ethereum/log" "github.com/ethereum/go-ethereum/metrics" "github.com/ethereum/go-ethereum/params" - "golang.org/x/exp/slices" ) var ( diff --git a/core/types/bid.go b/core/types/bid.go index d2b9a073f7..b457c44caf 100644 --- a/core/types/bid.go +++ b/core/types/bid.go @@ -64,7 +64,7 @@ func (b *BidArgs) ToBid(builder common.Address, signer Signer) (*Bid, error) { ParentHash: b.RawBid.ParentHash, Txs: txs, UnRevertible: unRevertibleHashes, - GasUsed: b.RawBid.GasUsed + b.PayBidTxGasUsed, + GasUsed: b.RawBid.GasUsed, GasFee: b.RawBid.GasFee, BuilderFee: b.RawBid.BuilderFee, rawBid: *b.RawBid, @@ -172,10 +172,19 @@ type Bid struct { GasUsed uint64 GasFee *big.Int BuilderFee *big.Int + committed bool // whether the bid has been committed to simulate or not rawBid RawBid } +func (b *Bid) Commit() { + b.committed = true +} + +func (b *Bid) IsCommitted() bool { + return b.committed +} + // Hash returns the bid hash. func (b *Bid) Hash() common.Hash { return b.rawBid.Hash() @@ -192,6 +201,7 @@ type BidIssue struct { type MevParams struct { ValidatorCommission uint64 // 100 means 1% BidSimulationLeftOver time.Duration + NoInterruptLeftOver time.Duration GasCeil uint64 GasPrice *big.Int // Minimum avg gas price for bid block BuilderFeeCeil *big.Int diff --git a/core/types/block.go b/core/types/block.go index af8027fd8b..f359850a0a 100644 --- a/core/types/block.go +++ b/core/types/block.go @@ -30,6 +30,8 @@ import ( "golang.org/x/crypto/sha3" + "github.com/holiman/uint256" + "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/common/hexutil" "github.com/ethereum/go-ethereum/rlp" @@ -156,6 +158,20 @@ func (h *Header) Hash() common.Hash { return rlpHash(h) } +// SetMilliseconds can be called once millisecond representation supported +func (h *Header) SetMilliseconds(milliseconds uint64) { + h.MixDigest = common.Hash(uint256.NewInt(milliseconds % 1000).Bytes32()) +} + +// Ensure Milliseconds is less than 1000 when verifying the block header +func (h *Header) MilliTimestamp() uint64 { + milliseconds := uint64(0) + if h.MixDigest != (common.Hash{}) { + milliseconds = uint256.NewInt(0).SetBytes32(h.MixDigest[:]).Uint64() + } + return h.Time*1000 + milliseconds +} + var headerSize = common.StorageSize(reflect.TypeOf(Header{}).Size()) // Size returns the approximate memory used by all internal contents. It is used diff --git a/core/types/tx_setcode.go b/core/types/tx_setcode.go index 894bac10a3..01e4ea6ac7 100644 --- a/core/types/tx_setcode.go +++ b/core/types/tx_setcode.go @@ -113,7 +113,7 @@ func (a *SetCodeAuthorization) sigHash() common.Hash { }) } -// Authority recovers the the authorizing account of an authorization. +// Authority recovers the authorizing account of an authorization. func (a *SetCodeAuthorization) Authority() (common.Address, error) { sighash := a.sigHash() if !crypto.ValidateSignatureValues(a.V, a.R.ToBig(), a.S.ToBig(), true) { diff --git a/core/vote/vote_manager.go b/core/vote/vote_manager.go index aed7d29b41..841dae4c3f 100644 --- a/core/vote/vote_manager.go +++ b/core/vote/vote_manager.go @@ -148,7 +148,12 @@ func (voteManager *VoteManager) loop() { curHead := cHead.Header if p, ok := voteManager.engine.(*parlia.Parlia); ok { - nextBlockMinedTime := time.Unix(int64((curHead.Time + p.Period())), 0) + // Approximately equal to the block interval of next block, except for the switch block. + blockInterval, err := p.BlockInterval(voteManager.chain, curHead) + if err != nil { + log.Debug("failed to get BlockInterval when voting") + } + nextBlockMinedTime := time.UnixMilli(int64((curHead.MilliTimestamp() + blockInterval))) timeForBroadcast := 50 * time.Millisecond // enough to broadcast a vote if time.Now().Add(timeForBroadcast).After(nextBlockMinedTime) { log.Warn("too late to vote", "Head.Time(Second)", curHead.Time, "Now(Millisecond)", time.Now().UnixMilli()) @@ -198,6 +203,7 @@ func (voteManager *VoteManager) loop() { log.Debug("vote manager produced vote", "votedBlockNumber", voteMessage.Data.TargetNumber, "votedBlockHash", voteMessage.Data.TargetHash, "voteMessageHash", voteMessage.Hash()) voteManager.pool.PutVote(voteMessage) + voteManager.chain.GetBlockStats(curHead.Hash()).SendVoteTime.Store(time.Now().UnixMilli()) votesManagerCounter.Inc(1) } diff --git a/core/vote/vote_pool.go b/core/vote/vote_pool.go index 3b64e2cea3..ee4dace62f 100644 --- a/core/vote/vote_pool.go +++ b/core/vote/vote_pool.go @@ -3,6 +3,7 @@ package vote import ( "container/heap" "sync" + "time" mapset "github.com/deckarep/golang-set/v2" @@ -25,6 +26,8 @@ const ( upperLimitOfVoteBlockNumber = 11 // refer to fetcher.maxUncleDist highestVerifiedBlockChanSize = 10 // highestVerifiedBlockChanSize is the size of channel listening to HighestVerifiedBlockEvent. + + defaultMajorityThreshold = 14 // this is an inaccurate value, mainly used for metric acquisition, ref parlia.verifyVoteAttestation ) var ( @@ -39,9 +42,23 @@ var ( type VoteBox struct { blockNumber uint64 + blockHash common.Hash voteMessages []*types.VoteEnvelope } +func (v *VoteBox) trySetRecvVoteTime(chain *core.BlockChain) { + stats := chain.GetBlockStats(v.blockHash) + if len(v.voteMessages) == 1 { + stats.FirstRecvVoteTime.Store(time.Now().UnixMilli()) + } + if stats.RecvMajorityVoteTime.Load() > 0 { + return + } + if len(v.voteMessages) >= defaultMajorityThreshold { + stats.RecvMajorityVoteTime.Store(time.Now().UnixMilli()) + } +} + type VotePool struct { chain *core.BlockChain mu sync.RWMutex @@ -184,6 +201,7 @@ func (pool *VotePool) putVote(m map[common.Hash]*VoteBox, votesPq *votesPriority heap.Push(votesPq, voteData) voteBox := &VoteBox{ blockNumber: targetNumber, + blockHash: targetHash, voteMessages: make([]*types.VoteEnvelope, 0, maxFutureVoteAmountPerBlock), } m[targetHash] = voteBox @@ -197,6 +215,7 @@ func (pool *VotePool) putVote(m map[common.Hash]*VoteBox, votesPq *votesPriority // Put into corresponding votes map. m[targetHash].voteMessages = append(m[targetHash].voteMessages, vote) + m[targetHash].trySetRecvVoteTime(pool.chain) // Add into received vote to avoid future duplicated vote comes. pool.receivedVotes.Add(voteHash) log.Debug("VoteHash put into votepool is:", "voteHash", voteHash) @@ -269,7 +288,11 @@ func (pool *VotePool) transfer(blockHash common.Hash) { // may len(curVotes[blockHash].voteMessages) extra maxCurVoteAmountPerBlock, but it doesn't matter if _, ok := curVotes[blockHash]; !ok { heap.Push(curPq, voteData) - curVotes[blockHash] = &VoteBox{voteBox.blockNumber, validVotes} + curVotes[blockHash] = &VoteBox{ + blockNumber: voteBox.blockNumber, + blockHash: voteBox.blockHash, + voteMessages: validVotes, + } localCurVotesPqGauge.Update(int64(curPq.Len())) } else { curVotes[blockHash].voteMessages = append(curVotes[blockHash].voteMessages, validVotes...) @@ -338,7 +361,7 @@ func (pool *VotePool) basicVerify(vote *types.VoteEnvelope, headNumber uint64, m // Check duplicate voteMessage firstly. if pool.receivedVotes.Contains(voteHash) { - log.Debug("Vote pool already contained the same vote", "voteHash", voteHash) + log.Trace("Vote pool already contained the same vote", "voteHash", voteHash) return false } diff --git a/eth/backend.go b/eth/backend.go index 8214984b59..60776152a4 100644 --- a/eth/backend.go +++ b/eth/backend.go @@ -26,6 +26,8 @@ import ( "sync" "time" + "github.com/ethereum/go-ethereum/metrics" + "github.com/ethereum/go-ethereum/accounts" "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/common/hexutil" @@ -76,6 +78,17 @@ const ( ChainData = "chaindata" ) +var ( + sendBlockTimer = metrics.NewRegisteredTimer("chain/delay/block/send", nil) + recvBlockTimer = metrics.NewRegisteredTimer("chain/delay/block/recv", nil) + startInsertBlockTimer = metrics.NewRegisteredTimer("chain/delay/block/insert", nil) + startMiningTimer = metrics.NewRegisteredTimer("chain/delay/block/mining", nil) + importedBlockTimer = metrics.NewRegisteredTimer("chain/delay/block/imported", nil) + sendVoteTimer = metrics.NewRegisteredTimer("chain/delay/vote/send", nil) + firstVoteTimer = metrics.NewRegisteredTimer("chain/delay/vote/first", nil) + majorityVoteTimer = metrics.NewRegisteredTimer("chain/delay/vote/majority", nil) +) + // Config contains the configuration options of the ETH protocol. // Deprecated: use ethconfig.Config instead. type Config = ethconfig.Config @@ -117,7 +130,8 @@ type Ethereum struct { shutdownTracker *shutdowncheck.ShutdownTracker // Tracks if and when the node has shutdown ungracefully - votePool *vote.VotePool + votePool *vote.VotePool + stopReportCh chan struct{} } // New creates a new Ethereum object (including the initialisation of the common Ethereum object), @@ -240,6 +254,7 @@ func New(stack *node.Node, config *ethconfig.Config) (*Ethereum, error) { p2pServer: stack.Server(), discmix: enode.NewFairMix(0), shutdownTracker: shutdowncheck.NewShutdownTracker(chainDb), + stopReportCh: make(chan struct{}, 1), } eth.APIBackend = &EthAPIBackend{stack.Config().ExtRPCEnabled(), stack.Config().AllowUnprotectedTxs, eth, nil} @@ -599,6 +614,8 @@ func (s *Ethereum) Start() error { // Start the networking layer s.handler.Start(s.p2pServer.MaxPeers, s.p2pServer.MaxPeersPerIP) + + go s.reportRecentBlocksLoop() return nil } @@ -676,5 +693,80 @@ func (s *Ethereum) Stop() error { s.chainDb.Close() s.eventMux.Stop() + // stop report loop + s.stopReportCh <- struct{}{} return nil } + +func (s *Ethereum) reportRecentBlocksLoop() { + reportCnt := uint64(2) + reportTicker := time.NewTicker(time.Second) + for { + select { + case <-reportTicker.C: + cur := s.blockchain.CurrentBlock() + if cur == nil || cur.Number.Uint64() <= reportCnt { + continue + } + num := cur.Number.Uint64() + stats := s.blockchain.GetBlockStats(cur.Hash()) + sendBlockTime := stats.SendBlockTime.Load() + startImportBlockTime := stats.StartImportBlockTime.Load() + recvNewBlockTime := stats.RecvNewBlockTime.Load() + recvNewBlockHashTime := stats.RecvNewBlockHashTime.Load() + sendVoteTime := stats.SendVoteTime.Load() + firstVoteTime := stats.FirstRecvVoteTime.Load() + recvMajorityTime := stats.RecvMajorityVoteTime.Load() + startMiningTime := stats.StartMiningTime.Load() + importedBlockTime := stats.ImportedBlockTime.Load() + + records := make(map[string]interface{}) + records["BlockNum"] = num + records["SendBlockTime"] = common.FormatMilliTime(sendBlockTime) + records["StartImportBlockTime"] = common.FormatMilliTime(startImportBlockTime) + records["RecvNewBlockTime"] = common.FormatMilliTime(recvNewBlockTime) + records["RecvNewBlockHashTime"] = common.FormatMilliTime(recvNewBlockHashTime) + records["RecvNewBlockFrom"] = stats.RecvNewBlockFrom.Load() + records["RecvNewBlockHashFrom"] = stats.RecvNewBlockHashFrom.Load() + + records["SendVoteTime"] = common.FormatMilliTime(sendVoteTime) + records["FirstRecvVoteTime"] = common.FormatMilliTime(firstVoteTime) + records["RecvMajorityVoteTime"] = common.FormatMilliTime(recvMajorityTime) + + records["StartMiningTime"] = common.FormatMilliTime(startMiningTime) + records["ImportedBlockTime"] = common.FormatMilliTime(importedBlockTime) + + records["Coinbase"] = cur.Coinbase.String() + blockMsTime := int64(cur.MilliTimestamp()) + records["BlockTime"] = common.FormatMilliTime(blockMsTime) + metrics.GetOrRegisterLabel("report-blocks", nil).Mark(records) + + if sendBlockTime > blockMsTime { + sendBlockTimer.Update(time.Duration(sendBlockTime - blockMsTime)) + } + if recvNewBlockTime > blockMsTime { + recvBlockTimer.Update(time.Duration(recvNewBlockTime - blockMsTime)) + } + if startImportBlockTime > blockMsTime { + startInsertBlockTimer.Update(time.Duration(startImportBlockTime - blockMsTime)) + } + if sendVoteTime > blockMsTime { + sendVoteTimer.Update(time.Duration(sendVoteTime - blockMsTime)) + } + if firstVoteTime > blockMsTime { + firstVoteTimer.Update(time.Duration(firstVoteTime - blockMsTime)) + } + if recvMajorityTime > blockMsTime { + majorityVoteTimer.Update(time.Duration(recvMajorityTime - blockMsTime)) + } + if importedBlockTime > blockMsTime { + importedBlockTimer.Update(time.Duration(importedBlockTime - blockMsTime)) + } + if startMiningTime < blockMsTime { + startMiningTimer.Update(time.Duration(blockMsTime - startMiningTime)) + } + case <-s.stopReportCh: + return + } + } +} diff --git a/eth/downloader/queue.go b/eth/downloader/queue.go index b5f4c76640..e4e244ca13 100644 --- a/eth/downloader/queue.go +++ b/eth/downloader/queue.go @@ -839,9 +839,6 @@ func (q *queue) DeliverBodies(id string, txLists [][]*types.Transaction, txListH if want := *header.BlobGasUsed / params.BlobTxBlobGasPerBlob; uint64(blobs) != want { // div because the header is surely good vs the body might be bloated return errInvalidBody } - if blobs > params.MaxBlobsPerBlockForBSC { - return errInvalidBody - } } else { if blobs != 0 { return errInvalidBody diff --git a/eth/handler_eth.go b/eth/handler_eth.go index dc1f3e744b..06c60f70a2 100644 --- a/eth/handler_eth.go +++ b/eth/handler_eth.go @@ -104,6 +104,16 @@ func (h *ethHandler) handleBlockAnnounces(peer *eth.Peer, hashes []common.Hash, for i := 0; i < len(unknownHashes); i++ { h.blockFetcher.Notify(peer.ID(), unknownHashes[i], unknownNumbers[i], time.Now(), peer.RequestOneHeader, peer.RequestBodies) } + for _, hash := range hashes { + stats := h.chain.GetBlockStats(hash) + if stats.RecvNewBlockHashTime.Load() == 0 { + stats.RecvNewBlockHashTime.Store(time.Now().UnixMilli()) + addr := peer.RemoteAddr() + if addr != nil { + stats.RecvNewBlockHashFrom.Store(addr.String()) + } + } + } return nil } @@ -119,6 +129,14 @@ func (h *ethHandler) handleBlockBroadcast(peer *eth.Peer, packet *eth.NewBlockPa // Schedule the block for import h.blockFetcher.Enqueue(peer.ID(), block) + stats := h.chain.GetBlockStats(block.Hash()) + if stats.RecvNewBlockTime.Load() == 0 { + stats.RecvNewBlockTime.Store(time.Now().UnixMilli()) + addr := peer.RemoteAddr() + if addr != nil { + stats.RecvNewBlockFrom.Store(addr.String()) + } + } // Assuming the block is importable by the peer, but possibly not yet done so, // calculate the head hash and TD that the peer truly must have. diff --git a/go.mod b/go.mod index e6e8c8bf1a..2c48d35be4 100644 --- a/go.mod +++ b/go.mod @@ -1,6 +1,6 @@ module github.com/ethereum/go-ethereum -go 1.22.0 +go 1.23.0 require ( github.com/Azure/azure-sdk-for-go/sdk/storage/azblob v1.2.0 @@ -31,7 +31,7 @@ require ( github.com/fsnotify/fsnotify v1.6.0 github.com/gballet/go-libpcsclite v0.0.0-20191108122812-4678299bea08 github.com/gofrs/flock v0.8.1 - github.com/golang-jwt/jwt/v4 v4.5.1 + github.com/golang-jwt/jwt/v4 v4.5.2 github.com/golang/snappy v0.0.5-0.20220116011046-fa5810519dcb github.com/google/gofuzz v1.2.0 github.com/google/pprof v0.0.0-20241210010833-40e02aabc2ad @@ -79,11 +79,11 @@ require ( github.com/wealdtech/go-eth2-wallet-encryptor-keystorev4 v1.1.3 github.com/willf/bitset v1.1.3 go.uber.org/automaxprocs v1.5.2 - golang.org/x/crypto v0.32.0 + golang.org/x/crypto v0.35.0 golang.org/x/exp v0.0.0-20241217172543-b2144cdd0a67 - golang.org/x/sync v0.10.0 - golang.org/x/sys v0.29.0 - golang.org/x/text v0.21.0 + golang.org/x/sync v0.11.0 + golang.org/x/sys v0.30.0 + golang.org/x/text v0.22.0 golang.org/x/time v0.5.0 golang.org/x/tools v0.29.0 google.golang.org/protobuf v1.36.0 @@ -295,9 +295,9 @@ require ( go.uber.org/multierr v1.11.0 // indirect go.uber.org/zap v1.27.0 // indirect golang.org/x/mod v0.22.0 // indirect - golang.org/x/net v0.34.0 // indirect + golang.org/x/net v0.36.0 // indirect golang.org/x/oauth2 v0.24.0 // indirect - golang.org/x/term v0.28.0 // indirect + golang.org/x/term v0.29.0 // indirect google.golang.org/api v0.44.0 // indirect google.golang.org/genproto v0.0.0-20231016165738-49dd2c1f3d0b // indirect google.golang.org/genproto/googleapis/api v0.0.0-20231012201019-e917dd12ba7a // indirect diff --git a/go.sum b/go.sum index 6548905886..c88da3d733 100644 --- a/go.sum +++ b/go.sum @@ -422,8 +422,8 @@ github.com/gogo/protobuf v1.2.1/go.mod h1:hp+jE20tsWTFYpLwKvXlhS1hjn+gTNwPg2I6zV github.com/gogo/protobuf v1.3.1/go.mod h1:SlYgWuQ5SjCEi6WLHjHCa1yvBfUnHcTbrrZtXPKa29o= github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q= github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q= -github.com/golang-jwt/jwt/v4 v4.5.1 h1:JdqV9zKUdtaa9gdPlywC3aeoEsR681PlKC+4F5gQgeo= -github.com/golang-jwt/jwt/v4 v4.5.1/go.mod h1:m21LjoU+eqJr34lmDMbreY2eSTRJ1cv77w39/MY0Ch0= +github.com/golang-jwt/jwt/v4 v4.5.2 h1:YtQM7lnr8iZ+j5q71MGKkNw9Mn7AjHM68uc9g5fXeUI= +github.com/golang-jwt/jwt/v4 v4.5.2/go.mod h1:m21LjoU+eqJr34lmDMbreY2eSTRJ1cv77w39/MY0Ch0= github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= github.com/golang/glog v1.1.2 h1:DVjP2PbBOzHyzA+dn3WhHIq4NdVu3Q+pvivFICf/7fo= github.com/golang/glog v1.1.2/go.mod h1:zR+okUeTbrL6EL3xHUDxZuEtGv04p5shwip1+mL/rLQ= @@ -1292,8 +1292,8 @@ golang.org/x/crypto v0.0.0-20220722155217-630584e8d5aa/go.mod h1:IxCIyHEi3zRg3s0 golang.org/x/crypto v0.8.0/go.mod h1:mRqEX+O9/h5TFCrQhkgjo2yKi0yYA+9ecGkdQoHrywE= golang.org/x/crypto v0.12.0/go.mod h1:NF0Gs7EO5K4qLn+Ylc+fih8BSTeIjAP05siRnAh98yw= golang.org/x/crypto v0.18.0/go.mod h1:R0j02AL6hcrfOiy9T4ZYp/rcWeMxM3L6QYxlOuEG1mg= -golang.org/x/crypto v0.32.0 h1:euUpcYgM8WcP71gNpTqQCn6rC2t6ULUPiOzfWaXVVfc= -golang.org/x/crypto v0.32.0/go.mod h1:ZnnJkOaASj8g0AjIduWNlq2NRxL0PlBrbKVyZ6V/Ugc= +golang.org/x/crypto v0.35.0 h1:b15kiHdrGCHrP6LvwaQ3c03kgNhhiMgvlhxHQhmg2Xs= +golang.org/x/crypto v0.35.0/go.mod h1:dy7dXNW32cAb/6/PRuTNsix8T+vJAqvuIy5Bli/x0YQ= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8= @@ -1391,8 +1391,8 @@ golang.org/x/net v0.9.0/go.mod h1:d48xBJpPfHeWQsugry2m+kC02ZBRGRgulfHnEXEuWns= golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg= golang.org/x/net v0.14.0/go.mod h1:PpSgVXXLK0OxS0F31C1/tv6XNguvCrnXIDrFMspZIUI= golang.org/x/net v0.20.0/go.mod h1:z8BVo6PvndSri0LbOE3hAn0apkU+1YvI6E70E9jsnvY= -golang.org/x/net v0.34.0 h1:Mb7Mrk043xzHgnRM88suvJFwzVrRfHEHJEl5/71CKw0= -golang.org/x/net v0.34.0/go.mod h1:di0qlW3YNM5oh6GqDGQr92MyTozJPmybPK4Ev/Gm31k= +golang.org/x/net v0.36.0 h1:vWF2fRbw4qslQsQzgFqZff+BItCvGFQqKzKIzx1rmoA= +golang.org/x/net v0.36.0/go.mod h1:bFmbeoIPfrw4sMHNhb4J9f6+tPziuGjq7Jk/38fxi1I= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20181017192945-9dcd33a902f4/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20181203162652-d668ce993890/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= @@ -1423,8 +1423,8 @@ golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJ golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.10.0 h1:3NQrjDixjgGwUOCaF8w2+VYHv0Ve/vGYSbdkTa98gmQ= -golang.org/x/sync v0.10.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= +golang.org/x/sync v0.11.0 h1:GGz8+XQP4FvTTrjZPzNKTMFtSXH80RAzG+5ghFPgK9w= +golang.org/x/sync v0.11.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= golang.org/x/sys v0.0.0-20180810173357-98c5dad5d1a0/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180823144017-11551d06cbcc/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= @@ -1519,8 +1519,8 @@ golang.org/x/sys v0.9.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.11.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.14.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/sys v0.16.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= -golang.org/x/sys v0.29.0 h1:TPYlXGxvx1MGTn2GiZDhnjPA9wZzZeGKHHmKhHYvgaU= -golang.org/x/sys v0.29.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/sys v0.30.0 h1:QjkSwP/36a20jFYWkSue1YwXzLmsV5Gfq7Eiy72C1uc= +golang.org/x/sys v0.30.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= @@ -1529,8 +1529,8 @@ golang.org/x/term v0.7.0/go.mod h1:P32HKFT3hSsZrRxla30E9HqToFYAQPCMs/zFMBUFqPY= golang.org/x/term v0.8.0/go.mod h1:xPskH00ivmX89bAKVGSKKtLOWNx2+17Eiy94tnKShWo= golang.org/x/term v0.11.0/go.mod h1:zC9APTIj3jG3FdV/Ons+XE1riIZXG4aZ4GTHiPZJPIU= golang.org/x/term v0.16.0/go.mod h1:yn7UURbUtPyrVJPGPq404EukNFxcm/foM+bV/bfcDsY= -golang.org/x/term v0.28.0 h1:/Ts8HFuMR2E6IP/jlo7QVLZHggjKQbhu/7H0LJFr3Gg= -golang.org/x/term v0.28.0/go.mod h1:Sw/lC2IAUZ92udQNf3WodGtn4k/XoLyZoh8v/8uiwek= +golang.org/x/term v0.29.0 h1:L6pJp37ocefwRRtYPKSWOWzOtWSxVajvz2ldH/xi3iU= +golang.org/x/term v0.29.0/go.mod h1:6bl4lRlvVuDgSf3179VpIxBF0o10JUpXWOnI7nErv7s= golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= @@ -1545,8 +1545,8 @@ golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= golang.org/x/text v0.12.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= -golang.org/x/text v0.21.0 h1:zyQAAkrwaneQ066sspRyJaG9VNi/YJ1NfzcGB3hZ/qo= -golang.org/x/text v0.21.0/go.mod h1:4IBbMaMmOPCJ8SecivzSH54+73PCFmPWxNTLm+vZkEQ= +golang.org/x/text v0.22.0 h1:bofq7m3/HAFvbF51jz3Q9wLg3jkvSPuiZu/pD1XwgtM= +golang.org/x/text v0.22.0/go.mod h1:YRoo4H8PVmsu+E3Ou7cqLVH8oXWIHVoX0jqUWALQhfY= golang.org/x/time v0.0.0-20180412165947-fbb02b2291d2/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= diff --git a/internal/ethapi/api.go b/internal/ethapi/api.go index a86835a41f..53f38938bb 100644 --- a/internal/ethapi/api.go +++ b/internal/ethapi/api.go @@ -573,7 +573,8 @@ func (api *BlockChainAPI) getFinalizedNumber(ctx context.Context, verifiedValida lastHeader := latestHeader confirmedValSet := make(map[common.Address]struct{}, valLen) confirmedValSet[lastHeader.Coinbase] = struct{}{} - for count := 1; int64(len(confirmedValSet)) < verifiedValidatorNum && count <= int(parliaConfig.Epoch) && lastHeader.Number.Int64() > max(fastFinalizedHeader.Number.Int64(), 1); count++ { + epochLength := int(500) // TODO(Nathan)(BEP-524 Phase Two): use `maxwellEpochLength` instead + for count := 1; int64(len(confirmedValSet)) < verifiedValidatorNum && count <= epochLength && lastHeader.Number.Int64() > max(fastFinalizedHeader.Number.Int64(), 1); count++ { lastHeader, err = api.b.HeaderByHash(ctx, lastHeader.ParentHash) if err != nil { // impossible return 0, err @@ -1439,6 +1440,7 @@ func RPCMarshalBlock(block *types.Block, inclTx bool, fullTx bool, config *param func (api *BlockChainAPI) rpcMarshalHeader(ctx context.Context, header *types.Header) map[string]interface{} { fields := RPCMarshalHeader(header) fields["totalDifficulty"] = (*hexutil.Big)(api.b.GetTd(ctx, header.Hash())) + fields["milliTimestamp"] = hexutil.Uint64(header.MilliTimestamp()) return fields } @@ -1448,6 +1450,7 @@ func (api *BlockChainAPI) rpcMarshalBlock(ctx context.Context, b *types.Block, i fields := RPCMarshalBlock(b, inclTx, fullTx, api.b.ChainConfig()) if inclTx { fields["totalDifficulty"] = (*hexutil.Big)(api.b.GetTd(ctx, b.Hash())) + fields["milliTimestamp"] = hexutil.Uint64(b.Header().MilliTimestamp()) } return fields, nil } diff --git a/internal/ethapi/api_test.go b/internal/ethapi/api_test.go index 3b02826bcd..75c48c8246 100644 --- a/internal/ethapi/api_test.go +++ b/internal/ethapi/api_test.go @@ -3187,6 +3187,9 @@ func TestRPCGetBlockOrHeader(t *testing.T) { t.Errorf("test %d: want no error, have %v", i, err) continue } + if result != nil { + delete(result, "milliTimestamp") + } testRPCResponseWithFile(t, i, result, rpc, tt.file) } diff --git a/miner/bid_simulator.go b/miner/bid_simulator.go index baa2c9c1c5..999efe06a8 100644 --- a/miner/bid_simulator.go +++ b/miner/bid_simulator.go @@ -17,6 +17,7 @@ import ( "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/common/bidutil" "github.com/ethereum/go-ethereum/consensus" + "github.com/ethereum/go-ethereum/consensus/misc/eip4844" "github.com/ethereum/go-ethereum/consensus/parlia" "github.com/ethereum/go-ethereum/core" "github.com/ethereum/go-ethereum/core/txpool" @@ -111,8 +112,9 @@ type bidSimulator struct { pendingMu sync.RWMutex pending map[uint64]map[common.Address]map[common.Hash]struct{} // blockNumber -> builder -> bidHash -> struct{} - bestBidMu sync.RWMutex - bestBid map[common.Hash]*BidRuntime // prevBlockHash -> bidRuntime + bestBidMu sync.RWMutex + bestBid map[common.Hash]*BidRuntime // prevBlockHash -> bidRuntime + bestBidToRun map[common.Hash]*types.Bid // prevBlockHash -> *types.Bid simBidMu sync.RWMutex simulatingBid map[common.Hash]*BidRuntime // prevBlockHash -> bidRuntime, in the process of simulation @@ -143,6 +145,7 @@ func newBidSimulator( newBidCh: make(chan newBidPackage, 100), pending: make(map[uint64]map[common.Address]map[common.Hash]struct{}), bestBid: make(map[common.Hash]*BidRuntime), + bestBidToRun: make(map[common.Hash]*types.Bid), simulatingBid: make(map[common.Hash]*BidRuntime), } @@ -255,6 +258,7 @@ func (b *bidSimulator) ExistBuilder(builder common.Address) bool { return ok } +// best bid here is based on packedBlockReward after the bid is simulated func (b *bidSimulator) SetBestBid(prevBlockHash common.Hash, bid *BidRuntime) { b.bestBidMu.Lock() defer b.bestBidMu.Unlock() @@ -275,6 +279,34 @@ func (b *bidSimulator) GetBestBid(prevBlockHash common.Hash) *BidRuntime { return b.bestBid[prevBlockHash] } +// best bid to run is based on bid's expectedBlockReward before the bid is simulated +func (b *bidSimulator) SetBestBidToRun(prevBlockHash common.Hash, bid *types.Bid) { + b.bestBidMu.Lock() + defer b.bestBidMu.Unlock() + + b.bestBidToRun[prevBlockHash] = bid +} + +// in case the bid is invalid(invalid GasUsed,Reward,GasPrice...), remove it. +func (b *bidSimulator) DelBestBidToRun(prevBlockHash common.Hash, delBid *types.Bid) { + b.bestBidMu.Lock() + defer b.bestBidMu.Unlock() + cur := b.bestBidToRun[prevBlockHash] + if cur == nil || delBid == nil { + return + } + if cur.Hash() == delBid.Hash() { + delete(b.bestBidToRun, prevBlockHash) + } +} + +func (b *bidSimulator) GetBestBidToRun(prevBlockHash common.Hash) *types.Bid { + b.bestBidMu.RLock() + defer b.bestBidMu.RUnlock() + + return b.bestBidToRun[prevBlockHash] +} + func (b *bidSimulator) SetSimulatingBid(prevBlockHash common.Hash, bid *BidRuntime) { b.simBidMu.Lock() defer b.simBidMu.Unlock() @@ -318,6 +350,15 @@ func (b *bidSimulator) mainLoop() { } } +func (b *bidSimulator) canBeInterrupted(targetTime uint64) bool { + if targetTime == 0 { + // invalid targetTime, disable the interrupt check + return true + } + left := time.Until(time.UnixMilli(int64(targetTime))) + return left >= b.config.NoInterruptLeftOver +} + func (b *bidSimulator) newBidLoop() { var ( interruptCh chan int32 @@ -331,6 +372,7 @@ func (b *bidSimulator) newBidLoop() { close(interruptCh) } interruptCh = make(chan int32, 1) + bidRuntime.bid.Commit() select { case b.simBidCh <- &simBidReq{interruptCh: interruptCh, bid: bidRuntime}: log.Debug("BidSimulator: commit", "builder", bidRuntime.bid.Builder, "bidHash", bidRuntime.bid.Hash().Hex()) @@ -359,27 +401,61 @@ func (b *bidSimulator) newBidLoop() { } var replyErr error - // simulatingBid will be nil if there is no bid in simulation, compare with the bestBid instead - if simulatingBid := b.GetSimulatingBid(newBid.bid.ParentHash); simulatingBid != nil { - // simulatingBid always better than bestBid, so only compare with simulatingBid if a simulatingBid exists - if bidRuntime.isExpectedBetterThan(simulatingBid) { - commit(commitInterruptBetterBid, bidRuntime) + toCommit := true + bestBidToRun := b.GetBestBidToRun(newBid.bid.ParentHash) + if bestBidToRun != nil { + bestBidRuntime, _ := newBidRuntime(bestBidToRun, b.config.ValidatorCommission) + if bidRuntime.isExpectedBetterThan(bestBidRuntime) { + // new bid has better expectedBlockReward, use bidRuntime + log.Debug("new bid has better expectedBlockReward", + "builder", bidRuntime.bid.Builder, "bidHash", bidRuntime.bid.Hash().TerminalString()) + } else if !bestBidToRun.IsCommitted() { + // bestBidToRun is not committed yet, this newBid will trigger bestBidToRun to commit + bidRuntime = bestBidRuntime + replyErr = genDiscardedReply(bidRuntime) + log.Debug("discard new bid and to simulate the non-committed bestBidToRun", + "builder", bestBidToRun.Builder, "bidHash", bestBidToRun.Hash().TerminalString()) } else { - replyErr = genDiscardedReply(simulatingBid) + // new bid will be discarded, as it is useless now. + toCommit = false + replyErr = genDiscardedReply(bestBidRuntime) + log.Debug("new bid will be discarded", "builder", bestBidToRun.Builder, + "bidHash", bestBidToRun.Hash().TerminalString()) } - } else { - // bestBid is nil means the bid is the first bid, otherwise the bid should compare with the bestBid - if bestBid := b.GetBestBid(newBid.bid.ParentHash); bestBid == nil || - bidRuntime.isExpectedBetterThan(bestBid) { - commit(commitInterruptBetterBid, bidRuntime) + } + + if toCommit { + b.SetBestBidToRun(bidRuntime.bid.ParentHash, bidRuntime.bid) + // try to commit the new bid + // but if there is a simulating bid and with a short time left, don't interrupt it + if simulatingBid := b.GetSimulatingBid(newBid.bid.ParentHash); simulatingBid != nil { + parentHeader := b.chain.GetHeaderByHash(newBid.bid.ParentHash) + blockInterval := b.getBlockInterval(parentHeader) + blockTime := parentHeader.MilliTimestamp() + blockInterval + left := time.Until(time.UnixMilli(int64(blockTime))) + if b.canBeInterrupted(blockTime) { + log.Debug("simulate in progress, interrupt", + "blockTime", blockTime, "left", left.Milliseconds(), + "NoInterruptLeftOver", b.config.NoInterruptLeftOver.Milliseconds(), + "builder", bidRuntime.bid.Builder, "bidHash", bidRuntime.bid.Hash().TerminalString()) + commit(commitInterruptBetterBid, bidRuntime) + } else { + log.Debug("simulate in progress, no interrupt", + "blockTime", blockTime, "left", left.Milliseconds(), + "NoInterruptLeftOver", b.config.NoInterruptLeftOver.Milliseconds(), + "builder", bidRuntime.bid.Builder, "bidHash", bidRuntime.bid.Hash().TerminalString()) + if newBid.bid.Hash() == bidRuntime.bid.Hash() { + replyErr = fmt.Errorf("bid is pending as no enough time to interrupt, left:%d, NoInterruptLeftOver:%d", + left.Milliseconds(), b.config.NoInterruptLeftOver.Milliseconds()) + } + } } else { - replyErr = genDiscardedReply(bestBid) + commit(commitInterruptBetterBid, bidRuntime) } } if newBid.feedback != nil { newBid.feedback <- replyErr - log.Info("[BID ARRIVED]", "block", newBid.bid.BlockNumber, "builder", newBid.bid.Builder, @@ -397,9 +473,24 @@ func (b *bidSimulator) newBidLoop() { } } +// get block interval for current block by using parent header +func (b *bidSimulator) getBlockInterval(parentHeader *types.Header) uint64 { + if parentHeader == nil { + return 1500 // lorentzBlockInterval + } + parlia, _ := b.engine.(*parlia.Parlia) + // only `Number` and `ParentHash` are used when `BlockInterval` + tmpHeader := &types.Header{ParentHash: parentHeader.Hash(), Number: new(big.Int).Add(parentHeader.Number, common.Big1)} + blockInterval, err := parlia.BlockInterval(b.chain, tmpHeader) + if err != nil { + log.Debug("failed to get BlockInterval when bidBetterBefore") + } + return blockInterval +} + func (b *bidSimulator) bidBetterBefore(parentHash common.Hash) time.Time { parentHeader := b.chain.GetHeaderByHash(parentHash) - return bidutil.BidBetterBefore(parentHeader, b.chainConfig.Parlia.Period, b.delayLeftOver, b.config.BidSimulationLeftOver) + return bidutil.BidBetterBefore(parentHeader, b.getBlockInterval(parentHeader), b.delayLeftOver, b.config.BidSimulationLeftOver) } func (b *bidSimulator) clearLoop() { @@ -419,6 +510,12 @@ func (b *bidSimulator) clearLoop() { delete(b.bestBid, k) } } + delete(b.bestBidToRun, parentHash) + for k, v := range b.bestBidToRun { + if v.BlockNumber <= blockNumber-b.chain.TriesInMemory() { + delete(b.bestBidToRun, k) + } + } b.bestBidMu.Unlock() b.simBidMu.Lock() @@ -519,6 +616,7 @@ func (b *bidSimulator) simBid(interruptCh chan int32, bidRuntime *BidRuntime) { // ensure simulation exited then start next simulation b.SetSimulatingBid(parentHash, bidRuntime) + bestBidOnStart := b.GetBestBid(parentHash) defer func(simStart time.Time) { logCtx := []any{ @@ -526,6 +624,7 @@ func (b *bidSimulator) simBid(interruptCh chan int32, bidRuntime *BidRuntime) { "parentHash", parentHash, "builder", builder, "gasUsed", bidRuntime.bid.GasUsed, + "simElapsed", time.Since(simStart), } if bidRuntime.env != nil { @@ -557,9 +656,12 @@ func (b *bidSimulator) simBid(interruptCh chan int32, bidRuntime *BidRuntime) { select { case b.newBidCh <- newBidPackage{bid: bidRuntime.bid}: - log.Debug("BidSimulator: recommit", "builder", bidRuntime.bid.Builder, "bidHash", bidRuntime.bid.Hash().Hex()) + log.Debug("BidSimulator: recommit", "builder", bidRuntime.bid.Builder, + "bidHash", bidRuntime.bid.Hash().Hex(), "simElapsed", bidRuntime.duration) default: } + } else { + b.DelBestBidToRun(parentHash, bidRuntime.bid) } }(startTS) @@ -589,6 +691,17 @@ func (b *bidSimulator) simBid(interruptCh chan int32, bidRuntime *BidRuntime) { bidRuntime.env.gasPool.SubGas(params.PayBidTxGasLimit) } + // error log: + // simulation failed blockNumber=47630147 parentHash=0x2476bcc93db4c924a2c8079c6d5d783441a72d6ff70c5850b1afd778102e175e builder=0x48a5Ed9abC1a8FBe86ceC4900483f43a7f2dBB48 + // gasUsed=136807406 gasLimit=137816878 err="gas used exceeds gas limit" + // error tracing: + // left: b.RawBid.GasUsed + b.PayBidTxGasUsed => (136782406 + 25000 = 136807406) + // right: headerGasLimit - b.PayBidTxGasLimit - systemGasReserved => (137816878 - 25000 - 1000000 = 136791878) + // cause: 136807406 > 136791878 => true + // error reason: + // left should not be added with PayBidTxGasUsed, Or right should be not be subtracted with PayBidTxGasLimit + // error fix: + // 136782406 > 136791878 => false, Or 136807406 > 136816878 => false if bidRuntime.bid.GasUsed > bidRuntime.env.gasPool.Gas() { err = errors.New("gas used exceeds gas limit") return @@ -670,14 +783,17 @@ func (b *bidSimulator) simBid(interruptCh chan int32, bidRuntime *BidRuntime) { // if enable greedy merge, fill bid env with transactions from mempool if b.config.GreedyMergeTx { - delay := b.engine.Delay(b.chain, bidRuntime.env.header, &b.delayLeftOver) + endingBidsExtra := 20 * time.Millisecond // Add a buffer to ensure ending bids before `delayLeftOver` + minTimeLeftForEndingBids := b.delayLeftOver + endingBidsExtra + delay := b.engine.Delay(b.chain, bidRuntime.env.header, &minTimeLeftForEndingBids) if delay != nil && *delay > 0 { bidTxsSet := mapset.NewThreadUnsafeSetWithSize[common.Hash](len(bidRuntime.bid.Txs)) for _, tx := range bidRuntime.bid.Txs { bidTxsSet.Add(tx.Hash()) } - - fillErr := b.bidWorker.fillTransactions(interruptCh, bidRuntime.env, nil, bidTxsSet) + stopTimer := time.NewTimer(*delay) + defer stopTimer.Stop() + fillErr := b.bidWorker.fillTransactions(interruptCh, bidRuntime.env, stopTimer, bidTxsSet) log.Trace("BidSimulator: greedy merge stopped", "block", bidRuntime.env.header.Number, "builder", bidRuntime.bid.Builder, "tx count", bidRuntime.env.tcount-bidTxLen+1, "err", fillErr) @@ -706,7 +822,12 @@ func (b *bidSimulator) simBid(interruptCh chan int32, bidRuntime *BidRuntime) { bestBid := b.GetBestBid(parentHash) if bestBid == nil { - log.Info("[BID RESULT]", "win", "true[first]", "builder", bidRuntime.bid.Builder, "hash", bidRuntime.bid.Hash().TerminalString()) + winResult := "true[first]" + if bestBidOnStart != nil { + // new block was imported, so the bestBidOnStart was cleared, the bid will be stale and useless. + winResult = "false[stale]" + } + log.Info("[BID RESULT]", "win", winResult, "builder", bidRuntime.bid.Builder, "hash", bidRuntime.bid.Hash().TerminalString()) b.SetBestBid(bidRuntime.bid.ParentHash, bidRuntime) success = true return @@ -844,7 +965,7 @@ func (r *BidRuntime) commitTransaction(chain *core.BlockChain, chainConfig *para // isn't really a better place right now. The blob gas limit is checked at block validation time // and not during execution. This means core.ApplyTransaction will not return an error if the // tx has too many blobs. So we have to explicitly check it here. - if (env.blobs + len(sc.Blobs)) > params.MaxBlobsPerBlockForBSC { + if (env.blobs + len(sc.Blobs)) > eip4844.MaxBlobsPerBlock(chainConfig, r.env.header.Time) { return errors.New("max data blobs reached") } } diff --git a/miner/miner_mev.go b/miner/miner_mev.go index dbf0b2d6cb..9e5619a9ce 100644 --- a/miner/miner_mev.go +++ b/miner/miner_mev.go @@ -99,6 +99,7 @@ func (miner *Miner) MevParams() *types.MevParams { return &types.MevParams{ ValidatorCommission: miner.worker.config.Mev.ValidatorCommission, BidSimulationLeftOver: miner.worker.config.Mev.BidSimulationLeftOver, + NoInterruptLeftOver: miner.worker.config.Mev.NoInterruptLeftOver, GasCeil: miner.worker.config.GasCeil, GasPrice: miner.worker.config.GasPrice, BuilderFeeCeil: builderFeeCeil, diff --git a/miner/minerconfig/config.go b/miner/minerconfig/config.go index 36e43e0b66..31bf5499cc 100644 --- a/miner/minerconfig/config.go +++ b/miner/minerconfig/config.go @@ -75,12 +75,15 @@ type MevConfig struct { Builders []BuilderConfig // The list of builders ValidatorCommission uint64 // 100 means the validator claims 1% from block reward BidSimulationLeftOver time.Duration + NoInterruptLeftOver time.Duration } var DefaultMevConfig = MevConfig{ Enabled: false, + GreedyMergeTx: true, SentryURL: "", Builders: nil, ValidatorCommission: 100, BidSimulationLeftOver: 50 * time.Millisecond, + NoInterruptLeftOver: 400 * time.Millisecond, } diff --git a/miner/worker.go b/miner/worker.go index 6a32188484..89dedca337 100644 --- a/miner/worker.go +++ b/miner/worker.go @@ -70,9 +70,6 @@ const ( // save height, keep recently mined blocks to avoid double sign for safety, recentMinedCacheLimit = 20 - // the default to wait for the mev miner to finish - waitMEVMinerEndTimeLimit = 50 * time.Millisecond - // Reserve block size for the following 3 components: // a. System transactions at the end of the block // b. Seal in the block header @@ -81,6 +78,12 @@ const ( ) var ( + bidExistGauge = metrics.NewRegisteredGauge("worker/bidExist", nil) + bidWinGauge = metrics.NewRegisteredGauge("worker/bidWin", nil) + inturnBlocksGauge = metrics.NewRegisteredGauge("worker/inturnBlocks", nil) + bestBidGasUsedGauge = metrics.NewRegisteredGauge("worker/bestBidGasUsed", nil) // MGas + bestWorkGasUsedGauge = metrics.NewRegisteredGauge("worker/bestWorkGasUsed", nil) // MGas + writeBlockTimer = metrics.NewRegisteredTimer("worker/writeblock", nil) finalizeBlockTimer = metrics.NewRegisteredTimer("worker/finalizeblock", nil) @@ -154,6 +157,8 @@ type task struct { state *state.StateDB block *types.Block createdAt time.Time + + miningStartAt time.Time } const ( @@ -474,7 +479,7 @@ func (w *worker) newWorkLoop(recommit time.Duration) { // If sealing is running resubmit a new work cycle periodically to pull in // higher priced transactions. Disable this overhead for pending blocks. if w.isRunning() && ((w.chainConfig.Clique != nil && - w.chainConfig.Clique.Period > 0) || (w.chainConfig.Parlia != nil && w.chainConfig.Parlia.Period > 0)) { + w.chainConfig.Clique.Period > 0) || (w.chainConfig.Parlia != nil)) { // Short circuit if no new transaction arrives. commit(commitInterruptResubmit) } @@ -668,6 +673,9 @@ func (w *worker) resultLoop() { continue } writeBlockTimer.UpdateSince(start) + stats := w.chain.GetBlockStats(block.Hash()) + stats.SendBlockTime.Store(time.Now().UnixMilli()) + stats.StartMiningTime.Store(task.miningStartAt.UnixMilli()) log.Info("Successfully sealed new block", "number", block.Number(), "sealhash", sealhash, "hash", hash, "elapsed", common.PrettyDuration(time.Since(task.createdAt))) w.mux.Post(core.NewMinedBlockEvent{Block: block}) @@ -1293,7 +1301,7 @@ LOOP: break } else { log.Debug("commitWork stopTimer", "block", work.header.Number, - "header time", time.Until(time.Unix(int64(work.header.Time), 0)), + "header time", time.UnixMilli(int64(work.header.MilliTimestamp())), "commit delay", *delay, "DelayLeftOver", w.config.DelayLeftOver) stopTimer.Reset(*delay) } @@ -1337,7 +1345,7 @@ LOOP: newTxsNum := 0 // stopTimer was the maximum delay for each fillTransactions // but now it is used to wait until (head.Time - DelayLeftOver) is reached. - stopTimer.Reset(time.Until(time.Unix(int64(work.header.Time), 0)) - w.config.DelayLeftOver) + stopTimer.Reset(time.Until(time.UnixMilli(int64(work.header.MilliTimestamp()))) - w.config.DelayLeftOver) LOOP_WAIT: for { select { @@ -1400,11 +1408,12 @@ LOOP: // when in-turn, compare with remote work. from := bestWork.coinbase if w.bidFetcher != nil && bestWork.header.Difficulty.Cmp(diffInTurn) == 0 { + inturnBlocksGauge.Inc(1) // We want to start sealing the block as late as possible here if mev is enabled, so we could give builder the chance to send their final bid. // Time left till sealing the block. - tillSealingTime := time.Until(time.Unix(int64(bestWork.header.Time), 0)) - w.config.DelayLeftOver - if tillSealingTime > max(100*time.Millisecond, w.config.DelayLeftOver) { - // Still a lot of time left, wait for the best bid. + tillSealingTime := time.Until(time.UnixMilli(int64(bestWork.header.MilliTimestamp()))) - w.config.DelayLeftOver + if tillSealingTime > 0 { + // Still some time left, wait for the best bid. // This happens during the peak time of the network, the local block building LOOP would break earlier than // the final sealing time by meeting the errBlockInterruptedByOutOfGas criteria. @@ -1418,18 +1427,13 @@ LOOP: } } - if pendingBid := w.bidFetcher.GetSimulatingBid(bestWork.header.ParentHash); pendingBid != nil { - waitBidTimer := time.NewTimer(waitMEVMinerEndTimeLimit) - defer waitBidTimer.Stop() - select { - case <-waitBidTimer.C: - case <-pendingBid.finished: - } - } - bestBid := w.bidFetcher.GetBestBid(bestWork.header.ParentHash) if bestBid != nil { + bidExistGauge.Inc(1) + bestBidGasUsedGauge.Update(int64(bestBid.bid.GasUsed) / 1_000_000) + bestWorkGasUsedGauge.Update(int64(bestWork.header.GasUsed) / 1_000_000) + log.Debug("BidSimulator: final compare", "block", bestWork.header.Number.Uint64(), "localBlockReward", bestReward.String(), "bidBlockReward", bestBid.packedBlockReward.String()) @@ -1446,6 +1450,8 @@ LOOP: // blockReward(benefits delegators) and validatorReward(benefits the validator) are both optimal if localValidatorReward.CmpBig(bestBid.packedValidatorReward) < 0 { + bidWinGauge.Inc(1) + bestWork = bestBid.env from = bestBid.bid.Builder @@ -1514,7 +1520,7 @@ func (w *worker) commit(env *environment, interval func(), update bool, start ti block = block.WithSidecars(env.sidecars) select { - case w.taskCh <- &task{receipts: receipts, state: env.state, block: block, createdAt: time.Now()}: + case w.taskCh <- &task{receipts: receipts, state: env.state, block: block, createdAt: time.Now(), miningStartAt: start}: log.Info("Commit new sealing work", "number", block.Number(), "sealhash", w.engine.SealHash(block.Header()), "txs", env.tcount, "blobs", env.blobs, "gas", block.GasUsed(), "fees", feesInEther, "elapsed", common.PrettyDuration(time.Since(start))) @@ -1545,15 +1551,15 @@ func (w *worker) getSealingBlock(params *generateParams) *newPayloadResult { } func (w *worker) tryWaitProposalDoneWhenStopping() { - posa, ok := w.engine.(consensus.PoSA) - // if the consensus is not PoSA, just skip waiting + parlia, ok := w.engine.(*parlia.Parlia) + // if the consensus is not parlia, just skip waiting if !ok { return } currentHeader := w.chain.CurrentBlock() currentBlock := currentHeader.Number.Uint64() - startBlock, endBlock, err := posa.NextProposalBlock(w.chain, currentHeader, w.coinbase) + startBlock, endBlock, err := parlia.NextProposalBlock(w.chain, currentHeader, w.coinbase) if err != nil { log.Warn("Failed to get next proposal block, skip waiting", "err", err) return @@ -1565,13 +1571,17 @@ func (w *worker) tryWaitProposalDoneWhenStopping() { log.Warn("next proposal end block has passed, ignore") return } - if startBlock > currentBlock && (startBlock-currentBlock)*posa.BlockInterval() > w.config.MaxWaitProposalInSecs { + blockInterval, err := parlia.BlockInterval(w.chain, currentHeader) + if err != nil { + log.Debug("failed to get BlockInterval when tryWaitProposalDoneWhenStopping") + } + if startBlock > currentBlock && ((startBlock-currentBlock)*blockInterval/1000) > w.config.MaxWaitProposalInSecs { log.Warn("the next proposal start block is too far, just skip waiting") return } // wait one more block for safety - waitSecs := (endBlock - currentBlock + 1) * posa.BlockInterval() + waitSecs := (endBlock - currentBlock + 1) * blockInterval / 1000 log.Info("The miner will propose in later, waiting for the proposal to be done", "currentBlock", currentBlock, "nextProposalStart", startBlock, "nextProposalEnd", endBlock, "waitTime", waitSecs) time.Sleep(time.Duration(waitSecs) * time.Second) diff --git a/p2p/metrics.go b/p2p/metrics.go index d713a2fc8d..493acbf035 100644 --- a/p2p/metrics.go +++ b/p2p/metrics.go @@ -68,6 +68,8 @@ var ( serveUnexpectedIdentity = metrics.NewRegisteredMeter("p2p/serves/error/id/unexpected", nil) serveEncHandshakeError = metrics.NewRegisteredMeter("p2p/serves/error/rlpx/enc", nil) serveProtoHandshakeError = metrics.NewRegisteredMeter("p2p/serves/error/rlpx/proto", nil) + + peerLatencyStat = metrics.NewRegisteredTimer("p2p/peers/latency", nil) ) // markDialError matches errors that occur while setting up a dial connection diff --git a/p2p/peer.go b/p2p/peer.go index bd45dba5cf..8e561a978d 100644 --- a/p2p/peer.go +++ b/p2p/peer.go @@ -23,6 +23,7 @@ import ( "net" "slices" "sync" + "sync/atomic" "time" "github.com/ethereum/go-ethereum/common/mclock" @@ -46,6 +47,8 @@ const ( snappyProtocolVersion = 5 pingInterval = 15 * time.Second + + slowPeerLatencyThreshold = 500 ) const ( @@ -113,12 +116,15 @@ type Peer struct { protoErr chan error closed chan struct{} pingRecv chan struct{} + pongRecv chan struct{} disc chan DiscReason // events receives message send / receive events if set events *event.Feed testPipe *MsgPipeRW // for testing testRemoteAddr string // for testing + + latency atomic.Int64 // mill second latency, estimated by ping msg } // NewPeer returns a peer for testing purposes. @@ -268,6 +274,7 @@ func newPeer(log log.Logger, conn *conn, protocols []Protocol) *Peer { protoErr: make(chan error, len(protomap)+1), // protocols + pingLoop closed: make(chan struct{}), pingRecv: make(chan struct{}, 16), + pongRecv: make(chan struct{}, 16), log: log.New("id", conn.node.ID(), "conn", conn.flags), } return p @@ -333,9 +340,11 @@ func (p *Peer) pingLoop() { ping := time.NewTimer(pingInterval) defer ping.Stop() + var startPing atomic.Int64 for { select { case <-ping.C: + startPing.Store(time.Now().UnixMilli()) if err := SendItems(p.rw, pingMsg); err != nil { p.protoErr <- err return @@ -345,6 +354,16 @@ func (p *Peer) pingLoop() { case <-p.pingRecv: SendItems(p.rw, pongMsg) + case <-p.pongRecv: + // estimate latency here, it also includes tiny msg encode/decode, io wait time + latency := (time.Now().UnixMilli() - startPing.Load()) / 2 + if latency > 0 { + p.latency.Store(latency) + peerLatencyStat.Update(time.Duration(latency)) + if latency > slowPeerLatencyThreshold { + log.Warn("find a too slow peer", "id", p.ID(), "peer", p.RemoteAddr(), "latency", latency) + } + } case <-p.closed: return } @@ -375,6 +394,12 @@ func (p *Peer) handle(msg Msg) error { case p.pingRecv <- struct{}{}: case <-p.closed: } + case msg.Code == pongMsg: + msg.Discard() + select { + case p.pongRecv <- struct{}{}: + case <-p.closed: + } case msg.Code == discMsg: // This is the last message. We don't need to discard or // check errors because, the connection will be closed after it. @@ -557,6 +582,7 @@ type PeerInfo struct { Static bool `json:"static"` } `json:"network"` Protocols map[string]interface{} `json:"protocols"` // Sub-protocol specific metadata fields + Latency int64 `json:"latency"` // the estimate latency from ping msg } // Info gathers and returns a collection of metadata known about a peer. @@ -573,6 +599,7 @@ func (p *Peer) Info() *PeerInfo { Name: p.Fullname(), Caps: caps, Protocols: make(map[string]interface{}, len(p.running)), + Latency: p.latency.Load(), } if p.Node().Seq() > 0 { info.ENR = p.Node().String() diff --git a/params/config.go b/params/config.go index a5dd62808f..fca8e918c1 100644 --- a/params/config.go +++ b/params/config.go @@ -191,10 +191,7 @@ var ( PragueTime: newUint64(1742436600), LorentzTime: nil, - Parlia: &ParliaConfig{ - Period: 3, - Epoch: 200, - }, + Parlia: &ParliaConfig{}, BlobScheduleConfig: &BlobScheduleConfig{ Cancun: DefaultCancunBlobConfig, Prague: DefaultPragueBlobConfigBSC, @@ -237,13 +234,9 @@ var ( BohrTime: newUint64(1724116996), // 2024-08-20 01:23:16 AM UTC PascalTime: newUint64(1740452880), // 2025-02-25 03:08:00 AM UTC PragueTime: newUint64(1740452880), // 2025-02-25 03:08:00 AM UTC - // TODO - LorentzTime: nil, + LorentzTime: newUint64(1744097580), // 2025-04-08 07:33:00 AM UTC - Parlia: &ParliaConfig{ - Period: 3, - Epoch: 200, - }, + Parlia: &ParliaConfig{}, BlobScheduleConfig: &BlobScheduleConfig{ Cancun: DefaultCancunBlobConfig, Prague: DefaultPragueBlobConfigBSC, @@ -290,10 +283,7 @@ var ( PragueTime: nil, LorentzTime: nil, - Parlia: &ParliaConfig{ - Period: 3, - Epoch: 200, - }, + Parlia: &ParliaConfig{}, BlobScheduleConfig: &BlobScheduleConfig{ Cancun: DefaultCancunBlobConfig, Prague: DefaultPragueBlobConfigBSC, @@ -332,10 +322,7 @@ var ( FeynmanFixTime: newUint64(0), CancunTime: newUint64(0), - Parlia: &ParliaConfig{ - Period: 3, - Epoch: 200, - }, + Parlia: &ParliaConfig{}, BlobScheduleConfig: &BlobScheduleConfig{ Cancun: DefaultCancunBlobConfig, }, @@ -557,8 +544,6 @@ var ( } DefaultPragueBlobConfigBSC = DefaultCancunBlobConfig - // for bsc, only DefaultCancunBlobConfig is used, so we can define MaxBlobsPerBlockForBSC more directly - MaxBlobsPerBlockForBSC = DefaultCancunBlobConfig.Max ) // NetworkNames are user friendly names to use in the chain spec banner. @@ -680,8 +665,6 @@ func (c CliqueConfig) String() string { // ParliaConfig is the consensus engine configs for proof-of-staked-authority based sealing. type ParliaConfig struct { - Period uint64 `json:"period"` // Number of seconds between blocks to enforce - Epoch uint64 `json:"epoch"` // Epoch length to update validatorSet } // String implements the stringer interface, returning the consensus engine details. @@ -1501,6 +1484,8 @@ func (c *ChainConfig) LatestFork(time uint64) forks.Fork { switch { case c.IsOsaka(london, time): return forks.Osaka + case c.IsLorentz(london, time): + return forks.Lorentz case c.IsPrague(london, time): return forks.Prague case c.IsCancun(london, time): diff --git a/params/forks/forks.go b/params/forks/forks.go index 2d44e13b04..de6ffa4d26 100644 --- a/params/forks/forks.go +++ b/params/forks/forks.go @@ -39,5 +39,6 @@ const ( Shanghai Cancun Prague + Lorentz Osaka ) diff --git a/params/protocol_params.go b/params/protocol_params.go index 800c8578cd..74a9ec3fb9 100644 --- a/params/protocol_params.go +++ b/params/protocol_params.go @@ -23,7 +23,7 @@ import ( ) const ( - GasLimitBoundDivisor uint64 = 256 // The bound divisor of the gas limit, used in update calculations. + GasLimitBoundDivisor uint64 = 1024 // The bound divisor of the gas limit, used in update calculations. MinGasLimit uint64 = 5000 // Minimum the gas limit may ever be. MaxGasLimit uint64 = 0x7fffffffffffffff // Maximum the gas limit (2^63-1). GenesisGasLimit uint64 = 4712388 // Gas limit of the Genesis block. @@ -194,9 +194,13 @@ const ( ) var ( - MinBlocksForBlobRequests uint64 = 524288 // it keeps blob data available for ~18.2 days in local, ref: https://github.com/bnb-chain/BEPs/blob/master/BEPs/BEP-336.md#51-parameters. - DefaultExtraReserveForBlobRequests uint64 = 1 * (24 * 3600) / 3 // it adds more time for expired blobs for some request cases, like expiry blob when remote peer is syncing, default 1 day. - BreatheBlockInterval uint64 = 86400 // Controls the interval for updateValidatorSetV2 + // lorentzBlockInterval = 1.5 + MinTimeDurationForBlobRequests uint64 = uint64(float64(24*3600) * 18.2) // it keeps blob data available for 18.2 days in local + MinBlocksForBlobRequests uint64 = uint64(float64(MinTimeDurationForBlobRequests) / 1.5) // ref: https://github.com/bnb-chain/BEPs/blob/master/BEPs/BEP-524.md#421-change-table. + DefaultExtraReserveForBlobRequests uint64 = uint64(24 * 3600 / 1.5) // it adds more time for expired blobs for some request cases, like expiry blob when remote peer is syncing, default 1 day. + + BreatheBlockInterval uint64 = 24 * 3600 // Controls the interval for updateValidatorSetV2 + // used for testing: // [1,9] except 2 --> used as turn length directly // 2 --> use random values to test switching turn length diff --git a/rpc/handler.go b/rpc/handler.go index 24310a373e..5b4399d6a6 100644 --- a/rpc/handler.go +++ b/rpc/handler.go @@ -481,9 +481,6 @@ func (h *handler) handleCallMsg(ctx *callProc, reqCtx context.Context, msg *json var logctx []any logctx = append(logctx, "reqid", idForLog{msg.ID}, "duration", time.Since(start)) if resp.Error != nil { - xForward := reqCtx.Value("X-Forwarded-For") - h.log.Warn("Served "+msg.Method, "reqid", idForLog{msg.ID}, "t", time.Since(start), "err", resp.Error.Message, "X-Forwarded-For", xForward) - monitoredError := "sender or to in black list" // using legacypool.ErrInBlackList.Error() will cause `import cycle` if strings.Contains(resp.Error.Message, monitoredError) { accountBlacklistRpcCounter.Inc(1) @@ -493,6 +490,9 @@ func (h *handler) handleCallMsg(ctx *callProc, reqCtx context.Context, msg *json if resp.Error.Data != nil { logctx = append(logctx, "errdata", formatErrorData(resp.Error.Data)) } + + xForward := reqCtx.Value("X-Forwarded-For") + logctx = append(logctx, "X-Forwarded-For", xForward) h.log.Warn("Served "+msg.Method, logctx...) } else { h.log.Debug("Served "+msg.Method, logctx...) diff --git a/tests/0001-diff-go-ethereum.patch b/tests/0001-diff-go-ethereum.patch index 10a946c6bd..176f79e9af 100644 --- a/tests/0001-diff-go-ethereum.patch +++ b/tests/0001-diff-go-ethereum.patch @@ -1,13 +1,13 @@ -From dba05084d6425657211702dd690ebef0c9c45448 Mon Sep 17 00:00:00 2001 +0001-diff-go-ethereum.patch +bdaa06d694bf10297 Mon Sep 17 00:00:00 2001 From: buddh0 -Date: Wed, 5 Feb 2025 20:34:36 +0800 +Date: Tue, 4 Mar 2025 11:22:17 +0800 Subject: [PATCH] diff go ethereum --- - core/vm/contracts.go | 19 ------------------- - core/vm/jump_table.go | 2 +- - params/protocol_params.go | 2 +- - 3 files changed, 2 insertions(+), 21 deletions(-) + core/vm/contracts.go | 19 ------------------- + core/vm/jump_table.go | 2 +- + 2 files changed, 1 insertion(+), 20 deletions(-) diff --git a/core/vm/contracts.go b/core/vm/contracts.go index ddde8b0c9..39065b2f7 100644 @@ -66,19 +66,6 @@ index 299ee4c55..6610fa7f9 100644 enable3855(&instructionSet) // PUSH0 instruction enable3860(&instructionSet) // Limit and meter initcode -diff --git a/params/protocol_params.go b/params/protocol_params.go -index c83e330a8..903e758df 100644 ---- a/params/protocol_params.go -+++ b/params/protocol_params.go -@@ -23,7 +23,7 @@ import ( - ) - - const ( -- GasLimitBoundDivisor uint64 = 256 // The bound divisor of the gas limit, used in update calculations. -+ GasLimitBoundDivisor uint64 = 1024 // The bound divisor of the gas limit, used in update calculations. - MinGasLimit uint64 = 5000 // Minimum the gas limit may ever be. - MaxGasLimit uint64 = 0x7fffffffffffffff // Maximum the gas limit (2^63-1). - GenesisGasLimit uint64 = 4712388 // Gas limit of the Genesis block. -- 2.41.0 diff --git a/version/version.go b/version/version.go index ef23218d31..bdd38d8ceb 100644 --- a/version/version.go +++ b/version/version.go @@ -19,6 +19,6 @@ package version const ( Major = 1 // Major version component of the current release Minor = 5 // Minor version component of the current release - Patch = 7 // Patch version component of the current release + Patch = 9 // Patch version component of the current release Meta = "" // Version metadata to append to the version string )