diff --git a/Dockerfile b/Dockerfile index b056ba02615..c11b6aeb82f 100644 --- a/Dockerfile +++ b/Dockerfile @@ -38,6 +38,11 @@ FROM docker.io/library/alpine:3.17 RUN apk add --no-cache ca-certificates libstdc++ tzdata RUN apk add --no-cache curl jq bind-tools +WORKDIR /usr/local/bin +RUN wget https://github.com/grpc-ecosystem/grpc-health-probe/releases/download/v0.4.11/grpc_health_probe-linux-amd64 -P /usr/local/bin/ && \ + mv /usr/local/bin/grpc_health_probe-linux-amd64 /usr/local/bin/grpc_health_probe && \ + chmod +x /usr/local/bin/grpc_health_probe + # Setup user and group # # from the perspective of the container, uid=1000, gid=1000 is a sensible choice @@ -76,6 +81,7 @@ COPY --from=builder /app/build/bin/sentry /usr/local/bin/sentry COPY --from=builder /app/build/bin/state /usr/local/bin/state COPY --from=builder /app/build/bin/txpool /usr/local/bin/txpool COPY --from=builder /app/build/bin/verkle /usr/local/bin/verkle +COPY --from=builder /app/build/bin/caplin-phase1 /usr/local/bin/caplin-phase1 diff --git a/Dockerfile.debian b/Dockerfile.debian index 91154739756..7cf40a1e903 100644 --- a/Dockerfile.debian +++ b/Dockerfile.debian @@ -65,7 +65,6 @@ COPY --from=builder /app/build/bin/erigon-cl /usr/local/bin/erigon-cl COPY --from=builder /app/build/bin/evm /usr/local/bin/evm COPY --from=builder /app/build/bin/hack /usr/local/bin/hack COPY --from=builder /app/build/bin/integration /usr/local/bin/integration -COPY --from=builder /app/build/bin/lightclient /usr/local/bin/lightclient COPY --from=builder /app/build/bin/observer /usr/local/bin/observer COPY --from=builder /app/build/bin/pics /usr/local/bin/pics COPY --from=builder /app/build/bin/rpcdaemon /usr/local/bin/rpcdaemon @@ -75,6 +74,7 @@ COPY --from=builder /app/build/bin/sentry /usr/local/bin/sentry COPY --from=builder /app/build/bin/state /usr/local/bin/state COPY --from=builder /app/build/bin/txpool /usr/local/bin/txpool COPY --from=builder /app/build/bin/verkle /usr/local/bin/verkle +COPY --from=builder /app/build/bin/caplin-phase1 /usr/local/bin/caplin-phase1 EXPOSE 8545 \ 8551 \ diff --git a/Makefile b/Makefile index 8a587de4e75..98a212dbfba 100644 --- a/Makefile +++ b/Makefile @@ -28,7 +28,7 @@ CGO_CFLAGS += -Wno-error=strict-prototypes # for Clang15, remove it when can htt CGO_CFLAGS := CGO_CFLAGS="$(CGO_CFLAGS)" DBG_CGO_CFLAGS += -DMDBX_DEBUG=1 -BUILD_TAGS = nosqlite,noboltdb +BUILD_TAGS = nosqlite,noboltdb,netgo # about netgo see: https://github.com/golang/go/issues/30310#issuecomment-471669125 PACKAGE = github.com/ledgerwatch/erigon GO_FLAGS += -trimpath -tags $(BUILD_TAGS) -buildvcs=false @@ -42,8 +42,8 @@ default: all ## go-version: print and verify go version go-version: - @if [ $(shell $(GO) version | cut -c 16-17) -lt 18 ]; then \ - echo "minimum required Golang version is 1.18"; \ + @if [ $(shell $(GO) version | cut -c 16-17) -lt 19 ]; then \ + echo "minimum required Golang version is 1.19"; \ exit 1 ;\ fi @@ -105,6 +105,7 @@ geth: erigon erigon: go-version erigon.cmd @rm -f $(GOBIN)/tg # Remove old binary to prevent confusion where users still use it because of the scripts +COMMANDS += starter COMMANDS += devnet COMMANDS += erigon-el-mock COMMANDS += downloader @@ -120,9 +121,9 @@ COMMANDS += state COMMANDS += txpool COMMANDS += verkle COMMANDS += evm -COMMANDS += lightclient COMMANDS += sentinel -COMMANDS += erigon-el +COMMANDS += erigon-el +COMMANDS += caplin-phase1 # build each command using %.cmd rule $(COMMANDS): %: %.cmd @@ -136,6 +137,7 @@ db-tools: go mod vendor cd vendor/github.com/torquem-ch/mdbx-go && MDBX_BUILD_TIMESTAMP=unknown make tools + mkdir -p $(GOBIN) cd vendor/github.com/torquem-ch/mdbx-go/mdbxdist && cp mdbx_chk $(GOBIN) && cp mdbx_copy $(GOBIN) && cp mdbx_dump $(GOBIN) && cp mdbx_drop $(GOBIN) && cp mdbx_load $(GOBIN) && cp mdbx_stat $(GOBIN) rm -rf vendor @echo "Run \"$(GOBIN)/mdbx_stat -h\" to get info about mdbx db file." @@ -166,7 +168,7 @@ lintci: ## lintci-deps: (re)installs golangci-lint to build/bin/golangci-lint lintci-deps: rm -f ./build/bin/golangci-lint - curl -sSfL https://raw.githubusercontent.com/golangci/golangci-lint/master/install.sh | sh -s -- -b ./build/bin v1.51.1 + curl -sSfL https://raw.githubusercontent.com/golangci/golangci-lint/master/install.sh | sh -s -- -b ./build/bin v1.52.2 ## clean: cleans the go cache, build dir, libmdbx db dir clean: @@ -181,10 +183,10 @@ devtools: # Notice! If you adding new binary - add it also to cmd/hack/binary-deps/main.go file $(GOBUILD) -o $(GOBIN)/go-bindata github.com/kevinburke/go-bindata/go-bindata $(GOBUILD) -o $(GOBIN)/gencodec github.com/fjl/gencodec - $(GOBUILD) -o $(GOBIN)/codecgen github.com/ugorji/go/codec/codecgen $(GOBUILD) -o $(GOBIN)/abigen ./cmd/abigen + $(GOBUILD) -o $(GOBIN)/codecgen github.com/ugorji/go/codec/codecgen PATH=$(GOBIN):$(PATH) go generate ./common - PATH=$(GOBIN):$(PATH) go generate ./core/types +# PATH=$(GOBIN):$(PATH) go generate ./core/types PATH=$(GOBIN):$(PATH) go generate ./consensus/aura/... #PATH=$(GOBIN):$(PATH) go generate ./eth/ethconfig/... @type "npm" 2> /dev/null || echo 'Please install node.js and npm' @@ -214,7 +216,7 @@ git-submodules: @git submodule update --quiet --init --recursive --force || true PACKAGE_NAME := github.com/ledgerwatch/erigon -GOLANG_CROSS_VERSION ?= v1.19.5 +GOLANG_CROSS_VERSION ?= v1.20.2 .PHONY: release-dry-run release-dry-run: git-submodules diff --git a/README.md b/README.md index 0b2f698b8ad..127fc7bb3d5 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,8 @@ # Erigon -Erigon is an implementation of Ethereum (execution client with light client for consensus layer), on the efficiency frontier. [Archive Node](https://ethereum.org/en/developers/docs/nodes-and-clients/archive-nodes/#what-is-an-archive-node) by default. +Erigon is an implementation of Ethereum (execution client with light client for consensus layer), on the efficiency +frontier. [Archive Node](https://ethereum.org/en/developers/docs/nodes-and-clients/archive-nodes/#what-is-an-archive-node) +by default. ![Build status](https://github.com/ledgerwatch/erigon/actions/workflows/ci.yml/badge.svg) @@ -24,7 +26,7 @@ Erigon is an implementation of Ethereum (execution client with light client for + [Faster Initial Sync](#faster-initial-sync) + [JSON-RPC daemon](#json-rpc-daemon) + [Run all components by docker-compose](#run-all-components-by-docker-compose) - + [Grafana dashboar god](#grafana-dashboard) + + [Grafana dashboard](#grafana-dashboard) - [Documentation](#documentation) - [FAQ](#faq) - [Getting in touch](#getting-in-touch) @@ -39,7 +41,8 @@ Erigon is an implementation of Ethereum (execution client with light client for **Disclaimer**: this software is currently a tech preview. We will do our best to keep it stable and make no breaking changes but we don't guarantee anything. Things can and will break. -**Important defaults**: Erigon is an Archive Node by default (to remove history see: `--prune` flags in `erigon --help`). We don't allow change this flag after first start. +**Important defaults**: Erigon is an Archive Node by default (to remove history see: `--prune` flags +in `erigon --help`). We don't allow change this flag after first start. In-depth links are marked by the microscope sign (🔬) @@ -54,16 +57,16 @@ System Requirements * Gnosis Chain Archive: 370GB (January 2023). -* BSC Archive: 7TB. BSC Full: 1TB. +* BSC Archive: 7TB. BSC Full: 1TB. (April 2022). -* Polygon Mainnet Archive: 5TB. Polygon Mumbai Archive: 1TB. +* Polygon Mainnet Archive: 5TB. Polygon Mumbai Archive: 1TB. (April 2022). SSD or NVMe. Do not recommend HDD - on HDD Erigon will always stay N blocks behind chain tip, but not fall behind. Bear in mind that SSD performance deteriorates when close to capacity. RAM: >=16GB, 64-bit architecture. -[Golang version >= 1.18](https://golang.org/doc/install); GCC 10+ or Clang; On Linux: kernel > v4 +[Golang version >= 1.19](https://golang.org/doc/install); GCC 10+ or Clang; On Linux: kernel > v4 🔬 more details on disk storage [here](https://erigon.substack.com/p/disk-footprint-changes-in-new-erigon?s=r) and [here](https://ledgerwatch.github.io/turbo_geth_release.html#Disk-space). @@ -94,39 +97,41 @@ make erigon ./build/bin/erigon ``` -Default `--snapshots` for `mainnet`, `goerli`, `gnosis`, `bsc`. Other networks now have default `--snapshots=false`. Increase +Default `--snapshots` for `mainnet`, `goerli`, `gnosis`, `bsc`. Other networks now have default `--snapshots=false`. +Increase download speed by flag `--torrent.download.rate=20mb`. 🔬 See [Downloader docs](./cmd/downloader/readme.md) Use `--datadir` to choose where to store data. -Use `--chain=gnosis` for [Gnosis Chain](https://www.gnosis.io/), `--chain=bor-mainnet` for Polygon Mainnet, and `--chain=mumbai` for Polygon Mumbai. -For Gnosis Chain you need a [Consensus Layer](#beacon-chain-consensus-layer) client alongside Erigon (https://docs.gnosischain.com/node/guide/beacon). +Use `--chain=gnosis` for [Gnosis Chain](https://www.gnosis.io/), `--chain=bor-mainnet` for Polygon Mainnet, +and `--chain=mumbai` for Polygon Mumbai. +For Gnosis Chain you need a [Consensus Layer](#beacon-chain-consensus-layer) client alongside +Erigon (https://docs.gnosischain.com/node/guide/beacon). Running `make help` will list and describe the convenience commands available in the [Makefile](./Makefile). ### Datadir structure -- chaindata: recent blocks, state, recent state history. low-latency disk recommended. +- chaindata: recent blocks, state, recent state history. low-latency disk recommended. - snapshots: old blocks, old state history. can symlink/mount it to cheaper disk. mostly immutable. - temp: can grow to ~100gb, but usually empty. can symlink/mount it to cheaper disk. - txpool: pending transactions. safe to remove. - nodes: p2p peers. safe to remove. - ### Logging -_Flags:_ - - - `verbosity` - - `log.console.verbosity` (overriding alias for `verbosity`) - - `log.json` - - `log.console.json` (alias for `log.json`) - - `log.dir.path` - - `log.dir.verbosity` - - `log.dir.json` +_Flags:_ +- `verbosity` +- `log.console.verbosity` (overriding alias for `verbosity`) +- `log.json` +- `log.console.json` (alias for `log.json`) +- `log.dir.path` +- `log.dir.verbosity` +- `log.dir.json` -In order to log only to the stdout/stderr the `--verbosity` (or `log.console.verbosity`) flag can be used to supply an int value specifying the highest output log level: +In order to log only to the stdout/stderr the `--verbosity` (or `log.console.verbosity`) flag can be used to supply an +int value specifying the highest output log level: ``` LvlCrit = 0 @@ -137,9 +142,12 @@ In order to log only to the stdout/stderr the `--verbosity` (or `log.console.ver LvlTrace = 5 ``` -To set an output dir for logs to be collected on disk, please set `--log.dir.path`. The flag `--log.dir.verbosity` is also available to control the verbosity of this logging, with the same int value as above, or the string value e.g. 'debug' or 'info'. Default verbosity is 'debug' (4), for disk logging. +To set an output dir for logs to be collected on disk, please set `--log.dir.path`. The flag `--log.dir.verbosity` is +also available to control the verbosity of this logging, with the same int value as above, or the string value e.g. ' +debug' or 'info'. Default verbosity is 'debug' (4), for disk logging. -Log format can be set to json by the use of the boolean flags `log.json` or `log.console.json`, or for the disk output `--log.dir.json`. +Log format can be set to json by the use of the boolean flags `log.json` or `log.console.json`, or for the disk +output `--log.dir.json`. ### Modularity @@ -151,9 +159,10 @@ How to start Erigon's services as separated processes, see in [docker-compose.ym ### Embedded Consensus Layer -By default, on Ethereum Mainnet, Görli, and Sepolia, the Engine API is disabled in favour of the Erigon native Embedded Consensus Layer. -If you want to use an external Consensus Layer, run Erigon with flag `--externalcl`. -_Warning:_ Staking (block production) is not possible with the embedded CL – use `--externalcl` instead. +On Ethereum Mainnet, Görli, and Sepolia, the Engine API can be disabled in favour of the Erigon native Embedded +Consensus Layer. +If you want to use the internal Consensus Layer, run Erigon with flag `--internalcl`. +_Warning:_ Staking (block production) is not possible with the embedded CL. ### Testnets @@ -202,7 +211,7 @@ Windows users may run erigon in 3 possible ways: build on windows : * [Git](https://git-scm.com/downloads) for Windows must be installed. If you're cloning this repository is very likely you already have it - * [GO Programming Language](https://golang.org/dl/) must be installed. Minimum required version is 1.18 + * [GO Programming Language](https://golang.org/dl/) must be installed. Minimum required version is 1.19 * GNU CC Compiler at least version 10 (is highly suggested that you install `chocolatey` package manager - see following point) * If you need to build MDBX tools (i.e. `.\wmake.ps1 db-tools`) @@ -369,7 +378,8 @@ Examples of stages are: ### JSON-RPC daemon -Most of Erigon's components (txpool, rpcdaemon, snapshots downloader, sentry, ...) can work inside Erigon and as independent process. +Most of Erigon's components (txpool, rpcdaemon, snapshots downloader, sentry, ...) can work inside Erigon and as +independent process. To enable built-in RPC server: `--http` and `--ws` (sharing same port with http) @@ -492,7 +502,8 @@ Windows support for docker-compose is not ready yet. Please help us with .ps1 po `docker-compose up prometheus grafana`, [detailed docs](./cmd/prometheus/Readme.md). -### +### + old data Disabled by default. To enable see `./build/bin/erigon --help` for flags `--prune` @@ -518,7 +529,7 @@ FAQ Detailed explanation: [./docs/programmers_guide/db_faq.md](./docs/programmers_guide/db_faq.md) -### Default Ports and Protocols / Firewalls? +### Default Ports and Firewalls #### `erigon` ports @@ -558,12 +569,11 @@ Port #### `sentinel` ports -| Port | Protocol | Purpose | Expose | -|:-----:|:---------:|:----------------:|:-------:| -| 4000 | UDP | Peering | Public | -| 4001 | TCP | Peering | Public | -| 7777 | TCP | gRPC Connections | Private | - +| Port | Protocol | Purpose | Expose | +|:----:|:--------:|:----------------:|:-------:| +| 4000 | UDP | Peering | Public | +| 4001 | TCP | Peering | Public | +| 7777 | TCP | gRPC Connections | Private | #### Other ports @@ -577,12 +587,13 @@ you'll have to change one if you want to run both at the same time. use `--help` Reserved for future use: **gRPC ports**: `9092` consensus engine, `9093` snapshot downloader, `9094` TxPool -Hetzner may want strict firewall rules, like: +#### Hetzner expecting strict firewall rules + ``` 0.0.0.0/8 "This" Network RFC 1122, Section 3.2.1.3 10.0.0.0/8 Private-Use Networks RFC 1918 100.64.0.0/10 Carrier-Grade NAT (CGN) RFC 6598, Section 7 -127.0.0.0/8 Loopback RFC 1122, Section 3.2.1.3 +127.16.0.0/12 Private-Use Networks RFC 1918 169.254.0.0/16 Link Local RFC 3927 172.16.0.0/12 Private-Use Networks RFC 1918 192.0.0.0/24 IETF Protocol Assignments RFC 5736 @@ -599,6 +610,8 @@ Hetzner may want strict firewall rules, like: RFC 922, Section 7 ``` +Same in [IpTables syntax](https://ethereum.stackexchange.com/questions/6386/how-to-prevent-being-blacklisted-for-running-an-ethereum-client/13068#13068) + ### How to get diagnostic for bug report? - Get stack trace: `kill -SIGUSR1 `, get trace and stop: `kill -6 ` diff --git a/accounts/abi/bind/backends/simulated.go b/accounts/abi/bind/backends/simulated.go index 69a8238f46a..3c401323422 100644 --- a/accounts/abi/bind/backends/simulated.go +++ b/accounts/abi/bind/backends/simulated.go @@ -32,6 +32,7 @@ import ( "github.com/ledgerwatch/erigon-lib/kv" state2 "github.com/ledgerwatch/erigon-lib/state" types2 "github.com/ledgerwatch/erigon-lib/types" + "github.com/ledgerwatch/erigon/eth/ethconfig" "github.com/ledgerwatch/log/v3" ethereum "github.com/ledgerwatch/erigon" @@ -46,10 +47,8 @@ import ( "github.com/ledgerwatch/erigon/core/state" "github.com/ledgerwatch/erigon/core/types" "github.com/ledgerwatch/erigon/core/vm" - "github.com/ledgerwatch/erigon/ethdb/olddb" "github.com/ledgerwatch/erigon/event" "github.com/ledgerwatch/erigon/params" - "github.com/ledgerwatch/erigon/rpc" "github.com/ledgerwatch/erigon/turbo/snapshotsync" "github.com/ledgerwatch/erigon/turbo/stages" ) @@ -79,6 +78,7 @@ type SimulatedBackend struct { gasPool *core.GasPool pendingBlock *types.Block // Currently pending block that will be imported on request pendingReader *state.PlainStateReader + pendingReaderTx kv.Tx pendingState *state.IntraBlockState // Currently pending state that will be the active on request rmLogsFeed event.Feed @@ -88,8 +88,8 @@ type SimulatedBackend struct { // NewSimulatedBackend creates a new binding backend using a simulated blockchain // for testing purposes. -func NewSimulatedBackendWithConfig(alloc core.GenesisAlloc, config *chain.Config, gasLimit uint64) *SimulatedBackend { - genesis := core.Genesis{Config: config, GasLimit: gasLimit, Alloc: alloc} +func NewSimulatedBackendWithConfig(alloc types.GenesisAlloc, config *chain.Config, gasLimit uint64) *SimulatedBackend { + genesis := types.Genesis{Config: config, GasLimit: gasLimit, Alloc: alloc} engine := ethash.NewFaker() m := stages.MockWithGenesisEngine(nil, &genesis, engine, false) backend := &SimulatedBackend{ @@ -110,25 +110,15 @@ func NewSimulatedBackendWithConfig(alloc core.GenesisAlloc, config *chain.Config } // A simulated backend always uses chainID 1337. -func NewSimulatedBackend(t *testing.T, alloc core.GenesisAlloc, gasLimit uint64) *SimulatedBackend { +func NewSimulatedBackend(t *testing.T, alloc types.GenesisAlloc, gasLimit uint64) *SimulatedBackend { b := NewSimulatedBackendWithConfig(alloc, params.TestChainConfig, gasLimit) - t.Cleanup(func() { - b.Close() - }) - if b.m.HistoryV3 { - t.Skip("TODO: Fixme") - } + t.Cleanup(b.Close) return b } -func NewTestSimulatedBackendWithConfig(t *testing.T, alloc core.GenesisAlloc, config *chain.Config, gasLimit uint64) *SimulatedBackend { +func NewTestSimulatedBackendWithConfig(t *testing.T, alloc types.GenesisAlloc, config *chain.Config, gasLimit uint64) *SimulatedBackend { b := NewSimulatedBackendWithConfig(alloc, config, gasLimit) - t.Cleanup(func() { - b.Close() - }) - if b.m.HistoryV3 { - t.Skip("TODO: Fixme") - } + t.Cleanup(b.Close) return b } func (b *SimulatedBackend) DB() kv.RwDB { return b.m.DB } @@ -141,6 +131,9 @@ func (b *SimulatedBackend) Engine() consensus.Engine { return b.m.Engine } // Close terminates the underlying blockchain's update loop. func (b *SimulatedBackend) Close() { + if b.pendingReaderTx != nil { + b.pendingReaderTx.Rollback() + } b.m.Close() } @@ -180,18 +173,29 @@ func (b *SimulatedBackend) emptyPendingBlock() { b.pendingReceipts = chain.Receipts[0] b.pendingHeader = chain.Headers[0] b.gasPool = new(core.GasPool).AddGas(b.pendingHeader.GasLimit) - b.pendingReader = state.NewPlainStateReader(olddb.NewObjectDatabase(b.m.DB)) + if b.pendingReaderTx != nil { + b.pendingReaderTx.Rollback() + } + tx, err := b.m.DB.BeginRo(context.Background()) + if err != nil { + panic(err) + } + b.pendingReaderTx = tx + if ethconfig.EnableHistoryV4InTest { + panic("implement me") + //b.pendingReader = state.NewReaderV4(b.pendingReaderTx.(kv.TemporalTx)) + } else { + b.pendingReader = state.NewPlainStateReader(b.pendingReaderTx) + } b.pendingState = state.New(b.pendingReader) } // stateByBlockNumber retrieves a state by a given blocknumber. func (b *SimulatedBackend) stateByBlockNumber(db kv.Tx, blockNumber *big.Int) *state.IntraBlockState { if blockNumber == nil || blockNumber.Cmp(b.pendingBlock.Number()) == 0 { - return state.New(state.NewPlainState(db, b.pendingBlock.NumberU64()+1, nil)) - //return state.New(b.m.NewHistoryStateReader(b.pendingBlock.NumberU64()+1, db)) + return state.New(b.m.NewHistoryStateReader(b.pendingBlock.NumberU64()+1, db)) } - return state.New(state.NewPlainState(db, blockNumber.Uint64()+1, nil)) - //return state.New(b.m.NewHistoryStateReader(blockNumber.Uint64()+1, db)) + return state.New(b.m.NewHistoryStateReader(blockNumber.Uint64()+1, db)) } // CodeAt returns the code associated with a certain account in the blockchain. @@ -570,9 +574,9 @@ func (b *SimulatedBackend) EstimateGas(ctx context.Context, call ethereum.CallMs // Determine the lowest and highest possible gas limits to binary search in between var ( - lo = params.TxGas - 1 - hi uint64 - cap uint64 + lo = params.TxGas - 1 + hi uint64 + gasCap uint64 ) if call.Gas >= params.TxGas { hi = call.Gas @@ -600,7 +604,7 @@ func (b *SimulatedBackend) EstimateGas(ctx context.Context, call ethereum.CallMs hi = allowance.Uint64() } } - cap = hi + gasCap = hi b.pendingState.Prepare(libcommon.Hash{}, libcommon.Hash{}, len(b.pendingBlock.Transactions())) // Create a helper to check if a gas allowance results in an executable transaction @@ -637,7 +641,7 @@ func (b *SimulatedBackend) EstimateGas(ctx context.Context, call ethereum.CallMs } } // Reject the transaction as invalid if it still fails at the highest allowance - if hi == cap { + if hi == gasCap { failed, result, err := executable(hi) if err != nil { return 0, err @@ -650,7 +654,7 @@ func (b *SimulatedBackend) EstimateGas(ctx context.Context, call ethereum.CallMs return 0, result.Err } // Otherwise, the specified gas cap is too low - return 0, fmt.Errorf("gas required exceeds allowance (%d)", cap) + return 0, fmt.Errorf("gas required exceeds allowance (%d)", gasCap) } } return hi, nil @@ -684,7 +688,8 @@ func (b *SimulatedBackend) callContract(_ context.Context, call ethereum.CallMsg txContext := core.NewEVMTxContext(msg) header := block.Header() - evmContext := core.NewEVMBlockContext(header, core.GetHashFn(header, b.getHeader), b.m.Engine, nil) + excessDataGas := header.ParentExcessDataGas(b.getHeader) + evmContext := core.NewEVMBlockContext(header, core.GetHashFn(header, b.getHeader), b.m.Engine, nil, excessDataGas) // Create a new environment which holds all relevant information // about the transaction and calling mechanisms. vmEnv := vm.NewEVM(evmContext, txContext, statedb, b.m.ChainConfig, vm.Config{}) @@ -717,7 +722,8 @@ func (b *SimulatedBackend) SendTransaction(ctx context.Context, tx types.Transac &b.pendingHeader.Coinbase, b.gasPool, b.pendingState, state.NewNoopWriter(), b.pendingHeader, tx, - &b.pendingHeader.GasUsed, vm.Config{}); err != nil { + &b.pendingHeader.GasUsed, vm.Config{}, + b.pendingHeader.ParentExcessDataGas(b.getHeader)); err != nil { return err } //fmt.Printf("==== Start producing block %d\n", (b.prependBlock.NumberU64() + 1)) @@ -799,6 +805,11 @@ func (m callMsg) Data() []byte { return m.CallMsg.Data } func (m callMsg) AccessList() types2.AccessList { return m.CallMsg.AccessList } func (m callMsg) IsFree() bool { return false } +func (m callMsg) DataGas() uint64 { return params.DataGasPerBlob * uint64(len(m.CallMsg.DataHashes)) } +func (m callMsg) MaxFeePerDataGas() *uint256.Int { return m.CallMsg.MaxFeePerDataGas } +func (m callMsg) DataHashes() []libcommon.Hash { return m.CallMsg.DataHashes } + +/* // filterBackend implements filters.Backend to support filtering for logs without // taking bloom-bits acceleration structures into account. type filterBackend struct { @@ -895,3 +906,4 @@ func nullSubscription() event.Subscription { return nil }) } +*/ diff --git a/accounts/abi/bind/backends/simulated_test.go b/accounts/abi/bind/backends/simulated_test.go index 2e984e3db71..a42141eb36b 100644 --- a/accounts/abi/bind/backends/simulated_test.go +++ b/accounts/abi/bind/backends/simulated_test.go @@ -36,7 +36,6 @@ import ( "github.com/ledgerwatch/erigon/common/u256" "github.com/ledgerwatch/erigon/core" "github.com/ledgerwatch/erigon/core/rawdb" - "github.com/ledgerwatch/erigon/core/state" "github.com/ledgerwatch/erigon/core/types" "github.com/ledgerwatch/erigon/crypto" "github.com/ledgerwatch/erigon/params" @@ -148,8 +147,7 @@ func TestNewSimulatedBackend(t *testing.T) { t.Fatal(err) } - //statedb := sim.stateByBlockNumber(tx, big.NewInt(int64(num+1))) - statedb := state.New(state.NewPlainState(tx, num+1, nil)) + statedb := sim.stateByBlockNumber(tx, big.NewInt(int64(num+1))) bal := statedb.GetBalance(testAddr) if !bal.Eq(expectedBal) { t.Errorf("expected balance for test address not received. expected: %v actual: %v", expectedBal, bal) diff --git a/accounts/abi/bind/bind_test.go b/accounts/abi/bind/bind_test.go index c0778687809..4c3f2be0cb4 100644 --- a/accounts/abi/bind/bind_test.go +++ b/accounts/abi/bind/bind_test.go @@ -1849,11 +1849,18 @@ func TestGolangBindings(t *testing.T) { t.Fatalf("failed to replace binding test dependency to current source tree: %v\n%s", err, out) } - replacer = exec.Command(gocmd, "mod", "edit", "-x", "-require", "github.com/tendermint/tendermint@v0.0.0", "-replace", "github.com/tendermint/tendermint=github.com/bnb-chain/tendermint@v0.31.12") // Repo root + replacer = exec.Command(gocmd, "mod", "edit", "-x", "-require", "github.com/tendermint/tendermint@v0.0.0", "-replace", "github.com/tendermint/tendermint=github.com/bnb-chain/tendermint@v0.31.15") // Repo root replacer.Dir = pkg if out, err := replacer.CombinedOutput(); err != nil { t.Fatalf("failed to replace tendermint dependency to bnb-chain source: %v\n%s", err, out) } + + replacer = exec.Command(gocmd, "mod", "edit", "-x", "-require", "github.com/cometbft/cometbft@v0.0.0", "-replace", "github.com/cometbft/cometbft=github.com/bnb-chain/greenfield-tendermint@v0.0.0-20230417032003-4cda1f296fb2") // Repo root + replacer.Dir = pkg + if out, err := replacer.CombinedOutput(); err != nil { + t.Fatalf("failed to replace cometbft dependency to bnb-chain source: %v\n%s", err, out) + } + tidier := exec.Command(gocmd, "mod", "tidy") tidier.Dir = pkg if out, err := tidier.CombinedOutput(); err != nil { diff --git a/cl/clparams/config.go b/cl/clparams/config.go index 343efceb58e..49fed33a99e 100644 --- a/cl/clparams/config.go +++ b/cl/clparams/config.go @@ -68,21 +68,6 @@ var ( "enr:-LK4QA8FfhaAjlb_BXsXxSfiysR7R52Nhi9JBt4F8SPssu8hdE1BXQQEtVDC3qStCW60LSO7hEsVHv5zm8_6Vnjhcn0Bh2F0dG5ldHOIAAAAAAAAAACEZXRoMpC1MD8qAAAAAP__________gmlkgnY0gmlwhAN4aBKJc2VjcDI1NmsxoQJerDhsJ-KxZ8sHySMOCmTO6sHM3iCFQ6VMvLTe948MyYN0Y3CCI4yDdWRwgiOM", "enr:-LK4QKWrXTpV9T78hNG6s8AM6IO4XH9kFT91uZtFg1GcsJ6dKovDOr1jtAAFPnS2lvNltkOGA9k29BUN7lFh_sjuc9QBh2F0dG5ldHOIAAAAAAAAAACEZXRoMpC1MD8qAAAAAP__________gmlkgnY0gmlwhANAdd-Jc2VjcDI1NmsxoQLQa6ai7y9PMN5hpLe5HmiJSlYzMuzP7ZhwRiwHvqNXdoN0Y3CCI4yDdWRwgiOM", } - GoerliBootstrapNodes = []string{ - "enr:-Ku4QFmUkNp0g9bsLX2PfVeIyT-9WO-PZlrqZBNtEyofOOfLMScDjaTzGxIb1Ns9Wo5Pm_8nlq-SZwcQfTH2cgO-s88Bh2F0dG5ldHOIAAAAAAAAAACEZXRoMpDkvpOTAAAQIP__________gmlkgnY0gmlwhBLf22SJc2VjcDI1NmsxoQLV_jMOIxKbjHFKgrkFvwDvpexo6Nd58TK5k7ss4Vt0IoN1ZHCCG1g", - "enr:-LK4QH1xnjotgXwg25IDPjrqRGFnH1ScgNHA3dv1Z8xHCp4uP3N3Jjl_aYv_WIxQRdwZvSukzbwspXZ7JjpldyeVDzMCh2F0dG5ldHOIAAAAAAAAAACEZXRoMpB53wQoAAAQIP__________gmlkgnY0gmlwhIe1te-Jc2VjcDI1NmsxoQOkcGXqbCJYbcClZ3z5f6NWhX_1YPFRYRRWQpJjwSHpVIN0Y3CCIyiDdWRwgiMo", - "enr:-Ly4QFPk-cTMxZ3jWTafiNblEZkQIXGF2aVzCIGW0uHp6KaEAvBMoctE8S7YU0qZtuS7By0AA4YMfKoN9ls_GJRccVpFh2F0dG5ldHOI__________-EZXRoMpCC9KcrAgAQIIS2AQAAAAAAgmlkgnY0gmlwhKh3joWJc2VjcDI1NmsxoQKrxz8M1IHwJqRIpDqdVW_U1PeixMW5SfnBD-8idYIQrIhzeW5jbmV0cw-DdGNwgiMog3VkcIIjKA", - "enr:-L64QJmwSDtaHVgGiqIxJWUtxWg6uLCipsms6j-8BdsOJfTWAs7CLF9HJnVqFE728O-JYUDCxzKvRdeMqBSauHVCMdaCAVWHYXR0bmV0c4j__________4RldGgykIL0pysCABAghLYBAAAAAACCaWSCdjSCaXCEQWxOdolzZWNwMjU2azGhA7Qmod9fK86WidPOzLsn5_8QyzL7ZcJ1Reca7RnD54vuiHN5bmNuZXRzD4N0Y3CCIyiDdWRwgiMo", - "enr:-KG4QCIzJZTY_fs_2vqWEatJL9RrtnPwDCv-jRBuO5FQ2qBrfJubWOWazri6s9HsyZdu-fRUfEzkebhf1nvO42_FVzwDhGV0aDKQed8EKAAAECD__________4JpZIJ2NIJpcISHtbYziXNlY3AyNTZrMaED4m9AqVs6F32rSCGsjtYcsyfQE2K8nDiGmocUY_iq-TSDdGNwgiMog3VkcIIjKA", - } - - SepoliaBootstrapNodes = []string{ - // EF boot nodes - "enr:-Iq4QMCTfIMXnow27baRUb35Q8iiFHSIDBJh6hQM5Axohhf4b6Kr_cOCu0htQ5WvVqKvFgY28893DHAg8gnBAXsAVqmGAX53x8JggmlkgnY0gmlwhLKAlv6Jc2VjcDI1NmsxoQK6S-Cii_KmfFdUJL2TANL3ksaKUnNXvTCv1tLwXs0QgIN1ZHCCIyk", - "enr:-KG4QE5OIg5ThTjkzrlVF32WT_-XT14WeJtIz2zoTqLLjQhYAmJlnk4ItSoH41_2x0RX0wTFIe5GgjRzU2u7Q1fN4vADhGV0aDKQqP7o7pAAAHAyAAAAAAAAAIJpZIJ2NIJpcISlFsStiXNlY3AyNTZrMaEC-Rrd_bBZwhKpXzFCrStKp1q_HmGOewxY3KwM8ofAj_ODdGNwgiMog3VkcIIjKA", - // Teku boot node - "enr:-Ly4QFoZTWR8ulxGVsWydTNGdwEESueIdj-wB6UmmjUcm-AOPxnQi7wprzwcdo7-1jBW_JxELlUKJdJES8TDsbl1EdNlh2F0dG5ldHOI__78_v2bsV-EZXRoMpA2-lATkAAAcf__________gmlkgnY0gmlwhBLYJjGJc2VjcDI1NmsxoQI0gujXac9rMAb48NtMqtSTyHIeNYlpjkbYpWJw46PmYYhzeW5jbmV0cw-DdGNwgiMog3VkcIIjKA", - } GnosisBootstrapNodes = []string{ "enr:-Ly4QMU1y81COwm1VZgxGF4_eZ21ub9-GHF6dXZ29aEJ0oZpcV2Rysw-viaEKfpcpu9ZarILJLxFZjcKOjE0Sybs3MQBh2F0dG5ldHOIAAAAAAAAAACEZXRoMpCCS-QxAgAAZP__________gmlkgnY0gmlwhANLnx-Jc2VjcDI1NmsxoQKoaYT8I-wf2I_f_ii6EgoSSXj5T3bhiDyW-7ZLsY3T64hzeW5jbmV0cwCDdGNwgiMog3VkcIIjKA", @@ -174,7 +159,7 @@ var NetworkConfigs map[NetworkType]NetworkConfig = map[NetworkType]NetworkConfig SyncCommsSubnetKey: "syncnets", MinimumPeersInSubnetSearch: 20, ContractDeploymentBlock: 1273020, - BootNodes: SepoliaBootstrapNodes, + BootNodes: MainnetBootstrapNodes, }, GoerliNetwork: { @@ -194,7 +179,7 @@ var NetworkConfigs map[NetworkType]NetworkConfig = map[NetworkType]NetworkConfig SyncCommsSubnetKey: "syncnets", MinimumPeersInSubnetSearch: 20, ContractDeploymentBlock: 4367322, - BootNodes: GoerliBootstrapNodes, + BootNodes: MainnetBootstrapNodes, }, GnosisNetwork: { @@ -266,18 +251,18 @@ var CheckpointSyncEndpoints = map[NetworkType][]string{ MainnetNetwork: { "https://sync.invis.tools/eth/v2/debug/beacon/states/finalized", "https://mainnet-checkpoint-sync.attestant.io/eth/v2/debug/beacon/states/finalized", - "https://mainnet.checkpoint.sigp.io/eth/v2/debug/beacon/states/finalized", + //"https://mainnet.checkpoint.sigp.io/eth/v2/debug/beacon/states/finalized", "https://mainnet-checkpoint-sync.stakely.io/eth/v2/debug/beacon/states/finalized", "https://checkpointz.pietjepuk.net/eth/v2/debug/beacon/states/finalized", }, GoerliNetwork: { "https://goerli.beaconstate.info/eth/v2/debug/beacon/states/finalized", "https://goerli-sync.invis.tools/eth/v2/debug/beacon/states/finalized", - "https://goerli.checkpoint-sync.ethdevops.io/eth/v2/debug/beacon/states/finalized", + "https://goerli.checkpoint-sync.ethpandaops.io/eth/v2/debug/beacon/states/finalized", "https://prater-checkpoint-sync.stakely.io/eth/v2/debug/beacon/states/finalized", }, SepoliaNetwork: { - "https://sepolia.checkpoint-sync.ethdevops.io/eth/v2/debug/beacon/states/finalized", + "https://checkpoint-sync.sepolia.ethpandaops.io/eth/v2/debug/beacon/states/finalized", "https://sepolia.beaconstate.info/eth/v2/debug/beacon/states/finalized", }, GnosisNetwork: { @@ -670,9 +655,9 @@ var MainnetBeaconConfig BeaconChainConfig = BeaconChainConfig{ AltairForkVersion: 0x01000000, AltairForkEpoch: 74240, BellatrixForkVersion: 0x02000000, - BellatrixForkEpoch: 144869, + BellatrixForkEpoch: 144896, CapellaForkVersion: 0x03000000, - CapellaForkEpoch: math.MaxUint64, + CapellaForkEpoch: 194048, DenebForkVersion: 0x04000000, DenebForkEpoch: math.MaxUint64, diff --git a/cl/cltypes/attestations.go b/cl/cltypes/attestations.go index 24e11980082..e418197fe57 100644 --- a/cl/cltypes/attestations.go +++ b/cl/cltypes/attestations.go @@ -7,9 +7,8 @@ import ( libcommon "github.com/ledgerwatch/erigon-lib/common" "github.com/ledgerwatch/erigon-lib/common/length" - ssz "github.com/prysmaticlabs/fastssz" - "github.com/ledgerwatch/erigon/cl/cltypes/ssz_utils" + "github.com/ledgerwatch/erigon/cl/cltypes/ssz" "github.com/ledgerwatch/erigon/cl/merkle_tree" "github.com/ledgerwatch/erigon/common" ) @@ -271,7 +270,7 @@ func rebuildAggregationBits(buf []byte) (n int, ret []byte) { // MarshalSSZTo ssz marshals the Attestation object to a target array func (a *Attestation) EncodeSSZ(buf []byte) (dst []byte, err error) { dst = buf - dst = append(dst, ssz_utils.OffsetSSZ(228)...) + dst = append(dst, ssz.OffsetSSZ(228)...) if dst, err = a.Data.EncodeSSZ(dst); err != nil { return @@ -291,7 +290,7 @@ func (a *Attestation) DecodeSSZ(buf []byte) error { var err error size := uint64(len(buf)) if size < 228 { - return ssz_utils.ErrLowBufferSize + return ssz.ErrLowBufferSize } tail := buf @@ -308,16 +307,14 @@ func (a *Attestation) DecodeSSZ(buf []byte) error { copy(a.Signature[:], buf[132:228]) // Field (0) 'AggregationBits' - { - buf = tail[228:] - if err = ssz.ValidateBitlist(buf, 2048); err != nil { - return err - } - if cap(a.AggregationBits) == 0 { - a.AggregationBits = make([]byte, 0, len(buf)) - } - a.AggregationBits = append(a.AggregationBits, buf...) + + buf = tail[228:] + + if cap(a.AggregationBits) == 0 { + a.AggregationBits = make([]byte, 0, len(buf)) } + a.AggregationBits = append(a.AggregationBits, buf...) + return err } @@ -367,7 +364,7 @@ type IndexedAttestation struct { func (i *IndexedAttestation) EncodeSSZ(buf []byte) (dst []byte, err error) { dst = buf // Write indicies offset. - dst = append(dst, ssz_utils.OffsetSSZ(228)...) + dst = append(dst, ssz.OffsetSSZ(228)...) // Process data field. if dst, err = i.Data.EncodeSSZ(dst); err != nil { @@ -381,7 +378,7 @@ func (i *IndexedAttestation) EncodeSSZ(buf []byte) (dst []byte, err error) { return nil, errors.New("too bing attesting indices") } for _, index := range i.AttestingIndices { - dst = append(dst, ssz_utils.Uint64SSZ(index)...) + dst = append(dst, ssz.Uint64SSZ(index)...) } return @@ -392,7 +389,7 @@ func (i *IndexedAttestation) DecodeSSZ(buf []byte) error { var err error size := uint64(len(buf)) if size < 228 { - return ssz_utils.ErrLowBufferSize + return ssz.ErrLowBufferSize } i.Data = new(AttestationData) @@ -404,15 +401,15 @@ func (i *IndexedAttestation) DecodeSSZ(buf []byte) error { bitsBuf := buf[228:] num := len(bitsBuf) / 8 if len(bitsBuf)%8 != 0 { - return ssz_utils.ErrBufferNotRounded + return ssz.ErrBufferNotRounded } if num > 2048 { - return ssz_utils.ErrBadDynamicLength + return ssz.ErrBadDynamicLength } i.AttestingIndices = make([]uint64, num) for index := 0; index < num; index++ { - i.AttestingIndices[index] = ssz_utils.UnmarshalUint64SSZ(bitsBuf[index*8:]) + i.AttestingIndices[index] = ssz.UnmarshalUint64SSZ(bitsBuf[index*8:]) } return nil } @@ -426,7 +423,7 @@ func (i *IndexedAttestation) EncodingSizeSSZ() int { func (i *IndexedAttestation) HashSSZ() ([32]byte, error) { leaves := make([][32]byte, 3) var err error - leaves[0], err = merkle_tree.Uint64ListRootWithLimit(i.AttestingIndices, ssz_utils.CalculateIndiciesLimit(2048, uint64(len(i.AttestingIndices)), 8)) + leaves[0], err = merkle_tree.Uint64ListRootWithLimit(i.AttestingIndices, ssz.CalculateIndiciesLimit(2048, uint64(len(i.AttestingIndices)), 8)) if err != nil { return [32]byte{}, err } @@ -461,8 +458,8 @@ func (a *AttestationData) Equal(other *AttestationData) bool { func (a *AttestationData) EncodeSSZ(dst []byte) ([]byte, error) { buf := dst var err error - buf = append(buf, ssz_utils.Uint64SSZ(a.Slot)...) - buf = append(buf, ssz_utils.Uint64SSZ(a.Index)...) + buf = append(buf, ssz.Uint64SSZ(a.Slot)...) + buf = append(buf, ssz.Uint64SSZ(a.Index)...) buf = append(buf, a.BeaconBlockHash[:]...) if buf, err = a.Source.EncodeSSZ(buf); err != nil { return nil, err @@ -475,11 +472,11 @@ func (a *AttestationData) DecodeSSZ(buf []byte) error { var err error size := uint64(len(buf)) if size != uint64(a.EncodingSizeSSZ()) { - return ssz_utils.ErrLowBufferSize + return ssz.ErrLowBufferSize } - a.Slot = ssz_utils.UnmarshalUint64SSZ(buf) - a.Index = ssz_utils.UnmarshalUint64SSZ(buf[8:]) + a.Slot = ssz.UnmarshalUint64SSZ(buf) + a.Index = ssz.UnmarshalUint64SSZ(buf[8:]) copy(a.BeaconBlockHash[:], buf[16:48]) a.Source = new(Checkpoint) @@ -497,7 +494,7 @@ func (a *AttestationData) DecodeSSZ(buf []byte) error { // EncodingSizeSSZ returns the ssz encoded size in bytes for the AttestationData object func (a *AttestationData) EncodingSizeSSZ() int { - return 2*common.BlockNumberLength + length.Hash + a.Source.EncodingSizeSSZ() + a.Target.EncodingSizeSSZ() + return 2*common.BlockNumberLength + length.Hash + 40 + 40 } // HashSSZ ssz hashes the AttestationData object @@ -518,3 +515,96 @@ func (a *AttestationData) HashSSZ() ([32]byte, error) { targetRoot, }, 8) } + +// Pending attestation. (only in Phase0 state) +type PendingAttestation struct { + AggregationBits []byte + Data *AttestationData + InclusionDelay uint64 + ProposerIndex uint64 +} + +// MarshalSSZTo ssz marshals the Attestation object to a target array +func (a *PendingAttestation) EncodeSSZ(buf []byte) (dst []byte, err error) { + dst = buf + dst = append(dst, ssz.OffsetSSZ(148)...) + if dst, err = a.Data.EncodeSSZ(dst); err != nil { + return + } + dst = append(dst, ssz.Uint64SSZ(a.InclusionDelay)...) + dst = append(dst, ssz.Uint64SSZ(a.ProposerIndex)...) + + if len(a.AggregationBits) > 2048 { + return nil, fmt.Errorf("too many aggregation bits in attestation") + } + dst = append(dst, a.AggregationBits...) + + return +} + +// DecodeSSZ ssz unmarshals the Attestation object +func (a *PendingAttestation) DecodeSSZ(buf []byte) error { + var err error + if len(buf) < a.EncodingSizeSSZ() { + return ssz.ErrLowBufferSize + } + + tail := buf + + // Field (1) 'Data' + if a.Data == nil { + a.Data = new(AttestationData) + } + if err = a.Data.DecodeSSZ(buf[4:132]); err != nil { + return err + } + + a.InclusionDelay = ssz.UnmarshalUint64SSZ(buf[132:]) + a.ProposerIndex = ssz.UnmarshalUint64SSZ(buf[140:]) + + buf = tail[148:] + + if cap(a.AggregationBits) == 0 { + a.AggregationBits = make([]byte, 0, len(buf)) + } + a.AggregationBits = append(a.AggregationBits, buf...) + + return err +} + +func (a *PendingAttestation) DecodeSSZWithVersion(buf []byte, _ int) error { + return a.DecodeSSZ(buf) +} + +// EncodingSizeSSZ returns the ssz encoded size in bytes for the Attestation object +func (a *PendingAttestation) EncodingSizeSSZ() int { + return 148 + len(a.AggregationBits) +} + +// HashSSZ ssz hashes the Attestation object +func (a *PendingAttestation) HashSSZ() ([32]byte, error) { + leaves := make([][32]byte, 4) + var err error + if a.Data == nil { + return [32]byte{}, fmt.Errorf("missing attestation data") + } + leaves[0], err = merkle_tree.BitlistRootWithLimit(a.AggregationBits, 2048) + if err != nil { + return [32]byte{}, err + } + + leaves[1], err = a.Data.HashSSZ() + if err != nil { + return [32]byte{}, err + } + + leaves[2] = merkle_tree.Uint64Root(a.InclusionDelay) + leaves[3] = merkle_tree.Uint64Root(a.ProposerIndex) + + return merkle_tree.ArraysRoot(leaves, 4) +} + +func IsSlashableAttestationData(d1, d2 *AttestationData) bool { + return (!d1.Equal(d2) && d1.Target.Epoch == d2.Target.Epoch) || + (d1.Source.Epoch < d2.Source.Epoch && d2.Target.Epoch < d1.Target.Epoch) +} diff --git a/cl/cltypes/beacon_header.go b/cl/cltypes/beacon_header.go index 67e92b41a8e..5576cd31785 100644 --- a/cl/cltypes/beacon_header.go +++ b/cl/cltypes/beacon_header.go @@ -20,6 +20,10 @@ type BeaconBlockHeader struct { BodyRoot libcommon.Hash } +func (b *BeaconBlockHeader) Copy() *BeaconBlockHeader { + copied := *b + return &copied +} func (b *BeaconBlockHeader) EncodeSSZ(dst []byte) ([]byte, error) { buf := dst buf = append(buf, ssz_utils.Uint64SSZ(b.Slot)...) diff --git a/cl/cltypes/checkpoint.go b/cl/cltypes/checkpoint.go index f5dcde87e51..0f007b8f6f5 100644 --- a/cl/cltypes/checkpoint.go +++ b/cl/cltypes/checkpoint.go @@ -4,7 +4,7 @@ import ( libcommon "github.com/ledgerwatch/erigon-lib/common" "github.com/ledgerwatch/erigon-lib/common/length" - "github.com/ledgerwatch/erigon/cl/cltypes/ssz_utils" + "github.com/ledgerwatch/erigon/cl/cltypes/ssz" "github.com/ledgerwatch/erigon/cl/merkle_tree" ) @@ -13,21 +13,31 @@ type Checkpoint struct { Root libcommon.Hash } +func (c *Checkpoint) DecodeSSZWithVersion(buf []byte, _ int) error { + return c.DecodeSSZ(buf) +} + +func (c *Checkpoint) Copy() *Checkpoint { + copiedCheckpoint := new(Checkpoint) + *copiedCheckpoint = *c + return copiedCheckpoint +} + func (c *Checkpoint) Equal(other *Checkpoint) bool { return c.Epoch == other.Epoch && c.Root == other.Root } func (c *Checkpoint) EncodeSSZ(buf []byte) ([]byte, error) { - return append(buf, append(ssz_utils.Uint64SSZ(c.Epoch), c.Root[:]...)...), nil + return append(buf, append(ssz.Uint64SSZ(c.Epoch), c.Root[:]...)...), nil } func (c *Checkpoint) DecodeSSZ(buf []byte) error { var err error size := uint64(len(buf)) if size < uint64(c.EncodingSizeSSZ()) { - return ssz_utils.ErrLowBufferSize + return ssz.ErrLowBufferSize } - c.Epoch = ssz_utils.UnmarshalUint64SSZ(buf[0:8]) + c.Epoch = ssz.UnmarshalUint64SSZ(buf[0:8]) copy(c.Root[:], buf[8:40]) return err diff --git a/cl/cltypes/clone.go b/cl/cltypes/clone.go index d943b96d70b..50d780b0bd9 100644 --- a/cl/cltypes/clone.go +++ b/cl/cltypes/clone.go @@ -54,14 +54,6 @@ func (*AttesterSlashing) Clone() clonable.Clonable { return &AttesterSlashing{} } -func (*LightClientFinalityUpdate) Clone() clonable.Clonable { - return &LightClientFinalityUpdate{} -} - -func (*LightClientOptimisticUpdate) Clone() clonable.Clonable { - return &LightClientOptimisticUpdate{} -} - func (*Metadata) Clone() clonable.Clonable { return &Metadata{} } @@ -74,14 +66,6 @@ func (*Deposit) Clone() clonable.Clonable { return &Deposit{} } -func (*LightClientBootstrap) Clone() clonable.Clonable { - return &LightClientBootstrap{} -} - func (*BeaconBlock) Clone() clonable.Clonable { return &BeaconBlock{} } - -func (*LightClientUpdate) Clone() clonable.Clonable { - return &LightClientUpdate{} -} diff --git a/cl/cltypes/eth1_block.go b/cl/cltypes/eth1_block.go index 1be3ce582fe..1da0c7d5db6 100644 --- a/cl/cltypes/eth1_block.go +++ b/cl/cltypes/eth1_block.go @@ -2,81 +2,181 @@ package cltypes import ( "fmt" + "math/big" libcommon "github.com/ledgerwatch/erigon-lib/common" "github.com/ledgerwatch/erigon/cl/clparams" - "github.com/ledgerwatch/erigon/cl/cltypes/ssz_utils" + "github.com/ledgerwatch/erigon/cl/cltypes/ssz" "github.com/ledgerwatch/erigon/cl/merkle_tree" "github.com/ledgerwatch/erigon/common" + "github.com/ledgerwatch/erigon/consensus/serenity" "github.com/ledgerwatch/erigon/core/types" ) // ETH1Block represents a block structure CL-side. type Eth1Block struct { - Header *types.Header - // Transactions can be kept in bytes. - Body *types.RawBody + ParentHash libcommon.Hash + FeeRecipient libcommon.Address + StateRoot libcommon.Hash + ReceiptsRoot libcommon.Hash + LogsBloom types.Bloom + PrevRandao libcommon.Hash + BlockNumber uint64 + GasLimit uint64 + GasUsed uint64 + Time uint64 + Extra []byte + BaseFeePerGas [32]byte + // Extra fields + BlockHash libcommon.Hash + Transactions [][]byte + Withdrawals types.Withdrawals + // internals + version clparams.StateVersion } -func (b *Eth1Block) NumberU64() uint64 { - return b.Header.Number.Uint64() +// NewEth1Block creates a new Eth1Block. +func NewEth1Block(version clparams.StateVersion) *Eth1Block { + return &Eth1Block{version: version} } -func (b *Eth1Block) Withdrawals() types.Withdrawals { - return types.Withdrawals(b.Body.Withdrawals) -} +// NewEth1BlockFromHeaderAndBody with given header/body. +func NewEth1BlockFromHeaderAndBody(header *types.Header, body *types.RawBody) *Eth1Block { + baseFeeBytes := header.BaseFee.Bytes() + for i, j := 0, len(baseFeeBytes)-1; i < j; i, j = i+1, j-1 { + baseFeeBytes[i], baseFeeBytes[j] = baseFeeBytes[j], baseFeeBytes[i] + } + var baseFee32 [32]byte + copy(baseFee32[:], baseFeeBytes) -func (b *Eth1Block) EncodingSizeSSZ(version clparams.StateVersion) (size int) { - size = 508 + block := &Eth1Block{ + ParentHash: header.ParentHash, + FeeRecipient: header.Coinbase, + StateRoot: header.Root, + ReceiptsRoot: header.ReceiptHash, + LogsBloom: header.Bloom, + PrevRandao: header.MixDigest, + BlockNumber: header.Number.Uint64(), + GasLimit: header.GasLimit, + GasUsed: header.GasUsed, + Time: header.Time, + Extra: header.Extra, + BaseFeePerGas: baseFee32, + BlockHash: header.Hash(), + Transactions: body.Transactions, + Withdrawals: body.Withdrawals, + } + if header.WithdrawalsHash == nil { + block.version = clparams.BellatrixVersion + } else { + block.version = clparams.CapellaVersion + } + return block +} - if b.Header == nil { - return +// PayloadHeader returns the equivalent ExecutionPayloadHeader object. +func (b *Eth1Block) PayloadHeader() (*Eth1Header, error) { + var err error + var transactionsRoot, withdrawalsRoot libcommon.Hash + if transactionsRoot, err = merkle_tree.TransactionsListRoot(b.Transactions); err != nil { + return nil, err + } + if b.version >= clparams.CapellaVersion { + withdrawalsRoot, err = b.Withdrawals.HashSSZ(16) + if err != nil { + return nil, err + } } + + return &Eth1Header{ + ParentHash: b.ParentHash, + FeeRecipient: b.FeeRecipient, + StateRoot: b.StateRoot, + ReceiptsRoot: b.ReceiptsRoot, + LogsBloom: b.LogsBloom, + PrevRandao: b.PrevRandao, + BlockNumber: b.BlockNumber, + GasLimit: b.GasLimit, + GasUsed: b.GasUsed, + Time: b.Time, + Extra: b.Extra, + BaseFeePerGas: b.BaseFeePerGas, + BlockHash: b.BlockHash, + TransactionsRoot: transactionsRoot, + WithdrawalsRoot: withdrawalsRoot, + version: b.version, + }, nil +} + +// Return minimum required buffer length to be an acceptable SSZ encoding. +func (b *Eth1Block) EncodingSizeSSZ() (size int) { + size = 508 // Field (10) 'ExtraData' - size += len(b.Header.Extra) + size += len(b.Extra) // Field (13) 'Transactions' - for _, tx := range b.Body.Transactions { + for _, tx := range b.Transactions { size += 4 size += len(tx) } - if version >= clparams.CapellaVersion { - size += len(b.Body.Withdrawals)*44 + 4 + if b.version >= clparams.CapellaVersion { + size += len(b.Withdrawals)*44 + 4 } return } -func (b *Eth1Block) DecodeSSZ(buf []byte, version clparams.StateVersion) error { - if len(buf) < b.EncodingSizeSSZ(clparams.BellatrixVersion) { - return ssz_utils.ErrLowBufferSize - } - b.Header = new(types.Header) +// Need a version +func (b *Eth1Block) DecodeSSZ(buf []byte) error { + panic("stop") +} - pos, extraDataOffset := b.Header.DecodeHeaderMetadataForSSZ(buf) - transactionsOffset := ssz_utils.DecodeOffset(buf[pos:]) +// DecodeSSZWithVersion decodes the block in SSZ format. +func (b *Eth1Block) DecodeSSZWithVersion(buf []byte, version int) error { + b.version = clparams.StateVersion(version) + if len(buf) < b.EncodingSizeSSZ() { + return ssz.ErrLowBufferSize + } + // We can reuse code from eth1-header for partial decoding + payloadHeader := Eth1Header{} + pos, extraDataOffset := payloadHeader.decodeHeaderMetadataForSSZ(buf) + // Set all header shared fields accordingly + b.ParentHash = payloadHeader.ParentHash + b.FeeRecipient = payloadHeader.FeeRecipient + b.StateRoot = payloadHeader.StateRoot + b.ReceiptsRoot = payloadHeader.ReceiptsRoot + b.BlockHash = payloadHeader.BlockHash + b.LogsBloom = payloadHeader.LogsBloom + b.PrevRandao = payloadHeader.PrevRandao + b.BlockNumber = payloadHeader.BlockNumber + b.GasLimit = payloadHeader.GasLimit + b.GasUsed = payloadHeader.GasUsed + b.Time = payloadHeader.Time + b.BaseFeePerGas = payloadHeader.BaseFeePerGas + // Decode the rest + transactionsOffset := ssz.DecodeOffset(buf[pos:]) pos += 4 var withdrawalOffset *uint32 - if version >= clparams.CapellaVersion { + if version >= int(clparams.CapellaVersion) { withdrawalOffset = new(uint32) - *withdrawalOffset = ssz_utils.DecodeOffset(buf[pos:]) + *withdrawalOffset = ssz.DecodeOffset(buf[pos:]) } // Compute extra data. - b.Header.Extra = common.CopyBytes(buf[extraDataOffset:transactionsOffset]) - if len(b.Header.Extra) > 32 { - return fmt.Errorf("Decode(SSZ): Extra data field length should be less or equal to 32, got %d", len(b.Header.Extra)) + b.Extra = common.CopyBytes(buf[extraDataOffset:transactionsOffset]) + if len(b.Extra) > 32 { + return fmt.Errorf("Decode(SSZ): Extra data field length should be less or equal to 32, got %d", len(b.Extra)) } // Compute transactions var transactionsBuffer []byte if withdrawalOffset == nil { if len(transactionsBuffer) > len(buf) { - return ssz_utils.ErrLowBufferSize + return ssz.ErrLowBufferSize } transactionsBuffer = buf[transactionsOffset:] } else { if len(transactionsBuffer) > int(*withdrawalOffset) || int(*withdrawalOffset) > len(buf) { - return ssz_utils.ErrBadOffset + return ssz.ErrBadOffset } transactionsBuffer = buf[transactionsOffset:*withdrawalOffset] } @@ -88,18 +188,17 @@ func (b *Eth1Block) DecodeSSZ(buf []byte, version clparams.StateVersion) error { length = 0 } else { if len(transactionsBuffer) < 4 { - return ssz_utils.ErrLowBufferSize + return ssz.ErrLowBufferSize } - txOffset = ssz_utils.DecodeOffset(transactionsBuffer) + txOffset = ssz.DecodeOffset(transactionsBuffer) length = txOffset / 4 // Retrieve tx length if txOffset%4 != 0 { - return ssz_utils.ErrBadDynamicLength + return ssz.ErrBadDynamicLength } } - b.Body = new(types.RawBody) - b.Body.Transactions = make([][]byte, length) + b.Transactions = make([][]byte, length) txIdx := 0 // Loop through each transaction for length > 0 { @@ -107,109 +206,142 @@ func (b *Eth1Block) DecodeSSZ(buf []byte, version clparams.StateVersion) error { if length == 1 { txEndOffset = uint32(len(transactionsBuffer)) } else { - txEndOffset = ssz_utils.DecodeOffset(transactionsBuffer[transactionsPosition:]) + txEndOffset = ssz.DecodeOffset(transactionsBuffer[transactionsPosition:]) } transactionsPosition += 4 if txOffset > txEndOffset { - return ssz_utils.ErrBadOffset + return ssz.ErrBadOffset } - b.Body.Transactions[txIdx] = transactionsBuffer[txOffset:txEndOffset] + b.Transactions[txIdx] = transactionsBuffer[txOffset:txEndOffset] // Decode RLP and put it in the tx list. // Update parameters for next iteration txOffset = txEndOffset txIdx++ length-- } - // Cache transaction ssz root. - var err error - b.Header.TxHashSSZ, err = merkle_tree.TransactionsListRoot(b.Body.Transactions) - if err != nil { - return err - } - // Cache transaction rlp hash. - b.Header.TxHash = types.DeriveSha(types.BinaryTransactions(b.Body.Transactions)) // If withdrawals are enabled, process them. if withdrawalOffset != nil { - b.Body.Withdrawals, err = ssz_utils.DecodeStaticList[*types.Withdrawal](buf, *withdrawalOffset, uint32(len(buf)), 44, 16) + var err error + b.Withdrawals, err = ssz.DecodeStaticList[*types.Withdrawal](buf, *withdrawalOffset, uint32(len(buf)), 44, 16) if err != nil { return err } - withdrawalRoot, err := b.Withdrawals().HashSSZ(16) - if err != nil { - return err - } - b.Header.WithdrawalsHash = new(libcommon.Hash) - *b.Header.WithdrawalsHash = withdrawalRoot } return nil } -func (b *Eth1Block) EncodeSSZ(dst []byte, version clparams.StateVersion) ([]byte, error) { +// EncodeSSZ encodes the block in SSZ format. +func (b *Eth1Block) EncodeSSZ(dst []byte) ([]byte, error) { buf := dst var err error - currentOffset := ssz_utils.BaseExtraDataSSZOffsetBlock + currentOffset := ssz.BaseExtraDataSSZOffsetBlock - if version >= clparams.CapellaVersion { + if b.version >= clparams.CapellaVersion { currentOffset += 4 } - buf, err = b.Header.EncodeHeaderMetadataForSSZ(buf, currentOffset) + payloadHeader, err := b.PayloadHeader() + if err != nil { + return nil, err + } + buf, err = payloadHeader.encodeHeaderMetadataForSSZ(buf, currentOffset) if err != nil { return nil, err } - currentOffset += len(b.Header.Extra) - // use raw body for encoded txs and offsets. - body := b.Body + currentOffset += len(b.Extra) // Write transaction offset - buf = append(buf, ssz_utils.OffsetSSZ(uint32(currentOffset))...) + buf = append(buf, ssz.OffsetSSZ(uint32(currentOffset))...) - for _, tx := range body.Transactions { + for _, tx := range b.Transactions { currentOffset += len(tx) + 4 } // Write withdrawals offset if exist - if version >= clparams.CapellaVersion { - buf = append(buf, ssz_utils.OffsetSSZ(uint32(currentOffset))...) + if b.version >= clparams.CapellaVersion { + buf = append(buf, ssz.OffsetSSZ(uint32(currentOffset))...) } // Sanity check for extra data then write it. - if len(b.Header.Extra) > 32 { - return nil, fmt.Errorf("Encode(SSZ): Extra data field length should be less or equal to 32, got %d", len(b.Header.Extra)) + if len(b.Extra) > 32 { + return nil, fmt.Errorf("Encode(SSZ): Extra data field length should be less or equal to 32, got %d", len(b.Extra)) } - buf = append(buf, b.Header.Extra...) + buf = append(buf, b.Extra...) // Write all tx offsets - txOffset := len(body.Transactions) * 4 - for _, tx := range body.Transactions { - buf = append(buf, ssz_utils.OffsetSSZ(uint32(txOffset))...) + txOffset := len(b.Transactions) * 4 + for _, tx := range b.Transactions { + buf = append(buf, ssz.OffsetSSZ(uint32(txOffset))...) txOffset += len(tx) } // Write all transactions - for _, tx := range body.Transactions { + for _, tx := range b.Transactions { buf = append(buf, tx...) } - if version >= clparams.CapellaVersion { - // Append all withdrawals SSZ - for _, withdrawal := range body.Withdrawals { - buf = append(buf, withdrawal.EncodeSSZ()...) - } + // Append all withdrawals SSZ + for _, withdrawal := range b.Withdrawals { + buf = append(buf, withdrawal.EncodeSSZ()...) } + return buf, nil } +// HashSSZ calculates the SSZ hash of the Eth1Block's payload header. func (b *Eth1Block) HashSSZ(version clparams.StateVersion) ([32]byte, error) { - var err error - if b.Header.TxHashSSZ, err = merkle_tree.TransactionsListRoot(b.Body.Transactions); err != nil { + // Get the payload header. + header, err := b.PayloadHeader() + if err != nil { return [32]byte{}, err } - if version >= clparams.CapellaVersion { - b.Header.WithdrawalsHash = new(libcommon.Hash) - if *b.Header.WithdrawalsHash, err = types.Withdrawals(b.Body.Withdrawals).HashSSZ(16); err != nil { - return [32]byte{}, err - } - } else { - b.Header.WithdrawalsHash = nil + + // Calculate the SSZ hash of the header and return it. + return header.HashSSZ() +} + +// RlpHeader returns the equivalent types.Header struct with RLP-based fields. +func (b *Eth1Block) RlpHeader() (*types.Header, error) { + // Reverse the order of the bytes in the BaseFeePerGas array and convert it to a big integer. + reversedBaseFeePerGas := libcommon.Copy(b.BaseFeePerGas[:]) + for i, j := 0, len(reversedBaseFeePerGas)-1; i < j; i, j = i+1, j-1 { + reversedBaseFeePerGas[i], reversedBaseFeePerGas[j] = reversedBaseFeePerGas[j], reversedBaseFeePerGas[i] } - return b.Header.HashSSZ() + baseFee := new(big.Int).SetBytes(reversedBaseFeePerGas) + + // If the block version is Capella or later, calculate the withdrawals hash. + var withdrawalsHash *libcommon.Hash + if b.version >= clparams.CapellaVersion { + withdrawalsHash = new(libcommon.Hash) + *withdrawalsHash = types.DeriveSha(b.Withdrawals) + } + + header := &types.Header{ + ParentHash: b.ParentHash, + UncleHash: types.EmptyUncleHash, + Coinbase: b.FeeRecipient, + Root: b.StateRoot, + TxHash: types.DeriveSha(types.BinaryTransactions(b.Transactions)), + ReceiptHash: b.ReceiptsRoot, + Bloom: b.LogsBloom, + Difficulty: serenity.SerenityDifficulty, + Number: big.NewInt(int64(b.BlockNumber)), + GasLimit: b.GasLimit, + GasUsed: b.GasUsed, + Time: b.Time, + Extra: b.Extra, + MixDigest: b.PrevRandao, + Nonce: serenity.SerenityNonce, + BaseFee: baseFee, + WithdrawalsHash: withdrawalsHash, + } + + // If the header hash does not match the block hash, return an error. + if header.Hash() != b.BlockHash { + return nil, fmt.Errorf("cannot derive rlp header: mismatching hash") + } + + return header, nil } -func (b *Eth1Block) Hash() libcommon.Hash { - return b.Header.Hash() +// Body returns the equivalent raw body (only eth1 body section). +func (b *Eth1Block) Body() *types.RawBody { + return &types.RawBody{ + Transactions: b.Transactions, + Withdrawals: b.Withdrawals, + } } diff --git a/cl/cltypes/eth1_data.go b/cl/cltypes/eth1_data.go index b60a1352fcc..4521a650a70 100644 --- a/cl/cltypes/eth1_data.go +++ b/cl/cltypes/eth1_data.go @@ -14,6 +14,11 @@ type Eth1Data struct { DepositCount uint64 } +func (e *Eth1Data) Copy() *Eth1Data { + copied := *e + return &copied +} + func (e *Eth1Data) Equal(b *Eth1Data) bool { return e.BlockHash == b.BlockHash && e.Root == b.Root && b.DepositCount == e.DepositCount } diff --git a/cl/cltypes/eth1_header.go b/cl/cltypes/eth1_header.go new file mode 100644 index 00000000000..7b104adf8ce --- /dev/null +++ b/cl/cltypes/eth1_header.go @@ -0,0 +1,216 @@ +package cltypes + +import ( + libcommon "github.com/ledgerwatch/erigon-lib/common" + "github.com/ledgerwatch/erigon/cl/clparams" + "github.com/ledgerwatch/erigon/cl/cltypes/ssz" + "github.com/ledgerwatch/erigon/cl/merkle_tree" + "github.com/ledgerwatch/erigon/common" + "github.com/ledgerwatch/erigon/core/types" +) + +// ETH1Header represents the ethereum 1 header structure CL-side. +type Eth1Header struct { + ParentHash libcommon.Hash + FeeRecipient libcommon.Address + StateRoot libcommon.Hash + ReceiptsRoot libcommon.Hash + LogsBloom types.Bloom + PrevRandao libcommon.Hash + BlockNumber uint64 + GasLimit uint64 + GasUsed uint64 + Time uint64 + Extra []byte + BaseFeePerGas [32]byte + // Extra fields + BlockHash libcommon.Hash + TransactionsRoot libcommon.Hash + WithdrawalsRoot libcommon.Hash + // internals + version clparams.StateVersion +} + +// NewEth1Header creates new header with given version. +func NewEth1Header(version clparams.StateVersion) *Eth1Header { + return &Eth1Header{version: version} +} + +func (e *Eth1Header) Copy() *Eth1Header { + copied := *e + copied.Extra = libcommon.Copy(e.Extra) + return &copied +} + +// Capella converts the header to capella version. +func (e *Eth1Header) Capella() { + e.version = clparams.CapellaVersion + e.WithdrawalsRoot = libcommon.Hash{} +} + +func (e *Eth1Header) IsZero() bool { + return e.ParentHash == libcommon.Hash{} && e.FeeRecipient == libcommon.Address{} && e.StateRoot == libcommon.Hash{} && + e.ReceiptsRoot == libcommon.Hash{} && e.LogsBloom == types.Bloom{} && e.PrevRandao == libcommon.Hash{} && e.BlockNumber == 0 && + e.GasLimit == 0 && e.GasUsed == 0 && e.Time == 0 && len(e.Extra) == 0 && e.BaseFeePerGas == [32]byte{} && e.BlockHash == libcommon.Hash{} && e.TransactionsRoot == libcommon.Hash{} +} + +// Encodes header data partially. used to not dupicate code across Eth1Block and Eth1Header. +func (h *Eth1Header) encodeHeaderMetadataForSSZ(dst []byte, extraDataOffset int) ([]byte, error) { + buf := dst + buf = append(buf, h.ParentHash[:]...) + buf = append(buf, h.FeeRecipient[:]...) + buf = append(buf, h.StateRoot[:]...) + buf = append(buf, h.ReceiptsRoot[:]...) + buf = append(buf, h.LogsBloom[:]...) + buf = append(buf, h.PrevRandao[:]...) + buf = append(buf, ssz.Uint64SSZ(h.BlockNumber)...) + buf = append(buf, ssz.Uint64SSZ(h.GasLimit)...) + buf = append(buf, ssz.Uint64SSZ(h.GasUsed)...) + buf = append(buf, ssz.Uint64SSZ(h.Time)...) + buf = append(buf, ssz.OffsetSSZ(uint32(extraDataOffset))...) + + // Add Base Fee + buf = append(buf, h.BaseFeePerGas[:]...) + buf = append(buf, h.BlockHash[:]...) + return buf, nil +} + +// EncodeSSZ encodes the header in SSZ format. +func (h *Eth1Header) EncodeSSZ(dst []byte) (buf []byte, err error) { + buf = dst + offset := ssz.BaseExtraDataSSZOffsetHeader + + if h.version >= clparams.CapellaVersion { + offset += 32 + } + + buf, err = h.encodeHeaderMetadataForSSZ(buf, offset) + if err != nil { + return nil, err + } + buf = append(buf, h.TransactionsRoot[:]...) + + if h.version >= clparams.CapellaVersion { + buf = append(buf, h.WithdrawalsRoot[:]...) + } + + buf = append(buf, h.Extra...) + return +} + +// Decodes header data partially. used to not dupicate code across Eth1Block and Eth1Header. +func (h *Eth1Header) decodeHeaderMetadataForSSZ(buf []byte) (pos int, extraDataOffset int) { + copy(h.ParentHash[:], buf) + pos = len(h.ParentHash) + + copy(h.FeeRecipient[:], buf[pos:]) + pos += len(h.FeeRecipient) + + copy(h.StateRoot[:], buf[pos:]) + pos += len(h.StateRoot) + + copy(h.ReceiptsRoot[:], buf[pos:]) + pos += len(h.ReceiptsRoot) + + h.LogsBloom.SetBytes(buf[pos : pos+types.BloomByteLength]) + pos += types.BloomByteLength + + copy(h.PrevRandao[:], buf[pos:]) + pos += len(h.PrevRandao) + + h.BlockNumber = ssz.UnmarshalUint64SSZ(buf[pos:]) + h.GasLimit = ssz.UnmarshalUint64SSZ(buf[pos+8:]) + h.GasUsed = ssz.UnmarshalUint64SSZ(buf[pos+16:]) + h.Time = ssz.UnmarshalUint64SSZ(buf[pos+24:]) + pos += 32 + extraDataOffset = int(ssz.DecodeOffset(buf[pos:])) + pos += 4 + // Add Base Fee + copy(h.BaseFeePerGas[:], buf[pos:]) + pos += 32 + copy(h.BlockHash[:], buf[pos:]) + pos += 32 + return +} + +// DecodeSSZWithVersion decodes given SSZ slice. +func (h *Eth1Header) DecodeSSZWithVersion(buf []byte, version int) error { + h.version = clparams.StateVersion(version) + if len(buf) < h.EncodingSizeSSZ() { + return ssz.ErrLowBufferSize + } + pos, _ := h.decodeHeaderMetadataForSSZ(buf) + copy(h.TransactionsRoot[:], buf[pos:]) + pos += len(h.TransactionsRoot) + + if h.version >= clparams.CapellaVersion { + copy(h.WithdrawalsRoot[:], buf[pos:]) + pos += len(h.WithdrawalsRoot) + } + h.Extra = common.CopyBytes(buf[pos:]) + return nil +} + +// EncodingSizeSSZ returns the ssz encoded size in bytes for the Header object +func (h *Eth1Header) EncodingSizeSSZ() int { + size := 536 + + if h.version >= clparams.CapellaVersion { + size += 32 + } + + return size + len(h.Extra) +} + +// HashSSZ encodes the header in SSZ tree format. +func (h *Eth1Header) HashSSZ() ([32]byte, error) { + // Compute coinbase leaf + var coinbase32 [32]byte + copy(coinbase32[:], h.FeeRecipient[:]) + // Compute Bloom leaf + bloomLeaf, err := merkle_tree.ArraysRoot([][32]byte{ + libcommon.BytesToHash(h.LogsBloom[:32]), + libcommon.BytesToHash(h.LogsBloom[32:64]), + libcommon.BytesToHash(h.LogsBloom[64:96]), + libcommon.BytesToHash(h.LogsBloom[96:128]), + libcommon.BytesToHash(h.LogsBloom[128:160]), + libcommon.BytesToHash(h.LogsBloom[160:192]), + libcommon.BytesToHash(h.LogsBloom[192:224]), + libcommon.BytesToHash(h.LogsBloom[224:]), + }, 8) + if err != nil { + return [32]byte{}, err + } + // Compute extra data leaf + var extraLeaf libcommon.Hash + + var baseExtraLeaf [32]byte + copy(baseExtraLeaf[:], h.Extra) + extraLeaf, err = merkle_tree.ArraysRoot([][32]byte{ + baseExtraLeaf, + merkle_tree.Uint64Root(uint64(len(h.Extra)))}, 2) + if err != nil { + return [32]byte{}, err + } + + leaves := [][32]byte{ + h.ParentHash, + coinbase32, + h.StateRoot, + h.ReceiptsRoot, + bloomLeaf, + h.PrevRandao, + merkle_tree.Uint64Root(h.BlockNumber), + merkle_tree.Uint64Root(h.GasLimit), + merkle_tree.Uint64Root(h.GasUsed), + merkle_tree.Uint64Root(h.Time), + extraLeaf, + h.BaseFeePerGas, + h.BlockHash, + h.TransactionsRoot, + } + if h.version >= clparams.CapellaVersion { + leaves = append(leaves, h.WithdrawalsRoot) + } + return merkle_tree.ArraysRoot(leaves, 16) +} diff --git a/cl/cltypes/fork.go b/cl/cltypes/fork.go index af0fb2920c6..3b828378c70 100644 --- a/cl/cltypes/fork.go +++ b/cl/cltypes/fork.go @@ -13,6 +13,14 @@ type Fork struct { Epoch uint64 } +func (f *Fork) Copy() *Fork { + return &Fork{ + PreviousVersion: f.PreviousVersion, + CurrentVersion: f.CurrentVersion, + Epoch: f.Epoch, + } +} + func (f *Fork) EncodeSSZ(dst []byte) ([]byte, error) { buf := dst buf = append(buf, f.PreviousVersion[:]...) diff --git a/cl/cltypes/lightclient.go b/cl/cltypes/lightclient.go deleted file mode 100644 index d752f244903..00000000000 --- a/cl/cltypes/lightclient.go +++ /dev/null @@ -1,630 +0,0 @@ -package cltypes - -import ( - "fmt" - - libcommon "github.com/ledgerwatch/erigon-lib/common" - "github.com/ledgerwatch/erigon-lib/common/length" - "github.com/ledgerwatch/erigon/cl/clparams" - "github.com/ledgerwatch/erigon/cl/cltypes/ssz_utils" - "github.com/ledgerwatch/erigon/cl/utils" - "github.com/ledgerwatch/erigon/core/types" -) - -const ( - SyncCommitteeBranchLength = 5 - FinalityBranchLength = 6 - ExecutionBranchLength = 4 -) - -type LightClientHeader struct { - HeaderEth2 *BeaconBlockHeader - HeaderEth1 *types.Header - ExecutionBranch [ExecutionBranchLength]libcommon.Hash - version clparams.StateVersion -} - -func (l *LightClientHeader) WithVersion(v clparams.StateVersion) *LightClientHeader { - l.version = v - return l -} - -func (l *LightClientHeader) DecodeSSZ([]byte) error { - panic("not implemnted") -} - -func (l *LightClientHeader) DecodeSSZWithVersion(buf []byte, v int) error { - var err error - l.version = clparams.StateVersion(v) - l.HeaderEth2 = new(BeaconBlockHeader) - if err = l.HeaderEth2.DecodeSSZ(buf); err != nil { - return err - } - if l.version <= clparams.BellatrixVersion { - return nil - } - pos := l.HeaderEth2.EncodingSizeSSZ() + 4 // Skip the offset, assume it is at the end. - // Decode branch - for i := range l.ExecutionBranch { - copy(l.ExecutionBranch[i][:], buf[pos:]) - pos += length.Hash - } - l.HeaderEth1 = new(types.Header) - return l.HeaderEth1.DecodeSSZ(buf[pos:], l.version) -} - -func (l *LightClientHeader) EncodeSSZ(buf []byte) ([]byte, error) { - var ( - err error - dst = buf - ) - if dst, err = l.HeaderEth2.EncodeSSZ(dst); err != nil { - return nil, err - } - // Pre-capella is easy, encode only header. - if l.version < clparams.CapellaVersion { - return dst, nil - } - // Post-Capella - offset := uint32(l.HeaderEth2.EncodingSizeSSZ() + len(l.ExecutionBranch)*length.Hash + 4) - dst = append(dst, ssz_utils.OffsetSSZ(offset)...) - for _, root := range l.ExecutionBranch { - dst = append(dst, root[:]...) - } - return l.HeaderEth1.EncodeSSZ(dst) -} - -func (l *LightClientHeader) EncodingSizeSSZ() int { - if l.HeaderEth2 == nil { - l.HeaderEth2 = new(BeaconBlockHeader) - } - size := l.HeaderEth2.EncodingSizeSSZ() - if l.version >= clparams.CapellaVersion { - if l.HeaderEth1 == nil { - l.HeaderEth1 = new(types.Header) - } - size += l.HeaderEth1.EncodingSizeSSZ(l.version) + 4 - size += length.Hash * len(l.ExecutionBranch) - } - return size -} - -// LightClientBootstrap is used to bootstrap the lightclient from checkpoint sync. -type LightClientBootstrap struct { - Header *LightClientHeader - CurrentSyncCommittee *SyncCommittee - CurrentSyncCommitteeBranch []libcommon.Hash - version clparams.StateVersion -} - -func (l *LightClientBootstrap) WithVersion(v clparams.StateVersion) *LightClientBootstrap { - l.version = v - return l -} - -func (l *LightClientBootstrap) DecodeSSZ(buf []byte) error { - panic("AAAAAA") -} - -// EncodeSSZ ssz marshals the LightClientBootstrap object -func (l *LightClientBootstrap) EncodeSSZ(dst []byte) ([]byte, error) { - buf := dst - var err error - offset := l.CurrentSyncCommittee.EncodingSizeSSZ() + len(l.CurrentSyncCommitteeBranch)*length.Hash + 4 - if l.version < clparams.CapellaVersion { - if buf, err = l.Header.EncodeSSZ(buf); err != nil { - return nil, err - } - } else { - buf = append(buf, ssz_utils.OffsetSSZ(uint32(offset))...) - } - - if buf, err = l.CurrentSyncCommittee.EncodeSSZ(buf); err != nil { - return nil, err - } - if len(l.CurrentSyncCommitteeBranch) != SyncCommitteeBranchLength { - return nil, fmt.Errorf("sync committee branch is invalid") - } - for _, leaf := range l.CurrentSyncCommitteeBranch { - buf = append(buf, leaf[:]...) - } - if l.version >= clparams.CapellaVersion { - if buf, err = l.Header.EncodeSSZ(buf); err != nil { - return nil, err - } - } - return buf, nil -} - -// DecodeSSZ ssz unmarshals the LightClientBootstrap object -func (l *LightClientBootstrap) DecodeSSZWithVersion(buf []byte, version int) error { - var err error - l.version = clparams.StateVersion(version) - - if len(buf) < l.EncodingSizeSSZ() { - return ssz_utils.ErrLowBufferSize - } - l.Header = new(LightClientHeader) - l.CurrentSyncCommittee = new(SyncCommittee) - l.CurrentSyncCommitteeBranch = make([]libcommon.Hash, 5) - - pos := 0 - if l.version >= clparams.CapellaVersion { - pos += 4 - } else { - if err = l.Header.DecodeSSZWithVersion(buf[pos:], int(l.version)); err != nil { - return err - } - pos += l.Header.EncodingSizeSSZ() - } - - if err = l.CurrentSyncCommittee.DecodeSSZ(buf[pos:]); err != nil { - return err - } - pos += l.CurrentSyncCommittee.EncodingSizeSSZ() - - for i := range l.CurrentSyncCommitteeBranch { - copy(l.CurrentSyncCommitteeBranch[i][:], buf[pos:pos+32]) - pos += 32 - } - if l.version >= clparams.CapellaVersion { - if err = l.Header.DecodeSSZWithVersion(buf[pos:], int(l.version)); err != nil { - return err - } - } - - return err -} - -// EncodingSizeSSZ returns the ssz encoded size in bytes for the LightClientBootstrap object -func (l *LightClientBootstrap) EncodingSizeSSZ() (size int) { - if l.Header == nil { - l.Header = &LightClientHeader{version: l.version} - } - size = 0 - size += l.Header.EncodingSizeSSZ() - if l.version >= clparams.CapellaVersion { - size += 4 - } - if l.CurrentSyncCommittee == nil { - l.CurrentSyncCommittee = new(SyncCommittee) - l.CurrentSyncCommittee.PubKeys = make([][48]byte, SyncCommitteeSize) - } - - size += l.CurrentSyncCommittee.EncodingSizeSSZ() - - if len(l.CurrentSyncCommitteeBranch) == 0 { - l.CurrentSyncCommitteeBranch = make([]libcommon.Hash, SyncCommitteeBranchLength) - } - size += len(l.CurrentSyncCommitteeBranch) * length.Hash - - return -} - -// LightClientUpdate is used to update the sync committee every 27 hours. -type LightClientUpdate struct { - AttestedHeader *LightClientHeader - NextSyncCommitee *SyncCommittee - NextSyncCommitteeBranch []libcommon.Hash - FinalizedHeader *LightClientHeader - FinalityBranch []libcommon.Hash - SyncAggregate *SyncAggregate - SignatureSlot uint64 - - version clparams.StateVersion -} - -func (l *LightClientUpdate) WithVersion(v clparams.StateVersion) *LightClientUpdate { - l.version = v - return l -} - -func (l *LightClientUpdate) DecodeSSZ(buf []byte) error { - panic("OOOH") -} - -func (l *LightClientUpdate) HasNextSyncCommittee() bool { - return l.NextSyncCommitee != nil -} - -func (l *LightClientUpdate) IsFinalityUpdate() bool { - return l.FinalityBranch != nil -} - -func (l *LightClientUpdate) HasSyncFinality() bool { - return l.FinalizedHeader != nil && - utils.SlotToPeriod(l.AttestedHeader.HeaderEth2.Slot) == utils.SlotToPeriod(l.FinalizedHeader.HeaderEth2.Slot) -} - -// MarshalSSZTo ssz marshals the LightClientUpdate object to a target array -func (l *LightClientUpdate) EncodeSSZ(buf []byte) ([]byte, error) { - dst := buf - var err error - offset := 8 + l.NextSyncCommitee.EncodingSizeSSZ() + len(l.NextSyncCommitteeBranch)*length.Hash + - len(l.FinalityBranch)*length.Hash + l.SyncAggregate.EncodingSizeSSZ() + 8 - - if l.version >= clparams.CapellaVersion { - dst = append(dst, ssz_utils.OffsetSSZ(uint32(offset))...) - offset += l.AttestedHeader.EncodingSizeSSZ() - } else { - // Generic Update Specific - if dst, err = l.AttestedHeader.EncodeSSZ(dst); err != nil { - return nil, err - } - } - - if dst, err = l.NextSyncCommitee.EncodeSSZ(dst); err != nil { - return nil, err - } - - if len(l.NextSyncCommitteeBranch) != SyncCommitteeBranchLength { - return nil, fmt.Errorf("invalid size for nextSyncCommitteeBranch") - } - for _, leaf := range l.NextSyncCommitteeBranch { - dst = append(dst, leaf[:]...) - } - - dst, err = encodeFinalityUpdateSpecificField(dst, l.FinalizedHeader, l.FinalityBranch, uint32(offset)) - if err != nil { - return nil, err - } - - dst = encodeUpdateFooter(dst, l.SyncAggregate, l.SignatureSlot) - if l.version >= clparams.CapellaVersion { - if dst, err = l.AttestedHeader.EncodeSSZ(dst); err != nil { - return nil, err - } - if dst, err = l.FinalizedHeader.EncodeSSZ(dst); err != nil { - return nil, err - } - } - return dst, nil -} - -func encodeFinalityUpdateSpecificField(buf []byte, finalizedHeader *LightClientHeader, finalityBranch []libcommon.Hash, offset uint32) ([]byte, error) { - dst := buf - var err error - if finalizedHeader.version >= clparams.CapellaVersion { - dst = append(dst, ssz_utils.OffsetSSZ(offset)...) - } else { - if dst, err = finalizedHeader.EncodeSSZ(dst); err != nil { - return nil, err - } - } - - if len(finalityBranch) != FinalityBranchLength { - return nil, fmt.Errorf("invalid finality branch length") - } - for _, leaf := range finalityBranch { - dst = append(dst, leaf[:]...) - } - return dst, nil -} - -func encodeUpdateFooter(buf []byte, aggregate *SyncAggregate, signatureSlot uint64) []byte { - dst := buf - dst = aggregate.EncodeSSZ(dst) - return append(dst, ssz_utils.Uint64SSZ(signatureSlot)...) -} - -func decodeFinalityUpdateSpecificField(buf []byte, version clparams.StateVersion) (*LightClientHeader, []libcommon.Hash, uint32, int, error) { - header := &LightClientHeader{} - var offset uint32 - pos := 0 - if version < clparams.CapellaVersion { - if err := header.DecodeSSZWithVersion(buf, int(version)); err != nil { - return nil, nil, 0, 0, err - } - pos += header.EncodingSizeSSZ() - } else { - offset = ssz_utils.DecodeOffset(buf) - pos += 4 - } - - finalityBranch := make([]libcommon.Hash, FinalityBranchLength) - for i := range finalityBranch { - copy(finalityBranch[i][:], buf[pos:]) - pos += length.Hash - } - return header, finalityBranch, offset, pos, nil -} - -func decodeUpdateFooter(buf []byte) (*SyncAggregate, uint64, error) { - aggregate := &SyncAggregate{} - if err := aggregate.DecodeSSZ(buf); err != nil { - return nil, 0, err - } - return aggregate, ssz_utils.UnmarshalUint64SSZ(buf[aggregate.EncodingSizeSSZ():]), nil -} - -// LightClientFinalityUpdate is used to update the sync aggreggate every 6 minutes. -type LightClientFinalityUpdate struct { - AttestedHeader *LightClientHeader - FinalizedHeader *LightClientHeader - FinalityBranch []libcommon.Hash `ssz-size:"6,32"` - SyncAggregate *SyncAggregate - SignatureSlot uint64 - - version clparams.StateVersion -} - -func (l *LightClientFinalityUpdate) WithVersion(v clparams.StateVersion) *LightClientFinalityUpdate { - l.version = v - return l -} - -func (l *LightClientFinalityUpdate) DecodeSSZ(buf []byte) error { - panic("OOOOOOOOOOOOO") -} - -// DecodeSSZ ssz unmarshals the LightClientUpdate object -func (l *LightClientUpdate) DecodeSSZWithVersion(buf []byte, version int) error { - var err error - l.version = clparams.StateVersion(version) - if len(buf) < l.EncodingSizeSSZ() { - return ssz_utils.ErrLowBufferSize - } - - l.AttestedHeader = new(LightClientHeader) - l.NextSyncCommitee = new(SyncCommittee) - l.NextSyncCommitteeBranch = make([]libcommon.Hash, SyncCommitteeBranchLength) - l.FinalizedHeader = new(LightClientHeader) - l.SyncAggregate = new(SyncAggregate) - - var ( - pos int - offsetAttested uint32 - offsetFinalized uint32 - ) - - if l.version >= clparams.CapellaVersion { - offsetAttested = ssz_utils.DecodeOffset(buf) - pos += 4 - } else { - if err = l.AttestedHeader.DecodeSSZWithVersion(buf, version); err != nil { - return err - } - pos += l.AttestedHeader.EncodingSizeSSZ() - } - - if err = l.NextSyncCommitee.DecodeSSZ(buf[pos:]); err != nil { - return err - } - pos += l.NextSyncCommitee.EncodingSizeSSZ() - for i := range l.NextSyncCommitteeBranch { - copy(l.NextSyncCommitteeBranch[i][:], buf[pos:]) - pos += 32 - } - - var written int - l.FinalizedHeader, l.FinalityBranch, offsetFinalized, written, err = decodeFinalityUpdateSpecificField(buf[pos:], l.version) - if err != nil { - return err - } - pos += written - - l.SyncAggregate, l.SignatureSlot, err = decodeUpdateFooter(buf[pos:]) - if l.version >= clparams.CapellaVersion { - if offsetAttested > offsetFinalized || offsetFinalized > uint32(len(buf)) { - return ssz_utils.ErrBadOffset - } - if err = l.AttestedHeader.DecodeSSZWithVersion(buf[offsetAttested:offsetFinalized], version); err != nil { - return err - } - if err = l.FinalizedHeader.DecodeSSZWithVersion(buf[offsetFinalized:], version); err != nil { - return err - } - } - return err -} - -// EncodingSizeSSZ returns the ssz encoded size in bytes for the LightClientUpdate object -func (l *LightClientUpdate) EncodingSizeSSZ() int { - size := 0 - if l.version >= clparams.CapellaVersion { - size += 8 - } - if l.AttestedHeader == nil { - l.AttestedHeader = &LightClientHeader{version: l.version} - } - if l.NextSyncCommitee == nil { - l.NextSyncCommitee = new(SyncCommittee) - l.NextSyncCommitee.PubKeys = make([][48]byte, 512) - } - if l.FinalizedHeader == nil { - l.FinalizedHeader = &LightClientHeader{version: l.version} - } - if l.SyncAggregate == nil { - l.SyncAggregate = new(SyncAggregate) - } - if len(l.NextSyncCommitteeBranch) == 0 { - l.NextSyncCommitteeBranch = make([]libcommon.Hash, SyncCommitteeBranchLength) - } - if len(l.FinalityBranch) == 0 { - l.FinalityBranch = make([]libcommon.Hash, FinalityBranchLength) - } - return size + l.AttestedHeader.EncodingSizeSSZ() + l.FinalizedHeader.EncodingSizeSSZ() + l.SyncAggregate.EncodingSizeSSZ() + - 8 + len(l.FinalityBranch)*length.Hash + len(l.NextSyncCommitteeBranch)*length.Hash + l.NextSyncCommitee.EncodingSizeSSZ() -} - -func (l *LightClientFinalityUpdate) EncodeSSZ(buf []byte) ([]byte, error) { - dst := buf - var err error - offset := 8 + len(l.FinalityBranch)*length.Hash + l.SyncAggregate.EncodingSizeSSZ() + 8 - if l.version >= clparams.CapellaVersion { - dst = append(dst, ssz_utils.OffsetSSZ(uint32(offset))...) - offset += l.AttestedHeader.EncodingSizeSSZ() - } else { - // Generic Update Specific - if dst, err = l.AttestedHeader.EncodeSSZ(dst); err != nil { - return nil, err - } - } - - dst, err = encodeFinalityUpdateSpecificField(dst, l.FinalizedHeader, l.FinalityBranch, uint32(offset)) - if err != nil { - return nil, err - } - dst = encodeUpdateFooter(dst, l.SyncAggregate, l.SignatureSlot) - if l.version >= clparams.CapellaVersion { - if dst, err = l.AttestedHeader.EncodeSSZ(dst); err != nil { - return nil, err - } - if dst, err = l.FinalizedHeader.EncodeSSZ(dst); err != nil { - return nil, err - } - } - return dst, nil -} - -// DecodeSSZ ssz unmarshals the LightClientFinalityUpdate object -func (l *LightClientFinalityUpdate) DecodeSSZWithVersion(buf []byte, version int) error { - var err error - l.version = clparams.StateVersion(version) - if len(buf) < l.EncodingSizeSSZ() { - return ssz_utils.ErrBadOffset - } - - pos := 0 - l.AttestedHeader = new(LightClientHeader) - - var offsetAttested, offsetFinalized uint32 - if l.version < clparams.CapellaVersion { - if err = l.AttestedHeader.DecodeSSZWithVersion(buf, int(l.version)); err != nil { - return err - } - pos += l.AttestedHeader.EncodingSizeSSZ() - } else { - offsetAttested = ssz_utils.DecodeOffset(buf) - pos += 4 - } - - var written int - l.FinalizedHeader, l.FinalityBranch, offsetFinalized, written, err = decodeFinalityUpdateSpecificField(buf[pos:], l.version) - if err != nil { - return err - } - pos += written - - l.SyncAggregate, l.SignatureSlot, err = decodeUpdateFooter(buf[pos:]) - if err != nil { - return err - } - if l.version >= clparams.CapellaVersion { - if offsetAttested > offsetFinalized || offsetFinalized > uint32(len(buf)) { - return ssz_utils.ErrBadOffset - } - if err = l.AttestedHeader.DecodeSSZWithVersion(buf[offsetAttested:offsetFinalized], version); err != nil { - return err - } - if err = l.FinalizedHeader.DecodeSSZWithVersion(buf[offsetFinalized:], version); err != nil { - return err - } - } - return err -} - -func (l *LightClientFinalityUpdate) EncodingSizeSSZ() int { - size := 0 - if l.version >= clparams.CapellaVersion { - size += 8 - } - if l.AttestedHeader == nil { - l.AttestedHeader = &LightClientHeader{version: l.version} - } - if l.FinalizedHeader == nil { - l.FinalizedHeader = &LightClientHeader{version: l.version} - } - if l.SyncAggregate == nil { - l.SyncAggregate = new(SyncAggregate) - } - if len(l.FinalityBranch) == 0 { - l.FinalityBranch = make([]libcommon.Hash, FinalityBranchLength) - } - return size + l.AttestedHeader.EncodingSizeSSZ() + l.FinalizedHeader.EncodingSizeSSZ() + l.SyncAggregate.EncodingSizeSSZ() + - 8 + len(l.FinalityBranch)*length.Hash - -} - -// LightClientOptimisticUpdate is used for verifying N-1 block. -type LightClientOptimisticUpdate struct { - AttestedHeader *LightClientHeader - SyncAggregate *SyncAggregate - SignatureSlot uint64 - - version clparams.StateVersion -} - -func (l *LightClientOptimisticUpdate) WithVersion(v clparams.StateVersion) *LightClientOptimisticUpdate { - l.version = v - return l -} - -func (l *LightClientOptimisticUpdate) EncodeSSZ(buf []byte) ([]byte, error) { - dst := buf - var err error - if l.version >= clparams.CapellaVersion { - dst = append(dst, ssz_utils.OffsetSSZ(uint32(8+l.SyncAggregate.EncodingSizeSSZ()+4))...) - } else { - if dst, err = l.AttestedHeader.EncodeSSZ(dst); err != nil { - return nil, err - } - } - dst = encodeUpdateFooter(dst, l.SyncAggregate, l.SignatureSlot) - if l.version >= clparams.CapellaVersion { - if dst, err = l.AttestedHeader.EncodeSSZ(dst); err != nil { - return nil, err - } - } - return dst, nil -} - -func (l *LightClientOptimisticUpdate) DecodeSSZWithVersion(buf []byte, version int) error { - var err error - l.version = clparams.StateVersion(version) - if len(buf) < l.EncodingSizeSSZ() { - return ssz_utils.ErrBadOffset - } - - pos := 0 - l.AttestedHeader = new(LightClientHeader) - - if l.version < clparams.CapellaVersion { - if err = l.AttestedHeader.DecodeSSZWithVersion(buf, int(l.version)); err != nil { - return err - } - pos += l.AttestedHeader.EncodingSizeSSZ() - } else { - pos += 4 - } - - l.SyncAggregate, l.SignatureSlot, err = decodeUpdateFooter(buf[pos:]) - if err != nil { - return err - } - pos += l.SyncAggregate.EncodingSizeSSZ() + 8 - if l.version >= clparams.CapellaVersion { - if err = l.AttestedHeader.DecodeSSZWithVersion(buf[pos:], version); err != nil { - return err - } - } - return err - -} - -func (l *LightClientOptimisticUpdate) DecodeSSZ([]byte) error { - panic("DJFCF") -} - -func (l *LightClientOptimisticUpdate) EncodingSizeSSZ() (size int) { - if l.version >= clparams.CapellaVersion { - size += 4 - } - if l.AttestedHeader == nil { - l.AttestedHeader = &LightClientHeader{version: l.version} - } - if l.SyncAggregate == nil { - l.SyncAggregate = new(SyncAggregate) - } - return size + l.AttestedHeader.EncodingSizeSSZ() + l.SyncAggregate.EncodingSizeSSZ() + 8 -} diff --git a/cl/cltypes/lightclient_test.go b/cl/cltypes/lightclient_test.go deleted file mode 100644 index b4c98dcb4b3..00000000000 --- a/cl/cltypes/lightclient_test.go +++ /dev/null @@ -1,115 +0,0 @@ -package cltypes_test - -import ( - "testing" - - _ "embed" - - libcommon "github.com/ledgerwatch/erigon-lib/common" - - "github.com/ledgerwatch/erigon/cl/clparams" - "github.com/ledgerwatch/erigon/cl/cltypes" - "github.com/ledgerwatch/erigon/cl/utils" - "github.com/ledgerwatch/erigon/common" - "github.com/stretchr/testify/require" -) - -//go:embed tests/light_client_bootstrap.ssz_snappy -var bootstrapTest []byte - -//go:embed tests/light_client_optimistic.ssz_snappy -var optimisticTest []byte - -//go:embed tests/light_client_finality.ssz_snappy -var finalityTest []byte - -//go:embed tests/light_client_update.ssz_snappy -var updateTest []byte - -func TestLightclientBootstrapEncodingDecoding(t *testing.T) { - lc := cltypes.LightClientBootstrap{} - decodedSSZ, err := utils.DecompressSnappy(bootstrapTest) - require.NoError(t, err) - require.NoError(t, lc.DecodeSSZWithVersion(decodedSSZ, int(clparams.CapellaVersion))) - // checking fields - require.Equal(t, lc.Header.HeaderEth2.BodyRoot, libcommon.HexToHash("0x9eb9f39c2e88739dc4274483d1e9072c3685864d5bcbf2f3c072b97f54536a4e")) - require.Equal(t, *lc.Header.HeaderEth1.WithdrawalsHash, libcommon.HexToHash("0xd327e2d43fedf327de8f01ab8bbf4fbdbfececc890c5059ad53cfb37264cc03c")) - require.Equal(t, lc.Header.ExecutionBranch[0], libcommon.HexToHash("0x4138a3e27e9aea5c1c9eb311a7889bfddeb3d2ad3987943d68ee7cc659b6d947")) - require.Equal(t, lc.CurrentSyncCommittee.PubKeys[0][:], common.Hex2Bytes("009c6eacc6e3f29b10763a446fc6a6dfff95b408fb44c92b453e1349572d2b45b77305668349d39360e775752a4faf9a")) - require.Equal(t, lc.CurrentSyncCommittee.PubKeys[len(lc.CurrentSyncCommittee.PubKeys)-1][:], common.Hex2Bytes("dce9afb56fe779662a206c7d1503efacaf9d62fe81fa79d1fbfb9fd8ff03f7a11f263be6e4df633094cdfebcbd50112c")) - require.Equal(t, lc.CurrentSyncCommittee.AggregatePublicKey[:], common.Hex2Bytes("7455aa9ac6113a04b6976796d95dc2e4d7435ca37f47b9463b10fbaa32759db32ff9f7c4920c67d461ac1e4ebca56bb4")) - require.Equal(t, lc.CurrentSyncCommitteeBranch[0], libcommon.HexToHash("0x93a080a9f03a19868f6293f18236b8203f7ade39b78043184ada44b6b363ecfb")) - // encoding it back - dec, err := lc.EncodeSSZ(nil) - require.NoError(t, err) - require.Equal(t, dec, decodedSSZ) -} - -func TestLightclientOptimisticEncodingDecoding(t *testing.T) { - lc := cltypes.LightClientOptimisticUpdate{} - decodedSSZ, err := utils.DecompressSnappy(optimisticTest) - require.NoError(t, err) - require.NoError(t, lc.DecodeSSZWithVersion(decodedSSZ, int(clparams.CapellaVersion))) - // checking fields - require.Equal(t, lc.AttestedHeader.HeaderEth2.BodyRoot, libcommon.HexToHash("0x95e145e5890ccf3bf6c1c3708a51d42d7c602312d0ac2b225a1d54e30649e2f6")) - require.Equal(t, *lc.AttestedHeader.HeaderEth1.WithdrawalsHash, libcommon.HexToHash("0xdc96edf3b75ae19c608c0d5f821c3e71a577f310bf5da42bf51293394205b282")) - require.Equal(t, lc.AttestedHeader.ExecutionBranch[0], libcommon.HexToHash("0x9e29304aab0d41643d772d076861e0c951c5212f92e2c8b7788ee79c7a03c045")) - require.Equal(t, lc.SignatureSlot, uint64(6292665015452153680)) - require.Equal(t, lc.SyncAggregate.SyncCommiteeSignature[:], common.Hex2Bytes("60ac5c67c7a2f460b665a3a5f618d3b8e2356a2338279e2d24134795398e286ac0299cd6367986266f073c3a6b400f7d62a586e9687e7aace3dede4172677c6af2515338ceb3591a86bdae014c3cc057ffbcc1afe4127e8b55ad508ebcead13a")) - // encoding it back - dec, err := lc.EncodeSSZ(nil) - require.NoError(t, err) - require.Equal(t, dec, decodedSSZ) -} - -func TestLightclientFinalityEncodingDecoding(t *testing.T) { - lc := cltypes.LightClientFinalityUpdate{} - decodedSSZ, err := utils.DecompressSnappy(finalityTest) - require.NoError(t, err) - require.NoError(t, lc.DecodeSSZWithVersion(decodedSSZ, int(clparams.CapellaVersion))) - // checking fields - require.Equal(t, lc.AttestedHeader.HeaderEth2.BodyRoot, libcommon.HexToHash("0xcc67d01f9d529e16333170f366defcc0bb8fbd0a9b84bd13d787bbcf86fe3cc5")) - require.Equal(t, *lc.AttestedHeader.HeaderEth1.WithdrawalsHash, libcommon.HexToHash("0x28ce6c427881a19a7aaf0d2f8255e30376ee19193cd0278244141e1a66f3c45b")) - require.Equal(t, lc.AttestedHeader.ExecutionBranch[0], libcommon.HexToHash("0x3e85d631970da85df7a6dab6c62c198d0a291e891d5a897bafc87bcfd2312cf6")) - // Finalized header - require.Equal(t, lc.FinalizedHeader.HeaderEth2.BodyRoot, libcommon.HexToHash("0xbaa18d70c7a36d7e3af79bf0874b902a173d83daad5c56f83ede72788abda4e8")) - require.Equal(t, *lc.FinalizedHeader.HeaderEth1.WithdrawalsHash, libcommon.HexToHash("0x778c759c4dc95d80121cc56338c0e8fa657d3a39b6cfa67eec5ec471de48fa7e")) - require.Equal(t, lc.FinalizedHeader.ExecutionBranch[0], libcommon.HexToHash("0x103bab66f63d57f6158eef6f18c9ffcc6e9b2e2593731a58001fc991c39ac618")) - // Rest - require.Equal(t, lc.FinalityBranch[0], libcommon.HexToHash("838ab6e8d817f3d454a69e79a435cca780df0e5b1e62971df7fec176e57f7f37")) - require.Equal(t, lc.SignatureSlot, uint64(9588297899091073326)) - require.Equal(t, lc.SyncAggregate.SyncCommiteeSignature[:], common.Hex2Bytes("8eb0eb4c085e840235f15086287f62815607f2aac486f07b78a8b41ec6d0baee8b34f664b8efdee877080b44e3104792fe90dce4a211e9e58abeeefcb67b4918c61e01950b927ad25a988ebf52761c6c1d26eae4f501238359aac17361d6c3ae")) - // encoding it back - dec, err := lc.EncodeSSZ(nil) - require.NoError(t, err) - require.Equal(t, dec, decodedSSZ) -} - -func TestLightclientUpdateEncodingDecoding(t *testing.T) { - lc := cltypes.LightClientUpdate{} - decodedSSZ, err := utils.DecompressSnappy(updateTest) - require.NoError(t, err) - require.NoError(t, lc.DecodeSSZWithVersion(decodedSSZ, int(clparams.CapellaVersion))) - // checking fields - require.Equal(t, lc.AttestedHeader.HeaderEth2.BodyRoot, libcommon.HexToHash("0x49f3c74b8874e1595d74d970886245aff4748a11d499a8e4a9459e76e2c8c42f")) - require.Equal(t, *lc.AttestedHeader.HeaderEth1.WithdrawalsHash, libcommon.HexToHash("0xab14e4976e1af2983f637d57360f03fafb3d0586be3efe254ba32d612ebf21ea")) - require.Equal(t, lc.AttestedHeader.ExecutionBranch[0], libcommon.HexToHash("0x1b42aa11e8fb2cfe30f4ce521021426eb22824b1f2934e85c134c8d71795faf7")) - // Finalized header - require.Equal(t, lc.FinalizedHeader.HeaderEth2.BodyRoot, libcommon.HexToHash("0xcb968a1a97415c40e9fffcb2afc34cf97a41f37dabe0a2135f54441652cc9f9d")) - require.Equal(t, *lc.FinalizedHeader.HeaderEth1.WithdrawalsHash, libcommon.HexToHash("0xf9c686992daa952349ec70a44bf14238135b25c788f1286d8c5cb7aa8d43b94b")) - require.Equal(t, lc.FinalizedHeader.ExecutionBranch[0], libcommon.HexToHash("0x0c921fe9c8f7818d508ff6fb77c65ec143f1822ae520a63c4ebf8a80f11d5456")) - // Next sync committee - require.Equal(t, lc.NextSyncCommitee.PubKeys[0][:], common.Hex2Bytes("29a24e45031507af4f61d534c734042b67ce0e36a549f93e8b72644a4e3874e142a438d4e30eaa53d235125dd1cd7853")) - require.Equal(t, lc.NextSyncCommitee.PubKeys[len(lc.NextSyncCommitee.PubKeys)-1][:], common.Hex2Bytes("9dd39a3f44bdcf1b8df92202049b3f9114d59964d75d838bdd0011e161d65c1b320b22df82e78cc1ded097738e44f943")) - require.Equal(t, lc.NextSyncCommitee.AggregatePublicKey[:], common.Hex2Bytes("fa65b9c18cdc09b0378365eef95bc7607f15c27ac655b0d36ab415eec9b86b611f9e4a91fde40ee41f9756e445b7bf60")) - require.Equal(t, lc.NextSyncCommitteeBranch[0], libcommon.HexToHash("dbfa8fa48e3d6ddc4f03f7eaf7a8c972d93874be3dc099f04321d9f0330b4a7a")) - - // Rest - require.Equal(t, lc.FinalityBranch[0], libcommon.HexToHash("4fba794addb5d9a72464494236a7d571d4291bce2e03d64bec942f1fc72ab0df")) - require.Equal(t, lc.SignatureSlot, uint64(10239421204327532221)) - require.Equal(t, lc.SyncAggregate.SyncCommiteeSignature[:], common.Hex2Bytes("7d280e88d4358bcd312e9ccd894fef1dfeaf46e4a081ea07971779238a3dd8ad2ba339954e464df0a4cbbbbbd22258bdf543ad6f51232ec48e2d151527909c084189480dd6e350d5e022621aceeb478ff215b9d0e8fcd4fc7dca8c963f70533a")) - // encoding it back - dec, err := lc.EncodeSSZ(nil) - require.NoError(t, err) - require.Equal(t, dec, decodedSSZ) -} diff --git a/cl/cltypes/network_test.go b/cl/cltypes/network_test.go index 94f89921e02..1ffc3faf6bb 100644 --- a/cl/cltypes/network_test.go +++ b/cl/cltypes/network_test.go @@ -8,7 +8,7 @@ import ( "github.com/ledgerwatch/erigon/cl/clparams" "github.com/ledgerwatch/erigon/cl/cltypes" - "github.com/ledgerwatch/erigon/cl/cltypes/ssz_utils" + "github.com/ledgerwatch/erigon/cl/cltypes/ssz" ) var testMetadata = &cltypes.Metadata{ @@ -49,70 +49,23 @@ var testHeader = &cltypes.BeaconBlockHeader{ BodyRoot: libcommon.HexToHash("ad"), } -var testLcHeader = (&cltypes.LightClientHeader{ - HeaderEth1: getTestEth1Block().Header, - HeaderEth2: testHeader, -}).WithVersion(clparams.CapellaVersion) - -var testLcUpdate = (&cltypes.LightClientUpdate{ - AttestedHeader: testLcHeader, - NextSyncCommitee: &cltypes.SyncCommittee{ - PubKeys: make([][48]byte, 512), - }, - NextSyncCommitteeBranch: make([]libcommon.Hash, 5), - FinalizedHeader: testLcHeader, - FinalityBranch: make([]libcommon.Hash, 6), - SyncAggregate: &cltypes.SyncAggregate{}, - SignatureSlot: 294, -}).WithVersion(clparams.CapellaVersion) - -var testLcUpdateFinality = (&cltypes.LightClientFinalityUpdate{ - AttestedHeader: testLcHeader, - FinalizedHeader: testLcHeader, - FinalityBranch: make([]libcommon.Hash, 6), - SyncAggregate: &cltypes.SyncAggregate{}, - SignatureSlot: 294, -}).WithVersion(clparams.CapellaVersion) - -var testLcUpdateOptimistic = (&cltypes.LightClientOptimisticUpdate{ - AttestedHeader: testLcHeader, - SyncAggregate: &cltypes.SyncAggregate{}, - SignatureSlot: 294, -}).WithVersion(clparams.CapellaVersion) - -var testLcBootstrap = (&cltypes.LightClientBootstrap{ - Header: testLcHeader, - CurrentSyncCommittee: &cltypes.SyncCommittee{ - PubKeys: make([][48]byte, 512), - }, - CurrentSyncCommitteeBranch: make([]libcommon.Hash, 5), -}).WithVersion(clparams.CapellaVersion) - func TestMarshalNetworkTypes(t *testing.T) { - cases := []ssz_utils.EncodableSSZ{ + cases := []ssz.EncodableSSZ{ testMetadata, testPing, testSingleRoot, testLcRangeRequest, testBlockRangeRequest, testStatus, - testLcUpdate, - testLcUpdateFinality, - testLcUpdateOptimistic, - testLcBootstrap, } - unmarshalDestinations := []ssz_utils.EncodableSSZ{ + unmarshalDestinations := []ssz.EncodableSSZ{ &cltypes.Metadata{}, &cltypes.Ping{}, &cltypes.SingleRoot{}, &cltypes.LightClientUpdatesByRangeRequest{}, &cltypes.BeaconBlocksByRangeRequest{}, &cltypes.Status{}, - &cltypes.LightClientUpdate{}, - &cltypes.LightClientFinalityUpdate{}, - &cltypes.LightClientOptimisticUpdate{}, - &cltypes.LightClientBootstrap{}, } for i, tc := range cases { marshalledBytes, err := tc.EncodeSSZ(nil) diff --git a/cl/cltypes/ssz_utils/ssz.go b/cl/cltypes/ssz_utils/ssz.go index 80b9999a1d8..91a48b3ac0d 100644 --- a/cl/cltypes/ssz_utils/ssz.go +++ b/cl/cltypes/ssz_utils/ssz.go @@ -99,7 +99,9 @@ func DecodeDynamicList[T Unmarshaler](bytes []byte, start, end, max uint32) ([]T return nil, ErrBadOffset } objs[i] = objs[i].Clone().(T) - objs[i].DecodeSSZ(buf[currentOffset:endOffset]) + if err := objs[i].DecodeSSZ(buf[currentOffset:endOffset]); err != nil { + return nil, err + } currentOffset = endOffset } return objs, nil @@ -121,7 +123,9 @@ func DecodeStaticList[T Unmarshaler](bytes []byte, start, end, bytesPerElement u objs := make([]T, elementsNum) for i := range objs { objs[i] = objs[i].Clone().(T) - objs[i].DecodeSSZ(buf[i*int(bytesPerElement):]) + if err := objs[i].DecodeSSZ(buf[i*int(bytesPerElement):]); err != nil { + return nil, err + } } return objs, nil } diff --git a/cl/cltypes/validator.go b/cl/cltypes/validator.go index 87c086b42e9..ed2331baf8c 100644 --- a/cl/cltypes/validator.go +++ b/cl/cltypes/validator.go @@ -207,6 +207,14 @@ type SyncCommittee struct { AggregatePublicKey [48]byte `ssz-size:"48"` } +func (s *SyncCommittee) Copy() *SyncCommittee { + copied := new(SyncCommittee) + copied.AggregatePublicKey = s.AggregatePublicKey + copied.PubKeys = make([][48]byte, len(s.PubKeys)) + copy(copied.PubKeys, s.PubKeys) + return copied +} + // MarshalSSZTo ssz marshals the SyncCommittee object to a target array func (s *SyncCommittee) EncodeSSZ(buf []byte) ([]byte, error) { dst := buf @@ -360,3 +368,8 @@ func (v *Validator) HashSSZ() ([32]byte, error) { func (v *Validator) Active(epoch uint64) bool { return v.ActivationEpoch <= epoch && epoch < v.ExitEpoch } + +func (v *Validator) Copy() *Validator { + copied := *v + return &copied +} diff --git a/cl/fork/fork_test.go b/cl/fork/fork_test.go index 30e47f4c4cf..9aaaf4e1de3 100644 --- a/cl/fork/fork_test.go +++ b/cl/fork/fork_test.go @@ -27,5 +27,5 @@ func TestMainnetFork(t *testing.T) { require.NoError(t, err) _, err = ComputeForkId(&beaconCfg, &genesisCfg) require.NoError(t, err) - require.Equal(t, digest, [4]byte{74, 38, 197, 139}) + require.Equal(t, [4]byte{0xbb, 0xa4, 0xda, 0x96}, digest) } diff --git a/cl/fork/id.go b/cl/fork/id.go deleted file mode 100644 index 6f49755bda2..00000000000 --- a/cl/fork/id.go +++ /dev/null @@ -1,99 +0,0 @@ -package fork - -import ( - "github.com/ledgerwatch/erigon/cl/clparams" - "github.com/ledgerwatch/erigon/cl/utils" - pubsubpb "github.com/libp2p/go-libp2p-pubsub/pb" -) - -// MsgID return the id of Gossip message during subscription. -func MsgID(pmsg *pubsubpb.Message, networkConfig *clparams.NetworkConfig, beaconConfig *clparams.BeaconChainConfig, genesisConfig *clparams.GenesisConfig) string { - if pmsg == nil || pmsg.Data == nil || pmsg.Topic == nil { - // Impossible condition that should - // never be hit. - msg := make([]byte, 20) - copy(msg, "invalid") - return string(msg) - } - - fEpoch := getLastForkEpoch(beaconConfig, genesisConfig) - - if fEpoch >= beaconConfig.AltairForkEpoch { - return postAltairMsgID(pmsg, fEpoch, networkConfig, beaconConfig) - } - - decodedData, err := utils.DecompressSnappy(pmsg.Data) - if err != nil { - msg := make([]byte, 20) - copy(msg, "invalid") - return string(msg) - } - - if err != nil { - combinedData := append(networkConfig.MessageDomainInvalidSnappy[:], pmsg.Data...) - h := utils.Keccak256(combinedData) - return string(h[:20]) - } - combinedData := append(networkConfig.MessageDomainValidSnappy[:], decodedData...) - h := utils.Keccak256(combinedData) - return string(h[:20]) -} - -func postAltairMsgID(pmsg *pubsubpb.Message, fEpoch uint64, networkConfig *clparams.NetworkConfig, beaconConfig *clparams.BeaconChainConfig) string { - topic := *pmsg.Topic - topicLen := len(topic) - topicLenBytes := utils.Uint64ToLE(uint64(topicLen)) // topicLen cannot be negative - - // beyond Bellatrix epoch, allow 10 Mib gossip data size - gossipPubSubSize := networkConfig.GossipMaxSize - if fEpoch >= beaconConfig.BellatrixForkEpoch { - gossipPubSubSize = networkConfig.GossipMaxSizeBellatrix - } - - decodedData, err := utils.DecompressSnappy(pmsg.Data) - if err != nil { - totalLength := len(networkConfig.MessageDomainValidSnappy) + len(topicLenBytes) + topicLen + len(pmsg.Data) - if uint64(totalLength) > gossipPubSubSize { - // this should never happen - msg := make([]byte, 20) - copy(msg, "invalid") - return string(msg) - } - combinedData := make([]byte, 0, totalLength) - combinedData = append(combinedData, networkConfig.MessageDomainInvalidSnappy[:]...) - combinedData = append(combinedData, topicLenBytes...) - combinedData = append(combinedData, topic...) - combinedData = append(combinedData, pmsg.Data...) - h := utils.Keccak256(combinedData) - return string(h[:20]) - } - totalLength := len(networkConfig.MessageDomainValidSnappy) + - len(topicLenBytes) + - topicLen + - len(decodedData) - - combinedData := make([]byte, 0, totalLength) - combinedData = append(combinedData, networkConfig.MessageDomainValidSnappy[:]...) - combinedData = append(combinedData, topicLenBytes...) - combinedData = append(combinedData, topic...) - combinedData = append(combinedData, decodedData...) - h := utils.Keccak256(combinedData) - return string(h[:20]) -} - -func getLastForkEpoch( - beaconConfig *clparams.BeaconChainConfig, - genesisConfig *clparams.GenesisConfig, -) uint64 { - currentEpoch := utils.GetCurrentEpoch(genesisConfig.GenesisTime, beaconConfig.SecondsPerSlot, beaconConfig.SlotsPerEpoch) - // Retrieve current fork version. - var currentForkEpoch uint64 - for _, fork := range forkList(beaconConfig.ForkVersionSchedule) { - if currentEpoch >= fork.epoch { - currentForkEpoch = fork.epoch - continue - } - break - } - return currentForkEpoch -} diff --git a/cl/rpc/rpc.go b/cl/rpc/rpc.go index 86f93ddaa40..57adac1ab59 100644 --- a/cl/rpc/rpc.go +++ b/cl/rpc/rpc.go @@ -17,7 +17,6 @@ import ( "github.com/ledgerwatch/erigon/cl/clparams" "github.com/ledgerwatch/erigon/cl/cltypes" - "github.com/ledgerwatch/erigon/cl/cltypes/ssz_utils" "github.com/ledgerwatch/erigon/cl/fork" "github.com/ledgerwatch/erigon/cl/utils" "github.com/ledgerwatch/erigon/cmd/sentinel/sentinel/communication" @@ -50,108 +49,6 @@ func NewBeaconRpcP2P(ctx context.Context, sentinel sentinel.SentinelClient, beac } } -// SendLightClientFinalityUpdateReqV1 sends a request for a LightClientFinalityUpdate message to a beacon chain node. -// It returns a LightClientFinalityUpdate struct or an error if one occurred. -func (b *BeaconRpcP2P) SendLightClientFinaltyUpdateReqV1() (*cltypes.LightClientFinalityUpdate, error) { - responsePacket := &cltypes.LightClientFinalityUpdate{} - - message, err := b.sentinel.SendRequest(b.ctx, &sentinel.RequestData{ - Topic: communication.LightClientFinalityUpdateV1, - }) - if err != nil { - return nil, err - } - if message.Error { - log.Warn("received error", "err", string(message.Data)) - return nil, nil - } - - if err := ssz_snappy.DecodeAndRead(bytes.NewReader(message.Data), responsePacket, b.beaconConfig, b.genesisConfig.GenesisValidatorRoot); err != nil { - return nil, fmt.Errorf("unable to decode packet: %v", err) - } - return responsePacket, nil -} - -// SendLightClientOptimisticUpdateReqV1 sends a request for a LightClientOptimisticUpdate message to a beacon chain node. -// It returns a LightClientOptimisticUpdate struct or an error if one occurred. -func (b *BeaconRpcP2P) SendLightClientOptimisticUpdateReqV1() (*cltypes.LightClientOptimisticUpdate, error) { - responsePacket := &cltypes.LightClientOptimisticUpdate{} - - message, err := b.sentinel.SendRequest(b.ctx, &sentinel.RequestData{ - Topic: communication.LightClientOptimisticUpdateV1, - }) - if err != nil { - return nil, err - } - if message.Error { - log.Warn("received error", "err", string(message.Data)) - return nil, nil - } - - if err := ssz_snappy.DecodeAndRead(bytes.NewReader(message.Data), responsePacket, b.beaconConfig, b.genesisConfig.GenesisValidatorRoot); err != nil { - return nil, fmt.Errorf("unable to decode packet: %v", err) - } - return responsePacket, nil -} - -// SendLightClientBootstrapReqV1 sends a request for a LightClientBootstrap message to a beacon chain node. -// It returns a LightClientBootstrap struct or an error if one occurred. -func (b *BeaconRpcP2P) SendLightClientBootstrapReqV1(root libcommon.Hash) (*cltypes.LightClientBootstrap, error) { - var buffer buffer.Buffer - if err := ssz_snappy.EncodeAndWrite(&buffer, &cltypes.SingleRoot{Root: root}); err != nil { - return nil, err - } - responsePacket := &cltypes.LightClientBootstrap{} - data := common.CopyBytes(buffer.Bytes()) - message, err := b.sentinel.SendRequest(b.ctx, &sentinel.RequestData{ - Data: data, - Topic: communication.LightClientBootstrapV1, - }) - if err != nil { - return nil, err - } - if message.Error { - log.Warn("received error", "err", string(message.Data)) - return nil, nil - } - if err := ssz_snappy.DecodeAndRead(bytes.NewReader(message.Data), responsePacket, b.beaconConfig, b.genesisConfig.GenesisValidatorRoot); err != nil { - return nil, fmt.Errorf("unable to decode packet: %v", err) - } - return responsePacket, nil -} - -// SendLightClientUpdatesReqV1 retrieves one lightclient update. -func (b *BeaconRpcP2P) SendLightClientUpdatesReqV1(period uint64) (*cltypes.LightClientUpdate, error) { - // This is approximately one day worth of data, we dont need to receive more than 1. - req := &cltypes.LightClientUpdatesByRangeRequest{ - Period: period, - Count: 1, - } - var buffer buffer.Buffer - if err := ssz_snappy.EncodeAndWrite(&buffer, req); err != nil { - return nil, err - } - - responsePacket := []ssz_utils.EncodableSSZ{&cltypes.LightClientUpdate{}} - - data := common.CopyBytes(buffer.Bytes()) - message, err := b.sentinel.SendRequest(b.ctx, &sentinel.RequestData{ - Data: data, - Topic: communication.LightClientUpdatesByRangeV1, - }) - if err != nil { - return nil, err - } - if message.Error { - log.Warn("received error", "err", string(message.Data)) - return nil, nil - } - if err := ssz_snappy.DecodeListSSZ(message.Data, 1, responsePacket, b.beaconConfig, b.genesisConfig.GenesisValidatorRoot); err != nil { - return nil, fmt.Errorf("unable to decode packet: %v", err) - } - return responsePacket[0].(*cltypes.LightClientUpdate), nil -} - func (b *BeaconRpcP2P) sendBlocksRequest(topic string, reqData []byte, count uint64) ([]*cltypes.SignedBeaconBlock, error) { // Prepare output slice. responsePacket := []*cltypes.SignedBeaconBlock{} @@ -272,3 +169,15 @@ func (b *BeaconRpcP2P) SetStatus(finalizedRoot libcommon.Hash, finalizedEpoch ui }) return err } + +func (b *BeaconRpcP2P) PropagateBlock(block *cltypes.SignedBeaconBlock) error { + encoded, err := block.EncodeSSZ(nil) + if err != nil { + return err + } + _, err = b.sentinel.PublishGossip(b.ctx, &sentinel.GossipData{ + Data: encoded, + Type: sentinel.GossipType_BeaconBlockGossipType, + }) + return err +} diff --git a/cmd/abigen/main.go b/cmd/abigen/main.go index b6a75323f58..6d361b48388 100644 --- a/cmd/abigen/main.go +++ b/cmd/abigen/main.go @@ -180,7 +180,7 @@ func abigen(c *cli.Context) error { } else { // Generate the list of types to exclude from binding exclude := make(map[string]bool) - for _, kind := range strings.Split(c.String(excFlag.Name), ",") { + for _, kind := range utils.SplitAndTrim(c.String(excFlag.Name)) { exclude[strings.ToLower(kind)] = true } var err error diff --git a/cmd/bootnode/main.go b/cmd/bootnode/main.go index abdbbecd384..b954f536e14 100644 --- a/cmd/bootnode/main.go +++ b/cmd/bootnode/main.go @@ -51,7 +51,7 @@ func main() { ) flag.Parse() - _ = logging.GetLogger("bootnode") + logging.SetupLogger("bootnode") natm, err := nat.Parse(*natdesc) if err != nil { diff --git a/cmd/caplin-phase1/caplin1/run.go b/cmd/caplin-phase1/caplin1/run.go new file mode 100644 index 00000000000..04c7e5074bd --- /dev/null +++ b/cmd/caplin-phase1/caplin1/run.go @@ -0,0 +1,31 @@ +package caplin1 + +import ( + "context" + + "github.com/ledgerwatch/erigon-lib/gointerfaces/sentinel" + "github.com/ledgerwatch/erigon/cl/clparams" + "github.com/ledgerwatch/erigon/cl/rpc" + "github.com/ledgerwatch/erigon/cmd/erigon-cl/core/state" + "github.com/ledgerwatch/erigon/cmd/erigon-cl/execution_client" + "github.com/ledgerwatch/erigon/cmd/erigon-cl/forkchoice" + "github.com/ledgerwatch/erigon/cmd/erigon-cl/network" + "github.com/ledgerwatch/erigon/cmd/erigon-cl/stages" + "github.com/ledgerwatch/log/v3" + + "github.com/ledgerwatch/erigon/eth/stagedsync" +) + +func RunCaplinPhase1(ctx context.Context, sentinel sentinel.SentinelClient, beaconConfig *clparams.BeaconChainConfig, genesisConfig *clparams.GenesisConfig, engine execution_client.ExecutionEngine, state *state.BeaconState) error { + beaconRpc := rpc.NewBeaconRpcP2P(ctx, sentinel, beaconConfig, genesisConfig) + downloader := network.NewForwardBeaconDownloader(ctx, beaconRpc) + + forkChoice, err := forkchoice.NewForkChoiceStore(state, engine, true) + if err != nil { + log.Error("Could not create forkchoice", "err", err) + return err + } + gossipManager := network.NewGossipReceiver(ctx, sentinel, forkChoice, beaconConfig, genesisConfig) + + return stages.SpawnStageForkChoice(stages.StageForkChoice(nil, downloader, genesisConfig, beaconConfig, state, nil, gossipManager, forkChoice), &stagedsync.StageState{ID: "Caplin"}, nil, ctx) +} diff --git a/cmd/lightclient/main.go b/cmd/caplin-phase1/main.go similarity index 66% rename from cmd/lightclient/main.go rename to cmd/caplin-phase1/main.go index 9a1e1c599e9..262b02c1b5a 100644 --- a/cmd/lightclient/main.go +++ b/cmd/caplin-phase1/main.go @@ -19,27 +19,24 @@ import ( "os" "github.com/ledgerwatch/erigon-lib/gointerfaces/remote" - "github.com/ledgerwatch/erigon-lib/kv" - "github.com/ledgerwatch/erigon-lib/kv/mdbx" - "github.com/ledgerwatch/erigon-lib/kv/memdb" "github.com/ledgerwatch/log/v3" "github.com/urfave/cli/v2" "google.golang.org/grpc" "github.com/ledgerwatch/erigon/cl/cltypes" "github.com/ledgerwatch/erigon/cl/fork" + "github.com/ledgerwatch/erigon/cmd/caplin-phase1/caplin1" "github.com/ledgerwatch/erigon/cmd/erigon-cl/core" - "github.com/ledgerwatch/erigon/cmd/lightclient/lightclient" + "github.com/ledgerwatch/erigon/cmd/erigon-cl/execution_client" lcCli "github.com/ledgerwatch/erigon/cmd/sentinel/cli" "github.com/ledgerwatch/erigon/cmd/sentinel/cli/flags" "github.com/ledgerwatch/erigon/cmd/sentinel/sentinel" - "github.com/ledgerwatch/erigon/cmd/sentinel/sentinel/handshake" "github.com/ledgerwatch/erigon/cmd/sentinel/sentinel/service" lightclientapp "github.com/ledgerwatch/erigon/turbo/app" ) func main() { - app := lightclientapp.MakeApp(runLightClientNode, flags.LCDefaultFlags) + app := lightclientapp.MakeApp(runCaplinNode, flags.LCDefaultFlags) if err := app.Run(os.Args); err != nil { _, printErr := fmt.Fprintln(os.Stderr, err) if printErr != nil { @@ -49,25 +46,15 @@ func main() { } } -func runLightClientNode(cliCtx *cli.Context) error { +func runCaplinNode(cliCtx *cli.Context) error { ctx := context.Background() cfg, err := lcCli.SetupConsensusClientCfg(cliCtx) if err != nil { - log.Error("[Lightclient] Could not initialize lightclient", "err", err) + log.Error("[Phase1] Could not initialize caplin", "err", err) } log.Root().SetHandler(log.LvlFilterHandler(log.Lvl(cfg.LogLvl), log.StderrHandler)) - log.Info("[LightClient]", "chain", cliCtx.String(flags.Chain.Name)) - log.Info("[LightClient] Running lightclient", "cfg", cfg) - var db kv.RwDB - if cfg.Chaindata == "" { - log.Info("chaindata is in-memory") - db = memdb.New("" /* tmpDir */) - } else { - db, err = mdbx.Open(cfg.Chaindata, log.Root(), false) - if err != nil { - return err - } - } + log.Info("[Phase1]", "chain", cliCtx.String(flags.Chain.Name)) + log.Info("[Phase1] Running Caplin", "cfg", cfg) state, err := core.RetrieveBeaconState(ctx, cfg.BeaconCfg, cfg.GenesisCfg, cfg.CheckpointUri) if err != nil { return err @@ -86,40 +73,31 @@ func runLightClientNode(cliCtx *cli.Context) error { NetworkConfig: cfg.NetworkCfg, BeaconConfig: cfg.BeaconCfg, NoDiscovery: cfg.NoDiscovery, - }, db, &service.ServerConfig{Network: cfg.ServerProtocol, Addr: cfg.ServerAddr}, nil, &cltypes.Status{ + }, nil, &service.ServerConfig{Network: cfg.ServerProtocol, Addr: cfg.ServerAddr}, nil, &cltypes.Status{ ForkDigest: forkDigest, FinalizedRoot: state.FinalizedCheckpoint().Root, FinalizedEpoch: state.FinalizedCheckpoint().Epoch, HeadSlot: state.FinalizedCheckpoint().Epoch * cfg.BeaconCfg.SlotsPerEpoch, HeadRoot: state.FinalizedCheckpoint().Root, - }, handshake.LightClientRule) + }) if err != nil { log.Error("Could not start sentinel", "err", err) } + log.Info("Sentinel started", "addr", cfg.ServerAddr) if err != nil { log.Error("[Checkpoint Sync] Failed", "reason", err) return err } - var execution remote.ETHBACKENDClient + var engine execution_client.ExecutionEngine if cfg.ErigonPrivateApi != "" { cc, err := grpc.Dial(cfg.ErigonPrivateApi, grpc.WithInsecure()) if err != nil { log.Error("could not connect to erigon private api", "err", err) } defer cc.Close() - execution = remote.NewETHBACKENDClient(cc) - } - lc, err := lightclient.NewLightClient(ctx, db, cfg.GenesisCfg, cfg.BeaconCfg, nil, execution, sentinel, 0, true) - if err != nil { - log.Error("Could not make Lightclient", "err", err) - return err - } - if err := lc.BootstrapCheckpoint(ctx, state.FinalizedCheckpoint().Root); err != nil { - log.Error("[Bootstrap] failed to bootstrap", "err", err) - return err + engine = execution_client.NewExecutionEnginePhase1FromClient(ctx, remote.NewETHBACKENDClient(cc)) } - lc.Start() - return nil + return caplin1.RunCaplinPhase1(ctx, sentinel, cfg.BeaconCfg, cfg.GenesisCfg, engine, state) } diff --git a/cmd/devnet/commands/all.go b/cmd/devnet/commands/all.go index e746bd415e2..0236e36af82 100644 --- a/cmd/devnet/commands/all.go +++ b/cmd/devnet/commands/all.go @@ -22,7 +22,7 @@ func ExecuteAllMethods() { // confirm that the txpool is empty fmt.Println("CONFIRMING TXPOOL IS EMPTY BEFORE SENDING TRANSACTION...") - services.CheckTxPoolContent(0, 0) + services.CheckTxPoolContent(0, 0, 0) fmt.Println() /* @@ -39,8 +39,6 @@ func ExecuteAllMethods() { //} //fmt.Println() - // USING DYNAMIC FEE - // send a token from the dev address to the recipient address _, err := callSendTxWithDynamicFee(recipientAddress, models.DevAddress) if err != nil { fmt.Printf("callSendTxWithDynamicFee error: %v\n", err) diff --git a/cmd/devnet/commands/block.go b/cmd/devnet/commands/block.go index 6259557b310..da7cd8c9712 100644 --- a/cmd/devnet/commands/block.go +++ b/cmd/devnet/commands/block.go @@ -2,8 +2,11 @@ package commands import ( "fmt" + "time" libcommon "github.com/ledgerwatch/erigon-lib/common" + "github.com/ledgerwatch/erigon-lib/common/hexutility" + "github.com/ledgerwatch/erigon/cmd/devnet/devnetutils" "github.com/ledgerwatch/erigon/cmd/devnet/models" "github.com/ledgerwatch/erigon/cmd/devnet/requests" @@ -40,8 +43,6 @@ func callSendTx(value uint64, toAddr, fromAddr string) (*libcommon.Hash, error) return nil, err } - fmt.Printf("SUCCESS => Tx submitted, adding tx with hash %q to txpool\n", hash) - hashes := map[libcommon.Hash]bool{*hash: true} if _, err = services.SearchReservesForTransactionHash(hashes); err != nil { return nil, fmt.Errorf("failed to call contract tx: %v", err) @@ -58,7 +59,7 @@ func callSendTxWithDynamicFee(toAddr, fromAddr string) ([]*libcommon.Hash, error return nil, err } - lowerThanBaseFeeTxs, higherThanBaseFeeTxs, err := services.CreateManyEIP1559TransactionsRefWithBaseFee(toAddr, &nonce) + lowerThanBaseFeeTxs, higherThanBaseFeeTxs, err := services.CreateManyEIP1559TransactionsRefWithBaseFee2(toAddr, &nonce) if err != nil { fmt.Printf("failed CreateManyEIP1559TransactionsRefWithBaseFee: %s\n", err) return nil, err @@ -76,7 +77,7 @@ func callSendTxWithDynamicFee(toAddr, fromAddr string) ([]*libcommon.Hash, error return nil, err } - services.CheckTxPoolContent(2, 0) + services.CheckTxPoolContent(100, 0, 100) hashmap := make(map[libcommon.Hash]bool) for _, hash := range higherThanBaseFeeHashlist { @@ -87,6 +88,24 @@ func callSendTxWithDynamicFee(toAddr, fromAddr string) ([]*libcommon.Hash, error return nil, fmt.Errorf("failed to call contract tx: %v", err) } + fmt.Println("SUCCESS: All transactions in pending pool mined.") + + for i := 1; i <= 20; i++ { + blockNumber, err := requests.BlockNumber(models.ReqId) + if err != nil { + fmt.Printf("FAILURE => error getting block number: %v\n", err) + } else { + fmt.Printf("Block number: %d\n", blockNumber) + } + pendingSize, queuedSize, baseFeeSize, err := requests.TxpoolContent(models.ReqId) + if err != nil { + fmt.Printf("FAILURE => error getting txpool content: %v\n", err) + } else { + fmt.Printf("Pending %d Queued %d, BaseFee %d\n", pendingSize, queuedSize, baseFeeSize) + } + time.Sleep(5 * time.Second) + } + return append(lowerThanBaseFeeHashlist, higherThanBaseFeeHashlist...), nil } @@ -114,7 +133,6 @@ func callContractTx() (*libcommon.Hash, error) { return nil, err } hashes[*hash] = true - fmt.Printf("SUCCESS => Tx submitted, adding tx with hash %q to txpool\n", hash) fmt.Println() eventHash, err := services.EmitFallbackEvent(subscriptionContract, transactOpts) @@ -137,7 +155,7 @@ func callContractTx() (*libcommon.Hash, error) { } expectedLog := devnetutils.BuildLog(*eventHash, blockNum, address, - devnetutils.GenerateTopic(models.SolContractMethodSignature), hexutil.Bytes{}, hexutil.Uint(1), + devnetutils.GenerateTopic(models.SolContractMethodSignature), hexutility.Bytes{}, hexutil.Uint(1), block.Result.Hash, hexutil.Uint(0), false) if err = requests.GetAndCompareLogs(models.ReqId, 0, 20, expectedLog); err != nil { diff --git a/cmd/devnet/devnetutils/utils.go b/cmd/devnet/devnetutils/utils.go index 5faa8665a82..81e5460acf7 100644 --- a/cmd/devnet/devnetutils/utils.go +++ b/cmd/devnet/devnetutils/utils.go @@ -5,6 +5,8 @@ import ( "encoding/json" "fmt" libcommon "github.com/ledgerwatch/erigon-lib/common" + "github.com/ledgerwatch/erigon-lib/common/hexutility" + "github.com/ledgerwatch/erigon/cmd/devnet/models" "github.com/ledgerwatch/erigon/cmd/rpctest/rpctest" "github.com/ledgerwatch/erigon/common/hexutil" @@ -115,7 +117,7 @@ func HashSlicesAreEqual(s1, s2 []libcommon.Hash) bool { return true } -func BuildLog(hash libcommon.Hash, blockNum string, address libcommon.Address, topics []libcommon.Hash, data hexutil.Bytes, txIndex hexutil.Uint, blockHash libcommon.Hash, index hexutil.Uint, removed bool) rpctest.Log { +func BuildLog(hash libcommon.Hash, blockNum string, address libcommon.Address, topics []libcommon.Hash, data hexutility.Bytes, txIndex hexutil.Uint, blockHash libcommon.Hash, index hexutil.Uint, removed bool) rpctest.Log { return rpctest.Log{ Address: address, Topics: topics, diff --git a/cmd/devnet/models/model.go b/cmd/devnet/models/model.go index c864f75329c..e375d80e74f 100644 --- a/cmd/devnet/models/model.go +++ b/cmd/devnet/models/model.go @@ -116,6 +116,8 @@ const ( ETHGetBlock RPCMethod = "eth_getBlock" // ETHGetLogs represents the eth_getLogs method ETHGetLogs RPCMethod = "eth_getLogs" + // ETHBlockNumber represents the eth_blockNumber method + ETHBlockNumber RPCMethod = "eth_blockNumber" // AdminNodeInfo represents the admin_nodeInfo method AdminNodeInfo RPCMethod = "admin_nodeInfo" // TxpoolContent represents the txpool_content method diff --git a/cmd/devnet/node/node.go b/cmd/devnet/node/node.go index 69eafce965d..66b00c10a33 100644 --- a/cmd/devnet/node/node.go +++ b/cmd/devnet/node/node.go @@ -78,15 +78,13 @@ func StartNode(wg *sync.WaitGroup, args []string) { // runNode configures, creates and serves an erigon node func runNode(ctx *cli.Context) error { - logger := log.New() - // Initializing the node and providing the current git commit there - logger.Info("Build info", "git_branch", params.GitBranch, "git_tag", params.GitTag, "git_commit", params.GitCommit) + log.Info("Build info", "git_branch", params.GitBranch, "git_tag", params.GitTag, "git_commit", params.GitCommit) nodeCfg := node.NewNodConfigUrfave(ctx) ethCfg := node.NewEthConfigUrfave(ctx, nodeCfg) - ethNode, err := node.New(nodeCfg, ethCfg, logger) + ethNode, err := node.New(nodeCfg, ethCfg) if err != nil { log.Error("Devnet startup", "err", err) return err diff --git a/cmd/devnet/requests/block.go b/cmd/devnet/requests/block.go index 3fae52c245d..98083c85d02 100644 --- a/cmd/devnet/requests/block.go +++ b/cmd/devnet/requests/block.go @@ -11,6 +11,21 @@ import ( "github.com/ledgerwatch/erigon/core/types" ) +func BlockNumber(reqId int) (uint64, error) { + reqGen := initialiseRequestGenerator(reqId) + var b rpctest.EthBlockNumber + + req := reqGen.BlockNumber() + res := reqGen.Erigon(models.ETHBlockNumber, req, &b) + number := uint64(b.Number) + + if res.Err != nil { + return number, fmt.Errorf("error getting current block number: %v", res.Err) + } + + return number, nil +} + func GetBlockByNumber(reqId int, blockNum uint64, withTxs bool) (rpctest.EthBlockByNumber, error) { reqGen := initialiseRequestGenerator(reqId) var b rpctest.EthBlockByNumber diff --git a/cmd/devnet/requests/request_generator.go b/cmd/devnet/requests/request_generator.go index a7feb87a311..48dbd8e7e0d 100644 --- a/cmd/devnet/requests/request_generator.go +++ b/cmd/devnet/requests/request_generator.go @@ -68,6 +68,11 @@ func (req *RequestGenerator) Erigon(method models.RPCMethod, body string, respon return req.call(models.ErigonUrl, string(method), body, response) } +func (req *RequestGenerator) BlockNumber() string { + const template = `{"jsonrpc":"2.0","method":%q,"id":%d}` + return fmt.Sprintf(template, models.ETHBlockNumber, req.reqID) +} + func (req *RequestGenerator) GetAdminNodeInfo() string { const template = `{"jsonrpc":"2.0","method":%q,"id":%d}` return fmt.Sprintf(template, models.AdminNodeInfo, req.reqID) diff --git a/cmd/devnet/requests/tx.go b/cmd/devnet/requests/tx.go index 407b9b3e9c6..bc254af58d1 100644 --- a/cmd/devnet/requests/tx.go +++ b/cmd/devnet/requests/tx.go @@ -3,37 +3,49 @@ package requests import ( "fmt" - "github.com/ledgerwatch/erigon/cmd/devnet/devnetutils" "github.com/ledgerwatch/erigon/cmd/rpctest/rpctest" ) -func TxpoolContent(reqId int) (int, int, error) { +func TxpoolContent(reqId int) (int, int, int, error) { var ( b rpctest.EthTxPool pending map[string]interface{} queued map[string]interface{} + baseFee map[string]interface{} ) reqGen := initialiseRequestGenerator(reqId) if res := reqGen.Erigon("txpool_content", reqGen.TxpoolContent(), &b); res.Err != nil { - return len(pending), len(queued), fmt.Errorf("failed to fetch txpool content: %v", res.Err) + return len(pending), len(queued), len(baseFee), fmt.Errorf("failed to fetch txpool content: %v", res.Err) } resp := b.Result.(map[string]interface{}) - s, err := devnetutils.ParseResponse(b) - if err != nil { - return len(pending), len(queued), fmt.Errorf("error parsing resonse: %v", err) - } + pendingLen := 0 + queuedLen := 0 + baseFeeLen := 0 if resp["pending"] != nil { pending = resp["pending"].(map[string]interface{}) + for _, txs := range pending { // iterate over senders + pendingLen += len(txs.(map[string]interface{})) + } } + if resp["queue"] != nil { queued = resp["queue"].(map[string]interface{}) + for _, txs := range queued { + queuedLen += len(txs.(map[string]interface{})) + } + } + + if resp["baseFee"] != nil { + baseFee = resp["baseFee"].(map[string]interface{}) + for _, txs := range baseFee { + baseFeeLen += len(txs.(map[string]interface{})) + } } - fmt.Printf("Txpool content: %v\n", s) - return len(pending), len(queued), nil + return pendingLen, queuedLen, baseFeeLen, nil } diff --git a/cmd/devnet/services/block.go b/cmd/devnet/services/block.go index 18f822d7f4f..103069bdc45 100644 --- a/cmd/devnet/services/block.go +++ b/cmd/devnet/services/block.go @@ -44,6 +44,24 @@ func CreateManyEIP1559TransactionsRefWithBaseFee(addr string, startingNonce *uin return lowerBaseFeeTransactions, higherBaseFeeTransactions, nil } +func CreateManyEIP1559TransactionsRefWithBaseFee2(addr string, startingNonce *uint64) ([]*types.Transaction, []*types.Transaction, error) { + toAddress := libcommon.HexToAddress(addr) + + baseFeePerGas, err := BaseFeeFromBlock() + if err != nil { + return nil, nil, fmt.Errorf("failed BaseFeeFromBlock: %v", err) + } + + fmt.Printf("BaseFeePerGas: %v\n", baseFeePerGas) + + lowerBaseFeeTransactions, higherBaseFeeTransactions, err := signEIP1559TxsLowerAndHigherThanBaseFee2(100, 100, baseFeePerGas, startingNonce, toAddress) + if err != nil { + return nil, nil, fmt.Errorf("failed signEIP1559TxsLowerAndHigherThanBaseFee2: %v", err) + } + + return lowerBaseFeeTransactions, higherBaseFeeTransactions, nil +} + // CreateTransaction creates a transaction depending on the type of transaction being passed func CreateTransaction(txType models.TransactionType, addr string, value, nonce uint64) (*types.Transaction, libcommon.Address, *contracts.Subscription, *bind.TransactOpts, error) { switch txType { @@ -77,14 +95,14 @@ func createNonContractTx(addr string, value, nonce uint64) (*types.Transaction, } func signEIP1559TxsLowerAndHigherThanBaseFee2(amountLower, amountHigher int, baseFeePerGas uint64, nonce *uint64, toAddress libcommon.Address) ([]*types.Transaction, []*types.Transaction, error) { - lowerBaseFeeTransactions, err := signEIP1559TxsLowerThanBaseFee(amountLower, baseFeePerGas, nonce, toAddress) + higherBaseFeeTransactions, err := signEIP1559TxsHigherThanBaseFee(amountHigher, baseFeePerGas, nonce, toAddress) if err != nil { - return nil, nil, fmt.Errorf("failed signEIP1559TxsLowerThanBaseFee: %v", err) + return nil, nil, fmt.Errorf("failed signEIP1559TxsHigherThanBaseFee: %v", err) } - higherBaseFeeTransactions, err := signEIP1559TxsHigherThanBaseFee(amountHigher, baseFeePerGas, nonce, toAddress) + lowerBaseFeeTransactions, err := signEIP1559TxsLowerThanBaseFee(amountLower, baseFeePerGas, nonce, toAddress) if err != nil { - return nil, nil, fmt.Errorf("failed signEIP1559TxsHigherThanBaseFee: %v", err) + return nil, nil, fmt.Errorf("failed signEIP1559TxsLowerThanBaseFee: %v", err) } return lowerBaseFeeTransactions, higherBaseFeeTransactions, nil @@ -122,6 +140,7 @@ func signEIP1559TxsLowerThanBaseFee(n int, baseFeePerGas uint64, nonce *uint64, } signedTransactions = append(signedTransactions, &signedTransaction) + *nonce++ } return signedTransactions, nil @@ -256,7 +275,6 @@ func EmitFallbackEvent(subContract *contracts.Subscription, opts *bind.TransactO if err != nil { return nil, fmt.Errorf("failed to send fallback transaction: %v", err) } - fmt.Printf("Tx submitted, adding tx with hash %q to txpool\n", hash) return hash, nil } @@ -287,7 +305,6 @@ func SendManyTransactions(signedTransactions []*types.Transaction) ([]*libcommon fmt.Printf("failed SendTransaction: %s\n", err) return nil, err } - fmt.Printf("SUCCESS => Tx submitted, adding tx with hash %q to txpool\n", hash) hashes[idx] = hash } diff --git a/cmd/devnet/services/tx.go b/cmd/devnet/services/tx.go index 00a76991e2c..837eb98ec89 100644 --- a/cmd/devnet/services/tx.go +++ b/cmd/devnet/services/tx.go @@ -7,8 +7,8 @@ import ( "github.com/ledgerwatch/erigon/cmd/devnet/requests" ) -func CheckTxPoolContent(expectedPendingSize, expectedQueuedSize int) { - pendingSize, queuedSize, err := requests.TxpoolContent(models.ReqId) +func CheckTxPoolContent(expectedPendingSize, expectedQueuedSize, expectedBaseFeeSize int) { + pendingSize, queuedSize, baseFeeSize, err := requests.TxpoolContent(models.ReqId) if err != nil { fmt.Printf("FAILURE => error getting txpool content: %v\n", err) return @@ -24,5 +24,9 @@ func CheckTxPoolContent(expectedPendingSize, expectedQueuedSize int) { return } - fmt.Printf("SUCCESS => %d transaction(s) in the pending pool and %d transaction(s) in the queued pool\n", pendingSize, queuedSize) + if baseFeeSize != expectedBaseFeeSize { + fmt.Printf("FAILURE => %v\n", fmt.Errorf("expected %d transaction(s) in baseFee pool, got %d", expectedBaseFeeSize, baseFeeSize)) + } + + fmt.Printf("SUCCESS => %d transaction(s) in the pending pool, %d transaction(s) in the queued pool and %d transaction(s) in the baseFee pool\n", pendingSize, queuedSize, baseFeeSize) } diff --git a/cmd/downloader/main.go b/cmd/downloader/main.go index 09cbb2cf2b3..457f480cefd 100644 --- a/cmd/downloader/main.go +++ b/cmd/downloader/main.go @@ -24,7 +24,7 @@ import ( "github.com/ledgerwatch/erigon/p2p/nat" "github.com/ledgerwatch/erigon/params" "github.com/ledgerwatch/erigon/turbo/debug" - logging2 "github.com/ledgerwatch/erigon/turbo/logging" + "github.com/ledgerwatch/erigon/turbo/logging" "github.com/ledgerwatch/log/v3" "github.com/pelletier/go-toml/v2" "github.com/spf13/cobra" @@ -45,6 +45,7 @@ var ( torrentVerbosity int downloadRateStr, uploadRateStr string torrentDownloadSlots int + staticPeersStr string torrentPort int torrentMaxPeers int torrentConnsPerFile int @@ -54,7 +55,7 @@ var ( ) func init() { - utils.CobraFlags(rootCmd, debug.Flags, utils.MetricFlags, logging2.Flags) + utils.CobraFlags(rootCmd, debug.Flags, utils.MetricFlags, logging.Flags) withDataDir(rootCmd) @@ -67,6 +68,7 @@ func init() { rootCmd.Flags().IntVar(&torrentMaxPeers, "torrent.maxpeers", utils.TorrentMaxPeersFlag.Value, utils.TorrentMaxPeersFlag.Usage) rootCmd.Flags().IntVar(&torrentConnsPerFile, "torrent.conns.perfile", utils.TorrentConnsPerFileFlag.Value, utils.TorrentConnsPerFileFlag.Usage) rootCmd.Flags().IntVar(&torrentDownloadSlots, "torrent.download.slots", utils.TorrentDownloadSlotsFlag.Value, utils.TorrentDownloadSlotsFlag.Usage) + rootCmd.Flags().StringVar(&staticPeersStr, utils.TorrentStaticPeersFlag.Name, utils.TorrentStaticPeersFlag.Value, utils.TorrentStaticPeersFlag.Usage) rootCmd.Flags().BoolVar(&disableIPV6, "downloader.disable.ipv6", utils.DisableIPV6.Value, utils.DisableIPV6.Usage) rootCmd.Flags().BoolVar(&disableIPV4, "downloader.disable.ipv4", utils.DisableIPV4.Value, utils.DisableIPV6.Usage) @@ -111,7 +113,7 @@ var rootCmd = &cobra.Command{ debug.Exit() }, Run: func(cmd *cobra.Command, args []string) { - _ = logging2.GetLoggerCmd("downloader", cmd) + logging.SetupLoggerCmd("downloader", cmd) if err := Downloader(cmd.Context()); err != nil { if !errors.Is(err, context.Canceled) { log.Error(err.Error()) @@ -141,9 +143,10 @@ func Downloader(ctx context.Context) error { if err != nil { return fmt.Errorf("invalid nat option %s: %w", natSetting, err) } + staticPeers := utils.SplitAndTrim(staticPeersStr) version := "erigon: " + params.VersionWithCommit(params.GitCommit) - cfg, err := downloadercfg2.New(dirs.Snap, version, torrentLogLevel, downloadRate, uploadRate, torrentPort, torrentConnsPerFile, torrentDownloadSlots) + cfg, err := downloadercfg2.New(dirs.Snap, version, torrentLogLevel, downloadRate, uploadRate, torrentPort, torrentConnsPerFile, torrentDownloadSlots, staticPeers) if err != nil { return err } @@ -158,7 +161,7 @@ func Downloader(ctx context.Context) error { } defer d.Close() log.Info("[torrent] Start", "my peerID", fmt.Sprintf("%x", d.Torrent().PeerID())) - go downloader.MainLoop(ctx, d, false) + d.MainLoopInBackground(ctx, false) bittorrentServer, err := downloader.NewGrpcServer(d) if err != nil { diff --git a/cmd/ef-tests-cl/consensus_tests/consensus_tester.go b/cmd/ef-tests-cl/consensus_tests/consensus_tester.go index bf9c1ebb75d..026ebcfa7a2 100644 --- a/cmd/ef-tests-cl/consensus_tests/consensus_tester.go +++ b/cmd/ef-tests-cl/consensus_tests/consensus_tester.go @@ -11,7 +11,7 @@ import ( "golang.org/x/exp/slices" ) -var supportedVersions = []string{"altair", "bellatrix"} +var supportedVersions = []string{"phase0", "altair", "bellatrix", "capella"} type ConsensusTester struct { // parameters @@ -70,7 +70,7 @@ func (c *ConsensusTester) iterateOverTests(dir, p string, depth int) { // Depth 1 means that we are setting the version if depth == 1 { if !slices.Contains(supportedVersions, childName) { - return + continue } c.context.version = stringToClVersion(childName) } @@ -81,12 +81,15 @@ func (c *ConsensusTester) iterateOverTests(dir, p string, depth int) { // depth 3 we find the specific c.context.caseName = childName } + // If we found a non-directory then it is a test folder. if !childDir.IsDir() { // Check if it matches case specified. if *c.pattern != "" && !strings.Contains(p, *c.pattern) { return } + log.Debug("Executing", "name", p) + // If yes execute it. if implemented, err := c.executeTest(p); err != nil { log.Warn("Test Failed", "err", err, "test", p) @@ -94,6 +97,7 @@ func (c *ConsensusTester) iterateOverTests(dir, p string, depth int) { } else if implemented { // Mark it as passed only if the test was actually implemented had no errors were found. c.passed++ + log.Debug("Test passed", "name", p) } return diff --git a/cmd/ef-tests-cl/consensus_tests/fork.go b/cmd/ef-tests-cl/consensus_tests/fork.go new file mode 100644 index 00000000000..05670134dab --- /dev/null +++ b/cmd/ef-tests-cl/consensus_tests/fork.go @@ -0,0 +1,54 @@ +package consensustests + +import ( + "fmt" + "os" + + "github.com/ledgerwatch/erigon/cl/clparams" +) + +func forkTest(context testContext) error { + prevContext := context + prevContext.version-- + preState, err := decodeStateFromFile(prevContext, "pre.ssz_snappy") + if err != nil { + return err + } + postState, err := decodeStateFromFile(context, "post.ssz_snappy") + expectedError := os.IsNotExist(err) + if err != nil && !expectedError { + return err + } + + if preState.Version() == clparams.Phase0Version { + if err := preState.UpgradeToAltair(); err != nil { + return err + } + } else if preState.Version() == clparams.AltairVersion { + if err := preState.UpgradeToBellatrix(); err != nil { + return err + } + } else if preState.Version() == clparams.BellatrixVersion { + if err := preState.UpgradeToCapella(); err != nil { + return err + } + } + if expectedError { + return fmt.Errorf("expected error") + } + root, err := preState.HashSSZ() + if err != nil { + return err + } + expectedRoot, err := postState.HashSSZ() + if err != nil { + return err + } + if root != expectedRoot { + return fmt.Errorf("mismatching state roots") + } + if context.version == clparams.AltairVersion { + return nil + } + return nil +} diff --git a/cmd/ef-tests-cl/consensus_tests/sanity.go b/cmd/ef-tests-cl/consensus_tests/sanity.go index 558fce8e8f6..b0c2642cefc 100644 --- a/cmd/ef-tests-cl/consensus_tests/sanity.go +++ b/cmd/ef-tests-cl/consensus_tests/sanity.go @@ -4,6 +4,7 @@ import ( "fmt" "os" + "github.com/ledgerwatch/erigon/cl/cltypes" "github.com/ledgerwatch/erigon/cmd/erigon-cl/core/transition" ) @@ -12,6 +13,7 @@ func testSanityFunction(context testContext) error { if err != nil { return err } + testState.HashSSZ() var expectedError bool expectedState, err := decodeStateFromFile(context, "post.ssz_snappy") if os.IsNotExist(err) { @@ -25,12 +27,16 @@ func testSanityFunction(context testContext) error { if err != nil { return err } - for _, block := range blocks { + startSlot := testState.Slot() + + var block *cltypes.SignedBeaconBlock + for _, block = range blocks { err = transition.TransitionState(testState, block, true) if err != nil { break } } + // Deal with transition error if expectedError && err == nil { return fmt.Errorf("expected error") @@ -39,9 +45,9 @@ func testSanityFunction(context testContext) error { if expectedError { return nil } - return err + return fmt.Errorf("cannot transition state: %s. slot=%d. start_slot=%d", err, block.Block.Slot, startSlot) } - expectedRoot, err := expectedState.HashSSZ() + finalRoot, err := expectedState.HashSSZ() if err != nil { return err } @@ -49,7 +55,7 @@ func testSanityFunction(context testContext) error { if err != nil { return err } - if haveRoot != expectedRoot { + if haveRoot != finalRoot { return fmt.Errorf("mismatching state roots") } return nil diff --git a/cmd/erigon-cl/core/rawdb/accessors.go b/cmd/erigon-cl/core/rawdb/accessors.go index 5b019710ea9..6cb87c1cf01 100644 --- a/cmd/erigon-cl/core/rawdb/accessors.go +++ b/cmd/erigon-cl/core/rawdb/accessors.go @@ -48,86 +48,6 @@ func ReadBeaconState(tx kv.Getter, slot uint64) (*state.BeaconState, error) { return state, nil } -func WriteLightClientUpdate(tx kv.RwTx, update *cltypes.LightClientUpdate) error { - key := make([]byte, 4) - binary.BigEndian.PutUint32(key, uint32(update.SignatureSlot/8192)) - - encoded, err := update.EncodeSSZ(nil) - if err != nil { - return err - } - return tx.Put(kv.LightClientUpdates, key, encoded) -} - -func WriteLightClientFinalityUpdate(tx kv.RwTx, update *cltypes.LightClientFinalityUpdate) error { - encoded, err := update.EncodeSSZ(nil) - if err != nil { - return err - } - return tx.Put(kv.LightClient, kv.LightClientFinalityUpdate, encoded) -} - -func WriteLightClientOptimisticUpdate(tx kv.RwTx, update *cltypes.LightClientOptimisticUpdate) error { - encoded, err := update.EncodeSSZ(nil) - if err != nil { - return err - } - return tx.Put(kv.LightClient, kv.LightClientOptimisticUpdate, encoded) -} - -func ReadLightClientUpdate(tx kv.RwTx, period uint32) (*cltypes.LightClientUpdate, error) { - key := make([]byte, 4) - binary.BigEndian.PutUint32(key, period) - - encoded, err := tx.GetOne(kv.LightClientUpdates, key) - if err != nil { - return nil, err - } - update := &cltypes.LightClientUpdate{} - if err = update.DecodeSSZ(encoded); err != nil { - return nil, err - } - return update, nil -} - -func ReadLightClientFinalityUpdate(tx kv.Tx) (*cltypes.LightClientFinalityUpdate, error) { - encoded, err := tx.GetOne(kv.LightClient, kv.LightClientFinalityUpdate) - if err != nil { - return nil, err - } - if len(encoded) == 0 { - return nil, nil - } - update := &cltypes.LightClientFinalityUpdate{} - if err = update.DecodeSSZ(encoded); err != nil { - return nil, err - } - return update, nil -} - -func ReadLightClientOptimisticUpdate(tx kv.Tx) (*cltypes.LightClientOptimisticUpdate, error) { - encoded, err := tx.GetOne(kv.LightClient, kv.LightClientOptimisticUpdate) - if err != nil { - return nil, err - } - if len(encoded) == 0 { - return nil, nil - } - update := &cltypes.LightClientOptimisticUpdate{} - if err = update.DecodeSSZ(encoded); err != nil { - return nil, err - } - return update, nil -} - -// Bytes2FromLength convert length to 2 bytes repressentation -func Bytes2FromLength(size int) []byte { - return []byte{ - byte(size>>8) & 0xFF, - byte(size>>0) & 0xFF, - } -} - // LengthBytes2 convert length to 2 bytes repressentation func LengthFromBytes2(buf []byte) int { return int(buf[0])*0x100 + int(buf[1]) diff --git a/cmd/erigon-cl/core/rawdb/accessors_test.go b/cmd/erigon-cl/core/rawdb/accessors_test.go index 860908c3ee9..2b57b3d9901 100644 --- a/cmd/erigon-cl/core/rawdb/accessors_test.go +++ b/cmd/erigon-cl/core/rawdb/accessors_test.go @@ -1,28 +1,15 @@ package rawdb_test import ( - "math/big" "testing" "github.com/ledgerwatch/erigon-lib/kv/memdb" "github.com/ledgerwatch/erigon/cl/cltypes" "github.com/ledgerwatch/erigon/cmd/erigon-cl/core/rawdb" - "github.com/ledgerwatch/erigon/core/types" "github.com/stretchr/testify/require" ) -func TestBytes2(t *testing.T) { - len := 1000 - buf := rawdb.Bytes2FromLength(len) - require.Equal(t, len, rawdb.LengthFromBytes2(buf)) -} - -var emptyBlock = &cltypes.Eth1Block{ - Header: &types.Header{ - BaseFee: big.NewInt(0), - Number: big.NewInt(0), - }, -} +var emptyBlock = &cltypes.Eth1Block{} func TestBeaconBlock(t *testing.T) { _, tx := memdb.NewTestTx(t) diff --git a/cmd/erigon-cl/core/state/accessors.go b/cmd/erigon-cl/core/state/accessors.go index 1f9be6b849c..7d6015c9151 100644 --- a/cmd/erigon-cl/core/state/accessors.go +++ b/cmd/erigon-cl/core/state/accessors.go @@ -2,24 +2,31 @@ package state import ( "encoding/binary" + "errors" "fmt" - "math/bits" + "math" "sort" + "github.com/Giulio2002/bls" libcommon "github.com/ledgerwatch/erigon-lib/common" "github.com/ledgerwatch/erigon/cl/clparams" "github.com/ledgerwatch/erigon/cl/cltypes" "github.com/ledgerwatch/erigon/cl/fork" "github.com/ledgerwatch/erigon/cl/utils" + "github.com/ledgerwatch/erigon/core/types" eth2_shuffle "github.com/protolambda/eth2-shuffle" ) const PreAllocatedRewardsAndPenalties = 8192 +var ( + ErrGetBlockRootAtSlotFuture = errors.New("GetBlockRootAtSlot: slot in the future") +) + // GetActiveValidatorsIndices returns the list of validator indices active for the given epoch. func (b *BeaconState) GetActiveValidatorsIndices(epoch uint64) (indicies []uint64) { - if cachedIndicies, ok := b.activeValidatorsCache.Get(epoch); ok { - return cachedIndicies.([]uint64) + if cachedIndicies, ok := b.activeValidatorsCache.Get(epoch); ok && len(cachedIndicies) > 0 { + return cachedIndicies } for i, validator := range b.validators { if !validator.Active(epoch) { @@ -63,7 +70,7 @@ func (b *BeaconState) GetUnslashedParticipatingIndices(flagIndex int, epoch uint return nil, fmt.Errorf("getUnslashedParticipatingIndices: only epoch and previous epoch can be used") } // Iterate over all validators and include the active ones that have flag_index enabled and are not slashed. - for i, validator := range b.Validators() { + for i, validator := range b.validators { if !validator.Active(epoch) || !participation[i].HasFlag(flagIndex) || validator.Slashed { @@ -118,7 +125,7 @@ func (b *BeaconState) GetBlockRoot(epoch uint64) (libcommon.Hash, error) { // GetBlockRootAtSlot returns the block root at a given slot func (b *BeaconState) GetBlockRootAtSlot(slot uint64) (libcommon.Hash, error) { if slot >= b.slot { - return libcommon.Hash{}, fmt.Errorf("GetBlockRootAtSlot: slot in the future") + return libcommon.Hash{}, ErrGetBlockRootAtSlotFuture } if b.slot > slot+b.beaconConfig.SlotsPerHistoricalRoot { return libcommon.Hash{}, fmt.Errorf("GetBlockRootAtSlot: slot too much far behind") @@ -185,7 +192,7 @@ func (b *BeaconState) ComputeCommittee(indicies []uint64, seed libcommon.Hash, i end := (lenIndicies * (index + 1)) / count var shuffledIndicies []uint64 if shuffledIndicesInterface, ok := b.shuffledSetsCache.Get(seed); ok { - shuffledIndicies = shuffledIndicesInterface.([]uint64) + shuffledIndicies = shuffledIndicesInterface } else { shuffledIndicies = make([]uint64, lenIndicies) copy(shuffledIndicies, indicies) @@ -221,11 +228,11 @@ func (b *BeaconState) ComputeProposerIndex(indices []uint64, seed [32]byte) (uin input := append(seed[:], buf...) randomByte := uint64(utils.Keccak256(input)[i%32]) - validator, err := b.ValidatorAt(int(candidateIndex)) + validator, err := b.ValidatorForValidatorIndex(int(candidateIndex)) if err != nil { return 0, err } - if validator.EffectiveBalance*maxRandomByte >= clparams.MainnetBeaconConfig.MaxEffectiveBalance*randomByte { + if validator.EffectiveBalance*maxRandomByte >= b.beaconConfig.MaxEffectiveBalance*randomByte { return candidateIndex, nil } i += 1 @@ -267,7 +274,13 @@ func (b *BeaconState) BaseReward(index uint64) (uint64, error) { if index >= uint64(len(b.validators)) { return 0, ErrInvalidValidatorIndex } - return (b.validators[index].EffectiveBalance / b.beaconConfig.EffectiveBalanceIncrement) * b.BaseRewardPerIncrement(), nil + if b.totalActiveBalanceCache == nil { + b._refreshActiveBalances() + } + if b.version != clparams.Phase0Version { + return (b.validators[index].EffectiveBalance / b.beaconConfig.EffectiveBalanceIncrement) * b.BaseRewardPerIncrement(), nil + } + return b.validators[index].EffectiveBalance * b.beaconConfig.BaseRewardFactor / b.totalActiveBalanceRootCache / b.beaconConfig.BaseRewardsPerEpoch, nil } // SyncRewards returns the proposer reward and the sync participant reward given the total active balance in state. @@ -352,7 +365,7 @@ func (b *BeaconState) GetBeaconCommitee(slot, committeeIndex uint64) ([]uint64, binary.BigEndian.PutUint64(cacheKey[:], slot) binary.BigEndian.PutUint64(cacheKey[8:], committeeIndex) if cachedCommittee, ok := b.committeeCache.Get(cacheKey); ok { - return cachedCommittee.([]uint64), nil + return cachedCommittee, nil } epoch := b.GetEpochAtSlot(slot) committeesPerSlot := b.CommitteeCount(epoch) @@ -384,33 +397,16 @@ func (b *BeaconState) GetIndexedAttestation(attestation *cltypes.Attestation, at }, nil } -// getBitlistLength return the amount of bits in given bitlist. -func getBitlistLength(b []byte) int { - if len(b) == 0 { - return 0 - } - // The most significant bit is present in the last byte in the array. - last := b[len(b)-1] - - // Determine the position of the most significant bit. - msb := bits.Len8(last) - if msb == 0 { - return 0 - } - - // The absolute position of the most significant bit will be the number of - // bits in the preceding bytes plus the position of the most significant - // bit. Subtract this value by 1 to determine the length of the bitlist. - return 8*(len(b)-1) + msb - 1 -} - -func (b *BeaconState) GetAttestingIndicies(attestation *cltypes.AttestationData, aggregationBits []byte) ([]uint64, error) { +// GetAttestingIndicies retrieves attesting indicies for a specific attestation. however some tests will not expect the aggregation bits check. +// thus, it is a flag now. +func (b *BeaconState) GetAttestingIndicies(attestation *cltypes.AttestationData, aggregationBits []byte, checkBitsLength bool) ([]uint64, error) { committee, err := b.GetBeaconCommitee(attestation.Slot, attestation.Index) if err != nil { return nil, err } - if getBitlistLength(aggregationBits) != len(committee) { - return nil, fmt.Errorf("GetAttestingIndicies: invalid aggregation bits") + aggregationBitsLen := utils.GetBitlistLength(aggregationBits) + if checkBitsLength && utils.GetBitlistLength(aggregationBits) != len(committee) { + return nil, fmt.Errorf("GetAttestingIndicies: invalid aggregation bits. agg bits size: %d, expect: %d", aggregationBitsLen, len(committee)) } attestingIndices := []uint64{} for i, member := range committee { @@ -439,9 +435,14 @@ func (b *BeaconState) EligibleValidatorsIndicies() (eligibleValidators []uint64) return } +// FinalityDelay determines by how many epochs we are late on finality. +func (b *BeaconState) FinalityDelay() uint64 { + return b.PreviousEpoch() - b.finalizedCheckpoint.Epoch +} + // Implementation of is_in_inactivity_leak. tells us if network is in danger pretty much. defined in ETH 2.0 specs. func (b *BeaconState) InactivityLeaking() bool { - return (b.PreviousEpoch() - b.finalizedCheckpoint.Epoch) > b.beaconConfig.MinEpochsToInactivityPenalty + return b.FinalityDelay() > b.beaconConfig.MinEpochsToInactivityPenalty } func (b *BeaconState) IsUnslashedParticipatingIndex(epoch, index uint64, flagIdx int) bool { @@ -462,21 +463,166 @@ func (b *BeaconState) IsValidatorEligibleForActivation(validator *cltypes.Valida validator.ActivationEpoch == b.beaconConfig.FarFutureEpoch } -// Implementation of get_validator_churn_limit. Specs at: https://github.com/ethereum/consensus-specs/blob/dev/specs/phase0/beacon-chain.md#get_validator_churn_limit -func (b *BeaconState) ValidatorChurnLimit() (limit uint64) { +// Get the maximum number of validators that can be churned in a single epoch. +// See: https://github.com/ethereum/consensus-specs/blob/dev/specs/phase0/beacon-chain.md#get_validator_churn_limit +func (b *BeaconState) ValidatorChurnLimit() uint64 { activeValidatorsCount := uint64(len(b.GetActiveValidatorsIndices(b.Epoch()))) - limit = activeValidatorsCount / b.beaconConfig.ChurnLimitQuotient - if limit < b.beaconConfig.MinPerEpochChurnLimit { - limit = b.beaconConfig.MinPerEpochChurnLimit - } - return - + churnLimit := activeValidatorsCount / b.beaconConfig.ChurnLimitQuotient + return utils.Max64(b.beaconConfig.MinPerEpochChurnLimit, churnLimit) } +// Check whether a merge transition is complete by verifying the presence of a valid execution payload header. func (b *BeaconState) IsMergeTransitionComplete() bool { - return b.latestExecutionPayloadHeader.Root != libcommon.Hash{} + return !b.latestExecutionPayloadHeader.IsZero() } +// Compute the Unix timestamp at the specified slot number. func (b *BeaconState) ComputeTimestampAtSlot(slot uint64) uint64 { return b.genesisTime + (slot-b.beaconConfig.GenesisSlot)*b.beaconConfig.SecondsPerSlot } + +// Check whether a validator is fully withdrawable at the given epoch. +func (b *BeaconState) isFullyWithdrawableValidator(validator *cltypes.Validator, balance uint64, epoch uint64) bool { + return validator.WithdrawalCredentials[0] == b.beaconConfig.ETH1AddressWithdrawalPrefixByte && + validator.WithdrawableEpoch <= epoch && balance > 0 +} + +// Check whether a validator is partially withdrawable. +func (b *BeaconState) isPartiallyWithdrawableValidator(validator *cltypes.Validator, balance uint64) bool { + return validator.WithdrawalCredentials[0] == b.beaconConfig.ETH1AddressWithdrawalPrefixByte && + validator.EffectiveBalance == b.beaconConfig.MaxEffectiveBalance && balance > b.beaconConfig.MaxEffectiveBalance +} + +// ExpectedWithdrawals calculates the expected withdrawals that can be made by validators in the current epoch +func (b *BeaconState) ExpectedWithdrawals() []*types.Withdrawal { + // Get the current epoch, the next withdrawal index, and the next withdrawal validator index + currentEpoch := b.Epoch() + nextWithdrawalIndex := b.nextWithdrawalIndex + nextWithdrawalValidatorIndex := b.nextWithdrawalValidatorIndex + + // Determine the upper bound for the loop and initialize the withdrawals slice with a capacity of bound + maxValidators := uint64(len(b.validators)) + maxValidatorsPerWithdrawalsSweep := b.beaconConfig.MaxValidatorsPerWithdrawalsSweep + bound := utils.Min64(maxValidators, maxValidatorsPerWithdrawalsSweep) + withdrawals := make([]*types.Withdrawal, 0, bound) + + // Loop through the validators to calculate expected withdrawals + for validatorCount := uint64(0); validatorCount < bound && len(withdrawals) != int(b.beaconConfig.MaxWithdrawalsPerPayload); validatorCount++ { + // Get the validator and balance for the current validator index + currentValidator := b.validators[nextWithdrawalValidatorIndex] + currentBalance := b.balances[nextWithdrawalValidatorIndex] + + // Check if the validator is fully withdrawable + if b.isFullyWithdrawableValidator(currentValidator, currentBalance, currentEpoch) { + // Add a new withdrawal with the validator's withdrawal credentials and balance + newWithdrawal := &types.Withdrawal{ + Index: nextWithdrawalIndex, + Validator: nextWithdrawalValidatorIndex, + Address: libcommon.BytesToAddress(currentValidator.WithdrawalCredentials[12:]), + Amount: currentBalance, + } + withdrawals = append(withdrawals, newWithdrawal) + nextWithdrawalIndex++ + } else if b.isPartiallyWithdrawableValidator(currentValidator, currentBalance) { // Check if the validator is partially withdrawable + // Add a new withdrawal with the validator's withdrawal credentials and balance minus the maximum effective balance + newWithdrawal := &types.Withdrawal{ + Index: nextWithdrawalIndex, + Validator: nextWithdrawalValidatorIndex, + Address: libcommon.BytesToAddress(currentValidator.WithdrawalCredentials[12:]), + Amount: currentBalance - b.beaconConfig.MaxEffectiveBalance, + } + withdrawals = append(withdrawals, newWithdrawal) + nextWithdrawalIndex++ + } + + // Increment the validator index, looping back to 0 if necessary + nextWithdrawalValidatorIndex = (nextWithdrawalValidatorIndex + 1) % maxValidators + } + + // Return the withdrawals slice + return withdrawals +} +func (b *BeaconState) ComputeNextSyncCommittee() (*cltypes.SyncCommittee, error) { + beaconConfig := b.beaconConfig + optimizedHashFunc := utils.OptimizedKeccak256() + epoch := b.Epoch() + 1 + //math.MaxUint8 + activeValidatorIndicies := b.GetActiveValidatorsIndices(epoch) + activeValidatorCount := uint64(len(activeValidatorIndicies)) + seed := b.GetSeed(epoch, beaconConfig.DomainSyncCommittee) + i := uint64(0) + syncCommitteePubKeys := make([][48]byte, 0, cltypes.SyncCommitteeSize) + preInputs := b.ComputeShuffledIndexPreInputs(seed) + for len(syncCommitteePubKeys) < cltypes.SyncCommitteeSize { + shuffledIndex, err := b.ComputeShuffledIndex(i%activeValidatorCount, activeValidatorCount, seed, preInputs, optimizedHashFunc) + if err != nil { + return nil, err + } + candidateIndex := activeValidatorIndicies[shuffledIndex] + // Compute random byte. + buf := make([]byte, 8) + binary.LittleEndian.PutUint64(buf, i/32) + input := append(seed[:], buf...) + randomByte := uint64(utils.Keccak256(input)[i%32]) + // retrieve validator. + validator, err := b.ValidatorForValidatorIndex(int(candidateIndex)) + if err != nil { + return nil, err + } + if validator.EffectiveBalance*math.MaxUint8 >= beaconConfig.MaxEffectiveBalance*randomByte { + syncCommitteePubKeys = append(syncCommitteePubKeys, validator.PublicKey) + } + i++ + } + // Format public keys. + formattedKeys := make([][]byte, cltypes.SyncCommitteeSize) + for i := range formattedKeys { + formattedKeys[i] = make([]byte, 48) + copy(formattedKeys[i], syncCommitteePubKeys[i][:]) + } + aggregatePublicKeyBytes, err := bls.AggregatePublickKeys(formattedKeys) + if err != nil { + return nil, err + } + var aggregate [48]byte + copy(aggregate[:], aggregatePublicKeyBytes) + return &cltypes.SyncCommittee{ + PubKeys: syncCommitteePubKeys, + AggregatePublicKey: aggregate, + }, nil +} + +func (b *BeaconState) IsValidIndexedAttestation(att *cltypes.IndexedAttestation) (bool, error) { + inds := att.AttestingIndices + if len(inds) == 0 || !utils.IsSliceSortedSet(inds) { + return false, fmt.Errorf("isValidIndexedAttestation: attesting indices are not sorted or are null") + } + + pks := [][]byte{} + for _, v := range inds { + val, err := b.ValidatorForValidatorIndex(int(v)) + if err != nil { + return false, err + } + pks = append(pks, val.PublicKey[:]) + } + + domain, err := b.GetDomain(b.beaconConfig.DomainBeaconAttester, att.Data.Target.Epoch) + if err != nil { + return false, fmt.Errorf("unable to get the domain: %v", err) + } + + signingRoot, err := fork.ComputeSigningRoot(att.Data, domain) + if err != nil { + return false, fmt.Errorf("unable to get signing root: %v", err) + } + + valid, err := bls.VerifyAggregate(att.Signature[:], signingRoot[:], pks) + if err != nil { + return false, fmt.Errorf("error while validating signature: %v", err) + } + if !valid { + return false, fmt.Errorf("invalid aggregate signature") + } + return true, nil +} diff --git a/cmd/erigon-cl/core/state/mutators.go b/cmd/erigon-cl/core/state/mutators.go index bf0a933cc37..184bba5a2a8 100644 --- a/cmd/erigon-cl/core/state/mutators.go +++ b/cmd/erigon-cl/core/state/mutators.go @@ -60,12 +60,13 @@ func (b *BeaconState) InitiateValidatorExit(index uint64) error { exitQueueEpoch += 1 } - b.validators[index].ExitEpoch = exitQueueEpoch var overflow bool - if b.validators[index].WithdrawableEpoch, overflow = math.SafeAdd(b.validators[index].ExitEpoch, b.beaconConfig.MinValidatorWithdrawabilityDelay); overflow { + var newWithdrawableEpoch uint64 + if newWithdrawableEpoch, overflow = math.SafeAdd(exitQueueEpoch, b.beaconConfig.MinValidatorWithdrawabilityDelay); overflow { return fmt.Errorf("withdrawable epoch is too big") } - b.touchedLeaves[ValidatorsLeafIndex] = true + b.SetExitEpochForValidatorAtIndex(int(index), exitQueueEpoch) + b.SetWithdrawableEpochForValidatorAtIndex(int(index), newWithdrawableEpoch) return nil } @@ -81,12 +82,15 @@ func (b *BeaconState) SlashValidator(slashedInd uint64, whistleblowerInd *uint64 if err := b.InitiateValidatorExit(slashedInd); err != nil { return err } + // Record changes in changeset + slashingsIndex := int(epoch % b.beaconConfig.EpochsPerSlashingsVector) + // Change the validator to be slashed b.validators[slashedInd].Slashed = true b.validators[slashedInd].WithdrawableEpoch = utils.Max64(b.validators[slashedInd].WithdrawableEpoch, epoch+b.beaconConfig.EpochsPerSlashingsVector) b.touchedLeaves[ValidatorsLeafIndex] = true // Update slashings vector - b.slashings[epoch%b.beaconConfig.EpochsPerSlashingsVector] += b.validators[slashedInd].EffectiveBalance + b.slashings[slashingsIndex] += b.validators[slashedInd].EffectiveBalance b.touchedLeaves[SlashingsLeafIndex] = true if err := b.DecreaseBalance(slashedInd, b.validators[slashedInd].EffectiveBalance/b.beaconConfig.GetMinSlashingPenaltyQuotient(b.version)); err != nil { return err diff --git a/cmd/erigon-cl/core/state/root.go b/cmd/erigon-cl/core/state/root.go index 2f979cb4818..929d35f985d 100644 --- a/cmd/erigon-cl/core/state/root.go +++ b/cmd/erigon-cl/core/state/root.go @@ -14,6 +14,10 @@ func (b *BeaconState) HashSSZ() ([32]byte, error) { if err = b.computeDirtyLeaves(); err != nil { return [32]byte{}, err } + /*fmt.Println(b.slot) + for i, val := range b.leaves { + fmt.Println(i, libcommon.Hash(val)) + }*/ // Pad to 32 of length return merkle_tree.MerkleRootFromLeaves(b.leaves[:]) diff --git a/cmd/erigon-cl/core/state/setters.go b/cmd/erigon-cl/core/state/setters.go index 532c1bbfeb1..25d16d5e164 100644 --- a/cmd/erigon-cl/core/state/setters.go +++ b/cmd/erigon-cl/core/state/setters.go @@ -4,27 +4,19 @@ import ( libcommon "github.com/ledgerwatch/erigon-lib/common" "github.com/ledgerwatch/erigon/cl/cltypes" - "github.com/ledgerwatch/erigon/core/types" ) const maxEth1Votes = 2048 // Below are setters. Note that they also dirty the state. -func (b *BeaconState) SetGenesisTime(genesisTime uint64) { - b.touchedLeaves[GenesisTimeLeafIndex] = true - b.genesisTime = genesisTime -} - -func (b *BeaconState) SetGenesisValidatorsRoot(genesisValidatorRoot libcommon.Hash) { - b.touchedLeaves[GenesisValidatorsRootLeafIndex] = true - b.genesisValidatorsRoot = genesisValidatorRoot -} - func (b *BeaconState) SetSlot(slot uint64) { b.touchedLeaves[SlotLeafIndex] = true b.slot = slot b.proposerIndex = nil + if b.slot%b.beaconConfig.SlotsPerEpoch == 0 { + b.totalActiveBalanceCache = nil + } } func (b *BeaconState) SetFork(fork *cltypes.Fork) { @@ -37,11 +29,6 @@ func (b *BeaconState) SetLatestBlockHeader(header *cltypes.BeaconBlockHeader) { b.latestBlockHeader = header } -func (b *BeaconState) SetHistoricalRoots(historicalRoots []libcommon.Hash) { - b.touchedLeaves[HistoricalRootsLeafIndex] = true - b.historicalRoots = historicalRoots -} - func (b *BeaconState) SetBlockRootAt(index int, root libcommon.Hash) { b.touchedLeaves[BlockRootsLeafIndex] = true b.blockRoots[index] = root @@ -57,15 +44,34 @@ func (b *BeaconState) SetHistoricalRootAt(index int, root [32]byte) { b.historicalRoots[index] = root } -func (b *BeaconState) SetValidatorAt(index int, validator *cltypes.Validator) error { - if index >= len(b.validators) { - return ErrInvalidValidatorIndex - } - b.validators[index] = validator +func (b *BeaconState) SetWithdrawalCredentialForValidatorAtIndex(index int, creds libcommon.Hash) { b.touchedLeaves[ValidatorsLeafIndex] = true - // change in validator set means cache purging - b.totalActiveBalanceCache = nil - return nil + b.validators[index].WithdrawalCredentials = creds +} + +func (b *BeaconState) SetExitEpochForValidatorAtIndex(index int, epoch uint64) { + b.touchedLeaves[ValidatorsLeafIndex] = true + b.validators[index].ExitEpoch = epoch +} + +func (b *BeaconState) SetWithdrawableEpochForValidatorAtIndex(index int, epoch uint64) { + b.touchedLeaves[ValidatorsLeafIndex] = true + b.validators[index].WithdrawableEpoch = epoch +} + +func (b *BeaconState) SetEffectiveBalanceForValidatorAtIndex(index int, balance uint64) { + b.touchedLeaves[ValidatorsLeafIndex] = true + b.validators[index].EffectiveBalance = balance +} + +func (b *BeaconState) SetActivationEpochForValidatorAtIndex(index int, epoch uint64) { + b.touchedLeaves[ValidatorsLeafIndex] = true + b.validators[index].ActivationEpoch = epoch +} + +func (b *BeaconState) SetActivationEligibilityEpochForValidatorAtIndex(index int, epoch uint64) { + b.touchedLeaves[ValidatorsLeafIndex] = true + b.validators[index].ActivationEligibilityEpoch = epoch } func (b *BeaconState) SetEth1Data(eth1Data *cltypes.Eth1Data) { @@ -80,7 +86,7 @@ func (b *BeaconState) AddEth1DataVote(vote *cltypes.Eth1Data) { func (b *BeaconState) ResetEth1DataVotes() { b.touchedLeaves[Eth1DataVotesLeafIndex] = true - b.eth1DataVotes = b.eth1DataVotes[:0] + b.eth1DataVotes = nil } func (b *BeaconState) SetEth1DepositIndex(eth1DepositIndex uint64) { @@ -131,14 +137,26 @@ func (b *BeaconState) SetSlashingSegmentAt(index int, segment uint64) { b.slashings[index] = segment } -func (b *BeaconState) SetPreviousEpochParticipation(previousEpochParticipation []cltypes.ParticipationFlags) { +func (b *BeaconState) SetEpochParticipationForValidatorIndex(isCurrentEpoch bool, index int, flags cltypes.ParticipationFlags) { + if isCurrentEpoch { + b.touchedLeaves[CurrentEpochParticipationLeafIndex] = true + b.currentEpochParticipation[index] = flags + return + } b.touchedLeaves[PreviousEpochParticipationLeafIndex] = true - b.previousEpochParticipation = previousEpochParticipation + b.previousEpochParticipation[index] = flags } -func (b *BeaconState) SetCurrentEpochParticipation(currentEpochParticipation []cltypes.ParticipationFlags) { +func (b *BeaconState) SetValidatorAtIndex(index int, validator *cltypes.Validator) { + b.touchedLeaves[ValidatorsLeafIndex] = true + b.validators[index] = validator +} + +func (b *BeaconState) ResetEpochParticipation() { + b.touchedLeaves[PreviousEpochParticipationLeafIndex] = true b.touchedLeaves[CurrentEpochParticipationLeafIndex] = true - b.currentEpochParticipation = currentEpochParticipation + b.previousEpochParticipation = b.currentEpochParticipation + b.currentEpochParticipation = make(cltypes.ParticipationFlagsList, len(b.validators)) } func (b *BeaconState) SetJustificationBits(justificationBits cltypes.JustificationBits) { @@ -171,7 +189,7 @@ func (b *BeaconState) SetNextSyncCommittee(nextSyncCommittee *cltypes.SyncCommit b.nextSyncCommittee = nextSyncCommittee } -func (b *BeaconState) SetLatestExecutionPayloadHeader(header *types.Header) { +func (b *BeaconState) SetLatestExecutionPayloadHeader(header *cltypes.Eth1Header) { b.touchedLeaves[LatestExecutionPayloadHeaderLeafIndex] = true b.latestExecutionPayloadHeader = header } @@ -187,7 +205,7 @@ func (b *BeaconState) SetNextWithdrawalValidatorIndex(index uint64) { } func (b *BeaconState) AddHistoricalSummary(summary *cltypes.HistoricalSummary) { - b.touchedLeaves[HistoricalRootsLeafIndex] = true + b.touchedLeaves[HistoricalSummariesLeafIndex] = true b.historicalSummaries = append(b.historicalSummaries, summary) } @@ -219,3 +237,23 @@ func (b *BeaconState) AddPreviousEpochParticipationFlags(flags cltypes.Participa b.touchedLeaves[PreviousEpochParticipationLeafIndex] = true b.previousEpochParticipation = append(b.previousEpochParticipation, flags) } + +func (b *BeaconState) AddCurrentEpochAtteastation(attestation *cltypes.PendingAttestation) { + b.touchedLeaves[CurrentEpochParticipationLeafIndex] = true + b.currentEpochAttestations = append(b.currentEpochAttestations, attestation) +} + +func (b *BeaconState) AddPreviousEpochAttestation(attestation *cltypes.PendingAttestation) { + b.touchedLeaves[PreviousEpochParticipationLeafIndex] = true + b.previousEpochAttestations = append(b.previousEpochAttestations, attestation) +} + +func (b *BeaconState) ResetCurrentEpochAttestations() { + b.touchedLeaves[CurrentEpochParticipationLeafIndex] = true + b.currentEpochAttestations = nil +} + +func (b *BeaconState) SetPreviousEpochAttestations(attestations []*cltypes.PendingAttestation) { + b.touchedLeaves[PreviousEpochParticipationLeafIndex] = true + b.previousEpochAttestations = attestations +} diff --git a/cmd/erigon-cl/core/state/state.go b/cmd/erigon-cl/core/state/state.go index d8930609edc..74c8f44abc2 100644 --- a/cmd/erigon-cl/core/state/state.go +++ b/cmd/erigon-cl/core/state/state.go @@ -4,13 +4,13 @@ import ( "crypto/sha256" "encoding/binary" - lru "github.com/hashicorp/golang-lru" + lru "github.com/hashicorp/golang-lru/v2" + "github.com/ledgerwatch/erigon-lib/common" libcommon "github.com/ledgerwatch/erigon-lib/common" "github.com/ledgerwatch/erigon/cl/clparams" "github.com/ledgerwatch/erigon/cl/cltypes" "github.com/ledgerwatch/erigon/cl/utils" - "github.com/ledgerwatch/erigon/core/types" ) type HashFunc func([]byte) ([32]byte, error) @@ -25,19 +25,19 @@ const ( type BeaconState struct { // State fields genesisTime uint64 - genesisValidatorsRoot libcommon.Hash + genesisValidatorsRoot common.Hash slot uint64 fork *cltypes.Fork latestBlockHeader *cltypes.BeaconBlockHeader - blockRoots [blockRootsLength]libcommon.Hash - stateRoots [stateRootsLength]libcommon.Hash - historicalRoots []libcommon.Hash + blockRoots [blockRootsLength]common.Hash + stateRoots [stateRootsLength]common.Hash + historicalRoots []common.Hash eth1Data *cltypes.Eth1Data eth1DataVotes []*cltypes.Eth1Data eth1DepositIndex uint64 validators []*cltypes.Validator balances []uint64 - randaoMixes [randoMixesLength]libcommon.Hash + randaoMixes [randoMixesLength]common.Hash slashings [slashingsLength]uint64 previousEpochParticipation cltypes.ParticipationFlagsList currentEpochParticipation cltypes.ParticipationFlagsList @@ -50,24 +50,27 @@ type BeaconState struct { currentSyncCommittee *cltypes.SyncCommittee nextSyncCommittee *cltypes.SyncCommittee // Bellatrix - latestExecutionPayloadHeader *types.Header + latestExecutionPayloadHeader *cltypes.Eth1Header // Capella nextWithdrawalIndex uint64 nextWithdrawalValidatorIndex uint64 historicalSummaries []*cltypes.HistoricalSummary + // Phase0: genesis fork. these 2 fields replace participation bits. + previousEpochAttestations []*cltypes.PendingAttestation + currentEpochAttestations []*cltypes.PendingAttestation // Internals version clparams.StateVersion // State version leaves [32][32]byte // Pre-computed leaves. touchedLeaves map[StateLeafIndex]bool // Maps each leaf to whether they were touched or not. publicKeyIndicies map[[48]byte]uint64 // Caches - activeValidatorsCache *lru.Cache - committeeCache *lru.Cache - shuffledSetsCache *lru.Cache + activeValidatorsCache *lru.Cache[uint64, []uint64] + committeeCache *lru.Cache[[16]byte, []uint64] + shuffledSetsCache *lru.Cache[common.Hash, []uint64] totalActiveBalanceCache *uint64 totalActiveBalanceRootCache uint64 proposerIndex *uint64 - previousStateRoot libcommon.Hash + previousStateRoot common.Hash // Configs beaconConfig *clparams.BeaconChainConfig } @@ -80,7 +83,7 @@ func New(cfg *clparams.BeaconChainConfig) *BeaconState { return state } -func preparateRootsForHashing(roots []libcommon.Hash) [][32]byte { +func preparateRootsForHashing(roots []common.Hash) [][32]byte { ret := make([][32]byte, len(roots)) for i := range roots { copy(ret[i][:], roots[i][:]) @@ -126,7 +129,7 @@ func (b *BeaconState) _updateProposerIndex() (err error) { hash := sha256.New() // Input for the seed hash. - input := b.GetSeed(epoch, clparams.MainnetBeaconConfig.DomainBeaconProposer) + input := b.GetSeed(epoch, b.BeaconConfig().DomainBeaconProposer) slotByteArray := make([]byte, 8) binary.LittleEndian.PutUint64(slotByteArray, b.slot) @@ -147,27 +150,205 @@ func (b *BeaconState) _updateProposerIndex() (err error) { return } +// _initializeValidatorsPhase0 initializes the validators matching flags based on previous/current attestations +func (b *BeaconState) _initializeValidatorsPhase0() error { + // Previous Pending attestations + if b.slot == 0 { + return nil + } + previousEpochRoot, err := b.GetBlockRoot(b.PreviousEpoch()) + if err != nil { + return err + } + for _, attestation := range b.previousEpochAttestations { + slotRoot, err := b.GetBlockRootAtSlot(attestation.Data.Slot) + if err != nil { + return err + } + indicies, err := b.GetAttestingIndicies(attestation.Data, attestation.AggregationBits, false) + if err != nil { + return err + } + for _, index := range indicies { + if b.validators[index].MinPreviousInclusionDelayAttestation == nil || b.validators[index].MinPreviousInclusionDelayAttestation.InclusionDelay > attestation.InclusionDelay { + b.validators[index].MinPreviousInclusionDelayAttestation = attestation + } + b.validators[index].IsPreviousMatchingSourceAttester = true + if attestation.Data.Target.Root != previousEpochRoot { + continue + } + b.validators[index].IsPreviousMatchingTargetAttester = true + + if attestation.Data.BeaconBlockHash == slotRoot { + b.validators[index].IsPreviousMatchingHeadAttester = true + } + } + } + + // Current Pending attestations + if len(b.currentEpochAttestations) == 0 { + return nil + } + currentEpochRoot, err := b.GetBlockRoot(b.Epoch()) + if err != nil { + return err + } + for _, attestation := range b.currentEpochAttestations { + slotRoot, err := b.GetBlockRootAtSlot(attestation.Data.Slot) + if err != nil { + return err + } + if err != nil { + return err + } + indicies, err := b.GetAttestingIndicies(attestation.Data, attestation.AggregationBits, false) + if err != nil { + return err + } + for _, index := range indicies { + if b.validators[index].MinCurrentInclusionDelayAttestation == nil || b.validators[index].MinCurrentInclusionDelayAttestation.InclusionDelay > attestation.InclusionDelay { + b.validators[index].MinCurrentInclusionDelayAttestation = attestation + } + b.validators[index].IsCurrentMatchingSourceAttester = true + if attestation.Data.Target.Root == currentEpochRoot { + b.validators[index].IsCurrentMatchingTargetAttester = true + } + if attestation.Data.BeaconBlockHash == slotRoot { + b.validators[index].IsCurrentMatchingHeadAttester = true + } + } + } + return nil +} + +func (b *BeaconState) initCaches() error { + var err error + if b.activeValidatorsCache, err = lru.New[uint64, []uint64](5); err != nil { + return err + } + if b.shuffledSetsCache, err = lru.New[common.Hash, []uint64](5); err != nil { + return err + } + if b.committeeCache, err = lru.New[[16]byte, []uint64](256); err != nil { + return err + } + return nil +} + func (b *BeaconState) initBeaconState() error { + if b.touchedLeaves == nil { b.touchedLeaves = make(map[StateLeafIndex]bool) } + b.publicKeyIndicies = make(map[[48]byte]uint64) b._refreshActiveBalances() for i, validator := range b.validators { b.publicKeyIndicies[validator.PublicKey] = uint64(i) } - var err error - if b.activeValidatorsCache, err = lru.New(5); err != nil { + b.initCaches() + if err := b._updateProposerIndex(); err != nil { return err } - if b.shuffledSetsCache, err = lru.New(25); err != nil { - return err + if b.version >= clparams.Phase0Version { + return b._initializeValidatorsPhase0() } - if b.committeeCache, err = lru.New(256); err != nil { - return err + return nil +} + +func (b *BeaconState) Copy() (*BeaconState, error) { + copied := New(b.beaconConfig) + // Fill all the fields with copies + copied.genesisTime = b.genesisTime + copied.genesisValidatorsRoot = b.genesisValidatorsRoot + copied.slot = b.slot + copied.fork = b.fork.Copy() + copied.latestBlockHeader = b.latestBlockHeader.Copy() + copy(copied.blockRoots[:], b.blockRoots[:]) + copy(copied.stateRoots[:], b.stateRoots[:]) + copied.historicalRoots = make([]libcommon.Hash, len(b.historicalRoots)) + copy(copied.historicalRoots, b.historicalRoots) + copied.eth1Data = b.eth1Data.Copy() + copied.eth1DataVotes = make([]*cltypes.Eth1Data, len(b.eth1DataVotes)) + for i := range b.eth1DataVotes { + copied.eth1DataVotes[i] = b.eth1DataVotes[i].Copy() } - if err := b._updateProposerIndex(); err != nil { - return err + copied.eth1DepositIndex = b.eth1DepositIndex + copied.validators = make([]*cltypes.Validator, len(b.validators)) + for i := range b.validators { + copied.validators[i] = b.validators[i].Copy() } - return nil + copied.balances = make([]uint64, len(b.balances)) + copy(copied.balances, b.balances) + copy(copied.randaoMixes[:], b.randaoMixes[:]) + copy(copied.slashings[:], b.slashings[:]) + copied.previousEpochParticipation = b.previousEpochParticipation.Copy() + copied.currentEpochParticipation = b.currentEpochParticipation.Copy() + copied.finalizedCheckpoint = b.finalizedCheckpoint.Copy() + copied.currentJustifiedCheckpoint = b.currentJustifiedCheckpoint.Copy() + copied.previousJustifiedCheckpoint = b.previousJustifiedCheckpoint.Copy() + if b.version == clparams.Phase0Version { + return copied, copied.initBeaconState() + } + copied.currentSyncCommittee = b.currentSyncCommittee.Copy() + copied.nextSyncCommittee = b.nextSyncCommittee.Copy() + copied.inactivityScores = make([]uint64, len(b.inactivityScores)) + copy(copied.inactivityScores, b.inactivityScores) + copied.justificationBits = b.justificationBits.Copy() + + if b.version >= clparams.BellatrixVersion { + copied.latestExecutionPayloadHeader = b.latestExecutionPayloadHeader.Copy() + } + copied.nextWithdrawalIndex = b.nextWithdrawalIndex + copied.nextWithdrawalValidatorIndex = b.nextWithdrawalValidatorIndex + copied.historicalSummaries = make([]*cltypes.HistoricalSummary, len(b.historicalSummaries)) + for i := range b.historicalSummaries { + copied.historicalSummaries[i] = &cltypes.HistoricalSummary{ + BlockSummaryRoot: b.historicalSummaries[i].BlockSummaryRoot, + StateSummaryRoot: b.historicalSummaries[i].StateSummaryRoot, + } + } + copied.version = b.version + // Now sync internals + copy(copied.leaves[:], b.leaves[:]) + copied.touchedLeaves = make(map[StateLeafIndex]bool) + for leafIndex, touchedVal := range b.touchedLeaves { + copied.touchedLeaves[leafIndex] = touchedVal + } + copied.publicKeyIndicies = make(map[[48]byte]uint64) + for pk, index := range b.publicKeyIndicies { + copied.publicKeyIndicies[pk] = index + } + // Sync caches + if err := copied.initCaches(); err != nil { + return nil, err + } + for _, epoch := range b.activeValidatorsCache.Keys() { + val, has := b.activeValidatorsCache.Get(epoch) + if !has { + continue + } + copied.activeValidatorsCache.Add(epoch, val) + } + for _, key := range b.shuffledSetsCache.Keys() { + val, has := b.shuffledSetsCache.Get(key) + if !has { + continue + } + copied.shuffledSetsCache.Add(key, val) + } + for _, key := range b.committeeCache.Keys() { + val, has := b.committeeCache.Get(key) + if !has { + continue + } + copied.committeeCache.Add(key, val) + } + if b.totalActiveBalanceCache != nil { + copied.totalActiveBalanceCache = new(uint64) + *copied.totalActiveBalanceCache = *b.totalActiveBalanceCache + copied.totalActiveBalanceRootCache = b.totalActiveBalanceRootCache + } + + return copied, nil } diff --git a/cmd/erigon-cl/core/state/upgrade.go b/cmd/erigon-cl/core/state/upgrade.go new file mode 100644 index 00000000000..2ad0a126ae6 --- /dev/null +++ b/cmd/erigon-cl/core/state/upgrade.go @@ -0,0 +1,95 @@ +package state + +import ( + libcommon "github.com/ledgerwatch/erigon-lib/common" + "github.com/ledgerwatch/erigon/cl/clparams" + "github.com/ledgerwatch/erigon/cl/cltypes" + "github.com/ledgerwatch/erigon/cl/utils" +) + +func (b *BeaconState) UpgradeToAltair() error { + b.previousStateRoot = libcommon.Hash{} + epoch := b.Epoch() + // update version + b.fork.Epoch = epoch + b.fork.CurrentVersion = utils.Uint32ToBytes4(b.beaconConfig.AltairForkVersion) + // Process new fields + b.previousEpochParticipation = make(cltypes.ParticipationFlagsList, len(b.validators)) + b.currentEpochParticipation = make(cltypes.ParticipationFlagsList, len(b.validators)) + b.inactivityScores = make([]uint64, len(b.validators)) + // Change version + b.version = clparams.AltairVersion + // Fill in previous epoch participation from the pre state's pending attestations + for _, attestation := range b.previousEpochAttestations { + flags, err := b.GetAttestationParticipationFlagIndicies(attestation.Data, attestation.InclusionDelay) + if err != nil { + return err + } + indicies, err := b.GetAttestingIndicies(attestation.Data, attestation.AggregationBits, false) + if err != nil { + return err + } + + for _, index := range indicies { + for _, flagIndex := range flags { + b.previousEpochParticipation[index] = b.previousEpochParticipation[index].Add(int(flagIndex)) + } + } + } + b.previousEpochAttestations = nil + // Process sync committees + var err error + if b.currentSyncCommittee, err = b.ComputeNextSyncCommittee(); err != nil { + return err + } + if b.nextSyncCommittee, err = b.ComputeNextSyncCommittee(); err != nil { + return err + } + // Update the state root cache + b.touchedLeaves[ForkLeafIndex] = true + b.touchedLeaves[PreviousEpochParticipationLeafIndex] = true + b.touchedLeaves[CurrentEpochParticipationLeafIndex] = true + b.touchedLeaves[InactivityScoresLeafIndex] = true + b.touchedLeaves[CurrentSyncCommitteeLeafIndex] = true + b.touchedLeaves[NextSyncCommitteeLeafIndex] = true + + return nil +} + +func (b *BeaconState) UpgradeToBellatrix() error { + b.previousStateRoot = libcommon.Hash{} + epoch := b.Epoch() + // update version + b.fork.Epoch = epoch + b.fork.PreviousVersion = b.fork.CurrentVersion + b.fork.CurrentVersion = utils.Uint32ToBytes4(b.beaconConfig.BellatrixForkVersion) + b.latestExecutionPayloadHeader = cltypes.NewEth1Header(clparams.BellatrixVersion) + // Update the state root cache + b.touchedLeaves[ForkLeafIndex] = true + b.touchedLeaves[LatestExecutionPayloadHeaderLeafIndex] = true + b.version = clparams.BellatrixVersion + return nil +} + +func (b *BeaconState) UpgradeToCapella() error { + b.previousStateRoot = libcommon.Hash{} + epoch := b.Epoch() + // update version + b.fork.Epoch = epoch + b.fork.PreviousVersion = b.fork.CurrentVersion + b.fork.CurrentVersion = utils.Uint32ToBytes4(b.beaconConfig.CapellaForkVersion) + // Update the payload header. + b.latestExecutionPayloadHeader.Capella() + // Set new fields + b.nextWithdrawalIndex = 0 + b.nextWithdrawalValidatorIndex = 0 + b.historicalSummaries = nil + // Update the state root cache + b.touchedLeaves[ForkLeafIndex] = true + b.touchedLeaves[LatestExecutionPayloadHeaderLeafIndex] = true + b.touchedLeaves[NextWithdrawalIndexLeafIndex] = true + b.touchedLeaves[NextWithdrawalValidatorIndexLeafIndex] = true + b.touchedLeaves[HistoricalSummariesLeafIndex] = true + b.version = clparams.CapellaVersion + return nil +} diff --git a/cmd/erigon-cl/core/transition/operations.go b/cmd/erigon-cl/core/transition/operations.go index 54e5cd3db03..0b8de4e0e0b 100644 --- a/cmd/erigon-cl/core/transition/operations.go +++ b/cmd/erigon-cl/core/transition/operations.go @@ -5,53 +5,16 @@ import ( "fmt" "github.com/Giulio2002/bls" + "github.com/ledgerwatch/log/v3" + "github.com/ledgerwatch/erigon/cl/clparams" "github.com/ledgerwatch/erigon/cl/cltypes" "github.com/ledgerwatch/erigon/cl/fork" "github.com/ledgerwatch/erigon/cl/utils" "github.com/ledgerwatch/erigon/cmd/erigon-cl/core/state" + "github.com/ledgerwatch/erigon/core/types" ) -func isSlashableAttestationData(d1, d2 *cltypes.AttestationData) bool { - return (!d1.Equal(d2) && d1.Target.Epoch == d2.Target.Epoch) || - (d1.Source.Epoch < d2.Source.Epoch && d2.Target.Epoch < d1.Target.Epoch) -} - -func isValidIndexedAttestation(state *state.BeaconState, att *cltypes.IndexedAttestation) (bool, error) { - inds := att.AttestingIndices - if len(inds) == 0 || !utils.IsSliceSortedSet(inds) { - return false, fmt.Errorf("isValidIndexedAttestation: attesting indices are not sorted or are null") - } - - pks := [][]byte{} - for _, v := range inds { - val, err := state.ValidatorAt(int(v)) - if err != nil { - return false, err - } - pks = append(pks, val.PublicKey[:]) - } - - domain, err := state.GetDomain(state.BeaconConfig().DomainBeaconAttester, att.Data.Target.Epoch) - if err != nil { - return false, fmt.Errorf("unable to get the domain: %v", err) - } - - signingRoot, err := fork.ComputeSigningRoot(att.Data, domain) - if err != nil { - return false, fmt.Errorf("unable to get signing root: %v", err) - } - - valid, err := bls.VerifyAggregate(att.Signature[:], signingRoot[:], pks) - if err != nil { - return false, fmt.Errorf("error while validating signature: %v", err) - } - if !valid { - return false, fmt.Errorf("invalid aggregate signature") - } - return true, nil -} - func ProcessProposerSlashing(state *state.BeaconState, propSlashing *cltypes.ProposerSlashing) error { h1 := propSlashing.Header1.Header h2 := propSlashing.Header2.Header @@ -76,7 +39,7 @@ func ProcessProposerSlashing(state *state.BeaconState, propSlashing *cltypes.Pro return fmt.Errorf("propose slashing headers are the same: %v == %v", h1Root, h2Root) } - proposer, err := state.ValidatorAt(int(h1.ProposerIndex)) + proposer, err := state.ValidatorForValidatorIndex(int(h1.ProposerIndex)) if err != nil { return err } @@ -111,11 +74,11 @@ func ProcessAttesterSlashing(state *state.BeaconState, attSlashing *cltypes.Atte att1 := attSlashing.Attestation_1 att2 := attSlashing.Attestation_2 - if !isSlashableAttestationData(att1.Data, att2.Data) { + if !cltypes.IsSlashableAttestationData(att1.Data, att2.Data) { return fmt.Errorf("attestation data not slashable: %+v; %+v", att1.Data, att2.Data) } - valid, err := isValidIndexedAttestation(state, att1) + valid, err := state.IsValidIndexedAttestation(att1) if err != nil { return fmt.Errorf("error calculating indexed attestation 1 validity: %v", err) } @@ -123,7 +86,7 @@ func ProcessAttesterSlashing(state *state.BeaconState, attSlashing *cltypes.Atte return fmt.Errorf("invalid indexed attestation 1") } - valid, err = isValidIndexedAttestation(state, att2) + valid, err = state.IsValidIndexedAttestation(att2) if err != nil { return fmt.Errorf("error calculating indexed attestation 2 validity: %v", err) } @@ -134,7 +97,7 @@ func ProcessAttesterSlashing(state *state.BeaconState, attSlashing *cltypes.Atte slashedAny := false currentEpoch := state.GetEpochAtSlot(state.Slot()) for _, ind := range utils.IntersectionOfSortedSets(att1.AttestingIndices, att2.AttestingIndices) { - validator, err := state.ValidatorAt(int(ind)) + validator, err := state.ValidatorForValidatorIndex(int(ind)) if err != nil { return err } @@ -195,6 +158,7 @@ func ProcessDeposit(state *state.BeaconState, deposit *cltypes.Deposit, fullVali valid, err := bls.Verify(deposit.Data.Signature[:], signedRoot[:], publicKey[:]) // Literally you can input it trash. if !valid || err != nil { + log.Debug("Validator BLS verification failed", "valid", valid, "err", err) return nil } // Append validator @@ -216,7 +180,7 @@ func ProcessVoluntaryExit(state *state.BeaconState, signedVoluntaryExit *cltypes // Sanity checks so that we know it is good. voluntaryExit := signedVoluntaryExit.VolunaryExit currentEpoch := state.Epoch() - validator, err := state.ValidatorAt(int(voluntaryExit.ValidatorIndex)) + validator, err := state.ValidatorForValidatorIndex(int(voluntaryExit.ValidatorIndex)) if err != nil { return err } @@ -254,3 +218,49 @@ func ProcessVoluntaryExit(state *state.BeaconState, signedVoluntaryExit *cltypes // Do the exit (same process in slashing). return state.InitiateValidatorExit(voluntaryExit.ValidatorIndex) } + +// ProcessWithdrawals processes withdrawals by decreasing the balance of each validator +// and updating the next withdrawal index and validator index. +func ProcessWithdrawals(state *state.BeaconState, withdrawals types.Withdrawals, fullValidation bool) error { + // Get the list of withdrawals, the expected withdrawals (if performing full validation), + // and the beacon configuration. + beaconConfig := state.BeaconConfig() + numValidators := uint64(len(state.Validators())) + + // Check if full validation is required and verify expected withdrawals. + if fullValidation { + expectedWithdrawals := state.ExpectedWithdrawals() + if len(expectedWithdrawals) != len(withdrawals) { + return fmt.Errorf("ProcessWithdrawals: expected %d withdrawals, but got %d", len(expectedWithdrawals), len(withdrawals)) + } + for i, withdrawal := range withdrawals { + if !expectedWithdrawals[i].Equal(withdrawal) { + return fmt.Errorf("ProcessWithdrawals: withdrawal %d does not match expected withdrawal", i) + } + } + } + + // Decrease the balance of each validator for the corresponding withdrawal. + for _, withdrawal := range withdrawals { + if err := state.DecreaseBalance(withdrawal.Validator, withdrawal.Amount); err != nil { + return err + } + } + + // Update next withdrawal index based on number of withdrawals. + if len(withdrawals) > 0 { + lastWithdrawalIndex := withdrawals[len(withdrawals)-1].Index + state.SetNextWithdrawalIndex(lastWithdrawalIndex + 1) + } + + // Update next withdrawal validator index based on number of withdrawals. + if len(withdrawals) == int(beaconConfig.MaxWithdrawalsPerPayload) { + lastWithdrawalValidatorIndex := withdrawals[len(withdrawals)-1].Validator + 1 + state.SetNextWithdrawalValidatorIndex(lastWithdrawalValidatorIndex % numValidators) + } else { + nextIndex := state.NextWithdrawalValidatorIndex() + beaconConfig.MaxValidatorsPerWithdrawalsSweep + state.SetNextWithdrawalValidatorIndex(nextIndex % numValidators) + } + + return nil +} diff --git a/cmd/erigon-cl/core/transition/operations_test.go b/cmd/erigon-cl/core/transition/operations_test.go index 490720ab481..05eb86de165 100644 --- a/cmd/erigon-cl/core/transition/operations_test.go +++ b/cmd/erigon-cl/core/transition/operations_test.go @@ -350,29 +350,3 @@ func TestProcessVoluntaryExits(t *testing.T) { newRegistry := state.Validators() require.Equal(t, newRegistry[0].ExitEpoch, uint64(266)) } - -func TestProcessAttestationAggBitsInvalid(t *testing.T) { - beaconState := state.GetEmptyBeaconState() - beaconState.SetSlot(beaconState.Slot() + clparams.MainnetBeaconConfig.MinAttestationInclusionDelay) - for i := 0; i < 64; i++ { - beaconState.AddValidator(&cltypes.Validator{ - EffectiveBalance: clparams.MainnetBeaconConfig.MaxEffectiveBalance, - ExitEpoch: clparams.MainnetBeaconConfig.FarFutureEpoch, - WithdrawableEpoch: clparams.MainnetBeaconConfig.FarFutureEpoch, - }, clparams.MainnetBeaconConfig.MaxEffectiveBalance) - beaconState.AddCurrentEpochParticipationFlags(cltypes.ParticipationFlags(0)) - } - - aggBits := []byte{7} - r, err := beaconState.GetBlockRootAtSlot(0) - require.NoError(t, err) - att := &cltypes.Attestation{ - Data: &cltypes.AttestationData{ - BeaconBlockHash: r, - Source: &cltypes.Checkpoint{}, - Target: &cltypes.Checkpoint{}, - }, - AggregationBits: aggBits, - } - require.Error(t, ProcessAttestations(beaconState, []*cltypes.Attestation{att}, false)) -} diff --git a/cmd/erigon-cl/core/transition/process_attestations.go b/cmd/erigon-cl/core/transition/process_attestations.go index 8a3d30704af..497da856adc 100644 --- a/cmd/erigon-cl/core/transition/process_attestations.go +++ b/cmd/erigon-cl/core/transition/process_attestations.go @@ -104,7 +104,7 @@ func verifyAttestationWorker(state *state.BeaconState, attestation *cltypes.Atte resultCh <- verifyAttestationWorkersResult{err: err} return } - success, err := isValidIndexedAttestation(state, indexedAttestation) + success, err := state.IsValidIndexedAttestation(indexedAttestation) resultCh <- verifyAttestationWorkersResult{success: success, err: err} } diff --git a/cmd/erigon-cl/core/transition/process_slots.go b/cmd/erigon-cl/core/transition/process_slots.go index d208e7e5a36..43ead92a8ea 100644 --- a/cmd/erigon-cl/core/transition/process_slots.go +++ b/cmd/erigon-cl/core/transition/process_slots.go @@ -97,7 +97,7 @@ func ProcessSlots(state *state.BeaconState, slot uint64) error { if err := ProcessEpoch(state); err != nil { return err } - log.Info("Processed new epoch successfully", "epoch", state.Epoch(), "process_epoch_elpsed", time.Since(start)) + log.Debug("Processed new epoch successfully", "epoch", state.Epoch(), "process_epoch_elpsed", time.Since(start)) } // TODO: add logic to process epoch updates. stateSlot += 1 diff --git a/cmd/erigon-cl/execution_client/execution_engine.go b/cmd/erigon-cl/execution_client/execution_engine.go new file mode 100644 index 00000000000..66cff77eeff --- /dev/null +++ b/cmd/erigon-cl/execution_client/execution_engine.go @@ -0,0 +1,148 @@ +package execution_client + +import ( + "context" + "fmt" + "time" + + "github.com/holiman/uint256" + libcommon "github.com/ledgerwatch/erigon-lib/common" + "github.com/ledgerwatch/erigon-lib/gointerfaces" + "github.com/ledgerwatch/erigon-lib/gointerfaces/remote" + "github.com/ledgerwatch/erigon-lib/gointerfaces/types" + "github.com/ledgerwatch/erigon/cl/cltypes" + "github.com/ledgerwatch/erigon/ethdb/privateapi" +) + +var errContextExceeded = "rpc error: code = DeadlineExceeded desc = context deadline exceeded" + +// ExecutionEngine is used only for syncing up very close to chain tip and to stay in sync. +// It pretty much mimics engine API. +type ExecutionEngine interface { + NewPayload(payload *cltypes.Eth1Block) error + ForkChoiceUpdate(finalized libcommon.Hash, head libcommon.Hash) error +} + +// ExecutionEnginePhase1 is just the normal engine api. +type ExecutionEnginePhase1 struct { + // Either execution server or client + executionServer remote.ETHBACKENDServer + executionClient remote.ETHBACKENDClient + + ctx context.Context +} + +// NewExecutionEnginePhase1FromServer use ethbackend server +func NewExecutionEnginePhase1FromServer(ctx context.Context, executionServer remote.ETHBACKENDServer) *ExecutionEnginePhase1 { + return &ExecutionEnginePhase1{ + executionServer: executionServer, + ctx: ctx, + } +} + +// NewExecutionEnginePhase1FromServer use ethbackend client +func NewExecutionEnginePhase1FromClient(ctx context.Context, executionClient remote.ETHBACKENDClient) *ExecutionEnginePhase1 { + return &ExecutionEnginePhase1{ + executionClient: executionClient, + ctx: ctx, + } +} + +func (e *ExecutionEnginePhase1) NewPayload(payload *cltypes.Eth1Block) error { + grpcMessage, err := convertPayloadToGrpc(payload) + if err != nil { + return err + } + ctx, cancel := context.WithTimeout(e.ctx, 3*time.Second) + defer cancel() + + var status *remote.EnginePayloadStatus + if e.executionServer != nil { + status, err = e.executionServer.EngineNewPayload(ctx, grpcMessage) + } else if e.executionClient != nil { + status, err = e.executionClient.EngineNewPayload(ctx, grpcMessage) + } + // Ignore timeouts + if err != nil { + if err.Error() == errContextExceeded { + return nil + } + return err + } + if status.Status == remote.EngineStatus_INVALID { + return fmt.Errorf("invalid block") + } + if status.Status == remote.EngineStatus_INVALID_BLOCK_HASH { + return fmt.Errorf("invalid block hash") + } + return err +} + +func (e *ExecutionEnginePhase1) ForkChoiceUpdate(finalized libcommon.Hash, head libcommon.Hash) error { + grpcMessage := &remote.EngineForkChoiceUpdatedRequest{ + ForkchoiceState: &remote.EngineForkChoiceState{ + HeadBlockHash: gointerfaces.ConvertHashToH256(head), + SafeBlockHash: gointerfaces.ConvertHashToH256(head), + FinalizedBlockHash: gointerfaces.ConvertHashToH256(finalized), + }, + } + var err error + ctx, cancel := context.WithTimeout(e.ctx, 3*time.Second) + defer cancel() + if e.executionClient != nil { + _, err = e.executionClient.EngineForkChoiceUpdated(ctx, grpcMessage) + } else if e.executionServer != nil { + _, err = e.executionServer.EngineForkChoiceUpdated(ctx, grpcMessage) + } + // Ignore timeouts + if err != nil && err.Error() == errContextExceeded { + return nil + } + + return err +} + +// ExecutionEnginePhase2 is "real merge" (TODO). +type ExecutionEnginePhase2 struct { +} + +func convertPayloadToGrpc(e *cltypes.Eth1Block) (*types.ExecutionPayload, error) { + var baseFee *uint256.Int + header, err := e.RlpHeader() + if err != nil { + return nil, err + } + + if header.BaseFee != nil { + var overflow bool + baseFee, overflow = uint256.FromBig(header.BaseFee) + if overflow { + panic("NewPayload BaseFeePerGas overflow") + } + } + + res := &types.ExecutionPayload{ + Version: 1, + ParentHash: gointerfaces.ConvertHashToH256(header.ParentHash), + Coinbase: gointerfaces.ConvertAddressToH160(header.Coinbase), + StateRoot: gointerfaces.ConvertHashToH256(header.Root), + ReceiptRoot: gointerfaces.ConvertHashToH256(header.ReceiptHash), + LogsBloom: gointerfaces.ConvertBytesToH2048(header.Bloom[:]), + PrevRandao: gointerfaces.ConvertHashToH256(header.MixDigest), + BlockNumber: header.Number.Uint64(), + GasLimit: header.GasLimit, + GasUsed: header.GasUsed, + Timestamp: header.Time, + ExtraData: header.Extra, + BaseFeePerGas: gointerfaces.ConvertUint256IntToH256(baseFee), + BlockHash: gointerfaces.ConvertHashToH256(e.BlockHash), + Transactions: e.Transactions, + Withdrawals: privateapi.ConvertWithdrawalsToRpc(e.Withdrawals), + } + if e.Withdrawals != nil { + res.Version = 2 + res.Withdrawals = privateapi.ConvertWithdrawalsToRpc(e.Withdrawals) + } + + return res, nil +} diff --git a/cmd/erigon-cl/forkchoice/fork_choice_test.go b/cmd/erigon-cl/forkchoice/fork_choice_test.go new file mode 100644 index 00000000000..2a73378bad0 --- /dev/null +++ b/cmd/erigon-cl/forkchoice/fork_choice_test.go @@ -0,0 +1,88 @@ +package forkchoice_test + +import ( + _ "embed" + "testing" + + libcommon "github.com/ledgerwatch/erigon-lib/common" + + "github.com/ledgerwatch/erigon/cl/clparams" + "github.com/ledgerwatch/erigon/cl/cltypes" + "github.com/ledgerwatch/erigon/cl/utils" + "github.com/ledgerwatch/erigon/cmd/erigon-cl/core/state" + "github.com/ledgerwatch/erigon/cmd/erigon-cl/forkchoice" + "github.com/stretchr/testify/require" +) + +//go:embed test_data/anchor_state.ssz_snappy +var anchorStateEncoded []byte + +//go:embed test_data/block_0x3af8b5b42ca135c75b32abb32b3d71badb73695d3dc638bacfb6c8b7bcbee1a9.ssz_snappy +var block3aEncoded []byte + +//go:embed test_data/block_0xc2788d6005ee2b92c3df2eff0aeab0374d155fa8ca1f874df305fa376ce334cf.ssz_snappy +var blockc2Encoded []byte + +//go:embed test_data/block_0xd4503d46e43df56de4e19acb0f93b3b52087e422aace49a7c3816cf59bafb0ad.ssz_snappy +var blockd4Encoded []byte + +//go:embed test_data/attestation_0xfb924d35b2888d9cd70e6879c1609e6cad7ea3b028a501967747d96e49068cb6.ssz_snappy +var attestationEncoded []byte + +// this is consensus spec test altair/forkchoice/ex_ante/ex_ante_attestations_is_greater_than_proposer_boost_with_boost +func TestForkChoiceBasic(t *testing.T) { + expectedCheckpoint := &cltypes.Checkpoint{ + Epoch: 0, + Root: libcommon.HexToHash("0x564d76d91f66c1fb2977484a6184efda2e1c26dd01992e048353230e10f83201"), + } + // Decode test blocks + block0x3a, block0xc2, block0xd4 := &cltypes.SignedBeaconBlock{}, &cltypes.SignedBeaconBlock{}, &cltypes.SignedBeaconBlock{} + require.NoError(t, utils.DecodeSSZSnappyWithVersion(block0x3a, block3aEncoded, int(clparams.AltairVersion))) + require.NoError(t, utils.DecodeSSZSnappyWithVersion(block0xc2, blockc2Encoded, int(clparams.AltairVersion))) + require.NoError(t, utils.DecodeSSZSnappyWithVersion(block0xd4, blockd4Encoded, int(clparams.AltairVersion))) + // decode test attestation + testAttestation := &cltypes.Attestation{} + require.NoError(t, utils.DecodeSSZSnappyWithVersion(testAttestation, attestationEncoded, int(clparams.AltairVersion))) + // Initialize forkchoice store + anchorState := state.New(&clparams.MainnetBeaconConfig) + require.NoError(t, utils.DecodeSSZSnappyWithVersion(anchorState, anchorStateEncoded, int(clparams.AltairVersion))) + store, err := forkchoice.NewForkChoiceStore(anchorState, nil, false) + require.NoError(t, err) + // first steps + store.OnTick(0) + store.OnTick(12) + require.NoError(t, store.OnBlock(block0x3a, true)) + // Check if we get correct status (1) + require.Equal(t, store.Time(), uint64(12)) + require.Equal(t, store.ProposerBoostRoot(), libcommon.HexToHash("0xc9bd7bcb6dfa49dc4e5a67ca75e89062c36b5c300bc25a1b31db4e1a89306071")) + require.Equal(t, store.JustifiedCheckpoint(), expectedCheckpoint) + require.Equal(t, store.FinalizedCheckpoint(), expectedCheckpoint) + headRoot, headSlot, err := store.GetHead() + require.NoError(t, err) + require.Equal(t, headRoot, libcommon.HexToHash("0xc9bd7bcb6dfa49dc4e5a67ca75e89062c36b5c300bc25a1b31db4e1a89306071")) + require.Equal(t, headSlot, uint64(1)) + // process another tick and another block + store.OnTick(36) + require.NoError(t, store.OnBlock(block0xc2, true)) + // Check if we get correct status (2) + require.Equal(t, store.Time(), uint64(36)) + require.Equal(t, store.ProposerBoostRoot(), libcommon.HexToHash("0x744cc484f6503462f0f3a5981d956bf4fcb3e57ab8687ed006467e05049ee033")) + require.Equal(t, store.JustifiedCheckpoint(), expectedCheckpoint) + require.Equal(t, store.FinalizedCheckpoint(), expectedCheckpoint) + headRoot, headSlot, err = store.GetHead() + require.NoError(t, err) + require.Equal(t, headSlot, uint64(3)) + require.Equal(t, headRoot, libcommon.HexToHash("0x744cc484f6503462f0f3a5981d956bf4fcb3e57ab8687ed006467e05049ee033")) + // last block + require.NoError(t, store.OnBlock(block0xd4, true)) + require.Equal(t, store.Time(), uint64(36)) + require.Equal(t, store.ProposerBoostRoot(), libcommon.HexToHash("0x744cc484f6503462f0f3a5981d956bf4fcb3e57ab8687ed006467e05049ee033")) + require.Equal(t, store.JustifiedCheckpoint(), expectedCheckpoint) + require.Equal(t, store.FinalizedCheckpoint(), expectedCheckpoint) + headRoot, headSlot, err = store.GetHead() + require.NoError(t, err) + require.Equal(t, headSlot, uint64(3)) + require.Equal(t, headRoot, libcommon.HexToHash("0x744cc484f6503462f0f3a5981d956bf4fcb3e57ab8687ed006467e05049ee033")) + // lastly do attestation + require.NoError(t, store.OnAttestation(testAttestation, false)) +} diff --git a/cmd/erigon-cl/forkchoice/fork_graph/fork_graph.go b/cmd/erigon-cl/forkchoice/fork_graph/fork_graph.go new file mode 100644 index 00000000000..a342a461d1d --- /dev/null +++ b/cmd/erigon-cl/forkchoice/fork_graph/fork_graph.go @@ -0,0 +1,284 @@ +package fork_graph + +import ( + libcommon "github.com/ledgerwatch/erigon-lib/common" + "github.com/ledgerwatch/erigon/cl/clparams" + "github.com/ledgerwatch/erigon/cl/cltypes" + "github.com/ledgerwatch/erigon/cmd/erigon-cl/core/state" + "github.com/ledgerwatch/erigon/cmd/erigon-cl/core/transition" + "github.com/ledgerwatch/log/v3" + "golang.org/x/exp/slices" +) + +type ChainSegmentInsertionResult uint + +const ( + Success ChainSegmentInsertionResult = 0 + InvalidBlock ChainSegmentInsertionResult = 1 + MissingSegment ChainSegmentInsertionResult = 2 + BelowAnchor ChainSegmentInsertionResult = 3 + LogisticError ChainSegmentInsertionResult = 4 + PreValidated ChainSegmentInsertionResult = 5 +) + +const snapshotStateEverySlot = 64 + +/* +* The state store process is related to graph theory in the sense that the Ethereum blockchain can be thought of as a directed graph, +* where each block represents a node and the links between blocks represent directed edges. +* In this context, rolling back the state of Ethereum to a previous state can be thought of as traversing the graph in reverse, +* from the current state to a previous state. +* The process of reverting the state involves undoing the changes made in the blocks that have been added to the blockchain since the previous state. +* This can be thought of as "reversing the edges" in the graph, effectively undoing the changes made to the state of Ethereum. +* By thinking of the Ethereum blockchain as a graph, we can use graph theory concepts, such as traversal algorithms, +* to analyze and manipulate the state of the blockchain. + */ + +// ForkGraph is our graph for ETH 2.0 consensus forkchoice. Each node is a (block root, changes) pair and +// each edge is the path described as (prevBlockRoot, currBlockRoot). if we want to go forward we use blocks. +type ForkGraph struct { + // Alternate beacon states + currentReferenceState *state.BeaconState + nextReferenceState *state.BeaconState + currentReferenceStateRoot libcommon.Hash + blocks map[libcommon.Hash]*cltypes.SignedBeaconBlock // set of blocks + headers map[libcommon.Hash]*cltypes.BeaconBlockHeader // set of headers + badBlocks map[libcommon.Hash]struct{} // blocks that are invalid and that leads to automatic fail of extension. + // current state data + currentState *state.BeaconState + currentStateBlockRoot libcommon.Hash + // childrens maps each block roots to its children block roots + childrens map[libcommon.Hash][]libcommon.Hash + // for each block root we also keep track of te equivalent current justified and finalized checkpoints for faster head retrieval. + currentJustifiedCheckpoints map[libcommon.Hash]*cltypes.Checkpoint + finalizedCheckpoints map[libcommon.Hash]*cltypes.Checkpoint + // Disable for tests + enabledPruning bool + // configurations + beaconCfg *clparams.BeaconChainConfig + genesisTime uint64 +} + +// Initialize fork graph with a new state +func New(anchorState *state.BeaconState, enabledPruning bool) *ForkGraph { + farthestExtendingPath := make(map[libcommon.Hash]bool) + anchorRoot, err := anchorState.BlockRoot() + if err != nil { + panic(err) + } + headers := make(map[libcommon.Hash]*cltypes.BeaconBlockHeader) + anchorHeader := anchorState.LatestBlockHeader() + if anchorHeader.Root, err = anchorState.HashSSZ(); err != nil { + panic(err) + } + headers[anchorRoot] = &anchorHeader + + farthestExtendingPath[anchorRoot] = true + currentStateReference, err := anchorState.Copy() + if err != nil { + panic(err) + } + return &ForkGraph{ + currentReferenceState: currentStateReference, + nextReferenceState: currentStateReference, + // storage + blocks: make(map[libcommon.Hash]*cltypes.SignedBeaconBlock), + headers: headers, + badBlocks: make(map[libcommon.Hash]struct{}), + // current state data + currentState: anchorState, + currentStateBlockRoot: anchorRoot, + currentReferenceStateRoot: anchorRoot, + // childrens + childrens: make(map[libcommon.Hash][]libcommon.Hash), + // checkpoints trackers + currentJustifiedCheckpoints: make(map[libcommon.Hash]*cltypes.Checkpoint), + finalizedCheckpoints: make(map[libcommon.Hash]*cltypes.Checkpoint), + enabledPruning: enabledPruning, + // configuration + beaconCfg: anchorState.BeaconConfig(), + genesisTime: anchorState.GenesisTime(), + } +} + +// Add a new node and edge to the graph +func (f *ForkGraph) AddChainSegment(signedBlock *cltypes.SignedBeaconBlock, fullValidation bool) (*state.BeaconState, ChainSegmentInsertionResult, error) { + block := signedBlock.Block + blockRoot, err := block.HashSSZ() + if err != nil { + return nil, LogisticError, err + } + + if _, ok := f.blocks[blockRoot]; ok { + return nil, PreValidated, nil + } + // Blocks below anchors are invalid. + if block.Slot <= f.currentReferenceState.Slot() { + log.Debug("block below anchor slot", "slot", block.Slot, "hash", libcommon.Hash(blockRoot)) + f.badBlocks[blockRoot] = struct{}{} + return nil, BelowAnchor, nil + } + // Check if block being process right now was marked as invalid. + if _, ok := f.badBlocks[blockRoot]; ok { + log.Debug("block has invalid parent", "slot", block.Slot, "hash", libcommon.Hash(blockRoot)) + f.badBlocks[blockRoot] = struct{}{} + return nil, InvalidBlock, nil + } + + newState, err := f.GetState(block.ParentRoot, false) + if err != nil { + return nil, InvalidBlock, err + } + if newState == nil { + return nil, MissingSegment, nil + } + // We may just use the current beacon state + prevCurrentStateSlot := f.currentState.Slot() + + // Execute the state + if err := transition.TransitionState(newState, signedBlock, fullValidation); err != nil { + // Add block to list of invalid blocks + log.Debug("Invalid beacon block", "reason", err) + f.badBlocks[blockRoot] = struct{}{} + f.currentState = nil + return nil, InvalidBlock, err + } + + f.blocks[blockRoot] = signedBlock + bodyRoot, err := signedBlock.Block.Body.HashSSZ() + if err != nil { + return nil, LogisticError, err + } + f.headers[blockRoot] = &cltypes.BeaconBlockHeader{ + Slot: block.Slot, + ProposerIndex: block.ProposerIndex, + ParentRoot: block.ParentRoot, + Root: block.StateRoot, + BodyRoot: bodyRoot, + } + // Update the children of the parent + f.updateChildren(block.ParentRoot, blockRoot) + // Lastly add checkpoints to caches as well. + f.currentJustifiedCheckpoints[blockRoot] = newState.CurrentJustifiedCheckpoint().Copy() + f.finalizedCheckpoints[blockRoot] = newState.FinalizedCheckpoint().Copy() + if newState.Slot() > prevCurrentStateSlot { + f.currentState = newState + f.currentStateBlockRoot = blockRoot + if newState.Slot()%snapshotStateEverySlot == 0 && f.enabledPruning { + if err := f.removeOldData(); err != nil { + return nil, LogisticError, err + } + } + } + return newState, Success, nil +} + +func (f *ForkGraph) GenesisTime() uint64 { + return f.genesisTime +} + +func (f *ForkGraph) Config() *clparams.BeaconChainConfig { + return f.beaconCfg +} + +func (f *ForkGraph) GetHeader(blockRoot libcommon.Hash) (*cltypes.BeaconBlockHeader, bool) { + obj, has := f.headers[blockRoot] + return obj, has +} + +func (f *ForkGraph) getBlock(blockRoot libcommon.Hash) (*cltypes.SignedBeaconBlock, bool) { + obj, has := f.blocks[blockRoot] + return obj, has +} + +func (f *ForkGraph) GetState(blockRoot libcommon.Hash, alwaysCopy bool) (*state.BeaconState, error) { + if f.currentStateBlockRoot == blockRoot { + if alwaysCopy { + return f.currentState.Copy() + } + return f.currentState, nil + } + // collect all blocks beetwen greatest extending node path and block. + blocksInTheWay := []*cltypes.SignedBeaconBlock{} + // Use the parent root as a reverse iterator. + currentIteratorRoot := blockRoot + // use the current reference state root as reconnectio + reconnectionRoot, err := f.currentReferenceState.BlockRoot() + if err != nil { + return nil, err + } + // try and find the point of recconection + for currentIteratorRoot != reconnectionRoot { + block, isSegmentPresent := f.getBlock(currentIteratorRoot) + if !isSegmentPresent { + log.Debug("Could not retrieve state: Missing header", "missing", currentIteratorRoot) + return nil, nil + } + blocksInTheWay = append(blocksInTheWay, block) + currentIteratorRoot = block.Block.ParentRoot + } + // Take a copy to the reference state. + copyReferencedState, err := f.currentReferenceState.Copy() + if err != nil { + return nil, err + } + // Traverse the blocks from top to bottom. + for i := len(blocksInTheWay) - 1; i >= 0; i-- { + if err := transition.TransitionState(copyReferencedState, blocksInTheWay[i], false); err != nil { + return nil, err + } + } + return copyReferencedState, nil +} + +// updateChildren adds a new child to the parent node hash. +func (f *ForkGraph) updateChildren(parent, child libcommon.Hash) { + childrens := f.childrens[parent] + if slices.Contains(childrens, child) { + return + } + childrens = append(childrens, child) + f.childrens[parent] = childrens +} + +// GetChildren retrieves the children block root of the given block root. +func (f *ForkGraph) GetChildren(parent libcommon.Hash) []libcommon.Hash { + return f.childrens[parent] +} + +func (f *ForkGraph) GetCurrentJustifiedCheckpoint(blockRoot libcommon.Hash) (*cltypes.Checkpoint, bool) { + obj, has := f.currentJustifiedCheckpoints[blockRoot] + return obj, has +} + +func (f *ForkGraph) GetFinalizedCheckpoint(blockRoot libcommon.Hash) (*cltypes.Checkpoint, bool) { + obj, has := f.finalizedCheckpoints[blockRoot] + return obj, has +} + +func (f *ForkGraph) removeOldData() (err error) { + pruneSlot := f.nextReferenceState.Slot() + log.Debug("Pruning old blocks", "pruneSlot", pruneSlot) + oldRoots := make([]libcommon.Hash, 0, len(f.blocks)) + for hash, signedBlock := range f.blocks { + if signedBlock.Block.Slot >= pruneSlot { + continue + } + oldRoots = append(oldRoots, hash) + } + for _, root := range oldRoots { + delete(f.badBlocks, root) + delete(f.blocks, root) + delete(f.childrens, root) + delete(f.currentJustifiedCheckpoints, root) + delete(f.finalizedCheckpoints, root) + delete(f.headers, root) + } + // Lastly snapshot the state + f.currentReferenceState = f.nextReferenceState + if f.currentReferenceStateRoot, err = f.currentReferenceState.HashSSZ(); err != nil { + return + } + f.nextReferenceState, err = f.currentState.Copy() + return +} diff --git a/cmd/erigon-cl/forkchoice/fork_graph/fork_graph_test.go b/cmd/erigon-cl/forkchoice/fork_graph/fork_graph_test.go new file mode 100644 index 00000000000..78e8eeab938 --- /dev/null +++ b/cmd/erigon-cl/forkchoice/fork_graph/fork_graph_test.go @@ -0,0 +1,49 @@ +package fork_graph_test + +import ( + _ "embed" + "testing" + + "github.com/ledgerwatch/erigon/cl/clparams" + "github.com/ledgerwatch/erigon/cl/cltypes" + "github.com/ledgerwatch/erigon/cl/utils" + "github.com/ledgerwatch/erigon/cmd/erigon-cl/core/state" + "github.com/ledgerwatch/erigon/cmd/erigon-cl/forkchoice/fork_graph" + "github.com/stretchr/testify/require" +) + +//go:embed test_data/block_0xe2a37a22d208ebe969c50e9d44bb3f1f63c5404787b9c214a5f2f28fb9835feb.ssz_snappy +var block1 []byte + +//go:embed test_data/block_0xbf1a9ba2d349f6b5a5095bff40bd103ae39177e36018fb1f589953b9eeb0ca9d.ssz_snappy +var block2 []byte + +//go:embed test_data/anchor_state.ssz_snappy +var anchor []byte + +func TestForkGraph(t *testing.T) { + blockA, blockB, blockC := &cltypes.SignedBeaconBlock{}, &cltypes.SignedBeaconBlock{}, &cltypes.SignedBeaconBlock{} + anchorState := state.New(&clparams.MainnetBeaconConfig) + require.NoError(t, utils.DecodeSSZSnappyWithVersion(blockA, block1, int(clparams.Phase0Version))) + require.NoError(t, utils.DecodeSSZSnappyWithVersion(blockB, block2, int(clparams.Phase0Version))) + require.NoError(t, utils.DecodeSSZSnappyWithVersion(blockC, block2, int(clparams.Phase0Version))) + require.NoError(t, utils.DecodeSSZSnappyWithVersion(anchorState, anchor, int(clparams.Phase0Version))) + graph := fork_graph.New(anchorState, false) + _, status, err := graph.AddChainSegment(blockA, true) + require.NoError(t, err) + // Save current state hash + require.NoError(t, err) + require.Equal(t, status, fork_graph.Success) + _, status, err = graph.AddChainSegment(blockB, true) + require.NoError(t, err) + require.Equal(t, status, fork_graph.Success) + // Try again with same should yield success + _, status, err = graph.AddChainSegment(blockB, true) + require.NoError(t, err) + require.Equal(t, status, fork_graph.PreValidated) + // Now make blockC a bad block + blockC.Block.ProposerIndex = 81214459 // some invalid thing + _, status, err = graph.AddChainSegment(blockC, true) + require.Error(t, err) + require.Equal(t, status, fork_graph.InvalidBlock) +} diff --git a/cmd/erigon-cl/forkchoice/forkchoice.go b/cmd/erigon-cl/forkchoice/forkchoice.go new file mode 100644 index 00000000000..7a3da411ecd --- /dev/null +++ b/cmd/erigon-cl/forkchoice/forkchoice.go @@ -0,0 +1,133 @@ +package forkchoice + +import ( + "sync" + + lru "github.com/hashicorp/golang-lru/v2" + libcommon "github.com/ledgerwatch/erigon-lib/common" + "github.com/ledgerwatch/erigon/cl/cltypes" + "github.com/ledgerwatch/erigon/cmd/erigon-cl/core/state" + "github.com/ledgerwatch/erigon/cmd/erigon-cl/execution_client" + "github.com/ledgerwatch/erigon/cmd/erigon-cl/forkchoice/fork_graph" +) + +const ( + checkpointsPerCache = 1024 + allowedCachedStates = 4 +) + +// We cache partial data of each validator instead of storing all checkpoint states +type partialValidator struct { + index uint32 + effectiveBalance uint64 +} + +type ForkChoiceStore struct { + time uint64 + highestSeen uint64 + justifiedCheckpoint *cltypes.Checkpoint + finalizedCheckpoint *cltypes.Checkpoint + unrealizedJustifiedCheckpoint *cltypes.Checkpoint + unrealizedFinalizedCheckpoint *cltypes.Checkpoint + proposerBoostRoot libcommon.Hash + // Use go map because this is actually an unordered set + equivocatingIndicies map[uint64]struct{} + forkGraph *fork_graph.ForkGraph + // I use the cache due to the convenient auto-cleanup feauture. + checkpointStates *lru.Cache[cltypes.Checkpoint, *state.BeaconState] // We keep ssz snappy of it as the full beacon state is full of rendundant data. + latestMessages map[uint64]*LatestMessage + // We keep track of them so that we can forkchoice with EL. + eth2Roots *lru.Cache[libcommon.Hash, libcommon.Hash] // ETH2 root -> ETH1 hash + mu sync.Mutex + // EL + engine execution_client.ExecutionEngine +} + +type LatestMessage struct { + Epoch uint64 + Root libcommon.Hash +} + +// NewForkChoiceStore initialize a new store from the given anchor state, either genesis or checkpoint sync state. +func NewForkChoiceStore(anchorState *state.BeaconState, engine execution_client.ExecutionEngine, enabledPruning bool) (*ForkChoiceStore, error) { + anchorRoot, err := anchorState.BlockRoot() + if err != nil { + return nil, err + } + anchorCheckpoint := &cltypes.Checkpoint{ + Epoch: anchorState.Epoch(), + Root: anchorRoot, + } + checkpointStates, err := lru.New[cltypes.Checkpoint, *state.BeaconState](allowedCachedStates) + if err != nil { + return nil, err + } + eth2Roots, err := lru.New[libcommon.Hash, libcommon.Hash](checkpointsPerCache) + if err != nil { + return nil, err + } + return &ForkChoiceStore{ + highestSeen: anchorState.Slot(), + time: anchorState.GenesisTime() + anchorState.BeaconConfig().SecondsPerSlot*anchorState.Slot(), + justifiedCheckpoint: anchorCheckpoint.Copy(), + finalizedCheckpoint: anchorCheckpoint.Copy(), + unrealizedJustifiedCheckpoint: anchorCheckpoint.Copy(), + unrealizedFinalizedCheckpoint: anchorCheckpoint.Copy(), + forkGraph: fork_graph.New(anchorState, enabledPruning), + equivocatingIndicies: map[uint64]struct{}{}, + latestMessages: map[uint64]*LatestMessage{}, + checkpointStates: checkpointStates, + eth2Roots: eth2Roots, + engine: engine, + }, nil +} + +// Highest seen returns highest seen slot +func (f *ForkChoiceStore) HighestSeen() uint64 { + f.mu.Lock() + defer f.mu.Unlock() + return f.highestSeen +} + +// Time returns current time +func (f *ForkChoiceStore) Time() uint64 { + f.mu.Lock() + defer f.mu.Unlock() + return f.time +} + +// ProposerBoostRoot returns proposer boost root +func (f *ForkChoiceStore) ProposerBoostRoot() libcommon.Hash { + f.mu.Lock() + defer f.mu.Unlock() + return f.proposerBoostRoot +} + +// JustifiedCheckpoint returns justified checkpoint +func (f *ForkChoiceStore) JustifiedCheckpoint() *cltypes.Checkpoint { + f.mu.Lock() + defer f.mu.Unlock() + return f.justifiedCheckpoint +} + +// FinalizedCheckpoint returns justified checkpoint +func (f *ForkChoiceStore) FinalizedCheckpoint() *cltypes.Checkpoint { + f.mu.Lock() + defer f.mu.Unlock() + return f.finalizedCheckpoint +} + +// FinalizedCheckpoint returns justified checkpoint +func (f *ForkChoiceStore) Engine() execution_client.ExecutionEngine { + f.mu.Lock() + defer f.mu.Unlock() + return f.engine +} + +// FinalizedCheckpoint returns justified checkpoint +func (f *ForkChoiceStore) GetEth1Hash(eth2Root libcommon.Hash) libcommon.Hash { + f.mu.Lock() + defer f.mu.Unlock() + ret, _ := f.eth2Roots.Get(eth2Root) + return ret +} diff --git a/cmd/erigon-cl/forkchoice/get_head.go b/cmd/erigon-cl/forkchoice/get_head.go new file mode 100644 index 00000000000..f0d15ab8d11 --- /dev/null +++ b/cmd/erigon-cl/forkchoice/get_head.go @@ -0,0 +1,160 @@ +package forkchoice + +import ( + "bytes" + "fmt" + "sort" + + libcommon "github.com/ledgerwatch/erigon-lib/common" + "github.com/ledgerwatch/erigon/cl/cltypes" + "github.com/ledgerwatch/erigon/cmd/erigon-cl/core/state" +) + +// GetHead fetches the current head. +func (f *ForkChoiceStore) GetHead() (libcommon.Hash, uint64, error) { + f.mu.Lock() + defer f.mu.Unlock() + // Retrieve att + head := f.justifiedCheckpoint.Root + blocks := f.getFilteredBlockTree(head) + // See which validators can be used for attestation score + justificationState, err := f.getCheckpointState(*f.justifiedCheckpoint) + if err != nil { + return libcommon.Hash{}, 0, err + } + // Filter all validators deemed as bad + filteredIndicies := f.filterValidatorSetForAttestationScores(justificationState.Validators(), justificationState.Epoch()) + for { + // Filter out current head children. + unfilteredChildren := f.forkGraph.GetChildren(head) + children := []libcommon.Hash{} + for _, child := range unfilteredChildren { + if _, ok := blocks[child]; ok { + children = append(children, child) + } + } + // Stop if we dont have any more children + if len(children) == 0 { + header, hasHeader := f.forkGraph.GetHeader(head) + if !hasHeader { + return libcommon.Hash{}, 0, fmt.Errorf("no slot for head is stored") + } + return head, header.Slot, nil + } + // Average case scenario. + if len(children) == 1 { + head = children[0] + continue + } + // Sort children by lexigographical order + sort.Slice(children, func(i, j int) bool { + childA := children[i] + childB := children[j] + return bytes.Compare(childA[:], childB[:]) < 0 + }) + + // After sorting is done determine best fit. + head = children[0] + maxWeight := f.getWeight(children[0], filteredIndicies, justificationState) + for i := 1; i < len(children); i++ { + weight := f.getWeight(children[i], filteredIndicies, justificationState) + // Lexicographical order is king. + if weight >= maxWeight { + head = children[i] + maxWeight = weight + } + } + } +} + +// filterValidatorSetForAttestationScores preliminarly filter the validator set obliging to consensus rules. +func (f *ForkChoiceStore) filterValidatorSetForAttestationScores(validatorSet []*cltypes.Validator, epoch uint64) []uint64 { + filtered := make([]uint64, 0, len(validatorSet)) + for validatorIndex, validator := range validatorSet { + if !validator.Active(epoch) || validator.Slashed { + continue + } + if _, hasLatestMessage := f.latestMessages[uint64(validatorIndex)]; !hasLatestMessage { + continue + } + if _, isUnequivocating := f.equivocatingIndicies[uint64(validatorIndex)]; isUnequivocating { + continue + } + filtered = append(filtered, uint64(validatorIndex)) + } + return filtered +} + +// getWeight computes weight in head decision of canonical chain. +func (f *ForkChoiceStore) getWeight(root libcommon.Hash, indicies []uint64, state *state.BeaconState) uint64 { + header, has := f.forkGraph.GetHeader(root) + if !has { + return 0 + } + validators := state.Validators() + // Compute attestation score + var attestationScore uint64 + for _, validatorIndex := range indicies { + if f.Ancestor(f.latestMessages[validatorIndex].Root, header.Slot) != root { + continue + } + attestationScore += validators[validatorIndex].EffectiveBalance + } + if f.proposerBoostRoot == (libcommon.Hash{}) { + return attestationScore + } + + // Boost is applied if root is an ancestor of proposer_boost_root + if f.Ancestor(f.proposerBoostRoot, header.Slot) == root { + committeeWeight := state.GetTotalActiveBalance() / state.BeaconConfig().SlotsPerEpoch + attestationScore += (committeeWeight * state.BeaconConfig().ProposerScoreBoost) / 100 + } + return attestationScore +} + +// getFilteredBlockTree filters out dumb blocks. +func (f *ForkChoiceStore) getFilteredBlockTree(base libcommon.Hash) map[libcommon.Hash]*cltypes.BeaconBlockHeader { + blocks := make(map[libcommon.Hash]*cltypes.BeaconBlockHeader) + f.getFilterBlockTree(base, blocks) + return blocks +} + +// getFilterBlockTree recursively traverses the block tree to identify viable blocks. +// It takes a block hash and a map of viable blocks as input parameters, and returns a boolean value indicating +// whether the current block is viable. +func (f *ForkChoiceStore) getFilterBlockTree(blockRoot libcommon.Hash, blocks map[libcommon.Hash]*cltypes.BeaconBlockHeader) bool { + header, has := f.forkGraph.GetHeader(blockRoot) + if !has { + return false + } + children := f.forkGraph.GetChildren(blockRoot) + // If there are children iterate down recursively and see which branches are viable. + if len(children) > 0 { + isAnyViable := false + for _, child := range children { + if f.getFilterBlockTree(child, blocks) { + isAnyViable = true + } + } + if isAnyViable { + blocks[blockRoot] = header + } + return isAnyViable + } + currentJustifiedCheckpoint, has := f.forkGraph.GetCurrentJustifiedCheckpoint(blockRoot) + if !has { + return false + } + finalizedJustifiedCheckpoint, has := f.forkGraph.GetFinalizedCheckpoint(blockRoot) + if !has { + return false + } + + genesisEpoch := f.forkGraph.Config().GenesisEpoch + if (f.justifiedCheckpoint.Epoch == genesisEpoch || currentJustifiedCheckpoint.Equal(f.justifiedCheckpoint)) && + (f.finalizedCheckpoint.Epoch == genesisEpoch || finalizedJustifiedCheckpoint.Equal(f.finalizedCheckpoint)) { + blocks[blockRoot] = header + return true + } + return false +} diff --git a/cmd/erigon-cl/forkchoice/on_attestation.go b/cmd/erigon-cl/forkchoice/on_attestation.go new file mode 100644 index 00000000000..216b7c95f12 --- /dev/null +++ b/cmd/erigon-cl/forkchoice/on_attestation.go @@ -0,0 +1,108 @@ +package forkchoice + +import ( + "fmt" + + libcommon "github.com/ledgerwatch/erigon-lib/common" + "github.com/ledgerwatch/erigon/cl/cltypes" +) + +// OnAttestation processes incoming attestations. TODO(Giulio2002): finish it with forward changesets. +func (f *ForkChoiceStore) OnAttestation(attestation *cltypes.Attestation, fromBlock bool) error { + f.mu.Lock() + defer f.mu.Unlock() + if err := f.validateOnAttestation(attestation, fromBlock); err != nil { + return err + } + target := attestation.Data.Target + + targetState, err := f.getCheckpointState(*target) + if err != nil { + return nil + } + // Verify attestation signature. + if targetState == nil { + return fmt.Errorf("target state does not exist") + } + attestationIndicies, err := targetState.GetAttestingIndicies(attestation.Data, attestation.AggregationBits, false) + if err != nil { + return err + } + if !fromBlock { + + indexedAttestation, err := targetState.GetIndexedAttestation(attestation, attestationIndicies) + if err != nil { + return err + } + + valid, err := targetState.IsValidIndexedAttestation(indexedAttestation) + if err != nil { + return err + } + if !valid { + return fmt.Errorf("invalid attestation") + } + } + // Lastly update latest messages. + beaconBlockRoot := attestation.Data.BeaconBlockHash + for _, index := range attestationIndicies { + if _, ok := f.equivocatingIndicies[index]; ok { + continue + } + validatorMessage, has := f.latestMessages[index] + if !has || target.Epoch > validatorMessage.Epoch { + f.latestMessages[index] = &LatestMessage{ + Epoch: target.Epoch, + Root: beaconBlockRoot, + } + } + } + return nil +} + +func (f *ForkChoiceStore) validateOnAttestation(attestation *cltypes.Attestation, fromBlock bool) error { + target := attestation.Data.Target + + if !fromBlock { + if err := f.validateTargetEpochAgainstCurrentTime(attestation); err != nil { + return err + } + } + if target.Epoch != f.computeEpochAtSlot(attestation.Data.Slot) { + return fmt.Errorf("mismatching target epoch with slot data") + } + if _, has := f.forkGraph.GetHeader(target.Root); !has { + return fmt.Errorf("target root is missing") + } + if blockHeader, has := f.forkGraph.GetHeader(attestation.Data.BeaconBlockHash); !has || blockHeader.Slot > attestation.Data.Slot { + return fmt.Errorf("bad attestation data") + } + // LMD vote must be consistent with FFG vote target + targetSlot := f.computeStartSlotAtEpoch(target.Epoch) + ancestorRoot := f.Ancestor(attestation.Data.BeaconBlockHash, targetSlot) + if ancestorRoot == (libcommon.Hash{}) { + return fmt.Errorf("could not retrieve ancestor") + } + if ancestorRoot != target.Root { + return fmt.Errorf("ancestor root mismatches with target") + } + if f.Slot() < attestation.Data.Slot+1 { + return fmt.Errorf("future attestation") + } + return nil +} + +func (f *ForkChoiceStore) validateTargetEpochAgainstCurrentTime(attestation *cltypes.Attestation) error { + target := attestation.Data.Target + // Attestations must be from the current or previous epoch + currentEpoch := f.computeEpochAtSlot(f.Slot()) + // Use GENESIS_EPOCH for previous when genesis to avoid underflow + previousEpoch := currentEpoch - 1 + if currentEpoch <= f.forkGraph.Config().GenesisEpoch { + previousEpoch = f.forkGraph.Config().GenesisEpoch + } + if target.Epoch == currentEpoch || target.Epoch == previousEpoch { + return nil + } + return fmt.Errorf("verification of attestation against current time failed") +} diff --git a/cmd/erigon-cl/forkchoice/on_attester_slashing.go b/cmd/erigon-cl/forkchoice/on_attester_slashing.go new file mode 100644 index 00000000000..57a4d5be2ff --- /dev/null +++ b/cmd/erigon-cl/forkchoice/on_attester_slashing.go @@ -0,0 +1,48 @@ +package forkchoice + +import ( + "fmt" + + "github.com/ledgerwatch/erigon/cl/cltypes" + "github.com/ledgerwatch/erigon/cl/utils" +) + +func (f *ForkChoiceStore) OnAttesterSlashing(attesterSlashing *cltypes.AttesterSlashing) error { + f.mu.Lock() + defer f.mu.Unlock() + // Check if these attestation is even slashable. + attestation1 := attesterSlashing.Attestation_1 + attestation2 := attesterSlashing.Attestation_2 + if !cltypes.IsSlashableAttestationData(attestation1.Data, attestation2.Data) { + return fmt.Errorf("attestation data is not slashable") + } + // Retrieve justified state + state, err := f.forkGraph.GetState(f.justifiedCheckpoint.Root, false) + if err != nil { + return err + } + if state == nil { + return fmt.Errorf("justified checkpoint state not accessible") + } + // Verify validity of slashings + valid, err := state.IsValidIndexedAttestation(attestation1) + if err != nil { + return fmt.Errorf("error calculating indexed attestation 1 validity: %v", err) + } + if !valid { + return fmt.Errorf("invalid indexed attestation 1") + } + + valid, err = state.IsValidIndexedAttestation(attestation2) + if err != nil { + return fmt.Errorf("error calculating indexed attestation 2 validity: %v", err) + } + if !valid { + return fmt.Errorf("invalid indexed attestation 2") + } + for _, index := range utils.IntersectionOfSortedSets(attestation1.AttestingIndices, attestation2.AttestingIndices) { + f.equivocatingIndicies[index] = struct{}{} + } + // add attestation indicies to equivocating indicies. + return nil +} diff --git a/cmd/erigon-cl/forkchoice/on_block.go b/cmd/erigon-cl/forkchoice/on_block.go new file mode 100644 index 00000000000..297e32855b1 --- /dev/null +++ b/cmd/erigon-cl/forkchoice/on_block.go @@ -0,0 +1,78 @@ +package forkchoice + +import ( + "fmt" + + "github.com/ledgerwatch/erigon/cl/cltypes" + "github.com/ledgerwatch/erigon/cmd/erigon-cl/core/transition" + "github.com/ledgerwatch/erigon/cmd/erigon-cl/forkchoice/fork_graph" + "github.com/ledgerwatch/log/v3" +) + +func (f *ForkChoiceStore) OnBlock(block *cltypes.SignedBeaconBlock, fullValidation bool) error { + f.mu.Lock() + defer f.mu.Unlock() + blockRoot, err := block.Block.HashSSZ() + if err != nil { + return err + } + // Check that block is later than the finalized epoch slot (optimization to reduce calls to get_ancestor) + finalizedSlot := f.computeStartSlotAtEpoch(f.finalizedCheckpoint.Epoch) + if block.Block.Slot <= finalizedSlot { + return fmt.Errorf("block is too late compared to finalized") + } + + config := f.forkGraph.Config() + if fullValidation && f.engine != nil { + if err := f.engine.NewPayload(block.Block.Body.ExecutionPayload); err != nil { + log.Warn("newPayload failed", "err", err) + return err + } + } + lastProcessedState, status, err := f.forkGraph.AddChainSegment(block, fullValidation) + if status != fork_graph.Success { + if status != fork_graph.PreValidated { + log.Debug("Could not replay block", "slot", block.Block.Slot, "code", status, "reason", err) + return fmt.Errorf("could not replay block, err: %s, code: %d", err, status) + } + return nil + } + if block.Block.Body.ExecutionPayload != nil { + f.eth2Roots.Add(blockRoot, block.Block.Body.ExecutionPayload.BlockHash) + } + if block.Block.Slot > f.highestSeen { + f.highestSeen = block.Block.Slot + } + // Add proposer score boost if the block is timely + timeIntoSlot := (f.time - f.forkGraph.GenesisTime()) % lastProcessedState.BeaconConfig().SecondsPerSlot + isBeforeAttestingInterval := timeIntoSlot < config.SecondsPerSlot/config.IntervalsPerSlot + if f.Slot() == block.Block.Slot && isBeforeAttestingInterval { + f.proposerBoostRoot = blockRoot + } + // Update checkpoints + f.updateCheckpoints(lastProcessedState.CurrentJustifiedCheckpoint().Copy(), lastProcessedState.FinalizedCheckpoint().Copy()) + // First thing save previous values of the checkpoints (avoid memory copy of all states and ensure easy revert) + var ( + previousJustifiedCheckpoint = lastProcessedState.PreviousJustifiedCheckpoint().Copy() + currentJustifiedCheckpoint = lastProcessedState.CurrentJustifiedCheckpoint().Copy() + finalizedCheckpoint = lastProcessedState.FinalizedCheckpoint().Copy() + justificationBits = lastProcessedState.JustificationBits().Copy() + ) + // Eagerly compute unrealized justification and finality + if err := transition.ProcessJustificationBitsAndFinality(lastProcessedState); err != nil { + return err + } + f.updateUnrealizedCheckpoints(lastProcessedState.CurrentJustifiedCheckpoint().Copy(), lastProcessedState.FinalizedCheckpoint().Copy()) + // Set the changed value pre-simulation + lastProcessedState.SetPreviousJustifiedCheckpoint(previousJustifiedCheckpoint) + lastProcessedState.SetCurrentJustifiedCheckpoint(currentJustifiedCheckpoint) + lastProcessedState.SetFinalizedCheckpoint(finalizedCheckpoint) + lastProcessedState.SetJustificationBits(justificationBits) + // If the block is from a prior epoch, apply the realized values + blockEpoch := f.computeEpochAtSlot(block.Block.Slot) + currentEpoch := f.computeEpochAtSlot(f.Slot()) + if blockEpoch < currentEpoch { + f.updateCheckpoints(lastProcessedState.CurrentJustifiedCheckpoint().Copy(), lastProcessedState.FinalizedCheckpoint().Copy()) + } + return nil +} diff --git a/cmd/erigon-cl/forkchoice/on_tick.go b/cmd/erigon-cl/forkchoice/on_tick.go new file mode 100644 index 00000000000..4f59528d25c --- /dev/null +++ b/cmd/erigon-cl/forkchoice/on_tick.go @@ -0,0 +1,30 @@ +package forkchoice + +import libcommon "github.com/ledgerwatch/erigon-lib/common" + +// OnTick executes on_tick operation for forkchoice. +func (f *ForkChoiceStore) OnTick(time uint64) { + f.mu.Lock() + defer f.mu.Unlock() + tickSlot := (time - f.forkGraph.GenesisTime()) / f.forkGraph.Config().SecondsPerSlot + for f.Slot() < tickSlot { + previousTime := f.forkGraph.GenesisTime() + (f.Slot()+1)*f.forkGraph.Config().SecondsPerSlot + f.onTickPerSlot(previousTime) + } + f.onTickPerSlot(time) +} + +// onTickPerSlot handles ticks +func (f *ForkChoiceStore) onTickPerSlot(time uint64) { + previousSlot := f.Slot() + f.time = time + currentSlot := f.Slot() + if currentSlot <= previousSlot { + return + } + // If this is a new slot, reset store.proposer_boost_root + f.proposerBoostRoot = libcommon.Hash{} + if f.computeSlotsSinceEpochStart(currentSlot) == 0 { + f.updateCheckpoints(f.unrealizedJustifiedCheckpoint.Copy(), f.unrealizedFinalizedCheckpoint.Copy()) + } +} diff --git a/cmd/erigon-cl/forkchoice/test_data/anchor_state.ssz_snappy b/cmd/erigon-cl/forkchoice/test_data/anchor_state.ssz_snappy new file mode 100644 index 00000000000..974265ff1c9 Binary files /dev/null and b/cmd/erigon-cl/forkchoice/test_data/anchor_state.ssz_snappy differ diff --git a/cmd/erigon-cl/forkchoice/test_data/attestation_0xfb924d35b2888d9cd70e6879c1609e6cad7ea3b028a501967747d96e49068cb6.ssz_snappy b/cmd/erigon-cl/forkchoice/test_data/attestation_0xfb924d35b2888d9cd70e6879c1609e6cad7ea3b028a501967747d96e49068cb6.ssz_snappy new file mode 100644 index 00000000000..c6bcef772e0 Binary files /dev/null and b/cmd/erigon-cl/forkchoice/test_data/attestation_0xfb924d35b2888d9cd70e6879c1609e6cad7ea3b028a501967747d96e49068cb6.ssz_snappy differ diff --git a/cmd/erigon-cl/forkchoice/test_data/block_0x3af8b5b42ca135c75b32abb32b3d71badb73695d3dc638bacfb6c8b7bcbee1a9.ssz_snappy b/cmd/erigon-cl/forkchoice/test_data/block_0x3af8b5b42ca135c75b32abb32b3d71badb73695d3dc638bacfb6c8b7bcbee1a9.ssz_snappy new file mode 100644 index 00000000000..dc0e77a83a4 Binary files /dev/null and b/cmd/erigon-cl/forkchoice/test_data/block_0x3af8b5b42ca135c75b32abb32b3d71badb73695d3dc638bacfb6c8b7bcbee1a9.ssz_snappy differ diff --git a/cmd/erigon-cl/forkchoice/test_data/block_0xc2788d6005ee2b92c3df2eff0aeab0374d155fa8ca1f874df305fa376ce334cf.ssz_snappy b/cmd/erigon-cl/forkchoice/test_data/block_0xc2788d6005ee2b92c3df2eff0aeab0374d155fa8ca1f874df305fa376ce334cf.ssz_snappy new file mode 100644 index 00000000000..a0777340033 Binary files /dev/null and b/cmd/erigon-cl/forkchoice/test_data/block_0xc2788d6005ee2b92c3df2eff0aeab0374d155fa8ca1f874df305fa376ce334cf.ssz_snappy differ diff --git a/cmd/erigon-cl/forkchoice/test_data/block_0xd4503d46e43df56de4e19acb0f93b3b52087e422aace49a7c3816cf59bafb0ad.ssz_snappy b/cmd/erigon-cl/forkchoice/test_data/block_0xd4503d46e43df56de4e19acb0f93b3b52087e422aace49a7c3816cf59bafb0ad.ssz_snappy new file mode 100644 index 00000000000..7d02fee497e Binary files /dev/null and b/cmd/erigon-cl/forkchoice/test_data/block_0xd4503d46e43df56de4e19acb0f93b3b52087e422aace49a7c3816cf59bafb0ad.ssz_snappy differ diff --git a/cmd/erigon-cl/forkchoice/utils.go b/cmd/erigon-cl/forkchoice/utils.go new file mode 100644 index 00000000000..0a6d393dacb --- /dev/null +++ b/cmd/erigon-cl/forkchoice/utils.go @@ -0,0 +1,94 @@ +package forkchoice + +import ( + "fmt" + + libcommon "github.com/ledgerwatch/erigon-lib/common" + "github.com/ledgerwatch/erigon/cl/cltypes" + "github.com/ledgerwatch/erigon/cmd/erigon-cl/core/state" + "github.com/ledgerwatch/erigon/cmd/erigon-cl/core/transition" + "github.com/ledgerwatch/log/v3" +) + +// Slot calculates the current slot number using the time and genesis slot. +func (f *ForkChoiceStore) Slot() uint64 { + return f.forkGraph.Config().GenesisSlot + ((f.time - f.forkGraph.GenesisTime()) / f.forkGraph.Config().SecondsPerSlot) +} + +// updateCheckpoints updates the justified and finalized checkpoints if new checkpoints have higher epochs. +func (f *ForkChoiceStore) updateCheckpoints(justifiedCheckpoint, finalizedCheckpoint *cltypes.Checkpoint) { + if justifiedCheckpoint.Epoch > f.justifiedCheckpoint.Epoch { + f.justifiedCheckpoint = justifiedCheckpoint + } + if finalizedCheckpoint.Epoch > f.finalizedCheckpoint.Epoch { + f.finalizedCheckpoint = finalizedCheckpoint + } +} + +// updateCheckpoints updates the justified and finalized checkpoints if new checkpoints have higher epochs. +func (f *ForkChoiceStore) updateUnrealizedCheckpoints(justifiedCheckpoint, finalizedCheckpoint *cltypes.Checkpoint) { + if justifiedCheckpoint.Epoch > f.unrealizedJustifiedCheckpoint.Epoch { + f.unrealizedJustifiedCheckpoint = justifiedCheckpoint + } + if finalizedCheckpoint.Epoch > f.unrealizedFinalizedCheckpoint.Epoch { + f.unrealizedFinalizedCheckpoint = finalizedCheckpoint + } +} + +// computeEpochAtSlot calculates the epoch at a given slot number. +func (f *ForkChoiceStore) computeEpochAtSlot(slot uint64) uint64 { + return slot / f.forkGraph.Config().SlotsPerEpoch +} + +// computeStartSlotAtEpoch calculates the starting slot of a given epoch. +func (f *ForkChoiceStore) computeStartSlotAtEpoch(epoch uint64) uint64 { + return epoch * f.forkGraph.Config().SlotsPerEpoch +} + +// computeSlotsSinceEpochStart calculates the number of slots since the start of the epoch of a given slot. +func (f *ForkChoiceStore) computeSlotsSinceEpochStart(slot uint64) uint64 { + return slot - f.computeStartSlotAtEpoch(f.computeEpochAtSlot(slot)) +} + +// Ancestor returns the ancestor to the given root. +func (f *ForkChoiceStore) Ancestor(root libcommon.Hash, slot uint64) libcommon.Hash { + header, has := f.forkGraph.GetHeader(root) + if !has { + return libcommon.Hash{} + } + for header.Slot > slot { + root = header.ParentRoot + header, has = f.forkGraph.GetHeader(header.ParentRoot) + if !has { + return libcommon.Hash{} + } + } + return root +} + +// getCheckpointState computes and caches checkpoint states. +func (f *ForkChoiceStore) getCheckpointState(checkpoint cltypes.Checkpoint) (*state.BeaconState, error) { + // check if it can be found in cache. + if state, ok := f.checkpointStates.Get(checkpoint); ok { + return state, nil + } + // If it is not in cache compute it and then put in cache. + baseState, err := f.forkGraph.GetState(checkpoint.Root, true) + if err != nil { + return nil, err + } + if baseState == nil { + return nil, fmt.Errorf("getCheckpointState: baseState not found in graph") + } + // By default use the no change encoding to signal that there is no future epoch here. + if baseState.Slot() < f.computeStartSlotAtEpoch(checkpoint.Epoch) { + log.Debug("Long checkpoint detected") + // If we require to change it then process the future epoch + if err := transition.ProcessSlots(baseState, f.computeStartSlotAtEpoch(checkpoint.Epoch)); err != nil { + return nil, err + } + } + // Cache in memory what we are left with. + f.checkpointStates.Add(checkpoint, baseState) + return baseState, nil +} diff --git a/cmd/erigon-cl/main.go b/cmd/erigon-cl/main.go index 6240a6e2b75..8a78f90c2b7 100644 --- a/cmd/erigon-cl/main.go +++ b/cmd/erigon-cl/main.go @@ -10,6 +10,7 @@ import ( "github.com/ledgerwatch/erigon-lib/kv" "github.com/ledgerwatch/erigon-lib/kv/mdbx" "github.com/ledgerwatch/erigon/cl/clparams" + "github.com/ledgerwatch/erigon/cl/clparams/initial_state" "github.com/ledgerwatch/erigon/cl/cltypes" "github.com/ledgerwatch/erigon/cl/fork" "github.com/ledgerwatch/erigon/cl/rpc" @@ -17,12 +18,13 @@ import ( "github.com/ledgerwatch/erigon/cmd/erigon-cl/core/rawdb" "github.com/ledgerwatch/erigon/cmd/erigon-cl/core/state" "github.com/ledgerwatch/erigon/cmd/erigon-cl/execution_client" + "github.com/ledgerwatch/erigon/cmd/erigon-cl/forkchoice" "github.com/ledgerwatch/erigon/cmd/erigon-cl/network" "github.com/ledgerwatch/erigon/cmd/erigon-cl/stages" lcCli "github.com/ledgerwatch/erigon/cmd/sentinel/cli" + "github.com/ledgerwatch/erigon/cmd/sentinel/cli/flags" "github.com/ledgerwatch/erigon/cmd/sentinel/sentinel" - "github.com/ledgerwatch/erigon/cmd/sentinel/sentinel/handshake" "github.com/ledgerwatch/erigon/cmd/sentinel/sentinel/service" sentinelapp "github.com/ledgerwatch/erigon/turbo/app" "github.com/ledgerwatch/log/v3" @@ -58,23 +60,31 @@ func runConsensusLayerNode(cliCtx *cli.Context) error { log.Error("Could load beacon data configuration", "err", err) return err } - // Fetch the checkpoint state. - cpState, err := getCheckpointState(ctx, db, cfg.BeaconCfg, cfg.GenesisCfg, cfg.CheckpointUri) + + tmpdir := "/tmp" + executionClient, err := execution_client.NewExecutionClient(ctx, "127.0.0.1:8989") if err != nil { - log.Error("Could not get checkpoint", "err", err) + log.Warn("Could not connect to execution client", "err", err) return err } - var executionClient *execution_client.ExecutionClient - if cfg.ELEnabled { - executionClient, err = execution_client.NewExecutionClient(ctx, "127.0.0.1:8989") + + if cfg.TransitionChain { + state, err := initial_state.GetGenesisState(cfg.NetworkType) if err != nil { - log.Warn("Could not connect to execution client", "err", err) return err } + // Execute from genesis to whatever we have. + return stages.SpawnStageBeaconState(stages.StageBeaconState(db, cfg.BeaconCfg, state, executionClient), nil, ctx) + } + + // Fetch the checkpoint state. + cpState, err := getCheckpointState(ctx, db, cfg.BeaconCfg, cfg.GenesisCfg, cfg.CheckpointUri) + if err != nil { + log.Error("Could not get checkpoint", "err", err) + return err } log.Info("Starting sync from checkpoint.") - tmpdir := "/tmp" // Start the sentinel service log.Root().SetHandler(log.LvlFilterHandler(log.Lvl(cfg.LogLvl), log.StderrHandler)) log.Info("[Sentinel] running sentinel with configuration", "cfg", cfg) @@ -89,10 +99,13 @@ func runConsensusLayerNode(cliCtx *cli.Context) error { downloader := network.NewForwardBeaconDownloader(ctx, beaconRpc) bdownloader := network.NewBackwardBeaconDownloader(ctx, beaconRpc) - gossipManager := network.NewGossipReceiver(ctx, s) - gossipManager.AddReceiver(sentinelrpc.GossipType_BeaconBlockGossipType, downloader) - go gossipManager.Loop() - stageloop, err := stages.NewConsensusStagedSync(ctx, db, downloader, bdownloader, genesisCfg, beaconConfig, cpState, nil, false, tmpdir, executionClient, cfg.BeaconDataCfg) + forkChoice, err := forkchoice.NewForkChoiceStore(cpState, nil, true) + if err != nil { + log.Error("Could not start forkchoice service", "err", err) + return nil + } + gossipManager := network.NewGossipReceiver(ctx, s, forkChoice, beaconConfig, genesisCfg) + stageloop, err := stages.NewConsensusStagedSync(ctx, db, downloader, bdownloader, genesisCfg, beaconConfig, cpState, tmpdir, executionClient, cfg.BeaconDataCfg, gossipManager, forkChoice) if err != nil { return err } @@ -129,7 +142,7 @@ func startSentinel(cliCtx *cli.Context, cfg lcCli.ConsensusClientCliCfg, beaconS FinalizedEpoch: beaconState.FinalizedCheckpoint().Epoch, HeadSlot: beaconState.FinalizedCheckpoint().Epoch * cfg.BeaconCfg.SlotsPerEpoch, HeadRoot: beaconState.FinalizedCheckpoint().Root, - }, handshake.FullClientRule) + }) if err != nil { log.Error("Could not start sentinel", "err", err) return nil, err diff --git a/cmd/erigon-cl/network/beacon_downloader.go b/cmd/erigon-cl/network/beacon_downloader.go index d5633d58fb4..89a4e8b302c 100644 --- a/cmd/erigon-cl/network/beacon_downloader.go +++ b/cmd/erigon-cl/network/beacon_downloader.go @@ -2,12 +2,12 @@ package network import ( "sync" + "time" libcommon "github.com/ledgerwatch/erigon-lib/common" "golang.org/x/net/context" "github.com/ledgerwatch/erigon/cl/cltypes" - "github.com/ledgerwatch/erigon/cl/cltypes/ssz_utils" "github.com/ledgerwatch/erigon/cl/rpc" ) @@ -25,11 +25,8 @@ type ForwardBeaconDownloader struct { ctx context.Context highestSlotProcessed uint64 highestBlockRootProcessed libcommon.Hash - targetSlot uint64 rpc *rpc.BeaconRpcP2P process ProcessFn - isDownloading bool // Should be set to true to set the blocks to download - limitSegmentsLength int // Limit how many blocks we store in the downloader without processing segments []*cltypes.SignedBeaconBlock // Unprocessed downloaded segments mu sync.Mutex @@ -37,42 +34,12 @@ type ForwardBeaconDownloader struct { func NewForwardBeaconDownloader(ctx context.Context, rpc *rpc.BeaconRpcP2P) *ForwardBeaconDownloader { return &ForwardBeaconDownloader{ - ctx: ctx, - segments: []*cltypes.SignedBeaconBlock{}, - rpc: rpc, - isDownloading: false, + ctx: ctx, + segments: []*cltypes.SignedBeaconBlock{}, + rpc: rpc, } } -// Start begins the gossip listening process. -func (f *ForwardBeaconDownloader) ReceiveGossip(obj ssz_utils.Unmarshaler) { - signedBlock := obj.(*cltypes.SignedBeaconBlock) - if signedBlock.Block.ParentRoot == f.highestBlockRootProcessed { - f.addSegment(signedBlock) - } -} - -// SetIsDownloading sets isDownloading -func (f *ForwardBeaconDownloader) SetIsDownloading(isDownloading bool) { - f.mu.Lock() - defer f.mu.Unlock() - f.isDownloading = isDownloading -} - -// SetLimitSegmentsLength sets the segments limiter. -func (f *ForwardBeaconDownloader) SetLimitSegmentsLength(limitSegmentsLength int) { - f.mu.Lock() - defer f.mu.Unlock() - f.limitSegmentsLength = limitSegmentsLength -} - -// SetTargetSlot sets the target slot. -func (f *ForwardBeaconDownloader) SetTargetSlot(targetSlot uint64) { - f.mu.Lock() - defer f.mu.Unlock() - f.targetSlot = targetSlot -} - // SetProcessFunction sets the function used to process segments. func (f *ForwardBeaconDownloader) SetProcessFunction(fn ProcessFn) { f.mu.Lock() @@ -103,10 +70,6 @@ func (f *ForwardBeaconDownloader) HighestProcessedRoot() libcommon.Hash { // addSegment process new block segment. func (f *ForwardBeaconDownloader) addSegment(block *cltypes.SignedBeaconBlock) { - // Skip if it is not downloading or limit was reached - if !f.isDownloading || len(f.segments) >= f.limitSegmentsLength { - return - } f.mu.Lock() defer f.mu.Unlock() // Skip if does continue the segment. @@ -114,10 +77,12 @@ func (f *ForwardBeaconDownloader) addSegment(block *cltypes.SignedBeaconBlock) { } func (f *ForwardBeaconDownloader) RequestMore() { - count := uint64(64) + count := uint64(4) // dont need many responses, err := f.rpc.SendBeaconBlocksByRangeReq(f.highestSlotProcessed+1, count) if err != nil { + // Wait a bit in this case (we do not need to be super performant here). + time.Sleep(time.Second) return } for _, response := range responses { @@ -152,3 +117,7 @@ func (f *ForwardBeaconDownloader) GetHighestProcessedSlot() uint64 { defer f.mu.Unlock() return f.highestSlotProcessed } + +func (f *ForwardBeaconDownloader) Peers() (uint64, error) { + return f.rpc.Peers() +} diff --git a/cmd/erigon-cl/network/gossip_manager.go b/cmd/erigon-cl/network/gossip_manager.go index aadab8daac1..961a7446063 100644 --- a/cmd/erigon-cl/network/gossip_manager.go +++ b/cmd/erigon-cl/network/gossip_manager.go @@ -2,42 +2,42 @@ package network import ( "context" + "runtime" + libcommon "github.com/ledgerwatch/erigon-lib/common" + "github.com/ledgerwatch/erigon-lib/common/dbg" "github.com/ledgerwatch/erigon-lib/gointerfaces/sentinel" "github.com/ledgerwatch/erigon/cl/clparams" "github.com/ledgerwatch/erigon/cl/cltypes" - "github.com/ledgerwatch/erigon/cl/cltypes/ssz_utils" + "github.com/ledgerwatch/erigon/cl/cltypes/ssz" + "github.com/ledgerwatch/erigon/cl/utils" + "github.com/ledgerwatch/erigon/cmd/erigon-cl/forkchoice" "github.com/ledgerwatch/erigon/common" "github.com/ledgerwatch/log/v3" ) -type GossipReceiver interface { - ReceiveGossip(ssz_utils.Unmarshaler) -} - +// Gossip manager is sending all messages to fork choice or others type GossipManager struct { ctx context.Context - receivers map[sentinel.GossipType][]GossipReceiver - sentinel sentinel.SentinelClient + forkChoice *forkchoice.ForkChoiceStore + sentinel sentinel.SentinelClient + // configs + beaconConfig *clparams.BeaconChainConfig + genesisConfig *clparams.GenesisConfig } -func NewGossipReceiver(ctx context.Context, s sentinel.SentinelClient) *GossipManager { +func NewGossipReceiver(ctx context.Context, s sentinel.SentinelClient, forkChoice *forkchoice.ForkChoiceStore, beaconConfig *clparams.BeaconChainConfig, genesisConfig *clparams.GenesisConfig) *GossipManager { return &GossipManager{ - sentinel: s, - receivers: make(map[sentinel.GossipType][]GossipReceiver), - ctx: ctx, - } -} - -func (g *GossipManager) AddReceiver(t sentinel.GossipType, receiver GossipReceiver) { - if _, ok := g.receivers[t]; !ok { - g.receivers[t] = make([]GossipReceiver, 0) + sentinel: s, + forkChoice: forkChoice, + ctx: ctx, + beaconConfig: beaconConfig, + genesisConfig: genesisConfig, } - g.receivers[t] = append(g.receivers[t], receiver) } -func (g *GossipManager) Loop() { +func (g *GossipManager) Start() { subscription, err := g.sentinel.SubscribeGossip(g.ctx, &sentinel.EmptyMessage{}) if err != nil { return @@ -46,52 +46,109 @@ func (g *GossipManager) Loop() { for { data, err := subscription.Recv() if err != nil { - log.Warn("[Beacon Gossip] Failure in receiving", "err", err) + log.Debug("[Beacon Gossip] Failure in receiving", "err", err) continue } + + currentEpoch := utils.GetCurrentEpoch(g.genesisConfig.GenesisTime, g.beaconConfig.SecondsPerSlot, g.beaconConfig.SlotsPerEpoch) + version := g.beaconConfig.GetCurrentStateVersion(currentEpoch) + // Depending on the type of the received data, we create an instance of a specific type that implements the ObjectSSZ interface, // then attempts to deserialize the received data into it. - //If the deserialization fails, an error is logged and the loop continues to the next iteration. - //If the deserialization is successful, the object is set to the deserialized value and the loop continues to the next iteration. - receivers := g.receivers[data.Type] - var object ssz_utils.Unmarshaler + // If the deserialization fails, an error is logged and the loop continues to the next iteration. + // If the deserialization is successful, the object is set to the deserialized value and the loop continues to the next iteration. + var object ssz.Unmarshaler switch data.Type { case sentinel.GossipType_BeaconBlockGossipType: object = &cltypes.SignedBeaconBlock{} - if err := object.DecodeSSZWithVersion(common.CopyBytes(data.Data), int(clparams.BellatrixVersion)); err != nil { - log.Warn("[Beacon Gossip] Failure in decoding block", "err", err) + if err := object.DecodeSSZWithVersion(common.CopyBytes(data.Data), int(version)); err != nil { + log.Debug("[Beacon Gossip] Failure in decoding block", "err", err) + g.sentinel.BanPeer(g.ctx, data.Peer) + continue + } + block := object.(*cltypes.SignedBeaconBlock) + + currentSlotByTime := utils.GetCurrentSlot(g.genesisConfig.GenesisTime, g.beaconConfig.SecondsPerSlot) + maxGossipSlotThreshold := uint64(4) + // Skip if slot is too far behind. + if block.Block.Slot+maxGossipSlotThreshold < currentSlotByTime { + continue + } + if block.Block.Slot+maxGossipSlotThreshold == currentSlotByTime { + if _, err := g.sentinel.PublishGossip(g.ctx, data); err != nil { + log.Debug("cannot publish gossip", "err", err) + } + } + + log.Debug("Received block via gossip", "slot", block.Block.Slot) + + if err := g.forkChoice.OnBlock(block, true); err != nil { + log.Debug("[Beacon Gossip] Failure in processing block", "err", err) + continue + } + for _, attestation := range block.Block.Body.Attestations { + if err := g.forkChoice.OnAttestation(attestation, true); err != nil { + log.Debug("[Beacon Gossip] Failure in processing attestation", "err", err) + continue + } + } + + // Now check the head + headRoot, headSlot, err := g.forkChoice.GetHead() + if err != nil { + log.Debug("Could not fetch head data", "err", err) continue } + // Do forkchoice if possible + if g.forkChoice.Engine() != nil { + finalizedCheckpoint := g.forkChoice.FinalizedCheckpoint() + // Run forkchoice + if err := g.forkChoice.Engine().ForkChoiceUpdate( + g.forkChoice.GetEth1Hash(finalizedCheckpoint.Root), + g.forkChoice.GetEth1Hash(headRoot), + ); err != nil { + log.Warn("Could send not forkchoice", "err", err) + return + } + } + var m runtime.MemStats + dbg.ReadMemStats(&m) + // Log final result + log.Debug("New block imported", + "slot", block.Block.Slot, "head", headSlot, "headRoot", headRoot, + "alloc", libcommon.ByteCount(m.Alloc)) case sentinel.GossipType_VoluntaryExitGossipType: object = &cltypes.SignedVoluntaryExit{} - if err := object.DecodeSSZWithVersion(data.Data, int(clparams.BellatrixVersion)); err != nil { - log.Warn("[Beacon Gossip] Failure in decoding exit", "err", err) + if err := object.DecodeSSZWithVersion(data.Data, int(version)); err != nil { + log.Debug("[Beacon Gossip] Failure in decoding exit", "err", err) + g.sentinel.BanPeer(g.ctx, data.Peer) continue } case sentinel.GossipType_ProposerSlashingGossipType: object = &cltypes.ProposerSlashing{} - if err := object.DecodeSSZWithVersion(data.Data, int(clparams.BellatrixVersion)); err != nil { - log.Warn("[Beacon Gossip] Failure in decoding proposer slashing", "err", err) + if err := object.DecodeSSZWithVersion(data.Data, int(version)); err != nil { + log.Debug("[Beacon Gossip] Failure in decoding proposer slashing", "err", err) + g.sentinel.BanPeer(g.ctx, data.Peer) continue } case sentinel.GossipType_AttesterSlashingGossipType: object = &cltypes.AttesterSlashing{} - if err := object.DecodeSSZWithVersion(data.Data, int(clparams.BellatrixVersion)); err != nil { - log.Warn("[Beacon Gossip] Failure in decoding attester slashing", "err", err) + if err := object.DecodeSSZWithVersion(data.Data, int(version)); err != nil { + log.Debug("[Beacon Gossip] Failure in decoding attester slashing", "err", err) + g.sentinel.BanPeer(g.ctx, data.Peer) + continue + } + if err := g.forkChoice.OnAttesterSlashing(object.(*cltypes.AttesterSlashing)); err != nil { + log.Debug("[Beacon Gossip] Failure in processing block", "err", err) continue } case sentinel.GossipType_AggregateAndProofGossipType: object = &cltypes.SignedAggregateAndProof{} - if err := object.DecodeSSZWithVersion(data.Data, int(clparams.BellatrixVersion)); err != nil { - log.Warn("[Beacon Gossip] Failure in decoding proof", "err", err) + if err := object.DecodeSSZWithVersion(data.Data, int(version)); err != nil { + log.Debug("[Beacon Gossip] Failure in decoding proof", "err", err) + g.sentinel.BanPeer(g.ctx, data.Peer) continue } } - // If we received a valid object give it to our receiver - if object != nil { - for _, receiver := range receivers { - receiver.ReceiveGossip(object) - } - } } } diff --git a/cmd/erigon-cl/stages/stage_beacon_blocks.go b/cmd/erigon-cl/stages/stage_beacon_blocks.go deleted file mode 100644 index 3bf5a8bfa36..00000000000 --- a/cmd/erigon-cl/stages/stage_beacon_blocks.go +++ /dev/null @@ -1,183 +0,0 @@ -package stages - -import ( - "context" - "fmt" - "time" - - libcommon "github.com/ledgerwatch/erigon-lib/common" - "github.com/ledgerwatch/erigon-lib/kv" - "github.com/ledgerwatch/log/v3" - - "github.com/ledgerwatch/erigon/cl/clparams" - "github.com/ledgerwatch/erigon/cl/cltypes" - "github.com/ledgerwatch/erigon/cl/utils" - "github.com/ledgerwatch/erigon/cmd/erigon-cl/core/rawdb" - "github.com/ledgerwatch/erigon/cmd/erigon-cl/core/state" - "github.com/ledgerwatch/erigon/cmd/erigon-cl/execution_client" - "github.com/ledgerwatch/erigon/cmd/erigon-cl/network" - "github.com/ledgerwatch/erigon/eth/stagedsync" -) - -type StageBeaconsBlockCfg struct { - db kv.RwDB - downloader *network.ForwardBeaconDownloader - genesisCfg *clparams.GenesisConfig - beaconCfg *clparams.BeaconChainConfig - executionClient *execution_client.ExecutionClient - state *state.BeaconState -} - -func StageBeaconsBlock(db kv.RwDB, downloader *network.ForwardBeaconDownloader, genesisCfg *clparams.GenesisConfig, - beaconCfg *clparams.BeaconChainConfig, state *state.BeaconState, executionClient *execution_client.ExecutionClient) StageBeaconsBlockCfg { - return StageBeaconsBlockCfg{ - db: db, - downloader: downloader, - genesisCfg: genesisCfg, - beaconCfg: beaconCfg, - state: state, - executionClient: executionClient, - } -} - -// SpawnStageBeaconsForward spawn the beacon forward stage -func SpawnStageBeaconsBlocks(cfg StageBeaconsBlockCfg, s *stagedsync.StageState, tx kv.RwTx, ctx context.Context) error { - useExternalTx := tx != nil - var err error - if !useExternalTx { - tx, err = cfg.db.BeginRw(ctx) - if err != nil { - return err - } - defer tx.Rollback() - } - progress := s.BlockNumber - var lastRoot libcommon.Hash - if progress == 0 { - progress = cfg.state.LatestBlockHeader().Slot - lastRoot, err = cfg.state.BlockRoot() - } else { - lastRoot, err = rawdb.ReadFinalizedBlockRoot(tx, progress) - } - if err != nil { - return err - } - // Initialize payload insertion batch - executionPayloadInsertionBatch := execution_client.NewInsertBatch(cfg.executionClient) - - // We add one so that we wait for Gossiped blocks if we are on chain tip. - targetSlot := utils.GetCurrentSlot(cfg.genesisCfg.GenesisTime, cfg.beaconCfg.SecondsPerSlot) + 1 - - log.Info(fmt.Sprintf("[%s] Started", s.LogPrefix()), "start", progress, "target", targetSlot) - cfg.downloader.SetHighestProcessedSlot(progress) - if cfg.downloader.HighestProcessedRoot() == (libcommon.Hash{}) { - cfg.downloader.SetHighestProcessedRoot(lastRoot) - } - cfg.downloader.SetTargetSlot(targetSlot) - cfg.downloader.SetLimitSegmentsLength(1024) - // On new blocks we just check slot sequencing for now :) - cfg.downloader.SetProcessFunction(func( - highestSlotProcessed uint64, - highestRootProcessed libcommon.Hash, - newBlocks []*cltypes.SignedBeaconBlock) (newHighestSlotProcessed uint64, newHighestBlockRootProcessed libcommon.Hash, err error) { - // Setup - newHighestSlotProcessed = highestSlotProcessed - newHighestBlockRootProcessed = highestRootProcessed - // Skip if segment is empty - if len(newBlocks) == 0 { - return - } - // Retrieve last blocks to do reverse soft checks - var lastRootInSegment libcommon.Hash - lastBlockInSegment := newBlocks[len(newBlocks)-1] - lastSlotInSegment := lastBlockInSegment.Block.Slot - lastRootInSegment, err = lastBlockInSegment.Block.HashSSZ() - parentRoot := lastBlockInSegment.Block.ParentRoot - - if err != nil { - return - } - - for i := len(newBlocks) - 2; i >= 0; i-- { - var blockRoot libcommon.Hash - blockRoot, err = newBlocks[i].Block.HashSSZ() - if err != nil { - return - } - // Check if block root makes sense, if not segment is invalid - if blockRoot != parentRoot { - return - } - // Update the parent root. - parentRoot = newBlocks[i].Block.ParentRoot - if parentRoot == highestRootProcessed { - // We found a connection point? interrupt cycle and move on. - newBlocks = newBlocks[i:] - break - } - } - // If segment is not recconecting then skip. - if parentRoot != highestRootProcessed { - return - } - for _, block := range newBlocks { - if err = rawdb.WriteBeaconBlock(tx, block); err != nil { - return - } - var currentRoot libcommon.Hash - currentRoot, err = block.Block.HashSSZ() - if err != nil { - return - } - // Assume all of them are finalized - if err = rawdb.WriteFinalizedBlockRoot(tx, block.Block.Slot, currentRoot); err != nil { - return - } - if cfg.executionClient != nil && block.Version() >= clparams.BellatrixVersion { - if err = executionPayloadInsertionBatch.WriteExecutionPayload(block.Block.Body.ExecutionPayload); err != nil { - log.Warn("Could not send Execution Payload", "err", err) - } - } - } - - // Checks done, update all internals accordingly - return lastSlotInSegment, lastRootInSegment, nil - }) - cfg.downloader.SetIsDownloading(true) - logInterval := time.NewTicker(30 * time.Second) - defer logInterval.Stop() - triggerInterval := time.NewTicker(150 * time.Millisecond) - defer triggerInterval.Stop() - // Process blocks until we reach our target - for highestProcessed := cfg.downloader.GetHighestProcessedSlot(); targetSlot > highestProcessed; highestProcessed = cfg.downloader.GetHighestProcessedSlot() { - currentSlot := utils.GetCurrentSlot(cfg.genesisCfg.GenesisTime, cfg.beaconCfg.SecondsPerSlot) - // Send request every 50 Millisecond only if not on chain tip - if currentSlot != highestProcessed { - cfg.downloader.RequestMore() - } - - if err := cfg.downloader.ProcessBlocks(); err != nil { - return err - } - select { - case <-logInterval.C: - log.Info(fmt.Sprintf("[%s] Processed and collected blocks", s.LogPrefix()), "slot", cfg.downloader.GetHighestProcessedSlot()) - case <-triggerInterval.C: - } - } - // Flush inserted payloads to execution client - if err := executionPayloadInsertionBatch.Flush(); err != nil { - return err - } - - log.Info(fmt.Sprintf("[%s] Processed and collected blocks", s.LogPrefix()), "count", targetSlot-progress) - if err := s.Update(tx, cfg.downloader.GetHighestProcessedSlot()); err != nil { - return err - } - if !useExternalTx { - if err = tx.Commit(); err != nil { - return err - } - } - return nil -} diff --git a/cmd/erigon-cl/stages/stage_fork_choice.go b/cmd/erigon-cl/stages/stage_fork_choice.go new file mode 100644 index 00000000000..31ffd4cee76 --- /dev/null +++ b/cmd/erigon-cl/stages/stage_fork_choice.go @@ -0,0 +1,173 @@ +package stages + +import ( + "context" + "runtime" + "time" + + libcommon "github.com/ledgerwatch/erigon-lib/common" + "github.com/ledgerwatch/erigon-lib/common/dbg" + "github.com/ledgerwatch/erigon-lib/kv" + "github.com/ledgerwatch/log/v3" + + "github.com/ledgerwatch/erigon/cl/clparams" + "github.com/ledgerwatch/erigon/cl/cltypes" + "github.com/ledgerwatch/erigon/cl/utils" + "github.com/ledgerwatch/erigon/cmd/erigon-cl/core/state" + "github.com/ledgerwatch/erigon/cmd/erigon-cl/execution_client" + "github.com/ledgerwatch/erigon/cmd/erigon-cl/forkchoice" + "github.com/ledgerwatch/erigon/cmd/erigon-cl/network" + "github.com/ledgerwatch/erigon/eth/stagedsync" +) + +type StageForkChoiceCfg struct { + db kv.RwDB + downloader *network.ForwardBeaconDownloader + genesisCfg *clparams.GenesisConfig + beaconCfg *clparams.BeaconChainConfig + executionClient *execution_client.ExecutionClient + state *state.BeaconState + gossipManager *network.GossipManager + forkChoice *forkchoice.ForkChoiceStore +} + +func StageForkChoice(db kv.RwDB, downloader *network.ForwardBeaconDownloader, genesisCfg *clparams.GenesisConfig, + beaconCfg *clparams.BeaconChainConfig, state *state.BeaconState, executionClient *execution_client.ExecutionClient, gossipManager *network.GossipManager, forkChoice *forkchoice.ForkChoiceStore) StageForkChoiceCfg { + return StageForkChoiceCfg{ + db: db, + downloader: downloader, + genesisCfg: genesisCfg, + beaconCfg: beaconCfg, + state: state, + executionClient: executionClient, + gossipManager: gossipManager, + forkChoice: forkChoice, + } +} + +// StageForkChoice enables the fork choice state. it is never supposed to exit this stage once it gets in. +func SpawnStageForkChoice(cfg StageForkChoiceCfg, s *stagedsync.StageState, tx kv.RwTx, ctx context.Context) error { + /*useExternalTx := tx != nil + var err error + if !useExternalTx { + tx, err = cfg.db.BeginRw(ctx) + if err != nil { + return err + } + defer tx.Rollback() + }*/ + // Start download service + log.Info("Started Ethereum 2.0 Gossip Service") + // We start gossip management. + go cfg.gossipManager.Start() + go onTickService(ctx, cfg) + go func() { + logIntervalPeers := time.NewTicker(1 * time.Minute) + for { + select { + case <-logIntervalPeers.C: + if peerCount, err := cfg.downloader.Peers(); err == nil { + log.Info("[Caplin] P2P", "peers", peerCount) + + } + case <-ctx.Done(): + return + } + + } + }() + startDownloadService(s, cfg) + /*if !useExternalTx { + if err = tx.Commit(); err != nil { + return err + } + }*/ + return nil +} + +func startDownloadService(s *stagedsync.StageState, cfg StageForkChoiceCfg) { + cfg.downloader.SetHighestProcessedRoot(libcommon.Hash{}) + cfg.downloader.SetHighestProcessedSlot(cfg.state.Slot()) + cfg.downloader.SetProcessFunction(func(highestSlotProcessed uint64, _ libcommon.Hash, newBlocks []*cltypes.SignedBeaconBlock) (uint64, libcommon.Hash, error) { + for _, block := range newBlocks { + sendForckchoice := + utils.GetCurrentSlot(cfg.genesisCfg.GenesisTime, cfg.beaconCfg.SecondsPerSlot) == block.Block.Slot + if err := cfg.forkChoice.OnBlock(block, true); err != nil { + log.Warn("Could not download block", "reason", err) + return highestSlotProcessed, libcommon.Hash{}, nil + } + if sendForckchoice { + // Import the head + headRoot, headSlot, err := cfg.forkChoice.GetHead() + if err != nil { + log.Debug("Could not fetch head data", "err", err) + continue + } + var m runtime.MemStats + dbg.ReadMemStats(&m) + log.Debug("New block imported", + "slot", block.Block.Slot, "head", headSlot, "headRoot", headRoot, + "alloc", libcommon.ByteCount(m.Alloc)) + + // Do forkchoice if possible + if cfg.forkChoice.Engine() != nil { + finalizedCheckpoint := cfg.forkChoice.FinalizedCheckpoint() + // Run forkchoice + if err := cfg.forkChoice.Engine().ForkChoiceUpdate( + cfg.forkChoice.GetEth1Hash(finalizedCheckpoint.Root), + cfg.forkChoice.GetEth1Hash(headRoot), + ); err != nil { + log.Warn("Could send not forkchoice", "err", err) + } + } + } + highestSlotProcessed = utils.Max64(block.Block.Slot, highestSlotProcessed) + } + // Checks done, update all internals accordingly + return highestSlotProcessed, libcommon.Hash{}, nil + }) + maxBlockBehindBeforeDownload := int64(5) + firstTime := true + + for { + targetSlot := utils.GetCurrentSlot(cfg.genesisCfg.GenesisTime, cfg.beaconCfg.SecondsPerSlot) + if targetSlot == cfg.forkChoice.HighestSeen() { + time.Sleep(time.Second) + continue + } + // if not the first time then send back the downloader a little bit. + if !firstTime { + cfg.downloader.SetHighestProcessedRoot(libcommon.Hash{}) + cfg.downloader.SetHighestProcessedSlot(cfg.forkChoice.HighestSeen() - uint64(maxBlockBehindBeforeDownload)) + } + // Wait small time + time.Sleep(100 * time.Millisecond) + firstTime = false + log.Debug("Caplin has missed some slots, started downloading chain") + // Process blocks until we reach our target + for highestProcessed := cfg.downloader.GetHighestProcessedSlot(); utils.GetCurrentSlot(cfg.genesisCfg.GenesisTime, cfg.beaconCfg.SecondsPerSlot) > highestProcessed; highestProcessed = cfg.downloader.GetHighestProcessedSlot() { + currentSlot := utils.GetCurrentSlot(cfg.genesisCfg.GenesisTime, cfg.beaconCfg.SecondsPerSlot) + // Send request every 50 Millisecond only if not on chain tip + if currentSlot != highestProcessed { + cfg.downloader.RequestMore() + } + + if err := cfg.downloader.ProcessBlocks(); err != nil { + log.Warn("Could not download block in processing", "reason", err) + } + } + log.Debug("Finished catching up", "slot", cfg.downloader.GetHighestProcessedSlot()) + } +} + +func onTickService(ctx context.Context, cfg StageForkChoiceCfg) { + tickInterval := time.NewTicker(50 * time.Millisecond) + for { + select { + case <-tickInterval.C: + cfg.forkChoice.OnTick(uint64(time.Now().Unix())) + case <-ctx.Done(): + return + } + } +} diff --git a/cmd/erigon-cl/stages/stages.go b/cmd/erigon-cl/stages/stages.go index b5264b11f54..01356fe1109 100644 --- a/cmd/erigon-cl/stages/stages.go +++ b/cmd/erigon-cl/stages/stages.go @@ -8,13 +8,14 @@ import ( "github.com/ledgerwatch/erigon/cmd/erigon-cl/core/rawdb" "github.com/ledgerwatch/erigon/cmd/erigon-cl/core/state" "github.com/ledgerwatch/erigon/cmd/erigon-cl/execution_client" + "github.com/ledgerwatch/erigon/cmd/erigon-cl/forkchoice" "github.com/ledgerwatch/erigon/cmd/erigon-cl/network" "github.com/ledgerwatch/erigon/eth/stagedsync" "github.com/ledgerwatch/erigon/eth/stagedsync/stages" ) // StateStages are all stages necessary for basic unwind and stage computation, it is primarly used to process side forks and memory execution. -func ConsensusStages(ctx context.Context, historyReconstruction StageHistoryReconstructionCfg, beaconsBlocks StageBeaconsBlockCfg, beaconState StageBeaconStateCfg) []*stagedsync.Stage { +func ConsensusStages(ctx context.Context, historyReconstruction StageHistoryReconstructionCfg, beaconState StageBeaconStateCfg, forkchoice StageForkChoiceCfg) []*stagedsync.Stage { return []*stagedsync.Stage{ { ID: stages.BeaconHistoryReconstruction, @@ -27,20 +28,20 @@ func ConsensusStages(ctx context.Context, historyReconstruction StageHistoryReco }, }, { - ID: stages.BeaconBlocks, - Description: "Download beacon blocks forward.", + ID: stages.BeaconState, + Description: "Execute Consensus Layer transition", Forward: func(firstCycle bool, badBlockUnwind bool, s *stagedsync.StageState, u stagedsync.Unwinder, tx kv.RwTx, quiet bool) error { - return SpawnStageBeaconsBlocks(beaconsBlocks, s, tx, ctx) + return SpawnStageBeaconState(beaconState, tx, ctx) }, Unwind: func(firstCycle bool, u *stagedsync.UnwindState, s *stagedsync.StageState, tx kv.RwTx) error { return nil }, }, { - ID: stages.BeaconState, - Description: "Execute Consensus Layer transition", + ID: stages.BeaconBlocks, + Description: "Download beacon blocks forward.", Forward: func(firstCycle bool, badBlockUnwind bool, s *stagedsync.StageState, u stagedsync.Unwinder, tx kv.RwTx, quiet bool) error { - return SpawnStageBeaconState(beaconState, s, tx, ctx) + return SpawnStageForkChoice(forkchoice, s, tx, ctx) }, Unwind: func(firstCycle bool, u *stagedsync.UnwindState, s *stagedsync.StageState, tx kv.RwTx) error { return nil @@ -66,18 +67,18 @@ func NewConsensusStagedSync(ctx context.Context, genesisCfg *clparams.GenesisConfig, beaconCfg *clparams.BeaconChainConfig, state *state.BeaconState, - triggerExecution triggerExecutionFunc, - clearEth1Data bool, tmpdir string, executionClient *execution_client.ExecutionClient, beaconDBCfg *rawdb.BeaconDataConfig, + gossipManager *network.GossipManager, + forkChoice *forkchoice.ForkChoiceStore, ) (*stagedsync.Sync, error) { return stagedsync.New( ConsensusStages( ctx, StageHistoryReconstruction(db, backwardDownloader, genesisCfg, beaconCfg, beaconDBCfg, state, tmpdir, executionClient), - StageBeaconsBlock(db, forwardDownloader, genesisCfg, beaconCfg, state, executionClient), - StageBeaconState(db, genesisCfg, beaconCfg, state, triggerExecution, clearEth1Data, executionClient), + StageBeaconState(db, beaconCfg, state, executionClient), + StageForkChoice(db, forwardDownloader, genesisCfg, beaconCfg, state, executionClient, gossipManager, forkChoice), ), ConsensusUnwindOrder, ConsensusPruneOrder, diff --git a/cmd/erigon-cl/stages/stages_beacon_state.go b/cmd/erigon-cl/stages/stages_beacon_state.go index 57583401982..a61d6e718ff 100644 --- a/cmd/erigon-cl/stages/stages_beacon_state.go +++ b/cmd/erigon-cl/stages/stages_beacon_state.go @@ -2,51 +2,44 @@ package stages import ( "context" - "fmt" libcommon "github.com/ledgerwatch/erigon-lib/common" "github.com/ledgerwatch/erigon-lib/kv" - "github.com/ledgerwatch/erigon-lib/kv/kvcfg" "github.com/ledgerwatch/erigon/cl/clparams" - "github.com/ledgerwatch/erigon/cl/cltypes" "github.com/ledgerwatch/erigon/cl/utils" "github.com/ledgerwatch/erigon/cmd/erigon-cl/core/rawdb" "github.com/ledgerwatch/erigon/cmd/erigon-cl/core/state" "github.com/ledgerwatch/erigon/cmd/erigon-cl/core/transition" "github.com/ledgerwatch/erigon/cmd/erigon-cl/execution_client" - "github.com/ledgerwatch/erigon/eth/stagedsync" "github.com/ledgerwatch/erigon/eth/stagedsync/stages" "github.com/ledgerwatch/log/v3" ) -// This function will trigger block execution, hence: insert + validate + fcu. -type triggerExecutionFunc func(*cltypes.SignedBeaconBlock) error - type StageBeaconStateCfg struct { - db kv.RwDB - genesisCfg *clparams.GenesisConfig - beaconCfg *clparams.BeaconChainConfig - state *state.BeaconState - clearEth1Data bool // Whether we want to discard eth1 data. - triggerExecution triggerExecutionFunc - executionClient *execution_client.ExecutionClient + db kv.RwDB + beaconCfg *clparams.BeaconChainConfig + state *state.BeaconState + executionClient *execution_client.ExecutionClient + enabled bool } -func StageBeaconState(db kv.RwDB, genesisCfg *clparams.GenesisConfig, - beaconCfg *clparams.BeaconChainConfig, state *state.BeaconState, triggerExecution triggerExecutionFunc, clearEth1Data bool, executionClient *execution_client.ExecutionClient) StageBeaconStateCfg { +func StageBeaconState(db kv.RwDB, + beaconCfg *clparams.BeaconChainConfig, state *state.BeaconState, executionClient *execution_client.ExecutionClient) StageBeaconStateCfg { return StageBeaconStateCfg{ - db: db, - genesisCfg: genesisCfg, - beaconCfg: beaconCfg, - state: state, - clearEth1Data: clearEth1Data, - triggerExecution: triggerExecution, - executionClient: executionClient, + db: db, + beaconCfg: beaconCfg, + state: state, + executionClient: executionClient, + enabled: false, } } -// SpawnStageBeaconForward spawn the beacon forward stage -func SpawnStageBeaconState(cfg StageBeaconStateCfg, s *stagedsync.StageState, tx kv.RwTx, ctx context.Context) error { +// SpawnStageBeaconState is used to replay historical states +func SpawnStageBeaconState(cfg StageBeaconStateCfg, tx kv.RwTx, ctx context.Context) error { + if !cfg.enabled { + return nil + } + // This code need to be fixed. useExternalTx := tx != nil var err error if !useExternalTx { @@ -77,59 +70,23 @@ func SpawnStageBeaconState(cfg StageBeaconStateCfg, s *stagedsync.StageState, tx if err != nil { return err } - // TODO: Pass this to state transition with the state - if cfg.executionClient != nil { + + // Query execution engine only if the payload have an hash. + if eth1Hash != (libcommon.Hash{}) { if block.Block.Body.ExecutionPayload, err = cfg.executionClient.ReadExecutionPayload(eth1Number, eth1Hash); err != nil { return err } - // validate fully only in current epoch. - fullValidate := utils.GetCurrentEpoch(cfg.genesisCfg.GenesisTime, cfg.beaconCfg.SecondsPerSlot, cfg.beaconCfg.SlotsPerEpoch) == cfg.state.Epoch() - if err := transition.TransitionState(cfg.state, block, fullValidate); err != nil { - log.Info("Found epoch, so stopping now...", "count", slot-(fromSlot+1), "slot", slot) - return err - } - log.Info("Applied state transition", "from", slot, "to", slot+1) - } - } - // If successful update fork choice - if cfg.executionClient != nil { - finalizedRoot, err := rawdb.ReadFinalizedBlockRoot(tx, endSlot) - if err != nil { - return err - } - _, _, eth1Hash, _, err := rawdb.ReadBeaconBlockForStorage(tx, finalizedRoot, endSlot) - if err != nil { - return err - } - receipt, err := cfg.executionClient.ForkChoiceUpdate(eth1Hash) - if err != nil { - return err - } - log.Info("Forkchoice Status", "outcome", receipt.Success) - } - - // Clear all ETH1 data from CL db - if cfg.clearEth1Data { - if err := tx.ClearBucket(kv.Headers); err != nil { - return err - } - if err := tx.ClearBucket(kv.BlockBody); err != nil { - return err - } - ethTx := kv.EthTx - transactionsV3, _ := kvcfg.TransactionsV3.Enabled(tx) - if transactionsV3 { - ethTx = kv.EthTxV3 - } - if err := tx.ClearBucket(ethTx); err != nil { - return err } - if err := tx.ClearBucket(kv.Sequence); err != nil { + // validate fully only in current epoch. + fullValidate := utils.GetCurrentEpoch(cfg.state.GenesisTime(), cfg.beaconCfg.SecondsPerSlot, cfg.beaconCfg.SlotsPerEpoch) == cfg.state.Epoch() + if err := transition.TransitionState(cfg.state, block, fullValidate); err != nil { + log.Info("Found epoch, so stopping now...", "count", slot-(fromSlot+1), "slot", slot) return err } + log.Info("Applied state transition", "from", slot, "to", slot+1) } - log.Info(fmt.Sprintf("[%s] Finished transitioning state", s.LogPrefix()), "from", fromSlot, "to", endSlot) + log.Info("[BeaconState] Finished transitioning state", "from", fromSlot, "to", endSlot) if !useExternalTx { if err = tx.Commit(); err != nil { return err diff --git a/cmd/erigon-el/backend/backend.go b/cmd/erigon-el/backend/backend.go index 3a8f837d72a..324cb74e121 100644 --- a/cmd/erigon-el/backend/backend.go +++ b/cmd/erigon-el/backend/backend.go @@ -16,6 +16,12 @@ import ( "github.com/c2h5oh/datasize" "github.com/holiman/uint256" + "github.com/ledgerwatch/log/v3" + "golang.org/x/exp/slices" + "google.golang.org/grpc" + "google.golang.org/grpc/credentials" + "google.golang.org/protobuf/types/known/emptypb" + "github.com/ledgerwatch/erigon-lib/chain" libcommon "github.com/ledgerwatch/erigon-lib/common" "github.com/ledgerwatch/erigon-lib/common/datadir" @@ -39,17 +45,6 @@ import ( txpool2 "github.com/ledgerwatch/erigon-lib/txpool" "github.com/ledgerwatch/erigon-lib/txpool/txpooluitl" types2 "github.com/ledgerwatch/erigon-lib/types" - "github.com/ledgerwatch/erigon/core/systemcontracts" - "github.com/ledgerwatch/log/v3" - "golang.org/x/exp/slices" - "google.golang.org/grpc" - "google.golang.org/grpc/credentials" - "google.golang.org/protobuf/types/known/emptypb" - - "github.com/ledgerwatch/erigon/core/state/historyv2read" - "github.com/ledgerwatch/erigon/core/types/accounts" - "github.com/ledgerwatch/erigon/p2p/dnsdisc" - "github.com/ledgerwatch/erigon/p2p/enode" "github.com/ledgerwatch/erigon/cmd/erigon-el/eth1" stages3 "github.com/ledgerwatch/erigon/cmd/erigon-el/stages" @@ -65,8 +60,11 @@ import ( "github.com/ledgerwatch/erigon/consensus/serenity" "github.com/ledgerwatch/erigon/core" "github.com/ledgerwatch/erigon/core/rawdb" + "github.com/ledgerwatch/erigon/core/state/historyv2read" "github.com/ledgerwatch/erigon/core/state/temporal" + "github.com/ledgerwatch/erigon/core/systemcontracts" "github.com/ledgerwatch/erigon/core/types" + "github.com/ledgerwatch/erigon/core/types/accounts" "github.com/ledgerwatch/erigon/core/vm" "github.com/ledgerwatch/erigon/crypto" "github.com/ledgerwatch/erigon/eth/ethconfig" @@ -79,6 +77,8 @@ import ( "github.com/ledgerwatch/erigon/ethstats" "github.com/ledgerwatch/erigon/node" "github.com/ledgerwatch/erigon/p2p" + "github.com/ledgerwatch/erigon/p2p/dnsdisc" + "github.com/ledgerwatch/erigon/p2p/enode" "github.com/ledgerwatch/erigon/params" "github.com/ledgerwatch/erigon/rpc" "github.com/ledgerwatch/erigon/turbo/engineapi" @@ -172,7 +172,7 @@ func NewBackend(stack *node.Node, config *ethconfig.Config, logger log.Logger) ( } // Assemble the Ethereum object - chainKv, err := node.OpenDatabase(stack.Config(), logger, kv.ChainDB) + chainKv, err := node.OpenDatabase(stack.Config(), kv.ChainDB) if err != nil { return nil, err } @@ -256,7 +256,6 @@ func NewBackend(stack *node.Node, config *ethconfig.Config, logger log.Logger) ( sentryCtx: ctx, sentryCancel: ctxCancel, config: config, - log: logger, chainDB: chainKv, networkID: config.NetworkID, etherbase: config.Miner.Etherbase, @@ -418,7 +417,6 @@ func NewBackend(stack *node.Node, config *ethconfig.Config, logger log.Logger) ( if chainConfig.Clique != nil { consensusConfig = &config.Clique } else if chainConfig.Aura != nil { - config.Aura.Etherbase = config.Miner.Etherbase consensusConfig = &config.Aura } else if chainConfig.Parlia != nil { consensusConfig = &config.Parlia @@ -427,7 +425,7 @@ func NewBackend(stack *node.Node, config *ethconfig.Config, logger log.Logger) ( } else { consensusConfig = &config.Ethash } - backend.engine = ethconsensusconfig.CreateConsensusEngine(chainConfig, logger, consensusConfig, config.Miner.Notify, config.Miner.Noverify, config.HeimdallgRPCAddress, config.HeimdallURL, config.WithoutHeimdall, stack.DataDir(), allSnapshots, false /* readonly */, backend.chainDB) + backend.engine = ethconsensusconfig.CreateConsensusEngine(chainConfig, consensusConfig, config.Miner.Notify, config.Miner.Noverify, config.HeimdallgRPCAddress, config.HeimdallURL, config.WithoutHeimdall, stack.DataDir(), allSnapshots, false /* readonly */, backend.chainDB) backend.forkValidator = engineapi.NewForkValidator(currentBlockNumber, inMemoryExecution, tmpdir) if err != nil { @@ -446,6 +444,7 @@ func NewBackend(stack *node.Node, config *ethconfig.Config, logger log.Logger) ( backend.blockReader, stack.Config().SentryLogPeerInfo, backend.forkValidator, + config.DropUselessPeers, ) if err != nil { return nil, err diff --git a/cmd/erigon-el/main.go b/cmd/erigon-el/main.go index 30b89cb98f4..0c915999100 100644 --- a/cmd/erigon-el/main.go +++ b/cmd/erigon-el/main.go @@ -52,15 +52,15 @@ func runErigon(cliCtx *cli.Context) error { } } - logger := logging.GetLoggerCtx("erigon", cliCtx) + logging.SetupLoggerCtx("erigon", cliCtx) // initializing the node and providing the current git commit there - logger.Info("Build info", "git_branch", params.GitBranch, "git_tag", params.GitTag, "git_commit", params.GitCommit) + log.Info("Build info", "git_branch", params.GitBranch, "git_tag", params.GitTag, "git_commit", params.GitCommit) nodeCfg := node.NewNodConfigUrfave(cliCtx) ethCfg := node.NewEthConfigUrfave(cliCtx, nodeCfg) - ethNode, err := backend.NewNode(nodeCfg, ethCfg, logger) + ethNode, err := backend.NewNode(nodeCfg, ethCfg, log.Root()) if err != nil { log.Error("Erigon startup", "err", err) return err diff --git a/cmd/erigon/main.go b/cmd/erigon/main.go index 6fede0ef395..432bcb0f437 100644 --- a/cmd/erigon/main.go +++ b/cmd/erigon/main.go @@ -18,7 +18,6 @@ import ( "github.com/ledgerwatch/erigon/params" erigonapp "github.com/ledgerwatch/erigon/turbo/app" erigoncli "github.com/ledgerwatch/erigon/turbo/cli" - "github.com/ledgerwatch/erigon/turbo/logging" "github.com/ledgerwatch/erigon/turbo/node" ) @@ -51,15 +50,13 @@ func runErigon(cliCtx *cli.Context) error { } } - logger := logging.GetLoggerCtx("erigon", cliCtx) - // initializing the node and providing the current git commit there - logger.Info("Build info", "git_branch", params.GitBranch, "git_tag", params.GitTag, "git_commit", params.GitCommit) + log.Info("Build info", "git_branch", params.GitBranch, "git_tag", params.GitTag, "git_commit", params.GitCommit) nodeCfg := node.NewNodConfigUrfave(cliCtx) ethCfg := node.NewEthConfigUrfave(cliCtx, nodeCfg) - ethNode, err := node.New(nodeCfg, ethCfg, logger) + ethNode, err := node.New(nodeCfg, ethCfg) if err != nil { log.Error("Erigon startup", "err", err) return err diff --git a/cmd/evm/internal/t8ntool/execution.go b/cmd/evm/internal/t8ntool/execution.go index 559fed975ca..c8e0292dab7 100644 --- a/cmd/evm/internal/t8ntool/execution.go +++ b/cmd/evm/internal/t8ntool/execution.go @@ -48,6 +48,7 @@ type stEnv struct { Coinbase libcommon.Address `json:"currentCoinbase" gencodec:"required"` Difficulty *big.Int `json:"currentDifficulty"` Random *big.Int `json:"currentRandom"` + MixDigest libcommon.Hash `json:"mixHash,omitempty"` ParentDifficulty *big.Int `json:"parentDifficulty"` GasLimit uint64 `json:"currentGasLimit" gencodec:"required"` Number uint64 `json:"currentNumber" gencodec:"required"` @@ -57,7 +58,9 @@ type stEnv struct { Ommers []ommer `json:"ommers,omitempty"` BaseFee *big.Int `json:"currentBaseFee,omitempty"` ParentUncleHash libcommon.Hash `json:"parentUncleHash"` + UncleHash libcommon.Hash `json:"uncleHash,omitempty"` Withdrawals []*types.Withdrawal `json:"withdrawals,omitempty"` + WithdrawalsHash *libcommon.Hash `json:"withdrawalsRoot,omitempty"` } type stEnvMarshaling struct { diff --git a/cmd/evm/internal/t8ntool/flags.go b/cmd/evm/internal/t8ntool/flags.go index bcef839dd50..3a42f32e542 100644 --- a/cmd/evm/internal/t8ntool/flags.go +++ b/cmd/evm/internal/t8ntool/flags.go @@ -99,7 +99,7 @@ var ( "\n\tSyntax (+ExtraEip)", strings.Join(tests.AvailableForks(), "\n\t "), strings.Join(vm.ActivateableEips(), ", ")), - Value: "ArrowGlacier", + Value: "Merge", } VerbosityFlag = cli.IntFlag{ Name: "verbosity", diff --git a/cmd/evm/internal/t8ntool/gen_stenv.go b/cmd/evm/internal/t8ntool/gen_stenv.go index bf84cc3c7bf..7f08b6a3735 100644 --- a/cmd/evm/internal/t8ntool/gen_stenv.go +++ b/cmd/evm/internal/t8ntool/gen_stenv.go @@ -11,6 +11,7 @@ import ( "github.com/ledgerwatch/erigon/common" "github.com/ledgerwatch/erigon/common/math" + "github.com/ledgerwatch/erigon/core/types" ) var _ = (*stEnvMarshaling)(nil) @@ -30,6 +31,8 @@ func (s stEnv) MarshalJSON() ([]byte, error) { Ommers []ommer `json:"ommers,omitempty"` BaseFee *math.HexOrDecimal256 `json:"currentBaseFee,omitempty"` ParentUncleHash libcommon.Hash `json:"parentUncleHash"` + UncleHash libcommon.Hash `json:"uncleHash,omitempty"` + Withdrawals []*types.Withdrawal `json:"withdrawals,omitempty"` } var enc stEnv enc.Coinbase = common.UnprefixedAddress(s.Coinbase) @@ -44,6 +47,8 @@ func (s stEnv) MarshalJSON() ([]byte, error) { enc.Ommers = s.Ommers enc.BaseFee = (*math.HexOrDecimal256)(s.BaseFee) enc.ParentUncleHash = s.ParentUncleHash + enc.UncleHash = s.UncleHash + enc.Withdrawals = s.Withdrawals return json.Marshal(&enc) } @@ -62,6 +67,8 @@ func (s *stEnv) UnmarshalJSON(input []byte) error { Ommers []ommer `json:"ommers,omitempty"` BaseFee *math.HexOrDecimal256 `json:"currentBaseFee,omitempty"` ParentUncleHash *libcommon.Hash `json:"parentUncleHash"` + UncleHash libcommon.Hash `json:"uncleHash,omitempty"` + Withdrawals []*types.Withdrawal `json:"withdrawals,omitempty"` } var dec stEnv if err := json.Unmarshal(input, &dec); err != nil { @@ -107,5 +114,10 @@ func (s *stEnv) UnmarshalJSON(input []byte) error { if dec.ParentUncleHash != nil { s.ParentUncleHash = *dec.ParentUncleHash } + s.UncleHash = dec.UncleHash + if dec.Withdrawals != nil { + s.Withdrawals = dec.Withdrawals + } + return nil } diff --git a/cmd/evm/internal/t8ntool/transition.go b/cmd/evm/internal/t8ntool/transition.go index d0dd21f46bc..16da940872c 100644 --- a/cmd/evm/internal/t8ntool/transition.go +++ b/cmd/evm/internal/t8ntool/transition.go @@ -28,20 +28,22 @@ import ( "path/filepath" "github.com/holiman/uint256" + "github.com/ledgerwatch/log/v3" + "github.com/urfave/cli/v2" + "github.com/ledgerwatch/erigon-lib/chain" libcommon "github.com/ledgerwatch/erigon-lib/common" + "github.com/ledgerwatch/erigon-lib/common/hexutility" "github.com/ledgerwatch/erigon-lib/common/length" "github.com/ledgerwatch/erigon-lib/kv" "github.com/ledgerwatch/erigon-lib/kv/kvcfg" "github.com/ledgerwatch/erigon-lib/kv/memdb" - "github.com/ledgerwatch/log/v3" - "github.com/urfave/cli/v2" "github.com/ledgerwatch/erigon/cmd/rpcdaemon/commands" "github.com/ledgerwatch/erigon/common" - "github.com/ledgerwatch/erigon/common/hexutil" "github.com/ledgerwatch/erigon/common/math" "github.com/ledgerwatch/erigon/consensus/ethash" + "github.com/ledgerwatch/erigon/consensus/serenity" "github.com/ledgerwatch/erigon/core" "github.com/ledgerwatch/erigon/core/state" "github.com/ledgerwatch/erigon/core/types" @@ -231,18 +233,28 @@ func Main(ctx *cli.Context) error { if prestate.Env.BaseFee == nil { return NewError(ErrorVMConfig, errors.New("EIP-1559 config but missing 'currentBaseFee' in env section")) } - } - - // Sanity check, to not `panic` in state_transition - if prestate.Env.Random != nil && !eip1559 { - return NewError(ErrorVMConfig, errors.New("can only apply RANDOM on top of London chain rules")) + } else { + prestate.Env.Random = nil } if chainConfig.IsShanghai(prestate.Env.Timestamp) && prestate.Env.Withdrawals == nil { return NewError(ErrorVMConfig, errors.New("Shanghai config but missing 'withdrawals' in env section")) } - if env := prestate.Env; env.Difficulty == nil { + isMerged := chainConfig.TerminalTotalDifficulty != nil && chainConfig.TerminalTotalDifficulty.BitLen() == 0 + env := prestate.Env + if isMerged { + // post-merge: + // - random must be supplied + // - difficulty must be zero + switch { + case env.Random == nil: + return NewError(ErrorVMConfig, errors.New("post-merge requires currentRandom to be defined in env")) + case env.Difficulty != nil && env.Difficulty.BitLen() != 0: + return NewError(ErrorVMConfig, errors.New("post-merge difficulty must be zero (or omitted) in env")) + } + prestate.Env.Difficulty = nil + } else if env.Difficulty == nil { // If difficulty was not provided by caller, we need to calculate it. switch { case env.ParentDifficulty == nil: @@ -282,6 +294,7 @@ func Main(ctx *cli.Context) error { return h } db := memdb.New("" /* tmpDir */) + defer db.Close() tx, err := db.BeginRw(context.Background()) if err != nil { @@ -290,9 +303,11 @@ func Main(ctx *cli.Context) error { defer tx.Rollback() reader, writer := MakePreState(chainConfig.Rules(0, 0), tx, prestate.Pre) - engine := ethash.NewFaker() + // serenity engine can be used for pre-merge blocks as well, as it + // redirects to the ethash engine based on the block number + engine := serenity.New(ðash.FakeEthash{}) - result, err := core.ExecuteBlockEphemerally(chainConfig, &vmConfig, getHash, engine, block, reader, writer, nil, nil, getTracer) + result, err := core.ExecuteBlockEphemerally(chainConfig, &vmConfig, getHash, engine, block, reader, writer, nil, getTracer) if hashError != nil { return NewError(ErrorMissingBlockhash, fmt.Errorf("blockhash error: %v", err)) @@ -525,7 +540,7 @@ func saveFile(baseDir, filename string, data interface{}) error { // dispatchOutput writes the output data to either stderr or stdout, or to the specified // files -func dispatchOutput(ctx *cli.Context, baseDir string, result *core.EphemeralExecResult, alloc Alloc, body hexutil.Bytes) error { +func dispatchOutput(ctx *cli.Context, baseDir string, result *core.EphemeralExecResult, alloc Alloc, body hexutility.Bytes) error { stdOutObject := make(map[string]interface{}) stdErrObject := make(map[string]interface{}) dispatch := func(baseDir, fName, name string, obj interface{}) error { @@ -571,13 +586,16 @@ func dispatchOutput(ctx *cli.Context, baseDir string, result *core.EphemeralExec func NewHeader(env stEnv) *types.Header { var header types.Header - header.UncleHash = env.ParentUncleHash header.Coinbase = env.Coinbase header.Difficulty = env.Difficulty - header.Number = big.NewInt(int64(env.Number)) header.GasLimit = env.GasLimit + header.Number = big.NewInt(int64(env.Number)) header.Time = env.Timestamp header.BaseFee = env.BaseFee + header.MixDigest = env.MixDigest + + header.UncleHash = env.UncleHash + header.WithdrawalsHash = env.WithdrawalsHash return &header } diff --git a/cmd/evm/main.go b/cmd/evm/main.go index f18e30c6d0b..5b95192c089 100644 --- a/cmd/evm/main.go +++ b/cmd/evm/main.go @@ -26,7 +26,7 @@ import ( "github.com/urfave/cli/v2" "github.com/ledgerwatch/erigon/cmd/evm/internal/t8ntool" - "github.com/ledgerwatch/erigon/cmd/utils" + "github.com/ledgerwatch/erigon/cmd/utils/flags" "github.com/ledgerwatch/erigon/params" cli2 "github.com/ledgerwatch/erigon/turbo/cli" ) @@ -63,12 +63,12 @@ var ( Usage: "gas limit for the evm", Value: 10000000000, } - PriceFlag = utils.BigFlag{ + PriceFlag = flags.BigFlag{ Name: "price", Usage: "price set for the evm", Value: new(big.Int), } - ValueFlag = utils.BigFlag{ + ValueFlag = flags.BigFlag{ Name: "value", Usage: "value set for the evm", Value: new(big.Int), diff --git a/cmd/evm/runner.go b/cmd/evm/runner.go index 298b9a61da7..547dd534d8a 100644 --- a/cmd/evm/runner.go +++ b/cmd/evm/runner.go @@ -33,8 +33,11 @@ import ( "github.com/ledgerwatch/erigon-lib/chain" libcommon "github.com/ledgerwatch/erigon-lib/common" common2 "github.com/ledgerwatch/erigon-lib/common/dbg" + "github.com/ledgerwatch/erigon-lib/common/hexutility" "github.com/ledgerwatch/erigon-lib/kv/kvcfg" "github.com/ledgerwatch/erigon-lib/kv/memdb" + "github.com/ledgerwatch/erigon/cmd/utils/flags" + "github.com/ledgerwatch/erigon/core/types" "github.com/ledgerwatch/log/v3" "github.com/urfave/cli/v2" @@ -59,7 +62,7 @@ var runCommand = cli.Command{ // readGenesis will read the given JSON format genesis file and return // the initialized Genesis structure -func readGenesis(genesisPath string) *core.Genesis { +func readGenesis(genesisPath string) *types.Genesis { // Make sure we have a valid genesis JSON //genesisPath := ctx.Args().First() if len(genesisPath) == 0 { @@ -76,7 +79,7 @@ func readGenesis(genesisPath string) *core.Genesis { } }(file) - genesis := new(core.Genesis) + genesis := new(types.Genesis) if err := json.NewDecoder(file).Decode(genesis); err != nil { utils.Fatalf("invalid genesis file: %v", err) } @@ -136,7 +139,7 @@ func runCmd(ctx *cli.Context) error { chainConfig *chain.Config sender = libcommon.BytesToAddress([]byte("sender")) receiver = libcommon.BytesToAddress([]byte("receiver")) - genesisConfig *core.Genesis + genesisConfig *types.Genesis ) if ctx.Bool(MachineFlag.Name) { tracer = logger.NewJSONLogger(logconfig, os.Stdout) @@ -147,13 +150,14 @@ func runCmd(ctx *cli.Context) error { debugLogger = logger.NewStructLogger(logconfig) } db := memdb.New("") + defer db.Close() if ctx.String(GenesisFlag.Name) != "" { gen := readGenesis(ctx.String(GenesisFlag.Name)) - gen.MustCommit(db, "") + core.MustCommitGenesis(gen, db, "") genesisConfig = gen chainConfig = gen.Config } else { - genesisConfig = new(core.Genesis) + genesisConfig = new(types.Genesis) } tx, err := db.BeginRw(context.Background()) if err != nil { @@ -202,7 +206,7 @@ func runCmd(ctx *cli.Context) error { fmt.Printf("Invalid input length for hex data (%d)\n", len(hexcode)) os.Exit(1) } - code = common.FromHex(string(hexcode)) + code = hexutility.MustDecodeHex(string(hexcode)) } else if fn := ctx.Args().First(); len(fn) > 0 { // EASM-file to compile src, err := os.ReadFile(fn) @@ -219,8 +223,8 @@ func runCmd(ctx *cli.Context) error { if genesisConfig.GasLimit != 0 { initialGas = genesisConfig.GasLimit } - value, _ := uint256.FromBig(utils.BigFlagValue(ctx, ValueFlag.Name)) - gasPrice, _ := uint256.FromBig(utils.BigFlagValue(ctx, PriceFlag.Name)) + value, _ := uint256.FromBig(flags.GlobalBig(ctx, ValueFlag.Name)) + gasPrice, _ := uint256.FromBig(flags.GlobalBig(ctx, PriceFlag.Name)) runtimeConfig := runtime.Config{ Origin: sender, State: statedb, @@ -266,7 +270,7 @@ func runCmd(ctx *cli.Context) error { } else { hexInput = []byte(ctx.String(InputFlag.Name)) } - input := common.FromHex(string(bytes.TrimSpace(hexInput))) + input := hexutility.MustDecodeHex(string(bytes.TrimSpace(hexInput))) var execFunc func() ([]byte, uint64, error) if ctx.Bool(CreateFlag.Name) { diff --git a/cmd/evm/staterunner.go b/cmd/evm/staterunner.go index 0bf182b1be5..3c0c332569c 100644 --- a/cmd/evm/staterunner.go +++ b/cmd/evm/staterunner.go @@ -22,10 +22,13 @@ import ( "errors" "fmt" "os" + "path/filepath" + "github.com/c2h5oh/datasize" libcommon "github.com/ledgerwatch/erigon-lib/common" - "github.com/ledgerwatch/erigon-lib/kv/memdb" + "github.com/ledgerwatch/erigon-lib/kv/mdbx" "github.com/ledgerwatch/log/v3" + mdbx2 "github.com/torquem-ch/mdbx-go/mdbx" "github.com/urfave/cli/v2" "github.com/ledgerwatch/erigon/core/state" @@ -114,7 +117,17 @@ func aggregateResultsFromStateTests( Tracer: tracer, Debug: ctx.Bool(DebugFlag.Name) || ctx.Bool(MachineFlag.Name), } - db := memdb.New("") + + //this DB is shared. means: + // - faster sequential tests: don't need create/delete db + // - less parallelism: multiple processes can open same DB but only 1 can create rw-transaction (other will wait when 1-st finish) + db := mdbx.NewMDBX(log.New()). + Path(filepath.Join(os.TempDir(), "erigon-statetest")). + Flags(func(u uint) uint { + return u | mdbx2.UtterlyNoSync | mdbx2.NoMetaSync | mdbx2.LifoReclaim | mdbx2.NoMemInit + }). + GrowthStep(1 * datasize.MB). + MustOpen() defer db.Close() tx, txErr := db.BeginRw(context.Background()) diff --git a/cmd/evm/t8n_test.go b/cmd/evm/t8n_test.go index e5bd4ab19a8..509e93bb6f2 100644 --- a/cmd/evm/t8n_test.go +++ b/cmd/evm/t8n_test.go @@ -188,6 +188,14 @@ func TestT8n(t *testing.T) { expOut: "exp_arrowglacier.json", output: t8nOutput{alloc: true, result: true}, }, + { // eip-4895 + base: "./testdata/26", + input: t8nInput{ + "alloc.json", "txs.json", "env.json", "Shanghai", + }, + expOut: "exp.json", + output: t8nOutput{alloc: true, result: true}, + }, } { args := []string{"t8n"} diff --git a/cmd/evm/testdata/26/alloc.json b/cmd/evm/testdata/26/alloc.json new file mode 100644 index 00000000000..d67655a8a8e --- /dev/null +++ b/cmd/evm/testdata/26/alloc.json @@ -0,0 +1,8 @@ +{ + "a94f5374fce5edbc8e2a8697c15331677e6ebf0b": { + "balance": "0x0", + "code": "0x", + "nonce": "0xac", + "storage": {} + } +} diff --git a/cmd/evm/testdata/26/env.json b/cmd/evm/testdata/26/env.json new file mode 100644 index 00000000000..03d817b93bc --- /dev/null +++ b/cmd/evm/testdata/26/env.json @@ -0,0 +1,17 @@ +{ + "currentCoinbase": "0xc94f5374fce5edbc8e2a8697c15331677e6ebf0b", + "currentDifficulty": null, + "currentRandom": "0xdeadc0de", + "currentGasLimit": "0x750a163df65e8a", + "currentBaseFee": "0x500", + "currentNumber": "1", + "currentTimestamp": "1000", + "withdrawals": [ + { + "index": "0x42", + "validatorIndex": "0x42", + "address": "0xa94f5374fce5edbc8e2a8697c15331677e6ebf0b", + "amount": "0x2a" + } + ] +} diff --git a/cmd/evm/testdata/26/exp.json b/cmd/evm/testdata/26/exp.json new file mode 100644 index 00000000000..86438389cb4 --- /dev/null +++ b/cmd/evm/testdata/26/exp.json @@ -0,0 +1,18 @@ +{ + "alloc": { + "0xa94f5374fce5edbc8e2a8697c15331677e6ebf0b": { + "balance": "0x9c7652400", + "nonce": "0xac" + } + }, + "result": { + "stateRoot": "0x6e061c2f6513af27d267a0e3b07cb9a10f1ba3a0f65ab648d3a17c36e15021d2", + "txRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", + "receiptsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", + "logsHash": "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347", + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "receipts": null, + "currentDifficulty": "0x0", + "gasUsed": "0x0" + } + } \ No newline at end of file diff --git a/cmd/evm/testdata/26/txs.json b/cmd/evm/testdata/26/txs.json new file mode 100644 index 00000000000..fe51488c706 --- /dev/null +++ b/cmd/evm/testdata/26/txs.json @@ -0,0 +1 @@ +[] diff --git a/cmd/hack/hack.go b/cmd/hack/hack.go index b91a6f0faa1..0a9dcc27925 100644 --- a/cmd/hack/hack.go +++ b/cmd/hack/hack.go @@ -1403,7 +1403,7 @@ func main() { debug.RaiseFdLimit() flag.Parse() - _ = logging.GetLogger("hack") + logging.SetupLogger("hack") if *cpuprofile != "" { f, err := os.Create(*cpuprofile) diff --git a/cmd/integration/commands/stages.go b/cmd/integration/commands/stages.go index bf10ac722fe..ae7aca61760 100644 --- a/cmd/integration/commands/stages.go +++ b/cmd/integration/commands/stages.go @@ -19,6 +19,11 @@ import ( "github.com/ledgerwatch/erigon-lib/kv/kvcfg" "github.com/ledgerwatch/erigon-lib/kv/rawdbv3" libstate "github.com/ledgerwatch/erigon-lib/state" + "github.com/ledgerwatch/log/v3" + "github.com/ledgerwatch/secp256k1" + "github.com/spf13/cobra" + "golang.org/x/exp/slices" + "github.com/ledgerwatch/erigon/cmd/hack/tool/fromdb" "github.com/ledgerwatch/erigon/cmd/sentry/sentry" "github.com/ledgerwatch/erigon/consensus" @@ -42,10 +47,6 @@ import ( "github.com/ledgerwatch/erigon/turbo/snapshotsync" "github.com/ledgerwatch/erigon/turbo/snapshotsync/snap" stages2 "github.com/ledgerwatch/erigon/turbo/stages" - "github.com/ledgerwatch/log/v3" - "github.com/ledgerwatch/secp256k1" - "github.com/spf13/cobra" - "golang.org/x/exp/slices" ) var cmdStageSnapshots = &cobra.Command{ @@ -814,7 +815,7 @@ func stageTrie(db kv.RwDB, ctx context.Context) error { log.Info("StageExec", "progress", execStage.BlockNumber) log.Info("StageTrie", "progress", s.BlockNumber) - cfg := stagedsync.StageTrieCfg(db, true, true, false, dirs.Tmp, getBlockReader(db), nil, historyV3, agg) + cfg := stagedsync.StageTrieCfg(db, true /* checkRoot */, true /* saveHashesToDb */, false /* badBlockHalt */, dirs.Tmp, getBlockReader(db), nil /* hd */, historyV3, agg) if unwind > 0 { u := sync.NewUnwindState(stages.IntermediateHashes, s.BlockNumber-unwind, s.BlockNumber) if err := stagedsync.UnwindIntermediateHashesStage(u, s, tx, cfg, ctx); err != nil { @@ -1276,6 +1277,7 @@ func newSync(ctx context.Context, db kv.RwDB, miningConfig *params.MiningConfig) br, false, nil, + ethconfig.Defaults.DropUselessPeers, ) if err != nil { panic(err) @@ -1342,7 +1344,6 @@ func overrideStorageMode(db kv.RwDB) error { } func initConsensusEngine(cc *chain2.Config, datadir string, db kv.RwDB) (engine consensus.Engine) { - l := log.New() snapshots, _ := allSnapshots(context.Background(), db) config := ethconfig.Defaults @@ -1351,7 +1352,6 @@ func initConsensusEngine(cc *chain2.Config, datadir string, db kv.RwDB) (engine if cc.Clique != nil { consensusConfig = params.CliqueSnapshot } else if cc.Aura != nil { - config.Aura.Etherbase = config.Miner.Etherbase consensusConfig = &config.Aura } else if cc.Parlia != nil { consensusConfig = &config.Parlia @@ -1360,5 +1360,5 @@ func initConsensusEngine(cc *chain2.Config, datadir string, db kv.RwDB) (engine } else { consensusConfig = &config.Ethash } - return ethconsensusconfig.CreateConsensusEngine(cc, l, consensusConfig, config.Miner.Notify, config.Miner.Noverify, HeimdallgRPCAddress, HeimdallURL, config.WithoutHeimdall, datadir, snapshots, db.ReadOnly(), db) + return ethconsensusconfig.CreateConsensusEngine(cc, consensusConfig, config.Miner.Notify, config.Miner.Noverify, HeimdallgRPCAddress, HeimdallURL, config.WithoutHeimdall, datadir, snapshots, db.ReadOnly(), db) } diff --git a/cmd/integration/commands/state_domains.go b/cmd/integration/commands/state_domains.go new file mode 100644 index 00000000000..9d4047081b7 --- /dev/null +++ b/cmd/integration/commands/state_domains.go @@ -0,0 +1,762 @@ +package commands + +import ( + "bytes" + "context" + "encoding/hex" + "errors" + "fmt" + "os" + "path/filepath" + "runtime" + "strings" + "time" + + "github.com/VictoriaMetrics/metrics" + "github.com/holiman/uint256" + "github.com/ledgerwatch/log/v3" + "github.com/spf13/cobra" + + chain2 "github.com/ledgerwatch/erigon-lib/chain" + "github.com/ledgerwatch/erigon-lib/commitment" + libcommon "github.com/ledgerwatch/erigon-lib/common" + "github.com/ledgerwatch/erigon-lib/common/datadir" + "github.com/ledgerwatch/erigon-lib/common/dbg" + "github.com/ledgerwatch/erigon-lib/common/length" + "github.com/ledgerwatch/erigon-lib/kv" + kv2 "github.com/ledgerwatch/erigon-lib/kv/mdbx" + libstate "github.com/ledgerwatch/erigon-lib/state" + + "github.com/ledgerwatch/erigon/cmd/hack/tool/fromdb" + "github.com/ledgerwatch/erigon/cmd/state/exec3" + "github.com/ledgerwatch/erigon/cmd/utils" + "github.com/ledgerwatch/erigon/consensus" + "github.com/ledgerwatch/erigon/consensus/misc" + "github.com/ledgerwatch/erigon/core" + "github.com/ledgerwatch/erigon/core/state" + "github.com/ledgerwatch/erigon/core/types" + "github.com/ledgerwatch/erigon/core/types/accounts" + "github.com/ledgerwatch/erigon/core/vm" + "github.com/ledgerwatch/erigon/eth/ethconfig" + "github.com/ledgerwatch/erigon/node/nodecfg" + erigoncli "github.com/ledgerwatch/erigon/turbo/cli" + "github.com/ledgerwatch/erigon/turbo/services" +) + +func init() { + withConfig(stateDomains) + withDataDir(stateDomains) + withUnwind(stateDomains) + withUnwindEvery(stateDomains) + withBlock(stateDomains) + withIntegrityChecks(stateDomains) + withChain(stateDomains) + withHeimdall(stateDomains) + withWorkers(stateDomains) + withStartTx(stateDomains) + withCommitment(stateDomains) + withTraceFromTx(stateDomains) + + stateDomains.Flags().Uint64Var(&stepSize, "step-size", ethconfig.HistoryV3AggregationStep, "size of aggregation step, tx") + stateDomains.Flags().Uint64Var(&lastStep, "last-step", 0, "step of last aggregation, step=txnum/step-size, unsigned integers only") + + rootCmd.AddCommand(stateDomains) + + withDataDir(readDomains) + withChain(readDomains) + withHeimdall(readDomains) + withWorkers(readDomains) + withStartTx(readDomains) + + rootCmd.AddCommand(readDomains) +} + +// if trie variant is not hex, we could not have another rootHash with to verify it +var ( + stepSize uint64 + lastStep uint64 + dirtySpaceThreshold = uint64(2 * 1024 * 1024 * 1024) /* threshold of dirty space in MDBX transaction that triggers a commit */ + blockRootMismatchExpected bool + + mxBlockExecutionTimer = metrics.GetOrCreateSummary("chain_execution_seconds") + mxCommitTook = metrics.GetOrCreateHistogram("domain_commit_took") +) + +// write command to just seek and query state by addr and domain from state db and files (if any) +var readDomains = &cobra.Command{ + Use: "read_domains", + Short: `Run block execution and commitment with Domains.`, + Example: "go run ./cmd/integration read_domains --datadir=... --verbosity=3", + ValidArgs: []string{"account", "storage", "code", "commitment"}, + Args: cobra.ArbitraryArgs, + Run: func(cmd *cobra.Command, args []string) { + ctx, _ := libcommon.RootContext() + cfg := &nodecfg.DefaultConfig + utils.SetNodeConfigCobra(cmd, cfg) + ethConfig := ðconfig.Defaults + ethConfig.Genesis = core.GenesisBlockByChainName(chain) + erigoncli.ApplyFlagsForEthConfigCobra(cmd.Flags(), ethConfig) + + var readFromDomain string + var addrs [][]byte + for i := 0; i < len(args); i++ { + if i == 0 { + switch s := strings.ToLower(args[i]); s { + case "account", "storage", "code", "commitment": + readFromDomain = s + default: + log.Error("invalid domain to read from", "arg", args[i]) + return + } + continue + } + addr, err := hex.DecodeString(strings.TrimPrefix(args[i], "0x")) + if err != nil { + log.Warn("invalid address passed", "str", args[i], "at position", i, "err", err) + continue + } + addrs = append(addrs, addr) + } + + dirs := datadir.New(datadirCli) + chainDb := openDB(dbCfg(kv.ChainDB, dirs.Chaindata), true) + defer chainDb.Close() + + stateDb, err := kv2.NewMDBX(log.New()).Path(filepath.Join(dirs.DataDir, "statedb")).WriteMap().Open() + if err != nil { + return + } + defer stateDb.Close() + + if err := requestDomains(chainDb, stateDb, ctx, readFromDomain, addrs); err != nil { + if !errors.Is(err, context.Canceled) { + log.Error(err.Error()) + } + return + } + }, +} + +func requestDomains(chainDb, stateDb kv.RwDB, ctx context.Context, readDomain string, addrs [][]byte) error { + trieVariant := commitment.ParseTrieVariant(commitmentTrie) + if trieVariant != commitment.VariantHexPatriciaTrie { + blockRootMismatchExpected = true + } + mode := libstate.ParseCommitmentMode(commitmentMode) + libstate.COMPARE_INDEXES = true + + _, _, _, agg := newDomains(ctx, chainDb, stepSize, mode, trieVariant) + defer agg.Close() + + histTx, err := chainDb.BeginRo(ctx) + must(err) + defer histTx.Rollback() + + stateTx, err := stateDb.BeginRw(ctx) + must(err) + defer stateTx.Rollback() + + agg.SetTx(stateTx) + defer agg.StartWrites().FinishWrites() + + latestBlock, latestTx, err := agg.SeekCommitment() + if err != nil && startTxNum != 0 { + return fmt.Errorf("failed to seek commitment to tx %d: %w", startTxNum, err) + } + if latestTx < startTxNum { + return fmt.Errorf("latest available tx to start is %d and its less than start tx %d", latestTx, startTxNum) + } + if latestTx > 0 { + log.Info("aggregator files opened", "txn", latestTx, "block", latestBlock) + } + agg.SetTxNum(latestTx) + + r := ReaderWrapper4{ + roTx: histTx, + ac: agg.MakeContext(), + } + + switch readDomain { + case "account": + for _, addr := range addrs { + acc, err := r.ReadAccountData(libcommon.BytesToAddress(addr)) + if err != nil { + log.Error("failed to read account", "addr", addr, "err", err) + continue + } + fmt.Printf("%x: nonce=%d balance=%d code=%x root=%x\n", addr, acc.Nonce, acc.Balance.Uint64(), acc.CodeHash, acc.Root) + } + case "storage": + for _, addr := range addrs { + a, s := libcommon.BytesToAddress(addr[:length.Addr]), libcommon.BytesToHash(addr[length.Addr:]) + st, err := r.ReadAccountStorage(a, 0, &s) + if err != nil { + log.Error("failed to read storage", "addr", a.String(), "key", s.String(), "err", err) + continue + } + fmt.Printf("%s %s -> %x\n", a.String(), s.String(), st) + } + case "code": + for _, addr := range addrs { + code, err := r.ReadAccountCode(libcommon.BytesToAddress(addr), 0, libcommon.Hash{}) + if err != nil { + log.Error("failed to read code", "addr", addr, "err", err) + continue + } + fmt.Printf("%s: %x\n", addr, code) + } + } + return nil +} + +// write command to just seek and query state by addr and domain from state db and files (if any) +var stateDomains = &cobra.Command{ + Use: "state_domains", + Short: `Run block execution and commitment with Domains.`, + Example: "go run ./cmd/integration state_domains --datadir=... --verbosity=3 --unwind=100 --unwind.every=100000 --block=2000000", + Run: func(cmd *cobra.Command, args []string) { + ctx, _ := libcommon.RootContext() + cfg := &nodecfg.DefaultConfig + utils.SetNodeConfigCobra(cmd, cfg) + ethConfig := ðconfig.Defaults + ethConfig.Genesis = core.GenesisBlockByChainName(chain) + erigoncli.ApplyFlagsForEthConfigCobra(cmd.Flags(), ethConfig) + + dirs := datadir.New(datadirCli) + chainDb := openDB(dbCfg(kv.ChainDB, dirs.Chaindata), true) + defer chainDb.Close() + + //stateDB := kv.Label(6) + //stateOpts := dbCfg(stateDB, filepath.Join(dirs.DataDir, "statedb")).WriteMap() + //stateOpts.MapSize(1 * datasize.TB).WriteMap().DirtySpace(dirtySpaceThreshold) + //stateDb := openDB(stateOpts, true) + //defer stateDb.Close() + + stateDb, err := kv2.NewMDBX(log.New()).Path(filepath.Join(dirs.DataDir, "statedb")).WriteMap().Open() + if err != nil { + return + } + defer stateDb.Close() + + if err := loopProcessDomains(chainDb, stateDb, ctx); err != nil { + if !errors.Is(err, context.Canceled) { + log.Error(err.Error()) + } + return + } + }, +} + +func loopProcessDomains(chainDb, stateDb kv.RwDB, ctx context.Context) error { + trieVariant := commitment.ParseTrieVariant(commitmentTrie) + if trieVariant != commitment.VariantHexPatriciaTrie { + blockRootMismatchExpected = true + } + mode := libstate.ParseCommitmentMode(commitmentMode) + + engine, _, _, agg := newDomains(ctx, chainDb, stepSize, mode, trieVariant) + defer agg.Close() + + histTx, err := chainDb.BeginRo(ctx) + must(err) + defer histTx.Rollback() + + stateTx, err := stateDb.BeginRw(ctx) + must(err) + defer stateTx.Rollback() + + agg.SetTx(stateTx) + defer agg.StartWrites().FinishWrites() + + latestBlock, latestTx, err := agg.SeekCommitment() + if err != nil && startTxNum != 0 { + return fmt.Errorf("failed to seek commitment to tx %d: %w", startTxNum, err) + } + if latestTx < startTxNum { + return fmt.Errorf("latest available tx to start is %d and its less than start tx %d", latestTx, startTxNum) + } + if latestTx > 0 { + log.Info("aggregator files opened", "txn", latestTx, "block", latestBlock) + } + + aggWriter, aggReader := WrapAggregator(agg, stateTx) + proc := blockProcessor{ + chainConfig: fromdb.ChainConfig(chainDb), + vmConfig: vm.Config{}, + engine: engine, + reader: aggReader, + writer: aggWriter, + blockReader: getBlockReader(chainDb), + stateTx: stateTx, + stateDb: stateDb, + blockNum: latestBlock, + txNum: latestTx, + startTxNum: latestTx, + histTx: histTx, + agg: agg, + logger: log.New(), + stat: stat4{startedAt: time.Now()}, + } + if proc.txNum > 0 { + proc.txNum-- + } + if proc.blockNum == 0 { + proc.txNum = 2 + } + + mergedRoots := agg.AggregatedRoots() + go proc.PrintStatsLoop(ctx, 30*time.Second) + + if proc.startTxNum == 0 { + genesis := core.GenesisBlockByChainName(chain) + if err := proc.ApplyGenesis(genesis); err != nil { + return err + } + } + + for { + // Check for interrupts + select { + case <-ctx.Done(): + log.Info(fmt.Sprintf("interrupted, please wait for commitment and cleanup, next time start with --tx %d", proc.txNum)) + rh, err := proc.agg.ComputeCommitment(true, false) + if err != nil { + log.Error("failed to compute commitment", "err", err) + } + log.Info("commitment: state root computed", "root", hex.EncodeToString(rh)) + if err := agg.Flush(ctx); err != nil { + log.Error("failed to flush aggregator", "err", err) + } + os.Exit(0) + case <-mergedRoots: // notified with rootHash of latest aggregation + if err := proc.commit(ctx); err != nil { + log.Error("chainDb commit on merge", "err", err) + } + default: + } + + if lastStep > 0 && proc.txNum/stepSize >= lastStep { + log.Info("last step reached") + // Commit transaction only when interrupted or just before computing commitment (so it can be re-done) + break + } + + err := proc.ProcessNext(ctx) + if err != nil { + return err + } + } + return nil +} + +type blockProcessor struct { + engine consensus.Engine + agg *libstate.Aggregator + blockReader services.FullBlockReader + writer *WriterWrapper4 + reader *ReaderWrapper4 + stateDb kv.RwDB + stateTx kv.RwTx + histTx kv.Tx + blockNum uint64 + startTxNum uint64 + txNum uint64 + stat stat4 + trace bool + logger log.Logger + vmConfig vm.Config + chainConfig *chain2.Config +} + +func (b *blockProcessor) getHeader(hash libcommon.Hash, number uint64) *types.Header { + h, err := b.blockReader.Header(context.Background(), b.histTx, hash, number) + if err != nil { + panic(err) + } + return h +} + +func (b *blockProcessor) commit(ctx context.Context) error { + if b.stateDb == nil || b.stateTx == nil { + return fmt.Errorf("commit failed due to invalid chainDb/rwTx") + } + + s := time.Now() + defer mxCommitTook.UpdateDuration(s) + + var spaceDirty uint64 + var err error + if spaceDirty, _, err = b.stateTx.(*kv2.MdbxTx).SpaceDirty(); err != nil { + return fmt.Errorf("retrieving spaceDirty: %w", err) + } + if spaceDirty >= dirtySpaceThreshold { + b.logger.Info("Initiated tx commit", "block", b.blockNum, "space dirty", libcommon.ByteCount(spaceDirty)) + } + + b.logger.Info("database commitment", "block", b.blockNum, "txNum", b.txNum, "uptime", time.Since(b.stat.startedAt)) + if err := b.agg.Flush(ctx); err != nil { + return err + } + if err = b.stateTx.Commit(); err != nil { + return err + } + + if b.stateTx, err = b.stateDb.BeginRw(ctx); err != nil { + return err + } + + b.agg.SetTx(b.stateTx) + b.reader.SetTx(b.stateTx, b.agg.MakeContext()) + + return nil +} + +func (b *blockProcessor) PrintStatsLoop(ctx context.Context, interval time.Duration) { + ticker := time.NewTicker(interval) + defer ticker.Stop() + + for { + select { + case <-ctx.Done(): + return + case <-ticker.C: + b.stat.delta(b.blockNum, b.txNum).print(b.agg.Stats(), b.logger) + } + } +} + +func (b *blockProcessor) ApplyGenesis(genesis *types.Genesis) error { + b.logger.Info("apply genesis", "chain_id", genesis.Config.ChainID) + genBlock, genesisIbs, err := core.GenesisToBlock(genesis, "") + if err != nil { + return err + } + b.agg.SetTxNum(0) + if err = genesisIbs.CommitBlock(&chain2.Rules{}, b.writer); err != nil { + return fmt.Errorf("cannot write state: %w", err) + } + + blockRootHash, err := b.agg.ComputeCommitment(true, false) + if err != nil { + return err + } + if err = b.agg.FinishTx(); err != nil { + return err + } + + genesisRootHash := genBlock.Root() + if !blockRootMismatchExpected && !bytes.Equal(blockRootHash, genesisRootHash[:]) { + return fmt.Errorf("genesis root hash mismatch: expected %x got %x", genesisRootHash, blockRootHash) + } + return nil +} + +func (b *blockProcessor) ProcessNext(ctx context.Context) error { + b.blockNum++ + b.trace = traceFromTx > 0 && b.txNum == traceFromTx + + blockHash, err := b.blockReader.CanonicalHash(ctx, b.histTx, b.blockNum) + if err != nil { + return err + } + + block, _, err := b.blockReader.BlockWithSenders(ctx, b.histTx, blockHash, b.blockNum) + if err != nil { + return err + } + if block == nil { + b.logger.Info("history: block is nil", "block", b.blockNum) + return fmt.Errorf("block %d is nil", b.blockNum) + } + + b.agg.SetTx(b.stateTx) + b.agg.SetTxNum(b.txNum) + b.agg.SetBlockNum(b.blockNum) + + if _, err = b.applyBlock(ctx, block); err != nil { + b.logger.Error("processing error", "block", b.blockNum, "err", err) + return fmt.Errorf("processing block %d: %w", b.blockNum, err) + } + return err +} + +func (b *blockProcessor) applyBlock( + ctx context.Context, + block *types.Block, +) (types.Receipts, error) { + defer mxBlockExecutionTimer.UpdateDuration(time.Now()) + + header := block.Header() + b.vmConfig.Debug = true + gp := new(core.GasPool).AddGas(block.GasLimit()) + usedGas := new(uint64) + var receipts types.Receipts + rules := b.chainConfig.Rules(block.NumberU64(), block.Time()) + + b.blockNum = block.NumberU64() + b.writer.w.SetTxNum(b.txNum) + + daoFork := b.txNum >= b.startTxNum && b.chainConfig.DAOForkBlock != nil && b.chainConfig.DAOForkBlock.Cmp(block.Number()) == 0 + if daoFork { + ibs := state.New(b.reader) + // TODO Actually add tracing to the DAO related accounts + misc.ApplyDAOHardFork(ibs) + if err := ibs.FinalizeTx(rules, b.writer); err != nil { + return nil, err + } + if err := b.writer.w.FinishTx(); err != nil { + return nil, fmt.Errorf("finish daoFork failed: %w", err) + } + } + + b.txNum++ // Pre-block transaction + b.writer.w.SetTxNum(b.txNum) + if err := b.writer.w.FinishTx(); err != nil { + return nil, fmt.Errorf("finish pre-block tx %d (block %d) has failed: %w", b.txNum, block.NumberU64(), err) + } + + getHashFn := core.GetHashFn(header, b.getHeader) + parentHeader := b.getHeader(block.ParentHash(), b.blockNum-1) + for i, tx := range block.Transactions() { + if b.txNum >= b.startTxNum { + ibs := state.New(b.reader) + ibs.Prepare(tx.Hash(), block.Hash(), i) + ct := exec3.NewCallTracer() + b.vmConfig.Tracer = ct + receipt, _, err := core.ApplyTransaction(b.chainConfig, getHashFn, b.engine, nil, gp, ibs, b.writer, header, tx, usedGas, b.vmConfig, parentHeader.ExcessDataGas) + if err != nil { + return nil, fmt.Errorf("could not apply tx %d [%x] failed: %w", i, tx.Hash(), err) + } + for from := range ct.Froms() { + if err := b.writer.w.AddTraceFrom(from[:]); err != nil { + return nil, err + } + } + for to := range ct.Tos() { + if err := b.writer.w.AddTraceTo(to[:]); err != nil { + return nil, err + } + } + receipts = append(receipts, receipt) + for _, log := range receipt.Logs { + if err = b.writer.w.AddLogAddr(log.Address[:]); err != nil { + return nil, fmt.Errorf("adding event log for addr %x: %w", log.Address, err) + } + for _, topic := range log.Topics { + if err = b.writer.w.AddLogTopic(topic[:]); err != nil { + return nil, fmt.Errorf("adding event log for topic %x: %w", topic, err) + } + } + } + if err = b.writer.w.FinishTx(); err != nil { + return nil, fmt.Errorf("finish tx %d [%x] failed: %w", i, tx.Hash(), err) + } + if b.trace { + fmt.Printf("FinishTx called for blockNum=%d, txIndex=%d, txNum=%d txHash=[%x]\n", b.blockNum, i, b.txNum, tx.Hash()) + } + } + b.txNum++ + b.writer.w.SetTxNum(b.txNum) + } + + if b.txNum >= b.startTxNum { + if b.chainConfig.IsByzantium(block.NumberU64()) { + receiptSha := types.DeriveSha(receipts) + if receiptSha != block.ReceiptHash() { + fmt.Printf("mismatched receipt headers for block %d\n", block.NumberU64()) + for j, receipt := range receipts { + fmt.Printf("tx %d, used gas: %d\n", j, receipt.GasUsed) + } + } + } + ibs := state.New(b.reader) + if err := b.writer.w.AddTraceTo(block.Coinbase().Bytes()); err != nil { + return nil, fmt.Errorf("adding coinbase trace: %w", err) + } + for _, uncle := range block.Uncles() { + if err := b.writer.w.AddTraceTo(uncle.Coinbase.Bytes()); err != nil { + return nil, fmt.Errorf("adding uncle trace: %w", err) + } + } + + // Finalize the block, applying any consensus engine specific extras (e.g. block rewards) + if _, _, err := b.engine.Finalize(b.chainConfig, header, ibs, block.Transactions(), block.Uncles(), receipts, block.Withdrawals(), nil, nil); err != nil { + return nil, fmt.Errorf("finalize of block %d failed: %w", block.NumberU64(), err) + } + + if err := ibs.CommitBlock(rules, b.writer); err != nil { + return nil, fmt.Errorf("committing block %d failed: %w", block.NumberU64(), err) + } + + if err := b.writer.w.FinishTx(); err != nil { + return nil, fmt.Errorf("failed to finish tx: %w", err) + } + if b.trace { + fmt.Printf("FinishTx called for %d block %d\n", b.txNum, block.NumberU64()) + } + } + + b.txNum++ // Post-block transaction + b.writer.w.SetTxNum(b.txNum) + if b.txNum >= b.startTxNum { + if block.Number().Uint64()%uint64(commitmentFreq) == 0 { + rootHash, err := b.writer.w.ComputeCommitment(true, b.trace) + if err != nil { + return nil, err + } + if !blockRootMismatchExpected && !bytes.Equal(rootHash, header.Root[:]) { + return nil, fmt.Errorf("invalid root hash for block %d: expected %x got %x", block.NumberU64(), header.Root, rootHash) + } + } + + if err := b.writer.w.FinishTx(); err != nil { + return nil, fmt.Errorf("finish after-block tx %d (block %d) has failed: %w", b.txNum, block.NumberU64(), err) + } + } + + return receipts, nil +} + +// Implements StateReader and StateWriter +type ReaderWrapper4 struct { + roTx kv.Tx + ac *libstate.AggregatorContext +} + +type WriterWrapper4 struct { + w *libstate.Aggregator +} + +func WrapAggregator(agg *libstate.Aggregator, roTx kv.Tx) (*WriterWrapper4, *ReaderWrapper4) { + return &WriterWrapper4{w: agg}, &ReaderWrapper4{ac: agg.MakeContext(), roTx: roTx} +} + +func (rw *ReaderWrapper4) SetTx(roTx kv.Tx, ctx *libstate.AggregatorContext) { + rw.roTx = roTx + rw.ac.Close() + rw.ac = ctx +} + +func (rw *ReaderWrapper4) ReadAccountData(address libcommon.Address) (*accounts.Account, error) { + enc, err := rw.ac.ReadAccountData(address.Bytes(), rw.roTx) + if err != nil { + return nil, err + } + if len(enc) == 0 { + return nil, nil + } + var a accounts.Account + if err := accounts.DeserialiseV3(&a, enc); err != nil { + return nil, err + } + return &a, nil +} + +func (rw *ReaderWrapper4) ReadAccountStorage(address libcommon.Address, incarnation uint64, key *libcommon.Hash) ([]byte, error) { + enc, err := rw.ac.ReadAccountStorage(address.Bytes(), key.Bytes(), rw.roTx) + if err != nil { + return nil, err + } + if enc == nil { + return nil, nil + } + if len(enc) == 1 && enc[0] == 0 { + return nil, nil + } + return enc, nil +} + +func (rw *ReaderWrapper4) ReadAccountCode(address libcommon.Address, incarnation uint64, codeHash libcommon.Hash) ([]byte, error) { + return rw.ac.ReadAccountCode(address.Bytes(), rw.roTx) +} + +func (rw *ReaderWrapper4) ReadAccountCodeSize(address libcommon.Address, incarnation uint64, codeHash libcommon.Hash) (int, error) { + return rw.ac.ReadAccountCodeSize(address.Bytes(), rw.roTx) +} + +func (rw *ReaderWrapper4) ReadAccountIncarnation(address libcommon.Address) (uint64, error) { + return 0, nil +} + +func (ww *WriterWrapper4) UpdateAccountData(address libcommon.Address, original, account *accounts.Account) error { + value := accounts.SerialiseV3(account) + if err := ww.w.UpdateAccountData(address.Bytes(), value); err != nil { + return err + } + return nil +} + +func (ww *WriterWrapper4) UpdateAccountCode(address libcommon.Address, incarnation uint64, codeHash libcommon.Hash, code []byte) error { + if err := ww.w.UpdateAccountCode(address.Bytes(), code); err != nil { + return err + } + return nil +} + +func (ww *WriterWrapper4) DeleteAccount(address libcommon.Address, original *accounts.Account) error { + if err := ww.w.DeleteAccount(address.Bytes()); err != nil { + return err + } + return nil +} + +func (ww *WriterWrapper4) WriteAccountStorage(address libcommon.Address, incarnation uint64, key *libcommon.Hash, original, value *uint256.Int) error { + if err := ww.w.WriteAccountStorage(address.Bytes(), key.Bytes(), value.Bytes()); err != nil { + return err + } + return nil +} + +func (ww *WriterWrapper4) CreateContract(address libcommon.Address) error { + return nil +} + +type stat4 struct { + prevBlock uint64 + blockNum uint64 + hits uint64 + misses uint64 + hitMissRatio float64 + blockSpeed float64 + txSpeed float64 + prevTxNum uint64 + txNum uint64 + prevTime time.Time + mem runtime.MemStats + startedAt time.Time +} + +func (s *stat4) print(aStats libstate.FilesStats, logger log.Logger) { + totalFiles := aStats.FilesCount + totalDatSize := aStats.DataSize + totalIdxSize := aStats.IdxSize + + logger.Info("Progress", "block", s.blockNum, "blk/s", s.blockSpeed, "tx", s.txNum, "txn/s", s.txSpeed, "state files", totalFiles, + "total dat", libcommon.ByteCount(totalDatSize), "total idx", libcommon.ByteCount(totalIdxSize), + "hit ratio", s.hitMissRatio, "hits+misses", s.hits+s.misses, + "alloc", libcommon.ByteCount(s.mem.Alloc), "sys", libcommon.ByteCount(s.mem.Sys), + ) +} + +func (s *stat4) delta(blockNum, txNum uint64) *stat4 { + currentTime := time.Now() + dbg.ReadMemStats(&s.mem) + + interval := currentTime.Sub(s.prevTime).Seconds() + s.blockNum = blockNum + s.blockSpeed = float64(s.blockNum-s.prevBlock) / interval + s.txNum = txNum + s.txSpeed = float64(s.txNum-s.prevTxNum) / interval + s.prevBlock = blockNum + s.prevTxNum = txNum + s.prevTime = currentTime + if s.startedAt.IsZero() { + s.startedAt = currentTime + } + + total := s.hits + s.misses + if total > 0 { + s.hitMissRatio = float64(s.hits) / float64(total) + } + return s +} diff --git a/cmd/lightclient/LICENSE b/cmd/lightclient/LICENSE deleted file mode 100644 index 773fed3c024..00000000000 --- a/cmd/lightclient/LICENSE +++ /dev/null @@ -1,201 +0,0 @@ - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - - APPENDIX: How to apply the Apache License to your work. - - To apply the Apache License to your work, attach the following - boilerplate notice, with the fields enclosed by brackets "[]" - replaced with your own identifying information. (Don't include - the brackets!) The text should be enclosed in the appropriate - comment syntax for the file format. We also recommend that a - file or class name and description of purpose be included on the - same "printed page" as the copyright notice for easier - identification within third-party archives. - - Copyright [2022] Erigon-Ligthclient Authors. - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. \ No newline at end of file diff --git a/cmd/lightclient/lightclient/checkpoint.go b/cmd/lightclient/lightclient/checkpoint.go deleted file mode 100644 index c4876d6a72c..00000000000 --- a/cmd/lightclient/lightclient/checkpoint.go +++ /dev/null @@ -1,63 +0,0 @@ -package lightclient - -import ( - "context" - "time" - - "github.com/ledgerwatch/erigon/cl/cltypes" - "github.com/ledgerwatch/erigon/common" - "github.com/ledgerwatch/log/v3" -) - -func (l *LightClient) BootstrapCheckpoint(ctx context.Context, finalized [32]byte) error { - log.Info("[Checkpoint Sync] Retrieving lightclient bootstrap from sentinel", - "root", common.Bytes2Hex(finalized[:])) - retryInterval := time.NewTicker(200 * time.Millisecond) - defer retryInterval.Stop() - - logInterval := time.NewTicker(10 * time.Second) - defer logInterval.Stop() - - doneLogCh := make(chan struct{}) - var ( - b *cltypes.LightClientBootstrap - err error - ) - // Start log go routine. - - go func() { - for { - select { - case <-logInterval.C: - peers, err := l.rpc.Peers() - if err != nil { - continue - } - log.Info("[Checkpoint Sync] P2P", "peers", peers) - case <-doneLogCh: - return - } - } - }() - - b, err = l.rpc.SendLightClientBootstrapReqV1(finalized) - for err != nil || b == nil { - if err != nil { - log.Debug("[lightclient] SendLightClientBootstrapReqV1", "err", err) - } - b, err = l.rpc.SendLightClientBootstrapReqV1(finalized) - } - - doneLogCh <- struct{}{} - s, err := NewLightClientStore(finalized, b) - if err != nil { - log.Warn("[Checkpoint Sync] could not create/validate store", "err", err) - return err - } - - l.store = s - log.Info("Store Initialized successfully", - "slot", l.store.finalizedHeader.Slot, - "root", common.Bytes2Hex(l.store.finalizedHeader.Root[:])) - return nil -} diff --git a/cmd/lightclient/lightclient/execution.go b/cmd/lightclient/lightclient/execution.go deleted file mode 100644 index f71fc22e9e3..00000000000 --- a/cmd/lightclient/lightclient/execution.go +++ /dev/null @@ -1,116 +0,0 @@ -package lightclient - -import ( - "time" - - "github.com/holiman/uint256" - "github.com/ledgerwatch/erigon-lib/gointerfaces" - "github.com/ledgerwatch/erigon-lib/gointerfaces/remote" - "github.com/ledgerwatch/erigon-lib/gointerfaces/types" - - "github.com/ledgerwatch/erigon/cl/cltypes" - "github.com/ledgerwatch/erigon/ethdb/privateapi" -) - -func convertLightrpcExecutionPayloadToEthbacked(e *cltypes.Eth1Block) *types.ExecutionPayload { - var baseFee *uint256.Int - var ( - header = e.Header - body = e.Body - ) - - if e.Header.BaseFee != nil { - var overflow bool - baseFee, overflow = uint256.FromBig(header.BaseFee) - if overflow { - panic("NewPayload BaseFeePerGas overflow") - } - } - - res := &types.ExecutionPayload{ - Version: 1, - ParentHash: gointerfaces.ConvertHashToH256(header.ParentHash), - Coinbase: gointerfaces.ConvertAddressToH160(header.Coinbase), - StateRoot: gointerfaces.ConvertHashToH256(header.Root), - ReceiptRoot: gointerfaces.ConvertHashToH256(header.ReceiptHash), - LogsBloom: gointerfaces.ConvertBytesToH2048(header.Bloom[:]), - PrevRandao: gointerfaces.ConvertHashToH256(header.MixDigest), - BlockNumber: header.Number.Uint64(), - GasLimit: header.GasLimit, - GasUsed: header.GasUsed, - Timestamp: header.Time, - ExtraData: header.Extra, - BaseFeePerGas: gointerfaces.ConvertUint256IntToH256(baseFee), - BlockHash: gointerfaces.ConvertHashToH256(header.BlockHashCL), - Transactions: body.Transactions, - Withdrawals: privateapi.ConvertWithdrawalsToRpc(body.Withdrawals), - } - if body.Withdrawals != nil { - res.Version = 2 - res.Withdrawals = privateapi.ConvertWithdrawalsToRpc(body.Withdrawals) - } - - return res -} - -func (l *LightClient) processBeaconBlock(beaconBlock *cltypes.BeaconBlock) error { - if l.execution == nil && l.executionClient == nil { - return nil - } - // If we recently imported the beacon block, skip. - bcRoot, err := beaconBlock.HashSSZ() - if err != nil { - return err - } - if l.recentHashesCache.Contains(bcRoot) { - return nil - } - // Save as recent - l.recentHashesCache.Add(bcRoot, struct{}{}) - - payloadHash := gointerfaces.ConvertHashToH256(beaconBlock.Body.ExecutionPayload.Header.BlockHashCL) - - payload := convertLightrpcExecutionPayloadToEthbacked(beaconBlock.Body.ExecutionPayload) - - if l.execution != nil { - _, err = l.execution.EngineNewPayload(l.ctx, payload) - if err != nil { - return err - } - } - - if l.executionClient != nil { - _, err = l.executionClient.EngineNewPayload(l.ctx, payload) - if err != nil { - return err - } - } - - // Wait a bit - time.Sleep(500 * time.Millisecond) - if l.execution != nil { - _, err = l.execution.EngineForkChoiceUpdated(l.ctx, &remote.EngineForkChoiceUpdatedRequest{ - ForkchoiceState: &remote.EngineForkChoiceState{ - HeadBlockHash: payloadHash, - SafeBlockHash: payloadHash, - FinalizedBlockHash: gointerfaces.ConvertHashToH256(l.finalizedEth1Hash), - }, - }) - if err != nil { - return err - } - } - if l.executionClient != nil { - _, err = l.executionClient.EngineForkChoiceUpdated(l.ctx, &remote.EngineForkChoiceUpdatedRequest{ - ForkchoiceState: &remote.EngineForkChoiceState{ - HeadBlockHash: payloadHash, - SafeBlockHash: payloadHash, - FinalizedBlockHash: gointerfaces.ConvertHashToH256(l.finalizedEth1Hash), - }, - }) - if err != nil { - return err - } - } - return err -} diff --git a/cmd/lightclient/lightclient/lightclient.go b/cmd/lightclient/lightclient/lightclient.go deleted file mode 100644 index e0cc3780ba3..00000000000 --- a/cmd/lightclient/lightclient/lightclient.go +++ /dev/null @@ -1,268 +0,0 @@ -/* - Copyright 2022 Erigon-Lightclient contributors - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - http://www.apache.org/licenses/LICENSE-2.0 - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -*/ - -package lightclient - -import ( - "context" - "errors" - "runtime" - "time" - - lru "github.com/hashicorp/golang-lru" - common2 "github.com/ledgerwatch/erigon-lib/common" - "github.com/ledgerwatch/erigon-lib/common/dbg" - "github.com/ledgerwatch/erigon-lib/gointerfaces/remote" - "github.com/ledgerwatch/erigon-lib/gointerfaces/sentinel" - "github.com/ledgerwatch/erigon-lib/kv" - "github.com/ledgerwatch/log/v3" - - "github.com/ledgerwatch/erigon/cl/clparams" - "github.com/ledgerwatch/erigon/cl/cltypes" - "github.com/ledgerwatch/erigon/cl/rpc" - "github.com/ledgerwatch/erigon/cl/utils" - "github.com/ledgerwatch/erigon/cmd/erigon-cl/core/rawdb" -) - -const ( - maxRecentHashes = 5 // 0.16 KB - safetyRange = 16 // 16 block of safety - maxChainExtension = 8 // 8 blocks of chain extension -) - -type LightClient struct { - ctx context.Context - genesisConfig *clparams.GenesisConfig - beaconConfig *clparams.BeaconChainConfig - chainTip *ChainTipSubscriber - - verbose bool - highestSeen uint64 // Highest ETH1 block seen. - highestValidated uint64 // Highest ETH2 slot validated. - highestProcessedRoot common2.Hash // Highest processed ETH2 block root. - lastEth2ParentRoot common2.Hash // Last ETH2 Parent root. - finalizedEth1Hash common2.Hash - recentHashesCache *lru.Cache - db kv.RwDB - rpc *rpc.BeaconRpcP2P - // Either execution server or client - execution remote.ETHBACKENDServer - executionClient remote.ETHBACKENDClient - store *LightClientStore -} - -func NewLightClient(ctx context.Context, db kv.RwDB, genesisConfig *clparams.GenesisConfig, beaconConfig *clparams.BeaconChainConfig, - execution remote.ETHBACKENDServer, executionClient remote.ETHBACKENDClient, sentinel sentinel.SentinelClient, - highestSeen uint64, verbose bool) (*LightClient, error) { - recentHashesCache, err := lru.New(maxRecentHashes) - rpc := rpc.NewBeaconRpcP2P(ctx, sentinel, beaconConfig, genesisConfig) - return &LightClient{ - ctx: ctx, - beaconConfig: beaconConfig, - genesisConfig: genesisConfig, - chainTip: NewChainTipSubscriber(ctx, beaconConfig, genesisConfig, sentinel), - recentHashesCache: recentHashesCache, - rpc: rpc, - execution: execution, - verbose: verbose, - highestSeen: highestSeen, - db: db, - executionClient: executionClient, - }, err -} - -func (l *LightClient) Start() { - if l.store == nil { - log.Error("No trusted setup") - return - } - tx, err := l.db.BeginRw(l.ctx) - if err != nil { - log.Error("Could not open MDBX transaction", "err", err) - return - } - defer tx.Rollback() - logPeers := time.NewTicker(time.Minute) - - go l.chainTip.StartLoop() - for { - start := time.Now() - var ( - updates = []*cltypes.LightClientUpdate{} - finalizedPeriod = utils.SlotToPeriod(l.store.finalizedHeader.Slot) - optimisticPeriod = utils.SlotToPeriod(l.store.optimisticHeader.Slot) - currentSlot = utils.GetCurrentSlot(l.genesisConfig.GenesisTime, l.beaconConfig.SecondsPerSlot) - currentPeriod = utils.SlotToPeriod(currentSlot) - ) - - switch { - // Clause 4 (i): - // if finalized period == optimistic period and the next sync committee is unknown, - // fetch the corresponding lightclient update for this cycle - case finalizedPeriod == optimisticPeriod && l.store.nextSyncCommittee == nil: - update, err := l.FetchUpdate(l.ctx, finalizedPeriod) - if err != nil { - log.Error("[LightClient] Could not fetch lightclient update", "reason", err) - } else { - updates = append(updates, update) - } - // Clause 4 (ii): - // When finalized_period + 1 < current_period, the light client fetches a LightClientUpdate - // for each sync committee period in range [finalized_period + 1, current_period) - case finalizedPeriod+1 < currentPeriod: - for period := finalizedPeriod + 1; period < currentPeriod; period++ { - update, err := l.FetchUpdate(l.ctx, period) - if err != nil { - log.Error("[LightClient] Could not fetch lightclient update, truncating sync session...", - "period", period, "reason", err) - break - } else { - updates = append(updates, update) - } - } - // Clause 4 (iii): - // When finalized_period + 1 >= current_period, the light client keeps observing LightClientFinalityUpdate and LightClientOptimisticUpdate. - // Received objects are passed to process_light_client_update. This ensures that finalized_header and - // optimistic_header reflect the latest blocks. - case finalizedPeriod+1 >= currentPeriod: - newUpdate := l.chainTip.PopLastUpdate() - if newUpdate != nil { - updates = append(updates, newUpdate) - } - } - - // Push updates - for _, update := range updates { - err := l.processLightClientUpdate(update) - if err != nil { - log.Warn("Could not validate update", "err", err) - updates = []*cltypes.LightClientUpdate{} - break - } - } - // log new validated segment - if len(updates) > 0 { - lastValidated := updates[len(updates)-1] - l.highestValidated = lastValidated.AttestedHeader.HeaderEth2.Slot - l.highestProcessedRoot, err = lastValidated.AttestedHeader.HeaderEth2.HashSSZ() - if err != nil { - log.Warn("could not compute root", "err", err) - continue - } - // Save to Database - if lastValidated.HasNextSyncCommittee() { - if err := rawdb.WriteLightClientUpdate(tx, lastValidated); err != nil { - log.Warn("Could not write lightclient update to db", "err", err) - } - } - if lastValidated.IsFinalityUpdate() { - if err := rawdb.WriteLightClientFinalityUpdate(tx, &cltypes.LightClientFinalityUpdate{ - AttestedHeader: lastValidated.AttestedHeader, - FinalizedHeader: lastValidated.FinalizedHeader, - FinalityBranch: lastValidated.FinalityBranch, - SyncAggregate: lastValidated.SyncAggregate, - SignatureSlot: lastValidated.SignatureSlot, - }); err != nil { - log.Warn("Could not write finality lightclient update to db", "err", err) - } - } - if err := rawdb.WriteLightClientOptimisticUpdate(tx, &cltypes.LightClientOptimisticUpdate{ - AttestedHeader: lastValidated.AttestedHeader, - SyncAggregate: lastValidated.SyncAggregate, - SignatureSlot: lastValidated.SignatureSlot, - }); err != nil { - log.Warn("Could not write optimistic lightclient update to db", "err", err) - } - - if err := tx.Commit(); err != nil { - log.Error("[LightClient] could not commit to database", "err", err) - return - } - tx, err = l.db.BeginRw(l.ctx) - if err != nil { - log.Error("[LightClient] could not begin database transaction", "err", err) - return - } - defer tx.Rollback() - - if l.verbose { - var m runtime.MemStats - dbg.ReadMemStats(&m) - log.Info("[LightClient] Validated Chain Segments", - "elapsed", time.Since(start), "from", updates[0].AttestedHeader.HeaderEth2.Slot-1, - "to", lastValidated.AttestedHeader.HeaderEth2.Slot, "alloc", common2.ByteCount(m.Alloc), "sys", common2.ByteCount(m.Sys)) - } - } - l.importBlockIfPossible() - // do not have high CPU load - timer := time.NewTimer(200 * time.Millisecond) - select { - case <-timer.C: - case <-logPeers.C: - peers, err := l.rpc.Peers() - if err != nil { - if errors.Is(err, context.Canceled) { - return - } - log.Warn("could not read peers", "err", err) - continue - } - log.Info("[LightClient] P2P", "peers", peers) - case <-l.ctx.Done(): - return - } - } -} - -func (l *LightClient) importBlockIfPossible() { - var err error - curr := l.chainTip.GetLastBlock() - if curr == nil { - return - } - // Skip if we are too far ahead without validating - if curr.Slot > l.highestValidated+maxChainExtension { - return - } - currentRoot, err := curr.HashSSZ() - if err != nil { - log.Warn("Could not send beacon block to ETH1", "err", err) - return - } - - if (curr.Slot+1)%l.beaconConfig.SlotsPerEpoch == 0 { - l.finalizedEth1Hash = curr.Body.ExecutionPayload.Header.BlockHashCL - } - - if l.lastEth2ParentRoot != l.highestProcessedRoot && l.highestProcessedRoot != curr.ParentRoot { - l.lastEth2ParentRoot = curr.ParentRoot - return - } - l.lastEth2ParentRoot = curr.ParentRoot - l.highestProcessedRoot = currentRoot - - eth1Number := curr.Body.ExecutionPayload.NumberU64() - if l.highestSeen != 0 && (l.highestSeen > safetyRange && eth1Number < l.highestSeen-safetyRange) { - return - } - if l.verbose { - log.Info("Processed block", "slot", curr.Body.ExecutionPayload.NumberU64()) - } - - // If all of the above is gud then do the push - if err := l.processBeaconBlock(curr); err != nil { - log.Warn("Could not send beacon block to ETH1", "err", err) - } else { - l.highestSeen = eth1Number - } -} diff --git a/cmd/lightclient/lightclient/process_updates.go b/cmd/lightclient/lightclient/process_updates.go deleted file mode 100644 index 5167afea910..00000000000 --- a/cmd/lightclient/lightclient/process_updates.go +++ /dev/null @@ -1,111 +0,0 @@ -package lightclient - -import ( - "fmt" - - "github.com/ledgerwatch/erigon/cl/cltypes" - "github.com/ledgerwatch/erigon/cl/utils" -) - -func (l *LightClient) isBetterUpdate(oldUpdate *cltypes.LightClientUpdate, newUpdate *cltypes.LightClientUpdate) bool { - var ( - maxActiveParticipants = len(newUpdate.SyncAggregate.SyncCommiteeBits) * 8 // Bits - newActiveParticipants = newUpdate.SyncAggregate.Sum() - oldActiveParticipants = oldUpdate.SyncAggregate.Sum() - newHasSuperMajority = newActiveParticipants*3 >= maxActiveParticipants*2 - oldHasSuperMajority = oldActiveParticipants*3 >= maxActiveParticipants*2 - ) - - // Compare supermajority (> 2/3) sync committee participation - if newHasSuperMajority != oldHasSuperMajority { - return newHasSuperMajority && !oldHasSuperMajority - } - - if !newHasSuperMajority && newActiveParticipants != oldActiveParticipants { - return newActiveParticipants > oldActiveParticipants - } - - // Compare presence of relevant sync committee - isNewUpdateRelevant := newUpdate.HasNextSyncCommittee() && - utils.SlotToPeriod(newUpdate.AttestedHeader.HeaderEth2.Slot) == utils.SlotToPeriod(newUpdate.SignatureSlot) - isOldUpdateRelevant := oldUpdate.HasNextSyncCommittee() && - utils.SlotToPeriod(oldUpdate.AttestedHeader.HeaderEth2.Slot) == utils.SlotToPeriod(oldUpdate.SignatureSlot) - - if isNewUpdateRelevant != isOldUpdateRelevant { - return isNewUpdateRelevant - } - - isNewFinality := newUpdate.IsFinalityUpdate() - isOldFinality := oldUpdate.IsFinalityUpdate() - - if isNewFinality != isOldFinality { - return isNewFinality - } - - // Compare sync committee finality - if isNewFinality && newUpdate.HasSyncFinality() != oldUpdate.HasSyncFinality() { - return newUpdate.HasSyncFinality() - } - - // Tie Breakers - if newActiveParticipants != oldActiveParticipants { - return newActiveParticipants > oldActiveParticipants - } - if newUpdate.AttestedHeader.HeaderEth2.Slot != oldUpdate.AttestedHeader.HeaderEth2.Slot { - return newUpdate.AttestedHeader.HeaderEth2.Slot < oldUpdate.AttestedHeader.HeaderEth2.Slot - } - return newUpdate.SignatureSlot < oldUpdate.SignatureSlot -} - -func (l *LightClient) applyLightClientUpdate(update *cltypes.LightClientUpdate) error { - storePeriod := utils.SlotToPeriod(l.store.finalizedHeader.Slot) - finalizedPeriod := utils.SlotToPeriod(update.FinalizedHeader.HeaderEth2.Slot) - if l.store.nextSyncCommittee == nil { - if storePeriod != finalizedPeriod { - return fmt.Errorf("periods shall be matching") - } - l.store.nextSyncCommittee = update.NextSyncCommitee - } else if finalizedPeriod == storePeriod+1 { - l.store.currentSyncCommittee = l.store.nextSyncCommittee - l.store.nextSyncCommittee = update.NextSyncCommitee - l.store.previousMaxActivePartecipants = l.store.currentMaxActivePartecipants - l.store.currentMaxActivePartecipants = 0 - } - if update.FinalizedHeader.HeaderEth2.Slot > l.store.finalizedHeader.Slot { - l.store.finalizedHeader = update.FinalizedHeader.HeaderEth2 - if update.FinalizedHeader.HeaderEth2.Slot > l.store.optimisticHeader.Slot { - l.store.optimisticHeader = update.FinalizedHeader.HeaderEth2 - } - } - return nil -} - -func (l *LightClient) processLightClientUpdate(update *cltypes.LightClientUpdate) error { - valid, err := l.validateUpdate(update) - if err != nil { - return err - } - if !valid { - return fmt.Errorf("BLS validation failed") - } - - if l.store.bestValidUpdate == nil || l.isBetterUpdate(update, l.store.bestValidUpdate) { - l.store.bestValidUpdate = update - } - updateParticipants := uint64(update.SyncAggregate.Sum()) - if updateParticipants > l.store.currentMaxActivePartecipants { - l.store.currentMaxActivePartecipants = updateParticipants - } - - // Apply lc update (should happen when every 27 hours) - if update.SyncAggregate.Sum()*3 >= len(update.SyncAggregate.SyncCommiteeBits)*16 && - ((update.IsFinalityUpdate() && update.FinalizedHeader.HeaderEth2.Slot > l.store.finalizedHeader.Slot) || - l.store.nextSyncCommittee == nil && update.HasNextSyncCommittee() && - update.IsFinalityUpdate() && update.HasSyncFinality()) { - // Conditions are met so we can make all changes - err = l.applyLightClientUpdate(update) - l.store.bestValidUpdate = nil - } - - return err -} diff --git a/cmd/lightclient/lightclient/request.go b/cmd/lightclient/lightclient/request.go deleted file mode 100644 index 14c6606aefc..00000000000 --- a/cmd/lightclient/lightclient/request.go +++ /dev/null @@ -1,26 +0,0 @@ -package lightclient - -import ( - "context" - - "github.com/ledgerwatch/erigon/cl/cltypes" - "github.com/ledgerwatch/log/v3" -) - -func (l *LightClient) FetchUpdate(ctx context.Context, period uint64) (*cltypes.LightClientUpdate, error) { - log.Info("[Lightclient] Fetching Sync Committee Period", "period", period) - var ( - update *cltypes.LightClientUpdate - err error - ) - for update == nil { - update, err = l.rpc.SendLightClientUpdatesReqV1(period) - if err != nil { - log.Trace("[Checkpoint Sync] could not retrieve bootstrap", "err", err) - return nil, err - } - } - - return update, nil - -} diff --git a/cmd/lightclient/lightclient/store.go b/cmd/lightclient/lightclient/store.go deleted file mode 100644 index efb27b1bb35..00000000000 --- a/cmd/lightclient/lightclient/store.go +++ /dev/null @@ -1,65 +0,0 @@ -package lightclient - -import ( - "fmt" - - "github.com/ledgerwatch/erigon/cl/cltypes" - "github.com/ledgerwatch/erigon/cl/utils" -) - -type LightClientStore struct { - // Beacon block header that is finalized - finalizedHeader *cltypes.BeaconBlockHeader - // Most recent available reasonably-safe header - optimisticHeader *cltypes.BeaconBlockHeader - - // Sync committees corresponding to the header - currentSyncCommittee *cltypes.SyncCommittee - nextSyncCommittee *cltypes.SyncCommittee - - // Best available header to switch finalized head to if we see nothing else - bestValidUpdate *cltypes.LightClientUpdate - - // Max number of active participants in a sync committee (used to calculate safety threshold) - previousMaxActivePartecipants uint64 - currentMaxActivePartecipants uint64 -} - -/* - * A light client maintains its state in a store object of type LightClientStore. - * initialize_light_client_store initializes a new store with a - * received LightClientBootstrap derived from a given trusted_block_root. - */ -func NewLightClientStore(trustedRoot [32]byte, bootstrap *cltypes.LightClientBootstrap) (*LightClientStore, error) { - headerRoot, err := bootstrap.Header.HeaderEth2.HashSSZ() - if err != nil { - return nil, err - } - if headerRoot != trustedRoot { - return nil, fmt.Errorf("trusted root is mismatching, headerRoot: %x, trustedRoot: %x", - headerRoot, trustedRoot) - } - - syncCommitteeRoot, err := bootstrap.CurrentSyncCommittee.HashSSZ() - if err != nil { - return nil, err - } - if !utils.IsValidMerkleBranch( - syncCommitteeRoot, - bootstrap.CurrentSyncCommitteeBranch, - 5, // floorlog2(CURRENT_SYNC_COMMITTEE_INDEX) - 22, // get_subtree_index(CURRENT_SYNC_COMMITTEE_INDEX), - bootstrap.Header.HeaderEth2.Root, - ) { - return nil, fmt.Errorf("invalid sync committee") - } - - return &LightClientStore{ - finalizedHeader: bootstrap.Header.HeaderEth2, - currentSyncCommittee: bootstrap.CurrentSyncCommittee, - nextSyncCommittee: nil, - optimisticHeader: bootstrap.Header.HeaderEth2, - previousMaxActivePartecipants: 0, - currentMaxActivePartecipants: 0, - }, nil -} diff --git a/cmd/lightclient/lightclient/subscriber.go b/cmd/lightclient/lightclient/subscriber.go deleted file mode 100644 index 9eb148cb115..00000000000 --- a/cmd/lightclient/lightclient/subscriber.go +++ /dev/null @@ -1,145 +0,0 @@ -package lightclient - -import ( - "context" - "errors" - "fmt" - "sync" - - "github.com/ledgerwatch/erigon-lib/gointerfaces/sentinel" - "github.com/ledgerwatch/erigon/cl/clparams" - "github.com/ledgerwatch/erigon/cl/cltypes" - "github.com/ledgerwatch/erigon/cl/utils" - "github.com/ledgerwatch/log/v3" -) - -// ChainTipSubscriber tells us what are the newly received gossip arguments -type ChainTipSubscriber struct { - ctx context.Context - - currBlock *cltypes.BeaconBlock // Most recent gossipped block - - lastUpdate *cltypes.LightClientUpdate - started bool - sentinel sentinel.SentinelClient - beaconConfig *clparams.BeaconChainConfig - genesisConfig *clparams.GenesisConfig - lastReceivedSlot uint64 - - mu sync.Mutex -} - -func NewChainTipSubscriber(ctx context.Context, beaconConfig *clparams.BeaconChainConfig, genesisConfig *clparams.GenesisConfig, sentinel sentinel.SentinelClient) *ChainTipSubscriber { - return &ChainTipSubscriber{ - ctx: ctx, - started: false, - sentinel: sentinel, - genesisConfig: genesisConfig, - beaconConfig: beaconConfig, - } -} - -func (c *ChainTipSubscriber) StartLoop() { - if c.started { - log.Error("Chain tip subscriber already started") - return - } - log.Info("[LightClient Gossip] Started Gossip") - c.started = true - stream, err := c.sentinel.SubscribeGossip(c.ctx, &sentinel.EmptyMessage{}) - if err != nil { - log.Warn("could not start lightclient", "reason", err) - return - } - defer stream.CloseSend() - - for { - data, err := stream.Recv() - if err != nil { - if !errors.Is(err, context.Canceled) { - log.Debug("[Lightclient] could not read gossip :/", "reason", err) - } - continue - } - if err := c.handleGossipData(data); err != nil { - log.Warn("could not process new gossip", - "gossipType", data.Type, "reason", err) - } - } -} - -func (c *ChainTipSubscriber) handleGossipData(data *sentinel.GossipData) error { - c.mu.Lock() - defer c.mu.Unlock() - - currentEpoch := utils.GetCurrentEpoch(c.genesisConfig.GenesisTime, c.beaconConfig.SecondsPerSlot, c.beaconConfig.SlotsPerEpoch) - version := c.beaconConfig.GetCurrentStateVersion(currentEpoch) - - switch data.Type { - case sentinel.GossipType_BeaconBlockGossipType: - block := &cltypes.SignedBeaconBlock{} - if err := block.DecodeSSZWithVersion(data.Data, int(version)); err != nil { - return fmt.Errorf("could not unmarshall block: %s", err) - } - - c.currBlock = block.Block - c.lastReceivedSlot = block.Block.Slot - case sentinel.GossipType_LightClientFinalityUpdateGossipType: - finalityUpdate := &cltypes.LightClientFinalityUpdate{} - if err := finalityUpdate.DecodeSSZWithVersion(data.Data, int(version)); err != nil { - return fmt.Errorf("could not unmarshall finality update: %s", err) - } - c.lastUpdate = &cltypes.LightClientUpdate{ - AttestedHeader: finalityUpdate.AttestedHeader, - NextSyncCommitee: nil, - NextSyncCommitteeBranch: nil, - FinalizedHeader: finalityUpdate.FinalizedHeader, - FinalityBranch: finalityUpdate.FinalityBranch, - SyncAggregate: finalityUpdate.SyncAggregate, - SignatureSlot: finalityUpdate.SignatureSlot, - } - case sentinel.GossipType_LightClientOptimisticUpdateGossipType: - if c.lastUpdate != nil && c.lastUpdate.IsFinalityUpdate() { - // We already have a finality update, we can skip this one - return nil - } - - optimisticUpdate := &cltypes.LightClientOptimisticUpdate{} - if err := optimisticUpdate.DecodeSSZWithVersion(data.Data, int(version)); err != nil { - return fmt.Errorf("could not unmarshall optimistic update: %s", err) - } - c.lastUpdate = &cltypes.LightClientUpdate{ - AttestedHeader: optimisticUpdate.AttestedHeader, - NextSyncCommitee: nil, - NextSyncCommitteeBranch: nil, - FinalizedHeader: nil, - FinalityBranch: nil, - SyncAggregate: optimisticUpdate.SyncAggregate, - SignatureSlot: optimisticUpdate.SignatureSlot, - } - default: - } - return nil -} - -func (c *ChainTipSubscriber) PopLastUpdate() *cltypes.LightClientUpdate { - c.mu.Lock() - defer c.mu.Unlock() - update := c.lastUpdate - c.lastUpdate = nil - return update -} - -func (c *ChainTipSubscriber) GetLastBlock() *cltypes.BeaconBlock { - c.mu.Lock() - defer c.mu.Unlock() - // Check if we are up to date - currentSlot := utils.GetCurrentSlot(c.genesisConfig.GenesisTime, c.beaconConfig.SecondsPerSlot) - // Gossip failed use the rpc and attempt to retrieve last block. - if c.lastReceivedSlot != currentSlot { - return nil - } - block := c.currBlock - c.currBlock = nil - return block -} diff --git a/cmd/lightclient/lightclient/verify.go b/cmd/lightclient/lightclient/verify.go deleted file mode 100644 index 46a6abb4bf9..00000000000 --- a/cmd/lightclient/lightclient/verify.go +++ /dev/null @@ -1,110 +0,0 @@ -package lightclient - -import ( - "fmt" - - "github.com/Giulio2002/bls" - "github.com/ledgerwatch/erigon/cl/cltypes" - "github.com/ledgerwatch/erigon/cl/fork" - "github.com/ledgerwatch/erigon/cl/utils" - "github.com/ledgerwatch/erigon/common" -) - -const MinSyncCommitteeParticipants = 1 - -var DomainSyncCommittee = common.Hex2Bytes("07000000") - -func (l *LightClient) validateUpdate(update *cltypes.LightClientUpdate) (bool, error) { - if update.SyncAggregate.Sum() < MinSyncCommitteeParticipants { - return false, fmt.Errorf("not enough participants") - } - isNextSyncCommitteeKnown := l.store.nextSyncCommittee != nil - // Check if the timings and slot are valid - current_slot := utils.GetCurrentSlot(l.genesisConfig.GenesisTime, l.beaconConfig.SecondsPerSlot) - if current_slot < update.SignatureSlot || update.SignatureSlot <= update.AttestedHeader.HeaderEth2.Slot || - (update.IsFinalityUpdate() && update.AttestedHeader.HeaderEth2.Slot < update.FinalizedHeader.HeaderEth2.Slot) { - return false, fmt.Errorf("too far in the future") - } - storePeriod := utils.SlotToPeriod(l.store.finalizedHeader.Slot) - updateSignaturePeriod := utils.SlotToPeriod(update.SignatureSlot) - - if !isNextSyncCommitteeKnown && - updateSignaturePeriod != storePeriod && updateSignaturePeriod != storePeriod+1 { - return false, fmt.Errorf("mismatching periods") - } - - // Verify whether update is relevant - attestedPeriod := utils.SlotToPeriod(update.AttestedHeader.HeaderEth2.Slot) - hasNextSyncCommittee := l.store.nextSyncCommittee == nil && - update.HasNextSyncCommittee() && attestedPeriod == storePeriod - - if update.AttestedHeader.HeaderEth2.Slot <= l.store.finalizedHeader.Slot && !hasNextSyncCommittee { - return false, fmt.Errorf("invalid sync committee") - } - - // Verify that the `finality_branch`, if present, confirms `finalized_header` - if update.IsFinalityUpdate() { - finalizedRoot, err := update.FinalizedHeader.HeaderEth2.HashSSZ() - if err != nil { - return false, err - } - if !utils.IsValidMerkleBranch( - finalizedRoot, - update.FinalityBranch, - 6, // floorlog2(FINALIZED_ROOT_INDEX) - 41, // get_subtree_index(FINALIZED_ROOT_INDEX), - update.AttestedHeader.HeaderEth2.Root, - ) { - return false, fmt.Errorf("update is not part of the merkle tree") - } - } - if update.HasNextSyncCommittee() { - if attestedPeriod == storePeriod && isNextSyncCommitteeKnown && - !update.NextSyncCommitee.Equal(l.store.nextSyncCommittee) { - return false, fmt.Errorf("mismatching sync committee") - } - syncRoot, err := update.NextSyncCommitee.HashSSZ() - if err != nil { - return false, err - } - if !utils.IsValidMerkleBranch( - syncRoot, - update.NextSyncCommitteeBranch, - 5, // floorlog2(NEXT_SYNC_COMMITTEE_INDEX) - 23, // get_subtree_index(NEXT_SYNC_COMMITTEE_INDEX), - update.AttestedHeader.HeaderEth2.Root, - ) { - return false, fmt.Errorf("sync committee is not part of the merkle tree") - } - } - var syncCommittee *cltypes.SyncCommittee - if updateSignaturePeriod == storePeriod { - syncCommittee = l.store.currentSyncCommittee - } else { - syncCommittee = l.store.nextSyncCommittee - } - syncAggregateBits := update.SyncAggregate.SyncCommiteeBits - - var pubkeys [][]byte - currPubKeyIndex := 0 - for i := range syncAggregateBits { - for bit := 1; bit <= 128; bit *= 2 { - if syncAggregateBits[i]&byte(bit) > 0 { - pubkeys = append(pubkeys, syncCommittee.PubKeys[currPubKeyIndex][:]) - } - currPubKeyIndex++ - } - } - // Support only post-bellatrix forks - forkVersion := fork.GetLastFork(l.beaconConfig, l.genesisConfig) - domain, err := fork.ComputeDomain(DomainSyncCommittee, forkVersion, l.genesisConfig.GenesisValidatorRoot) - if err != nil { - return false, err - } - // Computing signing root - signingRoot, err := fork.ComputeSigningRoot(update.AttestedHeader.HeaderEth2, domain) - if err != nil { - return false, err - } - return bls.VerifyAggregate(update.SyncAggregate.SyncCommiteeSignature[:], signingRoot[:], pubkeys) -} diff --git a/cmd/observer/database/db_sqlite.go b/cmd/observer/database/db_sqlite.go index 0823b3715ac..ba056fbe8c1 100644 --- a/cmd/observer/database/db_sqlite.go +++ b/cmd/observer/database/db_sqlite.go @@ -9,6 +9,7 @@ import ( "strings" "time" + "github.com/ledgerwatch/erigon/cmd/utils" _ "modernc.org/sqlite" ) @@ -708,7 +709,7 @@ func (db *DBSQLite) FindNeighborBucketKeys(ctx context.Context, id NodeID) ([]st if !keysStr.Valid { return nil, nil } - return strings.Split(keysStr.String, ","), nil + return utils.SplitAndTrim(keysStr.String), nil } func (db *DBSQLite) UpdateSentryCandidatesLastEventTime(ctx context.Context, value time.Time) error { diff --git a/cmd/p2psim/main.go b/cmd/p2psim/main.go index 0dd4e5d8529..b2e83339ed8 100644 --- a/cmd/p2psim/main.go +++ b/cmd/p2psim/main.go @@ -44,6 +44,7 @@ import ( "strings" "text/tabwriter" + "github.com/ledgerwatch/erigon/cmd/utils" "github.com/urfave/cli/v2" "github.com/ledgerwatch/erigon/crypto" @@ -289,7 +290,7 @@ func createNode(ctx *cli.Context) error { config.PrivateKey = privKey } if services := ctx.String("services"); services != "" { - config.Lifecycles = strings.Split(services, ",") + config.Lifecycles = utils.SplitAndTrim(services) } node, err := client.CreateNode(config) if err != nil { diff --git a/cmd/prometheus/dashboards/erigon.json b/cmd/prometheus/dashboards/erigon.json index 37317c6ceea..1995cfe875e 100644 --- a/cmd/prometheus/dashboards/erigon.json +++ b/cmd/prometheus/dashboards/erigon.json @@ -30,8 +30,7 @@ "panels": [ { "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" + "type": "prometheus" }, "gridPos": { "h": 1, @@ -43,8 +42,7 @@ "targets": [ { "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" + "type": "prometheus" }, "refId": "A" } @@ -54,8 +52,7 @@ }, { "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" + "type": "prometheus" }, "fieldConfig": { "defaults": { @@ -112,7 +109,7 @@ "overrides": [] }, "gridPos": { - "h": 7, + "h": 10, "w": 8, "x": 0, "y": 1 @@ -137,15 +134,16 @@ "targets": [ { "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" + "type": "prometheus" }, + "editorMode": "code", "exemplar": true, "expr": "sync{instance=~\"$instance\"}", "format": "time_series", "interval": "", "intervalFactor": 1, "legendFormat": "{{ stage }}: {{instance}}", + "range": true, "refId": "A" } ], @@ -154,8 +152,7 @@ }, { "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" + "type": "prometheus" }, "fieldConfig": { "defaults": { @@ -236,15 +233,16 @@ "targets": [ { "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" + "type": "prometheus" }, + "editorMode": "code", "exemplar": true, "expr": "rate(sync{instance=~\"$instance\"}[$rate_interval])", "format": "time_series", "interval": "", "intervalFactor": 1, "legendFormat": "{{ stage }}: {{instance}}", + "range": true, "refId": "A" } ], @@ -253,8 +251,7 @@ }, { "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" + "type": "prometheus" }, "fieldConfig": { "defaults": { @@ -305,7 +302,7 @@ } ] }, - "unit": "s" + "unit": "ops" }, "overrides": [] }, @@ -315,6 +312,105 @@ "x": 16, "y": 1 }, + "id": 195, + "links": [], + "options": { + "legend": { + "calcs": [ + "mean" + ], + "displayMode": "list", + "placement": "bottom", + "showLegend": true + }, + "tooltip": { + "mode": "multi", + "sort": "none" + } + }, + "pluginVersion": "8.0.6", + "targets": [ + { + "datasource": { + "type": "prometheus" + }, + "editorMode": "code", + "exemplar": true, + "expr": "rate(exec_txs_done{instance=~\"$instance\"}[$rate_interval])", + "format": "time_series", + "interval": "", + "intervalFactor": 1, + "legendFormat": "txs apply: {{instance}}", + "range": true, + "refId": "A" + } + ], + "title": "Exec v3: txs/s ", + "type": "timeseries" + }, + { + "datasource": { + "type": "prometheus" + }, + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisCenteredZero": false, + "axisColorMode": "text", + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "drawStyle": "line", + "fillOpacity": 10, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "lineInterpolation": "linear", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "never", + "spanNulls": true, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "red", + "value": 80 + } + ] + }, + "unit": "s" + }, + "overrides": [] + }, + "gridPos": { + "h": 5, + "w": 8, + "x": 8, + "y": 6 + }, "id": 112, "links": [], "options": { @@ -336,8 +432,7 @@ "targets": [ { "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" + "type": "prometheus" }, "exemplar": true, "expr": "chain_execution_seconds{quantile=\"$quantile\",instance=~\"$instance\"}", @@ -351,25 +446,138 @@ "title": "Block Execution speed ", "type": "timeseries" }, + { + "datasource": { + "type": "prometheus" + }, + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisCenteredZero": false, + "axisColorMode": "text", + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "drawStyle": "line", + "fillOpacity": 10, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "lineInterpolation": "linear", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "never", + "spanNulls": true, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "decimals": 2, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "red", + "value": 80 + } + ] + }, + "unit": "percentunit" + }, + "overrides": [] + }, + "gridPos": { + "h": 5, + "w": 8, + "x": 16, + "y": 6 + }, + "id": 194, + "links": [], + "options": { + "legend": { + "calcs": [ + "mean" + ], + "displayMode": "list", + "placement": "bottom", + "showLegend": true + }, + "tooltip": { + "mode": "multi", + "sort": "none" + } + }, + "pluginVersion": "8.0.6", + "targets": [ + { + "datasource": { + "type": "prometheus" + }, + "editorMode": "code", + "exemplar": true, + "expr": "rate(exec_repeats{instance=~\"$instance\"}[$rate_interval])/rate(exec_txs_done{instance=~\"$instance\"}[$rate_interval])", + "format": "time_series", + "interval": "", + "intervalFactor": 1, + "legendFormat": "repeats: {{instance}}", + "range": true, + "refId": "A" + }, + { + "datasource": { + "type": "prometheus" + }, + "editorMode": "code", + "exemplar": true, + "expr": "rate(exec_triggers{instance=~\"$instance\"}[$rate_interval])/rate(exec_txs_done{instance=~\"$instance\"}[$rate_interval])", + "format": "time_series", + "hide": false, + "interval": "", + "intervalFactor": 1, + "legendFormat": "triggers: {{instance}}", + "range": true, + "refId": "B" + } + ], + "title": "Exec v3", + "type": "timeseries" + }, { "collapsed": false, "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" + "type": "prometheus" }, "gridPos": { "h": 1, "w": 24, "x": 0, - "y": 8 + "y": 11 }, "id": 17, "panels": [], "targets": [ { "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" + "type": "prometheus" }, "refId": "A" } @@ -379,8 +587,7 @@ }, { "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" + "type": "prometheus" }, "fieldConfig": { "defaults": { @@ -439,7 +646,7 @@ "h": 5, "w": 8, "x": 0, - "y": 9 + "y": 12 }, "id": 141, "options": { @@ -458,8 +665,7 @@ "targets": [ { "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" + "type": "prometheus" }, "exemplar": true, "expr": "rate(db_commit_seconds_count{phase=\"total\",instance=~\"$instance\"}[$rate_interval])", @@ -473,8 +679,7 @@ }, { "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" + "type": "prometheus" }, "description": "", "fieldConfig": { @@ -534,7 +739,7 @@ "h": 9, "w": 16, "x": 8, - "y": 9 + "y": 12 }, "id": 166, "options": { @@ -555,8 +760,7 @@ "targets": [ { "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" + "type": "prometheus" }, "editorMode": "code", "exemplar": true, @@ -568,8 +772,7 @@ }, { "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" + "type": "prometheus" }, "editorMode": "code", "exemplar": true, @@ -582,8 +785,7 @@ }, { "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" + "type": "prometheus" }, "editorMode": "code", "exemplar": true, @@ -596,8 +798,7 @@ }, { "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" + "type": "prometheus" }, "editorMode": "code", "exemplar": true, @@ -610,8 +811,7 @@ }, { "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" + "type": "prometheus" }, "editorMode": "code", "exemplar": true, @@ -624,8 +824,7 @@ }, { "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" + "type": "prometheus" }, "editorMode": "code", "exemplar": true, @@ -638,8 +837,7 @@ }, { "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" + "type": "prometheus" }, "editorMode": "code", "exemplar": true, @@ -652,8 +850,7 @@ }, { "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" + "type": "prometheus" }, "editorMode": "code", "exemplar": true, @@ -666,8 +863,7 @@ }, { "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" + "type": "prometheus" }, "editorMode": "code", "exemplar": true, @@ -680,8 +876,7 @@ }, { "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" + "type": "prometheus" }, "editorMode": "code", "exemplar": true, @@ -694,8 +889,7 @@ }, { "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" + "type": "prometheus" }, "editorMode": "code", "exemplar": true, @@ -708,8 +902,7 @@ }, { "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" + "type": "prometheus" }, "editorMode": "code", "exemplar": true, @@ -722,8 +915,7 @@ }, { "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" + "type": "prometheus" }, "editorMode": "code", "exemplar": true, @@ -740,8 +932,7 @@ }, { "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" + "type": "prometheus" }, "fieldConfig": { "defaults": { @@ -794,60 +985,32 @@ }, "unit": "decbytes" }, - "overrides": [ - { - "__systemRef": "hideSeriesFrom", - "matcher": { - "id": "byNames", - "options": { - "mode": "exclude", - "names": [ - "db_mi_last_pgno: bsc-sn3-2:6061" - ], - "prefix": "All except:", - "readOnly": true - } - }, - "properties": [ - { - "id": "custom.hideFrom", - "value": { - "legend": false, - "tooltip": false, - "viz": true - } - } - ] - } - ] + "overrides": [] }, "gridPos": { "h": 5, "w": 8, "x": 0, - "y": 14 + "y": 17 }, "id": 159, "options": { "legend": { - "calcs": [ - "lastNotNull" - ], + "calcs": [], "displayMode": "list", "placement": "bottom", "showLegend": true }, "tooltip": { - "mode": "single", + "mode": "multi", "sort": "none" } }, - "pluginVersion": "8.0.6", + "pluginVersion": "8.4.7", "targets": [ { "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" + "type": "prometheus" }, "expr": "db_size{instance=~\"$instance\"}", "interval": "", @@ -856,8 +1019,7 @@ }, { "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" + "type": "prometheus" }, "editorMode": "code", "expr": "db_mi_last_pgno{instance=~\"$instance\"}", @@ -873,8 +1035,7 @@ }, { "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" + "type": "prometheus" }, "fieldConfig": { "defaults": { @@ -888,7 +1049,7 @@ "axisPlacement": "auto", "barAlignment": 0, "drawStyle": "line", - "fillOpacity": 10, + "fillOpacity": 25, "gradientMode": "none", "hideFrom": { "legend": false, @@ -901,11 +1062,11 @@ "scaleDistribution": { "type": "linear" }, - "showPoints": "never", - "spanNulls": true, + "showPoints": "auto", + "spanNulls": false, "stacking": { "group": "A", - "mode": "none" + "mode": "normal" }, "thresholdsStyle": { "mode": "off" @@ -916,36 +1077,34 @@ "mode": "absolute", "steps": [ { - "color": "green" + "color": "green", + "value": null }, { "color": "red", "value": 80 } ] - }, - "unit": "short" + } }, "overrides": [] }, "gridPos": { - "h": 6, + "h": 7, "w": 16, "x": 8, - "y": 18 + "y": 21 }, - "id": 192, + "id": 168, "options": { "legend": { - "calcs": [ - "mean" - ], + "calcs": [], "displayMode": "list", "placement": "bottom", "showLegend": true }, "tooltip": { - "mode": "multi", + "mode": "single", "sort": "none" } }, @@ -953,67 +1112,190 @@ "targets": [ { "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" + "type": "prometheus" }, "editorMode": "code", "exemplar": true, - "expr": "db_gc_work_pnl_merge_volume{instance=~\"$instance\"}", + "expr": "rate(db_pgops{phase=\"newly\", instance=~\"$instance\"}[$rate_interval])", + "hide": false, "interval": "", - "legendFormat": "work_pnl_merge_volume: {{instance}}", + "legendFormat": "newly: {{instance}}", "range": true, "refId": "A" }, { "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" + "type": "prometheus" }, - "editorMode": "code", "exemplar": true, - "expr": "db_gc_work_pnl_merge_calls{instance=~\"$instance\"}", + "expr": "rate(db_pgops{phase=\"cow\", instance=~\"$instance\"}[$rate_interval])", "hide": false, "interval": "", - "legendFormat": "work_pnl_merge_calls: {{instance}}", - "range": true, + "legendFormat": "cow: {{instance}}", "refId": "B" }, { "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" + "type": "prometheus" }, - "editorMode": "code", "exemplar": true, - "expr": "db_gc_slef_pnl_merge_volume{instance=~\"$instance\"}", + "expr": "rate(db_pgops{phase=\"clone\", instance=~\"$instance\"}[$rate_interval])", "hide": false, "interval": "", - "legendFormat": "slef_pnl_merge_volume: {{instance}}", - "range": true, + "legendFormat": "clone: {{instance}}", "refId": "C" }, { "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" + "type": "prometheus" }, - "editorMode": "code", "exemplar": true, - "expr": "db_gc_slef_pnl_merge_calls{instance=~\"$instance\"}", + "expr": "rate(db_pgops{phase=\"split\", instance=~\"$instance\"}[$rate_interval])", "hide": false, "interval": "", - "legendFormat": "slef_pnl_merge_calls: {{instance}}", - "range": true, + "legendFormat": "split: {{instance}}", "refId": "D" - } - ], - "title": "pnl_merge", - "type": "timeseries" - }, + }, + { + "datasource": { + "type": "prometheus" + }, + "editorMode": "code", + "exemplar": true, + "expr": "rate(db_pgops{phase=\"merge\", instance=~\"$instance\"}[$rate_interval])", + "hide": false, + "interval": "", + "legendFormat": "merge: {{instance}}", + "range": true, + "refId": "E" + }, + { + "datasource": { + "type": "prometheus" + }, + "exemplar": true, + "expr": "rate(db_pgops{phase=\"spill\", instance=~\"$instance\"}[$rate_interval])", + "hide": false, + "interval": "", + "legendFormat": "spill: {{instance}}", + "refId": "F" + }, + { + "datasource": { + "type": "prometheus" + }, + "exemplar": true, + "expr": "rate(db_pgops{phase=\"wops\", instance=~\"$instance\"}[$rate_interval])", + "hide": false, + "interval": "", + "legendFormat": "wops: {{instance}}", + "refId": "G" + }, + { + "datasource": { + "type": "prometheus" + }, + "exemplar": true, + "expr": "rate(db_pgops{phase=\"unspill\", instance=~\"$instance\"}[$rate_interval])", + "hide": false, + "interval": "", + "legendFormat": "unspill: {{instance}}", + "refId": "H" + }, + { + "datasource": { + "type": "prometheus" + }, + "editorMode": "code", + "exemplar": true, + "expr": "rate(db_pgops{phase=\"gcrloops\", instance=~\"$instance\"}[$rate_interval])", + "hide": false, + "interval": "", + "legendFormat": "gcrloops: {{instance}}", + "range": true, + "refId": "I" + }, + { + "datasource": { + "type": "prometheus" + }, + "editorMode": "code", + "exemplar": true, + "expr": "rate(db_pgops{phase=\"gcwloops\", instance=~\"$instance\"}[$rate_interval])", + "hide": false, + "interval": "", + "legendFormat": "gcwloops: {{instance}}", + "range": true, + "refId": "J" + }, + { + "datasource": { + "type": "prometheus" + }, + "editorMode": "code", + "exemplar": true, + "expr": "rate(db_pgops{phase=\"gcxpages\", instance=~\"$instance\"}[$rate_interval])", + "hide": false, + "interval": "", + "legendFormat": "gcxpages: {{instance}}", + "range": true, + "refId": "K" + }, + { + "datasource": { + "type": "prometheus" + }, + "editorMode": "code", + "exemplar": true, + "expr": "rate(db_pgops{phase=\"msync\", instance=~\"$instance\"}[$rate_interval])", + "hide": false, + "interval": "", + "legendFormat": "msync: {{instance}}", + "range": true, + "refId": "L" + }, + { + "datasource": { + "type": "prometheus" + }, + "editorMode": "code", + "exemplar": true, + "expr": "rate(db_pgops{phase=\"fsync\", instance=~\"$instance\"}[$rate_interval])", + "hide": false, + "interval": "", + "legendFormat": "fsync: {{instance}}", + "range": true, + "refId": "M" + }, + { + "datasource": { + "type": "prometheus" + }, + "exemplar": true, + "expr": "rate(db_pgops{phase=\"minicore\", instance=~\"$instance\"}[$rate_interval])", + "hide": false, + "interval": "", + "legendFormat": "minicore: {{instance}}", + "refId": "N" + }, + { + "datasource": { + "type": "prometheus" + }, + "exemplar": true, + "expr": "rate(db_pgops{phase=\"prefault\", instance=~\"$instance\"}[$rate_interval])", + "hide": false, + "interval": "", + "legendFormat": "prefault: {{instance}}", + "refId": "O" + } + ], + "title": "DB Pages Ops/sec", + "type": "timeseries" + }, { "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" + "type": "prometheus" }, "fieldConfig": { "defaults": { @@ -1055,7 +1337,8 @@ "mode": "absolute", "steps": [ { - "color": "green" + "color": "green", + "value": null }, { "color": "red", @@ -1071,7 +1354,7 @@ "h": 6, "w": 8, "x": 0, - "y": 19 + "y": 22 }, "id": 167, "options": { @@ -1092,8 +1375,7 @@ "targets": [ { "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" + "type": "prometheus" }, "editorMode": "code", "expr": "tx_limit{instance=~\"$instance\"}", @@ -1104,8 +1386,7 @@ }, { "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" + "type": "prometheus" }, "editorMode": "code", "expr": "tx_dirty{instance=~\"$instance\"}", @@ -1121,8 +1402,7 @@ }, { "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" + "type": "prometheus" }, "fieldConfig": { "defaults": { @@ -1136,7 +1416,7 @@ "axisPlacement": "auto", "barAlignment": 0, "drawStyle": "line", - "fillOpacity": 10, + "fillOpacity": 25, "gradientMode": "none", "hideFrom": { "legend": false, @@ -1149,11 +1429,11 @@ "scaleDistribution": { "type": "linear" }, - "showPoints": "never", - "spanNulls": true, + "showPoints": "auto", + "spanNulls": false, "stacking": { "group": "A", - "mode": "none" + "mode": "normal" }, "thresholdsStyle": { "mode": "off" @@ -1164,61 +1444,34 @@ "mode": "absolute", "steps": [ { - "color": "green" + "color": "green", + "value": null }, { "color": "red", "value": 80 } ] - }, - "unit": "short" - }, - "overrides": [ - { - "__systemRef": "hideSeriesFrom", - "matcher": { - "id": "byNames", - "options": { - "mode": "exclude", - "names": [ - "fsync: mainnet2-2:6061" - ], - "prefix": "All except:", - "readOnly": true - } - }, - "properties": [ - { - "id": "custom.hideFrom", - "value": { - "legend": false, - "tooltip": false, - "viz": true - } - } - ] } - ] + }, + "overrides": [] }, "gridPos": { - "h": 7, - "w": 16, - "x": 8, - "y": 24 + "h": 6, + "w": 8, + "x": 0, + "y": 28 }, - "id": 168, + "id": 169, "options": { "legend": { - "calcs": [ - "mean" - ], + "calcs": [], "displayMode": "list", "placement": "bottom", "showLegend": true }, "tooltip": { - "mode": "multi", + "mode": "single", "sort": "none" } }, @@ -1226,182 +1479,148 @@ "targets": [ { "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" + "type": "prometheus" }, - "editorMode": "code", "exemplar": true, - "expr": "rate(db_pgops_newly{instance=~\"$instance\"}[$rate_interval])", - "hide": false, + "expr": "db_gc_leaf{instance=~\"$instance\"}", "interval": "", - "legendFormat": "newly: {{instance}}", - "range": true, + "legendFormat": "gc_leaf: {{instance}}", "refId": "A" }, { "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" + "type": "prometheus" }, "exemplar": true, - "expr": "rate(db_pgops_cow{instance=~\"$instance\"}[$rate_interval])", + "expr": "db_gc_overflow{instance=~\"$instance\"}", "hide": false, "interval": "", - "legendFormat": "cow: {{instance}}", + "legendFormat": "gc_overflow: {{instance}}", "refId": "B" }, { "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" + "type": "prometheus" }, + "editorMode": "code", "exemplar": true, - "expr": "rate(db_pgops_clone{instance=~\"$instance\"}[$rate_interval])", + "expr": "exec_steps_in_db{instance=~\"$instance\"}/100", "hide": false, "interval": "", - "legendFormat": "clone: {{instance}}", - "refId": "C" + "legendFormat": "exec_steps_in_db: {{instance}}", + "range": true, + "refId": "E" + } + ], + "title": "GC and State", + "type": "timeseries" + }, + { + "datasource": { + "type": "prometheus" + }, + "description": "", + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisCenteredZero": false, + "axisColorMode": "text", + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "drawStyle": "line", + "fillOpacity": 25, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "lineInterpolation": "linear", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "auto", + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "normal" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "red", + "value": 80 + } + ] + } }, + "overrides": [] + }, + "gridPos": { + "h": 6, + "w": 16, + "x": 8, + "y": 28 + }, + "id": 150, + "options": { + "legend": { + "calcs": [], + "displayMode": "list", + "placement": "bottom", + "showLegend": true + }, + "tooltip": { + "mode": "single", + "sort": "none" + } + }, + "pluginVersion": "8.0.6", + "targets": [ { "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" + "type": "prometheus" }, "exemplar": true, - "expr": "rate(db_pgops_split{instance=~\"$instance\"}[$rate_interval])", - "hide": false, + "expr": "rate(process_minor_pagefaults_total{instance=~\"$instance\"}[$rate_interval])", "interval": "", - "legendFormat": "split: {{instance}}", - "refId": "D" + "legendFormat": "soft: {{instance}}", + "refId": "A" }, { "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" + "type": "prometheus" }, - "editorMode": "code", "exemplar": true, - "expr": "rate(db_pgops_merge{instance=~\"$instance\"}[$rate_interval])", + "expr": "rate(process_major_pagefaults_total{instance=~\"$instance\"}[$rate_interval])", "hide": false, "interval": "", - "legendFormat": "merge: {{instance}}", - "range": true, - "refId": "E" - }, - { - "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" - }, - "exemplar": true, - "expr": "rate(db_pgops_spill{instance=~\"$instance\"}[$rate_interval])", - "hide": false, - "interval": "", - "legendFormat": "spill: {{instance}}", - "refId": "F" - }, - { - "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" - }, - "exemplar": true, - "expr": "rate(db_pgops_wops{instance=~\"$instance\"}[$rate_interval])", - "hide": false, - "interval": "", - "legendFormat": "wops: {{instance}}", - "refId": "G" - }, - { - "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" - }, - "exemplar": true, - "expr": "rate(db_pgops_unspill{instance=~\"$instance\"}[$rate_interval])", - "hide": false, - "interval": "", - "legendFormat": "unspill: {{instance}}", - "refId": "H" - }, - { - "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" - }, - "editorMode": "code", - "exemplar": true, - "expr": "rate(db_pgops_gcrloops{instance=~\"$instance\"}[$rate_interval])", - "hide": false, - "interval": "", - "legendFormat": "gcrloops: {{instance}}", - "range": true, - "refId": "I" - }, - { - "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" - }, - "editorMode": "code", - "exemplar": true, - "expr": "rate(db_pgops_gcwloops{instance=~\"$instance\"}[$rate_interval])", - "hide": false, - "interval": "", - "legendFormat": "gcwloops: {{instance}}", - "range": true, - "refId": "J" - }, - { - "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" - }, - "editorMode": "code", - "exemplar": true, - "expr": "rate(db_pgops_gcxpages{instance=~\"$instance\"}[$rate_interval])", - "hide": false, - "interval": "", - "legendFormat": "gcxpages: {{instance}}", - "range": true, - "refId": "K" - }, - { - "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" - }, - "editorMode": "code", - "exemplar": true, - "expr": "rate(db_pgops_msync{instance=~\"$instance\"}[$rate_interval])", - "hide": false, - "interval": "", - "legendFormat": "msync: {{instance}}", - "range": true, - "refId": "L" - }, - { - "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" - }, - "editorMode": "code", - "exemplar": true, - "expr": "rate(db_pgops_fsnc{instance=~\"$instance\"}[$rate_interval])", - "hide": false, - "interval": "", - "legendFormat": "fsync: {{instance}}", - "range": true, - "refId": "M" + "legendFormat": "hard: {{instance}}", + "refId": "B" } ], - "title": "DB Pages Ops/sec", + "title": "getrusage: minflt - soft page faults (reclaims), majflt - hard faults", "type": "timeseries" }, { "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" + "type": "prometheus" }, "fieldConfig": { "defaults": { @@ -1415,7 +1634,7 @@ "axisPlacement": "auto", "barAlignment": 0, "drawStyle": "line", - "fillOpacity": 10, + "fillOpacity": 0, "gradientMode": "none", "hideFrom": { "legend": false, @@ -1428,8 +1647,8 @@ "scaleDistribution": { "type": "linear" }, - "showPoints": "never", - "spanNulls": true, + "showPoints": "auto", + "spanNulls": false, "stacking": { "group": "A", "mode": "none" @@ -1443,187 +1662,15 @@ "mode": "absolute", "steps": [ { - "color": "green" + "color": "green", + "value": null }, { "color": "red", "value": 80 } ] - }, - "unit": "short" - }, - "overrides": [ - { - "__systemRef": "hideSeriesFrom", - "matcher": { - "id": "byNames", - "options": { - "mode": "exclude", - "names": [ - "gc_overflow: mainnet2-2:6061" - ], - "prefix": "All except:", - "readOnly": true - } - }, - "properties": [ - { - "id": "custom.hideFrom", - "value": { - "legend": false, - "tooltip": false, - "viz": true - } - } - ] } - ] - }, - "gridPos": { - "h": 6, - "w": 8, - "x": 0, - "y": 25 - }, - "id": 169, - "options": { - "legend": { - "calcs": [ - "mean" - ], - "displayMode": "list", - "placement": "bottom", - "showLegend": true - }, - "tooltip": { - "mode": "multi", - "sort": "none" - } - }, - "pluginVersion": "8.0.6", - "targets": [ - { - "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" - }, - "exemplar": true, - "expr": "db_gc_leaf{instance=~\"$instance\"}", - "interval": "", - "legendFormat": "gc_leaf: {{instance}}", - "refId": "A" - }, - { - "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" - }, - "exemplar": true, - "expr": "db_gc_overflow{instance=~\"$instance\"}", - "hide": false, - "interval": "", - "legendFormat": "gc_overflow: {{instance}}", - "refId": "B" - }, - { - "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" - }, - "exemplar": true, - "expr": "db_state_leaf{instance=~\"$instance\"}", - "hide": false, - "interval": "", - "legendFormat": "state_leaf: {{instance}}", - "refId": "C" - }, - { - "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" - }, - "editorMode": "code", - "exemplar": true, - "expr": "db_state_branch{instance=~\"$instance\"}", - "hide": false, - "interval": "", - "legendFormat": "state_branch: {{instance}}", - "range": true, - "refId": "D" - }, - { - "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" - }, - "editorMode": "code", - "exemplar": true, - "expr": "exec_steps_in_db{instance=~\"$instance\"}/100", - "hide": false, - "interval": "", - "legendFormat": "exec_steps_in_db: {{instance}}", - "range": true, - "refId": "E" - } - ], - "title": "GC and State", - "type": "timeseries" - }, - { - "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" - }, - "fieldConfig": { - "defaults": { - "color": { - "mode": "palette-classic" - }, - "custom": { - "axisCenteredZero": false, - "axisColorMode": "text", - "axisLabel": "", - "axisPlacement": "auto", - "barAlignment": 0, - "drawStyle": "points", - "fillOpacity": 10, - "gradientMode": "none", - "hideFrom": { - "legend": false, - "tooltip": false, - "viz": false - }, - "lineInterpolation": "linear", - "lineWidth": 1, - "pointSize": 2, - "scaleDistribution": { - "type": "linear" - }, - "showPoints": "never", - "spanNulls": true, - "stacking": { - "group": "A", - "mode": "none" - }, - "thresholdsStyle": { - "mode": "off" - } - }, - "mappings": [], - "thresholds": { - "mode": "absolute", - "steps": [ - { - "color": "green" - }, - { - "color": "red", - "value": 80 - } - ] - }, - "unit": "short" }, "overrides": [] }, @@ -1631,20 +1678,18 @@ "h": 8, "w": 16, "x": 8, - "y": 31 + "y": 34 }, "id": 191, "options": { "legend": { - "calcs": [ - "mean" - ], + "calcs": [], "displayMode": "list", "placement": "bottom", "showLegend": true }, "tooltip": { - "mode": "multi", + "mode": "single", "sort": "none" } }, @@ -1652,12 +1697,11 @@ "targets": [ { "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" + "type": "prometheus" }, "editorMode": "code", "exemplar": true, - "expr": "db_gc_work_rxpages{instance=~\"$instance\"}", + "expr": "db_gc{phase=\"work_rxpages\", instance=~\"$instance\"}", "hide": false, "interval": "", "legendFormat": "work_rxpages: {{instance}}", @@ -1666,12 +1710,11 @@ }, { "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" + "type": "prometheus" }, "editorMode": "code", "exemplar": true, - "expr": "db_gc_self_rsteps{instance=~\"$instance\"}", + "expr": "db_gc{phase=\"self_rsteps\", instance=~\"$instance\"}", "hide": false, "interval": "", "legendFormat": "self_rsteps: {{instance}}", @@ -1680,12 +1723,11 @@ }, { "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" + "type": "prometheus" }, "editorMode": "code", "exemplar": true, - "expr": "db_gc_wloop{instance=~\"$instance\"}", + "expr": "db_gc{phase=\"wloop\", instance=~\"$instance\"}", "hide": false, "interval": "", "legendFormat": "wloop: {{instance}}", @@ -1694,12 +1736,11 @@ }, { "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" + "type": "prometheus" }, "editorMode": "code", "exemplar": true, - "expr": "db_gc_coalescences{instance=~\"$instance\"}", + "expr": "db_gc{phase=\"coalescences\", instance=~\"$instance\"}", "hide": false, "interval": "", "legendFormat": "coalescences: {{instance}}", @@ -1708,12 +1749,11 @@ }, { "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" + "type": "prometheus" }, "editorMode": "code", "exemplar": true, - "expr": "db_gc_wipes{instance=~\"$instance\"}", + "expr": "db_gc{phase=\"wipes\", instance=~\"$instance\"}", "hide": false, "interval": "", "legendFormat": "wipes: {{instance}}", @@ -1722,12 +1762,11 @@ }, { "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" + "type": "prometheus" }, "editorMode": "code", "exemplar": true, - "expr": "db_gc_flushes{instance=~\"$instance\"}", + "expr": "db_gc{phase=\"flushes\", instance=~\"$instance\"}", "hide": false, "interval": "", "legendFormat": "flushes: {{instance}}", @@ -1736,12 +1775,11 @@ }, { "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" + "type": "prometheus" }, "editorMode": "code", "exemplar": true, - "expr": "db_gc_kicks{instance=~\"$instance\"}", + "expr": "db_gc{phase=\"kicks\", instance=~\"$instance\"}", "hide": false, "interval": "", "legendFormat": "kicks: {{instance}}", @@ -1750,12 +1788,11 @@ }, { "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" + "type": "prometheus" }, "editorMode": "code", "exemplar": true, - "expr": "db_gc_work_rsteps{instance=~\"$instance\"}", + "expr": "db_gc{phase=\"work_rsteps\", instance=~\"$instance\"}", "hide": false, "interval": "", "legendFormat": "gc_work_rsteps: {{instance}}", @@ -1764,12 +1801,11 @@ }, { "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" + "type": "prometheus" }, "editorMode": "code", "exemplar": true, - "expr": "db_gc_self_xpages{instance=~\"$instance\"}", + "expr": "db_gc{phase=\"self_xpages\", instance=~\"$instance\"}", "hide": false, "interval": "", "legendFormat": "self_xpages: {{instance}}", @@ -1778,12 +1814,11 @@ }, { "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" + "type": "prometheus" }, "editorMode": "code", "exemplar": true, - "expr": "db_gc_work_majflt{instance=~\"$instance\"}", + "expr": "db_gc{phase=\"work_majflt\", instance=~\"$instance\"}", "hide": false, "interval": "", "legendFormat": "gc_work_majflt: {{instance}}", @@ -1792,12 +1827,11 @@ }, { "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" + "type": "prometheus" }, "editorMode": "code", "exemplar": true, - "expr": "db_gc_self_majflt{instance=~\"$instance\"}", + "expr": "db_gc{phase=\"self_majflt\", instance=~\"$instance\"}", "hide": false, "interval": "", "legendFormat": "gc_self_majflt: {{instance}}", @@ -1806,12 +1840,11 @@ }, { "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" + "type": "prometheus" }, "editorMode": "code", "exemplar": true, - "expr": "db_gc_self_counter{instance=~\"$instance\"}", + "expr": "db_gc{phase=\"self_counter\", instance=~\"$instance\"}", "hide": false, "interval": "", "legendFormat": "gc_self_counter: {{instance}}", @@ -1820,12 +1853,11 @@ }, { "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" + "type": "prometheus" }, "editorMode": "code", "exemplar": true, - "expr": "db_gc_work_counter{instance=~\"$instance\"}", + "expr": "db_gc{phase=\"work_counter\", instance=~\"$instance\"}", "hide": false, "interval": "", "legendFormat": "gc_work_counter: {{instance}}", @@ -1837,157 +1869,22 @@ "type": "timeseries" }, { + "collapsed": false, "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" + "type": "prometheus" }, - "description": "", - "fieldConfig": { - "defaults": { - "color": { - "mode": "palette-classic" - }, - "custom": { - "axisCenteredZero": false, - "axisColorMode": "text", - "axisLabel": "", - "axisPlacement": "auto", - "barAlignment": 0, - "drawStyle": "line", - "fillOpacity": 10, - "gradientMode": "none", - "hideFrom": { - "legend": false, - "tooltip": false, - "viz": false - }, - "lineInterpolation": "linear", - "lineWidth": 1, - "pointSize": 5, - "scaleDistribution": { - "type": "linear" - }, - "showPoints": "never", - "spanNulls": true, - "stacking": { - "group": "A", - "mode": "none" - }, - "thresholdsStyle": { - "mode": "off" - } - }, - "mappings": [], - "thresholds": { - "mode": "absolute", - "steps": [ - { - "color": "green" - }, - { - "color": "red", - "value": 80 - } - ] - }, - "unit": "ops" - }, - "overrides": [ - { - "__systemRef": "hideSeriesFrom", - "matcher": { - "id": "byNames", - "options": { - "mode": "exclude", - "names": [ - "hard: mainnet2-2:6061" - ], - "prefix": "All except:", - "readOnly": true - } - }, - "properties": [ - { - "id": "custom.hideFrom", - "value": { - "legend": false, - "tooltip": false, - "viz": true - } - } - ] - } - ] - }, - "gridPos": { - "h": 6, - "w": 16, - "x": 8, - "y": 39 - }, - "id": 150, - "options": { - "legend": { - "calcs": [ - "mean" - ], - "displayMode": "list", - "placement": "bottom", - "showLegend": true - }, - "tooltip": { - "mode": "multi", - "sort": "none" - } - }, - "pluginVersion": "8.0.6", - "targets": [ - { - "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" - }, - "exemplar": true, - "expr": "rate(process_minor_pagefaults_total{instance=~\"$instance\"}[$rate_interval])", - "interval": "", - "legendFormat": "soft: {{instance}}", - "refId": "A" - }, - { - "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" - }, - "exemplar": true, - "expr": "rate(process_major_pagefaults_total{instance=~\"$instance\"}[$rate_interval])", - "hide": false, - "interval": "", - "legendFormat": "hard: {{instance}}", - "refId": "B" - } - ], - "title": "getrusage: minflt - soft page faults (reclaims), majflt - hard faults", - "type": "timeseries" - }, - { - "collapsed": false, - "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" - }, - "gridPos": { - "h": 1, - "w": 24, - "x": 0, - "y": 45 - }, - "id": 134, - "panels": [], - "targets": [ - { - "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" + "gridPos": { + "h": 1, + "w": 24, + "x": 0, + "y": 42 + }, + "id": 134, + "panels": [], + "targets": [ + { + "datasource": { + "type": "prometheus" }, "refId": "A" } @@ -1997,8 +1894,7 @@ }, { "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" + "type": "prometheus" }, "fieldConfig": { "defaults": { @@ -2018,7 +1914,7 @@ "h": 18, "w": 8, "x": 0, - "y": 46 + "y": 43 }, "id": 165, "options": { @@ -2039,12 +1935,11 @@ }, "textMode": "auto" }, - "pluginVersion": "9.2.3", + "pluginVersion": "9.4.7", "targets": [ { "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" + "type": "prometheus" }, "expr": "ru_inblock{instance=~\"$instance\"}", "interval": "", @@ -2053,8 +1948,7 @@ }, { "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" + "type": "prometheus" }, "expr": "ru_outblock{instance=~\"$instance\"}", "hide": false, @@ -2064,8 +1958,7 @@ }, { "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" + "type": "prometheus" }, "expr": "ru_minflt{instance=~\"$instance\"}", "hide": false, @@ -2075,8 +1968,7 @@ }, { "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" + "type": "prometheus" }, "expr": "ru_majflt{instance=~\"$instance\"}", "hide": false, @@ -2086,8 +1978,7 @@ }, { "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" + "type": "prometheus" }, "expr": "system_disk_readbytes{instance=~\"$instance\"}", "hide": false, @@ -2097,8 +1988,7 @@ }, { "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" + "type": "prometheus" }, "expr": "system_disk_writebytes{instance=~\"$instance\"}", "hide": false, @@ -2108,8 +1998,7 @@ }, { "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" + "type": "prometheus" }, "expr": "db_pgops_newly{instance=~\"$instance\"}", "hide": false, @@ -2119,8 +2008,7 @@ }, { "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" + "type": "prometheus" }, "expr": "db_pgops_cow{instance=~\"$instance\"}", "hide": false, @@ -2130,8 +2018,7 @@ }, { "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" + "type": "prometheus" }, "expr": "db_pgops_clone{instance=~\"$instance\"}", "hide": false, @@ -2141,8 +2028,7 @@ }, { "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" + "type": "prometheus" }, "expr": "db_pgops_split{instance=~\"$instance\"}", "hide": false, @@ -2152,8 +2038,7 @@ }, { "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" + "type": "prometheus" }, "expr": "db_pgops_merge{instance=~\"$instance\"}", "hide": false, @@ -2163,8 +2048,7 @@ }, { "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" + "type": "prometheus" }, "expr": "db_pgops_spill{instance=~\"$instance\"}", "hide": false, @@ -2174,8 +2058,7 @@ }, { "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" + "type": "prometheus" }, "expr": "db_pgops_unspill{instance=~\"$instance\"}", "hide": false, @@ -2185,8 +2068,7 @@ }, { "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" + "type": "prometheus" }, "expr": "db_pgops_wops{instance=~\"$instance\"}", "hide": false, @@ -2200,8 +2082,7 @@ }, { "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" + "type": "prometheus" }, "description": "", "fieldConfig": { @@ -2244,7 +2125,8 @@ "mode": "absolute", "steps": [ { - "color": "green" + "color": "green", + "value": null }, { "color": "red", @@ -2260,7 +2142,7 @@ "h": 6, "w": 8, "x": 8, - "y": 46 + "y": 43 }, "id": 155, "links": [], @@ -2282,8 +2164,7 @@ "targets": [ { "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" + "type": "prometheus" }, "exemplar": true, "expr": "rate(process_io_write_syscalls_total{instance=~\"$instance\"}[$rate_interval])", @@ -2296,8 +2177,7 @@ }, { "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" + "type": "prometheus" }, "exemplar": true, "expr": "rate(process_io_read_syscalls_total{instance=~\"$instance\"}[$rate_interval])", @@ -2314,8 +2194,7 @@ }, { "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" + "type": "prometheus" }, "description": "", "fieldConfig": { @@ -2358,7 +2237,8 @@ "mode": "absolute", "steps": [ { - "color": "green" + "color": "green", + "value": null }, { "color": "red", @@ -2374,7 +2254,7 @@ "h": 6, "w": 8, "x": 16, - "y": 46 + "y": 43 }, "id": 153, "options": { @@ -2395,8 +2275,7 @@ "targets": [ { "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" + "type": "prometheus" }, "editorMode": "code", "exemplar": true, @@ -2412,8 +2291,7 @@ }, { "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" + "type": "prometheus" }, "fieldConfig": { "defaults": { @@ -2421,13 +2299,11 @@ "mode": "palette-classic" }, "custom": { - "axisCenteredZero": false, - "axisColorMode": "text", "axisLabel": "", "axisPlacement": "auto", "barAlignment": 0, "drawStyle": "line", - "fillOpacity": 10, + "fillOpacity": 25, "gradientMode": "none", "hideFrom": { "legend": false, @@ -2440,11 +2316,11 @@ "scaleDistribution": { "type": "linear" }, - "showPoints": "never", - "spanNulls": true, + "showPoints": "auto", + "spanNulls": false, "stacking": { "group": "A", - "mode": "none" + "mode": "normal" }, "thresholdsStyle": { "mode": "off" @@ -2462,55 +2338,27 @@ "value": 80 } ] - }, - "unit": "Bps" - }, - "overrides": [ - { - "__systemRef": "hideSeriesFrom", - "matcher": { - "id": "byNames", - "options": { - "mode": "exclude", - "names": [ - "write: mainnet2-2:6061" - ], - "prefix": "All except:", - "readOnly": true - } - }, - "properties": [ - { - "id": "custom.hideFrom", - "value": { - "legend": false, - "tooltip": false, - "viz": true - } - } - ] } - ] + }, + "overrides": [] }, "gridPos": { "h": 6, "w": 8, "x": 8, - "y": 52 + "y": 49 }, "id": 85, "links": [], "options": { "legend": { - "calcs": [ - "mean" - ], + "calcs": [], "displayMode": "list", "placement": "bottom", "showLegend": true }, "tooltip": { - "mode": "multi", + "mode": "single", "sort": "none" } }, @@ -2518,8 +2366,7 @@ "targets": [ { "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" + "type": "prometheus" }, "exemplar": true, "expr": "rate(process_io_storage_read_bytes_total{instance=~\"$instance\"}[$rate_interval])", @@ -2531,8 +2378,7 @@ }, { "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" + "type": "prometheus" }, "exemplar": true, "expr": "rate(process_io_storage_written_bytes_total{instance=~\"$instance\"}[$rate_interval])", @@ -2548,8 +2394,7 @@ }, { "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" + "type": "prometheus" }, "fieldConfig": { "defaults": { @@ -2557,8 +2402,6 @@ "mode": "palette-classic" }, "custom": { - "axisCenteredZero": false, - "axisColorMode": "text", "axisLabel": "", "axisPlacement": "auto", "barAlignment": 0, @@ -2607,7 +2450,7 @@ "h": 6, "w": 8, "x": 16, - "y": 52 + "y": 49 }, "id": 128, "options": { @@ -2626,8 +2469,7 @@ "targets": [ { "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" + "type": "prometheus" }, "editorMode": "code", "expr": "go_goroutines{instance=~\"$instance\"}", @@ -2638,8 +2480,7 @@ }, { "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" + "type": "prometheus" }, "editorMode": "code", "expr": "go_threads{instance=~\"$instance\"}", @@ -2654,8 +2495,7 @@ }, { "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" + "type": "prometheus" }, "description": "", "fieldConfig": { @@ -2664,8 +2504,6 @@ "mode": "palette-classic" }, "custom": { - "axisCenteredZero": false, - "axisColorMode": "text", "axisLabel": "", "axisPlacement": "auto", "barAlignment": 0, @@ -2714,7 +2552,7 @@ "h": 6, "w": 8, "x": 8, - "y": 58 + "y": 55 }, "id": 154, "links": [], @@ -2734,8 +2572,7 @@ "targets": [ { "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" + "type": "prometheus" }, "editorMode": "code", "exemplar": true, @@ -2749,8 +2586,7 @@ }, { "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" + "type": "prometheus" }, "editorMode": "code", "exemplar": true, @@ -2765,8 +2601,7 @@ }, { "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" + "type": "prometheus" }, "editorMode": "code", "exemplar": true, @@ -2781,8 +2616,7 @@ }, { "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" + "type": "prometheus" }, "editorMode": "code", "exemplar": true, @@ -2797,8 +2631,7 @@ }, { "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" + "type": "prometheus" }, "editorMode": "code", "exemplar": true, @@ -2813,8 +2646,7 @@ }, { "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" + "type": "prometheus" }, "editorMode": "code", "exemplar": true, @@ -2833,8 +2665,7 @@ }, { "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" + "type": "prometheus" }, "fieldConfig": { "defaults": { @@ -2842,8 +2673,6 @@ "mode": "palette-classic" }, "custom": { - "axisCenteredZero": false, - "axisColorMode": "text", "axisLabel": "", "axisPlacement": "auto", "barAlignment": 0, @@ -2892,7 +2721,7 @@ "h": 5, "w": 8, "x": 16, - "y": 58 + "y": 55 }, "id": 124, "options": { @@ -2911,8 +2740,7 @@ "targets": [ { "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" + "type": "prometheus" }, "editorMode": "code", "exemplar": true, @@ -2928,8 +2756,7 @@ }, { "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" + "type": "prometheus" }, "description": "", "fieldConfig": { @@ -2938,8 +2765,6 @@ "mode": "palette-classic" }, "custom": { - "axisCenteredZero": false, - "axisColorMode": "text", "axisLabel": "", "axisPlacement": "auto", "barAlignment": 0, @@ -2988,7 +2813,7 @@ "h": 5, "w": 8, "x": 0, - "y": 64 + "y": 61 }, "id": 148, "options": { @@ -3009,8 +2834,7 @@ "targets": [ { "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" + "type": "prometheus" }, "exemplar": true, "expr": "process_virtual_memory_bytes{instance=~\"$instance\"}", @@ -3021,8 +2845,7 @@ }, { "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" + "type": "prometheus" }, "exemplar": true, "expr": "process_resident_memory_anon_bytes{instance=~\"$instance\"}", @@ -3033,8 +2856,7 @@ }, { "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" + "type": "prometheus" }, "exemplar": true, "expr": "process_resident_memory_bytes{instance=~\"$instance\"}", @@ -3045,8 +2867,7 @@ }, { "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" + "type": "prometheus" }, "expr": "mem_data{instance=~\"$instance\"}", "hide": false, @@ -3056,8 +2877,7 @@ }, { "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" + "type": "prometheus" }, "expr": "mem_stack{instance=~\"$instance\"}", "hide": false, @@ -3067,8 +2887,7 @@ }, { "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" + "type": "prometheus" }, "expr": "mem_locked{instance=~\"$instance\"}", "hide": false, @@ -3078,8 +2897,7 @@ }, { "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" + "type": "prometheus" }, "expr": "mem_swap{instance=~\"$instance\"}", "hide": false, @@ -3093,8 +2911,7 @@ }, { "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" + "type": "prometheus" }, "description": "", "fieldConfig": { @@ -3103,8 +2920,6 @@ "mode": "palette-classic" }, "custom": { - "axisCenteredZero": false, - "axisColorMode": "text", "axisLabel": "", "axisPlacement": "auto", "barAlignment": 0, @@ -3153,7 +2968,7 @@ "h": 5, "w": 8, "x": 0, - "y": 69 + "y": 66 }, "id": 86, "links": [], @@ -3173,8 +2988,7 @@ "targets": [ { "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" + "type": "prometheus" }, "editorMode": "code", "exemplar": true, @@ -3188,8 +3002,7 @@ }, { "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" + "type": "prometheus" }, "editorMode": "code", "exemplar": true, @@ -3208,8 +3021,7 @@ }, { "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" + "type": "prometheus" }, "fieldConfig": { "defaults": { @@ -3217,8 +3029,6 @@ "mode": "palette-classic" }, "custom": { - "axisCenteredZero": false, - "axisColorMode": "text", "axisLabel": "", "axisPlacement": "auto", "barAlignment": 0, @@ -3267,7 +3077,7 @@ "h": 5, "w": 8, "x": 0, - "y": 74 + "y": 71 }, "id": 106, "links": [], @@ -3287,8 +3097,7 @@ "targets": [ { "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" + "type": "prometheus" }, "exemplar": true, "expr": "increase(process_cpu_seconds_system_total{instance=~\"$instance\"}[1m])", @@ -3300,8 +3109,7 @@ }, { "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" + "type": "prometheus" }, "exemplar": true, "expr": "increase(process_cpu_seconds_user_total{instance=~\"$instance\"}[1m])", @@ -3318,22 +3126,20 @@ { "collapsed": false, "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" + "type": "prometheus" }, "gridPos": { "h": 1, "w": 24, "x": 0, - "y": 79 + "y": 76 }, "id": 82, "panels": [], "targets": [ { "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" + "type": "prometheus" }, "refId": "A" } @@ -3343,8 +3149,7 @@ }, { "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" + "type": "prometheus" }, "description": "", "fieldConfig": { @@ -3353,8 +3158,6 @@ "mode": "palette-classic" }, "custom": { - "axisCenteredZero": false, - "axisColorMode": "text", "axisLabel": "", "axisPlacement": "auto", "barAlignment": 0, @@ -3403,7 +3206,7 @@ "h": 5, "w": 8, "x": 0, - "y": 80 + "y": 77 }, "id": 157, "links": [], @@ -3425,8 +3228,7 @@ "targets": [ { "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" + "type": "prometheus" }, "expr": "vmem_total{instance=~\"$instance\"}", "format": "time_series", @@ -3437,8 +3239,7 @@ }, { "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" + "type": "prometheus" }, "expr": "vmem_available{instance=~\"$instance\"}", "format": "time_series", @@ -3450,8 +3251,7 @@ }, { "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" + "type": "prometheus" }, "expr": "vmem_used{instance=~\"$instance\"}", "format": "time_series", @@ -3463,8 +3263,7 @@ }, { "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" + "type": "prometheus" }, "expr": "vmem_buffers{instance=~\"$instance\"}", "format": "time_series", @@ -3476,8 +3275,7 @@ }, { "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" + "type": "prometheus" }, "expr": "vmem_cached{instance=~\"$instance\"}", "format": "time_series", @@ -3489,8 +3287,7 @@ }, { "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" + "type": "prometheus" }, "expr": "vmem_writeback{instance=~\"$instance\"}", "format": "time_series", @@ -3502,8 +3299,7 @@ }, { "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" + "type": "prometheus" }, "expr": "vmem_dirty{instance=~\"$instance\"}", "format": "time_series", @@ -3515,8 +3311,7 @@ }, { "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" + "type": "prometheus" }, "expr": "vmem_shared{instance=~\"$instance\"}", "format": "time_series", @@ -3528,8 +3323,7 @@ }, { "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" + "type": "prometheus" }, "expr": "vmem_mapped{instance=~\"$instance\"}", "format": "time_series", @@ -3546,22 +3340,20 @@ { "collapsed": false, "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" + "type": "prometheus" }, "gridPos": { "h": 1, "w": 24, "x": 0, - "y": 85 + "y": 82 }, "id": 173, "panels": [], "targets": [ { "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" + "type": "prometheus" }, "refId": "A" } @@ -3571,8 +3363,7 @@ }, { "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" + "type": "prometheus" }, "fieldConfig": { "defaults": { @@ -3580,8 +3371,6 @@ "mode": "palette-classic" }, "custom": { - "axisCenteredZero": false, - "axisColorMode": "text", "axisLabel": "", "axisPlacement": "auto", "barAlignment": 0, @@ -3630,7 +3419,7 @@ "h": 8, "w": 12, "x": 0, - "y": 86 + "y": 83 }, "id": 175, "options": { @@ -3651,8 +3440,7 @@ "targets": [ { "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" + "type": "prometheus" }, "exemplar": true, "expr": "pool_process_remote_txs{quantile=\"$quantile\",instance=~\"$instance\"}", @@ -3662,8 +3450,7 @@ }, { "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" + "type": "prometheus" }, "exemplar": true, "expr": "pool_add_remote_txs{quantile=\"$quantile\",instance=~\"$instance\"}", @@ -3674,8 +3461,7 @@ }, { "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" + "type": "prometheus" }, "exemplar": true, "expr": "pool_new_block{quantile=\"$quantile\",instance=~\"$instance\"}", @@ -3686,8 +3472,7 @@ }, { "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" + "type": "prometheus" }, "exemplar": true, "expr": "pool_write_to_db{quantile=\"$quantile\",instance=~\"$instance\"}", @@ -3698,8 +3483,7 @@ }, { "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" + "type": "prometheus" }, "exemplar": true, "expr": "pool_propagate_to_new_peer{quantile=\"$quantile\",instance=~\"$instance\"}", @@ -3710,8 +3494,7 @@ }, { "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" + "type": "prometheus" }, "exemplar": true, "expr": "pool_propagate_new_txs{quantile=\"$quantile\",instance=~\"$instance\"}", @@ -3727,8 +3510,7 @@ }, { "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" + "type": "prometheus" }, "fieldConfig": { "defaults": { @@ -3736,8 +3518,6 @@ "mode": "palette-classic" }, "custom": { - "axisCenteredZero": false, - "axisColorMode": "text", "axisLabel": "", "axisPlacement": "auto", "barAlignment": 0, @@ -3786,7 +3566,7 @@ "h": 8, "w": 12, "x": 12, - "y": 86 + "y": 83 }, "id": 177, "options": { @@ -3807,8 +3587,7 @@ "targets": [ { "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" + "type": "prometheus" }, "exemplar": true, "expr": "rate(pool_process_remote_txs_count{instance=~\"$instance\"}[$rate_interval])", @@ -3819,8 +3598,7 @@ }, { "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" + "type": "prometheus" }, "exemplar": true, "expr": "rate(pool_add_remote_txs_count{instance=~\"$instance\"}[$rate_interval])", @@ -3831,8 +3609,7 @@ }, { "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" + "type": "prometheus" }, "exemplar": true, "expr": "rate(pool_new_block_count{instance=~\"$instance\"}[$rate_interval])", @@ -3843,8 +3620,7 @@ }, { "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" + "type": "prometheus" }, "exemplar": true, "expr": "rate(pool_write_to_db_count{instance=~\"$instance\"}[$rate_interval])", @@ -3860,8 +3636,7 @@ }, { "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" + "type": "prometheus" }, "fieldConfig": { "defaults": { @@ -3869,8 +3644,6 @@ "mode": "palette-classic" }, "custom": { - "axisCenteredZero": false, - "axisColorMode": "text", "axisLabel": "", "axisPlacement": "auto", "barAlignment": 0, @@ -3918,7 +3691,7 @@ "h": 6, "w": 8, "x": 0, - "y": 94 + "y": 91 }, "id": 176, "options": { @@ -3939,8 +3712,7 @@ "targets": [ { "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" + "type": "prometheus" }, "exemplar": true, "expr": "sum(delta(cache_total{result=\"hit\",name=\"txpool\",instance=~\"$instance\"}[1m]))/sum(delta(cache_total{name=\"txpool\",instance=~\"$instance\"}[1m])) ", @@ -3955,8 +3727,7 @@ }, { "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" + "type": "prometheus" }, "fieldConfig": { "defaults": { @@ -3964,8 +3735,6 @@ "mode": "palette-classic" }, "custom": { - "axisCenteredZero": false, - "axisColorMode": "text", "axisLabel": "", "axisPlacement": "auto", "barAlignment": 0, @@ -4013,7 +3782,7 @@ "h": 6, "w": 8, "x": 8, - "y": 94 + "y": 91 }, "id": 180, "options": { @@ -4034,8 +3803,7 @@ "targets": [ { "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" + "type": "prometheus" }, "exemplar": true, "expr": "rate(cache_total{name=\"txpool\",instance=~\"$instance\"}[1m])", @@ -4046,8 +3814,7 @@ }, { "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" + "type": "prometheus" }, "exemplar": true, "expr": "rate(cache_timeout_total{name=\"txpool\",instance=~\"$instance\"}[1m])", @@ -4062,8 +3829,7 @@ }, { "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" + "type": "prometheus" }, "fieldConfig": { "defaults": { @@ -4071,8 +3837,6 @@ "mode": "palette-classic" }, "custom": { - "axisCenteredZero": false, - "axisColorMode": "text", "axisLabel": "", "axisPlacement": "auto", "barAlignment": 0, @@ -4121,7 +3885,7 @@ "h": 6, "w": 8, "x": 16, - "y": 94 + "y": 91 }, "id": 181, "options": { @@ -4142,8 +3906,7 @@ "targets": [ { "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" + "type": "prometheus" }, "exemplar": true, "expr": "cache_keys_total{name=\"txpool\",instance=~\"$instance\"}", @@ -4154,8 +3917,7 @@ }, { "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" + "type": "prometheus" }, "exemplar": true, "expr": "cache_list_total{name=\"txpool\",instance=~\"$instance\"}", @@ -4170,8 +3932,7 @@ }, { "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" + "type": "prometheus" }, "fieldConfig": { "defaults": { @@ -4179,8 +3940,6 @@ "mode": "palette-classic" }, "custom": { - "axisCenteredZero": false, - "axisColorMode": "text", "axisLabel": "", "axisPlacement": "auto", "barAlignment": 0, @@ -4229,7 +3988,7 @@ "h": 6, "w": 8, "x": 0, - "y": 100 + "y": 97 }, "id": 178, "options": { @@ -4250,8 +4009,7 @@ "targets": [ { "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" + "type": "prometheus" }, "exemplar": true, "expr": "rate(pool_write_to_db_bytes{instance=~\"$instance\"}[$rate_interval])", @@ -4267,22 +4025,20 @@ { "collapsed": false, "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" + "type": "prometheus" }, "gridPos": { "h": 1, "w": 24, "x": 0, - "y": 106 + "y": 103 }, "id": 183, "panels": [], "targets": [ { "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" + "type": "prometheus" }, "refId": "A" } @@ -4292,8 +4048,7 @@ }, { "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" + "type": "prometheus" }, "fieldConfig": { "defaults": { @@ -4301,8 +4056,6 @@ "mode": "palette-classic" }, "custom": { - "axisCenteredZero": false, - "axisColorMode": "text", "axisLabel": "", "axisPlacement": "auto", "barAlignment": 0, @@ -4351,7 +4104,7 @@ "h": 8, "w": 12, "x": 0, - "y": 107 + "y": 104 }, "id": 185, "options": { @@ -4372,8 +4125,7 @@ "targets": [ { "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" + "type": "prometheus" }, "exemplar": true, "expr": "rate(rpc_duration_seconds_count{instance=~\"$instance\",success=\"success\"}[1m])", @@ -4383,8 +4135,7 @@ }, { "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" + "type": "prometheus" }, "exemplar": true, "expr": "rate(rpc_duration_seconds_count{instance=~\"$instance\",success=\"failure\"}[1m])", @@ -4400,8 +4151,7 @@ }, { "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" + "type": "prometheus" }, "fieldConfig": { "defaults": { @@ -4409,8 +4159,6 @@ "mode": "palette-classic" }, "custom": { - "axisCenteredZero": false, - "axisColorMode": "text", "axisLabel": "", "axisPlacement": "auto", "barAlignment": 0, @@ -4459,7 +4207,7 @@ "h": 8, "w": 12, "x": 12, - "y": 107 + "y": 104 }, "id": 186, "options": { @@ -4480,8 +4228,7 @@ "targets": [ { "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" + "type": "prometheus" }, "exemplar": true, "expr": "db_begin_seconds{quantile=\"$quantile\",instance=~\"$instance\"}", @@ -4496,8 +4243,7 @@ }, { "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" + "type": "prometheus" }, "fieldConfig": { "defaults": { @@ -4505,8 +4251,6 @@ "mode": "palette-classic" }, "custom": { - "axisCenteredZero": false, - "axisColorMode": "text", "axisLabel": "", "axisPlacement": "auto", "barAlignment": 0, @@ -4555,7 +4299,7 @@ "h": 8, "w": 12, "x": 0, - "y": 115 + "y": 112 }, "id": 187, "options": { @@ -4576,8 +4320,7 @@ "targets": [ { "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" + "type": "prometheus" }, "exemplar": true, "expr": "rpc_duration_seconds{quantile=\"$quantile\",instance=~\"$instance\"}", @@ -4592,8 +4335,7 @@ }, { "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" + "type": "prometheus" }, "fieldConfig": { "defaults": { @@ -4601,8 +4343,6 @@ "mode": "palette-classic" }, "custom": { - "axisCenteredZero": false, - "axisColorMode": "text", "axisLabel": "", "axisPlacement": "auto", "barAlignment": 0, @@ -4651,7 +4391,7 @@ "h": 8, "w": 12, "x": 12, - "y": 115 + "y": 112 }, "id": 188, "options": { @@ -4670,8 +4410,7 @@ "targets": [ { "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" + "type": "prometheus" }, "expr": "go_goroutines{instance=~\"$instance\"}", "instant": false, @@ -4681,8 +4420,7 @@ }, { "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" + "type": "prometheus" }, "expr": "go_threads{instance=~\"$instance\"}", "instant": false, @@ -4696,8 +4434,7 @@ }, { "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" + "type": "prometheus" }, "fieldConfig": { "defaults": { @@ -4705,8 +4442,6 @@ "mode": "palette-classic" }, "custom": { - "axisCenteredZero": false, - "axisColorMode": "text", "axisLabel": "", "axisPlacement": "auto", "barAlignment": 0, @@ -4755,7 +4490,7 @@ "h": 6, "w": 8, "x": 8, - "y": 123 + "y": 120 }, "id": 189, "options": { @@ -4776,8 +4511,7 @@ "targets": [ { "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" + "type": "prometheus" }, "exemplar": true, "expr": "cache_keys_total{name=\"rpc\",instance=~\"$instance\"}", @@ -4788,8 +4522,7 @@ }, { "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" + "type": "prometheus" }, "exemplar": true, "expr": "cache_list_total{name=\"rpc\",instance=~\"$instance\"}", @@ -4800,8 +4533,7 @@ }, { "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" + "type": "prometheus" }, "exemplar": true, "expr": "cache_code_keys_total{name=\"rpc\",instance=~\"$instance\"}", @@ -4812,8 +4544,7 @@ }, { "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" + "type": "prometheus" }, "exemplar": true, "expr": "cache_code_list_total{name=\"rpc\",instance=~\"$instance\"}", @@ -4828,8 +4559,7 @@ }, { "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" + "type": "prometheus" }, "fieldConfig": { "defaults": { @@ -4837,8 +4567,6 @@ "mode": "palette-classic" }, "custom": { - "axisCenteredZero": false, - "axisColorMode": "text", "axisLabel": "", "axisPlacement": "auto", "barAlignment": 0, @@ -4886,7 +4614,7 @@ "h": 6, "w": 8, "x": 16, - "y": 123 + "y": 120 }, "id": 184, "options": { @@ -4907,8 +4635,7 @@ "targets": [ { "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" + "type": "prometheus" }, "editorMode": "code", "exemplar": true, @@ -4921,8 +4648,7 @@ }, { "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" + "type": "prometheus" }, "exemplar": true, "expr": "sum(delta(cache_code_total{result=\"hit\",name=\"rpc\",instance=~\"$instance\"}[1m]))/sum(delta(cache_code_total{name=\"rpc\",instance=~\"$instance\"}[1m])) ", @@ -4936,844 +4662,797 @@ "type": "timeseries" }, { - "collapsed": true, + "collapsed": false, "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" + "type": "prometheus" }, "gridPos": { "h": 1, "w": 24, "x": 0, - "y": 129 + "y": 126 }, "id": 146, - "panels": [ - { - "aliasColors": {}, - "bars": false, - "dashLength": 10, - "dashes": false, - "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" - }, - "fill": 1, - "fillGradient": 0, - "gridPos": { - "h": 5, - "w": 8, - "x": 0, - "y": 54 - }, - "hiddenSeries": false, - "id": 122, - "legend": { - "alignAsTable": true, - "avg": true, - "current": false, - "hideEmpty": false, - "hideZero": false, - "max": false, - "min": false, - "rightSide": false, - "show": true, - "sort": "avg", - "sortDesc": true, - "total": false, - "values": true - }, - "lines": true, - "linewidth": 1, - "nullPointMode": "null", - "options": { - "alertThreshold": true - }, - "percentage": false, - "pluginVersion": "8.0.6", - "pointradius": 2, - "points": false, - "renderer": "flot", - "seriesOverrides": [], - "spaceLength": 10, - "stack": false, - "steppedLine": false, - "targets": [ - { - "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" - }, - "expr": "trie_subtrieloader_flatdb{quantile=\"$quantile\",instance=~\"$instance\"}", - "interval": "", - "legendFormat": "trie_subtrieloader_flatdb: {{quantile}}, {{instance}}", - "refId": "B" - }, - { - "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" - }, - "expr": "trie_subtrieloader_witnessdb{quantile=\"$quantile\",instance=~\"$instance\"}", - "interval": "", - "legendFormat": "trie_subtrieloader_witnessdb: {{quantile}}, {{instance}}", - "refId": "C" - } - ], - "thresholds": [], - "timeRegions": [], - "title": "Merkle Root calculation (stage 5)", - "tooltip": { - "shared": true, - "sort": 0, - "value_type": "individual" - }, - "type": "graph", - "xaxis": { - "buckets": 6, - "mode": "time", - "show": true, - "values": [] - }, - "yaxes": [ - { - "$$hashKey": "object:431", - "format": "ns", - "logBase": 1, - "show": true - }, - { - "$$hashKey": "object:432", - "format": "short", - "logBase": 1, - "show": false - } - ], - "yaxis": { - "align": false - } + "panels": [], + "targets": [ + { + "datasource": { + "type": "prometheus" + }, + "refId": "A" + } + ], + "title": "Hidden", + "type": "row" + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": { + "type": "prometheus" + }, + "fill": 1, + "fillGradient": 0, + "gridPos": { + "h": 5, + "w": 8, + "x": 0, + "y": 127 + }, + "hiddenSeries": false, + "id": 122, + "legend": { + "alignAsTable": true, + "avg": true, + "current": false, + "hideEmpty": false, + "hideZero": false, + "max": false, + "min": false, + "rightSide": false, + "show": true, + "sort": "avg", + "sortDesc": true, + "total": false, + "values": true + }, + "lines": true, + "linewidth": 1, + "nullPointMode": "null", + "options": { + "alertThreshold": true + }, + "percentage": false, + "pluginVersion": "8.4.7", + "pointradius": 2, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "datasource": { + "type": "prometheus" + }, + "expr": "trie_subtrieloader_flatdb{quantile=\"$quantile\",instance=~\"$instance\"}", + "interval": "", + "legendFormat": "trie_subtrieloader_flatdb: {{quantile}}, {{instance}}", + "refId": "B" + }, + { + "datasource": { + "type": "prometheus" + }, + "expr": "trie_subtrieloader_witnessdb{quantile=\"$quantile\",instance=~\"$instance\"}", + "interval": "", + "legendFormat": "trie_subtrieloader_witnessdb: {{quantile}}, {{instance}}", + "refId": "C" + } + ], + "thresholds": [], + "timeRegions": [], + "title": "Merkle Root calculation (stage 5)", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": 6, + "mode": "time", + "show": true, + "values": [] + }, + "yaxes": [ + { + "$$hashKey": "object:431", + "format": "ns", + "logBase": 1, + "show": true + }, + { + "$$hashKey": "object:432", + "format": "short", + "logBase": 1, + "show": false + } + ], + "yaxis": { + "align": false + } + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": { + "type": "prometheus" + }, + "description": "", + "fill": 1, + "fillGradient": 0, + "gridPos": { + "h": 5, + "w": 8, + "x": 8, + "y": 127 + }, + "hiddenSeries": false, + "id": 162, + "legend": { + "avg": false, + "current": false, + "hideEmpty": true, + "hideZero": true, + "max": false, + "min": false, + "rightSide": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "nullPointMode": "null", + "options": { + "alertThreshold": true + }, + "percentage": false, + "pluginVersion": "8.4.7", + "pointradius": 2, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "datasource": { + "type": "prometheus" + }, + "expr": "rate(db_op_set_count{instance=~\"$instance\"}[1m])", + "interval": "", + "legendFormat": "", + "refId": "E" + }, + { + "datasource": { + "type": "prometheus" + }, + "expr": "rate(db_op_set_range_count{instance=~\"$instance\"}[1m])", + "interval": "", + "legendFormat": "", + "refId": "F" + }, + { + "datasource": { + "type": "prometheus" + }, + "expr": "rate(db_op_get_count{instance=~\"$instance\"}[1m])", + "interval": "", + "legendFormat": "", + "refId": "G" + }, + { + "datasource": { + "type": "prometheus" + }, + "expr": "rate(db_op_get_both{instance=~\"$instance\"}[1m])", + "hide": false, + "interval": "", + "legendFormat": "", + "refId": "A" + }, + { + "datasource": { + "type": "prometheus" + }, + "expr": "rate(db_op_get_both_range_count{instance=~\"$instance\"}[1m])", + "hide": false, + "interval": "", + "legendFormat": "", + "refId": "B" + }, + { + "datasource": { + "type": "prometheus" + }, + "expr": "db_op_put{quantile=\"$quantile\",instance=~\"$instance\"}", + "hide": false, + "interval": "", + "legendFormat": "", + "refId": "C" + }, + { + "datasource": { + "type": "prometheus" + }, + "expr": "db_op_put_current{quantile=\"$quantile\",instance=~\"$instance\"}", + "hide": false, + "interval": "", + "legendFormat": "", + "refId": "D" + }, + { + "datasource": { + "type": "prometheus" + }, + "expr": "db_op_put_no_overwrite{quantile=\"$quantile\",instance=~\"$instance\"}", + "hide": false, + "interval": "", + "legendFormat": "", + "refId": "H" + } + ], + "thresholds": [], + "timeRegions": [], + "title": "AutoDupsort Call/Sec", + "tooltip": { + "shared": true, + "sort": 2, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "mode": "time", + "show": true, + "values": [] + }, + "yaxes": [ + { + "$$hashKey": "object:139", + "format": "short", + "logBase": 1, + "show": true + }, + { + "$$hashKey": "object:140", + "format": "short", + "logBase": 1, + "show": true + } + ], + "yaxis": { + "align": false + } + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": { + "type": "prometheus" + }, + "fill": 1, + "fillGradient": 0, + "gridPos": { + "h": 4, + "w": 8, + "x": 16, + "y": 127 + }, + "hiddenSeries": false, + "id": 156, + "legend": { + "avg": true, + "current": true, + "max": false, + "min": false, + "show": true, + "total": false, + "values": true + }, + "lines": true, + "linewidth": 1, + "nullPointMode": "null", + "options": { + "alertThreshold": true + }, + "percentage": false, + "pluginVersion": "8.4.7", + "pointradius": 2, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "datasource": { + "type": "prometheus" + }, + "expr": "db_get{quantile=\"$quantile\",instance=~\"$instance\"}", + "interval": "", + "legendFormat": "get: {{quantile}}, {{instance}}", + "refId": "A" + } + ], + "thresholds": [], + "timeRegions": [], + "title": "db.Get() latency", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "mode": "time", + "show": true, + "values": [] + }, + "yaxes": [ + { + "$$hashKey": "object:887", + "format": "ns", + "logBase": 1, + "show": true + }, + { + "$$hashKey": "object:888", + "format": "short", + "logBase": 1, + "show": true + } + ], + "yaxis": { + "align": false + } + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": { + "type": "prometheus" + }, + "description": "", + "fill": 1, + "fillGradient": 0, + "gridPos": { + "h": 5, + "w": 8, + "x": 0, + "y": 132 + }, + "hiddenSeries": false, + "id": 143, + "legend": { + "avg": false, + "current": false, + "hideEmpty": true, + "hideZero": true, + "max": false, + "min": false, + "rightSide": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "nullPointMode": "null", + "options": { + "alertThreshold": true + }, + "percentage": false, + "pluginVersion": "8.4.7", + "pointradius": 2, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "datasource": { + "type": "prometheus" + }, + "expr": "db_op_set{quantile=\"$quantile\",instance=~\"$instance\"}", + "interval": "", + "legendFormat": "", + "refId": "E" + }, + { + "datasource": { + "type": "prometheus" + }, + "expr": "db_op_set_range{quantile=\"$quantile\",instance=~\"$instance\"}", + "interval": "", + "legendFormat": "", + "refId": "F" + }, + { + "datasource": { + "type": "prometheus" + }, + "expr": "db_op_get{quantile=\"$quantile\",instance=~\"$instance\"}", + "interval": "", + "legendFormat": "", + "refId": "G" + }, + { + "datasource": { + "type": "prometheus" + }, + "expr": "db_op_get_both{quantile=\"$quantile\",instance=~\"$instance\"}", + "hide": false, + "interval": "", + "legendFormat": "", + "refId": "A" + }, + { + "datasource": { + "type": "prometheus" + }, + "expr": "db_op_get_both_range{quantile=\"$quantile\",instance=~\"$instance\"}", + "hide": false, + "interval": "", + "legendFormat": "", + "refId": "B" + }, + { + "datasource": { + "type": "prometheus" + }, + "expr": "db_op_put{quantile=\"$quantile\",instance=~\"$instance\"}", + "hide": false, + "interval": "", + "legendFormat": "", + "refId": "C" + }, + { + "datasource": { + "type": "prometheus" + }, + "expr": "db_op_put_current{quantile=\"$quantile\",instance=~\"$instance\"}", + "hide": false, + "interval": "", + "legendFormat": "", + "refId": "D" + }, + { + "datasource": { + "type": "prometheus" + }, + "expr": "db_op_put_no_overwrite{quantile=\"$quantile\",instance=~\"$instance\"}", + "hide": false, + "interval": "", + "legendFormat": "", + "refId": "H" + } + ], + "thresholds": [], + "timeRegions": [], + "title": "AutoDupsort Call/Sec", + "tooltip": { + "shared": true, + "sort": 2, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "mode": "time", + "show": true, + "values": [] + }, + "yaxes": [ + { + "$$hashKey": "object:139", + "format": "ns", + "logBase": 1, + "show": true + }, + { + "$$hashKey": "object:140", + "format": "short", + "logBase": 1, + "show": true + } + ], + "yaxis": { + "align": false + } + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": { + "type": "prometheus" + }, + "description": "", + "fill": 1, + "fillGradient": 0, + "gridPos": { + "h": 5, + "w": 8, + "x": 8, + "y": 132 + }, + "hiddenSeries": false, + "id": 142, + "legend": { + "alignAsTable": false, + "avg": true, + "current": false, + "hideEmpty": true, + "hideZero": true, + "max": false, + "min": false, + "rightSide": false, + "show": true, + "sort": "avg", + "sortDesc": true, + "total": false, + "values": true + }, + "lines": true, + "linewidth": 1, + "nullPointMode": "null", + "options": { + "alertThreshold": true + }, + "percentage": false, + "pluginVersion": "8.4.7", + "pointradius": 2, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "datasource": { + "type": "prometheus" + }, + "expr": "mdbx_put_direct{quantile=\"$quantile\",instance=~\"$instance\"}", + "instant": false, + "interval": "", + "legendFormat": "mdbx_put_direct: {{quantile}}, {{instance}}", + "refId": "A" + }, + { + "datasource": { + "type": "prometheus" + }, + "expr": "mdbx_put_direct{quantile=\"$quantile\",instance=~\"$instance\"}", + "interval": "", + "legendFormat": "mdbx_put_direct: {{quantile}}, {{instance}}", + "refId": "C" + }, + { + "datasource": { + "type": "prometheus" + }, + "expr": "mdbx_put_both_range{quantile=\"$quantile\",instance=~\"$instance\"}", + "instant": false, + "interval": "", + "legendFormat": "mdbx_put_both_range: {{quantile}}, {{instance}}", + "refId": "B" + }, + { + "datasource": { + "type": "prometheus" + }, + "expr": "mdbx_put_both_range{quantile=\"$quantile\",instance=~\"$instance\"}", + "interval": "", + "legendFormat": "mdbx_put_both_range: {{quantile}}, {{instance}}", + "refId": "D" + }, + { + "datasource": { + "type": "prometheus" + }, + "expr": "mdbx_seek_exact{quantile=\"$quantile\",instance=~\"$instance\"}", + "hide": false, + "interval": "", + "legendFormat": "mdbx_seek_exact: {{quantile}}, {{instance}}", + "refId": "I" + }, + { + "datasource": { + "type": "prometheus" + }, + "expr": "mdbx_seek_exact{quantile=\"$quantile\",instance=~\"$instance\"}", + "hide": false, + "interval": "", + "legendFormat": "mdbx_seek_exact: {{quantile}}, {{instance}}", + "refId": "J" + }, + { + "datasource": { + "type": "prometheus" + }, + "expr": "mdbx_put_no_overwrite{quantile=\"$quantile\",instance=~\"$instance\"}", + "interval": "", + "legendFormat": "mdbx_put_no_overwrite: {{quantile}}, {{instance}}", + "refId": "F" + }, + { + "datasource": { + "type": "prometheus" + }, + "expr": "mdbx_put_no_overwrite{quantile=\"$quantile\",instance=~\"$instance\"}", + "interval": "", + "legendFormat": "mdbx_put_no_overwrite: {{quantile}}, {{instance}}", + "refId": "E" + }, + { + "datasource": { + "type": "prometheus" + }, + "expr": "mdbx_put_upsert{quantile=\"$quantile\",instance=~\"$instance\"}", + "interval": "", + "legendFormat": "mdbx_put_upsert: {{quantile}}, {{instance}}", + "refId": "G" }, { - "aliasColors": {}, - "bars": false, - "dashLength": 10, - "dashes": false, - "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" - }, - "description": "", - "fill": 1, - "fillGradient": 0, - "gridPos": { - "h": 5, - "w": 8, - "x": 8, - "y": 54 - }, - "hiddenSeries": false, - "id": 162, - "legend": { - "avg": false, - "current": false, - "hideEmpty": true, - "hideZero": true, - "max": false, - "min": false, - "rightSide": false, - "show": true, - "total": false, - "values": false - }, - "lines": true, - "linewidth": 1, - "nullPointMode": "null", - "options": { - "alertThreshold": true - }, - "percentage": false, - "pluginVersion": "8.0.6", - "pointradius": 2, - "points": false, - "renderer": "flot", - "seriesOverrides": [], - "spaceLength": 10, - "stack": false, - "steppedLine": false, - "targets": [ - { - "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" - }, - "expr": "rate(db_op_set_count{instance=~\"$instance\"}[1m])", - "interval": "", - "legendFormat": "", - "refId": "E" - }, - { - "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" - }, - "expr": "rate(db_op_set_range_count{instance=~\"$instance\"}[1m])", - "interval": "", - "legendFormat": "", - "refId": "F" - }, - { - "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" - }, - "expr": "rate(db_op_get_count{instance=~\"$instance\"}[1m])", - "interval": "", - "legendFormat": "", - "refId": "G" - }, - { - "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" - }, - "expr": "rate(db_op_get_both{instance=~\"$instance\"}[1m])", - "hide": false, - "interval": "", - "legendFormat": "", - "refId": "A" - }, - { - "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" - }, - "expr": "rate(db_op_get_both_range_count{instance=~\"$instance\"}[1m])", - "hide": false, - "interval": "", - "legendFormat": "", - "refId": "B" - }, - { - "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" - }, - "expr": "db_op_put{quantile=\"$quantile\",instance=~\"$instance\"}", - "hide": false, - "interval": "", - "legendFormat": "", - "refId": "C" - }, - { - "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" - }, - "expr": "db_op_put_current{quantile=\"$quantile\",instance=~\"$instance\"}", - "hide": false, - "interval": "", - "legendFormat": "", - "refId": "D" - }, - { - "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" - }, - "expr": "db_op_put_no_overwrite{quantile=\"$quantile\",instance=~\"$instance\"}", - "hide": false, - "interval": "", - "legendFormat": "", - "refId": "H" - } - ], - "thresholds": [], - "timeRegions": [], - "title": "AutoDupsort Call/Sec", - "tooltip": { - "shared": true, - "sort": 2, - "value_type": "individual" - }, - "type": "graph", - "xaxis": { - "mode": "time", - "show": true, - "values": [] - }, - "yaxes": [ - { - "$$hashKey": "object:139", - "format": "short", - "logBase": 1, - "show": true - }, - { - "$$hashKey": "object:140", - "format": "short", - "logBase": 1, - "show": true - } - ], - "yaxis": { - "align": false - } + "datasource": { + "type": "prometheus" + }, + "expr": "mdbx_put_upsert{quantile=\"$quantile\",instance=~\"$instance\"}", + "interval": "", + "legendFormat": "mdbx_put_upsert: {{quantile}}, {{instance}}", + "refId": "H" }, { - "aliasColors": {}, - "bars": false, - "dashLength": 10, - "dashes": false, - "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" - }, - "fill": 1, - "fillGradient": 0, - "gridPos": { - "h": 4, - "w": 8, - "x": 16, - "y": 54 - }, - "hiddenSeries": false, - "id": 156, - "legend": { - "avg": true, - "current": true, - "max": false, - "min": false, - "show": true, - "total": false, - "values": true - }, - "lines": true, - "linewidth": 1, - "nullPointMode": "null", - "options": { - "alertThreshold": true - }, - "percentage": false, - "pluginVersion": "8.0.6", - "pointradius": 2, - "points": false, - "renderer": "flot", - "seriesOverrides": [], - "spaceLength": 10, - "stack": false, - "steppedLine": false, - "targets": [ - { - "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" - }, - "expr": "db_get{quantile=\"$quantile\",instance=~\"$instance\"}", - "interval": "", - "legendFormat": "get: {{quantile}}, {{instance}}", - "refId": "A" - } - ], - "thresholds": [], - "timeRegions": [], - "title": "db.Get() latency", - "tooltip": { - "shared": true, - "sort": 0, - "value_type": "individual" - }, - "type": "graph", - "xaxis": { - "mode": "time", - "show": true, - "values": [] - }, - "yaxes": [ - { - "$$hashKey": "object:887", - "format": "ns", - "logBase": 1, - "show": true - }, - { - "$$hashKey": "object:888", - "format": "short", - "logBase": 1, - "show": true - } - ], - "yaxis": { - "align": false - } + "datasource": { + "type": "prometheus" + }, + "expr": "mdbx_put_current2{quantile=\"$quantile\",instance=~\"$instance\"}", + "interval": "", + "legendFormat": "mdbx_put_current2: {{quantile}}, {{instance}}", + "refId": "K" }, { - "aliasColors": {}, - "bars": false, - "dashLength": 10, - "dashes": false, - "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" - }, - "description": "", - "fill": 1, - "fillGradient": 0, - "gridPos": { - "h": 5, - "w": 8, - "x": 0, - "y": 59 - }, - "hiddenSeries": false, - "id": 143, - "legend": { - "avg": false, - "current": false, - "hideEmpty": true, - "hideZero": true, - "max": false, - "min": false, - "rightSide": false, - "show": true, - "total": false, - "values": false - }, - "lines": true, - "linewidth": 1, - "nullPointMode": "null", - "options": { - "alertThreshold": true - }, - "percentage": false, - "pluginVersion": "8.0.6", - "pointradius": 2, - "points": false, - "renderer": "flot", - "seriesOverrides": [], - "spaceLength": 10, - "stack": false, - "steppedLine": false, - "targets": [ - { - "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" - }, - "expr": "db_op_set{quantile=\"$quantile\",instance=~\"$instance\"}", - "interval": "", - "legendFormat": "", - "refId": "E" - }, - { - "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" - }, - "expr": "db_op_set_range{quantile=\"$quantile\",instance=~\"$instance\"}", - "interval": "", - "legendFormat": "", - "refId": "F" - }, - { - "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" - }, - "expr": "db_op_get{quantile=\"$quantile\",instance=~\"$instance\"}", - "interval": "", - "legendFormat": "", - "refId": "G" - }, - { - "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" - }, - "expr": "db_op_get_both{quantile=\"$quantile\",instance=~\"$instance\"}", - "hide": false, - "interval": "", - "legendFormat": "", - "refId": "A" - }, - { - "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" - }, - "expr": "db_op_get_both_range{quantile=\"$quantile\",instance=~\"$instance\"}", - "hide": false, - "interval": "", - "legendFormat": "", - "refId": "B" - }, - { - "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" - }, - "expr": "db_op_put{quantile=\"$quantile\",instance=~\"$instance\"}", - "hide": false, - "interval": "", - "legendFormat": "", - "refId": "C" - }, - { - "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" - }, - "expr": "db_op_put_current{quantile=\"$quantile\",instance=~\"$instance\"}", - "hide": false, - "interval": "", - "legendFormat": "", - "refId": "D" - }, - { - "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" - }, - "expr": "db_op_put_no_overwrite{quantile=\"$quantile\",instance=~\"$instance\"}", - "hide": false, - "interval": "", - "legendFormat": "", - "refId": "H" - } - ], - "thresholds": [], - "timeRegions": [], - "title": "AutoDupsort Call/Sec", - "tooltip": { - "shared": true, - "sort": 2, - "value_type": "individual" - }, - "type": "graph", - "xaxis": { - "mode": "time", - "show": true, - "values": [] - }, - "yaxes": [ - { - "$$hashKey": "object:139", - "format": "ns", - "logBase": 1, - "show": true - }, - { - "$$hashKey": "object:140", - "format": "short", - "logBase": 1, - "show": true - } - ], - "yaxis": { - "align": false - } + "datasource": { + "type": "prometheus" + }, + "expr": "mdbx_put_current2{quantile=\"$quantile\",instance=~\"$instance\"}", + "interval": "", + "legendFormat": "mdbx_put_current2: {{quantile}}, {{instance}}", + "refId": "L" }, { - "aliasColors": {}, - "bars": false, - "dashLength": 10, - "dashes": false, - "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" - }, - "description": "", - "fill": 1, - "fillGradient": 0, - "gridPos": { - "h": 5, - "w": 8, - "x": 8, - "y": 59 - }, - "hiddenSeries": false, - "id": 142, - "legend": { - "alignAsTable": false, - "avg": true, - "current": false, - "hideEmpty": true, - "hideZero": true, - "max": false, - "min": false, - "rightSide": false, - "show": true, - "sort": "avg", - "sortDesc": true, - "total": false, - "values": true - }, - "lines": true, - "linewidth": 1, - "nullPointMode": "null", - "options": { - "alertThreshold": true - }, - "percentage": false, - "pluginVersion": "8.0.6", - "pointradius": 2, - "points": false, - "renderer": "flot", - "seriesOverrides": [], - "spaceLength": 10, - "stack": false, - "steppedLine": false, - "targets": [ - { - "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" - }, - "expr": "mdbx_put_direct{quantile=\"$quantile\",instance=~\"$instance\"}", - "instant": false, - "interval": "", - "legendFormat": "mdbx_put_direct: {{quantile}}, {{instance}}", - "refId": "A" - }, - { - "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" - }, - "expr": "mdbx_put_direct{quantile=\"$quantile\",instance=~\"$instance\"}", - "interval": "", - "legendFormat": "mdbx_put_direct: {{quantile}}, {{instance}}", - "refId": "C" - }, - { - "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" - }, - "expr": "mdbx_put_both_range{quantile=\"$quantile\",instance=~\"$instance\"}", - "instant": false, - "interval": "", - "legendFormat": "mdbx_put_both_range: {{quantile}}, {{instance}}", - "refId": "B" - }, - { - "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" - }, - "expr": "mdbx_put_both_range{quantile=\"$quantile\",instance=~\"$instance\"}", - "interval": "", - "legendFormat": "mdbx_put_both_range: {{quantile}}, {{instance}}", - "refId": "D" - }, - { - "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" - }, - "expr": "mdbx_seek_exact{quantile=\"$quantile\",instance=~\"$instance\"}", - "hide": false, - "interval": "", - "legendFormat": "mdbx_seek_exact: {{quantile}}, {{instance}}", - "refId": "I" - }, - { - "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" - }, - "expr": "mdbx_seek_exact{quantile=\"$quantile\",instance=~\"$instance\"}", - "hide": false, - "interval": "", - "legendFormat": "mdbx_seek_exact: {{quantile}}, {{instance}}", - "refId": "J" - }, - { - "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" - }, - "expr": "mdbx_put_no_overwrite{quantile=\"$quantile\",instance=~\"$instance\"}", - "interval": "", - "legendFormat": "mdbx_put_no_overwrite: {{quantile}}, {{instance}}", - "refId": "F" - }, - { - "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" - }, - "expr": "mdbx_put_no_overwrite{quantile=\"$quantile\",instance=~\"$instance\"}", - "interval": "", - "legendFormat": "mdbx_put_no_overwrite: {{quantile}}, {{instance}}", - "refId": "E" - }, - { - "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" - }, - "expr": "mdbx_put_upsert{quantile=\"$quantile\",instance=~\"$instance\"}", - "interval": "", - "legendFormat": "mdbx_put_upsert: {{quantile}}, {{instance}}", - "refId": "G" - }, - { - "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" - }, - "expr": "mdbx_put_upsert{quantile=\"$quantile\",instance=~\"$instance\"}", - "interval": "", - "legendFormat": "mdbx_put_upsert: {{quantile}}, {{instance}}", - "refId": "H" - }, - { - "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" - }, - "expr": "mdbx_put_current2{quantile=\"$quantile\",instance=~\"$instance\"}", - "interval": "", - "legendFormat": "mdbx_put_current2: {{quantile}}, {{instance}}", - "refId": "K" - }, - { - "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" - }, - "expr": "mdbx_put_current2{quantile=\"$quantile\",instance=~\"$instance\"}", - "interval": "", - "legendFormat": "mdbx_put_current2: {{quantile}}, {{instance}}", - "refId": "L" - }, - { - "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" - }, - "expr": "mdbx_put_upsert2{quantile=\"$quantile\",instance=~\"$instance\"}", - "interval": "", - "legendFormat": "mdbx_put_upsert2: {{quantile}}, {{instance}}", - "refId": "M" - }, - { - "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" - }, - "expr": "mdbx_put_upsert2{quantile=\"$quantile\",instance=~\"$instance\"}", - "interval": "", - "legendFormat": "mdbx_put_upsert2: {{quantile}}, {{instance}}", - "refId": "N" - }, - { - "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" - }, - "expr": "mdbx_del_current{quantile=\"$quantile\",instance=~\"$instance\"}", - "interval": "", - "legendFormat": "mdbx_put_current: {{quantile}}, {{instance}}", - "refId": "O" - }, - { - "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" - }, - "expr": "mdbx_del_current{quantile=\"$quantile\",instance=~\"$instance\"}", - "interval": "", - "legendFormat": "mdbx_del_current: {{quantile}}, {{instance}}", - "refId": "P" - }, - { - "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" - }, - "expr": "mdbx_seek_exact2{quantile=\"$quantile\",instance=~\"$instance\"}", - "hide": false, - "interval": "", - "legendFormat": "mdbx_seek_exact2: {{quantile}}, {{instance}}", - "refId": "Q" - }, - { - "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" - }, - "expr": "mdbx_seek_exact2{quantile=\"$quantile\",instance=~\"$instance\"}", - "hide": false, - "interval": "", - "legendFormat": "mdbx_seek_exact2: {{quantile}}, {{instance}}", - "refId": "R" - } - ], - "thresholds": [], - "timeRegions": [], - "title": "AutoDupsort Put latency", - "tooltip": { - "shared": true, - "sort": 2, - "value_type": "individual" - }, - "type": "graph", - "xaxis": { - "mode": "time", - "show": true, - "values": [] - }, - "yaxes": [ - { - "$$hashKey": "object:139", - "format": "ns", - "logBase": 1, - "show": true - }, - { - "$$hashKey": "object:140", - "format": "short", - "logBase": 1, - "show": false - } - ], - "yaxis": { - "align": false - } - } - ], - "targets": [ + "datasource": { + "type": "prometheus" + }, + "expr": "mdbx_put_upsert2{quantile=\"$quantile\",instance=~\"$instance\"}", + "interval": "", + "legendFormat": "mdbx_put_upsert2: {{quantile}}, {{instance}}", + "refId": "M" + }, { "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" + "type": "prometheus" }, - "refId": "A" + "expr": "mdbx_put_upsert2{quantile=\"$quantile\",instance=~\"$instance\"}", + "interval": "", + "legendFormat": "mdbx_put_upsert2: {{quantile}}, {{instance}}", + "refId": "N" + }, + { + "datasource": { + "type": "prometheus" + }, + "expr": "mdbx_del_current{quantile=\"$quantile\",instance=~\"$instance\"}", + "interval": "", + "legendFormat": "mdbx_put_current: {{quantile}}, {{instance}}", + "refId": "O" + }, + { + "datasource": { + "type": "prometheus" + }, + "expr": "mdbx_del_current{quantile=\"$quantile\",instance=~\"$instance\"}", + "interval": "", + "legendFormat": "mdbx_del_current: {{quantile}}, {{instance}}", + "refId": "P" + }, + { + "datasource": { + "type": "prometheus" + }, + "expr": "mdbx_seek_exact2{quantile=\"$quantile\",instance=~\"$instance\"}", + "hide": false, + "interval": "", + "legendFormat": "mdbx_seek_exact2: {{quantile}}, {{instance}}", + "refId": "Q" + }, + { + "datasource": { + "type": "prometheus" + }, + "expr": "mdbx_seek_exact2{quantile=\"$quantile\",instance=~\"$instance\"}", + "hide": false, + "interval": "", + "legendFormat": "mdbx_seek_exact2: {{quantile}}, {{instance}}", + "refId": "R" } ], - "title": "Hidden", - "type": "row" + "thresholds": [], + "timeRegions": [], + "title": "AutoDupsort Put latency", + "tooltip": { + "shared": true, + "sort": 2, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "mode": "time", + "show": true, + "values": [] + }, + "yaxes": [ + { + "$$hashKey": "object:139", + "format": "ns", + "logBase": 1, + "show": true + }, + { + "$$hashKey": "object:140", + "format": "short", + "logBase": 1, + "show": false + } + ], + "yaxis": { + "align": false + } }, { "collapsed": false, "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" + "type": "prometheus" }, "gridPos": { "h": 1, "w": 24, "x": 0, - "y": 130 + "y": 137 }, "id": 75, "panels": [], "targets": [ { "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" + "type": "prometheus" }, "refId": "A" } @@ -5783,8 +5462,7 @@ }, { "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" + "type": "prometheus" }, "fieldConfig": { "defaults": { @@ -5792,8 +5470,6 @@ "mode": "palette-classic" }, "custom": { - "axisCenteredZero": false, - "axisColorMode": "text", "axisLabel": "", "axisPlacement": "auto", "barAlignment": 0, @@ -5842,7 +5518,7 @@ "h": 6, "w": 12, "x": 0, - "y": 131 + "y": 138 }, "id": 96, "links": [], @@ -5867,8 +5543,7 @@ "targets": [ { "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" + "type": "prometheus" }, "exemplar": true, "expr": "rate(p2p_ingress{instance=~\"$instance\"}[$rate_interval])", @@ -5880,8 +5555,7 @@ }, { "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" + "type": "prometheus" }, "exemplar": true, "expr": "rate(p2p_egress{instance=~\"$instance\"}[$rate_interval])", @@ -5898,8 +5572,7 @@ }, { "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" + "type": "prometheus" }, "fieldConfig": { "defaults": { @@ -5907,8 +5580,6 @@ "mode": "palette-classic" }, "custom": { - "axisCenteredZero": false, - "axisColorMode": "text", "axisLabel": "", "axisPlacement": "auto", "barAlignment": 0, @@ -5957,7 +5628,7 @@ "h": 6, "w": 12, "x": 12, - "y": 131 + "y": 138 }, "id": 77, "links": [], @@ -5982,8 +5653,7 @@ "targets": [ { "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" + "type": "prometheus" }, "expr": "p2p_peers{instance=~\"$instance\"}", "format": "time_series", @@ -5994,8 +5664,7 @@ }, { "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" + "type": "prometheus" }, "expr": "rate(p2p_dials{instance=~\"$instance\"}[1m])", "format": "time_series", @@ -6006,8 +5675,7 @@ }, { "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" + "type": "prometheus" }, "expr": "rate(p2p_serves{instance=~\"$instance\"}[1m])", "format": "time_series", @@ -6023,22 +5691,20 @@ { "collapsed": false, "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" + "type": "prometheus" }, "gridPos": { "h": 1, "w": 24, "x": 0, - "y": 137 + "y": 144 }, "id": 4, "panels": [], "targets": [ { "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" + "type": "prometheus" }, "refId": "A" } @@ -6048,8 +5714,7 @@ }, { "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" + "type": "prometheus" }, "fieldConfig": { "defaults": { @@ -6084,7 +5749,7 @@ "h": 3, "w": 4, "x": 0, - "y": 138 + "y": 145 }, "id": 108, "links": [], @@ -6109,12 +5774,11 @@ "text": {}, "textMode": "auto" }, - "pluginVersion": "9.2.3", + "pluginVersion": "8.4.7", "targets": [ { "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" + "type": "prometheus" }, "expr": "sync{instance=~\"$instance\",stage=\"headers\"}", "format": "time_series", @@ -6129,8 +5793,7 @@ }, { "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" + "type": "prometheus" }, "fieldConfig": { "defaults": { @@ -6165,7 +5828,7 @@ "h": 3, "w": 4, "x": 8, - "y": 138 + "y": 145 }, "id": 109, "links": [], @@ -6190,15 +5853,14 @@ "text": {}, "textMode": "auto" }, - "pluginVersion": "9.2.3", + "pluginVersion": "8.4.7", "targets": [ { "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" + "type": "prometheus" }, "exemplar": true, - "expr": "stage_headers{instance=~\"$instance\"}", + "expr": "sync{stage=\"headers\", instance=~\"$instance\"}", "format": "time_series", "interval": "", "intervalFactor": 1, @@ -6211,8 +5873,7 @@ }, { "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" + "type": "prometheus" }, "fieldConfig": { "defaults": { @@ -6247,7 +5908,7 @@ "h": 3, "w": 4, "x": 12, - "y": 138 + "y": 145 }, "id": 113, "links": [], @@ -6272,12 +5933,11 @@ "text": {}, "textMode": "auto" }, - "pluginVersion": "9.2.3", + "pluginVersion": "8.4.7", "targets": [ { "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" + "type": "prometheus" }, "expr": "txpool_pending{instance=~\"$instance\"}", "format": "time_series", @@ -6292,8 +5952,7 @@ }, { "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" + "type": "prometheus" }, "fieldConfig": { "defaults": { @@ -6328,7 +5987,7 @@ "h": 3, "w": 4, "x": 16, - "y": 138 + "y": 145 }, "id": 114, "links": [], @@ -6353,12 +6012,11 @@ "text": {}, "textMode": "auto" }, - "pluginVersion": "9.2.3", + "pluginVersion": "8.4.7", "targets": [ { "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" + "type": "prometheus" }, "expr": "txpool_queued{instance=~\"$instance\"}", "format": "time_series", @@ -6373,8 +6031,7 @@ }, { "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" + "type": "prometheus" }, "fieldConfig": { "defaults": { @@ -6409,7 +6066,7 @@ "h": 3, "w": 4, "x": 20, - "y": 138 + "y": 145 }, "id": 115, "links": [], @@ -6434,13 +6091,13 @@ "text": {}, "textMode": "auto" }, - "pluginVersion": "9.2.3", + "pluginVersion": "8.4.7", "targets": [ { "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" + "type": "prometheus" }, + "exemplar": true, "expr": "txpool_local{instance=~\"$instance\"}", "format": "time_series", "interval": "", @@ -6454,8 +6111,7 @@ }, { "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" + "type": "prometheus" }, "fieldConfig": { "defaults": { @@ -6463,8 +6119,6 @@ "mode": "palette-classic" }, "custom": { - "axisCenteredZero": false, - "axisColorMode": "text", "axisLabel": "", "axisPlacement": "auto", "barAlignment": 0, @@ -6513,7 +6167,7 @@ "h": 6, "w": 12, "x": 0, - "y": 141 + "y": 148 }, "id": 110, "links": [], @@ -6533,8 +6187,7 @@ "targets": [ { "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" + "type": "prometheus" }, "expr": "chain_head_header{instance=~\"$instance\"}", "format": "time_series", @@ -6545,8 +6198,7 @@ }, { "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" + "type": "prometheus" }, "expr": "chain_head_receipt{instance=~\"$instance\"}", "format": "time_series", @@ -6557,8 +6209,7 @@ }, { "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" + "type": "prometheus" }, "expr": "chain_head_block{instance=~\"$instance\"}", "format": "time_series", @@ -6573,8 +6224,7 @@ }, { "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" + "type": "prometheus" }, "fieldConfig": { "defaults": { @@ -6582,8 +6232,6 @@ "mode": "palette-classic" }, "custom": { - "axisCenteredZero": false, - "axisColorMode": "text", "axisLabel": "", "axisPlacement": "auto", "barAlignment": 0, @@ -6632,7 +6280,7 @@ "h": 6, "w": 12, "x": 12, - "y": 141 + "y": 148 }, "id": 116, "links": [], @@ -6652,8 +6300,7 @@ "targets": [ { "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" + "type": "prometheus" }, "expr": "txpool_pending{instance=~\"$instance\"}", "format": "time_series", @@ -6664,8 +6311,7 @@ }, { "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" + "type": "prometheus" }, "expr": "txpool_queued{instance=~\"$instance\"}", "format": "time_series", @@ -6676,8 +6322,7 @@ }, { "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" + "type": "prometheus" }, "expr": "txpool_local{instance=~\"$instance\"}", "format": "time_series", @@ -6692,8 +6337,7 @@ }, { "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" + "type": "prometheus" }, "fieldConfig": { "defaults": { @@ -6701,8 +6345,6 @@ "mode": "palette-classic" }, "custom": { - "axisCenteredZero": false, - "axisColorMode": "text", "axisLabel": "", "axisPlacement": "auto", "barAlignment": 0, @@ -6751,7 +6393,7 @@ "h": 7, "w": 24, "x": 0, - "y": 147 + "y": 154 }, "id": 117, "links": [], @@ -6776,8 +6418,7 @@ "targets": [ { "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" + "type": "prometheus" }, "expr": "rate(txpool_valid{instance=~\"$instance\"}[1m])", "format": "time_series", @@ -6788,8 +6429,7 @@ }, { "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" + "type": "prometheus" }, "expr": "rate(txpool_invalid{instance=~\"$instance\"}[1m])", "format": "time_series", @@ -6800,8 +6440,7 @@ }, { "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" + "type": "prometheus" }, "expr": "rate(txpool_underpriced{instance=\"$instance\"}[1m])", "format": "time_series", @@ -6813,8 +6452,7 @@ }, { "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" + "type": "prometheus" }, "expr": "rate(txpool_pending_discard{instance=\"$instance\"}[1m])", "format": "time_series", @@ -6826,8 +6464,7 @@ }, { "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" + "type": "prometheus" }, "expr": "rate(txpool_pending_replace{instance=\"$instance\"}[1m])", "format": "time_series", @@ -6838,8 +6475,7 @@ }, { "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" + "type": "prometheus" }, "expr": "rate(txpool_pending_ratelimit{instance=\"$instance\"}[1m])", "format": "time_series", @@ -6850,8 +6486,7 @@ }, { "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" + "type": "prometheus" }, "expr": "rate(txpool_pending_nofunds{instance=\"$instance\"}[1m])", "format": "time_series", @@ -6862,8 +6497,7 @@ }, { "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" + "type": "prometheus" }, "expr": "rate(txpool_queued_discard{instance=\"$instance\"}[1m])", "format": "time_series", @@ -6875,8 +6509,7 @@ }, { "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" + "type": "prometheus" }, "expr": "rate(txpool_queued_replace{instance=\"$instance\"}[1m])", "format": "time_series", @@ -6888,8 +6521,7 @@ }, { "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" + "type": "prometheus" }, "expr": "rate(txpool_queued_ratelimit{instance=\"$instance\"}[1m])", "format": "time_series", @@ -6901,8 +6533,7 @@ }, { "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" + "type": "prometheus" }, "expr": "rate(txpool_queued_nofunds{instance=\"$instance\"}[1m])", "format": "time_series", @@ -6917,136 +6548,125 @@ "type": "timeseries" }, { - "collapsed": true, + "collapsed": false, "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" + "type": "prometheus" }, "gridPos": { "h": 1, "w": 24, "x": 0, - "y": 154 + "y": 161 }, "id": 138, - "panels": [ + "panels": [], + "targets": [ { - "aliasColors": {}, - "bars": false, - "dashLength": 10, - "dashes": false, "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" + "type": "prometheus" }, - "fieldConfig": { - "defaults": { - "custom": {} - }, - "overrides": [] - }, - "fill": 1, - "fillGradient": 0, - "gridPos": { - "h": 8, - "w": 12, - "x": 0, - "y": 64 - }, - "hiddenSeries": false, - "id": 136, - "legend": { - "avg": false, - "current": false, - "max": false, - "min": false, - "show": true, - "total": false, - "values": false - }, - "lines": true, - "linewidth": 1, - "nullPointMode": "null", - "options": { - "alertThreshold": true - }, - "percentage": false, - "pluginVersion": "7.4.3", - "pointradius": 2, - "points": false, - "renderer": "flot", - "seriesOverrides": [], - "spaceLength": 10, - "stack": false, - "steppedLine": false, - "targets": [ - { - "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" - }, - "expr": "sum by (grpc_service, grpc_method, instance) (rate(grpc_server_started_total{instance=~\"$instance\"}[1m]))", - "interval": "", - "legendFormat": "Calls: {{grpc_service}}.{{grpc_method}}, {{instance}}", - "refId": "A" - }, - { - "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" - }, - "expr": "sum by (grpc_service, grpc_method, instance) (rate(grpc_server_handled_total{instance=~\"$instance\",grpc_code!=\"OK\"}[1m])) ", - "interval": "", - "legendFormat": "Errors: {{grpc_service}}.{{grpc_method}}, {{instance}}", - "refId": "B" - } - ], - "thresholds": [], - "timeRegions": [], - "title": "gRPC call, error rates ", - "tooltip": { - "shared": true, - "sort": 0, - "value_type": "individual" - }, - "type": "graph", - "xaxis": { - "mode": "time", - "show": true, - "values": [] - }, - "yaxes": [ - { - "format": "short", - "logBase": 1, - "show": true - }, - { - "format": "short", - "logBase": 1, - "show": true - } - ], - "yaxis": { - "align": false - } + "refId": "A" } ], + "title": "Private api", + "type": "row" + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": { + "type": "prometheus" + }, + "fill": 1, + "fillGradient": 0, + "gridPos": { + "h": 8, + "w": 12, + "x": 0, + "y": 162 + }, + "hiddenSeries": false, + "id": 136, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "nullPointMode": "null", + "options": { + "alertThreshold": true + }, + "percentage": false, + "pluginVersion": "8.4.7", + "pointradius": 2, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, "targets": [ { "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" + "type": "prometheus" }, + "expr": "sum by (grpc_service, grpc_method, instance) (rate(grpc_server_started_total{instance=~\"$instance\"}[1m]))", + "interval": "", + "legendFormat": "Calls: {{grpc_service}}.{{grpc_method}}, {{instance}}", "refId": "A" + }, + { + "datasource": { + "type": "prometheus" + }, + "expr": "sum by (grpc_service, grpc_method, instance) (rate(grpc_server_handled_total{instance=~\"$instance\",grpc_code!=\"OK\"}[1m])) ", + "interval": "", + "legendFormat": "Errors: {{grpc_service}}.{{grpc_method}}, {{instance}}", + "refId": "B" } ], - "title": "Private api", - "type": "row" + "thresholds": [], + "timeRegions": [], + "title": "gRPC call, error rates ", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "mode": "time", + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "short", + "logBase": 1, + "show": true + }, + { + "format": "short", + "logBase": 1, + "show": true + } + ], + "yaxis": { + "align": false + } } ], "refresh": "30s", - "schemaVersion": 37, + "revision": 1, + "schemaVersion": 38, "style": "dark", "tags": [], "templating": { @@ -7107,15 +6727,16 @@ "current": { "selected": true, "text": [ - "All" + "mainnet3-2:6061", + "mainnet3-3:6061" ], "value": [ - "$__all" + "mainnet3-2:6061", + "mainnet3-3:6061" ] }, "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" + "type": "prometheus" }, "definition": "go_goroutines", "hide": 0, @@ -7142,7 +6763,7 @@ "auto_count": 30, "auto_min": "10s", "current": { - "selected": true, + "selected": false, "text": "1m", "value": "1m" }, @@ -7215,7 +6836,7 @@ ] }, "time": { - "from": "now-1h", + "from": "now-15m", "to": "now" }, "timepicker": { @@ -7245,6 +6866,6 @@ "timezone": "", "title": "Erigon Prometheus", "uid": "FPpjH6Hik", - "version": 89, + "version": 103, "weekStart": "" } \ No newline at end of file diff --git a/cmd/rpcdaemon/README.md b/cmd/rpcdaemon/README.md index e1cbc8262bd..043f3efe73b 100644 --- a/cmd/rpcdaemon/README.md +++ b/cmd/rpcdaemon/README.md @@ -254,7 +254,7 @@ The following table shows the current implementation status of Erigon's RPC daem | eth_signTransaction | - | not yet implemented | | eth_signTypedData | - | ???? | | | | | -| eth_getProof | - | not yet implemented | +| eth_getProof | Yes | Limited to last 1000 blocks | | | | | | eth_mining | Yes | returns true if --mine flag provided | | eth_coinbase | Yes | | diff --git a/cmd/rpcdaemon/commands/call_traces_test.go b/cmd/rpcdaemon/commands/call_traces_test.go index 730410db4ea..7b040bfd5bc 100644 --- a/cmd/rpcdaemon/commands/call_traces_test.go +++ b/cmd/rpcdaemon/commands/call_traces_test.go @@ -75,7 +75,7 @@ func TestCallTraceOneByOne(t *testing.T) { ToBlock: (*hexutil.Uint64)(&toBlock), ToAddress: []*common.Address{&toAddress1}, } - if err = api.Filter(context.Background(), traceReq1, stream); err != nil { + if err = api.Filter(context.Background(), traceReq1, stream, new(bool)); err != nil { t.Fatalf("trace_filter failed: %v", err) } assert.Equal(t, []int{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}, blockNumbersFromTraces(t, stream.Buffer())) @@ -119,7 +119,7 @@ func TestCallTraceUnwind(t *testing.T) { ToBlock: (*hexutil.Uint64)(&toBlock), ToAddress: []*common.Address{&toAddress1}, } - if err = api.Filter(context.Background(), traceReq1, stream); err != nil { + if err = api.Filter(context.Background(), traceReq1, stream, new(bool)); err != nil { t.Fatalf("trace_filter failed: %v", err) } assert.Equal(t, []int{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}, blockNumbersFromTraces(t, stream.Buffer())) @@ -134,7 +134,7 @@ func TestCallTraceUnwind(t *testing.T) { ToBlock: (*hexutil.Uint64)(&toBlock), ToAddress: []*common.Address{&toAddress1}, } - if err = api.Filter(context.Background(), traceReq2, stream); err != nil { + if err = api.Filter(context.Background(), traceReq2, stream, new(bool)); err != nil { t.Fatalf("trace_filter failed: %v", err) } assert.Equal(t, []int{1, 2, 3, 4, 5, 11, 12}, blockNumbersFromTraces(t, stream.Buffer())) @@ -150,7 +150,7 @@ func TestCallTraceUnwind(t *testing.T) { ToBlock: (*hexutil.Uint64)(&toBlock), ToAddress: []*common.Address{&toAddress1}, } - if err = api.Filter(context.Background(), traceReq3, stream); err != nil { + if err = api.Filter(context.Background(), traceReq3, stream, new(bool)); err != nil { t.Fatalf("trace_filter failed: %v", err) } assert.Equal(t, []int{12, 13, 14, 15, 16, 17, 18, 19, 20}, blockNumbersFromTraces(t, stream.Buffer())) @@ -182,7 +182,7 @@ func TestFilterNoAddresses(t *testing.T) { FromBlock: (*hexutil.Uint64)(&fromBlock), ToBlock: (*hexutil.Uint64)(&toBlock), } - if err = api.Filter(context.Background(), traceReq1, stream); err != nil { + if err = api.Filter(context.Background(), traceReq1, stream, new(bool)); err != nil { t.Fatalf("trace_filter failed: %v", err) } assert.Equal(t, []int{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}, blockNumbersFromTraces(t, stream.Buffer())) @@ -233,7 +233,7 @@ func TestFilterAddressIntersection(t *testing.T) { ToAddress: []*common.Address{&m.Address, &toAddress2}, Mode: TraceFilterModeIntersection, } - if err = api.Filter(context.Background(), traceReq1, stream); err != nil { + if err = api.Filter(context.Background(), traceReq1, stream, new(bool)); err != nil { t.Fatalf("trace_filter failed: %v", err) } assert.Equal(t, []int{6, 7, 8, 9, 10}, blockNumbersFromTraces(t, stream.Buffer())) @@ -249,7 +249,7 @@ func TestFilterAddressIntersection(t *testing.T) { ToAddress: []*common.Address{&toAddress1, &m.Address}, Mode: TraceFilterModeIntersection, } - if err = api.Filter(context.Background(), traceReq1, stream); err != nil { + if err = api.Filter(context.Background(), traceReq1, stream, new(bool)); err != nil { t.Fatalf("trace_filter failed: %v", err) } assert.Equal(t, []int{1, 2, 3, 4, 5}, blockNumbersFromTraces(t, stream.Buffer())) @@ -265,7 +265,7 @@ func TestFilterAddressIntersection(t *testing.T) { FromAddress: []*common.Address{&toAddress2, &toAddress1, &other}, Mode: TraceFilterModeIntersection, } - if err = api.Filter(context.Background(), traceReq1, stream); err != nil { + if err = api.Filter(context.Background(), traceReq1, stream, new(bool)); err != nil { t.Fatalf("trace_filter failed: %v", err) } require.Empty(t, blockNumbersFromTraces(t, stream.Buffer())) diff --git a/cmd/rpcdaemon/commands/daemon.go b/cmd/rpcdaemon/commands/daemon.go index 87f30d6c909..12bdec39db8 100644 --- a/cmd/rpcdaemon/commands/daemon.go +++ b/cmd/rpcdaemon/commands/daemon.go @@ -15,7 +15,7 @@ import ( // APIList describes the list of available RPC apis func APIList(db kv.RoDB, borDb kv.RoDB, eth rpchelper.ApiBackend, txPool txpool.TxpoolClient, mining txpool.MiningClient, filters *rpchelper.Filters, stateCache kvcache.Cache, - blockReader services.FullBlockReader, agg *libstate.AggregatorV3, cfg httpcfg.HttpCfg, engine consensus.EngineReader, + blockReader services.FullBlockReader, agg *libstate.AggregatorV3, cfg httpcfg.HttpCfg, engine consensus.Engine, ) (list []rpc.API) { base := NewBaseApi(filters, stateCache, blockReader, agg, cfg.WithDatadir, cfg.EvmCallTimeout, engine) ethImpl := NewEthAPI(base, db, eth, txPool, mining, cfg.Gascap, cfg.ReturnDataLimit) diff --git a/cmd/rpcdaemon/commands/db_api_deprecated.go b/cmd/rpcdaemon/commands/db_api_deprecated.go index 886987e05c1..2ee0700a347 100644 --- a/cmd/rpcdaemon/commands/db_api_deprecated.go +++ b/cmd/rpcdaemon/commands/db_api_deprecated.go @@ -4,15 +4,15 @@ import ( "context" "fmt" - "github.com/ledgerwatch/erigon/common/hexutil" + "github.com/ledgerwatch/erigon-lib/common/hexutility" ) // DBAPI the interface for the db_ RPC commands (deprecated) type DBAPI interface { GetString(_ context.Context, _ string, _ string) (string, error) PutString(_ context.Context, _ string, _ string, _ string) (bool, error) - GetHex(_ context.Context, _ string, _ string) (hexutil.Bytes, error) - PutHex(_ context.Context, _ string, _ string, _ hexutil.Bytes) (bool, error) + GetHex(_ context.Context, _ string, _ string) (hexutility.Bytes, error) + PutHex(_ context.Context, _ string, _ string, _ hexutility.Bytes) (bool, error) } // DBAPIImpl data structure to store things needed for db_ commands @@ -41,12 +41,12 @@ func (api *DBAPIImpl) PutString(_ context.Context, _ string, _ string, _ string) // GetHex implements db_getHex. Returns binary data from the local database. // Deprecated: This function will be removed in the future. -func (api *DBAPIImpl) GetHex(_ context.Context, _ string, _ string) (hexutil.Bytes, error) { - return hexutil.Bytes(""), fmt.Errorf(NotAvailableDeprecated, "db_getHex") +func (api *DBAPIImpl) GetHex(_ context.Context, _ string, _ string) (hexutility.Bytes, error) { + return hexutility.Bytes(""), fmt.Errorf(NotAvailableDeprecated, "db_getHex") } // PutHex implements db_putHex. Stores binary data in the local database. // Deprecated: This function will be removed in the future. -func (api *DBAPIImpl) PutHex(_ context.Context, _ string, _ string, _ hexutil.Bytes) (bool, error) { +func (api *DBAPIImpl) PutHex(_ context.Context, _ string, _ string, _ hexutility.Bytes) (bool, error) { return false, fmt.Errorf(NotAvailableDeprecated, "db_putHex") } diff --git a/cmd/rpcdaemon/commands/debug_api.go b/cmd/rpcdaemon/commands/debug_api.go index 682c6a6e524..b6f72e536d8 100644 --- a/cmd/rpcdaemon/commands/debug_api.go +++ b/cmd/rpcdaemon/commands/debug_api.go @@ -6,19 +6,25 @@ import ( jsoniter "github.com/json-iterator/go" "github.com/ledgerwatch/erigon-lib/common" + "github.com/ledgerwatch/erigon-lib/common/hexutility" "github.com/ledgerwatch/erigon-lib/kv" "github.com/ledgerwatch/erigon-lib/kv/order" "github.com/ledgerwatch/erigon-lib/kv/rawdbv3" + "github.com/ledgerwatch/erigon/common/changeset" "github.com/ledgerwatch/erigon/common/hexutil" + "github.com/ledgerwatch/erigon/consensus" "github.com/ledgerwatch/erigon/core/rawdb" "github.com/ledgerwatch/erigon/core/state" "github.com/ledgerwatch/erigon/core/state/temporal" "github.com/ledgerwatch/erigon/core/types/accounts" + "github.com/ledgerwatch/erigon/eth/stagedsync" "github.com/ledgerwatch/erigon/eth/stagedsync/stages" "github.com/ledgerwatch/erigon/eth/tracers" + "github.com/ledgerwatch/erigon/rlp" "github.com/ledgerwatch/erigon/rpc" "github.com/ledgerwatch/erigon/turbo/adapter/ethapi" + "github.com/ledgerwatch/erigon/turbo/rpchelper" "github.com/ledgerwatch/erigon/turbo/transactions" ) @@ -27,7 +33,7 @@ const AccountRangeMaxResults = 256 // PrivateDebugAPI Exposed RPC endpoints for debugging use type PrivateDebugAPI interface { - StorageRangeAt(ctx context.Context, blockHash common.Hash, txIndex uint64, contractAddress common.Address, keyStart hexutil.Bytes, maxResult int) (StorageRangeResult, error) + StorageRangeAt(ctx context.Context, blockHash common.Hash, txIndex uint64, contractAddress common.Address, keyStart hexutility.Bytes, maxResult int) (StorageRangeResult, error) TraceTransaction(ctx context.Context, hash common.Hash, config *tracers.TraceConfig, stream *jsoniter.Stream) error TraceBlockByHash(ctx context.Context, hash common.Hash, config *tracers.TraceConfig, stream *jsoniter.Stream) error TraceBlockByNumber(ctx context.Context, number rpc.BlockNumber, config *tracers.TraceConfig, stream *jsoniter.Stream) error @@ -36,6 +42,8 @@ type PrivateDebugAPI interface { GetModifiedAccountsByHash(_ context.Context, startHash common.Hash, endHash *common.Hash) ([]common.Address, error) TraceCall(ctx context.Context, args ethapi.CallArgs, blockNrOrHash rpc.BlockNumberOrHash, config *tracers.TraceConfig, stream *jsoniter.Stream) error AccountAt(ctx context.Context, blockHash common.Hash, txIndex uint64, account common.Address) (*AccountResult, error) + GetRawHeader(ctx context.Context, blockNrOrHash rpc.BlockNumberOrHash) (hexutility.Bytes, error) + GetRawBlock(ctx context.Context, blockNrOrHash rpc.BlockNumberOrHash) (hexutility.Bytes, error) } // PrivateDebugAPIImpl is implementation of the PrivateDebugAPI interface based on remote Db access @@ -55,7 +63,7 @@ func NewPrivateDebugAPI(base *BaseAPI, db kv.RoDB, gascap uint64) *PrivateDebugA } // storageRangeAt implements debug_storageRangeAt. Returns information about a range of storage locations (if any) for the given address. -func (api *PrivateDebugAPIImpl) StorageRangeAt(ctx context.Context, blockHash common.Hash, txIndex uint64, contractAddress common.Address, keyStart hexutil.Bytes, maxResult int) (StorageRangeResult, error) { +func (api *PrivateDebugAPIImpl) StorageRangeAt(ctx context.Context, blockHash common.Hash, txIndex uint64, contractAddress common.Address, keyStart hexutility.Bytes, maxResult int) (StorageRangeResult, error) { tx, err := api.db.BeginRo(ctx) if err != nil { return StorageRangeResult{}, err @@ -113,6 +121,45 @@ func (api *PrivateDebugAPIImpl) AccountRange(ctx context.Context, blockNrOrHash if err != nil { return state.IteratorDump{}, fmt.Errorf("last block has not found: %w", err) } + } else if number == rpc.FinalizedBlockNumber { + if posa, isPoSA := api.engine().(consensus.PoSA); isPoSA { + headerNumber, err := stages.GetStageProgress(tx, stages.Execution) + if err != nil { + return state.IteratorDump{}, err + } + headerHash, err := rawdb.ReadCanonicalHash(tx, headerNumber) + if err != nil { + return state.IteratorDump{}, err + } + if headerHash != (common.Hash{}) { + if header := rawdb.ReadHeader(tx, headerHash, headerNumber); header != nil { + if chainConfig, err := api.chainConfig(tx); err == nil { + blockNumber = posa.GetFinalizedHeader(stagedsync.NewChainReaderImpl(chainConfig, tx, nil), header).Number.Uint64() + } + } + } + } + } else if number == rpc.SafeBlockNumber { + if posa, isPoSA := api.engine().(consensus.PoSA); isPoSA { + headerNumber, err := stages.GetStageProgress(tx, stages.Execution) + if err != nil { + return state.IteratorDump{}, err + } + headerHash, err := rawdb.ReadCanonicalHash(tx, headerNumber) + if err != nil { + return state.IteratorDump{}, err + } + if headerHash != (common.Hash{}) { + if header := rawdb.ReadHeader(tx, headerHash, headerNumber); header != nil { + if chainConfig, err := api.chainConfig(tx); err == nil { + blockNumber, _, err = posa.GetJustifiedNumberAndHash(stagedsync.NewChainReaderImpl(chainConfig, tx, nil), header) + if err != nil { + return state.IteratorDump{}, err + } + } + } + } + } } else { blockNumber = uint64(number) } @@ -351,8 +398,48 @@ func (api *PrivateDebugAPIImpl) AccountAt(ctx context.Context, blockHash common. } type AccountResult struct { - Balance hexutil.Big `json:"balance"` - Nonce hexutil.Uint64 `json:"nonce"` - Code hexutil.Bytes `json:"code"` - CodeHash common.Hash `json:"codeHash"` + Balance hexutil.Big `json:"balance"` + Nonce hexutil.Uint64 `json:"nonce"` + Code hexutility.Bytes `json:"code"` + CodeHash common.Hash `json:"codeHash"` +} + +func (api *PrivateDebugAPIImpl) GetRawHeader(ctx context.Context, blockNrOrHash rpc.BlockNumberOrHash) (hexutility.Bytes, error) { + tx, err := api.db.BeginRo(ctx) + if err != nil { + return nil, err + } + defer tx.Rollback() + n, h, _, err := rpchelper.GetBlockNumber(blockNrOrHash, tx, api.filters) + if err != nil { + return nil, err + } + header, err := api._blockReader.Header(context.Background(), tx, h, n) + if err != nil { + return nil, err + } + if header == nil { + return nil, fmt.Errorf("header not found") + } + return rlp.EncodeToBytes(header) +} + +func (api *PrivateDebugAPIImpl) GetRawBlock(ctx context.Context, blockNrOrHash rpc.BlockNumberOrHash) (hexutility.Bytes, error) { + tx, err := api.db.BeginRo(ctx) + if err != nil { + return nil, err + } + defer tx.Rollback() + n, h, _, err := rpchelper.GetBlockNumber(blockNrOrHash, tx, api.filters) + if err != nil { + return nil, err + } + block, err := api.blockWithSenders(tx, h, n) + if err != nil { + return nil, err + } + if block == nil { + return nil, fmt.Errorf("block not found") + } + return rlp.EncodeToBytes(block) } diff --git a/cmd/rpcdaemon/commands/engine_api.go b/cmd/rpcdaemon/commands/engine_api.go index e581bcb54a8..a4080ff700a 100644 --- a/cmd/rpcdaemon/commands/engine_api.go +++ b/cmd/rpcdaemon/commands/engine_api.go @@ -3,6 +3,7 @@ package commands import ( "context" "encoding/binary" + "errors" "fmt" "math/big" @@ -10,6 +11,7 @@ import ( "github.com/ledgerwatch/log/v3" "github.com/ledgerwatch/erigon-lib/common" + "github.com/ledgerwatch/erigon-lib/common/hexutility" "github.com/ledgerwatch/erigon-lib/gointerfaces" "github.com/ledgerwatch/erigon-lib/gointerfaces/remote" types2 "github.com/ledgerwatch/erigon-lib/gointerfaces/types" @@ -29,16 +31,16 @@ type ExecutionPayload struct { FeeRecipient common.Address `json:"feeRecipient" gencodec:"required"` StateRoot common.Hash `json:"stateRoot" gencodec:"required"` ReceiptsRoot common.Hash `json:"receiptsRoot" gencodec:"required"` - LogsBloom hexutil.Bytes `json:"logsBloom" gencodec:"required"` + LogsBloom hexutility.Bytes `json:"logsBloom" gencodec:"required"` PrevRandao common.Hash `json:"prevRandao" gencodec:"required"` BlockNumber hexutil.Uint64 `json:"blockNumber" gencodec:"required"` GasLimit hexutil.Uint64 `json:"gasLimit" gencodec:"required"` GasUsed hexutil.Uint64 `json:"gasUsed" gencodec:"required"` Timestamp hexutil.Uint64 `json:"timestamp" gencodec:"required"` - ExtraData hexutil.Bytes `json:"extraData" gencodec:"required"` + ExtraData hexutility.Bytes `json:"extraData" gencodec:"required"` BaseFeePerGas *hexutil.Big `json:"baseFeePerGas" gencodec:"required"` BlockHash common.Hash `json:"blockHash" gencodec:"required"` - Transactions []hexutil.Bytes `json:"transactions" gencodec:"required"` + Transactions []hexutility.Bytes `json:"transactions" gencodec:"required"` Withdrawals []*types.Withdrawal `json:"withdrawals"` } @@ -48,6 +50,13 @@ type GetPayloadV2Response struct { BlockValue *hexutil.Big `json:"blockValue" gencodec:"required"` } +// GetPayloadV3Response represents the response of the getPayloadV3 method +type GetPayloadV3Response struct { + ExecutionPayload *ExecutionPayload `json:"executionPayload" gencodec:"required"` + BlockValue *hexutil.Big `json:"blockValue" gencodec:"required"` + BlobsBundle *BlobsBundleV1 `json:"blobsBundle" gencodec:"required"` +} + // PayloadAttributes represent the attributes required to start assembling a payload type ForkChoiceState struct { HeadHash common.Hash `json:"headBlockHash" gencodec:"required"` @@ -70,8 +79,14 @@ type TransitionConfiguration struct { TerminalBlockNumber *hexutil.Big `json:"terminalBlockNumber" gencodec:"required"` } +// BlobsBundleV1 holds the blobs of an execution payload +type BlobsBundleV1 struct { + KZGs []types.KZGCommitment `json:"kzgs" gencodec:"required"` + Blobs []types.Blob `json:"blobs" gencodec:"required"` +} + type ExecutionPayloadBodyV1 struct { - Transactions []hexutil.Bytes `json:"transactions" gencodec:"required"` + Transactions []hexutility.Bytes `json:"transactions" gencodec:"required"` Withdrawals []*types.Withdrawal `json:"withdrawals" gencodec:"required"` } @@ -81,8 +96,9 @@ type EngineAPI interface { NewPayloadV2(context.Context, *ExecutionPayload) (map[string]interface{}, error) ForkchoiceUpdatedV1(ctx context.Context, forkChoiceState *ForkChoiceState, payloadAttributes *PayloadAttributes) (map[string]interface{}, error) ForkchoiceUpdatedV2(ctx context.Context, forkChoiceState *ForkChoiceState, payloadAttributes *PayloadAttributes) (map[string]interface{}, error) - GetPayloadV1(ctx context.Context, payloadID hexutil.Bytes) (*ExecutionPayload, error) - GetPayloadV2(ctx context.Context, payloadID hexutil.Bytes) (*GetPayloadV2Response, error) + GetPayloadV1(ctx context.Context, payloadID hexutility.Bytes) (*ExecutionPayload, error) + GetPayloadV2(ctx context.Context, payloadID hexutility.Bytes) (*GetPayloadV2Response, error) + GetPayloadV3(ctx context.Context, payloadID hexutility.Bytes) (*GetPayloadV3Response, error) ExchangeTransitionConfigurationV1(ctx context.Context, transitionConfiguration *TransitionConfiguration) (*TransitionConfiguration, error) GetPayloadBodiesByHashV1(ctx context.Context, hashes []common.Hash) ([]*ExecutionPayloadBodyV1, error) GetPayloadBodiesByRangeV1(ctx context.Context, start, count hexutil.Uint64) ([]*ExecutionPayloadBodyV1, error) @@ -139,7 +155,7 @@ func addPayloadId(json map[string]interface{}, payloadId uint64) { if payloadId != 0 { encodedPayloadId := make([]byte, 8) binary.BigEndian.PutUint64(encodedPayloadId, payloadId) - json["payloadId"] = hexutil.Bytes(encodedPayloadId) + json["payloadId"] = hexutility.Bytes(encodedPayloadId) } } @@ -151,13 +167,33 @@ func (e *EngineImpl) ForkchoiceUpdatedV2(ctx context.Context, forkChoiceState *F return e.forkchoiceUpdated(2, ctx, forkChoiceState, payloadAttributes) } +// Converts slice of pointers to slice of structs +func withdrawalValues(ptrs []*types.Withdrawal) []types.Withdrawal { + if ptrs == nil { + return nil + } + vals := make([]types.Withdrawal, 0, len(ptrs)) + for _, w := range ptrs { + vals = append(vals, *w) + } + return vals +} + +var errEmbedeedConsensus = errors.New("engine api should not be used, restart without --internalcl") + func (e *EngineImpl) forkchoiceUpdated(version uint32, ctx context.Context, forkChoiceState *ForkChoiceState, payloadAttributes *PayloadAttributes) (map[string]interface{}, error) { if e.internalCL { - log.Error("EXTERNAL CONSENSUS LAYER IS NOT ENABLED, PLEASE RESTART WITH FLAG --externalcl") - return nil, fmt.Errorf("engine api should not be used, restart with --externalcl") + return nil, errEmbedeedConsensus + } + if payloadAttributes == nil { + log.Debug("Received ForkchoiceUpdated", "version", version, + "head", forkChoiceState.HeadHash, "safe", forkChoiceState.SafeBlockHash, "finalized", forkChoiceState.FinalizedBlockHash) + } else { + log.Info("Received ForkchoiceUpdated [build]", "version", version, + "head", forkChoiceState.HeadHash, "safe", forkChoiceState.SafeBlockHash, "finalized", forkChoiceState.FinalizedBlockHash, + "timestamp", payloadAttributes.Timestamp, "prevRandao", payloadAttributes.PrevRandao, "suggestedFeeRecipient", payloadAttributes.SuggestedFeeRecipient, + "withdrawals", withdrawalValues(payloadAttributes.Withdrawals)) } - log.Debug("Received ForkchoiceUpdated", "version", version, "head", forkChoiceState.HeadHash, "safe", forkChoiceState.HeadHash, "finalized", forkChoiceState.FinalizedBlockHash, - "build", payloadAttributes != nil) var attributes *remote.EnginePayloadAttributes if payloadAttributes != nil { @@ -211,8 +247,7 @@ func (e *EngineImpl) NewPayloadV2(ctx context.Context, payload *ExecutionPayload func (e *EngineImpl) newPayload(version uint32, ctx context.Context, payload *ExecutionPayload) (map[string]interface{}, error) { if e.internalCL { - log.Error("EXTERNAL CONSENSUS LAYER IS NOT ENABLED, PLEASE RESTART WITH FLAG --externalcl") - return nil, fmt.Errorf("engine api should not be used, restart with --externalcl") + return nil, errEmbedeedConsensus } log.Debug("Received NewPayload", "version", version, "height", uint64(payload.BlockNumber), "hash", payload.BlockHash) @@ -222,7 +257,7 @@ func (e *EngineImpl) newPayload(version uint32, ctx context.Context, payload *Ex return nil, fmt.Errorf("invalid request") } - // Convert slice of hexutil.Bytes to a slice of slice of bytes + // Convert slice of hexutility.Bytes to a slice of slice of bytes transactions := make([][]byte, len(payload.Transactions)) for i, transaction := range payload.Transactions { transactions[i] = transaction @@ -261,8 +296,8 @@ func convertPayloadFromRpc(payload *types2.ExecutionPayload) *ExecutionPayload { var bloom types.Bloom = gointerfaces.ConvertH2048ToBloom(payload.LogsBloom) baseFee := gointerfaces.ConvertH256ToUint256Int(payload.BaseFeePerGas).ToBig() - // Convert slice of hexutil.Bytes to a slice of slice of bytes - transactions := make([]hexutil.Bytes, len(payload.Transactions)) + // Convert slice of hexutility.Bytes to a slice of slice of bytes + transactions := make([]hexutility.Bytes, len(payload.Transactions)) for i, transaction := range payload.Transactions { transactions[i] = transaction } @@ -290,10 +325,9 @@ func convertPayloadFromRpc(payload *types2.ExecutionPayload) *ExecutionPayload { return res } -func (e *EngineImpl) GetPayloadV1(ctx context.Context, payloadID hexutil.Bytes) (*ExecutionPayload, error) { +func (e *EngineImpl) GetPayloadV1(ctx context.Context, payloadID hexutility.Bytes) (*ExecutionPayload, error) { if e.internalCL { - log.Error("EXTERNAL CONSENSUS LAYER IS NOT ENABLED, PLEASE RESTART WITH FLAG --externalcl") - return nil, fmt.Errorf("engine api should not be used, restart with --externalcl") + return nil, errEmbedeedConsensus } decodedPayloadId := binary.BigEndian.Uint64(payloadID) @@ -307,10 +341,9 @@ func (e *EngineImpl) GetPayloadV1(ctx context.Context, payloadID hexutil.Bytes) return convertPayloadFromRpc(response.ExecutionPayload), nil } -func (e *EngineImpl) GetPayloadV2(ctx context.Context, payloadID hexutil.Bytes) (*GetPayloadV2Response, error) { +func (e *EngineImpl) GetPayloadV2(ctx context.Context, payloadID hexutility.Bytes) (*GetPayloadV2Response, error) { if e.internalCL { - log.Error("EXTERNAL CONSENSUS LAYER IS NOT ENABLED, PLEASE RESTART WITH FLAG --externalcl") - return nil, fmt.Errorf("engine api should not be used, restart with --externalcl") + return nil, errEmbedeedConsensus } decodedPayloadId := binary.BigEndian.Uint64(payloadID) @@ -329,13 +362,56 @@ func (e *EngineImpl) GetPayloadV2(ctx context.Context, payloadID hexutil.Bytes) }, nil } +func (e *EngineImpl) GetPayloadV3(ctx context.Context, payloadID hexutility.Bytes) (*GetPayloadV3Response, error) { + if e.internalCL { // TODO: find out what is the way around it + log.Error("EXTERNAL CONSENSUS LAYER IS NOT ENABLED, PLEASE RESTART WITH FLAG --externalcl") + return nil, fmt.Errorf("engine api should not be used, restart with --externalcl") + } + + decodedPayloadId := binary.BigEndian.Uint64(payloadID) + log.Info("Received GetPayloadV3", "payloadId", decodedPayloadId) + + response, err := e.api.EngineGetPayload(ctx, decodedPayloadId) + if err != nil { + return nil, err + } + + epl := convertPayloadFromRpc(response.ExecutionPayload) + blockValue := gointerfaces.ConvertH256ToUint256Int(response.BlockValue).ToBig() + + ep, err := e.api.EngineGetBlobsBundleV1(ctx, decodedPayloadId) + if err != nil { + return nil, err + } + kzgs := ep.GetKzgs() + blobs := ep.GetBlobs() + if len(kzgs) != len(blobs) { + return nil, fmt.Errorf("should have same number of kzgs and blobs, got %v vs %v", len(kzgs), len(blobs)) + } + replyKzgs := make([]types.KZGCommitment, len(kzgs)) + replyBlobs := make([]types.Blob, len(blobs)) + for i := range kzgs { + copy(replyKzgs[i][:], kzgs[i]) + copy(replyBlobs[i][:], blobs[i]) + } + bb := &BlobsBundleV1{ + KZGs: replyKzgs, + Blobs: replyBlobs, + } + + return &GetPayloadV3Response{ + epl, + (*hexutil.Big)(blockValue), + bb, + }, nil +} + // Receives consensus layer's transition configuration and checks if the execution layer has the correct configuration. // Can also be used to ping the execution layer (heartbeats). // See https://github.com/ethereum/execution-apis/blob/v1.0.0-beta.1/src/engine/specification.md#engine_exchangetransitionconfigurationv1 func (e *EngineImpl) ExchangeTransitionConfigurationV1(ctx context.Context, beaconConfig *TransitionConfiguration) (*TransitionConfiguration, error) { if e.internalCL { - log.Error("EXTERNAL CONSENSUS LAYER IS NOT ENABLED, PLEASE RESTART WITH FLAG --externalcl") - return nil, fmt.Errorf("engine api should not be used, restart with --externalcl") + return nil, errEmbedeedConsensus } tx, err := e.db.BeginRo(ctx) @@ -448,7 +524,7 @@ func convertExecutionPayloadV1(response *remote.EngineGetPayloadBodiesV1Response result[idx] = nil } else { pl := &ExecutionPayloadBodyV1{ - Transactions: make([]hexutil.Bytes, len(body.Transactions)), + Transactions: make([]hexutility.Bytes, len(body.Transactions)), Withdrawals: privateapi.ConvertWithdrawalsFromRpc(body.Withdrawals), } for i := range body.Transactions { diff --git a/cmd/rpcdaemon/commands/eth_accounts.go b/cmd/rpcdaemon/commands/eth_accounts.go index 8594ad60066..40feb36b6da 100644 --- a/cmd/rpcdaemon/commands/eth_accounts.go +++ b/cmd/rpcdaemon/commands/eth_accounts.go @@ -75,7 +75,7 @@ func (api *APIImpl) GetTransactionCount(ctx context.Context, address libcommon.A } // GetCode implements eth_getCode. Returns the byte code at a given address (if it's a smart contract). -func (api *APIImpl) GetCode(ctx context.Context, address libcommon.Address, blockNrOrHash rpc.BlockNumberOrHash) (hexutil.Bytes, error) { +func (api *APIImpl) GetCode(ctx context.Context, address libcommon.Address, blockNrOrHash rpc.BlockNumberOrHash) (hexutility.Bytes, error) { tx, err1 := api.db.BeginRo(ctx) if err1 != nil { return nil, fmt.Errorf("getCode cannot open tx: %w", err1) @@ -92,11 +92,11 @@ func (api *APIImpl) GetCode(ctx context.Context, address libcommon.Address, bloc acc, err := reader.ReadAccountData(address) if acc == nil || err != nil { - return hexutil.Bytes(""), nil + return hexutility.Bytes(""), nil } res, _ := reader.ReadAccountCode(address, acc.Incarnation, acc.CodeHash) if res == nil { - return hexutil.Bytes(""), nil + return hexutility.Bytes(""), nil } return res, nil } diff --git a/cmd/rpcdaemon/commands/eth_api.go b/cmd/rpcdaemon/commands/eth_api.go index 27b25ed9ccd..ce895102351 100644 --- a/cmd/rpcdaemon/commands/eth_api.go +++ b/cmd/rpcdaemon/commands/eth_api.go @@ -6,14 +6,17 @@ import ( "fmt" "math/big" "sync" + "sync/atomic" "time" lru "github.com/hashicorp/golang-lru/v2" "github.com/holiman/uint256" - "go.uber.org/atomic" + "github.com/ledgerwatch/log/v3" "github.com/ledgerwatch/erigon-lib/chain" "github.com/ledgerwatch/erigon-lib/common" + "github.com/ledgerwatch/erigon-lib/common/datadir" + "github.com/ledgerwatch/erigon-lib/common/hexutility" "github.com/ledgerwatch/erigon-lib/gointerfaces/txpool" "github.com/ledgerwatch/erigon-lib/kv" "github.com/ledgerwatch/erigon-lib/kv/kvcache" @@ -27,13 +30,13 @@ import ( "github.com/ledgerwatch/erigon/consensus/misc" "github.com/ledgerwatch/erigon/core/rawdb" "github.com/ledgerwatch/erigon/core/types" + "github.com/ledgerwatch/erigon/core/types/accounts" ethFilters "github.com/ledgerwatch/erigon/eth/filters" "github.com/ledgerwatch/erigon/ethdb/prune" "github.com/ledgerwatch/erigon/rpc" ethapi2 "github.com/ledgerwatch/erigon/turbo/adapter/ethapi" "github.com/ledgerwatch/erigon/turbo/rpchelper" "github.com/ledgerwatch/erigon/turbo/services" - "github.com/ledgerwatch/log/v3" ) // EthAPI is a collection of functions that are exposed in the @@ -48,9 +51,9 @@ type EthAPI interface { GetTransactionByHash(ctx context.Context, hash common.Hash) (*RPCTransaction, error) GetTransactionByBlockHashAndIndex(ctx context.Context, blockHash common.Hash, txIndex hexutil.Uint64) (*RPCTransaction, error) GetTransactionByBlockNumberAndIndex(ctx context.Context, blockNr rpc.BlockNumber, txIndex hexutil.Uint) (*RPCTransaction, error) - GetRawTransactionByBlockNumberAndIndex(ctx context.Context, blockNr rpc.BlockNumber, index hexutil.Uint) (hexutil.Bytes, error) - GetRawTransactionByBlockHashAndIndex(ctx context.Context, blockHash common.Hash, index hexutil.Uint) (hexutil.Bytes, error) - GetRawTransactionByHash(ctx context.Context, hash common.Hash) (hexutil.Bytes, error) + GetRawTransactionByBlockNumberAndIndex(ctx context.Context, blockNr rpc.BlockNumber, index hexutil.Uint) (hexutility.Bytes, error) + GetRawTransactionByBlockHashAndIndex(ctx context.Context, blockHash common.Hash, index hexutil.Uint) (hexutility.Bytes, error) + GetRawTransactionByHash(ctx context.Context, hash common.Hash) (hexutility.Bytes, error) // Receipt related (see ./eth_receipts.go) GetTransactionReceipt(ctx context.Context, hash common.Hash) (map[string]interface{}, error) @@ -76,7 +79,7 @@ type EthAPI interface { GetBalance(ctx context.Context, address common.Address, blockNrOrHash rpc.BlockNumberOrHash) (*hexutil.Big, error) GetTransactionCount(ctx context.Context, address common.Address, blockNrOrHash rpc.BlockNumberOrHash) (*hexutil.Uint64, error) GetStorageAt(ctx context.Context, address common.Address, index string, blockNrOrHash rpc.BlockNumberOrHash) (string, error) - GetCode(ctx context.Context, address common.Address, blockNrOrHash rpc.BlockNumberOrHash) (hexutil.Bytes, error) + GetCode(ctx context.Context, address common.Address, blockNrOrHash rpc.BlockNumberOrHash) (hexutility.Bytes, error) // System related (see ./eth_system.go) BlockNumber(ctx context.Context) (hexutil.Uint64, error) @@ -86,13 +89,13 @@ type EthAPI interface { GasPrice(_ context.Context) (*hexutil.Big, error) // Sending related (see ./eth_call.go) - Call(ctx context.Context, args ethapi2.CallArgs, blockNrOrHash rpc.BlockNumberOrHash, overrides *ethapi2.StateOverrides) (hexutil.Bytes, error) + Call(ctx context.Context, args ethapi2.CallArgs, blockNrOrHash rpc.BlockNumberOrHash, overrides *ethapi2.StateOverrides) (hexutility.Bytes, error) EstimateGas(ctx context.Context, argsOrNil *ethapi2.CallArgs, blockNrOrHash *rpc.BlockNumberOrHash) (hexutil.Uint64, error) - SendRawTransaction(ctx context.Context, encodedTx hexutil.Bytes) (common.Hash, error) + SendRawTransaction(ctx context.Context, encodedTx hexutility.Bytes) (common.Hash, error) SendTransaction(_ context.Context, txObject interface{}) (common.Hash, error) - Sign(ctx context.Context, _ common.Address, _ hexutil.Bytes) (hexutil.Bytes, error) + Sign(ctx context.Context, _ common.Address, _ hexutility.Bytes) (hexutility.Bytes, error) SignTransaction(_ context.Context, txObject interface{}) (common.Hash, error) - GetProof(ctx context.Context, address common.Address, storageKeys []string, blockNr rpc.BlockNumber) (*interface{}, error) + GetProof(ctx context.Context, address common.Address, storageKeys []common.Hash, blockNr rpc.BlockNumberOrHash) (*accounts.AccProofResult, error) CreateAccessList(ctx context.Context, args ethapi2.CallArgs, blockNrOrHash *rpc.BlockNumberOrHash, optimizeGas *bool) (*accessListResult, error) // Mining related (see ./eth_mining.go) @@ -119,9 +122,10 @@ type BaseAPI struct { _engine consensus.EngineReader evmCallTimeout time.Duration + dirs datadir.Dirs } -func NewBaseApi(f *rpchelper.Filters, stateCache kvcache.Cache, blockReader services.FullBlockReader, agg *libstate.AggregatorV3, singleNodeMode bool, evmCallTimeout time.Duration, engine consensus.EngineReader) *BaseAPI { +func NewBaseApi(f *rpchelper.Filters, stateCache kvcache.Cache, blockReader services.FullBlockReader, agg *libstate.AggregatorV3, singleNodeMode bool, evmCallTimeout time.Duration, engine consensus.EngineReader, dirs datadir.Dirs) *BaseAPI { blocksLRUSize := 128 // ~32Mb if !singleNodeMode { blocksLRUSize = 512 @@ -131,7 +135,7 @@ func NewBaseApi(f *rpchelper.Filters, stateCache kvcache.Cache, blockReader serv panic(err) } - return &BaseAPI{filters: f, stateCache: stateCache, blocksLRU: blocksLRU, _blockReader: blockReader, _txnReader: blockReader, _agg: agg, evmCallTimeout: evmCallTimeout, _engine: engine} + return &BaseAPI{filters: f, stateCache: stateCache, blocksLRU: blocksLRU, _blockReader: blockReader, _txnReader: blockReader, _agg: agg, evmCallTimeout: evmCallTimeout, _engine: engine, dirs: dirs} } func (api *BaseAPI) chainConfig(tx kv.Tx) (*chain.Config, error) { @@ -279,6 +283,9 @@ func (api *BaseAPI) checkPruneHistory(tx kv.Tx, block uint64) error { if err != nil { return err } + if latest == nil { + return nil + } prunedTo := p.History.PruneTo(latest.Number().Uint64()) if block < prunedTo { return fmt.Errorf("history has been pruned for this block") @@ -344,7 +351,7 @@ type RPCTransaction struct { Tip *hexutil.Big `json:"maxPriorityFeePerGas,omitempty"` FeeCap *hexutil.Big `json:"maxFeePerGas,omitempty"` Hash common.Hash `json:"hash"` - Input hexutil.Bytes `json:"input"` + Input hexutility.Bytes `json:"input"` Nonce hexutil.Uint64 `json:"nonce"` To *common.Address `json:"to"` TransactionIndex *hexutil.Uint64 `json:"transactionIndex"` @@ -369,7 +376,7 @@ func newRPCTransaction(tx types.Transaction, blockHash common.Hash, blockNumber Type: hexutil.Uint64(tx.Type()), Gas: hexutil.Uint64(tx.GetGas()), Hash: tx.Hash(), - Input: hexutil.Bytes(tx.GetData()), + Input: hexutility.Bytes(tx.GetData()), Nonce: hexutil.Uint64(tx.GetNonce()), To: tx.GetTo(), Value: (*hexutil.Big)(tx.GetValue().ToBig()), @@ -431,7 +438,7 @@ func newRPCBorTransaction(opaqueTx types.Transaction, txHash common.Hash, blockH GasPrice: (*hexutil.Big)(tx.GasPrice.ToBig()), Gas: hexutil.Uint64(tx.GetGas()), Hash: txHash, - Input: hexutil.Bytes(tx.GetData()), + Input: hexutility.Bytes(tx.GetData()), Nonce: hexutil.Uint64(tx.GetNonce()), From: common.Address{}, To: tx.GetTo(), @@ -459,7 +466,7 @@ func newRPCPendingTransaction(tx types.Transaction, current *types.Header, confi } // newRPCRawTransactionFromBlockIndex returns the bytes of a transaction given a block and a transaction index. -func newRPCRawTransactionFromBlockIndex(b *types.Block, index uint64) (hexutil.Bytes, error) { +func newRPCRawTransactionFromBlockIndex(b *types.Block, index uint64) (hexutility.Bytes, error) { txs := b.Transactions() if index >= uint64(len(txs)) { return nil, nil diff --git a/cmd/rpcdaemon/commands/eth_call.go b/cmd/rpcdaemon/commands/eth_call.go index 2e295fc88ac..f9ab76249b4 100644 --- a/cmd/rpcdaemon/commands/eth_call.go +++ b/cmd/rpcdaemon/commands/eth_call.go @@ -7,32 +7,38 @@ import ( "math/big" "github.com/holiman/uint256" + "github.com/ledgerwatch/log/v3" + "google.golang.org/grpc" + libcommon "github.com/ledgerwatch/erigon-lib/common" + "github.com/ledgerwatch/erigon-lib/common/hexutility" "github.com/ledgerwatch/erigon-lib/gointerfaces" txpool_proto "github.com/ledgerwatch/erigon-lib/gointerfaces/txpool" "github.com/ledgerwatch/erigon-lib/kv" + "github.com/ledgerwatch/erigon-lib/kv/memdb" types2 "github.com/ledgerwatch/erigon-lib/types" - "github.com/ledgerwatch/log/v3" - "google.golang.org/grpc" "github.com/ledgerwatch/erigon/common/hexutil" "github.com/ledgerwatch/erigon/core" "github.com/ledgerwatch/erigon/core/state" "github.com/ledgerwatch/erigon/core/types" + "github.com/ledgerwatch/erigon/core/types/accounts" "github.com/ledgerwatch/erigon/core/vm" "github.com/ledgerwatch/erigon/crypto" + "github.com/ledgerwatch/erigon/eth/stagedsync" "github.com/ledgerwatch/erigon/eth/tracers/logger" "github.com/ledgerwatch/erigon/params" "github.com/ledgerwatch/erigon/rpc" ethapi2 "github.com/ledgerwatch/erigon/turbo/adapter/ethapi" "github.com/ledgerwatch/erigon/turbo/rpchelper" "github.com/ledgerwatch/erigon/turbo/transactions" + "github.com/ledgerwatch/erigon/turbo/trie" ) var latestNumOrHash = rpc.BlockNumberOrHashWithNumber(rpc.LatestBlockNumber) // Call implements eth_call. Executes a new message call immediately without creating a transaction on the block chain. -func (api *APIImpl) Call(ctx context.Context, args ethapi2.CallArgs, blockNrOrHash rpc.BlockNumberOrHash, overrides *ethapi2.StateOverrides) (hexutil.Bytes, error) { +func (api *APIImpl) Call(ctx context.Context, args ethapi2.CallArgs, blockNrOrHash rpc.BlockNumberOrHash, overrides *ethapi2.StateOverrides) (hexutility.Bytes, error) { tx, err := api.db.BeginRo(ctx) if err != nil { return nil, err @@ -72,7 +78,7 @@ func (api *APIImpl) Call(ctx context.Context, args ethapi2.CallArgs, blockNrOrHa } if len(result.ReturnData) > api.ReturnDataLimit { - return nil, fmt.Errorf("call retuned result on length %d exceeding limit %d", len(result.ReturnData), api.ReturnDataLimit) + return nil, fmt.Errorf("call returned result on length %d exceeding --rpc.returndata.limit %d", len(result.ReturnData), api.ReturnDataLimit) } // If the result contains a revert reason, try to unpack and return it. @@ -122,9 +128,9 @@ func (api *APIImpl) EstimateGas(ctx context.Context, argsOrNil *ethapi2.CallArgs // Binary search the gas requirement, as it may be higher than the amount used var ( - lo = params.TxGas - 1 - hi uint64 - cap uint64 + lo = params.TxGas - 1 + hi uint64 + gasCap uint64 ) // Use zero address if sender unspecified. if args.From == nil { @@ -212,7 +218,7 @@ func (api *APIImpl) EstimateGas(ctx context.Context, argsOrNil *ethapi2.CallArgs log.Warn("Caller gas above allowance, capping", "requested", hi, "cap", api.GasCap) hi = api.GasCap } - cap = hi + gasCap = hi chainConfig, err := api.chainConfig(dbtx) if err != nil { @@ -281,7 +287,7 @@ func (api *APIImpl) EstimateGas(ctx context.Context, argsOrNil *ethapi2.CallArgs } // Reject the transaction as invalid if it still fails at the highest allowance - if hi == cap { + if hi == gasCap { failed, result, err := executable(hi) if err != nil { return 0, err @@ -294,16 +300,106 @@ func (api *APIImpl) EstimateGas(ctx context.Context, argsOrNil *ethapi2.CallArgs return 0, result.Err } // Otherwise, the specified gas cap is too low - return 0, fmt.Errorf("gas required exceeds allowance (%d)", cap) + return 0, fmt.Errorf("gas required exceeds allowance (%d)", gasCap) } } return hexutil.Uint64(hi), nil } -// GetProof not implemented -func (api *APIImpl) GetProof(ctx context.Context, address libcommon.Address, storageKeys []string, blockNr rpc.BlockNumber) (*interface{}, error) { - var stub interface{} - return &stub, fmt.Errorf(NotImplemented, "eth_getProof") +// maxGetProofRewindBlockCount limits the number of blocks into the past that +// GetProof will allow computing proofs. Because we must rewind the hash state +// and re-compute the state trie, the further back in time the request, the more +// computationally intensive the operation becomes. The staged sync code +// assumes that if more than 100_000 blocks are skipped, that the entire trie +// should be re-computed. Re-computing the entire trie will currently take ~15 +// minutes on mainnet. The current limit has been chosen arbitrarily as +// 'useful' without likely being overly computationally intense. This parameter +// could possibly be made configurable in the future if needed. +var maxGetProofRewindBlockCount uint64 = 1_000 + +// GetProof is partially implemented; no Storage proofs, and proofs must be for +// blocks within maxGetProofRewindBlockCount blocks of the head. +func (api *APIImpl) GetProof(ctx context.Context, address libcommon.Address, storageKeys []libcommon.Hash, blockNrOrHash rpc.BlockNumberOrHash) (*accounts.AccProofResult, error) { + + tx, err := api.db.BeginRo(ctx) + if err != nil { + return nil, err + } + defer tx.Rollback() + if api.historyV3(tx) { + return nil, fmt.Errorf("not supported by Erigon3") + } + + blockNr, _, _, err := rpchelper.GetBlockNumber(blockNrOrHash, tx, api.filters) + if err != nil { + return nil, err + } + + header, err := api._blockReader.HeaderByNumber(ctx, tx, blockNr) + if err != nil { + return nil, err + } + + latestBlock, err := rpchelper.GetLatestBlockNumber(tx) + if err != nil { + return nil, err + } + + if latestBlock < blockNr { + // shouldn't happen, but check anyway + return nil, fmt.Errorf("block number is in the future latest=%d requested=%d", latestBlock, blockNr) + } + + rl := trie.NewRetainList(0) + var loader *trie.FlatDBTrieLoader + if blockNr < latestBlock { + if latestBlock-blockNr > maxGetProofRewindBlockCount { + return nil, fmt.Errorf("requested block is too old, block must be within %d blocks of the head block number (currently %d)", maxGetProofRewindBlockCount, latestBlock) + } + batch := memdb.NewMemoryBatch(tx, api.dirs.Tmp) + defer batch.Rollback() + + unwindState := &stagedsync.UnwindState{UnwindPoint: blockNr} + stageState := &stagedsync.StageState{BlockNumber: latestBlock} + + hashStageCfg := stagedsync.StageHashStateCfg(nil, api.dirs, api.historyV3(batch), api._agg) + if err := stagedsync.UnwindHashStateStage(unwindState, stageState, batch, hashStageCfg, ctx); err != nil { + return nil, err + } + + interHashStageCfg := stagedsync.StageTrieCfg(nil, false, false, false, api.dirs.Tmp, api._blockReader, nil, api.historyV3(batch), api._agg) + loader, err = stagedsync.UnwindIntermediateHashesForTrieLoader("eth_getProof", rl, unwindState, stageState, batch, interHashStageCfg, nil, nil, ctx.Done()) + if err != nil { + return nil, err + } + tx = batch + } else { + loader = trie.NewFlatDBTrieLoader("eth_getProof", rl, nil, nil, false) + } + + reader, err := rpchelper.CreateStateReader(ctx, tx, blockNrOrHash, 0, api.filters, api.stateCache, api.historyV3(tx), "") + if err != nil { + return nil, err + } + a, err := reader.ReadAccountData(address) + if err != nil { + return nil, err + } + pr, err := trie.NewProofRetainer(address, a, storageKeys, rl) + if err != nil { + return nil, err + } + + loader.SetProofRetainer(pr) + root, err := loader.CalcTrieRoot(tx, nil) + if err != nil { + return nil, err + } + + if root != header.Root { + return nil, fmt.Errorf("mismatch in expected state root computed %v vs %v indicates bug in proof implementation", root, header.Root) + } + return pr.ProofResult() } func (api *APIImpl) tryBlockFromLru(hash libcommon.Hash) *types.Block { diff --git a/cmd/rpcdaemon/commands/eth_callMany_test.go b/cmd/rpcdaemon/commands/eth_callMany_test.go index b86b04cac1a..4dbeb9488a1 100644 --- a/cmd/rpcdaemon/commands/eth_callMany_test.go +++ b/cmd/rpcdaemon/commands/eth_callMany_test.go @@ -8,12 +8,15 @@ import ( "strconv" "testing" + "github.com/ledgerwatch/erigon-lib/common/datadir" + "github.com/ledgerwatch/erigon-lib/common/hexutility" "github.com/ledgerwatch/erigon-lib/kv/kvcache" + "github.com/ledgerwatch/erigon/accounts/abi/bind" "github.com/ledgerwatch/erigon/accounts/abi/bind/backends" "github.com/ledgerwatch/erigon/cmd/rpcdaemon/commands/contracts" "github.com/ledgerwatch/erigon/common/hexutil" - "github.com/ledgerwatch/erigon/core" + "github.com/ledgerwatch/erigon/core/types" "github.com/ledgerwatch/erigon/crypto" "github.com/ledgerwatch/erigon/params" "github.com/ledgerwatch/erigon/rpc" @@ -37,9 +40,9 @@ func TestCallMany(t *testing.T) { address = crypto.PubkeyToAddress(key.PublicKey) address1 = crypto.PubkeyToAddress(key1.PublicKey) address2 = crypto.PubkeyToAddress(key2.PublicKey) - gspec = &core.Genesis{ + gspec = &types.Genesis{ Config: params.TestChainConfig, - Alloc: core.GenesisAlloc{ + Alloc: types.GenesisAlloc{ address: {Balance: big.NewInt(9000000000000000000)}, address1: {Balance: big.NewInt(200000000000000000)}, address2: {Balance: big.NewInt(300000000000000000)}, @@ -55,11 +58,11 @@ func TestCallMany(t *testing.T) { ) hexBytes, _ := hex.DecodeString(addr2BalanceCheck) - balanceCallAddr2 := hexutil.Bytes(hexBytes) + balanceCallAddr2 := hexutility.Bytes(hexBytes) hexBytes, _ = hex.DecodeString(addr1BalanceCheck) - balanceCallAddr1 := hexutil.Bytes(hexBytes) + balanceCallAddr1 := hexutility.Bytes(hexBytes) hexBytes, _ = hex.DecodeString(transferAddr2) - transferCallData := hexutil.Bytes(hexBytes) + transferCallData := hexutility.Bytes(hexBytes) //submit 3 Transactions and commit the results transactOpts, _ := bind.NewKeyedTransactorWithChainID(key, chainID) @@ -79,7 +82,7 @@ func TestCallMany(t *testing.T) { db := contractBackend.DB() engine := contractBackend.Engine() - api := NewEthAPI(NewBaseApi(nil, stateCache, contractBackend.BlockReader(), contractBackend.Agg(), false, rpccfg.DefaultEvmCallTimeout, engine), db, nil, nil, nil, 5000000, 100_000) + api := NewEthAPI(NewBaseApi(nil, stateCache, contractBackend.BlockReader(), contractBackend.Agg(), false, rpccfg.DefaultEvmCallTimeout, engine, datadir.New(t.TempDir())), db, nil, nil, nil, 5000000, 100_000) callArgAddr1 := ethapi.CallArgs{From: &address, To: &tokenAddr, Nonce: &nonce, MaxPriorityFeePerGas: (*hexutil.Big)(big.NewInt(1e9)), diff --git a/cmd/rpcdaemon/commands/eth_call_test.go b/cmd/rpcdaemon/commands/eth_call_test.go index e7dcadc5a12..bd7bd99becb 100644 --- a/cmd/rpcdaemon/commands/eth_call_test.go +++ b/cmd/rpcdaemon/commands/eth_call_test.go @@ -7,14 +7,13 @@ import ( "testing" "time" - libcommon "github.com/ledgerwatch/erigon-lib/common" - - "github.com/ledgerwatch/erigon/rpc/rpccfg" - "github.com/ledgerwatch/erigon/turbo/adapter/ethapi" - "github.com/holiman/uint256" "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + libcommon "github.com/ledgerwatch/erigon-lib/common" + "github.com/ledgerwatch/erigon-lib/common/hexutility" + "github.com/ledgerwatch/erigon-lib/common/length" "github.com/ledgerwatch/erigon-lib/gointerfaces/txpool" "github.com/ledgerwatch/erigon-lib/kv" "github.com/ledgerwatch/erigon-lib/kv/kvcache" @@ -26,12 +25,17 @@ import ( "github.com/ledgerwatch/erigon/core/rawdb" "github.com/ledgerwatch/erigon/core/state" "github.com/ledgerwatch/erigon/core/types" + "github.com/ledgerwatch/erigon/core/types/accounts" "github.com/ledgerwatch/erigon/crypto" "github.com/ledgerwatch/erigon/params" + "github.com/ledgerwatch/erigon/rlp" "github.com/ledgerwatch/erigon/rpc" + "github.com/ledgerwatch/erigon/rpc/rpccfg" + "github.com/ledgerwatch/erigon/turbo/adapter/ethapi" "github.com/ledgerwatch/erigon/turbo/rpchelper" "github.com/ledgerwatch/erigon/turbo/snapshotsync" "github.com/ledgerwatch/erigon/turbo/stages" + "github.com/ledgerwatch/erigon/turbo/trie" ) func TestEstimateGas(t *testing.T) { @@ -42,7 +46,7 @@ func TestEstimateGas(t *testing.T) { ctx, conn := rpcdaemontest.CreateTestGrpcConn(t, stages.Mock(t)) mining := txpool.NewMiningClient(conn) ff := rpchelper.New(ctx, nil, nil, mining, func() {}) - api := NewEthAPI(NewBaseApi(ff, stateCache, br, agg, false, rpccfg.DefaultEvmCallTimeout, m.Engine), m.DB, nil, nil, nil, 5000000, 100_000) + api := NewEthAPI(NewBaseApi(ff, stateCache, br, agg, false, rpccfg.DefaultEvmCallTimeout, m.Engine, m.Dirs), m.DB, nil, nil, nil, 5000000, 100_000) var from = libcommon.HexToAddress("0x71562b71999873db5b286df957af199ec94617f7") var to = libcommon.HexToAddress("0x0d3ab14bbad3d99f4203bd7a11acb94882050e7e") if _, err := api.EstimateGas(context.Background(), ðapi.CallArgs{ @@ -58,7 +62,7 @@ func TestEthCallNonCanonical(t *testing.T) { agg := m.HistoryV3Components() br := snapshotsync.NewBlockReaderWithSnapshots(m.BlockSnapshots, m.TransactionsV3) stateCache := kvcache.New(kvcache.DefaultCoherentConfig) - api := NewEthAPI(NewBaseApi(nil, stateCache, br, agg, false, rpccfg.DefaultEvmCallTimeout, m.Engine), m.DB, nil, nil, nil, 5000000, 100_000) + api := NewEthAPI(NewBaseApi(nil, stateCache, br, agg, false, rpccfg.DefaultEvmCallTimeout, m.Engine, m.Dirs), m.DB, nil, nil, nil, 5000000, 100_000) var from = libcommon.HexToAddress("0x71562b71999873db5b286df957af199ec94617f7") var to = libcommon.HexToAddress("0x0d3ab14bbad3d99f4203bd7a11acb94882050e7e") if _, err := api.Call(context.Background(), ethapi.CallArgs{ @@ -83,10 +87,10 @@ func TestEthCallToPrunedBlock(t *testing.T) { agg := m.HistoryV3Components() stateCache := kvcache.New(kvcache.DefaultCoherentConfig) - api := NewEthAPI(NewBaseApi(nil, stateCache, br, agg, false, rpccfg.DefaultEvmCallTimeout, m.Engine), m.DB, nil, nil, nil, 5000000, 100_000) + api := NewEthAPI(NewBaseApi(nil, stateCache, br, agg, false, rpccfg.DefaultEvmCallTimeout, m.Engine, m.Dirs), m.DB, nil, nil, nil, 5000000, 100_000) callData := hexutil.MustDecode("0x2e64cec1") - callDataBytes := hexutil.Bytes(callData) + callDataBytes := hexutility.Bytes(callData) if _, err := api.Call(context.Background(), ethapi.CallArgs{ From: &bankAddress, @@ -97,6 +101,275 @@ func TestEthCallToPrunedBlock(t *testing.T) { } } +type valueNode []byte +type hashNode libcommon.Hash + +type shortNode struct { + Key trie.Keybytes + Val any +} + +type fullNode struct { + Children [17]any +} + +func decodeRef(t *testing.T, buf []byte) (any, []byte) { + t.Helper() + kind, val, rest, err := rlp.Split(buf) + require.NoError(t, err) + switch { + case kind == rlp.List: + require.Less(t, len(buf)-len(rest), length.Hash, "embedded nodes must be less than hash size") + return decodeNode(t, buf), rest + case kind == rlp.String && len(val) == 0: + return nil, rest + case kind == rlp.String && len(val) == 32: + return hashNode(libcommon.CastToHash(val)), rest + default: + t.Fatalf("invalid RLP string size %d (want 0 through 32)", len(val)) + return nil, rest + } +} + +func decodeFull(t *testing.T, elems []byte) fullNode { + t.Helper() + n := fullNode{} + for i := 0; i < 16; i++ { + n.Children[i], elems = decodeRef(t, elems) + } + val, _, err := rlp.SplitString(elems) + require.NoError(t, err) + if len(val) > 0 { + n.Children[16] = valueNode(val) + } + return n +} + +func decodeShort(t *testing.T, elems []byte) shortNode { + t.Helper() + kbuf, rest, err := rlp.SplitString(elems) + require.NoError(t, err) + kb := trie.CompactToKeybytes(kbuf) + if kb.Terminating { + val, _, err := rlp.SplitString(rest) + require.NoError(t, err) + return shortNode{ + Key: kb, + Val: valueNode(val), + } + } + + val, _ := decodeRef(t, rest) + return shortNode{ + Key: kb, + Val: val, + } +} + +func decodeNode(t *testing.T, encoded []byte) any { + t.Helper() + require.NotEmpty(t, encoded) + elems, _, err := rlp.SplitList(encoded) + require.NoError(t, err) + switch c, _ := rlp.CountValues(elems); c { + case 2: + return decodeShort(t, elems) + case 17: + return decodeFull(t, elems) + default: + t.Fatalf("invalid number of list elements: %v", c) + return nil // unreachable + } +} + +type rawProofElement struct { + index int + value []byte +} + +// proofMap creates a map from hash to proof node +func proofMap(t *testing.T, proof []hexutility.Bytes) (map[libcommon.Hash]any, map[libcommon.Hash]rawProofElement) { + res := map[libcommon.Hash]any{} + raw := map[libcommon.Hash]rawProofElement{} + for i, proofB := range proof { + hash := crypto.Keccak256Hash(proofB) + res[hash] = decodeNode(t, proofB) + raw[hash] = rawProofElement{ + index: i, + value: proofB, + } + } + return res, raw +} + +func verifyProof(t *testing.T, root libcommon.Hash, key []byte, proofs map[libcommon.Hash]any, used map[libcommon.Hash]rawProofElement) []byte { + t.Helper() + nextIndex := 0 + key = (&trie.Keybytes{Data: key}).ToHex() + var node any = hashNode(root) + for { + switch nt := node.(type) { + case fullNode: + require.NotEmpty(t, key, "full nodes should not have values") + node, key = nt.Children[key[0]], key[1:] + case shortNode: + shortHex := nt.Key.ToHex()[:nt.Key.Nibbles()] // There is a trailing 0 on odd otherwise + require.LessOrEqual(t, len(shortHex), len(key)) + require.Equal(t, shortHex, key[:len(shortHex)]) + node, key = nt.Val, key[len(shortHex):] + case hashNode: + var ok bool + node, ok = proofs[libcommon.Hash(nt)] + require.True(t, ok, "missing hash %x", nt) + raw, ok := used[libcommon.Hash(nt)] + require.True(t, ok) + require.Equal(t, nextIndex, raw.index, "proof elements not in expected order") + nextIndex++ + delete(used, libcommon.Hash(nt)) + case valueNode: + require.Len(t, key, 0) + for hash, raw := range used { + require.Failf(t, "not all proof elements were used", "hash=%x index=%d value=%x decoded=%#v", hash, raw.index, raw.value, proofs[hash]) + } + return nt + default: + t.Fatalf("unexpected type: %T", node) + } + } +} + +func verifyAccountProof(t *testing.T, stateRoot libcommon.Hash, proof *accounts.AccProofResult) { + t.Helper() + accountKey := crypto.Keccak256(proof.Address[:]) + pm, used := proofMap(t, proof.AccountProof) + value := verifyProof(t, stateRoot, accountKey, pm, used) + + expected, err := rlp.EncodeToBytes([]any{ + uint64(proof.Nonce), + proof.Balance.ToInt().Bytes(), + proof.StorageHash, + proof.CodeHash, + }) + require.NoError(t, err) + + require.Equal(t, expected, value) +} + +func verifyStorageProof(t *testing.T, storageRoot libcommon.Hash, proof accounts.StorProofResult) { + t.Helper() + + storageKey := crypto.Keccak256(proof.Key[:]) + pm, used := proofMap(t, proof.Proof) + value := verifyProof(t, storageRoot, storageKey, pm, used) + + expected, err := rlp.EncodeToBytes(proof.Value.ToInt().Bytes()) + require.NoError(t, err) + + require.Equal(t, expected, value) +} + +func TestGetProof(t *testing.T) { + maxGetProofRewindBlockCount = 1 // Note, this is unsafe for parallel tests, but, this test is the only consumer for now + + m, bankAddr, contractAddr := chainWithDeployedContract(t) + br := snapshotsync.NewBlockReaderWithSnapshots(m.BlockSnapshots, m.TransactionsV3) + + if m.HistoryV3 { + t.Skip("not supported by Erigon3") + } + agg := m.HistoryV3Components() + + stateCache := kvcache.New(kvcache.DefaultCoherentConfig) + api := NewEthAPI(NewBaseApi(nil, stateCache, br, agg, false, rpccfg.DefaultEvmCallTimeout, m.Engine, m.Dirs), m.DB, nil, nil, nil, 5000000, 100_000) + + key := func(b byte) libcommon.Hash { + result := libcommon.Hash{} + result[31] = b + return result + } + + tests := []struct { + name string + blockNum uint64 + addr libcommon.Address + storageKeys []libcommon.Hash + stateVal uint64 + expectedErr string + }{ + { + name: "currentBlockNoState", + addr: contractAddr, + blockNum: 3, + }, + { + name: "currentBlockEOA", + addr: bankAddr, + blockNum: 3, + }, + { + name: "currentBlockWithState", + addr: contractAddr, + blockNum: 3, + storageKeys: []libcommon.Hash{key(0), key(4), key(8), key(10)}, + stateVal: 2, + }, + { + name: "olderBlockWithState", + addr: contractAddr, + blockNum: 2, + storageKeys: []libcommon.Hash{key(1), key(5), key(9), key(13)}, + stateVal: 1, + }, + { + name: "tooOldBlock", + addr: contractAddr, + blockNum: 1, + expectedErr: "requested block is too old, block must be within 1 blocks of the head block number (currently 3)", + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + proof, err := api.GetProof( + context.Background(), + tt.addr, + tt.storageKeys, + rpc.BlockNumberOrHashWithNumber(rpc.BlockNumber(tt.blockNum)), + ) + if tt.expectedErr != "" { + require.EqualError(t, err, tt.expectedErr) + require.Nil(t, proof) + return + } + require.NoError(t, err) + require.NotNil(t, proof) + + tx, err := m.DB.BeginRo(context.Background()) + assert.NoError(t, err) + defer tx.Rollback() + header, err := api.headerByRPCNumber(rpc.BlockNumber(tt.blockNum), tx) + require.NoError(t, err) + + require.Equal(t, tt.addr, proof.Address) + verifyAccountProof(t, header.Root, proof) + + require.Equal(t, len(tt.storageKeys), len(proof.StorageProof)) + for _, storageKey := range tt.storageKeys { + found := false + for _, storageProof := range proof.StorageProof { + if storageProof.Key != storageKey { + continue + } + found = true + require.Equal(t, uint256.NewInt(tt.stateVal).ToBig(), (*big.Int)(storageProof.Value)) + verifyStorageProof(t, proof.StorageHash, storageProof) + } + require.True(t, found, "did not find storage proof for key=%x", storageKey) + } + }) + } +} + func TestGetBlockByTimestampLatestTime(t *testing.T) { ctx := context.Background() m, _, _ := rpcdaemontest.CreateTestSentry(t) @@ -109,7 +382,7 @@ func TestGetBlockByTimestampLatestTime(t *testing.T) { defer tx.Rollback() stateCache := kvcache.New(kvcache.DefaultCoherentConfig) - api := NewErigonAPI(NewBaseApi(nil, stateCache, br, agg, false, rpccfg.DefaultEvmCallTimeout, m.Engine), m.DB, nil) + api := NewErigonAPI(NewBaseApi(nil, stateCache, br, agg, false, rpccfg.DefaultEvmCallTimeout, m.Engine, m.Dirs), m.DB, nil) latestBlock := rawdb.ReadCurrentBlock(tx) response, err := ethapi.RPCMarshalBlockDeprecated(latestBlock, true, false) @@ -147,7 +420,7 @@ func TestGetBlockByTimestampOldestTime(t *testing.T) { defer tx.Rollback() stateCache := kvcache.New(kvcache.DefaultCoherentConfig) - api := NewErigonAPI(NewBaseApi(nil, stateCache, br, agg, false, rpccfg.DefaultEvmCallTimeout, m.Engine), m.DB, nil) + api := NewErigonAPI(NewBaseApi(nil, stateCache, br, agg, false, rpccfg.DefaultEvmCallTimeout, m.Engine, m.Dirs), m.DB, nil) oldestBlock, err := rawdb.ReadBlockByNumber(tx, 0) if err != nil { @@ -189,7 +462,7 @@ func TestGetBlockByTimeHigherThanLatestBlock(t *testing.T) { defer tx.Rollback() stateCache := kvcache.New(kvcache.DefaultCoherentConfig) - api := NewErigonAPI(NewBaseApi(nil, stateCache, br, agg, false, rpccfg.DefaultEvmCallTimeout, m.Engine), m.DB, nil) + api := NewErigonAPI(NewBaseApi(nil, stateCache, br, agg, false, rpccfg.DefaultEvmCallTimeout, m.Engine, m.Dirs), m.DB, nil) latestBlock := rawdb.ReadCurrentBlock(tx) @@ -228,7 +501,7 @@ func TestGetBlockByTimeMiddle(t *testing.T) { defer tx.Rollback() stateCache := kvcache.New(kvcache.DefaultCoherentConfig) - api := NewErigonAPI(NewBaseApi(nil, stateCache, br, agg, false, rpccfg.DefaultEvmCallTimeout, m.Engine), m.DB, nil) + api := NewErigonAPI(NewBaseApi(nil, stateCache, br, agg, false, rpccfg.DefaultEvmCallTimeout, m.Engine, m.Dirs), m.DB, nil) currentHeader := rawdb.ReadCurrentHeader(tx) oldestHeader, err := api._blockReader.HeaderByNumber(ctx, tx, 0) @@ -262,7 +535,6 @@ func TestGetBlockByTimeMiddle(t *testing.T) { if err != nil { t.Errorf("couldn't retrieve block %v", err) } - if block["timestamp"] != response["timestamp"] || block["hash"] != response["hash"] { t.Errorf("Retrieved the wrong block.\nexpected block hash: %s expected timestamp: %d\nblock hash retrieved: %s timestamp retrieved: %d", response["hash"], response["timestamp"], block["hash"], block["timestamp"]) } @@ -280,7 +552,7 @@ func TestGetBlockByTimestamp(t *testing.T) { defer tx.Rollback() stateCache := kvcache.New(kvcache.DefaultCoherentConfig) - api := NewErigonAPI(NewBaseApi(nil, stateCache, br, agg, false, rpccfg.DefaultEvmCallTimeout, m.Engine), m.DB, nil) + api := NewErigonAPI(NewBaseApi(nil, stateCache, br, agg, false, rpccfg.DefaultEvmCallTimeout, m.Engine, m.Dirs), m.DB, nil) highestBlockNumber := rawdb.ReadCurrentHeader(tx).Number pickedBlock, err := rawdb.ReadBlockByNumber(tx, highestBlockNumber.Uint64()/3) @@ -314,16 +586,88 @@ func TestGetBlockByTimestamp(t *testing.T) { } } +// contractHexString is the output of compiling the following solidity contract: +// +// pragma solidity ^0.8.0; +// +// contract Box { +// uint256 private _value0x0; +// uint256 private _value0x1; +// uint256 private _value0x2; +// uint256 private _value0x3; +// uint256 private _value0x4; +// uint256 private _value0x5; +// uint256 private _value0x6; +// uint256 private _value0x7; +// uint256 private _value0x8; +// uint256 private _value0x9; +// uint256 private _value0xa; +// uint256 private _value0xb; +// uint256 private _value0xc; +// uint256 private _value0xd; +// uint256 private _value0xe; +// uint256 private _value0xf; +// uint256 private _value0x10; +// +// // Emitted when the stored value changes +// event ValueChanged(uint256 value); +// +// // Stores a new value in the contract +// function store(uint256 value) public { +// _value0x0 = value; +// _value0x1 = value; +// _value0x2 = value; +// _value0x3 = value; +// _value0x4 = value; +// _value0x5 = value; +// _value0x6 = value; +// _value0x7 = value; +// _value0x8 = value; +// _value0x9 = value; +// _value0xa = value; +// _value0xb = value; +// _value0xc = value; +// _value0xd = value; +// _value0xe = value; +// _value0xf = value; +// _value0x10 = value; +// emit ValueChanged(value); +// } +// +// // Reads the last stored value +// function retrieve() public view returns (uint256) { +// return _value0x0; +// } +// } +// +// You may produce this hex string by saving the contract into a file +// Box.sol and invoking +// +// solc Box.sol --bin --abi --optimize +// +// This contract is a slight modification of Box.sol to use more storage nodes +// and ensure the contract storage will contain at least 1 non-leaf node (by +// storing 17 values). +const contractHexString = "0x608060405234801561001057600080fd5b5061013f806100206000396000f3fe608060405234801561001057600080fd5b50600436106100365760003560e01c80632e64cec11461003b5780636057361d14610050575b600080fd5b60005460405190815260200160405180910390f35b61006361005e3660046100f0565b610065565b005b6000819055600181905560028190556003819055600481905560058190556006819055600781905560088190556009819055600a819055600b819055600c819055600d819055600e819055600f81905560108190556040518181527f93fe6d397c74fdf1402a8b72e47b68512f0510d7b98a4bc4cbdf6ac7108b3c599060200160405180910390a150565b60006020828403121561010257600080fd5b503591905056fea2646970667358221220031e17f1bd1d1dcbee088287a905b152410b180064c149763590a0bbc516d95e64736f6c63430008130033" + +var contractFuncSelector = crypto.Keccak256([]byte("store(uint256)"))[:4] + +// contractInvocationData returns data suitable for invoking the 'store' +// function of the contract in contractHexString, note +func contractInvocationData(val byte) []byte { + return hexutil.MustDecode(fmt.Sprintf("0x%x00000000000000000000000000000000000000000000000000000000000000%02x", contractFuncSelector, val)) +} + func chainWithDeployedContract(t *testing.T) (*stages.MockSentry, libcommon.Address, libcommon.Address) { var ( signer = types.LatestSignerForChainID(nil) bankKey, _ = crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291") bankAddress = crypto.PubkeyToAddress(bankKey.PublicKey) bankFunds = big.NewInt(1e9) - contract = hexutil.MustDecode("0x608060405234801561001057600080fd5b50610150806100206000396000f3fe608060405234801561001057600080fd5b50600436106100365760003560e01c80632e64cec11461003b5780636057361d14610059575b600080fd5b610043610075565b60405161005091906100d9565b60405180910390f35b610073600480360381019061006e919061009d565b61007e565b005b60008054905090565b8060008190555050565b60008135905061009781610103565b92915050565b6000602082840312156100b3576100b26100fe565b5b60006100c184828501610088565b91505092915050565b6100d3816100f4565b82525050565b60006020820190506100ee60008301846100ca565b92915050565b6000819050919050565b600080fd5b61010c816100f4565b811461011757600080fd5b5056fea26469706673582212209a159a4f3847890f10bfb87871a61eba91c5dbf5ee3cf6398207e292eee22a1664736f6c63430008070033") - gspec = &core.Genesis{ + contract = hexutil.MustDecode(contractHexString) + gspec = &types.Genesis{ Config: params.TestChainConfig, - Alloc: core.GenesisAlloc{bankAddress: {Balance: bankFunds}}, + Alloc: types.GenesisAlloc{bankAddress: {Balance: bankFunds}}, } ) m := stages.MockWithGenesis(t, gspec, bankKey, false) @@ -331,7 +675,7 @@ func chainWithDeployedContract(t *testing.T) (*stages.MockSentry, libcommon.Addr var contractAddr libcommon.Address - chain, err := core.GenerateChain(m.ChainConfig, m.Genesis, m.Engine, m.DB, 2, func(i int, block *core.BlockGen) { + chain, err := core.GenerateChain(m.ChainConfig, m.Genesis, m.Engine, m.DB, 3, func(i int, block *core.BlockGen) { nonce := block.TxNonce(bankAddress) switch i { case 0: @@ -340,7 +684,11 @@ func chainWithDeployedContract(t *testing.T) (*stages.MockSentry, libcommon.Addr block.AddTx(tx) contractAddr = crypto.CreateAddress(bankAddress, nonce) case 1: - txn, err := types.SignTx(types.NewTransaction(nonce, contractAddr, new(uint256.Int), 90000, new(uint256.Int), nil), *signer, bankKey) + txn, err := types.SignTx(types.NewTransaction(nonce, contractAddr, new(uint256.Int), 900000, new(uint256.Int), contractInvocationData(1)), *signer, bankKey) + assert.NoError(t, err) + block.AddTx(txn) + case 2: + txn, err := types.SignTx(types.NewTransaction(nonce, contractAddr, new(uint256.Int), 900000, new(uint256.Int), contractInvocationData(2)), *signer, bankKey) assert.NoError(t, err) block.AddTx(txn) } diff --git a/cmd/rpcdaemon/commands/eth_deprecated.go b/cmd/rpcdaemon/commands/eth_deprecated.go index 16a8553d27c..6c59ba83e38 100644 --- a/cmd/rpcdaemon/commands/eth_deprecated.go +++ b/cmd/rpcdaemon/commands/eth_deprecated.go @@ -5,8 +5,7 @@ import ( "fmt" "github.com/ledgerwatch/erigon-lib/common" - - "github.com/ledgerwatch/erigon/common/hexutil" + "github.com/ledgerwatch/erigon-lib/common/hexutility" ) // Accounts implements eth_accounts. Returns a list of addresses owned by the client. @@ -17,8 +16,8 @@ func (api *APIImpl) Accounts(ctx context.Context) ([]common.Address, error) { // Sign implements eth_sign. Calculates an Ethereum specific signature with: sign(keccak256('\\x19Ethereum Signed Message:\\n' + len(message) + message))). // Deprecated: This function will be removed in the future. -func (api *APIImpl) Sign(ctx context.Context, _ common.Address, _ hexutil.Bytes) (hexutil.Bytes, error) { - return hexutil.Bytes(""), fmt.Errorf(NotAvailableDeprecated, "eth_sign") +func (api *APIImpl) Sign(ctx context.Context, _ common.Address, _ hexutility.Bytes) (hexutility.Bytes, error) { + return hexutility.Bytes(""), fmt.Errorf(NotAvailableDeprecated, "eth_sign") } // SignTransaction deprecated diff --git a/cmd/rpcdaemon/commands/eth_receipts.go b/cmd/rpcdaemon/commands/eth_receipts.go index 354cd99282f..69c07d81abc 100644 --- a/cmd/rpcdaemon/commands/eth_receipts.go +++ b/cmd/rpcdaemon/commands/eth_receipts.go @@ -61,10 +61,11 @@ func (api *BaseAPI) getReceipts(ctx context.Context, tx kv.Tx, chainConfig *chai } return h } + header := block.Header() + excessDataGas := header.ParentExcessDataGas(getHeader) for i, txn := range block.Transactions() { ibs.Prepare(txn.Hash(), block.Hash(), i) - header := block.Header() - receipt, _, err := core.ApplyTransaction(chainConfig, core.GetHashFn(header, getHeader), engine, nil, gp, ibs, noopWriter, header, txn, usedGas, vm.Config{}) + receipt, _, err := core.ApplyTransaction(chainConfig, core.GetHashFn(header, getHeader), engine, nil, gp, ibs, noopWriter, header, txn, usedGas, vm.Config{}, excessDataGas) if err != nil { return nil, err } @@ -482,6 +483,7 @@ func txnExecutor(tx kv.TemporalTx, chainConfig *chain.Config, engine consensus.E stateReader.SetTx(tx) ie := &intraBlockExec{ + tx: tx, engine: engine, chainConfig: chainConfig, br: br, diff --git a/cmd/rpcdaemon/commands/eth_subscribe_test.go b/cmd/rpcdaemon/commands/eth_subscribe_test.go index 17e726edfe7..94c3828facc 100644 --- a/cmd/rpcdaemon/commands/eth_subscribe_test.go +++ b/cmd/rpcdaemon/commands/eth_subscribe_test.go @@ -22,9 +22,6 @@ import ( func TestEthSubscribe(t *testing.T) { m, require := stages.Mock(t), require.New(t) - if m.HistoryV3 { - t.Skip() - } br := snapshotsync.NewBlockReaderWithSnapshots(m.BlockSnapshots, m.TransactionsV3) chain, err := core.GenerateChain(m.ChainConfig, m.Genesis, m.Engine, m.DB, 7, func(i int, b *core.BlockGen) { b.SetCoinbase(libcommon.Address{1}) diff --git a/cmd/rpcdaemon/commands/eth_txs.go b/cmd/rpcdaemon/commands/eth_txs.go index 527798a36db..21fe98462ac 100644 --- a/cmd/rpcdaemon/commands/eth_txs.go +++ b/cmd/rpcdaemon/commands/eth_txs.go @@ -6,6 +6,7 @@ import ( "math/big" "github.com/ledgerwatch/erigon-lib/common" + "github.com/ledgerwatch/erigon-lib/common/hexutility" "github.com/ledgerwatch/erigon-lib/gointerfaces" "github.com/ledgerwatch/erigon-lib/gointerfaces/txpool" "github.com/ledgerwatch/erigon-lib/gointerfaces/types" @@ -117,7 +118,7 @@ func (api *APIImpl) GetTransactionByHash(ctx context.Context, txnHash common.Has } // GetRawTransactionByHash returns the bytes of the transaction for the given hash. -func (api *APIImpl) GetRawTransactionByHash(ctx context.Context, hash common.Hash) (hexutil.Bytes, error) { +func (api *APIImpl) GetRawTransactionByHash(ctx context.Context, hash common.Hash) (hexutility.Bytes, error) { tx, err := api.db.BeginRo(ctx) if err != nil { return nil, err @@ -204,7 +205,7 @@ func (api *APIImpl) GetTransactionByBlockHashAndIndex(ctx context.Context, block } // GetRawTransactionByBlockHashAndIndex returns the bytes of the transaction for the given block hash and index. -func (api *APIImpl) GetRawTransactionByBlockHashAndIndex(ctx context.Context, blockHash common.Hash, index hexutil.Uint) (hexutil.Bytes, error) { +func (api *APIImpl) GetRawTransactionByBlockHashAndIndex(ctx context.Context, blockHash common.Hash, index hexutil.Uint) (hexutility.Bytes, error) { tx, err := api.db.BeginRo(ctx) if err != nil { return nil, err @@ -268,7 +269,7 @@ func (api *APIImpl) GetTransactionByBlockNumberAndIndex(ctx context.Context, blo } // GetRawTransactionByBlockNumberAndIndex returns the bytes of the transaction for the given block number and index. -func (api *APIImpl) GetRawTransactionByBlockNumberAndIndex(ctx context.Context, blockNr rpc.BlockNumber, index hexutil.Uint) (hexutil.Bytes, error) { +func (api *APIImpl) GetRawTransactionByBlockNumberAndIndex(ctx context.Context, blockNr rpc.BlockNumber, index hexutil.Uint) (hexutility.Bytes, error) { tx, err := api.db.BeginRo(ctx) if err != nil { return nil, err diff --git a/cmd/rpcdaemon/commands/gen_traces_test.go b/cmd/rpcdaemon/commands/gen_traces_test.go index 241acf35d56..1250560ec20 100644 --- a/cmd/rpcdaemon/commands/gen_traces_test.go +++ b/cmd/rpcdaemon/commands/gen_traces_test.go @@ -122,7 +122,7 @@ func TestGeneratedTraceApi(t *testing.T) { stateCache := kvcache.New(kvcache.DefaultCoherentConfig) baseApi := NewBaseApi(nil, stateCache, br, agg, false, rpccfg.DefaultEvmCallTimeout, m.Engine) api := NewTraceAPI(baseApi, m.DB, &httpcfg.HttpCfg{}) - traces, err := api.Block(context.Background(), rpc.BlockNumber(1)) + traces, err := api.Block(context.Background(), rpc.BlockNumber(1), new(bool)) if err != nil { t.Errorf("trace_block %d: %v", 0, err) } @@ -281,7 +281,7 @@ func TestGeneratedTraceApiCollision(t *testing.T) { stateCache := kvcache.New(kvcache.DefaultCoherentConfig) baseApi := NewBaseApi(nil, stateCache, br, agg, false, rpccfg.DefaultEvmCallTimeout, m.Engine) api := NewTraceAPI(baseApi, m.DB, &httpcfg.HttpCfg{}) - traces, err := api.Transaction(context.Background(), common.HexToHash("0xb2b9fa4c999c1c8370ce1fbd1c4315a9ce7f8421fe2ebed8a9051ff2e4e7e3da")) + traces, err := api.Transaction(context.Background(), common.HexToHash("0xb2b9fa4c999c1c8370ce1fbd1c4315a9ce7f8421fe2ebed8a9051ff2e4e7e3da"), new(bool)) if err != nil { t.Errorf("trace_block %d: %v", 0, err) } diff --git a/cmd/rpcdaemon/commands/graphql_api.go b/cmd/rpcdaemon/commands/graphql_api.go index a81ca838a05..947540fb858 100644 --- a/cmd/rpcdaemon/commands/graphql_api.go +++ b/cmd/rpcdaemon/commands/graphql_api.go @@ -79,7 +79,13 @@ func (api *GraphQLAPIImpl) GetBlockDetails(ctx context.Context, blockNumber rpc. result := make([]map[string]interface{}, 0, len(receipts)) for _, receipt := range receipts { txn := block.Transactions()[receipt.TransactionIndex] - result = append(result, marshalReceipt(receipt, txn, chainConfig, block.HeaderNoCopy(), txn.Hash(), true)) + + transaction := marshalReceipt(receipt, txn, chainConfig, block.HeaderNoCopy(), txn.Hash(), true) + transaction["nonce"] = txn.GetNonce() + transaction["value"] = txn.GetValue() + transaction["data"] = txn.GetData() + transaction["gasPrice"] = txn.GetPrice() + result = append(result, transaction) } response := map[string]interface{}{} diff --git a/cmd/rpcdaemon/commands/otterscan_api.go b/cmd/rpcdaemon/commands/otterscan_api.go index 13dd6d32467..b66868f6ccd 100644 --- a/cmd/rpcdaemon/commands/otterscan_api.go +++ b/cmd/rpcdaemon/commands/otterscan_api.go @@ -8,14 +8,16 @@ import ( "sync" "github.com/holiman/uint256" + "github.com/ledgerwatch/log/v3" + "github.com/ledgerwatch/erigon-lib/chain" "github.com/ledgerwatch/erigon-lib/common" + "github.com/ledgerwatch/erigon-lib/common/hexutility" "github.com/ledgerwatch/erigon-lib/kv" "github.com/ledgerwatch/erigon-lib/kv/iter" "github.com/ledgerwatch/erigon-lib/kv/order" "github.com/ledgerwatch/erigon-lib/kv/rawdbv3" "github.com/ledgerwatch/erigon/core/state/temporal" - "github.com/ledgerwatch/log/v3" "github.com/ledgerwatch/erigon/common/hexutil" "github.com/ledgerwatch/erigon/consensus/ethash" @@ -49,7 +51,7 @@ type OtterscanAPI interface { GetBlockTransactions(ctx context.Context, number rpc.BlockNumber, pageNumber uint8, pageSize uint8) (map[string]interface{}, error) HasCode(ctx context.Context, address common.Address, blockNrOrHash rpc.BlockNumberOrHash) (bool, error) TraceTransaction(ctx context.Context, hash common.Hash) ([]*TraceEntry, error) - GetTransactionError(ctx context.Context, hash common.Hash) (hexutil.Bytes, error) + GetTransactionError(ctx context.Context, hash common.Hash) (hexutility.Bytes, error) GetTransactionBySenderAndNonce(ctx context.Context, addr common.Address, nonce uint64) (*common.Hash, error) GetContractCreator(ctx context.Context, addr common.Address) (*ContractCreatorData, error) } diff --git a/cmd/rpcdaemon/commands/otterscan_generic_tracer.go b/cmd/rpcdaemon/commands/otterscan_generic_tracer.go index 8b46f309fa5..2f0bb9addff 100644 --- a/cmd/rpcdaemon/commands/otterscan_generic_tracer.go +++ b/cmd/rpcdaemon/commands/otterscan_generic_tracer.go @@ -82,13 +82,14 @@ func (api *OtterscanAPIImpl) genericTracer(dbtx kv.Tx, ctx context.Context, bloc } header := block.Header() + excessDataGas := header.ParentExcessDataGas(getHeader) rules := chainConfig.Rules(block.NumberU64(), header.Time) for idx, tx := range block.Transactions() { ibs.Prepare(tx.Hash(), block.Hash(), idx) msg, _ := tx.AsMessage(*signer, header.BaseFee, rules) - BlockContext := core.NewEVMBlockContext(header, core.GetHashFn(header, getHeader), engine, nil) + BlockContext := core.NewEVMBlockContext(header, core.GetHashFn(header, getHeader), engine, nil, excessDataGas) TxContext := core.NewEVMTxContext(msg) vmenv := vm.NewEVM(BlockContext, TxContext, ibs, chainConfig, vm.Config{Debug: true, Tracer: tracer}) diff --git a/cmd/rpcdaemon/commands/otterscan_search_trace.go b/cmd/rpcdaemon/commands/otterscan_search_trace.go index 47924536d66..83174cca030 100644 --- a/cmd/rpcdaemon/commands/otterscan_search_trace.go +++ b/cmd/rpcdaemon/commands/otterscan_search_trace.go @@ -77,6 +77,7 @@ func (api *OtterscanAPIImpl) traceBlock(dbtx kv.Tx, ctx context.Context, blockNu blockReceipts := rawdb.ReadReceipts(dbtx, block, senders) header := block.Header() + excessDataGas := header.ParentExcessDataGas(getHeader) rules := chainConfig.Rules(block.NumberU64(), header.Time) found := false for idx, tx := range block.Transactions() { @@ -85,7 +86,7 @@ func (api *OtterscanAPIImpl) traceBlock(dbtx kv.Tx, ctx context.Context, blockNu msg, _ := tx.AsMessage(*signer, header.BaseFee, rules) tracer := NewTouchTracer(searchAddr) - BlockContext := core.NewEVMBlockContext(header, core.GetHashFn(header, getHeader), engine, nil) + BlockContext := core.NewEVMBlockContext(header, core.GetHashFn(header, getHeader), engine, nil, excessDataGas) TxContext := core.NewEVMTxContext(msg) vmenv := vm.NewEVM(BlockContext, TxContext, ibs, chainConfig, vm.Config{Debug: true, Tracer: tracer}) diff --git a/cmd/rpcdaemon/commands/otterscan_trace_transaction.go b/cmd/rpcdaemon/commands/otterscan_trace_transaction.go index 79767ec5c75..9778c69c908 100644 --- a/cmd/rpcdaemon/commands/otterscan_trace_transaction.go +++ b/cmd/rpcdaemon/commands/otterscan_trace_transaction.go @@ -5,7 +5,9 @@ import ( "math/big" "github.com/holiman/uint256" + "github.com/ledgerwatch/erigon-lib/common" + "github.com/ledgerwatch/erigon-lib/common/hexutility" "github.com/ledgerwatch/erigon/common/hexutil" "github.com/ledgerwatch/erigon/core/vm" @@ -27,12 +29,12 @@ func (api *OtterscanAPIImpl) TraceTransaction(ctx context.Context, hash common.H } type TraceEntry struct { - Type string `json:"type"` - Depth int `json:"depth"` - From common.Address `json:"from"` - To common.Address `json:"to"` - Value *hexutil.Big `json:"value"` - Input hexutil.Bytes `json:"input"` + Type string `json:"type"` + Depth int `json:"depth"` + From common.Address `json:"from"` + To common.Address `json:"to"` + Value *hexutil.Big `json:"value"` + Input hexutility.Bytes `json:"input"` } type TransactionTracer struct { diff --git a/cmd/rpcdaemon/commands/otterscan_transaction_error.go b/cmd/rpcdaemon/commands/otterscan_transaction_error.go index 503bfc183d7..c15b4c83b8e 100644 --- a/cmd/rpcdaemon/commands/otterscan_transaction_error.go +++ b/cmd/rpcdaemon/commands/otterscan_transaction_error.go @@ -4,11 +4,10 @@ import ( "context" "github.com/ledgerwatch/erigon-lib/common" - - "github.com/ledgerwatch/erigon/common/hexutil" + "github.com/ledgerwatch/erigon-lib/common/hexutility" ) -func (api *OtterscanAPIImpl) GetTransactionError(ctx context.Context, hash common.Hash) (hexutil.Bytes, error) { +func (api *OtterscanAPIImpl) GetTransactionError(ctx context.Context, hash common.Hash) (hexutility.Bytes, error) { tx, err := api.db.BeginRo(ctx) if err != nil { return nil, err diff --git a/cmd/rpcdaemon/commands/parity_api.go b/cmd/rpcdaemon/commands/parity_api.go index a1ac2e935ec..604b232f03b 100644 --- a/cmd/rpcdaemon/commands/parity_api.go +++ b/cmd/rpcdaemon/commands/parity_api.go @@ -6,10 +6,10 @@ import ( "fmt" libcommon "github.com/ledgerwatch/erigon-lib/common" + "github.com/ledgerwatch/erigon-lib/common/hexutility" "github.com/ledgerwatch/erigon-lib/common/length" "github.com/ledgerwatch/erigon-lib/kv" - "github.com/ledgerwatch/erigon/common/hexutil" "github.com/ledgerwatch/erigon/core/state" "github.com/ledgerwatch/erigon/rpc" ) @@ -20,7 +20,7 @@ var ErrWrongTag = fmt.Errorf("listStorageKeys wrong block tag or number: must be // ParityAPI the interface for the parity_ RPC commands type ParityAPI interface { - ListStorageKeys(ctx context.Context, account libcommon.Address, quantity int, offset *hexutil.Bytes, blockNumber rpc.BlockNumberOrHash) ([]hexutil.Bytes, error) + ListStorageKeys(ctx context.Context, account libcommon.Address, quantity int, offset *hexutility.Bytes, blockNumber rpc.BlockNumberOrHash) ([]hexutility.Bytes, error) } // ParityAPIImpl data structure to store things needed for parity_ commands @@ -36,7 +36,7 @@ func NewParityAPIImpl(db kv.RoDB) *ParityAPIImpl { } // ListStorageKeys implements parity_listStorageKeys. Returns all storage keys of the given address -func (api *ParityAPIImpl) ListStorageKeys(ctx context.Context, account libcommon.Address, quantity int, offset *hexutil.Bytes, blockNumberOrTag rpc.BlockNumberOrHash) ([]hexutil.Bytes, error) { +func (api *ParityAPIImpl) ListStorageKeys(ctx context.Context, account libcommon.Address, quantity int, offset *hexutility.Bytes, blockNumberOrTag rpc.BlockNumberOrHash) ([]hexutility.Bytes, error) { if err := api.checkBlockNumber(blockNumberOrTag); err != nil { return nil, err } @@ -62,7 +62,7 @@ func (api *ParityAPIImpl) ListStorageKeys(ctx context.Context, account libcommon return nil, err } defer c.Close() - keys := make([]hexutil.Bytes, 0) + keys := make([]hexutility.Bytes, 0) var v []byte var seekVal []byte if offset != nil { diff --git a/cmd/rpcdaemon/commands/parity_api_test.go b/cmd/rpcdaemon/commands/parity_api_test.go index d3728cc7952..1b23060b846 100644 --- a/cmd/rpcdaemon/commands/parity_api_test.go +++ b/cmd/rpcdaemon/commands/parity_api_test.go @@ -5,12 +5,13 @@ import ( "fmt" "testing" - libcommon "github.com/ledgerwatch/erigon-lib/common" "github.com/stretchr/testify/assert" + libcommon "github.com/ledgerwatch/erigon-lib/common" + "github.com/ledgerwatch/erigon-lib/common/hexutility" + "github.com/ledgerwatch/erigon/cmd/rpcdaemon/rpcdaemontest" "github.com/ledgerwatch/erigon/common" - "github.com/ledgerwatch/erigon/common/hexutil" "github.com/ledgerwatch/erigon/rpc" ) @@ -51,7 +52,7 @@ func TestParityAPIImpl_ListStorageKeys_WithOffset_ExistingPrefix(t *testing.T) { } addr := libcommon.HexToAddress("0x920fd5070602feaea2e251e9e7238b6c376bcae5") offset := common.Hex2Bytes("29") - b := hexutil.Bytes(offset) + b := hexutility.Bytes(offset) result, err := api.ListStorageKeys(context.Background(), addr, 5, &b, latestBlock) if err != nil { t.Errorf("calling ListStorageKeys: %v", err) @@ -72,7 +73,7 @@ func TestParityAPIImpl_ListStorageKeys_WithOffset_NonExistingPrefix(t *testing.T } addr := libcommon.HexToAddress("0x920fd5070602feaea2e251e9e7238b6c376bcae5") offset := common.Hex2Bytes("30") - b := hexutil.Bytes(offset) + b := hexutility.Bytes(offset) result, err := api.ListStorageKeys(context.Background(), addr, 2, &b, latestBlock) if err != nil { t.Errorf("calling ListStorageKeys: %v", err) @@ -89,7 +90,7 @@ func TestParityAPIImpl_ListStorageKeys_WithOffset_EmptyResponse(t *testing.T) { api := NewParityAPIImpl(m.DB) addr := libcommon.HexToAddress("0x920fd5070602feaea2e251e9e7238b6c376bcae5") offset := common.Hex2Bytes("ff") - b := hexutil.Bytes(offset) + b := hexutility.Bytes(offset) result, err := api.ListStorageKeys(context.Background(), addr, 2, &b, latestBlock) if err != nil { t.Errorf("calling ListStorageKeys: %v", err) diff --git a/cmd/rpcdaemon/commands/send_transaction.go b/cmd/rpcdaemon/commands/send_transaction.go index bd274d19237..700ec0680bb 100644 --- a/cmd/rpcdaemon/commands/send_transaction.go +++ b/cmd/rpcdaemon/commands/send_transaction.go @@ -8,10 +8,10 @@ import ( "math/big" "github.com/ledgerwatch/erigon-lib/common" + "github.com/ledgerwatch/erigon-lib/common/hexutility" txPoolProto "github.com/ledgerwatch/erigon-lib/gointerfaces/txpool" "github.com/ledgerwatch/log/v3" - "github.com/ledgerwatch/erigon/common/hexutil" "github.com/ledgerwatch/erigon/core/rawdb" "github.com/ledgerwatch/erigon/core/types" "github.com/ledgerwatch/erigon/crypto" @@ -21,7 +21,7 @@ import ( ) // SendRawTransaction implements eth_sendRawTransaction. Creates new message call transaction or a contract creation for previously-signed transactions. -func (api *APIImpl) SendRawTransaction(ctx context.Context, encodedTx hexutil.Bytes) (common.Hash, error) { +func (api *APIImpl) SendRawTransaction(ctx context.Context, encodedTx hexutility.Bytes) (common.Hash, error) { txn, err := types.DecodeTransaction(rlp.NewStream(bytes.NewReader(encodedTx), uint64(len(encodedTx)))) if err != nil { return common.Hash{}, err diff --git a/cmd/rpcdaemon/commands/trace_adhoc.go b/cmd/rpcdaemon/commands/trace_adhoc.go index 9980745edbc..79988b862fa 100644 --- a/cmd/rpcdaemon/commands/trace_adhoc.go +++ b/cmd/rpcdaemon/commands/trace_adhoc.go @@ -9,10 +9,12 @@ import ( "strings" "github.com/holiman/uint256" + "github.com/ledgerwatch/log/v3" + libcommon "github.com/ledgerwatch/erigon-lib/common" + "github.com/ledgerwatch/erigon-lib/common/hexutility" "github.com/ledgerwatch/erigon-lib/kv" types2 "github.com/ledgerwatch/erigon-lib/types" - "github.com/ledgerwatch/log/v3" "github.com/ledgerwatch/erigon/common" "github.com/ledgerwatch/erigon/common/hexutil" @@ -50,8 +52,9 @@ type TraceCallParam struct { GasPrice *hexutil.Big `json:"gasPrice"` MaxPriorityFeePerGas *hexutil.Big `json:"maxPriorityFeePerGas"` MaxFeePerGas *hexutil.Big `json:"maxFeePerGas"` + MaxFeePerDataGas *hexutil.Big `json:"maxFeePerDataGas"` Value *hexutil.Big `json:"value"` - Data hexutil.Bytes `json:"data"` + Data hexutility.Bytes `json:"data"` AccessList *types2.AccessList `json:"accessList"` txHash *libcommon.Hash traceTypes []string @@ -59,7 +62,7 @@ type TraceCallParam struct { // TraceCallResult is the response to `trace_call` method type TraceCallResult struct { - Output hexutil.Bytes `json:"output"` + Output hexutility.Bytes `json:"output"` StateDiff map[libcommon.Address]*StateDiffAccount `json:"stateDiff"` Trace []*ParityTrace `json:"trace"` VmTrace *VmTrace `json:"vmTrace"` @@ -80,8 +83,8 @@ type StateDiffBalance struct { } type StateDiffCode struct { - From hexutil.Bytes `json:"from"` - To hexutil.Bytes `json:"to"` + From hexutility.Bytes `json:"from"` + To hexutility.Bytes `json:"to"` } type StateDiffNonce struct { @@ -96,8 +99,8 @@ type StateDiffStorage struct { // VmTrace is the part of `trace_call` response that is under "vmTrace" tag type VmTrace struct { - Code hexutil.Bytes `json:"code"` - Ops []*VmTraceOp `json:"ops"` + Code hexutility.Bytes `json:"code"` + Ops []*VmTraceOp `json:"ops"` } // VmTraceOp is one element of the vmTrace ops trace @@ -148,9 +151,10 @@ func (args *TraceCallParam) ToMessage(globalGasCap uint64, baseFee *uint256.Int) gas = globalGasCap } var ( - gasPrice *uint256.Int - gasFeeCap *uint256.Int - gasTipCap *uint256.Int + gasPrice *uint256.Int + gasFeeCap *uint256.Int + gasTipCap *uint256.Int + maxFeePerDataGas *uint256.Int ) if baseFee == nil { // If there's no basefee, then it must be a non-1559 execution @@ -198,6 +202,9 @@ func (args *TraceCallParam) ToMessage(globalGasCap uint64, baseFee *uint256.Int) gasFeeCap, gasTipCap = gasPrice, gasPrice } } + if args.MaxFeePerDataGas != nil { + maxFeePerDataGas.SetFromBig(args.MaxFeePerDataGas.ToInt()) + } } value := new(uint256.Int) if args.Value != nil { @@ -214,7 +221,7 @@ func (args *TraceCallParam) ToMessage(globalGasCap uint64, baseFee *uint256.Int) if args.AccessList != nil { accessList = *args.AccessList } - msg := types.NewMessage(addr, args.To, 0, value, gas, gasPrice, gasFeeCap, gasTipCap, data, accessList, false /* checkNonce */, false /* isFree */) + msg := types.NewMessage(addr, args.To, 0, value, gas, gasPrice, gasFeeCap, gasTipCap, data, accessList, false /* checkNonce */, false /* isFree */, maxFeePerDataGas) return msg, nil } @@ -659,7 +666,7 @@ func (sd *StateDiff) CompareStates(initialIbs, ibs *state.IntraBlockState) { accountDiff.Balance = m } { - m := make(map[string]hexutil.Bytes) + m := make(map[string]hexutility.Bytes) m["-"] = initialIbs.GetCode(addr) accountDiff.Code = m } @@ -676,7 +683,7 @@ func (sd *StateDiff) CompareStates(initialIbs, ibs *state.IntraBlockState) { accountDiff.Balance = m } { - m := make(map[string]hexutil.Bytes) + m := make(map[string]hexutility.Bytes) m["+"] = ibs.GetCode(addr) accountDiff.Code = m } @@ -700,7 +707,10 @@ func (sd *StateDiff) CompareStates(initialIbs, ibs *state.IntraBlockState) { } } -func (api *TraceAPIImpl) ReplayTransaction(ctx context.Context, txHash libcommon.Hash, traceTypes []string) (*TraceCallResult, error) { +func (api *TraceAPIImpl) ReplayTransaction(ctx context.Context, txHash libcommon.Hash, traceTypes []string, gasBailOut *bool) (*TraceCallResult, error) { + if gasBailOut == nil { + gasBailOut = new(bool) // false by default + } tx, err := api.kv.BeginRo(ctx) if err != nil { return nil, err @@ -744,15 +754,8 @@ func (api *TraceAPIImpl) ReplayTransaction(ctx context.Context, txHash libcommon } } - bn := hexutil.Uint64(blockNum) - - parentNr := bn - if parentNr > 0 { - parentNr -= 1 - } - // Returns an array of trace arrays, one trace array for each transaction - traces, err := api.callManyTransactions(ctx, tx, block.Transactions(), traceTypes, block.ParentHash(), rpc.BlockNumber(parentNr), block.Header(), int(txnIndex), types.MakeSigner(chainConfig, blockNum), chainConfig.Rules(blockNum, block.Time())) + traces, err := api.callManyTransactions(ctx, tx, block, traceTypes, int(txnIndex), *gasBailOut, types.MakeSigner(chainConfig, blockNum), chainConfig) if err != nil { return nil, err } @@ -792,7 +795,10 @@ func (api *TraceAPIImpl) ReplayTransaction(ctx context.Context, txHash libcommon return result, nil } -func (api *TraceAPIImpl) ReplayBlockTransactions(ctx context.Context, blockNrOrHash rpc.BlockNumberOrHash, traceTypes []string) ([]*TraceCallResult, error) { +func (api *TraceAPIImpl) ReplayBlockTransactions(ctx context.Context, blockNrOrHash rpc.BlockNumberOrHash, traceTypes []string, gasBailOut *bool) ([]*TraceCallResult, error) { + if gasBailOut == nil { + gasBailOut = new(bool) // false by default + } tx, err := api.kv.BeginRo(ctx) if err != nil { return nil, err @@ -808,10 +814,6 @@ func (api *TraceAPIImpl) ReplayBlockTransactions(ctx context.Context, blockNrOrH return nil, err } - parentNr := blockNumber - if parentNr > 0 { - parentNr -= 1 - } // Extract transactions from block block, bErr := api.blockByNumberWithSenders(tx, blockNumber) if bErr != nil { @@ -835,7 +837,7 @@ func (api *TraceAPIImpl) ReplayBlockTransactions(ctx context.Context, blockNrOrH } // Returns an array of trace arrays, one trace array for each transaction - traces, err := api.callManyTransactions(ctx, tx, block.Transactions(), traceTypes, block.ParentHash(), rpc.BlockNumber(parentNr), block.Header(), -1 /* all tx indices */, types.MakeSigner(chainConfig, blockNumber), chainConfig.Rules(blockNumber, block.Time())) + traces, err := api.callManyTransactions(ctx, tx, block, traceTypes, -1 /* all tx indices */, *gasBailOut, types.MakeSigner(chainConfig, blockNumber), chainConfig) if err != nil { return nil, err } @@ -1060,10 +1062,10 @@ func (api *TraceAPIImpl) CallMany(ctx context.Context, calls json.RawMessage, pa if err != nil { return nil, err } - parentHeader := parentBlock.Header() - if parentHeader == nil { - return nil, fmt.Errorf("parent header %d(%x) not found", blockNumber, hash) + if parentBlock == nil { + return nil, fmt.Errorf("parent block %d(%x) not found", blockNumber, hash) } + parentHeader := parentBlock.Header() if parentHeader != nil && parentHeader.BaseFee != nil { var overflow bool baseFee, overflow = uint256.FromBig(parentHeader.BaseFee) diff --git a/cmd/rpcdaemon/commands/trace_adhoc_test.go b/cmd/rpcdaemon/commands/trace_adhoc_test.go index 92f4aba64de..f03151879ad 100644 --- a/cmd/rpcdaemon/commands/trace_adhoc_test.go +++ b/cmd/rpcdaemon/commands/trace_adhoc_test.go @@ -89,7 +89,7 @@ func TestReplayTransaction(t *testing.T) { } // Call GetTransactionReceipt for transaction which is not in the database - results, err := api.ReplayTransaction(context.Background(), txnHash, []string{"stateDiff"}) + results, err := api.ReplayTransaction(context.Background(), txnHash, []string{"stateDiff"}, new(bool)) if err != nil { t.Errorf("calling ReplayTransaction: %v", err) } @@ -110,7 +110,7 @@ func TestReplayBlockTransactions(t *testing.T) { // Call GetTransactionReceipt for transaction which is not in the database n := rpc.BlockNumber(6) - results, err := api.ReplayBlockTransactions(m.Ctx, rpc.BlockNumberOrHash{BlockNumber: &n}, []string{"stateDiff"}) + results, err := api.ReplayBlockTransactions(m.Ctx, rpc.BlockNumberOrHash{BlockNumber: &n}, []string{"stateDiff"}, new(bool)) if err != nil { t.Errorf("calling ReplayBlockTransactions: %v", err) } diff --git a/cmd/rpcdaemon/commands/trace_api.go b/cmd/rpcdaemon/commands/trace_api.go index 50ac4e652fc..fce0cb9877d 100644 --- a/cmd/rpcdaemon/commands/trace_api.go +++ b/cmd/rpcdaemon/commands/trace_api.go @@ -3,8 +3,8 @@ package commands import ( "context" "encoding/json" - jsoniter "github.com/json-iterator/go" + libcommon "github.com/ledgerwatch/erigon-lib/common" "github.com/ledgerwatch/erigon-lib/kv" @@ -16,17 +16,17 @@ import ( // TraceAPI RPC interface into tracing API type TraceAPI interface { // Ad-hoc (see ./trace_adhoc.go) - ReplayBlockTransactions(ctx context.Context, blockNr rpc.BlockNumberOrHash, traceTypes []string) ([]*TraceCallResult, error) - ReplayTransaction(ctx context.Context, txHash libcommon.Hash, traceTypes []string) (*TraceCallResult, error) + ReplayBlockTransactions(ctx context.Context, blockNr rpc.BlockNumberOrHash, traceTypes []string, gasBailOut *bool) ([]*TraceCallResult, error) + ReplayTransaction(ctx context.Context, txHash libcommon.Hash, traceTypes []string, gasBailOut *bool) (*TraceCallResult, error) Call(ctx context.Context, call TraceCallParam, types []string, blockNr *rpc.BlockNumberOrHash) (*TraceCallResult, error) CallMany(ctx context.Context, calls json.RawMessage, blockNr *rpc.BlockNumberOrHash) ([]*TraceCallResult, error) RawTransaction(ctx context.Context, txHash libcommon.Hash, traceTypes []string) ([]interface{}, error) // Filtering (see ./trace_filtering.go) - Transaction(ctx context.Context, txHash libcommon.Hash) (ParityTraces, error) - Get(ctx context.Context, txHash libcommon.Hash, txIndicies []hexutil.Uint64) (*ParityTrace, error) - Block(ctx context.Context, blockNr rpc.BlockNumber) (ParityTraces, error) - Filter(ctx context.Context, req TraceFilterRequest, stream *jsoniter.Stream) error + Transaction(ctx context.Context, txHash libcommon.Hash, gasBailOut *bool) (ParityTraces, error) + Get(ctx context.Context, txHash libcommon.Hash, txIndicies []hexutil.Uint64, gasBailOut *bool) (*ParityTrace, error) + Block(ctx context.Context, blockNr rpc.BlockNumber, gasBailOut *bool) (ParityTraces, error) + Filter(ctx context.Context, req TraceFilterRequest, gasBailOut *bool, stream *jsoniter.Stream) error } // TraceAPIImpl is implementation of the TraceAPI interface based on remote Db access diff --git a/cmd/rpcdaemon/commands/trace_filtering.go b/cmd/rpcdaemon/commands/trace_filtering.go index 66a39793c05..2b362dd242a 100644 --- a/cmd/rpcdaemon/commands/trace_filtering.go +++ b/cmd/rpcdaemon/commands/trace_filtering.go @@ -15,7 +15,9 @@ import ( "github.com/ledgerwatch/erigon-lib/kv/iter" "github.com/ledgerwatch/erigon-lib/kv/order" "github.com/ledgerwatch/erigon-lib/kv/rawdbv3" + "github.com/ledgerwatch/erigon/common/hexutil" + "github.com/ledgerwatch/erigon/consensus" "github.com/ledgerwatch/erigon/consensus/ethash" "github.com/ledgerwatch/erigon/core" "github.com/ledgerwatch/erigon/core/rawdb" @@ -23,6 +25,7 @@ import ( "github.com/ledgerwatch/erigon/core/state/temporal" "github.com/ledgerwatch/erigon/core/types" "github.com/ledgerwatch/erigon/core/vm" + "github.com/ledgerwatch/erigon/eth/stagedsync" "github.com/ledgerwatch/erigon/ethdb" "github.com/ledgerwatch/erigon/rpc" "github.com/ledgerwatch/erigon/turbo/rpchelper" @@ -31,7 +34,10 @@ import ( ) // Transaction implements trace_transaction -func (api *TraceAPIImpl) Transaction(ctx context.Context, txHash common.Hash) (ParityTraces, error) { +func (api *TraceAPIImpl) Transaction(ctx context.Context, txHash common.Hash, gasBailOut *bool) (ParityTraces, error) { + if gasBailOut == nil { + gasBailOut = new(bool) // false by default + } tx, err := api.kv.BeginRo(ctx) if err != nil { return nil, err @@ -85,14 +91,10 @@ func (api *TraceAPIImpl) Transaction(ctx context.Context, txHash common.Hash) (P } bn := hexutil.Uint64(blockNumber) - parentNr := bn - if parentNr > 0 { - parentNr -= 1 - } hash := block.Hash() // Returns an array of trace arrays, one trace array for each transaction - traces, err := api.callManyTransactions(ctx, tx, block.Transactions(), []string{TraceTypeTrace}, block.ParentHash(), rpc.BlockNumber(parentNr), block.Header(), txIndex, types.MakeSigner(chainConfig, blockNumber), chainConfig.Rules(blockNumber, block.Time())) + traces, err := api.callManyTransactions(ctx, tx, block, []string{TraceTypeTrace}, txIndex, *gasBailOut, types.MakeSigner(chainConfig, blockNumber), chainConfig) if err != nil { return nil, err } @@ -118,13 +120,12 @@ func (api *TraceAPIImpl) Transaction(ctx context.Context, txHash common.Hash) (P } // Get implements trace_get -func (api *TraceAPIImpl) Get(ctx context.Context, txHash common.Hash, indicies []hexutil.Uint64) (*ParityTrace, error) { +func (api *TraceAPIImpl) Get(ctx context.Context, txHash common.Hash, indicies []hexutil.Uint64, gasBailOut *bool) (*ParityTrace, error) { // Parity fails if it gets more than a single index. It returns nothing in this case. Must we? if len(indicies) > 1 { return nil, nil } - - traces, err := api.Transaction(ctx, txHash) + traces, err := api.Transaction(ctx, txHash, gasBailOut) if err != nil { return nil, err } @@ -140,7 +141,10 @@ func (api *TraceAPIImpl) Get(ctx context.Context, txHash common.Hash, indicies [ } // Block implements trace_block -func (api *TraceAPIImpl) Block(ctx context.Context, blockNr rpc.BlockNumber) (ParityTraces, error) { +func (api *TraceAPIImpl) Block(ctx context.Context, blockNr rpc.BlockNumber, gasBailOut *bool) (ParityTraces, error) { + if gasBailOut == nil { + gasBailOut = new(bool) // false by default + } tx, err := api.kv.BeginRo(ctx) if err != nil { return nil, err @@ -164,16 +168,11 @@ func (api *TraceAPIImpl) Block(ctx context.Context, blockNr rpc.BlockNumber) (Pa return nil, fmt.Errorf("could not find block %d", uint64(bn)) } - parentNr := bn - if parentNr > 0 { - parentNr -= 1 - } - chainConfig, err := api.chainConfig(tx) if err != nil { return nil, err } - traces, err := api.callManyTransactions(ctx, tx, block.Transactions(), []string{TraceTypeTrace}, block.ParentHash(), rpc.BlockNumber(parentNr), block.Header(), -1 /* all tx indices */, types.MakeSigner(chainConfig, blockNum), chainConfig.Rules(blockNum, block.Time())) + traces, err := api.callManyTransactions(ctx, tx, block, []string{TraceTypeTrace}, -1 /* all tx indices */, *gasBailOut /* gasBailOut */, types.MakeSigner(chainConfig, blockNum), chainConfig) if err != nil { return nil, err } @@ -296,33 +295,33 @@ func traceFilterBitmapsV3(tx kv.TemporalTx, req TraceFilterRequest, from, to uin for _, addr := range req.FromAddress { if addr != nil { - it, err := tx.IndexRange(temporal.TracesFromIdx, addr.Bytes(), int(from), int(to), order.Asc, -1) + it, err := tx.IndexRange(temporal.TracesFromIdx, addr.Bytes(), int(from), int(to), order.Asc, kv.Unlim) if errors.Is(err, ethdb.ErrKeyNotFound) { continue } - allBlocks = iter.Union[uint64](allBlocks, it) + allBlocks = iter.Union[uint64](allBlocks, it, order.Asc, -1) fromAddresses[*addr] = struct{}{} } } for _, addr := range req.ToAddress { if addr != nil { - it, err := tx.IndexRange(temporal.TracesToIdx, addr.Bytes(), int(from), int(to), order.Asc, -1) + it, err := tx.IndexRange(temporal.TracesToIdx, addr.Bytes(), int(from), int(to), order.Asc, kv.Unlim) if errors.Is(err, ethdb.ErrKeyNotFound) { continue } - blocksTo = iter.Union[uint64](blocksTo, it) + blocksTo = iter.Union[uint64](blocksTo, it, order.Asc, -1) toAddresses[*addr] = struct{}{} } } switch req.Mode { case TraceFilterModeIntersection: - allBlocks = iter.Intersect[uint64](allBlocks, blocksTo) + allBlocks = iter.Intersect[uint64](allBlocks, blocksTo, -1) case TraceFilterModeUnion: fallthrough default: - allBlocks = iter.Union[uint64](allBlocks, blocksTo) + allBlocks = iter.Union[uint64](allBlocks, blocksTo, order.Asc, -1) } // Special case - if no addresses specified, take all traces @@ -339,7 +338,10 @@ func traceFilterBitmapsV3(tx kv.TemporalTx, req TraceFilterRequest, from, to uin // Filter implements trace_filter // NOTE: We do not store full traces - we just store index for each address // Pull blocks which have txs with matching address -func (api *TraceAPIImpl) Filter(ctx context.Context, req TraceFilterRequest, stream *jsoniter.Stream) error { +func (api *TraceAPIImpl) Filter(ctx context.Context, req TraceFilterRequest, gasBailOut *bool, stream *jsoniter.Stream) error { + if gasBailOut == nil { + gasBailOut = new(bool) // false by default + } dbtx, err1 := api.kv.BeginRo(ctx) if err1 != nil { return fmt.Errorf("traceFilter cannot open tx: %w", err1) @@ -443,7 +445,7 @@ func (api *TraceAPIImpl) Filter(ctx context.Context, req TraceFilterRequest, str isPos = header.Difficulty.Cmp(common.Big0) == 0 || header.Difficulty.Cmp(chainConfig.TerminalTotalDifficulty) >= 0 } txs := block.Transactions() - t, tErr := api.callManyTransactions(ctx, dbtx, txs, []string{TraceTypeTrace}, block.ParentHash(), rpc.BlockNumber(block.NumberU64()-1), block.Header(), -1 /* all tx indices */, types.MakeSigner(chainConfig, b), chainConfig.Rules(b, block.Time())) + t, tErr := api.callManyTransactions(ctx, dbtx, block, []string{TraceTypeTrace}, -1 /* all tx indices */, *gasBailOut, types.MakeSigner(chainConfig, b), chainConfig) if tErr != nil { if first { first = false @@ -455,13 +457,14 @@ func (api *TraceAPIImpl) Filter(ctx context.Context, req TraceFilterRequest, str stream.WriteObjectEnd() continue } + isIntersectionMode := req.Mode == TraceFilterModeIntersection includeAll := len(fromAddresses) == 0 && len(toAddresses) == 0 for i, trace := range t { txPosition := uint64(i) txHash := txs[i].Hash() // Check if transaction concerns any of the addresses we wanted for _, pt := range trace.Trace { - if includeAll || filter_trace(pt, fromAddresses, toAddresses) { + if includeAll || filter_trace(pt, fromAddresses, toAddresses, isIntersectionMode) { nSeen++ pt.BlockHash = &blockHash pt.BlockNumber = &blockNumber @@ -870,8 +873,9 @@ func (api *TraceAPIImpl) filterV3(ctx context.Context, dbtx kv.TemporalTx, fromB stream.WriteObjectEnd() continue } + isIntersectionMode := req.Mode == TraceFilterModeIntersection for _, pt := range traceResult.Trace { - if includeAll || filter_trace(pt, fromAddresses, toAddresses) { + if includeAll || filter_trace(pt, fromAddresses, toAddresses, isIntersectionMode) { nSeen++ pt.BlockHash = &lastBlockHash pt.BlockNumber = &blockNum @@ -905,41 +909,73 @@ func (api *TraceAPIImpl) filterV3(ctx context.Context, dbtx kv.TemporalTx, fromB return stream.Flush() } -func filter_trace(pt *ParityTrace, fromAddresses map[common.Address]struct{}, toAddresses map[common.Address]struct{}) bool { +func filter_trace(pt *ParityTrace, fromAddresses map[common.Address]struct{}, toAddresses map[common.Address]struct{}, isIntersectionMode bool) bool { + f, t := false, false switch action := pt.Action.(type) { case *CallTraceAction: - _, f := fromAddresses[action.From] - _, t := toAddresses[action.To] - - if f || t { - return true - } + _, f = fromAddresses[action.From] + _, t = toAddresses[action.To] case *CreateTraceAction: - _, f := fromAddresses[action.From] - if f { - return true - } + _, f = fromAddresses[action.From] if res, ok := pt.Result.(*CreateTraceResult); ok { if res.Address != nil { - if _, t := toAddresses[*res.Address]; t { - return true - } + _, t = toAddresses[*res.Address] } } case *SuicideTraceAction: - _, f := fromAddresses[action.Address] - _, t := toAddresses[action.RefundAddress] - if f || t { - return true - } + _, f = fromAddresses[action.Address] + _, t = toAddresses[action.RefundAddress] } - return false + if isIntersectionMode { + return f && t + } else { + return f || t + } } -func (api *TraceAPIImpl) callManyTransactions(ctx context.Context, dbtx kv.Tx, txs []types.Transaction, traceTypes []string, parentHash common.Hash, parentNo rpc.BlockNumber, header *types.Header, txIndex int, signer *types.Signer, rules *chain.Rules) ([]*TraceCallResult, error) { +func (api *TraceAPIImpl) callManyTransactions( + ctx context.Context, + dbtx kv.Tx, + block *types.Block, + traceTypes []string, + txIndex int, + gasBailOut bool, + signer *types.Signer, + cfg *chain.Config, +) ([]*TraceCallResult, error) { + blockNumber := block.NumberU64() + pNo := blockNumber + if pNo > 0 { + pNo -= 1 + } + parentNo := rpc.BlockNumber(pNo) + rules := cfg.Rules(blockNumber, block.Time()) + header := block.Header() + var excessDataGas *big.Int + parentBlock, err := api.blockByRPCNumber(parentNo, dbtx) + if err != nil { + return nil, err + } else if parentBlock != nil { + excessDataGas = parentBlock.ExcessDataGas() + } + txs := block.Transactions() callParams := make([]TraceCallParam, 0, len(txs)) + reader, err := rpchelper.CreateHistoryStateReader(dbtx, blockNumber, txIndex, api.historyV3(dbtx), cfg.ChainName) + if err != nil { + return nil, err + } + stateDb := state.New(reader) + if err != nil { + return nil, err + } + engine := api.engine() + consensusHeaderReader := stagedsync.NewChainReaderImpl(cfg, dbtx, nil) + err = core.InitializeBlockExecution(engine.(consensus.Engine), consensusHeaderReader, block.HeaderNoCopy(), block.Transactions(), block.Uncles(), cfg, stateDb, excessDataGas) + if err != nil { + return nil, err + } msgs := make([]types.Message, len(txs)) for i, tx := range txs { hash := tx.Hash() @@ -948,16 +984,30 @@ func (api *TraceAPIImpl) callManyTransactions(ctx context.Context, dbtx kv.Tx, t traceTypes: traceTypes, }) var err error - if msgs[i], err = tx.AsMessage(*signer, header.BaseFee, rules); err != nil { + + msg, err := tx.AsMessage(*signer, header.BaseFee, rules) + if err != nil { return nil, fmt.Errorf("convert tx into msg: %w", err) } + + // gnosis might have a fee free account here + if msg.FeeCap().IsZero() && engine != nil { + syscall := func(contract common.Address, data []byte) ([]byte, error) { + return core.SysCallContract(contract, data, *cfg, stateDb, header, engine, true /* constCall */, excessDataGas) + } + msg.SetIsFree(engine.IsServiceTransaction(msg.From(), syscall)) + } + + msgs[i] = msg } + parentHash := block.ParentHash() + traces, cmErr := api.doCallMany(ctx, dbtx, msgs, callParams, &rpc.BlockNumberOrHash{ BlockNumber: &parentNo, BlockHash: &parentHash, RequireCanonical: true, - }, header, false /* gasBailout */, txIndex) + }, header, gasBailOut /* gasBailout */, txIndex) if cmErr != nil { return nil, cmErr diff --git a/cmd/rpcdaemon/commands/trace_types.go b/cmd/rpcdaemon/commands/trace_types.go index 9ebdbdf58da..a905d3a4c8a 100644 --- a/cmd/rpcdaemon/commands/trace_types.go +++ b/cmd/rpcdaemon/commands/trace_types.go @@ -4,6 +4,7 @@ import ( "fmt" "github.com/ledgerwatch/erigon-lib/common" + "github.com/ledgerwatch/erigon-lib/common/hexutility" "github.com/ledgerwatch/erigon/common/hexutil" "github.com/ledgerwatch/erigon/core/types" @@ -56,34 +57,34 @@ type ParityTraces []ParityTrace // TraceAction A parity formatted trace action type TraceAction struct { // Do not change the ordering of these fields -- allows for easier comparison with other clients - Author string `json:"author,omitempty"` - RewardType string `json:"rewardType,omitempty"` - SelfDestructed string `json:"address,omitempty"` - Balance string `json:"balance,omitempty"` - CallType string `json:"callType,omitempty"` - From common.Address `json:"from"` - Gas hexutil.Big `json:"gas"` - Init hexutil.Bytes `json:"init,omitempty"` - Input hexutil.Bytes `json:"input,omitempty"` - RefundAddress string `json:"refundAddress,omitempty"` - To string `json:"to,omitempty"` - Value string `json:"value,omitempty"` + Author string `json:"author,omitempty"` + RewardType string `json:"rewardType,omitempty"` + SelfDestructed string `json:"address,omitempty"` + Balance string `json:"balance,omitempty"` + CallType string `json:"callType,omitempty"` + From common.Address `json:"from"` + Gas hexutil.Big `json:"gas"` + Init hexutility.Bytes `json:"init,omitempty"` + Input hexutility.Bytes `json:"input,omitempty"` + RefundAddress string `json:"refundAddress,omitempty"` + To string `json:"to,omitempty"` + Value string `json:"value,omitempty"` } type CallTraceAction struct { - From common.Address `json:"from"` - CallType string `json:"callType"` - Gas hexutil.Big `json:"gas"` - Input hexutil.Bytes `json:"input"` - To common.Address `json:"to"` - Value hexutil.Big `json:"value"` + From common.Address `json:"from"` + CallType string `json:"callType"` + Gas hexutil.Big `json:"gas"` + Input hexutility.Bytes `json:"input"` + To common.Address `json:"to"` + Value hexutil.Big `json:"value"` } type CreateTraceAction struct { - From common.Address `json:"from"` - Gas hexutil.Big `json:"gas"` - Init hexutil.Bytes `json:"init"` - Value hexutil.Big `json:"value"` + From common.Address `json:"from"` + Gas hexutil.Big `json:"gas"` + Init hexutility.Bytes `json:"init"` + Value hexutil.Big `json:"value"` } type SuicideTraceAction struct { @@ -100,16 +101,16 @@ type RewardTraceAction struct { type CreateTraceResult struct { // Do not change the ordering of these fields -- allows for easier comparison with other clients - Address *common.Address `json:"address,omitempty"` - Code hexutil.Bytes `json:"code"` - GasUsed *hexutil.Big `json:"gasUsed"` + Address *common.Address `json:"address,omitempty"` + Code hexutility.Bytes `json:"code"` + GasUsed *hexutil.Big `json:"gasUsed"` } // TraceResult A parity formatted trace result type TraceResult struct { // Do not change the ordering of these fields -- allows for easier comparison with other clients - GasUsed *hexutil.Big `json:"gasUsed"` - Output hexutil.Bytes `json:"output"` + GasUsed *hexutil.Big `json:"gasUsed"` + Output hexutility.Bytes `json:"output"` } // Allows for easy printing of a geth trace for debugging diff --git a/cmd/rpcdaemon/commands/tracing.go b/cmd/rpcdaemon/commands/tracing.go index b92fc571eef..3d84f6aadb2 100644 --- a/cmd/rpcdaemon/commands/tracing.go +++ b/cmd/rpcdaemon/commands/tracing.go @@ -79,10 +79,23 @@ func (api *PrivateDebugAPIImpl) traceBlock(ctx context.Context, blockNrOrHash rp return err } + if config == nil { + config = &tracers.TraceConfig{} + } + if config.BorTraceEnabled == nil { config.BorTraceEnabled = newBoolPtr(false) } + var excessDataGas *big.Int + parentBlock, err := api.blockByHashWithSenders(tx, block.ParentHash()) + if err != nil { + stream.WriteNil() + return err + } + if parentBlock != nil { + excessDataGas = parentBlock.ExcessDataGas() + } chainConfig, err := api.chainConfig(tx) if err != nil { stream.WriteNil() @@ -120,7 +133,7 @@ func (api *PrivateDebugAPIImpl) traceBlock(ctx context.Context, blockNrOrHash rp if msg.FeeCap().IsZero() && engine != nil { syscall := func(contract common.Address, data []byte) ([]byte, error) { - return core.SysCallContract(contract, data, *chainConfig, ibs, block.Header(), engine, true /* constCall */) + return core.SysCallContract(contract, data, *chainConfig, ibs, block.Header(), engine, true /* constCall */, excessDataGas) } msg.SetIsFree(engine.IsServiceTransaction(msg.From(), syscall)) } @@ -229,7 +242,6 @@ func (api *PrivateDebugAPIImpl) TraceTransaction(ctx context.Context, hash commo var borTx types.Transaction borTx, _, _, _, err = rawdb.ReadBorTransaction(tx, hash) if err != nil { - stream.WriteNil() return err } @@ -323,6 +335,10 @@ func (api *PrivateDebugAPIImpl) TraceCallMany(ctx context.Context, bundles []Bun baseFee uint256.Int ) + if config == nil { + config = &tracers.TraceConfig{} + } + overrideBlockHash = make(map[uint64]common.Hash) tx, err := api.db.BeginRo(ctx) if err != nil { diff --git a/cmd/rpcdaemon/commands/txpool_api_test.go b/cmd/rpcdaemon/commands/txpool_api_test.go index 9a1b0dd7d11..8bb1e9134e8 100644 --- a/cmd/rpcdaemon/commands/txpool_api_test.go +++ b/cmd/rpcdaemon/commands/txpool_api_test.go @@ -25,9 +25,6 @@ import ( func TestTxPoolContent(t *testing.T) { m, require := stages.MockWithTxPool(t), require.New(t) - if m.HistoryV3 { - t.Skip("HistoryV3: please implement StateStream support") - } chain, err := core.GenerateChain(m.ChainConfig, m.Genesis, m.Engine, m.DB, 1, func(i int, b *core.BlockGen) { b.SetCoinbase(libcommon.Address{1}) }, false /* intermediateHashes */) diff --git a/cmd/rpcdaemon/commands/web3_api.go b/cmd/rpcdaemon/commands/web3_api.go index c35f62c632e..d66e99da5ed 100644 --- a/cmd/rpcdaemon/commands/web3_api.go +++ b/cmd/rpcdaemon/commands/web3_api.go @@ -3,7 +3,8 @@ package commands import ( "context" - "github.com/ledgerwatch/erigon/common/hexutil" + "github.com/ledgerwatch/erigon-lib/common/hexutility" + "github.com/ledgerwatch/erigon/crypto" "github.com/ledgerwatch/erigon/turbo/rpchelper" ) @@ -11,7 +12,7 @@ import ( // Web3API provides interfaces for the web3_ RPC commands type Web3API interface { ClientVersion(_ context.Context) (string, error) - Sha3(_ context.Context, input hexutil.Bytes) hexutil.Bytes + Sha3(_ context.Context, input hexutility.Bytes) hexutility.Bytes } type Web3APIImpl struct { @@ -33,6 +34,6 @@ func (api *Web3APIImpl) ClientVersion(ctx context.Context) (string, error) { } // Sha3 implements web3_sha3. Returns Keccak-256 (not the standardized SHA3-256) of the given data. -func (api *Web3APIImpl) Sha3(_ context.Context, input hexutil.Bytes) hexutil.Bytes { +func (api *Web3APIImpl) Sha3(_ context.Context, input hexutility.Bytes) hexutility.Bytes { return crypto.Keccak256(input) } diff --git a/cmd/rpcdaemon/graphql/graph/helpers.go b/cmd/rpcdaemon/graphql/graph/helpers.go index 1b780f9f2b0..64a76183d41 100644 --- a/cmd/rpcdaemon/graphql/graph/helpers.go +++ b/cmd/rpcdaemon/graphql/graph/helpers.go @@ -6,7 +6,11 @@ import ( "reflect" "strconv" + "github.com/holiman/uint256" + libcommon "github.com/ledgerwatch/erigon-lib/common" + "github.com/ledgerwatch/erigon-lib/common/hexutility" + "github.com/ledgerwatch/erigon/common/hexutil" "github.com/ledgerwatch/erigon/core/types" ) @@ -14,12 +18,16 @@ import ( func convertDataToStringP(abstractMap map[string]interface{}, field string) *string { var result string + if reflect.ValueOf(abstractMap[field]).IsZero() { + return nil + } + switch v := abstractMap[field].(type) { case int64: result = strconv.FormatInt(v, 10) case *hexutil.Big: result = v.String() - case hexutil.Bytes: + case hexutility.Bytes: result = v.String() case hexutil.Uint: result = v.String() @@ -35,10 +43,15 @@ func convertDataToStringP(abstractMap map[string]interface{}, field string) *str result = hex.EncodeToString(v.Bytes()) case types.BlockNonce: result = "0x" + strconv.FormatInt(int64(v.Uint64()), 16) + case []uint8: + result = "0x" + hex.EncodeToString(v) + case *uint256.Int: + result = v.Hex() default: - fmt.Println("string", field, abstractMap[field], reflect.TypeOf(abstractMap[field])) + fmt.Println("unhandled/string", reflect.TypeOf(abstractMap[field]), field, abstractMap[field]) result = "unhandled" } + return &result } @@ -63,7 +76,7 @@ func convertDataToIntP(abstractMap map[string]interface{}, field string) *int { case int: result = v default: - fmt.Println("int", field, abstractMap[field], reflect.TypeOf(abstractMap[field])) + fmt.Println("unhandled/int", reflect.TypeOf(abstractMap[field]), field, abstractMap[field]) result = 0 } @@ -92,8 +105,10 @@ func convertDataToUint64P(abstractMap map[string]interface{}, field string) *uin result = v.ToInt().Uint64() case int: result = abstractMap[field].(uint64) + case uint64: + result = abstractMap[field].(uint64) default: - fmt.Println("uint64", field, abstractMap[field], reflect.TypeOf(abstractMap[field])) + fmt.Println("unhandled/uint64", reflect.TypeOf(abstractMap[field]), field, abstractMap[field]) result = 0 } diff --git a/cmd/rpcdaemon/graphql/graph/schema.resolvers.go b/cmd/rpcdaemon/graphql/graph/schema.resolvers.go index db4865b21fd..061f27bc2b5 100644 --- a/cmd/rpcdaemon/graphql/graph/schema.resolvers.go +++ b/cmd/rpcdaemon/graphql/graph/schema.resolvers.go @@ -60,67 +60,79 @@ func (r *queryResolver) Block(ctx context.Context, number *string, hash *string) return nil, err } + block := &model.Block{} absBlk := res["block"] - blk := absBlk.(map[string]interface{}) - block := &model.Block{} - block.Difficulty = *convertDataToStringP(blk, "difficulty") - block.ExtraData = *convertDataToStringP(blk, "extraData") - block.GasLimit = uint64(*convertDataToUint64P(blk, "gasLimit")) - block.GasUsed = *convertDataToUint64P(blk, "gasUsed") - block.Hash = *convertDataToStringP(blk, "hash") - block.Miner = &model.Account{} - block.Miner.Address = strings.ToLower(*convertDataToStringP(blk, "miner")) - block.MixHash = *convertDataToStringP(blk, "mixHash") - block.Nonce = *convertDataToStringP(blk, "nonce") - block.Number = *convertDataToUint64P(blk, "number") - block.Ommers = []*model.Block{} - block.Parent = &model.Block{} - block.Parent.Hash = *convertDataToStringP(blk, "parentHash") - block.ReceiptsRoot = *convertDataToStringP(blk, "receiptsRoot") - block.StateRoot = *convertDataToStringP(blk, "stateRoot") - block.Timestamp = *convertDataToUint64P(blk, "timestamp") // int in the schema but Geth displays in HEX !!! - block.TransactionCount = convertDataToIntP(blk, "transactionCount") - block.TransactionsRoot = *convertDataToStringP(blk, "transactionsRoot") - block.TotalDifficulty = *convertDataToStringP(blk, "totalDifficulty") - block.Transactions = []*model.Transaction{} - - block.LogsBloom = "0x" + *convertDataToStringP(blk, "logsBloom") - block.OmmerHash = "" // OmmerHash: gointerfaces.ConvertHashToH256(header.UncleHash), - - /* - Missing Block fields to fill : - - ommerHash - */ - - absRcp := res["receipts"] - rcp := absRcp.([]map[string]interface{}) - for _, transReceipt := range rcp { - trans := &model.Transaction{} - trans.CumulativeGasUsed = convertDataToUint64P(transReceipt, "cumulativeGasUsed") - trans.EffectiveGasPrice = convertDataToStringP(transReceipt, "effectiveGasPrice") - trans.GasUsed = convertDataToUint64P(transReceipt, "gasUsed") - trans.Hash = *convertDataToStringP(transReceipt, "transactionHash") - trans.Index = convertDataToIntP(transReceipt, "transactionIndex") - trans.Status = convertDataToUint64P(transReceipt, "status") - trans.Type = convertDataToIntP(transReceipt, "type") - trans.Logs = make([]*model.Log, 0) - - trans.From = &model.Account{} - trans.From.Address = strings.ToLower(*convertDataToStringP(transReceipt, "from")) - - trans.To = &model.Account{} - trans.To.Address = strings.ToLower(*convertDataToStringP(transReceipt, "to")) - - block.Transactions = append(block.Transactions, trans) + if absBlk != nil { + blk := absBlk.(map[string]interface{}) + + block.Difficulty = *convertDataToStringP(blk, "difficulty") + block.ExtraData = *convertDataToStringP(blk, "extraData") + block.GasLimit = uint64(*convertDataToUint64P(blk, "gasLimit")) + block.GasUsed = *convertDataToUint64P(blk, "gasUsed") + block.Hash = *convertDataToStringP(blk, "hash") + block.Miner = &model.Account{} + address := convertDataToStringP(blk, "miner") + if address != nil { + block.Miner.Address = strings.ToLower(*address) + } + mixHash := convertDataToStringP(blk, "mixHash") + if mixHash != nil { + block.MixHash = *mixHash + } + blockNonce := convertDataToStringP(blk, "nonce") + if blockNonce != nil { + block.Nonce = *blockNonce + } + block.Number = *convertDataToUint64P(blk, "number") + block.Ommers = []*model.Block{} + block.Parent = &model.Block{} + block.Parent.Hash = *convertDataToStringP(blk, "parentHash") + block.ReceiptsRoot = *convertDataToStringP(blk, "receiptsRoot") + block.StateRoot = *convertDataToStringP(blk, "stateRoot") + block.Timestamp = *convertDataToUint64P(blk, "timestamp") // int in the schema but Geth displays in HEX !!! + block.TransactionCount = convertDataToIntP(blk, "transactionCount") + block.TransactionsRoot = *convertDataToStringP(blk, "transactionsRoot") + block.TotalDifficulty = *convertDataToStringP(blk, "totalDifficulty") + block.Transactions = []*model.Transaction{} + + block.LogsBloom = "0x" + *convertDataToStringP(blk, "logsBloom") + block.OmmerHash = "" // OmmerHash: gointerfaces.ConvertHashToH256(header.UncleHash), /* - Missing Transaction fields to fill : - - gasPrice - - inputData (even if geth often display "0x") - - nonce (we get 0, geth displays "0xZZZZZZZ" hex data) - - value + Missing Block fields to fill : + - ommerHash */ + + absRcp := res["receipts"] + rcp := absRcp.([]map[string]interface{}) + for _, transReceipt := range rcp { + trans := &model.Transaction{} + trans.CumulativeGasUsed = convertDataToUint64P(transReceipt, "cumulativeGasUsed") + trans.InputData = *convertDataToStringP(transReceipt, "data") + trans.EffectiveGasPrice = convertDataToStringP(transReceipt, "effectiveGasPrice") + trans.GasPrice = *convertDataToStringP(transReceipt, "gasPrice") + trans.GasUsed = convertDataToUint64P(transReceipt, "gasUsed") + trans.Hash = *convertDataToStringP(transReceipt, "transactionHash") + trans.Index = convertDataToIntP(transReceipt, "transactionIndex") + trans.Nonce = *convertDataToUint64P(transReceipt, "nonce") + trans.Status = convertDataToUint64P(transReceipt, "status") + trans.Type = convertDataToIntP(transReceipt, "type") + trans.Value = *convertDataToStringP(transReceipt, "value") + trans.Logs = make([]*model.Log, 0) + + trans.From = &model.Account{} + trans.From.Address = strings.ToLower(*convertDataToStringP(transReceipt, "from")) + + trans.To = &model.Account{} + address := convertDataToStringP(transReceipt, "to") + // To address could be nil in case of contract creation + if address != nil { + trans.To.Address = strings.ToLower(*convertDataToStringP(transReceipt, "to")) + } + + block.Transactions = append(block.Transactions, trans) + } } return block, ctx.Err() diff --git a/cmd/rpcdaemon/main.go b/cmd/rpcdaemon/main.go index e4d58612d9b..3db874b5106 100644 --- a/cmd/rpcdaemon/main.go +++ b/cmd/rpcdaemon/main.go @@ -17,8 +17,8 @@ func main() { rootCtx, rootCancel := common.RootContext() cmd.RunE = func(cmd *cobra.Command, args []string) error { ctx := cmd.Context() - logger := logging.GetLoggerCmd("rpcdaemon", cmd) - db, borDb, backend, txPool, mining, stateCache, blockReader, ff, agg, err := cli.RemoteServices(ctx, *cfg, logger, rootCancel) + logging.SetupLoggerCmd("rpcdaemon", cmd) + db, borDb, backend, txPool, mining, stateCache, blockReader, ff, agg, err := cli.RemoteServices(ctx, *cfg, log.Root(), rootCancel) if err != nil { log.Error("Could not connect to DB", "err", err) return nil diff --git a/cmd/rpcdaemon/rpcservices/eth_backend.go b/cmd/rpcdaemon/rpcservices/eth_backend.go index bbd0e4f7ac0..4fe9ba8500f 100644 --- a/cmd/rpcdaemon/rpcservices/eth_backend.go +++ b/cmd/rpcdaemon/rpcservices/eth_backend.go @@ -220,6 +220,12 @@ func (back *RemoteBackend) EngineGetPayloadBodiesByRangeV1(ctx context.Context, return back.remoteEthBackend.EngineGetPayloadBodiesByRangeV1(ctx, request) } +func (back *RemoteBackend) EngineGetBlobsBundleV1(ctx context.Context, payloadId uint64) (*types2.BlobsBundleV1, error) { + return back.remoteEthBackend.EngineGetBlobsBundleV1(ctx, &remote.EngineGetBlobsBundleRequest{ + PayloadId: payloadId, + }) +} + func (back *RemoteBackend) NodeInfo(ctx context.Context, limit uint32) ([]p2p.NodeInfo, error) { nodes, err := back.remoteEthBackend.NodeInfo(ctx, &remote.NodesInfoRequest{Limit: limit}) if err != nil { diff --git a/cmd/rpctest/rpctest/bench_tracecallmany.go b/cmd/rpctest/rpctest/bench_tracecallmany.go index 69b86136d6d..a3599af7c0c 100644 --- a/cmd/rpctest/rpctest/bench_tracecallmany.go +++ b/cmd/rpctest/rpctest/bench_tracecallmany.go @@ -8,6 +8,7 @@ import ( "time" libcommon "github.com/ledgerwatch/erigon-lib/common" + "github.com/ledgerwatch/erigon-lib/common/hexutility" "github.com/ledgerwatch/erigon/common/hexutil" ) @@ -80,7 +81,7 @@ func BenchTraceCallMany(erigonURL, oeURL string, needCompare bool, blockFrom uin gas := make([]*hexutil.Big, n) gasPrice := make([]*hexutil.Big, n) value := make([]*hexutil.Big, n) - data := make([]hexutil.Bytes, n) + data := make([]hexutility.Bytes, n) for i := 0; i < n; i++ { tx := b.Result.Transactions[i] diff --git a/cmd/rpctest/rpctest/request_generator.go b/cmd/rpctest/rpctest/request_generator.go index 4b5b9aaafb9..b5936b8980a 100644 --- a/cmd/rpctest/rpctest/request_generator.go +++ b/cmd/rpctest/rpctest/request_generator.go @@ -7,9 +7,11 @@ import ( "strings" "time" - libcommon "github.com/ledgerwatch/erigon-lib/common" "github.com/valyala/fastjson" + libcommon "github.com/ledgerwatch/erigon-lib/common" + "github.com/ledgerwatch/erigon-lib/common/hexutility" + "github.com/ledgerwatch/erigon/common/hexutil" ) @@ -97,7 +99,7 @@ func (g *RequestGenerator) getProof(bn uint64, account libcommon.Address, storag return fmt.Sprintf(template, account, strings.Join(storageStr, ","), bn, g.reqID) } -func (g *RequestGenerator) traceCall(from libcommon.Address, to *libcommon.Address, gas *hexutil.Big, gasPrice *hexutil.Big, value *hexutil.Big, data hexutil.Bytes, bn uint64) string { +func (g *RequestGenerator) traceCall(from libcommon.Address, to *libcommon.Address, gas *hexutil.Big, gasPrice *hexutil.Big, value *hexutil.Big, data hexutility.Bytes, bn uint64) string { var sb strings.Builder fmt.Fprintf(&sb, `{ "jsonrpc": "2.0", "method": "trace_call", "params": [{"from":"0x%x"`, from) if to != nil { @@ -120,7 +122,7 @@ func (g *RequestGenerator) traceCall(from libcommon.Address, to *libcommon.Addre return sb.String() } -func (g *RequestGenerator) traceCallMany(from []libcommon.Address, to []*libcommon.Address, gas []*hexutil.Big, gasPrice []*hexutil.Big, value []*hexutil.Big, data []hexutil.Bytes, bn uint64) string { +func (g *RequestGenerator) traceCallMany(from []libcommon.Address, to []*libcommon.Address, gas []*hexutil.Big, gasPrice []*hexutil.Big, value []*hexutil.Big, data []hexutility.Bytes, bn uint64) string { var sb strings.Builder fmt.Fprintf(&sb, `{ "jsonrpc": "2.0", "method": "trace_callMany", "params": [[`) for i, f := range from { @@ -149,7 +151,7 @@ func (g *RequestGenerator) traceCallMany(from []libcommon.Address, to []*libcomm return sb.String() } -func (g *RequestGenerator) debugTraceCall(from libcommon.Address, to *libcommon.Address, gas *hexutil.Big, gasPrice *hexutil.Big, value *hexutil.Big, data hexutil.Bytes, bn uint64) string { +func (g *RequestGenerator) debugTraceCall(from libcommon.Address, to *libcommon.Address, gas *hexutil.Big, gasPrice *hexutil.Big, value *hexutil.Big, data hexutility.Bytes, bn uint64) string { var sb strings.Builder fmt.Fprintf(&sb, `{ "jsonrpc": "2.0", "method": "debug_traceCall", "params": [{"from":"0x%x"`, from) if to != nil { @@ -197,7 +199,7 @@ func (g *RequestGenerator) traceReplayTransaction(hash string) string { return fmt.Sprintf(template, hash, g.reqID) } -func (g *RequestGenerator) ethCall(from libcommon.Address, to *libcommon.Address, gas *hexutil.Big, gasPrice *hexutil.Big, value *hexutil.Big, data hexutil.Bytes, bn uint64) string { +func (g *RequestGenerator) ethCall(from libcommon.Address, to *libcommon.Address, gas *hexutil.Big, gasPrice *hexutil.Big, value *hexutil.Big, data hexutility.Bytes, bn uint64) string { var sb strings.Builder fmt.Fprintf(&sb, `{ "jsonrpc": "2.0", "method": "eth_call", "params": [{"from":"0x%x"`, from) if to != nil { @@ -219,7 +221,7 @@ func (g *RequestGenerator) ethCall(from libcommon.Address, to *libcommon.Address return sb.String() } -func (g *RequestGenerator) ethCallLatest(from libcommon.Address, to *libcommon.Address, gas *hexutil.Big, gasPrice *hexutil.Big, value *hexutil.Big, data hexutil.Bytes) string { +func (g *RequestGenerator) ethCallLatest(from libcommon.Address, to *libcommon.Address, gas *hexutil.Big, gasPrice *hexutil.Big, value *hexutil.Big, data hexutility.Bytes) string { var sb strings.Builder fmt.Fprintf(&sb, `{ "jsonrpc": "2.0", "method": "eth_call", "params": [{"from":"0x%x"`, from) if to != nil { diff --git a/cmd/rpctest/rpctest/type.go b/cmd/rpctest/rpctest/type.go index 64af871d364..134bbbd1b7b 100644 --- a/cmd/rpctest/rpctest/type.go +++ b/cmd/rpctest/rpctest/type.go @@ -4,6 +4,7 @@ import ( "fmt" libcommon "github.com/ledgerwatch/erigon-lib/common" + "github.com/ledgerwatch/erigon-lib/common/hexutility" "github.com/ledgerwatch/erigon/common/hexutil" "github.com/ledgerwatch/erigon/core/state" @@ -39,7 +40,7 @@ type EthTransaction struct { Hash string `json:"hash"` Gas hexutil.Big `json:"gas"` GasPrice hexutil.Big `json:"gasPrice"` - Input hexutil.Bytes `json:"input"` + Input hexutility.Bytes `json:"input"` Value hexutil.Big `json:"value"` } @@ -96,7 +97,7 @@ type TraceCall struct { } type TraceCallResult struct { - Output hexutil.Bytes `json:"output"` + Output hexutility.Bytes `json:"output"` Trace []TraceCallTrace `json:"trace"` StateDiff map[libcommon.Address]TraceCallStateDiff `json:"stateDiff"` } @@ -119,16 +120,16 @@ type TraceCallAction struct { Gas hexutil.Big `json:"gas"` Value hexutil.Big `json:"value"` Balance hexutil.Big `json:"balance"` - Init hexutil.Bytes `json:"init"` - Input hexutil.Bytes `json:"input"` + Init hexutility.Bytes `json:"init"` + Input hexutility.Bytes `json:"input"` CallType string `json:"callType"` } type TraceCallTraceResult struct { GasUsed hexutil.Big `json:"gasUsed"` - Output hexutil.Bytes `json:"output"` + Output hexutility.Bytes `json:"output"` Address libcommon.Address `json:"address"` - Code hexutil.Bytes `json:"code"` + Code hexutility.Bytes `json:"code"` } type TraceCallStateDiff struct { @@ -191,7 +192,7 @@ type Log struct { //nolint // list of topics provided by the contract. Topics []libcommon.Hash `json:"topics" gencodec:"required"` // supplied by the contract, usually ABI-encoded - Data hexutil.Bytes `json:"data" gencodec:"required"` + Data hexutility.Bytes `json:"data" gencodec:"required"` // Derived fields. These fields are filled in by the node // but not secured by consensus. @@ -213,11 +214,11 @@ type Log struct { //nolint type Receipt struct { // Consensus fields - PostState libcommon.Hash `json:"root"` - Status hexutil.Uint64 `json:"status"` - CumulativeGasUsed hexutil.Uint64 `json:"cumulativeGasUsed" gencodec:"required"` - Bloom hexutil.Bytes `json:"logsBloom" gencodec:"required"` - Logs []*Log `json:"logs" gencodec:"required"` + PostState libcommon.Hash `json:"root"` + Status hexutil.Uint64 `json:"status"` + CumulativeGasUsed hexutil.Uint64 `json:"cumulativeGasUsed" gencodec:"required"` + Bloom hexutility.Bytes `json:"logsBloom" gencodec:"required"` + Logs []*Log `json:"logs" gencodec:"required"` // Implementation fields (don't reorder!) TxHash libcommon.Hash `json:"transactionHash" gencodec:"required"` @@ -263,5 +264,5 @@ type StorageResult struct { type ParityListStorageKeysResult struct { CommonResponse - Result []hexutil.Bytes `json:"result"` + Result []hexutility.Bytes `json:"result"` } diff --git a/cmd/sentinel/cli/cliSettings.go b/cmd/sentinel/cli/cliSettings.go index 177f68a178b..2dd22d7140a 100644 --- a/cmd/sentinel/cli/cliSettings.go +++ b/cmd/sentinel/cli/cliSettings.go @@ -2,13 +2,14 @@ package cli import ( "fmt" - "strings" + "github.com/ledgerwatch/erigon/cmd/utils" "github.com/urfave/cli/v2" "github.com/ledgerwatch/erigon/cl/clparams" "github.com/ledgerwatch/erigon/cmd/erigon-cl/core/rawdb" "github.com/ledgerwatch/erigon/cmd/sentinel/cli/flags" + "github.com/ledgerwatch/log/v3" ) type ConsensusClientCliCfg struct { @@ -60,6 +61,9 @@ func SetupConsensusClientCfg(ctx *cli.Context) (*ConsensusClientCliCfg, error) { cfg.Addr = ctx.String(flags.SentinelDiscoveryAddr.Name) cfg.LogLvl = ctx.Uint(flags.Verbosity.Name) + if cfg.LogLvl == uint(log.LvlInfo) { + cfg.LogLvl = uint(log.LvlDebug) + } cfg.NoDiscovery = ctx.Bool(flags.NoDiscovery.Name) if ctx.String(flags.CheckpointSyncUrlFlag.Name) != "" { cfg.CheckpointUri = ctx.String(flags.CheckpointSyncUrlFlag.Name) @@ -71,10 +75,10 @@ func SetupConsensusClientCfg(ctx *cli.Context) (*ConsensusClientCliCfg, error) { cfg.BeaconDataCfg = rawdb.BeaconDataConfigurations[ctx.String(flags.BeaconDBModeFlag.Name)] // Process bootnodes if ctx.String(flags.BootnodesFlag.Name) != "" { - cfg.NetworkCfg.BootNodes = strings.Split(ctx.String(flags.BootnodesFlag.Name), ",") + cfg.NetworkCfg.BootNodes = utils.SplitAndTrim(ctx.String(flags.BootnodesFlag.Name)) } if ctx.String(flags.SentinelStaticPeersFlag.Name) != "" { - cfg.NetworkCfg.StaticPeers = strings.Split(ctx.String(flags.SentinelStaticPeersFlag.Name), ",") + cfg.NetworkCfg.StaticPeers = utils.SplitAndTrim(ctx.String(flags.SentinelStaticPeersFlag.Name)) } return cfg, nil } diff --git a/cmd/sentinel/main.go b/cmd/sentinel/main.go index 601a00be2bd..d06a4d349ff 100644 --- a/cmd/sentinel/main.go +++ b/cmd/sentinel/main.go @@ -15,26 +15,16 @@ package main import ( "context" - "encoding/hex" "fmt" "os" - "time" "github.com/ledgerwatch/log/v3" "github.com/urfave/cli/v2" - "go.uber.org/zap/buffer" - sentinelrpc "github.com/ledgerwatch/erigon-lib/gointerfaces/sentinel" - "github.com/ledgerwatch/erigon/cl/cltypes" - "github.com/ledgerwatch/erigon/cl/cltypes/ssz_utils" - "github.com/ledgerwatch/erigon/cl/fork" lcCli "github.com/ledgerwatch/erigon/cmd/sentinel/cli" "github.com/ledgerwatch/erigon/cmd/sentinel/cli/flags" "github.com/ledgerwatch/erigon/cmd/sentinel/sentinel" - "github.com/ledgerwatch/erigon/cmd/sentinel/sentinel/communication/ssz_snappy" - "github.com/ledgerwatch/erigon/cmd/sentinel/sentinel/handshake" "github.com/ledgerwatch/erigon/cmd/sentinel/sentinel/service" - "github.com/ledgerwatch/erigon/common" sentinelapp "github.com/ledgerwatch/erigon/turbo/app" ) @@ -49,34 +39,8 @@ func main() { } } -func check(err error) { - if err != nil { - panic(err) - } -} - -func constructBodyFreeRequest(t string) *sentinelrpc.RequestData { - return &sentinelrpc.RequestData{ - Topic: t, - } -} - -func constructRequest(t string, reqBody ssz_utils.EncodableSSZ) (*sentinelrpc.RequestData, error) { - var buffer buffer.Buffer - if err := ssz_snappy.EncodeAndWrite(&buffer, reqBody); err != nil { - return nil, fmt.Errorf("unable to encode request body: %v", err) - } - - data := common.CopyBytes(buffer.Bytes()) - return &sentinelrpc.RequestData{ - Data: data, - Topic: t, - }, nil -} - func runSentinelNode(cliCtx *cli.Context) error { cfg, _ := lcCli.SetupConsensusClientCfg(cliCtx) - //ctx := context.Background() log.Root().SetHandler(log.LvlFilterHandler(log.Lvl(cfg.LogLvl), log.StderrHandler)) log.Info("[Sentinel] running sentinel with configuration", "cfg", cfg) @@ -88,163 +52,13 @@ func runSentinelNode(cliCtx *cli.Context) error { NetworkConfig: cfg.NetworkCfg, BeaconConfig: cfg.BeaconCfg, NoDiscovery: cfg.NoDiscovery, - }, nil, &service.ServerConfig{Network: cfg.ServerProtocol, Addr: cfg.ServerAddr}, nil, nil, handshake.NoRule) + }, nil, &service.ServerConfig{Network: cfg.ServerProtocol, Addr: cfg.ServerAddr}, nil, nil) if err != nil { log.Error("[Sentinel] Could not start sentinel", "err", err) return err } log.Info("[Sentinel] Sentinel started", "addr", cfg.ServerAddr) - digest, err := fork.ComputeForkDigest(cfg.BeaconCfg, cfg.GenesisCfg) - if err != nil { - log.Error("[Sentinel] Could not compute fork digeest", "err", err) - return err - } - log.Info("[Sentinel] Fork digest", "data", digest) - - log.Info("[Sentinel] Sending test request") - /* - sendRequest(ctx, s, constructBodyFreeRequest(handlers.LightClientFinalityUpdateV1)) - sendRequest(ctx, s, constructBodyFreeRequest(handlers.MetadataProtocolV1)) - sendRequest(ctx, s, constructBodyFreeRequest(handlers.MetadataProtocolV2)) - sendRequest(ctx, s, constructBodyFreeRequest(handlers.LightClientOptimisticUpdateV1)) - - lcUpdateReq := &cltypes.LightClientUpdatesByRangeRequest{ - Period: 604, - Count: 1, - } - - blocksByRangeReq := &cltypes.BeaconBlocksByRangeRequest{ - StartSlot: 5000005, // arbitrary slot (currently at ~5030000) - Count: 3, - Step: 1, // deprecated, must be set to 1. - } - - roots := make([][32]byte, 3) - rawRoot1, err := hex.DecodeString("57dd8e0ee7ed614283fbf80ca19229752839d4a4e232148efd128e85edee9b12") - check(err) - rawRoot2, err := hex.DecodeString("1d527f21e17897198752838431821558d1b9864654bcaf476232da55458ed5ce") - check(err) - rawRoot3, err := hex.DecodeString("830eab2e3de70cc7ebc80b6c950ebb2a7946d8a6e3bb653f8b6dafd6a402d49b") - check(err) - - copy(roots[0][:], rawRoot1) - copy(roots[1][:], rawRoot2) - copy(roots[2][:], rawRoot3) - - var blocksByRootReq cltypes.BeaconBlocksByRootRequest = roots - - // Getting fork digest into bytes array. - forkDigest := "4a26c58b" - fdSlice, err := hex.DecodeString(forkDigest) - check(err) - var fdArr [4]byte - copy(fdArr[:], fdSlice) - - // Getting CP block root into bytes array. - cpRootRaw := "60ee0f7170ed4984e4a7e735dff36bce28d2fb03a3f698287b73415d70fe7355" - cpRootSlice, err := hex.DecodeString(cpRootRaw) - check(err) - var cpRootArr [32]byte - copy(cpRootArr[:], cpRootSlice) - - // Getting head block root into bytes array. - headRootRaw := "b52fc95e02471414451e6cf465709f53f65145fc5efbb18817252c33e301fa3a" - headRootSlice, err := hex.DecodeString(headRootRaw) - check(err) - var headRootArr [32]byte - copy(headRootArr[:], headRootSlice) - - // USING: https://beaconcha.in/slot/5101760 as the checkpoint & current block. - statusReq := &cltypes.Status{ - ForkDigest: fdArr, - FinalizedRoot: cpRootArr, - FinalizedEpoch: 160285, - HeadRoot: headRootArr, - HeadSlot: 5129184, - } - - blocksByRangeReq := &cltypes.BeaconBlocksByRangeRequest{ - StartSlot: 5142800, - Count: 2, - Step: 1, // deprecated, must be set to 1. - } - req, err := constructRequest(handlers.BeaconBlocksByRangeProtocolV2, blocksByRangeReq) - if err != nil { - log.Error("[Sentinel] could not construct request", "err", err) - } - sendRequest(ctx, s, req) - */ - /*roots := make([][32]byte, 1) - rawRoot1, err := hex.DecodeString("cc85056af7f6e3e4835436cb12a09a9d56e0aac15d08436af82dbe0cd7ae60e0") - check(err) - - copy(roots[0][:], rawRoot1) - - var blocksByRootReq cltypes.BeaconBlocksByRootRequest = roots - req, err := constructRequest(communication.BeaconBlocksByRootProtocolV2, &blocksByRootReq) - if err != nil { - log.Error("[Sentinel] could not construct request", "err", err) - return err - } - sendRequest(ctx, s, req)*/ + <-context.Background().Done() return nil } - -func debugGossip(ctx context.Context, s sentinelrpc.SentinelClient) { - subscription, err := s.SubscribeGossip(ctx, &sentinelrpc.EmptyMessage{}) - if err != nil { - log.Error("[Sentinel] Could not start sentinel", "err", err) - return - } - for { - data, err := subscription.Recv() - if err != nil { - return - } - if data.Type != sentinelrpc.GossipType_AggregateAndProofGossipType { - continue - } - block := &cltypes.SignedAggregateAndProof{} - if err := block.DecodeSSZ(data.Data); err != nil { - log.Error("[Sentinel] Error", "err", err) - continue - } - log.Info("[Sentinel] Received", "msg", block) - } -} - -// Debug function to recieve test packets on the req/resp domain. -func sendRequest(ctx context.Context, s sentinelrpc.SentinelClient, req *sentinelrpc.RequestData) { - newReqTicker := time.NewTicker(100 * time.Millisecond) - for { - select { - case <-ctx.Done(): - case <-newReqTicker.C: - go func() { - log.Info("[Sentinel] Sending request", "data", req) - message, err := s.SendRequest(ctx, req) - if err != nil { - log.Error("[Sentinel] Error returned", "err", err) - return - } - if message.Error { - log.Error("[Sentinel] received error", "err", string(message.Data)) - return - } - - log.Info("[Sentinel] Non-error response received", "data", message.Data) - f, err := os.Create("out") - if err != nil { - panic(fmt.Sprintf("unable to open file: %v\n", err)) - } - _, err = f.WriteString(hex.EncodeToString(message.Data)) - if err != nil { - panic(fmt.Sprintf("unable to write to file: %v\n", err)) - } - log.Info("[Sentinel] Hex representation", "data", hex.EncodeToString(message.Data)) - f.Close() - }() - } - } -} diff --git a/cmd/sentinel/sentinel/discovery.go b/cmd/sentinel/sentinel/discovery.go index 94efb11b900..51d9f355c9a 100644 --- a/cmd/sentinel/sentinel/discovery.go +++ b/cmd/sentinel/sentinel/discovery.go @@ -78,8 +78,8 @@ func (s *Sentinel) listenForPeers() { iterator := s.listener.RandomNodes() defer iterator.Close() for { - - if s.ctx.Err() != nil { + if err := s.ctx.Err(); err != nil { + log.Debug("Stopping Ethereum 2.0 peer discovery", "err", err) break } if s.HasTooManyPeers() { @@ -89,7 +89,7 @@ func (s *Sentinel) listenForPeers() { } exists := iterator.Next() if !exists { - break + continue } node := iterator.Node() peerInfo, _, err := convertToAddrInfo(node) diff --git a/cmd/sentinel/sentinel/handlers/blocks.go b/cmd/sentinel/sentinel/handlers/blocks.go index 107a7477a7b..07525bd1d4f 100644 --- a/cmd/sentinel/sentinel/handlers/blocks.go +++ b/cmd/sentinel/sentinel/handlers/blocks.go @@ -20,8 +20,12 @@ import ( func (c *ConsensusHandlers) blocksByRangeHandler(stream network.Stream) { log.Trace("Got block by range handler call") + stream.Write([]byte{0x3}) + stream.Close() } func (c *ConsensusHandlers) beaconBlocksByRootHandler(stream network.Stream) { log.Trace("Got beacon block by root handler call") + stream.Write([]byte{0x3}) + stream.Close() } diff --git a/cmd/sentinel/sentinel/handlers/handlers.go b/cmd/sentinel/sentinel/handlers/handlers.go index 738636ba401..c0b12a92dd8 100644 --- a/cmd/sentinel/sentinel/handlers/handlers.go +++ b/cmd/sentinel/sentinel/handlers/handlers.go @@ -62,8 +62,6 @@ func NewConsensusHandlers(ctx context.Context, db kv.RoDB, host host.Host, protocol.ID(communication.MetadataProtocolV2): c.metadataV2Handler, protocol.ID(communication.BeaconBlocksByRangeProtocolV1): c.blocksByRangeHandler, protocol.ID(communication.BeaconBlocksByRootProtocolV1): c.beaconBlocksByRootHandler, - protocol.ID(communication.LightClientFinalityUpdateV1): c.lightClientFinalityUpdateHandler, - protocol.ID(communication.LightClientOptimisticUpdateV1): c.lightClientOptimisticUpdateHandler, } return c } diff --git a/cmd/sentinel/sentinel/handshake/handshake.go b/cmd/sentinel/sentinel/handshake/handshake.go index 96a134ab7e7..8d9f9f61c52 100644 --- a/cmd/sentinel/sentinel/handshake/handshake.go +++ b/cmd/sentinel/sentinel/handshake/handshake.go @@ -7,6 +7,7 @@ import ( "github.com/ledgerwatch/erigon/cl/clparams" "github.com/ledgerwatch/erigon/cl/cltypes" + "github.com/ledgerwatch/erigon/cl/fork" "github.com/ledgerwatch/erigon/cmd/sentinel/sentinel/communication" "github.com/ledgerwatch/erigon/cmd/sentinel/sentinel/communication/ssz_snappy" "github.com/ledgerwatch/erigon/common" @@ -22,7 +23,6 @@ type HandShaker struct { // Status object to send over. status *cltypes.Status // Contains status object for handshakes set bool - rule RuleFunc // Method that determine if peer is worth connecting to or not. host host.Host genesisConfig *clparams.GenesisConfig beaconConfig *clparams.BeaconChainConfig @@ -30,10 +30,9 @@ type HandShaker struct { mu sync.Mutex } -func New(ctx context.Context, genesisConfig *clparams.GenesisConfig, beaconConfig *clparams.BeaconChainConfig, host host.Host, rule RuleFunc) *HandShaker { +func New(ctx context.Context, genesisConfig *clparams.GenesisConfig, beaconConfig *clparams.BeaconChainConfig, host host.Host) *HandShaker { return &HandShaker{ ctx: ctx, - rule: rule, host: host, genesisConfig: genesisConfig, beaconConfig: beaconConfig, @@ -86,5 +85,9 @@ func (h *HandShaker) ValidatePeer(id peer.ID) bool { if err := ssz_snappy.DecodeAndReadNoForkDigest(bytes.NewReader(response), responseStatus, clparams.Phase0Version); err != nil { return false } - return h.rule(responseStatus, status, h.genesisConfig, h.beaconConfig) + forkDigest, err := fork.ComputeForkDigest(h.beaconConfig, h.genesisConfig) + if err != nil { + return false + } + return responseStatus.ForkDigest == forkDigest } diff --git a/cmd/sentinel/sentinel/handshake/rules.go b/cmd/sentinel/sentinel/handshake/rules.go deleted file mode 100644 index 6a385f041df..00000000000 --- a/cmd/sentinel/sentinel/handshake/rules.go +++ /dev/null @@ -1,44 +0,0 @@ -package handshake - -import ( - "github.com/ledgerwatch/erigon/cl/clparams" - "github.com/ledgerwatch/erigon/cl/cltypes" - "github.com/ledgerwatch/erigon/cl/fork" - "github.com/ledgerwatch/erigon/cl/utils" -) - -type RuleFunc func( - status *cltypes.Status, - ourStatus *cltypes.Status, - genesisConfig *clparams.GenesisConfig, - beaconConfig *clparams.BeaconChainConfig, -) bool - -// NoRule no rules in place. -func NoRule(status *cltypes.Status, ourStatus *cltypes.Status, genesisConfig *clparams.GenesisConfig, beaconConfig *clparams.BeaconChainConfig) bool { - return true -} - -// FullClientRule only checks against fork digest. -func FullClientRule(status *cltypes.Status, ourStatus *cltypes.Status, genesisConfig *clparams.GenesisConfig, beaconConfig *clparams.BeaconChainConfig) bool { - forkDigest, err := fork.ComputeForkDigest(beaconConfig, genesisConfig) - if err != nil { - return false - } - - accept := status.ForkDigest == forkDigest - if ourStatus.HeadSlot != utils.GetCurrentSlot(genesisConfig.GenesisTime, beaconConfig.SecondsPerSlot) { - accept = accept && ourStatus.HeadSlot < status.HeadSlot - } - return accept -} - -// LightClientRule checks against fork digest and whether the peer head is on chain tip. -func LightClientRule(status *cltypes.Status, ourStatus *cltypes.Status, genesisConfig *clparams.GenesisConfig, beaconConfig *clparams.BeaconChainConfig) bool { - forkDigest, err := fork.ComputeForkDigest(beaconConfig, genesisConfig) - if err != nil { - return false - } - return status.ForkDigest == forkDigest && - status.HeadSlot == utils.GetCurrentSlot(genesisConfig.GenesisTime, beaconConfig.SecondsPerSlot) -} diff --git a/cmd/sentinel/sentinel/msg_id.go b/cmd/sentinel/sentinel/msg_id.go new file mode 100644 index 00000000000..bf584681d1f --- /dev/null +++ b/cmd/sentinel/sentinel/msg_id.go @@ -0,0 +1,60 @@ +package sentinel + +import ( + "github.com/ledgerwatch/erigon/cl/utils" + pubsubpb "github.com/libp2p/go-libp2p-pubsub/pb" +) + +// Spec:BeaconConfig() +// The derivation of the message-id has changed starting with Altair to incorporate the message topic along with the message data. +// These are fields of the Message Protobuf, and interpreted as empty byte strings if missing. The message-id MUST be the following +// 20 byte value computed from the message: +// +// If message.data has a valid snappy decompression, set message-id to the first 20 bytes of the SHA256 hash of the concatenation of +// the following data: MESSAGE_DOMAIN_VALID_SNAPPY, the length of the topic byte string (encoded as little-endian uint64), the topic +// byte string, and the snappy decompressed message data: i.e. SHA256(MESSAGE_DOMAIN_VALID_SNAPPY + uint_to_bytes(uint64(len(message.topic))) +// + message.topic + snappy_decompress(message.data))[:20]. Otherwise, set message-id to the first 20 bytes of the SHA256 hash of the concatenation +// of the following data: MESSAGE_DOMAIN_INVALID_SNAPPY, the length of the topic byte string (encoded as little-endian uint64), +// the topic byte string, and the raw message data: i.e. SHA256(MESSAGE_DOMAIN_INVALID_SNAPPY + uint_to_bytes(uint64(len(message.topic))) + message.topic + message.data)[:20]. +func (s *Sentinel) msgId(pmsg *pubsubpb.Message) string { + topic := *pmsg.Topic + topicLen := len(topic) + topicLenBytes := utils.Uint64ToLE(uint64(topicLen)) // topicLen cannot be negative + + // beyond Bellatrix epoch, allow 10 Mib gossip data size + gossipPubSubSize := s.cfg.NetworkConfig.GossipMaxSizeBellatrix + + decodedData, err := utils.DecompressSnappy(pmsg.Data) + if err != nil || uint64(len(decodedData)) > gossipPubSubSize { + totalLength := + len(s.cfg.NetworkConfig.MessageDomainValidSnappy) + + len(topicLenBytes) + + topicLen + + len(pmsg.Data) + if uint64(totalLength) > gossipPubSubSize { + // this should never happen + msg := make([]byte, 20) + copy(msg, "invalid") + return string(msg) + } + combinedData := make([]byte, 0, totalLength) + combinedData = append(combinedData, s.cfg.NetworkConfig.MessageDomainInvalidSnappy[:]...) + combinedData = append(combinedData, topicLenBytes...) + combinedData = append(combinedData, topic...) + combinedData = append(combinedData, pmsg.Data...) + h := utils.Keccak256(combinedData) + return string(h[:20]) + } + totalLength := len(s.cfg.NetworkConfig.MessageDomainValidSnappy) + + len(topicLenBytes) + + topicLen + + len(decodedData) + + combinedData := make([]byte, 0, totalLength) + combinedData = append(combinedData, s.cfg.NetworkConfig.MessageDomainValidSnappy[:]...) + combinedData = append(combinedData, topicLenBytes...) + combinedData = append(combinedData, topic...) + combinedData = append(combinedData, decodedData...) + h := utils.Keccak256(combinedData) + return string(h[:20]) +} diff --git a/cmd/sentinel/sentinel/msg_id_test.go b/cmd/sentinel/sentinel/msg_id_test.go new file mode 100644 index 00000000000..d8313aeb8cb --- /dev/null +++ b/cmd/sentinel/sentinel/msg_id_test.go @@ -0,0 +1,50 @@ +package sentinel + +import ( + "context" + "fmt" + "testing" + + "github.com/golang/snappy" + "github.com/ledgerwatch/erigon/cl/clparams" + "github.com/ledgerwatch/erigon/cl/utils" + pubsubpb "github.com/libp2p/go-libp2p-pubsub/pb" + "github.com/stretchr/testify/require" +) + +func TestMsgID(t *testing.T) { + g := clparams.GenesisConfigs[clparams.MainnetNetwork] + n := clparams.NetworkConfigs[clparams.MainnetNetwork] + s := &Sentinel{ + ctx: context.TODO(), + cfg: &SentinelConfig{ + BeaconConfig: &clparams.MainnetBeaconConfig, + GenesisConfig: &g, + NetworkConfig: &n, + }, + } + d := [4]byte{108, 122, 33, 65} + tpc := fmt.Sprintf("/eth2/%x/beacon_block", d) + topicLen := uint64(len(tpc)) + topicLenBytes := utils.Uint64ToLE(topicLen) + invalidSnappy := [32]byte{'J', 'U', 'N', 'K'} + pMsg := &pubsubpb.Message{Data: invalidSnappy[:], Topic: &tpc} + // Create object to hash + combinedObj := append(n.MessageDomainInvalidSnappy[:], topicLenBytes...) + combinedObj = append(combinedObj, tpc...) + combinedObj = append(combinedObj, pMsg.Data...) + hashedData := utils.Keccak256(combinedObj) + msgID := string(hashedData[:20]) + require.Equal(t, msgID, s.msgId(pMsg), "Got incorrect msg id") + + validObj := [32]byte{'v', 'a', 'l', 'i', 'd'} + enc := snappy.Encode(nil, validObj[:]) + nMsg := &pubsubpb.Message{Data: enc, Topic: &tpc} + // Create object to hash + combinedObj = append(n.MessageDomainValidSnappy[:], topicLenBytes...) + combinedObj = append(combinedObj, tpc...) + combinedObj = append(combinedObj, validObj[:]...) + hashedData = utils.Keccak256(combinedObj) + msgID = string(hashedData[:20]) + require.Equal(t, msgID, s.msgId(nMsg), "Got incorrect msg id") +} diff --git a/cmd/sentinel/sentinel/peers/peers.go b/cmd/sentinel/sentinel/peers/peers.go index 413bc735430..3c040f8782e 100644 --- a/cmd/sentinel/sentinel/peers/peers.go +++ b/cmd/sentinel/sentinel/peers/peers.go @@ -17,14 +17,14 @@ import ( "sync" "time" - lru2 "github.com/hashicorp/golang-lru/v2" + lru "github.com/hashicorp/golang-lru/v2" "github.com/ledgerwatch/log/v3" "github.com/libp2p/go-libp2p/core/host" "github.com/libp2p/go-libp2p/core/peer" ) const ( - maxBadPeers = 50 + maxBadPeers = 50000 maxPeerRecordSize = 1000 DefaultMaxPeers = 33 MaxBadResponses = 50 @@ -40,26 +40,26 @@ type Peer struct { } type Peers struct { - badPeers *lru2.Cache[peer.ID, int] // Keep track of bad peers - penalties *lru2.Cache[peer.ID, int] // Keep track on how many penalties a peer accumulated, PeerId => penalties - peerRecord *lru2.Cache[peer.ID, Peer] // Keep track of our peer statuses + badPeers *lru.Cache[peer.ID, int] // Keep track of bad peers + penalties *lru.Cache[peer.ID, int] // Keep track on how many penalties a peer accumulated, PeerId => penalties + peerRecord *lru.Cache[peer.ID, Peer] // Keep track of our peer statuses host host.Host mu sync.Mutex } func New(host host.Host) *Peers { - badPeers, err := lru2.New[peer.ID, int](maxBadPeers) + badPeers, err := lru.New[peer.ID, int](maxBadPeers) if err != nil { panic(err) } - penalties, err := lru2.New[peer.ID, int](maxBadPeers) + penalties, err := lru.New[peer.ID, int](maxBadPeers) if err != nil { panic(err) } - peerRecord, err := lru2.New[peer.ID, Peer](maxPeerRecordSize) + peerRecord, err := lru.New[peer.ID, Peer](maxPeerRecordSize) if err != nil { panic(err) } @@ -87,7 +87,6 @@ func (p *Peers) Penalize(pid peer.ID) { // Drop peer and delete the map element. if penalties > MaxBadResponses { p.DisconnectPeer(pid) - p.penalties.Remove(pid) } } @@ -113,6 +112,7 @@ func (p *Peers) DisconnectPeer(pid peer.ID) { log.Trace("[Sentinel Peers] disconnecting from peer", "peer-id", pid) p.host.Peerstore().RemovePeer(pid) p.host.Network().ClosePeer(pid) + p.penalties.Remove(pid) } // PeerDoRequest signals that the peer is doing a request. diff --git a/cmd/sentinel/sentinel/pubsub.go b/cmd/sentinel/sentinel/pubsub.go index 1dc805a0823..ddd0b51af2c 100644 --- a/cmd/sentinel/sentinel/pubsub.go +++ b/cmd/sentinel/sentinel/pubsub.go @@ -16,40 +16,14 @@ package sentinel import ( "context" "fmt" - "strconv" "strings" "sync" - "time" "github.com/ledgerwatch/erigon/cl/fork" "github.com/ledgerwatch/log/v3" pubsub "github.com/libp2p/go-libp2p-pubsub" ) -const ( - // overlay parameters - gossipSubD = 8 // topic stable mesh target count - gossipSubDlo = 6 // topic stable mesh low watermark - gossipSubDhi = 12 // topic stable mesh high watermark - - // gossip parameters - gossipSubMcacheLen = 6 // number of windows to retain full messages in cache for `IWANT` responses - gossipSubMcacheGossip = 3 // number of windows to gossip about - gossipSubSeenTTL = 550 // number of heartbeat intervals to retain message IDs - - // fanout ttl - gossipSubFanoutTTL = 60000000000 // TTL for fanout maps for topics we are not subscribed to but have published to, in nano seconds - - // heartbeat interval - gossipSubHeartbeatInterval = 700 * time.Millisecond // frequency of heartbeat, milliseconds - - // misc - rSubD = 8 // random gossip target -) - -// Specifies the prefix for any pubsub topic. -const gossipTopicPrefix = "/eth2/" -const blockSubnetTopicFormat = "/eth2/%x/beacon_block" const SSZSnappyCodec = "ssz_snappy" type TopicName string @@ -119,42 +93,12 @@ func (s *GossipManager) Recv() <-chan *pubsub.Message { return s.ch } -// closes a specific topic -func (s *GossipManager) CloseTopic(topic string) { - s.mu.Lock() - defer s.mu.Unlock() - if val, ok := s.subscriptions[topic]; ok { - val.Close() - delete(s.subscriptions, topic) - } -} - -// reset'em -func (s *GossipManager) Reset() { - s.mu.Lock() - defer s.mu.Unlock() - for _, val := range s.subscriptions { - val.Close() // Close all. - } - s.subscriptions = map[string]*GossipSubscription{} -} - -// get a specific topic -func (s *GossipManager) GetSubscription(topic string) (*GossipSubscription, bool) { - s.mu.Lock() - defer s.mu.Unlock() - if val, ok := s.subscriptions[topic]; ok { - return val, true - } - return nil, false -} - func (s *GossipManager) GetMatchingSubscription(match string) *GossipSubscription { s.mu.Lock() defer s.mu.Unlock() var sub *GossipSubscription for topic, currSub := range s.subscriptions { - if strings.Contains(topic, string(BeaconBlockTopic)) { + if strings.Contains(topic, match) { sub = currSub } } @@ -167,79 +111,43 @@ func (s *GossipManager) AddSubscription(topic string, sub *GossipSubscription) { s.subscriptions[topic] = sub } -// starts listening to a specific topic (forwarding its messages to the gossip manager channel) -func (s *GossipManager) ListenTopic(topic string) error { - s.mu.Lock() - defer s.mu.Unlock() - if val, ok := s.subscriptions[topic]; ok { - return val.Listen() - } - return nil -} - -// closes the gossip manager -func (s *GossipManager) Close() { - s.mu.Lock() - defer s.mu.Unlock() - for _, val := range s.subscriptions { - val.Close() - } - close(s.ch) -} - -func (s *GossipManager) String() string { +func (s *GossipManager) unsubscribe(topic string) { s.mu.Lock() defer s.mu.Unlock() - sb := strings.Builder{} - sb.Grow(len(s.subscriptions) * 4) - - for _, v := range s.subscriptions { - sb.Write([]byte(v.topic.String())) - sb.WriteString("=") - sb.WriteString(strconv.Itoa(len(v.topic.ListPeers()))) - sb.WriteString(" ") - } - return sb.String() -} - -func (s *Sentinel) RestartTopics() { - // Reset all topics - s.subManager.Reset() - for _, topic := range s.gossipTopics { - s.SubscribeGossip(topic) + if _, ok := s.subscriptions[topic]; !ok { + return } + s.subscriptions[topic].Close() + delete(s.subscriptions, topic) } func (s *Sentinel) SubscribeGossip(topic GossipTopic, opts ...pubsub.TopicOpt) (sub *GossipSubscription, err error) { + digest, err := fork.ComputeForkDigest(s.cfg.BeaconConfig, s.cfg.GenesisConfig) + if err != nil { + log.Error("[Gossip] Failed to calculate fork choice", "err", err) + } sub = &GossipSubscription{ gossip_topic: topic, ch: s.subManager.ch, host: s.host.ID(), ctx: s.ctx, } - path := s.getTopic(topic) + path := fmt.Sprintf("/eth2/%x/%s/%s", digest, topic.Name, topic.CodecStr) sub.topic, err = s.pubsub.Join(path, opts...) if err != nil { return nil, fmt.Errorf("failed to join topic %s, err=%w", path, err) } s.subManager.AddSubscription(path, sub) - for _, t := range s.gossipTopics { - if t.CodecStr == topic.CodecStr { - return sub, nil - } - } - s.gossipTopics = append(s.gossipTopics, topic) - return sub, nil -} -func (s *Sentinel) LogTopicPeers() { - log.Info("[Gossip] Network Update", "topic peers", s.subManager.String()) + return sub, nil } -func (s *Sentinel) getTopic(topic GossipTopic) string { - o, err := fork.ComputeForkDigest(s.cfg.BeaconConfig, s.cfg.GenesisConfig) +func (s *Sentinel) Unsubscribe(topic GossipTopic, opts ...pubsub.TopicOpt) (err error) { + digest, err := fork.ComputeForkDigest(s.cfg.BeaconConfig, s.cfg.GenesisConfig) if err != nil { log.Error("[Gossip] Failed to calculate fork choice", "err", err) } - return fmt.Sprintf("/eth2/%x/%s/%s", o, topic.Name, topic.CodecStr) + s.subManager.unsubscribe(fmt.Sprintf("/eth2/%x/%s/%s", digest, topic.Name, topic.CodecStr)) + + return nil } diff --git a/cmd/sentinel/sentinel/request.go b/cmd/sentinel/sentinel/request.go index 18d13b2bc78..1b9377dfa1f 100644 --- a/cmd/sentinel/sentinel/request.go +++ b/cmd/sentinel/sentinel/request.go @@ -15,7 +15,6 @@ package sentinel import ( "fmt" - "strings" "github.com/ledgerwatch/erigon/cmd/sentinel/sentinel/communication" "github.com/libp2p/go-libp2p/core/peer" @@ -43,11 +42,9 @@ func (s *Sentinel) RandomPeer(topic string) (peer.ID, error) { pid peer.ID err error ) - if strings.Contains(topic, "light_client") && !strings.Contains(topic, "bootstrap") { - pid, err = connectToRandomPeer(s, string(LightClientFinalityUpdateTopic)) - } else { - pid, err = connectToRandomPeer(s, string(BeaconBlockTopic)) - } + + pid, err = connectToRandomPeer(s, string(BeaconBlockTopic)) + if err != nil { return peer.ID(""), fmt.Errorf("failed to connect to a random peer err=%s", err) } diff --git a/cmd/sentinel/sentinel/sentinel.go b/cmd/sentinel/sentinel/sentinel.go index d0415af8cd9..f9f4049ecfb 100644 --- a/cmd/sentinel/sentinel/sentinel.go +++ b/cmd/sentinel/sentinel/sentinel.go @@ -19,10 +19,11 @@ import ( "fmt" "net" + "net/http" + "time" + "github.com/ledgerwatch/erigon-lib/kv" - "github.com/ledgerwatch/erigon/cl/clparams" "github.com/ledgerwatch/erigon/cl/cltypes" - "github.com/ledgerwatch/erigon/cl/fork" "github.com/ledgerwatch/erigon/cmd/sentinel/sentinel/handlers" "github.com/ledgerwatch/erigon/cmd/sentinel/sentinel/handshake" "github.com/ledgerwatch/erigon/cmd/sentinel/sentinel/peers" @@ -33,9 +34,26 @@ import ( "github.com/ledgerwatch/log/v3" "github.com/libp2p/go-libp2p" pubsub "github.com/libp2p/go-libp2p-pubsub" - pubsub_pb "github.com/libp2p/go-libp2p-pubsub/pb" "github.com/libp2p/go-libp2p/core/host" "github.com/libp2p/go-libp2p/core/network" + rcmgr "github.com/libp2p/go-libp2p/p2p/host/resource-manager" + rcmgrObs "github.com/libp2p/go-libp2p/p2p/host/resource-manager/obs" + "github.com/prometheus/client_golang/prometheus" + "github.com/prometheus/client_golang/prometheus/promhttp" +) + +const ( + // overlay parameters + gossipSubD = 8 // topic stable mesh target count + gossipSubDlo = 6 // topic stable mesh low watermark + gossipSubDhi = 12 // topic stable mesh high watermark + + // gossip parameters + gossipSubMcacheLen = 6 // number of windows to retain full messages in cache for `IWANT` responses + gossipSubMcacheGossip = 3 // number of windows to gossip about + gossipSubSeenTTL = 550 // number of heartbeat intervals to retain message IDs + // heartbeat interval + gossipSubHeartbeatInterval = 700 * time.Millisecond // frequency of heartbeat, milliseconds ) type Sentinel struct { @@ -53,7 +71,7 @@ type Sentinel struct { discoverConfig discover.Config pubsub *pubsub.PubSub subManager *GossipManager - gossipTopics []GossipTopic + metrics bool } func (s *Sentinel) createLocalNode( @@ -147,20 +165,27 @@ func (s *Sentinel) createListener() (*discover.UDPv5, error) { return net, err } +// creates a custom gossipsub parameter set. +func pubsubGossipParam() pubsub.GossipSubParams { + gParams := pubsub.DefaultGossipSubParams() + gParams.Dlo = gossipSubDlo + gParams.D = gossipSubD + gParams.HeartbeatInterval = gossipSubHeartbeatInterval + gParams.HistoryLength = gossipSubMcacheLen + gParams.HistoryGossip = gossipSubMcacheGossip + return gParams +} + func (s *Sentinel) pubsubOptions() []pubsub.Option { pubsubQueueSize := 600 - gsp := pubsub.DefaultGossipSubParams() psOpts := []pubsub.Option{ pubsub.WithMessageSignaturePolicy(pubsub.StrictNoSign), - pubsub.WithMessageSignaturePolicy(pubsub.StrictNoSign), - pubsub.WithMessageIdFn(func(pmsg *pubsub_pb.Message) string { - return fork.MsgID(pmsg, s.cfg.NetworkConfig, s.cfg.BeaconConfig, s.cfg.GenesisConfig) - }), pubsub.WithNoAuthor(), - pubsub.WithSubscriptionFilter(nil), + pubsub.WithMessageIdFn(s.msgId), + pubsub.WithNoAuthor(), pubsub.WithPeerOutboundQueueSize(pubsubQueueSize), pubsub.WithMaxMessageSize(int(s.cfg.NetworkConfig.GossipMaxSize)), pubsub.WithValidateQueueSize(pubsubQueueSize), - pubsub.WithGossipSubParams(gsp), + pubsub.WithGossipSubParams(pubsubGossipParam()), } return psOpts } @@ -170,12 +195,12 @@ func New( ctx context.Context, cfg *SentinelConfig, db kv.RoDB, - rule handshake.RuleFunc, ) (*Sentinel, error) { s := &Sentinel{ ctx: ctx, cfg: cfg, db: db, + // metrics: true, } // Setup discovery @@ -200,16 +225,38 @@ func New( if err != nil { return nil, err } + if s.metrics { + http.Handle("/metrics", promhttp.Handler()) + go func() { + server := &http.Server{ + Addr: ":2112", + ReadHeaderTimeout: time.Hour, + } + if err := server.ListenAndServe(); err != nil { + panic(err) + } + }() + + rcmgrObs.MustRegisterWith(prometheus.DefaultRegisterer) + + str, err := rcmgrObs.NewStatsTraceReporter() + if err != nil { + return nil, err + } + rmgr, err := rcmgr.NewResourceManager(rcmgr.NewFixedLimiter(rcmgr.DefaultLimits.AutoScale()), rcmgr.WithTraceReporter(str)) + if err != nil { + return nil, err + } + opts = append(opts, libp2p.ResourceManager(rmgr)) + } host, err := libp2p.New(opts...) if err != nil { return nil, err } - s.handshaker = handshake.New(ctx, cfg.GenesisConfig, cfg.BeaconConfig, host, rule) + s.handshaker = handshake.New(ctx, cfg.GenesisConfig, cfg.BeaconConfig, host) - // removed IdDelta in recent version of libp2p - host.RemoveStreamHandler("/p2p/id/delta/1.0.0") s.host = host s.peers = peers.New(s.host) @@ -221,10 +268,6 @@ func New( return s, nil } -func (s *Sentinel) ChainConfigs() (clparams.BeaconChainConfig, clparams.GenesisConfig) { - return *s.cfg.BeaconConfig, *s.cfg.GenesisConfig -} - func (s *Sentinel) RecvGossip() <-chan *pubsub.Message { return s.subManager.Recv() } @@ -258,16 +301,18 @@ func (s *Sentinel) String() string { } func (s *Sentinel) HasTooManyPeers() bool { - return s.GetPeersCount() >= peers.DefaultMaxPeers + nPeers, _ := s.GetPeersCount() + return nPeers >= peers.DefaultMaxPeers } -func (s *Sentinel) GetPeersCount() int { - sub := s.subManager.GetMatchingSubscription(string(LightClientFinalityUpdateTopic)) +func (s *Sentinel) GetPeersCount() (int, int) { + sub := s.subManager.GetMatchingSubscription(string(BeaconBlockTopic)) if sub == nil { - return len(s.host.Network().Peers()) + return len(s.host.Network().Peers()), 0 } - return len(sub.topic.ListPeers()) + + return len(s.host.Network().Peers()), len(sub.topic.ListPeers()) } func (s *Sentinel) Host() host.Host { @@ -277,3 +322,7 @@ func (s *Sentinel) Host() host.Host { func (s *Sentinel) Peers() *peers.Peers { return s.peers } + +func (s *Sentinel) GossipManager() *GossipManager { + return s.subManager +} diff --git a/cmd/sentinel/sentinel/service/notifiers.go b/cmd/sentinel/sentinel/service/notifiers.go index 9d0fca70921..594f2609252 100644 --- a/cmd/sentinel/sentinel/service/notifiers.go +++ b/cmd/sentinel/sentinel/service/notifiers.go @@ -14,6 +14,7 @@ const ( type gossipObject struct { data []byte // gossip data t sentinel.GossipType // determine which gossip message we are notifying of + pid string } type gossipNotifier struct { @@ -28,7 +29,7 @@ func newGossipNotifier() *gossipNotifier { } } -func (g *gossipNotifier) notify(t sentinel.GossipType, data []byte) { +func (g *gossipNotifier) notify(t sentinel.GossipType, data []byte, pid string) { g.mu.Lock() defer g.mu.Unlock() @@ -36,6 +37,7 @@ func (g *gossipNotifier) notify(t sentinel.GossipType, data []byte) { ch <- gossipObject{ data: data, t: t, + pid: pid, } } } diff --git a/cmd/sentinel/sentinel/service/service.go b/cmd/sentinel/sentinel/service/service.go index 2d8b3b55809..e2477cc7fc4 100644 --- a/cmd/sentinel/sentinel/service/service.go +++ b/cmd/sentinel/sentinel/service/service.go @@ -14,6 +14,7 @@ import ( "github.com/ledgerwatch/erigon/cmd/sentinel/sentinel/communication" "github.com/ledgerwatch/log/v3" pubsub "github.com/libp2p/go-libp2p-pubsub" + "github.com/libp2p/go-libp2p/core/peer" ) type SentinelServer struct { @@ -32,6 +33,17 @@ func NewSentinelServer(ctx context.Context, sentinel *sentinel.Sentinel) *Sentin } } +//BanPeer(context.Context, *Peer) (*EmptyMessage, error) + +func (s *SentinelServer) BanPeer(_ context.Context, p *sentinelrpc.Peer) (*sentinelrpc.EmptyMessage, error) { + var pid peer.ID + if err := pid.UnmarshalText([]byte(p.Pid)); err != nil { + return nil, err + } + s.sentinel.Peers().BanBadPeer(pid) + return &sentinelrpc.EmptyMessage{}, nil +} + func (s *SentinelServer) SubscribeGossip(_ *sentinelrpc.EmptyMessage, stream sentinelrpc.Sentinel_SubscribeGossipServer) error { // first of all subscribe ch, subId, err := s.gossipNotifier.addSubscriber() @@ -49,6 +61,9 @@ func (s *SentinelServer) SubscribeGossip(_ *sentinelrpc.EmptyMessage, stream sen if err := stream.Send(&sentinelrpc.GossipData{ Data: packet.data, Type: packet.t, + Peer: &sentinelrpc.Peer{ + Pid: packet.pid, + }, }); err != nil { log.Warn("[Sentinel] Could not relay gossip packet", "reason", err) } @@ -57,7 +72,9 @@ func (s *SentinelServer) SubscribeGossip(_ *sentinelrpc.EmptyMessage, stream sen } func (s *SentinelServer) SendRequest(_ context.Context, req *sentinelrpc.RequestData) (*sentinelrpc.ResponseData, error) { - retryReqInterval := time.NewTicker(20 * time.Millisecond) + retryReqInterval := time.NewTicker(200 * time.Millisecond) + defer retryReqInterval.Stop() + timeout := time.NewTimer(1 * time.Second) defer retryReqInterval.Stop() doneCh := make(chan *sentinelrpc.ResponseData) // Try finding the data to our peers @@ -93,6 +110,11 @@ func (s *SentinelServer) SendRequest(_ context.Context, req *sentinelrpc.Request }() case resp := <-doneCh: return resp, nil + case <-timeout.C: + return &sentinelrpc.ResponseData{ + Data: []byte("sentinel timeout"), + Error: true, + }, nil } } } @@ -110,9 +132,11 @@ func (s *SentinelServer) SetStatus(_ context.Context, req *sentinelrpc.Status) ( } func (s *SentinelServer) GetPeers(_ context.Context, _ *sentinelrpc.EmptyMessage) (*sentinelrpc.PeerCount, error) { + nPeers, gPeers := s.sentinel.GetPeersCount() + log.Debug("Gossip", "peers", gPeers) // Send the request and get the data if we get an answer. return &sentinelrpc.PeerCount{ - Amount: uint64(s.sentinel.GetPeersCount()), + Amount: uint64(nPeers), }, nil } @@ -131,6 +155,7 @@ func (s *SentinelServer) handleGossipPacket(pkt *pubsub.Message) error { var err error log.Trace("[Sentinel Gossip] Received Packet", "topic", pkt.Topic) data := pkt.GetData() + // If we use snappy codec then decompress it accordingly. if strings.Contains(*pkt.Topic, sentinel.SSZSnappyCodec) { data, err = utils.DecompressSnappy(data) @@ -138,21 +163,25 @@ func (s *SentinelServer) handleGossipPacket(pkt *pubsub.Message) error { return err } } + textPid, err := pkt.ReceivedFrom.MarshalText() + if err != nil { + return err + } // Check to which gossip it belongs to. if strings.Contains(*pkt.Topic, string(sentinel.BeaconBlockTopic)) { - s.gossipNotifier.notify(sentinelrpc.GossipType_BeaconBlockGossipType, data) + s.gossipNotifier.notify(sentinelrpc.GossipType_BeaconBlockGossipType, data, string(textPid)) } else if strings.Contains(*pkt.Topic, string(sentinel.BeaconAggregateAndProofTopic)) { - s.gossipNotifier.notify(sentinelrpc.GossipType_AggregateAndProofGossipType, data) + s.gossipNotifier.notify(sentinelrpc.GossipType_AggregateAndProofGossipType, data, string(textPid)) } else if strings.Contains(*pkt.Topic, string(sentinel.VoluntaryExitTopic)) { - s.gossipNotifier.notify(sentinelrpc.GossipType_VoluntaryExitGossipType, data) + s.gossipNotifier.notify(sentinelrpc.GossipType_VoluntaryExitGossipType, data, string(textPid)) } else if strings.Contains(*pkt.Topic, string(sentinel.ProposerSlashingTopic)) { - s.gossipNotifier.notify(sentinelrpc.GossipType_ProposerSlashingGossipType, data) + s.gossipNotifier.notify(sentinelrpc.GossipType_ProposerSlashingGossipType, data, string(textPid)) } else if strings.Contains(*pkt.Topic, string(sentinel.AttesterSlashingTopic)) { - s.gossipNotifier.notify(sentinelrpc.GossipType_AttesterSlashingGossipType, data) + s.gossipNotifier.notify(sentinelrpc.GossipType_AttesterSlashingGossipType, data, string(textPid)) } else if strings.Contains(*pkt.Topic, string(sentinel.LightClientFinalityUpdateTopic)) { - s.gossipNotifier.notify(sentinelrpc.GossipType_LightClientFinalityUpdateGossipType, data) + s.gossipNotifier.notify(sentinelrpc.GossipType_LightClientFinalityUpdateGossipType, data, string(textPid)) } else if strings.Contains(*pkt.Topic, string(sentinel.LightClientOptimisticUpdateTopic)) { - s.gossipNotifier.notify(sentinelrpc.GossipType_LightClientOptimisticUpdateGossipType, data) + s.gossipNotifier.notify(sentinelrpc.GossipType_LightClientOptimisticUpdateGossipType, data, string(textPid)) } return nil } diff --git a/cmd/sentinel/sentinel/service/start.go b/cmd/sentinel/sentinel/service/start.go index fcf1008d1c6..e00455420f3 100644 --- a/cmd/sentinel/sentinel/service/start.go +++ b/cmd/sentinel/sentinel/service/start.go @@ -9,9 +9,7 @@ import ( sentinelrpc "github.com/ledgerwatch/erigon-lib/gointerfaces/sentinel" "github.com/ledgerwatch/erigon-lib/kv" "github.com/ledgerwatch/erigon/cl/cltypes" - "github.com/ledgerwatch/erigon/cl/fork" "github.com/ledgerwatch/erigon/cmd/sentinel/sentinel" - "github.com/ledgerwatch/erigon/cmd/sentinel/sentinel/handshake" "github.com/ledgerwatch/log/v3" "google.golang.org/grpc" "google.golang.org/grpc/credentials" @@ -25,34 +23,9 @@ type ServerConfig struct { Addr string } -func hardForkListener(ctx context.Context, s *sentinel.Sentinel) { - tryAgainInterval := time.NewTicker(time.Second) - beaconCfg, genesisCfg := s.ChainConfigs() - currentDigest, err := fork.ComputeForkDigest(&beaconCfg, &genesisCfg) - if err != nil { - log.Error("cannot listen for hard forks", "reasons", err) - return - } - for { - select { - case <-ctx.Done(): - return - case <-tryAgainInterval.C: - newDigest, err := fork.ComputeForkDigest(&beaconCfg, &genesisCfg) - if err != nil { - log.Error("cannot listen for hard forks", "reasons", err) - return - } - if newDigest != currentDigest { - s.RestartTopics() - currentDigest = newDigest - } - } - } -} -func StartSentinelService(cfg *sentinel.SentinelConfig, db kv.RoDB, srvCfg *ServerConfig, creds credentials.TransportCredentials, initialStatus *cltypes.Status, rule handshake.RuleFunc) (sentinelrpc.SentinelClient, error) { +func StartSentinelService(cfg *sentinel.SentinelConfig, db kv.RoDB, srvCfg *ServerConfig, creds credentials.TransportCredentials, initialStatus *cltypes.Status) (sentinelrpc.SentinelClient, error) { ctx := context.Background() - sent, err := sentinel.New(context.Background(), cfg, db, rule) + sent, err := sentinel.New(context.Background(), cfg, db) if err != nil { return nil, err } @@ -63,13 +36,16 @@ func StartSentinelService(cfg *sentinel.SentinelConfig, db kv.RoDB, srvCfg *Serv sentinel.BeaconBlockSsz, // Cause problem due to buggy msg id will uncomment in the future. //sentinel.BeaconAggregateAndProofSsz, - sentinel.VoluntaryExitSsz, - sentinel.ProposerSlashingSsz, - sentinel.AttesterSlashingSsz, - sentinel.LightClientFinalityUpdateSsz, - sentinel.LightClientOptimisticUpdateSsz, + //sentinel.VoluntaryExitSsz, + //sentinel.ProposerSlashingSsz, + //sentinel.AttesterSlashingSsz, } + for _, v := range gossip_topics { + if err := sent.Unsubscribe(v); err != nil { + log.Error("[Sentinel] failed to start sentinel", "err", err) + continue + } // now lets separately connect to the gossip topics. this joins the room subscriber, err := sent.SubscribeGossip(v) if err != nil { @@ -81,7 +57,7 @@ func StartSentinelService(cfg *sentinel.SentinelConfig, db kv.RoDB, srvCfg *Serv log.Error("[Sentinel] failed to start sentinel", "err", err) } } - go hardForkListener(ctx, sent) + log.Info("[Sentinel] Sentinel started", "enr", sent.String()) if initialStatus != nil { sent.SetStatus(initialStatus) diff --git a/cmd/sentinel/sentinel/utils.go b/cmd/sentinel/sentinel/utils.go index 40d336941d8..8c38ffb4671 100644 --- a/cmd/sentinel/sentinel/utils.go +++ b/cmd/sentinel/sentinel/utils.go @@ -34,11 +34,11 @@ func convertToInterfacePubkey(pubkey *ecdsa.PublicKey) (crypto.PubKey, error) { xVal, yVal := new(btcec.FieldVal), new(btcec.FieldVal) overflows := xVal.SetByteSlice(pubkey.X.Bytes()) if overflows { - return nil, fmt.Errorf("X value overflows") + return nil, fmt.Errorf("x value overflows") } overflows = yVal.SetByteSlice(pubkey.Y.Bytes()) if overflows { - return nil, fmt.Errorf("Y value overflows") + return nil, fmt.Errorf("y value overflows") } newKey := crypto.PubKey((*crypto.Secp256k1PublicKey)(btcec.NewPublicKey(xVal, yVal))) // Zero out temporary values. @@ -116,7 +116,8 @@ func connectToRandomPeer(s *Sentinel, topic string) (peerInfo peer.ID, err error return peer.ID(""), fmt.Errorf("no peers") } - validPeerList := sub.topic.ListPeers() + validPeerList := s.Host().Network().Peers() + //validPeerList := sub.topic.ListPeers() if len(validPeerList) == 0 { return peer.ID(""), fmt.Errorf("no peers") } @@ -138,27 +139,12 @@ func connectToRandomPeer(s *Sentinel, topic string) (peerInfo peer.ID, err error index = n.Int64() } - node := validPeerList[index] - if !isPeerWhitelisted(node, validPeerList) { - - continue - } - - if !s.peers.IsPeerAvaiable(node) { + if !s.peers.IsPeerAvaiable(validPeerList[index]) { continue } - return node, nil + return validPeerList[index], nil } return peer.ID(""), fmt.Errorf("failed to connect to peer") - -} -func isPeerWhitelisted(peer peer.ID, whitelist []peer.ID) bool { - for _, currPeer := range whitelist { - if peer == currPeer { - return true - } - } - return false } diff --git a/cmd/sentinel/sentinel/utils_test.go b/cmd/sentinel/sentinel/utils_test.go index 38774a0d07a..10e60588b64 100644 --- a/cmd/sentinel/sentinel/utils_test.go +++ b/cmd/sentinel/sentinel/utils_test.go @@ -12,37 +12,6 @@ import ( var pyRecord, _ = hex.DecodeString("f884b8407098ad865b00a582051940cb9cf36836572411a47278783077011599ed5cd16b76f2635f4e234738f30813a89eb9137e3e3df5266e3a1f11df72ecf1145ccb9c01826964827634826970847f00000189736563703235366b31a103ca634cae0d49acb401d8a4c6b6fe8c55b70d115bf400769cc1400f3258cd31388375647082765f") -func TestIsPeerWhiteListed(t *testing.T) { - testCases := []struct { - whitelist []peer.ID - peer peer.ID - expectedRes bool - }{ - { - whitelist: []peer.ID{peer.ID("peer1"), peer.ID("peer2"), peer.ID("peer3"), peer.ID("peer4"), peer.ID("peer5")}, - peer: peer.ID("peer1"), - expectedRes: true, - }, - { - whitelist: []peer.ID{peer.ID("peer1"), peer.ID("peer2"), peer.ID("peer4"), peer.ID("peer5"), peer.ID("peer6")}, - peer: peer.ID("peer3"), - expectedRes: false, - }, - { - whitelist: []peer.ID{}, - peer: peer.ID(""), - expectedRes: false, - }, - } - - for _, testCase := range testCases { - got := isPeerWhitelisted(testCase.peer, testCase.whitelist) - if got != testCase.expectedRes { - t.Errorf("expected: %v, got: %v", testCase.expectedRes, got) - } - } -} - func TestMultiAddressBuilderWithID(t *testing.T) { testCases := []struct { ipAddr string diff --git a/cmd/sentry/main.go b/cmd/sentry/main.go index d73089de799..ca1f38f3db7 100644 --- a/cmd/sentry/main.go +++ b/cmd/sentry/main.go @@ -10,7 +10,7 @@ import ( "github.com/ledgerwatch/erigon/cmd/utils" "github.com/ledgerwatch/erigon/common/paths" "github.com/ledgerwatch/erigon/turbo/debug" - logging2 "github.com/ledgerwatch/erigon/turbo/logging" + "github.com/ledgerwatch/erigon/turbo/logging" node2 "github.com/ledgerwatch/erigon/turbo/node" "github.com/spf13/cobra" ) @@ -36,7 +36,7 @@ var ( ) func init() { - utils.CobraFlags(rootCmd, debug.Flags, utils.MetricFlags, logging2.Flags) + utils.CobraFlags(rootCmd, debug.Flags, utils.MetricFlags, logging.Flags) rootCmd.Flags().StringVar(&sentryAddr, "sentry.api.addr", "localhost:9091", "grpc addresses") rootCmd.Flags().StringVar(&datadirCli, utils.DataDirFlag.Name, paths.DefaultDataDir(), utils.DataDirFlag.Usage) @@ -90,7 +90,7 @@ var rootCmd = &cobra.Command{ return err } - _ = logging2.GetLoggerCmd("sentry", cmd) + logging.SetupLoggerCmd("sentry", cmd) return sentry.Sentry(cmd.Context(), dirs, sentryAddr, discoveryDNS, p2pConfig, protocol, healthCheck) }, } diff --git a/cmd/sentry/sentry/eth_handshake.go b/cmd/sentry/sentry/eth_handshake.go index e7c17bc08a5..ee5cbd02551 100644 --- a/cmd/sentry/sentry/eth_handshake.go +++ b/cmd/sentry/sentry/eth_handshake.go @@ -48,6 +48,8 @@ func tryDecodeStatusMessage(msg *p2p.Msg) (*eth.StatusPacket, error) { return &reply, nil } +var NetworkIdMissmatchErr = fmt.Errorf("network id does not match") + func checkPeerStatusCompatibility( reply *eth.StatusPacket, status *proto_sentry.StatusData, @@ -56,7 +58,7 @@ func checkPeerStatusCompatibility( ) error { networkID := status.NetworkId if reply.NetworkID != networkID { - return fmt.Errorf("network id does not match: theirs %d, ours %d", reply.NetworkID, networkID) + return fmt.Errorf("%w: theirs %d, ours %d", NetworkIdMissmatchErr, reply.NetworkID, networkID) } if uint(reply.ProtocolVersion) > version { diff --git a/cmd/sentry/sentry/sentry_grpc_server.go b/cmd/sentry/sentry/sentry_grpc_server.go index 52c9f1b3e2a..6282f8e6f5c 100644 --- a/cmd/sentry/sentry/sentry_grpc_server.go +++ b/cmd/sentry/sentry/sentry_grpc_server.go @@ -579,7 +579,7 @@ func NewGrpcServer(ctx context.Context, dialCandidates func() enode.Iterator, re log.Trace("[p2p] peer already has connection", "peerId", printablePeerID) return nil } - log.Debug("[p2p] start with peer", "peerId", printablePeerID) + log.Trace("[p2p] start with peer", "peerId", printablePeerID) peerInfo := NewPeerInfo(peer, rw) peerInfo.protocol = protocol @@ -592,7 +592,11 @@ func NewGrpcServer(ctx context.Context, dialCandidates func() enode.Iterator, re return ss.startSync(ctx, bestHash, peerID) }) if err != nil { - log.Debug("[p2p] Handshake failure", "peer", printablePeerID, "err", err) + if errors.Is(err, NetworkIdMissmatchErr) || errors.Is(err, io.EOF) || errors.Is(err, p2p.ErrShuttingDown) { + log.Trace("[p2p] Handshake failure", "peer", printablePeerID, "err", err) + } else { + log.Debug("[p2p] Handshake failure", "peer", printablePeerID, "err", err) + } return fmt.Errorf("[p2p]handshake to peer %s: %w", printablePeerID, err) } log.Trace("[p2p] Received status message OK", "peerId", printablePeerID, "name", peer.Name()) @@ -741,7 +745,12 @@ func (ss *GrpcServer) startSync(ctx context.Context, bestHash libcommon.Hash, pe func (ss *GrpcServer) PenalizePeer(_ context.Context, req *proto_sentry.PenalizePeerRequest) (*emptypb.Empty, error) { //log.Warn("Received penalty", "kind", req.GetPenalty().Descriptor().FullName, "from", fmt.Sprintf("%s", req.GetPeerId())) peerID := ConvertH512ToPeerID(req.PeerId) - ss.removePeer(peerID) + peerInfo := ss.getPeer(peerID) + if ss.statusData != nil && peerInfo != nil && !peerInfo.peer.Info().Network.Static && !peerInfo.peer.Info().Network.Trusted { + ss.removePeer(peerID) + printablePeerID := hex.EncodeToString(peerID[:])[:8] + log.Debug("[p2p] Penalized peer", "peerId", printablePeerID, "name", peerInfo.peer.Name()) + } return &emptypb.Empty{}, nil } @@ -753,17 +762,6 @@ func (ss *GrpcServer) PeerMinBlock(_ context.Context, req *proto_sentry.PeerMinB return &emptypb.Empty{}, nil } -func (ss *GrpcServer) PeerUseless(_ context.Context, req *proto_sentry.PeerUselessRequest) (*emptypb.Empty, error) { - peerID := ConvertH512ToPeerID(req.PeerId) - peerInfo := ss.getPeer(peerID) - if ss.statusData != nil && peerInfo != nil && !peerInfo.peer.Info().Network.Static && !peerInfo.peer.Info().Network.Trusted { - ss.removePeer(peerID) - printablePeerID := hex.EncodeToString(peerID[:])[:8] - log.Debug("[p2p] Removed useless peer", "peerId", printablePeerID, "name", peerInfo.peer.Name()) - } - return &emptypb.Empty{}, nil -} - func (ss *GrpcServer) findBestPeersWithPermit(peerCount int) []*PeerInfo { // Choose peer(s) that we can send this request to, with maximum number of permits now := time.Now() @@ -834,7 +832,7 @@ func (ss *GrpcServer) SendMessageByMinBlock(_ context.Context, inreq *proto_sent if inreq.MaxPeers == 1 { peerInfo, found := ss.findPeerByMinBlock(inreq.MinBlock) if found { - ss.writePeer("sendMessageByMinBlock", peerInfo, msgcode, inreq.Data.Data, 30*time.Second) + ss.writePeer("[sentry] sendMessageByMinBlock", peerInfo, msgcode, inreq.Data.Data, 30*time.Second) reply.Peers = []*proto_types.H512{gointerfaces.ConvertHashToH512(peerInfo.ID())} return reply, nil } @@ -842,7 +840,7 @@ func (ss *GrpcServer) SendMessageByMinBlock(_ context.Context, inreq *proto_sent peerInfos := ss.findBestPeersWithPermit(int(inreq.MaxPeers)) reply.Peers = make([]*proto_types.H512, len(peerInfos)) for i, peerInfo := range peerInfos { - ss.writePeer("sendMessageByMinBlock", peerInfo, msgcode, inreq.Data.Data, 15*time.Second) + ss.writePeer("[sentry] sendMessageByMinBlock", peerInfo, msgcode, inreq.Data.Data, 15*time.Second) reply.Peers[i] = gointerfaces.ConvertHashToH512(peerInfo.ID()) } return reply, nil @@ -870,7 +868,7 @@ func (ss *GrpcServer) SendMessageById(_ context.Context, inreq *proto_sentry.Sen return reply, nil } - ss.writePeer("sendMessageById", peerInfo, msgcode, inreq.Data.Data, 0) + ss.writePeer("[sentry] sendMessageById", peerInfo, msgcode, inreq.Data.Data, 0) reply.Peers = []*proto_types.H512{inreq.PeerId} return reply, nil } @@ -904,7 +902,7 @@ func (ss *GrpcServer) SendMessageToRandomPeers(ctx context.Context, req *proto_s var lastErr error // Send the block to a subset of our peers at random for _, peerInfo := range peerInfos[:peersToSendCount] { - ss.writePeer("sendMessageToRandomPeers", peerInfo, msgcode, req.Data.Data, 0) + ss.writePeer("[sentry] sendMessageToRandomPeers", peerInfo, msgcode, req.Data.Data, 0) reply.Peers = append(reply.Peers, gointerfaces.ConvertHashToH512(peerInfo.ID())) } return reply, lastErr @@ -922,7 +920,7 @@ func (ss *GrpcServer) SendMessageToAll(ctx context.Context, req *proto_sentry.Ou var lastErr error ss.rangePeers(func(peerInfo *PeerInfo) bool { - ss.writePeer("SendMessageToAll", peerInfo, msgcode, req.Data, 0) + ss.writePeer("[sentry] SendMessageToAll", peerInfo, msgcode, req.Data, 0) reply.Peers = append(reply.Peers, gointerfaces.ConvertHashToH512(peerInfo.ID())) return true }) diff --git a/cmd/sentry/sentry/sentry_multi_client.go b/cmd/sentry/sentry/sentry_multi_client.go index e7715bcaf61..b56b1cd1006 100644 --- a/cmd/sentry/sentry/sentry_multi_client.go +++ b/cmd/sentry/sentry/sentry_multi_client.go @@ -266,7 +266,8 @@ type MultiClient struct { logPeerInfo bool sendHeaderRequestsToMultiplePeers bool - historyV3 bool + historyV3 bool + dropUselessPeers bool } func NewMultiClient( @@ -281,6 +282,7 @@ func NewMultiClient( blockReader services.HeaderAndCanonicalReader, logPeerInfo bool, forkValidator *engineapi.ForkValidator, + dropUselessPeers bool, ) (*MultiClient, error) { historyV3 := kvcfg.HistoryV3.FromDB(db) @@ -311,6 +313,7 @@ func NewMultiClient( forkValidator: forkValidator, historyV3: historyV3, sendHeaderRequestsToMultiplePeers: chainConfig.TerminalTotalDifficultyPassed, + dropUselessPeers: dropUselessPeers, } cs.ChainConfig = chainConfig cs.heightForks, cs.timeForks = forkid.GatherForks(cs.ChainConfig) @@ -392,11 +395,11 @@ func (cs *MultiClient) blockHeaders66(ctx context.Context, in *proto_sentry.Inbo } func (cs *MultiClient) blockHeaders(ctx context.Context, pkt eth.BlockHeadersPacket, rlpStream *rlp.Stream, peerID *proto_types.H512, sentry direct.SentryClient) error { - if len(pkt) == 0 { - outreq := proto_sentry.PeerUselessRequest{ + if cs.dropUselessPeers && len(pkt) == 0 { + outreq := proto_sentry.PenalizePeerRequest{ PeerId: peerID, } - if _, err := sentry.PeerUseless(ctx, &outreq, &grpc.EmptyCallOption{}); err != nil { + if _, err := sentry.PenalizePeer(ctx, &outreq, &grpc.EmptyCallOption{}); err != nil { return fmt.Errorf("sending peer useless request: %v", err) } log.Debug("Requested removal of peer for empty header response", "peerId", fmt.Sprintf("%x", ConvertH512ToPeerID(peerID))[:8]) @@ -556,11 +559,11 @@ func (cs *MultiClient) blockBodies66(ctx context.Context, inreq *proto_sentry.In return fmt.Errorf("decode BlockBodiesPacket66: %w", err) } txs, uncles, withdrawals := request.BlockRawBodiesPacket.Unpack() - if len(txs) == 0 && len(uncles) == 0 && len(withdrawals) == 0 { - outreq := proto_sentry.PeerUselessRequest{ + if cs.dropUselessPeers && len(txs) == 0 && len(uncles) == 0 && len(withdrawals) == 0 { + outreq := proto_sentry.PenalizePeerRequest{ PeerId: inreq.PeerId, } - if _, err := sentry.PeerUseless(ctx, &outreq, &grpc.EmptyCallOption{}); err != nil { + if _, err := sentry.PenalizePeer(ctx, &outreq, &grpc.EmptyCallOption{}); err != nil { return fmt.Errorf("sending peer useless request: %v", err) } log.Debug("Requested removal of peer for empty body response", "peerId", fmt.Sprintf("%x", ConvertH512ToPeerID(inreq.PeerId))) diff --git a/cmd/starter/README.md b/cmd/starter/README.md new file mode 100644 index 00000000000..11c25d09141 --- /dev/null +++ b/cmd/starter/README.md @@ -0,0 +1,32 @@ +# Starter + +Starter is an additional utility for tracking errors in the logs of the main process. If the given substring is found in the logs more than N times in the given period of time, then the starter will restart the process. + +If starter receives a signal to stop, it will stop the main process and exit. + +## Build + +```go build -o /build/bin/starter cmd/starter/main.go``` + +or + +```make starter``` + +## Usage +Each `--errortrack` flag requires 3 arguments after it, the rest of arguments is a command for child process. + +```starter [--errortrack error_substring error_limit time_window] [args...]``` + +- `error_substring` - substring to search in the logs +- `error_limit` - maximum number of occurrences of the substring in the given period +- `time_window` - time window for error searching (e.g. 60s, 1m, 1h, 1d) +- `command` - command to run +- `[args...]` - arguments for the command +## Example +This command will restart erigon if the substring 'No block bodies' is found in the logs more than 50 times in 5 minutes: + +```starter --errortrack 'No block bodies' 50 5m erigon --datadir /data --private.api.addr``` + +It is possible to track multiple errors by using `--errortrack` flag multiple times. + +```starter --errortrack 'No block bodies' 50 5m --errortrack 'No peers' 10 60s erigon --datadir /data --private.api.addr``` diff --git a/cmd/starter/main.go b/cmd/starter/main.go new file mode 100644 index 00000000000..35bfab4df2d --- /dev/null +++ b/cmd/starter/main.go @@ -0,0 +1,176 @@ +package main + +import ( + "bufio" + "fmt" + "io" + "os" + "os/exec" + "os/signal" + "strconv" + "strings" + "sync" + "syscall" + "time" +) + +type ErrorTracker struct { + Substring string + Limit int + Window time.Duration + Errors []time.Time +} + +func (et *ErrorTracker) AddError(t time.Time) { + et.Errors = append(et.Errors, t) + if len(et.Errors) > et.Limit { + et.Errors = et.Errors[1:] + } +} + +func (et *ErrorTracker) ShouldRestartProcess() bool { + if len(et.Errors) < et.Limit { + return false + } + + firstError := et.Errors[0] + lastError := et.Errors[len(et.Errors)-1] + return lastError.Sub(firstError) <= et.Window +} + +func parseErrorTrackers() ([]ErrorTracker, []string) { + trackers := make([]ErrorTracker, 0) + args := os.Args[1:] + maxArg := -1 + + for i, arg := range args { + if arg == "--errortrack" { + if i+3 >= len(args) { + log("Invalid --errortrack parameters") + os.Exit(1) + } + + substring := args[i+1] + limit, err := strconv.Atoi(args[i+2]) + if err != nil { + log("Error parsing limit: %v", err) + os.Exit(1) + } + + window, err := time.ParseDuration(args[i+3]) + if err != nil { + log("Error parsing time window: %v", err) + os.Exit(1) + } + + trackers = append(trackers, ErrorTracker{Substring: substring, Limit: limit, Window: window}) + if i+3 > maxArg { + maxArg = i + 3 + } + } + } + + if maxArg >= len(args)-1 { + log("No command provided") + os.Exit(1) + } + + cmdArgs := args[maxArg+1:] + return trackers, cmdArgs +} + +func log(format string, a ...interface{}) { + fmt.Printf(fmt.Sprintf("[starter] %s ", time.Now().Format("[01-02|15:04:05.000]"))+format+"\n", a...) +} + +func main() { + trackers, cmdArgs := parseErrorTrackers() + if len(cmdArgs) == 0 { + log("No command provided") + os.Exit(1) + } + + cmdName := cmdArgs[0] + cmdArgs = cmdArgs[1:] + + // Set up signal handling + sigChan := make(chan os.Signal, 1) + signal.Notify(sigChan, syscall.SIGINT, syscall.SIGTERM) + restartChan := make(chan struct{}, 2) + var cmd *exec.Cmd + var stdoutPipe, stderrPipe io.ReadCloser + var wg sync.WaitGroup + + scanAndTrackErrors := func(scanner *bufio.Scanner, trackers []ErrorTracker, lasrwriter io.Writer, restartChan chan struct{}) { + restartInit := false + for scanner.Scan() { + + line := scanner.Text() + + fmt.Fprintln(lasrwriter, line) + + if restartInit { + continue + } + + for i := range trackers { + if strings.Contains(line, trackers[i].Substring) { + trackers[i].AddError(time.Now()) + log("Find error substring %q, %d errors in %s", trackers[i].Substring, len(trackers[i].Errors), trackers[i].Window) + + if trackers[i].ShouldRestartProcess() { + log("Restarting process due to error limit for substring %q", trackers[i].Substring) + restartChan <- struct{}{} + restartInit = true + } + } + } + } + } + + runCmd := func() { + cmd = exec.Command(cmdName, cmdArgs...) + stdoutPipe, _ = cmd.StdoutPipe() + stderrPipe, _ = cmd.StderrPipe() + + wg.Add(2) + go func() { + defer wg.Done() + scanner := bufio.NewScanner(stdoutPipe) + scanAndTrackErrors(scanner, trackers, os.Stdout, restartChan) + }() + + go func() { + defer wg.Done() + scanner := bufio.NewScanner(stderrPipe) + scanAndTrackErrors(scanner, trackers, os.Stderr, restartChan) + }() + cmd.Start() + } + + runCmd() + + for { + select { + case sig := <-sigChan: + switch sig { + case syscall.SIGINT, syscall.SIGTERM: + cmd.Process.Signal(sig) + cmd.Process.Wait() + wg.Wait() + os.Exit(0) + } + case <-restartChan: + if err := cmd.Process.Signal(syscall.SIGINT); err != nil { + log("Error sending signal to process: %v", err) + } + cmd.Process.Wait() + wg.Wait() + log("Restarting process due to error limits") + for i := range trackers { + trackers[i].Errors = []time.Time{} + } + runCmd() + } + } +} diff --git a/cmd/state/commands/erigon4.go b/cmd/state/commands/erigon4.go index d327c0e296e..8335d76e958 100644 --- a/cmd/state/commands/erigon4.go +++ b/cmd/state/commands/erigon4.go @@ -81,8 +81,8 @@ var erigon4Cmd = &cobra.Command{ Use: "erigon4", Short: "Experimental command to re-execute blocks from beginning using erigon2 state representation and history/domain", RunE: func(cmd *cobra.Command, args []string) error { - logger := logging.GetLoggerCmd("erigon4", cmd) - return Erigon4(genesis, chainConfig, logger) + logging.SetupLoggerCmd("erigon4", cmd) + return Erigon4(genesis, chainConfig, log.Root()) }, } @@ -418,14 +418,14 @@ func processBlock23(startTxNum uint64, trace bool, txNumStart uint64, rw *Reader } getHashFn := core.GetHashFn(header, getHeader) - + excessDataGas := header.ParentExcessDataGas(getHeader) for i, tx := range block.Transactions() { if txNum >= startTxNum { ibs := state.New(rw) ibs.Prepare(tx.Hash(), block.Hash(), i) ct := exec3.NewCallTracer() vmConfig.Tracer = ct - receipt, _, err := core.ApplyTransaction(chainConfig, getHashFn, engine, nil, gp, ibs, ww, header, tx, usedGas, vmConfig) + receipt, _, err := core.ApplyTransaction(chainConfig, getHashFn, engine, nil, gp, ibs, ww, header, tx, usedGas, vmConfig, excessDataGas) if err != nil { return 0, nil, fmt.Errorf("could not apply tx %d [%x] failed: %w", i, tx.Hash(), err) } @@ -482,7 +482,7 @@ func processBlock23(startTxNum uint64, trace bool, txNumStart uint64, rw *Reader } // Finalize the block, applying any consensus engine specific extras (e.g. block rewards) - if _, _, err := engine.Finalize(chainConfig, header, ibs, block.Transactions(), block.Uncles(), receipts, block.Withdrawals(), nil, nil, nil); err != nil { + if _, _, err := engine.Finalize(chainConfig, header, ibs, block.Transactions(), block.Uncles(), receipts, block.Withdrawals(), nil, nil); err != nil { return 0, nil, fmt.Errorf("finalize of block %d failed: %w", block.NumberU64(), err) } @@ -690,7 +690,6 @@ func (ww *WriterWrapper23) CreateContract(address libcommon.Address) error { } func initConsensusEngine(cc *chain2.Config, snapshots *snapshotsync.RoSnapshots) (engine consensus.Engine) { - l := log.New() config := ethconfig.Defaults var consensusConfig interface{} @@ -698,7 +697,6 @@ func initConsensusEngine(cc *chain2.Config, snapshots *snapshotsync.RoSnapshots) if cc.Clique != nil { consensusConfig = params.CliqueSnapshot } else if cc.Aura != nil { - config.Aura.Etherbase = config.Miner.Etherbase consensusConfig = &config.Aura } else if cc.Parlia != nil { consensusConfig = &config.Parlia @@ -707,7 +705,7 @@ func initConsensusEngine(cc *chain2.Config, snapshots *snapshotsync.RoSnapshots) } else { consensusConfig = &config.Ethash } - return ethconsensusconfig.CreateConsensusEngine(cc, l, consensusConfig, config.Miner.Notify, config.Miner.Noverify, config.HeimdallgRPCAddress, config.HeimdallURL, config.WithoutHeimdall, datadirCli, snapshots, true /* readonly */) + return ethconsensusconfig.CreateConsensusEngine(cc, consensusConfig, config.Miner.Notify, config.Miner.Noverify, config.HeimdallgRPCAddress, config.HeimdallURL, config.WithoutHeimdall, datadirCli, snapshots, true /* readonly */) } func bytesToUint64(buf []byte) (x uint64) { diff --git a/cmd/state/commands/history22.go b/cmd/state/commands/history22.go index e36c657335b..432e6532ff5 100644 --- a/cmd/state/commands/history22.go +++ b/cmd/state/commands/history22.go @@ -232,6 +232,7 @@ func History22(genesis *core.Genesis, logger log.Logger) error { func runHistory22(trace bool, blockNum, txNumStart uint64, hw *state.HistoryReaderV4, ww state.StateWriter, chainConfig *chain2.Config, getHeader func(hash libcommon.Hash, number uint64) *types.Header, block *types.Block, vmConfig vm.Config) (uint64, types.Receipts, error) { header := block.Header() + excessDataGas := header.ParentExcessDataGas(getHeader) vmConfig.TraceJumpDest = true engine := ethash.NewFullFaker() gp := new(core.GasPool).AddGas(block.GasLimit()) @@ -256,7 +257,7 @@ func runHistory22(trace bool, blockNum, txNumStart uint64, hw *state.HistoryRead hw.SetTxNum(txNum) ibs := state.New(hw) ibs.Prepare(tx.Hash(), block.Hash(), i) - receipt, _, err := core.ApplyTransaction(chainConfig, core.GetHashFn(header, getHeader), engine, nil, gp, ibs, ww, header, tx, usedGas, vmConfig) + receipt, _, err := core.ApplyTransaction(chainConfig, core.GetHashFn(header, getHeader), engine, nil, gp, ibs, ww, header, tx, usedGas, vmConfig, excessDataGas) if err != nil { return 0, nil, fmt.Errorf("could not apply tx %d [%x] failed: %w", i, tx.Hash(), err) } diff --git a/cmd/state/commands/opcode_tracer.go b/cmd/state/commands/opcode_tracer.go index ff5a83225e2..e7482e01d94 100644 --- a/cmd/state/commands/opcode_tracer.go +++ b/cmd/state/commands/opcode_tracer.go @@ -703,6 +703,7 @@ func OpcodeTracer(genesis *core.Genesis, blockNum uint64, chaindata string, numB func runBlock(engine consensus.Engine, ibs *state.IntraBlockState, txnWriter state.StateWriter, blockWriter state.StateWriter, chainConfig *chain2.Config, getHeader func(hash libcommon.Hash, number uint64) *types.Header, block *types.Block, vmConfig vm.Config, trace bool) (types.Receipts, error) { header := block.Header() + excessDataGas := header.ParentExcessDataGas(getHeader) vmConfig.TraceJumpDest = true gp := new(core.GasPool).AddGas(block.GasLimit()) usedGas := new(uint64) @@ -714,7 +715,7 @@ func runBlock(engine consensus.Engine, ibs *state.IntraBlockState, txnWriter sta rules := chainConfig.Rules(block.NumberU64(), block.Time()) for i, tx := range block.Transactions() { ibs.Prepare(tx.Hash(), block.Hash(), i) - receipt, _, err := core.ApplyTransaction(chainConfig, core.GetHashFn(header, getHeader), engine, nil, gp, ibs, txnWriter, header, tx, usedGas, vmConfig) + receipt, _, err := core.ApplyTransaction(chainConfig, core.GetHashFn(header, getHeader), engine, nil, gp, ibs, txnWriter, header, tx, usedGas, vmConfig, excessDataGas) if err != nil { return nil, fmt.Errorf("could not apply tx %d [%x] failed: %w", i, tx.Hash(), err) } @@ -727,7 +728,7 @@ func runBlock(engine consensus.Engine, ibs *state.IntraBlockState, txnWriter sta if !vmConfig.ReadOnly { // Finalize the block, applying any consensus engine specific extras (e.g. block rewards) tx := block.Transactions() - if _, _, _, err := engine.FinalizeAndAssemble(chainConfig, header, ibs, tx, block.Uncles(), receipts, block.Withdrawals(), nil, nil, nil, nil); err != nil { + if _, _, _, err := engine.FinalizeAndAssemble(chainConfig, header, ibs, tx, block.Uncles(), receipts, block.Withdrawals(), nil, nil, nil); err != nil { return nil, fmt.Errorf("finalize of block %d failed: %w", block.NumberU64(), err) } diff --git a/cmd/state/exec22/txtask.go b/cmd/state/exec22/txtask.go index 3353080e371..4f83e7fe74c 100644 --- a/cmd/state/exec22/txtask.go +++ b/cmd/state/exec22/txtask.go @@ -1,6 +1,10 @@ package exec22 import ( + "container/heap" + "context" + "sync" + "github.com/holiman/uint256" "github.com/ledgerwatch/erigon-lib/chain" libcommon "github.com/ledgerwatch/erigon-lib/common" @@ -38,7 +42,6 @@ type TxTask struct { AccountDels map[string]*accounts.Account StoragePrevs map[string][]byte CodePrevs map[string]uint64 - ResultsSize int64 Error error Logs []*types.Log TraceFroms map[libcommon.Address]struct{} @@ -47,11 +50,18 @@ type TxTask struct { UsedGas uint64 } +// TxTaskQueue non-thread-safe priority-queue type TxTaskQueue []*TxTask func (h TxTaskQueue) Len() int { return len(h) } +func LenLocked(h *TxTaskQueue, lock *sync.Mutex) (l int) { + lock.Lock() + l = h.Len() + lock.Unlock() + return l +} func (h TxTaskQueue) Less(i, j int) bool { return h[i].TxNum < h[j].TxNum @@ -92,3 +102,304 @@ func (l *KvList) Swap(i, j int) { l.Keys[i], l.Keys[j] = l.Keys[j], l.Keys[i] l.Vals[i], l.Vals[j] = l.Vals[j], l.Vals[i] } + +// QueueWithRetry is trhead-safe priority-queue of tasks - which attempt to minimize conflict-rate (retry-rate). +// Tasks may conflict and return to queue for re-try/re-exec. +// Tasks added by method `ReTry` have higher priority than tasks added by `Add`. +// Method `Add` expecting already-ordered (by priority) tasks - doesn't do any additional sorting of new tasks. +type QueueWithRetry struct { + closed bool + newTasks chan *TxTask + retires TxTaskQueue + retiresLock sync.Mutex + capacity int +} + +func NewQueueWithRetry(capacity int) *QueueWithRetry { + return &QueueWithRetry{newTasks: make(chan *TxTask, capacity), capacity: capacity} +} + +func (q *QueueWithRetry) NewTasksLen() int { return len(q.newTasks) } +func (q *QueueWithRetry) Capacity() int { return q.capacity } +func (q *QueueWithRetry) RetriesLen() (l int) { + q.retiresLock.Lock() + l = q.retires.Len() + q.retiresLock.Unlock() + return l +} +func (q *QueueWithRetry) RetryTxNumsList() (out []uint64) { + q.retiresLock.Lock() + for _, t := range q.retires { + out = append(out, t.TxNum) + } + q.retiresLock.Unlock() + return out +} +func (q *QueueWithRetry) Len() (l int) { return q.RetriesLen() + len(q.newTasks) } + +// Add "new task" (which was never executed yet). May block internal channel is full. +// Expecting already-ordered tasks. +func (q *QueueWithRetry) Add(ctx context.Context, t *TxTask) { + select { + case q.newTasks <- t: + case <-ctx.Done(): + return + } +} + +// ReTry returns failed (conflicted) task. It's non-blocking method. +// All failed tasks have higher priority than new one. +// No limit on amount of txs added by this method. +func (q *QueueWithRetry) ReTry(t *TxTask) { + q.retiresLock.Lock() + heap.Push(&q.retires, t) + q.retiresLock.Unlock() + if q.closed { + return + } + select { + case q.newTasks <- nil: + default: + } +} + +// Next - blocks until new task available +func (q *QueueWithRetry) Next(ctx context.Context) (*TxTask, bool) { + task, ok := q.popNoWait() + if ok { + return task, true + } + return q.popWait(ctx) +} + +func (q *QueueWithRetry) popWait(ctx context.Context) (task *TxTask, ok bool) { + for { + select { + case inTask, ok := <-q.newTasks: + if !ok { + q.retiresLock.Lock() + if q.retires.Len() > 0 { + task = heap.Pop(&q.retires).(*TxTask) + } + q.retiresLock.Unlock() + return task, task != nil + } + + q.retiresLock.Lock() + if inTask != nil { + heap.Push(&q.retires, inTask) + } + if q.retires.Len() > 0 { + task = heap.Pop(&q.retires).(*TxTask) + } + q.retiresLock.Unlock() + if task != nil { + return task, true + } + case <-ctx.Done(): + return nil, false + } + } +} +func (q *QueueWithRetry) popNoWait() (task *TxTask, ok bool) { + q.retiresLock.Lock() + has := q.retires.Len() > 0 + if has { // means have conflicts to re-exec: it has higher priority than new tasks + task = heap.Pop(&q.retires).(*TxTask) + } + q.retiresLock.Unlock() + + if has { + return task, task != nil + } + + // otherwise get some new task. non-blocking way. without adding to queue. + for task == nil { + select { + case task, ok = <-q.newTasks: + if !ok { + + return nil, false + } + default: + return nil, false + } + } + return task, task != nil +} + +// Close safe to call multiple times +func (q *QueueWithRetry) Close() { + if q.closed { + return + } + q.closed = true + close(q.newTasks) +} + +// ResultsQueue thread-safe priority-queue of execution results +type ResultsQueue struct { + limit int + closed bool + + resultCh chan *TxTask + iter *ResultsQueueIter + + sync.Mutex + results *TxTaskQueue +} + +func NewResultsQueue(newTasksLimit, queueLimit int) *ResultsQueue { + r := &ResultsQueue{ + results: &TxTaskQueue{}, + limit: queueLimit, + resultCh: make(chan *TxTask, newTasksLimit), + } + heap.Init(r.results) + r.iter = &ResultsQueueIter{q: r, results: r.results} + return r +} + +// Add result of execution. May block when internal channel is full +func (q *ResultsQueue) Add(ctx context.Context, task *TxTask) error { + select { + case q.resultCh <- task: // Needs to have outside of the lock + case <-ctx.Done(): + return ctx.Err() + } + return nil +} +func (q *ResultsQueue) drainNoBlock(task *TxTask) { + q.Lock() + defer q.Unlock() + if task != nil { + heap.Push(q.results, task) + } + + for { + select { + case txTask, ok := <-q.resultCh: + if !ok { + return + } + if txTask != nil { + heap.Push(q.results, txTask) + } + default: // we are inside mutex section, can't block here + return + } + } +} + +func (q *ResultsQueue) Iter() *ResultsQueueIter { + q.Lock() + q.iter.needUnlock = true + return q.iter +} +func (q *ResultsQueue) IterLocked() *ResultsQueueIter { + q.iter.needUnlock = false + return q.iter +} + +type ResultsQueueIter struct { + q *ResultsQueue + results *TxTaskQueue //pointer to `q.results` - just to reduce amount of dereferences + needUnlock bool +} + +func (q *ResultsQueueIter) Close() { + if q.needUnlock { + q.q.Unlock() + } +} +func (q *ResultsQueueIter) HasNext(outputTxNum uint64) bool { + return len(*q.results) > 0 && (*q.results)[0].TxNum == outputTxNum +} +func (q *ResultsQueueIter) PopNext() *TxTask { + return heap.Pop(q.results).(*TxTask) +} + +func (q *ResultsQueue) Drain(ctx context.Context) error { + select { + case <-ctx.Done(): + return ctx.Err() + case txTask, ok := <-q.resultCh: + if !ok { + return nil + } + q.drainNoBlock(txTask) + } + return nil +} +func (q *ResultsQueue) DrainNonBlocking() { q.drainNoBlock(nil) } + +func (q *ResultsQueue) DrainLocked() { + var drained bool + for !drained { + select { + case txTask, ok := <-q.resultCh: + if !ok { + return + } + heap.Push(q.results, txTask) + default: + drained = true + } + } +} +func (q *ResultsQueue) DropResults(f func(t *TxTask)) { + q.Lock() + defer q.Unlock() +Loop: + for { + select { + case txTask, ok := <-q.resultCh: + if !ok { + break Loop + } + f(txTask) + default: + break Loop + } + } + + // Drain results queue as well + for q.results.Len() > 0 { + f(heap.Pop(q.results).(*TxTask)) + } +} + +func (q *ResultsQueue) Close() { + if q.closed { + return + } + q.closed = true + close(q.resultCh) +} +func (q *ResultsQueue) ResultChLen() int { return len(q.resultCh) } +func (q *ResultsQueue) ResultChCap() int { return cap(q.resultCh) } +func (q *ResultsQueue) Limit() int { return q.limit } +func (q *ResultsQueue) Len() (l int) { + q.Lock() + l = q.results.Len() + q.Unlock() + return l +} +func (q *ResultsQueue) FirstTxNumLocked() uint64 { return (*q.results)[0].TxNum } +func (q *ResultsQueue) LenLocked() (l int) { return q.results.Len() } +func (q *ResultsQueue) HasLocked() bool { return len(*q.results) > 0 } +func (q *ResultsQueue) PushLocked(t *TxTask) { heap.Push(q.results, t) } +func (q *ResultsQueue) Push(t *TxTask) { + q.Lock() + heap.Push(q.results, t) + q.Unlock() +} +func (q *ResultsQueue) PopLocked() (t *TxTask) { + return heap.Pop(q.results).(*TxTask) +} +func (q *ResultsQueue) Dbg() (t *TxTask) { + if len(*q.results) > 0 { + return (*q.results)[0] + } + return nil +} diff --git a/cmd/state/exec3/state.go b/cmd/state/exec3/state.go index 8c204dec37e..dc50c649acb 100644 --- a/cmd/state/exec3/state.go +++ b/cmd/state/exec3/state.go @@ -5,11 +5,12 @@ import ( "math/big" "sync" + "github.com/ledgerwatch/log/v3" + "golang.org/x/sync/errgroup" + "github.com/ledgerwatch/erigon-lib/chain" libcommon "github.com/ledgerwatch/erigon-lib/common" "github.com/ledgerwatch/erigon-lib/kv" - "github.com/ledgerwatch/log/v3" - "golang.org/x/sync/errgroup" "github.com/ledgerwatch/erigon/cmd/state/exec22" "github.com/ledgerwatch/erigon/consensus" @@ -30,6 +31,7 @@ type Worker struct { chainTx kv.Tx background bool // if true - worker does manage RoTx (begin/rollback) in .ResetTx() blockReader services.FullBlockReader + in *exec22.QueueWithRetry rs *state.StateV3 stateWriter *state.StateWriterV3 stateReader *state.StateReaderV3 @@ -38,10 +40,8 @@ type Worker struct { ctx context.Context engine consensus.Engine - logger log.Logger - genesis *core.Genesis - resultCh chan *exec22.TxTask - epoch EpochReader + genesis *types.Genesis + resultCh *exec22.ResultsQueue chain ChainReader isPoSA bool posa consensus.PoSA @@ -53,10 +53,11 @@ type Worker struct { ibs *state.IntraBlockState } -func NewWorker(lock sync.Locker, ctx context.Context, background bool, chainDb kv.RoDB, rs *state.StateV3, blockReader services.FullBlockReader, chainConfig *chain.Config, logger log.Logger, genesis *core.Genesis, resultCh chan *exec22.TxTask, engine consensus.Engine) *Worker { +func NewWorker(lock sync.Locker, ctx context.Context, background bool, chainDb kv.RoDB, rs *state.StateV3, in *exec22.QueueWithRetry, blockReader services.FullBlockReader, chainConfig *chain.Config, genesis *types.Genesis, results *exec22.ResultsQueue, engine consensus.Engine) *Worker { w := &Worker{ lock: lock, chainDb: chainDb, + in: in, rs: rs, background: background, blockReader: blockReader, @@ -65,9 +66,8 @@ func NewWorker(lock sync.Locker, ctx context.Context, background bool, chainDb k chainConfig: chainConfig, ctx: ctx, - logger: logger, genesis: genesis, - resultCh: resultCh, + resultCh: results, engine: engine, evm: vm.NewEVM(evmtypes.BlockContext{}, evmtypes.TxContext{}, nil, chainConfig, vm.Config{}), @@ -85,6 +85,7 @@ func NewWorker(lock sync.Locker, ctx context.Context, background bool, chainDb k w.ibs = state.New(w.stateReader) w.posa, w.isPoSA = engine.(consensus.PoSA) + return w } @@ -98,18 +99,15 @@ func (rw *Worker) ResetTx(chainTx kv.Tx) { if chainTx != nil { rw.chainTx = chainTx rw.stateReader.SetTx(rw.chainTx) - rw.epoch = EpochReader{tx: rw.chainTx} rw.chain = ChainReader{config: rw.chainConfig, tx: rw.chainTx, blockReader: rw.blockReader} } } func (rw *Worker) Run() error { - for txTask, ok := rw.rs.Schedule(); ok; txTask, ok = rw.rs.Schedule() { + for txTask, ok := rw.in.Next(rw.ctx); ok; txTask, ok = rw.in.Next(rw.ctx) { rw.RunTxTask(txTask) - select { - case rw.resultCh <- txTask: // Needs to have outside of the lock - case <-rw.ctx.Done(): - return rw.ctx.Err() + if err := rw.resultCh.Add(rw.ctx, txTask); err != nil { + return err } } return nil @@ -128,7 +126,6 @@ func (rw *Worker) RunTxTaskNoLock(txTask *exec22.TxTask) { panic(err) } rw.stateReader.SetTx(rw.chainTx) - rw.epoch = EpochReader{tx: rw.chainTx} rw.chain = ChainReader{config: rw.chainConfig, tx: rw.chainTx, blockReader: rw.blockReader} } txTask.Error = nil @@ -140,13 +137,13 @@ func (rw *Worker) RunTxTaskNoLock(txTask *exec22.TxTask) { ibs := rw.ibs rules := txTask.Rules - daoForkTx := rw.chainConfig.DAOForkSupport && rw.chainConfig.DAOForkBlock != nil && rw.chainConfig.DAOForkBlock.Uint64() == txTask.BlockNum && txTask.TxIndex == -1 + daoForkTx := rw.chainConfig.DAOForkBlock != nil && rw.chainConfig.DAOForkBlock.Uint64() == txTask.BlockNum && txTask.TxIndex == -1 var err error header := txTask.Header if txTask.BlockNum == 0 && txTask.TxIndex == -1 { //fmt.Printf("txNum=%d, blockNum=%d, Genesis\n", txTask.TxNum, txTask.BlockNum) // Genesis block - _, ibs, err = rw.genesis.ToBlock("") + _, ibs, err = core.GenesisToBlock(rw.genesis, "") if err != nil { panic(err) } @@ -163,21 +160,23 @@ func (rw *Worker) RunTxTaskNoLock(txTask *exec22.TxTask) { systemcontracts.UpgradeBuildInSystemContract(rw.chainConfig, header.Number, ibs) } syscall := func(contract libcommon.Address, data []byte) ([]byte, error) { - return core.SysCallContract(contract, data, *rw.chainConfig, ibs, header, rw.engine, false /* constCall */) + return core.SysCallContract(contract, data, *rw.chainConfig, ibs, header, rw.engine, false /* constCall */, nil /*excessDataGas*/) } - rw.engine.Initialize(rw.chainConfig, rw.chain, rw.epoch, header, ibs, txTask.Txs, txTask.Uncles, syscall) + rw.engine.Initialize(rw.chainConfig, rw.chain, header, ibs, txTask.Txs, txTask.Uncles, syscall) } else if txTask.Final { if txTask.BlockNum > 0 { //fmt.Printf("txNum=%d, blockNum=%d, finalisation of the block\n", txTask.TxNum, txTask.BlockNum) // End of block transaction in a block syscall := func(contract libcommon.Address, data []byte) ([]byte, error) { - return core.SysCallContract(contract, data, *rw.chainConfig, ibs, header, rw.engine, false /* constCall */) + return core.SysCallContract(contract, data, *rw.chainConfig, ibs, header, rw.engine, false /* constCall */, nil /*excessDataGas*/) } - if _, _, err := rw.engine.Finalize(rw.chainConfig, types.CopyHeader(header), ibs, txTask.Txs, txTask.Uncles, nil /* receipts */, txTask.Withdrawals, rw.epoch, rw.chain, syscall); err != nil { + if _, _, err := rw.engine.Finalize(rw.chainConfig, types.CopyHeader(header), ibs, txTask.Txs, txTask.Uncles, nil, txTask.Withdrawals, rw.chain, syscall); err != nil { //fmt.Printf("error=%v\n", err) txTask.Error = err } else { + //rw.callTracer.AddCoinbase(txTask.Coinbase, txTask.Uncles) + //txTask.TraceTos = rw.callTracer.Tos() txTask.TraceTos = map[libcommon.Address]struct{}{} txTask.TraceTos[txTask.Coinbase] = struct{}{} for _, uncle := range txTask.Uncles { @@ -205,7 +204,7 @@ func (rw *Worker) RunTxTaskNoLock(txTask *exec22.TxTask) { blockContext := txTask.EvmBlockContext if !rw.background { getHashFn := core.GetHashFn(header, rw.getHeader) - blockContext = core.NewEVMBlockContext(header, getHashFn, rw.engine, nil /* author */) + blockContext = core.NewEVMBlockContext(header, getHashFn, rw.engine, nil /* author */, nil /*excessDataGas*/) } rw.evm.ResetBetweenBlocks(blockContext, core.NewEVMTxContext(msg), ibs, vmConfig, rules) vmenv := rw.evm @@ -235,24 +234,6 @@ func (rw *Worker) RunTxTaskNoLock(txTask *exec22.TxTask) { txTask.ReadLists = rw.stateReader.ReadSet() txTask.WriteLists = rw.stateWriter.WriteSet() txTask.AccountPrevs, txTask.AccountDels, txTask.StoragePrevs, txTask.CodePrevs = rw.stateWriter.PrevAndDels() - size := (20 + 32) * len(txTask.BalanceIncreaseSet) - for _, list := range txTask.ReadLists { - for _, b := range list.Keys { - size += len(b) - } - for _, b := range list.Vals { - size += len(b) - } - } - for _, list := range txTask.WriteLists { - for _, b := range list.Keys { - size += len(b) - } - for _, b := range list.Vals { - size += len(b) - } - } - txTask.ResultsSize = int64(size) } } @@ -303,39 +284,18 @@ func (cr ChainReader) GetTd(hash libcommon.Hash, number uint64) *big.Int { return td } -type EpochReader struct { - tx kv.Tx -} - -func NewEpochReader(tx kv.Tx) EpochReader { return EpochReader{tx: tx} } - -func (cr EpochReader) GetEpoch(hash libcommon.Hash, number uint64) ([]byte, error) { - return rawdb.ReadEpoch(cr.tx, number, hash) -} -func (cr EpochReader) PutEpoch(hash libcommon.Hash, number uint64, proof []byte) error { - panic("") -} -func (cr EpochReader) GetPendingEpoch(hash libcommon.Hash, number uint64) ([]byte, error) { - return rawdb.ReadPendingEpoch(cr.tx, number, hash) -} -func (cr EpochReader) PutPendingEpoch(hash libcommon.Hash, number uint64, proof []byte) error { - panic("") -} -func (cr EpochReader) FindBeforeOrEqualNumber(number uint64) (blockNum uint64, blockHash libcommon.Hash, transitionProof []byte, err error) { - return rawdb.FindEpochBeforeOrEqualNumber(cr.tx, number) -} - -func NewWorkersPool(lock sync.Locker, ctx context.Context, background bool, chainDb kv.RoDB, rs *state.StateV3, blockReader services.FullBlockReader, chainConfig *chain.Config, logger log.Logger, genesis *core.Genesis, engine consensus.Engine, workerCount int) (reconWorkers []*Worker, applyWorker *Worker, resultCh chan *exec22.TxTask, clear func(), wait func()) { - queueSize := workerCount * 256 +func NewWorkersPool(lock sync.Locker, ctx context.Context, background bool, chainDb kv.RoDB, rs *state.StateV3, in *exec22.QueueWithRetry, blockReader services.FullBlockReader, chainConfig *chain.Config, genesis *types.Genesis, engine consensus.Engine, workerCount int) (reconWorkers []*Worker, applyWorker *Worker, rws *exec22.ResultsQueue, clear func(), wait func()) { reconWorkers = make([]*Worker, workerCount) - resultCh = make(chan *exec22.TxTask, queueSize) + + resultChSize := workerCount * 8 + rws = exec22.NewResultsQueue(resultChSize, workerCount) // workerCount * 4 { // we all errors in background workers (except ctx.Cancele), because applyLoop will detect this error anyway. // and in applyLoop all errors are critical ctx, cancel := context.WithCancel(ctx) g, ctx := errgroup.WithContext(ctx) for i := 0; i < workerCount; i++ { - reconWorkers[i] = NewWorker(lock, ctx, background, chainDb, rs, blockReader, chainConfig, logger, genesis, resultCh, engine) + reconWorkers[i] = NewWorker(lock, ctx, background, chainDb, rs, in, blockReader, chainConfig, genesis, rws, engine) } if background { for i := 0; i < workerCount; i++ { @@ -359,10 +319,9 @@ func NewWorkersPool(lock sync.Locker, ctx context.Context, background bool, chai w.ResetTx(nil) } //applyWorker.ResetTx(nil) - close(resultCh) } } - applyWorker = NewWorker(lock, ctx, false, chainDb, rs, blockReader, chainConfig, logger, genesis, resultCh, engine) + applyWorker = NewWorker(lock, ctx, false, chainDb, rs, in, blockReader, chainConfig, genesis, rws, engine) - return reconWorkers, applyWorker, resultCh, clear, wait + return reconWorkers, applyWorker, rws, clear, wait } diff --git a/cmd/state/exec3/state_recon.go b/cmd/state/exec3/state_recon.go index 716e86b82f0..5fbc3d18055 100644 --- a/cmd/state/exec3/state_recon.go +++ b/cmd/state/exec3/state_recon.go @@ -7,13 +7,14 @@ import ( "sync" "github.com/RoaringBitmap/roaring/roaring64" + "github.com/ledgerwatch/log/v3" + "github.com/ledgerwatch/erigon-lib/chain" libcommon "github.com/ledgerwatch/erigon-lib/common" "github.com/ledgerwatch/erigon-lib/common/length" "github.com/ledgerwatch/erigon-lib/etl" "github.com/ledgerwatch/erigon-lib/kv" libstate "github.com/ledgerwatch/erigon-lib/state" - "github.com/ledgerwatch/log/v3" "github.com/ledgerwatch/erigon/cmd/state/exec22" "github.com/ledgerwatch/erigon/common" @@ -30,11 +31,10 @@ import ( ) type ScanWorker struct { - txNum uint64 - as *libstate.AggregatorStep - fromKey, toKey []byte - currentKey []byte - bitmap roaring64.Bitmap + txNum uint64 + as *libstate.AggregatorStep + toKey []byte + bitmap roaring64.Bitmap } func NewScanWorker(txNum uint64, as *libstate.AggregatorStep) *ScanWorker { @@ -58,13 +58,13 @@ func NewFillWorker(txNum uint64, as *libstate.AggregatorStep) *FillWorker { return fw } -func (fw *FillWorker) FillAccounts(plainStateCollector *etl.Collector) { +func (fw *FillWorker) FillAccounts(plainStateCollector *etl.Collector) error { it := fw.as.IterateAccountsHistory(fw.txNum) value := make([]byte, 1024) for it.HasNext() { key, val, err := it.Next() if err != nil { - panic(err) + return err } if len(val) > 0 { var a accounts.Account @@ -102,42 +102,44 @@ func (fw *FillWorker) FillAccounts(plainStateCollector *etl.Collector) { value = value[:a.EncodingLengthForStorage()] a.EncodeForStorage(value) if err := plainStateCollector.Collect(key, value); err != nil { - panic(err) + return err } //fmt.Printf("Account [%x]=>{Balance: %d, Nonce: %d, Root: %x, CodeHash: %x}\n", key, &a.Balance, a.Nonce, a.Root, a.CodeHash) } else { if err := plainStateCollector.Collect(key, nil); err != nil { - panic(err) + return err } } } + return nil } -func (fw *FillWorker) FillStorage(plainStateCollector *etl.Collector) { +func (fw *FillWorker) FillStorage(plainStateCollector *etl.Collector) error { it := fw.as.IterateStorageHistory(fw.txNum) var compositeKey = make([]byte, length.Addr+length.Incarnation+length.Hash) binary.BigEndian.PutUint64(compositeKey[20:], state.FirstContractIncarnation) for it.HasNext() { key, val, err := it.Next() if err != nil { - panic(err) + return err } copy(compositeKey[:20], key[:20]) copy(compositeKey[20+8:], key[20:]) if len(val) > 0 { if err := plainStateCollector.Collect(compositeKey, val); err != nil { - panic(err) + return err } //fmt.Printf("Storage [%x] => [%x]\n", compositeKey, val) } else { if err := plainStateCollector.Collect(compositeKey, nil); err != nil { - panic(err) + return err } } } + return nil } -func (fw *FillWorker) FillCode(codeCollector, plainContractCollector *etl.Collector) { +func (fw *FillWorker) FillCode(codeCollector, plainContractCollector *etl.Collector) error { it := fw.as.IterateCodeHistory(fw.txNum) var compositeKey = make([]byte, length.Addr+length.Incarnation) binary.BigEndian.PutUint64(compositeKey[length.Addr:], state.FirstContractIncarnation) @@ -145,28 +147,29 @@ func (fw *FillWorker) FillCode(codeCollector, plainContractCollector *etl.Collec for it.HasNext() { key, val, err := it.Next() if err != nil { - panic(err) + return err } copy(compositeKey, key) if len(val) > 0 { codeHash, err := common.HashData(val) if err != nil { - panic(err) + return err } if err = codeCollector.Collect(codeHash[:], val); err != nil { - panic(err) + return err } if err = plainContractCollector.Collect(compositeKey, codeHash[:]); err != nil { - panic(err) + return err } //fmt.Printf("Code [%x] => %d\n", compositeKey, len(val)) } else { if err := plainContractCollector.Collect(compositeKey, nil); err != nil { - panic(err) + return err } } } + return nil } func (sw *ScanWorker) BitmapAccounts() error { @@ -219,7 +222,6 @@ func (sw *ScanWorker) Bitmap() *roaring64.Bitmap { return &sw.bitmap } type ReconWorker struct { lock sync.Locker - wg *sync.WaitGroup rs *state.ReconState blockReader services.FullBlockReader stateWriter *state.StateReconWriterInc @@ -228,8 +230,7 @@ type ReconWorker struct { engine consensus.Engine chainConfig *chain.Config logger log.Logger - genesis *core.Genesis - epoch EpochReader + genesis *types.Genesis chain ChainReader isPoSA bool posa consensus.PoSA @@ -238,17 +239,16 @@ type ReconWorker struct { ibs *state.IntraBlockState } -func NewReconWorker(lock sync.Locker, wg *sync.WaitGroup, rs *state.ReconState, +func NewReconWorker(lock sync.Locker, ctx context.Context, rs *state.ReconState, as *libstate.AggregatorStep, blockReader services.FullBlockReader, - chainConfig *chain.Config, logger log.Logger, genesis *core.Genesis, engine consensus.Engine, + chainConfig *chain.Config, logger log.Logger, genesis *types.Genesis, engine consensus.Engine, chainTx kv.Tx, ) *ReconWorker { rw := &ReconWorker{ lock: lock, - wg: wg, + ctx: ctx, rs: rs, blockReader: blockReader, - ctx: context.Background(), stateWriter: state.NewStateReconWriterInc(as, rs), stateReader: state.NewHistoryReaderInc(as, rs), chainConfig: chainConfig, @@ -257,7 +257,6 @@ func NewReconWorker(lock sync.Locker, wg *sync.WaitGroup, rs *state.ReconState, engine: engine, evm: vm.NewEVM(evmtypes.BlockContext{}, evmtypes.TxContext{}, nil, chainConfig, vm.Config{}), } - rw.epoch = NewEpochReader(chainTx) rw.chain = NewChainReader(chainConfig, chainTx, blockReader) rw.ibs = state.New(rw.stateReader) rw.posa, rw.isPoSA = engine.(consensus.PoSA) @@ -274,16 +273,21 @@ func (rw *ReconWorker) SetChainTx(chainTx kv.Tx) { rw.stateWriter.SetChainTx(chainTx) } -func (rw *ReconWorker) Run() { - defer rw.wg.Done() - for txTask, ok := rw.rs.Schedule(); ok; txTask, ok = rw.rs.Schedule() { - rw.runTxTask(txTask) +func (rw *ReconWorker) Run() error { + for txTask, ok, err := rw.rs.Schedule(rw.ctx); ok || err != nil; txTask, ok, err = rw.rs.Schedule(rw.ctx) { + if err != nil { + return err + } + if err := rw.runTxTask(txTask); err != nil { + return err + } } + return nil } var noop = state.NewNoopWriter() -func (rw *ReconWorker) runTxTask(txTask *exec22.TxTask) { +func (rw *ReconWorker) runTxTask(txTask *exec22.TxTask) error { rw.lock.Lock() defer rw.lock.Unlock() rw.stateReader.SetTxNum(txTask.TxNum) @@ -292,14 +296,14 @@ func (rw *ReconWorker) runTxTask(txTask *exec22.TxTask) { rw.ibs.Reset() ibs := rw.ibs rules := txTask.Rules - daoForkTx := rw.chainConfig.DAOForkSupport && rw.chainConfig.DAOForkBlock != nil && rw.chainConfig.DAOForkBlock.Uint64() == txTask.BlockNum && txTask.TxIndex == -1 + daoForkTx := rw.chainConfig.DAOForkBlock != nil && rw.chainConfig.DAOForkBlock.Uint64() == txTask.BlockNum && txTask.TxIndex == -1 var err error if txTask.BlockNum == 0 && txTask.TxIndex == -1 { //fmt.Printf("txNum=%d, blockNum=%d, Genesis\n", txTask.TxNum, txTask.BlockNum) // Genesis block - _, ibs, err = rw.genesis.ToBlock("") + _, ibs, err = core.GenesisToBlock(rw.genesis, "") if err != nil { - panic(err) + return err } // For Genesis, rules should be empty, so that empty accounts can be included rules = &chain.Rules{} @@ -312,11 +316,11 @@ func (rw *ReconWorker) runTxTask(txTask *exec22.TxTask) { //fmt.Printf("txNum=%d, blockNum=%d, finalisation of the block\n", txTask.TxNum, txTask.BlockNum) // End of block transaction in a block syscall := func(contract libcommon.Address, data []byte) ([]byte, error) { - return core.SysCallContract(contract, data, *rw.chainConfig, ibs, txTask.Header, rw.engine, false /* constCall */) + return core.SysCallContract(contract, data, *rw.chainConfig, ibs, txTask.Header, rw.engine, false /* constCall */, nil /*excessDataGas*/) } - if _, _, err := rw.engine.Finalize(rw.chainConfig, types.CopyHeader(txTask.Header), ibs, txTask.Txs, txTask.Uncles, nil /* receipts */, txTask.Withdrawals, rw.epoch, rw.chain, syscall); err != nil { + if _, _, err := rw.engine.Finalize(rw.chainConfig, types.CopyHeader(txTask.Header), ibs, txTask.Txs, txTask.Uncles, nil, txTask.Withdrawals, rw.chain, syscall); err != nil { if _, readError := rw.stateReader.ReadError(); !readError { - panic(fmt.Errorf("finalize of block %d failed: %w", txTask.BlockNum, err)) + return fmt.Errorf("finalize of block %d failed: %w", txTask.BlockNum, err) } } } @@ -326,18 +330,18 @@ func (rw *ReconWorker) runTxTask(txTask *exec22.TxTask) { systemcontracts.UpgradeBuildInSystemContract(rw.chainConfig, txTask.Header.Number, ibs) } syscall := func(contract libcommon.Address, data []byte) ([]byte, error) { - return core.SysCallContract(contract, data, *rw.chainConfig, ibs, txTask.Header, rw.engine, false /* constCall */) + return core.SysCallContract(contract, data, *rw.chainConfig, ibs, txTask.Header, rw.engine, false /* constCall */, nil /*excessDataGas*/) } - rw.engine.Initialize(rw.chainConfig, rw.chain, rw.epoch, txTask.Header, ibs, txTask.Txs, txTask.Uncles, syscall) + rw.engine.Initialize(rw.chainConfig, rw.chain, txTask.Header, ibs, txTask.Txs, txTask.Uncles, syscall) } else { if rw.isPoSA { if isSystemTx, err := rw.posa.IsSystemTransaction(txTask.Tx, txTask.Header); err != nil { if _, readError := rw.stateReader.ReadError(); !readError { - panic(err) + return err } } else if isSystemTx { - return + return nil } } gp := new(core.GasPool).AddGas(txTask.Tx.GetGas()) @@ -351,12 +355,12 @@ func (rw *ReconWorker) runTxTask(txTask *exec22.TxTask) { _, err = core.ApplyMessage(vmenv, msg, gp, true /* refunds */, false /* gasBailout */) if err != nil { if _, readError := rw.stateReader.ReadError(); !readError { - panic(fmt.Errorf("could not apply blockNum=%d, txIdx=%d txNum=%d [%x] failed: %w", txTask.BlockNum, txTask.TxIndex, txTask.TxNum, txTask.Tx.Hash(), err)) + return fmt.Errorf("could not apply blockNum=%d, txIdx=%d txNum=%d [%x] failed: %w", txTask.BlockNum, txTask.TxIndex, txTask.TxNum, txTask.Tx.Hash(), err) } } if err = ibs.FinalizeTx(rules, noop); err != nil { if _, readError := rw.stateReader.ReadError(); !readError { - panic(err) + return err } } } @@ -365,9 +369,10 @@ func (rw *ReconWorker) runTxTask(txTask *exec22.TxTask) { rw.rs.RollbackTx(txTask, dependency) } else { if err = ibs.CommitBlock(rules, rw.stateWriter); err != nil { - panic(err) + return err } //fmt.Printf("commit %d\n", txNum) rw.rs.CommitTxNum(txTask.TxNum) } + return nil } diff --git a/cmd/txpool/main.go b/cmd/txpool/main.go index 7ca936f3718..138d871b7c2 100644 --- a/cmd/txpool/main.go +++ b/cmd/txpool/main.go @@ -19,9 +19,11 @@ import ( "github.com/ledgerwatch/erigon-lib/kv/remotedb" "github.com/ledgerwatch/erigon-lib/kv/remotedbserver" "github.com/ledgerwatch/erigon-lib/txpool" + "github.com/ledgerwatch/erigon-lib/txpool/txpoolcfg" "github.com/ledgerwatch/erigon-lib/txpool/txpooluitl" "github.com/ledgerwatch/erigon-lib/types" "github.com/ledgerwatch/erigon/cmd/rpcdaemon/rpcdaemontest" + common2 "github.com/ledgerwatch/erigon/common" "github.com/ledgerwatch/erigon/ethdb/privateapi" "github.com/ledgerwatch/log/v3" "github.com/spf13/cobra" @@ -29,7 +31,7 @@ import ( "github.com/ledgerwatch/erigon/cmd/utils" "github.com/ledgerwatch/erigon/common/paths" "github.com/ledgerwatch/erigon/turbo/debug" - logging2 "github.com/ledgerwatch/erigon/turbo/logging" + "github.com/ledgerwatch/erigon/turbo/logging" ) var ( @@ -50,10 +52,12 @@ var ( priceLimit uint64 accountSlots uint64 priceBump uint64 + + commitEvery time.Duration ) func init() { - utils.CobraFlags(rootCmd, debug.Flags, utils.MetricFlags, logging2.Flags) + utils.CobraFlags(rootCmd, debug.Flags, utils.MetricFlags, logging.Flags) rootCmd.Flags().StringSliceVar(&sentryAddr, "sentry.api.addr", []string{"localhost:9091"}, "comma separated sentry addresses ':,:'") rootCmd.Flags().StringVar(&privateApiAddr, "private.api.addr", "localhost:9090", "execution service :") rootCmd.Flags().StringVar(&txpoolApiAddr, "txpool.api.addr", "localhost:9094", "txpool service :") @@ -65,12 +69,13 @@ func init() { rootCmd.PersistentFlags().StringVar(&TLSKeyFile, "tls.key", "", "key file for client side TLS handshake") rootCmd.PersistentFlags().StringVar(&TLSCACert, "tls.cacert", "", "CA certificate for client side TLS handshake") - rootCmd.PersistentFlags().IntVar(&pendingPoolLimit, "txpool.globalslots", txpool.DefaultConfig.PendingSubPoolLimit, "Maximum number of executable transaction slots for all accounts") - rootCmd.PersistentFlags().IntVar(&baseFeePoolLimit, "txpool.globalbasefeeeslots", txpool.DefaultConfig.BaseFeeSubPoolLimit, "Maximum number of non-executable transactions where only not enough baseFee") - rootCmd.PersistentFlags().IntVar(&queuedPoolLimit, "txpool.globalqueue", txpool.DefaultConfig.QueuedSubPoolLimit, "Maximum number of non-executable transaction slots for all accounts") - rootCmd.PersistentFlags().Uint64Var(&priceLimit, "txpool.pricelimit", txpool.DefaultConfig.MinFeeCap, "Minimum gas price (fee cap) limit to enforce for acceptance into the pool") - rootCmd.PersistentFlags().Uint64Var(&accountSlots, "txpool.accountslots", txpool.DefaultConfig.AccountSlots, "Minimum number of executable transaction slots guaranteed per account") - rootCmd.PersistentFlags().Uint64Var(&priceBump, "txpool.pricebump", txpool.DefaultConfig.PriceBump, "Price bump percentage to replace an already existing transaction") + rootCmd.PersistentFlags().IntVar(&pendingPoolLimit, "txpool.globalslots", txpoolcfg.DefaultConfig.PendingSubPoolLimit, "Maximum number of executable transaction slots for all accounts") + rootCmd.PersistentFlags().IntVar(&baseFeePoolLimit, "txpool.globalbasefeeslots", txpoolcfg.DefaultConfig.BaseFeeSubPoolLimit, "Maximum number of non-executable transactions where only not enough baseFee") + rootCmd.PersistentFlags().IntVar(&queuedPoolLimit, "txpool.globalqueue", txpoolcfg.DefaultConfig.QueuedSubPoolLimit, "Maximum number of non-executable transaction slots for all accounts") + rootCmd.PersistentFlags().Uint64Var(&priceLimit, "txpool.pricelimit", txpoolcfg.DefaultConfig.MinFeeCap, "Minimum gas price (fee cap) limit to enforce for acceptance into the pool") + rootCmd.PersistentFlags().Uint64Var(&accountSlots, "txpool.accountslots", txpoolcfg.DefaultConfig.AccountSlots, "Minimum number of executable transaction slots guaranteed per account") + rootCmd.PersistentFlags().Uint64Var(&priceBump, "txpool.pricebump", txpoolcfg.DefaultConfig.PriceBump, "Price bump percentage to replace an already existing transaction") + rootCmd.PersistentFlags().DurationVar(&commitEvery, utils.TxPoolCommitEveryFlag.Name, utils.TxPoolCommitEveryFlag.Value, utils.TxPoolCommitEveryFlag.Usage) rootCmd.Flags().StringSliceVar(&traceSenders, utils.TxPoolTraceSendersFlag.Name, []string{}, utils.TxPoolTraceSendersFlag.Usage) } @@ -84,7 +89,7 @@ var rootCmd = &cobra.Command{ debug.Exit() }, Run: func(cmd *cobra.Command, args []string) { - _ = logging2.GetLoggerCmd("txpool", cmd) + logging.SetupLoggerCmd("txpool", cmd) if err := doTxpool(cmd.Context()); err != nil { if !errors.Is(err, context.Canceled) { @@ -127,11 +132,12 @@ func doTxpool(ctx context.Context) error { sentryClients[i] = direct.NewSentryClientRemote(proto_sentry.NewSentryClient(sentryConn)) } - cfg := txpool.DefaultConfig + cfg := txpoolcfg.DefaultConfig dirs := datadir.New(datadirCli) cfg.DBDir = dirs.TxPool - cfg.CommitEvery = 30 * time.Second + + cfg.CommitEvery = common2.RandomizeDuration(commitEvery) cfg.PendingSubPoolLimit = pendingPoolLimit cfg.BaseFeeSubPoolLimit = baseFeePoolLimit cfg.QueuedSubPoolLimit = queuedPoolLimit diff --git a/cmd/txpool/readme.md b/cmd/txpool/readme.md index a3077ea7b8d..12b1f2bdaff 100644 --- a/cmd/txpool/readme.md +++ b/cmd/txpool/readme.md @@ -27,7 +27,7 @@ make txpool # --private.api.addr - connect to Erigon's grpc api # --sentry.api.addr - connect to Sentry's grpc api # --txpool.api.addr - other services to connect TxPool's grpc api -# Increase limits flags: --txpool.globalslots, --txpool.globalbasefeeeslots, --txpool.globalqueue +# Increase limits flags: --txpool.globalslots, --txpool.globalbasefeeslots, --txpool.globalqueue # --txpool.trace.senders - print more logs about Txs with senders in this list ./build/bin/txpool --private.api.addr=localhost:9090 --sentry.api.addr=localhost:9091 --txpool.api.addr=localhost:9094 --datadir= diff --git a/cmd/utils/customflags_test.go b/cmd/utils/customflags_test.go deleted file mode 100644 index de39ca36a11..00000000000 --- a/cmd/utils/customflags_test.go +++ /dev/null @@ -1,41 +0,0 @@ -// Copyright 2015 The go-ethereum Authors -// This file is part of go-ethereum. -// -// go-ethereum is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// go-ethereum is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with go-ethereum. If not, see . - -package utils - -import ( - "os" - "os/user" - "testing" -) - -func TestPathExpansion(t *testing.T) { - user, _ := user.Current() - tests := map[string]string{ - "/home/someuser/tmp": "/home/someuser/tmp", - "~/tmp": user.HomeDir + "/tmp", - "~thisOtherUser/b/": "~thisOtherUser/b", - "$DDDXXX/a/b": "/tmp/a/b", - "/a/b/": "/a/b", - } - os.Setenv("DDDXXX", "/tmp") - for test, expected := range tests { - got := expandPath(test) - if got != expected { - t.Errorf("test %s, got %s, expected %s\n", test, got, expected) - } - } -} diff --git a/cmd/utils/diskusage_windows.go b/cmd/utils/diskusage_windows.go deleted file mode 100644 index 75e76500ded..00000000000 --- a/cmd/utils/diskusage_windows.go +++ /dev/null @@ -1,38 +0,0 @@ -// Copyright 2021 The go-ethereum Authors -// This file is part of the go-ethereum library. -// -// The go-ethereum library is free software: you can redistribute it and/or modify -// it under the terms of the GNU Lesser General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// The go-ethereum library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public License -// along with the go-ethereum library. If not, see . - -package utils - -import ( - "fmt" - - "golang.org/x/sys/windows" -) - -func getFreeDiskSpace(path string) (uint64, error) { - - cwd, err := windows.UTF16PtrFromString(path) - if err != nil { - return 0, fmt.Errorf("failed to call UTF16PtrFromString: %w", err) - } - - var freeBytesAvailableToCaller, totalNumberOfBytes, totalNumberOfFreeBytes uint64 - if err := windows.GetDiskFreeSpaceEx(cwd, &freeBytesAvailableToCaller, &totalNumberOfBytes, &totalNumberOfFreeBytes); err != nil { - return 0, fmt.Errorf("failed to call GetDiskFreeSpaceEx: %w", err) - } - - return freeBytesAvailableToCaller, nil -} diff --git a/cmd/utils/flags.go b/cmd/utils/flags.go index 423fe073f6e..3f32428ff1b 100644 --- a/cmd/utils/flags.go +++ b/cmd/utils/flags.go @@ -34,7 +34,11 @@ import ( "github.com/ledgerwatch/erigon-lib/common/metrics" downloadercfg2 "github.com/ledgerwatch/erigon-lib/downloader/downloadercfg" "github.com/ledgerwatch/erigon-lib/kv" - "github.com/ledgerwatch/erigon-lib/txpool" + "github.com/ledgerwatch/erigon-lib/txpool/txpoolcfg" + "github.com/ledgerwatch/erigon/cmd/utils/flags" + common2 "github.com/ledgerwatch/erigon/common" + "github.com/ledgerwatch/erigon/consensus/ethash/ethashcfg" + "github.com/ledgerwatch/erigon/eth/gasprice/gaspricecfg" "github.com/ledgerwatch/log/v3" "github.com/spf13/cobra" "github.com/spf13/pflag" @@ -43,11 +47,9 @@ import ( "github.com/ledgerwatch/erigon/cl/clparams" "github.com/ledgerwatch/erigon/cmd/downloader/downloadernat" "github.com/ledgerwatch/erigon/common/paths" - "github.com/ledgerwatch/erigon/consensus/ethash" "github.com/ledgerwatch/erigon/core" "github.com/ledgerwatch/erigon/crypto" "github.com/ledgerwatch/erigon/eth/ethconfig" - "github.com/ledgerwatch/erigon/eth/gasprice" "github.com/ledgerwatch/erigon/eth/protocols/eth" "github.com/ledgerwatch/erigon/node/nodecfg" "github.com/ledgerwatch/erigon/p2p" @@ -67,17 +69,17 @@ import ( var ( // General settings - DataDirFlag = DirectoryFlag{ + DataDirFlag = flags.DirectoryFlag{ Name: "datadir", Usage: "Data directory for the databases", - Value: DirectoryString(paths.DefaultDataDir()), + Value: flags.DirectoryString(paths.DefaultDataDir()), } - AncientFlag = DirectoryFlag{ + AncientFlag = flags.DirectoryFlag{ Name: "datadir.ancient", Usage: "Data directory for ancient chain segments (default = inside chaindata)", } - MinFreeDiskSpaceFlag = DirectoryFlag{ + MinFreeDiskSpaceFlag = flags.DirectoryFlag{ Name: "datadir.minfreedisk", Usage: "Minimum free disk space in MB, once reached triggers auto shut down (default = --cache.gc converted to MB, 0 = disabled)", } @@ -103,7 +105,7 @@ var ( Name: "whitelist", Usage: "Comma separated block number-to-hash mappings to enforce (=)", } - OverrideShanghaiTime = BigFlag{ + OverrideShanghaiTime = flags.BigFlag{ Name: "override.shanghaiTime", Usage: "Manually specify Shanghai fork time, overriding the bundled setting", } @@ -117,10 +119,10 @@ var ( Name: "ethash.cacheslockmmap", Usage: "Lock memory maps of recent ethash caches", } - EthashDatasetDirFlag = DirectoryFlag{ + EthashDatasetDirFlag = flags.DirectoryFlag{ Name: "ethash.dagdir", Usage: "Directory to store the ethash mining DAGs", - Value: DirectoryString(ethconfig.Defaults.Ethash.DatasetDir), + Value: flags.DirectoryString(ethconfig.Defaults.Ethash.DatasetDir), } EthashDatasetsLockMmapFlag = cli.BoolFlag{ Name: "ethash.dagslockmmap", @@ -131,8 +133,8 @@ var ( Usage: `Default: use snapshots "true" for BSC, Mainnet and Goerli. use snapshots "false" in all other cases`, Value: true, } - ExternalConsensusFlag = cli.BoolFlag{ - Name: "externalcl", + InternalConsensusFlag = cli.BoolFlag{ + Name: "internalcl", Usage: "enables external consensus", } // Transaction pool settings @@ -156,7 +158,7 @@ var ( TxPoolPriceBumpFlag = cli.Uint64Flag{ Name: "txpool.pricebump", Usage: "Price bump percentage to replace an already existing transaction", - Value: txpool.DefaultConfig.PriceBump, + Value: txpoolcfg.DefaultConfig.PriceBump, } TxPoolAccountSlotsFlag = cli.Uint64Flag{ Name: "txpool.accountslots", @@ -193,6 +195,11 @@ var ( Usage: "Comma separared list of addresses, whoes transactions will traced in transaction pool with debug printing", Value: "", } + TxPoolCommitEveryFlag = cli.DurationFlag{ + Name: "txpool.commit.every", + Usage: "How often transactions should be committed to the storage", + Value: txpoolcfg.DefaultConfig.CommitEvery, + } // Miner settings MiningEnabledFlag = cli.BoolFlag{ Name: "mine", @@ -211,7 +218,7 @@ var ( Usage: "Target gas limit for mined blocks", Value: ethconfig.Defaults.Miner.GasLimit, } - MinerGasPriceFlag = BigFlag{ + MinerGasPriceFlag = flags.BigFlag{ Name: "miner.gasprice", Usage: "Minimum gas price for mining a transaction", Value: ethconfig.Defaults.Miner.GasPrice, @@ -272,7 +279,7 @@ var ( Name: "ipcdisable", Usage: "Disable the IPC-RPC server", } - IPCPathFlag = DirectoryFlag{ + IPCPathFlag = flags.DirectoryFlag{ Name: "ipcpath", Usage: "Filename for IPC socket/pipe within the datadir (explicit paths escape it)", } @@ -500,6 +507,11 @@ var ( Name: "sentry.log-peer-info", Usage: "Log detailed peer info when a peer connects or disconnects. Enable to integrate with observer.", } + SentryDropUselessPeers = cli.BoolFlag{ + Name: "sentry.drop-useless-peers", + Usage: "Drop useless peers, those returning empty body or header responses", + Value: false, + } DownloaderAddrFlag = cli.StringFlag{ Name: "downloader.api.addr", Usage: "downloader address ':'", @@ -602,10 +614,6 @@ var ( Usage: "Metrics HTTP server listening port", Value: metrics.DefaultConfig.Port, } - MetricsURLsFlag = cli.StringSliceFlag{ - Name: "metrics.urls", - Usage: "Comma separated list of URLs to the metrics endpoints thats are being diagnosed", - } HistoryV3Flag = cli.BoolFlag{ Name: "experimental.history.v3", Usage: "(also known as Erigon3) Not recommended yet: Can't change this flag after node creation. New DB and Snapshots format of history allows: parallel blocks execution, get state as of given transaction without executing whole block.", @@ -630,7 +638,7 @@ var ( Usage: "number of recent block signatures to keep in memory", Value: 16384, } - CliqueDataDirFlag = DirectoryFlag{ + CliqueDataDirFlag = flags.DirectoryFlag{ Name: "clique.datadir", Usage: "a path to clique db folder", Value: "", @@ -664,6 +672,11 @@ var ( Value: 3, Usage: "amount of files to download in parallel. If network has enough seeders 1-3 slot enough, if network has lack of seeders increase to 5-7 (too big value will slow down everything).", } + TorrentStaticPeersFlag = cli.StringFlag{ + Name: "torrent.staticpeers", + Usage: "Comma separated enode URLs to connect to", + Value: "", + } NoDownloaderFlag = cli.BoolFlag{ Name: "no-downloader", Usage: "to disable downloader component", @@ -700,9 +713,14 @@ var ( } DbPageSizeFlag = cli.StringFlag{ Name: "db.pagesize", - Usage: "set mdbx pagesize on db creation: must be power of 2 and '256b <= pagesize <= 64kb'. default: equal to OperationSystem's pageSize", + Usage: "DB is splitted to 'pages' of fixed size. Can't change DB creation. Must be power of 2 and '256b <= pagesize <= 64kb'. Default: equal to OperationSystem's pageSize. Bigger pageSize causing: 1. More writes to disk during commit 2. Smaller b-tree high 3. Less fragmentation 4. Less overhead on 'free-pages list' maintainance (a bit faster Put/Commit) 5. If expecting DB-size > 8Tb then set pageSize >= 8Kb", Value: datasize.ByteSize(kv.DefaultPageSize()).String(), } + DbSizeLimitFlag = cli.StringFlag{ + Name: "db.size.limit", + Usage: "runtime limit of chandata db size. you can change value of this flag at any time", + Value: (7 * datasize.TB).String(), + } HealthCheckFlag = cli.BoolFlag{ Name: "healthcheck", @@ -758,10 +776,6 @@ var ( Usage: "Port for sentinel", Value: 7777, } - DiagnosticsURLFlag = cli.StringFlag{ - Name: "diagnostics.url", - Usage: "URL of the diagnostics system provided by the support team", - } ) var MetricFlags = []cli.Flag{&MetricsEnabledFlag, &MetricsHTTPFlag, &MetricsPortFlag} @@ -895,6 +909,7 @@ func NewP2PConfig( port uint, protocol uint, allowedPorts []uint, + metricsEnabled bool, ) (*p2p.Config, error) { var enodeDBPath string switch protocol { @@ -925,6 +940,7 @@ func NewP2PConfig( NodeDatabase: enodeDBPath, AllowedPorts: allowedPorts, TmpDir: dirs.Tmp, + MetricsEnabled: metricsEnabled, } if netRestrict != "" { cfg.NetRestrict = new(netutil.Netlist) @@ -1088,6 +1104,10 @@ func SetP2PConfig(ctx *cli.Context, cfg *p2p.Config, nodeName, datadir string) { cfg.DiscoveryV5 = ctx.Bool(DiscoveryV5Flag.Name) } + if ctx.IsSet(MetricsEnabledFlag.Name) { + cfg.MetricsEnabled = ctx.Bool(MetricsEnabledFlag.Name) + } + ethPeers := cfg.MaxPeers cfg.Name = nodeName log.Info("Maximum peer count", "ETH", ethPeers, "total", cfg.MaxPeers) @@ -1139,9 +1159,16 @@ func setDataDir(ctx *cli.Context, cfg *nodecfg.Config) { if err := cfg.MdbxPageSize.UnmarshalText([]byte(ctx.String(DbPageSizeFlag.Name))); err != nil { panic(err) } + if err := cfg.MdbxDBSizeLimit.UnmarshalText([]byte(ctx.String(DbSizeLimitFlag.Name))); err != nil { + panic(err) + } sz := cfg.MdbxPageSize.Bytes() if !isPowerOfTwo(sz) || sz < 256 || sz > 64*1024 { - panic(fmt.Errorf("invalid --db.pagesize: %s=%d, see: %s", ctx.String(DbPageSizeFlag.Name), sz, DbPageSizeFlag.Usage)) + panic(fmt.Errorf("invalid --db.pageSize: %s=%d, see: %s", ctx.String(DbPageSizeFlag.Name), sz, DbPageSizeFlag.Usage)) + } + szLimit := cfg.MdbxDBSizeLimit.Bytes() + if szLimit%sz != 0 || szLimit < 256 { + panic(fmt.Errorf("invalid --db.size.limit: %s=%d, see: %s", ctx.String(DbSizeLimitFlag.Name), szLimit, DbSizeLimitFlag.Usage)) } } @@ -1171,7 +1198,7 @@ func setDataDirCobra(f *pflag.FlagSet, cfg *nodecfg.Config) { cfg.Dirs = datadir.New(cfg.Dirs.DataDir) } -func setGPO(ctx *cli.Context, cfg *gasprice.Config) { +func setGPO(ctx *cli.Context, cfg *gaspricecfg.Config) { if ctx.IsSet(GpoBlocksFlag.Name) { cfg.Blocks = ctx.Int(GpoBlocksFlag.Name) } @@ -1184,7 +1211,7 @@ func setGPO(ctx *cli.Context, cfg *gasprice.Config) { } // nolint -func setGPOCobra(f *pflag.FlagSet, cfg *gasprice.Config) { +func setGPOCobra(f *pflag.FlagSet, cfg *gaspricecfg.Config) { if v := f.Int(GpoBlocksFlag.Name, GpoBlocksFlag.Value, GpoBlocksFlag.Usage); v != nil { cfg.Blocks = *v } @@ -1196,15 +1223,15 @@ func setGPOCobra(f *pflag.FlagSet, cfg *gasprice.Config) { } } -func setTxPool(ctx *cli.Context, cfg *core.TxPoolConfig) { +func setTxPool(ctx *cli.Context, cfg *ethconfig.DeprecatedTxPoolConfig) { if ctx.IsSet(TxPoolDisableFlag.Name) { cfg.Disable = true } if ctx.IsSet(TxPoolLocalsFlag.Name) { - locals := strings.Split(ctx.String(TxPoolLocalsFlag.Name), ",") + locals := SplitAndTrim(ctx.String(TxPoolLocalsFlag.Name)) for _, account := range locals { - if trimmed := strings.TrimSpace(account); !libcommon.IsHexAddress(trimmed) { - Fatalf("Invalid account in --txpool.locals: %s", trimmed) + if !libcommon.IsHexAddress(account) { + Fatalf("Invalid account in --txpool.locals: %s", account) } else { cfg.Locals = append(cfg.Locals, libcommon.HexToAddress(account)) } @@ -1246,6 +1273,8 @@ func setTxPool(ctx *cli.Context, cfg *core.TxPoolConfig) { cfg.TracedSenders[i] = string(sender[:]) } } + + cfg.CommitEvery = common2.RandomizeDuration(ctx.Duration(TxPoolCommitEveryFlag.Name)) } func setEthash(ctx *cli.Context, datadir string, cfg *ethconfig.Config) { @@ -1261,7 +1290,7 @@ func setEthash(ctx *cli.Context, datadir string, cfg *ethconfig.Config) { cfg.Ethash.CachesLockMmap = ctx.Bool(EthashCachesLockMmapFlag.Name) } if ctx.IsSet(FakePoWFlag.Name) { - cfg.Ethash.PowMode = ethash.ModeFake + cfg.Ethash.PowMode = ethashcfg.ModeFake } if ctx.IsSet(EthashDatasetsLockMmapFlag.Name) { cfg.Ethash.DatasetsLockMmap = ctx.Bool(EthashDatasetsLockMmapFlag.Name) @@ -1330,10 +1359,6 @@ func setClique(ctx *cli.Context, cfg *params.ConsensusSnapshotConfig, datadir st } } -func setAuRa(ctx *cli.Context, cfg *chain.AuRaConfig, datadir string) { - cfg.DBPath = filepath.Join(datadir, "aura") -} - func setParlia(ctx *cli.Context, cfg *chain.ParliaConfig, datadir string) { cfg.DBPath = filepath.Join(datadir, "parlia") } @@ -1352,7 +1377,7 @@ func setMiner(ctx *cli.Context, cfg *params.MiningConfig) { panic(fmt.Sprintf("Erigon supports only remote miners. Flag --%s or --%s is required", MinerNotifyFlag.Name, MinerSigningKeyFileFlag.Name)) } if ctx.IsSet(MinerNotifyFlag.Name) { - cfg.Notify = strings.Split(ctx.String(MinerNotifyFlag.Name), ",") + cfg.Notify = SplitAndTrim(ctx.String(MinerNotifyFlag.Name)) } if ctx.IsSet(MinerExtraDataFlag.Name) { cfg.ExtraData = []byte(ctx.String(MinerExtraDataFlag.Name)) @@ -1361,7 +1386,7 @@ func setMiner(ctx *cli.Context, cfg *params.MiningConfig) { cfg.GasLimit = ctx.Uint64(MinerGasLimitFlag.Name) } if ctx.IsSet(MinerGasPriceFlag.Name) { - cfg.GasPrice = BigFlagValue(ctx, MinerGasPriceFlag.Name) + cfg.GasPrice = flags.GlobalBig(ctx, MinerGasPriceFlag.Name) } if ctx.IsSet(MinerRecommitIntervalFlag.Name) { cfg.Recommit = ctx.Duration(MinerRecommitIntervalFlag.Name) @@ -1377,7 +1402,7 @@ func setWhitelist(ctx *cli.Context, cfg *ethconfig.Config) { return } cfg.Whitelist = make(map[uint64]libcommon.Hash) - for _, entry := range strings.Split(whitelist, ",") { + for _, entry := range SplitAndTrim(whitelist) { parts := strings.Split(entry, "=") if len(parts) != 2 { Fatalf("Invalid whitelist entry: %s", entry) @@ -1470,7 +1495,7 @@ func SetEthConfig(ctx *cli.Context, nodeConfig *nodecfg.Config, cfg *ethconfig.C } log.Info("torrent verbosity", "level", lvl.LogString()) version := "erigon: " + params.VersionWithCommit(params.GitCommit) - cfg.Downloader, err = downloadercfg2.New(cfg.Dirs.Snap, version, lvl, downloadRate, uploadRate, ctx.Int(TorrentPortFlag.Name), ctx.Int(TorrentConnsPerFileFlag.Name), ctx.Int(TorrentDownloadSlotsFlag.Name)) + cfg.Downloader, err = downloadercfg2.New(cfg.Dirs.Snap, version, lvl, downloadRate, uploadRate, ctx.Int(TorrentPortFlag.Name), ctx.Int(TorrentConnsPerFileFlag.Name), ctx.Int(TorrentDownloadSlotsFlag.Name), ctx.StringSlice(TorrentDownloadSlotsFlag.Name)) if err != nil { panic(err) } @@ -1487,12 +1512,11 @@ func SetEthConfig(ctx *cli.Context, nodeConfig *nodecfg.Config, cfg *ethconfig.C setGPO(ctx, &cfg.GPO) setTxPool(ctx, &cfg.DeprecatedTxPool) - cfg.TxPool = core.DefaultTxPool2Config(cfg.DeprecatedTxPool) + cfg.TxPool = ethconfig.DefaultTxPool2Config(cfg.DeprecatedTxPool) cfg.TxPool.DBDir = nodeConfig.Dirs.TxPool setEthash(ctx, nodeConfig.Dirs.DataDir, cfg) setClique(ctx, &cfg.Clique, nodeConfig.Dirs.DataDir) - setAuRa(ctx, &cfg.Aura, nodeConfig.Dirs.DataDir) setParlia(ctx, &cfg.Parlia, nodeConfig.Dirs.DataDir) setMiner(ctx, &cfg.Miner) setWhitelist(ctx, cfg) @@ -1532,7 +1556,7 @@ func SetEthConfig(ctx *cli.Context, nodeConfig *nodecfg.Config, cfg *ethconfig.C switch chain { default: - genesis := core.DefaultGenesisBlockByChainName(chain) + genesis := core.GenesisBlockByChainName(chain) genesisHash := params.GenesisHashByChainName(chain) if (genesis == nil) || (genesisHash == nil) { Fatalf("ChainDB name is not recognized: %s", chain) @@ -1568,16 +1592,18 @@ func SetEthConfig(ctx *cli.Context, nodeConfig *nodecfg.Config, cfg *ethconfig.C } if ctx.IsSet(OverrideShanghaiTime.Name) { - cfg.OverrideShanghaiTime = BigFlagValue(ctx, OverrideShanghaiTime.Name) + cfg.OverrideShanghaiTime = flags.GlobalBig(ctx, OverrideShanghaiTime.Name) cfg.TxPool.OverrideShanghaiTime = cfg.OverrideShanghaiTime } - if ctx.IsSet(ExternalConsensusFlag.Name) { - cfg.ExternalCL = ctx.Bool(ExternalConsensusFlag.Name) - } else { - cfg.ExternalCL = !clparams.EmbeddedEnabledByDefault(cfg.NetworkID) + if ctx.IsSet(InternalConsensusFlag.Name) && clparams.EmbeddedEnabledByDefault(cfg.NetworkID) { + cfg.InternalCL = ctx.Bool(InternalConsensusFlag.Name) + } + nodeConfig.Http.InternalCL = cfg.InternalCL + + if ctx.IsSet(SentryDropUselessPeers.Name) { + cfg.DropUselessPeers = ctx.Bool(SentryDropUselessPeers.Name) } - nodeConfig.Http.InternalCL = !cfg.ExternalCL } // SetDNSDiscoveryDefaults configures DNS discovery with the given URL if @@ -1593,7 +1619,7 @@ func SetDNSDiscoveryDefaults(cfg *ethconfig.Config, genesis libcommon.Hash) { } func SplitTagsFlag(tagsFlag string) map[string]string { - tags := strings.Split(tagsFlag, ",") + tags := SplitAndTrim(tagsFlag) tagsMap := map[string]string{} for _, t := range tags { @@ -1617,12 +1643,7 @@ func MakeConsolePreloads(ctx *cli.Context) []string { return nil } // Otherwise resolve absolute paths and return them - files := strings.Split(ctx.String(PreloadJSFlag.Name), ",") - preloads := make([]string, 0, len(files)) - for _, file := range files { - preloads = append(preloads, strings.TrimSpace(file)) - } - return preloads + return SplitAndTrim(ctx.String(PreloadJSFlag.Name)) } func CobraFlags(cmd *cobra.Command, urfaveCliFlagsLists ...[]cli.Flag) { diff --git a/cmd/utils/customflags.go b/cmd/utils/flags/flags.go similarity index 50% rename from cmd/utils/customflags.go rename to cmd/utils/flags/flags.go index c50a1660293..683a3cd4a41 100644 --- a/cmd/utils/customflags.go +++ b/cmd/utils/flags/flags.go @@ -1,36 +1,36 @@ // Copyright 2015 The go-ethereum Authors -// This file is part of go-ethereum. +// This file is part of the go-ethereum library. // -// go-ethereum is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by +// The go-ethereum library is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // -// go-ethereum is distributed in the hope that it will be useful, +// The go-ethereum library is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. +// GNU Lesser General Public License for more details. // -// You should have received a copy of the GNU General Public License -// along with go-ethereum. If not, see . +// You should have received a copy of the GNU Lesser General Public License +// along with the go-ethereum library. If not, see . -package utils +package flags import ( + "encoding" "errors" "flag" "math/big" "os" "os/user" - "path" + "path/filepath" "strings" - "github.com/urfave/cli/v2" - "github.com/ledgerwatch/erigon/common/math" + "github.com/urfave/cli/v2" ) -// Custom type which is registered in the flags library which cli uses for +// DirectoryString is custom type which is registered in the flags library which cli uses for // argument parsing. This allows us to expand Value to an absolute path when // the argument is parsed type DirectoryString string @@ -44,7 +44,15 @@ func (s *DirectoryString) Set(value string) error { return nil } -// Custom cli.Flag type which expand the received string to an absolute path. +var ( + _ cli.Flag = (*DirectoryFlag)(nil) + _ cli.RequiredFlag = (*DirectoryFlag)(nil) + _ cli.VisibleFlag = (*DirectoryFlag)(nil) + _ cli.DocGenerationFlag = (*DirectoryFlag)(nil) + _ cli.CategorizableFlag = (*DirectoryFlag)(nil) +) + +// DirectoryFlag is custom cli.Flag type which expand the received string to an absolute path. // e.g. ~/.ethereum -> /home/username/.ethereum type DirectoryFlag struct { Name string @@ -62,11 +70,13 @@ type DirectoryFlag struct { Aliases []string } +// For cli.Flag: + func (f *DirectoryFlag) Names() []string { return append([]string{f.Name}, f.Aliases...) } func (f *DirectoryFlag) IsSet() bool { return f.HasBeenSet } func (f *DirectoryFlag) String() string { return cli.FlagStringer(f) } -// called by cli library, grabs variable from environment (if in env) +// Apply called by cli library, grabs variable from environment (if in env) // and adds variable to flag set for parsing. func (f *DirectoryFlag) Apply(set *flag.FlagSet) error { eachName(f, func(name string) { @@ -75,12 +85,20 @@ func (f *DirectoryFlag) Apply(set *flag.FlagSet) error { return nil } +// For cli.RequiredFlag: + func (f *DirectoryFlag) IsRequired() bool { return f.Required } +// For cli.VisibleFlag: + func (f *DirectoryFlag) IsVisible() bool { return !f.Hidden } +// For cli.CategorizableFlag: + func (f *DirectoryFlag) GetCategory() string { return f.Category } +// For cli.DocGenerationFlag: + func (f *DirectoryFlag) TakesValue() bool { return true } func (f *DirectoryFlag) GetUsage() string { return f.Usage } func (f *DirectoryFlag) GetValue() string { return f.Value.String() } @@ -93,13 +111,116 @@ func (f *DirectoryFlag) GetDefaultText() string { return f.GetValue() } -func eachName(f cli.Flag, fn func(string)) { - for _, name := range f.Names() { - name = strings.Trim(name, " ") - fn(name) +type TextMarshaler interface { + encoding.TextMarshaler + encoding.TextUnmarshaler +} + +// textMarshalerVal turns a TextMarshaler into a flag.Value +type textMarshalerVal struct { + v TextMarshaler +} + +func (v textMarshalerVal) String() string { + if v.v == nil { + return "" + } + text, _ := v.v.MarshalText() + return string(text) +} + +func (v textMarshalerVal) Set(s string) error { + return v.v.UnmarshalText([]byte(s)) +} + +var ( + _ cli.Flag = (*TextMarshalerFlag)(nil) + _ cli.RequiredFlag = (*TextMarshalerFlag)(nil) + _ cli.VisibleFlag = (*TextMarshalerFlag)(nil) + _ cli.DocGenerationFlag = (*TextMarshalerFlag)(nil) + _ cli.CategorizableFlag = (*TextMarshalerFlag)(nil) +) + +// TextMarshalerFlag wraps a TextMarshaler value. +type TextMarshalerFlag struct { + Name string + + Category string + DefaultText string + Usage string + + Required bool + Hidden bool + HasBeenSet bool + + Value TextMarshaler + + Aliases []string +} + +// For cli.Flag: + +func (f *TextMarshalerFlag) Names() []string { return append([]string{f.Name}, f.Aliases...) } +func (f *TextMarshalerFlag) IsSet() bool { return f.HasBeenSet } +func (f *TextMarshalerFlag) String() string { return cli.FlagStringer(f) } + +func (f *TextMarshalerFlag) Apply(set *flag.FlagSet) error { + eachName(f, func(name string) { + set.Var(textMarshalerVal{f.Value}, f.Name, f.Usage) + }) + return nil +} + +// For cli.RequiredFlag: + +func (f *TextMarshalerFlag) IsRequired() bool { return f.Required } + +// For cli.VisibleFlag: + +func (f *TextMarshalerFlag) IsVisible() bool { return !f.Hidden } + +// For cli.CategorizableFlag: + +func (f *TextMarshalerFlag) GetCategory() string { return f.Category } + +// For cli.DocGenerationFlag: + +func (f *TextMarshalerFlag) TakesValue() bool { return true } +func (f *TextMarshalerFlag) GetUsage() string { return f.Usage } +func (f *TextMarshalerFlag) GetEnvVars() []string { return nil } // env not supported + +func (f *TextMarshalerFlag) GetValue() string { + t, err := f.Value.MarshalText() + if err != nil { + return "(ERR: " + err.Error() + ")" + } + return string(t) +} + +func (f *TextMarshalerFlag) GetDefaultText() string { + if f.DefaultText != "" { + return f.DefaultText } + return f.GetValue() } +// GlobalTextMarshaler returns the value of a TextMarshalerFlag from the global flag set. +func GlobalTextMarshaler(ctx *cli.Context, name string) TextMarshaler { + val := ctx.Generic(name) + if val == nil { + return nil + } + return val.(textMarshalerVal).v +} + +var ( + _ cli.Flag = (*BigFlag)(nil) + _ cli.RequiredFlag = (*BigFlag)(nil) + _ cli.VisibleFlag = (*BigFlag)(nil) + _ cli.DocGenerationFlag = (*BigFlag)(nil) + _ cli.CategorizableFlag = (*BigFlag)(nil) +) + // BigFlag is a command line flag that accepts 256 bit big integers in decimal or // hexadecimal syntax. type BigFlag struct { @@ -118,6 +239,8 @@ type BigFlag struct { Aliases []string } +// For cli.Flag: + func (f *BigFlag) Names() []string { return append([]string{f.Name}, f.Aliases...) } func (f *BigFlag) IsSet() bool { return f.HasBeenSet } func (f *BigFlag) String() string { return cli.FlagStringer(f) } @@ -131,12 +254,20 @@ func (f *BigFlag) Apply(set *flag.FlagSet) error { return nil } +// For cli.RequiredFlag: + func (f *BigFlag) IsRequired() bool { return f.Required } +// For cli.VisibleFlag: + func (f *BigFlag) IsVisible() bool { return !f.Hidden } +// For cli.CategorizableFlag: + func (f *BigFlag) GetCategory() string { return f.Category } +// For cli.DocGenerationFlag: + func (f *BigFlag) TakesValue() bool { return true } func (f *BigFlag) GetUsage() string { return f.Usage } func (f *BigFlag) GetValue() string { return f.Value.String() } @@ -164,12 +295,12 @@ func (b *bigValue) Set(s string) error { if !ok { return errors.New("invalid integer syntax") } - *b = bigValue(*intVal) + *b = (bigValue)(*intVal) return nil } -// BigFlagValue returns the value of a BigFlag from the flag set. -func BigFlagValue(ctx *cli.Context, name string) *big.Int { +// GlobalBig returns the value of a BigFlag from the global flag set. +func GlobalBig(ctx *cli.Context, name string) *big.Int { val := ctx.Generic(name) if val == nil { return nil @@ -183,12 +314,16 @@ func BigFlagValue(ctx *cli.Context, name string) *big.Int { // 3. cleans the path, e.g. /a/b/../c -> /a/c // Note, it has limitations, e.g. ~someuser/tmp will not be expanded func expandPath(p string) string { + // Named pipes are not file paths on windows, ignore + if strings.HasPrefix(p, `\\.\pipe`) { + return p + } if strings.HasPrefix(p, "~/") || strings.HasPrefix(p, "~\\") { if home := HomeDir(); home != "" { p = home + p[1:] } } - return path.Clean(os.ExpandEnv(p)) + return filepath.Clean(os.ExpandEnv(p)) } func HomeDir() string { @@ -200,3 +335,10 @@ func HomeDir() string { } return "" } + +func eachName(f cli.Flag, fn func(string)) { + for _, name := range f.Names() { + name = strings.Trim(name, " ") + fn(name) + } +} diff --git a/cmd/utils/flags/flags_test.go b/cmd/utils/flags/flags_test.go new file mode 100644 index 00000000000..681586b46c7 --- /dev/null +++ b/cmd/utils/flags/flags_test.go @@ -0,0 +1,61 @@ +// Copyright 2015 The go-ethereum Authors +// This file is part of the go-ethereum library. +// +// The go-ethereum library is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// The go-ethereum library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with the go-ethereum library. If not, see . + +package flags + +import ( + "os" + "os/user" + "runtime" + "testing" +) + +func TestPathExpansion(t *testing.T) { + user, _ := user.Current() + var tests map[string]string + + if runtime.GOOS == "windows" { + tests = map[string]string{ + `/home/someuser/tmp`: `\home\someuser\tmp`, + `~/tmp`: user.HomeDir + `\tmp`, + `~thisOtherUser/b/`: `~thisOtherUser\b`, + `$DDDXXX/a/b`: `\tmp\a\b`, + `/a/b/`: `\a\b`, + `C:\Documents\Newsletters\`: `C:\Documents\Newsletters`, + `C:\`: `C:\`, + `\\.\pipe\\pipe\geth621383`: `\\.\pipe\\pipe\geth621383`, + } + } else { + tests = map[string]string{ + `/home/someuser/tmp`: `/home/someuser/tmp`, + `~/tmp`: user.HomeDir + `/tmp`, + `~thisOtherUser/b/`: `~thisOtherUser/b`, + `$DDDXXX/a/b`: `/tmp/a/b`, + `/a/b/`: `/a/b`, + `C:\Documents\Newsletters\`: `C:\Documents\Newsletters\`, + `C:\`: `C:\`, + `\\.\pipe\\pipe\geth621383`: `\\.\pipe\\pipe\geth621383`, + } + } + + os.Setenv(`DDDXXX`, `/tmp`) + for test, expected := range tests { + got := expandPath(test) + if got != expected { + t.Errorf(`test %s, got %s, expected %s\n`, test, got, expected) + } + } +} diff --git a/cmd/utils/flags/helpers.go b/cmd/utils/flags/helpers.go new file mode 100644 index 00000000000..51dc2e8274f --- /dev/null +++ b/cmd/utils/flags/helpers.go @@ -0,0 +1,200 @@ +// Copyright 2020 The go-ethereum Authors +// This file is part of the go-ethereum library. +// +// The go-ethereum library is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// The go-ethereum library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with the go-ethereum library. If not, see . + +package flags + +import ( + "fmt" + "strings" + + "github.com/urfave/cli/v2" +) + +// Merge merges the given flag slices. +func Merge(groups ...[]cli.Flag) []cli.Flag { + var ret []cli.Flag + for _, group := range groups { + ret = append(ret, group...) + } + return ret +} + +var migrationApplied = map[*cli.Command]struct{}{} + +// MigrateGlobalFlags makes all global flag values available in the +// context. This should be called as early as possible in app.Before. +// +// Example: +// +// geth account new --keystore /tmp/mykeystore --lightkdf +// +// is equivalent after calling this method with: +// +// geth --keystore /tmp/mykeystore --lightkdf account new +// +// i.e. in the subcommand Action function of 'account new', ctx.Bool("lightkdf) +// will return true even if --lightkdf is set as a global option. +// +// This function may become unnecessary when https://github.com/urfave/cli/pull/1245 is merged. +func MigrateGlobalFlags(ctx *cli.Context) { + var iterate func(cs []*cli.Command, fn func(*cli.Command)) + iterate = func(cs []*cli.Command, fn func(*cli.Command)) { + for _, cmd := range cs { + if _, ok := migrationApplied[cmd]; ok { + continue + } + migrationApplied[cmd] = struct{}{} + fn(cmd) + iterate(cmd.Subcommands, fn) + } + } + + // This iterates over all commands and wraps their action function. + iterate(ctx.App.Commands, func(cmd *cli.Command) { + if cmd.Action == nil { + return + } + + action := cmd.Action + cmd.Action = func(ctx *cli.Context) error { + doMigrateFlags(ctx) + return action(ctx) + } + }) +} + +func doMigrateFlags(ctx *cli.Context) { + // Figure out if there are any aliases of commands. If there are, we want + // to ignore them when iterating over the flags. + var aliases = make(map[string]bool) + for _, fl := range ctx.Command.Flags { + for _, alias := range fl.Names()[1:] { + aliases[alias] = true + } + } + for _, name := range ctx.FlagNames() { + for _, parent := range ctx.Lineage()[1:] { + if parent.IsSet(name) { + // When iterating across the lineage, we will be served both + // the 'canon' and alias formats of all commmands. In most cases, + // it's fine to set it in the ctx multiple times (one for each + // name), however, the Slice-flags are not fine. + // The slice-flags accumulate, so if we set it once as + // "foo" and once as alias "F", then both will be present in the slice. + if _, isAlias := aliases[name]; isAlias { + continue + } + // If it is a string-slice, we need to set it as + // "alfa, beta, gamma" instead of "[alfa beta gamma]", in order + // for the backing StringSlice to parse it properly. + if result := parent.StringSlice(name); len(result) > 0 { + ctx.Set(name, strings.Join(result, ",")) + } else { + ctx.Set(name, parent.String(name)) + } + break + } + } + } +} + +/* +func init() { + cli.FlagStringer = FlagString +} +*/ + +// FlagString prints a single flag in help. +func FlagString(f cli.Flag) string { + df, ok := f.(cli.DocGenerationFlag) + if !ok { + return "" + } + + needsPlaceholder := df.TakesValue() + placeholder := "" + if needsPlaceholder { + placeholder = "value" + } + + namesText := pad(cli.FlagNamePrefixer(df.Names(), placeholder), 30) + + defaultValueString := "" + if s := df.GetDefaultText(); s != "" { + defaultValueString = " (default: " + s + ")" + } + + usage := strings.TrimSpace(df.GetUsage()) + envHint := strings.TrimSpace(cli.FlagEnvHinter(df.GetEnvVars(), "")) + if len(envHint) > 0 { + usage += " " + envHint + } + + usage = wordWrap(usage, 80) + usage = indent(usage, 10) + + return fmt.Sprintf("\n %s%s\n%s", namesText, defaultValueString, usage) +} + +func pad(s string, length int) string { + if len(s) < length { + s += strings.Repeat(" ", length-len(s)) + } + return s +} + +func indent(s string, nspace int) string { + ind := strings.Repeat(" ", nspace) + return ind + strings.ReplaceAll(s, "\n", "\n"+ind) +} + +func wordWrap(s string, width int) string { + var ( + output strings.Builder + lineLength = 0 + ) + + for { + sp := strings.IndexByte(s, ' ') + var word string + if sp == -1 { + word = s + } else { + word = s[:sp] + } + wlen := len(word) + over := lineLength+wlen >= width + if over { + output.WriteByte('\n') + lineLength = 0 + } else { + if lineLength != 0 { + output.WriteByte(' ') + lineLength++ + } + } + + output.WriteString(word) + lineLength += wlen + + if sp == -1 { + break + } + s = s[wlen+1:] + } + + return output.String() +} diff --git a/common/hexutil/json.go b/common/hexutil/json.go index 265e98ed3da..ce1ce9a05d7 100644 --- a/common/hexutil/json.go +++ b/common/hexutil/json.go @@ -23,59 +23,14 @@ import ( "math/big" "reflect" "strconv" - - "github.com/ledgerwatch/erigon-lib/common/hexutility" ) var ( - bytesT = reflect.TypeOf(Bytes(nil)) bigT = reflect.TypeOf((*Big)(nil)) uintT = reflect.TypeOf(Uint(0)) uint64T = reflect.TypeOf(Uint64(0)) ) -// Bytes marshals/unmarshals as a JSON string with 0x prefix. -// The empty slice marshals as "0x". -type Bytes []byte - -const hexPrefix = `0x` - -// MarshalText implements encoding.TextMarshaler -func (b Bytes) MarshalText() ([]byte, error) { - result := make([]byte, len(b)*2+2) - copy(result, hexPrefix) - hex.Encode(result[2:], b) - return result, nil -} - -// UnmarshalJSON implements json.Unmarshaler. -func (b *Bytes) UnmarshalJSON(input []byte) error { - if !isString(input) { - return errNonString(bytesT) - } - return wrapTypeError(b.UnmarshalText(input[1:len(input)-1]), bytesT) -} - -// UnmarshalText implements encoding.TextUnmarshaler. -func (b *Bytes) UnmarshalText(input []byte) error { - raw, err := checkText(input, true) - if err != nil { - return err - } - dec := make([]byte, len(raw)/2) - if _, err = hex.Decode(dec, raw); err != nil { - err = mapError(err) - } else { - *b = dec - } - return err -} - -// String returns the hex encoding of b. -func (b Bytes) String() string { - return hexutility.Encode(b) -} - // UnmarshalFixedUnprefixedText decodes the input as a string with optional 0x prefix. The // length of out determines the required input length. This function is commonly used to // implement the UnmarshalText method for fixed-size types. diff --git a/common/hexutil/json_example_test.go b/common/hexutil/json_example_test.go index b513fba60b5..c256b412e39 100644 --- a/common/hexutil/json_example_test.go +++ b/common/hexutil/json_example_test.go @@ -21,8 +21,6 @@ import ( "fmt" "github.com/ledgerwatch/erigon-lib/common/hexutility" - - "github.com/ledgerwatch/erigon/common/hexutil" ) type MyType [5]byte @@ -32,7 +30,7 @@ func (v *MyType) UnmarshalText(input []byte) error { } func (v MyType) String() string { - return hexutil.Bytes(v[:]).String() + return hexutility.Bytes(v[:]).String() } func ExampleUnmarshalFixedText() { diff --git a/common/hexutil/json_test.go b/common/hexutil/json_test.go index ed7d6fad1a8..21f4a35ce58 100644 --- a/common/hexutil/json_test.go +++ b/common/hexutil/json_test.go @@ -18,7 +18,6 @@ package hexutil import ( "bytes" - "encoding/hex" "encoding/json" "errors" "math/big" @@ -49,81 +48,8 @@ func referenceBig(s string) *big.Int { return b } -func referenceBytes(s string) []byte { - b, err := hex.DecodeString(s) - if err != nil { - panic(err) - } - return b -} - var errJSONEOF = errors.New("unexpected end of JSON input") -var unmarshalBytesTests = []unmarshalTest{ - // invalid encoding - {input: "", wantErr: errJSONEOF}, - {input: "null", wantErr: errNonString(bytesT)}, - {input: "10", wantErr: errNonString(bytesT)}, - {input: `"0"`, wantErr: wrapTypeError(ErrMissingPrefix, bytesT)}, - {input: `"0x0"`, wantErr: wrapTypeError(ErrOddLength, bytesT)}, - {input: `"0xxx"`, wantErr: wrapTypeError(ErrSyntax, bytesT)}, - {input: `"0x01zz01"`, wantErr: wrapTypeError(ErrSyntax, bytesT)}, - - // valid encoding - {input: `""`, want: referenceBytes("")}, - {input: `"0x"`, want: referenceBytes("")}, - {input: `"0x02"`, want: referenceBytes("02")}, - {input: `"0X02"`, want: referenceBytes("02")}, - {input: `"0xffffffffff"`, want: referenceBytes("ffffffffff")}, - { - input: `"0xffffffffffffffffffffffffffffffffffff"`, - want: referenceBytes("ffffffffffffffffffffffffffffffffffff"), - }, -} - -func TestUnmarshalBytes(t *testing.T) { - for _, test := range unmarshalBytesTests { - var v Bytes - err := json.Unmarshal([]byte(test.input), &v) - if !checkError(t, test.input, err, test.wantErr) { - continue - } - if !bytes.Equal(test.want.([]byte), v) { - t.Errorf("input %s: value mismatch: got %x, want %x", test.input, &v, test.want) - continue - } - } -} - -func BenchmarkUnmarshalBytes(b *testing.B) { - input := []byte(`"0x123456789abcdef123456789abcdef"`) - for i := 0; i < b.N; i++ { - var v Bytes - if err := v.UnmarshalJSON(input); err != nil { - b.Fatal(err) - } - } -} - -func TestMarshalBytes(t *testing.T) { - for _, test := range encodeBytesTests { - in := test.input.([]byte) - out, err := json.Marshal(Bytes(in)) - if err != nil { - t.Errorf("%x: %v", in, err) - continue - } - if want := `"` + test.want + `"`; string(out) != want { - t.Errorf("%x: MarshalJSON output mismatch: got %q, want %q", in, out, want) - continue - } - if out := Bytes(in).String(); out != test.want { - t.Errorf("%x: String mismatch: got %q, want %q", in, out, test.want) - continue - } - } -} - var unmarshalBigTests = []unmarshalTest{ // invalid encoding {input: "", wantErr: errJSONEOF}, diff --git a/common/math/integer.go b/common/math/integer.go index 5b306de4295..7f451ca9d40 100644 --- a/common/math/integer.go +++ b/common/math/integer.go @@ -96,3 +96,10 @@ func RandInt64() (int64, error) { } return n.Int64(), nil } + +func CeilDiv(x, y int) int { + if y == 0 { + return 0 + } + return (x + y - 1) / y +} diff --git a/common/paths/paths.go b/common/paths/paths.go index c617c801008..5d1e9916633 100644 --- a/common/paths/paths.go +++ b/common/paths/paths.go @@ -86,8 +86,6 @@ func DataDirForNetwork(datadir string, network string) string { return networkDataDirCheckingLegacy(datadir, "rinkeby") case networkname.GoerliChainName: return networkDataDirCheckingLegacy(datadir, "goerli") - case networkname.SokolChainName: - return networkDataDirCheckingLegacy(datadir, "sokol") case networkname.MumbaiChainName: return networkDataDirCheckingLegacy(datadir, "mumbai") case networkname.BorMainnetChainName: diff --git a/consensus/aura/aura.go b/consensus/aura/aura.go index d706b635656..30a64d1fbc5 100644 --- a/consensus/aura/aura.go +++ b/consensus/aura/aura.go @@ -19,21 +19,22 @@ package aura import ( "bytes" "container/list" - "encoding/json" + "context" "fmt" "math/big" "sort" "sync" + "sync/atomic" "time" - lru "github.com/hashicorp/golang-lru" + lru "github.com/hashicorp/golang-lru/v2" "github.com/holiman/uint256" + "github.com/ledgerwatch/log/v3" + "github.com/ledgerwatch/secp256k1" + "github.com/ledgerwatch/erigon-lib/chain" libcommon "github.com/ledgerwatch/erigon-lib/common" "github.com/ledgerwatch/erigon-lib/kv" - "github.com/ledgerwatch/log/v3" - "github.com/ledgerwatch/secp256k1" - "go.uber.org/atomic" "github.com/ledgerwatch/erigon/accounts/abi" "github.com/ledgerwatch/erigon/common" @@ -42,10 +43,10 @@ import ( "github.com/ledgerwatch/erigon/consensus/aura/contracts" "github.com/ledgerwatch/erigon/consensus/clique" "github.com/ledgerwatch/erigon/consensus/ethash" + "github.com/ledgerwatch/erigon/core/rawdb" "github.com/ledgerwatch/erigon/core/state" "github.com/ledgerwatch/erigon/core/types" "github.com/ledgerwatch/erigon/crypto" - "github.com/ledgerwatch/erigon/params" "github.com/ledgerwatch/erigon/rlp" "github.com/ledgerwatch/erigon/rpc" ) @@ -97,7 +98,7 @@ type EpochTransition struct { type Step struct { calibrate bool // whether calibration is enabled. - inner *atomic.Uint64 + inner atomic.Uint64 // Planned durations of steps. durations []StepDurationInfo } @@ -138,7 +139,7 @@ func (s *Step) optCalibrate() bool { type PermissionedStep struct { inner *Step - canPropose *atomic.Bool + canPropose atomic.Bool } type ReceivedStepHashes map[uint64]map[libcommon.Address]libcommon.Hash //BTreeMap<(u64, Address), H256> @@ -192,7 +193,7 @@ func (e *EpochManager) noteNewEpoch() { e.force = true } // zoomValidators - Zooms to the epoch after the header with the given hash. Returns true if succeeded, false otherwise. // It's analog of zoom_to_after function in OE, but doesn't require external locking // nolint -func (e *EpochManager) zoomToAfter(chain consensus.ChainHeaderReader, er consensus.EpochReader, validators ValidatorSet, hash libcommon.Hash, call consensus.SystemCall) (*RollingFinality, uint64, bool) { +func (e *EpochManager) zoomToAfter(chain consensus.ChainHeaderReader, er *NonTransactionalEpochReader, validators ValidatorSet, hash libcommon.Hash, call consensus.SystemCall) (*RollingFinality, uint64, bool) { var lastWasParent bool if e.finalityChecker.lastPushed != nil { lastWasParent = *e.finalityChecker.lastPushed == hash @@ -209,7 +210,7 @@ func (e *EpochManager) zoomToAfter(chain consensus.ChainHeaderReader, er consens // forks it will only need to be called for the block directly after // epoch transition, in which case it will be O(1) and require a single // DB lookup. - lastTransition, ok := epochTransitionFor2(chain, er, hash) + lastTransition, ok := epochTransitionFor(chain, er, hash) if !ok { if lastTransition.BlockNumber > DEBUG_LOG_FROM { fmt.Printf("zoom1: %d\n", lastTransition.BlockNumber) @@ -255,7 +256,7 @@ func (e *EpochManager) zoomToAfter(chain consensus.ChainHeaderReader, er consens // / // / The block corresponding the the parent hash must be stored already. // nolint -func epochTransitionFor2(chain consensus.ChainHeaderReader, e consensus.EpochReader, parentHash libcommon.Hash) (transition EpochTransition, ok bool) { +func epochTransitionFor(chain consensus.ChainHeaderReader, e *NonTransactionalEpochReader, parentHash libcommon.Hash) (transition EpochTransition, ok bool) { //TODO: probably this version of func doesn't support non-canonical epoch transitions h := chain.GetHeaderByHash(parentHash) if h == nil { @@ -271,62 +272,10 @@ func epochTransitionFor2(chain consensus.ChainHeaderReader, e consensus.EpochRea return EpochTransition{BlockNumber: num, BlockHash: hash, ProofRlp: transitionProof}, true } -// nolint -func epochTransitionFor(chain consensus.ChainHeaderReader, e consensus.EpochReader, parentHash libcommon.Hash) (transition EpochTransition, ok bool) { - // slow path: loop back block by block - for { - h := chain.GetHeaderByHash(parentHash) - if h == nil { - return transition, false - } - - // look for transition in database. - transitionProof, err := e.GetEpoch(h.Hash(), h.Number.Uint64()) - if err != nil { - panic(err) - } - - if transitionProof != nil { - return EpochTransition{ - BlockNumber: h.Number.Uint64(), - BlockHash: h.Hash(), - ProofRlp: transitionProof, - }, true - } - - // canonical hash -> fast breakout: - // get the last epoch transition up to this block. - // - // if `block_hash` is canonical it will only return transitions up to - // the parent. - canonical := chain.GetHeaderByNumber(h.Number.Uint64()) - if canonical == nil { - return transition, false - } - //nolint - if canonical.Hash() == parentHash { - return EpochTransition{ - BlockNumber: 0, - BlockHash: libcommon.HexToHash("0x5b28c1bfd3a15230c9a46b399cd0f9a6920d432e85381cc6a140b06e8410112f"), - ProofRlp: params.SokolGenesisEpochProof, - }, true - /* TODO: - return self - .epoch_transitions() - .map(|(_, t)| t) - .take_while(|t| t.block_number <= details.number) - .last(); - */ - } - - parentHash = h.Hash() - } -} - // AuRa // nolint type AuRa struct { - db kv.RwDB // Database to store and retrieve snapshot checkpoints + e *NonTransactionalEpochReader exitCh chan struct{} lock sync.RWMutex // Protects the signer fields @@ -334,24 +283,23 @@ type AuRa struct { // History of step hashes recently received from peers. receivedStepHashes ReceivedStepHashes - OurSigningAddress libcommon.Address // Same as Etherbase in Mining - cfg AuthorityRoundParams - EmptyStepsSet *EmptyStepSet - EpochManager *EpochManager // Mutex, + cfg AuthorityRoundParams + EmptyStepsSet *EmptyStepSet + EpochManager *EpochManager // Mutex, certifier *libcommon.Address // certifies service transactions certifierLock sync.RWMutex } type GasLimitOverride struct { - cache *lru.Cache + cache *lru.Cache[libcommon.Hash, *uint256.Int] } func NewGasLimitOverride() *GasLimitOverride { // The number of recent block hashes for which the gas limit override is memoized. const GasLimitOverrideCacheCapacity = 10 - cache, err := lru.New(GasLimitOverrideCacheCapacity) + cache, err := lru.New[libcommon.Hash, *uint256.Int](GasLimitOverrideCacheCapacity) if err != nil { panic("error creating prefetching cache for blocks") } @@ -361,9 +309,7 @@ func NewGasLimitOverride() *GasLimitOverride { func (pb *GasLimitOverride) Pop(hash libcommon.Hash) *uint256.Int { if val, ok := pb.cache.Get(hash); ok && val != nil { pb.cache.Remove(hash) - if v, ok := val.(*uint256.Int); ok { - return v - } + return val } return nil } @@ -375,12 +321,7 @@ func (pb *GasLimitOverride) Add(hash libcommon.Hash, b *uint256.Int) { pb.cache.ContainsOrAdd(hash, b) } -func NewAuRa(config *chain.AuRaConfig, db kv.RwDB, ourSigningAddress libcommon.Address, engineParamsJson []byte) (*AuRa, error) { - spec := JsonSpec{} - err := json.Unmarshal(engineParamsJson, &spec) - if err != nil { - return nil, err - } +func NewAuRa(spec *chain.AuRaConfig, db kv.RwDB) (*AuRa, error) { auraParams, err := FromJson(spec) if err != nil { return nil, err @@ -420,10 +361,10 @@ func NewAuRa(config *chain.AuRaConfig, db kv.RwDB, ourSigningAddress libcommon.A durations = append(durations, durInfo) } step := &Step{ - inner: atomic.NewUint64(initialStep), calibrate: auraParams.StartStep == nil, durations: durations, } + step.inner.Store(initialStep) step.doCalibrate() /* @@ -447,19 +388,66 @@ func NewAuRa(config *chain.AuRaConfig, db kv.RwDB, ourSigningAddress libcommon.A exitCh := make(chan struct{}) c := &AuRa{ - db: db, + e: newEpochReader(db), exitCh: exitCh, - step: PermissionedStep{inner: step, canPropose: atomic.NewBool(true)}, - OurSigningAddress: ourSigningAddress, + step: PermissionedStep{inner: step}, cfg: auraParams, receivedStepHashes: ReceivedStepHashes{}, EpochManager: NewEpochManager(), } - _ = config + c.step.canPropose.Store(true) return c, nil } +type epochReader interface { + GetEpoch(blockHash libcommon.Hash, blockN uint64) (transitionProof []byte, err error) + GetPendingEpoch(blockHash libcommon.Hash, blockN uint64) (transitionProof []byte, err error) + FindBeforeOrEqualNumber(number uint64) (blockNum uint64, blockHash libcommon.Hash, transitionProof []byte, err error) +} +type epochWriter interface { + epochReader + PutEpoch(blockHash libcommon.Hash, blockN uint64, transitionProof []byte) (err error) + PutPendingEpoch(blockHash libcommon.Hash, blockN uint64, transitionProof []byte) (err error) +} + +type NonTransactionalEpochReader struct { + db kv.RwDB +} + +func newEpochReader(db kv.RwDB) *NonTransactionalEpochReader { + return &NonTransactionalEpochReader{db: db} +} + +func (cr *NonTransactionalEpochReader) GetEpoch(hash libcommon.Hash, number uint64) (v []byte, err error) { + return v, cr.db.View(context.Background(), func(tx kv.Tx) error { + v, err = rawdb.ReadEpoch(tx, number, hash) + return err + }) +} +func (cr *NonTransactionalEpochReader) PutEpoch(hash libcommon.Hash, number uint64, proof []byte) error { + return cr.db.UpdateNosync(context.Background(), func(tx kv.RwTx) error { + return rawdb.WriteEpoch(tx, number, hash, proof) + }) +} +func (cr *NonTransactionalEpochReader) GetPendingEpoch(hash libcommon.Hash, number uint64) (v []byte, err error) { + return v, cr.db.View(context.Background(), func(tx kv.Tx) error { + v, err = rawdb.ReadPendingEpoch(tx, number, hash) + return err + }) +} +func (cr *NonTransactionalEpochReader) PutPendingEpoch(hash libcommon.Hash, number uint64, proof []byte) error { + return cr.db.UpdateNosync(context.Background(), func(tx kv.RwTx) error { + return rawdb.WritePendingEpoch(tx, number, hash, proof) + }) +} +func (cr *NonTransactionalEpochReader) FindBeforeOrEqualNumber(number uint64) (blockNum uint64, blockHash libcommon.Hash, transitionProof []byte, err error) { + return blockNum, blockHash, transitionProof, cr.db.View(context.Background(), func(tx kv.Tx) error { + blockNum, blockHash, transitionProof, err = rawdb.FindEpochBeforeOrEqualNumber(tx, number) + return err + }) +} + // A helper accumulator function mapping a step duration and a step duration transition timestamp // to the corresponding step number and the correct starting second of the step. func nextStepTimeDuration(info StepDurationInfo, time uint64) (uint64, uint64, bool) { @@ -530,7 +518,7 @@ func (c *AuRa) insertReceivedStepHashes(step uint64, author libcommon.Address, n } // nolint -func (c *AuRa) verifyFamily(chain consensus.ChainHeaderReader, e consensus.EpochReader, header *types.Header, call consensus.Call, syscall consensus.SystemCall) error { +func (c *AuRa) verifyFamily(chain consensus.ChainHeaderReader, e *NonTransactionalEpochReader, header *types.Header, call consensus.Call, syscall consensus.SystemCall) error { // TODO: I call it from Initialize - because looks like no much reason to have separated "verifyFamily" call step := header.AuRaStep @@ -771,9 +759,7 @@ func (c *AuRa) Prepare(chain consensus.ChainHeaderReader, header *types.Header, //return nil } -func (c *AuRa) Initialize(config *chain.Config, chain consensus.ChainHeaderReader, e consensus.EpochReader, header *types.Header, - state *state.IntraBlockState, txs []types.Transaction, uncles []*types.Header, syscall consensus.SystemCall, -) { +func (c *AuRa) Initialize(config *chain.Config, chain consensus.ChainHeaderReader, header *types.Header, state *state.IntraBlockState, txs []types.Transaction, uncles []*types.Header, syscall consensus.SystemCall) { blockNum := header.Number.Uint64() for address, rewrittenCode := range c.cfg.RewriteBytecode[blockNum] { state.SetCode(address, rewrittenCode) @@ -790,7 +776,7 @@ func (c *AuRa) Initialize(config *chain.Config, chain consensus.ChainHeaderReade if err != nil { panic(err) } - err = e.PutEpoch(header.ParentHash, 0, proof) //TODO: block 0 hardcoded - need fix it inside validators + err = c.e.PutEpoch(header.ParentHash, 0, proof) //TODO: block 0 hardcoded - need fix it inside validators if err != nil { panic(err) } @@ -802,12 +788,7 @@ func (c *AuRa) Initialize(config *chain.Config, chain consensus.ChainHeaderReade // check_and_lock_block -> check_epoch_end_signal - if e == nil { - // for tracing, we pass e that is `nil` - return - } - - epoch, err := e.GetEpoch(header.ParentHash, blockNum-1) + epoch, err := c.e.GetEpoch(header.ParentHash, blockNum-1) if err != nil { log.Warn("[aura] initialize block: on epoch begin", "err", err) return @@ -838,10 +819,7 @@ func (c *AuRa) ApplyRewards(header *types.Header, state *state.IntraBlockState, } // word `signal epoch` == word `pending epoch` -func (c *AuRa) Finalize(config *chain.Config, header *types.Header, state *state.IntraBlockState, - txs types.Transactions, uncles []*types.Header, receipts types.Receipts, withdrawals []*types.Withdrawal, - e consensus.EpochReader, chain consensus.ChainHeaderReader, syscall consensus.SystemCall, -) (types.Transactions, types.Receipts, error) { +func (c *AuRa) Finalize(config *chain.Config, header *types.Header, state *state.IntraBlockState, txs types.Transactions, uncles []*types.Header, receipts types.Receipts, withdrawals []*types.Withdrawal, chain consensus.ChainHeaderReader, syscall consensus.SystemCall) (types.Transactions, types.Receipts, error) { if err := c.ApplyRewards(header, state, syscall); err != nil { return nil, nil, err } @@ -858,22 +836,22 @@ func (c *AuRa) Finalize(config *chain.Config, header *types.Header, state *state if header.Number.Uint64() >= DEBUG_LOG_FROM { fmt.Printf("insert_pending_transition: %d,receipts=%d, lenProof=%d\n", header.Number.Uint64(), len(receipts), len(pendingTransitionProof)) } - if err = e.PutPendingEpoch(header.Hash(), header.Number.Uint64(), pendingTransitionProof); err != nil { + if err = c.e.PutPendingEpoch(header.Hash(), header.Number.Uint64(), pendingTransitionProof); err != nil { return nil, nil, err } } // check_and_lock_block -> check_epoch_end_signal END - finalized := buildFinality(c.EpochManager, chain, e, c.cfg.Validators, header, syscall) + finalized := buildFinality(c.EpochManager, chain, c.e, c.cfg.Validators, header, syscall) c.EpochManager.finalityChecker.print(header.Number.Uint64()) - epochEndProof, err := isEpochEnd(chain, e, finalized, header) + epochEndProof, err := isEpochEnd(chain, c.e, finalized, header) if err != nil { return nil, nil, err } if epochEndProof != nil { c.EpochManager.noteNewEpoch() log.Info("[aura] epoch transition", "block_num", header.Number.Uint64()) - if err := e.PutEpoch(header.Hash(), header.Number.Uint64(), epochEndProof); err != nil { + if err := c.e.PutEpoch(header.Hash(), header.Number.Uint64(), epochEndProof); err != nil { return nil, nil, err } } @@ -881,7 +859,7 @@ func (c *AuRa) Finalize(config *chain.Config, header *types.Header, state *state return txs, receipts, nil } -func buildFinality(e *EpochManager, chain consensus.ChainHeaderReader, er consensus.EpochReader, validators ValidatorSet, header *types.Header, syscall consensus.SystemCall) []unAssembledHeader { +func buildFinality(e *EpochManager, chain consensus.ChainHeaderReader, er *NonTransactionalEpochReader, validators ValidatorSet, header *types.Header, syscall consensus.SystemCall) []unAssembledHeader { // commit_block -> aura.build_finality _, _, ok := e.zoomToAfter(chain, er, validators, header.ParentHash, syscall) if !ok { @@ -908,7 +886,7 @@ func buildFinality(e *EpochManager, chain consensus.ChainHeaderReader, er consen return res } -func isEpochEnd(chain consensus.ChainHeaderReader, e consensus.EpochReader, finalized []unAssembledHeader, header *types.Header) ([]byte, error) { +func isEpochEnd(chain consensus.ChainHeaderReader, e *NonTransactionalEpochReader, finalized []unAssembledHeader, header *types.Header) ([]byte, error) { // commit_block -> aura.is_epoch_end for i := range finalized { pendingTransitionProof, err := e.GetPendingEpoch(finalized[i].hash, finalized[i].number) @@ -978,11 +956,8 @@ func allHeadersUntil(chain consensus.ChainHeaderReader, from *types.Header, to l //} // FinalizeAndAssemble implements consensus.Engine -func (c *AuRa) FinalizeAndAssemble(chainConfig *chain.Config, header *types.Header, state *state.IntraBlockState, - txs types.Transactions, uncles []*types.Header, receipts types.Receipts, withdrawals []*types.Withdrawal, - e consensus.EpochReader, chain consensus.ChainHeaderReader, syscall consensus.SystemCall, call consensus.Call, -) (*types.Block, types.Transactions, types.Receipts, error) { - outTxs, outReceipts, err := c.Finalize(chainConfig, header, state, txs, uncles, receipts, withdrawals, e, chain, syscall) +func (c *AuRa) FinalizeAndAssemble(config *chain.Config, header *types.Header, state *state.IntraBlockState, txs types.Transactions, uncles []*types.Header, receipts types.Receipts, withdrawals []*types.Withdrawal, chain consensus.ChainHeaderReader, syscall consensus.SystemCall, call consensus.Call) (*types.Block, types.Transactions, types.Receipts, error) { + outTxs, outReceipts, err := c.Finalize(config, header, state, txs, uncles, receipts, withdrawals, chain, syscall) if err != nil { return nil, nil, nil, err } @@ -1188,7 +1163,7 @@ func (c *AuRa) GenerateSeal(chain consensus.ChainHeaderReader, current, parent * // epochSet fetch correct validator set for epoch at header, taking into account // finality of previous transitions. -func (c *AuRa) epochSet(chain consensus.ChainHeaderReader, e consensus.EpochReader, h *types.Header, call consensus.SystemCall) (ValidatorSet, uint64, error) { +func (c *AuRa) epochSet(chain consensus.ChainHeaderReader, e *NonTransactionalEpochReader, h *types.Header, call consensus.SystemCall) (ValidatorSet, uint64, error) { if c.cfg.ImmediateTransitions { return c.cfg.Validators, h.Number.Uint64(), nil } @@ -1421,6 +1396,7 @@ func (c *AuRa) ExecuteSystemWithdrawals(withdrawals []*types.Withdrawal, syscall return nil } + maxFailedWithdrawalsToProcess := big.NewInt(4) amounts := make([]uint64, 0, len(withdrawals)) addresses := make([]libcommon.Address, 0, len(withdrawals)) for _, w := range withdrawals { @@ -1428,12 +1404,15 @@ func (c *AuRa) ExecuteSystemWithdrawals(withdrawals []*types.Withdrawal, syscall addresses = append(addresses, w.Address) } - packed, err := withdrawalAbi().Pack("executeSystemWithdrawals", amounts, addresses) + packed, err := withdrawalAbi().Pack("executeSystemWithdrawals", maxFailedWithdrawalsToProcess, amounts, addresses) if err != nil { return err } _, err = syscall(*c.cfg.WithdrawalContractAddress, packed) + if err != nil { + log.Warn("ExecuteSystemWithdrawals", "err", err) + } return err } diff --git a/consensus/aura/aura_test.go b/consensus/aura/aura_test.go index 6cf88e6b5eb..d3c9da5c6c9 100644 --- a/consensus/aura/aura_test.go +++ b/consensus/aura/aura_test.go @@ -1,216 +1,33 @@ package aura_test import ( - "context" - "fmt" "testing" + "github.com/stretchr/testify/require" + libcommon "github.com/ledgerwatch/erigon-lib/common" - "github.com/ledgerwatch/erigon-lib/kv" "github.com/ledgerwatch/erigon-lib/kv/memdb" - "github.com/stretchr/testify/require" "github.com/ledgerwatch/erigon/consensus/aura" - "github.com/ledgerwatch/erigon/consensus/aura/consensusconfig" - "github.com/ledgerwatch/erigon/consensus/aura/test" "github.com/ledgerwatch/erigon/core" - "github.com/ledgerwatch/erigon/core/rawdb" "github.com/ledgerwatch/erigon/core/types" - "github.com/ledgerwatch/erigon/core/types/accounts" - "github.com/ledgerwatch/erigon/eth/ethconfig" "github.com/ledgerwatch/erigon/turbo/stages" "github.com/ledgerwatch/erigon/turbo/trie" ) -/* -#[test] - - fn block_reward_contract() { - let spec = Spec::new_test_round_block_reward_contract(); - let tap = Arc::new(AccountProvider::transient_provider()); - - let addr1 = tap.insert_account(keccak("1").into(), &"1".into()).unwrap(); - - let engine = &*spec.engine; - let genesis_header = spec.genesis_header(); - let db1 = spec - .ensure_db_good(get_temp_state_db(), &Default::default()) - .unwrap(); - let db2 = spec - .ensure_db_good(get_temp_state_db(), &Default::default()) - .unwrap(); - - let last_hashes = Arc::new(vec![genesis_header.hash()]); - - let client = generate_dummy_client_with_spec(Spec::new_test_round_block_reward_contract); - engine.register_client(Arc::downgrade(&client) as _); - - // step 2 - let b1 = OpenBlock::new( - engine, - Default::default(), - false, - db1, - &genesis_header, - last_hashes.clone(), - addr1, - (3141562.into(), 31415620.into()), - vec![], - false, - None, - ) - .unwrap(); - let b1 = b1.close_and_lock().unwrap(); - - // since the block is empty it isn't sealed and we generate empty steps - engine.set_signer(Some(Box::new((tap.clone(), addr1, "1".into())))); - assert_eq!(engine.generate_seal(&b1, &genesis_header), Seal::None); - engine.step(); - - // step 3 - // the signer of the accumulated empty step message should be rewarded - let b2 = OpenBlock::new( - engine, - Default::default(), - false, - db2, - &genesis_header, - last_hashes.clone(), - addr1, - (3141562.into(), 31415620.into()), - vec![], - false, - None, - ) - .unwrap(); - let addr1_balance = b2.state.balance(&addr1).unwrap(); - - // after closing the block `addr1` should be reward twice, one for the included empty step - // message and another for block creation - let b2 = b2.close_and_lock().unwrap(); - - // the contract rewards (1000 + kind) for each benefactor/reward kind - assert_eq!( - b2.state.balance(&addr1).unwrap(), - addr1_balance + (1000 + 0) + (1000 + 2), - ) - } -*/ -func TestRewardContract(t *testing.T) { - t.Skip("not ready yet") - auraDB, require := memdb.NewTestDB(t), require.New(t) - engine, err := aura.NewAuRa(nil, auraDB, libcommon.Address{}, test.AuthorityRoundBlockRewardContract) - require.NoError(err) - m := stages.MockWithGenesisEngine(t, core.DefaultSokolGenesisBlock(), engine, false) - m.EnableLogs() - - var accBefore *accounts.Account - err = auraDB.View(context.Background(), func(tx kv.Tx) (err error) { _, err = rawdb.ReadAccount(tx, m.Address, accBefore); return err }) - require.NoError(err) - - chain, err := core.GenerateChain(m.ChainConfig, m.Genesis, m.Engine, m.DB, 2, func(i int, gen *core.BlockGen) { - gen.SetCoinbase(m.Address) - }, false /* intermediateHashes */) - require.NoError(err) - - err = m.InsertChain(chain) - require.NoError(err) - - var accAfter *accounts.Account - err = auraDB.View(context.Background(), func(tx kv.Tx) (err error) { _, err = rawdb.ReadAccount(tx, m.Address, accAfter); return err }) - require.NoError(err) - - fmt.Printf("balance: %d\n", accAfter.Balance.Uint64()) - /* - - let spec = Spec::new_test_round_block_reward_contract(); - let tap = Arc::new(AccountProvider::transient_provider()); - - let addr1 = tap.insert_account(keccak("1").into(), &"1".into()).unwrap(); - - let engine = &*spec.engine; - let genesis_header = spec.genesis_header(); - let db1 = spec - .ensure_db_good(get_temp_state_db(), &Default::default()) - .unwrap(); - let db2 = spec - .ensure_db_good(get_temp_state_db(), &Default::default()) - .unwrap(); - - let last_hashes = Arc::new(vec![genesis_header.hash()]); - - let client = generate_dummy_client_with_spec(Spec::new_test_round_block_reward_contract); - engine.register_client(Arc::downgrade(&client) as _); - - // step 2 - let b1 = OpenBlock::new( - engine, - Default::default(), - false, - db1, - &genesis_header, - last_hashes.clone(), - addr1, - (3141562.into(), 31415620.into()), - vec![], - false, - None, - ) - .unwrap(); - let b1 = b1.close_and_lock().unwrap(); - - // since the block is empty it isn't sealed and we generate empty steps - engine.set_signer(Some(Box::new((tap.clone(), addr1, "1".into())))); - assert_eq!(engine.generate_seal(&b1, &genesis_header), Seal::None); - engine.step(); - - // step 3 - // the signer of the accumulated empty step message should be rewarded - let b2 = OpenBlock::new( - engine, - Default::default(), - false, - db2, - &genesis_header, - last_hashes.clone(), - addr1, - (3141562.into(), 31415620.into()), - vec![], - false, - None, - ) - .unwrap(); - let addr1_balance = b2.state.balance(&addr1).unwrap(); - - // after closing the block `addr1` should be reward twice, one for the included empty step - // message and another for block creation - let b2 = b2.close_and_lock().unwrap(); - - // the contract rewards (1000 + kind) for each benefactor/reward kind - assert_eq!( - b2.state.balance(&addr1).unwrap(), - addr1_balance + (1000 + 0) + (1000 + 2), - ) - */ -} - // Check that the first block of Gnosis Chain, which doesn't have any transactions, // does not change the state root. func TestEmptyBlock(t *testing.T) { - if ethconfig.EnableHistoryV3InTest { - t.Skip("") - } - require := require.New(t) - genesis := core.DefaultGnosisGenesisBlock() - genesisBlock, _, err := genesis.ToBlock("") + genesis := core.GnosisGenesisBlock() + genesisBlock, _, err := core.GenesisToBlock(genesis, "") require.NoError(err) genesis.Config.TerminalTotalDifficultyPassed = false chainConfig := genesis.Config auraDB := memdb.NewTestDB(t) - engine, err := aura.NewAuRa(chainConfig.Aura, auraDB, chainConfig.Aura.Etherbase, consensusconfig.GetConfigByChain(chainConfig.ChainName)) + engine, err := aura.NewAuRa(chainConfig.Aura, auraDB) require.NoError(err) m := stages.MockWithGenesisEngine(t, genesis, engine, false) diff --git a/consensus/aura/config.go b/consensus/aura/config.go index 94ec56b8f73..00c12b4da27 100644 --- a/consensus/aura/config.go +++ b/consensus/aura/config.go @@ -22,9 +22,10 @@ import ( "sort" "github.com/holiman/uint256" + + "github.com/ledgerwatch/erigon-lib/chain" libcommon "github.com/ledgerwatch/erigon-lib/common" - "github.com/ledgerwatch/erigon/common/hexutil" "github.com/ledgerwatch/erigon/common/u256" "github.com/ledgerwatch/erigon/consensus" ) @@ -38,19 +39,7 @@ func GetFromValidatorSet(set ValidatorSet, parent libcommon.Hash, nonce uint, ca return set.getWithCaller(parent, nonce, call) } -// Different ways of specifying validators. -type ValidatorSetJson struct { - // A simple list of authorities. - List []libcommon.Address `json:"list"` - // Address of a contract that indicates the list of authorities. - SafeContract *libcommon.Address `json:"safeContract"` - // Address of a contract that indicates the list of authorities and enables reporting of their misbehaviour using transactions. - Contract *libcommon.Address `json:"contract"` - // A map of starting blocks for each validator set. - Multi map[uint64]*ValidatorSetJson `json:"multi"` -} - -func newValidatorSetFromJson(j *ValidatorSetJson, posdaoTransition *uint64) ValidatorSet { +func newValidatorSetFromJson(j *chain.ValidatorSetJson, posdaoTransition *uint64) ValidatorSet { if j.List != nil { return &SimpleList{validators: j.List} } @@ -75,60 +64,6 @@ func newValidatorSetFromJson(j *ValidatorSetJson, posdaoTransition *uint64) Vali return nil } -// TODO: StepDuration and BlockReward - now are uint64, but it can be an object in non-sokol consensus -type JsonSpec struct { - StepDuration *uint64 `json:"stepDuration"` // Block duration, in seconds. - Validators *ValidatorSetJson `json:"validators"` // Valid authorities - - // Starting step. Determined automatically if not specified. - // To be used for testing only. - StartStep *uint64 `json:"startStep"` - ValidateScoreTransition *uint64 `json:"validateScoreTransition"` // Block at which score validation should start. - ValidateStepTransition *uint64 `json:"validateStepTransition"` // Block from which monotonic steps start. - ImmediateTransitions *bool `json:"immediateTransitions"` // Whether transitions should be immediate. - BlockReward *hexutil.Uint64 `json:"blockReward"` // Reward per block in wei. - // Block at which the block reward contract should start being used. This option allows one to - // add a single block reward contract transition and is compatible with the multiple address - // option `block_reward_contract_transitions` below. - BlockRewardContractTransition *uint64 `json:"blockRewardContractTransition"` - /// Block reward contract address which overrides the `block_reward` setting. This option allows - /// one to add a single block reward contract address and is compatible with the multiple - /// address option `block_reward_contract_transitions` below. - BlockRewardContractAddress *libcommon.Address `json:"blockRewardContractAddress"` - // Block reward contract addresses with their associated starting block numbers. - // - // Setting the block reward contract overrides `block_reward`. If the single block reward - // contract address is also present then it is added into the map at the block number stored in - // `block_reward_contract_transition` or 0 if that block number is not provided. Therefore both - // a single block reward contract transition and a map of reward contract transitions can be - // used simultaneously in the same configuration. In such a case the code requires that the - // block number of the single transition is strictly less than any of the block numbers in the - // map. - BlockRewardContractTransitions map[uint]libcommon.Address `json:"blockRewardContractTransitions"` - // Block at which maximum uncle count should be considered. - MaximumUncleCountTransition *uint64 `json:"maximumUncleCountTransition"` - // Maximum number of accepted uncles. - MaximumUncleCount *uint `json:"maximumUncleCount"` - // Strict validation of empty steps transition block. - StrictEmptyStepsTransition *uint `json:"strictEmptyStepsTransition"` - // The random number contract's address, or a map of contract transitions. - RandomnessContractAddress map[uint64]libcommon.Address `json:"randomnessContractAddress"` - // The addresses of contracts that determine the block gas limit starting from the block number - // associated with each of those contracts. - BlockGasLimitContractTransitions map[uint64]libcommon.Address `json:"blockGasLimitContractTransitions"` - // The block number at which the consensus engine switches from AuRa to AuRa with POSDAO - // modifications. - PosdaoTransition *uint64 `json:"PosdaoTransition"` - // Stores human-readable keys associated with addresses, like DNS information. - // This contract is primarily required to store the address of the Certifier contract. - Registrar *libcommon.Address `json:"registrar"` - - // See https://github.com/gnosischain/specs/blob/master/execution/withdrawals.md - WithdrawalContractAddress *libcommon.Address `json:"withdrawalContractAddress"` - - RewriteBytecode map[uint64]map[libcommon.Address]hexutil.Bytes `json:"rewriteBytecode"` -} - type Code struct { Code []byte CodeHash libcommon.Hash @@ -206,7 +141,7 @@ type AuthorityRoundParams struct { RewriteBytecode map[uint64]map[libcommon.Address][]byte } -func FromJson(jsonParams JsonSpec) (AuthorityRoundParams, error) { +func FromJson(jsonParams *chain.AuRaConfig) (AuthorityRoundParams, error) { params := AuthorityRoundParams{ Validators: newValidatorSetFromJson(jsonParams.Validators, jsonParams.PosdaoTransition), StartStep: jsonParams.StartStep, @@ -257,7 +192,7 @@ func FromJson(jsonParams JsonSpec) (AuthorityRoundParams, error) { params.BlockReward = append(params.BlockReward, BlockReward{blockNum: 0, amount: u256.Num0}) } else { if jsonParams.BlockReward != nil { - params.BlockReward = append(params.BlockReward, BlockReward{blockNum: 0, amount: uint256.NewInt(uint64(*jsonParams.BlockReward))}) + params.BlockReward = append(params.BlockReward, BlockReward{blockNum: 0, amount: uint256.NewInt(*jsonParams.BlockReward)}) } } sort.Sort(params.BlockReward) diff --git a/consensus/aura/config_test.go b/consensus/aura/config_test.go index c68eb17cf2d..a910625fd9a 100644 --- a/consensus/aura/config_test.go +++ b/consensus/aura/config_test.go @@ -1,21 +1,18 @@ package aura import ( - "encoding/json" "testing" - libcommon "github.com/ledgerwatch/erigon-lib/common" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" - "github.com/ledgerwatch/erigon/consensus/aura/consensusconfig" - "github.com/ledgerwatch/erigon/params/networkname" + libcommon "github.com/ledgerwatch/erigon-lib/common" + + "github.com/ledgerwatch/erigon/params" ) func TestGnosisBlockRewardContractTransitions(t *testing.T) { - config := consensusconfig.GetConfigByChain(networkname.GnosisChainName) - spec := JsonSpec{} - require.NoError(t, json.Unmarshal(config, &spec)) + spec := params.GnosisChainConfig.Aura param, err := FromJson(spec) require.NoError(t, err) @@ -28,14 +25,12 @@ func TestGnosisBlockRewardContractTransitions(t *testing.T) { } func TestInvalidBlockRewardContractTransition(t *testing.T) { - config := consensusconfig.GetConfigByChain(networkname.GnosisChainName) - spec := JsonSpec{} - require.NoError(t, json.Unmarshal(config, &spec)) + spec := *(params.GnosisChainConfig.Aura) // blockRewardContractTransition should be smaller than any block number in blockRewardContractTransitions invalidTransition := uint64(10_000_000) spec.BlockRewardContractTransition = &invalidTransition - _, err := FromJson(spec) + _, err := FromJson(&spec) assert.Error(t, err) } diff --git a/consensus/aura/consensusconfig/embed.go b/consensus/aura/consensusconfig/embed.go deleted file mode 100644 index ff58ed20216..00000000000 --- a/consensus/aura/consensusconfig/embed.go +++ /dev/null @@ -1,32 +0,0 @@ -package consensusconfig - -import ( - _ "embed" - - "github.com/ledgerwatch/erigon/params/networkname" -) - -//go:embed poasokol.json -var Sokol []byte - -//go:embed poagnosis.json -var Gnosis []byte - -//go:embed poachiado.json -var Chiado []byte - -//go:embed test.json -var Test []byte - -func GetConfigByChain(chainName string) []byte { - switch chainName { - case networkname.SokolChainName: - return Sokol - case networkname.GnosisChainName: - return Gnosis - case networkname.ChiadoChainName: - return Chiado - default: - return Test - } -} diff --git a/consensus/aura/consensusconfig/kovan.json b/consensus/aura/consensusconfig/kovan.json deleted file mode 100644 index 603a5fbdd31..00000000000 --- a/consensus/aura/consensusconfig/kovan.json +++ /dev/null @@ -1,36 +0,0 @@ -{ - "stepDuration": 4, - "blockReward": "0x4563918244F40000", - "validators": { - "multi": { - "0": { - "list": [ - "0x00D6Cc1BA9cf89BD2e58009741f4F7325BAdc0ED", - "0x00427feae2419c15b89d1c21af10d1b6650a4d3d", - "0x4Ed9B08e6354C70fE6F8CB0411b0d3246b424d6c", - "0x0020ee4Be0e2027d76603cB751eE069519bA81A1", - "0x0010f94b296a852aaac52ea6c5ac72e03afd032d", - "0x007733a1FE69CF3f2CF989F81C7b4cAc1693387A", - "0x00E6d2b931F55a3f1701c7389d592a7778897879", - "0x00e4a10650e5a6D6001C38ff8E64F97016a1645c", - "0x00a0a24b9f0e5ec7aa4c7389b8302fd0123194de" - ] - }, - "10960440": { - "list": [ - "0x00D6Cc1BA9cf89BD2e58009741f4F7325BAdc0ED", - "0x0010f94b296a852aaac52ea6c5ac72e03afd032d", - "0x00a0a24b9f0e5ec7aa4c7389b8302fd0123194de" - ] - }, - "10960500": { - "safeContract": "0xaE71807C1B0a093cB1547b682DC78316D945c9B8" - } - } - }, - "validateScoreTransition": 4301764, - "validateStepTransition": 1500000, - "maximumUncleCountTransition": 5067000, - "maximumUncleCount": 0 -} - diff --git a/consensus/aura/consensusconfig/poachiado.json b/consensus/aura/consensusconfig/poachiado.json deleted file mode 100644 index f64e714cb11..00000000000 --- a/consensus/aura/consensusconfig/poachiado.json +++ /dev/null @@ -1,34 +0,0 @@ -{ - "stepDuration": 5, - "blockReward": "0x0", - "maximumUncleCountTransition": 0, - "maximumUncleCount": 0, - "validators": { - "multi": { - "0": { - "list": ["0x14747a698Ec1227e6753026C08B29b4d5D3bC484"] - }, - "67334": { - "list": [ - "0x14747a698Ec1227e6753026C08B29b4d5D3bC484", - "0x56D421c0AC39976E89fa400d34ca6579417B84cA", - "0x5CD99ac2F0F8C25a1e670F6BaB19D52Aad69D875", - "0x60F1CF46B42Df059b98Acf67C1dD7771b100e124", - "0x655e97bA0f63A56c2b56EB3e84f7bf42b20Bae14", - "0x755B6259938D140626301c0B6026c1C00C9eD5d9", - "0xa8010da9Cb0AC018C86A06301963853CC371a18c" - ] - } - } - }, - "blockRewardContractAddress": "0x2000000000000000000000000000000000000001", - "blockRewardContractTransition": 0, - "randomnessContractAddress": { - "0": "0x3000000000000000000000000000000000000001" - }, - "posdaoTransition": 0, - "blockGasLimitContractTransitions": { - "0": "0x4000000000000000000000000000000000000001" - }, - "registrar": "0x6000000000000000000000000000000000000000" -} diff --git a/consensus/aura/consensusconfig/poagnosis.json b/consensus/aura/consensusconfig/poagnosis.json deleted file mode 100644 index e9fc20cb9b2..00000000000 --- a/consensus/aura/consensusconfig/poagnosis.json +++ /dev/null @@ -1,36 +0,0 @@ -{ - "stepDuration": 5, - "blockReward": "0x0", - "maximumUncleCountTransition": 0, - "maximumUncleCount": 0, - "validators": { - "multi": { - "0": { - "list": [ - "0xcace5b3c29211740e595850e80478416ee77ca21" - ] - }, - "1300": { - "safeContract": "0x22e1229a2c5b95a60983b5577f745a603284f535" - }, - "9186425": { - "contract": "0xB87BE9f7196F2AE084Ca1DE6af5264292976e013" - } - } - }, - "blockRewardContractAddress": "0x867305d19606aadba405ce534e303d0e225f9556", - "blockRewardContractTransition": 1310, - "blockRewardContractTransitions": { - "9186425": "0x481c034c6d9441db23ea48de68bcae812c5d39ba" - }, - "randomnessContractAddress": { - "9186425": "0x5870b0527DeDB1cFBD9534343Feda1a41Ce47766" - }, - "posdaoTransition": 9186425, - "registrar": "0x6B53721D4f2Fb9514B85f5C49b197D857e36Cf03", - "rewriteBytecode": { - "21735000": { - "0xf8D1677c8a0c961938bf2f9aDc3F3CFDA759A9d9": "0x6080604052600436106101b35763ffffffff60e060020a60003504166305d2035b81146101b857806306fdde03146101e1578063095ea7b31461026b5780630b26cf661461028f57806318160ddd146102b257806323b872dd146102d957806330adf81f14610303578063313ce567146103185780633644e5151461034357806339509351146103585780634000aea01461037c57806340c10f19146103ad57806342966c68146103d157806354fd4d50146103e957806366188463146103fe57806369ffa08a1461042257806370a0823114610449578063715018a61461046a578063726600ce1461047f5780637d64bcb4146104a05780637ecebe00146104b5578063859ba28c146104d65780638da5cb5b146105175780638fcbaf0c1461054857806395d89b4114610586578063a457c2d71461059b578063a9059cbb146105bf578063b753a98c146105e3578063bb35783b14610607578063c6a1dedf14610631578063cd59658314610646578063d505accf1461065b578063d73dd62314610694578063dd62ed3e146106b8578063f2d5d56b146106df578063f2fde38b14610703578063ff9e884d14610724575b600080fd5b3480156101c457600080fd5b506101cd61074b565b604080519115158252519081900360200190f35b3480156101ed57600080fd5b506101f661076c565b6040805160208082528351818301528351919283929083019185019080838360005b83811015610230578181015183820152602001610218565b50505050905090810190601f16801561025d5780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b34801561027757600080fd5b506101cd600160a060020a03600435166024356107fa565b34801561029b57600080fd5b506102b0600160a060020a0360043516610810565b005b3480156102be57600080fd5b506102c761086a565b60408051918252519081900360200190f35b3480156102e557600080fd5b506101cd600160a060020a0360043581169060243516604435610870565b34801561030f57600080fd5b506102c7610a38565b34801561032457600080fd5b5061032d610a5c565b6040805160ff9092168252519081900360200190f35b34801561034f57600080fd5b506102c7610a65565b34801561036457600080fd5b506101cd600160a060020a0360043516602435610a6b565b34801561038857600080fd5b506101cd60048035600160a060020a0316906024803591604435918201910135610aac565b3480156103b957600080fd5b506101cd600160a060020a0360043516602435610bbd565b3480156103dd57600080fd5b506102b0600435610cc8565b3480156103f557600080fd5b506101f6610cd5565b34801561040a57600080fd5b506101cd600160a060020a0360043516602435610d0c565b34801561042e57600080fd5b506102b0600160a060020a0360043581169060243516610de9565b34801561045557600080fd5b506102c7600160a060020a0360043516610e0e565b34801561047657600080fd5b506102b0610e29565b34801561048b57600080fd5b506101cd600160a060020a0360043516610e40565b3480156104ac57600080fd5b506101cd610e54565b3480156104c157600080fd5b506102c7600160a060020a0360043516610e5b565b3480156104e257600080fd5b506104eb610e6d565b6040805167ffffffffffffffff9485168152928416602084015292168183015290519081900360600190f35b34801561052357600080fd5b5061052c610e78565b60408051600160a060020a039092168252519081900360200190f35b34801561055457600080fd5b506102b0600160a060020a0360043581169060243516604435606435608435151560ff60a4351660c43560e435610e87565b34801561059257600080fd5b506101f6610fc5565b3480156105a757600080fd5b506101cd600160a060020a036004351660243561101f565b3480156105cb57600080fd5b506101cd600160a060020a0360043516602435611032565b3480156105ef57600080fd5b506102b0600160a060020a0360043516602435611054565b34801561061357600080fd5b506102b0600160a060020a0360043581169060243516604435611064565b34801561063d57600080fd5b506102c7611075565b34801561065257600080fd5b5061052c611099565b34801561066757600080fd5b506102b0600160a060020a036004358116906024351660443560643560ff6084351660a43560c4356110a8565b3480156106a057600080fd5b506101cd600160a060020a0360043516602435611184565b3480156106c457600080fd5b506102c7600160a060020a036004358116906024351661120b565b3480156106eb57600080fd5b506102b0600160a060020a0360043516602435611236565b34801561070f57600080fd5b506102b0600160a060020a0360043516611241565b34801561073057600080fd5b506102c7600160a060020a0360043581169060243516611261565b60065474010000000000000000000000000000000000000000900460ff1681565b6000805460408051602060026001851615610100026000190190941693909304601f810184900484028201840190925281815292918301828280156107f25780601f106107c7576101008083540402835291602001916107f2565b820191906000526020600020905b8154815290600101906020018083116107d557829003601f168201915b505050505081565b600061080733848461127e565b50600192915050565b600654600160a060020a0316331461082757600080fd5b610830816112c0565b151561083b57600080fd5b6007805473ffffffffffffffffffffffffffffffffffffffff1916600160a060020a0392909216919091179055565b60045490565b600080600160a060020a038516151561088857600080fd5b600160a060020a038416151561089d57600080fd5b600160a060020a0385166000908152600360205260409020546108c6908463ffffffff6112c816565b600160a060020a0380871660009081526003602052604080822093909355908616815220546108fb908463ffffffff6112da16565b600160a060020a038086166000818152600360209081526040918290209490945580518781529051919392891692600080516020611d7283398151915292918290030190a3600160a060020a0385163314610a225761095a853361120b565b905060001981146109c457610975818463ffffffff6112c816565b600160a060020a038616600081815260056020908152604080832033808552908352928190208590558051948552519193600080516020611d92833981519152929081900390910190a3610a22565b600160a060020a0385166000908152600a602090815260408083203384529091529020541580610a175750600160a060020a0385166000908152600a602090815260408083203384529091529020544211155b1515610a2257600080fd5b610a2d8585856112ed565b506001949350505050565b7f6e71edae12b1b97f4d1f60370fef10105fa2faae0126114a169c64845d6126c981565b60025460ff1681565b60085481565b336000818152600560209081526040808320600160a060020a03871684529091528120549091610807918590610aa7908663ffffffff6112da16565b61127e565b600084600160a060020a03811615801590610ad05750600160a060020a0381163014155b1515610adb57600080fd5b610ae58686611324565b1515610af057600080fd5b85600160a060020a031633600160a060020a03167fe19260aff97b920c7df27010903aeb9c8d2be5d310a2c67824cf3f15396e4c16878787604051808481526020018060200182810382528484828181526020019250808284376040519201829003965090945050505050a3610b65866112c0565b15610bb157610ba633878787878080601f01602080910402602001604051908101604052809392919081815260200183838082843750611330945050505050565b1515610bb157600080fd5b50600195945050505050565b600654600090600160a060020a03163314610bd757600080fd5b60065474010000000000000000000000000000000000000000900460ff1615610bff57600080fd5b600454610c12908363ffffffff6112da16565b600455600160a060020a038316600090815260036020526040902054610c3e908363ffffffff6112da16565b600160a060020a038416600081815260036020908152604091829020939093558051858152905191927f0f6798a560793a54c3bcfe86a93cde1e73087d944c0ea20544137d412139688592918290030190a2604080518381529051600160a060020a03851691600091600080516020611d728339815191529181900360200190a350600192915050565b610cd233826114ad565b50565b60408051808201909152600181527f3100000000000000000000000000000000000000000000000000000000000000602082015281565b336000908152600560209081526040808320600160a060020a0386168452909152812054808310610d6057336000908152600560209081526040808320600160a060020a0388168452909152812055610d95565b610d70818463ffffffff6112c816565b336000908152600560209081526040808320600160a060020a03891684529091529020555b336000818152600560209081526040808320600160a060020a038916808552908352928190205481519081529051929392600080516020611d92833981519152929181900390910190a35060019392505050565b600654600160a060020a03163314610e0057600080fd5b610e0a828261159c565b5050565b600160a060020a031660009081526003602052604090205490565b600654600160a060020a031633146101b357600080fd5b600754600160a060020a0390811691161490565b6000806000fd5b60096020526000908152604090205481565b600260056000909192565b600654600160a060020a031681565b600080861580610e975750864211155b1515610ea257600080fd5b604080517fea2aa0a1be11a07ed86d755c93467f4f82362b452371d1ba94d1715123511acb6020820152600160a060020a03808d16828401528b166060820152608081018a905260a0810189905287151560c0808301919091528251808303909101815260e0909101909152610f17906115da565b9150610f25828686866116e1565b600160a060020a038b8116911614610f3c57600080fd5b600160a060020a038a1660009081526009602052604090208054600181019091558814610f6857600080fd5b85610f74576000610f78565b6000195b905085610f86576000610f88565b865b600160a060020a03808c166000908152600a60209081526040808320938e1683529290522055610fb98a8a836118e3565b50505050505050505050565b60018054604080516020600284861615610100026000190190941693909304601f810184900484028201840190925281815292918301828280156107f25780601f106107c7576101008083540402835291602001916107f2565b600061102b8383610d0c565b9392505050565b600061103e8383611324565b151561104957600080fd5b6108073384846112ed565b61105f338383610870565b505050565b61106f838383610870565b50505050565b7fea2aa0a1be11a07ed86d755c93467f4f82362b452371d1ba94d1715123511acb81565b600754600160a060020a031690565b600080428610156110b857600080fd5b600160a060020a03808a1660008181526009602090815260409182902080546001810190915582517f6e71edae12b1b97f4d1f60370fef10105fa2faae0126114a169c64845d6126c99281019290925281830193909352928b166060840152608083018a905260a0830182905260c08084018a90528151808503909101815260e090930190529250611149906115da565b9050611157818686866116e1565b600160a060020a038a811691161461116e57600080fd5b61117989898961127e565b505050505050505050565b336000908152600560209081526040808320600160a060020a03861684529091528120546111b8908363ffffffff6112da16565b336000818152600560209081526040808320600160a060020a038916808552908352928190208590558051948552519193600080516020611d92833981519152929081900390910190a350600192915050565b600160a060020a03918216600090815260056020908152604080832093909416825291909152205490565b61105f823383610870565b600654600160a060020a0316331461125857600080fd5b610cd281611a3e565b600a60209081526000928352604080842090915290825290205481565b6112898383836118e3565b60001981141561105f57600160a060020a038084166000908152600a60209081526040808320938616835292905290812055505050565b6000903b1190565b6000828211156112d457fe5b50900390565b818101828110156112e757fe5b92915050565b6112f682610e40565b1561105f5760408051600081526020810190915261131990849084908490611330565b151561105f57600080fd5b600061102b8383611abc565b600083600160a060020a031663a4c0ed3660e060020a028685856040516024018084600160a060020a0316600160a060020a0316815260200183815260200180602001828103825283818151815260200191508051906020019080838360005b838110156113a8578181015183820152602001611390565b50505050905090810190601f1680156113d55780820380516001836020036101000a031916815260200191505b5060408051601f198184030181529181526020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff00000000000000000000000000000000000000000000000000000000909916989098178852518151919790965086955093509150819050838360005b8381101561146357818101518382015260200161144b565b50505050905090810190601f1680156114905780820380516001836020036101000a031916815260200191505b509150506000604051808303816000865af1979650505050505050565b600160a060020a0382166000908152600360205260409020548111156114d257600080fd5b600160a060020a0382166000908152600360205260409020546114fb908263ffffffff6112c816565b600160a060020a038316600090815260036020526040902055600454611527908263ffffffff6112c816565b600455604080518281529051600160a060020a038416917fcc16f5dbb4873280815c1ee09dbd06736cffcc184412cf7a71a0fdb75d397ca5919081900360200190a2604080518281529051600091600160a060020a03851691600080516020611d728339815191529181900360200190a35050565b80600160a060020a03811615156115b257600080fd5b600160a060020a03831615156115d0576115cb82611b8b565b61105f565b61105f8383611b97565b6000600854826040518082805190602001908083835b6020831061160f5780518252601f1990920191602091820191016115f0565b51815160209384036101000a6000190180199092169116179052604080519290940182900382207f190100000000000000000000000000000000000000000000000000000000000083830152602283019790975260428083019790975283518083039097018752606290910192839052855192945084935085019190508083835b602083106116af5780518252601f199092019160209182019101611690565b5181516020939093036101000a6000190180199091169216919091179052604051920182900390912095945050505050565b6000808460ff16601b14806116f957508460ff16601c145b1515611775576040805160e560020a62461bcd02815260206004820152602260248201527f45434453413a20696e76616c6964207369676e6174757265202776272076616c60448201527f7565000000000000000000000000000000000000000000000000000000000000606482015290519081900360840190fd5b7f7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a0831115611813576040805160e560020a62461bcd02815260206004820152602260248201527f45434453413a20696e76616c6964207369676e6174757265202773272076616c60448201527f7565000000000000000000000000000000000000000000000000000000000000606482015290519081900360840190fd5b60408051600080825260208083018085528a905260ff8916838501526060830188905260808301879052925160019360a0808501949193601f19840193928390039091019190865af115801561186d573d6000803e3d6000fd5b5050604051601f190151915050600160a060020a03811615156118da576040805160e560020a62461bcd02815260206004820152601860248201527f45434453413a20696e76616c6964207369676e61747572650000000000000000604482015290519081900360640190fd5b95945050505050565b600160a060020a0383161515611968576040805160e560020a62461bcd028152602060048201526024808201527f45524332303a20617070726f76652066726f6d20746865207a65726f2061646460448201527f7265737300000000000000000000000000000000000000000000000000000000606482015290519081900360840190fd5b600160a060020a03821615156119ee576040805160e560020a62461bcd02815260206004820152602260248201527f45524332303a20617070726f766520746f20746865207a65726f20616464726560448201527f7373000000000000000000000000000000000000000000000000000000000000606482015290519081900360840190fd5b600160a060020a0380841660008181526005602090815260408083209487168084529482529182902085905581518581529151600080516020611d928339815191529281900390910190a3505050565b600160a060020a0381161515611a5357600080fd5b600654604051600160a060020a038084169216907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a36006805473ffffffffffffffffffffffffffffffffffffffff1916600160a060020a0392909216919091179055565b33600090815260036020526040812054821115611ad857600080fd5b600160a060020a0383161515611aed57600080fd5b33600090815260036020526040902054611b0d908363ffffffff6112c816565b3360009081526003602052604080822092909255600160a060020a03851681522054611b3f908363ffffffff6112da16565b600160a060020a038416600081815260036020908152604091829020939093558051858152905191923392600080516020611d728339815191529281900390910190a350600192915050565b3031610e0a8282611c44565b604080517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015290518391600091600160a060020a038416916370a0823191602480830192602092919082900301818787803b158015611bfc57600080fd5b505af1158015611c10573d6000803e3d6000fd5b505050506040513d6020811015611c2657600080fd5b5051905061106f600160a060020a038516848363ffffffff611cac16565b604051600160a060020a0383169082156108fc029083906000818181858888f193505050501515610e0a578082611c79611d41565b600160a060020a039091168152604051908190036020019082f080158015611ca5573d6000803e3d6000fd5b5050505050565b82600160a060020a031663a9059cbb83836040518363ffffffff1660e060020a0281526004018083600160a060020a0316600160a060020a0316815260200182815260200192505050600060405180830381600087803b158015611d0f57600080fd5b505af1158015611d23573d6000803e3d6000fd5b505050503d1561105f5760206000803e600051151561105f57600080fd5b604051602180611d51833901905600608060405260405160208060218339810160405251600160a060020a038116ff00ddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925a165627a7a72305820b96bb0733a3e45fdddafa592f51114d0cf16cad047ad60b9b91ae91eb772c6940029" - } - } -} diff --git a/consensus/aura/consensusconfig/poasokol.json b/consensus/aura/consensusconfig/poasokol.json deleted file mode 100644 index 0c8775312a4..00000000000 --- a/consensus/aura/consensusconfig/poasokol.json +++ /dev/null @@ -1,28 +0,0 @@ -{ - "stepDuration": 5, - "blockReward": "0xDE0B6B3A7640000", - "maximumUncleCountTransition": 0, - "maximumUncleCount": 0, - "validators": { - "multi": { - "0": { - "safeContract": "0x8bf38d4764929064f2d4d3a56520a76ab3df415b" - }, - "362296": { - "safeContract": "0xf5cE3f5D0366D6ec551C74CCb1F67e91c56F2e34" - }, - "509355": { - "safeContract": "0x03048F666359CFD3C74a1A5b9a97848BF71d5038" - }, - "4622420": { - "safeContract": "0x4c6a159659CCcb033F4b2e2Be0C16ACC62b89DDB" - } - } - }, - "blockRewardContractAddress": "0x3145197AD50D7083D0222DE4fCCf67d9BD05C30D", - "blockRewardContractTransition": 4639000, - "randomnessContractAddress": { - "13391641": "0x8f2b78169B0970F11a762e56659Db52B59CBCf1B" - } -} - diff --git a/consensus/aura/consensusconfig/test.json b/consensus/aura/consensusconfig/test.json deleted file mode 100644 index 07cbe9760b5..00000000000 --- a/consensus/aura/consensusconfig/test.json +++ /dev/null @@ -1,28 +0,0 @@ -{ - "stepDuration": 5, - "blockReward": "0x0", - "maximumUncleCountTransition": 0, - "maximumUncleCount": 0, - "validators": { - "multi": { - "0": { - "safeContract": "0x8bf38d4764929064f2d4d3a56520a76ab3df415b" - }, - "362296": { - "safeContract": "0xf5cE3f5D0366D6ec551C74CCb1F67e91c56F2e34" - }, - "509355": { - "safeContract": "0x03048F666359CFD3C74a1A5b9a97848BF71d5038" - }, - "4622420": { - "safeContract": "0x4c6a159659CCcb033F4b2e2Be0C16ACC62b89DDB" - } - } - }, - "blockRewardContractAddress": "0x3145197AD50D7083D0222DE4fCCf67d9BD05C30D", - "blockRewardContractTransition": 4639000, - "randomnessContractAddress": { - "13391641": "0x8f2b78169B0970F11a762e56659Db52B59CBCf1B" - } -} - diff --git a/consensus/aura/oe-test/authority_round.json b/consensus/aura/oe-test/authority_round.json deleted file mode 100644 index 292760444d6..00000000000 --- a/consensus/aura/oe-test/authority_round.json +++ /dev/null @@ -1,96 +0,0 @@ -{ - "name": "TestAuthorityRound", - "engine": { - "authorityRound": { - "params": { - "stepDuration": 1, - "startStep": 2, - "validators": { - "list": [ - "0x7d577a597b2742b498cb5cf0c26cdcd726d39e6e", - "0x82a978b3f5962a5b0957d9ee9eef472ee55b42f1" - ] - }, - "immediateTransitions": true - } - } - }, - "params": { - "gasLimitBoundDivisor": "0x0400", - "accountStartNonce": "0x0", - "maximumExtraDataSize": "0x20", - "minGasLimit": "0x1388", - "networkID" : "0x69", - "eip140Transition": "0x0", - "eip211Transition": "0x0", - "eip214Transition": "0x0", - "eip658Transition": "0x0" - }, - "genesis": { - "seal": { - "authorityRound": { - "step": "0x0", - "signature": "0x0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000" - } - }, - "difficulty": "0x20000", - "author": "0x0000000000000000000000000000000000000000", - "timestamp": "0x00", - "parentHash": "0x0000000000000000000000000000000000000000000000000000000000000000", - "extraData": "0x", - "gasLimit": "0x222222" - }, - "accounts": { - "0000000000000000000000000000000000000001": { "balance": "1", "nonce": "1048576", "builtin": { "name": "ecrecover", "pricing": { "linear": { "base": 3000, "word": 0 } } } }, - "0000000000000000000000000000000000000002": { "balance": "1", "nonce": "1048576", "builtin": { "name": "sha256", "pricing": { "linear": { "base": 60, "word": 12 } } } }, - "0000000000000000000000000000000000000003": { "balance": "1", "nonce": "1048576", "builtin": { "name": "ripemd160", "pricing": { "linear": { "base": 600, "word": 120 } } } }, - "0000000000000000000000000000000000000004": { "balance": "1", "nonce": "1048576", "builtin": { "name": "identity", "pricing": { "linear": { "base": 15, "word": 3 } } } }, - "0000000000000000000000000000000000000005": { "balance": "1", "builtin": { "name": "modexp", "activate_at": 0, "pricing": { "modexp": { "divisor": 20 } } } }, - "0000000000000000000000000000000000000006": { - "balance": "1", - "builtin": { - "name": "alt_bn128_add", - "pricing": { - "0": { - "price": { "alt_bn128_const_operations": { "price": 500 }} - }, - "0x7fffffffffffff": { - "info": "EIP 1108 transition", - "price": { "alt_bn128_const_operations": { "price": 150 }} - } - } - } - }, - "0000000000000000000000000000000000000007": { - "balance": "1", - "builtin": { - "name": "alt_bn128_mul", - "pricing": { - "0": { - "price": { "alt_bn128_const_operations": { "price": 40000 }} - }, - "0x7fffffffffffff": { - "info": "EIP 1108 transition", - "price": { "alt_bn128_const_operations": { "price": 6000 }} - } - } - } - }, - "0000000000000000000000000000000000000008": { - "balance": "1", - "builtin": { - "name": "alt_bn128_pairing", - "pricing": { - "0": { - "price": { "alt_bn128_pairing": { "base": 100000, "pair": 80000 }} - }, - "0x7fffffffffffff": { - "info": "EIP 1108 transition", - "price": { "alt_bn128_pairing": { "base": 45000, "pair": 34000 }} - } - } - } - }, - "9cce34f7ab185c7aba1b7c8140d620b4bda941d6": { "balance": "1606938044258990275541962092341162602522202993782792835301376", "nonce": "1048576" } - } -} diff --git a/consensus/aura/oe-test/authority_round_block_reward_contract.json b/consensus/aura/oe-test/authority_round_block_reward_contract.json deleted file mode 100644 index 4adb9a8d43c..00000000000 --- a/consensus/aura/oe-test/authority_round_block_reward_contract.json +++ /dev/null @@ -1,103 +0,0 @@ -{ - "name": "TestAuthorityRoundBlockRewardContract", - "engine": { - "authorityRound": { - "params": { - "stepDuration": 1, - "startStep": 2, - "validators": { - "list": [ - "0x7d577a597b2742b498cb5cf0c26cdcd726d39e6e", - "0x82a978b3f5962a5b0957d9ee9eef472ee55b42f1" - ] - }, - "immediateTransitions": true, - "emptyStepsTransition": "1", - "maximumEmptySteps": "2", - "blockRewardContractAddress": "0x0000000000000000000000000000000000000042" - } - } - }, - "params": { - "gasLimitBoundDivisor": "0x0400", - "accountStartNonce": "0x0", - "maximumExtraDataSize": "0x20", - "minGasLimit": "0x1388", - "networkID" : "0x69", - "eip140Transition": "0x0", - "eip211Transition": "0x0", - "eip214Transition": "0x0", - "eip658Transition": "0x0" - }, - "genesis": { - "seal": { - "authorityRound": { - "step": "0x0", - "signature": "0x0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000" - } - }, - "difficulty": "0x20000", - "author": "0x0000000000000000000000000000000000000000", - "timestamp": "0x00", - "parentHash": "0x0000000000000000000000000000000000000000000000000000000000000000", - "extraData": "0x", - "gasLimit": "0x222222" - }, - "accounts": { - "0000000000000000000000000000000000000001": { "balance": "1", "nonce": "1048576", "builtin": { "name": "ecrecover", "pricing": { "linear": { "base": 3000, "word": 0 } } } }, - "0000000000000000000000000000000000000002": { "balance": "1", "nonce": "1048576", "builtin": { "name": "sha256", "pricing": { "linear": { "base": 60, "word": 12 } } } }, - "0000000000000000000000000000000000000003": { "balance": "1", "nonce": "1048576", "builtin": { "name": "ripemd160", "pricing": { "linear": { "base": 600, "word": 120 } } } }, - "0000000000000000000000000000000000000004": { "balance": "1", "nonce": "1048576", "builtin": { "name": "identity", "pricing": { "linear": { "base": 15, "word": 3 } } } }, - "0000000000000000000000000000000000000005": { "balance": "1", "builtin": { "name": "modexp", "activate_at": 0, "pricing": { "modexp": { "divisor": 20 } } } }, - "0000000000000000000000000000000000000006": { - "balance": "1", - "builtin": { - "name": "alt_bn128_add", - "pricing": { - "0": { - "price": { "alt_bn128_const_operations": { "price": 500 }} - }, - "0x7fffffffffffff": { - "info": "EIP 1108 transition", - "price": { "alt_bn128_const_operations": { "price": 150 }} - } - } - } - }, - "0000000000000000000000000000000000000007": { - "balance": "1", - "builtin": { - "name": "alt_bn128_mul", - "pricing": { - "0": { - "price": { "alt_bn128_const_operations": { "price": 40000 }} - }, - "0x7fffffffffffff": { - "info": "EIP 1108 transition", - "price": { "alt_bn128_const_operations": { "price": 6000 }} - } - } - } - }, - "0000000000000000000000000000000000000008": { - "balance": "1", - "builtin": { - "name": "alt_bn128_pairing", - "pricing": { - "0": { - "price": { "alt_bn128_pairing": { "base": 100000, "pair": 80000 }} - }, - "0x7fffffffffffff": { - "info": "EIP 1108 transition", - "price": { "alt_bn128_pairing": { "base": 45000, "pair": 34000 }} - } - } - } - }, - "9cce34f7ab185c7aba1b7c8140d620b4bda941d6": { "balance": "1606938044258990275541962092341162602522202993782792835301376", "nonce": "1048576" }, - "0000000000000000000000000000000000000042": { - "balance": "1", - "constructor": "6060604052341561000f57600080fd5b6102b88061001e6000396000f300606060405260043610610041576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff168063f91c289814610046575b600080fd5b341561005157600080fd5b610086600480803590602001908201803590602001919091929080359060200190820180359060200191909192905050610125565b604051808060200180602001838103835285818151815260200191508051906020019060200280838360005b838110156100cd5780820151818401526020810190506100b2565b50505050905001838103825284818151815260200191508051906020019060200280838360005b8381101561010f5780820151818401526020810190506100f4565b5050505090500194505050505060405180910390f35b61012d610264565b610135610278565b61013d610278565b600073fffffffffffffffffffffffffffffffffffffffe73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614151561018d57600080fd5b85859050888890501415156101a157600080fd5b878790506040518059106101b25750595b90808252806020026020018201604052509150600090505b815181101561021d5785858281811015156101e157fe5b9050602002013561ffff166103e80161ffff16828281518110151561020257fe5b906020019060200201818152505080806001019150506101ca565b878783828280806020026020016040519081016040528093929190818152602001838360200280828437820191505050505050915090915093509350505094509492505050565b602060405190810160405280600081525090565b6020604051908101604052806000815250905600a165627a7a723058201da0f164e75517fb8baf51f030b904032cb748334938e7386f63025bfb23f3de0029" - } - } -} diff --git a/consensus/aura/oe-test/authority_round_empty_steps.json b/consensus/aura/oe-test/authority_round_empty_steps.json deleted file mode 100644 index b884e8e15a3..00000000000 --- a/consensus/aura/oe-test/authority_round_empty_steps.json +++ /dev/null @@ -1,51 +0,0 @@ -{ - "name": "TestAuthorityRoundEmptySteps", - "engine": { - "authorityRound": { - "params": { - "stepDuration": 1, - "startStep": 2, - "validators": { - "list": [ - "0x7d577a597b2742b498cb5cf0c26cdcd726d39e6e", - "0x82a978b3f5962a5b0957d9ee9eef472ee55b42f1" - ] - }, - "blockReward": "10", - "immediateTransitions": true, - "emptyStepsTransition": "1", - "maximumEmptySteps": "2" - } - } - }, - "params": { - "gasLimitBoundDivisor": "0x0400", - "accountStartNonce": "0x0", - "maximumExtraDataSize": "0x20", - "minGasLimit": "0x1388", - "networkID" : "0x69" - }, - "genesis": { - "seal": { - "authorityRound": { - "step": "0x0", - "signature": "0x0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000" - } - }, - "difficulty": "0x20000", - "author": "0x0000000000000000000000000000000000000000", - "timestamp": "0x00", - "parentHash": "0x0000000000000000000000000000000000000000000000000000000000000000", - "extraData": "0x", - "gasLimit": "0x222222" - }, - "accounts": { - "0000000000000000000000000000000000000001": { "balance": "1", "nonce": "1048576", "builtin": { "name": "ecrecover", "pricing": { "linear": { "base": 3000, "word": 0 } } } }, - "0000000000000000000000000000000000000002": { "balance": "1", "nonce": "1048576", "builtin": { "name": "sha256", "pricing": { "linear": { "base": 60, "word": 12 } } } }, - "0000000000000000000000000000000000000003": { "balance": "1", "nonce": "1048576", "builtin": { "name": "ripemd160", "pricing": { "linear": { "base": 600, "word": 120 } } } }, - "0000000000000000000000000000000000000004": { "balance": "1", "nonce": "1048576", "builtin": { "name": "identity", "pricing": { "linear": { "base": 15, "word": 3 } } } }, - "9cce34f7ab185c7aba1b7c8140d620b4bda941d6": { "balance": "1606938044258990275541962092341162602522202993782792835301376", "nonce": "1048576" }, - "7d577a597b2742b498cb5cf0c26cdcd726d39e6e": { "balance": "1000000000" }, - "82a978b3f5962a5b0957d9ee9eef472ee55b42f1": { "balance": "1000000000" } - } -} diff --git a/consensus/aura/oe-test/authority_round_randomness_contract.json b/consensus/aura/oe-test/authority_round_randomness_contract.json deleted file mode 100644 index 2c820ee7712..00000000000 --- a/consensus/aura/oe-test/authority_round_randomness_contract.json +++ /dev/null @@ -1,100 +0,0 @@ -{ - "name": "TestAuthorityRoundRandomnessContract", - "engine": { - "authorityRound": { - "params": { - "stepDuration": 1, - "startStep": 2, - "validators": { - "list": [ - "0x7d577a597b2742b498cb5cf0c26cdcd726d39e6e" - ] - }, - "immediateTransitions": true, - "maximumEmptySteps": "2", - "randomnessContractAddress": { - "0": "0x0000000000000000000000000000000000000042" - } - } - } - }, - "params": { - "gasLimitBoundDivisor": "0x0400", - "accountStartNonce": "0x0", - "maximumExtraDataSize": "0x20", - "minGasLimit": "0x1388", - "networkID" : "0x69", - "eip140Transition": "0x0", - "eip211Transition": "0x0", - "eip214Transition": "0x0", - "eip658Transition": "0x0" - }, - "genesis": { - "seal": { - "authorityRound": { - "step": "0x0", - "signature": "0x0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000" - } - }, - "difficulty": "0x20000", - "author": "0x0000000000000000000000000000000000000000", - "timestamp": "0x00", - "parentHash": "0x0000000000000000000000000000000000000000000000000000000000000000", - "extraData": "0x", - "gasLimit": "0x222222" - }, - "accounts": { - "0x7d577a597b2742b498cb5cf0c26cdcd726d39e6e": { "balance": "100000000000" }, - "0000000000000000000000000000000000000001": { "balance": "1", "nonce": "1048576", "builtin": { "name": "ecrecover", "pricing": { "linear": { "base": 3000, "word": 0 } } } }, - "0000000000000000000000000000000000000002": { "balance": "1", "nonce": "1048576", "builtin": { "name": "sha256", "pricing": { "linear": { "base": 60, "word": 12 } } } }, - "0000000000000000000000000000000000000003": { "balance": "1", "nonce": "1048576", "builtin": { "name": "ripemd160", "pricing": { "linear": { "base": 600, "word": 120 } } } }, - "0000000000000000000000000000000000000004": { "balance": "1", "nonce": "1048576", "builtin": { "name": "identity", "pricing": { "linear": { "base": 15, "word": 3 } } } }, - "0000000000000000000000000000000000000005": { "balance": "1", "builtin": { "name": "modexp", "activate_at": 0, "pricing": { "modexp": { "divisor": 20 } } } }, - "0000000000000000000000000000000000000006": { - "balance": "1", - "builtin": { - "name": "alt_bn128_add", - "pricing": { - "0x0": { - "price": { "linear": { "base": 500, "word": 0 }} - }, - "0x7fffffffffffff": { - "price": { "linear": { "base": 150, "word": 0 }} - } - } - } - }, - "0000000000000000000000000000000000000007": { - "balance": "1", - "builtin": { - "name": "alt_bn128_mul", - "pricing": { - "0x0": { - "price": { "linear": { "base": 40000, "word": 0 }} - }, - "0x7fffffffffffff": { - "price": { "linear": { "base": 6000, "word": 0 }} - } - } - } - }, - "0000000000000000000000000000000000000008": { - "balance": "1", - "builtin": { - "name": "alt_bn128_pairing", - "pricing": { - "0x0": { - "price": { "alt_bn128_pairing": { "base": 100000, "pair": 80000 }} - }, - "0x7fffffffffffff": { - "price": { "alt_bn128_pairing": { "base": 45000, "pair": 34000 }} - } - } - } - }, - "0000000000000000000000000000000000000042": { - "balance": "1", - "constructor": "608060405234801561001057600080fd5b50610820806100206000396000f3fe608060405234801561001057600080fd5b50600436106100ec576000357c01000000000000000000000000000000000000000000000000000000009004806363f160e6116100a95780637a3e286b116100835780637a3e286b14610378578063baf11cab14610380578063c358ced0146103ac578063fe7d567d146103b4576100ec565b806363f160e614610285578063695e89f6146102c557806374ce906714610370576100ec565b806304fdb016146100f15780630b61ba8514610192578063209652551461020b5780632e8a8dd5146102255780633fa4f245146102515780635580e58b14610259575b600080fd5b61011d6004803603604081101561010757600080fd5b5080359060200135600160a060020a03166103d1565b6040805160208082528351818301528351919283929083019185019080838360005b8381101561015757818101518382015260200161013f565b50505050905090810190601f1680156101845780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b610209600480360360408110156101a857600080fd5b813591908101906040810160208201356401000000008111156101ca57600080fd5b8201836020820111156101dc57600080fd5b803590602001918460018302840111640100000000831117156101fe57600080fd5b509092509050610475565b005b6102136104fa565b60408051918252519081900360200190f35b6102136004803603604081101561023b57600080fd5b5080359060200135600160a060020a0316610501565b61021361051b565b6102136004803603604081101561026f57600080fd5b5080359060200135600160a060020a0316610521565b6102b16004803603604081101561029b57600080fd5b5080359060200135600160a060020a031661053e565b604080519115158252519081900360200190f35b6102f1600480360360408110156102db57600080fd5b5080359060200135600160a060020a0316610568565b6040518083815260200180602001828103825283818151815260200191508051906020019080838360005b8381101561033457818101518382015260200161031c565b50505050905090810190601f1680156103615780820380516001836020036101000a031916815260200191505b50935050505060405180910390f35b6102b1610639565b610213610649565b6102b16004803603604081101561039657600080fd5b5080359060200135600160a060020a0316610654565b6102b161067c565b610209600480360360208110156103ca57600080fd5b5035610687565b600160208181526000938452604080852082529284529282902080548351600293821615610100026000190190911692909204601f8101859004850283018501909352828252909290919083018282801561046d5780601f106104425761010080835404028352916020019161046d565b820191906000526020600020905b81548152906001019060200180831161045057829003601f168201915b505050505081565b41331461048157600080fd5b61048d60014303610735565b61049657600080fd5b60006104a460014303610740565b90506104b08133610654565b156104ba57600080fd5b600081815260208181526040808320338085529083528184208890558484526001835281842090845290915290206104f3908484610753565b5050505050565b6003545b90565b600060208181529281526040808220909352908152205481565b60035481565b600260209081526000928352604080842090915290825290205481565b6000918252600260209081526040808420600160a060020a03939093168452919052902054151590565b600082815260208181526040808320600160a060020a03851680855290835281842054868552600180855283862092865291845282852080548451600294821615610100026000190190911693909304601f810186900486028401860190945283835260609491939092918391908301828280156106275780601f106105fc57610100808354040283529160200191610627565b820191906000526020600020905b81548152906001019060200180831161060a57829003601f168201915b50505050509050915091509250929050565b600061064443610735565b905090565b600061064443610740565b600091825260208281526040808420600160a060020a03939093168452919052902054151590565b600061064443610747565b41331461069357600080fd5b61069f60014303610747565b6106a857600080fd5b60006106b660014303610740565b90506106c2813361053e565b156106cc57600080fd5b60408051602080820185905282518083038201815291830183528151918101919091206000848152808352838120338252909252919020541461070e57600080fd5b60009081526002602090815260408083203384529091529020819055600380549091189055565b600360069091061090565b6006900490565b60036006909106101590565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f106107945782800160ff198235161785556107c1565b828001600101855582156107c1579182015b828111156107c15782358255916020019190600101906107a6565b506107cd9291506107d1565b5090565b6104fe91905b808211156107cd57600081556001016107d756fea265627a7a7230582008bb7311af9026bd70ddb998741333d414a366275b9b433a2943bbd6bedc27ae64736f6c634300050a0032" - } - } -} \ No newline at end of file diff --git a/consensus/aura/test/authority_round.json b/consensus/aura/test/authority_round.json deleted file mode 100644 index 292760444d6..00000000000 --- a/consensus/aura/test/authority_round.json +++ /dev/null @@ -1,96 +0,0 @@ -{ - "name": "TestAuthorityRound", - "engine": { - "authorityRound": { - "params": { - "stepDuration": 1, - "startStep": 2, - "validators": { - "list": [ - "0x7d577a597b2742b498cb5cf0c26cdcd726d39e6e", - "0x82a978b3f5962a5b0957d9ee9eef472ee55b42f1" - ] - }, - "immediateTransitions": true - } - } - }, - "params": { - "gasLimitBoundDivisor": "0x0400", - "accountStartNonce": "0x0", - "maximumExtraDataSize": "0x20", - "minGasLimit": "0x1388", - "networkID" : "0x69", - "eip140Transition": "0x0", - "eip211Transition": "0x0", - "eip214Transition": "0x0", - "eip658Transition": "0x0" - }, - "genesis": { - "seal": { - "authorityRound": { - "step": "0x0", - "signature": "0x0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000" - } - }, - "difficulty": "0x20000", - "author": "0x0000000000000000000000000000000000000000", - "timestamp": "0x00", - "parentHash": "0x0000000000000000000000000000000000000000000000000000000000000000", - "extraData": "0x", - "gasLimit": "0x222222" - }, - "accounts": { - "0000000000000000000000000000000000000001": { "balance": "1", "nonce": "1048576", "builtin": { "name": "ecrecover", "pricing": { "linear": { "base": 3000, "word": 0 } } } }, - "0000000000000000000000000000000000000002": { "balance": "1", "nonce": "1048576", "builtin": { "name": "sha256", "pricing": { "linear": { "base": 60, "word": 12 } } } }, - "0000000000000000000000000000000000000003": { "balance": "1", "nonce": "1048576", "builtin": { "name": "ripemd160", "pricing": { "linear": { "base": 600, "word": 120 } } } }, - "0000000000000000000000000000000000000004": { "balance": "1", "nonce": "1048576", "builtin": { "name": "identity", "pricing": { "linear": { "base": 15, "word": 3 } } } }, - "0000000000000000000000000000000000000005": { "balance": "1", "builtin": { "name": "modexp", "activate_at": 0, "pricing": { "modexp": { "divisor": 20 } } } }, - "0000000000000000000000000000000000000006": { - "balance": "1", - "builtin": { - "name": "alt_bn128_add", - "pricing": { - "0": { - "price": { "alt_bn128_const_operations": { "price": 500 }} - }, - "0x7fffffffffffff": { - "info": "EIP 1108 transition", - "price": { "alt_bn128_const_operations": { "price": 150 }} - } - } - } - }, - "0000000000000000000000000000000000000007": { - "balance": "1", - "builtin": { - "name": "alt_bn128_mul", - "pricing": { - "0": { - "price": { "alt_bn128_const_operations": { "price": 40000 }} - }, - "0x7fffffffffffff": { - "info": "EIP 1108 transition", - "price": { "alt_bn128_const_operations": { "price": 6000 }} - } - } - } - }, - "0000000000000000000000000000000000000008": { - "balance": "1", - "builtin": { - "name": "alt_bn128_pairing", - "pricing": { - "0": { - "price": { "alt_bn128_pairing": { "base": 100000, "pair": 80000 }} - }, - "0x7fffffffffffff": { - "info": "EIP 1108 transition", - "price": { "alt_bn128_pairing": { "base": 45000, "pair": 34000 }} - } - } - } - }, - "9cce34f7ab185c7aba1b7c8140d620b4bda941d6": { "balance": "1606938044258990275541962092341162602522202993782792835301376", "nonce": "1048576" } - } -} diff --git a/consensus/aura/test/authority_round_block_reward_contract.json b/consensus/aura/test/authority_round_block_reward_contract.json deleted file mode 100644 index d3b62b76d54..00000000000 --- a/consensus/aura/test/authority_round_block_reward_contract.json +++ /dev/null @@ -1,14 +0,0 @@ -{ - "stepDuration": 1, - "startStep": 2, - "validators": { - "list": [ - "0x7d577a597b2742b498cb5cf0c26cdcd726d39e6e", - "0x82a978b3f5962a5b0957d9ee9eef472ee55b42f1" - ] - }, - "immediateTransitions": true, - "emptyStepsTransition": 1, - "maximumEmptySteps": 2, - "blockRewardContractAddress": "0x0000000000000000000000000000000000000042" -} \ No newline at end of file diff --git a/consensus/aura/test/authority_round_empty_steps.json b/consensus/aura/test/authority_round_empty_steps.json deleted file mode 100644 index b884e8e15a3..00000000000 --- a/consensus/aura/test/authority_round_empty_steps.json +++ /dev/null @@ -1,51 +0,0 @@ -{ - "name": "TestAuthorityRoundEmptySteps", - "engine": { - "authorityRound": { - "params": { - "stepDuration": 1, - "startStep": 2, - "validators": { - "list": [ - "0x7d577a597b2742b498cb5cf0c26cdcd726d39e6e", - "0x82a978b3f5962a5b0957d9ee9eef472ee55b42f1" - ] - }, - "blockReward": "10", - "immediateTransitions": true, - "emptyStepsTransition": "1", - "maximumEmptySteps": "2" - } - } - }, - "params": { - "gasLimitBoundDivisor": "0x0400", - "accountStartNonce": "0x0", - "maximumExtraDataSize": "0x20", - "minGasLimit": "0x1388", - "networkID" : "0x69" - }, - "genesis": { - "seal": { - "authorityRound": { - "step": "0x0", - "signature": "0x0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000" - } - }, - "difficulty": "0x20000", - "author": "0x0000000000000000000000000000000000000000", - "timestamp": "0x00", - "parentHash": "0x0000000000000000000000000000000000000000000000000000000000000000", - "extraData": "0x", - "gasLimit": "0x222222" - }, - "accounts": { - "0000000000000000000000000000000000000001": { "balance": "1", "nonce": "1048576", "builtin": { "name": "ecrecover", "pricing": { "linear": { "base": 3000, "word": 0 } } } }, - "0000000000000000000000000000000000000002": { "balance": "1", "nonce": "1048576", "builtin": { "name": "sha256", "pricing": { "linear": { "base": 60, "word": 12 } } } }, - "0000000000000000000000000000000000000003": { "balance": "1", "nonce": "1048576", "builtin": { "name": "ripemd160", "pricing": { "linear": { "base": 600, "word": 120 } } } }, - "0000000000000000000000000000000000000004": { "balance": "1", "nonce": "1048576", "builtin": { "name": "identity", "pricing": { "linear": { "base": 15, "word": 3 } } } }, - "9cce34f7ab185c7aba1b7c8140d620b4bda941d6": { "balance": "1606938044258990275541962092341162602522202993782792835301376", "nonce": "1048576" }, - "7d577a597b2742b498cb5cf0c26cdcd726d39e6e": { "balance": "1000000000" }, - "82a978b3f5962a5b0957d9ee9eef472ee55b42f1": { "balance": "1000000000" } - } -} diff --git a/consensus/aura/test/authority_round_randomness_contract.json b/consensus/aura/test/authority_round_randomness_contract.json deleted file mode 100644 index 2c820ee7712..00000000000 --- a/consensus/aura/test/authority_round_randomness_contract.json +++ /dev/null @@ -1,100 +0,0 @@ -{ - "name": "TestAuthorityRoundRandomnessContract", - "engine": { - "authorityRound": { - "params": { - "stepDuration": 1, - "startStep": 2, - "validators": { - "list": [ - "0x7d577a597b2742b498cb5cf0c26cdcd726d39e6e" - ] - }, - "immediateTransitions": true, - "maximumEmptySteps": "2", - "randomnessContractAddress": { - "0": "0x0000000000000000000000000000000000000042" - } - } - } - }, - "params": { - "gasLimitBoundDivisor": "0x0400", - "accountStartNonce": "0x0", - "maximumExtraDataSize": "0x20", - "minGasLimit": "0x1388", - "networkID" : "0x69", - "eip140Transition": "0x0", - "eip211Transition": "0x0", - "eip214Transition": "0x0", - "eip658Transition": "0x0" - }, - "genesis": { - "seal": { - "authorityRound": { - "step": "0x0", - "signature": "0x0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000" - } - }, - "difficulty": "0x20000", - "author": "0x0000000000000000000000000000000000000000", - "timestamp": "0x00", - "parentHash": "0x0000000000000000000000000000000000000000000000000000000000000000", - "extraData": "0x", - "gasLimit": "0x222222" - }, - "accounts": { - "0x7d577a597b2742b498cb5cf0c26cdcd726d39e6e": { "balance": "100000000000" }, - "0000000000000000000000000000000000000001": { "balance": "1", "nonce": "1048576", "builtin": { "name": "ecrecover", "pricing": { "linear": { "base": 3000, "word": 0 } } } }, - "0000000000000000000000000000000000000002": { "balance": "1", "nonce": "1048576", "builtin": { "name": "sha256", "pricing": { "linear": { "base": 60, "word": 12 } } } }, - "0000000000000000000000000000000000000003": { "balance": "1", "nonce": "1048576", "builtin": { "name": "ripemd160", "pricing": { "linear": { "base": 600, "word": 120 } } } }, - "0000000000000000000000000000000000000004": { "balance": "1", "nonce": "1048576", "builtin": { "name": "identity", "pricing": { "linear": { "base": 15, "word": 3 } } } }, - "0000000000000000000000000000000000000005": { "balance": "1", "builtin": { "name": "modexp", "activate_at": 0, "pricing": { "modexp": { "divisor": 20 } } } }, - "0000000000000000000000000000000000000006": { - "balance": "1", - "builtin": { - "name": "alt_bn128_add", - "pricing": { - "0x0": { - "price": { "linear": { "base": 500, "word": 0 }} - }, - "0x7fffffffffffff": { - "price": { "linear": { "base": 150, "word": 0 }} - } - } - } - }, - "0000000000000000000000000000000000000007": { - "balance": "1", - "builtin": { - "name": "alt_bn128_mul", - "pricing": { - "0x0": { - "price": { "linear": { "base": 40000, "word": 0 }} - }, - "0x7fffffffffffff": { - "price": { "linear": { "base": 6000, "word": 0 }} - } - } - } - }, - "0000000000000000000000000000000000000008": { - "balance": "1", - "builtin": { - "name": "alt_bn128_pairing", - "pricing": { - "0x0": { - "price": { "alt_bn128_pairing": { "base": 100000, "pair": 80000 }} - }, - "0x7fffffffffffff": { - "price": { "alt_bn128_pairing": { "base": 45000, "pair": 34000 }} - } - } - } - }, - "0000000000000000000000000000000000000042": { - "balance": "1", - "constructor": "608060405234801561001057600080fd5b50610820806100206000396000f3fe608060405234801561001057600080fd5b50600436106100ec576000357c01000000000000000000000000000000000000000000000000000000009004806363f160e6116100a95780637a3e286b116100835780637a3e286b14610378578063baf11cab14610380578063c358ced0146103ac578063fe7d567d146103b4576100ec565b806363f160e614610285578063695e89f6146102c557806374ce906714610370576100ec565b806304fdb016146100f15780630b61ba8514610192578063209652551461020b5780632e8a8dd5146102255780633fa4f245146102515780635580e58b14610259575b600080fd5b61011d6004803603604081101561010757600080fd5b5080359060200135600160a060020a03166103d1565b6040805160208082528351818301528351919283929083019185019080838360005b8381101561015757818101518382015260200161013f565b50505050905090810190601f1680156101845780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b610209600480360360408110156101a857600080fd5b813591908101906040810160208201356401000000008111156101ca57600080fd5b8201836020820111156101dc57600080fd5b803590602001918460018302840111640100000000831117156101fe57600080fd5b509092509050610475565b005b6102136104fa565b60408051918252519081900360200190f35b6102136004803603604081101561023b57600080fd5b5080359060200135600160a060020a0316610501565b61021361051b565b6102136004803603604081101561026f57600080fd5b5080359060200135600160a060020a0316610521565b6102b16004803603604081101561029b57600080fd5b5080359060200135600160a060020a031661053e565b604080519115158252519081900360200190f35b6102f1600480360360408110156102db57600080fd5b5080359060200135600160a060020a0316610568565b6040518083815260200180602001828103825283818151815260200191508051906020019080838360005b8381101561033457818101518382015260200161031c565b50505050905090810190601f1680156103615780820380516001836020036101000a031916815260200191505b50935050505060405180910390f35b6102b1610639565b610213610649565b6102b16004803603604081101561039657600080fd5b5080359060200135600160a060020a0316610654565b6102b161067c565b610209600480360360208110156103ca57600080fd5b5035610687565b600160208181526000938452604080852082529284529282902080548351600293821615610100026000190190911692909204601f8101859004850283018501909352828252909290919083018282801561046d5780601f106104425761010080835404028352916020019161046d565b820191906000526020600020905b81548152906001019060200180831161045057829003601f168201915b505050505081565b41331461048157600080fd5b61048d60014303610735565b61049657600080fd5b60006104a460014303610740565b90506104b08133610654565b156104ba57600080fd5b600081815260208181526040808320338085529083528184208890558484526001835281842090845290915290206104f3908484610753565b5050505050565b6003545b90565b600060208181529281526040808220909352908152205481565b60035481565b600260209081526000928352604080842090915290825290205481565b6000918252600260209081526040808420600160a060020a03939093168452919052902054151590565b600082815260208181526040808320600160a060020a03851680855290835281842054868552600180855283862092865291845282852080548451600294821615610100026000190190911693909304601f810186900486028401860190945283835260609491939092918391908301828280156106275780601f106105fc57610100808354040283529160200191610627565b820191906000526020600020905b81548152906001019060200180831161060a57829003601f168201915b50505050509050915091509250929050565b600061064443610735565b905090565b600061064443610740565b600091825260208281526040808420600160a060020a03939093168452919052902054151590565b600061064443610747565b41331461069357600080fd5b61069f60014303610747565b6106a857600080fd5b60006106b660014303610740565b90506106c2813361053e565b156106cc57600080fd5b60408051602080820185905282518083038201815291830183528151918101919091206000848152808352838120338252909252919020541461070e57600080fd5b60009081526002602090815260408083203384529091529020819055600380549091189055565b600360069091061090565b6006900490565b60036006909106101590565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f106107945782800160ff198235161785556107c1565b828001600101855582156107c1579182015b828111156107c15782358255916020019190600101906107a6565b506107cd9291506107d1565b5090565b6104fe91905b808211156107cd57600081556001016107d756fea265627a7a7230582008bb7311af9026bd70ddb998741333d414a366275b9b433a2943bbd6bedc27ae64736f6c634300050a0032" - } - } -} \ No newline at end of file diff --git a/consensus/aura/test/embed.go b/consensus/aura/test/embed.go deleted file mode 100644 index 8d9a4bc5e80..00000000000 --- a/consensus/aura/test/embed.go +++ /dev/null @@ -1,8 +0,0 @@ -package test - -import ( - _ "embed" -) - -//go:embed authority_round_block_reward_contract.json -var AuthorityRoundBlockRewardContract []byte diff --git a/consensus/aura/validators.go b/consensus/aura/validators.go index 57de94dc0db..0e2b8ea0235 100644 --- a/consensus/aura/validators.go +++ b/consensus/aura/validators.go @@ -8,7 +8,7 @@ import ( "strings" "sync" - lru "github.com/hashicorp/golang-lru" + "github.com/hashicorp/golang-lru/v2" libcommon "github.com/ledgerwatch/erigon-lib/common" "github.com/ledgerwatch/log/v3" "go.uber.org/atomic" @@ -412,8 +412,8 @@ func (q *ReportQueue) truncate() { // nolint type ValidatorSafeContract struct { contractAddress libcommon.Address - validators *lru.Cache // RwLock>, - reportQueue ReportQueue //Mutex, + validators *lru.Cache[libcommon.Hash, *SimpleList] // RwLock>, + reportQueue ReportQueue //Mutex, // The block number where we resent the queued reports last time. resentReportsInBlock atomic.Uint64 // If set, this is the block number at which the consensus engine switches from AuRa to AuRa @@ -426,7 +426,7 @@ type ValidatorSafeContract struct { func NewValidatorSafeContract(contractAddress libcommon.Address, posdaoTransition *uint64, client client) *ValidatorSafeContract { const MemoizeCapacity = 500 - c, err := lru.New(MemoizeCapacity) + c, err := lru.New[libcommon.Hash, *SimpleList](MemoizeCapacity) if err != nil { panic("error creating ValidatorSafeContract cache") } @@ -592,7 +592,7 @@ func (s *ValidatorSafeContract) defaultCaller(blockHash libcommon.Hash) (Call, e func (s *ValidatorSafeContract) getWithCaller(blockHash libcommon.Hash, nonce uint, caller consensus.Call) (libcommon.Address, error) { set, ok := s.validators.Get(blockHash) if ok { - return get(set.(ValidatorSet), blockHash, nonce, caller) + return get(set, blockHash, nonce, caller) } list, ok := s.getList(caller) @@ -605,7 +605,7 @@ func (s *ValidatorSafeContract) getWithCaller(blockHash libcommon.Hash, nonce ui func (s *ValidatorSafeContract) countWithCaller(parentHash libcommon.Hash, caller consensus.Call) (uint64, error) { set, ok := s.validators.Get(parentHash) if ok { - return count(set.(ValidatorSet), parentHash, caller) + return count(set, parentHash, caller) } list, ok := s.getList(caller) if !ok { diff --git a/consensus/bor/api.go b/consensus/bor/api.go index c8b5284bdb1..ca78de76494 100644 --- a/consensus/bor/api.go +++ b/consensus/bor/api.go @@ -8,8 +8,8 @@ import ( "strconv" "sync" - lru2 "github.com/hashicorp/golang-lru/v2" - libcommon "github.com/ledgerwatch/erigon-lib/common" + "github.com/hashicorp/golang-lru/v2" + "github.com/ledgerwatch/erigon-lib/common" "github.com/xsleonard/go-merkle" "golang.org/x/crypto/sha3" @@ -30,7 +30,7 @@ var ( type API struct { chain consensus.ChainHeaderReader bor *Bor - rootHashCache *lru2.ARCCache[string, string] + rootHashCache *lru.ARCCache[string, string] } // GetSnapshot retrieves the state snapshot at a given block. @@ -53,15 +53,15 @@ func (api *API) GetSnapshot(number *rpc.BlockNumber) (*Snapshot, error) { type BlockSigners struct { Signers []difficultiesKV Diff int - Author libcommon.Address + Author common.Address } type difficultiesKV struct { - Signer libcommon.Address + Signer common.Address Difficulty uint64 } -func rankMapDifficulties(values map[libcommon.Address]uint64) []difficultiesKV { +func rankMapDifficulties(values map[common.Address]uint64) []difficultiesKV { ss := make([]difficultiesKV, 0, len(values)) for k, v := range values { ss = append(ss, difficultiesKV{k, v}) @@ -78,7 +78,7 @@ func rankMapDifficulties(values map[libcommon.Address]uint64) []difficultiesKV { func (api *API) GetSnapshotProposerSequence(number *rpc.BlockNumber) (BlockSigners, error) { snapNumber := *number - 1 - var difficulties = make(map[libcommon.Address]uint64) + var difficulties = make(map[common.Address]uint64) snap, err := api.GetSnapshot(&snapNumber) @@ -117,19 +117,19 @@ func (api *API) GetSnapshotProposerSequence(number *rpc.BlockNumber) (BlockSigne } // GetSnapshotProposer retrieves the in-turn signer at a given block. -func (api *API) GetSnapshotProposer(number *rpc.BlockNumber) (libcommon.Address, error) { +func (api *API) GetSnapshotProposer(number *rpc.BlockNumber) (common.Address, error) { *number -= 1 snap, err := api.GetSnapshot(number) if err != nil { - return libcommon.Address{}, err + return common.Address{}, err } return snap.ValidatorSet.GetProposer().Address, nil } // GetAuthor retrieves the author a block. -func (api *API) GetAuthor(number *rpc.BlockNumber) (*libcommon.Address, error) { +func (api *API) GetAuthor(number *rpc.BlockNumber) (*common.Address, error) { // Retrieve the requested block number (or current if none requested) var header *types.Header if number == nil || *number == rpc.LatestBlockNumber { @@ -148,7 +148,7 @@ func (api *API) GetAuthor(number *rpc.BlockNumber) (*libcommon.Address, error) { } // GetSnapshotAtHash retrieves the state snapshot at a given block. -func (api *API) GetSnapshotAtHash(hash libcommon.Hash) (*Snapshot, error) { +func (api *API) GetSnapshotAtHash(hash common.Hash) (*Snapshot, error) { header := api.chain.GetHeaderByHash(hash) if header == nil { return nil, errUnknownBlock @@ -158,7 +158,7 @@ func (api *API) GetSnapshotAtHash(hash libcommon.Hash) (*Snapshot, error) { } // GetSigners retrieves the list of authorized signers at the specified block. -func (api *API) GetSigners(number *rpc.BlockNumber) ([]libcommon.Address, error) { +func (api *API) GetSigners(number *rpc.BlockNumber) ([]common.Address, error) { // Retrieve the requested block number (or current if none requested) var header *types.Header if number == nil || *number == rpc.LatestBlockNumber { @@ -181,7 +181,7 @@ func (api *API) GetSigners(number *rpc.BlockNumber) ([]libcommon.Address, error) } // GetSignersAtHash retrieves the list of authorized signers at the specified block. -func (api *API) GetSignersAtHash(hash libcommon.Hash) ([]libcommon.Address, error) { +func (api *API) GetSignersAtHash(hash common.Hash) ([]common.Address, error) { header := api.chain.GetHeaderByHash(hash) if header == nil { return nil, errUnknownBlock @@ -197,10 +197,10 @@ func (api *API) GetSignersAtHash(hash libcommon.Hash) ([]libcommon.Address, erro } // GetCurrentProposer gets the current proposer -func (api *API) GetCurrentProposer() (libcommon.Address, error) { +func (api *API) GetCurrentProposer() (common.Address, error) { snap, err := api.GetSnapshot(nil) if err != nil { - return libcommon.Address{}, err + return common.Address{}, err } return snap.ValidatorSet.GetProposer().Address, nil @@ -289,7 +289,7 @@ func (api *API) GetRootHash(start uint64, end uint64) (string, error) { func (api *API) initializeRootHashCache() error { var err error if api.rootHashCache == nil { - api.rootHashCache, err = lru2.NewARC[string, string](10) + api.rootHashCache, err = lru.NewARC[string, string](10) } return err diff --git a/consensus/bor/bor.go b/consensus/bor/bor.go index 583811953ac..c4759484fdd 100644 --- a/consensus/bor/bor.go +++ b/consensus/bor/bor.go @@ -760,7 +760,7 @@ func (c *Bor) Prepare(chain consensus.ChainHeaderReader, header *types.Header, s // rewards given. func (c *Bor) Finalize(config *chain.Config, header *types.Header, state *state.IntraBlockState, txs types.Transactions, uncles []*types.Header, r types.Receipts, withdrawals []*types.Withdrawal, - e consensus.EpochReader, chain consensus.ChainHeaderReader, syscall consensus.SystemCall, + chain consensus.ChainHeaderReader, syscall consensus.SystemCall, ) (types.Transactions, types.Receipts, error) { var err error @@ -836,7 +836,7 @@ func (c *Bor) changeContractCodeIfNeeded(headerNumber uint64, state *state.Intra // nor block rewards given, and returns the final block. func (c *Bor) FinalizeAndAssemble(chainConfig *chain.Config, header *types.Header, state *state.IntraBlockState, txs types.Transactions, uncles []*types.Header, receipts types.Receipts, withdrawals []*types.Withdrawal, - e consensus.EpochReader, chain consensus.ChainHeaderReader, syscall consensus.SystemCall, call consensus.Call, + chain consensus.ChainHeaderReader, syscall consensus.SystemCall, call consensus.Call, ) (*types.Block, types.Transactions, types.Receipts, error) { // stateSyncData := []*types.StateSyncData{} @@ -885,7 +885,7 @@ func (c *Bor) GenerateSeal(chain consensus.ChainHeaderReader, currnt, parent *ty return nil } -func (c *Bor) Initialize(config *chain.Config, chain consensus.ChainHeaderReader, e consensus.EpochReader, header *types.Header, +func (c *Bor) Initialize(config *chain.Config, chain consensus.ChainHeaderReader, header *types.Header, state *state.IntraBlockState, txs []types.Transaction, uncles []*types.Header, syscall consensus.SystemCall) { } diff --git a/consensus/bor/clerk/clerk.go b/consensus/bor/clerk/clerk.go index 1069ce8d9a4..fa796213909 100644 --- a/consensus/bor/clerk/clerk.go +++ b/consensus/bor/clerk/clerk.go @@ -5,15 +5,14 @@ import ( "time" libcommon "github.com/ledgerwatch/erigon-lib/common" - - "github.com/ledgerwatch/erigon/common/hexutil" + "github.com/ledgerwatch/erigon-lib/common/hexutility" ) // EventRecord represents state record type EventRecord struct { ID uint64 `json:"id" yaml:"id"` Contract libcommon.Address `json:"contract" yaml:"contract"` - Data hexutil.Bytes `json:"data" yaml:"data"` + Data hexutility.Bytes `json:"data" yaml:"data"` TxHash libcommon.Hash `json:"tx_hash" yaml:"tx_hash"` LogIndex uint64 `json:"log_index" yaml:"log_index"` ChainID string `json:"bor_chain_id" yaml:"bor_chain_id"` diff --git a/consensus/bor/heimdall/span/spanner.go b/consensus/bor/heimdall/span/spanner.go index b978294e119..85eb4440c3b 100644 --- a/consensus/bor/heimdall/span/spanner.go +++ b/consensus/bor/heimdall/span/spanner.go @@ -6,8 +6,8 @@ import ( "github.com/ledgerwatch/erigon-lib/chain" libcommon "github.com/ledgerwatch/erigon-lib/common" - "github.com/ledgerwatch/erigon/accounts/abi" "github.com/ledgerwatch/erigon/consensus" + "github.com/ledgerwatch/erigon/consensus/bor/abi" "github.com/ledgerwatch/erigon/consensus/bor/valset" "github.com/ledgerwatch/erigon/params/networkname" "github.com/ledgerwatch/erigon/rlp" diff --git a/consensus/bor/snapshot.go b/consensus/bor/snapshot.go index 028d23246ac..31f361d7276 100644 --- a/consensus/bor/snapshot.go +++ b/consensus/bor/snapshot.go @@ -5,9 +5,9 @@ import ( "context" "encoding/json" - lru2 "github.com/hashicorp/golang-lru/v2" + "github.com/hashicorp/golang-lru/v2" "github.com/ledgerwatch/erigon-lib/chain" - libcommon "github.com/ledgerwatch/erigon-lib/common" + "github.com/ledgerwatch/erigon-lib/common" "github.com/ledgerwatch/erigon-lib/kv" "github.com/ledgerwatch/erigon/consensus/bor/valset" "github.com/ledgerwatch/erigon/core/types" @@ -15,19 +15,19 @@ import ( // Snapshot is the state of the authorization voting at a given point in time. type Snapshot struct { - config *chain.BorConfig // Consensus engine parameters to fine tune behavior - sigcache *lru2.ARCCache[libcommon.Hash, libcommon.Address] // Cache of recent block signatures to speed up ecrecover + config *chain.BorConfig // Consensus engine parameters to fine tune behavior + sigcache *lru.ARCCache[common.Hash, common.Address] // Cache of recent block signatures to speed up ecrecover - Number uint64 `json:"number"` // Block number where the snapshot was created - Hash libcommon.Hash `json:"hash"` // Block hash where the snapshot was created - ValidatorSet *valset.ValidatorSet `json:"validatorSet"` // Validator set at this moment - Recents map[uint64]libcommon.Address `json:"recents"` // Set of recent signers for spam protections + Number uint64 `json:"number"` // Block number where the snapshot was created + Hash common.Hash `json:"hash"` // Block hash where the snapshot was created + ValidatorSet *valset.ValidatorSet `json:"validatorSet"` // Validator set at this moment + Recents map[uint64]common.Address `json:"recents"` // Set of recent signers for spam protections } const BorSeparate = "BorSeparate" // signersAscending implements the sort interface to allow sorting a list of addresses -// type signersAscending []libcommon.Address +// type signersAscending []common.Address // func (s signersAscending) Len() int { return len(s) } // func (s signersAscending) Less(i, j int) bool { return bytes.Compare(s[i][:], s[j][:]) < 0 } @@ -38,9 +38,9 @@ const BorSeparate = "BorSeparate" // the genesis block. func newSnapshot( config *chain.BorConfig, - sigcache *lru2.ARCCache[libcommon.Hash, libcommon.Address], + sigcache *lru.ARCCache[common.Hash, common.Address], number uint64, - hash libcommon.Hash, + hash common.Hash, validators []*valset.Validator, ) *Snapshot { snap := &Snapshot{ @@ -49,13 +49,13 @@ func newSnapshot( Number: number, Hash: hash, ValidatorSet: valset.NewValidatorSet(validators), - Recents: make(map[uint64]libcommon.Address), + Recents: make(map[uint64]common.Address), } return snap } // loadSnapshot loads an existing snapshot from the database. -func loadSnapshot(config *chain.BorConfig, sigcache *lru2.ARCCache[libcommon.Hash, libcommon.Address], db kv.RwDB, hash libcommon.Hash) (*Snapshot, error) { +func loadSnapshot(config *chain.BorConfig, sigcache *lru.ARCCache[common.Hash, common.Address], db kv.RwDB, hash common.Hash) (*Snapshot, error) { tx, err := db.BeginRo(context.Background()) if err != nil { return nil, err @@ -74,6 +74,8 @@ func loadSnapshot(config *chain.BorConfig, sigcache *lru2.ARCCache[libcommon.Has return nil, err } + snap.ValidatorSet.UpdateValidatorMap() + snap.config = config snap.sigcache = sigcache @@ -105,7 +107,7 @@ func (s *Snapshot) copy() *Snapshot { Number: s.Number, Hash: s.Hash, ValidatorSet: s.ValidatorSet.Copy(), - Recents: make(map[uint64]libcommon.Address), + Recents: make(map[uint64]common.Address), } for block, signer := range s.Recents { cpy.Recents[block] = signer @@ -181,7 +183,7 @@ func (s *Snapshot) apply(headers []*types.Header) (*Snapshot, error) { } // GetSignerSuccessionNumber returns the relative position of signer in terms of the in-turn proposer -func (s *Snapshot) GetSignerSuccessionNumber(signer libcommon.Address) (int, error) { +func (s *Snapshot) GetSignerSuccessionNumber(signer common.Address) (int, error) { validators := s.ValidatorSet.Validators proposer := s.ValidatorSet.GetProposer().Address proposerIndex, _ := s.ValidatorSet.GetByAddress(proposer) @@ -207,8 +209,8 @@ func (s *Snapshot) GetSignerSuccessionNumber(signer libcommon.Address) (int, err } // signers retrieves the list of authorized signers in ascending order. -func (s *Snapshot) signers() []libcommon.Address { - sigs := make([]libcommon.Address, 0, len(s.ValidatorSet.Validators)) +func (s *Snapshot) signers() []common.Address { + sigs := make([]common.Address, 0, len(s.ValidatorSet.Validators)) for _, sig := range s.ValidatorSet.Validators { sigs = append(sigs, sig.Address) } @@ -217,9 +219,9 @@ func (s *Snapshot) signers() []libcommon.Address { } // Difficulty returns the difficulty for a particular signer at the current snapshot number -func (s *Snapshot) Difficulty(signer libcommon.Address) uint64 { +func (s *Snapshot) Difficulty(signer common.Address) uint64 { // if signer is empty - if bytes.Equal(signer.Bytes(), libcommon.Address{}.Bytes()) { + if bytes.Equal(signer.Bytes(), common.Address{}.Bytes()) { return 1 } diff --git a/consensus/clique/clique.go b/consensus/clique/clique.go index dab221f122c..19dd62b6f4c 100644 --- a/consensus/clique/clique.go +++ b/consensus/clique/clique.go @@ -29,7 +29,7 @@ import ( "time" "github.com/goccy/go-json" - lru "github.com/hashicorp/golang-lru" + lru "github.com/hashicorp/golang-lru/v2" "github.com/ledgerwatch/erigon-lib/chain" libcommon "github.com/ledgerwatch/erigon-lib/common" "github.com/ledgerwatch/erigon-lib/kv" @@ -40,6 +40,7 @@ import ( "github.com/ledgerwatch/erigon/common/debug" "github.com/ledgerwatch/erigon/common/hexutil" "github.com/ledgerwatch/erigon/consensus" + "github.com/ledgerwatch/erigon/consensus/misc" "github.com/ledgerwatch/erigon/core/state" "github.com/ledgerwatch/erigon/core/types" "github.com/ledgerwatch/erigon/core/types/accounts" @@ -144,13 +145,13 @@ var ( type SignerFn func(signer libcommon.Address, mimeType string, message []byte) ([]byte, error) // ecrecover extracts the Ethereum account address from a signed header. -func ecrecover(header *types.Header, sigcache *lru.ARCCache) (libcommon.Address, error) { +func ecrecover(header *types.Header, sigcache *lru.ARCCache[libcommon.Hash, libcommon.Address]) (libcommon.Address, error) { // If the signature's already cached, return that hash := header.Hash() // hitrate while straight-forward sync is from 0.5 to 0.65 if address, known := sigcache.Peek(hash); known { - return address.(libcommon.Address), nil + return address, nil } // Retrieve the signature from the header extra-data @@ -180,8 +181,8 @@ type Clique struct { snapshotConfig *params.ConsensusSnapshotConfig // Consensus engine configuration parameters db kv.RwDB // Database to store and retrieve snapshot checkpoints - signatures *lru.ARCCache // Signatures of recent blocks to speed up mining - recents *lru.ARCCache // Snapshots for recent block to speed up reorgs + signatures *lru.ARCCache[libcommon.Hash, libcommon.Address] // Signatures of recent blocks to speed up mining + recents *lru.ARCCache[libcommon.Hash, *Snapshot] // Snapshots for recent block to speed up reorgs proposals map[libcommon.Address]bool // Current list of proposals we are pushing @@ -206,8 +207,8 @@ func New(cfg *chain.Config, snapshotConfig *params.ConsensusSnapshotConfig, cliq conf.Epoch = epochLength } // Allocate the snapshot caches and create the engine - recents, _ := lru.NewARC(snapshotConfig.InmemorySnapshots) - signatures, _ := lru.NewARC(snapshotConfig.InmemorySignatures) + recents, _ := lru.NewARC[libcommon.Hash, *Snapshot](snapshotConfig.InmemorySnapshots) + signatures, _ := lru.NewARC[libcommon.Hash, libcommon.Address](snapshotConfig.InmemorySignatures) exitCh := make(chan struct{}) @@ -361,7 +362,7 @@ func (c *Clique) Prepare(chain consensus.ChainHeaderReader, header *types.Header return nil } -func (c *Clique) Initialize(config *chain.Config, chain consensus.ChainHeaderReader, e consensus.EpochReader, header *types.Header, +func (c *Clique) Initialize(config *chain.Config, chain consensus.ChainHeaderReader, header *types.Header, state *state.IntraBlockState, txs []types.Transaction, uncles []*types.Header, syscall consensus.SystemCall) { } @@ -369,10 +370,17 @@ func (c *Clique) Initialize(config *chain.Config, chain consensus.ChainHeaderRea // rewards given. func (c *Clique) Finalize(config *chain.Config, header *types.Header, state *state.IntraBlockState, txs types.Transactions, uncles []*types.Header, r types.Receipts, withdrawals []*types.Withdrawal, - e consensus.EpochReader, chain consensus.ChainHeaderReader, syscall consensus.SystemCall, + chain consensus.ChainHeaderReader, syscall consensus.SystemCall, ) (types.Transactions, types.Receipts, error) { // No block rewards in PoA, so the state remains as is and uncles are dropped header.UncleHash = types.CalcUncleHash(nil) + if config.IsCancun(header.Time) { + if parent := chain.GetHeaderByHash(header.ParentHash); parent != nil { + header.SetExcessDataGas(misc.CalcExcessDataGas(parent.ExcessDataGas, misc.CountBlobs(txs))) + } else { + header.SetExcessDataGas(new(big.Int)) + } + } return txs, r, nil } @@ -380,7 +388,7 @@ func (c *Clique) Finalize(config *chain.Config, header *types.Header, state *sta // nor block rewards given, and returns the final block. func (c *Clique) FinalizeAndAssemble(chainConfig *chain.Config, header *types.Header, state *state.IntraBlockState, txs types.Transactions, uncles []*types.Header, receipts types.Receipts, withdrawals []*types.Withdrawal, - e consensus.EpochReader, chain consensus.ChainHeaderReader, syscall consensus.SystemCall, call consensus.Call, + chain consensus.ChainHeaderReader, syscall consensus.SystemCall, call consensus.Call, ) (*types.Block, types.Transactions, types.Receipts, error) { // No block rewards in PoA, so the state remains as is and uncles are dropped header.UncleHash = types.CalcUncleHash(nil) diff --git a/consensus/clique/snapshot.go b/consensus/clique/snapshot.go index 43637c73b80..db588c41f5f 100644 --- a/consensus/clique/snapshot.go +++ b/consensus/clique/snapshot.go @@ -25,7 +25,7 @@ import ( "time" "github.com/goccy/go-json" - lru "github.com/hashicorp/golang-lru" + "github.com/hashicorp/golang-lru/v2" "github.com/ledgerwatch/erigon-lib/chain" libcommon "github.com/ledgerwatch/erigon-lib/common" "github.com/ledgerwatch/erigon-lib/kv" @@ -124,7 +124,7 @@ func lastSnapshot(db kv.RwDB) (uint64, error) { lastEnc, err := tx.GetOne(kv.CliqueLastSnapshot, LastSnapshotKey()) if err != nil { - return 0, fmt.Errorf("failed check last clique snapshot: %d", err) + return 0, fmt.Errorf("failed check last clique snapshot: %w", err) } if len(lastEnc) == 0 { return 0, ErrNotFound @@ -196,7 +196,7 @@ func (s *Snapshot) uncast(address libcommon.Address, authorize bool) bool { // apply creates a new authorization snapshot by applying the given headers to // the original one. -func (s *Snapshot) apply(sigcache *lru.ARCCache, headers ...*types.Header) (*Snapshot, error) { +func (s *Snapshot) apply(sigcache *lru.ARCCache[libcommon.Hash, libcommon.Address], headers ...*types.Header) (*Snapshot, error) { // Allow passing in no headers for cleaner code if len(headers) == 0 { return s, nil diff --git a/consensus/clique/verifier.go b/consensus/clique/verifier.go index 4802d5dfb1e..8955e28fb8f 100644 --- a/consensus/clique/verifier.go +++ b/consensus/clique/verifier.go @@ -135,6 +135,14 @@ func (c *Clique) verifyCascadingFields(chain consensus.ChainHeaderReader, header // Verify the header's EIP-1559 attributes. return err } + if !chain.Config().IsCancun(header.Time) { + if header.ExcessDataGas != nil { + return fmt.Errorf("invalid excessDataGas before fork: have %v, expected 'nil'", header.ExcessDataGas) + } + } else if err := misc.VerifyEip4844Header(chain.Config(), parent, header); err != nil { + // Verify the header's EIP-4844 attributes. + return err + } // Retrieve the snapshot needed to verify this header and cache it snap, err := c.Snapshot(chain, number-1, header.ParentHash, parents) diff --git a/consensus/consensus.go b/consensus/consensus.go index 05500de6fe8..c4cd265496d 100644 --- a/consensus/consensus.go +++ b/consensus/consensus.go @@ -63,14 +63,6 @@ type ChainReader interface { HasBlock(hash libcommon.Hash, number uint64) bool } -type EpochReader interface { - GetEpoch(blockHash libcommon.Hash, blockN uint64) (transitionProof []byte, err error) - PutEpoch(blockHash libcommon.Hash, blockN uint64, transitionProof []byte) (err error) - GetPendingEpoch(blockHash libcommon.Hash, blockN uint64) (transitionProof []byte, err error) - PutPendingEpoch(blockHash libcommon.Hash, blockN uint64, transitionProof []byte) (err error) - FindBeforeOrEqualNumber(number uint64) (blockNum uint64, blockHash libcommon.Hash, transitionProof []byte, err error) -} - type SystemCall func(contract libcommon.Address, data []byte) ([]byte, error) type Call func(contract libcommon.Address, data []byte) ([]byte, error) @@ -110,7 +102,7 @@ type EngineWriter interface { Prepare(chain ChainHeaderReader, header *types.Header, state *state.IntraBlockState) error // Initialize runs any pre-transaction state modifications (e.g. epoch start) - Initialize(config *chain.Config, chain ChainHeaderReader, e EpochReader, header *types.Header, + Initialize(config *chain.Config, chain ChainHeaderReader, header *types.Header, state *state.IntraBlockState, txs []types.Transaction, uncles []*types.Header, syscall SystemCall) // Finalize runs any post-transaction state modifications (e.g. block rewards) @@ -120,7 +112,7 @@ type EngineWriter interface { // consensus rules that happen at finalization (e.g. block rewards). Finalize(config *chain.Config, header *types.Header, state *state.IntraBlockState, txs types.Transactions, uncles []*types.Header, receipts types.Receipts, withdrawals []*types.Withdrawal, - e EpochReader, chain ChainHeaderReader, syscall SystemCall, + chain ChainHeaderReader, syscall SystemCall, ) (types.Transactions, types.Receipts, error) // FinalizeAndAssemble runs any post-transaction state modifications (e.g. block @@ -128,10 +120,7 @@ type EngineWriter interface { // // Note: The block header and state database might be updated to reflect any // consensus rules that happen at finalization (e.g. block rewards). - FinalizeAndAssemble(config *chain.Config, header *types.Header, state *state.IntraBlockState, - txs types.Transactions, uncles []*types.Header, receipts types.Receipts, withdrawals []*types.Withdrawal, - e EpochReader, chain ChainHeaderReader, syscall SystemCall, call Call, - ) (*types.Block, types.Transactions, types.Receipts, error) + FinalizeAndAssemble(config *chain.Config, header *types.Header, state *state.IntraBlockState, txs types.Transactions, uncles []*types.Header, receipts types.Receipts, withdrawals []*types.Withdrawal, chain ChainHeaderReader, syscall SystemCall, call Call) (*types.Block, types.Transactions, types.Receipts, error) // Seal generates a new sealing request for the given input block and pushes // the result into the given channel. @@ -176,6 +165,8 @@ type PoSA interface { EnoughDistance(chain ChainReader, header *types.Header) bool IsLocalBlock(header *types.Header) bool AllowLightProcess(chain ChainReader, currentHeader *types.Header) bool + GetJustifiedNumberAndHash(chain ChainHeaderReader, header *types.Header) (uint64, libcommon.Hash, error) + GetFinalizedHeader(chain ChainHeaderReader, header *types.Header) *types.Header } type AsyncEngine interface { diff --git a/consensus/db/db.go b/consensus/db/db.go index c65ecc12c9d..118770100d7 100644 --- a/consensus/db/db.go +++ b/consensus/db/db.go @@ -6,8 +6,8 @@ import ( "github.com/ledgerwatch/log/v3" ) -func OpenDatabase(path string, logger log.Logger, inMem bool, readonly bool) kv.RwDB { - opts := mdbx.NewMDBX(logger).Label(kv.ConsensusDB) +func OpenDatabase(path string, inMem bool, readonly bool) kv.RwDB { + opts := mdbx.NewMDBX(log.Root()).Label(kv.ConsensusDB) if readonly { opts = opts.Readonly() } diff --git a/consensus/ethash/consensus.go b/consensus/ethash/consensus.go index 955cae04753..5469588deea 100644 --- a/consensus/ethash/consensus.go +++ b/consensus/ethash/consensus.go @@ -238,6 +238,14 @@ func VerifyHeaderBasics(chain consensus.ChainHeaderReader, header, parent *types // Verify the header's EIP-1559 attributes. return err } + if !chain.Config().IsCancun(header.Time) { + if header.ExcessDataGas != nil { + return fmt.Errorf("invalid excessDataGas before fork: have %v, expected 'nil'", header.ExcessDataGas) + } + } else if err := misc.VerifyEip4844Header(chain.Config(), parent, header); err != nil { + // Verify the header's EIP-4844 attributes. + return err + } // Verify that the block number is parent's +1 if diff := new(big.Int).Sub(header.Number, parent.Number); diff.Cmp(big.NewInt(1)) != 0 { @@ -551,7 +559,7 @@ func (ethash *Ethash) Prepare(chain consensus.ChainHeaderReader, header *types.H return nil } -func (ethash *Ethash) Initialize(config *chain.Config, chain consensus.ChainHeaderReader, e consensus.EpochReader, header *types.Header, +func (ethash *Ethash) Initialize(config *chain.Config, chain consensus.ChainHeaderReader, header *types.Header, state *state.IntraBlockState, txs []types.Transaction, uncles []*types.Header, syscall consensus.SystemCall) { } @@ -559,10 +567,17 @@ func (ethash *Ethash) Initialize(config *chain.Config, chain consensus.ChainHead // setting the final state on the header func (ethash *Ethash) Finalize(config *chain.Config, header *types.Header, state *state.IntraBlockState, txs types.Transactions, uncles []*types.Header, r types.Receipts, withdrawals []*types.Withdrawal, - e consensus.EpochReader, chain consensus.ChainHeaderReader, syscall consensus.SystemCall, + chain consensus.ChainHeaderReader, syscall consensus.SystemCall, ) (types.Transactions, types.Receipts, error) { // Accumulate any block and uncle rewards and commit the final state root accumulateRewards(config, state, header, uncles) + if config.IsCancun(header.Time) { + if parent := chain.GetHeaderByHash(header.ParentHash); parent != nil { + header.SetExcessDataGas(misc.CalcExcessDataGas(parent.ExcessDataGas, misc.CountBlobs(txs))) + } else { + header.SetExcessDataGas(new(big.Int)) + } + } return txs, r, nil } @@ -570,11 +585,11 @@ func (ethash *Ethash) Finalize(config *chain.Config, header *types.Header, state // uncle rewards, setting the final state and assembling the block. func (ethash *Ethash) FinalizeAndAssemble(chainConfig *chain.Config, header *types.Header, state *state.IntraBlockState, txs types.Transactions, uncles []*types.Header, r types.Receipts, withdrawals []*types.Withdrawal, - e consensus.EpochReader, chain consensus.ChainHeaderReader, syscall consensus.SystemCall, call consensus.Call, + chain consensus.ChainHeaderReader, syscall consensus.SystemCall, call consensus.Call, ) (*types.Block, types.Transactions, types.Receipts, error) { // Finalize block - outTxs, outR, err := ethash.Finalize(chainConfig, header, state, txs, uncles, r, withdrawals, e, chain, syscall) + outTxs, outR, err := ethash.Finalize(chainConfig, header, state, txs, uncles, r, withdrawals, chain, syscall) if err != nil { return nil, nil, nil, err } @@ -604,6 +619,9 @@ func (ethash *Ethash) SealHash(header *types.Header) (hash libcommon.Hash) { if header.BaseFee != nil { enc = append(enc, header.BaseFee) } + if header.ExcessDataGas != nil { + enc = append(enc, header.ExcessDataGas) + } rlp.Encode(hasher, enc) hasher.Sum(hash[:0]) return hash diff --git a/consensus/misc/eip4844.go b/consensus/misc/eip4844.go new file mode 100644 index 00000000000..84a649ff88d --- /dev/null +++ b/consensus/misc/eip4844.go @@ -0,0 +1,84 @@ +// Copyright 2021 The go-ethereum Authors +// This file is part of the go-ethereum library. +// +// The go-ethereum library is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// The go-ethereum library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with the go-ethereum library. If not, see . + +package misc + +import ( + "fmt" + "math/big" + + "github.com/ledgerwatch/erigon-lib/chain" + + "github.com/ledgerwatch/erigon/core/types" + "github.com/ledgerwatch/erigon/params" +) + +// CalcExcessDataGas implements calc_excess_data_gas from EIP-4844 +func CalcExcessDataGas(parentExcessDataGas *big.Int, newBlobs int) *big.Int { + excessDataGas := new(big.Int) + if parentExcessDataGas != nil { + excessDataGas.Set(parentExcessDataGas) + } + consumedGas := big.NewInt(params.DataGasPerBlob) + consumedGas.Mul(consumedGas, big.NewInt(int64(newBlobs))) + + excessDataGas.Add(excessDataGas, consumedGas) + targetGas := big.NewInt(params.TargetDataGasPerBlock) + if excessDataGas.Cmp(targetGas) < 0 { + return new(big.Int) + } + return new(big.Int).Set(excessDataGas.Sub(excessDataGas, targetGas)) +} + +// FakeExponential approximates factor * e ** (num / denom) using a taylor expansion +// as described in the EIP-4844 spec. +func FakeExponential(factor, num, denom *big.Int) *big.Int { + output := new(big.Int) + numAccum := new(big.Int).Mul(factor, denom) + for i := 1; numAccum.Sign() > 0; i++ { + output.Add(output, numAccum) + numAccum.Mul(numAccum, num) + iBig := big.NewInt(int64(i)) + numAccum.Div(numAccum, iBig.Mul(iBig, denom)) + } + return output.Div(output, denom) +} + +// CountBlobs returns the number of blob transactions in txs +func CountBlobs(txs []types.Transaction) int { + var count int + for _, tx := range txs { + count += len(tx.GetDataHashes()) + } + return count +} + +// VerifyEip4844Header verifies that the header is not malformed +func VerifyEip4844Header(config *chain.Config, parent, header *types.Header) error { + if header.ExcessDataGas == nil { + return fmt.Errorf("header is missing excessDataGas") + } + return nil +} + +// GetDataGasPrice implements get_data_gas_price from EIP-4844 +func GetDataGasPrice(excessDataGas *big.Int) *big.Int { + return FakeExponential(big.NewInt(params.MinDataGasPrice), excessDataGas, big.NewInt(params.DataGasPriceUpdateFraction)) +} + +func GetDataGasUsed(numBlobs int) uint64 { + return uint64(numBlobs) * params.DataGasPerBlob +} diff --git a/consensus/parlia/abi.go b/consensus/parlia/abi.go index e841eb5cd5c..ffe97a45ce4 100644 --- a/consensus/parlia/abi.go +++ b/consensus/parlia/abi.go @@ -1,6 +1,6 @@ package parlia -const validatorSetABI = ` +const validatorSetABIBeforeLuban = ` [ { "anonymous": false, @@ -1388,7 +1388,1605 @@ const validatorSetABI = ` "stateMutability": "view", "type": "function" } - ] +] +` + +const validatorSetABI = ` +[ + { + "anonymous":false, + "inputs":[ + { + "indexed":false, + "internalType":"uint256", + "name":"amount", + "type":"uint256" + } + ], + "name":"batchTransfer", + "type":"event" + }, + { + "anonymous":false, + "inputs":[ + { + "indexed":true, + "internalType":"uint256", + "name":"amount", + "type":"uint256" + }, + { + "indexed":false, + "internalType":"string", + "name":"reason", + "type":"string" + } + ], + "name":"batchTransferFailed", + "type":"event" + }, + { + "anonymous":false, + "inputs":[ + { + "indexed":true, + "internalType":"uint256", + "name":"amount", + "type":"uint256" + }, + { + "indexed":false, + "internalType":"bytes", + "name":"reason", + "type":"bytes" + } + ], + "name":"batchTransferLowerFailed", + "type":"event" + }, + { + "anonymous":false, + "inputs":[ + { + "indexed":true, + "internalType":"address", + "name":"validator", + "type":"address" + }, + { + "indexed":false, + "internalType":"uint256", + "name":"amount", + "type":"uint256" + } + ], + "name":"deprecatedDeposit", + "type":"event" + }, + { + "anonymous":false, + "inputs":[ + { + "indexed":true, + "internalType":"address", + "name":"validator", + "type":"address" + }, + { + "indexed":false, + "internalType":"uint256", + "name":"amount", + "type":"uint256" + } + ], + "name":"deprecatedFinalityRewardDeposit", + "type":"event" + }, + { + "anonymous":false, + "inputs":[ + { + "indexed":true, + "internalType":"address payable", + "name":"validator", + "type":"address" + }, + { + "indexed":false, + "internalType":"uint256", + "name":"amount", + "type":"uint256" + } + ], + "name":"directTransfer", + "type":"event" + }, + { + "anonymous":false, + "inputs":[ + { + "indexed":true, + "internalType":"address payable", + "name":"validator", + "type":"address" + }, + { + "indexed":false, + "internalType":"uint256", + "name":"amount", + "type":"uint256" + } + ], + "name":"directTransferFail", + "type":"event" + }, + { + "anonymous":false, + "inputs":[ + { + "indexed":false, + "internalType":"string", + "name":"message", + "type":"string" + } + ], + "name":"failReasonWithStr", + "type":"event" + }, + { + "anonymous":false, + "inputs":[ + { + "indexed":false, + "internalType":"uint256", + "name":"amount", + "type":"uint256" + } + ], + "name":"feeBurned", + "type":"event" + }, + { + "anonymous":false, + "inputs":[ + { + "indexed":true, + "internalType":"address", + "name":"validator", + "type":"address" + }, + { + "indexed":false, + "internalType":"uint256", + "name":"amount", + "type":"uint256" + } + ], + "name":"finalityRewardDeposit", + "type":"event" + }, + { + "anonymous":false, + "inputs":[ + { + "indexed":false, + "internalType":"string", + "name":"key", + "type":"string" + }, + { + "indexed":false, + "internalType":"bytes", + "name":"value", + "type":"bytes" + } + ], + "name":"paramChange", + "type":"event" + }, + { + "anonymous":false, + "inputs":[ + { + "indexed":false, + "internalType":"uint256", + "name":"amount", + "type":"uint256" + } + ], + "name":"systemTransfer", + "type":"event" + }, + { + "anonymous":false, + "inputs":[ + { + "indexed":false, + "internalType":"uint8", + "name":"channelId", + "type":"uint8" + }, + { + "indexed":false, + "internalType":"bytes", + "name":"msgBytes", + "type":"bytes" + } + ], + "name":"unexpectedPackage", + "type":"event" + }, + { + "anonymous":false, + "inputs":[ + { + "indexed":true, + "internalType":"address", + "name":"validator", + "type":"address" + }, + { + "indexed":false, + "internalType":"uint256", + "name":"amount", + "type":"uint256" + } + ], + "name":"validatorDeposit", + "type":"event" + }, + { + "anonymous":false, + "inputs":[ + { + "indexed":true, + "internalType":"address", + "name":"validator", + "type":"address" + } + ], + "name":"validatorEmptyJailed", + "type":"event" + }, + { + "anonymous":false, + "inputs":[ + { + "indexed":true, + "internalType":"address", + "name":"validator", + "type":"address" + } + ], + "name":"validatorEnterMaintenance", + "type":"event" + }, + { + "anonymous":false, + "inputs":[ + { + "indexed":true, + "internalType":"address", + "name":"validator", + "type":"address" + } + ], + "name":"validatorExitMaintenance", + "type":"event" + }, + { + "anonymous":false, + "inputs":[ + { + "indexed":true, + "internalType":"address", + "name":"validator", + "type":"address" + }, + { + "indexed":false, + "internalType":"uint256", + "name":"amount", + "type":"uint256" + } + ], + "name":"validatorFelony", + "type":"event" + }, + { + "anonymous":false, + "inputs":[ + { + "indexed":true, + "internalType":"address", + "name":"validator", + "type":"address" + } + ], + "name":"validatorJailed", + "type":"event" + }, + { + "anonymous":false, + "inputs":[ + { + "indexed":true, + "internalType":"address", + "name":"validator", + "type":"address" + }, + { + "indexed":false, + "internalType":"uint256", + "name":"amount", + "type":"uint256" + } + ], + "name":"validatorMisdemeanor", + "type":"event" + }, + { + "anonymous":false, + "inputs":[ + + ], + "name":"validatorSetUpdated", + "type":"event" + }, + { + "inputs":[ + + ], + "name":"BIND_CHANNELID", + "outputs":[ + { + "internalType":"uint8", + "name":"", + "type":"uint8" + } + ], + "stateMutability":"view", + "type":"function" + }, + { + "inputs":[ + + ], + "name":"BURN_ADDRESS", + "outputs":[ + { + "internalType":"address", + "name":"", + "type":"address" + } + ], + "stateMutability":"view", + "type":"function" + }, + { + "inputs":[ + + ], + "name":"BURN_RATIO_SCALE", + "outputs":[ + { + "internalType":"uint256", + "name":"", + "type":"uint256" + } + ], + "stateMutability":"view", + "type":"function" + }, + { + "inputs":[ + + ], + "name":"CODE_OK", + "outputs":[ + { + "internalType":"uint32", + "name":"", + "type":"uint32" + } + ], + "stateMutability":"view", + "type":"function" + }, + { + "inputs":[ + + ], + "name":"CROSS_CHAIN_CONTRACT_ADDR", + "outputs":[ + { + "internalType":"address", + "name":"", + "type":"address" + } + ], + "stateMutability":"view", + "type":"function" + }, + { + "inputs":[ + + ], + "name":"CROSS_STAKE_CHANNELID", + "outputs":[ + { + "internalType":"uint8", + "name":"", + "type":"uint8" + } + ], + "stateMutability":"view", + "type":"function" + }, + { + "inputs":[ + + ], + "name":"DUSTY_INCOMING", + "outputs":[ + { + "internalType":"uint256", + "name":"", + "type":"uint256" + } + ], + "stateMutability":"view", + "type":"function" + }, + { + "inputs":[ + + ], + "name":"EPOCH", + "outputs":[ + { + "internalType":"uint256", + "name":"", + "type":"uint256" + } + ], + "stateMutability":"view", + "type":"function" + }, + { + "inputs":[ + + ], + "name":"ERROR_FAIL_CHECK_VALIDATORS", + "outputs":[ + { + "internalType":"uint32", + "name":"", + "type":"uint32" + } + ], + "stateMutability":"view", + "type":"function" + }, + { + "inputs":[ + + ], + "name":"ERROR_FAIL_DECODE", + "outputs":[ + { + "internalType":"uint32", + "name":"", + "type":"uint32" + } + ], + "stateMutability":"view", + "type":"function" + }, + { + "inputs":[ + + ], + "name":"ERROR_LEN_OF_VAL_MISMATCH", + "outputs":[ + { + "internalType":"uint32", + "name":"", + "type":"uint32" + } + ], + "stateMutability":"view", + "type":"function" + }, + { + "inputs":[ + + ], + "name":"ERROR_RELAYFEE_TOO_LARGE", + "outputs":[ + { + "internalType":"uint32", + "name":"", + "type":"uint32" + } + ], + "stateMutability":"view", + "type":"function" + }, + { + "inputs":[ + + ], + "name":"ERROR_UNKNOWN_PACKAGE_TYPE", + "outputs":[ + { + "internalType":"uint32", + "name":"", + "type":"uint32" + } + ], + "stateMutability":"view", + "type":"function" + }, + { + "inputs":[ + + ], + "name":"EXPIRE_TIME_SECOND_GAP", + "outputs":[ + { + "internalType":"uint256", + "name":"", + "type":"uint256" + } + ], + "stateMutability":"view", + "type":"function" + }, + { + "inputs":[ + + ], + "name":"GOV_CHANNELID", + "outputs":[ + { + "internalType":"uint8", + "name":"", + "type":"uint8" + } + ], + "stateMutability":"view", + "type":"function" + }, + { + "inputs":[ + + ], + "name":"GOV_HUB_ADDR", + "outputs":[ + { + "internalType":"address", + "name":"", + "type":"address" + } + ], + "stateMutability":"view", + "type":"function" + }, + { + "inputs":[ + + ], + "name":"INCENTIVIZE_ADDR", + "outputs":[ + { + "internalType":"address", + "name":"", + "type":"address" + } + ], + "stateMutability":"view", + "type":"function" + }, + { + "inputs":[ + + ], + "name":"INIT_BURN_RATIO", + "outputs":[ + { + "internalType":"uint256", + "name":"", + "type":"uint256" + } + ], + "stateMutability":"view", + "type":"function" + }, + { + "inputs":[ + + ], + "name":"INIT_FINALITY_REWARD_RATIO", + "outputs":[ + { + "internalType":"uint256", + "name":"", + "type":"uint256" + } + ], + "stateMutability":"view", + "type":"function" + }, + { + "inputs":[ + + ], + "name":"INIT_MAINTAIN_SLASH_SCALE", + "outputs":[ + { + "internalType":"uint256", + "name":"", + "type":"uint256" + } + ], + "stateMutability":"view", + "type":"function" + }, + { + "inputs":[ + + ], + "name":"INIT_MAX_NUM_OF_MAINTAINING", + "outputs":[ + { + "internalType":"uint256", + "name":"", + "type":"uint256" + } + ], + "stateMutability":"view", + "type":"function" + }, + { + "inputs":[ + + ], + "name":"INIT_NUM_OF_CABINETS", + "outputs":[ + { + "internalType":"uint256", + "name":"", + "type":"uint256" + } + ], + "stateMutability":"view", + "type":"function" + }, + { + "inputs":[ + + ], + "name":"INIT_VALIDATORSET_BYTES", + "outputs":[ + { + "internalType":"bytes", + "name":"", + "type":"bytes" + } + ], + "stateMutability":"view", + "type":"function" + }, + { + "inputs":[ + + ], + "name":"JAIL_MESSAGE_TYPE", + "outputs":[ + { + "internalType":"uint8", + "name":"", + "type":"uint8" + } + ], + "stateMutability":"view", + "type":"function" + }, + { + "inputs":[ + + ], + "name":"LIGHT_CLIENT_ADDR", + "outputs":[ + { + "internalType":"address", + "name":"", + "type":"address" + } + ], + "stateMutability":"view", + "type":"function" + }, + { + "inputs":[ + + ], + "name":"MAX_NUM_OF_VALIDATORS", + "outputs":[ + { + "internalType":"uint256", + "name":"", + "type":"uint256" + } + ], + "stateMutability":"view", + "type":"function" + }, + { + "inputs":[ + + ], + "name":"PRECISION", + "outputs":[ + { + "internalType":"uint256", + "name":"", + "type":"uint256" + } + ], + "stateMutability":"view", + "type":"function" + }, + { + "inputs":[ + + ], + "name":"RELAYERHUB_CONTRACT_ADDR", + "outputs":[ + { + "internalType":"address", + "name":"", + "type":"address" + } + ], + "stateMutability":"view", + "type":"function" + }, + { + "inputs":[ + + ], + "name":"SLASH_CHANNELID", + "outputs":[ + { + "internalType":"uint8", + "name":"", + "type":"uint8" + } + ], + "stateMutability":"view", + "type":"function" + }, + { + "inputs":[ + + ], + "name":"SLASH_CONTRACT_ADDR", + "outputs":[ + { + "internalType":"address", + "name":"", + "type":"address" + } + ], + "stateMutability":"view", + "type":"function" + }, + { + "inputs":[ + + ], + "name":"STAKING_CHANNELID", + "outputs":[ + { + "internalType":"uint8", + "name":"", + "type":"uint8" + } + ], + "stateMutability":"view", + "type":"function" + }, + { + "inputs":[ + + ], + "name":"STAKING_CONTRACT_ADDR", + "outputs":[ + { + "internalType":"address", + "name":"", + "type":"address" + } + ], + "stateMutability":"view", + "type":"function" + }, + { + "inputs":[ + + ], + "name":"SYSTEM_REWARD_ADDR", + "outputs":[ + { + "internalType":"address", + "name":"", + "type":"address" + } + ], + "stateMutability":"view", + "type":"function" + }, + { + "inputs":[ + + ], + "name":"TOKEN_HUB_ADDR", + "outputs":[ + { + "internalType":"address", + "name":"", + "type":"address" + } + ], + "stateMutability":"view", + "type":"function" + }, + { + "inputs":[ + + ], + "name":"TOKEN_MANAGER_ADDR", + "outputs":[ + { + "internalType":"address", + "name":"", + "type":"address" + } + ], + "stateMutability":"view", + "type":"function" + }, + { + "inputs":[ + + ], + "name":"TRANSFER_IN_CHANNELID", + "outputs":[ + { + "internalType":"uint8", + "name":"", + "type":"uint8" + } + ], + "stateMutability":"view", + "type":"function" + }, + { + "inputs":[ + + ], + "name":"TRANSFER_OUT_CHANNELID", + "outputs":[ + { + "internalType":"uint8", + "name":"", + "type":"uint8" + } + ], + "stateMutability":"view", + "type":"function" + }, + { + "inputs":[ + + ], + "name":"VALIDATORS_UPDATE_MESSAGE_TYPE", + "outputs":[ + { + "internalType":"uint8", + "name":"", + "type":"uint8" + } + ], + "stateMutability":"view", + "type":"function" + }, + { + "inputs":[ + + ], + "name":"VALIDATOR_CONTRACT_ADDR", + "outputs":[ + { + "internalType":"address", + "name":"", + "type":"address" + } + ], + "stateMutability":"view", + "type":"function" + }, + { + "inputs":[ + + ], + "name":"alreadyInit", + "outputs":[ + { + "internalType":"bool", + "name":"", + "type":"bool" + } + ], + "stateMutability":"view", + "type":"function" + }, + { + "inputs":[ + + ], + "name":"bscChainID", + "outputs":[ + { + "internalType":"uint16", + "name":"", + "type":"uint16" + } + ], + "stateMutability":"view", + "type":"function" + }, + { + "inputs":[ + + ], + "name":"burnRatio", + "outputs":[ + { + "internalType":"uint256", + "name":"", + "type":"uint256" + } + ], + "stateMutability":"view", + "type":"function" + }, + { + "inputs":[ + + ], + "name":"burnRatioInitialized", + "outputs":[ + { + "internalType":"bool", + "name":"", + "type":"bool" + } + ], + "stateMutability":"view", + "type":"function" + }, + { + "inputs":[ + { + "internalType":"uint256", + "name":"index", + "type":"uint256" + } + ], + "name":"canEnterMaintenance", + "outputs":[ + { + "internalType":"bool", + "name":"", + "type":"bool" + } + ], + "stateMutability":"view", + "type":"function" + }, + { + "inputs":[ + { + "internalType":"uint256", + "name":"", + "type":"uint256" + } + ], + "name":"currentValidatorSet", + "outputs":[ + { + "internalType":"address", + "name":"consensusAddress", + "type":"address" + }, + { + "internalType":"address payable", + "name":"feeAddress", + "type":"address" + }, + { + "internalType":"address", + "name":"BBCFeeAddress", + "type":"address" + }, + { + "internalType":"uint64", + "name":"votingPower", + "type":"uint64" + }, + { + "internalType":"bool", + "name":"jailed", + "type":"bool" + }, + { + "internalType":"uint256", + "name":"incoming", + "type":"uint256" + } + ], + "stateMutability":"view", + "type":"function" + }, + { + "inputs":[ + { + "internalType":"address", + "name":"", + "type":"address" + } + ], + "name":"currentValidatorSetMap", + "outputs":[ + { + "internalType":"uint256", + "name":"", + "type":"uint256" + } + ], + "stateMutability":"view", + "type":"function" + }, + { + "inputs":[ + { + "internalType":"address", + "name":"valAddr", + "type":"address" + } + ], + "name":"deposit", + "outputs":[ + + ], + "stateMutability":"payable", + "type":"function" + }, + { + "inputs":[ + { + "internalType":"address[]", + "name":"valAddrs", + "type":"address[]" + }, + { + "internalType":"uint256[]", + "name":"weights", + "type":"uint256[]" + } + ], + "name":"distributeFinalityReward", + "outputs":[ + + ], + "stateMutability":"nonpayable", + "type":"function" + }, + { + "inputs":[ + + ], + "name":"enterMaintenance", + "outputs":[ + + ], + "stateMutability":"nonpayable", + "type":"function" + }, + { + "inputs":[ + + ], + "name":"exitMaintenance", + "outputs":[ + + ], + "stateMutability":"nonpayable", + "type":"function" + }, + { + "inputs":[ + + ], + "name":"expireTimeSecondGap", + "outputs":[ + { + "internalType":"uint256", + "name":"", + "type":"uint256" + } + ], + "stateMutability":"view", + "type":"function" + }, + { + "inputs":[ + { + "internalType":"address", + "name":"validator", + "type":"address" + } + ], + "name":"felony", + "outputs":[ + + ], + "stateMutability":"nonpayable", + "type":"function" + }, + { + "inputs":[ + + ], + "name":"finalityRewardRatio", + "outputs":[ + { + "internalType":"uint256", + "name":"", + "type":"uint256" + } + ], + "stateMutability":"view", + "type":"function" + }, + { + "inputs":[ + { + "internalType":"address", + "name":"_validator", + "type":"address" + } + ], + "name":"getCurrentValidatorIndex", + "outputs":[ + { + "internalType":"uint256", + "name":"", + "type":"uint256" + } + ], + "stateMutability":"view", + "type":"function" + }, + { + "inputs":[ + { + "internalType":"address", + "name":"validator", + "type":"address" + } + ], + "name":"getIncoming", + "outputs":[ + { + "internalType":"uint256", + "name":"", + "type":"uint256" + } + ], + "stateMutability":"view", + "type":"function" + }, + { + "inputs":[ + + ], + "name":"getLivingValidators", + "outputs":[ + { + "internalType":"address[]", + "name":"", + "type":"address[]" + }, + { + "internalType":"bytes[]", + "name":"", + "type":"bytes[]" + } + ], + "stateMutability":"view", + "type":"function" + }, + { + "inputs":[ + + ], + "name":"getMiningValidators", + "outputs":[ + { + "internalType":"address[]", + "name":"", + "type":"address[]" + }, + { + "internalType":"bytes[]", + "name":"", + "type":"bytes[]" + } + ], + "stateMutability":"view", + "type":"function" + }, + { + "inputs":[ + + ], + "name":"getValidators", + "outputs":[ + { + "internalType":"address[]", + "name":"", + "type":"address[]" + } + ], + "stateMutability":"view", + "type":"function" + }, + { + "inputs":[ + + ], + "name":"getWorkingValidatorCount", + "outputs":[ + { + "internalType":"uint256", + "name":"workingValidatorCount", + "type":"uint256" + } + ], + "stateMutability":"view", + "type":"function" + }, + { + "inputs":[ + { + "internalType":"uint8", + "name":"channelId", + "type":"uint8" + }, + { + "internalType":"bytes", + "name":"msgBytes", + "type":"bytes" + } + ], + "name":"handleAckPackage", + "outputs":[ + + ], + "stateMutability":"nonpayable", + "type":"function" + }, + { + "inputs":[ + { + "internalType":"uint8", + "name":"channelId", + "type":"uint8" + }, + { + "internalType":"bytes", + "name":"msgBytes", + "type":"bytes" + } + ], + "name":"handleFailAckPackage", + "outputs":[ + + ], + "stateMutability":"nonpayable", + "type":"function" + }, + { + "inputs":[ + { + "internalType":"uint8", + "name":"", + "type":"uint8" + }, + { + "internalType":"bytes", + "name":"msgBytes", + "type":"bytes" + } + ], + "name":"handleSynPackage", + "outputs":[ + { + "internalType":"bytes", + "name":"responsePayload", + "type":"bytes" + } + ], + "stateMutability":"nonpayable", + "type":"function" + }, + { + "inputs":[ + + ], + "name":"init", + "outputs":[ + + ], + "stateMutability":"nonpayable", + "type":"function" + }, + { + "inputs":[ + { + "internalType":"address", + "name":"validator", + "type":"address" + } + ], + "name":"isCurrentValidator", + "outputs":[ + { + "internalType":"bool", + "name":"", + "type":"bool" + } + ], + "stateMutability":"view", + "type":"function" + }, + { + "inputs":[ + { + "internalType":"uint256", + "name":"index", + "type":"uint256" + } + ], + "name":"isWorkingValidator", + "outputs":[ + { + "internalType":"bool", + "name":"", + "type":"bool" + } + ], + "stateMutability":"view", + "type":"function" + }, + { + "inputs":[ + + ], + "name":"maintainSlashScale", + "outputs":[ + { + "internalType":"uint256", + "name":"", + "type":"uint256" + } + ], + "stateMutability":"view", + "type":"function" + }, + { + "inputs":[ + + ], + "name":"maxNumOfCandidates", + "outputs":[ + { + "internalType":"uint256", + "name":"", + "type":"uint256" + } + ], + "stateMutability":"view", + "type":"function" + }, + { + "inputs":[ + + ], + "name":"maxNumOfMaintaining", + "outputs":[ + { + "internalType":"uint256", + "name":"", + "type":"uint256" + } + ], + "stateMutability":"view", + "type":"function" + }, + { + "inputs":[ + + ], + "name":"maxNumOfWorkingCandidates", + "outputs":[ + { + "internalType":"uint256", + "name":"", + "type":"uint256" + } + ], + "stateMutability":"view", + "type":"function" + }, + { + "inputs":[ + { + "internalType":"address", + "name":"validator", + "type":"address" + } + ], + "name":"misdemeanor", + "outputs":[ + + ], + "stateMutability":"nonpayable", + "type":"function" + }, + { + "inputs":[ + + ], + "name":"numOfCabinets", + "outputs":[ + { + "internalType":"uint256", + "name":"", + "type":"uint256" + } + ], + "stateMutability":"view", + "type":"function" + }, + { + "inputs":[ + + ], + "name":"numOfJailed", + "outputs":[ + { + "internalType":"uint256", + "name":"", + "type":"uint256" + } + ], + "stateMutability":"view", + "type":"function" + }, + { + "inputs":[ + + ], + "name":"numOfMaintaining", + "outputs":[ + { + "internalType":"uint256", + "name":"", + "type":"uint256" + } + ], + "stateMutability":"view", + "type":"function" + }, + { + "inputs":[ + + ], + "name":"previousHeight", + "outputs":[ + { + "internalType":"uint256", + "name":"", + "type":"uint256" + } + ], + "stateMutability":"view", + "type":"function" + }, + { + "inputs":[ + + ], + "name":"totalInComing", + "outputs":[ + { + "internalType":"uint256", + "name":"", + "type":"uint256" + } + ], + "stateMutability":"view", + "type":"function" + }, + { + "inputs":[ + { + "internalType":"string", + "name":"key", + "type":"string" + }, + { + "internalType":"bytes", + "name":"value", + "type":"bytes" + } + ], + "name":"updateParam", + "outputs":[ + + ], + "stateMutability":"nonpayable", + "type":"function" + }, + { + "inputs":[ + { + "internalType":"uint256", + "name":"", + "type":"uint256" + } + ], + "name":"validatorExtraSet", + "outputs":[ + { + "internalType":"uint256", + "name":"enterMaintenanceHeight", + "type":"uint256" + }, + { + "internalType":"bool", + "name":"isMaintaining", + "type":"bool" + }, + { + "internalType":"bytes", + "name":"voteAddress", + "type":"bytes" + } + ], + "stateMutability":"view", + "type":"function" + }, + { + "stateMutability":"payable", + "type":"receive" + } +] ` const slashABI = ` diff --git a/consensus/parlia/lubanFork.go b/consensus/parlia/lubanFork.go new file mode 100644 index 00000000000..b27ce7817ee --- /dev/null +++ b/consensus/parlia/lubanFork.go @@ -0,0 +1,37 @@ +package parlia + +import ( + libcommon "github.com/ledgerwatch/erigon-lib/common" + "github.com/ledgerwatch/erigon/common/u256" + "github.com/ledgerwatch/erigon/core/state" + "github.com/ledgerwatch/erigon/core/systemcontracts" + "github.com/ledgerwatch/erigon/core/types" + "github.com/ledgerwatch/log/v3" +) + +type Bytes []byte + +func (p *Parlia) getCurrentValidatorsBeforeLuban(header *types.Header, ibs *state.IntraBlockState) ([]libcommon.Address, error) { + + // prepare different method + method := "getValidators" + if p.chainConfig.IsEuler(header.Number) { + method = "getMiningValidators" + } + + data, err := p.validatorSetABIBeforeLuban.Pack(method) + if err != nil { + log.Error("Unable to pack tx for getValidators", "error", err) + return nil, err + } + // do smart contract call + msgData := Bytes(data) + _, returnData, err := p.systemCall(header.Coinbase, systemcontracts.ValidatorContract, msgData[:], ibs, header, u256.Num0) + if err != nil { + return nil, err + } + + var valSet []libcommon.Address + err = p.validatorSetABIBeforeLuban.UnpackIntoInterface(&valSet, method, returnData) + return valSet, err +} diff --git a/consensus/parlia/parlia.go b/consensus/parlia/parlia.go index 370b7e780a6..7edf7be34d9 100644 --- a/consensus/parlia/parlia.go +++ b/consensus/parlia/parlia.go @@ -13,22 +13,26 @@ import ( "sync" "time" + lru "github.com/hashicorp/golang-lru/v2" "github.com/ledgerwatch/erigon-lib/chain" libcommon "github.com/ledgerwatch/erigon-lib/common" "github.com/ledgerwatch/erigon-lib/common/length" + "github.com/ledgerwatch/erigon/common" + "github.com/ledgerwatch/erigon/common/math" + "github.com/prysmaticlabs/prysm/v4/crypto/bls" + "github.com/willf/bitset" "github.com/ledgerwatch/erigon/core/rawdb" + "github.com/ledgerwatch/erigon/core/types" "github.com/ledgerwatch/erigon/crypto/cryptopool" - lru "github.com/hashicorp/golang-lru" "github.com/holiman/uint256" + "github.com/ledgerwatch/erigon-lib/common/hexutility" "github.com/ledgerwatch/erigon-lib/kv" "github.com/ledgerwatch/log/v3" "golang.org/x/exp/slices" "github.com/ledgerwatch/erigon/accounts/abi" - "github.com/ledgerwatch/erigon/common/hexutil" - "github.com/ledgerwatch/erigon/common/math" "github.com/ledgerwatch/erigon/common/u256" "github.com/ledgerwatch/erigon/consensus" "github.com/ledgerwatch/erigon/consensus/misc" @@ -36,7 +40,6 @@ import ( "github.com/ledgerwatch/erigon/core/forkid" "github.com/ledgerwatch/erigon/core/state" "github.com/ledgerwatch/erigon/core/systemcontracts" - "github.com/ledgerwatch/erigon/core/types" "github.com/ledgerwatch/erigon/core/vm" "github.com/ledgerwatch/erigon/crypto" "github.com/ledgerwatch/erigon/params" @@ -56,12 +59,17 @@ const ( extraSeal = 65 // Fixed number of extra-data suffix bytes reserved for signer seal nextForkHashSize = 4 // Fixed number of extra-data suffix bytes reserved for nextForkHash. - validatorBytesLength = length.Addr - wiggleTime = uint64(1) // second, Random delay (per signer) to allow concurrent signers - initialBackOffTime = uint64(1) // second - processBackOffTime = uint64(1) // second + validatorBytesLengthBeforeLuban = length.Addr + validatorBytesLength = length.Addr + 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 + processBackOffTime = uint64(1) // second systemRewardPercent = 4 // it means 1/2^4 = 1/16 percentage of gas fee incoming will be distributed to system + + collectAdditionalVotesRewardRatio = float64(1) // ratio of additional reward for collecting more votes than needed ) var ( @@ -150,11 +158,11 @@ var ( type SignFn func(validator libcommon.Address, payload []byte, chainId *big.Int) ([]byte, error) // ecrecover extracts the Ethereum account address from a signed header. -func ecrecover(header *types.Header, sigCache *lru.ARCCache, chainId *big.Int) (libcommon.Address, error) { +func ecrecover(header *types.Header, sigCache *lru.ARCCache[libcommon.Hash, libcommon.Address], chainId *big.Int) (libcommon.Address, error) { // If the signature's already cached, return that hash := header.Hash() if address, known := sigCache.Get(hash); known { - return address.(libcommon.Address), nil + return address, nil } // Retrieve the signature from the header extra-data if len(header.Extra) < extraSeal { @@ -228,8 +236,8 @@ type Parlia struct { db kv.RwDB // Database to store and retrieve snapshot checkpoints chainDb kv.RwDB - recentSnaps *lru.ARCCache // Snapshots for recent block to speed up - signatures *lru.ARCCache // Signatures of recent blocks to speed up mining + recentSnaps *lru.ARCCache[libcommon.Hash, *Snapshot] // Snapshots for recent block to speed up + signatures *lru.ARCCache[libcommon.Hash, libcommon.Address] // Signatures of recent blocks to speed up mining signer *types.Signer @@ -240,13 +248,16 @@ type Parlia struct { snapLock sync.RWMutex // Protects snapshots creation - validatorSetABI abi.ABI - slashABI abi.ABI + validatorSetABIBeforeLuban abi.ABI + validatorSetABI abi.ABI + slashABI abi.ABI // The fields below are for testing only fakeDiff bool // Skip difficulty verifications heightForks, timeForks []uint64 // Forks extracted from the chainConfig snapshots *snapshotsync.RoSnapshots + newValidators []libcommon.Address + voteAddressMapmap map[libcommon.Address]*types.BLSPublicKey } // New creates a Parlia consensus engine. @@ -265,11 +276,15 @@ func New( } // Allocate the snapshot caches and create the engine - recentSnaps, err := lru.NewARC(inMemorySnapshots) + recentSnaps, err := lru.NewARC[libcommon.Hash, *Snapshot](inMemorySnapshots) if err != nil { panic(err) } - signatures, err := lru.NewARC(inMemorySignatures) + signatures, err := lru.NewARC[libcommon.Hash, libcommon.Address](inMemorySignatures) + if err != nil { + panic(err) + } + vABIBeforeLuban, err := abi.JSON(strings.NewReader(validatorSetABIBeforeLuban)) if err != nil { panic(err) } @@ -282,16 +297,17 @@ func New( panic(err) } c := &Parlia{ - chainConfig: chainConfig, - config: parliaConfig, - db: db, - chainDb: chainDb, - recentSnaps: recentSnaps, - signatures: signatures, - validatorSetABI: vABI, - slashABI: sABI, - signer: types.LatestSigner(chainConfig), - snapshots: snapshots, + chainConfig: chainConfig, + config: parliaConfig, + db: db, + chainDb: chainDb, + recentSnaps: recentSnaps, + signatures: signatures, + validatorSetABIBeforeLuban: vABIBeforeLuban, + validatorSetABI: vABI, + slashABI: sABI, + signer: types.LatestSigner(chainConfig), + snapshots: snapshots, } c.heightForks, c.timeForks = forkid.GatherForks(chainConfig) @@ -332,6 +348,160 @@ func (p *Parlia) VerifyHeaders(chain consensus.ChainHeaderReader, headers []*typ return nil } +// getValidatorBytesFromHeader returns the validators bytes extracted from the header's extra field if exists. +// The validators bytes would be contained only in the epoch block's header, and its each validator bytes length is fixed. +// 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---| +func getValidatorBytesFromHeader(header *types.Header, chainConfig *chain.Config, parliaConfig *chain.ParliaConfig) []byte { + if len(header.Extra) <= extraVanity+extraSeal { + return nil + } + + if !chainConfig.IsLuban(header.Number.Uint64()) { + if header.Number.Uint64()%parliaConfig.Epoch == 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 { + return nil + } + num := int(header.Extra[extraVanity]) + if num == 0 || len(header.Extra) <= extraVanity+extraSeal+num*validatorBytesLength { + return nil + } + start := extraVanity + validatorNumberSize + end := start + num*validatorBytesLength + return header.Extra[start:end] +} + +// getVoteAttestationFromHeader returns the vote attestation extracted from the header's extra field if exists. +func getVoteAttestationFromHeader(header *types.Header, chainConfig *chain.Config, parliaConfig *chain.ParliaConfig) (*types.VoteAttestation, error) { + if len(header.Extra) <= extraVanity+extraSeal { + return nil, nil + } + + if !chainConfig.IsLuban(header.Number.Uint64()) { + return nil, nil + } + + var attestationBytes []byte + if header.Number.Uint64()%parliaConfig.Epoch != 0 { + attestationBytes = header.Extra[extraVanity : len(header.Extra)-extraSeal] + } else { + num := int(header.Extra[extraVanity]) + if len(header.Extra) <= extraVanity+extraSeal+validatorNumberSize+num*validatorBytesLength { + return nil, nil + } + start := extraVanity + validatorNumberSize + num*validatorBytesLength + end := len(header.Extra) - extraSeal + attestationBytes = header.Extra[start:end] + } + + var attestation types.VoteAttestation + if err := rlp.Decode(bytes.NewReader(attestationBytes), &attestation); err != nil { + return nil, fmt.Errorf("block %d has vote attestation info, decode err: %s", header.Number.Uint64(), err) + } + return &attestation, nil +} + +// 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) + if err != nil { + return err + } + if attestation == nil { + return nil + } + if attestation.Data == nil { + return fmt.Errorf("invalid attestation, vote data is nil") + } + if len(attestation.Extra) > types.MaxAttestationExtraLength { + return fmt.Errorf("invalid attestation, too large extra length: %d", len(attestation.Extra)) + } + + // Get parent block + number := header.Number.Uint64() + var parent *types.Header + if len(parents) > 0 { + parent = parents[len(parents)-1] + } else { + parent = chain.GetHeader(header.ParentHash, number-1) + } + if parent == nil || parent.Hash() != header.ParentHash { + return consensus.ErrUnknownAncestor + } + + // The target block should be direct parent. + targetNumber := attestation.Data.TargetNumber + targetHash := attestation.Data.TargetHash + if targetNumber != parent.Number.Uint64() || targetHash != parent.Hash() { + return fmt.Errorf("invalid attestation, target mismatch, expected block: %d, hash: %s; real block: %d, hash: %s", + parent.Number.Uint64(), parent.Hash(), targetNumber, targetHash) + } + + // The source block should be the highest justified block. + sourceNumber := attestation.Data.SourceNumber + sourceHash := attestation.Data.SourceHash + justifiedBlockNumber, justifiedBlockHash, err := p.GetJustifiedNumberAndHash(chain, parent) + if err != nil { + return fmt.Errorf("unexpected error when getting the highest justified number and hash") + } + if sourceNumber != justifiedBlockNumber || sourceHash != justifiedBlockHash { + return fmt.Errorf("invalid attestation, source mismatch, expected block: %d, hash: %s; real block: %d, hash: %s", + justifiedBlockNumber, justifiedBlockHash, sourceNumber, sourceHash) + } + + // The snapshot should be the targetNumber-1 block's snapshot. + if len(parents) > 1 { + parents = parents[:len(parents)-1] + } else { + parents = nil + } + snap, err := p.snapshot(chain, parent.Number.Uint64()-1, parent.ParentHash, parents, true) + if err != nil { + return err + } + + // Filter out valid validator from attestation. + validators := snap.validators() + validatorsBitSet := bitset.From([]uint64{uint64(attestation.VoteAddressSet)}) + if validatorsBitSet.Count() > uint(len(validators)) { + return fmt.Errorf("invalid attestation, vote number larger than validators number") + } + votedAddrs := make([]bls.PublicKey, 0, validatorsBitSet.Count()) + for index, val := range validators { + if !validatorsBitSet.Test(uint(index)) { + continue + } + + voteAddr, err := bls.PublicKeyFromBytes(snap.Validators[val].VoteAddress[:]) + if err != nil { + return fmt.Errorf("BLS public key converts failed: %v", err) + } + votedAddrs = append(votedAddrs, voteAddr) + } + + // The valid voted validators should be no less than 2/3 validators. + if len(votedAddrs) < math.CeilDiv(len(snap.Validators)*2, 3) { + return fmt.Errorf("invalid attestation, not enough validators voted") + } + + // Verify the aggregated signature. + aggSig, err := bls.SignatureFromBytes(attestation.AggSignature[:]) + if err != nil { + return fmt.Errorf("BLS signature converts failed: %v", err) + } + if !aggSig.FastAggregateVerify(votedAddrs, attestation.Data.Hash()) { + return fmt.Errorf("invalid attestation, signature verify failed") + } + + return nil +} + // verifyHeader checks whether a header conforms to the consensus rules.The // caller may optionally pass in a batch of parents (ascending order) to avoid // looking those up from the database. This is useful for concurrently verifying @@ -340,7 +510,6 @@ func (p *Parlia) verifyHeader(chain consensus.ChainHeaderReader, header *types.H if header.Number == nil { return errUnknownBlock } - number := header.Number.Uint64() // Don't waste time checking blocks from the future if header.Time > uint64(time.Now().Unix()) { @@ -353,16 +522,18 @@ func (p *Parlia) verifyHeader(chain consensus.ChainHeaderReader, header *types.H if len(header.Extra) < extraVanity+extraSeal { return errMissingSignature } + // check extra data + number := header.Number.Uint64() isEpoch := number%p.config.Epoch == 0 // Ensure that the extra-data contains a signer list on checkpoint, but none otherwise - signersBytes := len(header.Extra) - extraVanity - extraSeal - if !isEpoch && signersBytes != 0 { + signersBytes := getValidatorBytesFromHeader(header, p.chainConfig, p.config) + if !isEpoch && len(signersBytes) != 0 { return errExtraValidators } - if isEpoch && signersBytes%validatorBytesLength != 0 { + if isEpoch && len(signersBytes) == 0 { return errInvalidSpanValidators } @@ -446,6 +617,15 @@ func (p *Parlia) verifyCascadingFields(chain consensus.ChainHeaderReader, header return fmt.Errorf("invalid gas limit: have %d, want %d += %d", header.GasLimit, parent.GasLimit, limit) } + // Verify vote attestation for fast finality. + if err := p.verifyVoteAttestation(chain, header, parents); err != nil { + if chain.Config().IsPlato(header.Number.Uint64()) { + return err + } + log.Warn("Verify vote attestation failed", "error", err, "hash", header.Hash(), "number", header.Number, + "parent", header.ParentHash, "coinbase", header.Coinbase, "extra", common.Bytes2Hex(header.Extra)) + } + // All basic checks passed, verify the seal and return return p.verifySeal(chain, header, parents) } @@ -503,7 +683,36 @@ func (p *Parlia) verifySeal(chain consensus.ChainHeaderReader, header *types.Hea return nil } +func (p *Parlia) prepareValidators(header *types.Header, chain consensus.ChainHeaderReader, ibs *state.IntraBlockState) error { + if header.Number.Uint64()%p.config.Epoch != 0 { + return nil + } + parentHeader := chain.GetHeader(header.ParentHash, header.Number.Uint64()) + + newValidators, voteAddressMap, err := p.getCurrentValidators(parentHeader, ibs) + if err != nil { + return err + } + // sort validator by address + sort.Sort(validatorsAscending(newValidators)) + if !p.chainConfig.IsLuban(header.Number.Uint64()) { + for _, validator := range newValidators { + header.Extra = append(header.Extra, validator.Bytes()...) + } + } else { + header.Extra = append(header.Extra, byte(len(newValidators))) + for _, validator := range newValidators { + header.Extra = append(header.Extra, validator.Bytes()...) + header.Extra = append(header.Extra, voteAddressMap[validator].Bytes()...) + } + } + return nil +} + // snapshot retrieves the authorization snapshot at a given point in time. +// !!! be careful +// the block with `number` and `hash` is just the last element of `parents`, +// unlike other interfaces such as verifyCascadingFields, `parents` are real parents func (p *Parlia) snapshot(chain consensus.ChainHeaderReader, number uint64, hash libcommon.Hash, parents []*types.Header, verify bool) (*Snapshot, error) { // Search for a snapshot in memory or on disk for checkpoints var ( @@ -513,7 +722,7 @@ func (p *Parlia) snapshot(chain consensus.ChainHeaderReader, number uint64, hash ) if s, ok := p.recentSnaps.Get(hash); ok { - snap = s.(*Snapshot) + snap = s } else { p.snapLock.Lock() defer p.snapLock.Unlock() @@ -523,7 +732,7 @@ func (p *Parlia) snapshot(chain consensus.ChainHeaderReader, number uint64, hash for snap == nil { // If an in-memory snapshot was found, use that if s, ok := p.recentSnaps.Get(hash); ok { - snap = s.(*Snapshot) + snap = s break } @@ -537,18 +746,17 @@ func (p *Parlia) snapshot(chain consensus.ChainHeaderReader, number uint64, hash } } } - if number == 0 { + if number == 0 || (number%p.config.Epoch == 0 && (len(headers) > params.FullImmutabilityThreshold)) { // Headers included into the snapshots have to be trusted as checkpoints checkpoint := chain.GetHeader(hash, number) if checkpoint != nil { - validatorBytes := checkpoint.Extra[extraVanity : len(checkpoint.Extra)-extraSeal] // get validators from headers - validators, err := ParseValidators(validatorBytes) + validators, voteAddrs, err := parseValidators(checkpoint, p.chainConfig, p.config) if err != nil { return nil, err } // new snapshot - snap = newSnapshot(p.config, p.signatures, number, hash, validators) + snap = newSnapshot(p.config, p.signatures, number, hash, validators, voteAddrs) if err := snap.store(p.db); err != nil { return nil, err } @@ -588,7 +796,16 @@ func (p *Parlia) snapshot(chain consensus.ChainHeaderReader, number uint64, hash for i := 0; i < len(headers)/2; i++ { headers[i], headers[len(headers)-1-i] = headers[len(headers)-1-i], headers[i] } - snap, err := snap.apply(headers, chain, parents, p.chainConfig.ChainID, doLog) + + verifiedAttestations := make(map[libcommon.Hash]struct{}, len(headers)) + for index, header := range headers { + // vote attestation should be checked here to decide whether to update attestation of snapshot between [Luban,Plato) + // because err of verifyVoteAttestation is ignored when importing blocks and headers before Plato. + if p.chainConfig.IsLuban(header.Number.Uint64()) && !p.chainConfig.IsPlato(header.Number.Uint64()) && p.verifyVoteAttestation(chain, header, headers[:index]) == nil { + verifiedAttestations[header.Hash()] = struct{}{} + } + } + snap, err := snap.apply(headers, chain, parents, p.chainConfig, verifiedAttestations, doLog) if err != nil { return nil, err } @@ -647,16 +864,8 @@ func (p *Parlia) Prepare(chain consensus.ChainHeaderReader, header *types.Header nextForkHash := forkid.NextForkHashFromForks(p.heightForks, p.timeForks, p.genesisHash, number, header.Time) header.Extra = append(header.Extra, nextForkHash[:]...) - if number%p.config.Epoch == 0 { - newValidators, err := p.getCurrentValidators(parent, ibs) - if err != nil { - return err - } - // sort validator by address - sort.Sort(validatorsAscending(newValidators)) - for _, validator := range newValidators { - header.Extra = append(header.Extra, validator.Bytes()...) - } + if err := p.prepareValidators(header, chain, ibs); err != nil { + return err } // add extra seal space @@ -668,8 +877,51 @@ func (p *Parlia) Prepare(chain consensus.ChainHeaderReader, header *types.Header return nil } +func (p *Parlia) verifyValidators(header, parentHeader *types.Header, state *state.IntraBlockState) error { + if (header.Number.Uint64()+1)%p.config.Epoch == 0 { + newValidators, voteAddressMap, err := p.getCurrentValidators(header, state) + if err != nil { + return err + } + p.newValidators = newValidators + p.voteAddressMapmap = voteAddressMap + return nil + } + + if header.Number.Uint64()%p.config.Epoch != 0 { + return nil + } + + + newValidators, voteAddressMap := p.newValidators, p.voteAddressMapmap + // sort validator by address + sort.Sort(validatorsAscending(newValidators)) + var validatorsBytes []byte + validatorsNumber := len(newValidators) + + if !p.chainConfig.IsLuban(header.Number.Uint64()) { + validatorsBytes = make([]byte, validatorsNumber*validatorBytesLengthBeforeLuban) + for i, validator := range newValidators { + copy(validatorsBytes[i*validatorBytesLengthBeforeLuban:], validator.Bytes()) + } + } else { + if uint8(validatorsNumber) != header.Extra[extraVanity] { + return errMismatchingEpochValidators + } + validatorsBytes = make([]byte, validatorsNumber*validatorBytesLength) + for i, validator := range newValidators { + copy(validatorsBytes[i*validatorBytesLength:], validator.Bytes()) + copy(validatorsBytes[i*validatorBytesLength+length.Addr:], voteAddressMap[validator].Bytes()) + } + } + if !bytes.Equal(getValidatorBytesFromHeader(header, p.chainConfig, p.config), validatorsBytes) { + return errMismatchingEpochValidators + } + return nil +} + // Initialize runs any pre-transaction state modifications (e.g. epoch start) -func (p *Parlia) Initialize(config *chain.Config, chain consensus.ChainHeaderReader, e consensus.EpochReader, header *types.Header, +func (p *Parlia) Initialize(config *chain.Config, chain consensus.ChainHeaderReader, header *types.Header, state *state.IntraBlockState, txs []types.Transaction, uncles []*types.Header, syscall consensus.SystemCall) { } @@ -698,7 +950,7 @@ func (p *Parlia) splitTxs(txs types.Transactions, header *types.Header) (userTxs // consensus rules that happen at finalization (e.g. block rewards). func (p *Parlia) Finalize(_ *chain.Config, header *types.Header, state *state.IntraBlockState, txs types.Transactions, _ []*types.Header, receipts types.Receipts, withdrawals []*types.Withdrawal, - e consensus.EpochReader, chain consensus.ChainHeaderReader, syscall consensus.SystemCall, + chain consensus.ChainHeaderReader, syscall consensus.SystemCall, ) (types.Transactions, types.Receipts, error) { return p.finalize(header, state, txs, receipts, chain, false) } @@ -726,23 +978,9 @@ func (p *Parlia) finalize(header *types.Header, state *state.IntraBlockState, tx */ // 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 number%p.config.Epoch == 0 { - parentHeader := chain.GetHeader(header.ParentHash, number-1) - newValidators, err := p.getCurrentValidators(parentHeader, state) - if err != nil { - return nil, nil, err - } - // sort validator by address - sort.Sort(validatorsAscending(newValidators)) - validatorsBytes := make([]byte, len(newValidators)*validatorBytesLength) - for i, validator := range newValidators { - copy(validatorsBytes[i*validatorBytesLength:], validator.Bytes()) - } - - extraSuffix := len(header.Extra) - extraSeal - if !bytes.Equal(header.Extra[extraVanity:extraSuffix], validatorsBytes) { - return nil, nil, errMismatchingEpochValidators - } + parentHeader := chain.GetHeader(header.ParentHash, number-1) + if err := p.verifyValidators(header, parentHeader, state); err != nil { + return nil, nil, err } // No block rewards in PoA, so the state remains as is and uncles are dropped if number == 1 { @@ -779,6 +1017,12 @@ func (p *Parlia) finalize(header *types.Header, state *state.IntraBlockState, tx //log.Error("distributeIncoming", "block hash", header.Hash(), "error", err, "systemTxs", len(systemTxs)) return nil, nil, err } + + if p.chainConfig.IsPlato(header.Number.Uint64()) { + if _, _, _, err := p.distributeFinalityReward(chain, state, header, txs, systemTxs, &header.GasUsed, false); err != nil { + return nil, nil, err + } + } //log.Debug("distribute successful", "txns", txs.Len(), "receipts", len(receipts), "gasUsed", header.GasUsed) if len(systemTxs) > 0 { return nil, nil, fmt.Errorf("the length of systemTxs is still %d", len(systemTxs)) @@ -788,6 +1032,79 @@ func (p *Parlia) finalize(header *types.Header, state *state.IntraBlockState, tx return txs, receipts, nil } +func (p *Parlia) distributeFinalityReward(chain consensus.ChainHeaderReader, state *state.IntraBlockState, header *types.Header, txs types.Transactions, systemTxs types.Transactions, + usedGas *uint64, mining bool) (types.Transactions, types.Transaction, *types.Receipt, error) { + currentHeight := header.Number.Uint64() + epoch := p.config.Epoch + chainConfig := chain.Config() + if currentHeight%epoch != 0 { + return nil, nil, nil, nil + } + + head := header + accumulatedWeights := make(map[libcommon.Address]uint64) + for height := currentHeight - 1; height+epoch >= currentHeight && height >= 1; height-- { + head = chain.GetHeaderByHash(head.ParentHash) + if head == nil { + return nil, nil, nil, fmt.Errorf("header is nil at height %d", height) + } + voteAttestation, err := getVoteAttestationFromHeader(head, chainConfig, p.config) + if err != nil { + return nil, nil, nil, err + } + if voteAttestation == nil { + continue + } + justifiedBlock := chain.GetHeaderByHash(voteAttestation.Data.TargetHash) + if justifiedBlock == nil { + log.Warn("justifiedBlock is nil at height %d", voteAttestation.Data.TargetNumber) + continue + } + + snap, err := p.snapshot(chain, justifiedBlock.Number.Uint64()-1, justifiedBlock.ParentHash, nil, true) + if err != nil { + return nil, nil, nil, err + } + validators := snap.validators() + validatorsBitSet := bitset.From([]uint64{uint64(voteAttestation.VoteAddressSet)}) + if validatorsBitSet.Count() > uint(len(validators)) { + log.Error("invalid attestation, vote number larger than validators number") + continue + } + validVoteCount := 0 + for index, val := range validators { + if validatorsBitSet.Test(uint(index)) { + accumulatedWeights[val] += 1 + validVoteCount += 1 + } + } + quorum := math.CeilDiv(len(snap.Validators)*2, 3) + if validVoteCount > quorum { + accumulatedWeights[head.Coinbase] += uint64(float64(validVoteCount-quorum) * collectAdditionalVotesRewardRatio) + } + } + + validators := make([]libcommon.Address, 0, len(accumulatedWeights)) + weights := make([]*big.Int, 0, len(accumulatedWeights)) + for val := range accumulatedWeights { + validators = append(validators, val) + } + sort.Sort(validatorsAscending(validators)) + for _, val := range validators { + weights = append(weights, big.NewInt(int64(accumulatedWeights[val]))) + } + + // generate system transaction + method := "distributeFinalityReward" + data, err := p.validatorSetABI.Pack(method, validators, weights) + if err != nil { + log.Error("Unable to pack tx for distributeFinalityReward", "error", err) + return nil, nil, nil, err + } + return p.applyTransaction(header.Coinbase, systemcontracts.ValidatorContract, u256.Num0, data, state, header, + len(txs), systemTxs, usedGas, mining) +} + // FinalizeAndAssemble runs any post-transaction state modifications (e.g. block // rewards) and assembles the final block. // @@ -795,7 +1112,7 @@ func (p *Parlia) finalize(header *types.Header, state *state.IntraBlockState, tx // consensus rules that happen at finalization (e.g. block rewards). func (p *Parlia) FinalizeAndAssemble(_ *chain.Config, header *types.Header, state *state.IntraBlockState, txs types.Transactions, _ []*types.Header, receipts types.Receipts, withdrawals []*types.Withdrawal, - e consensus.EpochReader, chain consensus.ChainHeaderReader, syscall consensus.SystemCall, call consensus.Call, + chain consensus.ChainHeaderReader, syscall consensus.SystemCall, call consensus.Call, ) (*types.Block, types.Transactions, types.Receipts, error) { outTxs, outReceipts, err := p.finalize(header, state, txs, receipts, chain, true) if err != nil { @@ -1024,36 +1341,42 @@ func (p *Parlia) Close() error { // ========================== interaction with contract/account ========= // getCurrentValidators get current validators -func (p *Parlia) getCurrentValidators(header *types.Header, ibs *state.IntraBlockState) ([]libcommon.Address, error) { - // method - var method string - if p.chainConfig.IsEuler(header.Number) { - method = "getMiningValidators" - } else { - method = "getValidators" +func (p *Parlia) getCurrentValidators(header *types.Header, ibs *state.IntraBlockState) ([]libcommon.Address, map[libcommon.Address]*types.BLSPublicKey, error) { + // This is actually the parentNumber + if !p.chainConfig.IsLuban(header.Number.Uint64()) { + validators, err := p.getCurrentValidatorsBeforeLuban(header, ibs) + return validators, nil, err } + + // method + method := "getMiningValidators" + data, err := p.validatorSetABI.Pack(method) if err != nil { - log.Error("Unable to pack tx for getValidators", "err", err) - return nil, err + log.Error("Unable to pack tx for getMiningValidators", "err", err) + return nil, nil, err } // call - msgData := hexutil.Bytes(data) + msgData := hexutility.Bytes(data) _, returnData, err := p.systemCall(header.Coinbase, systemcontracts.ValidatorContract, msgData[:], ibs, header, u256.Num0) if err != nil { - return nil, err + return nil, nil, err } - var ret0 = new([]libcommon.Address) - out := ret0 - if err := p.validatorSetABI.UnpackIntoInterface(out, method, returnData); err != nil { - return nil, err + var valSet []libcommon.Address + var voteAddrSet []types.BLSPublicKey + + if err := p.validatorSetABI.UnpackIntoInterface(&[]interface{}{&valSet, &voteAddrSet}, method, returnData); err != nil { + return nil, nil, err + } + + voteAddrmap := make(map[libcommon.Address]*types.BLSPublicKey, len(valSet)) + for i := 0; i < len(valSet); i++ { + voteAddrmap[valSet[i]] = &(voteAddrSet)[i] } - valz := make([]libcommon.Address, len(*ret0)) - copy(valz, *ret0) //for i, a := range *ret0 { // valz[i] = a //} - return valz, nil + return valSet, voteAddrmap, nil } // slash spoiled validators @@ -1263,6 +1586,7 @@ func (p *Parlia) systemCall(from, contract libcommon.Address, data []byte, ibs * nil, nil, data, nil, false, true, // isFree + nil, ) vmConfig := vm.Config{NoReceipts: true} // Create a new context to be used in the EVM environment @@ -1281,3 +1605,62 @@ func (p *Parlia) systemCall(from, contract libcommon.Address, data []byte, ibs * } return msg.Gas() - leftOverGas, ret, nil } + +// GetJustifiedNumberAndHash returns the highest justified block's number and hash on the branch including and before `header` +func (p *Parlia) GetJustifiedNumberAndHash(chain consensus.ChainHeaderReader, header *types.Header) (uint64, libcommon.Hash, error) { + if chain == nil || header == nil { + return 0, libcommon.Hash{}, fmt.Errorf("illegal chain or header") + } + snap, err := p.snapshot(chain, header.Number.Uint64(), header.Hash(), nil, true) + if err != nil { + log.Error("Unexpected error when getting snapshot", + "error", err, "blockNumber", header.Number.Uint64(), "blockHash", header.Hash()) + return 0, libcommon.Hash{}, err + } + + if snap.Attestation == nil { + if p.chainConfig.IsLuban(header.Number.Uint64()) { + log.Debug("once one attestation generated, attestation of snap would not be nil forever basically") + } + return 0, chain.GetHeaderByNumber(0).Hash(), nil + } + return snap.Attestation.TargetNumber, snap.Attestation.TargetHash, nil +} + +// GetFinalizedHeader returns highest finalized block header. +// It will find vote finalized block within NaturallyFinalizedDist blocks firstly, +// If the vote finalized block not found, return its naturally finalized block. +func (p *Parlia) GetFinalizedHeader(chain consensus.ChainHeaderReader, header *types.Header) *types.Header { + backward := uint64(types.NaturallyFinalizedDist) + if chain == nil || header == nil { + return nil + } + if !chain.Config().IsPlato(header.Number.Uint64()) { + return chain.GetHeaderByNumber(0) + } + if header.Number.Uint64() < backward { + backward = header.Number.Uint64() + } + + snap, err := p.snapshot(chain, header.Number.Uint64(), header.Hash(), nil, true) + if err != nil { + log.Error("Unexpected error when getting snapshot", + "error", err, "blockNumber", header.Number.Uint64(), "blockHash", header.Hash()) + return nil + } + + for snap.Attestation != nil && snap.Attestation.SourceNumber >= header.Number.Uint64()-backward { + if snap.Attestation.TargetNumber == snap.Attestation.SourceNumber+1 { + return chain.GetHeaderByHash(snap.Attestation.SourceHash) + } + + snap, err = p.snapshot(chain, snap.Attestation.SourceNumber, snap.Attestation.SourceHash, nil, true) + if err != nil { + log.Error("Unexpected error when getting snapshot", + "error", err, "blockNumber", snap.Attestation.SourceNumber, "blockHash", snap.Attestation.SourceHash) + return nil + } + } + + return FindAncientHeader(header, backward, chain, nil) +} diff --git a/consensus/parlia/ramanujanfork.go b/consensus/parlia/ramanujanfork.go index fbc77b9e468..305358e8fa2 100644 --- a/consensus/parlia/ramanujanfork.go +++ b/consensus/parlia/ramanujanfork.go @@ -30,15 +30,15 @@ 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 if p.chainConfig.IsRamanujan(header.Number.Uint64()) { - blockTime = blockTime + backOffTime(snap, p.val) + blockTime = blockTime + backOffTime(snap, header, p.val, p.chainConfig) } return blockTime } func (p *Parlia) blockTimeVerifyForRamanujanFork(snap *Snapshot, header, parent *types.Header) error { if p.chainConfig.IsRamanujan(header.Number.Uint64()) { - if header.Time < parent.Time+p.config.Period+backOffTime(snap, header.Coinbase) { - return fmt.Errorf("header %d, time %d, now %d, period: %d, backof: %d, %w", header.Number.Uint64(), header.Time, time.Now().Unix(), p.config.Period, backOffTime(snap, header.Coinbase), consensus.ErrFutureBlock) + if header.Time < parent.Time+p.config.Period+backOffTime(snap, header, header.Coinbase, p.chainConfig) { + return fmt.Errorf("header %d, time %d, now %d, period: %d, backof: %d, %w", header.Number.Uint64(), header.Time, time.Now().Unix(), p.config.Period, backOffTime(snap, header, header.Coinbase, p.chainConfig), consensus.ErrFutureBlock) } } return nil diff --git a/consensus/parlia/snapshot_test.go b/consensus/parlia/snaoshot_test.go similarity index 100% rename from consensus/parlia/snapshot_test.go rename to consensus/parlia/snaoshot_test.go diff --git a/consensus/parlia/snapshot.go b/consensus/parlia/snapshot.go index a73d8db5c31..f1ce5bc4764 100644 --- a/consensus/parlia/snapshot.go +++ b/consensus/parlia/snapshot.go @@ -23,13 +23,14 @@ import ( "encoding/json" "errors" "fmt" - "math/big" "sort" - lru "github.com/hashicorp/golang-lru" + lru "github.com/hashicorp/golang-lru/v2" "github.com/ledgerwatch/erigon-lib/chain" + "github.com/ledgerwatch/erigon-lib/common" libcommon "github.com/ledgerwatch/erigon-lib/common" "github.com/ledgerwatch/erigon-lib/common/hexutility" + "github.com/ledgerwatch/erigon-lib/common/length" "github.com/ledgerwatch/erigon-lib/kv" "github.com/ledgerwatch/log/v3" @@ -39,14 +40,20 @@ import ( // Snapshot is the state of the validatorSet at a given point. type Snapshot struct { - config *chain.ParliaConfig // Consensus engine parameters to fine tune behavior - sigCache *lru.ARCCache // Cache of recent block signatures to speed up ecrecover - - Number uint64 `json:"number"` // Block number where the snapshot was created - Hash libcommon.Hash `json:"hash"` // Block hash where the snapshot was created - Validators map[libcommon.Address]struct{} `json:"validators"` // Set of authorized validators at this moment - Recents map[uint64]libcommon.Address `json:"recents"` // Set of recent validators for spam protections - RecentForkHashes map[uint64]string `json:"recent_fork_hashes"` // Set of recent forkHash + config *chain.ParliaConfig // Consensus engine parameters to fine tune behavior + sigCache *lru.ARCCache[common.Hash, common.Address] // Cache of recent block signatures to speed up ecrecover + + Number uint64 `json:"number"` // Block number where the snapshot was created + Hash libcommon.Hash `json:"hash"` // Block hash where the snapshot was created + Validators map[libcommon.Address]*ValidatorInfo `json:"validators"` // Set of authorized validators at this moment + Recents map[uint64]libcommon.Address `json:"recents"` // Set of recent validators for spam protections + RecentForkHashes map[uint64]string `json:"recent_fork_hashes"` // Set of recent forkHash + Attestation *types.VoteData `json:"attestation:omitempty"` // Attestation for fast finality +} + +type ValidatorInfo struct { + Index int `json:"index:omitempty"` // The index should offset by 1 + VoteAddress types.BLSPublicKey `json:"vote_address,omitempty"` } // newSnapshot creates a new snapshot with the specified startup parameters. This @@ -54,42 +61,59 @@ type Snapshot struct { // the genesis block. func newSnapshot( config *chain.ParliaConfig, - sigCache *lru.ARCCache, + sigCache *lru.ARCCache[common.Hash, common.Address], number uint64, hash libcommon.Hash, validators []libcommon.Address, + voteAddrs []types.BLSPublicKey, ) *Snapshot { snap := &Snapshot{ config: config, sigCache: sigCache, Number: number, Hash: hash, - Recents: make(map[uint64]libcommon.Address), + Recents: make(map[uint64]common.Address), RecentForkHashes: make(map[uint64]string), - Validators: make(map[libcommon.Address]struct{}), + Validators: make(map[libcommon.Address]*ValidatorInfo), + } + + for idx, v := range validators { + // The luban fork from the genesis block + if len(voteAddrs) == len(validators) { + snap.Validators[v] = &ValidatorInfo{ + VoteAddress: voteAddrs[idx], + } + } else { + snap.Validators[v] = &ValidatorInfo{} + } } - for _, v := range validators { - snap.Validators[v] = struct{}{} + + // The luban fork from the genesis block + if len(voteAddrs) == len(validators) { + validators := snap.validators() + for idx, v := range validators { + snap.Validators[v].Index = idx + 1 // offset by 1 + } } return snap } // validatorsAscending implements the sort interface to allow sorting a list of addresses -type validatorsAscending []libcommon.Address +type validatorsAscending []common.Address func (s validatorsAscending) Len() int { return len(s) } func (s validatorsAscending) Less(i, j int) bool { return bytes.Compare(s[i][:], s[j][:]) < 0 } func (s validatorsAscending) Swap(i, j int) { s[i], s[j] = s[j], s[i] } // SnapshotFullKey = SnapshotBucket + num (uint64 big endian) + hash -func SnapshotFullKey(number uint64, hash libcommon.Hash) []byte { +func SnapshotFullKey(number uint64, hash common.Hash) []byte { return append(hexutility.EncodeTs(number), hash.Bytes()...) } var ErrNoSnapsnot = fmt.Errorf("no parlia snapshot") // loadSnapshot loads an existing snapshot from the database. -func loadSnapshot(config *chain.ParliaConfig, sigCache *lru.ARCCache, db kv.RwDB, num uint64, hash libcommon.Hash) (*Snapshot, error) { +func loadSnapshot(config *chain.ParliaConfig, sigCache *lru.ARCCache[common.Hash, common.Address], db kv.RwDB, num uint64, hash common.Hash) (*Snapshot, error) { tx, err := db.BeginRo(context.Background()) if err != nil { return nil, err @@ -130,13 +154,16 @@ func (s *Snapshot) copy() *Snapshot { sigCache: s.sigCache, Number: s.Number, Hash: s.Hash, - Validators: make(map[libcommon.Address]struct{}), + Validators: make(map[libcommon.Address]*ValidatorInfo), Recents: make(map[uint64]libcommon.Address), RecentForkHashes: make(map[uint64]string), } for v := range s.Validators { - cpy.Validators[v] = struct{}{} + cpy.Validators[v] = &ValidatorInfo{ + Index: s.Validators[v].Index, + VoteAddress: s.Validators[v].VoteAddress, + } } for block, v := range s.Recents { cpy.Recents[block] = v @@ -144,6 +171,14 @@ func (s *Snapshot) copy() *Snapshot { for block, id := range s.RecentForkHashes { cpy.RecentForkHashes[block] = id } + if s.Attestation != nil { + cpy.Attestation = &types.VoteData{ + SourceNumber: s.Attestation.SourceNumber, + SourceHash: s.Attestation.SourceHash, + TargetNumber: s.Attestation.TargetNumber, + TargetHash: s.Attestation.TargetHash, + } + } return cpy } @@ -158,7 +193,23 @@ func (s *Snapshot) isMajorityFork(forkHash string) bool { return ally > len(s.RecentForkHashes)/2 } -func (s *Snapshot) apply(headers []*types.Header, chain consensus.ChainHeaderReader, parents []*types.Header, chainId *big.Int, doLog bool) (*Snapshot, error) { +func (s *Snapshot) updateAttestation(header *types.Header, chainConfig *chain.Config, parliaConfig *chain.ParliaConfig) { + // The attestation should have been checked in verify header, update directly + attestation, _ := getVoteAttestationFromHeader(header, chainConfig, parliaConfig) + if attestation == nil { + return + } + + // Update attestation + s.Attestation = &types.VoteData{ + SourceNumber: attestation.Data.SourceNumber, + SourceHash: attestation.Data.SourceHash, + TargetNumber: attestation.Data.TargetNumber, + TargetHash: attestation.Data.TargetHash, + } +} + +func (s *Snapshot) apply(headers []*types.Header, chain consensus.ChainHeaderReader, parents []*types.Header, chainConfig *chain.Config, verifiedAttestations map[libcommon.Hash]struct{}, doLog bool) (*Snapshot, error) { // Allow passing in no headers for cleaner code if len(headers) == 0 { return s, nil @@ -194,7 +245,7 @@ func (s *Snapshot) apply(headers []*types.Header, chain consensus.ChainHeaderRea delete(snap.RecentForkHashes, number-limit) } // Resolve the authorization key and check against signers - validator, err := ecrecover(header, s.sigCache, chainId) + validator, err := ecrecover(header, s.sigCache, chainConfig.ChainID) if err != nil { return nil, err } @@ -218,15 +269,21 @@ func (s *Snapshot) apply(headers []*types.Header, chain consensus.ChainHeaderRea return nil, consensus.ErrUnknownAncestor } - validatorBytes := checkpointHeader.Extra[extraVanity : len(checkpointHeader.Extra)-extraSeal] // get validators from headers and use that for new validator set - newValArr, err := ParseValidators(validatorBytes) + newValArr, voteAddrs, err := parseValidators(checkpointHeader, chainConfig, s.config) if err != nil { return nil, err } - newVals := make(map[libcommon.Address]struct{}, len(newValArr)) - for _, val := range newValArr { - newVals[val] = struct{}{} + + newVals := make(map[libcommon.Address]*ValidatorInfo, len(newValArr)) + for idx, val := range newValArr { + if !chainConfig.IsLuban(header.Number.Uint64()) { + newVals[val] = &ValidatorInfo{} + } else { + newVals[val] = &ValidatorInfo{ + VoteAddress: voteAddrs[idx], + } + } } oldLimit := len(snap.Validators)/2 + 1 newLimit := len(newVals)/2 + 1 @@ -243,7 +300,19 @@ func (s *Snapshot) apply(headers []*types.Header, chain consensus.ChainHeaderRea } } snap.Validators = newVals + if chainConfig.IsLuban(header.Number.Uint64()) { + validators := snap.validators() + for idx, val := range validators { + snap.Validators[val].Index = idx + 1 // offset by 1 + } + } + } + + _, voteAssestationNoErr := verifiedAttestations[header.Hash()] + if chainConfig.IsPlato(header.Number.Uint64()) || (chainConfig.IsLuban(header.Number.Uint64()) && voteAssestationNoErr) { + snap.updateAttestation(header, chainConfig, s.config) } + snap.RecentForkHashes[number] = hex.EncodeToString(header.Extra[extraVanity-nextForkHashSize : extraVanity]) } snap.Number += uint64(len(headers)) @@ -252,8 +321,8 @@ func (s *Snapshot) apply(headers []*types.Header, chain consensus.ChainHeaderRea } // validators retrieves the list of validators in ascending order. -func (s *Snapshot) validators() []libcommon.Address { - validators := make([]libcommon.Address, 0, len(s.Validators)) +func (s *Snapshot) validators() []common.Address { + validators := make([]common.Address, 0, len(s.Validators)) for v := range s.Validators { validators = append(validators, v) } @@ -262,13 +331,13 @@ func (s *Snapshot) validators() []libcommon.Address { } // inturn returns if a validator at a given block height is in-turn or not. -func (s *Snapshot) inturn(validator libcommon.Address) bool { +func (s *Snapshot) inturn(validator common.Address) bool { validators := s.validators() offset := (s.Number + 1) % uint64(len(validators)) return validators[offset] == validator } -func (s *Snapshot) enoughDistance(validator libcommon.Address, header *types.Header) bool { +func (s *Snapshot) enoughDistance(validator common.Address, header *types.Header) bool { idx := s.indexOfVal(validator) if idx < 0 { return true @@ -289,6 +358,10 @@ func (s *Snapshot) enoughDistance(validator libcommon.Address, header *types.Hea } func (s *Snapshot) indexOfVal(validator libcommon.Address) int { + if validator, ok := s.Validators[validator]; ok && validator.Index > 0 { + return validator.Index - 1 // Index is offset by 1 + } + validators := s.validators() for idx, val := range validators { if val == validator { @@ -298,24 +371,35 @@ func (s *Snapshot) indexOfVal(validator libcommon.Address) int { return -1 } -func (s *Snapshot) supposeValidator() libcommon.Address { +func (s *Snapshot) supposeValidator() common.Address { validators := s.validators() index := (s.Number + 1) % uint64(len(validators)) return validators[index] } -func ParseValidators(validatorsBytes []byte) ([]libcommon.Address, error) { - if len(validatorsBytes)%validatorBytesLength != 0 { - return nil, errors.New("invalid validators bytes") +func parseValidators(header *types.Header, chainConfig *chain.Config, parliaConfig *chain.ParliaConfig) ([]libcommon.Address, []types.BLSPublicKey, error) { + validatorsBytes := getValidatorBytesFromHeader(header, chainConfig, parliaConfig) + if len(validatorsBytes) == 0 { + return nil, nil, errors.New("invalid validators bytes") } + + if !chainConfig.IsLuban(header.Number.Uint64()) { + n := len(validatorsBytes) / validatorBytesLengthBeforeLuban + result := make([]libcommon.Address, n) + for i := 0; i < n; i++ { + result[i] = libcommon.BytesToAddress(validatorsBytes[i*validatorBytesLengthBeforeLuban : (i+1)*validatorBytesLengthBeforeLuban]) + } + return result, nil, nil + } + n := len(validatorsBytes) / validatorBytesLength - result := make([]libcommon.Address, n) + cnsAddrs := make([]libcommon.Address, n) + voteAddrs := make([]types.BLSPublicKey, n) for i := 0; i < n; i++ { - address := make([]byte, validatorBytesLength) - copy(address, validatorsBytes[i*validatorBytesLength:(i+1)*validatorBytesLength]) - result[i] = libcommon.BytesToAddress(address) + cnsAddrs[i] = libcommon.BytesToAddress(validatorsBytes[i*validatorBytesLength : i*validatorBytesLength+length.Addr]) + copy(voteAddrs[i][:], validatorsBytes[i*validatorBytesLength+length.Addr:(i+1)*validatorBytesLength]) } - return result, nil + return cnsAddrs, voteAddrs, nil } func FindAncientHeader(header *types.Header, ite uint64, chain consensus.ChainHeaderReader, candidateParents []*types.Header) *types.Header { diff --git a/consensus/parlia/util.go b/consensus/parlia/util.go new file mode 100644 index 00000000000..650106cd926 --- /dev/null +++ b/consensus/parlia/util.go @@ -0,0 +1,83 @@ +package parlia + +import ( + "math/rand" + + "github.com/ledgerwatch/erigon-lib/chain" + libcommon "github.com/ledgerwatch/erigon-lib/common" + "github.com/ledgerwatch/erigon/core/types" + "github.com/ledgerwatch/log/v3" +) + +func backOffTime(snap *Snapshot, header *types.Header, val libcommon.Address, chainConfig *chain.Config) uint64 { + if snap.inturn(val) { + return 0 + } else { + delay := initialBackOffTime + validators := snap.validators() + if chainConfig.IsPlanck(header.Number.Uint64()) { + // reverse the key/value of snap.Recents to get recentsMap + recentsMap := make(map[libcommon.Address]uint64, len(snap.Recents)) + bound := uint64(0) + if n, limit := header.Number.Uint64(), uint64(len(validators)/2+1); n > limit { + bound = n - limit + } + for seen, recent := range snap.Recents { + if seen <= bound { + continue + } + recentsMap[recent] = seen + } + + // The backOffTime does not matter when a validator has signed recently. + if _, ok := recentsMap[val]; ok { + return 0 + } + + inTurnAddr := validators[(snap.Number+1)%uint64(len(validators))] + if _, ok := recentsMap[inTurnAddr]; ok { + log.Debug("in turn validator has recently signed, skip initialBackOffTime", + "inTurnAddr", inTurnAddr) + delay = 0 + } + + // Exclude the recently signed validators + temp := make([]libcommon.Address, 0, len(validators)) + for _, addr := range validators { + if _, ok := recentsMap[addr]; ok { + continue + } + temp = append(temp, addr) + } + validators = temp + } + + // get the index of current validator and its shuffled backoff time. + idx := -1 + for index, itemAddr := range validators { + if val == itemAddr { + idx = index + } + } + if idx < 0 { + log.Info("The validator is not authorized", "addr", val) + return 0 + } + + s := rand.NewSource(int64(snap.Number)) + r := rand.New(s) // nolint:gosec + n := len(validators) + backOffSteps := make([]uint64, 0, n) + + for i := uint64(0); i < uint64(n); i++ { + backOffSteps = append(backOffSteps, i) + } + + r.Shuffle(n, func(i, j int) { + backOffSteps[i], backOffSteps[j] = backOffSteps[j], backOffSteps[i] + }) + + delay += backOffSteps[idx] * wiggleTime + return delay + } +} diff --git a/consensus/parlia/utils.go b/consensus/parlia/utils.go deleted file mode 100644 index 6740131d071..00000000000 --- a/consensus/parlia/utils.go +++ /dev/null @@ -1,31 +0,0 @@ -package parlia - -import ( - "math/rand" - - libcommon "github.com/ledgerwatch/erigon-lib/common" -) - -func backOffTime(snap *Snapshot, val libcommon.Address) uint64 { - if snap.inturn(val) { - return 0 - } else { - idx := snap.indexOfVal(val) - if idx < 0 { - // The backOffTime does not matter when a validator is not authorized. - return 0 - } - s := rand.NewSource(int64(snap.Number)) - r := rand.New(s) // nolint: gosec - n := len(snap.Validators) - backOffSteps := make([]uint64, 0, n) - for idx := uint64(0); idx < uint64(n); idx++ { - backOffSteps = append(backOffSteps, idx) - } - r.Shuffle(n, func(i, j int) { - backOffSteps[i], backOffSteps[j] = backOffSteps[j], backOffSteps[i] - }) - delay := initialBackOffTime + backOffSteps[idx]*wiggleTime - return delay - } -} diff --git a/consensus/serenity/serenity.go b/consensus/serenity/serenity.go index 86756129da0..ab5b149aee8 100644 --- a/consensus/serenity/serenity.go +++ b/consensus/serenity/serenity.go @@ -125,10 +125,10 @@ func (s *Serenity) Prepare(chain consensus.ChainHeaderReader, header *types.Head func (s *Serenity) Finalize(config *chain.Config, header *types.Header, state *state.IntraBlockState, txs types.Transactions, uncles []*types.Header, r types.Receipts, withdrawals []*types.Withdrawal, - e consensus.EpochReader, chain consensus.ChainHeaderReader, syscall consensus.SystemCall, + chain consensus.ChainHeaderReader, syscall consensus.SystemCall, ) (types.Transactions, types.Receipts, error) { if !IsPoSHeader(header) { - return s.eth1Engine.Finalize(config, header, state, txs, uncles, r, withdrawals, e, chain, syscall) + return s.eth1Engine.Finalize(config, header, state, txs, uncles, r, withdrawals, chain, syscall) } if auraEngine, ok := s.eth1Engine.(*aura.AuRa); ok { if err := auraEngine.ApplyRewards(header, state, syscall); err != nil { @@ -143,17 +143,24 @@ func (s *Serenity) Finalize(config *chain.Config, header *types.Header, state *s state.AddBalance(w.Address, amountInWei) } } + if config.IsCancun(header.Time) { + parent := chain.GetHeaderByHash(header.ParentHash) + if parent == nil { + return nil, nil, fmt.Errorf("Could not find the parent of block %v to get excess data gas", header.Number.Uint64()) + } + header.SetExcessDataGas(misc.CalcExcessDataGas(parent.ExcessDataGas, misc.CountBlobs(txs))) + } return txs, r, nil } func (s *Serenity) FinalizeAndAssemble(config *chain.Config, header *types.Header, state *state.IntraBlockState, txs types.Transactions, uncles []*types.Header, receipts types.Receipts, withdrawals []*types.Withdrawal, - e consensus.EpochReader, chain consensus.ChainHeaderReader, syscall consensus.SystemCall, call consensus.Call, + chain consensus.ChainHeaderReader, syscall consensus.SystemCall, call consensus.Call, ) (*types.Block, types.Transactions, types.Receipts, error) { if !IsPoSHeader(header) { - return s.eth1Engine.FinalizeAndAssemble(config, header, state, txs, uncles, receipts, withdrawals, e, chain, syscall, call) + return s.eth1Engine.FinalizeAndAssemble(config, header, state, txs, uncles, receipts, withdrawals, chain, syscall, call) } - outTxs, outReceipts, err := s.Finalize(config, header, state, txs, uncles, receipts, withdrawals, e, chain, syscall) + outTxs, outReceipts, err := s.Finalize(config, header, state, txs, uncles, receipts, withdrawals, chain, syscall) if err != nil { return nil, nil, nil, err } @@ -225,6 +232,15 @@ func (s *Serenity) verifyHeader(chain consensus.ChainHeaderReader, header, paren if !shanghai && header.WithdrawalsHash != nil { return consensus.ErrUnexpectedWithdrawals } + + if !chain.Config().IsCancun(header.Time) { + if header.ExcessDataGas != nil { + return fmt.Errorf("invalid excessDataGas before fork: have %v, expected 'nil'", header.ExcessDataGas) + } + } else if err := misc.VerifyEip4844Header(chain.Config(), parent, header); err != nil { + // Verify the header's EIP-4844 attributes. + return err + } return nil } @@ -243,8 +259,8 @@ func (s *Serenity) IsServiceTransaction(sender libcommon.Address, syscall consen return s.eth1Engine.IsServiceTransaction(sender, syscall) } -func (s *Serenity) Initialize(config *chain.Config, chain consensus.ChainHeaderReader, e consensus.EpochReader, header *types.Header, state *state.IntraBlockState, txs []types.Transaction, uncles []*types.Header, syscall consensus.SystemCall) { - s.eth1Engine.Initialize(config, chain, e, header, state, txs, uncles, syscall) +func (s *Serenity) Initialize(config *chain.Config, chain consensus.ChainHeaderReader, header *types.Header, state *state.IntraBlockState, txs []types.Transaction, uncles []*types.Header, syscall consensus.SystemCall) { + s.eth1Engine.Initialize(config, chain, header, state, txs, uncles, syscall) } func (s *Serenity) APIs(chain consensus.ChainHeaderReader) []rpc.API { diff --git a/core/allocs/bsc.json b/core/allocs/bsc.json index 2ffe140b9e6..fdfe10775e2 100644 --- a/core/allocs/bsc.json +++ b/core/allocs/bsc.json @@ -1,51 +1,51 @@ { - "0xffffFFFfFFffffffffffffffFfFFFfffFFFfFFfE": { - "balance": "0x0" - }, - "0x0000000000000000000000000000000000001000": { - "balance": "0x0", - "code": "0x60806040526004361061027d5760003560e01c80639dc092621161014f578063c8509d81116100c1578063eb57e2021161007a578063eb57e20214610940578063eda5868c14610973578063f340fa0114610988578063f9a2bbc7146109ae578063fc3e5908146109c3578063fd6a6879146109d85761027d565b8063c8509d8114610609578063d86222d5146108d7578063daacdb66146108ec578063dc927faf14610901578063e086c7b114610916578063e1c7392a1461092b5761027d565b8063ab51bb9611610113578063ab51bb961461074a578063ac4317511461075f578063ad3c9da61461082a578063b7ab4db51461085d578063bf9f49951461041b578063c81b1662146108c25761027d565b80639dc09262146106cd578063a1a11bf5146106e2578063a5422d5c146106f7578063a78abc161461070c578063aaf5eb68146107355761027d565b80635667515a116101f35780637942fd05116101ac5780637942fd05146105df57806381650b62146105f4578063831d65d114610609578063853230aa1461068e57806386249882146106a357806396713da9146106b85761027d565b80635667515a146105005780635d77156c146105155780636969a25c1461052a5780636e47b482146105a057806370fd5bad146105b557806375d47a0a146105ca5761027d565b80633dffc387116102455780633dffc3871461041b57806343756e5c14610446578063493279b1146104775780634bf6c882146104a357806351e80672146104b8578063565c56b3146104cd5761027d565b80630bee7a67146102825780631182b875146102b05780631ff18069146103aa578063219f22d5146103d157806335409f7f146103e6575b600080fd5b34801561028e57600080fd5b506102976109ed565b6040805163ffffffff9092168252519081900360200190f35b3480156102bc57600080fd5b50610335600480360360408110156102d357600080fd5b60ff8235169190810190604081016020820135600160201b8111156102f757600080fd5b82018360208201111561030957600080fd5b803590602001918460018302840111600160201b8311171561032a57600080fd5b5090925090506109f2565b6040805160208082528351818301528351919283929083019185019080838360005b8381101561036f578181015183820152602001610357565b50505050905090810190601f16801561039c5780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b3480156103b657600080fd5b506103bf610bdf565b60408051918252519081900360200190f35b3480156103dd57600080fd5b50610297610be5565b3480156103f257600080fd5b506104196004803603602081101561040957600080fd5b50356001600160a01b0316610bea565b005b34801561042757600080fd5b50610430610efe565b6040805160ff9092168252519081900360200190f35b34801561045257600080fd5b5061045b610f03565b604080516001600160a01b039092168252519081900360200190f35b34801561048357600080fd5b5061048c610f09565b6040805161ffff9092168252519081900360200190f35b3480156104af57600080fd5b50610430610f0e565b3480156104c457600080fd5b5061045b610f13565b3480156104d957600080fd5b506103bf600480360360208110156104f057600080fd5b50356001600160a01b0316610f19565b34801561050c57600080fd5b50610430610f6b565b34801561052157600080fd5b50610297610f70565b34801561053657600080fd5b506105546004803603602081101561054d57600080fd5b5035610f75565b604080516001600160a01b039788168152958716602087015293909516848401526001600160401b0390911660608401521515608083015260a082019290925290519081900360c00190f35b3480156105ac57600080fd5b5061045b610fd9565b3480156105c157600080fd5b50610430610fdf565b3480156105d657600080fd5b5061045b610fe4565b3480156105eb57600080fd5b50610430610fea565b34801561060057600080fd5b50610297610fef565b34801561061557600080fd5b506104196004803603604081101561062c57600080fd5b60ff8235169190810190604081016020820135600160201b81111561065057600080fd5b82018360208201111561066257600080fd5b803590602001918460018302840111600160201b8311171561068357600080fd5b509092509050610ff4565b34801561069a57600080fd5b506103bf6110a7565b3480156106af57600080fd5b506103bf6110ad565b3480156106c457600080fd5b506104306110b3565b3480156106d957600080fd5b5061045b6110b8565b3480156106ee57600080fd5b5061045b6110be565b34801561070357600080fd5b506103356110c4565b34801561071857600080fd5b506107216110e3565b604080519115158252519081900360200190f35b34801561074157600080fd5b506103bf6110ec565b34801561075657600080fd5b50610297610f6b565b34801561076b57600080fd5b506104196004803603604081101561078257600080fd5b810190602081018135600160201b81111561079c57600080fd5b8201836020820111156107ae57600080fd5b803590602001918460018302840111600160201b831117156107cf57600080fd5b919390929091602081019035600160201b8111156107ec57600080fd5b8201836020820111156107fe57600080fd5b803590602001918460018302840111600160201b8311171561081f57600080fd5b5090925090506110f5565b34801561083657600080fd5b506103bf6004803603602081101561084d57600080fd5b50356001600160a01b031661139c565b34801561086957600080fd5b506108726113ae565b60408051602080825283518183015283519192839290830191858101910280838360005b838110156108ae578181015183820152602001610896565b505050509050019250505060405180910390f35b3480156108ce57600080fd5b5061045b6114d4565b3480156108e357600080fd5b506103bf6114da565b3480156108f857600080fd5b506103bf6114e6565b34801561090d57600080fd5b5061045b6114ec565b34801561092257600080fd5b506103bf6114f2565b34801561093757600080fd5b506104196114f7565b34801561094c57600080fd5b506104196004803603602081101561096357600080fd5b50356001600160a01b03166116fa565b34801561097f57600080fd5b506102976118c9565b6104196004803603602081101561099e57600080fd5b50356001600160a01b03166118ce565b3480156109ba57600080fd5b5061045b611b04565b3480156109cf57600080fd5b50610430611b0a565b3480156109e457600080fd5b5061045b611b0f565b606481565b60005460609060ff16610a48576040805162461bcd60e51b81526020600482015260196024820152781d1a194818dbdb9d1c9858dd081b9bdd081a5b9a5d081e595d603a1b604482015290519081900360640190fd5b3361200014610a885760405162461bcd60e51b815260040180806020018281038252602f815260200180614516602f913960400191505060405180910390fd5b610a90613d69565b6000610ad185858080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250611b1592505050565b9150915080610aed57610ae46064611c6e565b92505050610bd8565b815160009060ff16610b0d57610b068360200151611ccf565b9050610ba4565b825160ff1660011415610ba057826020015151600114610b7a577f70e72399380dcfb0338abc03dc8d47f9f470ada8e769c9a78d644ea97385ecb2604051808060200182810382526025815260200180613e6c6025913960400191505060405180910390a1506067610b9b565b610b068360200151600081518110610b8e57fe5b6020026020010151612ad5565b610ba4565b5060655b63ffffffff8116610bc95750506040805160008152602081019091529150610bd89050565b610bd281611c6e565b93505050505b9392505050565b60035481565b606881565b3361100114610c2a5760405162461bcd60e51b81526004018080602001828103825260298152602001806145726029913960400191505060405180910390fd5b6001600160a01b03811660009081526004602052604090205480610c4e5750610efb565b600181039050600060018281548110610c6357fe5b60009182526020909120600360049092020101546001549091506000190180610cb257600060018481548110610c9557fe5b906000526020600020906004020160030181905550505050610efb565b6040805183815290516001600160a01b038616917f3b6f9ef90462b512a1293ecec018670bf7b7f1876fb727590a8a6d7643130a70919081900360200190a26001600160a01b038416600090815260046020526040812055600154600019018314610e3457600180546000198101908110610d2957fe5b906000526020600020906004020160018481548110610d4457fe5b6000918252602082208354600492830290910180546001600160a01b03199081166001600160a01b0393841617825560018087015481840180548416918616919091179055600280880180549185018054909416919095161780835584546001600160401b03600160a01b91829004160267ffffffffffffffff60a01b1990911617808355935460ff600160e01b918290041615150260ff60e01b199094169390931790556003948501549401939093558254868401939192919087908110610e0957fe5b600091825260208083206004909202909101546001600160a01b031683528201929092526040019020555b6001805480610e3f57fe5b60008281526020812060046000199093019283020180546001600160a01b0319908116825560018201805490911690556002810180546001600160e81b03191690556003018190559155818381610e9257fe5b0490508015610ef65760015460005b81811015610ef3578260018281548110610eb757fe5b9060005260206000209060040201600301540160018281548110610ed757fe5b6000918252602090912060036004909202010155600101610ea1565b50505b505050505b50565b600181565b61100181565b603881565b600881565b61200081565b6001600160a01b03811660009081526004602052604081205480610f41576000915050610f66565b600180820381548110610f5057fe5b9060005260206000209060040201600301549150505b919050565b600081565b606781565b60018181548110610f8257fe5b600091825260209091206004909102018054600182015460028301546003909301546001600160a01b0392831694509082169291821691600160a01b81046001600160401b031691600160e01b90910460ff169086565b61100581565b600281565b61100881565b600b81565b606681565b33612000146110345760405162461bcd60e51b815260040180806020018281038252602f815260200180614516602f913960400191505060405180910390fd5b7f41ce201247b6ceb957dcdb217d0b8acb50b9ea0e12af9af4f5e7f38902101605838383604051808460ff1660ff168152602001806020018281038252848482818152602001925080828437600083820152604051601f909101601f1916909201829003965090945050505050a1505050565b6103e881565b60025481565b600981565b61100781565b61100681565b6040518061062001604052806105ef8152602001613f276105ef913981565b60005460ff1681565b6402540be40081565b60005460ff16611148576040805162461bcd60e51b81526020600482015260196024820152781d1a194818dbdb9d1c9858dd081b9bdd081a5b9a5d081e595d603a1b604482015290519081900360640190fd5b33611007146111885760405162461bcd60e51b815260040180806020018281038252602e815260200180613e91602e913960400191505060405180910390fd5b6111f284848080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525050604080518082019091526013815272065787069726554696d655365636f6e6447617606c1b60208201529150612c4c9050565b156112cd57602081146112365760405162461bcd60e51b8152600401808060200182810382526026815260200180613ee06026913960400191505060405180910390fd5b604080516020601f840181900481028201810190925282815260009161127491858580838501838280828437600092019190915250612d3492505050565b90506064811015801561128a5750620186a08111155b6112c55760405162461bcd60e51b8152600401808060200182810382526027815260200180613e456027913960400191505060405180910390fd5b60025561130a565b6040805162461bcd60e51b815260206004820152600d60248201526c756e6b6e6f776e20706172616d60981b604482015290519081900360640190fd5b7f6cdb0ac70ab7f2e2d035cca5be60d89906f2dede7648ddbd7402189c1eeed17a848484846040518080602001806020018381038352878782818152602001925080828437600083820152601f01601f191690910184810383528581526020019050858580828437600083820152604051601f909101601f19169092018290039850909650505050505050a150505050565b60046020526000908152604090205481565b6001546060906000805b828110156113ff57600181815481106113cd57fe5b9060005260206000209060040201600201601c9054906101000a900460ff166113f7576001909101905b6001016113b8565b5060608160405190808252806020026020018201604052801561142c578160200160208202803683370190505b50600092509050815b838110156114cc576001818154811061144a57fe5b9060005260206000209060040201600201601c9054906101000a900460ff166114c4576001818154811061147a57fe5b600091825260209091206004909102015482516001600160a01b03909116908390859081106114a557fe5b6001600160a01b03909216602092830291909101909101526001909201915b600101611435565b509250505090565b61100281565b67016345785d8a000081565b60055481565b61100381565b602981565b60005460ff161561154f576040805162461bcd60e51b815260206004820152601960248201527f74686520636f6e747261637420616c726561647920696e697400000000000000604482015290519081900360640190fd5b611557613d69565b600061157d6040518061062001604052806105ef8152602001613f276105ef9139611b15565b91509150806115bd5760405162461bcd60e51b8152600401808060200182810382526021815260200180613f066021913960400191505060405180910390fd5b60005b8260200151518110156116e2576001836020015182815181106115df57fe5b60209081029190910181015182546001818101855560009485528385208351600493840290910180546001600160a01b039283166001600160a01b03199182161782558587015182850180549185169183169190911790556040860151600283018054606089015160808a01511515600160e01b0260ff60e01b196001600160401b03909216600160a01b0267ffffffffffffffff60a01b199590981692909516919091179290921694909417161790915560a0909301516003909301929092559186015180519185019391859081106116b557fe5b602090810291909101810151516001600160a01b03168252810191909152604001600020556001016115c0565b50506103e8600255506000805460ff19166001179055565b336110011461173a5760405162461bcd60e51b81526004018080602001828103825260298152602001806145726029913960400191505060405180910390fd5b6001600160a01b0381166000908152600460205260409020548061175e5750610efb565b60018103905060006001828154811061177357fe5b906000526020600020906004020160030154905060006001838154811061179657fe5b906000526020600020906004020160030181905550600060018080549050039050836001600160a01b03167f8cd4e147d8af98a9e3b6724021b8bf6aed2e5dac71c38f2dce8161b82585b25d836040518082815260200191505060405180910390a28061180557505050610efb565b600081838161181057fe5b0490508015610ef65760005b8481101561186e57816001828154811061183257fe5b906000526020600020906004020160030154016001828154811061185257fe5b600091825260209091206003600490920201015560010161181c565b50600180549085015b81811015610ef357826001828154811061188d57fe5b90600052602060002090600402016003015401600182815481106118ad57fe5b6000918252602090912060036004909202010155600101611877565b606581565b33411461190c5760405162461bcd60e51b815260040180806020018281038252602d815260200180614545602d913960400191505060405180910390fd5b60005460ff1661195f576040805162461bcd60e51b81526020600482015260196024820152781d1a194818dbdb9d1c9858dd081b9bdd081a5b9a5d081e595d603a1b604482015290519081900360640190fd5b600034116119ac576040805162461bcd60e51b81526020600482015260156024820152746465706f7369742076616c7565206973207a65726f60581b604482015290519081900360640190fd5b6001600160a01b03811660009081526004602052604090205434908015611abf5760006001808303815481106119de57fe5b9060005260206000209060040201905080600201601c9054906101000a900460ff1615611a49576040805184815290516001600160a01b038616917ff177e5d6c5764d79c32883ed824111d9b13f5668cf6ab1cc12dd36791dd955b4919081900360200190a2611ab9565b600354611a5c908463ffffffff612d3916565b6003908155810154611a74908463ffffffff612d3916565b60038201556040805184815290516001600160a01b038616917f93a090ecc682c002995fad3c85b30c5651d7fd29b0be5da9d784a3302aedc055919081900360200190a25b50611aff565b6040805183815290516001600160a01b038516917ff177e5d6c5764d79c32883ed824111d9b13f5668cf6ab1cc12dd36791dd955b4919081900360200190a25b505050565b61100081565b600381565b61100481565b611b1d613d69565b6000611b27613d69565b611b2f613d81565b611b40611b3b86612d93565b612db8565b90506000805b611b4f83612e02565b15611c605780611b7457611b6a611b6584612e23565b612e71565b60ff168452611c58565b8060011415611c53576060611b90611b8b85612e23565b612f28565b90508051604051908082528060200260200182016040528015611bcd57816020015b611bba613da1565b815260200190600190039081611bb25790505b50602086015260005b8151811015611c4857611be7613da1565b6000611c05848481518110611bf857fe5b6020026020010151612ff9565b9150915080611c2257876000995099505050505050505050611c69565b8188602001518481518110611c3357fe5b60209081029190910101525050600101611bd6565b506001925050611c58565b611c60565b600101611b46565b50919350909150505b915091565b604080516001808252818301909252606091829190816020015b6060815260200190600190039081611c88579050509050611cae8363ffffffff166130d6565b81600081518110611cbb57fe5b6020026020010181905250610bd8816130e9565b6000806060611cdd84613173565b9150915081611d8a577f70e72399380dcfb0338abc03dc8d47f9f470ada8e769c9a78d644ea97385ecb2816040518080602001828103825283818151815260200191508051906020019080838360005b83811015611d45578181015183820152602001611d2d565b50505050905090810190601f168015611d725780820380516001836020036101000a031916815260200191505b509250505060405180910390a1606692505050610f66565b600080805b600154811015611e075767016345785d8a000060018281548110611daf57fe5b90600052602060002090600402016003015410611dd157600190920191611dff565b600060018281548110611de057fe5b9060005260206000209060040201600301541115611dff576001909101905b600101611d8f565b50606082604051908082528060200260200182016040528015611e34578160200160208202803683370190505b509050606083604051908082528060200260200182016040528015611e63578160200160208202803683370190505b509050606084604051908082528060200260200182016040528015611e92578160200160208202803683370190505b509050606085604051908082528060200260200182016040528015611ec1578160200160208202803683370190505b5090506000606086604051908082528060200260200182016040528015611ef2578160200160208202803683370190505b509050606087604051908082528060200260200182016040528015611f21578160200160208202803683370190505b509050600098506000975060608d905060006110046001600160a01b031663149d14d96040518163ffffffff1660e01b815260040160206040518083038186803b158015611f6e57600080fd5b505afa158015611f82573d6000803e3d6000fd5b505050506040513d6020811015611f9857600080fd5b5051905067016345785d8a000081111561200d577f70e72399380dcfb0338abc03dc8d47f9f470ada8e769c9a78d644ea97385ecb2604051808060200182810382526021815260200180613ebf6021913960400191505060405180910390a160689d5050505050505050505050505050610f66565b60005b6001548110156122805767016345785d8a00006001828154811061203057fe5b906000526020600020906004020160030154106121b6576001818154811061205457fe5b906000526020600020906004020160020160009054906101000a90046001600160a01b03168a8d8151811061208557fe5b60200260200101906001600160a01b031690816001600160a01b03168152505060006402540be400600183815481106120ba57fe5b906000526020600020906004020160030154816120d357fe5b06600183815481106120e157fe5b906000526020600020906004020160030154039050612109838261325590919063ffffffff16565b8a8e8151811061211557fe5b6020026020010181815250506001828154811061212e57fe5b906000526020600020906004020160020160009054906101000a90046001600160a01b0316888e8151811061215f57fe5b60200260200101906001600160a01b031690816001600160a01b03168152505081898e8151811061218c57fe5b60209081029190910101526121a7878263ffffffff612d3916565b6001909d019c96506122789050565b6000600182815481106121c557fe5b906000526020600020906004020160030154111561227857600181815481106121ea57fe5b906000526020600020906004020160010160009054906101000a90046001600160a01b0316858c8151811061221b57fe5b60200260200101906001600160a01b031690816001600160a01b0316815250506001818154811061224857fe5b906000526020600020906004020160030154848c8151811061226657fe5b60209081029190910101526001909a01995b600101612010565b50600085156126be576110046001600160a01b0316636e056520878c8c8b60025442016040518663ffffffff1660e01b815260040180806020018060200180602001856001600160401b03166001600160401b03168152602001848103845288818151815260200191508051906020019060200280838360005b838110156123125781810151838201526020016122fa565b50505050905001848103835287818151815260200191508051906020019060200280838360005b83811015612351578181015183820152602001612339565b50505050905001848103825286818151815260200191508051906020019060200280838360005b83811015612390578181015183820152602001612378565b505050509050019750505050505050506020604051808303818588803b1580156123b957600080fd5b505af1935050505080156123df57506040513d60208110156123da57600080fd5b505160015b61261a576040516000815260443d10156123fb57506000612496565b60046000803e60005160e01c6308c379a0811461241c576000915050612496565b60043d036004833e81513d60248201116001600160401b038211171561244757600092505050612496565b80830180516001600160401b03811115612468576000945050505050612496565b8060208301013d860181111561248657600095505050505050612496565b601f01601f191660405250925050505b806124a15750612545565b60019150867fa7cdeed7d0db45e3219a6e5d60838824c16f1d39991fcfe3f963029c844bf280826040518080602001828103825283818151815260200191508051906020019080838360005b838110156125055781810151838201526020016124ed565b50505050905090810190601f1680156125325780820380516001836020036101000a031916815260200191505b509250505060405180910390a250612615565b3d80801561256f576040519150601f19603f3d011682016040523d82523d6000602084013e612574565b606091505b5060019150867fbfa884552dd8921b6ce90bfe906952ae5b3b29be0cc1a951d4f62697635a3a45826040518080602001828103825283818151815260200191508051906020019080838360005b838110156125d95781810151838201526020016125c1565b50505050905090810190601f1680156126065780820380516001836020036101000a031916815260200191505b509250505060405180910390a2505b6126be565b8015612658576040805188815290517fa217d08e65f80c73121cd9db834d81652d544bfbf452f6d04922b16c90a37b709181900360200190a16126bc565b604080516020808252601b908201527f6261746368207472616e736665722072657475726e2066616c7365000000000081830152905188917fa7cdeed7d0db45e3219a6e5d60838824c16f1d39991fcfe3f963029c844bf280919081900360600190a25b505b80156128745760005b88518110156128725760008982815181106126de57fe5b602002602001015190506000600182815481106126f757fe5b60009182526020909120600160049092020181015481546001600160a01b03909116916108fc918590811061272857fe5b9060005260206000209060040201600301549081150290604051600060405180830381858888f19350505050905080156127e4576001828154811061276957fe5b60009182526020909120600160049092020181015481546001600160a01b03909116917f6c61d60f69a7beb3e1c80db7f39f37b208537cbb19da3174511b477812b2fc7d91859081106127b857fe5b9060005260206000209060040201600301546040518082815260200191505060405180910390a2612868565b600182815481106127f157fe5b60009182526020909120600160049092020181015481546001600160a01b03909116917f25d0ce7d2f0cec669a8c17efe49d195c13455bb8872b65fa610ac7f53fe4ca7d918590811061284057fe5b9060005260206000209060040201600301546040518082815260200191505060405180910390a25b50506001016126c7565b505b8451156129be5760005b85518110156129bc57600086828151811061289557fe5b60200260200101516001600160a01b03166108fc8784815181106128b557fe5b60200260200101519081150290604051600060405180830381858888f193505050509050801561294b578682815181106128eb57fe5b60200260200101516001600160a01b03167f6c61d60f69a7beb3e1c80db7f39f37b208537cbb19da3174511b477812b2fc7d87848151811061292957fe5b60200260200101516040518082815260200191505060405180910390a26129b3565b86828151811061295757fe5b60200260200101516001600160a01b03167f25d0ce7d2f0cec669a8c17efe49d195c13455bb8872b65fa610ac7f53fe4ca7d87848151811061299557fe5b60200260200101516040518082815260200191505060405180910390a25b5060010161287e565b505b4715612a27576040805147815290517f6ecc855f9440a9282c90913bbc91619fd44f5ec0b462af28d127b116f130aa4d9181900360200190a1604051611002904780156108fc02916000818181858888f19350505050158015612a25573d6000803e3d6000fd5b505b60006003819055600555825115612a4157612a4183613297565b6110016001600160a01b031663fc4333cd6040518163ffffffff1660e01b8152600401600060405180830381600087803b158015612a7e57600080fd5b505af1158015612a92573d6000803e3d6000fd5b50506040517fedd8d7296956dd970ab4de3f2fc03be2b0ffc615d20cd4c72c6e44f928630ebf925060009150a15060009f9e505050505050505050505050505050565b80516001600160a01b0316600090815260046020526040812054801580612b265750600180820381548110612b0657fe5b9060005260206000209060040201600201601c9054906101000a900460ff165b15612b6c5782516040516001600160a01b03909116907fe209c46bebf57cf265d5d9009a00870e256d9150f3ed5281ab9d9eb3cec6e4be90600090a26000915050610f66565b600154600554600019820111801590612bc25784516040516001600160a01b03909116907fe209c46bebf57cf265d5d9009a00870e256d9150f3ed5281ab9d9eb3cec6e4be90600090a260009350505050610f66565b600580546001908101909155805481906000198601908110612be057fe5b6000918252602082206002600490920201018054921515600160e01b0260ff60e01b199093169290921790915585516040516001600160a01b03909116917ff226e7d8f547ff903d9d419cf5f54e0d7d07efa9584135a53a057c5f1f27f49a91a2506000949350505050565b6000816040516020018082805190602001908083835b60208310612c815780518252601f199092019160209182019101612c62565b6001836020036101000a03801982511681845116808217855250505050505090500191505060405160208183030381529060405280519060200120836040516020018082805190602001908083835b60208310612cef5780518252601f199092019160209182019101612cd0565b6001836020036101000a038019825116818451168082178552505050505050905001915050604051602081830303815290604052805190602001201490505b92915050565b015190565b600082820183811015610bd8576040805162461bcd60e51b815260206004820152601b60248201527f536166654d6174683a206164646974696f6e206f766572666c6f770000000000604482015290519081900360640190fd5b612d9b613dd6565b506040805180820190915281518152602082810190820152919050565b612dc0613d81565b612dc98261375e565b612dd257600080fd5b6000612de18360200151613798565b60208085015160408051808201909152868152920190820152915050919050565b6000612e0c613dd6565b505080518051602091820151919092015191011190565b612e2b613dd6565b612e3482612e02565b612e3d57600080fd5b60208201516000612e4d826137fb565b80830160209586015260408051808201909152908152938401919091525090919050565b805160009015801590612e8657508151602110155b612e8f57600080fd5b6000612e9e8360200151613798565b90508083600001511015612ef9576040805162461bcd60e51b815260206004820152601a60248201527f6c656e677468206973206c657373207468616e206f6666736574000000000000604482015290519081900360640190fd5b825160208085015183018051928490039291831015612f1f57826020036101000a820491505b50949350505050565b6060612f338261375e565b612f3c57600080fd5b6000612f478361392e565b9050606081604051908082528060200260200182016040528015612f8557816020015b612f72613dd6565b815260200190600190039081612f6a5790505b5090506000612f978560200151613798565b60208601510190506000805b84811015612fee57612fb4836137fb565b9150604051806040016040528083815260200184815250848281518110612fd757fe5b602090810291909101015291810191600101612fa3565b509195945050505050565b613001613da1565b600061300b613da1565b613013613d81565b61301c85612db8565b90506000805b61302b83612e02565b15611c6057806130565761304661304184612e23565b61398a565b6001600160a01b031684526130ce565b806001141561307e5761306b61304184612e23565b6001600160a01b031660208501526130ce565b80600214156130a65761309361304184612e23565b6001600160a01b031660408501526130ce565b8060031415611c53576130bb611b6584612e23565b6001600160401b03166060850152600191505b600101613022565b6060612d2e6130e4836139a4565b613a8a565b606081516000141561310a5750604080516000815260208101909152610f66565b60608260008151811061311957fe5b602002602001015190506000600190505b835181101561315a576131508285838151811061314357fe5b6020026020010151613adc565b915060010161312a565b50610bd861316d825160c060ff16613b59565b82613adc565b600060606029835111156131a5576000604051806060016040528060298152602001613df16029913991509150611c69565b60005b835181101561323b5760005b81811015613232578481815181106131c857fe5b6020026020010151600001516001600160a01b03168583815181106131e957fe5b6020026020010151600001516001600160a01b0316141561322a5760006040518060600160405280602b8152602001613e1a602b9139935093505050611c69565b6001016131b4565b506001016131a8565b505060408051602081019091526000815260019150915091565b6000610bd883836040518060400160405280601e81526020017f536166654d6174683a207375627472616374696f6e206f766572666c6f770000815250613c51565b600154815160005b828110156133b45760016132b1613da1565b600183815481106132be57fe5b600091825260208083206040805160c08101825260049490940290910180546001600160a01b0390811685526001820154811693850193909352600281015492831691840191909152600160a01b82046001600160401b03166060840152600160e01b90910460ff16151560808301526003015460a082015291505b848110156133885786818151811061334e57fe5b6020026020010151600001516001600160a01b031682600001516001600160a01b031614156133805760009250613388565b60010161333a565b5081156133aa5780516001600160a01b03166000908152600460205260408120555b505060010161329f565b508082111561342957805b828110156134275760018054806133d257fe5b60008281526020812060046000199093019283020180546001600160a01b03199081168255600182810180549092169091556002820180546001600160e81b03191690556003909101919091559155016133bf565b505b6000818310613438578161343a565b825b905060005b81811015613634576134ec85828151811061345657fe5b60200260200101516001838154811061346b57fe5b60009182526020918290206040805160c08101825260049390930290910180546001600160a01b0390811684526001820154811694840194909452600281015493841691830191909152600160a01b83046001600160401b03166060830152600160e01b90920460ff161515608082015260039091015460a0820152613ce8565b61360757806001016004600087848151811061350457fe5b6020026020010151600001516001600160a01b03166001600160a01b031681526020019081526020016000208190555084818151811061354057fe5b60200260200101516001828154811061355557fe5b6000918252602091829020835160049092020180546001600160a01b039283166001600160a01b0319918216178255928401516001820180549184169185169190911790556040840151600282018054606087015160808801511515600160e01b0260ff60e01b196001600160401b03909216600160a01b0267ffffffffffffffff60a01b1995909716929097169190911792909216939093171692909217905560a09091015160039091015561362c565b60006001828154811061361657fe5b9060005260206000209060040201600301819055505b60010161343f565b508282111561375857825b82811015610ef657600185828151811061365557fe5b60209081029190910181015182546001818101855560009485528385208351600493840290910180546001600160a01b039283166001600160a01b03199182161782559585015181840180549184169188169190911790556040850151600282018054606088015160808901511515600160e01b0260ff60e01b196001600160401b03909216600160a01b0267ffffffffffffffff60a01b199590971692909a169190911792909216939093171695909517905560a0909201516003909301929092558751908401929088908590811061372b57fe5b602090810291909101810151516001600160a01b031682528101919091526040016000205560010161363f565b50505050565b805160009061376f57506000610f66565b6020820151805160001a9060c082101561378e57600092505050610f66565b5060019392505050565b8051600090811a60808110156137b2576000915050610f66565b60b88110806137cd575060c081108015906137cd575060f881105b156137dc576001915050610f66565b60c08110156137f05760b519019050610f66565b60f519019050610f66565b80516000908190811a60808110156138165760019150613927565b60b881101561382b57607e1981019150613927565b60c08110156138a557600060b78203600186019550806020036101000a86510491506001810182019350508083101561389f576040805162461bcd60e51b81526020600482015260116024820152706164646974696f6e206f766572666c6f7760781b604482015290519081900360640190fd5b50613927565b60f88110156138ba5760be1981019150613927565b600060f78203600186019550806020036101000a865104915060018101820193505080831015613925576040805162461bcd60e51b81526020600482015260116024820152706164646974696f6e206f766572666c6f7760781b604482015290519081900360640190fd5b505b5092915050565b805160009061393f57506000610f66565b600080905060006139538460200151613798565b602085015185519181019250015b8082101561398157613972826137fb565b60019093019290910190613961565b50909392505050565b805160009060151461399b57600080fd5b612d2e82612e71565b604080516020808252818301909252606091829190602082018180368337505050602081018490529050600067ffffffffffffffff1984166139e857506018613a0c565b6fffffffffffffffffffffffffffffffff198416613a0857506010613a0c565b5060005b6020811015613a4257818181518110613a2157fe5b01602001516001600160f81b03191615613a3a57613a42565b600101613a0c565b60008160200390506060816040519080825280601f01601f191660200182016040528015613a77576020820181803683370190505b5080830196909652508452509192915050565b606081516001148015613abc5750607f60f81b82600081518110613aaa57fe5b01602001516001600160f81b03191611155b15613ac8575080610f66565b612d2e613ada8351608060ff16613b59565b835b6060806040519050835180825260208201818101602087015b81831015613b0d578051835260209283019201613af5565b50855184518101855292509050808201602086015b81831015613b3a578051835260209283019201613b22565b508651929092011591909101601f01601f191660405250905092915050565b6060680100000000000000008310613ba9576040805162461bcd60e51b815260206004820152600e60248201526d696e70757420746f6f206c6f6e6760901b604482015290519081900360640190fd5b60408051600180825281830190925260609160208201818036833701905050905060378411613c035782840160f81b81600081518110613be557fe5b60200101906001600160f81b031916908160001a9053509050612d2e565b6060613c0e856139a4565b90508381510160370160f81b82600081518110613c2757fe5b60200101906001600160f81b031916908160001a905350613c488282613adc565b95945050505050565b60008184841115613ce05760405162461bcd60e51b81526004018080602001828103825283818151815260200191508051906020019080838360005b83811015613ca5578181015183820152602001613c8d565b50505050905090810190601f168015613cd25780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b505050900390565b805182516000916001600160a01b039182169116148015613d22575081602001516001600160a01b031683602001516001600160a01b0316145b8015613d47575081604001516001600160a01b031683604001516001600160a01b0316145b8015610bd85750506060908101519101516001600160401b0390811691161490565b60408051808201909152600081526060602082015290565b6040518060400160405280613d94613dd6565b8152602001600081525090565b6040805160c081018252600080825260208201819052918101829052606081018290526080810182905260a081019190915290565b60405180604001604052806000815260200160008152509056fe746865206e756d626572206f662076616c696461746f72732065786365656420746865206c696d69746475706c696361746520636f6e73656e7375732061646472657373206f662076616c696461746f725365747468652065787069726554696d655365636f6e64476170206973206f7574206f662072616e67656c656e677468206f66206a61696c2076616c696461746f7273206d757374206265206f6e65746865206d6573736167652073656e646572206d75737420626520676f7665726e616e636520636f6e7472616374666565206973206c6172676572207468616e2044555354595f494e434f4d494e476c656e677468206f662065787069726554696d655365636f6e64476170206d69736d617463686661696c656420746f20706172736520696e69742076616c696461746f72536574f905ec80f905e8f846942a7cdd959bfe8d9487b2a43b33565295a698f7e294b6a7edd747c0554875d3fc531d19ba1497992c5e941ff80f3f7f110ffd8920a3ac38fdef318fe94a3f86048c27395000f846946488aa4d1955ee33403f8ccb1d4de5fb97c7ade294220f003d8bdfaadf52aa1e55ae4cc485e6794875941a87e90e440a39c99aa9cb5cea0ad6a3f0b2407b86048c27395000f846949ef9f4360c606c7ab4db26b016007d3ad0ab86a0946103af86a874b705854033438383c82575f25bc29418e2db06cbff3e3c5f856410a1838649e760175786048c27395000f84694ee01c3b1283aa067c58eab4709f85e99d46de5fe94ee4b9bfb1871c64e2bcabb1dc382dc8b7c4218a29415904ab26ab0e99d70b51c220ccdcccabee6e29786048c27395000f84694685b1ded8013785d6623cc18d214320b6bb6475994a20ef4e5e4e7e36258dbf51f4d905114cb1b34bc9413e39085dc88704f4394d35209a02b1a9520320c86048c27395000f8469478f3adfc719c99674c072166708589033e2d9afe9448a30d5eaa7b64492a160f139e2da2800ec3834e94055838358c29edf4dcc1ba1985ad58aedbb6be2b86048c27395000f84694c2be4ec20253b8642161bc3f444f53679c1f3d479466f50c616d737e60d7ca6311ff0d9c434197898a94d1d678a2506eeaa365056fe565df8bc8659f28b086048c27395000f846942f7be8361c80a4c1e7e9aaf001d0877f1cfde218945f93992ac37f3e61db2ef8a587a436a161fd210b94ecbc4fb1a97861344dad0867ca3cba2b860411f086048c27395000f84694ce2fd7544e0b2cc94692d4a704debef7bcb613289444abc67b4b2fba283c582387f54c9cba7c34bafa948acc2ab395ded08bb75ce85bf0f95ad2abc51ad586048c27395000f84694b8f7166496996a7da21cf1f1b04d9b3e26a3d077946770572763289aac606e4f327c2f6cc1aa3b3e3b94882d745ed97d4422ca8da1c22ec49d880c4c097286048c27395000f846942d4c407bbe49438ed859fe965b140dcf1aab71a9943ad0939e120f33518fbba04631afe7a3ed6327b194b2bbb170ca4e499a2b0f3cc85ebfa6e8c4dfcbea86048c27395000f846946bbad7cf34b5fa511d8e963dbba288b1960e75d694853b0f6c324d1f4e76c8266942337ac1b0af1a229442498946a51ca5924552ead6fc2af08b94fcba648601d1a94a2000f846944430b3230294d12c6ab2aac5c2cd68e80b16b581947b107f4976a252a6939b771202c28e64e03f52d694795811a7f214084116949fc4f53cedbf189eeab28601d1a94a2000f84694ea0a6e3c511bbd10f4519ece37dc24887e11b55d946811ca77acfb221a49393c193f3a22db829fcc8e9464feb7c04830dd9ace164fc5c52b3f5a29e5018a8601d1a94a2000f846947ae2f5b9e386cd1b50a4550696d957cb4900f03a94e83bcc5077e6b873995c24bac871b5ad856047e19464e48d4057a90b233e026c1041e6012ada897fe88601d1a94a2000f8469482012708dafc9e1b880fd083b32182b869be8e09948e5adc73a2d233a1b496ed3115464dd6c7b887509428b383d324bc9a37f4e276190796ba5a8947f5ed8601d1a94a2000f8469422b81f8e175ffde54d797fe11eb03f9e3bf75f1d94a1c3ef7ca38d8ba80cce3bfc53ebd2903ed21658942767f7447f7b9b70313d4147b795414aecea54718601d1a94a2000f8469468bf0b8b6fb4e317a0f9d6f03eaf8ce6675bc60d94675cfe570b7902623f47e7f59c9664b5f5065dcf94d84f0d2e50bcf00f2fc476e1c57f5ca2d57f625b8601d1a94a2000f846948c4d90829ce8f72d0163c1d5cf348a862d5506309485c42a7b34309bee2ed6a235f86d16f059deec5894cc2cedc53f0fa6d376336efb67e43d167169f3b78601d1a94a2000f8469435e7a025f4da968de7e4d7e4004197917f4070f194b1182abaeeb3b4d8eba7e6a4162eac7ace23d57394c4fd0d870da52e73de2dd8ded19fe3d26f43a1138601d1a94a2000f84694d6caa02bbebaebb5d7e581e4b66559e635f805ff94c07335cf083c1c46a487f0325769d88e163b653694efaff03b42e41f953a925fc43720e45fb61a19938601d1a94a2000746865206d6573736167652073656e646572206d7573742062652063726f737320636861696e20636f6e7472616374746865206d6573736167652073656e646572206d7573742062652074686520626c6f636b2070726f6475636572746865206d6573736167652073656e646572206d75737420626520736c61736820636f6e7472616374a2646970667358221220f4016eb3755efa2abde797b21f8695280d971b0fea37198122d2e5867516da0464736f6c63430006040033" - }, - "0x0000000000000000000000000000000000001001": { - "balance": "0x0", - "code": "0x608060405234801561001057600080fd5b50600436106102275760003560e01c8063831d65d111610130578063c80d4b8f116100b8578063e1c7392a1161007c578063e1c7392a146106d9578063f9a2bbc7146106e1578063fc3e5908146106e9578063fc4333cd146106f1578063fd6a6879146106f957610227565b8063c80d4b8f14610623578063c81b16621461062b578063c8509d8114610633578063c96be4cb146106ab578063dc927faf146106d157610227565b8063a1a11bf5116100ff578063a1a11bf514610531578063a78abc1614610539578063ab51bb9614610555578063ac0af6291461055d578063ac4317511461056557610227565b8063831d65d11461049f57806396713da9146105195780639bc8e4f2146105215780639dc092621461052957610227565b80634bf6c882116101b35780636e47b482116101825780636e47b4821461047757806370fd5bad1461047f57806375d47a0a146104875780637912a65d1461048f5780637942fd051461049757610227565b80634bf6c8821461045757806351e806721461045f578063567a372d1461046757806362b72cf51461046f57610227565b806337c8dab9116101fa57806337c8dab9146103b9578063389f4f71146103f85780633dffc3871461041257806343756e5c14610430578063493279b11461043857610227565b80630bee7a671461022c5780631182b8751461024d57806323bac5a21461033a57806335aa2e4414610380575b600080fd5b610234610701565b6040805163ffffffff9092168252519081900360200190f35b6102c56004803603604081101561026357600080fd5b60ff8235169190810190604081016020820135600160201b81111561028757600080fd5b82018360208201111561029957600080fd5b803590602001918460018302840111600160201b831117156102ba57600080fd5b509092509050610706565b6040805160208082528351818301528351919283929083019185019080838360005b838110156102ff5781810151838201526020016102e7565b50505050905090810190601f16801561032c5780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b6103606004803603602081101561035057600080fd5b50356001600160a01b03166107da565b604080519384526020840192909252151582820152519081900360600190f35b61039d6004803603602081101561039657600080fd5b50356107fd565b604080516001600160a01b039092168252519081900360200190f35b6103df600480360360208110156103cf57600080fd5b50356001600160a01b0316610824565b6040805192835260208301919091528051918290030190f35b61040061087b565b60408051918252519081900360200190f35b61041a610881565b6040805160ff9092168252519081900360200190f35b61039d610886565b61044061088c565b6040805161ffff9092168252519081900360200190f35b61041a610891565b61039d610896565b61040061089c565b6104006108a2565b61039d6108a8565b61041a6108ae565b61039d6108b3565b6104006108b9565b61041a6108be565b610517600480360360408110156104b557600080fd5b60ff8235169190810190604081016020820135600160201b8111156104d957600080fd5b8201836020820111156104eb57600080fd5b803590602001918460018302840111600160201b8311171561050c57600080fd5b5090925090506108c3565b005b61041a610a1e565b610400610a23565b61039d610a2e565b61039d610a34565b610541610a3a565b604080519115158252519081900360200190f35b610234610a43565b610400610a48565b6105176004803603604081101561057b57600080fd5b810190602081018135600160201b81111561059557600080fd5b8201836020820111156105a757600080fd5b803590602001918460018302840111600160201b831117156105c857600080fd5b919390929091602081019035600160201b8111156105e557600080fd5b8201836020820111156105f757600080fd5b803590602001918460018302840111600160201b8311171561061857600080fd5b509092509050610a4d565b610400610e3b565b61039d610e40565b6105176004803603604081101561064957600080fd5b60ff8235169190810190604081016020820135600160201b81111561066d57600080fd5b82018360208201111561067f57600080fd5b803590602001918460018302840111600160201b831117156106a057600080fd5b509092509050610e46565b610517600480360360208110156106c157600080fd5b50356001600160a01b0316610ef9565b61039d61131e565b610517611324565b61039d611395565b61041a61139b565b6105176113a0565b61039d61182b565b606481565b606033612000146107485760405162461bcd60e51b815260040180806020018281038252602f815260200180612282602f913960400191505060405180910390fd5b60005460ff1661078d576040805162461bcd60e51b815260206004820152601960248201526000805160206122de833981519152604482015290519081900360640190fd5b6040805162461bcd60e51b815260206004820152601e60248201527f7265636569766520756e65787065637465642073796e207061636b6167650000604482015290519081900360640190fd5b600260208190526000918252604090912080546001820154919092015460ff1683565b6001818154811061080a57fe5b6000918252602090912001546001600160a01b0316905081565b60008061082f612146565b5050506001600160a01b0316600090815260026020818152604092839020835160608101855281548082526001830154938201849052919093015460ff16151592909301919091529091565b60055481565b600181565b61100181565b603881565b600881565b61200081565b60045481565b60035481565b61100581565b600281565b61100881565b603281565b600b81565b33612000146109035760405162461bcd60e51b815260040180806020018281038252602f815260200180612282602f913960400191505060405180910390fd5b60005460ff16610948576040805162461bcd60e51b815260206004820152601960248201526000805160206122de833981519152604482015290519081900360640190fd5b610950612169565b600061099184848080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061183192505050565b9150915080156109db5781516040805163ffffffff9092168252517f7f0956d47419b9525356e7111652b653b530ec6f5096dccc04589bc38e6299679181900360200190a1610a17565b81516040805163ffffffff9092168252517f7d45f62d17443dd4547bca8a8112c60e2385669318dc300ec61a5d2492f262e79181900360200190a15b5050505050565b600981565b662386f26fc1000081565b61100781565b61100681565b60005460ff1681565b600081565b600481565b60005460ff16610a92576040805162461bcd60e51b815260206004820152601960248201526000805160206122de833981519152604482015290519081900360640190fd5b3361100714610ad25760405162461bcd60e51b815260040180806020018281038252602e81526020018061220d602e913960400191505060405180910390fd5b610b3d84848080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250506040805180820190915260148152731b5a5cd9195b59585b9bdc951a1c995cda1bdb1960621b602082015291506118b19050565b15610c165760208114610b815760405162461bcd60e51b81526004018080602001828103825260278152602001806121b66027913960400191505060405180910390fd5b604080516020601f8401819004810282018101909252828152600091610bbf9185858083850183828082843760009201919091525061199992505050565b905060018110158015610bd3575060055481105b610c0e5760405162461bcd60e51b815260040180806020018281038252602581526020018061225d6025913960400191505060405180910390fd5b600455610da9565b610c7c84848080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152505060408051808201909152600f81526e19995b1bdb9e551a1c995cda1bdb19608a1b602082015291506118b19050565b15610d6c5760208114610cc05760405162461bcd60e51b815260040180806020018281038252602281526020018061223b6022913960400191505060405180910390fd5b604080516020601f8401819004810282018101909252828152600091610cfe9185858083850183828082843760009201919091525061199992505050565b90506103e88111158015610d13575060045481115b610d64576040805162461bcd60e51b815260206004820181905260248201527f7468652066656c6f6e795468726573686f6c64206f7574206f662072616e6765604482015290519081900360640190fd5b600555610da9565b6040805162461bcd60e51b815260206004820152600d60248201526c756e6b6e6f776e20706172616d60981b604482015290519081900360640190fd5b7f6cdb0ac70ab7f2e2d035cca5be60d89906f2dede7648ddbd7402189c1eeed17a848484846040518080602001806020018381038352878782818152602001925080828437600083820152601f01601f191690910184810383528581526020019050858580828437600083820152604051601f909101601f19169092018290039850909650505050505050a150505050565b609681565b61100281565b3361200014610e865760405162461bcd60e51b815260040180806020018281038252602f815260200180612282602f913960400191505060405180910390fd5b60005460ff16610ecb576040805162461bcd60e51b815260206004820152601960248201526000805160206122de833981519152604482015290519081900360640190fd5b6040517f07db600eebe2ac176be8dcebad61858c245a4961bb32ca2aa3d159b09aa0810e90600090a1505050565b334114610f375760405162461bcd60e51b815260040180806020018281038252602d8152602001806122b1602d913960400191505060405180910390fd5b60005460ff16610f7c576040805162461bcd60e51b815260206004820152601960248201526000805160206122de833981519152604482015290519081900360640190fd5b6003544311610fd2576040805162461bcd60e51b815260206004820181905260248201527f63616e206e6f7420736c61736820747769636520696e206f6e6520626c6f636b604482015290519081900360640190fd5b3a1561101c576040805162461bcd60e51b81526020600482015260146024820152736761737072696365206973206e6f74207a65726f60601b604482015290519081900360640190fd5b611024612146565b506001600160a01b0381166000908152600260208181526040928390208351606081018552815481526001820154928101929092529091015460ff16158015928201929092529061107f5760208101805160010190526110d8565b60016040820181905260208201819052805480820182556000919091527fb10e2d527612073b26eecdfd717e6a320cf44b4afac2b0732d9fcbe2b7fa0cf60180546001600160a01b0319166001600160a01b0384161790555b4381526005546020820151816110ea57fe5b0661123c57600060208201819052604080516335409f7f60e01b81526001600160a01b03851660048201529051611000926335409f7f926024808201939182900301818387803b15801561113d57600080fd5b505af1158015611151573d6000803e3d6000fd5b505050506120006001600160a01b031663f7a251d7600b6111718561199e565b60006040518463ffffffff1660e01b8152600401808460ff1660ff16815260200180602001838152602001828103825284818151815260200191508051906020019080838360005b838110156111d15781810151838201526020016111b9565b50505050905090810190601f1680156111fe5780820380516001836020036101000a031916815260200191505b50945050505050600060405180830381600087803b15801561121f57600080fd5b505af1158015611233573d6000803e3d6000fd5b505050506112b2565b60045481602001518161124b57fe5b066112b257604080516375abf10160e11b81526001600160a01b038416600482015290516110009163eb57e20291602480830192600092919082900301818387803b15801561129957600080fd5b505af11580156112ad573d6000803e3d6000fd5b505050505b6001600160a01b0382166000818152600260208181526040808420865181559186015160018301558581015191909201805460ff1916911515919091179055517fddb6012116e51abf5436d956a4f0ebd927e92c576ff96d7918290c8782291e3e9190a2505043600355565b61100381565b60005460ff161561137c576040805162461bcd60e51b815260206004820152601960248201527f74686520636f6e747261637420616c726561647920696e697400000000000000604482015290519081900360640190fd5b603260045560966005556000805460ff19166001179055565b61100081565b600381565b33611000146113e05760405162461bcd60e51b81526004018080602001828103825260308152602001806121dd6030913960400191505060405180910390fd5b60005460ff16611425576040805162461bcd60e51b815260206004820152601960248201526000805160206122de833981519152604482015290519081900360640190fd5b60015461143157611829565b600154600090600019015b8082116117fd576000805b8284101561156057611457612146565b600260006001878154811061146857fe5b60009182526020808320909101546001600160a01b0316835282810193909352604091820190208151606081018352815481526001820154938101939093526002015460ff16151590820152600554909150600490048160200151111561154a576004600554816114d557fe5b048160200151038160200181815250508060026000600188815481106114f757fe5b6000918252602080832091909101546001600160a01b0316835282810193909352604091820190208351815591830151600183015591909101516002909101805460ff1916911515919091179055611554565b6001925050611560565b50600190930192611447565b8284116116f75761156f612146565b600260006001868154811061158057fe5b60009182526020808320909101546001600160a01b0316835282810193909352604091820190208151606081018352815481526001820154938101939093526002015460ff161515908201526005549091506004900481602001511115611668576004600554816115ed57fe5b0481602001510381602001818152505080600260006001878154811061160f57fe5b6000918252602080832091909101546001600160a01b03168352828101939093526040918201902083518155918301516001808401919091559201516002909101805460ff191691151591909117905591506116f79050565b600260006001868154811061167957fe5b60009182526020808320909101546001600160a01b031683528201929092526040018120818155600181810192909255600201805460ff191690558054806116bd57fe5b600082815260209020810160001990810180546001600160a01b0319169055019055836116ea57506116f7565b5060001990920191611560565b8180156117015750805b156117e057600260006001868154811061171757fe5b60009182526020808320909101546001600160a01b031683528201929092526040018120818155600181810192909255600201805460ff1916905580548490811061175e57fe5b600091825260209091200154600180546001600160a01b03909216918690811061178457fe5b9060005260206000200160006101000a8154816001600160a01b0302191690836001600160a01b0316021790555060018054806117bd57fe5b600082815260209020810160001990810180546001600160a01b03191690550190555b826117ec5750506117fd565b50506001909101906000190161143c565b6040517fcfdb3b6ccaeccbdc68be3c59c840e3b3c90f0a7c491f5fff1cf56cfda200dd9c90600090a150505b565b61100481565b611839612169565b6000611843612169565b61184b61217b565b61185c61185786611a70565b611a95565b90506000805b61186b83611adf565b156118a457806118975761188661188184611b00565b611b4e565b63ffffffff1684526001915061189c565b6118a4565b600101611862565b5091935090915050915091565b6000816040516020018082805190602001908083835b602083106118e65780518252601f1990920191602091820191016118c7565b6001836020036101000a03801982511681845116808217855250505050505090500191505060405160208183030381529060405280519060200120836040516020018082805190602001908083835b602083106119545780518252601f199092019160209182019101611935565b6001836020036101000a038019825116818451168082178552505050505050905001915050604051602081830303815290604052805190602001201490505b92915050565b015190565b60408051600480825260a08201909252606091829190816020015b60608152602001906001900390816119b95790505090506119e2836001600160a01b0316611c05565b816000815181106119ef57fe5b6020026020010181905250611a0343611c28565b81600181518110611a1057fe5b6020908102919091010152611a256038611c28565b81600281518110611a3257fe5b6020026020010181905250611a4642611c28565b81600381518110611a5357fe5b6020026020010181905250611a6781611c3b565b9150505b919050565b611a7861219b565b506040805180820190915281518152602082810190820152919050565b611a9d61217b565b611aa682611cc5565b611aaf57600080fd5b6000611abe8360200151611cff565b60208085015160408051808201909152868152920190820152915050919050565b6000611ae961219b565b505080518051602091820151919092015191011190565b611b0861219b565b611b1182611adf565b611b1a57600080fd5b60208201516000611b2a82611d62565b80830160209586015260408051808201909152908152938401919091525090919050565b805160009015801590611b6357508151602110155b611b6c57600080fd5b6000611b7b8360200151611cff565b90508083600001511015611bd6576040805162461bcd60e51b815260206004820152601a60248201527f6c656e677468206973206c657373207468616e206f6666736574000000000000604482015290519081900360640190fd5b825160208085015183018051928490039291831015611bfc57826020036101000a820491505b50949350505050565b60408051600560a21b8318601482015260348101909152606090611a6781611e95565b6060611993611c3683611eeb565b611e95565b6060815160001415611c5c5750604080516000815260208101909152611a6b565b606082600081518110611c6b57fe5b602002602001015190506000600190505b8351811015611cac57611ca282858381518110611c9557fe5b6020026020010151611fd1565b9150600101611c7c565b50611a67611cbf825160c060ff1661204e565b82611fd1565b8051600090611cd657506000611a6b565b6020820151805160001a9060c0821015611cf557600092505050611a6b565b5060019392505050565b8051600090811a6080811015611d19576000915050611a6b565b60b8811080611d34575060c08110801590611d34575060f881105b15611d43576001915050611a6b565b60c0811015611d575760b519019050611a6b565b60f519019050611a6b565b80516000908190811a6080811015611d7d5760019150611e8e565b60b8811015611d9257607e1981019150611e8e565b60c0811015611e0c57600060b78203600186019550806020036101000a865104915060018101820193505080831015611e06576040805162461bcd60e51b81526020600482015260116024820152706164646974696f6e206f766572666c6f7760781b604482015290519081900360640190fd5b50611e8e565b60f8811015611e215760be1981019150611e8e565b600060f78203600186019550806020036101000a865104915060018101820193505080831015611e8c576040805162461bcd60e51b81526020600482015260116024820152706164646974696f6e206f766572666c6f7760781b604482015290519081900360640190fd5b505b5092915050565b606081516001148015611ec75750607f60f81b82600081518110611eb557fe5b01602001516001600160f81b03191611155b15611ed3575080611a6b565b611993611ee58351608060ff1661204e565b83611fd1565b604080516020808252818301909252606091829190602082018180368337505050602081018490529050600067ffffffffffffffff198416611f2f57506018611f53565b6fffffffffffffffffffffffffffffffff198416611f4f57506010611f53565b5060005b6020811015611f8957818181518110611f6857fe5b01602001516001600160f81b03191615611f8157611f89565b600101611f53565b60008160200390506060816040519080825280601f01601f191660200182016040528015611fbe576020820181803683370190505b5080830196909652508452509192915050565b6060806040519050835180825260208201818101602087015b81831015612002578051835260209283019201611fea565b50855184518101855292509050808201602086015b8183101561202f578051835260209283019201612017565b508651929092011591909101601f01601f191660405250905092915050565b606068010000000000000000831061209e576040805162461bcd60e51b815260206004820152600e60248201526d696e70757420746f6f206c6f6e6760901b604482015290519081900360640190fd5b604080516001808252818301909252606091602082018180368337019050509050603784116120f85782840160f81b816000815181106120da57fe5b60200101906001600160f81b031916908160001a9053509050611993565b606061210385611eeb565b90508381510160370160f81b8260008151811061211c57fe5b60200101906001600160f81b031916908160001a90535061213d8282611fd1565b95945050505050565b604051806060016040528060008152602001600081526020016000151581525090565b60408051602081019091526000815290565b604051806040016040528061218e61219b565b8152602001600081525090565b60405180604001604052806000815260200160008152509056fe6c656e677468206f66206d697364656d65616e6f725468726573686f6c64206d69736d61746368746865206d6573736167652073656e646572206d7573742062652076616c696461746f7253657420636f6e7472616374746865206d6573736167652073656e646572206d75737420626520676f7665726e616e636520636f6e74726163746c656e677468206f662066656c6f6e795468726573686f6c64206d69736d61746368746865206d697364656d65616e6f725468726573686f6c64206f7574206f662072616e6765746865206d6573736167652073656e646572206d7573742062652063726f737320636861696e20636f6e7472616374746865206d6573736167652073656e646572206d7573742062652074686520626c6f636b2070726f647563657274686520636f6e7472616374206e6f7420696e69742079657400000000000000a2646970667358221220978db7b9b4e7fb0a1f9436afd2b57418fb3ba1969a491794d2da96ee68de87d064736f6c63430006040033" - }, - "0x0000000000000000000000000000000000001002": { - "balance": "0x0", - "code": "0x60806040526004361061014f5760003560e01c806396713da9116100b6578063c81b16621161006f578063c81b1662146103dc578063dc927faf146103f1578063f9a2bbc714610406578063fb5478b31461041b578063fc3e590814610430578063fd6a68791461044557610193565b806396713da91461033a5780639a99b4f01461034f5780639dc0926214610388578063a1a11bf51461039d578063a78abc16146103b2578063ab51bb96146103c757610193565b806351e806721161010857806351e806721461028a5780636d70f7ae1461029f5780636e47b482146102e657806370fd5bad146102fb57806375d47a0a146103105780637942fd051461032557610193565b80630bee7a67146101985780633a0b0eff146101c65780633dffc387146101ed57806343756e5c14610218578063493279b1146102495780634bf6c8821461027557610193565b366101935734156101915760408051348152905133917f6c98249d85d88c3753a04a22230f595e4dc8d3dc86c34af35deeeedc861b89db919081900360200190a25b005b600080fd5b3480156101a457600080fd5b506101ad61045a565b6040805163ffffffff9092168252519081900360200190f35b3480156101d257600080fd5b506101db61045f565b60408051918252519081900360200190f35b3480156101f957600080fd5b50610202610465565b6040805160ff9092168252519081900360200190f35b34801561022457600080fd5b5061022d61046a565b604080516001600160a01b039092168252519081900360200190f35b34801561025557600080fd5b5061025e610470565b6040805161ffff9092168252519081900360200190f35b34801561028157600080fd5b50610202610475565b34801561029657600080fd5b5061022d61047a565b3480156102ab57600080fd5b506102d2600480360360208110156102c257600080fd5b50356001600160a01b0316610480565b604080519115158252519081900360200190f35b3480156102f257600080fd5b5061022d61049e565b34801561030757600080fd5b506102026104a4565b34801561031c57600080fd5b5061022d6104a9565b34801561033157600080fd5b506102026104af565b34801561034657600080fd5b506102026104b4565b34801561035b57600080fd5b506101db6004803603604081101561037257600080fd5b506001600160a01b0381351690602001356104b9565b34801561039457600080fd5b5061022d610664565b3480156103a957600080fd5b5061022d61066a565b3480156103be57600080fd5b506102d2610670565b3480156103d357600080fd5b506101ad610679565b3480156103e857600080fd5b5061022d61067e565b3480156103fd57600080fd5b5061022d610684565b34801561041257600080fd5b5061022d61068a565b34801561042757600080fd5b506101db610690565b34801561043c57600080fd5b5061020261069c565b34801561045157600080fd5b5061022d6106a1565b606481565b60015481565b600181565b61100181565b603881565b600881565b61200081565b6001600160a01b031660009081526002602052604090205460ff1690565b61100581565b600281565b61100881565b600b81565b600981565b6000805460ff1661053657600260208190527fe57bda0a954a7c7381b17b2c763e646ba2c60f67292d287ba583603e2c1c41668054600160ff19918216811790925561100560009081527fe25235fc0de9d7165652bef0846fefda506174abb9a190f03d0f7bcc6146dbce80548316841790559282558254161790555b3360009081526002602052604090205460ff166105845760405162461bcd60e51b815260040180806020018281038252602b8152602001806106a8602b913960400191505060405180910390fd5b60004783106105935747610595565b825b9050670de0b6b3a76400008111156105b25750670de0b6b3a76400005b8015610633576040516001600160a01b0385169082156108fc029083906000818181858888f193505050501580156105ee573d6000803e3d6000fd5b506040805182815290516001600160a01b038616917ff8b71c64315fc33b2ead2adfa487955065152a8ac33d9d5193aafd7f45dc15a0919081900360200190a261065d565b6040517fe589651933c2457488cc0d8e0941518abf748e799435e4e396d9c4d0b2db2d4d90600090a15b9392505050565b61100781565b61100681565b60005460ff1681565b600081565b61100281565b61100381565b61100081565b670de0b6b3a764000081565b600381565b6110048156fe6f6e6c79206f70657261746f7220697320616c6c6f77656420746f2063616c6c20746865206d6574686f64a2646970667358221220c09e2c37549a0aef291c4f977743d3cea839c669624a8cfae895b3979a32800764736f6c63430006040033" - }, - "0x0000000000000000000000000000000000001003": { - "balance": "0x0", - "code": "0x608060405234801561001057600080fd5b50600436106102115760003560e01c8063a78abc1611610125578063dda83148116100ad578063e405bbc31161007c578063e405bbc314610681578063ea54b2aa14610689578063f9a2bbc714610691578063fc3e590814610699578063fd6a6879146106a157610211565b8063dda8314814610609578063df5fe7041461062f578063e1c7392a14610655578063e2761af01461065d57610211565b8063c81b1662116100f4578063c81b166214610534578063cba510a91461053c578063d816987914610562578063da8d08f0146105db578063dc927faf1461060157610211565b8063a78abc1614610444578063ab51bb9614610460578063ac43175114610468578063adc879e91461052c57610211565b8063564b81ef116101a857806375d47a0a1161017757806375d47a0a1461041c5780637942fd051461042457806396713da91461042c5780639dc0926214610434578063a1a11bf51461043c57610211565b8063564b81ef146102ca5780635c5ae8db146103475780636e47b4821461040c57806370fd5bad1461041457610211565b806343756e5c116101e457806343756e5c14610277578063493279b11461029b5780634bf6c882146102ba57806351e80672146102c257610211565b80630bee7a67146102165780632657e9b61461023757806333f7798d146102515780633dffc38714610259575b600080fd5b61021e6106a9565b6040805163ffffffff9092168252519081900360200190f35b61023f6106ae565b60408051918252519081900360200190f35b61023f6106b9565b6102616106bf565b6040805160ff9092168252519081900360200190f35b61027f6106c4565b604080516001600160a01b039092168252519081900360200190f35b6102a36106ca565b6040805161ffff9092168252519081900360200190f35b6102616106cf565b61027f6106d4565b6102d26106da565b6040805160208082528351818301528351919283929083019185019080838360005b8381101561030c5781810151838201526020016102f4565b50505050905090810190601f1680156103395780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b61036d6004803603602081101561035d57600080fd5b50356001600160401b03166107e6565b60405180856001600160401b03166001600160401b0316815260200184815260200183815260200180602001828103825283818151815260200191508051906020019080838360005b838110156103ce5781810151838201526020016103b6565b50505050905090810190601f1680156103fb5780820380516001836020036101000a031916815260200191505b509550505050505060405180910390f35b61027f6108a1565b6102616108a7565b61027f6108ac565b6102616108b2565b6102616108b7565b61027f6108bc565b61027f6108c2565b61044c6108c8565b604080519115158252519081900360200190f35b61021e6108d1565b61052a6004803603604081101561047e57600080fd5b81019060208101813564010000000081111561049957600080fd5b8201836020820111156104ab57600080fd5b803590602001918460018302840111640100000000831117156104cd57600080fd5b9193909290916020810190356401000000008111156104eb57600080fd5b8201836020820111156104fd57600080fd5b8035906020019184600183028401116401000000008311171561051f57600080fd5b5090925090506108d6565b005b61023f610b8f565b61027f610b95565b61023f6004803603602081101561055257600080fd5b50356001600160401b0316610b9b565b61044c6004803603604081101561057857600080fd5b81019060208101813564010000000081111561059357600080fd5b8201836020820111156105a557600080fd5b803590602001918460018302840111640100000000831117156105c757600080fd5b9193509150356001600160401b0316610bba565b61027f600480360360208110156105f157600080fd5b50356001600160401b031661139b565b61027f6113b6565b61027f6004803603602081101561061f57600080fd5b50356001600160401b03166113bc565b61044c6004803603602081101561064557600080fd5b50356001600160401b03166113e0565b61052a611422565b6106656115c9565b604080516001600160401b039092168252519081900360200190f35b6106656115d8565b6102d26115ee565b61027f61160d565b610261611613565b61027f611618565b606481565b662386f26fc1000081565b60055481565b600181565b61100181565b603881565b600881565b61200081565b604080516020808252818301909252606091829190602082018180368337505060045460208301525090506000805b60208160ff16101561075057828160ff168151811061072457fe5b01602001516001600160f81b0319161561074357600190910190610748565b610750565b600101610709565b5060608160ff166040519080825280601f01601f191660200182016040528015610781576020820181803683370190505b50905060005b8260ff168160ff1610156107dd57838160ff16815181106107a457fe5b602001015160f81c60f81b828260ff16815181106107be57fe5b60200101906001600160f81b031916908160001a905350600101610787565b50925050505b90565b60016020818152600092835260409283902080548184015460028084015460038501805489516101009982161599909902600019011692909204601f81018790048702880187019098528787526001600160401b0390931696919592949091908301828280156108975780601f1061086c57610100808354040283529160200191610897565b820191906000526020600020905b81548152906001019060200180831161087a57829003601f168201915b5050505050905084565b61100581565b600281565b61100881565b600b81565b600981565b61100781565b61100681565b60005460ff1681565b600081565b60005460ff1661092d576040805162461bcd60e51b815260206004820152601960248201527f74686520636f6e7472616374206e6f7420696e69742079657400000000000000604482015290519081900360640190fd5b336110071461096d5760405162461bcd60e51b815260040180806020018281038252602e8152602001806119ea602e913960400191505060405180910390fd5b6109e184848080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152505060408051808201909152601b81527f726577617264466f7256616c696461746f725365744368616e676500000000006020820152915061161e9050565b15610ac05760208114610a255760405162461bcd60e51b815260040180806020018281038252602e815260200180611989602e913960400191505060405180910390fd5b604080516020601f8401819004810282018101909252828152600091610a639185858083850183828082843760009201919091525061170592505050565b9050600081118015610a7d5750670de0b6b3a76400008111155b610ab85760405162461bcd60e51b815260040180806020018281038252602f815260200180611a18602f913960400191505060405180910390fd5b600555610afd565b6040805162461bcd60e51b815260206004820152600d60248201526c756e6b6e6f776e20706172616d60981b604482015290519081900360640190fd5b7f6cdb0ac70ab7f2e2d035cca5be60d89906f2dede7648ddbd7402189c1eeed17a848484846040518080602001806020018381038352878782818152602001925080828437600083820152601f01601f191690910184810383528581526020019050858580828437600083820152604051601f909101601f19169092018290039850909650505050505050a150505050565b60045481565b61100281565b6001600160401b03166000908152600160208190526040909120015490565b60408051630a83aaa960e31b815233600482015290516000916110069163541d554891602480820192602092909190829003018186803b158015610bfd57600080fd5b505afa158015610c11573d6000803e3d6000fd5b505050506040513d6020811015610c2757600080fd5b5051610c7a576040805162461bcd60e51b815260206004820152601f60248201527f746865206d73672073656e646572206973206e6f7420612072656c6179657200604482015290519081900360640190fd5b6001600160401b0382166000908152600260205260409020546001600160a01b031615610cee576040805162461bcd60e51b815260206004820152601c60248201527f63616e27742073796e63206475706c6963617465642068656164657200000000604482015290519081900360640190fd5b6003546001600160401b0390811690831611610d3b5760405162461bcd60e51b8152600401808060200182810382526026815260200180611a476026913960400191505060405180910390fd5b600354600160401b90046001600160401b0316610d56611867565b6001600160401b0382811660009081526001602081815260409283902083516080810185528154909516855280830154858301526002808201548686015260038201805486516101009682161596909602600019011691909104601f81018490048402850184019095528484529093606086019392830182828015610e1c5780601f10610df157610100808354040283529160200191610e1c565b820191906000526020600020905b815481529060010190602001808311610dff57829003601f168201915b50505050508152505090505b836001600160401b0316826001600160401b031610158015610e5957506003546001600160401b0390811690831610155b15610f3a5780516001600160401b0380821660009081526001602081815260409283902083516080810185528154909516855280830154858301526002808201548686015260038201805486516101009682161596909602600019011691909104601f8101849004840285018401909552848452959750939460608601939091830182828015610f2a5780601f10610eff57610100808354040283529160200191610f2a565b820191906000526020600020905b815481529060010190602001808311610f0d57829003601f168201915b5050505050815250509050610e28565b6060810151516110315780516001600160401b03811660009081526001602081815260409283902060030180548451600294821615610100026000190190911693909304601f810183900483028401830190945283835293955090929190830182828015610fe95780601f10610fbe57610100808354040283529160200191610fe9565b820191906000526020600020905b815481529060010190602001808311610fcc57829003601f168201915b505050506060830182905250516110315760405162461bcd60e51b81526004018080602001828103825260218152602001806119686021913960400191505060405180910390fd5b6000816060015151608801905060608787905082016040519080825280601f01601f191660200182016040528015611070576020820181803683370190505b509050600061107e8261170a565b905061108c84868386611710565b6110c75760405162461bcd60e51b81526004018080602001828103825260238152602001806119456023913960400191505060405180910390fd5b6000838201915061110d8a8a8080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061177c92505050565b9450905061111c818386611786565b8251602001935061112b61188d565b6110008186866064600019fa61114057600080fd5b805194506000600160f81b8616156111cf5750600554604080516309a99b4f60e41b815233600482015260248101929092525160019161100291639a99b4f0916044808201926020929091908290030181600087803b1580156111a257600080fd5b505af11580156111b6573d6000803e3d6000fd5b505050506040513d60208110156111cc57600080fd5b50505b856001600160401b0316955060208201935060006111ef858884156117c7565b90985090506001600160401b03808216908c161461123e5760405162461bcd60e51b81526004018080602001828103825260338152602001806119b76033913960400191505060405180910390fd5b6001600160401b03808c16600081815260026020818152604080842080546001600160a01b031916331790558e86168e529383526001808252928490208d518154961667ffffffffffffffff199096169590951785558c81015192850192909255918b01519183019190915560608a015180518b93926112c59260038501929101906118ac565b50506003546001600160401b03600160401b9091048116908d161115905061130d576003805467ffffffffffffffff60401b1916600160401b6001600160401b038e16021790555b7f4042c1020a8f410fb1c8859d276ab436aeb2c3074960e48467299cf1c966d3b48b8a8a602001518560405180856001600160401b03166001600160401b03168152602001846001600160401b03166001600160401b031681526020018381526020018215151515815260200194505050505060405180910390a15060019c9b505050505050505050505050565b6002602052600090815260409020546001600160a01b031681565b61100381565b6001600160401b03166000908152600260205260409020546001600160a01b031690565b6001600160401b0381166000908152600260205260408120546001600160a01b031615158061141c57506003546001600160401b038381169116145b92915050565b60005460ff161561147a576040805162461bcd60e51b815260206004820152601960248201527f74686520636f6e747261637420616c726561647920696e697400000000000000604482015290519081900360640190fd5b6000806114a16040518061024001604052806102208152602001611a6d610220913961177c565b815160045590925090506114b3611867565b60006114c1848460006117c7565b60008083526001600160401b038281168252600160208181526040938490208651815467ffffffffffffffff191694169390931783558086015191830191909155918401516002820155606084015180519496509294508593909261152d9260038501929101906118ac565b50506003805467ffffffffffffffff19166001600160401b0384811691821767ffffffffffffffff60401b1916600160401b9290920291909117918290556000805460ff19166001179055662386f26fc10000600555602085810151604080519490931684529083015280517f5ac9b37d571677b80957ca05693f371526c602fd08042b416a29fdab7efefa499350918290030190a150505050565b6003546001600160401b031681565b600354600160401b90046001600160401b031681565b6040518061024001604052806102208152602001611a6d610220913981565b61100081565b600381565b61100481565b6000816040516020018082805190602001908083835b602083106116535780518252601f199092019160209182019101611634565b6001836020036101000a03801982511681845116808217855250505050505090500191505060405160208183030381529060405280519060200120836040516020018082805190602001908083835b602083106116c15780518252601f1990920191602091820191016116a2565b6001836020036101000a0380198251168184511680821785525050505050509050019150506040516020818303038152906040528051906020012014905092915050565b015190565b60200190565b600084606001515182840103925060008061172e876060015161177c565b909250905061173e828683611786565b5050506040840151601f1983810191909152602090940151603f19830152605f19820192909252600454606719820152910160871990910152600190565b8051602090910191565b5b602081106117a6578251825260209283019290910190601f1901611787565b915181516020939093036101000a6000190180199091169216919091179052565b6117cf611867565b60088401516028850151604890950180519095600092916117ee611867565b6020810183905260408101829052866118595760008060688a036040519080825280601f01601f191660200182016040528015611832576020820181803683370190505b50606084018190526118439061177c565b909250905061185660208c018383611786565b50505b989297509195505050505050565b604080516080810182526000808252602082018190529181019190915260608082015290565b6040518061100001604052806080906020820280368337509192915050565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f106118ed57805160ff191683800117855561191a565b8280016001018555821561191a579182015b8281111561191a5782518255916020019190600101906118ff565b5061192692915061192a565b5090565b6107e391905b80821115611926576000815560010161193056fe6661696c656420746f2073657269616c697a6520636f6e73656e7375732073746174656661696c656420746f206c6f61642076616c696461746f722073657420646174616c656e677468206f6620726577617264466f7256616c696461746f725365744368616e6765206d69736d617463686865616465722068656967687420646f65736e277420657175616c20746f207468652073706563696669656420686569676874746865206d6573736167652073656e646572206d75737420626520676f7665726e616e636520636f6e7472616374746865206e6577526577617264466f7256616c696461746f725365744368616e6765206f7574206f662072616e676563616e27742073796e6320686561646572206265666f726520696e697469616c48656967687442696e616e63652d436861696e2d5469677269730000000000000000000000000000000006915167cedaf7bbf7df47d932fdda630527ee648562cf3e52c5e5f46156a3a971a4ceb443c53a50d8653ef8cf1e5716da68120fb51b636dc6d111ec3277b098ecd42d49d3769d8a1f78b4c17a965f7a30d4181fabbd1f969f46d3c8e83b5ad4845421d8000000e8d4a510002ba4e81542f437b7ae1f8a35ddb233c789a8dc22734377d9b6d63af1ca403b61000000e8d4a51000df8da8c5abfdb38595391308bb71e5a1e0aabdc1d0cf38315d50d6be939b2606000000e8d4a51000b6619edca4143484800281d698b70c935e9152ad57b31d85c05f2f79f64b39f3000000e8d4a510009446d14ad86c8d2d74780b0847110001a1c2e252eedfea4753ebbbfce3a22f52000000e8d4a510000353c639f80cc8015944436dab1032245d44f912edc31ef668ff9f4a45cd0599000000e8d4a51000e81d3797e0544c3a718e1f05f0fb782212e248e784c1a851be87e77ae0db230e000000e8d4a510005e3fcda30bd19d45c4b73688da35e7da1fce7c6859b2c1f20ed5202d24144e3e000000e8d4a51000b06a59a2d75bf5d014fce7c999b5e71e7a960870f725847d4ba3235baeaa08ef000000e8d4a510000c910e2fe650e4e01406b3310b489fb60a84bc3ff5c5bee3a56d5898b6a8af32000000e8d4a5100071f2d7b8ec1c8b99a653429b0118cd201f794f409d0fea4d65b1b662f2b00063000000e8d4a51000a264697066735822122032fc162aed7c2a4fe0f40397d327efc38d8aaf5dbdd1720f7f5d8101877da61d64736f6c63430006040033" - }, - "0x0000000000000000000000000000000000001004": { - "balance": "176405560900000000000000000", - "code": "0x60806040526004361061031e5760003560e01c80639a99b4f0116101ab578063bd466461116100f7578063f014847211610095578063fc1a598f1161006f578063fc1a598f14610cb3578063fc3e590814610686578063fd6a687914610ce6578063ff9c0027146107dc57610366565b8063f014847214610c74578063f9a2bbc714610c89578063fa9e915914610c9e57610366565b8063d9e6dae9116100d1578063d9e6dae914610608578063dc927faf14610c35578063e1c7392a14610c4a578063ebf71d5314610c5f57610366565b8063bd46646114610b68578063c81b166214610b9b578063c8509d8114610bb057610366565b8063aa7415f511610164578063b99328c51161013e578063b99328c514610ad2578063b9fd21e314610b0b578063ba35ead614610b20578063bbface1f14610b3557610366565b8063aa7415f5146109ab578063ab51bb96146109f2578063ac43175114610a0757610366565b80639a99b4f01461091e5780639dc0926214610957578063a1a11bf51461096c578063a496fba214610981578063a78abc1614610996578063a7c9f02d1461068657610366565b8063613684751161026a57806375d47a0a116102235780638b87b21f116101fd5780638b87b21f146105875780638eff336c146108b557806396713da9146108f45780639a854bbd1461090957610366565b806375d47a0a146108065780637942fd051461081b578063831d65d11461083057610366565b8063613684751461060857806366dea52a146106865780636e0565201461069b5780636e47b482146107c757806370fd5bad146107dc57806371d30863146107f157610366565b806343a368b9116102d757806350432d32116102b157806350432d321461061d57806351e806721461063257806359b92789146106475780635d499b1b1461067157610366565b806343a368b9146105c7578063493279b1146105dc5780634bf6c8821461060857610366565b80630bee7a671461036b5780631182b87514610399578063149d14d9146104935780633d713223146104ba5780633dffc3871461058757806343756e5c146105b257610366565b36610366573415610364576040805133815234602082015281517f6c98249d85d88c3753a04a22230f595e4dc8d3dc86c34af35deeeedc861b89db929181900390910190a15b005b600080fd5b34801561037757600080fd5b50610380610cfb565b6040805163ffffffff9092168252519081900360200190f35b3480156103a557600080fd5b5061041e600480360360408110156103bc57600080fd5b60ff8235169190810190604081016020820135600160201b8111156103e057600080fd5b8201836020820111156103f257600080fd5b803590602001918460018302840111600160201b8311171561041357600080fd5b509092509050610d00565b6040805160208082528351818301528351919283929083019185019080838360005b83811015610458578181015183820152602001610440565b50505050905090810190601f1680156104855780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b34801561049f57600080fd5b506104a8610e2e565b60408051918252519081900360200190f35b3480156104c657600080fd5b5061056b600480360360208110156104dd57600080fd5b810190602081018135600160201b8111156104f757600080fd5b82018360208201111561050957600080fd5b803590602001918460018302840111600160201b8311171561052a57600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250929550610e34945050505050565b604080516001600160a01b039092168252519081900360200190f35b34801561059357600080fd5b5061059c610e58565b6040805160ff9092168252519081900360200190f35b3480156105be57600080fd5b5061056b610e5d565b3480156105d357600080fd5b506104a8610e63565b3480156105e857600080fd5b506105f1610e6f565b6040805161ffff9092168252519081900360200190f35b34801561061457600080fd5b5061059c610e74565b34801561062957600080fd5b506104a8610e79565b34801561063e57600080fd5b5061056b610e84565b34801561065357600080fd5b5061056b6004803603602081101561066a57600080fd5b5035610e8a565b34801561067d57600080fd5b506104a8610ea5565b34801561069257600080fd5b5061059c610eae565b6107b3600480360360808110156106b157600080fd5b810190602081018135600160201b8111156106cb57600080fd5b8201836020820111156106dd57600080fd5b803590602001918460208302840111600160201b831117156106fe57600080fd5b919390929091602081019035600160201b81111561071b57600080fd5b82018360208201111561072d57600080fd5b803590602001918460208302840111600160201b8311171561074e57600080fd5b919390929091602081019035600160201b81111561076b57600080fd5b82018360208201111561077d57600080fd5b803590602001918460208302840111600160201b8311171561079e57600080fd5b91935091503567ffffffffffffffff16610eb3565b604080519115158252519081900360200190f35b3480156107d357600080fd5b5061056b611388565b3480156107e857600080fd5b5061059c61138e565b3480156107fd57600080fd5b506104a8611393565b34801561081257600080fd5b5061056b611399565b34801561082757600080fd5b5061059c61139f565b34801561083c57600080fd5b506103646004803603604081101561085357600080fd5b60ff8235169190810190604081016020820135600160201b81111561087757600080fd5b82018360208201111561088957600080fd5b803590602001918460018302840111600160201b831117156108aa57600080fd5b5090925090506113a4565b3480156108c157600080fd5b50610364600480360360608110156108d857600080fd5b508035906001600160a01b0360208201351690604001356114ed565b34801561090057600080fd5b5061059c611573565b34801561091557600080fd5b506104a8611578565b34801561092a57600080fd5b506104a86004803603604081101561094157600080fd5b506001600160a01b038135169060200135611584565b34801561096357600080fd5b5061056b6116c2565b34801561097857600080fd5b5061056b6116c8565b34801561098d57600080fd5b5061059c6116ce565b3480156109a257600080fd5b506107b36116d3565b6107b3600480360360808110156109c157600080fd5b5080356001600160a01b03908116916020810135909116906040810135906060013567ffffffffffffffff166116dc565b3480156109fe57600080fd5b506103806116ce565b348015610a1357600080fd5b5061036460048036036040811015610a2a57600080fd5b810190602081018135600160201b811115610a4457600080fd5b820183602082011115610a5657600080fd5b803590602001918460018302840111600160201b83111715610a7757600080fd5b919390929091602081019035600160201b811115610a9457600080fd5b820183602082011115610aa657600080fd5b803590602001918460018302840111600160201b83111715610ac757600080fd5b509092509050611d9d565b348015610ade57600080fd5b5061036460048036036040811015610af557600080fd5b50803590602001356001600160a01b031661200c565b348015610b1757600080fd5b506104a8612082565b348015610b2c57600080fd5b506104a861208c565b348015610b4157600080fd5b506104a860048036036020811015610b5857600080fd5b50356001600160a01b0316612092565b348015610b7457600080fd5b506104a860048036036020811015610b8b57600080fd5b50356001600160a01b03166120a4565b348015610ba757600080fd5b5061056b6120bf565b348015610bbc57600080fd5b5061036460048036036040811015610bd357600080fd5b60ff8235169190810190604081016020820135600160201b811115610bf757600080fd5b820183602082011115610c0957600080fd5b803590602001918460018302840111600160201b83111715610c2a57600080fd5b5090925090506120c5565b348015610c4157600080fd5b5061056b612195565b348015610c5657600080fd5b5061036461219b565b348015610c6b57600080fd5b5061059c61223b565b348015610c8057600080fd5b5061059c612240565b348015610c9557600080fd5b5061056b612245565b348015610caa57600080fd5b506104a861224b565b348015610cbf57600080fd5b5061041e60048036036020811015610cd657600080fd5b50356001600160a01b0316612251565b348015610cf257600080fd5b5061056b612378565b606481565b60005460609060ff16610d48576040805162461bcd60e51b815260206004820152601960248201526000805160206147bf833981519152604482015290519081900360640190fd5b3361200014610d885760405162461bcd60e51b815260040180806020018281038252602f81526020018061476d602f913960400191505060405180910390fd5b60ff841660021415610dda57610dd383838080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061237e92505050565b9050610e27565b6040805162461bcd60e51b815260206004820152601860248201527f756e7265636f676e697a65642073796e207061636b6167650000000000000000604482015290519081900360640190fd5b9392505050565b60015490565b6020818101516000908152600490915260409020546001600160a01b03165b919050565b600181565b61100181565b670de0b6b3a764000081565b603881565b600881565b66071afd498d000081565b61200081565b6000908152600460205260409020546001600160a01b031690565b6402540be40081565b600381565b6000805460ff16610ef9576040805162461bcd60e51b815260206004820152601960248201526000805160206147bf833981519152604482015290519081900360640190fd5b868514610f375760405162461bcd60e51b815260040180806020018281038252603b815260200180614732603b913960400191505060405180910390fd5b868314610f755760405162461bcd60e51b815260040180806020018281038252603f815260200180614605603f913960400191505060405180910390fd5b426078018267ffffffffffffffff161015610fc15760405162461bcd60e51b81526004018080602001828103825260248152602001806144f56024913960400191505060405180910390fd5b6402540be4003406156110055760405162461bcd60e51b81526004018080602001828103825260408152602001806148356040913960400191505060405180910390fd5b60408051868152602080880282010190915285906000908190606090848015611038578160200160208202803683370190505b50905060005b84811015611113576402540be4008b8b8381811061105857fe5b905060200201358161106657fe5b06156110a35760405162461bcd60e51b815260040180806020018281038252603c815260200180614644603c913960400191505060405180910390fd5b6110c88b8b838181106110b257fe5b90506020020135856124a290919063ffffffff16565b93506110f46402540be4008c8c848181106110df57fe5b905060200201356124fc90919063ffffffff16565b82828151811061110057fe5b602090810291909101015260010161103e565b506001546111389061112b908663ffffffff61253e16565b849063ffffffff6124a216565b3410156111765760405162461bcd60e51b81526004018080602001828103825260568152602001806147df6056913960600191505060405180910390fd5b611186348463ffffffff61259716565b915061119061434e565b6040518060c001604052806221272160e91b60001b815260200160006001600160a01b031681526020018381526020018e8e808060200260200160405190810160405280939291908181526020018383602002808284376000920191909152505050908252506040805160208c810282810182019093528c82529283019290918d918d91829185019084908082843760009201919091525050509082525067ffffffffffffffff8916602090910152905061200063f7a251d76003611254846125d9565b611269876402540be40063ffffffff6124fc16565b6040518463ffffffff1660e01b8152600401808460ff1660ff16815260200180602001838152602001828103825284818151815260200191508051906020019080838360005b838110156112c75781810151838201526020016112af565b50505050905090810190601f1680156112f45780820380516001836020036101000a031916815260200191505b50945050505050600060405180830381600087803b15801561131557600080fd5b505af1158015611329573d6000803e3d6000fd5b505060408051600081523360208201528082018890526060810187905290517f74eab09b0e53aefc23f2e1b16da593f95c2dd49c6f5a23720463d10d9c330b2a9350908190036080019150a15060019c9b505050505050505050505050565b61100581565b600281565b60015481565b61100881565b600b81565b60005460ff166113e9576040805162461bcd60e51b815260206004820152601960248201526000805160206147bf833981519152604482015290519081900360640190fd5b33612000146114295760405162461bcd60e51b815260040180806020018281038252602f81526020018061476d602f913960400191505060405180910390fd5b60ff8316600314156114795761147482828080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061289492505050565b6114e8565b7f41ce201247b6ceb957dcdb217d0b8acb50b9ea0e12af9af4f5e7f38902101605838383604051808460ff1660ff168152602001806020018281038252848482818152602001925080828437600083820152604051601f909101601f1916909201829003965090945050505050a15b505050565b336110081461152d5760405162461bcd60e51b815260040180806020018281038252602381526020018061479c6023913960400191505060405180910390fd5b600083815260046020908152604080832080546001600160a01b039096166001600160a01b03199096168617905593825260038152838220949094556002909352912055565b600981565b677ce66c50e284000081565b6000805460ff166115ca576040805162461bcd60e51b815260206004820152601960248201526000805160206147bf833981519152604482015290519081900360640190fd5b336110051461160a5760405162461bcd60e51b815260040180806020018281038252602f815260200180614468602f913960400191505060405180910390fd5b6000478310611619574761161b565b825b9050670de0b6b3a76400008111156116375760009150506116bc565b80156116b9576040516001600160a01b0385169082156108fc029083906000818181858888f19350505050158015611673573d6000803e3d6000fd5b50604080516001600160a01b03861681526020810183905281517ff8b71c64315fc33b2ead2adfa487955065152a8ac33d9d5193aafd7f45dc15a0929181900390910190a15b90505b92915050565b61100781565b61100681565b600081565b60005460ff1681565b6000805460ff16611722576040805162461bcd60e51b815260206004820152601960248201526000805160206147bf833981519152604482015290519081900360640190fd5b426078018267ffffffffffffffff16101561176e5760405162461bcd60e51b81526004018080602001828103825260248152602001806144f56024913960400191505060405180910390fd5b6402540be4003406156117b25760405162461bcd60e51b81526004018080602001828103825260408152602001806148356040913960400191505060405180910390fd5b600080806001600160a01b038816611891576001546117d890879063ffffffff6124a216565b3410156118165760405162461bcd60e51b815260040180806020018281038252606181526020018061457f6061913960800191505060405180910390fd5b6402540be40086061561185a5760405162461bcd60e51b815260040180806020018281038252603c815260200180614644603c913960400191505060405180910390fd5b61186a348763ffffffff61259716565b9050611881866402540be40063ffffffff6124fc16565b6221272160e91b93509150611b34565b6001600160a01b0388166000908152600360205260409020549250826118e85760405162461bcd60e51b815260040180806020018281038252603181526020018061454e6031913960400191505060405180910390fd5b6001543410156119295760405162461bcd60e51b815260040180806020018281038252603f8152602001806146a1603f913960400191505060405180910390fd5b506001600160a01b038716600090815260026020526040902054349060088111158061197457506008811180156119745750611972876007198301600a0a63ffffffff6128f016565b155b6119af5760405162461bcd60e51b815260040180806020018281038252603c815260200180614644603c913960400191505060405180910390fd5b6119b98782612932565b92506119c484612972565b15611a0c576305f5e100831015611a0c5760405162461bcd60e51b815260040180806020018281038252603a815260200180614497603a913960400191505060405180910390fd5b600881101580611a265750600881108015611a2657508683115b611a615760405162461bcd60e51b81526004018080602001828103825260258152602001806145e06025913960400191505060405180910390fd5b677ce66c50e2840000831115611aa85760405162461bcd60e51b81526004018080602001828103825260358152602001806145196035913960400191505060405180910390fd5b604080516323b872dd60e01b81523360048201523060248201526044810189905290516001600160a01b038b16916323b872dd9160648083019260209291908290030181600087803b158015611afd57600080fd5b505af1158015611b11573d6000803e3d6000fd5b505050506040513d6020811015611b2757600080fd5b5051611b3257600080fd5b505b611b3c61434e565b6040805160c0810182528581526001600160a01b038b166020820152815160018082528184018452919283019181602001602082028036833750505081526040805160018082528183019092526020928301929091908083019080368337505050815260408051600180825281830190925260209283019290919080830190803683370190505081526020018767ffffffffffffffff168152509050828160400151600081518110611bea57fe5b602002602001018181525050878160600151600081518110611c0857fe5b60200260200101906001600160a01b031690816001600160a01b031681525050338160800151600081518110611c3a57fe5b6001600160a01b039092166020928302919091019091015261200063f7a251d76003611c65846125d9565b611c7a866402540be40063ffffffff6124fc16565b6040518463ffffffff1660e01b8152600401808460ff1660ff16815260200180602001838152602001828103825284818151815260200191508051906020019080838360005b83811015611cd8578181015183820152602001611cc0565b50505050905090810190601f168015611d055780820380516001836020036101000a031916815260200191505b50945050505050600060405180830381600087803b158015611d2657600080fd5b505af1158015611d3a573d6000803e3d6000fd5b5050604080516001600160a01b038d1681523360208201528082018b90526060810186905290517f74eab09b0e53aefc23f2e1b16da593f95c2dd49c6f5a23720463d10d9c330b2a9350908190036080019150a150600198975050505050505050565b3361100714611ddd5760405162461bcd60e51b815260040180806020018281038252602e8152602001806146e0602e913960400191505060405180910390fd5b60208114611e32576040805162461bcd60e51b815260206004820152601b60248201527f65787065637465642076616c7565206c656e6774682069732033320000000000604482015290519081900360640190fd5b606084848080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525050604080516020601f8801819004810282018101909252868152939450606093925086915085908190840183828082843760009201919091525050505060208301519091506772656c617946656560c01b811415611f3a576020820151670de0b6b3a76400008111801590611ee157506402540be4008106155b611f32576040805162461bcd60e51b815260206004820152601960248201527f7468652072656c6179466565206f7574206f662072616e676500000000000000604482015290519081900360640190fd5b600155611f77565b6040805162461bcd60e51b815260206004820152600d60248201526c756e6b6e6f776e20706172616d60981b604482015290519081900360640190fd5b7f6cdb0ac70ab7f2e2d035cca5be60d89906f2dede7648ddbd7402189c1eeed17a878787876040518080602001806020018381038352878782818152602001925080828437600083820152601f01601f191690910184810383528581526020019050858580828437600083820152604051601f909101601f19169092018290039850909650505050505050a150505050505050565b336110081461204c5760405162461bcd60e51b815260040180806020018281038252602381526020018061479c6023913960400191505060405180910390fd5b600091825260046020908152604080842080546001600160a01b03191690556001600160a01b0392909216835260039052812055565b6221272160e91b81565b61c35081565b60026020526000908152604090205481565b6001600160a01b031660009081526003602052604090205490565b61100281565b60005460ff1661210a576040805162461bcd60e51b815260206004820152601960248201526000805160206147bf833981519152604482015290519081900360640190fd5b336120001461214a5760405162461bcd60e51b815260040180806020018281038252602f81526020018061476d602f913960400191505060405180910390fd5b60ff8316600314156114795761147482828080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250612a7892505050565b61100381565b60005460ff16156121f3576040805162461bcd60e51b815260206004820152601960248201527f74686520636f6e747261637420616c726561647920696e697400000000000000604482015290519081900360640190fd5b66071afd498d000060019081556000808052600260205260127fac33ff75c19e70fe83507db0d683fd3465c996598dc972688b7ace676c89077b55805460ff19169091179055565b600481565b600581565b61100081565b61271081565b6001600160a01b03811660009081526003602090815260409182902054825182815280840190935260609290918391906020820181803683375050506020810183905290506000805b60208160ff1610156122e157828160ff16815181106122b557fe5b01602001516001600160f81b031916156122d4576001909101906122d9565b6122e1565b60010161229a565b5060608160ff166040519080825280601f01601f191660200182016040528015612312576020820181803683370190505b50905060005b8260ff168160ff16101561236e57838160ff168151811061233557fe5b602001015160f81c60f81b828260ff168151811061234f57fe5b60200101906001600160f81b031916908160001a905350600101612318565b5095945050505050565b61100481565b606061238861439a565b600061239384612b76565b91509150806123e9576040805162461bcd60e51b815260206004820152601f60248201527f756e7265636f676e697a6564207472616e73666572496e207061636b61676500604482015290519081900360640190fd5b60006123f483612cb5565b905063ffffffff811615612488576040808401516020808601516001600160a01b0316600090815260029091529182205461242f9190612932565b90506124396143cf565b60405180608001604052808660000151815260200183815260200186608001516001600160a01b031681526020018463ffffffff16815250905061247c81613002565b95505050505050610e53565b50506040805160008152602081019091529150610e539050565b6000828201838110156116b9576040805162461bcd60e51b815260206004820152601b60248201527f536166654d6174683a206164646974696f6e206f766572666c6f770000000000604482015290519081900360640190fd5b60006116b983836040518060400160405280601a81526020017f536166654d6174683a206469766973696f6e206279207a65726f0000000000008152506130de565b60008261254d575060006116bc565b8282028284828161255a57fe5b04146116b95760405162461bcd60e51b81526004018080602001828103825260218152602001806146806021913960400191505060405180910390fd5b60006116b983836040518060400160405280601e81526020017f536166654d6174683a207375627472616374696f6e206f766572666c6f770000815250613180565b60408051600680825260e08201909252606091829190816020015b60608152602001906001900390816125f45750508351909150612616906131da565b8160008151811061262357fe5b602002602001018190525061264483602001516001600160a01b03166131ed565b8160018151811061265157fe5b60200260200101819052506000836040015151905060608160405190808252806020026020018201604052801561269c57816020015b60608152602001906001900390816126875790505b50905060005b828110156126e9576126ca866040015182815181106126bd57fe5b60200260200101516131da565b8282815181106126d657fe5b60209081029190910101526001016126a2565b506126f381613210565b8360028151811061270057fe5b602002602001018190525060608260405190808252806020026020018201604052801561274157816020015b606081526020019060019003908161272c5790505b50905060005b83811015612797576127788760600151828151811061276257fe5b60200260200101516001600160a01b03166131ed565b82828151811061278457fe5b6020908102919091010152600101612747565b506127a181613210565b846003815181106127ae57fe5b60200260200101819052506060836040519080825280602002602001820160405280156127ef57816020015b60608152602001906001900390816127da5790505b50905060005b8481101561282f576128108860800151828151811061276257fe5b82828151811061281c57fe5b60209081029190910101526001016127f5565b5061283981613210565b8560048151811061284657fe5b60200260200101819052506128688760a0015167ffffffffffffffff166131da565b8560058151811061287557fe5b602002602001018190525061288985613210565b979650505050505050565b61289c6143f6565b60006128a78361329a565b91509150806128e75760405162461bcd60e51b815260040180806020018281038252602481526020018061470e6024913960400191505060405180910390fd5b6114e882613465565b60006116b983836040518060400160405280601881526020017f536166654d6174683a206d6f64756c6f206279207a65726f00000000000000008152506138e9565b6000600882111561295b57612954836007198401600a0a63ffffffff6124fc16565b90506116bc565b6116b9836008849003600a0a63ffffffff61253e16565b604080516020808252818301909252600091606091906020820181803683375050506020810184905290506000805b60208160ff1610156129e857828160ff16815181106129bc57fe5b01602001516001600160f81b031916156129db576001909101906129e0565b6129e8565b6001016129a1565b50600860ff82161015612a0057600092505050610e53565b816005820360ff1681518110612a1257fe5b6020910101516001600160f81b031916602d60f81b14612a3757600092505050610e53565b816001820360ff1681518110612a4957fe5b6020910101516001600160f81b031916604d60f81b14612a6e57600092505050610e53565b5060019392505050565b612a8061434e565b6000612a8b8361394b565b9150915080612acb5760405162461bcd60e51b81526004018080602001828103825260248152602001806144d16024913960400191505060405180910390fd5b612ad36143f6565b602080840180516001600160a01b0390811684526040808701518585015291511660009081526002909252812054905b846040015151811015612b5457612b3185604001518281518110612b2357fe5b602002602001015183613bc6565b85604001518281518110612b4157fe5b6020908102919091010152600101612b03565b506080840151604083015260056060830152612b6f82613465565b5050505050565b612b7e61439a565b6000612b8861439a565b612b9061442d565b612ba1612b9c86613bff565b613c24565b90506000805b612bb083613c6e565b15612ca85780612bd257612bcb612bc684613c8f565b613cdd565b8452612ca0565b8060011415612bff57612bec612be784613c8f565b613d94565b6001600160a01b03166020850152612ca0565b8060021415612c1e57612c14612bc684613c8f565b6040850152612ca0565b8060031415612c4657612c33612be784613c8f565b6001600160a01b03166060850152612ca0565b8060041415612c6e57612c5b612be784613c8f565b6001600160a01b03166080850152612ca0565b8060051415612c9b57612c83612bc684613c8f565b67ffffffffffffffff1660a085015260019150612ca0565b612ca8565b600101612ba7565b5091935090915050915091565b60208101516000906001600160a01b0316612dec578160a0015167ffffffffffffffff16421115612ce857506001610e53565b8160400151471015612cfc57506003610e53565b606082015160408084015190516000926001600160a01b0316916127109184818181858888f193505050503d8060008114612d53576040519150601f19603f3d011682016040523d82523d6000602084013e612d58565b606091505b5050905080612d6b575060049050610e53565b7f471eb9cc1ffe55ffadf15b32595415eb9d80f22e761d24bd6dffc607e1284d5983602001518460600151856040015160405180846001600160a01b03166001600160a01b03168152602001836001600160a01b03166001600160a01b03168152602001828152602001935050505060405180910390a15060009050610e53565b8160a0015167ffffffffffffffff16421115612e0a57506001610e53565b81516020808401516001600160a01b031660009081526003909152604090205414612e3757506002610e53565b602080830151604080516370a0823160e01b815230600482015290516000936001600160a01b03909316926370a082319261c3509260248083019392829003018187803b158015612e8757600080fd5b5086fa158015612e9b573d6000803e3d6000fd5b50505050506040513d6020811015612eb257600080fd5b50516040840151909150811015612ecd575060039050610e53565b600083602001516001600160a01b031663a9059cbb61c350866060015187604001516040518463ffffffff1660e01b815260040180836001600160a01b03166001600160a01b0316815260200182815260200192505050602060405180830381600088803b158015612f3e57600080fd5b5087f1158015612f52573d6000803e3d6000fd5b50505050506040513d6020811015612f6957600080fd5b505190508015612ff6577f471eb9cc1ffe55ffadf15b32595415eb9d80f22e761d24bd6dffc607e1284d5984602001518560600151866040015160405180846001600160a01b03166001600160a01b03168152602001836001600160a01b03166001600160a01b03168152602001828152602001935050505060405180910390a15060009150610e539050565b5060059150610e539050565b60408051600480825260a08201909252606091829190816020015b606081526020019060019003908161301d575050835190915061303f906131da565b8160008151811061304c57fe5b602002602001018190525061306483602001516131da565b8160018151811061307157fe5b602002602001018190525061309283604001516001600160a01b03166131ed565b8160028151811061309f57fe5b60200260200101819052506130bd836060015163ffffffff166131da565b816003815181106130ca57fe5b6020026020010181905250610e2781613210565b6000818361316a5760405162461bcd60e51b81526004018080602001828103825283818151815260200191508051906020019080838360005b8381101561312f578181015183820152602001613117565b50505050905090810190601f16801561315c5780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b50600083858161317657fe5b0495945050505050565b600081848411156131d25760405162461bcd60e51b815260206004820181815283516024840152835190928392604490910191908501908083836000831561312f578181015183820152602001613117565b505050900390565b60606116bc6131e883613dae565b613e94565b60408051600560a21b8318601482015260348101909152606090610e2781613e94565b60608151600014156132315750604080516000815260208101909152610e53565b60608260008151811061324057fe5b602002602001015190506000600190505b8351811015613281576132778285838151811061326a57fe5b6020026020010151613ee6565b9150600101613251565b50610e27613294825160c060ff16613f63565b82613ee6565b6132a26143f6565b60006132ac6143f6565b6132b461442d565b6132c0612b9c86613bff565b90506000805b6132cf83613c6e565b15612ca857806132f5576132e5612be784613c8f565b6001600160a01b0316845261345d565b806001141561339657606061331161330c85613c8f565b61405b565b9050805160405190808252806020026020018201604052801561333e578160200160208202803683370190505b50602086015260005b815181101561338f5761336c82828151811061335f57fe5b6020026020010151613cdd565b8660200151828151811061337c57fe5b6020908102919091010152600101613347565b505061345d565b80600214156134385760606133ad61330c85613c8f565b905080516040519080825280602002602001820160405280156133da578160200160208202803683370190505b50604086015260005b815181101561338f576134088282815181106133fb57fe5b6020026020010151613d94565b8660400151828151811061341857fe5b6001600160a01b03909216602092830291909101909101526001016133e3565b8060031415612c9b5761344d612bc684613c8f565b63ffffffff166060850152600191505b6001016132c6565b80516001600160a01b031661368f5760005b8160200151518110156136895760008260400151828151811061349657fe5b60200260200101516001600160a01b0316612710846020015184815181106134ba57fe5b60209081029190910101516040516000818181858888f193505050503d8060008114613502576040519150601f19603f3d011682016040523d82523d6000602084013e613507565b606091505b50509050806135ca577f203f9f67a785f4f81be4d48b109aa0c498d1bc8097ecc2627063f480cc5fe73e83600001518460400151848151811061354657fe5b60200260200101518560200151858151811061355e57fe5b6020026020010151866060015160405180856001600160a01b03166001600160a01b03168152602001846001600160a01b03166001600160a01b031681526020018381526020018263ffffffff1663ffffffff16815260200194505050505060405180910390a1613680565b7fd468d4fa5e8fb4adc119b29a983fd0785e04af5cb8b7a3a69a47270c54b6901a83600001518460400151848151811061360057fe5b60200260200101518560200151858151811061361857fe5b6020026020010151866060015160405180856001600160a01b03166001600160a01b03168152602001846001600160a01b03166001600160a01b031681526020018381526020018263ffffffff1663ffffffff16815260200194505050505060405180910390a15b50600101613477565b506138e6565b60005b8160200151518110156138e457600082600001516001600160a01b031663a9059cbb61c350856040015185815181106136c757fe5b6020026020010151866020015186815181106136df57fe5b60200260200101516040518463ffffffff1660e01b815260040180836001600160a01b03166001600160a01b0316815260200182815260200192505050602060405180830381600088803b15801561373657600080fd5b5087f115801561374a573d6000803e3d6000fd5b50505050506040513d602081101561376157600080fd5b505190508015613825577fd468d4fa5e8fb4adc119b29a983fd0785e04af5cb8b7a3a69a47270c54b6901a8360000151846040015184815181106137a157fe5b6020026020010151856020015185815181106137b957fe5b6020026020010151866060015160405180856001600160a01b03166001600160a01b03168152602001846001600160a01b03166001600160a01b031681526020018381526020018263ffffffff1663ffffffff16815260200194505050505060405180910390a16138db565b7f203f9f67a785f4f81be4d48b109aa0c498d1bc8097ecc2627063f480cc5fe73e83600001518460400151848151811061385b57fe5b60200260200101518560200151858151811061387357fe5b6020026020010151866060015160405180856001600160a01b03166001600160a01b03168152602001846001600160a01b03166001600160a01b031681526020018381526020018263ffffffff1663ffffffff16815260200194505050505060405180910390a15b50600101613692565b505b50565b600081836139385760405162461bcd60e51b815260206004820181815283516024840152835190928392604490910191908501908083836000831561312f578181015183820152602001613117565b5082848161394257fe5b06949350505050565b61395361434e565b600061395d61434e565b61396561442d565b613971612b9c86613bff565b90506000805b61398083613c6e565b15613bb8578061399d57613996612bc684613c8f565b8452613bb0565b80600114156139c5576139b2612be784613c8f565b6001600160a01b03166020850152613bb0565b8060021415613a545760606139dc61330c85613c8f565b90508051604051908082528060200260200182016040528015613a09578160200160208202803683370190505b50604086015260005b8151811015613a4d57613a2a82828151811061335f57fe5b86604001518281518110613a3a57fe5b6020908102919091010152600101613a12565b5050613bb0565b8060031415613ae9576060613a6b61330c85613c8f565b90508051604051908082528060200260200182016040528015613a98578160200160208202803683370190505b50606086015260005b8151811015613a4d57613ab98282815181106133fb57fe5b86606001518281518110613ac957fe5b6001600160a01b0390921660209283029190910190910152600101613aa1565b8060041415613b7e576060613b0061330c85613c8f565b90508051604051908082528060200260200182016040528015613b2d578160200160208202803683370190505b50608086015260005b8151811015613a4d57613b4e8282815181106133fb57fe5b86608001518281518110613b5e57fe5b6001600160a01b0390921660209283029190910190910152600101613b36565b8060051415613bab57613b93612bc684613c8f565b67ffffffffffffffff1660a085015260019150613bb0565b613bb8565b600101613977565b509195600195509350505050565b60006008821115613be857612954836007198401600a0a63ffffffff61253e16565b6116b9836008849003600a0a63ffffffff6124fc16565b613c0761444d565b506040805180820190915281518152602082810190820152919050565b613c2c61442d565b613c358261412c565b613c3e57600080fd5b6000613c4d836020015161415c565b60208085015160408051808201909152868152920190820152915050919050565b6000613c7861444d565b505080518051602091820151919092015191011190565b613c9761444d565b613ca082613c6e565b613ca957600080fd5b60208201516000613cb9826141bf565b80830160209586015260408051808201909152908152938401919091525090919050565b805160009015801590613cf257508151602110155b613cfb57600080fd5b6000613d0a836020015161415c565b90508083600001511015613d65576040805162461bcd60e51b815260206004820152601a60248201527f6c656e677468206973206c657373207468616e206f6666736574000000000000604482015290519081900360640190fd5b825160208085015183018051928490039291831015613d8b57826020036101000a820491505b50949350505050565b8051600090601514613da557600080fd5b6116bc82613cdd565b604080516020808252818301909252606091829190602082018180368337505050602081018490529050600067ffffffffffffffff198416613df257506018613e16565b6fffffffffffffffffffffffffffffffff198416613e1257506010613e16565b5060005b6020811015613e4c57818181518110613e2b57fe5b01602001516001600160f81b03191615613e4457613e4c565b600101613e16565b60008160200390506060816040519080825280601f01601f191660200182016040528015613e81576020820181803683370190505b5080830196909652508452509192915050565b606081516001148015613ec65750607f60f81b82600081518110613eb457fe5b01602001516001600160f81b03191611155b15613ed2575080610e53565b6116bc613ee48351608060ff16613f63565b835b6060806040519050835180825260208201818101602087015b81831015613f17578051835260209283019201613eff565b50855184518101855292509050808201602086015b81831015613f44578051835260209283019201613f2c565b508651929092011591909101601f01601f191660405250905092915050565b6060680100000000000000008310613fb3576040805162461bcd60e51b815260206004820152600e60248201526d696e70757420746f6f206c6f6e6760901b604482015290519081900360640190fd5b6040805160018082528183019092526060916020820181803683370190505090506037841161400d5782840160f81b81600081518110613fef57fe5b60200101906001600160f81b031916908160001a90535090506116bc565b606061401885613dae565b90508381510160370160f81b8260008151811061403157fe5b60200101906001600160f81b031916908160001a9053506140528282613ee6565b95945050505050565b60606140668261412c565b61406f57600080fd5b600061407a836142f2565b90506060816040519080825280602002602001820160405280156140b857816020015b6140a561444d565b81526020019060019003908161409d5790505b50905060006140ca856020015161415c565b60208601510190506000805b84811015614121576140e7836141bf565b915060405180604001604052808381526020018481525084828151811061410a57fe5b6020908102919091010152918101916001016140d6565b509195945050505050565b805160009061413d57506000610e53565b6020820151805160001a9060c0821015612a6e57600092505050610e53565b8051600090811a6080811015614176576000915050610e53565b60b8811080614191575060c08110801590614191575060f881105b156141a0576001915050610e53565b60c08110156141b45760b519019050610e53565b60f519019050610e53565b80516000908190811a60808110156141da57600191506142eb565b60b88110156141ef57607e19810191506142eb565b60c081101561426957600060b78203600186019550806020036101000a865104915060018101820193505080831015614263576040805162461bcd60e51b81526020600482015260116024820152706164646974696f6e206f766572666c6f7760781b604482015290519081900360640190fd5b506142eb565b60f881101561427e5760be19810191506142eb565b600060f78203600186019550806020036101000a8651049150600181018201935050808310156142e9576040805162461bcd60e51b81526020600482015260116024820152706164646974696f6e206f766572666c6f7760781b604482015290519081900360640190fd5b505b5092915050565b805160009061430357506000610e53565b60008090506000614317846020015161415c565b602085015185519181019250015b8082101561434557614336826141bf565b60019093019290910190614325565b50909392505050565b6040518060c001604052806000801916815260200160006001600160a01b03168152602001606081526020016060815260200160608152602001600067ffffffffffffffff1681525090565b6040805160c081018252600080825260208201819052918101829052606081018290526080810182905260a081019190915290565b60408051608081018252600080825260208201819052918101829052606081019190915290565b604051806080016040528060006001600160a01b031681526020016060815260200160608152602001600063ffffffff1681525090565b604051806040016040528061444061444d565b8152602001600081525090565b60405180604001604052806000815260200160008152509056fe746865206d6573736167652073656e646572206d75737420626520696e63656e746976697a6520636f6e7472616374466f72206d696e69546f6b656e2c20746865207472616e7366657220616d6f756e74206d757374206e6f74206265206c657373207468616e2031756e7265636f676e697a6564207472616e736665724f75742073796e207061636b61676565787069726554696d65206d7573742062652074776f206d696e75746573206c61746572616d6f756e7420697320746f6f206c617267652c20657863656564206d6178696d756d206265703220746f6b656e20616d6f756e7474686520636f6e747261637420686173206e6f74206265656e20626f756e6420746f20616e79206265703220746f6b656e726563656976656420424e4220616d6f756e742073686f756c64206265206e6f206c657373207468616e207468652073756d206f66207472616e736665724f757420424e4220616d6f756e7420616e64206d696e696d756d2072656c6179466565616d6f756e7420697320746f6f206c617267652c2075696e74323536206f766572666c6f774c656e677468206f6620726563697069656e74416464727320646f65736e277420657175616c20746f206c656e677468206f6620726566756e644164647273696e76616c6964207472616e7366657220616d6f756e743a20707265636973696f6e206c6f737320696e20616d6f756e7420636f6e76657273696f6e536166654d6174683a206d756c7469706c69636174696f6e206f766572666c6f77726563656976656420424e4220616d6f756e742073686f756c64206265206e6f206c657373207468616e20746865206d696e696d756d2072656c6179466565746865206d6573736167652073656e646572206d75737420626520676f7665726e616e636520636f6e7472616374756e7265636f676e697a6564207472616e736665724f75742061636b207061636b6167654c656e677468206f6620726563697069656e74416464727320646f65736e277420657175616c20746f206c656e677468206f6620616d6f756e7473746865206d6573736167652073656e646572206d7573742062652063726f737320636861696e20636f6e7472616374746865206d73672073656e646572206d75737420626520746f6b656e4d616e6167657274686520636f6e7472616374206e6f7420696e69742079657400000000000000726563656976656420424e4220616d6f756e742073686f756c64206265206e6f206c657373207468616e207468652073756d206f66207472616e7366657220424e4220616d6f756e7420616e642072656c6179466565696e76616c696420726563656976656420424e4220616d6f756e743a20707265636973696f6e206c6f737320696e20616d6f756e7420636f6e76657273696f6ea26469706673582212200ed3b493edce71fd9235e1f674e51718f846ead6af3ed00debad31d4e3d4dc5f64736f6c63430006040033" - }, - "0x0000000000000000000000000000000000001005": { - "balance": "0x0", - "code": "0x6080604052600436106102765760003560e01c80637e146cc51161014f578063af400681116100c1578063e75d72c71161007a578063e75d72c714610795578063e89a3020146107c8578063f9a2bbc7146107f2578063fc3e590814610807578063fd6a68791461081c578063fdd31fcd146108315761027d565b8063af400681146106ed578063bd4cc83014610717578063c81b166214610741578063dc927faf14610756578063dcae76ab1461076b578063e1c7392a146107805761027d565b8063a3c3c0ad11610113578063a3c3c0ad146105b3578063a78abc16146105c8578063a7c6a59d146105dd578063ab51bb96146105f2578063ac43175114610607578063ace9fcc2146106d85761027d565b80637e146cc51461052c578063930e1b091461054157806396713da9146105745780639dc0926214610589578063a1a11bf51461059e5761027d565b806343756e5c116101e85780636e47b482116101ac5780636e47b482146104645780636f93d2e61461047957806370fd5bad146104d857806374f2272d146104ed57806375d47a0a146105025780637942fd05146105175761027d565b806343756e5c146103e4578063493279b1146103f95780634bf6c8821461042557806351e806721461043a578063541333071461044f5761027d565b806312950c461161023a57806312950c46146103165780631b20087c1461032b5780631c643312146103405780633a975612146102825780633dffc3871461038657806340bb43c0146103b15761027d565b8063081e9d131461028257806308f2ec06146102a9578063093f2fc4146102be5780630bee7a67146102d357806310e06a76146103015761027d565b3661027d57005b600080fd5b34801561028e57600080fd5b50610297610864565b60408051918252519081900360200190f35b3480156102b557600080fd5b50610297610869565b3480156102ca57600080fd5b5061029761086e565b3480156102df57600080fd5b506102e8610873565b6040805163ffffffff9092168252519081900360200190f35b34801561030d57600080fd5b50610297610878565b34801561032257600080fd5b5061029761087e565b34801561033757600080fd5b50610297610884565b34801561034c57600080fd5b5061036a6004803603602081101561036357600080fd5b503561088a565b604080516001600160a01b039092168252519081900360200190f35b34801561039257600080fd5b5061039b610864565b6040805160ff9092168252519081900360200190f35b3480156103bd57600080fd5b50610297600480360360208110156103d457600080fd5b50356001600160a01b03166108b1565b3480156103f057600080fd5b5061036a6108c3565b34801561040557600080fd5b5061040e6108c9565b6040805161ffff9092168252519081900360200190f35b34801561043157600080fd5b5061039b6108ce565b34801561044657600080fd5b5061036a6108d3565b34801561045b57600080fd5b50610297610873565b34801561047057600080fd5b5061036a6108d9565b34801561048557600080fd5b506104c46004803603608081101561049c57600080fd5b506001600160a01b0381358116916020810135909116906040810135906060013515156108df565b604080519115158252519081900360200190f35b3480156104e457600080fd5b5061039b610cad565b3480156104f957600080fd5b50610297610cb2565b34801561050e57600080fd5b5061036a610cb8565b34801561052357600080fd5b5061039b610cbe565b34801561053857600080fd5b50610297610cc3565b34801561054d57600080fd5b506102976004803603602081101561056457600080fd5b50356001600160a01b0316610cc8565b34801561058057600080fd5b5061039b610cda565b34801561059557600080fd5b5061036a610cdf565b3480156105aa57600080fd5b5061036a610ce5565b3480156105bf57600080fd5b50610297610ceb565b3480156105d457600080fd5b506104c4610cf1565b3480156105e957600080fd5b50610297610cfa565b3480156105fe57600080fd5b506102e8610d00565b34801561061357600080fd5b506106d66004803603604081101561062a57600080fd5b81019060208101813564010000000081111561064557600080fd5b82018360208201111561065757600080fd5b8035906020019184600183028401116401000000008311171561067957600080fd5b91939092909160208101903564010000000081111561069757600080fd5b8201836020820111156106a957600080fd5b803590602001918460018302840111640100000000831117156106cb57600080fd5b509092509050610d05565b005b3480156106e457600080fd5b50610297611354565b3480156106f957600080fd5b506102976004803603602081101561071057600080fd5b503561135a565b34801561072357600080fd5b506102976004803603602081101561073a57600080fd5b50356113b5565b34801561074d57600080fd5b5061036a6113ce565b34801561076257600080fd5b5061036a6113d4565b34801561077757600080fd5b506102976113da565b34801561078c57600080fd5b506106d66113e0565b3480156107a157600080fd5b506106d6600480360360208110156107b857600080fd5b50356001600160a01b03166114a9565b3480156107d457600080fd5b5061036a600480360360208110156107eb57600080fd5b5035611602565b3480156107fe57600080fd5b5061036a61160f565b34801561081357600080fd5b5061039b611615565b34801561082857600080fd5b5061036a61161a565b34801561083d57600080fd5b506102976004803603602081101561085457600080fd5b50356001600160a01b0316611620565b600181565b602881565b605081565b606481565b600b5481565b60015481565b600c5481565b6006818154811061089757fe5b6000918252602090912001546001600160a01b0316905081565b60076020526000908152604090205481565b61100181565b603881565b600881565b61200081565b61100581565b6000805460ff16610937576040805162461bcd60e51b815260206004820152601960248201527f74686520636f6e7472616374206e6f7420696e69742079657400000000000000604482015290519081900360640190fd5b33612000146109775760405162461bcd60e51b815260040180806020018281038252602f815260200180612164602f913960400191505060405180910390fd5b600082156109fc57604080516309a99b4f60e41b8152611005600482015260248101869052905161100291639a99b4f09160448083019260209291908290030181600087803b1580156109c957600080fd5b505af11580156109dd573d6000803e3d6000fd5b505050506040513d60208110156109f357600080fd5b50519050610a75565b604080516309a99b4f60e41b8152611005600482015260248101869052905161100491639a99b4f09160448083019260209291908290030181600087803b158015610a4657600080fd5b505af1158015610a5a573d6000803e3d6000fd5b505050506040513d6020811015610a7057600080fd5b505190505b600c805460010190556000610a8982611632565b600954909150610a9f908263ffffffff61166116565b600955600a54610ac7908290610abb908563ffffffff61166116565b9063ffffffff6116c216565b600a556001600160a01b038716600090815260056020526040902054610b3357600680546001810182556000919091527ff652222313e28459528d920b65115c16c04f3efc82aaedc97be59f3f377c0d3f0180546001600160a01b0319166001600160a01b0389161790555b6001600160a01b038088166000908152600560209081526040808320805460010190559289168252600790522054610bb157600880546001810182556000919091527ff3f7a9fe364faab93b216da50a3214154f22a0a2b415b23a84c8169e8b636ee30180546001600160a01b0319166001600160a01b0388161790555b6001600160a01b038616600090815260076020526040902080546001019055600c54606411610ca057600b54600954600a5460408051938452602084019290925282820152517f2649b1b772a1a74bd332a67695e285317dd722941166595741c60a00fa65bb759181900360600190a16000610c2b611704565b90506000610c376119e8565b6001600160a01b0389166000908152600d6020526040902054909150610c75908290610c69908563ffffffff61166116565b9063ffffffff61166116565b6001600160a01b0389166000908152600d6020526040812091909155600b80546001019055600c5550505b5060019695505050505050565b600281565b60035481565b61100881565b600b81565b600581565b60056020526000908152604090205481565b600981565b61100781565b61100681565b600a5481565b60005460ff1681565b60045481565b600081565b3361100714610d455760405162461bcd60e51b815260040180806020018281038252602e8152602001806120a9602e913960400191505060405180910390fd5b60005460ff16610d865760405162461bcd60e51b81526004018080602001828103825260218152602001806120d76021913960400191505060405180910390fd5b610dfa84848080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152505060408051808201909152601f81527f68656164657252656c61796572526577617264526174654d6f6c6563756c650060208201529150611c669050565b15610ec75760208114610e3e5760405162461bcd60e51b81526004018080602001828103825260328152602001806121936032913960400191505060405180910390fd5b604080516020601f8401819004810282018101909252828152600091610e7c91858580838501838280828437600092019190915250611d4d92505050565b9050600254811115610ebf5760405162461bcd60e51b8152600401808060200182810382526060815260200180611f826060913960600191505060405180910390fd5b6001556112c2565b610f2084848080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250506040805160608101909152602280825290925090506120876020830139611c66565b15610ff85760208114610f645760405162461bcd60e51b815260040180806020018281038252602e815260200180612038602e913960400191505060405180910390fd5b604080516020601f8401819004810282018101909252828152600091610fa291858580838501838280828437600092019190915250611d4d92505050565b90508015801590610fb557506001548110155b610ff05760405162461bcd60e51b815260040180806020018281038252606c8152602001806120f8606c913960800191505060405180910390fd5b6002556112c2565b61106c84848080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152505060408051808201909152601a81527f63616c6c6572436f6d70656e736174696f6e4d6f6c6563756c6500000000000060208201529150611c669050565b1561113957602081146110b05760405162461bcd60e51b815260040180806020018281038252602e815260200180612038602e913960400191505060405180910390fd5b604080516020601f84018190048102820181019092528281526000916110ee91858580838501838280828437600092019190915250611d4d92505050565b90506004548111156111315760405162461bcd60e51b8152600401808060200182810382526056815260200180611fe26056913960600191505060405180910390fd5b6003556112c2565b6111ad84848080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152505060408051808201909152601d81527f63616c6c6572436f6d70656e736174696f6e44656e6f6d696e61746f7200000060208201529150611c669050565b1561128557602081146111f15760405162461bcd60e51b815260040180806020018281038252602e815260200180612038602e913960400191505060405180910390fd5b604080516020601f840181900481028201810190925282815260009161122f91858580838501838280828437600092019190915250611d4d92505050565b9050801580159061124257506003548110155b61127d5760405162461bcd60e51b8152600401808060200182810382526061815260200180611f216061913960800191505060405180910390fd5b6004556112c2565b6040805162461bcd60e51b815260206004820152600d60248201526c756e6b6e6f776e20706172616d60981b604482015290519081900360640190fd5b7f6cdb0ac70ab7f2e2d035cca5be60d89906f2dede7648ddbd7402189c1eeed17a848484846040518080602001806020018381038352878782818152602001925080828437600083820152601f01601f191690910184810383528581526020019050858580828437600083820152604051601f909101601f19169092018290039850909650505050505050a150505050565b60025481565b60006028821161136b5750806113b0565b81602810801561137c575060508211155b15611389575060286113b0565b60508211801561139a5750606e8211155b156113aa575060788190036113b0565b50600481045b919050565b6000602882116113c65750806113b0565b5060286113b0565b61100281565b61100381565b60095481565b60005460ff1615611438576040805162461bcd60e51b815260206004820152601960248201527f74686520636f6e747261637420616c726561647920696e697400000000000000604482015290519081900360640190fd5b60005460ff1615611486576040805162461bcd60e51b8152602060048201526013602482015272185b1c9958591e481a5b9a5d1a585b1a5e9959606a1b604482015290519081900360640190fd5b60018080556005600255600381905560506004556000805460ff19169091179055565b6001600160a01b0381166000908152600d602052604090205480611508576040805162461bcd60e51b81526020600482015260116024820152701b9bc81c995b185e595c881c995dd85c99607a1b604482015290519081900360640190fd5b6001600160a01b0382166000818152600d60205260408082208290555184929184156108fc02918591818181858888f193505050506115b85760405161100290819084156108fc029085906000818181858888f19350505050158015611572573d6000803e3d6000fd5b506040805161100281526020810185905281517f24502838a334c8f2bb2ee1f8262a4fa7183e4489a717e96cc824e325f8b39e11929181900390910190a15050506115ff565b604080516001600160a01b03851681526020810184905281517f24502838a334c8f2bb2ee1f8262a4fa7183e4489a717e96cc824e325f8b39e11929181900390910190a150505b50565b6008818154811061089757fe5b61100081565b600381565b61100481565b600d6020526000908152604090205481565b600061165b60025461164f60015485611d5290919063ffffffff16565b9063ffffffff611dab16565b92915050565b6000828201838110156116bb576040805162461bcd60e51b815260206004820152601b60248201527f536166654d6174683a206164646974696f6e206f766572666c6f770000000000604482015290519081900360640190fd5b9392505050565b60006116bb83836040518060400160405280601e81526020017f536166654d6174683a207375627472616374696f6e206f766572666c6f770000815250611ded565b600954600680546040805160208084028201810190925282815260009493859360609383018282801561176057602002820191906000526020600020905b81546001600160a01b03168152600190910190602001808311611742575b5050505050905060608151604051908082528060200260200182016040528015611794578160200160208202803683370190505b50905060005b82518110156118215760008382815181106117b157fe5b6020026020010151905060006117eb60056000846001600160a01b03166001600160a01b03168152602001908152602001600020546113b5565b9050808484815181106117fa57fe5b6020908102919091010152611815868263ffffffff61166116565b9550505060010161179a565b50600061183f60045461164f60035488611d5290919063ffffffff16565b9050611851858263ffffffff6116c216565b94508460015b845181101561192857600061188c8761164f8a88868151811061187657fe5b6020026020010151611d5290919063ffffffff16565b90506118d981600d60008986815181106118a257fe5b60200260200101516001600160a01b03166001600160a01b031681526020019081526020016000205461166190919063ffffffff16565b600d60008885815181106118e957fe5b6020908102919091018101516001600160a01b031682528101919091526040016000205561191d838263ffffffff6116c216565b925050600101611857565b5061193e81600d6000876000815181106118a257fe5b600d60008660008151811061194f57fe5b60200260200101516001600160a01b03166001600160a01b0316815260200190815260200160002081905550600060098190555060008090505b84518110156119d057600560008683815181106119a257fe5b6020908102919091018101516001600160a01b03168252810191909152604001600090812055600101611989565b506119dd60066000611ee9565b509450505050505b90565b600a546008805460408051602080840282018101909252828152600094938593606093830182828015611a4457602002820191906000526020600020905b81546001600160a01b03168152600190910190602001808311611a26575b5050505050905060608151604051908082528060200260200182016040528015611a78578160200160208202803683370190505b50905060005b8251811015611af7576000838281518110611a9557fe5b602002602001015190506000611acf60076000846001600160a01b03166001600160a01b031681526020019081526020016000205461135a565b905080848481518110611ade57fe5b6020908102919091010152949094019350600101611a7e565b506000611b1560045461164f60035488611d5290919063ffffffff16565b9050611b27858263ffffffff6116c216565b94508460015b8451811015611bb1576000611b4c8761164f8a88868151811061187657fe5b9050611b6281600d60008986815181106118a257fe5b600d6000888581518110611b7257fe5b6020908102919091018101516001600160a01b0316825281019190915260400160002055611ba6838263ffffffff6116c216565b925050600101611b2d565b50611bc781600d6000876000815181106118a257fe5b600d600086600081518110611bd857fe5b60200260200101516001600160a01b03166001600160a01b03168152602001908152602001600020819055506000600a8190555060008090505b8451811015611c595760076000868381518110611c2b57fe5b6020908102919091018101516001600160a01b03168252810191909152604001600090812055600101611c12565b506119dd60086000611ee9565b6000816040516020018082805190602001908083835b60208310611c9b5780518252601f199092019160209182019101611c7c565b6001836020036101000a03801982511681845116808217855250505050505090500191505060405160208183030381529060405280519060200120836040516020018082805190602001908083835b60208310611d095780518252601f199092019160209182019101611cea565b6001836020036101000a0380198251168184511680821785525050505050509050019150506040516020818303038152906040528051906020012014905092915050565b015190565b600082611d615750600061165b565b82820282848281611d6e57fe5b04146116bb5760405162461bcd60e51b81526004018080602001828103825260218152602001806120666021913960400191505060405180910390fd5b60006116bb83836040518060400160405280601a81526020017f536166654d6174683a206469766973696f6e206279207a65726f000000000000815250611e84565b60008184841115611e7c5760405162461bcd60e51b81526004018080602001828103825283818151815260200191508051906020019080838360005b83811015611e41578181015183820152602001611e29565b50505050905090810190601f168015611e6e5780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b505050900390565b60008183611ed35760405162461bcd60e51b8152602060048201818152835160248401528351909283926044909101919085019080838360008315611e41578181015183820152602001611e29565b506000838581611edf57fe5b0495945050505050565b50805460008255906000526020600020908101906115ff91906119e591905b80821115611f1c5760008155600101611f08565b509056fe746865206e657743616c6c6572436f6d70656e736174696f6e44656e6f6d696e61746f72206d757374206e6f74206265207a65726f20616e64206e6f206c657373207468616e2063616c6c6572436f6d70656e736174696f6e4d6f6c6563756c656e65772068656164657252656c61796572526577617264526174654d6f6c6563756c652073686f756c646e27742062652067726561746572207468616e2068656164657252656c617965725265776172645261746544656e6f6d696e61746f726e65772063616c6c6572436f6d70656e736174696f6e4d6f6c6563756c652073686f756c646e27742062652067726561746572207468616e2063616c6c6572436f6d70656e736174696f6e44656e6f6d696e61746f726c656e677468206f6620726577617264466f7256616c696461746f725365744368616e6765206d69736d61746368536166654d6174683a206d756c7469706c69636174696f6e206f766572666c6f7768656164657252656c617965725265776172645261746544656e6f6d696e61746f72746865206d6573736167652073656e646572206d75737420626520676f7665726e616e636520636f6e7472616374636f6e747261637420686173206e6f74206265656e20696e697469616c697a6564746865206e65772068656164657252656c617965725265776172645261746544656e6f6d696e61746f72206d757374206e6f74206265207a65726f20616e64206e6f206c657373207468616e2068656164657252656c61796572526577617264526174654d6f6c6563756c65746865206d6573736167652073656e646572206d7573742062652063726f737320636861696e20636f6e74726163746c656e677468206f662068656164657252656c61796572526577617264526174654d6f6c6563756c65206d69736d61746368a2646970667358221220cd7c1ec8296551de0c54d97959872d6570445d6b1250fde9150f66f3ae10dc7164736f6c63430006040033" - }, - "0x0000000000000000000000000000000000001006": { - "balance": "0x0", - "code": "0x6080604052600436106101c25760003560e01c806395468d26116100f7578063c81b166211610095578063f9a2bbc711610064578063f9a2bbc714610529578063fb7cfdd71461053e578063fc3e590814610553578063fd6a687914610568576101c2565b8063c81b1662146104d5578063dc927faf146104ea578063e1c7392a146104ff578063e79a198f14610514576101c2565b8063a1a11bf5116100d1578063a1a11bf5146103c7578063a78abc16146103dc578063ab51bb96146103f1578063ac43175114610406576101c2565b806395468d261461038857806396713da91461039d5780639dc09262146103b2576101c2565b8063541d55481161016457806370fd5bad1161013e57806370fd5bad1461033457806375d47a0a146103495780637942fd051461035e5780637ae2308814610373576101c2565b8063541d5548146102b15780636a87d780146102f85780636e47b4821461031f576101c2565b806343756e5c116101a057806343756e5c1461022a578063493279b11461025b5780634bf6c8821461028757806351e806721461029c576101c2565b80630bee7a67146101c75780631aa3a008146101f55780633dffc387146101ff575b600080fd5b3480156101d357600080fd5b506101dc61057d565b6040805163ffffffff9092168252519081900360200190f35b6101fd610582565b005b34801561020b57600080fd5b5061021461077d565b6040805160ff9092168252519081900360200190f35b34801561023657600080fd5b5061023f610782565b604080516001600160a01b039092168252519081900360200190f35b34801561026757600080fd5b50610270610788565b6040805161ffff9092168252519081900360200190f35b34801561029357600080fd5b5061021461078d565b3480156102a857600080fd5b5061023f610792565b3480156102bd57600080fd5b506102e4600480360360208110156102d457600080fd5b50356001600160a01b0316610798565b604080519115158252519081900360200190f35b34801561030457600080fd5b5061030d6107b6565b60408051918252519081900360200190f35b34801561032b57600080fd5b5061023f6107bc565b34801561034057600080fd5b506102146107c2565b34801561035557600080fd5b5061023f6107c7565b34801561036a57600080fd5b506102146107cd565b34801561037f57600080fd5b5061030d6107d2565b34801561039457600080fd5b5061030d6107df565b3480156103a957600080fd5b506102146107eb565b3480156103be57600080fd5b5061023f6107f0565b3480156103d357600080fd5b5061023f6107f6565b3480156103e857600080fd5b506102e46107fc565b3480156103fd57600080fd5b506101dc610805565b34801561041257600080fd5b506101fd6004803603604081101561042957600080fd5b81019060208101813564010000000081111561044457600080fd5b82018360208201111561045657600080fd5b8035906020019184600183028401116401000000008311171561047857600080fd5b91939092909160208101903564010000000081111561049657600080fd5b8201836020820111156104a857600080fd5b803590602001918460018302840111640100000000831117156104ca57600080fd5b50909250905061080a565b3480156104e157600080fd5b5061023f610c2c565b3480156104f657600080fd5b5061023f610c32565b34801561050b57600080fd5b506101fd610c38565b34801561052057600080fd5b506101fd610cba565b34801561053557600080fd5b5061023f610e73565b34801561054a57600080fd5b5061030d610e79565b34801561055f57600080fd5b50610214610e7f565b34801561057457600080fd5b5061023f610e84565b606481565b3360009081526004602052604090205460ff16156105df576040805162461bcd60e51b81526020600482015260156024820152741c995b185e595c88185b1c9958591e48195e1a5cdd605a1b604482015290519081900360640190fd5b60005460ff16610632576040805162461bcd60e51b81526020600482015260196024820152781d1a194818dbdb9d1c9858dd081b9bdd081a5b9a5d081e595d603a1b604482015290519081900360640190fd5b61063b33610e8a565b156106775760405162461bcd60e51b815260040180806020018281038252602781526020018061109c6027913960400191505060405180910390fd5b3332146106c1576040805162461bcd60e51b81526020600482015260136024820152721b9bc81c1c9bde1e481a5cc8185b1b1bddd959606a1b604482015290519081900360640190fd5b60015434146107015760405162461bcd60e51b81526004018080602001828103825260258152602001806110776025913960400191505060405180910390fd5b604080518082018252600180548252600254602080840191825233600081815260038352868120955186559251948401949094556004815290849020805460ff1916909217909155825191825291517fdb33a09d38b59a8fa8b7d92a1d82c8015e99f05f67ae9c9ae623157767959496929181900390910190a1565b600181565b61100181565b603881565b600881565b61200081565b6001600160a01b031660009081526004602052604090205460ff1690565b60025481565b61100581565b600281565b61100881565b600b81565b68056bc75e2d6310000081565b67016345785d8a000081565b600981565b61100781565b61100681565b60005460ff1681565b600081565b60005460ff1661085d576040805162461bcd60e51b81526020600482015260196024820152781d1a194818dbdb9d1c9858dd081b9bdd081a5b9a5d081e595d603a1b604482015290519081900360640190fd5b336110071461089d5760405162461bcd60e51b815260040180806020018281038252602e8152602001806110c3602e913960400191505060405180910390fd5b61090384848080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152505060408051808201909152600f81526e1c995c5d5a5c995911195c1bdcda5d608a1b60208201529150610e909050565b15610a0657602081146109475760405162461bcd60e51b81526004018080602001828103825260228152602001806110f16022913960400191505060405180910390fd5b604080516020601f840181900481028201810190925282815260009161098591858580838501838280828437600092019190915250610f7792505050565b90506001811180156109a05750683635c9adc5dea000008111155b80156109ad575060025481115b6109fe576040805162461bcd60e51b815260206004820181905260248201527f7468652072657175697265644465706f736974206f7574206f662072616e6765604482015290519081900360640190fd5b600155610b9a565b610a6184848080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250506040805180820190915260048152636475657360e01b60208201529150610e909050565b15610b5d5760208114610abb576040805162461bcd60e51b815260206004820152601760248201527f6c656e677468206f662064756573206d69736d61746368000000000000000000604482015290519081900360640190fd5b604080516020601f8401819004810282018101909252828152600091610af991858580838501838280828437600092019190915250610f7792505050565b9050600081118015610b0c575060015481105b610b55576040805162461bcd60e51b81526020600482015260156024820152747468652064756573206f7574206f662072616e676560581b604482015290519081900360640190fd5b600255610b9a565b6040805162461bcd60e51b815260206004820152600d60248201526c756e6b6e6f776e20706172616d60981b604482015290519081900360640190fd5b7f6cdb0ac70ab7f2e2d035cca5be60d89906f2dede7648ddbd7402189c1eeed17a848484846040518080602001806020018381038352878782818152602001925080828437600083820152601f01601f191690910184810383528581526020019050858580828437600083820152604051601f909101601f19169092018290039850909650505050505050a150505050565b61100281565b61100381565b60005460ff1615610c90576040805162461bcd60e51b815260206004820152601960248201527f74686520636f6e747261637420616c726561647920696e697400000000000000604482015290519081900360640190fd5b68056bc75e2d63100000600190815567016345785d8a00006002556000805460ff19169091179055565b3360009081526004602052604090205460ff16610d15576040805162461bcd60e51b81526020600482015260146024820152731c995b185e595c88191bc81b9bdd08195e1a5cdd60621b604482015290519081900360640190fd5b60005460ff16610d68576040805162461bcd60e51b81526020600482015260196024820152781d1a194818dbdb9d1c9858dd081b9bdd081a5b9a5d081e595d603a1b604482015290519081900360640190fd5b610d7061105c565b5033600081815260036020908152604091829020825180840190935280548084526001909101549183018290529192916108fc91610db4919063ffffffff610f7c16565b6040518115909202916000818181858888f19350505050158015610ddc573d6000803e3d6000fd5b50602081015160405161100291829181156108fc0291906000818181858888f19350505050158015610e12573d6000803e3d6000fd5b50336000818152600460209081526040808320805460ff191690556003825280832083815560010192909255815192835290517fd17202129b83db7880d6b9f25df81c58ad46f7e0e2c92236b1aa10663a4876679281900390910190a15050565b61100081565b60015481565b600381565b61100481565b3b151590565b6000816040516020018082805190602001908083835b60208310610ec55780518252601f199092019160209182019101610ea6565b6001836020036101000a03801982511681845116808217855250505050505090500191505060405160208183030381529060405280519060200120836040516020018082805190602001908083835b60208310610f335780518252601f199092019160209182019101610f14565b6001836020036101000a0380198251168184511680821785525050505050509050019150506040516020818303038152906040528051906020012014905092915050565b015190565b6000610fbe83836040518060400160405280601e81526020017f536166654d6174683a207375627472616374696f6e206f766572666c6f770000815250610fc5565b9392505050565b600081848411156110545760405162461bcd60e51b81526004018080602001828103825283818151815260200191508051906020019080838360005b83811015611019578181015183820152602001611001565b50505050905090810190601f1680156110465780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b505050900390565b60405180604001604052806000815260200160008152509056fe6465706f7369742076616c7565206973206e6f742065786163746c79207468652073616d65636f6e7472616374206973206e6f7420616c6c6f77656420746f20626520612072656c61796572746865206d6573736167652073656e646572206d75737420626520676f7665726e616e636520636f6e74726163746c656e677468206f662072657175697265644465706f736974206d69736d61746368a2646970667358221220449507f2557413401b33bd1aa888e40f31523a5d010a891cf7383c0090d7f49a64736f6c63430006040033" - }, - "0x0000000000000000000000000000000000001007": { - "balance": "0x0", - "code": "0x608060405234801561001057600080fd5b506004361061018e5760003560e01c8063831d65d1116100de578063ab51bb9611610097578063dc927faf11610071578063dc927faf14610486578063f9a2bbc71461048e578063fc3e590814610496578063fd6a68791461049e5761018e565b8063ab51bb96146103fc578063c81b166214610404578063c8509d811461040c5761018e565b8063831d65d11461034457806396713da9146103c05780639ab1a373146103c85780639dc09262146103d0578063a1a11bf5146103d8578063a78abc16146103e05761018e565b8063493279b11161014b5780636e47b482116101255780636e47b4821461032457806370fd5bad1461032c57806375d47a0a146103345780637942fd051461033c5761018e565b8063493279b1146102f55780634bf6c8821461031457806351e806721461031c5761018e565b80630bee7a67146101935780631182b875146101b45780633a21baae146102a35780633dffc387146102ab57806343756e5c146102c95780634900c4ea146102ed575b600080fd5b61019b6104a6565b6040805163ffffffff9092168252519081900360200190f35b61022e600480360360408110156101ca57600080fd5b60ff82351691908101906040810160208201356401000000008111156101ef57600080fd5b82018360208201111561020157600080fd5b8035906020019184600183028401116401000000008311171561022357600080fd5b5090925090506104ab565b6040805160208082528351818301528351919283929083019185019080838360005b83811015610268578181015183820152602001610250565b50505050905090810190601f1680156102955780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b61019b61059a565b6102b361059f565b6040805160ff9092168252519081900360200190f35b6102d16105a4565b604080516001600160a01b039092168252519081900360200190f35b6102b36105aa565b6102fd6105af565b6040805161ffff9092168252519081900360200190f35b6102b36105b4565b6102d16105b9565b6102d16105bf565b6102b36105c5565b6102d16105ca565b6102b36105d0565b6103be6004803603604081101561035a57600080fd5b60ff823516919081019060408101602082013564010000000081111561037f57600080fd5b82018360208201111561039157600080fd5b803590602001918460018302840111640100000000831117156103b357600080fd5b5090925090506105d5565b005b6102b3610667565b61019b61066c565b6102d1610671565b6102d1610677565b6103e861067d565b604080519115158252519081900360200190f35b61019b6105aa565b6102d1610686565b6103be6004803603604081101561042257600080fd5b60ff823516919081019060408101602082013564010000000081111561044757600080fd5b82018360208201111561045957600080fd5b8035906020019184600183028401116401000000008311171561047b57600080fd5b50909250905061068c565b6102d1610703565b6102d1610709565b6102b361070f565b6102d1610714565b606481565b606033612000146104ed5760405162461bcd60e51b815260040180806020018281038252602f8152602001806113e7602f913960400191505060405180910390fd5b6104f5611382565b600061053685858080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061071a92505050565b91509150806105525761054960646107e0565b92505050610593565b600061055d8361084a565b905063ffffffff811661058457505060408051600081526020810190915291506105939050565b61058d816107e0565b93505050505b9392505050565b606681565b600181565b61100181565b600081565b603881565b600881565b61200081565b61100581565b600281565b61100881565b600b81565b33612000146106155760405162461bcd60e51b815260040180806020018281038252602f8152602001806113e7602f913960400191505060405180910390fd5b6040805162461bcd60e51b815260206004820152601e60248201527f7265636569766520756e65787065637465642061636b207061636b6167650000604482015290519081900360640190fd5b505050565b600981565b606581565b61100781565b61100681565b60005460ff1681565b61100281565b33612000146106cc5760405162461bcd60e51b815260040180806020018281038252602f8152602001806113e7602f913960400191505060405180910390fd5b60405162461bcd60e51b81526004018080602001828103825260238152602001806114166023913960400191505060405180910390fd5b61100381565b61100081565b600381565b61100481565b610722611382565b600061072c611382565b6107346113ac565b61074561074086610beb565b610c10565b90506000805b61075483610c5a565b156107d357806107765761076f61076a84610c7b565b610cc9565b84526107cb565b80600114156107955761078b61076a84610c7b565b60208501526107cb565b80600214156107c6576107af6107aa84610c7b565b610d42565b6001600160a01b03166040850152600191506107cb565b6107d3565b60010161074b565b5091935090915050915091565b604080516001808252818301909252606091829190816020015b60608152602001906001900390816107fa5790505090506108208363ffffffff16610d62565b8160008151811061082d57fe5b602002602001018190525061084181610d75565b9150505b919050565b60006108598260400151610dff565b6108c557604080516020808252601c908201527f74686520746172676574206973206e6f74206120636f6e7472616374000000008183015290517f70e72399380dcfb0338abc03dc8d47f9f470ada8e769c9a78d644ea97385ecb29181900360600190a1506065610845565b81604001516001600160a01b031663ac431751836000015184602001516040518363ffffffff1660e01b8152600401808060200180602001838103835285818151815260200191508051906020019080838360005b8381101561093257818101518382015260200161091a565b50505050905090810190601f16801561095f5780820380516001836020036101000a031916815260200191505b50838103825284518152845160209182019186019080838360005b8381101561099257818101518382015260200161097a565b50505050905090810190601f1680156109bf5780820380516001836020036101000a031916815260200191505b50945050505050600060405180830381600087803b1580156109e057600080fd5b505af19250505080156109f1575060015b610be3576040516000815260443d1015610a0d57506000610aaa565b60046000803e60005160e01c6308c379a08114610a2e576000915050610aaa565b60043d036004833e81513d602482011167ffffffffffffffff82111715610a5a57600092505050610aaa565b808301805167ffffffffffffffff811115610a7c576000945050505050610aaa565b8060208301013d8601811115610a9a57600095505050505050610aaa565b601f01601f191660405250925050505b80610ab55750610b58565b7f70e72399380dcfb0338abc03dc8d47f9f470ada8e769c9a78d644ea97385ecb2816040518080602001828103825283818151815260200191508051906020019080838360005b83811015610b14578181015183820152602001610afc565b50505050905090810190601f168015610b415780820380516001836020036101000a031916815260200191505b509250505060405180910390a16066915050610845565b3d808015610b82576040519150601f19603f3d011682016040523d82523d6000602084013e610b87565b606091505b5060408051602080825283518183015283517f1279f84165b4fd69c35e1f338ff107231b036c655cd1688851e011ce617c4e8d938593928392918301919085019080838360008315610b14578181015183820152602001610afc565b506000919050565b610bf36113cc565b506040805180820190915281518152602082810190820152919050565b610c186113ac565b610c2182610e05565b610c2a57600080fd5b6000610c398360200151610e3f565b60208085015160408051808201909152868152920190820152915050919050565b6000610c646113cc565b505080518051602091820151919092015191011190565b610c836113cc565b610c8c82610c5a565b610c9557600080fd5b60208201516000610ca582610ea2565b80830160209586015260408051808201909152908152938401919091525090919050565b8051606090610cd757600080fd5b6000610ce68360200151610e3f565b83516040805191839003808352601f19601f8201168301602001909152919250606090828015610d1d576020820181803683370190505b5090506000816020019050610d39848760200151018285610fd5565b50949350505050565b8051600090601514610d5357600080fd5b610d5c82611020565b92915050565b6060610d5c610d70836110d5565b6111bb565b6060815160001415610d965750604080516000815260208101909152610845565b606082600081518110610da557fe5b602002602001015190506000600190505b8351811015610de657610ddc82858381518110610dcf57fe5b602002602001015161120d565b9150600101610db6565b50610841610df9825160c060ff1661128a565b8261120d565b3b151590565b8051600090610e1657506000610845565b6020820151805160001a9060c0821015610e3557600092505050610845565b5060019392505050565b8051600090811a6080811015610e59576000915050610845565b60b8811080610e74575060c08110801590610e74575060f881105b15610e83576001915050610845565b60c0811015610e975760b519019050610845565b60f519019050610845565b80516000908190811a6080811015610ebd5760019150610fce565b60b8811015610ed257607e1981019150610fce565b60c0811015610f4c57600060b78203600186019550806020036101000a865104915060018101820193505080831015610f46576040805162461bcd60e51b81526020600482015260116024820152706164646974696f6e206f766572666c6f7760781b604482015290519081900360640190fd5b50610fce565b60f8811015610f615760be1981019150610fce565b600060f78203600186019550806020036101000a865104915060018101820193505080831015610fcc576040805162461bcd60e51b81526020600482015260116024820152706164646974696f6e206f766572666c6f7760781b604482015290519081900360640190fd5b505b5092915050565b80610fdf57610662565b5b60208110610fff578251825260209283019290910190601f1901610fe0565b915181516020939093036101000a6000190180199091169216919091179052565b80516000901580159061103557508151602110155b61103e57600080fd5b600061104d8360200151610e3f565b905080836000015110156110a8576040805162461bcd60e51b815260206004820152601a60248201527f6c656e677468206973206c657373207468616e206f6666736574000000000000604482015290519081900360640190fd5b825160208085015183018051928490039291831015610d3957506020919091036101000a90049392505050565b604080516020808252818301909252606091829190602082018180368337505050602081018490529050600067ffffffffffffffff1984166111195750601861113d565b6fffffffffffffffffffffffffffffffff1984166111395750601061113d565b5060005b60208110156111735781818151811061115257fe5b01602001516001600160f81b0319161561116b57611173565b60010161113d565b60008160200390506060816040519080825280601f01601f1916602001820160405280156111a8576020820181803683370190505b5080830196909652508452509192915050565b6060815160011480156111ed5750607f60f81b826000815181106111db57fe5b01602001516001600160f81b03191611155b156111f9575080610845565b610d5c61120b8351608060ff1661128a565b835b6060806040519050835180825260208201818101602087015b8183101561123e578051835260209283019201611226565b50855184518101855292509050808201602086015b8183101561126b578051835260209283019201611253565b508651929092011591909101601f01601f191660405250905092915050565b60606801000000000000000083106112da576040805162461bcd60e51b815260206004820152600e60248201526d696e70757420746f6f206c6f6e6760901b604482015290519081900360640190fd5b604080516001808252818301909252606091602082018180368337019050509050603784116113345782840160f81b8160008151811061131657fe5b60200101906001600160f81b031916908160001a9053509050610d5c565b606061133f856110d5565b90508381510160370160f81b8260008151811061135857fe5b60200101906001600160f81b031916908160001a905350611379828261120d565b95945050505050565b6040518060600160405280606081526020016060815260200160006001600160a01b031681525090565b60405180604001604052806113bf6113cc565b8152602001600081525090565b60405180604001604052806000815260200160008152509056fe746865206d6573736167652073656e646572206d7573742062652063726f737320636861696e20636f6e74726163747265636569766520756e6578706563746564206661696c2061636b207061636b616765a2646970667358221220a5eefec118f5b467b996b871e3b96c20aa4fe4192a6c4b34c6afc795161d4a9a64736f6c63430006040033" - }, - "0x0000000000000000000000000000000000001008": { - "balance": "0x0", - "code": "0x6080604052600436106102465760003560e01c806375d47a0a11610139578063ab51bb96116100b6578063d9e6dae91161007a578063d9e6dae914610512578063dc927faf14610975578063f9a2bbc71461098a578063fc3e590814610566578063fd6a68791461099f578063fe3a2af5146104e857610246565b8063ab51bb96146108ca578063c81b1662146108df578063c8509d81146107da578063c8e704a414610566578063d117a110146108f457610246565b806395b9ad26116100fd57806395b9ad261461086157806396713da9146108765780639dc092621461088b578063a1a11bf5146108a0578063a78abc16146108b557610246565b806375d47a0a146106fc57806377d9dae8146107115780637942fd05146107c55780637d078e13146103b3578063831d65d1146107da57610246565b80634bc81c00116101c757806366dea52a1161018b57806366dea52a146105665780636b3f13071461057b5780636e47b4821461064357806370fd5bad1461055157806372c4e0861461065857610246565b80634bc81c00146104fd5780634bf6c8821461051257806351e80672146105275780635d499b1b1461053c5780635f558f861461055157610246565b80633dffc3871161020e5780633dffc387146103b357806343756e5c146103c8578063445fcefe146103f9578063493279b1146104bc5780634a688818146104e857610246565b80630bee7a671461024b5780630f212b1b146102795780631182b875146102a45780631f91600b1461039e57806323996b53146103b3575b600080fd5b34801561025757600080fd5b506102606109b4565b6040805163ffffffff9092168252519081900360200190f35b34801561028557600080fd5b5061028e6109b9565b6040805160ff9092168252519081900360200190f35b3480156102b057600080fd5b50610329600480360360408110156102c757600080fd5b60ff8235169190810190604081016020820135600160201b8111156102eb57600080fd5b8201836020820111156102fd57600080fd5b803590602001918460018302840111600160201b8311171561031e57600080fd5b5090925090506109be565b6040805160208082528351818301528351919283929083019185019080838360005b8381101561036357818101518382015260200161034b565b50505050905090810190601f1680156103905780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b3480156103aa57600080fd5b5061028e610a47565b3480156103bf57600080fd5b5061028e610a4c565b3480156103d457600080fd5b506103dd610a51565b604080516001600160a01b039092168252519081900360200190f35b34801561040557600080fd5b506104aa6004803603602081101561041c57600080fd5b810190602081018135600160201b81111561043657600080fd5b82018360208201111561044857600080fd5b803590602001918460018302840111600160201b8311171561046957600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250929550610a57945050505050565b60408051918252519081900360200190f35b3480156104c857600080fd5b506104d1610bb6565b6040805161ffff9092168252519081900360200190f35b3480156104f457600080fd5b5061028e610bbb565b34801561050957600080fd5b5061028e610bc0565b34801561051e57600080fd5b5061028e610bc5565b34801561053357600080fd5b506103dd610bca565b34801561054857600080fd5b506104aa610bd0565b34801561055d57600080fd5b5061028e610bd9565b34801561057257600080fd5b5061028e610bde565b61062f6004803603604081101561059157600080fd5b6001600160a01b038235169190810190604081016020820135600160201b8111156105bb57600080fd5b8201836020820111156105cd57600080fd5b803590602001918460018302840111600160201b831117156105ee57600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250929550610be3945050505050565b604080519115158252519081900360200190f35b34801561064f57600080fd5b506103dd611465565b61062f6004803603602081101561066e57600080fd5b810190602081018135600160201b81111561068857600080fd5b82018360208201111561069a57600080fd5b803590602001918460018302840111600160201b831117156106bb57600080fd5b91908080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525092955061146b945050505050565b34801561070857600080fd5b506103dd6118b9565b61062f6004803603604081101561072757600080fd5b6001600160a01b038235169190810190604081016020820135600160201b81111561075157600080fd5b82018360208201111561076357600080fd5b803590602001918460018302840111600160201b8311171561078457600080fd5b91908080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152509295506118bf945050505050565b3480156107d157600080fd5b5061028e611dc6565b3480156107e657600080fd5b5061085f600480360360408110156107fd57600080fd5b60ff8235169190810190604081016020820135600160201b81111561082157600080fd5b82018360208201111561083357600080fd5b803590602001918460018302840111600160201b8311171561085457600080fd5b509092509050611dcb565b005b34801561086d57600080fd5b5061028e611e7e565b34801561088257600080fd5b5061028e611e83565b34801561089757600080fd5b506103dd611e88565b3480156108ac57600080fd5b506103dd611e8e565b3480156108c157600080fd5b5061062f611e94565b3480156108d657600080fd5b50610260610bbb565b3480156108eb57600080fd5b506103dd611e9d565b34801561090057600080fd5b5061091e6004803603602081101561091757600080fd5b5035611ea3565b6040805160ff988916815260208101979097526001600160a01b03909516868601526060860193909352608085019190915290931660a083015267ffffffffffffffff90921660c082015290519081900360e00190f35b34801561098157600080fd5b506103dd611efb565b34801561099657600080fd5b506103dd611f01565b3480156109ab57600080fd5b506103dd611f07565b606481565b600681565b60603361200014610a005760405162461bcd60e51b815260040180806020018281038252602f8152602001806132a0602f913960400191505060405180910390fd5b610a3f83838080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250611f0d92505050565b949350505050565b600481565b600181565b61100181565b6020810151600090610a67613168565b50600081815260016020818152604092839020835160e081018552815460ff9081168252938201549281019290925260028101546001600160a01b031693820184905260038101546060830152600481015460808301526005015491821660a082015261010090910467ffffffffffffffff1660c082015290610aef57600092505050610bb1565b600081604001516001600160a01b03166370a082316110046040518263ffffffff1660e01b815260040180826001600160a01b03166001600160a01b0316815260200191505060206040518083038186803b158015610b4d57600080fd5b505afa158015610b61573d6000803e3d6000fd5b505050506040513d6020811015610b7757600080fd5b505160808301516060840151919250600091610b989163ffffffff61219e16565b9050610baa818363ffffffff61219e16565b9450505050505b919050565b603881565b600081565b600581565b600881565b61200081565b6402540be40081565b600281565b600381565b600080610bef836121e7565b9050610bf9613168565b50600081815260016020818152604092839020835160e081018552815460ff90811682529382015492810183905260028201546001600160a01b03169481019490945260038101546060850152600481015460808501526005015491821660a084015261010090910467ffffffffffffffff1660c0830152610cbf576040805162461bcd60e51b815260206004820152601a602482015279189a5b99081c995c5d595cdd08191bd95cdb89dd08195e1a5cdd60321b604482015290519081900360640190fd5b6000610cdc8260800151836060015161219e90919063ffffffff16565b905081604001516001600160a01b0316866001600160a01b031614610d325760405162461bcd60e51b815260040180806020018281038252604581526020018061325b6045913960600191505060405180910390fd5b336001600160a01b0316866001600160a01b031663893d20e86040518163ffffffff1660e01b815260040160206040518083038186803b158015610d7557600080fd5b505afa158015610d89573d6000803e3d6000fd5b505050506040513d6020811015610d9f57600080fd5b50516001600160a01b031614610de65760405162461bcd60e51b815260040180806020018281038252602e8152602001806131f6602e913960400191505060405180910390fd5b604080516370a0823160e01b8152611004600482015290516000916001600160a01b038916916370a0823191602480820192602092909190829003018186803b158015610e3257600080fd5b505afa158015610e46573d6000803e3d6000fd5b505050506040513d6020811015610e5c57600080fd5b505160408051636eb1769f60e11b815233600482015230602482015290519192508391610eed9184916001600160a01b038c169163dd62ed3e916044808301926020929190829003018186803b158015610eb557600080fd5b505afa158015610ec9573d6000803e3d6000fd5b505050506040513d6020811015610edf57600080fd5b50519063ffffffff6121ee16565b1015610f40576040805162461bcd60e51b815260206004820152601760248201527f616c6c6f77616e6365206973206e6f7420656e6f756768000000000000000000604482015290519081900360640190fd5b600034905060006110046001600160a01b031663149d14d96040518163ffffffff1660e01b815260040160206040518083038186803b158015610f8257600080fd5b505afa158015610f96573d6000803e3d6000fd5b505050506040513d6020811015610fac57600080fd5b50519050808210801590610fc557506402540be4008206155b6110005760405162461bcd60e51b81526004018080602001828103825260378152602001806132246037913960400191505060405180910390fd5b600061100c868b612248565b905063ffffffff811661120b576001600160a01b038a166323b872dd3361100461103c898963ffffffff61219e16565b6040518463ffffffff1660e01b815260040180846001600160a01b03166001600160a01b03168152602001836001600160a01b03166001600160a01b031681526020018281526020019350505050602060405180830381600087803b1580156110a457600080fd5b505af11580156110b8573d6000803e3d6000fd5b505050506040513d60208110156110ce57600080fd5b5050602086015160408088015160a089015182516323bfccdb60e21b815260048101949094526001600160a01b03909116602484015260ff1660448301525161100491638eff336c91606480830192600092919082900301818387803b15801561113757600080fd5b505af115801561114b573d6000803e3d6000fd5b50505050896001600160a01b03167f78e7dd9aefcdbf795c4936a66f7dc6d41bb56637b54f561a6bf7829dca3348a88a8860600151886040518080602001848152602001838152602001828103825285818151815260200191508051906020019080838360005b838110156111ca5781810151838201526020016111b2565b50505050905090810190601f1680156111f75780820380516001836020036101000a031916815260200191505b5094505050505060405180910390a26112c3565b896001600160a01b03167f831c0ef4d93bda3bce08b69ae3f29ef1a6e052b833200988554158494405a1078a8360405180806020018363ffffffff1663ffffffff168152602001828103825284818151815260200191508051906020019080838360005b8381101561128757818101518382015260200161126f565b50505050905090810190601f1680156112b45780820380516001836020036101000a031916815260200191505b50935050505060405180910390a25b60008781526001602081905260408220805460ff191681559081018290556002810180546001600160a01b0319169055600381018290556004810191909155600501805468ffffffffffffffffff1916905561131d6131a4565b5060408051808201825263ffffffff831681526020810189905290516110049085156108fc029086906000818181858888f19350505050158015611365573d6000803e3d6000fd5b5061200063f7a251d760016113798461269f565b61138e886402540be40063ffffffff61272916565b6040518463ffffffff1660e01b8152600401808460ff1660ff16815260200180602001838152602001828103825284818151815260200191508051906020019080838360005b838110156113ec5781810151838201526020016113d4565b50505050905090810190601f1680156114195780820380516001836020036101000a031916815260200191505b50945050505050600060405180830381600087803b15801561143a57600080fd5b505af115801561144e573d6000803e3d6000fd5b505050506001985050505050505050505b92915050565b61100581565b600080611477836121e7565b9050611481613168565b50600081815260016020818152604092839020835160e081018552815460ff90811682529382015492810183905260028201546001600160a01b03169481019490945260038101546060850152600481015460808501526005015491821660a084015261010090910467ffffffffffffffff1660c0830152611547576040805162461bcd60e51b815260206004820152601a602482015279189a5b99081c995c5d595cdd08191bd95cdb89dd08195e1a5cdd60321b604482015290519081900360640190fd5b428160c0015167ffffffffffffffff16106115a9576040805162461bcd60e51b815260206004820152601b60248201527f62696e642072657175657374206973206e6f7420657870697265640000000000604482015290519081900360640190fd5b600034905060006110046001600160a01b031663149d14d96040518163ffffffff1660e01b815260040160206040518083038186803b1580156115eb57600080fd5b505afa1580156115ff573d6000803e3d6000fd5b505050506040513d602081101561161557600080fd5b5051905080821080159061162e57506402540be4008206155b6116695760405162461bcd60e51b81526004018080602001828103825260378152602001806132246037913960400191505060405180910390fd5b60008481526001602081905260408220805460ff191681559081018290556002810180546001600160a01b0319169055600381018290556004810191909155600501805468ffffffffffffffffff191690556116c36131a4565b50604080518082018252600181526020810186905290516110049084156108fc029085906000818181858888f19350505050158015611706573d6000803e3d6000fd5b5061200063f7a251d7600161171a8461269f565b61172f876402540be40063ffffffff61272916565b6040518463ffffffff1660e01b8152600401808460ff1660ff16815260200180602001838152602001828103825284818151815260200191508051906020019080838360005b8381101561178d578181015183820152602001611775565b50505050905090810190601f1680156117ba5780820380516001836020036101000a031916815260200191505b50945050505050600060405180830381600087803b1580156117db57600080fd5b505af11580156117ef573d6000803e3d6000fd5b5050505083604001516001600160a01b03167f831c0ef4d93bda3bce08b69ae3f29ef1a6e052b833200988554158494405a10788600160405180806020018360ff1663ffffffff168152602001828103825284818151815260200191508051906020019080838360005b83811015611871578181015183820152602001611859565b50505050905090810190601f16801561189e5780820380516001836020036101000a031916815260200191505b50935050505060405180910390a25060019695505050505050565b61100881565b6000806118cb836121e7565b90506118d5613168565b50600081815260016020818152604092839020835160e081018552815460ff90811682529382015492810183905260028201546001600160a01b03169481019490945260038101546060850152600481015460808501526005015491821660a084015261010090910467ffffffffffffffff1660c083015261199b576040805162461bcd60e51b815260206004820152601a602482015279189a5b99081c995c5d595cdd08191bd95cdb89dd08195e1a5cdd60321b604482015290519081900360640190fd5b80604001516001600160a01b0316856001600160a01b0316146119ef5760405162461bcd60e51b815260040180806020018281038252604581526020018061325b6045913960600191505060405180910390fd5b336001600160a01b0316856001600160a01b031663893d20e86040518163ffffffff1660e01b815260040160206040518083038186803b158015611a3257600080fd5b505afa158015611a46573d6000803e3d6000fd5b505050506040513d6020811015611a5c57600080fd5b50516001600160a01b031614611ab9576040805162461bcd60e51b815260206004820152601b60248201527f6f6e6c79206265703230206f776e65722063616e2072656a6563740000000000604482015290519081900360640190fd5b600034905060006110046001600160a01b031663149d14d96040518163ffffffff1660e01b815260040160206040518083038186803b158015611afb57600080fd5b505afa158015611b0f573d6000803e3d6000fd5b505050506040513d6020811015611b2557600080fd5b50519050808210801590611b3e57506402540be4008206155b611b795760405162461bcd60e51b81526004018080602001828103825260378152602001806132246037913960400191505060405180910390fd5b60008481526001602081905260408220805460ff191681559081018290556002810180546001600160a01b0319169055600381018290556004810191909155600501805468ffffffffffffffffff19169055611bd36131a4565b50604080518082018252600781526020810186905290516110049084156108fc029085906000818181858888f19350505050158015611c16573d6000803e3d6000fd5b5061200063f7a251d76001611c2a8461269f565b611c3f876402540be40063ffffffff61272916565b6040518463ffffffff1660e01b8152600401808460ff1660ff16815260200180602001838152602001828103825284818151815260200191508051906020019080838360005b83811015611c9d578181015183820152602001611c85565b50505050905090810190601f168015611cca5780820380516001836020036101000a031916815260200191505b50945050505050600060405180830381600087803b158015611ceb57600080fd5b505af1158015611cff573d6000803e3d6000fd5b50505050876001600160a01b03167f831c0ef4d93bda3bce08b69ae3f29ef1a6e052b833200988554158494405a10788600760405180806020018360ff1663ffffffff168152602001828103825284818151815260200191508051906020019080838360005b83811015611d7d578181015183820152602001611d65565b50505050905090810190601f168015611daa5780820380516001836020036101000a031916815260200191505b50935050505060405180910390a2506001979650505050505050565b600b81565b3361200014611e0b5760405162461bcd60e51b815260040180806020018281038252602f8152602001806132a0602f913960400191505060405180910390fd5b7f41ce201247b6ceb957dcdb217d0b8acb50b9ea0e12af9af4f5e7f38902101605838383604051808460ff1660ff168152602001806020018281038252848482818152602001925080828437600083820152604051601f909101601f1916909201829003965090945050505050a1505050565b600781565b600981565b61100781565b61100681565b60005460ff1681565b61100281565b600160208190526000918252604090912080549181015460028201546003830154600484015460059094015460ff9586169593946001600160a01b0390931693919291811690610100900467ffffffffffffffff1687565b61100381565b61100081565b61100481565b6060611f17613168565b6000611f228461276b565b9150915080611f78576040805162461bcd60e51b815260206004820152601f60248201527f756e7265636f676e697a6564207472616e73666572496e207061636b61676500604482015290519081900360640190fd5b815160ff1661202c576020828101805160009081526001928390526040908190208551815460ff1990811660ff928316178355935194820194909455908501516002820180546001600160a01b0319166001600160a01b03909216919091179055606085015160038201556080850151600482015560a08501516005909101805460c08701519316919093161768ffffffffffffffff00191661010067ffffffffffffffff90921691909102179055612183565b815160ff16600114156121365760006110046001600160a01b03166359b9278984602001516040518263ffffffff1660e01b81526004018082815260200191505060206040518083038186803b15801561208557600080fd5b505afa158015612099573d6000803e3d6000fd5b505050506040513d60208110156120af57600080fd5b505190506001600160a01b038116156121305760208301516040805163b99328c560e01b815260048101929092526001600160a01b0383166024830152516110049163b99328c591604480830192600092919082900301818387803b15801561211757600080fd5b505af115801561212b573d6000803e3d6000fd5b505050505b50612183565b6040805162461bcd60e51b815260206004820152601960248201527f756e7265636f676e697a65642062696e64207061636b61676500000000000000604482015290519081900360640190fd5b60408051600080825260208201909252905b50949350505050565b60006121e083836040518060400160405280601e81526020017f536166654d6174683a207375627472616374696f6e206f766572666c6f7700008152506128bd565b9392505050565b6020015190565b6000828201838110156121e0576040805162461bcd60e51b815260206004820152601b60248201527f536166654d6174683a206164646974696f6e206f766572666c6f770000000000604482015290519081900360640190fd5b600080826001600160a01b031663313ce5676040518163ffffffff1660e01b815260040160206040518083038186803b15801561228457600080fd5b505afa158015612298573d6000803e3d6000fd5b505050506040513d60208110156122ae57600080fd5b5051604080516395d89b4160e01b815290519192506060916001600160a01b038616916395d89b41916004808301926000929190829003018186803b1580156122f657600080fd5b505afa15801561230a573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052602081101561233357600080fd5b8101908080516040519392919084600160201b82111561235257600080fd5b90830190602082018581111561236757600080fd5b8251600160201b81118282018810171561238057600080fd5b82525081516020918201929091019080838360005b838110156123ad578181015183820152602001612395565b50505050905090810190601f1680156123da5780820380516001836020036101000a031916815260200191505b5060408181526370a0823160e01b82526110046004830152519495506000946001600160a01b038a1694506370a08231935060248083019350602092829003018186803b15801561242a57600080fd5b505afa15801561243e573d6000803e3d6000fd5b505050506040513d602081101561245457600080fd5b5051608087015160608801519192506000916124759163ffffffff61219e16565b9050428760c0015167ffffffffffffffff16101561249b57506001935061145f92505050565b6124a9838860200151612954565b6124bb57506002935061145f92505050565b808211156124d157506003935061145f92505050565b866060015187604001516001600160a01b03166318160ddd6040518163ffffffff1660e01b815260040160206040518083038186803b15801561251357600080fd5b505afa158015612527573d6000803e3d6000fd5b505050506040513d602081101561253d57600080fd5b50511461255257506004935061145f92505050565b8660a0015160ff16841461256e57506005935061145f92505050565b602080880151604080516359b9278960e01b8152600481019290925251600092611004926359b927899260248083019392829003018186803b1580156125b357600080fd5b505afa1580156125c7573d6000803e3d6000fd5b505050506040513d60208110156125dd57600080fd5b50516001600160a01b031614158061267f57506000801b6110046001600160a01b031663bd46646189604001516040518263ffffffff1660e01b815260040180826001600160a01b03166001600160a01b0316815260200191505060206040518083038186803b15801561265057600080fd5b505afa158015612664573d6000803e3d6000fd5b505050506040513d602081101561267a57600080fd5b505114155b1561269257506006935061145f92505050565b5060009695505050505050565b6040805160028082526060828101909352829190816020015b60608152602001906001900390816126b857505083519091506126e09063ffffffff16612a3c565b816000815181106126ed57fe5b6020026020010181905250612708836020015160001c612a3c565b8160018151811061271557fe5b60200260200101819052506121e081612a4f565b60006121e083836040518060400160405280601a81526020017f536166654d6174683a206469766973696f6e206279207a65726f000000000000815250612ad9565b612773613168565b600061277d613168565b6127856131bb565b61279661279186612b3e565b612b63565b90506000805b6127a583612bad565b156128b057806127ca576127c06127bb84612bce565b612c1c565b60ff1684526128a8565b80600114156127e9576127df6127bb84612bce565b60208501526128a8565b8060021415612816576128036127fe84612bce565b612cd1565b6001600160a01b031660408501526128a8565b80600314156128355761282b6127bb84612bce565b60608501526128a8565b80600414156128545761284a6127bb84612bce565b60808501526128a8565b8060051415612876576128696127bb84612bce565b60ff1660a08501526128a8565b80600614156128a35761288b6127bb84612bce565b67ffffffffffffffff1660c0850152600191506128a8565b6128b0565b60010161279c565b5091935090915050915091565b6000818484111561294c5760405162461bcd60e51b81526004018080602001828103825283818151815260200191508051906020019080838360005b838110156129115781810151838201526020016128f9565b50505050905090810190601f16801561293e5780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b505050900390565b815160009083906008108061296a575080516003115b1561297957600091505061145f565b604080516020808252818301909252606091602082018180368337019050509050836020820152808251815181106129ad57fe5b6020910101516001600160f81b031916602d60f81b146129d25760009250505061145f565b600160005b8351811015612a32578281815181106129ec57fe5b602001015160f81c60f81b6001600160f81b031916848281518110612a0d57fe5b01602001516001600160f81b03191614612a2a5760009150612a32565b6001016129d7565b5095945050505050565b606061145f612a4a83612ceb565b612dd1565b6060815160001415612a705750604080516000815260208101909152610bb1565b606082600081518110612a7f57fe5b602002602001015190506000600190505b8351811015612ac057612ab682858381518110612aa957fe5b6020026020010151612e23565b9150600101612a90565b506121e0612ad3825160c060ff16612ea0565b82612e23565b60008183612b285760405162461bcd60e51b81526020600482018181528351602484015283519092839260449091019190850190808383600083156129115781810151838201526020016128f9565b506000838581612b3457fe5b0495945050505050565b612b466131db565b506040805180820190915281518152602082810190820152919050565b612b6b6131bb565b612b7482612f98565b612b7d57600080fd5b6000612b8c8360200151612fd2565b60208085015160408051808201909152868152920190820152915050919050565b6000612bb76131db565b505080518051602091820151919092015191011190565b612bd66131db565b612bdf82612bad565b612be857600080fd5b60208201516000612bf882613035565b80830160209586015260408051808201909152908152938401919091525090919050565b805160009015801590612c3157508151602110155b612c3a57600080fd5b6000612c498360200151612fd2565b90508083600001511015612ca4576040805162461bcd60e51b815260206004820152601a60248201527f6c656e677468206973206c657373207468616e206f6666736574000000000000604482015290519081900360640190fd5b82516020808501518301805192849003929183101561219557506020919091036101000a90049392505050565b8051600090601514612ce257600080fd5b61145f82612c1c565b604080516020808252818301909252606091829190602082018180368337505050602081018490529050600067ffffffffffffffff198416612d2f57506018612d53565b6fffffffffffffffffffffffffffffffff198416612d4f57506010612d53565b5060005b6020811015612d8957818181518110612d6857fe5b01602001516001600160f81b03191615612d8157612d89565b600101612d53565b60008160200390506060816040519080825280601f01601f191660200182016040528015612dbe576020820181803683370190505b5080830196909652508452509192915050565b606081516001148015612e035750607f60f81b82600081518110612df157fe5b01602001516001600160f81b03191611155b15612e0f575080610bb1565b61145f612e218351608060ff16612ea0565b835b6060806040519050835180825260208201818101602087015b81831015612e54578051835260209283019201612e3c565b50855184518101855292509050808201602086015b81831015612e81578051835260209283019201612e69565b508651929092011591909101601f01601f191660405250905092915050565b6060680100000000000000008310612ef0576040805162461bcd60e51b815260206004820152600e60248201526d696e70757420746f6f206c6f6e6760901b604482015290519081900360640190fd5b60408051600180825281830190925260609160208201818036833701905050905060378411612f4a5782840160f81b81600081518110612f2c57fe5b60200101906001600160f81b031916908160001a905350905061145f565b6060612f5585612ceb565b90508381510160370160f81b82600081518110612f6e57fe5b60200101906001600160f81b031916908160001a905350612f8f8282612e23565b95945050505050565b8051600090612fa957506000610bb1565b6020820151805160001a9060c0821015612fc857600092505050610bb1565b5060019392505050565b8051600090811a6080811015612fec576000915050610bb1565b60b8811080613007575060c08110801590613007575060f881105b15613016576001915050610bb1565b60c081101561302a5760b519019050610bb1565b60f519019050610bb1565b80516000908190811a60808110156130505760019150613161565b60b881101561306557607e1981019150613161565b60c08110156130df57600060b78203600186019550806020036101000a8651049150600181018201935050808310156130d9576040805162461bcd60e51b81526020600482015260116024820152706164646974696f6e206f766572666c6f7760781b604482015290519081900360640190fd5b50613161565b60f88110156130f45760be1981019150613161565b600060f78203600186019550806020036101000a86510491506001810182019350508083101561315f576040805162461bcd60e51b81526020600482015260116024820152706164646974696f6e206f766572666c6f7760781b604482015290519081900360640190fd5b505b5092915050565b6040805160e081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c081019190915290565b604080518082019091526000808252602082015290565b60405180604001604052806131ce6131db565b8152602001600081525090565b60405180604001604052806000815260200160008152509056fe6f6e6c79206265703230206f776e65722063616e20617070726f766520746869732062696e64207265717565737472656c6179466565206d757374206265204e202a203165313020616e642067726561746572207468616e206d696e6952656c6179466565636f6e74616374206164647265737320646f65736e277420657175616c20746f2074686520636f6e7472616374206164647265737320696e2062696e642072657175657374746865206d6573736167652073656e646572206d7573742062652063726f737320636861696e20636f6e7472616374a264697066735822122030cc6c250f37ad9452c0933399bf3f460a19215bce5c10c377f100761098776a64736f6c63430006040033" - }, - "0x0000000000000000000000000000000000002000": { - "balance": "0x0", - "code": "0x608060405234801561001057600080fd5b50600436106102485760003560e01c8063863fe4ab1161013b578063c81b1662116100b8578063e3b048051161007c578063e3b048051461072c578063f7a251d71461074c578063f9a2bbc7146107c4578063fc3e5908146107cc578063fd6a6879146107d457610248565b8063c81b1662146106dd578063d31f968d146106e5578063d76a867514610714578063dc927faf1461071c578063e1c7392a1461072457610248565b8063a78abc16116100ff578063a78abc16146105d3578063ab51bb96146105db578063ac431751146105e3578063b0355f5b146103ff578063c27cdcfb146106a157610248565b8063863fe4ab146105b35780638cc8f561146104b657806396713da9146105bb5780639dc09262146105c3578063a1a11bf5146105cb57610248565b8063493279b1116101c957806370fd5bad1161018d57806370fd5bad146104b657806374f079b8146104be57806375d47a0a146104c65780637942fd05146104ce57806384013b6a146104d657610248565b8063493279b11461045f5780634bf6c8821461047e57806351e80672146104865780636e47a51a1461048e5780636e47b482146104ae57610248565b8063308325f411610210578063308325f4146102cf5780633bdc47a6146102d75780633dffc387146103ff578063422f90501461040757806343756e5c1461043b57610248565b806305e682581461024d5780630bee7a671461026b57806314b3023b1461028c57806322556cdc146102a65780632ff32aea146102ae575b600080fd5b6102556107dc565b6040805160ff9092168252519081900360200190f35b6102736107e1565b6040805163ffffffff9092168252519081900360200190f35b6102946107e6565b60408051918252519081900360200190f35b6102946107ec565b6102b66107f1565b60408051600792830b90920b8252519081900360200190f35b6102946107fa565b61038a600480360360608110156102ed57600080fd5b60ff82351691602081013591810190606081016040820135600160201b81111561031657600080fd5b82018360208201111561032857600080fd5b803590602001918460018302840111600160201b8311171561034957600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250929550610800945050505050565b6040805160208082528351818301528351919283929083019185019080838360005b838110156103c45781810151838201526020016103ac565b50505050905090810190601f1680156103f15780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b610255610876565b6104276004803603602081101561041d57600080fd5b503560ff1661087b565b604080519115158252519081900360200190f35b610443610890565b604080516001600160a01b039092168252519081900360200190f35b610467610896565b6040805161ffff9092168252519081900360200190f35b61025561089b565b6104436108a0565b610443600480360360208110156104a457600080fd5b503560ff166108a6565b6104436108c1565b6102556108c7565b6102946108cc565b6104436108d2565b6102556108d8565b6105b1600480360360a08110156104ec57600080fd5b810190602081018135600160201b81111561050657600080fd5b82018360208201111561051857600080fd5b803590602001918460018302840111600160201b8311171561053957600080fd5b919390929091602081019035600160201b81111561055657600080fd5b82018360208201111561056857600080fd5b803590602001918460018302840111600160201b8311171561058957600080fd5b919350915080356001600160401b03908116916020810135909116906040013560ff166108dd565b005b610294611a8d565b610255611a95565b610443611a9a565b610443611aa0565b610427611aa6565b6102736107dc565b6105b1600480360360408110156105f957600080fd5b810190602081018135600160201b81111561061357600080fd5b82018360208201111561062557600080fd5b803590602001918460018302840111600160201b8311171561064657600080fd5b919390929091602081019035600160201b81111561066357600080fd5b82018360208201111561067557600080fd5b803590602001918460018302840111600160201b8311171561069657600080fd5b509092509050611aaf565b6106c1600480360360208110156106b757600080fd5b503560ff16612051565b604080516001600160401b039092168252519081900360200190f35b61044361206c565b610427600480360360408110156106fb57600080fd5b5080356001600160a01b0316906020013560ff16612072565b61038a612092565b6104436120b1565b6105b16120b7565b6106c16004803603602081101561074257600080fd5b503560ff1661246e565b6105b16004803603606081101561076257600080fd5b60ff8235169190810190604081016020820135600160201b81111561078657600080fd5b82018360208201111561079857600080fd5b803590602001918460018302840111600160201b831117156107b957600080fd5b919350915035612489565b6104436125da565b6102556125e0565b6104436125e5565b600081565b606481565b60015481565b603281565b60045460070b81565b60025481565b60606000825160210190506060816040519080825280601f01601f191660200182016040528015610838576020820181803683370190505b506021810186905260018101879052828152905060418101600061085b866125eb565b50905061086a818388516125f5565b50909695505050505050565b600181565b60096020526000908152604090205460ff1681565b61100181565b603881565b600881565b61200081565b6005602052600090815260409020546001600160a01b031681565b61100581565b600281565b60035481565b61100881565b600b81565b60005460ff16610930576040805162461bcd60e51b81526020600482015260196024820152781d1a194818dbdb9d1c9858dd081b9bdd081a5b9a5d081e595d603a1b604482015290519081900360640190fd5b60408051630a83aaa960e31b815233600482015290516110069163541d5548916024808301926020929190829003018186803b15801561096f57600080fd5b505afa158015610983573d6000803e3d6000fd5b505050506040513d602081101561099957600080fd5b50516109ec576040805162461bcd60e51b815260206004820152601f60248201527f746865206d73672073656e646572206973206e6f7420612072656c6179657200604482015290519081900360640190fd5b60ff8116600090815260086020526040902054829082906001600160401b039081169083168114610a5c576040805162461bcd60e51b815260206004820152601560248201527439b2b8bab2b731b2903737ba1034b71037b93232b960591b604482015290519081900360640190fd5b60ff8216600090815260086020908152604091829020805467ffffffffffffffff1916600185016001600160401b039081169190911790915582516337d7f9c160e21b81529089166004820152915188926110039263df5fe70492602480840193829003018186803b158015610ad157600080fd5b505afa158015610ae5573d6000803e3d6000fd5b505050506040513d6020811015610afb57600080fd5b5051610b385760405162461bcd60e51b8152600401808060200182810382526023815260200180612bcc6023913960400191505060405180910390fd5b60ff851660009081526005602052604090205485906001600160a01b0316610ba7576040805162461bcd60e51b815260206004820152601860248201527f6368616e6e656c206973206e6f7420737570706f727465640000000000000000604482015290519081900360640190fd5b60608c8c8080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f82011690508083019250505050505050905060608b8b8080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250506040805163cba510a960e01b81526001600160401b038f1660048201529051939450610cce93611003935063cba510a992506024808301926020929190829003018186803b158015610c7757600080fd5b505afa158015610c8b573d6000803e3d6000fd5b505050506040513d6020811015610ca157600080fd5b505160408051808201909152600381526269626360e81b6020820152610cc78c8c612636565b858561267d565b610d16576040805162461bcd60e51b815260206004820152601460248201527334b73b30b634b21036b2b935b63290383937b7b360611b604482015290519081900360640190fd5b60408051631bb5062960e31b81526001600160401b038c16600482015290516000916110039163dda8314891602480820192602092909190829003018186803b158015610d6257600080fd5b505afa158015610d76573d6000803e3d6000fd5b505050506040513d6020811015610d8c57600080fd5b5051905088600080806060610da08861277a565b935093509350935083610e61578460ff168f6001600160401b03167ff7b2e42d694eb1100184aae86d4245d9e46966100b1dc7e723275b98326854ac8a6040518080602001828103825283818151815260200191508051906020019080838360005b83811015610e1a578181015183820152602001610e02565b50505050905090810190601f168015610e475780820380516001836020036101000a031916815260200191505b509250505060405180910390a35050505050505050611a7f565b8460ff168f6001600160401b03167f36afdaf439a8f43fe72135135d804ae620b37a474f0943b5b85f6788312cad4085604051808260ff1660ff16815260200191505060405180910390a360ff83166113ea5760ff85166000818152600560209081526040808320548151631182b87560e01b815260048101958652602481019283528651604482015286516001600160a01b03909216958695631182b875958d958a9593949093606490910192918601918190849084905b83811015610f32578181015183820152602001610f1a565b50505050905090810190601f168015610f5f5780820380516001836020036101000a031916815260200191505b509350505050600060405180830381600087803b158015610f7f57600080fd5b505af192505050801561106357506040513d6000823e601f3d908101601f191682016040526020811015610fb257600080fd5b8101908080516040519392919084600160201b821115610fd157600080fd5b908301906020820185811115610fe657600080fd5b8251600160201b811182820188101715610fff57600080fd5b82525081516020918201929091019080838360005b8381101561102c578181015183820152602001611014565b50505050905090810190601f1680156110595780820380516001836020036101000a031916815260200191505b5060405250505060015b611375576040516000815260443d101561107f5750600061111a565b60046000803e60005160e01c6308c379a081146110a057600091505061111a565b60043d036004833e81513d60248201116001600160401b03821117156110cb5760009250505061111a565b80830180516001600160401b038111156110ec57600094505050505061111a565b8060208301013d860181111561110a5760009550505050505061111a565b601f01601f191660405250925050505b806111255750611237565b60ff871660009081526007602052604081205461115c916001600160401b039091169089906111579060029088610800565b61282a565b60ff8716600090815260076020908152604080832080546001600160401b038082166001011667ffffffffffffffff19909116179055805182815284518184015284516001600160a01b038716947ff91a8f63e5b3e0e89e5f93e1915a7805f3c52d9a73b3c09769785c2c7bf87acf948794849390840192918601918190849084905b838110156111f75781810151838201526020016111df565b50505050905090810190601f1680156112245780820380516001836020036101000a031916815260200191505b509250505060405180910390a250611370565b3d808015611261576040519150601f19603f3d011682016040523d82523d6000602084013e611266565b606091505b5060ff8716600090815260076020526040812054611299916001600160401b039091169089906111579060029088610800565b60ff8716600090815260076020908152604080832080546001600160401b038082166001011667ffffffffffffffff19909116179055805182815284518184015284516001600160a01b038716947f63ac299d6332d1cc4e61b81e59bc00c0ac7c798addadf33840f1307cd2977351948794849390840192918601918190849084905b8381101561133457818101518382015260200161131c565b50505050905090810190601f1680156113615780820380516001836020036101000a031916815260200191505b509250505060405180910390a2505b6113e4565b8051156113e25760ff87166000908152600760205260408120546113ae916001600160401b039091169089906111579060019086610800565b60ff8716600090815260076020526040902080546001600160401b038082166001011667ffffffffffffffff199091161790555b505b506119b8565b60ff83166001141561168e5760ff8516600081815260056020908152604080832054815163831d65d160e01b815260048101958652602481019283528651604482015286516001600160a01b0390921695869563831d65d1958d958a9593949093606490910192918601918190849084905b8381101561147457818101518382015260200161145c565b50505050905090810190601f1680156114a15780820380516001836020036101000a031916815260200191505b509350505050600060405180830381600087803b1580156114c157600080fd5b505af19250505080156114d2575060015b6113e4576040516000815260443d10156114ee57506000611589565b60046000803e60005160e01c6308c379a0811461150f576000915050611589565b60043d036004833e81513d60248201116001600160401b038211171561153a57600092505050611589565b80830180516001600160401b0381111561155b576000945050505050611589565b8060208301013d860181111561157957600095505050505050611589565b601f01601f191660405250925050505b8061159457506115f9565b60408051602080825283518183015283516001600160a01b038616937ff91a8f63e5b3e0e89e5f93e1915a7805f3c52d9a73b3c09769785c2c7bf87acf93869390928392830191850190808383600083156111f75781810151838201526020016111df565b3d808015611623576040519150601f19603f3d011682016040523d82523d6000602084013e611628565b606091505b5060408051602080825283518183015283516001600160a01b038616937f63ac299d6332d1cc4e61b81e59bc00c0ac7c798addadf33840f1307cd2977351938693909283928301918501908083836000831561133457818101518382015260200161131c565b60ff8316600214156119b85760ff8516600081815260056020908152604080832054815163c8509d8160e01b815260048101958652602481019283528651604482015286516001600160a01b0390921695869563c8509d81958d958a9593949093606490910192918601918190849084905b83811015611718578181015183820152602001611700565b50505050905090810190601f1680156117455780820380516001836020036101000a031916815260200191505b509350505050600060405180830381600087803b15801561176557600080fd5b505af1925050508015611776575060015b6119b6576040516000815260443d10156117925750600061182d565b60046000803e60005160e01c6308c379a081146117b357600091505061182d565b60043d036004833e81513d60248201116001600160401b03821117156117de5760009250505061182d565b80830180516001600160401b038111156117ff57600094505050505061182d565b8060208301013d860181111561181d5760009550505050505061182d565b601f01601f191660405250925050505b8061183857506118e1565b816001600160a01b03167ff91a8f63e5b3e0e89e5f93e1915a7805f3c52d9a73b3c09769785c2c7bf87acf826040518080602001828103825283818151815260200191508051906020019080838360005b838110156118a1578181015183820152602001611889565b50505050905090810190601f1680156118ce5780820380516001836020036101000a031916815260200191505b509250505060405180910390a2506119b6565b3d80801561190b576040519150601f19603f3d011682016040523d82523d6000602084013e611910565b606091505b50816001600160a01b03167f63ac299d6332d1cc4e61b81e59bc00c0ac7c798addadf33840f1307cd2977351826040518080602001828103825283818151815260200191508051906020019080838360005b8381101561197a578181015183820152602001611962565b50505050905090810190601f1680156119a75780820380516001836020036101000a031916815260200191505b509250505060405180910390a2505b505b60ff80861660009081526009602052604090205461100591636f93d2e69189913391879116806119ea575060ff881615155b604080516001600160e01b031960e088901b1681526001600160a01b039586166004820152939094166024840152604483019190915215156064820152905160848083019260209291908290030181600087803b158015611a4a57600080fd5b505af1158015611a5e573d6000803e3d6000fd5b505050506040513d6020811015611a7457600080fd5b505050505050505050505b505050505050505050505050565b630100380081565b600981565b61100781565b61100681565b60005460ff1681565b3361100714611aef5760405162461bcd60e51b815260040180806020018281038252602e815260200180612b22602e913960400191505060405180910390fd5b611b5884848080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525050604080518082019091526012815271626174636853697a65466f724f7261636c6560701b602082015291506129809050565b15611bf357604080516020601f8401819004810282018101909252828152600091611b9b91858580838501838280828437600092019190915250612a6792505050565b90506127108111158015611bb05750600a8110155b611beb5760405162461bcd60e51b8152600401808060200182810382526032815260200180612b9a6032913960400191505060405180910390fd5b600155611fbf565b611c5c84848080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152505060408051808201909152601281527118591913dc955c19185d1950da185b9b995b60721b602082015291506129809050565b15611de457606082828080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152505082519293505060169091149050611cdf5760405162461bcd60e51b815260040180806020018281038252605a815260200180612ac8605a913960600191505060405180910390fd5b60018101516002820151601683015160ff82161590611cfd81612a6c565b611d4e576040805162461bcd60e51b815260206004820152601960248201527f61646472657373206973206e6f74206120636f6e747261637400000000000000604482015290519081900360640190fd5b60ff8416600081815260056020908152604080832080546001600160a01b0319166001600160a01b038716908117909155808452600683528184208585528352818420805460ff199081166001179091556009909352818420805490931687151517909255519092917f7e3b6af43092577ee20e60eaa1d9b114a7031305c895ee7dd3ffe17196d2e1e091a35050505050611fbf565b611e5184848080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525050604080518082019091526016815275195b98589b1953dc911a5cd8589b1950da185b9b995b60521b602082015291506129809050565b15611f8257606082828080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152505082519293505060029091149050611ed45760405162461bcd60e51b815260040180806020018281038252604a815260200180612b50604a913960600191505060405180910390fd5b600181810151600283015160ff80831660009081526005602052604090205492939192908316909114906001600160a01b03168015611f78576001600160a01b038116600090815260066020908152604080832060ff881680855290835292819020805460ff1916861515908117909155815190815290517fa3132e3f9819fbddc7f0ed6d38d7feef59aa95112090b7c592f5cb5bc4aa4adc929181900390910190a25b5050505050611fbf565b6040805162461bcd60e51b815260206004820152600d60248201526c756e6b6e6f776e20706172616d60981b604482015290519081900360640190fd5b7f6cdb0ac70ab7f2e2d035cca5be60d89906f2dede7648ddbd7402189c1eeed17a848484846040518080602001806020018381038352878782818152602001925080828437600083820152601f01601f191690910184810383528581526020019050858580828437600083820152604051601f909101601f19169092018290039850909650505050505050a150505050565b6008602052600090815260409020546001600160401b031681565b61100281565b600660209081526000928352604080842090915290825290205460ff1681565b6040518060400160405280600381526020016269626360e81b81525081565b61100381565b60005460ff161561210f576040805162461bcd60e51b815260206004820152601960248201527f74686520636f6e747261637420616c726561647920696e697400000000000000604482015290519081900360640190fd5b7f1471eb6eb2c5e789fc3de43f8ce62938c7d1836ec861730447e2ada8fd81017b80546001600160a01b0319908116611008179091557f92e85d02570a8092d09a6e3a57665bc3815a2699a4074001bf1ccabf660f5a36805460ff199081169091557fd8af288fc1c8680b4f4706064cf021e264efb6828fcaf7eb5ca36818eb365bcc8054821660019081179091557f89832631fb3c3307a103ba2c84ab569c64d6182a18893dcd163f0f1c2090733a805484166110049081179091557f6cde3cea4b3a3fb2488b2808bae7556f4a405e50f65e1794383bc026131b13c38054841690557f72e4efa1513b071517c6c74dba31b5934a81aa83cddd400e7081df5529c9943680548416831790557fa9bc9a3a348c357ba16b37005d7e6b3236198c0e939f4af8c5f19b8deeb8ebc08054851690911790557fc575c31fea594a6eb97c8e9d3f9caee4c16218c6ef37e923234c0fe9014a61e78054831690557f4e523af77f034e9810f1c94057f5e931fb3d16a51511a4c3add793617d18610580548316821790557ffb33122aa9f93cc639ebe80a7bc4784c11e6053dde89c6f4f7e268c6a623da1e805484166110001790557fc7694af312c4f286114180fd0ba6a52461fcee8a381636770b19a343af92538a80548316821790557f01112dd68e482ba8d68a7e828cff8b3abcea08eab88941953c180a7e650e9cd480548316821790557fc0a4a8be475dfebc377ebef2d7c4ff47656f572a08dd92b81017efcdba0febe1805484166110071790557f87e8a52529e8ece4ef759037313542a6429ff494a9fab9027fb79db90124eba680548316821790557f4c7666bbcb22d46469f7cc282f70764a7012dca2cce630ff8d83db9a9cdd48f080548316821790557f40f28f99a40bc9f6beea1013afdbc3cdcc689eb76b82c4de06c0acf1e1932ed58054909316611001179092557f0d9cf2cd531699eed8dd34e40ff2884a14a698c4898184fba85194e6f6772d248054821683179055600b60009081527f23f68c9bd22b8a93d06adabe17481c87c016bcbd20adc8bfd707a4d813a572176020527fdf0d5d05428057f5455c2dc8e810dd86d1e9350faa72f16bda8a45443c5b39328054831684179055603283556004805467ffffffffffffffff19166001600160401b031790556002819055600381905580549091169091179055565b6007602052600090815260409020546001600160401b031681565b60005460ff166124dc576040805162461bcd60e51b81526020600482015260196024820152781d1a194818dbdb9d1c9858dd081b9bdd081a5b9a5d081e595d603a1b604482015290519081900360640190fd5b33600090815260066020908152604080832060ff80891685529252909120548591166125395760405162461bcd60e51b8152600401808060200182810382526031815260200180612a976031913960400191505060405180910390fd5b60ff85166000908152600760209081526040808320548151601f88018490048402810184019092528682526001600160401b03169261259e9284928a9261115792909189918c908c908190840183828082843760009201919091525061080092505050565b60ff959095166000908152600760205260409020805467ffffffffffffffff191660019096016001600160401b03169590951790945550505050565b61100081565b600381565b61100481565b8051602090910191565b5b60208110612615578251825260209283019290910190601f19016125f6565b915181516020939093036101000a6000190180199091169216919091179052565b60408051600e808252818301909252606091630100380060ff851617918391602082018180368337505050600e818101969096526006810192909252509283525090919050565b60008561268c57506000612771565b606082518451865160800101016040519080825280601f01601f1916602001820160405280156126c3576020820181803683370190505b50905060006126d182612a72565b6020808901518252019050866000806126e9896125eb565b80865260209095019490925090506127028285836125f5565b9283019261270f886125eb565b80865260209095019490925090506127288285836125f5565b9283018a81526020019261273b876125eb565b909250905061274b8285836125f5565b508351602001612759612a78565b60208183886065600019fa5051600114955050505050505b95945050505050565b600080600060606021855110156127aa575050604080516000808252602082019092529092508291508190612823565b600185015160218601518651604080516020198301808252601f19600119909401939093168101602001909152604189019392916060919080156127f5576020820181803683370190505b5090506000612803826125eb565b509050612815858260218d51036125f5565b506001975091955093509150505b9193509193565b600254431115612869576004805467ffffffffffffffff1981166001600160401b036001600793840b810190930b1617909155600355436002556128aa565b600380546001908101918290555410156128aa576004805467ffffffffffffffff1981166001600160401b036001600793840b810190930b16179091556003555b8160ff16836001600160401b0316600460009054906101000a900460070b6001600160401b03167f3a6e0fc61675aa2a100bcba0568368bb92bcec91c97673391074f11138f0cffe603885604051808361ffff1661ffff16815260200180602001828103825283818151815260200191508051906020019080838360005b83811015612940578181015183820152602001612928565b50505050905090810190601f16801561296d5780820380516001836020036101000a031916815260200191505b50935050505060405180910390a4505050565b6000816040516020018082805190602001908083835b602083106129b55780518252601f199092019160209182019101612996565b6001836020036101000a03801982511681845116808217855250505050505090500191505060405160208183030381529060405280519060200120836040516020018082805190602001908083835b60208310612a235780518252601f199092019160209182019101612a04565b6001836020036101000a0380198251168184511680821785525050505050509050019150506040516020818303038152906040528051906020012014905092915050565b015190565b3b151590565b60200190565b6040518060200160405280600190602082028036833750919291505056fe74686520636f6e747261637420616e64206368616e6e656c2068617665206e6f74206265656e20726567697374657265646c656e677468206f662076616c756520666f72206164644f725570646174654368616e6e656c2073686f756c642062652032322c206368616e6e656c49643a697346726f6d53797374656d3a68616e646c657241646472657373746865206d6573736167652073656e646572206d75737420626520676f7665726e616e636520636f6e74726163746c656e677468206f662076616c756520666f7220656e61626c654f7244697361626c654368616e6e656c2073686f756c6420626520322c206368616e6e656c49643a6973456e61626c65746865206e6577426174636853697a65466f724f7261636c652073686f756c6420626520696e205b31302c2031303030305d6c6967687420636c69656e74206e6f742073796e632074686520626c6f636b20796574a264697066735822122083f6194f9a326fa5963aa39ffe11dcd28d1421a9f74fbe97a97f4853026e29ff64736f6c63430006040033" - }, - "b005741528b86F5952469d80A8614591E3c5B632": { - "balance": "0x1b1ae4d6e2ef500000" - }, - "446AA6E0DC65690403dF3F127750da1322941F3e": { - "balance": "0x1b1ae4d6e2ef500000" - } + "0xffffFFFfFFffffffffffffffFfFFFfffFFFfFFfE": { + "balance": "0x0" + }, + "0x0000000000000000000000000000000000001000": { + "balance": "0x0", + "code": "0x60806040526004361061027d5760003560e01c80639dc092621161014f578063c8509d81116100c1578063eb57e2021161007a578063eb57e20214610940578063eda5868c14610973578063f340fa0114610988578063f9a2bbc7146109ae578063fc3e5908146109c3578063fd6a6879146109d85761027d565b8063c8509d8114610609578063d86222d5146108d7578063daacdb66146108ec578063dc927faf14610901578063e086c7b114610916578063e1c7392a1461092b5761027d565b8063ab51bb9611610113578063ab51bb961461074a578063ac4317511461075f578063ad3c9da61461082a578063b7ab4db51461085d578063bf9f49951461041b578063c81b1662146108c25761027d565b80639dc09262146106cd578063a1a11bf5146106e2578063a5422d5c146106f7578063a78abc161461070c578063aaf5eb68146107355761027d565b80635667515a116101f35780637942fd05116101ac5780637942fd05146105df57806381650b62146105f4578063831d65d114610609578063853230aa1461068e57806386249882146106a357806396713da9146106b85761027d565b80635667515a146105005780635d77156c146105155780636969a25c1461052a5780636e47b482146105a057806370fd5bad146105b557806375d47a0a146105ca5761027d565b80633dffc387116102455780633dffc3871461041b57806343756e5c14610446578063493279b1146104775780634bf6c882146104a357806351e80672146104b8578063565c56b3146104cd5761027d565b80630bee7a67146102825780631182b875146102b05780631ff18069146103aa578063219f22d5146103d157806335409f7f146103e6575b600080fd5b34801561028e57600080fd5b506102976109ed565b6040805163ffffffff9092168252519081900360200190f35b3480156102bc57600080fd5b50610335600480360360408110156102d357600080fd5b60ff8235169190810190604081016020820135600160201b8111156102f757600080fd5b82018360208201111561030957600080fd5b803590602001918460018302840111600160201b8311171561032a57600080fd5b5090925090506109f2565b6040805160208082528351818301528351919283929083019185019080838360005b8381101561036f578181015183820152602001610357565b50505050905090810190601f16801561039c5780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b3480156103b657600080fd5b506103bf610bdf565b60408051918252519081900360200190f35b3480156103dd57600080fd5b50610297610be5565b3480156103f257600080fd5b506104196004803603602081101561040957600080fd5b50356001600160a01b0316610bea565b005b34801561042757600080fd5b50610430610efe565b6040805160ff9092168252519081900360200190f35b34801561045257600080fd5b5061045b610f03565b604080516001600160a01b039092168252519081900360200190f35b34801561048357600080fd5b5061048c610f09565b6040805161ffff9092168252519081900360200190f35b3480156104af57600080fd5b50610430610f0e565b3480156104c457600080fd5b5061045b610f13565b3480156104d957600080fd5b506103bf600480360360208110156104f057600080fd5b50356001600160a01b0316610f19565b34801561050c57600080fd5b50610430610f6b565b34801561052157600080fd5b50610297610f70565b34801561053657600080fd5b506105546004803603602081101561054d57600080fd5b5035610f75565b604080516001600160a01b039788168152958716602087015293909516848401526001600160401b0390911660608401521515608083015260a082019290925290519081900360c00190f35b3480156105ac57600080fd5b5061045b610fd9565b3480156105c157600080fd5b50610430610fdf565b3480156105d657600080fd5b5061045b610fe4565b3480156105eb57600080fd5b50610430610fea565b34801561060057600080fd5b50610297610fef565b34801561061557600080fd5b506104196004803603604081101561062c57600080fd5b60ff8235169190810190604081016020820135600160201b81111561065057600080fd5b82018360208201111561066257600080fd5b803590602001918460018302840111600160201b8311171561068357600080fd5b509092509050610ff4565b34801561069a57600080fd5b506103bf6110a7565b3480156106af57600080fd5b506103bf6110ad565b3480156106c457600080fd5b506104306110b3565b3480156106d957600080fd5b5061045b6110b8565b3480156106ee57600080fd5b5061045b6110be565b34801561070357600080fd5b506103356110c4565b34801561071857600080fd5b506107216110e3565b604080519115158252519081900360200190f35b34801561074157600080fd5b506103bf6110ec565b34801561075657600080fd5b50610297610f6b565b34801561076b57600080fd5b506104196004803603604081101561078257600080fd5b810190602081018135600160201b81111561079c57600080fd5b8201836020820111156107ae57600080fd5b803590602001918460018302840111600160201b831117156107cf57600080fd5b919390929091602081019035600160201b8111156107ec57600080fd5b8201836020820111156107fe57600080fd5b803590602001918460018302840111600160201b8311171561081f57600080fd5b5090925090506110f5565b34801561083657600080fd5b506103bf6004803603602081101561084d57600080fd5b50356001600160a01b031661139c565b34801561086957600080fd5b506108726113ae565b60408051602080825283518183015283519192839290830191858101910280838360005b838110156108ae578181015183820152602001610896565b505050509050019250505060405180910390f35b3480156108ce57600080fd5b5061045b6114d4565b3480156108e357600080fd5b506103bf6114da565b3480156108f857600080fd5b506103bf6114e6565b34801561090d57600080fd5b5061045b6114ec565b34801561092257600080fd5b506103bf6114f2565b34801561093757600080fd5b506104196114f7565b34801561094c57600080fd5b506104196004803603602081101561096357600080fd5b50356001600160a01b03166116fa565b34801561097f57600080fd5b506102976118c9565b6104196004803603602081101561099e57600080fd5b50356001600160a01b03166118ce565b3480156109ba57600080fd5b5061045b611b04565b3480156109cf57600080fd5b50610430611b0a565b3480156109e457600080fd5b5061045b611b0f565b606481565b60005460609060ff16610a48576040805162461bcd60e51b81526020600482015260196024820152781d1a194818dbdb9d1c9858dd081b9bdd081a5b9a5d081e595d603a1b604482015290519081900360640190fd5b3361200014610a885760405162461bcd60e51b815260040180806020018281038252602f815260200180614516602f913960400191505060405180910390fd5b610a90613d69565b6000610ad185858080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250611b1592505050565b9150915080610aed57610ae46064611c6e565b92505050610bd8565b815160009060ff16610b0d57610b068360200151611ccf565b9050610ba4565b825160ff1660011415610ba057826020015151600114610b7a577f70e72399380dcfb0338abc03dc8d47f9f470ada8e769c9a78d644ea97385ecb2604051808060200182810382526025815260200180613e6c6025913960400191505060405180910390a1506067610b9b565b610b068360200151600081518110610b8e57fe5b6020026020010151612ad5565b610ba4565b5060655b63ffffffff8116610bc95750506040805160008152602081019091529150610bd89050565b610bd281611c6e565b93505050505b9392505050565b60035481565b606881565b3361100114610c2a5760405162461bcd60e51b81526004018080602001828103825260298152602001806145726029913960400191505060405180910390fd5b6001600160a01b03811660009081526004602052604090205480610c4e5750610efb565b600181039050600060018281548110610c6357fe5b60009182526020909120600360049092020101546001549091506000190180610cb257600060018481548110610c9557fe5b906000526020600020906004020160030181905550505050610efb565b6040805183815290516001600160a01b038616917f3b6f9ef90462b512a1293ecec018670bf7b7f1876fb727590a8a6d7643130a70919081900360200190a26001600160a01b038416600090815260046020526040812055600154600019018314610e3457600180546000198101908110610d2957fe5b906000526020600020906004020160018481548110610d4457fe5b6000918252602082208354600492830290910180546001600160a01b03199081166001600160a01b0393841617825560018087015481840180548416918616919091179055600280880180549185018054909416919095161780835584546001600160401b03600160a01b91829004160267ffffffffffffffff60a01b1990911617808355935460ff600160e01b918290041615150260ff60e01b199094169390931790556003948501549401939093558254868401939192919087908110610e0957fe5b600091825260208083206004909202909101546001600160a01b031683528201929092526040019020555b6001805480610e3f57fe5b60008281526020812060046000199093019283020180546001600160a01b0319908116825560018201805490911690556002810180546001600160e81b03191690556003018190559155818381610e9257fe5b0490508015610ef65760015460005b81811015610ef3578260018281548110610eb757fe5b9060005260206000209060040201600301540160018281548110610ed757fe5b6000918252602090912060036004909202010155600101610ea1565b50505b505050505b50565b600181565b61100181565b603881565b600881565b61200081565b6001600160a01b03811660009081526004602052604081205480610f41576000915050610f66565b600180820381548110610f5057fe5b9060005260206000209060040201600301549150505b919050565b600081565b606781565b60018181548110610f8257fe5b600091825260209091206004909102018054600182015460028301546003909301546001600160a01b0392831694509082169291821691600160a01b81046001600160401b031691600160e01b90910460ff169086565b61100581565b600281565b61100881565b600b81565b606681565b33612000146110345760405162461bcd60e51b815260040180806020018281038252602f815260200180614516602f913960400191505060405180910390fd5b7f41ce201247b6ceb957dcdb217d0b8acb50b9ea0e12af9af4f5e7f38902101605838383604051808460ff1660ff168152602001806020018281038252848482818152602001925080828437600083820152604051601f909101601f1916909201829003965090945050505050a1505050565b6103e881565b60025481565b600981565b61100781565b61100681565b6040518061062001604052806105ef8152602001613f276105ef913981565b60005460ff1681565b6402540be40081565b60005460ff16611148576040805162461bcd60e51b81526020600482015260196024820152781d1a194818dbdb9d1c9858dd081b9bdd081a5b9a5d081e595d603a1b604482015290519081900360640190fd5b33611007146111885760405162461bcd60e51b815260040180806020018281038252602e815260200180613e91602e913960400191505060405180910390fd5b6111f284848080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525050604080518082019091526013815272065787069726554696d655365636f6e6447617606c1b60208201529150612c4c9050565b156112cd57602081146112365760405162461bcd60e51b8152600401808060200182810382526026815260200180613ee06026913960400191505060405180910390fd5b604080516020601f840181900481028201810190925282815260009161127491858580838501838280828437600092019190915250612d3492505050565b90506064811015801561128a5750620186a08111155b6112c55760405162461bcd60e51b8152600401808060200182810382526027815260200180613e456027913960400191505060405180910390fd5b60025561130a565b6040805162461bcd60e51b815260206004820152600d60248201526c756e6b6e6f776e20706172616d60981b604482015290519081900360640190fd5b7f6cdb0ac70ab7f2e2d035cca5be60d89906f2dede7648ddbd7402189c1eeed17a848484846040518080602001806020018381038352878782818152602001925080828437600083820152601f01601f191690910184810383528581526020019050858580828437600083820152604051601f909101601f19169092018290039850909650505050505050a150505050565b60046020526000908152604090205481565b6001546060906000805b828110156113ff57600181815481106113cd57fe5b9060005260206000209060040201600201601c9054906101000a900460ff166113f7576001909101905b6001016113b8565b5060608160405190808252806020026020018201604052801561142c578160200160208202803683370190505b50600092509050815b838110156114cc576001818154811061144a57fe5b9060005260206000209060040201600201601c9054906101000a900460ff166114c4576001818154811061147a57fe5b600091825260209091206004909102015482516001600160a01b03909116908390859081106114a557fe5b6001600160a01b03909216602092830291909101909101526001909201915b600101611435565b509250505090565b61100281565b67016345785d8a000081565b60055481565b61100381565b602981565b60005460ff161561154f576040805162461bcd60e51b815260206004820152601960248201527f74686520636f6e747261637420616c726561647920696e697400000000000000604482015290519081900360640190fd5b611557613d69565b600061157d6040518061062001604052806105ef8152602001613f276105ef9139611b15565b91509150806115bd5760405162461bcd60e51b8152600401808060200182810382526021815260200180613f066021913960400191505060405180910390fd5b60005b8260200151518110156116e2576001836020015182815181106115df57fe5b60209081029190910181015182546001818101855560009485528385208351600493840290910180546001600160a01b039283166001600160a01b03199182161782558587015182850180549185169183169190911790556040860151600283018054606089015160808a01511515600160e01b0260ff60e01b196001600160401b03909216600160a01b0267ffffffffffffffff60a01b199590981692909516919091179290921694909417161790915560a0909301516003909301929092559186015180519185019391859081106116b557fe5b602090810291909101810151516001600160a01b03168252810191909152604001600020556001016115c0565b50506103e8600255506000805460ff19166001179055565b336110011461173a5760405162461bcd60e51b81526004018080602001828103825260298152602001806145726029913960400191505060405180910390fd5b6001600160a01b0381166000908152600460205260409020548061175e5750610efb565b60018103905060006001828154811061177357fe5b906000526020600020906004020160030154905060006001838154811061179657fe5b906000526020600020906004020160030181905550600060018080549050039050836001600160a01b03167f8cd4e147d8af98a9e3b6724021b8bf6aed2e5dac71c38f2dce8161b82585b25d836040518082815260200191505060405180910390a28061180557505050610efb565b600081838161181057fe5b0490508015610ef65760005b8481101561186e57816001828154811061183257fe5b906000526020600020906004020160030154016001828154811061185257fe5b600091825260209091206003600490920201015560010161181c565b50600180549085015b81811015610ef357826001828154811061188d57fe5b90600052602060002090600402016003015401600182815481106118ad57fe5b6000918252602090912060036004909202010155600101611877565b606581565b33411461190c5760405162461bcd60e51b815260040180806020018281038252602d815260200180614545602d913960400191505060405180910390fd5b60005460ff1661195f576040805162461bcd60e51b81526020600482015260196024820152781d1a194818dbdb9d1c9858dd081b9bdd081a5b9a5d081e595d603a1b604482015290519081900360640190fd5b600034116119ac576040805162461bcd60e51b81526020600482015260156024820152746465706f7369742076616c7565206973207a65726f60581b604482015290519081900360640190fd5b6001600160a01b03811660009081526004602052604090205434908015611abf5760006001808303815481106119de57fe5b9060005260206000209060040201905080600201601c9054906101000a900460ff1615611a49576040805184815290516001600160a01b038616917ff177e5d6c5764d79c32883ed824111d9b13f5668cf6ab1cc12dd36791dd955b4919081900360200190a2611ab9565b600354611a5c908463ffffffff612d3916565b6003908155810154611a74908463ffffffff612d3916565b60038201556040805184815290516001600160a01b038616917f93a090ecc682c002995fad3c85b30c5651d7fd29b0be5da9d784a3302aedc055919081900360200190a25b50611aff565b6040805183815290516001600160a01b038516917ff177e5d6c5764d79c32883ed824111d9b13f5668cf6ab1cc12dd36791dd955b4919081900360200190a25b505050565b61100081565b600381565b61100481565b611b1d613d69565b6000611b27613d69565b611b2f613d81565b611b40611b3b86612d93565b612db8565b90506000805b611b4f83612e02565b15611c605780611b7457611b6a611b6584612e23565b612e71565b60ff168452611c58565b8060011415611c53576060611b90611b8b85612e23565b612f28565b90508051604051908082528060200260200182016040528015611bcd57816020015b611bba613da1565b815260200190600190039081611bb25790505b50602086015260005b8151811015611c4857611be7613da1565b6000611c05848481518110611bf857fe5b6020026020010151612ff9565b9150915080611c2257876000995099505050505050505050611c69565b8188602001518481518110611c3357fe5b60209081029190910101525050600101611bd6565b506001925050611c58565b611c60565b600101611b46565b50919350909150505b915091565b604080516001808252818301909252606091829190816020015b6060815260200190600190039081611c88579050509050611cae8363ffffffff166130d6565b81600081518110611cbb57fe5b6020026020010181905250610bd8816130e9565b6000806060611cdd84613173565b9150915081611d8a577f70e72399380dcfb0338abc03dc8d47f9f470ada8e769c9a78d644ea97385ecb2816040518080602001828103825283818151815260200191508051906020019080838360005b83811015611d45578181015183820152602001611d2d565b50505050905090810190601f168015611d725780820380516001836020036101000a031916815260200191505b509250505060405180910390a1606692505050610f66565b600080805b600154811015611e075767016345785d8a000060018281548110611daf57fe5b90600052602060002090600402016003015410611dd157600190920191611dff565b600060018281548110611de057fe5b9060005260206000209060040201600301541115611dff576001909101905b600101611d8f565b50606082604051908082528060200260200182016040528015611e34578160200160208202803683370190505b509050606083604051908082528060200260200182016040528015611e63578160200160208202803683370190505b509050606084604051908082528060200260200182016040528015611e92578160200160208202803683370190505b509050606085604051908082528060200260200182016040528015611ec1578160200160208202803683370190505b5090506000606086604051908082528060200260200182016040528015611ef2578160200160208202803683370190505b509050606087604051908082528060200260200182016040528015611f21578160200160208202803683370190505b509050600098506000975060608d905060006110046001600160a01b031663149d14d96040518163ffffffff1660e01b815260040160206040518083038186803b158015611f6e57600080fd5b505afa158015611f82573d6000803e3d6000fd5b505050506040513d6020811015611f9857600080fd5b5051905067016345785d8a000081111561200d577f70e72399380dcfb0338abc03dc8d47f9f470ada8e769c9a78d644ea97385ecb2604051808060200182810382526021815260200180613ebf6021913960400191505060405180910390a160689d5050505050505050505050505050610f66565b60005b6001548110156122805767016345785d8a00006001828154811061203057fe5b906000526020600020906004020160030154106121b6576001818154811061205457fe5b906000526020600020906004020160020160009054906101000a90046001600160a01b03168a8d8151811061208557fe5b60200260200101906001600160a01b031690816001600160a01b03168152505060006402540be400600183815481106120ba57fe5b906000526020600020906004020160030154816120d357fe5b06600183815481106120e157fe5b906000526020600020906004020160030154039050612109838261325590919063ffffffff16565b8a8e8151811061211557fe5b6020026020010181815250506001828154811061212e57fe5b906000526020600020906004020160020160009054906101000a90046001600160a01b0316888e8151811061215f57fe5b60200260200101906001600160a01b031690816001600160a01b03168152505081898e8151811061218c57fe5b60209081029190910101526121a7878263ffffffff612d3916565b6001909d019c96506122789050565b6000600182815481106121c557fe5b906000526020600020906004020160030154111561227857600181815481106121ea57fe5b906000526020600020906004020160010160009054906101000a90046001600160a01b0316858c8151811061221b57fe5b60200260200101906001600160a01b031690816001600160a01b0316815250506001818154811061224857fe5b906000526020600020906004020160030154848c8151811061226657fe5b60209081029190910101526001909a01995b600101612010565b50600085156126be576110046001600160a01b0316636e056520878c8c8b60025442016040518663ffffffff1660e01b815260040180806020018060200180602001856001600160401b03166001600160401b03168152602001848103845288818151815260200191508051906020019060200280838360005b838110156123125781810151838201526020016122fa565b50505050905001848103835287818151815260200191508051906020019060200280838360005b83811015612351578181015183820152602001612339565b50505050905001848103825286818151815260200191508051906020019060200280838360005b83811015612390578181015183820152602001612378565b505050509050019750505050505050506020604051808303818588803b1580156123b957600080fd5b505af1935050505080156123df57506040513d60208110156123da57600080fd5b505160015b61261a576040516000815260443d10156123fb57506000612496565b60046000803e60005160e01c6308c379a0811461241c576000915050612496565b60043d036004833e81513d60248201116001600160401b038211171561244757600092505050612496565b80830180516001600160401b03811115612468576000945050505050612496565b8060208301013d860181111561248657600095505050505050612496565b601f01601f191660405250925050505b806124a15750612545565b60019150867fa7cdeed7d0db45e3219a6e5d60838824c16f1d39991fcfe3f963029c844bf280826040518080602001828103825283818151815260200191508051906020019080838360005b838110156125055781810151838201526020016124ed565b50505050905090810190601f1680156125325780820380516001836020036101000a031916815260200191505b509250505060405180910390a250612615565b3d80801561256f576040519150601f19603f3d011682016040523d82523d6000602084013e612574565b606091505b5060019150867fbfa884552dd8921b6ce90bfe906952ae5b3b29be0cc1a951d4f62697635a3a45826040518080602001828103825283818151815260200191508051906020019080838360005b838110156125d95781810151838201526020016125c1565b50505050905090810190601f1680156126065780820380516001836020036101000a031916815260200191505b509250505060405180910390a2505b6126be565b8015612658576040805188815290517fa217d08e65f80c73121cd9db834d81652d544bfbf452f6d04922b16c90a37b709181900360200190a16126bc565b604080516020808252601b908201527f6261746368207472616e736665722072657475726e2066616c7365000000000081830152905188917fa7cdeed7d0db45e3219a6e5d60838824c16f1d39991fcfe3f963029c844bf280919081900360600190a25b505b80156128745760005b88518110156128725760008982815181106126de57fe5b602002602001015190506000600182815481106126f757fe5b60009182526020909120600160049092020181015481546001600160a01b03909116916108fc918590811061272857fe5b9060005260206000209060040201600301549081150290604051600060405180830381858888f19350505050905080156127e4576001828154811061276957fe5b60009182526020909120600160049092020181015481546001600160a01b03909116917f6c61d60f69a7beb3e1c80db7f39f37b208537cbb19da3174511b477812b2fc7d91859081106127b857fe5b9060005260206000209060040201600301546040518082815260200191505060405180910390a2612868565b600182815481106127f157fe5b60009182526020909120600160049092020181015481546001600160a01b03909116917f25d0ce7d2f0cec669a8c17efe49d195c13455bb8872b65fa610ac7f53fe4ca7d918590811061284057fe5b9060005260206000209060040201600301546040518082815260200191505060405180910390a25b50506001016126c7565b505b8451156129be5760005b85518110156129bc57600086828151811061289557fe5b60200260200101516001600160a01b03166108fc8784815181106128b557fe5b60200260200101519081150290604051600060405180830381858888f193505050509050801561294b578682815181106128eb57fe5b60200260200101516001600160a01b03167f6c61d60f69a7beb3e1c80db7f39f37b208537cbb19da3174511b477812b2fc7d87848151811061292957fe5b60200260200101516040518082815260200191505060405180910390a26129b3565b86828151811061295757fe5b60200260200101516001600160a01b03167f25d0ce7d2f0cec669a8c17efe49d195c13455bb8872b65fa610ac7f53fe4ca7d87848151811061299557fe5b60200260200101516040518082815260200191505060405180910390a25b5060010161287e565b505b4715612a27576040805147815290517f6ecc855f9440a9282c90913bbc91619fd44f5ec0b462af28d127b116f130aa4d9181900360200190a1604051611002904780156108fc02916000818181858888f19350505050158015612a25573d6000803e3d6000fd5b505b60006003819055600555825115612a4157612a4183613297565b6110016001600160a01b031663fc4333cd6040518163ffffffff1660e01b8152600401600060405180830381600087803b158015612a7e57600080fd5b505af1158015612a92573d6000803e3d6000fd5b50506040517fedd8d7296956dd970ab4de3f2fc03be2b0ffc615d20cd4c72c6e44f928630ebf925060009150a15060009f9e505050505050505050505050505050565b80516001600160a01b0316600090815260046020526040812054801580612b265750600180820381548110612b0657fe5b9060005260206000209060040201600201601c9054906101000a900460ff165b15612b6c5782516040516001600160a01b03909116907fe209c46bebf57cf265d5d9009a00870e256d9150f3ed5281ab9d9eb3cec6e4be90600090a26000915050610f66565b600154600554600019820111801590612bc25784516040516001600160a01b03909116907fe209c46bebf57cf265d5d9009a00870e256d9150f3ed5281ab9d9eb3cec6e4be90600090a260009350505050610f66565b600580546001908101909155805481906000198601908110612be057fe5b6000918252602082206002600490920201018054921515600160e01b0260ff60e01b199093169290921790915585516040516001600160a01b03909116917ff226e7d8f547ff903d9d419cf5f54e0d7d07efa9584135a53a057c5f1f27f49a91a2506000949350505050565b6000816040516020018082805190602001908083835b60208310612c815780518252601f199092019160209182019101612c62565b6001836020036101000a03801982511681845116808217855250505050505090500191505060405160208183030381529060405280519060200120836040516020018082805190602001908083835b60208310612cef5780518252601f199092019160209182019101612cd0565b6001836020036101000a038019825116818451168082178552505050505050905001915050604051602081830303815290604052805190602001201490505b92915050565b015190565b600082820183811015610bd8576040805162461bcd60e51b815260206004820152601b60248201527f536166654d6174683a206164646974696f6e206f766572666c6f770000000000604482015290519081900360640190fd5b612d9b613dd6565b506040805180820190915281518152602082810190820152919050565b612dc0613d81565b612dc98261375e565b612dd257600080fd5b6000612de18360200151613798565b60208085015160408051808201909152868152920190820152915050919050565b6000612e0c613dd6565b505080518051602091820151919092015191011190565b612e2b613dd6565b612e3482612e02565b612e3d57600080fd5b60208201516000612e4d826137fb565b80830160209586015260408051808201909152908152938401919091525090919050565b805160009015801590612e8657508151602110155b612e8f57600080fd5b6000612e9e8360200151613798565b90508083600001511015612ef9576040805162461bcd60e51b815260206004820152601a60248201527f6c656e677468206973206c657373207468616e206f6666736574000000000000604482015290519081900360640190fd5b825160208085015183018051928490039291831015612f1f57826020036101000a820491505b50949350505050565b6060612f338261375e565b612f3c57600080fd5b6000612f478361392e565b9050606081604051908082528060200260200182016040528015612f8557816020015b612f72613dd6565b815260200190600190039081612f6a5790505b5090506000612f978560200151613798565b60208601510190506000805b84811015612fee57612fb4836137fb565b9150604051806040016040528083815260200184815250848281518110612fd757fe5b602090810291909101015291810191600101612fa3565b509195945050505050565b613001613da1565b600061300b613da1565b613013613d81565b61301c85612db8565b90506000805b61302b83612e02565b15611c6057806130565761304661304184612e23565b61398a565b6001600160a01b031684526130ce565b806001141561307e5761306b61304184612e23565b6001600160a01b031660208501526130ce565b80600214156130a65761309361304184612e23565b6001600160a01b031660408501526130ce565b8060031415611c53576130bb611b6584612e23565b6001600160401b03166060850152600191505b600101613022565b6060612d2e6130e4836139a4565b613a8a565b606081516000141561310a5750604080516000815260208101909152610f66565b60608260008151811061311957fe5b602002602001015190506000600190505b835181101561315a576131508285838151811061314357fe5b6020026020010151613adc565b915060010161312a565b50610bd861316d825160c060ff16613b59565b82613adc565b600060606029835111156131a5576000604051806060016040528060298152602001613df16029913991509150611c69565b60005b835181101561323b5760005b81811015613232578481815181106131c857fe5b6020026020010151600001516001600160a01b03168583815181106131e957fe5b6020026020010151600001516001600160a01b0316141561322a5760006040518060600160405280602b8152602001613e1a602b9139935093505050611c69565b6001016131b4565b506001016131a8565b505060408051602081019091526000815260019150915091565b6000610bd883836040518060400160405280601e81526020017f536166654d6174683a207375627472616374696f6e206f766572666c6f770000815250613c51565b600154815160005b828110156133b45760016132b1613da1565b600183815481106132be57fe5b600091825260208083206040805160c08101825260049490940290910180546001600160a01b0390811685526001820154811693850193909352600281015492831691840191909152600160a01b82046001600160401b03166060840152600160e01b90910460ff16151560808301526003015460a082015291505b848110156133885786818151811061334e57fe5b6020026020010151600001516001600160a01b031682600001516001600160a01b031614156133805760009250613388565b60010161333a565b5081156133aa5780516001600160a01b03166000908152600460205260408120555b505060010161329f565b508082111561342957805b828110156134275760018054806133d257fe5b60008281526020812060046000199093019283020180546001600160a01b03199081168255600182810180549092169091556002820180546001600160e81b03191690556003909101919091559155016133bf565b505b6000818310613438578161343a565b825b905060005b81811015613634576134ec85828151811061345657fe5b60200260200101516001838154811061346b57fe5b60009182526020918290206040805160c08101825260049390930290910180546001600160a01b0390811684526001820154811694840194909452600281015493841691830191909152600160a01b83046001600160401b03166060830152600160e01b90920460ff161515608082015260039091015460a0820152613ce8565b61360757806001016004600087848151811061350457fe5b6020026020010151600001516001600160a01b03166001600160a01b031681526020019081526020016000208190555084818151811061354057fe5b60200260200101516001828154811061355557fe5b6000918252602091829020835160049092020180546001600160a01b039283166001600160a01b0319918216178255928401516001820180549184169185169190911790556040840151600282018054606087015160808801511515600160e01b0260ff60e01b196001600160401b03909216600160a01b0267ffffffffffffffff60a01b1995909716929097169190911792909216939093171692909217905560a09091015160039091015561362c565b60006001828154811061361657fe5b9060005260206000209060040201600301819055505b60010161343f565b508282111561375857825b82811015610ef657600185828151811061365557fe5b60209081029190910181015182546001818101855560009485528385208351600493840290910180546001600160a01b039283166001600160a01b03199182161782559585015181840180549184169188169190911790556040850151600282018054606088015160808901511515600160e01b0260ff60e01b196001600160401b03909216600160a01b0267ffffffffffffffff60a01b199590971692909a169190911792909216939093171695909517905560a0909201516003909301929092558751908401929088908590811061372b57fe5b602090810291909101810151516001600160a01b031682528101919091526040016000205560010161363f565b50505050565b805160009061376f57506000610f66565b6020820151805160001a9060c082101561378e57600092505050610f66565b5060019392505050565b8051600090811a60808110156137b2576000915050610f66565b60b88110806137cd575060c081108015906137cd575060f881105b156137dc576001915050610f66565b60c08110156137f05760b519019050610f66565b60f519019050610f66565b80516000908190811a60808110156138165760019150613927565b60b881101561382b57607e1981019150613927565b60c08110156138a557600060b78203600186019550806020036101000a86510491506001810182019350508083101561389f576040805162461bcd60e51b81526020600482015260116024820152706164646974696f6e206f766572666c6f7760781b604482015290519081900360640190fd5b50613927565b60f88110156138ba5760be1981019150613927565b600060f78203600186019550806020036101000a865104915060018101820193505080831015613925576040805162461bcd60e51b81526020600482015260116024820152706164646974696f6e206f766572666c6f7760781b604482015290519081900360640190fd5b505b5092915050565b805160009061393f57506000610f66565b600080905060006139538460200151613798565b602085015185519181019250015b8082101561398157613972826137fb565b60019093019290910190613961565b50909392505050565b805160009060151461399b57600080fd5b612d2e82612e71565b604080516020808252818301909252606091829190602082018180368337505050602081018490529050600067ffffffffffffffff1984166139e857506018613a0c565b6fffffffffffffffffffffffffffffffff198416613a0857506010613a0c565b5060005b6020811015613a4257818181518110613a2157fe5b01602001516001600160f81b03191615613a3a57613a42565b600101613a0c565b60008160200390506060816040519080825280601f01601f191660200182016040528015613a77576020820181803683370190505b5080830196909652508452509192915050565b606081516001148015613abc5750607f60f81b82600081518110613aaa57fe5b01602001516001600160f81b03191611155b15613ac8575080610f66565b612d2e613ada8351608060ff16613b59565b835b6060806040519050835180825260208201818101602087015b81831015613b0d578051835260209283019201613af5565b50855184518101855292509050808201602086015b81831015613b3a578051835260209283019201613b22565b508651929092011591909101601f01601f191660405250905092915050565b6060680100000000000000008310613ba9576040805162461bcd60e51b815260206004820152600e60248201526d696e70757420746f6f206c6f6e6760901b604482015290519081900360640190fd5b60408051600180825281830190925260609160208201818036833701905050905060378411613c035782840160f81b81600081518110613be557fe5b60200101906001600160f81b031916908160001a9053509050612d2e565b6060613c0e856139a4565b90508381510160370160f81b82600081518110613c2757fe5b60200101906001600160f81b031916908160001a905350613c488282613adc565b95945050505050565b60008184841115613ce05760405162461bcd60e51b81526004018080602001828103825283818151815260200191508051906020019080838360005b83811015613ca5578181015183820152602001613c8d565b50505050905090810190601f168015613cd25780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b505050900390565b805182516000916001600160a01b039182169116148015613d22575081602001516001600160a01b031683602001516001600160a01b0316145b8015613d47575081604001516001600160a01b031683604001516001600160a01b0316145b8015610bd85750506060908101519101516001600160401b0390811691161490565b60408051808201909152600081526060602082015290565b6040518060400160405280613d94613dd6565b8152602001600081525090565b6040805160c081018252600080825260208201819052918101829052606081018290526080810182905260a081019190915290565b60405180604001604052806000815260200160008152509056fe746865206e756d626572206f662076616c696461746f72732065786365656420746865206c696d69746475706c696361746520636f6e73656e7375732061646472657373206f662076616c696461746f725365747468652065787069726554696d655365636f6e64476170206973206f7574206f662072616e67656c656e677468206f66206a61696c2076616c696461746f7273206d757374206265206f6e65746865206d6573736167652073656e646572206d75737420626520676f7665726e616e636520636f6e7472616374666565206973206c6172676572207468616e2044555354595f494e434f4d494e476c656e677468206f662065787069726554696d655365636f6e64476170206d69736d617463686661696c656420746f20706172736520696e69742076616c696461746f72536574f905ec80f905e8f846942a7cdd959bfe8d9487b2a43b33565295a698f7e294b6a7edd747c0554875d3fc531d19ba1497992c5e941ff80f3f7f110ffd8920a3ac38fdef318fe94a3f86048c27395000f846946488aa4d1955ee33403f8ccb1d4de5fb97c7ade294220f003d8bdfaadf52aa1e55ae4cc485e6794875941a87e90e440a39c99aa9cb5cea0ad6a3f0b2407b86048c27395000f846949ef9f4360c606c7ab4db26b016007d3ad0ab86a0946103af86a874b705854033438383c82575f25bc29418e2db06cbff3e3c5f856410a1838649e760175786048c27395000f84694ee01c3b1283aa067c58eab4709f85e99d46de5fe94ee4b9bfb1871c64e2bcabb1dc382dc8b7c4218a29415904ab26ab0e99d70b51c220ccdcccabee6e29786048c27395000f84694685b1ded8013785d6623cc18d214320b6bb6475994a20ef4e5e4e7e36258dbf51f4d905114cb1b34bc9413e39085dc88704f4394d35209a02b1a9520320c86048c27395000f8469478f3adfc719c99674c072166708589033e2d9afe9448a30d5eaa7b64492a160f139e2da2800ec3834e94055838358c29edf4dcc1ba1985ad58aedbb6be2b86048c27395000f84694c2be4ec20253b8642161bc3f444f53679c1f3d479466f50c616d737e60d7ca6311ff0d9c434197898a94d1d678a2506eeaa365056fe565df8bc8659f28b086048c27395000f846942f7be8361c80a4c1e7e9aaf001d0877f1cfde218945f93992ac37f3e61db2ef8a587a436a161fd210b94ecbc4fb1a97861344dad0867ca3cba2b860411f086048c27395000f84694ce2fd7544e0b2cc94692d4a704debef7bcb613289444abc67b4b2fba283c582387f54c9cba7c34bafa948acc2ab395ded08bb75ce85bf0f95ad2abc51ad586048c27395000f84694b8f7166496996a7da21cf1f1b04d9b3e26a3d077946770572763289aac606e4f327c2f6cc1aa3b3e3b94882d745ed97d4422ca8da1c22ec49d880c4c097286048c27395000f846942d4c407bbe49438ed859fe965b140dcf1aab71a9943ad0939e120f33518fbba04631afe7a3ed6327b194b2bbb170ca4e499a2b0f3cc85ebfa6e8c4dfcbea86048c27395000f846946bbad7cf34b5fa511d8e963dbba288b1960e75d694853b0f6c324d1f4e76c8266942337ac1b0af1a229442498946a51ca5924552ead6fc2af08b94fcba648601d1a94a2000f846944430b3230294d12c6ab2aac5c2cd68e80b16b581947b107f4976a252a6939b771202c28e64e03f52d694795811a7f214084116949fc4f53cedbf189eeab28601d1a94a2000f84694ea0a6e3c511bbd10f4519ece37dc24887e11b55d946811ca77acfb221a49393c193f3a22db829fcc8e9464feb7c04830dd9ace164fc5c52b3f5a29e5018a8601d1a94a2000f846947ae2f5b9e386cd1b50a4550696d957cb4900f03a94e83bcc5077e6b873995c24bac871b5ad856047e19464e48d4057a90b233e026c1041e6012ada897fe88601d1a94a2000f8469482012708dafc9e1b880fd083b32182b869be8e09948e5adc73a2d233a1b496ed3115464dd6c7b887509428b383d324bc9a37f4e276190796ba5a8947f5ed8601d1a94a2000f8469422b81f8e175ffde54d797fe11eb03f9e3bf75f1d94a1c3ef7ca38d8ba80cce3bfc53ebd2903ed21658942767f7447f7b9b70313d4147b795414aecea54718601d1a94a2000f8469468bf0b8b6fb4e317a0f9d6f03eaf8ce6675bc60d94675cfe570b7902623f47e7f59c9664b5f5065dcf94d84f0d2e50bcf00f2fc476e1c57f5ca2d57f625b8601d1a94a2000f846948c4d90829ce8f72d0163c1d5cf348a862d5506309485c42a7b34309bee2ed6a235f86d16f059deec5894cc2cedc53f0fa6d376336efb67e43d167169f3b78601d1a94a2000f8469435e7a025f4da968de7e4d7e4004197917f4070f194b1182abaeeb3b4d8eba7e6a4162eac7ace23d57394c4fd0d870da52e73de2dd8ded19fe3d26f43a1138601d1a94a2000f84694d6caa02bbebaebb5d7e581e4b66559e635f805ff94c07335cf083c1c46a487f0325769d88e163b653694efaff03b42e41f953a925fc43720e45fb61a19938601d1a94a2000746865206d6573736167652073656e646572206d7573742062652063726f737320636861696e20636f6e7472616374746865206d6573736167652073656e646572206d7573742062652074686520626c6f636b2070726f6475636572746865206d6573736167652073656e646572206d75737420626520736c61736820636f6e7472616374a2646970667358221220f4016eb3755efa2abde797b21f8695280d971b0fea37198122d2e5867516da0464736f6c63430006040033" + }, + "0x0000000000000000000000000000000000001001": { + "balance": "0x0", + "code": "0x608060405234801561001057600080fd5b50600436106102275760003560e01c8063831d65d111610130578063c80d4b8f116100b8578063e1c7392a1161007c578063e1c7392a146106d9578063f9a2bbc7146106e1578063fc3e5908146106e9578063fc4333cd146106f1578063fd6a6879146106f957610227565b8063c80d4b8f14610623578063c81b16621461062b578063c8509d8114610633578063c96be4cb146106ab578063dc927faf146106d157610227565b8063a1a11bf5116100ff578063a1a11bf514610531578063a78abc1614610539578063ab51bb9614610555578063ac0af6291461055d578063ac4317511461056557610227565b8063831d65d11461049f57806396713da9146105195780639bc8e4f2146105215780639dc092621461052957610227565b80634bf6c882116101b35780636e47b482116101825780636e47b4821461047757806370fd5bad1461047f57806375d47a0a146104875780637912a65d1461048f5780637942fd051461049757610227565b80634bf6c8821461045757806351e806721461045f578063567a372d1461046757806362b72cf51461046f57610227565b806337c8dab9116101fa57806337c8dab9146103b9578063389f4f71146103f85780633dffc3871461041257806343756e5c14610430578063493279b11461043857610227565b80630bee7a671461022c5780631182b8751461024d57806323bac5a21461033a57806335aa2e4414610380575b600080fd5b610234610701565b6040805163ffffffff9092168252519081900360200190f35b6102c56004803603604081101561026357600080fd5b60ff8235169190810190604081016020820135600160201b81111561028757600080fd5b82018360208201111561029957600080fd5b803590602001918460018302840111600160201b831117156102ba57600080fd5b509092509050610706565b6040805160208082528351818301528351919283929083019185019080838360005b838110156102ff5781810151838201526020016102e7565b50505050905090810190601f16801561032c5780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b6103606004803603602081101561035057600080fd5b50356001600160a01b03166107da565b604080519384526020840192909252151582820152519081900360600190f35b61039d6004803603602081101561039657600080fd5b50356107fd565b604080516001600160a01b039092168252519081900360200190f35b6103df600480360360208110156103cf57600080fd5b50356001600160a01b0316610824565b6040805192835260208301919091528051918290030190f35b61040061087b565b60408051918252519081900360200190f35b61041a610881565b6040805160ff9092168252519081900360200190f35b61039d610886565b61044061088c565b6040805161ffff9092168252519081900360200190f35b61041a610891565b61039d610896565b61040061089c565b6104006108a2565b61039d6108a8565b61041a6108ae565b61039d6108b3565b6104006108b9565b61041a6108be565b610517600480360360408110156104b557600080fd5b60ff8235169190810190604081016020820135600160201b8111156104d957600080fd5b8201836020820111156104eb57600080fd5b803590602001918460018302840111600160201b8311171561050c57600080fd5b5090925090506108c3565b005b61041a610a1e565b610400610a23565b61039d610a2e565b61039d610a34565b610541610a3a565b604080519115158252519081900360200190f35b610234610a43565b610400610a48565b6105176004803603604081101561057b57600080fd5b810190602081018135600160201b81111561059557600080fd5b8201836020820111156105a757600080fd5b803590602001918460018302840111600160201b831117156105c857600080fd5b919390929091602081019035600160201b8111156105e557600080fd5b8201836020820111156105f757600080fd5b803590602001918460018302840111600160201b8311171561061857600080fd5b509092509050610a4d565b610400610e3b565b61039d610e40565b6105176004803603604081101561064957600080fd5b60ff8235169190810190604081016020820135600160201b81111561066d57600080fd5b82018360208201111561067f57600080fd5b803590602001918460018302840111600160201b831117156106a057600080fd5b509092509050610e46565b610517600480360360208110156106c157600080fd5b50356001600160a01b0316610ef9565b61039d61131e565b610517611324565b61039d611395565b61041a61139b565b6105176113a0565b61039d61182b565b606481565b606033612000146107485760405162461bcd60e51b815260040180806020018281038252602f815260200180612282602f913960400191505060405180910390fd5b60005460ff1661078d576040805162461bcd60e51b815260206004820152601960248201526000805160206122de833981519152604482015290519081900360640190fd5b6040805162461bcd60e51b815260206004820152601e60248201527f7265636569766520756e65787065637465642073796e207061636b6167650000604482015290519081900360640190fd5b600260208190526000918252604090912080546001820154919092015460ff1683565b6001818154811061080a57fe5b6000918252602090912001546001600160a01b0316905081565b60008061082f612146565b5050506001600160a01b0316600090815260026020818152604092839020835160608101855281548082526001830154938201849052919093015460ff16151592909301919091529091565b60055481565b600181565b61100181565b603881565b600881565b61200081565b60045481565b60035481565b61100581565b600281565b61100881565b603281565b600b81565b33612000146109035760405162461bcd60e51b815260040180806020018281038252602f815260200180612282602f913960400191505060405180910390fd5b60005460ff16610948576040805162461bcd60e51b815260206004820152601960248201526000805160206122de833981519152604482015290519081900360640190fd5b610950612169565b600061099184848080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061183192505050565b9150915080156109db5781516040805163ffffffff9092168252517f7f0956d47419b9525356e7111652b653b530ec6f5096dccc04589bc38e6299679181900360200190a1610a17565b81516040805163ffffffff9092168252517f7d45f62d17443dd4547bca8a8112c60e2385669318dc300ec61a5d2492f262e79181900360200190a15b5050505050565b600981565b662386f26fc1000081565b61100781565b61100681565b60005460ff1681565b600081565b600481565b60005460ff16610a92576040805162461bcd60e51b815260206004820152601960248201526000805160206122de833981519152604482015290519081900360640190fd5b3361100714610ad25760405162461bcd60e51b815260040180806020018281038252602e81526020018061220d602e913960400191505060405180910390fd5b610b3d84848080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250506040805180820190915260148152731b5a5cd9195b59585b9bdc951a1c995cda1bdb1960621b602082015291506118b19050565b15610c165760208114610b815760405162461bcd60e51b81526004018080602001828103825260278152602001806121b66027913960400191505060405180910390fd5b604080516020601f8401819004810282018101909252828152600091610bbf9185858083850183828082843760009201919091525061199992505050565b905060018110158015610bd3575060055481105b610c0e5760405162461bcd60e51b815260040180806020018281038252602581526020018061225d6025913960400191505060405180910390fd5b600455610da9565b610c7c84848080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152505060408051808201909152600f81526e19995b1bdb9e551a1c995cda1bdb19608a1b602082015291506118b19050565b15610d6c5760208114610cc05760405162461bcd60e51b815260040180806020018281038252602281526020018061223b6022913960400191505060405180910390fd5b604080516020601f8401819004810282018101909252828152600091610cfe9185858083850183828082843760009201919091525061199992505050565b90506103e88111158015610d13575060045481115b610d64576040805162461bcd60e51b815260206004820181905260248201527f7468652066656c6f6e795468726573686f6c64206f7574206f662072616e6765604482015290519081900360640190fd5b600555610da9565b6040805162461bcd60e51b815260206004820152600d60248201526c756e6b6e6f776e20706172616d60981b604482015290519081900360640190fd5b7f6cdb0ac70ab7f2e2d035cca5be60d89906f2dede7648ddbd7402189c1eeed17a848484846040518080602001806020018381038352878782818152602001925080828437600083820152601f01601f191690910184810383528581526020019050858580828437600083820152604051601f909101601f19169092018290039850909650505050505050a150505050565b609681565b61100281565b3361200014610e865760405162461bcd60e51b815260040180806020018281038252602f815260200180612282602f913960400191505060405180910390fd5b60005460ff16610ecb576040805162461bcd60e51b815260206004820152601960248201526000805160206122de833981519152604482015290519081900360640190fd5b6040517f07db600eebe2ac176be8dcebad61858c245a4961bb32ca2aa3d159b09aa0810e90600090a1505050565b334114610f375760405162461bcd60e51b815260040180806020018281038252602d8152602001806122b1602d913960400191505060405180910390fd5b60005460ff16610f7c576040805162461bcd60e51b815260206004820152601960248201526000805160206122de833981519152604482015290519081900360640190fd5b6003544311610fd2576040805162461bcd60e51b815260206004820181905260248201527f63616e206e6f7420736c61736820747769636520696e206f6e6520626c6f636b604482015290519081900360640190fd5b3a1561101c576040805162461bcd60e51b81526020600482015260146024820152736761737072696365206973206e6f74207a65726f60601b604482015290519081900360640190fd5b611024612146565b506001600160a01b0381166000908152600260208181526040928390208351606081018552815481526001820154928101929092529091015460ff16158015928201929092529061107f5760208101805160010190526110d8565b60016040820181905260208201819052805480820182556000919091527fb10e2d527612073b26eecdfd717e6a320cf44b4afac2b0732d9fcbe2b7fa0cf60180546001600160a01b0319166001600160a01b0384161790555b4381526005546020820151816110ea57fe5b0661123c57600060208201819052604080516335409f7f60e01b81526001600160a01b03851660048201529051611000926335409f7f926024808201939182900301818387803b15801561113d57600080fd5b505af1158015611151573d6000803e3d6000fd5b505050506120006001600160a01b031663f7a251d7600b6111718561199e565b60006040518463ffffffff1660e01b8152600401808460ff1660ff16815260200180602001838152602001828103825284818151815260200191508051906020019080838360005b838110156111d15781810151838201526020016111b9565b50505050905090810190601f1680156111fe5780820380516001836020036101000a031916815260200191505b50945050505050600060405180830381600087803b15801561121f57600080fd5b505af1158015611233573d6000803e3d6000fd5b505050506112b2565b60045481602001518161124b57fe5b066112b257604080516375abf10160e11b81526001600160a01b038416600482015290516110009163eb57e20291602480830192600092919082900301818387803b15801561129957600080fd5b505af11580156112ad573d6000803e3d6000fd5b505050505b6001600160a01b0382166000818152600260208181526040808420865181559186015160018301558581015191909201805460ff1916911515919091179055517fddb6012116e51abf5436d956a4f0ebd927e92c576ff96d7918290c8782291e3e9190a2505043600355565b61100381565b60005460ff161561137c576040805162461bcd60e51b815260206004820152601960248201527f74686520636f6e747261637420616c726561647920696e697400000000000000604482015290519081900360640190fd5b603260045560966005556000805460ff19166001179055565b61100081565b600381565b33611000146113e05760405162461bcd60e51b81526004018080602001828103825260308152602001806121dd6030913960400191505060405180910390fd5b60005460ff16611425576040805162461bcd60e51b815260206004820152601960248201526000805160206122de833981519152604482015290519081900360640190fd5b60015461143157611829565b600154600090600019015b8082116117fd576000805b8284101561156057611457612146565b600260006001878154811061146857fe5b60009182526020808320909101546001600160a01b0316835282810193909352604091820190208151606081018352815481526001820154938101939093526002015460ff16151590820152600554909150600490048160200151111561154a576004600554816114d557fe5b048160200151038160200181815250508060026000600188815481106114f757fe5b6000918252602080832091909101546001600160a01b0316835282810193909352604091820190208351815591830151600183015591909101516002909101805460ff1916911515919091179055611554565b6001925050611560565b50600190930192611447565b8284116116f75761156f612146565b600260006001868154811061158057fe5b60009182526020808320909101546001600160a01b0316835282810193909352604091820190208151606081018352815481526001820154938101939093526002015460ff161515908201526005549091506004900481602001511115611668576004600554816115ed57fe5b0481602001510381602001818152505080600260006001878154811061160f57fe5b6000918252602080832091909101546001600160a01b03168352828101939093526040918201902083518155918301516001808401919091559201516002909101805460ff191691151591909117905591506116f79050565b600260006001868154811061167957fe5b60009182526020808320909101546001600160a01b031683528201929092526040018120818155600181810192909255600201805460ff191690558054806116bd57fe5b600082815260209020810160001990810180546001600160a01b0319169055019055836116ea57506116f7565b5060001990920191611560565b8180156117015750805b156117e057600260006001868154811061171757fe5b60009182526020808320909101546001600160a01b031683528201929092526040018120818155600181810192909255600201805460ff1916905580548490811061175e57fe5b600091825260209091200154600180546001600160a01b03909216918690811061178457fe5b9060005260206000200160006101000a8154816001600160a01b0302191690836001600160a01b0316021790555060018054806117bd57fe5b600082815260209020810160001990810180546001600160a01b03191690550190555b826117ec5750506117fd565b50506001909101906000190161143c565b6040517fcfdb3b6ccaeccbdc68be3c59c840e3b3c90f0a7c491f5fff1cf56cfda200dd9c90600090a150505b565b61100481565b611839612169565b6000611843612169565b61184b61217b565b61185c61185786611a70565b611a95565b90506000805b61186b83611adf565b156118a457806118975761188661188184611b00565b611b4e565b63ffffffff1684526001915061189c565b6118a4565b600101611862565b5091935090915050915091565b6000816040516020018082805190602001908083835b602083106118e65780518252601f1990920191602091820191016118c7565b6001836020036101000a03801982511681845116808217855250505050505090500191505060405160208183030381529060405280519060200120836040516020018082805190602001908083835b602083106119545780518252601f199092019160209182019101611935565b6001836020036101000a038019825116818451168082178552505050505050905001915050604051602081830303815290604052805190602001201490505b92915050565b015190565b60408051600480825260a08201909252606091829190816020015b60608152602001906001900390816119b95790505090506119e2836001600160a01b0316611c05565b816000815181106119ef57fe5b6020026020010181905250611a0343611c28565b81600181518110611a1057fe5b6020908102919091010152611a256038611c28565b81600281518110611a3257fe5b6020026020010181905250611a4642611c28565b81600381518110611a5357fe5b6020026020010181905250611a6781611c3b565b9150505b919050565b611a7861219b565b506040805180820190915281518152602082810190820152919050565b611a9d61217b565b611aa682611cc5565b611aaf57600080fd5b6000611abe8360200151611cff565b60208085015160408051808201909152868152920190820152915050919050565b6000611ae961219b565b505080518051602091820151919092015191011190565b611b0861219b565b611b1182611adf565b611b1a57600080fd5b60208201516000611b2a82611d62565b80830160209586015260408051808201909152908152938401919091525090919050565b805160009015801590611b6357508151602110155b611b6c57600080fd5b6000611b7b8360200151611cff565b90508083600001511015611bd6576040805162461bcd60e51b815260206004820152601a60248201527f6c656e677468206973206c657373207468616e206f6666736574000000000000604482015290519081900360640190fd5b825160208085015183018051928490039291831015611bfc57826020036101000a820491505b50949350505050565b60408051600560a21b8318601482015260348101909152606090611a6781611e95565b6060611993611c3683611eeb565b611e95565b6060815160001415611c5c5750604080516000815260208101909152611a6b565b606082600081518110611c6b57fe5b602002602001015190506000600190505b8351811015611cac57611ca282858381518110611c9557fe5b6020026020010151611fd1565b9150600101611c7c565b50611a67611cbf825160c060ff1661204e565b82611fd1565b8051600090611cd657506000611a6b565b6020820151805160001a9060c0821015611cf557600092505050611a6b565b5060019392505050565b8051600090811a6080811015611d19576000915050611a6b565b60b8811080611d34575060c08110801590611d34575060f881105b15611d43576001915050611a6b565b60c0811015611d575760b519019050611a6b565b60f519019050611a6b565b80516000908190811a6080811015611d7d5760019150611e8e565b60b8811015611d9257607e1981019150611e8e565b60c0811015611e0c57600060b78203600186019550806020036101000a865104915060018101820193505080831015611e06576040805162461bcd60e51b81526020600482015260116024820152706164646974696f6e206f766572666c6f7760781b604482015290519081900360640190fd5b50611e8e565b60f8811015611e215760be1981019150611e8e565b600060f78203600186019550806020036101000a865104915060018101820193505080831015611e8c576040805162461bcd60e51b81526020600482015260116024820152706164646974696f6e206f766572666c6f7760781b604482015290519081900360640190fd5b505b5092915050565b606081516001148015611ec75750607f60f81b82600081518110611eb557fe5b01602001516001600160f81b03191611155b15611ed3575080611a6b565b611993611ee58351608060ff1661204e565b83611fd1565b604080516020808252818301909252606091829190602082018180368337505050602081018490529050600067ffffffffffffffff198416611f2f57506018611f53565b6fffffffffffffffffffffffffffffffff198416611f4f57506010611f53565b5060005b6020811015611f8957818181518110611f6857fe5b01602001516001600160f81b03191615611f8157611f89565b600101611f53565b60008160200390506060816040519080825280601f01601f191660200182016040528015611fbe576020820181803683370190505b5080830196909652508452509192915050565b6060806040519050835180825260208201818101602087015b81831015612002578051835260209283019201611fea565b50855184518101855292509050808201602086015b8183101561202f578051835260209283019201612017565b508651929092011591909101601f01601f191660405250905092915050565b606068010000000000000000831061209e576040805162461bcd60e51b815260206004820152600e60248201526d696e70757420746f6f206c6f6e6760901b604482015290519081900360640190fd5b604080516001808252818301909252606091602082018180368337019050509050603784116120f85782840160f81b816000815181106120da57fe5b60200101906001600160f81b031916908160001a9053509050611993565b606061210385611eeb565b90508381510160370160f81b8260008151811061211c57fe5b60200101906001600160f81b031916908160001a90535061213d8282611fd1565b95945050505050565b604051806060016040528060008152602001600081526020016000151581525090565b60408051602081019091526000815290565b604051806040016040528061218e61219b565b8152602001600081525090565b60405180604001604052806000815260200160008152509056fe6c656e677468206f66206d697364656d65616e6f725468726573686f6c64206d69736d61746368746865206d6573736167652073656e646572206d7573742062652076616c696461746f7253657420636f6e7472616374746865206d6573736167652073656e646572206d75737420626520676f7665726e616e636520636f6e74726163746c656e677468206f662066656c6f6e795468726573686f6c64206d69736d61746368746865206d697364656d65616e6f725468726573686f6c64206f7574206f662072616e6765746865206d6573736167652073656e646572206d7573742062652063726f737320636861696e20636f6e7472616374746865206d6573736167652073656e646572206d7573742062652074686520626c6f636b2070726f647563657274686520636f6e7472616374206e6f7420696e69742079657400000000000000a2646970667358221220978db7b9b4e7fb0a1f9436afd2b57418fb3ba1969a491794d2da96ee68de87d064736f6c63430006040033" + }, + "0x0000000000000000000000000000000000001002": { + "balance": "0x0", + "code": "0x60806040526004361061014f5760003560e01c806396713da9116100b6578063c81b16621161006f578063c81b1662146103dc578063dc927faf146103f1578063f9a2bbc714610406578063fb5478b31461041b578063fc3e590814610430578063fd6a68791461044557610193565b806396713da91461033a5780639a99b4f01461034f5780639dc0926214610388578063a1a11bf51461039d578063a78abc16146103b2578063ab51bb96146103c757610193565b806351e806721161010857806351e806721461028a5780636d70f7ae1461029f5780636e47b482146102e657806370fd5bad146102fb57806375d47a0a146103105780637942fd051461032557610193565b80630bee7a67146101985780633a0b0eff146101c65780633dffc387146101ed57806343756e5c14610218578063493279b1146102495780634bf6c8821461027557610193565b366101935734156101915760408051348152905133917f6c98249d85d88c3753a04a22230f595e4dc8d3dc86c34af35deeeedc861b89db919081900360200190a25b005b600080fd5b3480156101a457600080fd5b506101ad61045a565b6040805163ffffffff9092168252519081900360200190f35b3480156101d257600080fd5b506101db61045f565b60408051918252519081900360200190f35b3480156101f957600080fd5b50610202610465565b6040805160ff9092168252519081900360200190f35b34801561022457600080fd5b5061022d61046a565b604080516001600160a01b039092168252519081900360200190f35b34801561025557600080fd5b5061025e610470565b6040805161ffff9092168252519081900360200190f35b34801561028157600080fd5b50610202610475565b34801561029657600080fd5b5061022d61047a565b3480156102ab57600080fd5b506102d2600480360360208110156102c257600080fd5b50356001600160a01b0316610480565b604080519115158252519081900360200190f35b3480156102f257600080fd5b5061022d61049e565b34801561030757600080fd5b506102026104a4565b34801561031c57600080fd5b5061022d6104a9565b34801561033157600080fd5b506102026104af565b34801561034657600080fd5b506102026104b4565b34801561035b57600080fd5b506101db6004803603604081101561037257600080fd5b506001600160a01b0381351690602001356104b9565b34801561039457600080fd5b5061022d610664565b3480156103a957600080fd5b5061022d61066a565b3480156103be57600080fd5b506102d2610670565b3480156103d357600080fd5b506101ad610679565b3480156103e857600080fd5b5061022d61067e565b3480156103fd57600080fd5b5061022d610684565b34801561041257600080fd5b5061022d61068a565b34801561042757600080fd5b506101db610690565b34801561043c57600080fd5b5061020261069c565b34801561045157600080fd5b5061022d6106a1565b606481565b60015481565b600181565b61100181565b603881565b600881565b61200081565b6001600160a01b031660009081526002602052604090205460ff1690565b61100581565b600281565b61100881565b600b81565b600981565b6000805460ff1661053657600260208190527fe57bda0a954a7c7381b17b2c763e646ba2c60f67292d287ba583603e2c1c41668054600160ff19918216811790925561100560009081527fe25235fc0de9d7165652bef0846fefda506174abb9a190f03d0f7bcc6146dbce80548316841790559282558254161790555b3360009081526002602052604090205460ff166105845760405162461bcd60e51b815260040180806020018281038252602b8152602001806106a8602b913960400191505060405180910390fd5b60004783106105935747610595565b825b9050670de0b6b3a76400008111156105b25750670de0b6b3a76400005b8015610633576040516001600160a01b0385169082156108fc029083906000818181858888f193505050501580156105ee573d6000803e3d6000fd5b506040805182815290516001600160a01b038616917ff8b71c64315fc33b2ead2adfa487955065152a8ac33d9d5193aafd7f45dc15a0919081900360200190a261065d565b6040517fe589651933c2457488cc0d8e0941518abf748e799435e4e396d9c4d0b2db2d4d90600090a15b9392505050565b61100781565b61100681565b60005460ff1681565b600081565b61100281565b61100381565b61100081565b670de0b6b3a764000081565b600381565b6110048156fe6f6e6c79206f70657261746f7220697320616c6c6f77656420746f2063616c6c20746865206d6574686f64a2646970667358221220c09e2c37549a0aef291c4f977743d3cea839c669624a8cfae895b3979a32800764736f6c63430006040033" + }, + "0x0000000000000000000000000000000000001003": { + "balance": "0x0", + "code": "0x608060405234801561001057600080fd5b50600436106102115760003560e01c8063a78abc1611610125578063dda83148116100ad578063e405bbc31161007c578063e405bbc314610681578063ea54b2aa14610689578063f9a2bbc714610691578063fc3e590814610699578063fd6a6879146106a157610211565b8063dda8314814610609578063df5fe7041461062f578063e1c7392a14610655578063e2761af01461065d57610211565b8063c81b1662116100f4578063c81b166214610534578063cba510a91461053c578063d816987914610562578063da8d08f0146105db578063dc927faf1461060157610211565b8063a78abc1614610444578063ab51bb9614610460578063ac43175114610468578063adc879e91461052c57610211565b8063564b81ef116101a857806375d47a0a1161017757806375d47a0a1461041c5780637942fd051461042457806396713da91461042c5780639dc0926214610434578063a1a11bf51461043c57610211565b8063564b81ef146102ca5780635c5ae8db146103475780636e47b4821461040c57806370fd5bad1461041457610211565b806343756e5c116101e457806343756e5c14610277578063493279b11461029b5780634bf6c882146102ba57806351e80672146102c257610211565b80630bee7a67146102165780632657e9b61461023757806333f7798d146102515780633dffc38714610259575b600080fd5b61021e6106a9565b6040805163ffffffff9092168252519081900360200190f35b61023f6106ae565b60408051918252519081900360200190f35b61023f6106b9565b6102616106bf565b6040805160ff9092168252519081900360200190f35b61027f6106c4565b604080516001600160a01b039092168252519081900360200190f35b6102a36106ca565b6040805161ffff9092168252519081900360200190f35b6102616106cf565b61027f6106d4565b6102d26106da565b6040805160208082528351818301528351919283929083019185019080838360005b8381101561030c5781810151838201526020016102f4565b50505050905090810190601f1680156103395780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b61036d6004803603602081101561035d57600080fd5b50356001600160401b03166107e6565b60405180856001600160401b03166001600160401b0316815260200184815260200183815260200180602001828103825283818151815260200191508051906020019080838360005b838110156103ce5781810151838201526020016103b6565b50505050905090810190601f1680156103fb5780820380516001836020036101000a031916815260200191505b509550505050505060405180910390f35b61027f6108a1565b6102616108a7565b61027f6108ac565b6102616108b2565b6102616108b7565b61027f6108bc565b61027f6108c2565b61044c6108c8565b604080519115158252519081900360200190f35b61021e6108d1565b61052a6004803603604081101561047e57600080fd5b81019060208101813564010000000081111561049957600080fd5b8201836020820111156104ab57600080fd5b803590602001918460018302840111640100000000831117156104cd57600080fd5b9193909290916020810190356401000000008111156104eb57600080fd5b8201836020820111156104fd57600080fd5b8035906020019184600183028401116401000000008311171561051f57600080fd5b5090925090506108d6565b005b61023f610b8f565b61027f610b95565b61023f6004803603602081101561055257600080fd5b50356001600160401b0316610b9b565b61044c6004803603604081101561057857600080fd5b81019060208101813564010000000081111561059357600080fd5b8201836020820111156105a557600080fd5b803590602001918460018302840111640100000000831117156105c757600080fd5b9193509150356001600160401b0316610bba565b61027f600480360360208110156105f157600080fd5b50356001600160401b031661139b565b61027f6113b6565b61027f6004803603602081101561061f57600080fd5b50356001600160401b03166113bc565b61044c6004803603602081101561064557600080fd5b50356001600160401b03166113e0565b61052a611422565b6106656115c9565b604080516001600160401b039092168252519081900360200190f35b6106656115d8565b6102d26115ee565b61027f61160d565b610261611613565b61027f611618565b606481565b662386f26fc1000081565b60055481565b600181565b61100181565b603881565b600881565b61200081565b604080516020808252818301909252606091829190602082018180368337505060045460208301525090506000805b60208160ff16101561075057828160ff168151811061072457fe5b01602001516001600160f81b0319161561074357600190910190610748565b610750565b600101610709565b5060608160ff166040519080825280601f01601f191660200182016040528015610781576020820181803683370190505b50905060005b8260ff168160ff1610156107dd57838160ff16815181106107a457fe5b602001015160f81c60f81b828260ff16815181106107be57fe5b60200101906001600160f81b031916908160001a905350600101610787565b50925050505b90565b60016020818152600092835260409283902080548184015460028084015460038501805489516101009982161599909902600019011692909204601f81018790048702880187019098528787526001600160401b0390931696919592949091908301828280156108975780601f1061086c57610100808354040283529160200191610897565b820191906000526020600020905b81548152906001019060200180831161087a57829003601f168201915b5050505050905084565b61100581565b600281565b61100881565b600b81565b600981565b61100781565b61100681565b60005460ff1681565b600081565b60005460ff1661092d576040805162461bcd60e51b815260206004820152601960248201527f74686520636f6e7472616374206e6f7420696e69742079657400000000000000604482015290519081900360640190fd5b336110071461096d5760405162461bcd60e51b815260040180806020018281038252602e8152602001806119ea602e913960400191505060405180910390fd5b6109e184848080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152505060408051808201909152601b81527f726577617264466f7256616c696461746f725365744368616e676500000000006020820152915061161e9050565b15610ac05760208114610a255760405162461bcd60e51b815260040180806020018281038252602e815260200180611989602e913960400191505060405180910390fd5b604080516020601f8401819004810282018101909252828152600091610a639185858083850183828082843760009201919091525061170592505050565b9050600081118015610a7d5750670de0b6b3a76400008111155b610ab85760405162461bcd60e51b815260040180806020018281038252602f815260200180611a18602f913960400191505060405180910390fd5b600555610afd565b6040805162461bcd60e51b815260206004820152600d60248201526c756e6b6e6f776e20706172616d60981b604482015290519081900360640190fd5b7f6cdb0ac70ab7f2e2d035cca5be60d89906f2dede7648ddbd7402189c1eeed17a848484846040518080602001806020018381038352878782818152602001925080828437600083820152601f01601f191690910184810383528581526020019050858580828437600083820152604051601f909101601f19169092018290039850909650505050505050a150505050565b60045481565b61100281565b6001600160401b03166000908152600160208190526040909120015490565b60408051630a83aaa960e31b815233600482015290516000916110069163541d554891602480820192602092909190829003018186803b158015610bfd57600080fd5b505afa158015610c11573d6000803e3d6000fd5b505050506040513d6020811015610c2757600080fd5b5051610c7a576040805162461bcd60e51b815260206004820152601f60248201527f746865206d73672073656e646572206973206e6f7420612072656c6179657200604482015290519081900360640190fd5b6001600160401b0382166000908152600260205260409020546001600160a01b031615610cee576040805162461bcd60e51b815260206004820152601c60248201527f63616e27742073796e63206475706c6963617465642068656164657200000000604482015290519081900360640190fd5b6003546001600160401b0390811690831611610d3b5760405162461bcd60e51b8152600401808060200182810382526026815260200180611a476026913960400191505060405180910390fd5b600354600160401b90046001600160401b0316610d56611867565b6001600160401b0382811660009081526001602081815260409283902083516080810185528154909516855280830154858301526002808201548686015260038201805486516101009682161596909602600019011691909104601f81018490048402850184019095528484529093606086019392830182828015610e1c5780601f10610df157610100808354040283529160200191610e1c565b820191906000526020600020905b815481529060010190602001808311610dff57829003601f168201915b50505050508152505090505b836001600160401b0316826001600160401b031610158015610e5957506003546001600160401b0390811690831610155b15610f3a5780516001600160401b0380821660009081526001602081815260409283902083516080810185528154909516855280830154858301526002808201548686015260038201805486516101009682161596909602600019011691909104601f8101849004840285018401909552848452959750939460608601939091830182828015610f2a5780601f10610eff57610100808354040283529160200191610f2a565b820191906000526020600020905b815481529060010190602001808311610f0d57829003601f168201915b5050505050815250509050610e28565b6060810151516110315780516001600160401b03811660009081526001602081815260409283902060030180548451600294821615610100026000190190911693909304601f810183900483028401830190945283835293955090929190830182828015610fe95780601f10610fbe57610100808354040283529160200191610fe9565b820191906000526020600020905b815481529060010190602001808311610fcc57829003601f168201915b505050506060830182905250516110315760405162461bcd60e51b81526004018080602001828103825260218152602001806119686021913960400191505060405180910390fd5b6000816060015151608801905060608787905082016040519080825280601f01601f191660200182016040528015611070576020820181803683370190505b509050600061107e8261170a565b905061108c84868386611710565b6110c75760405162461bcd60e51b81526004018080602001828103825260238152602001806119456023913960400191505060405180910390fd5b6000838201915061110d8a8a8080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061177c92505050565b9450905061111c818386611786565b8251602001935061112b61188d565b6110008186866064600019fa61114057600080fd5b805194506000600160f81b8616156111cf5750600554604080516309a99b4f60e41b815233600482015260248101929092525160019161100291639a99b4f0916044808201926020929091908290030181600087803b1580156111a257600080fd5b505af11580156111b6573d6000803e3d6000fd5b505050506040513d60208110156111cc57600080fd5b50505b856001600160401b0316955060208201935060006111ef858884156117c7565b90985090506001600160401b03808216908c161461123e5760405162461bcd60e51b81526004018080602001828103825260338152602001806119b76033913960400191505060405180910390fd5b6001600160401b03808c16600081815260026020818152604080842080546001600160a01b031916331790558e86168e529383526001808252928490208d518154961667ffffffffffffffff199096169590951785558c81015192850192909255918b01519183019190915560608a015180518b93926112c59260038501929101906118ac565b50506003546001600160401b03600160401b9091048116908d161115905061130d576003805467ffffffffffffffff60401b1916600160401b6001600160401b038e16021790555b7f4042c1020a8f410fb1c8859d276ab436aeb2c3074960e48467299cf1c966d3b48b8a8a602001518560405180856001600160401b03166001600160401b03168152602001846001600160401b03166001600160401b031681526020018381526020018215151515815260200194505050505060405180910390a15060019c9b505050505050505050505050565b6002602052600090815260409020546001600160a01b031681565b61100381565b6001600160401b03166000908152600260205260409020546001600160a01b031690565b6001600160401b0381166000908152600260205260408120546001600160a01b031615158061141c57506003546001600160401b038381169116145b92915050565b60005460ff161561147a576040805162461bcd60e51b815260206004820152601960248201527f74686520636f6e747261637420616c726561647920696e697400000000000000604482015290519081900360640190fd5b6000806114a16040518061024001604052806102208152602001611a6d610220913961177c565b815160045590925090506114b3611867565b60006114c1848460006117c7565b60008083526001600160401b038281168252600160208181526040938490208651815467ffffffffffffffff191694169390931783558086015191830191909155918401516002820155606084015180519496509294508593909261152d9260038501929101906118ac565b50506003805467ffffffffffffffff19166001600160401b0384811691821767ffffffffffffffff60401b1916600160401b9290920291909117918290556000805460ff19166001179055662386f26fc10000600555602085810151604080519490931684529083015280517f5ac9b37d571677b80957ca05693f371526c602fd08042b416a29fdab7efefa499350918290030190a150505050565b6003546001600160401b031681565b600354600160401b90046001600160401b031681565b6040518061024001604052806102208152602001611a6d610220913981565b61100081565b600381565b61100481565b6000816040516020018082805190602001908083835b602083106116535780518252601f199092019160209182019101611634565b6001836020036101000a03801982511681845116808217855250505050505090500191505060405160208183030381529060405280519060200120836040516020018082805190602001908083835b602083106116c15780518252601f1990920191602091820191016116a2565b6001836020036101000a0380198251168184511680821785525050505050509050019150506040516020818303038152906040528051906020012014905092915050565b015190565b60200190565b600084606001515182840103925060008061172e876060015161177c565b909250905061173e828683611786565b5050506040840151601f1983810191909152602090940151603f19830152605f19820192909252600454606719820152910160871990910152600190565b8051602090910191565b5b602081106117a6578251825260209283019290910190601f1901611787565b915181516020939093036101000a6000190180199091169216919091179052565b6117cf611867565b60088401516028850151604890950180519095600092916117ee611867565b6020810183905260408101829052866118595760008060688a036040519080825280601f01601f191660200182016040528015611832576020820181803683370190505b50606084018190526118439061177c565b909250905061185660208c018383611786565b50505b989297509195505050505050565b604080516080810182526000808252602082018190529181019190915260608082015290565b6040518061100001604052806080906020820280368337509192915050565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f106118ed57805160ff191683800117855561191a565b8280016001018555821561191a579182015b8281111561191a5782518255916020019190600101906118ff565b5061192692915061192a565b5090565b6107e391905b80821115611926576000815560010161193056fe6661696c656420746f2073657269616c697a6520636f6e73656e7375732073746174656661696c656420746f206c6f61642076616c696461746f722073657420646174616c656e677468206f6620726577617264466f7256616c696461746f725365744368616e6765206d69736d617463686865616465722068656967687420646f65736e277420657175616c20746f207468652073706563696669656420686569676874746865206d6573736167652073656e646572206d75737420626520676f7665726e616e636520636f6e7472616374746865206e6577526577617264466f7256616c696461746f725365744368616e6765206f7574206f662072616e676563616e27742073796e6320686561646572206265666f726520696e697469616c48656967687442696e616e63652d436861696e2d5469677269730000000000000000000000000000000006915167cedaf7bbf7df47d932fdda630527ee648562cf3e52c5e5f46156a3a971a4ceb443c53a50d8653ef8cf1e5716da68120fb51b636dc6d111ec3277b098ecd42d49d3769d8a1f78b4c17a965f7a30d4181fabbd1f969f46d3c8e83b5ad4845421d8000000e8d4a510002ba4e81542f437b7ae1f8a35ddb233c789a8dc22734377d9b6d63af1ca403b61000000e8d4a51000df8da8c5abfdb38595391308bb71e5a1e0aabdc1d0cf38315d50d6be939b2606000000e8d4a51000b6619edca4143484800281d698b70c935e9152ad57b31d85c05f2f79f64b39f3000000e8d4a510009446d14ad86c8d2d74780b0847110001a1c2e252eedfea4753ebbbfce3a22f52000000e8d4a510000353c639f80cc8015944436dab1032245d44f912edc31ef668ff9f4a45cd0599000000e8d4a51000e81d3797e0544c3a718e1f05f0fb782212e248e784c1a851be87e77ae0db230e000000e8d4a510005e3fcda30bd19d45c4b73688da35e7da1fce7c6859b2c1f20ed5202d24144e3e000000e8d4a51000b06a59a2d75bf5d014fce7c999b5e71e7a960870f725847d4ba3235baeaa08ef000000e8d4a510000c910e2fe650e4e01406b3310b489fb60a84bc3ff5c5bee3a56d5898b6a8af32000000e8d4a5100071f2d7b8ec1c8b99a653429b0118cd201f794f409d0fea4d65b1b662f2b00063000000e8d4a51000a264697066735822122032fc162aed7c2a4fe0f40397d327efc38d8aaf5dbdd1720f7f5d8101877da61d64736f6c63430006040033" + }, + "0x0000000000000000000000000000000000001004": { + "balance": "176405560900000000000000000", + "code": "0x60806040526004361061031e5760003560e01c80639a99b4f0116101ab578063bd466461116100f7578063f014847211610095578063fc1a598f1161006f578063fc1a598f14610cb3578063fc3e590814610686578063fd6a687914610ce6578063ff9c0027146107dc57610366565b8063f014847214610c74578063f9a2bbc714610c89578063fa9e915914610c9e57610366565b8063d9e6dae9116100d1578063d9e6dae914610608578063dc927faf14610c35578063e1c7392a14610c4a578063ebf71d5314610c5f57610366565b8063bd46646114610b68578063c81b166214610b9b578063c8509d8114610bb057610366565b8063aa7415f511610164578063b99328c51161013e578063b99328c514610ad2578063b9fd21e314610b0b578063ba35ead614610b20578063bbface1f14610b3557610366565b8063aa7415f5146109ab578063ab51bb96146109f2578063ac43175114610a0757610366565b80639a99b4f01461091e5780639dc0926214610957578063a1a11bf51461096c578063a496fba214610981578063a78abc1614610996578063a7c9f02d1461068657610366565b8063613684751161026a57806375d47a0a116102235780638b87b21f116101fd5780638b87b21f146105875780638eff336c146108b557806396713da9146108f45780639a854bbd1461090957610366565b806375d47a0a146108065780637942fd051461081b578063831d65d11461083057610366565b8063613684751461060857806366dea52a146106865780636e0565201461069b5780636e47b482146107c757806370fd5bad146107dc57806371d30863146107f157610366565b806343a368b9116102d757806350432d32116102b157806350432d321461061d57806351e806721461063257806359b92789146106475780635d499b1b1461067157610366565b806343a368b9146105c7578063493279b1146105dc5780634bf6c8821461060857610366565b80630bee7a671461036b5780631182b87514610399578063149d14d9146104935780633d713223146104ba5780633dffc3871461058757806343756e5c146105b257610366565b36610366573415610364576040805133815234602082015281517f6c98249d85d88c3753a04a22230f595e4dc8d3dc86c34af35deeeedc861b89db929181900390910190a15b005b600080fd5b34801561037757600080fd5b50610380610cfb565b6040805163ffffffff9092168252519081900360200190f35b3480156103a557600080fd5b5061041e600480360360408110156103bc57600080fd5b60ff8235169190810190604081016020820135600160201b8111156103e057600080fd5b8201836020820111156103f257600080fd5b803590602001918460018302840111600160201b8311171561041357600080fd5b509092509050610d00565b6040805160208082528351818301528351919283929083019185019080838360005b83811015610458578181015183820152602001610440565b50505050905090810190601f1680156104855780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b34801561049f57600080fd5b506104a8610e2e565b60408051918252519081900360200190f35b3480156104c657600080fd5b5061056b600480360360208110156104dd57600080fd5b810190602081018135600160201b8111156104f757600080fd5b82018360208201111561050957600080fd5b803590602001918460018302840111600160201b8311171561052a57600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250929550610e34945050505050565b604080516001600160a01b039092168252519081900360200190f35b34801561059357600080fd5b5061059c610e58565b6040805160ff9092168252519081900360200190f35b3480156105be57600080fd5b5061056b610e5d565b3480156105d357600080fd5b506104a8610e63565b3480156105e857600080fd5b506105f1610e6f565b6040805161ffff9092168252519081900360200190f35b34801561061457600080fd5b5061059c610e74565b34801561062957600080fd5b506104a8610e79565b34801561063e57600080fd5b5061056b610e84565b34801561065357600080fd5b5061056b6004803603602081101561066a57600080fd5b5035610e8a565b34801561067d57600080fd5b506104a8610ea5565b34801561069257600080fd5b5061059c610eae565b6107b3600480360360808110156106b157600080fd5b810190602081018135600160201b8111156106cb57600080fd5b8201836020820111156106dd57600080fd5b803590602001918460208302840111600160201b831117156106fe57600080fd5b919390929091602081019035600160201b81111561071b57600080fd5b82018360208201111561072d57600080fd5b803590602001918460208302840111600160201b8311171561074e57600080fd5b919390929091602081019035600160201b81111561076b57600080fd5b82018360208201111561077d57600080fd5b803590602001918460208302840111600160201b8311171561079e57600080fd5b91935091503567ffffffffffffffff16610eb3565b604080519115158252519081900360200190f35b3480156107d357600080fd5b5061056b611388565b3480156107e857600080fd5b5061059c61138e565b3480156107fd57600080fd5b506104a8611393565b34801561081257600080fd5b5061056b611399565b34801561082757600080fd5b5061059c61139f565b34801561083c57600080fd5b506103646004803603604081101561085357600080fd5b60ff8235169190810190604081016020820135600160201b81111561087757600080fd5b82018360208201111561088957600080fd5b803590602001918460018302840111600160201b831117156108aa57600080fd5b5090925090506113a4565b3480156108c157600080fd5b50610364600480360360608110156108d857600080fd5b508035906001600160a01b0360208201351690604001356114ed565b34801561090057600080fd5b5061059c611573565b34801561091557600080fd5b506104a8611578565b34801561092a57600080fd5b506104a86004803603604081101561094157600080fd5b506001600160a01b038135169060200135611584565b34801561096357600080fd5b5061056b6116c2565b34801561097857600080fd5b5061056b6116c8565b34801561098d57600080fd5b5061059c6116ce565b3480156109a257600080fd5b506107b36116d3565b6107b3600480360360808110156109c157600080fd5b5080356001600160a01b03908116916020810135909116906040810135906060013567ffffffffffffffff166116dc565b3480156109fe57600080fd5b506103806116ce565b348015610a1357600080fd5b5061036460048036036040811015610a2a57600080fd5b810190602081018135600160201b811115610a4457600080fd5b820183602082011115610a5657600080fd5b803590602001918460018302840111600160201b83111715610a7757600080fd5b919390929091602081019035600160201b811115610a9457600080fd5b820183602082011115610aa657600080fd5b803590602001918460018302840111600160201b83111715610ac757600080fd5b509092509050611d9d565b348015610ade57600080fd5b5061036460048036036040811015610af557600080fd5b50803590602001356001600160a01b031661200c565b348015610b1757600080fd5b506104a8612082565b348015610b2c57600080fd5b506104a861208c565b348015610b4157600080fd5b506104a860048036036020811015610b5857600080fd5b50356001600160a01b0316612092565b348015610b7457600080fd5b506104a860048036036020811015610b8b57600080fd5b50356001600160a01b03166120a4565b348015610ba757600080fd5b5061056b6120bf565b348015610bbc57600080fd5b5061036460048036036040811015610bd357600080fd5b60ff8235169190810190604081016020820135600160201b811115610bf757600080fd5b820183602082011115610c0957600080fd5b803590602001918460018302840111600160201b83111715610c2a57600080fd5b5090925090506120c5565b348015610c4157600080fd5b5061056b612195565b348015610c5657600080fd5b5061036461219b565b348015610c6b57600080fd5b5061059c61223b565b348015610c8057600080fd5b5061059c612240565b348015610c9557600080fd5b5061056b612245565b348015610caa57600080fd5b506104a861224b565b348015610cbf57600080fd5b5061041e60048036036020811015610cd657600080fd5b50356001600160a01b0316612251565b348015610cf257600080fd5b5061056b612378565b606481565b60005460609060ff16610d48576040805162461bcd60e51b815260206004820152601960248201526000805160206147bf833981519152604482015290519081900360640190fd5b3361200014610d885760405162461bcd60e51b815260040180806020018281038252602f81526020018061476d602f913960400191505060405180910390fd5b60ff841660021415610dda57610dd383838080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061237e92505050565b9050610e27565b6040805162461bcd60e51b815260206004820152601860248201527f756e7265636f676e697a65642073796e207061636b6167650000000000000000604482015290519081900360640190fd5b9392505050565b60015490565b6020818101516000908152600490915260409020546001600160a01b03165b919050565b600181565b61100181565b670de0b6b3a764000081565b603881565b600881565b66071afd498d000081565b61200081565b6000908152600460205260409020546001600160a01b031690565b6402540be40081565b600381565b6000805460ff16610ef9576040805162461bcd60e51b815260206004820152601960248201526000805160206147bf833981519152604482015290519081900360640190fd5b868514610f375760405162461bcd60e51b815260040180806020018281038252603b815260200180614732603b913960400191505060405180910390fd5b868314610f755760405162461bcd60e51b815260040180806020018281038252603f815260200180614605603f913960400191505060405180910390fd5b426078018267ffffffffffffffff161015610fc15760405162461bcd60e51b81526004018080602001828103825260248152602001806144f56024913960400191505060405180910390fd5b6402540be4003406156110055760405162461bcd60e51b81526004018080602001828103825260408152602001806148356040913960400191505060405180910390fd5b60408051868152602080880282010190915285906000908190606090848015611038578160200160208202803683370190505b50905060005b84811015611113576402540be4008b8b8381811061105857fe5b905060200201358161106657fe5b06156110a35760405162461bcd60e51b815260040180806020018281038252603c815260200180614644603c913960400191505060405180910390fd5b6110c88b8b838181106110b257fe5b90506020020135856124a290919063ffffffff16565b93506110f46402540be4008c8c848181106110df57fe5b905060200201356124fc90919063ffffffff16565b82828151811061110057fe5b602090810291909101015260010161103e565b506001546111389061112b908663ffffffff61253e16565b849063ffffffff6124a216565b3410156111765760405162461bcd60e51b81526004018080602001828103825260568152602001806147df6056913960600191505060405180910390fd5b611186348463ffffffff61259716565b915061119061434e565b6040518060c001604052806221272160e91b60001b815260200160006001600160a01b031681526020018381526020018e8e808060200260200160405190810160405280939291908181526020018383602002808284376000920191909152505050908252506040805160208c810282810182019093528c82529283019290918d918d91829185019084908082843760009201919091525050509082525067ffffffffffffffff8916602090910152905061200063f7a251d76003611254846125d9565b611269876402540be40063ffffffff6124fc16565b6040518463ffffffff1660e01b8152600401808460ff1660ff16815260200180602001838152602001828103825284818151815260200191508051906020019080838360005b838110156112c75781810151838201526020016112af565b50505050905090810190601f1680156112f45780820380516001836020036101000a031916815260200191505b50945050505050600060405180830381600087803b15801561131557600080fd5b505af1158015611329573d6000803e3d6000fd5b505060408051600081523360208201528082018890526060810187905290517f74eab09b0e53aefc23f2e1b16da593f95c2dd49c6f5a23720463d10d9c330b2a9350908190036080019150a15060019c9b505050505050505050505050565b61100581565b600281565b60015481565b61100881565b600b81565b60005460ff166113e9576040805162461bcd60e51b815260206004820152601960248201526000805160206147bf833981519152604482015290519081900360640190fd5b33612000146114295760405162461bcd60e51b815260040180806020018281038252602f81526020018061476d602f913960400191505060405180910390fd5b60ff8316600314156114795761147482828080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061289492505050565b6114e8565b7f41ce201247b6ceb957dcdb217d0b8acb50b9ea0e12af9af4f5e7f38902101605838383604051808460ff1660ff168152602001806020018281038252848482818152602001925080828437600083820152604051601f909101601f1916909201829003965090945050505050a15b505050565b336110081461152d5760405162461bcd60e51b815260040180806020018281038252602381526020018061479c6023913960400191505060405180910390fd5b600083815260046020908152604080832080546001600160a01b039096166001600160a01b03199096168617905593825260038152838220949094556002909352912055565b600981565b677ce66c50e284000081565b6000805460ff166115ca576040805162461bcd60e51b815260206004820152601960248201526000805160206147bf833981519152604482015290519081900360640190fd5b336110051461160a5760405162461bcd60e51b815260040180806020018281038252602f815260200180614468602f913960400191505060405180910390fd5b6000478310611619574761161b565b825b9050670de0b6b3a76400008111156116375760009150506116bc565b80156116b9576040516001600160a01b0385169082156108fc029083906000818181858888f19350505050158015611673573d6000803e3d6000fd5b50604080516001600160a01b03861681526020810183905281517ff8b71c64315fc33b2ead2adfa487955065152a8ac33d9d5193aafd7f45dc15a0929181900390910190a15b90505b92915050565b61100781565b61100681565b600081565b60005460ff1681565b6000805460ff16611722576040805162461bcd60e51b815260206004820152601960248201526000805160206147bf833981519152604482015290519081900360640190fd5b426078018267ffffffffffffffff16101561176e5760405162461bcd60e51b81526004018080602001828103825260248152602001806144f56024913960400191505060405180910390fd5b6402540be4003406156117b25760405162461bcd60e51b81526004018080602001828103825260408152602001806148356040913960400191505060405180910390fd5b600080806001600160a01b038816611891576001546117d890879063ffffffff6124a216565b3410156118165760405162461bcd60e51b815260040180806020018281038252606181526020018061457f6061913960800191505060405180910390fd5b6402540be40086061561185a5760405162461bcd60e51b815260040180806020018281038252603c815260200180614644603c913960400191505060405180910390fd5b61186a348763ffffffff61259716565b9050611881866402540be40063ffffffff6124fc16565b6221272160e91b93509150611b34565b6001600160a01b0388166000908152600360205260409020549250826118e85760405162461bcd60e51b815260040180806020018281038252603181526020018061454e6031913960400191505060405180910390fd5b6001543410156119295760405162461bcd60e51b815260040180806020018281038252603f8152602001806146a1603f913960400191505060405180910390fd5b506001600160a01b038716600090815260026020526040902054349060088111158061197457506008811180156119745750611972876007198301600a0a63ffffffff6128f016565b155b6119af5760405162461bcd60e51b815260040180806020018281038252603c815260200180614644603c913960400191505060405180910390fd5b6119b98782612932565b92506119c484612972565b15611a0c576305f5e100831015611a0c5760405162461bcd60e51b815260040180806020018281038252603a815260200180614497603a913960400191505060405180910390fd5b600881101580611a265750600881108015611a2657508683115b611a615760405162461bcd60e51b81526004018080602001828103825260258152602001806145e06025913960400191505060405180910390fd5b677ce66c50e2840000831115611aa85760405162461bcd60e51b81526004018080602001828103825260358152602001806145196035913960400191505060405180910390fd5b604080516323b872dd60e01b81523360048201523060248201526044810189905290516001600160a01b038b16916323b872dd9160648083019260209291908290030181600087803b158015611afd57600080fd5b505af1158015611b11573d6000803e3d6000fd5b505050506040513d6020811015611b2757600080fd5b5051611b3257600080fd5b505b611b3c61434e565b6040805160c0810182528581526001600160a01b038b166020820152815160018082528184018452919283019181602001602082028036833750505081526040805160018082528183019092526020928301929091908083019080368337505050815260408051600180825281830190925260209283019290919080830190803683370190505081526020018767ffffffffffffffff168152509050828160400151600081518110611bea57fe5b602002602001018181525050878160600151600081518110611c0857fe5b60200260200101906001600160a01b031690816001600160a01b031681525050338160800151600081518110611c3a57fe5b6001600160a01b039092166020928302919091019091015261200063f7a251d76003611c65846125d9565b611c7a866402540be40063ffffffff6124fc16565b6040518463ffffffff1660e01b8152600401808460ff1660ff16815260200180602001838152602001828103825284818151815260200191508051906020019080838360005b83811015611cd8578181015183820152602001611cc0565b50505050905090810190601f168015611d055780820380516001836020036101000a031916815260200191505b50945050505050600060405180830381600087803b158015611d2657600080fd5b505af1158015611d3a573d6000803e3d6000fd5b5050604080516001600160a01b038d1681523360208201528082018b90526060810186905290517f74eab09b0e53aefc23f2e1b16da593f95c2dd49c6f5a23720463d10d9c330b2a9350908190036080019150a150600198975050505050505050565b3361100714611ddd5760405162461bcd60e51b815260040180806020018281038252602e8152602001806146e0602e913960400191505060405180910390fd5b60208114611e32576040805162461bcd60e51b815260206004820152601b60248201527f65787065637465642076616c7565206c656e6774682069732033320000000000604482015290519081900360640190fd5b606084848080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525050604080516020601f8801819004810282018101909252868152939450606093925086915085908190840183828082843760009201919091525050505060208301519091506772656c617946656560c01b811415611f3a576020820151670de0b6b3a76400008111801590611ee157506402540be4008106155b611f32576040805162461bcd60e51b815260206004820152601960248201527f7468652072656c6179466565206f7574206f662072616e676500000000000000604482015290519081900360640190fd5b600155611f77565b6040805162461bcd60e51b815260206004820152600d60248201526c756e6b6e6f776e20706172616d60981b604482015290519081900360640190fd5b7f6cdb0ac70ab7f2e2d035cca5be60d89906f2dede7648ddbd7402189c1eeed17a878787876040518080602001806020018381038352878782818152602001925080828437600083820152601f01601f191690910184810383528581526020019050858580828437600083820152604051601f909101601f19169092018290039850909650505050505050a150505050505050565b336110081461204c5760405162461bcd60e51b815260040180806020018281038252602381526020018061479c6023913960400191505060405180910390fd5b600091825260046020908152604080842080546001600160a01b03191690556001600160a01b0392909216835260039052812055565b6221272160e91b81565b61c35081565b60026020526000908152604090205481565b6001600160a01b031660009081526003602052604090205490565b61100281565b60005460ff1661210a576040805162461bcd60e51b815260206004820152601960248201526000805160206147bf833981519152604482015290519081900360640190fd5b336120001461214a5760405162461bcd60e51b815260040180806020018281038252602f81526020018061476d602f913960400191505060405180910390fd5b60ff8316600314156114795761147482828080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250612a7892505050565b61100381565b60005460ff16156121f3576040805162461bcd60e51b815260206004820152601960248201527f74686520636f6e747261637420616c726561647920696e697400000000000000604482015290519081900360640190fd5b66071afd498d000060019081556000808052600260205260127fac33ff75c19e70fe83507db0d683fd3465c996598dc972688b7ace676c89077b55805460ff19169091179055565b600481565b600581565b61100081565b61271081565b6001600160a01b03811660009081526003602090815260409182902054825182815280840190935260609290918391906020820181803683375050506020810183905290506000805b60208160ff1610156122e157828160ff16815181106122b557fe5b01602001516001600160f81b031916156122d4576001909101906122d9565b6122e1565b60010161229a565b5060608160ff166040519080825280601f01601f191660200182016040528015612312576020820181803683370190505b50905060005b8260ff168160ff16101561236e57838160ff168151811061233557fe5b602001015160f81c60f81b828260ff168151811061234f57fe5b60200101906001600160f81b031916908160001a905350600101612318565b5095945050505050565b61100481565b606061238861439a565b600061239384612b76565b91509150806123e9576040805162461bcd60e51b815260206004820152601f60248201527f756e7265636f676e697a6564207472616e73666572496e207061636b61676500604482015290519081900360640190fd5b60006123f483612cb5565b905063ffffffff811615612488576040808401516020808601516001600160a01b0316600090815260029091529182205461242f9190612932565b90506124396143cf565b60405180608001604052808660000151815260200183815260200186608001516001600160a01b031681526020018463ffffffff16815250905061247c81613002565b95505050505050610e53565b50506040805160008152602081019091529150610e539050565b6000828201838110156116b9576040805162461bcd60e51b815260206004820152601b60248201527f536166654d6174683a206164646974696f6e206f766572666c6f770000000000604482015290519081900360640190fd5b60006116b983836040518060400160405280601a81526020017f536166654d6174683a206469766973696f6e206279207a65726f0000000000008152506130de565b60008261254d575060006116bc565b8282028284828161255a57fe5b04146116b95760405162461bcd60e51b81526004018080602001828103825260218152602001806146806021913960400191505060405180910390fd5b60006116b983836040518060400160405280601e81526020017f536166654d6174683a207375627472616374696f6e206f766572666c6f770000815250613180565b60408051600680825260e08201909252606091829190816020015b60608152602001906001900390816125f45750508351909150612616906131da565b8160008151811061262357fe5b602002602001018190525061264483602001516001600160a01b03166131ed565b8160018151811061265157fe5b60200260200101819052506000836040015151905060608160405190808252806020026020018201604052801561269c57816020015b60608152602001906001900390816126875790505b50905060005b828110156126e9576126ca866040015182815181106126bd57fe5b60200260200101516131da565b8282815181106126d657fe5b60209081029190910101526001016126a2565b506126f381613210565b8360028151811061270057fe5b602002602001018190525060608260405190808252806020026020018201604052801561274157816020015b606081526020019060019003908161272c5790505b50905060005b83811015612797576127788760600151828151811061276257fe5b60200260200101516001600160a01b03166131ed565b82828151811061278457fe5b6020908102919091010152600101612747565b506127a181613210565b846003815181106127ae57fe5b60200260200101819052506060836040519080825280602002602001820160405280156127ef57816020015b60608152602001906001900390816127da5790505b50905060005b8481101561282f576128108860800151828151811061276257fe5b82828151811061281c57fe5b60209081029190910101526001016127f5565b5061283981613210565b8560048151811061284657fe5b60200260200101819052506128688760a0015167ffffffffffffffff166131da565b8560058151811061287557fe5b602002602001018190525061288985613210565b979650505050505050565b61289c6143f6565b60006128a78361329a565b91509150806128e75760405162461bcd60e51b815260040180806020018281038252602481526020018061470e6024913960400191505060405180910390fd5b6114e882613465565b60006116b983836040518060400160405280601881526020017f536166654d6174683a206d6f64756c6f206279207a65726f00000000000000008152506138e9565b6000600882111561295b57612954836007198401600a0a63ffffffff6124fc16565b90506116bc565b6116b9836008849003600a0a63ffffffff61253e16565b604080516020808252818301909252600091606091906020820181803683375050506020810184905290506000805b60208160ff1610156129e857828160ff16815181106129bc57fe5b01602001516001600160f81b031916156129db576001909101906129e0565b6129e8565b6001016129a1565b50600860ff82161015612a0057600092505050610e53565b816005820360ff1681518110612a1257fe5b6020910101516001600160f81b031916602d60f81b14612a3757600092505050610e53565b816001820360ff1681518110612a4957fe5b6020910101516001600160f81b031916604d60f81b14612a6e57600092505050610e53565b5060019392505050565b612a8061434e565b6000612a8b8361394b565b9150915080612acb5760405162461bcd60e51b81526004018080602001828103825260248152602001806144d16024913960400191505060405180910390fd5b612ad36143f6565b602080840180516001600160a01b0390811684526040808701518585015291511660009081526002909252812054905b846040015151811015612b5457612b3185604001518281518110612b2357fe5b602002602001015183613bc6565b85604001518281518110612b4157fe5b6020908102919091010152600101612b03565b506080840151604083015260056060830152612b6f82613465565b5050505050565b612b7e61439a565b6000612b8861439a565b612b9061442d565b612ba1612b9c86613bff565b613c24565b90506000805b612bb083613c6e565b15612ca85780612bd257612bcb612bc684613c8f565b613cdd565b8452612ca0565b8060011415612bff57612bec612be784613c8f565b613d94565b6001600160a01b03166020850152612ca0565b8060021415612c1e57612c14612bc684613c8f565b6040850152612ca0565b8060031415612c4657612c33612be784613c8f565b6001600160a01b03166060850152612ca0565b8060041415612c6e57612c5b612be784613c8f565b6001600160a01b03166080850152612ca0565b8060051415612c9b57612c83612bc684613c8f565b67ffffffffffffffff1660a085015260019150612ca0565b612ca8565b600101612ba7565b5091935090915050915091565b60208101516000906001600160a01b0316612dec578160a0015167ffffffffffffffff16421115612ce857506001610e53565b8160400151471015612cfc57506003610e53565b606082015160408084015190516000926001600160a01b0316916127109184818181858888f193505050503d8060008114612d53576040519150601f19603f3d011682016040523d82523d6000602084013e612d58565b606091505b5050905080612d6b575060049050610e53565b7f471eb9cc1ffe55ffadf15b32595415eb9d80f22e761d24bd6dffc607e1284d5983602001518460600151856040015160405180846001600160a01b03166001600160a01b03168152602001836001600160a01b03166001600160a01b03168152602001828152602001935050505060405180910390a15060009050610e53565b8160a0015167ffffffffffffffff16421115612e0a57506001610e53565b81516020808401516001600160a01b031660009081526003909152604090205414612e3757506002610e53565b602080830151604080516370a0823160e01b815230600482015290516000936001600160a01b03909316926370a082319261c3509260248083019392829003018187803b158015612e8757600080fd5b5086fa158015612e9b573d6000803e3d6000fd5b50505050506040513d6020811015612eb257600080fd5b50516040840151909150811015612ecd575060039050610e53565b600083602001516001600160a01b031663a9059cbb61c350866060015187604001516040518463ffffffff1660e01b815260040180836001600160a01b03166001600160a01b0316815260200182815260200192505050602060405180830381600088803b158015612f3e57600080fd5b5087f1158015612f52573d6000803e3d6000fd5b50505050506040513d6020811015612f6957600080fd5b505190508015612ff6577f471eb9cc1ffe55ffadf15b32595415eb9d80f22e761d24bd6dffc607e1284d5984602001518560600151866040015160405180846001600160a01b03166001600160a01b03168152602001836001600160a01b03166001600160a01b03168152602001828152602001935050505060405180910390a15060009150610e539050565b5060059150610e539050565b60408051600480825260a08201909252606091829190816020015b606081526020019060019003908161301d575050835190915061303f906131da565b8160008151811061304c57fe5b602002602001018190525061306483602001516131da565b8160018151811061307157fe5b602002602001018190525061309283604001516001600160a01b03166131ed565b8160028151811061309f57fe5b60200260200101819052506130bd836060015163ffffffff166131da565b816003815181106130ca57fe5b6020026020010181905250610e2781613210565b6000818361316a5760405162461bcd60e51b81526004018080602001828103825283818151815260200191508051906020019080838360005b8381101561312f578181015183820152602001613117565b50505050905090810190601f16801561315c5780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b50600083858161317657fe5b0495945050505050565b600081848411156131d25760405162461bcd60e51b815260206004820181815283516024840152835190928392604490910191908501908083836000831561312f578181015183820152602001613117565b505050900390565b60606116bc6131e883613dae565b613e94565b60408051600560a21b8318601482015260348101909152606090610e2781613e94565b60608151600014156132315750604080516000815260208101909152610e53565b60608260008151811061324057fe5b602002602001015190506000600190505b8351811015613281576132778285838151811061326a57fe5b6020026020010151613ee6565b9150600101613251565b50610e27613294825160c060ff16613f63565b82613ee6565b6132a26143f6565b60006132ac6143f6565b6132b461442d565b6132c0612b9c86613bff565b90506000805b6132cf83613c6e565b15612ca857806132f5576132e5612be784613c8f565b6001600160a01b0316845261345d565b806001141561339657606061331161330c85613c8f565b61405b565b9050805160405190808252806020026020018201604052801561333e578160200160208202803683370190505b50602086015260005b815181101561338f5761336c82828151811061335f57fe5b6020026020010151613cdd565b8660200151828151811061337c57fe5b6020908102919091010152600101613347565b505061345d565b80600214156134385760606133ad61330c85613c8f565b905080516040519080825280602002602001820160405280156133da578160200160208202803683370190505b50604086015260005b815181101561338f576134088282815181106133fb57fe5b6020026020010151613d94565b8660400151828151811061341857fe5b6001600160a01b03909216602092830291909101909101526001016133e3565b8060031415612c9b5761344d612bc684613c8f565b63ffffffff166060850152600191505b6001016132c6565b80516001600160a01b031661368f5760005b8160200151518110156136895760008260400151828151811061349657fe5b60200260200101516001600160a01b0316612710846020015184815181106134ba57fe5b60209081029190910101516040516000818181858888f193505050503d8060008114613502576040519150601f19603f3d011682016040523d82523d6000602084013e613507565b606091505b50509050806135ca577f203f9f67a785f4f81be4d48b109aa0c498d1bc8097ecc2627063f480cc5fe73e83600001518460400151848151811061354657fe5b60200260200101518560200151858151811061355e57fe5b6020026020010151866060015160405180856001600160a01b03166001600160a01b03168152602001846001600160a01b03166001600160a01b031681526020018381526020018263ffffffff1663ffffffff16815260200194505050505060405180910390a1613680565b7fd468d4fa5e8fb4adc119b29a983fd0785e04af5cb8b7a3a69a47270c54b6901a83600001518460400151848151811061360057fe5b60200260200101518560200151858151811061361857fe5b6020026020010151866060015160405180856001600160a01b03166001600160a01b03168152602001846001600160a01b03166001600160a01b031681526020018381526020018263ffffffff1663ffffffff16815260200194505050505060405180910390a15b50600101613477565b506138e6565b60005b8160200151518110156138e457600082600001516001600160a01b031663a9059cbb61c350856040015185815181106136c757fe5b6020026020010151866020015186815181106136df57fe5b60200260200101516040518463ffffffff1660e01b815260040180836001600160a01b03166001600160a01b0316815260200182815260200192505050602060405180830381600088803b15801561373657600080fd5b5087f115801561374a573d6000803e3d6000fd5b50505050506040513d602081101561376157600080fd5b505190508015613825577fd468d4fa5e8fb4adc119b29a983fd0785e04af5cb8b7a3a69a47270c54b6901a8360000151846040015184815181106137a157fe5b6020026020010151856020015185815181106137b957fe5b6020026020010151866060015160405180856001600160a01b03166001600160a01b03168152602001846001600160a01b03166001600160a01b031681526020018381526020018263ffffffff1663ffffffff16815260200194505050505060405180910390a16138db565b7f203f9f67a785f4f81be4d48b109aa0c498d1bc8097ecc2627063f480cc5fe73e83600001518460400151848151811061385b57fe5b60200260200101518560200151858151811061387357fe5b6020026020010151866060015160405180856001600160a01b03166001600160a01b03168152602001846001600160a01b03166001600160a01b031681526020018381526020018263ffffffff1663ffffffff16815260200194505050505060405180910390a15b50600101613692565b505b50565b600081836139385760405162461bcd60e51b815260206004820181815283516024840152835190928392604490910191908501908083836000831561312f578181015183820152602001613117565b5082848161394257fe5b06949350505050565b61395361434e565b600061395d61434e565b61396561442d565b613971612b9c86613bff565b90506000805b61398083613c6e565b15613bb8578061399d57613996612bc684613c8f565b8452613bb0565b80600114156139c5576139b2612be784613c8f565b6001600160a01b03166020850152613bb0565b8060021415613a545760606139dc61330c85613c8f565b90508051604051908082528060200260200182016040528015613a09578160200160208202803683370190505b50604086015260005b8151811015613a4d57613a2a82828151811061335f57fe5b86604001518281518110613a3a57fe5b6020908102919091010152600101613a12565b5050613bb0565b8060031415613ae9576060613a6b61330c85613c8f565b90508051604051908082528060200260200182016040528015613a98578160200160208202803683370190505b50606086015260005b8151811015613a4d57613ab98282815181106133fb57fe5b86606001518281518110613ac957fe5b6001600160a01b0390921660209283029190910190910152600101613aa1565b8060041415613b7e576060613b0061330c85613c8f565b90508051604051908082528060200260200182016040528015613b2d578160200160208202803683370190505b50608086015260005b8151811015613a4d57613b4e8282815181106133fb57fe5b86608001518281518110613b5e57fe5b6001600160a01b0390921660209283029190910190910152600101613b36565b8060051415613bab57613b93612bc684613c8f565b67ffffffffffffffff1660a085015260019150613bb0565b613bb8565b600101613977565b509195600195509350505050565b60006008821115613be857612954836007198401600a0a63ffffffff61253e16565b6116b9836008849003600a0a63ffffffff6124fc16565b613c0761444d565b506040805180820190915281518152602082810190820152919050565b613c2c61442d565b613c358261412c565b613c3e57600080fd5b6000613c4d836020015161415c565b60208085015160408051808201909152868152920190820152915050919050565b6000613c7861444d565b505080518051602091820151919092015191011190565b613c9761444d565b613ca082613c6e565b613ca957600080fd5b60208201516000613cb9826141bf565b80830160209586015260408051808201909152908152938401919091525090919050565b805160009015801590613cf257508151602110155b613cfb57600080fd5b6000613d0a836020015161415c565b90508083600001511015613d65576040805162461bcd60e51b815260206004820152601a60248201527f6c656e677468206973206c657373207468616e206f6666736574000000000000604482015290519081900360640190fd5b825160208085015183018051928490039291831015613d8b57826020036101000a820491505b50949350505050565b8051600090601514613da557600080fd5b6116bc82613cdd565b604080516020808252818301909252606091829190602082018180368337505050602081018490529050600067ffffffffffffffff198416613df257506018613e16565b6fffffffffffffffffffffffffffffffff198416613e1257506010613e16565b5060005b6020811015613e4c57818181518110613e2b57fe5b01602001516001600160f81b03191615613e4457613e4c565b600101613e16565b60008160200390506060816040519080825280601f01601f191660200182016040528015613e81576020820181803683370190505b5080830196909652508452509192915050565b606081516001148015613ec65750607f60f81b82600081518110613eb457fe5b01602001516001600160f81b03191611155b15613ed2575080610e53565b6116bc613ee48351608060ff16613f63565b835b6060806040519050835180825260208201818101602087015b81831015613f17578051835260209283019201613eff565b50855184518101855292509050808201602086015b81831015613f44578051835260209283019201613f2c565b508651929092011591909101601f01601f191660405250905092915050565b6060680100000000000000008310613fb3576040805162461bcd60e51b815260206004820152600e60248201526d696e70757420746f6f206c6f6e6760901b604482015290519081900360640190fd5b6040805160018082528183019092526060916020820181803683370190505090506037841161400d5782840160f81b81600081518110613fef57fe5b60200101906001600160f81b031916908160001a90535090506116bc565b606061401885613dae565b90508381510160370160f81b8260008151811061403157fe5b60200101906001600160f81b031916908160001a9053506140528282613ee6565b95945050505050565b60606140668261412c565b61406f57600080fd5b600061407a836142f2565b90506060816040519080825280602002602001820160405280156140b857816020015b6140a561444d565b81526020019060019003908161409d5790505b50905060006140ca856020015161415c565b60208601510190506000805b84811015614121576140e7836141bf565b915060405180604001604052808381526020018481525084828151811061410a57fe5b6020908102919091010152918101916001016140d6565b509195945050505050565b805160009061413d57506000610e53565b6020820151805160001a9060c0821015612a6e57600092505050610e53565b8051600090811a6080811015614176576000915050610e53565b60b8811080614191575060c08110801590614191575060f881105b156141a0576001915050610e53565b60c08110156141b45760b519019050610e53565b60f519019050610e53565b80516000908190811a60808110156141da57600191506142eb565b60b88110156141ef57607e19810191506142eb565b60c081101561426957600060b78203600186019550806020036101000a865104915060018101820193505080831015614263576040805162461bcd60e51b81526020600482015260116024820152706164646974696f6e206f766572666c6f7760781b604482015290519081900360640190fd5b506142eb565b60f881101561427e5760be19810191506142eb565b600060f78203600186019550806020036101000a8651049150600181018201935050808310156142e9576040805162461bcd60e51b81526020600482015260116024820152706164646974696f6e206f766572666c6f7760781b604482015290519081900360640190fd5b505b5092915050565b805160009061430357506000610e53565b60008090506000614317846020015161415c565b602085015185519181019250015b8082101561434557614336826141bf565b60019093019290910190614325565b50909392505050565b6040518060c001604052806000801916815260200160006001600160a01b03168152602001606081526020016060815260200160608152602001600067ffffffffffffffff1681525090565b6040805160c081018252600080825260208201819052918101829052606081018290526080810182905260a081019190915290565b60408051608081018252600080825260208201819052918101829052606081019190915290565b604051806080016040528060006001600160a01b031681526020016060815260200160608152602001600063ffffffff1681525090565b604051806040016040528061444061444d565b8152602001600081525090565b60405180604001604052806000815260200160008152509056fe746865206d6573736167652073656e646572206d75737420626520696e63656e746976697a6520636f6e7472616374466f72206d696e69546f6b656e2c20746865207472616e7366657220616d6f756e74206d757374206e6f74206265206c657373207468616e2031756e7265636f676e697a6564207472616e736665724f75742073796e207061636b61676565787069726554696d65206d7573742062652074776f206d696e75746573206c61746572616d6f756e7420697320746f6f206c617267652c20657863656564206d6178696d756d206265703220746f6b656e20616d6f756e7474686520636f6e747261637420686173206e6f74206265656e20626f756e6420746f20616e79206265703220746f6b656e726563656976656420424e4220616d6f756e742073686f756c64206265206e6f206c657373207468616e207468652073756d206f66207472616e736665724f757420424e4220616d6f756e7420616e64206d696e696d756d2072656c6179466565616d6f756e7420697320746f6f206c617267652c2075696e74323536206f766572666c6f774c656e677468206f6620726563697069656e74416464727320646f65736e277420657175616c20746f206c656e677468206f6620726566756e644164647273696e76616c6964207472616e7366657220616d6f756e743a20707265636973696f6e206c6f737320696e20616d6f756e7420636f6e76657273696f6e536166654d6174683a206d756c7469706c69636174696f6e206f766572666c6f77726563656976656420424e4220616d6f756e742073686f756c64206265206e6f206c657373207468616e20746865206d696e696d756d2072656c6179466565746865206d6573736167652073656e646572206d75737420626520676f7665726e616e636520636f6e7472616374756e7265636f676e697a6564207472616e736665724f75742061636b207061636b6167654c656e677468206f6620726563697069656e74416464727320646f65736e277420657175616c20746f206c656e677468206f6620616d6f756e7473746865206d6573736167652073656e646572206d7573742062652063726f737320636861696e20636f6e7472616374746865206d73672073656e646572206d75737420626520746f6b656e4d616e6167657274686520636f6e7472616374206e6f7420696e69742079657400000000000000726563656976656420424e4220616d6f756e742073686f756c64206265206e6f206c657373207468616e207468652073756d206f66207472616e7366657220424e4220616d6f756e7420616e642072656c6179466565696e76616c696420726563656976656420424e4220616d6f756e743a20707265636973696f6e206c6f737320696e20616d6f756e7420636f6e76657273696f6ea26469706673582212200ed3b493edce71fd9235e1f674e51718f846ead6af3ed00debad31d4e3d4dc5f64736f6c63430006040033" + }, + "0x0000000000000000000000000000000000001005": { + "balance": "0x0", + "code": "0x6080604052600436106102765760003560e01c80637e146cc51161014f578063af400681116100c1578063e75d72c71161007a578063e75d72c714610795578063e89a3020146107c8578063f9a2bbc7146107f2578063fc3e590814610807578063fd6a68791461081c578063fdd31fcd146108315761027d565b8063af400681146106ed578063bd4cc83014610717578063c81b166214610741578063dc927faf14610756578063dcae76ab1461076b578063e1c7392a146107805761027d565b8063a3c3c0ad11610113578063a3c3c0ad146105b3578063a78abc16146105c8578063a7c6a59d146105dd578063ab51bb96146105f2578063ac43175114610607578063ace9fcc2146106d85761027d565b80637e146cc51461052c578063930e1b091461054157806396713da9146105745780639dc0926214610589578063a1a11bf51461059e5761027d565b806343756e5c116101e85780636e47b482116101ac5780636e47b482146104645780636f93d2e61461047957806370fd5bad146104d857806374f2272d146104ed57806375d47a0a146105025780637942fd05146105175761027d565b806343756e5c146103e4578063493279b1146103f95780634bf6c8821461042557806351e806721461043a578063541333071461044f5761027d565b806312950c461161023a57806312950c46146103165780631b20087c1461032b5780631c643312146103405780633a975612146102825780633dffc3871461038657806340bb43c0146103b15761027d565b8063081e9d131461028257806308f2ec06146102a9578063093f2fc4146102be5780630bee7a67146102d357806310e06a76146103015761027d565b3661027d57005b600080fd5b34801561028e57600080fd5b50610297610864565b60408051918252519081900360200190f35b3480156102b557600080fd5b50610297610869565b3480156102ca57600080fd5b5061029761086e565b3480156102df57600080fd5b506102e8610873565b6040805163ffffffff9092168252519081900360200190f35b34801561030d57600080fd5b50610297610878565b34801561032257600080fd5b5061029761087e565b34801561033757600080fd5b50610297610884565b34801561034c57600080fd5b5061036a6004803603602081101561036357600080fd5b503561088a565b604080516001600160a01b039092168252519081900360200190f35b34801561039257600080fd5b5061039b610864565b6040805160ff9092168252519081900360200190f35b3480156103bd57600080fd5b50610297600480360360208110156103d457600080fd5b50356001600160a01b03166108b1565b3480156103f057600080fd5b5061036a6108c3565b34801561040557600080fd5b5061040e6108c9565b6040805161ffff9092168252519081900360200190f35b34801561043157600080fd5b5061039b6108ce565b34801561044657600080fd5b5061036a6108d3565b34801561045b57600080fd5b50610297610873565b34801561047057600080fd5b5061036a6108d9565b34801561048557600080fd5b506104c46004803603608081101561049c57600080fd5b506001600160a01b0381358116916020810135909116906040810135906060013515156108df565b604080519115158252519081900360200190f35b3480156104e457600080fd5b5061039b610cad565b3480156104f957600080fd5b50610297610cb2565b34801561050e57600080fd5b5061036a610cb8565b34801561052357600080fd5b5061039b610cbe565b34801561053857600080fd5b50610297610cc3565b34801561054d57600080fd5b506102976004803603602081101561056457600080fd5b50356001600160a01b0316610cc8565b34801561058057600080fd5b5061039b610cda565b34801561059557600080fd5b5061036a610cdf565b3480156105aa57600080fd5b5061036a610ce5565b3480156105bf57600080fd5b50610297610ceb565b3480156105d457600080fd5b506104c4610cf1565b3480156105e957600080fd5b50610297610cfa565b3480156105fe57600080fd5b506102e8610d00565b34801561061357600080fd5b506106d66004803603604081101561062a57600080fd5b81019060208101813564010000000081111561064557600080fd5b82018360208201111561065757600080fd5b8035906020019184600183028401116401000000008311171561067957600080fd5b91939092909160208101903564010000000081111561069757600080fd5b8201836020820111156106a957600080fd5b803590602001918460018302840111640100000000831117156106cb57600080fd5b509092509050610d05565b005b3480156106e457600080fd5b50610297611354565b3480156106f957600080fd5b506102976004803603602081101561071057600080fd5b503561135a565b34801561072357600080fd5b506102976004803603602081101561073a57600080fd5b50356113b5565b34801561074d57600080fd5b5061036a6113ce565b34801561076257600080fd5b5061036a6113d4565b34801561077757600080fd5b506102976113da565b34801561078c57600080fd5b506106d66113e0565b3480156107a157600080fd5b506106d6600480360360208110156107b857600080fd5b50356001600160a01b03166114a9565b3480156107d457600080fd5b5061036a600480360360208110156107eb57600080fd5b5035611602565b3480156107fe57600080fd5b5061036a61160f565b34801561081357600080fd5b5061039b611615565b34801561082857600080fd5b5061036a61161a565b34801561083d57600080fd5b506102976004803603602081101561085457600080fd5b50356001600160a01b0316611620565b600181565b602881565b605081565b606481565b600b5481565b60015481565b600c5481565b6006818154811061089757fe5b6000918252602090912001546001600160a01b0316905081565b60076020526000908152604090205481565b61100181565b603881565b600881565b61200081565b61100581565b6000805460ff16610937576040805162461bcd60e51b815260206004820152601960248201527f74686520636f6e7472616374206e6f7420696e69742079657400000000000000604482015290519081900360640190fd5b33612000146109775760405162461bcd60e51b815260040180806020018281038252602f815260200180612164602f913960400191505060405180910390fd5b600082156109fc57604080516309a99b4f60e41b8152611005600482015260248101869052905161100291639a99b4f09160448083019260209291908290030181600087803b1580156109c957600080fd5b505af11580156109dd573d6000803e3d6000fd5b505050506040513d60208110156109f357600080fd5b50519050610a75565b604080516309a99b4f60e41b8152611005600482015260248101869052905161100491639a99b4f09160448083019260209291908290030181600087803b158015610a4657600080fd5b505af1158015610a5a573d6000803e3d6000fd5b505050506040513d6020811015610a7057600080fd5b505190505b600c805460010190556000610a8982611632565b600954909150610a9f908263ffffffff61166116565b600955600a54610ac7908290610abb908563ffffffff61166116565b9063ffffffff6116c216565b600a556001600160a01b038716600090815260056020526040902054610b3357600680546001810182556000919091527ff652222313e28459528d920b65115c16c04f3efc82aaedc97be59f3f377c0d3f0180546001600160a01b0319166001600160a01b0389161790555b6001600160a01b038088166000908152600560209081526040808320805460010190559289168252600790522054610bb157600880546001810182556000919091527ff3f7a9fe364faab93b216da50a3214154f22a0a2b415b23a84c8169e8b636ee30180546001600160a01b0319166001600160a01b0388161790555b6001600160a01b038616600090815260076020526040902080546001019055600c54606411610ca057600b54600954600a5460408051938452602084019290925282820152517f2649b1b772a1a74bd332a67695e285317dd722941166595741c60a00fa65bb759181900360600190a16000610c2b611704565b90506000610c376119e8565b6001600160a01b0389166000908152600d6020526040902054909150610c75908290610c69908563ffffffff61166116565b9063ffffffff61166116565b6001600160a01b0389166000908152600d6020526040812091909155600b80546001019055600c5550505b5060019695505050505050565b600281565b60035481565b61100881565b600b81565b600581565b60056020526000908152604090205481565b600981565b61100781565b61100681565b600a5481565b60005460ff1681565b60045481565b600081565b3361100714610d455760405162461bcd60e51b815260040180806020018281038252602e8152602001806120a9602e913960400191505060405180910390fd5b60005460ff16610d865760405162461bcd60e51b81526004018080602001828103825260218152602001806120d76021913960400191505060405180910390fd5b610dfa84848080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152505060408051808201909152601f81527f68656164657252656c61796572526577617264526174654d6f6c6563756c650060208201529150611c669050565b15610ec75760208114610e3e5760405162461bcd60e51b81526004018080602001828103825260328152602001806121936032913960400191505060405180910390fd5b604080516020601f8401819004810282018101909252828152600091610e7c91858580838501838280828437600092019190915250611d4d92505050565b9050600254811115610ebf5760405162461bcd60e51b8152600401808060200182810382526060815260200180611f826060913960600191505060405180910390fd5b6001556112c2565b610f2084848080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250506040805160608101909152602280825290925090506120876020830139611c66565b15610ff85760208114610f645760405162461bcd60e51b815260040180806020018281038252602e815260200180612038602e913960400191505060405180910390fd5b604080516020601f8401819004810282018101909252828152600091610fa291858580838501838280828437600092019190915250611d4d92505050565b90508015801590610fb557506001548110155b610ff05760405162461bcd60e51b815260040180806020018281038252606c8152602001806120f8606c913960800191505060405180910390fd5b6002556112c2565b61106c84848080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152505060408051808201909152601a81527f63616c6c6572436f6d70656e736174696f6e4d6f6c6563756c6500000000000060208201529150611c669050565b1561113957602081146110b05760405162461bcd60e51b815260040180806020018281038252602e815260200180612038602e913960400191505060405180910390fd5b604080516020601f84018190048102820181019092528281526000916110ee91858580838501838280828437600092019190915250611d4d92505050565b90506004548111156111315760405162461bcd60e51b8152600401808060200182810382526056815260200180611fe26056913960600191505060405180910390fd5b6003556112c2565b6111ad84848080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152505060408051808201909152601d81527f63616c6c6572436f6d70656e736174696f6e44656e6f6d696e61746f7200000060208201529150611c669050565b1561128557602081146111f15760405162461bcd60e51b815260040180806020018281038252602e815260200180612038602e913960400191505060405180910390fd5b604080516020601f840181900481028201810190925282815260009161122f91858580838501838280828437600092019190915250611d4d92505050565b9050801580159061124257506003548110155b61127d5760405162461bcd60e51b8152600401808060200182810382526061815260200180611f216061913960800191505060405180910390fd5b6004556112c2565b6040805162461bcd60e51b815260206004820152600d60248201526c756e6b6e6f776e20706172616d60981b604482015290519081900360640190fd5b7f6cdb0ac70ab7f2e2d035cca5be60d89906f2dede7648ddbd7402189c1eeed17a848484846040518080602001806020018381038352878782818152602001925080828437600083820152601f01601f191690910184810383528581526020019050858580828437600083820152604051601f909101601f19169092018290039850909650505050505050a150505050565b60025481565b60006028821161136b5750806113b0565b81602810801561137c575060508211155b15611389575060286113b0565b60508211801561139a5750606e8211155b156113aa575060788190036113b0565b50600481045b919050565b6000602882116113c65750806113b0565b5060286113b0565b61100281565b61100381565b60095481565b60005460ff1615611438576040805162461bcd60e51b815260206004820152601960248201527f74686520636f6e747261637420616c726561647920696e697400000000000000604482015290519081900360640190fd5b60005460ff1615611486576040805162461bcd60e51b8152602060048201526013602482015272185b1c9958591e481a5b9a5d1a585b1a5e9959606a1b604482015290519081900360640190fd5b60018080556005600255600381905560506004556000805460ff19169091179055565b6001600160a01b0381166000908152600d602052604090205480611508576040805162461bcd60e51b81526020600482015260116024820152701b9bc81c995b185e595c881c995dd85c99607a1b604482015290519081900360640190fd5b6001600160a01b0382166000818152600d60205260408082208290555184929184156108fc02918591818181858888f193505050506115b85760405161100290819084156108fc029085906000818181858888f19350505050158015611572573d6000803e3d6000fd5b506040805161100281526020810185905281517f24502838a334c8f2bb2ee1f8262a4fa7183e4489a717e96cc824e325f8b39e11929181900390910190a15050506115ff565b604080516001600160a01b03851681526020810184905281517f24502838a334c8f2bb2ee1f8262a4fa7183e4489a717e96cc824e325f8b39e11929181900390910190a150505b50565b6008818154811061089757fe5b61100081565b600381565b61100481565b600d6020526000908152604090205481565b600061165b60025461164f60015485611d5290919063ffffffff16565b9063ffffffff611dab16565b92915050565b6000828201838110156116bb576040805162461bcd60e51b815260206004820152601b60248201527f536166654d6174683a206164646974696f6e206f766572666c6f770000000000604482015290519081900360640190fd5b9392505050565b60006116bb83836040518060400160405280601e81526020017f536166654d6174683a207375627472616374696f6e206f766572666c6f770000815250611ded565b600954600680546040805160208084028201810190925282815260009493859360609383018282801561176057602002820191906000526020600020905b81546001600160a01b03168152600190910190602001808311611742575b5050505050905060608151604051908082528060200260200182016040528015611794578160200160208202803683370190505b50905060005b82518110156118215760008382815181106117b157fe5b6020026020010151905060006117eb60056000846001600160a01b03166001600160a01b03168152602001908152602001600020546113b5565b9050808484815181106117fa57fe5b6020908102919091010152611815868263ffffffff61166116565b9550505060010161179a565b50600061183f60045461164f60035488611d5290919063ffffffff16565b9050611851858263ffffffff6116c216565b94508460015b845181101561192857600061188c8761164f8a88868151811061187657fe5b6020026020010151611d5290919063ffffffff16565b90506118d981600d60008986815181106118a257fe5b60200260200101516001600160a01b03166001600160a01b031681526020019081526020016000205461166190919063ffffffff16565b600d60008885815181106118e957fe5b6020908102919091018101516001600160a01b031682528101919091526040016000205561191d838263ffffffff6116c216565b925050600101611857565b5061193e81600d6000876000815181106118a257fe5b600d60008660008151811061194f57fe5b60200260200101516001600160a01b03166001600160a01b0316815260200190815260200160002081905550600060098190555060008090505b84518110156119d057600560008683815181106119a257fe5b6020908102919091018101516001600160a01b03168252810191909152604001600090812055600101611989565b506119dd60066000611ee9565b509450505050505b90565b600a546008805460408051602080840282018101909252828152600094938593606093830182828015611a4457602002820191906000526020600020905b81546001600160a01b03168152600190910190602001808311611a26575b5050505050905060608151604051908082528060200260200182016040528015611a78578160200160208202803683370190505b50905060005b8251811015611af7576000838281518110611a9557fe5b602002602001015190506000611acf60076000846001600160a01b03166001600160a01b031681526020019081526020016000205461135a565b905080848481518110611ade57fe5b6020908102919091010152949094019350600101611a7e565b506000611b1560045461164f60035488611d5290919063ffffffff16565b9050611b27858263ffffffff6116c216565b94508460015b8451811015611bb1576000611b4c8761164f8a88868151811061187657fe5b9050611b6281600d60008986815181106118a257fe5b600d6000888581518110611b7257fe5b6020908102919091018101516001600160a01b0316825281019190915260400160002055611ba6838263ffffffff6116c216565b925050600101611b2d565b50611bc781600d6000876000815181106118a257fe5b600d600086600081518110611bd857fe5b60200260200101516001600160a01b03166001600160a01b03168152602001908152602001600020819055506000600a8190555060008090505b8451811015611c595760076000868381518110611c2b57fe5b6020908102919091018101516001600160a01b03168252810191909152604001600090812055600101611c12565b506119dd60086000611ee9565b6000816040516020018082805190602001908083835b60208310611c9b5780518252601f199092019160209182019101611c7c565b6001836020036101000a03801982511681845116808217855250505050505090500191505060405160208183030381529060405280519060200120836040516020018082805190602001908083835b60208310611d095780518252601f199092019160209182019101611cea565b6001836020036101000a0380198251168184511680821785525050505050509050019150506040516020818303038152906040528051906020012014905092915050565b015190565b600082611d615750600061165b565b82820282848281611d6e57fe5b04146116bb5760405162461bcd60e51b81526004018080602001828103825260218152602001806120666021913960400191505060405180910390fd5b60006116bb83836040518060400160405280601a81526020017f536166654d6174683a206469766973696f6e206279207a65726f000000000000815250611e84565b60008184841115611e7c5760405162461bcd60e51b81526004018080602001828103825283818151815260200191508051906020019080838360005b83811015611e41578181015183820152602001611e29565b50505050905090810190601f168015611e6e5780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b505050900390565b60008183611ed35760405162461bcd60e51b8152602060048201818152835160248401528351909283926044909101919085019080838360008315611e41578181015183820152602001611e29565b506000838581611edf57fe5b0495945050505050565b50805460008255906000526020600020908101906115ff91906119e591905b80821115611f1c5760008155600101611f08565b509056fe746865206e657743616c6c6572436f6d70656e736174696f6e44656e6f6d696e61746f72206d757374206e6f74206265207a65726f20616e64206e6f206c657373207468616e2063616c6c6572436f6d70656e736174696f6e4d6f6c6563756c656e65772068656164657252656c61796572526577617264526174654d6f6c6563756c652073686f756c646e27742062652067726561746572207468616e2068656164657252656c617965725265776172645261746544656e6f6d696e61746f726e65772063616c6c6572436f6d70656e736174696f6e4d6f6c6563756c652073686f756c646e27742062652067726561746572207468616e2063616c6c6572436f6d70656e736174696f6e44656e6f6d696e61746f726c656e677468206f6620726577617264466f7256616c696461746f725365744368616e6765206d69736d61746368536166654d6174683a206d756c7469706c69636174696f6e206f766572666c6f7768656164657252656c617965725265776172645261746544656e6f6d696e61746f72746865206d6573736167652073656e646572206d75737420626520676f7665726e616e636520636f6e7472616374636f6e747261637420686173206e6f74206265656e20696e697469616c697a6564746865206e65772068656164657252656c617965725265776172645261746544656e6f6d696e61746f72206d757374206e6f74206265207a65726f20616e64206e6f206c657373207468616e2068656164657252656c61796572526577617264526174654d6f6c6563756c65746865206d6573736167652073656e646572206d7573742062652063726f737320636861696e20636f6e74726163746c656e677468206f662068656164657252656c61796572526577617264526174654d6f6c6563756c65206d69736d61746368a2646970667358221220cd7c1ec8296551de0c54d97959872d6570445d6b1250fde9150f66f3ae10dc7164736f6c63430006040033" + }, + "0x0000000000000000000000000000000000001006": { + "balance": "0x0", + "code": "0x6080604052600436106101c25760003560e01c806395468d26116100f7578063c81b166211610095578063f9a2bbc711610064578063f9a2bbc714610529578063fb7cfdd71461053e578063fc3e590814610553578063fd6a687914610568576101c2565b8063c81b1662146104d5578063dc927faf146104ea578063e1c7392a146104ff578063e79a198f14610514576101c2565b8063a1a11bf5116100d1578063a1a11bf5146103c7578063a78abc16146103dc578063ab51bb96146103f1578063ac43175114610406576101c2565b806395468d261461038857806396713da91461039d5780639dc09262146103b2576101c2565b8063541d55481161016457806370fd5bad1161013e57806370fd5bad1461033457806375d47a0a146103495780637942fd051461035e5780637ae2308814610373576101c2565b8063541d5548146102b15780636a87d780146102f85780636e47b4821461031f576101c2565b806343756e5c116101a057806343756e5c1461022a578063493279b11461025b5780634bf6c8821461028757806351e806721461029c576101c2565b80630bee7a67146101c75780631aa3a008146101f55780633dffc387146101ff575b600080fd5b3480156101d357600080fd5b506101dc61057d565b6040805163ffffffff9092168252519081900360200190f35b6101fd610582565b005b34801561020b57600080fd5b5061021461077d565b6040805160ff9092168252519081900360200190f35b34801561023657600080fd5b5061023f610782565b604080516001600160a01b039092168252519081900360200190f35b34801561026757600080fd5b50610270610788565b6040805161ffff9092168252519081900360200190f35b34801561029357600080fd5b5061021461078d565b3480156102a857600080fd5b5061023f610792565b3480156102bd57600080fd5b506102e4600480360360208110156102d457600080fd5b50356001600160a01b0316610798565b604080519115158252519081900360200190f35b34801561030457600080fd5b5061030d6107b6565b60408051918252519081900360200190f35b34801561032b57600080fd5b5061023f6107bc565b34801561034057600080fd5b506102146107c2565b34801561035557600080fd5b5061023f6107c7565b34801561036a57600080fd5b506102146107cd565b34801561037f57600080fd5b5061030d6107d2565b34801561039457600080fd5b5061030d6107df565b3480156103a957600080fd5b506102146107eb565b3480156103be57600080fd5b5061023f6107f0565b3480156103d357600080fd5b5061023f6107f6565b3480156103e857600080fd5b506102e46107fc565b3480156103fd57600080fd5b506101dc610805565b34801561041257600080fd5b506101fd6004803603604081101561042957600080fd5b81019060208101813564010000000081111561044457600080fd5b82018360208201111561045657600080fd5b8035906020019184600183028401116401000000008311171561047857600080fd5b91939092909160208101903564010000000081111561049657600080fd5b8201836020820111156104a857600080fd5b803590602001918460018302840111640100000000831117156104ca57600080fd5b50909250905061080a565b3480156104e157600080fd5b5061023f610c2c565b3480156104f657600080fd5b5061023f610c32565b34801561050b57600080fd5b506101fd610c38565b34801561052057600080fd5b506101fd610cba565b34801561053557600080fd5b5061023f610e73565b34801561054a57600080fd5b5061030d610e79565b34801561055f57600080fd5b50610214610e7f565b34801561057457600080fd5b5061023f610e84565b606481565b3360009081526004602052604090205460ff16156105df576040805162461bcd60e51b81526020600482015260156024820152741c995b185e595c88185b1c9958591e48195e1a5cdd605a1b604482015290519081900360640190fd5b60005460ff16610632576040805162461bcd60e51b81526020600482015260196024820152781d1a194818dbdb9d1c9858dd081b9bdd081a5b9a5d081e595d603a1b604482015290519081900360640190fd5b61063b33610e8a565b156106775760405162461bcd60e51b815260040180806020018281038252602781526020018061109c6027913960400191505060405180910390fd5b3332146106c1576040805162461bcd60e51b81526020600482015260136024820152721b9bc81c1c9bde1e481a5cc8185b1b1bddd959606a1b604482015290519081900360640190fd5b60015434146107015760405162461bcd60e51b81526004018080602001828103825260258152602001806110776025913960400191505060405180910390fd5b604080518082018252600180548252600254602080840191825233600081815260038352868120955186559251948401949094556004815290849020805460ff1916909217909155825191825291517fdb33a09d38b59a8fa8b7d92a1d82c8015e99f05f67ae9c9ae623157767959496929181900390910190a1565b600181565b61100181565b603881565b600881565b61200081565b6001600160a01b031660009081526004602052604090205460ff1690565b60025481565b61100581565b600281565b61100881565b600b81565b68056bc75e2d6310000081565b67016345785d8a000081565b600981565b61100781565b61100681565b60005460ff1681565b600081565b60005460ff1661085d576040805162461bcd60e51b81526020600482015260196024820152781d1a194818dbdb9d1c9858dd081b9bdd081a5b9a5d081e595d603a1b604482015290519081900360640190fd5b336110071461089d5760405162461bcd60e51b815260040180806020018281038252602e8152602001806110c3602e913960400191505060405180910390fd5b61090384848080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152505060408051808201909152600f81526e1c995c5d5a5c995911195c1bdcda5d608a1b60208201529150610e909050565b15610a0657602081146109475760405162461bcd60e51b81526004018080602001828103825260228152602001806110f16022913960400191505060405180910390fd5b604080516020601f840181900481028201810190925282815260009161098591858580838501838280828437600092019190915250610f7792505050565b90506001811180156109a05750683635c9adc5dea000008111155b80156109ad575060025481115b6109fe576040805162461bcd60e51b815260206004820181905260248201527f7468652072657175697265644465706f736974206f7574206f662072616e6765604482015290519081900360640190fd5b600155610b9a565b610a6184848080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250506040805180820190915260048152636475657360e01b60208201529150610e909050565b15610b5d5760208114610abb576040805162461bcd60e51b815260206004820152601760248201527f6c656e677468206f662064756573206d69736d61746368000000000000000000604482015290519081900360640190fd5b604080516020601f8401819004810282018101909252828152600091610af991858580838501838280828437600092019190915250610f7792505050565b9050600081118015610b0c575060015481105b610b55576040805162461bcd60e51b81526020600482015260156024820152747468652064756573206f7574206f662072616e676560581b604482015290519081900360640190fd5b600255610b9a565b6040805162461bcd60e51b815260206004820152600d60248201526c756e6b6e6f776e20706172616d60981b604482015290519081900360640190fd5b7f6cdb0ac70ab7f2e2d035cca5be60d89906f2dede7648ddbd7402189c1eeed17a848484846040518080602001806020018381038352878782818152602001925080828437600083820152601f01601f191690910184810383528581526020019050858580828437600083820152604051601f909101601f19169092018290039850909650505050505050a150505050565b61100281565b61100381565b60005460ff1615610c90576040805162461bcd60e51b815260206004820152601960248201527f74686520636f6e747261637420616c726561647920696e697400000000000000604482015290519081900360640190fd5b68056bc75e2d63100000600190815567016345785d8a00006002556000805460ff19169091179055565b3360009081526004602052604090205460ff16610d15576040805162461bcd60e51b81526020600482015260146024820152731c995b185e595c88191bc81b9bdd08195e1a5cdd60621b604482015290519081900360640190fd5b60005460ff16610d68576040805162461bcd60e51b81526020600482015260196024820152781d1a194818dbdb9d1c9858dd081b9bdd081a5b9a5d081e595d603a1b604482015290519081900360640190fd5b610d7061105c565b5033600081815260036020908152604091829020825180840190935280548084526001909101549183018290529192916108fc91610db4919063ffffffff610f7c16565b6040518115909202916000818181858888f19350505050158015610ddc573d6000803e3d6000fd5b50602081015160405161100291829181156108fc0291906000818181858888f19350505050158015610e12573d6000803e3d6000fd5b50336000818152600460209081526040808320805460ff191690556003825280832083815560010192909255815192835290517fd17202129b83db7880d6b9f25df81c58ad46f7e0e2c92236b1aa10663a4876679281900390910190a15050565b61100081565b60015481565b600381565b61100481565b3b151590565b6000816040516020018082805190602001908083835b60208310610ec55780518252601f199092019160209182019101610ea6565b6001836020036101000a03801982511681845116808217855250505050505090500191505060405160208183030381529060405280519060200120836040516020018082805190602001908083835b60208310610f335780518252601f199092019160209182019101610f14565b6001836020036101000a0380198251168184511680821785525050505050509050019150506040516020818303038152906040528051906020012014905092915050565b015190565b6000610fbe83836040518060400160405280601e81526020017f536166654d6174683a207375627472616374696f6e206f766572666c6f770000815250610fc5565b9392505050565b600081848411156110545760405162461bcd60e51b81526004018080602001828103825283818151815260200191508051906020019080838360005b83811015611019578181015183820152602001611001565b50505050905090810190601f1680156110465780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b505050900390565b60405180604001604052806000815260200160008152509056fe6465706f7369742076616c7565206973206e6f742065786163746c79207468652073616d65636f6e7472616374206973206e6f7420616c6c6f77656420746f20626520612072656c61796572746865206d6573736167652073656e646572206d75737420626520676f7665726e616e636520636f6e74726163746c656e677468206f662072657175697265644465706f736974206d69736d61746368a2646970667358221220449507f2557413401b33bd1aa888e40f31523a5d010a891cf7383c0090d7f49a64736f6c63430006040033" + }, + "0x0000000000000000000000000000000000001007": { + "balance": "0x0", + "code": "0x608060405234801561001057600080fd5b506004361061018e5760003560e01c8063831d65d1116100de578063ab51bb9611610097578063dc927faf11610071578063dc927faf14610486578063f9a2bbc71461048e578063fc3e590814610496578063fd6a68791461049e5761018e565b8063ab51bb96146103fc578063c81b166214610404578063c8509d811461040c5761018e565b8063831d65d11461034457806396713da9146103c05780639ab1a373146103c85780639dc09262146103d0578063a1a11bf5146103d8578063a78abc16146103e05761018e565b8063493279b11161014b5780636e47b482116101255780636e47b4821461032457806370fd5bad1461032c57806375d47a0a146103345780637942fd051461033c5761018e565b8063493279b1146102f55780634bf6c8821461031457806351e806721461031c5761018e565b80630bee7a67146101935780631182b875146101b45780633a21baae146102a35780633dffc387146102ab57806343756e5c146102c95780634900c4ea146102ed575b600080fd5b61019b6104a6565b6040805163ffffffff9092168252519081900360200190f35b61022e600480360360408110156101ca57600080fd5b60ff82351691908101906040810160208201356401000000008111156101ef57600080fd5b82018360208201111561020157600080fd5b8035906020019184600183028401116401000000008311171561022357600080fd5b5090925090506104ab565b6040805160208082528351818301528351919283929083019185019080838360005b83811015610268578181015183820152602001610250565b50505050905090810190601f1680156102955780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b61019b61059a565b6102b361059f565b6040805160ff9092168252519081900360200190f35b6102d16105a4565b604080516001600160a01b039092168252519081900360200190f35b6102b36105aa565b6102fd6105af565b6040805161ffff9092168252519081900360200190f35b6102b36105b4565b6102d16105b9565b6102d16105bf565b6102b36105c5565b6102d16105ca565b6102b36105d0565b6103be6004803603604081101561035a57600080fd5b60ff823516919081019060408101602082013564010000000081111561037f57600080fd5b82018360208201111561039157600080fd5b803590602001918460018302840111640100000000831117156103b357600080fd5b5090925090506105d5565b005b6102b3610667565b61019b61066c565b6102d1610671565b6102d1610677565b6103e861067d565b604080519115158252519081900360200190f35b61019b6105aa565b6102d1610686565b6103be6004803603604081101561042257600080fd5b60ff823516919081019060408101602082013564010000000081111561044757600080fd5b82018360208201111561045957600080fd5b8035906020019184600183028401116401000000008311171561047b57600080fd5b50909250905061068c565b6102d1610703565b6102d1610709565b6102b361070f565b6102d1610714565b606481565b606033612000146104ed5760405162461bcd60e51b815260040180806020018281038252602f8152602001806113e7602f913960400191505060405180910390fd5b6104f5611382565b600061053685858080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061071a92505050565b91509150806105525761054960646107e0565b92505050610593565b600061055d8361084a565b905063ffffffff811661058457505060408051600081526020810190915291506105939050565b61058d816107e0565b93505050505b9392505050565b606681565b600181565b61100181565b600081565b603881565b600881565b61200081565b61100581565b600281565b61100881565b600b81565b33612000146106155760405162461bcd60e51b815260040180806020018281038252602f8152602001806113e7602f913960400191505060405180910390fd5b6040805162461bcd60e51b815260206004820152601e60248201527f7265636569766520756e65787065637465642061636b207061636b6167650000604482015290519081900360640190fd5b505050565b600981565b606581565b61100781565b61100681565b60005460ff1681565b61100281565b33612000146106cc5760405162461bcd60e51b815260040180806020018281038252602f8152602001806113e7602f913960400191505060405180910390fd5b60405162461bcd60e51b81526004018080602001828103825260238152602001806114166023913960400191505060405180910390fd5b61100381565b61100081565b600381565b61100481565b610722611382565b600061072c611382565b6107346113ac565b61074561074086610beb565b610c10565b90506000805b61075483610c5a565b156107d357806107765761076f61076a84610c7b565b610cc9565b84526107cb565b80600114156107955761078b61076a84610c7b565b60208501526107cb565b80600214156107c6576107af6107aa84610c7b565b610d42565b6001600160a01b03166040850152600191506107cb565b6107d3565b60010161074b565b5091935090915050915091565b604080516001808252818301909252606091829190816020015b60608152602001906001900390816107fa5790505090506108208363ffffffff16610d62565b8160008151811061082d57fe5b602002602001018190525061084181610d75565b9150505b919050565b60006108598260400151610dff565b6108c557604080516020808252601c908201527f74686520746172676574206973206e6f74206120636f6e7472616374000000008183015290517f70e72399380dcfb0338abc03dc8d47f9f470ada8e769c9a78d644ea97385ecb29181900360600190a1506065610845565b81604001516001600160a01b031663ac431751836000015184602001516040518363ffffffff1660e01b8152600401808060200180602001838103835285818151815260200191508051906020019080838360005b8381101561093257818101518382015260200161091a565b50505050905090810190601f16801561095f5780820380516001836020036101000a031916815260200191505b50838103825284518152845160209182019186019080838360005b8381101561099257818101518382015260200161097a565b50505050905090810190601f1680156109bf5780820380516001836020036101000a031916815260200191505b50945050505050600060405180830381600087803b1580156109e057600080fd5b505af19250505080156109f1575060015b610be3576040516000815260443d1015610a0d57506000610aaa565b60046000803e60005160e01c6308c379a08114610a2e576000915050610aaa565b60043d036004833e81513d602482011167ffffffffffffffff82111715610a5a57600092505050610aaa565b808301805167ffffffffffffffff811115610a7c576000945050505050610aaa565b8060208301013d8601811115610a9a57600095505050505050610aaa565b601f01601f191660405250925050505b80610ab55750610b58565b7f70e72399380dcfb0338abc03dc8d47f9f470ada8e769c9a78d644ea97385ecb2816040518080602001828103825283818151815260200191508051906020019080838360005b83811015610b14578181015183820152602001610afc565b50505050905090810190601f168015610b415780820380516001836020036101000a031916815260200191505b509250505060405180910390a16066915050610845565b3d808015610b82576040519150601f19603f3d011682016040523d82523d6000602084013e610b87565b606091505b5060408051602080825283518183015283517f1279f84165b4fd69c35e1f338ff107231b036c655cd1688851e011ce617c4e8d938593928392918301919085019080838360008315610b14578181015183820152602001610afc565b506000919050565b610bf36113cc565b506040805180820190915281518152602082810190820152919050565b610c186113ac565b610c2182610e05565b610c2a57600080fd5b6000610c398360200151610e3f565b60208085015160408051808201909152868152920190820152915050919050565b6000610c646113cc565b505080518051602091820151919092015191011190565b610c836113cc565b610c8c82610c5a565b610c9557600080fd5b60208201516000610ca582610ea2565b80830160209586015260408051808201909152908152938401919091525090919050565b8051606090610cd757600080fd5b6000610ce68360200151610e3f565b83516040805191839003808352601f19601f8201168301602001909152919250606090828015610d1d576020820181803683370190505b5090506000816020019050610d39848760200151018285610fd5565b50949350505050565b8051600090601514610d5357600080fd5b610d5c82611020565b92915050565b6060610d5c610d70836110d5565b6111bb565b6060815160001415610d965750604080516000815260208101909152610845565b606082600081518110610da557fe5b602002602001015190506000600190505b8351811015610de657610ddc82858381518110610dcf57fe5b602002602001015161120d565b9150600101610db6565b50610841610df9825160c060ff1661128a565b8261120d565b3b151590565b8051600090610e1657506000610845565b6020820151805160001a9060c0821015610e3557600092505050610845565b5060019392505050565b8051600090811a6080811015610e59576000915050610845565b60b8811080610e74575060c08110801590610e74575060f881105b15610e83576001915050610845565b60c0811015610e975760b519019050610845565b60f519019050610845565b80516000908190811a6080811015610ebd5760019150610fce565b60b8811015610ed257607e1981019150610fce565b60c0811015610f4c57600060b78203600186019550806020036101000a865104915060018101820193505080831015610f46576040805162461bcd60e51b81526020600482015260116024820152706164646974696f6e206f766572666c6f7760781b604482015290519081900360640190fd5b50610fce565b60f8811015610f615760be1981019150610fce565b600060f78203600186019550806020036101000a865104915060018101820193505080831015610fcc576040805162461bcd60e51b81526020600482015260116024820152706164646974696f6e206f766572666c6f7760781b604482015290519081900360640190fd5b505b5092915050565b80610fdf57610662565b5b60208110610fff578251825260209283019290910190601f1901610fe0565b915181516020939093036101000a6000190180199091169216919091179052565b80516000901580159061103557508151602110155b61103e57600080fd5b600061104d8360200151610e3f565b905080836000015110156110a8576040805162461bcd60e51b815260206004820152601a60248201527f6c656e677468206973206c657373207468616e206f6666736574000000000000604482015290519081900360640190fd5b825160208085015183018051928490039291831015610d3957506020919091036101000a90049392505050565b604080516020808252818301909252606091829190602082018180368337505050602081018490529050600067ffffffffffffffff1984166111195750601861113d565b6fffffffffffffffffffffffffffffffff1984166111395750601061113d565b5060005b60208110156111735781818151811061115257fe5b01602001516001600160f81b0319161561116b57611173565b60010161113d565b60008160200390506060816040519080825280601f01601f1916602001820160405280156111a8576020820181803683370190505b5080830196909652508452509192915050565b6060815160011480156111ed5750607f60f81b826000815181106111db57fe5b01602001516001600160f81b03191611155b156111f9575080610845565b610d5c61120b8351608060ff1661128a565b835b6060806040519050835180825260208201818101602087015b8183101561123e578051835260209283019201611226565b50855184518101855292509050808201602086015b8183101561126b578051835260209283019201611253565b508651929092011591909101601f01601f191660405250905092915050565b60606801000000000000000083106112da576040805162461bcd60e51b815260206004820152600e60248201526d696e70757420746f6f206c6f6e6760901b604482015290519081900360640190fd5b604080516001808252818301909252606091602082018180368337019050509050603784116113345782840160f81b8160008151811061131657fe5b60200101906001600160f81b031916908160001a9053509050610d5c565b606061133f856110d5565b90508381510160370160f81b8260008151811061135857fe5b60200101906001600160f81b031916908160001a905350611379828261120d565b95945050505050565b6040518060600160405280606081526020016060815260200160006001600160a01b031681525090565b60405180604001604052806113bf6113cc565b8152602001600081525090565b60405180604001604052806000815260200160008152509056fe746865206d6573736167652073656e646572206d7573742062652063726f737320636861696e20636f6e74726163747265636569766520756e6578706563746564206661696c2061636b207061636b616765a2646970667358221220a5eefec118f5b467b996b871e3b96c20aa4fe4192a6c4b34c6afc795161d4a9a64736f6c63430006040033" + }, + "0x0000000000000000000000000000000000001008": { + "balance": "0x0", + "code": "0x6080604052600436106102465760003560e01c806375d47a0a11610139578063ab51bb96116100b6578063d9e6dae91161007a578063d9e6dae914610512578063dc927faf14610975578063f9a2bbc71461098a578063fc3e590814610566578063fd6a68791461099f578063fe3a2af5146104e857610246565b8063ab51bb96146108ca578063c81b1662146108df578063c8509d81146107da578063c8e704a414610566578063d117a110146108f457610246565b806395b9ad26116100fd57806395b9ad261461086157806396713da9146108765780639dc092621461088b578063a1a11bf5146108a0578063a78abc16146108b557610246565b806375d47a0a146106fc57806377d9dae8146107115780637942fd05146107c55780637d078e13146103b3578063831d65d1146107da57610246565b80634bc81c00116101c757806366dea52a1161018b57806366dea52a146105665780636b3f13071461057b5780636e47b4821461064357806370fd5bad1461055157806372c4e0861461065857610246565b80634bc81c00146104fd5780634bf6c8821461051257806351e80672146105275780635d499b1b1461053c5780635f558f861461055157610246565b80633dffc3871161020e5780633dffc387146103b357806343756e5c146103c8578063445fcefe146103f9578063493279b1146104bc5780634a688818146104e857610246565b80630bee7a671461024b5780630f212b1b146102795780631182b875146102a45780631f91600b1461039e57806323996b53146103b3575b600080fd5b34801561025757600080fd5b506102606109b4565b6040805163ffffffff9092168252519081900360200190f35b34801561028557600080fd5b5061028e6109b9565b6040805160ff9092168252519081900360200190f35b3480156102b057600080fd5b50610329600480360360408110156102c757600080fd5b60ff8235169190810190604081016020820135600160201b8111156102eb57600080fd5b8201836020820111156102fd57600080fd5b803590602001918460018302840111600160201b8311171561031e57600080fd5b5090925090506109be565b6040805160208082528351818301528351919283929083019185019080838360005b8381101561036357818101518382015260200161034b565b50505050905090810190601f1680156103905780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b3480156103aa57600080fd5b5061028e610a47565b3480156103bf57600080fd5b5061028e610a4c565b3480156103d457600080fd5b506103dd610a51565b604080516001600160a01b039092168252519081900360200190f35b34801561040557600080fd5b506104aa6004803603602081101561041c57600080fd5b810190602081018135600160201b81111561043657600080fd5b82018360208201111561044857600080fd5b803590602001918460018302840111600160201b8311171561046957600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250929550610a57945050505050565b60408051918252519081900360200190f35b3480156104c857600080fd5b506104d1610bb6565b6040805161ffff9092168252519081900360200190f35b3480156104f457600080fd5b5061028e610bbb565b34801561050957600080fd5b5061028e610bc0565b34801561051e57600080fd5b5061028e610bc5565b34801561053357600080fd5b506103dd610bca565b34801561054857600080fd5b506104aa610bd0565b34801561055d57600080fd5b5061028e610bd9565b34801561057257600080fd5b5061028e610bde565b61062f6004803603604081101561059157600080fd5b6001600160a01b038235169190810190604081016020820135600160201b8111156105bb57600080fd5b8201836020820111156105cd57600080fd5b803590602001918460018302840111600160201b831117156105ee57600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250929550610be3945050505050565b604080519115158252519081900360200190f35b34801561064f57600080fd5b506103dd611465565b61062f6004803603602081101561066e57600080fd5b810190602081018135600160201b81111561068857600080fd5b82018360208201111561069a57600080fd5b803590602001918460018302840111600160201b831117156106bb57600080fd5b91908080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525092955061146b945050505050565b34801561070857600080fd5b506103dd6118b9565b61062f6004803603604081101561072757600080fd5b6001600160a01b038235169190810190604081016020820135600160201b81111561075157600080fd5b82018360208201111561076357600080fd5b803590602001918460018302840111600160201b8311171561078457600080fd5b91908080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152509295506118bf945050505050565b3480156107d157600080fd5b5061028e611dc6565b3480156107e657600080fd5b5061085f600480360360408110156107fd57600080fd5b60ff8235169190810190604081016020820135600160201b81111561082157600080fd5b82018360208201111561083357600080fd5b803590602001918460018302840111600160201b8311171561085457600080fd5b509092509050611dcb565b005b34801561086d57600080fd5b5061028e611e7e565b34801561088257600080fd5b5061028e611e83565b34801561089757600080fd5b506103dd611e88565b3480156108ac57600080fd5b506103dd611e8e565b3480156108c157600080fd5b5061062f611e94565b3480156108d657600080fd5b50610260610bbb565b3480156108eb57600080fd5b506103dd611e9d565b34801561090057600080fd5b5061091e6004803603602081101561091757600080fd5b5035611ea3565b6040805160ff988916815260208101979097526001600160a01b03909516868601526060860193909352608085019190915290931660a083015267ffffffffffffffff90921660c082015290519081900360e00190f35b34801561098157600080fd5b506103dd611efb565b34801561099657600080fd5b506103dd611f01565b3480156109ab57600080fd5b506103dd611f07565b606481565b600681565b60603361200014610a005760405162461bcd60e51b815260040180806020018281038252602f8152602001806132a0602f913960400191505060405180910390fd5b610a3f83838080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250611f0d92505050565b949350505050565b600481565b600181565b61100181565b6020810151600090610a67613168565b50600081815260016020818152604092839020835160e081018552815460ff9081168252938201549281019290925260028101546001600160a01b031693820184905260038101546060830152600481015460808301526005015491821660a082015261010090910467ffffffffffffffff1660c082015290610aef57600092505050610bb1565b600081604001516001600160a01b03166370a082316110046040518263ffffffff1660e01b815260040180826001600160a01b03166001600160a01b0316815260200191505060206040518083038186803b158015610b4d57600080fd5b505afa158015610b61573d6000803e3d6000fd5b505050506040513d6020811015610b7757600080fd5b505160808301516060840151919250600091610b989163ffffffff61219e16565b9050610baa818363ffffffff61219e16565b9450505050505b919050565b603881565b600081565b600581565b600881565b61200081565b6402540be40081565b600281565b600381565b600080610bef836121e7565b9050610bf9613168565b50600081815260016020818152604092839020835160e081018552815460ff90811682529382015492810183905260028201546001600160a01b03169481019490945260038101546060850152600481015460808501526005015491821660a084015261010090910467ffffffffffffffff1660c0830152610cbf576040805162461bcd60e51b815260206004820152601a602482015279189a5b99081c995c5d595cdd08191bd95cdb89dd08195e1a5cdd60321b604482015290519081900360640190fd5b6000610cdc8260800151836060015161219e90919063ffffffff16565b905081604001516001600160a01b0316866001600160a01b031614610d325760405162461bcd60e51b815260040180806020018281038252604581526020018061325b6045913960600191505060405180910390fd5b336001600160a01b0316866001600160a01b031663893d20e86040518163ffffffff1660e01b815260040160206040518083038186803b158015610d7557600080fd5b505afa158015610d89573d6000803e3d6000fd5b505050506040513d6020811015610d9f57600080fd5b50516001600160a01b031614610de65760405162461bcd60e51b815260040180806020018281038252602e8152602001806131f6602e913960400191505060405180910390fd5b604080516370a0823160e01b8152611004600482015290516000916001600160a01b038916916370a0823191602480820192602092909190829003018186803b158015610e3257600080fd5b505afa158015610e46573d6000803e3d6000fd5b505050506040513d6020811015610e5c57600080fd5b505160408051636eb1769f60e11b815233600482015230602482015290519192508391610eed9184916001600160a01b038c169163dd62ed3e916044808301926020929190829003018186803b158015610eb557600080fd5b505afa158015610ec9573d6000803e3d6000fd5b505050506040513d6020811015610edf57600080fd5b50519063ffffffff6121ee16565b1015610f40576040805162461bcd60e51b815260206004820152601760248201527f616c6c6f77616e6365206973206e6f7420656e6f756768000000000000000000604482015290519081900360640190fd5b600034905060006110046001600160a01b031663149d14d96040518163ffffffff1660e01b815260040160206040518083038186803b158015610f8257600080fd5b505afa158015610f96573d6000803e3d6000fd5b505050506040513d6020811015610fac57600080fd5b50519050808210801590610fc557506402540be4008206155b6110005760405162461bcd60e51b81526004018080602001828103825260378152602001806132246037913960400191505060405180910390fd5b600061100c868b612248565b905063ffffffff811661120b576001600160a01b038a166323b872dd3361100461103c898963ffffffff61219e16565b6040518463ffffffff1660e01b815260040180846001600160a01b03166001600160a01b03168152602001836001600160a01b03166001600160a01b031681526020018281526020019350505050602060405180830381600087803b1580156110a457600080fd5b505af11580156110b8573d6000803e3d6000fd5b505050506040513d60208110156110ce57600080fd5b5050602086015160408088015160a089015182516323bfccdb60e21b815260048101949094526001600160a01b03909116602484015260ff1660448301525161100491638eff336c91606480830192600092919082900301818387803b15801561113757600080fd5b505af115801561114b573d6000803e3d6000fd5b50505050896001600160a01b03167f78e7dd9aefcdbf795c4936a66f7dc6d41bb56637b54f561a6bf7829dca3348a88a8860600151886040518080602001848152602001838152602001828103825285818151815260200191508051906020019080838360005b838110156111ca5781810151838201526020016111b2565b50505050905090810190601f1680156111f75780820380516001836020036101000a031916815260200191505b5094505050505060405180910390a26112c3565b896001600160a01b03167f831c0ef4d93bda3bce08b69ae3f29ef1a6e052b833200988554158494405a1078a8360405180806020018363ffffffff1663ffffffff168152602001828103825284818151815260200191508051906020019080838360005b8381101561128757818101518382015260200161126f565b50505050905090810190601f1680156112b45780820380516001836020036101000a031916815260200191505b50935050505060405180910390a25b60008781526001602081905260408220805460ff191681559081018290556002810180546001600160a01b0319169055600381018290556004810191909155600501805468ffffffffffffffffff1916905561131d6131a4565b5060408051808201825263ffffffff831681526020810189905290516110049085156108fc029086906000818181858888f19350505050158015611365573d6000803e3d6000fd5b5061200063f7a251d760016113798461269f565b61138e886402540be40063ffffffff61272916565b6040518463ffffffff1660e01b8152600401808460ff1660ff16815260200180602001838152602001828103825284818151815260200191508051906020019080838360005b838110156113ec5781810151838201526020016113d4565b50505050905090810190601f1680156114195780820380516001836020036101000a031916815260200191505b50945050505050600060405180830381600087803b15801561143a57600080fd5b505af115801561144e573d6000803e3d6000fd5b505050506001985050505050505050505b92915050565b61100581565b600080611477836121e7565b9050611481613168565b50600081815260016020818152604092839020835160e081018552815460ff90811682529382015492810183905260028201546001600160a01b03169481019490945260038101546060850152600481015460808501526005015491821660a084015261010090910467ffffffffffffffff1660c0830152611547576040805162461bcd60e51b815260206004820152601a602482015279189a5b99081c995c5d595cdd08191bd95cdb89dd08195e1a5cdd60321b604482015290519081900360640190fd5b428160c0015167ffffffffffffffff16106115a9576040805162461bcd60e51b815260206004820152601b60248201527f62696e642072657175657374206973206e6f7420657870697265640000000000604482015290519081900360640190fd5b600034905060006110046001600160a01b031663149d14d96040518163ffffffff1660e01b815260040160206040518083038186803b1580156115eb57600080fd5b505afa1580156115ff573d6000803e3d6000fd5b505050506040513d602081101561161557600080fd5b5051905080821080159061162e57506402540be4008206155b6116695760405162461bcd60e51b81526004018080602001828103825260378152602001806132246037913960400191505060405180910390fd5b60008481526001602081905260408220805460ff191681559081018290556002810180546001600160a01b0319169055600381018290556004810191909155600501805468ffffffffffffffffff191690556116c36131a4565b50604080518082018252600181526020810186905290516110049084156108fc029085906000818181858888f19350505050158015611706573d6000803e3d6000fd5b5061200063f7a251d7600161171a8461269f565b61172f876402540be40063ffffffff61272916565b6040518463ffffffff1660e01b8152600401808460ff1660ff16815260200180602001838152602001828103825284818151815260200191508051906020019080838360005b8381101561178d578181015183820152602001611775565b50505050905090810190601f1680156117ba5780820380516001836020036101000a031916815260200191505b50945050505050600060405180830381600087803b1580156117db57600080fd5b505af11580156117ef573d6000803e3d6000fd5b5050505083604001516001600160a01b03167f831c0ef4d93bda3bce08b69ae3f29ef1a6e052b833200988554158494405a10788600160405180806020018360ff1663ffffffff168152602001828103825284818151815260200191508051906020019080838360005b83811015611871578181015183820152602001611859565b50505050905090810190601f16801561189e5780820380516001836020036101000a031916815260200191505b50935050505060405180910390a25060019695505050505050565b61100881565b6000806118cb836121e7565b90506118d5613168565b50600081815260016020818152604092839020835160e081018552815460ff90811682529382015492810183905260028201546001600160a01b03169481019490945260038101546060850152600481015460808501526005015491821660a084015261010090910467ffffffffffffffff1660c083015261199b576040805162461bcd60e51b815260206004820152601a602482015279189a5b99081c995c5d595cdd08191bd95cdb89dd08195e1a5cdd60321b604482015290519081900360640190fd5b80604001516001600160a01b0316856001600160a01b0316146119ef5760405162461bcd60e51b815260040180806020018281038252604581526020018061325b6045913960600191505060405180910390fd5b336001600160a01b0316856001600160a01b031663893d20e86040518163ffffffff1660e01b815260040160206040518083038186803b158015611a3257600080fd5b505afa158015611a46573d6000803e3d6000fd5b505050506040513d6020811015611a5c57600080fd5b50516001600160a01b031614611ab9576040805162461bcd60e51b815260206004820152601b60248201527f6f6e6c79206265703230206f776e65722063616e2072656a6563740000000000604482015290519081900360640190fd5b600034905060006110046001600160a01b031663149d14d96040518163ffffffff1660e01b815260040160206040518083038186803b158015611afb57600080fd5b505afa158015611b0f573d6000803e3d6000fd5b505050506040513d6020811015611b2557600080fd5b50519050808210801590611b3e57506402540be4008206155b611b795760405162461bcd60e51b81526004018080602001828103825260378152602001806132246037913960400191505060405180910390fd5b60008481526001602081905260408220805460ff191681559081018290556002810180546001600160a01b0319169055600381018290556004810191909155600501805468ffffffffffffffffff19169055611bd36131a4565b50604080518082018252600781526020810186905290516110049084156108fc029085906000818181858888f19350505050158015611c16573d6000803e3d6000fd5b5061200063f7a251d76001611c2a8461269f565b611c3f876402540be40063ffffffff61272916565b6040518463ffffffff1660e01b8152600401808460ff1660ff16815260200180602001838152602001828103825284818151815260200191508051906020019080838360005b83811015611c9d578181015183820152602001611c85565b50505050905090810190601f168015611cca5780820380516001836020036101000a031916815260200191505b50945050505050600060405180830381600087803b158015611ceb57600080fd5b505af1158015611cff573d6000803e3d6000fd5b50505050876001600160a01b03167f831c0ef4d93bda3bce08b69ae3f29ef1a6e052b833200988554158494405a10788600760405180806020018360ff1663ffffffff168152602001828103825284818151815260200191508051906020019080838360005b83811015611d7d578181015183820152602001611d65565b50505050905090810190601f168015611daa5780820380516001836020036101000a031916815260200191505b50935050505060405180910390a2506001979650505050505050565b600b81565b3361200014611e0b5760405162461bcd60e51b815260040180806020018281038252602f8152602001806132a0602f913960400191505060405180910390fd5b7f41ce201247b6ceb957dcdb217d0b8acb50b9ea0e12af9af4f5e7f38902101605838383604051808460ff1660ff168152602001806020018281038252848482818152602001925080828437600083820152604051601f909101601f1916909201829003965090945050505050a1505050565b600781565b600981565b61100781565b61100681565b60005460ff1681565b61100281565b600160208190526000918252604090912080549181015460028201546003830154600484015460059094015460ff9586169593946001600160a01b0390931693919291811690610100900467ffffffffffffffff1687565b61100381565b61100081565b61100481565b6060611f17613168565b6000611f228461276b565b9150915080611f78576040805162461bcd60e51b815260206004820152601f60248201527f756e7265636f676e697a6564207472616e73666572496e207061636b61676500604482015290519081900360640190fd5b815160ff1661202c576020828101805160009081526001928390526040908190208551815460ff1990811660ff928316178355935194820194909455908501516002820180546001600160a01b0319166001600160a01b03909216919091179055606085015160038201556080850151600482015560a08501516005909101805460c08701519316919093161768ffffffffffffffff00191661010067ffffffffffffffff90921691909102179055612183565b815160ff16600114156121365760006110046001600160a01b03166359b9278984602001516040518263ffffffff1660e01b81526004018082815260200191505060206040518083038186803b15801561208557600080fd5b505afa158015612099573d6000803e3d6000fd5b505050506040513d60208110156120af57600080fd5b505190506001600160a01b038116156121305760208301516040805163b99328c560e01b815260048101929092526001600160a01b0383166024830152516110049163b99328c591604480830192600092919082900301818387803b15801561211757600080fd5b505af115801561212b573d6000803e3d6000fd5b505050505b50612183565b6040805162461bcd60e51b815260206004820152601960248201527f756e7265636f676e697a65642062696e64207061636b61676500000000000000604482015290519081900360640190fd5b60408051600080825260208201909252905b50949350505050565b60006121e083836040518060400160405280601e81526020017f536166654d6174683a207375627472616374696f6e206f766572666c6f7700008152506128bd565b9392505050565b6020015190565b6000828201838110156121e0576040805162461bcd60e51b815260206004820152601b60248201527f536166654d6174683a206164646974696f6e206f766572666c6f770000000000604482015290519081900360640190fd5b600080826001600160a01b031663313ce5676040518163ffffffff1660e01b815260040160206040518083038186803b15801561228457600080fd5b505afa158015612298573d6000803e3d6000fd5b505050506040513d60208110156122ae57600080fd5b5051604080516395d89b4160e01b815290519192506060916001600160a01b038616916395d89b41916004808301926000929190829003018186803b1580156122f657600080fd5b505afa15801561230a573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052602081101561233357600080fd5b8101908080516040519392919084600160201b82111561235257600080fd5b90830190602082018581111561236757600080fd5b8251600160201b81118282018810171561238057600080fd5b82525081516020918201929091019080838360005b838110156123ad578181015183820152602001612395565b50505050905090810190601f1680156123da5780820380516001836020036101000a031916815260200191505b5060408181526370a0823160e01b82526110046004830152519495506000946001600160a01b038a1694506370a08231935060248083019350602092829003018186803b15801561242a57600080fd5b505afa15801561243e573d6000803e3d6000fd5b505050506040513d602081101561245457600080fd5b5051608087015160608801519192506000916124759163ffffffff61219e16565b9050428760c0015167ffffffffffffffff16101561249b57506001935061145f92505050565b6124a9838860200151612954565b6124bb57506002935061145f92505050565b808211156124d157506003935061145f92505050565b866060015187604001516001600160a01b03166318160ddd6040518163ffffffff1660e01b815260040160206040518083038186803b15801561251357600080fd5b505afa158015612527573d6000803e3d6000fd5b505050506040513d602081101561253d57600080fd5b50511461255257506004935061145f92505050565b8660a0015160ff16841461256e57506005935061145f92505050565b602080880151604080516359b9278960e01b8152600481019290925251600092611004926359b927899260248083019392829003018186803b1580156125b357600080fd5b505afa1580156125c7573d6000803e3d6000fd5b505050506040513d60208110156125dd57600080fd5b50516001600160a01b031614158061267f57506000801b6110046001600160a01b031663bd46646189604001516040518263ffffffff1660e01b815260040180826001600160a01b03166001600160a01b0316815260200191505060206040518083038186803b15801561265057600080fd5b505afa158015612664573d6000803e3d6000fd5b505050506040513d602081101561267a57600080fd5b505114155b1561269257506006935061145f92505050565b5060009695505050505050565b6040805160028082526060828101909352829190816020015b60608152602001906001900390816126b857505083519091506126e09063ffffffff16612a3c565b816000815181106126ed57fe5b6020026020010181905250612708836020015160001c612a3c565b8160018151811061271557fe5b60200260200101819052506121e081612a4f565b60006121e083836040518060400160405280601a81526020017f536166654d6174683a206469766973696f6e206279207a65726f000000000000815250612ad9565b612773613168565b600061277d613168565b6127856131bb565b61279661279186612b3e565b612b63565b90506000805b6127a583612bad565b156128b057806127ca576127c06127bb84612bce565b612c1c565b60ff1684526128a8565b80600114156127e9576127df6127bb84612bce565b60208501526128a8565b8060021415612816576128036127fe84612bce565b612cd1565b6001600160a01b031660408501526128a8565b80600314156128355761282b6127bb84612bce565b60608501526128a8565b80600414156128545761284a6127bb84612bce565b60808501526128a8565b8060051415612876576128696127bb84612bce565b60ff1660a08501526128a8565b80600614156128a35761288b6127bb84612bce565b67ffffffffffffffff1660c0850152600191506128a8565b6128b0565b60010161279c565b5091935090915050915091565b6000818484111561294c5760405162461bcd60e51b81526004018080602001828103825283818151815260200191508051906020019080838360005b838110156129115781810151838201526020016128f9565b50505050905090810190601f16801561293e5780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b505050900390565b815160009083906008108061296a575080516003115b1561297957600091505061145f565b604080516020808252818301909252606091602082018180368337019050509050836020820152808251815181106129ad57fe5b6020910101516001600160f81b031916602d60f81b146129d25760009250505061145f565b600160005b8351811015612a32578281815181106129ec57fe5b602001015160f81c60f81b6001600160f81b031916848281518110612a0d57fe5b01602001516001600160f81b03191614612a2a5760009150612a32565b6001016129d7565b5095945050505050565b606061145f612a4a83612ceb565b612dd1565b6060815160001415612a705750604080516000815260208101909152610bb1565b606082600081518110612a7f57fe5b602002602001015190506000600190505b8351811015612ac057612ab682858381518110612aa957fe5b6020026020010151612e23565b9150600101612a90565b506121e0612ad3825160c060ff16612ea0565b82612e23565b60008183612b285760405162461bcd60e51b81526020600482018181528351602484015283519092839260449091019190850190808383600083156129115781810151838201526020016128f9565b506000838581612b3457fe5b0495945050505050565b612b466131db565b506040805180820190915281518152602082810190820152919050565b612b6b6131bb565b612b7482612f98565b612b7d57600080fd5b6000612b8c8360200151612fd2565b60208085015160408051808201909152868152920190820152915050919050565b6000612bb76131db565b505080518051602091820151919092015191011190565b612bd66131db565b612bdf82612bad565b612be857600080fd5b60208201516000612bf882613035565b80830160209586015260408051808201909152908152938401919091525090919050565b805160009015801590612c3157508151602110155b612c3a57600080fd5b6000612c498360200151612fd2565b90508083600001511015612ca4576040805162461bcd60e51b815260206004820152601a60248201527f6c656e677468206973206c657373207468616e206f6666736574000000000000604482015290519081900360640190fd5b82516020808501518301805192849003929183101561219557506020919091036101000a90049392505050565b8051600090601514612ce257600080fd5b61145f82612c1c565b604080516020808252818301909252606091829190602082018180368337505050602081018490529050600067ffffffffffffffff198416612d2f57506018612d53565b6fffffffffffffffffffffffffffffffff198416612d4f57506010612d53565b5060005b6020811015612d8957818181518110612d6857fe5b01602001516001600160f81b03191615612d8157612d89565b600101612d53565b60008160200390506060816040519080825280601f01601f191660200182016040528015612dbe576020820181803683370190505b5080830196909652508452509192915050565b606081516001148015612e035750607f60f81b82600081518110612df157fe5b01602001516001600160f81b03191611155b15612e0f575080610bb1565b61145f612e218351608060ff16612ea0565b835b6060806040519050835180825260208201818101602087015b81831015612e54578051835260209283019201612e3c565b50855184518101855292509050808201602086015b81831015612e81578051835260209283019201612e69565b508651929092011591909101601f01601f191660405250905092915050565b6060680100000000000000008310612ef0576040805162461bcd60e51b815260206004820152600e60248201526d696e70757420746f6f206c6f6e6760901b604482015290519081900360640190fd5b60408051600180825281830190925260609160208201818036833701905050905060378411612f4a5782840160f81b81600081518110612f2c57fe5b60200101906001600160f81b031916908160001a905350905061145f565b6060612f5585612ceb565b90508381510160370160f81b82600081518110612f6e57fe5b60200101906001600160f81b031916908160001a905350612f8f8282612e23565b95945050505050565b8051600090612fa957506000610bb1565b6020820151805160001a9060c0821015612fc857600092505050610bb1565b5060019392505050565b8051600090811a6080811015612fec576000915050610bb1565b60b8811080613007575060c08110801590613007575060f881105b15613016576001915050610bb1565b60c081101561302a5760b519019050610bb1565b60f519019050610bb1565b80516000908190811a60808110156130505760019150613161565b60b881101561306557607e1981019150613161565b60c08110156130df57600060b78203600186019550806020036101000a8651049150600181018201935050808310156130d9576040805162461bcd60e51b81526020600482015260116024820152706164646974696f6e206f766572666c6f7760781b604482015290519081900360640190fd5b50613161565b60f88110156130f45760be1981019150613161565b600060f78203600186019550806020036101000a86510491506001810182019350508083101561315f576040805162461bcd60e51b81526020600482015260116024820152706164646974696f6e206f766572666c6f7760781b604482015290519081900360640190fd5b505b5092915050565b6040805160e081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c081019190915290565b604080518082019091526000808252602082015290565b60405180604001604052806131ce6131db565b8152602001600081525090565b60405180604001604052806000815260200160008152509056fe6f6e6c79206265703230206f776e65722063616e20617070726f766520746869732062696e64207265717565737472656c6179466565206d757374206265204e202a203165313020616e642067726561746572207468616e206d696e6952656c6179466565636f6e74616374206164647265737320646f65736e277420657175616c20746f2074686520636f6e7472616374206164647265737320696e2062696e642072657175657374746865206d6573736167652073656e646572206d7573742062652063726f737320636861696e20636f6e7472616374a264697066735822122030cc6c250f37ad9452c0933399bf3f460a19215bce5c10c377f100761098776a64736f6c63430006040033" + }, + "0x0000000000000000000000000000000000002000": { + "balance": "0x0", + "code": "0x608060405234801561001057600080fd5b50600436106102485760003560e01c8063863fe4ab1161013b578063c81b1662116100b8578063e3b048051161007c578063e3b048051461072c578063f7a251d71461074c578063f9a2bbc7146107c4578063fc3e5908146107cc578063fd6a6879146107d457610248565b8063c81b1662146106dd578063d31f968d146106e5578063d76a867514610714578063dc927faf1461071c578063e1c7392a1461072457610248565b8063a78abc16116100ff578063a78abc16146105d3578063ab51bb96146105db578063ac431751146105e3578063b0355f5b146103ff578063c27cdcfb146106a157610248565b8063863fe4ab146105b35780638cc8f561146104b657806396713da9146105bb5780639dc09262146105c3578063a1a11bf5146105cb57610248565b8063493279b1116101c957806370fd5bad1161018d57806370fd5bad146104b657806374f079b8146104be57806375d47a0a146104c65780637942fd05146104ce57806384013b6a146104d657610248565b8063493279b11461045f5780634bf6c8821461047e57806351e80672146104865780636e47a51a1461048e5780636e47b482146104ae57610248565b8063308325f411610210578063308325f4146102cf5780633bdc47a6146102d75780633dffc387146103ff578063422f90501461040757806343756e5c1461043b57610248565b806305e682581461024d5780630bee7a671461026b57806314b3023b1461028c57806322556cdc146102a65780632ff32aea146102ae575b600080fd5b6102556107dc565b6040805160ff9092168252519081900360200190f35b6102736107e1565b6040805163ffffffff9092168252519081900360200190f35b6102946107e6565b60408051918252519081900360200190f35b6102946107ec565b6102b66107f1565b60408051600792830b90920b8252519081900360200190f35b6102946107fa565b61038a600480360360608110156102ed57600080fd5b60ff82351691602081013591810190606081016040820135600160201b81111561031657600080fd5b82018360208201111561032857600080fd5b803590602001918460018302840111600160201b8311171561034957600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250929550610800945050505050565b6040805160208082528351818301528351919283929083019185019080838360005b838110156103c45781810151838201526020016103ac565b50505050905090810190601f1680156103f15780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b610255610876565b6104276004803603602081101561041d57600080fd5b503560ff1661087b565b604080519115158252519081900360200190f35b610443610890565b604080516001600160a01b039092168252519081900360200190f35b610467610896565b6040805161ffff9092168252519081900360200190f35b61025561089b565b6104436108a0565b610443600480360360208110156104a457600080fd5b503560ff166108a6565b6104436108c1565b6102556108c7565b6102946108cc565b6104436108d2565b6102556108d8565b6105b1600480360360a08110156104ec57600080fd5b810190602081018135600160201b81111561050657600080fd5b82018360208201111561051857600080fd5b803590602001918460018302840111600160201b8311171561053957600080fd5b919390929091602081019035600160201b81111561055657600080fd5b82018360208201111561056857600080fd5b803590602001918460018302840111600160201b8311171561058957600080fd5b919350915080356001600160401b03908116916020810135909116906040013560ff166108dd565b005b610294611a8d565b610255611a95565b610443611a9a565b610443611aa0565b610427611aa6565b6102736107dc565b6105b1600480360360408110156105f957600080fd5b810190602081018135600160201b81111561061357600080fd5b82018360208201111561062557600080fd5b803590602001918460018302840111600160201b8311171561064657600080fd5b919390929091602081019035600160201b81111561066357600080fd5b82018360208201111561067557600080fd5b803590602001918460018302840111600160201b8311171561069657600080fd5b509092509050611aaf565b6106c1600480360360208110156106b757600080fd5b503560ff16612051565b604080516001600160401b039092168252519081900360200190f35b61044361206c565b610427600480360360408110156106fb57600080fd5b5080356001600160a01b0316906020013560ff16612072565b61038a612092565b6104436120b1565b6105b16120b7565b6106c16004803603602081101561074257600080fd5b503560ff1661246e565b6105b16004803603606081101561076257600080fd5b60ff8235169190810190604081016020820135600160201b81111561078657600080fd5b82018360208201111561079857600080fd5b803590602001918460018302840111600160201b831117156107b957600080fd5b919350915035612489565b6104436125da565b6102556125e0565b6104436125e5565b600081565b606481565b60015481565b603281565b60045460070b81565b60025481565b60606000825160210190506060816040519080825280601f01601f191660200182016040528015610838576020820181803683370190505b506021810186905260018101879052828152905060418101600061085b866125eb565b50905061086a818388516125f5565b50909695505050505050565b600181565b60096020526000908152604090205460ff1681565b61100181565b603881565b600881565b61200081565b6005602052600090815260409020546001600160a01b031681565b61100581565b600281565b60035481565b61100881565b600b81565b60005460ff16610930576040805162461bcd60e51b81526020600482015260196024820152781d1a194818dbdb9d1c9858dd081b9bdd081a5b9a5d081e595d603a1b604482015290519081900360640190fd5b60408051630a83aaa960e31b815233600482015290516110069163541d5548916024808301926020929190829003018186803b15801561096f57600080fd5b505afa158015610983573d6000803e3d6000fd5b505050506040513d602081101561099957600080fd5b50516109ec576040805162461bcd60e51b815260206004820152601f60248201527f746865206d73672073656e646572206973206e6f7420612072656c6179657200604482015290519081900360640190fd5b60ff8116600090815260086020526040902054829082906001600160401b039081169083168114610a5c576040805162461bcd60e51b815260206004820152601560248201527439b2b8bab2b731b2903737ba1034b71037b93232b960591b604482015290519081900360640190fd5b60ff8216600090815260086020908152604091829020805467ffffffffffffffff1916600185016001600160401b039081169190911790915582516337d7f9c160e21b81529089166004820152915188926110039263df5fe70492602480840193829003018186803b158015610ad157600080fd5b505afa158015610ae5573d6000803e3d6000fd5b505050506040513d6020811015610afb57600080fd5b5051610b385760405162461bcd60e51b8152600401808060200182810382526023815260200180612bcc6023913960400191505060405180910390fd5b60ff851660009081526005602052604090205485906001600160a01b0316610ba7576040805162461bcd60e51b815260206004820152601860248201527f6368616e6e656c206973206e6f7420737570706f727465640000000000000000604482015290519081900360640190fd5b60608c8c8080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f82011690508083019250505050505050905060608b8b8080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250506040805163cba510a960e01b81526001600160401b038f1660048201529051939450610cce93611003935063cba510a992506024808301926020929190829003018186803b158015610c7757600080fd5b505afa158015610c8b573d6000803e3d6000fd5b505050506040513d6020811015610ca157600080fd5b505160408051808201909152600381526269626360e81b6020820152610cc78c8c612636565b858561267d565b610d16576040805162461bcd60e51b815260206004820152601460248201527334b73b30b634b21036b2b935b63290383937b7b360611b604482015290519081900360640190fd5b60408051631bb5062960e31b81526001600160401b038c16600482015290516000916110039163dda8314891602480820192602092909190829003018186803b158015610d6257600080fd5b505afa158015610d76573d6000803e3d6000fd5b505050506040513d6020811015610d8c57600080fd5b5051905088600080806060610da08861277a565b935093509350935083610e61578460ff168f6001600160401b03167ff7b2e42d694eb1100184aae86d4245d9e46966100b1dc7e723275b98326854ac8a6040518080602001828103825283818151815260200191508051906020019080838360005b83811015610e1a578181015183820152602001610e02565b50505050905090810190601f168015610e475780820380516001836020036101000a031916815260200191505b509250505060405180910390a35050505050505050611a7f565b8460ff168f6001600160401b03167f36afdaf439a8f43fe72135135d804ae620b37a474f0943b5b85f6788312cad4085604051808260ff1660ff16815260200191505060405180910390a360ff83166113ea5760ff85166000818152600560209081526040808320548151631182b87560e01b815260048101958652602481019283528651604482015286516001600160a01b03909216958695631182b875958d958a9593949093606490910192918601918190849084905b83811015610f32578181015183820152602001610f1a565b50505050905090810190601f168015610f5f5780820380516001836020036101000a031916815260200191505b509350505050600060405180830381600087803b158015610f7f57600080fd5b505af192505050801561106357506040513d6000823e601f3d908101601f191682016040526020811015610fb257600080fd5b8101908080516040519392919084600160201b821115610fd157600080fd5b908301906020820185811115610fe657600080fd5b8251600160201b811182820188101715610fff57600080fd5b82525081516020918201929091019080838360005b8381101561102c578181015183820152602001611014565b50505050905090810190601f1680156110595780820380516001836020036101000a031916815260200191505b5060405250505060015b611375576040516000815260443d101561107f5750600061111a565b60046000803e60005160e01c6308c379a081146110a057600091505061111a565b60043d036004833e81513d60248201116001600160401b03821117156110cb5760009250505061111a565b80830180516001600160401b038111156110ec57600094505050505061111a565b8060208301013d860181111561110a5760009550505050505061111a565b601f01601f191660405250925050505b806111255750611237565b60ff871660009081526007602052604081205461115c916001600160401b039091169089906111579060029088610800565b61282a565b60ff8716600090815260076020908152604080832080546001600160401b038082166001011667ffffffffffffffff19909116179055805182815284518184015284516001600160a01b038716947ff91a8f63e5b3e0e89e5f93e1915a7805f3c52d9a73b3c09769785c2c7bf87acf948794849390840192918601918190849084905b838110156111f75781810151838201526020016111df565b50505050905090810190601f1680156112245780820380516001836020036101000a031916815260200191505b509250505060405180910390a250611370565b3d808015611261576040519150601f19603f3d011682016040523d82523d6000602084013e611266565b606091505b5060ff8716600090815260076020526040812054611299916001600160401b039091169089906111579060029088610800565b60ff8716600090815260076020908152604080832080546001600160401b038082166001011667ffffffffffffffff19909116179055805182815284518184015284516001600160a01b038716947f63ac299d6332d1cc4e61b81e59bc00c0ac7c798addadf33840f1307cd2977351948794849390840192918601918190849084905b8381101561133457818101518382015260200161131c565b50505050905090810190601f1680156113615780820380516001836020036101000a031916815260200191505b509250505060405180910390a2505b6113e4565b8051156113e25760ff87166000908152600760205260408120546113ae916001600160401b039091169089906111579060019086610800565b60ff8716600090815260076020526040902080546001600160401b038082166001011667ffffffffffffffff199091161790555b505b506119b8565b60ff83166001141561168e5760ff8516600081815260056020908152604080832054815163831d65d160e01b815260048101958652602481019283528651604482015286516001600160a01b0390921695869563831d65d1958d958a9593949093606490910192918601918190849084905b8381101561147457818101518382015260200161145c565b50505050905090810190601f1680156114a15780820380516001836020036101000a031916815260200191505b509350505050600060405180830381600087803b1580156114c157600080fd5b505af19250505080156114d2575060015b6113e4576040516000815260443d10156114ee57506000611589565b60046000803e60005160e01c6308c379a0811461150f576000915050611589565b60043d036004833e81513d60248201116001600160401b038211171561153a57600092505050611589565b80830180516001600160401b0381111561155b576000945050505050611589565b8060208301013d860181111561157957600095505050505050611589565b601f01601f191660405250925050505b8061159457506115f9565b60408051602080825283518183015283516001600160a01b038616937ff91a8f63e5b3e0e89e5f93e1915a7805f3c52d9a73b3c09769785c2c7bf87acf93869390928392830191850190808383600083156111f75781810151838201526020016111df565b3d808015611623576040519150601f19603f3d011682016040523d82523d6000602084013e611628565b606091505b5060408051602080825283518183015283516001600160a01b038616937f63ac299d6332d1cc4e61b81e59bc00c0ac7c798addadf33840f1307cd2977351938693909283928301918501908083836000831561133457818101518382015260200161131c565b60ff8316600214156119b85760ff8516600081815260056020908152604080832054815163c8509d8160e01b815260048101958652602481019283528651604482015286516001600160a01b0390921695869563c8509d81958d958a9593949093606490910192918601918190849084905b83811015611718578181015183820152602001611700565b50505050905090810190601f1680156117455780820380516001836020036101000a031916815260200191505b509350505050600060405180830381600087803b15801561176557600080fd5b505af1925050508015611776575060015b6119b6576040516000815260443d10156117925750600061182d565b60046000803e60005160e01c6308c379a081146117b357600091505061182d565b60043d036004833e81513d60248201116001600160401b03821117156117de5760009250505061182d565b80830180516001600160401b038111156117ff57600094505050505061182d565b8060208301013d860181111561181d5760009550505050505061182d565b601f01601f191660405250925050505b8061183857506118e1565b816001600160a01b03167ff91a8f63e5b3e0e89e5f93e1915a7805f3c52d9a73b3c09769785c2c7bf87acf826040518080602001828103825283818151815260200191508051906020019080838360005b838110156118a1578181015183820152602001611889565b50505050905090810190601f1680156118ce5780820380516001836020036101000a031916815260200191505b509250505060405180910390a2506119b6565b3d80801561190b576040519150601f19603f3d011682016040523d82523d6000602084013e611910565b606091505b50816001600160a01b03167f63ac299d6332d1cc4e61b81e59bc00c0ac7c798addadf33840f1307cd2977351826040518080602001828103825283818151815260200191508051906020019080838360005b8381101561197a578181015183820152602001611962565b50505050905090810190601f1680156119a75780820380516001836020036101000a031916815260200191505b509250505060405180910390a2505b505b60ff80861660009081526009602052604090205461100591636f93d2e69189913391879116806119ea575060ff881615155b604080516001600160e01b031960e088901b1681526001600160a01b039586166004820152939094166024840152604483019190915215156064820152905160848083019260209291908290030181600087803b158015611a4a57600080fd5b505af1158015611a5e573d6000803e3d6000fd5b505050506040513d6020811015611a7457600080fd5b505050505050505050505b505050505050505050505050565b630100380081565b600981565b61100781565b61100681565b60005460ff1681565b3361100714611aef5760405162461bcd60e51b815260040180806020018281038252602e815260200180612b22602e913960400191505060405180910390fd5b611b5884848080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525050604080518082019091526012815271626174636853697a65466f724f7261636c6560701b602082015291506129809050565b15611bf357604080516020601f8401819004810282018101909252828152600091611b9b91858580838501838280828437600092019190915250612a6792505050565b90506127108111158015611bb05750600a8110155b611beb5760405162461bcd60e51b8152600401808060200182810382526032815260200180612b9a6032913960400191505060405180910390fd5b600155611fbf565b611c5c84848080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152505060408051808201909152601281527118591913dc955c19185d1950da185b9b995b60721b602082015291506129809050565b15611de457606082828080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152505082519293505060169091149050611cdf5760405162461bcd60e51b815260040180806020018281038252605a815260200180612ac8605a913960600191505060405180910390fd5b60018101516002820151601683015160ff82161590611cfd81612a6c565b611d4e576040805162461bcd60e51b815260206004820152601960248201527f61646472657373206973206e6f74206120636f6e747261637400000000000000604482015290519081900360640190fd5b60ff8416600081815260056020908152604080832080546001600160a01b0319166001600160a01b038716908117909155808452600683528184208585528352818420805460ff199081166001179091556009909352818420805490931687151517909255519092917f7e3b6af43092577ee20e60eaa1d9b114a7031305c895ee7dd3ffe17196d2e1e091a35050505050611fbf565b611e5184848080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525050604080518082019091526016815275195b98589b1953dc911a5cd8589b1950da185b9b995b60521b602082015291506129809050565b15611f8257606082828080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152505082519293505060029091149050611ed45760405162461bcd60e51b815260040180806020018281038252604a815260200180612b50604a913960600191505060405180910390fd5b600181810151600283015160ff80831660009081526005602052604090205492939192908316909114906001600160a01b03168015611f78576001600160a01b038116600090815260066020908152604080832060ff881680855290835292819020805460ff1916861515908117909155815190815290517fa3132e3f9819fbddc7f0ed6d38d7feef59aa95112090b7c592f5cb5bc4aa4adc929181900390910190a25b5050505050611fbf565b6040805162461bcd60e51b815260206004820152600d60248201526c756e6b6e6f776e20706172616d60981b604482015290519081900360640190fd5b7f6cdb0ac70ab7f2e2d035cca5be60d89906f2dede7648ddbd7402189c1eeed17a848484846040518080602001806020018381038352878782818152602001925080828437600083820152601f01601f191690910184810383528581526020019050858580828437600083820152604051601f909101601f19169092018290039850909650505050505050a150505050565b6008602052600090815260409020546001600160401b031681565b61100281565b600660209081526000928352604080842090915290825290205460ff1681565b6040518060400160405280600381526020016269626360e81b81525081565b61100381565b60005460ff161561210f576040805162461bcd60e51b815260206004820152601960248201527f74686520636f6e747261637420616c726561647920696e697400000000000000604482015290519081900360640190fd5b7f1471eb6eb2c5e789fc3de43f8ce62938c7d1836ec861730447e2ada8fd81017b80546001600160a01b0319908116611008179091557f92e85d02570a8092d09a6e3a57665bc3815a2699a4074001bf1ccabf660f5a36805460ff199081169091557fd8af288fc1c8680b4f4706064cf021e264efb6828fcaf7eb5ca36818eb365bcc8054821660019081179091557f89832631fb3c3307a103ba2c84ab569c64d6182a18893dcd163f0f1c2090733a805484166110049081179091557f6cde3cea4b3a3fb2488b2808bae7556f4a405e50f65e1794383bc026131b13c38054841690557f72e4efa1513b071517c6c74dba31b5934a81aa83cddd400e7081df5529c9943680548416831790557fa9bc9a3a348c357ba16b37005d7e6b3236198c0e939f4af8c5f19b8deeb8ebc08054851690911790557fc575c31fea594a6eb97c8e9d3f9caee4c16218c6ef37e923234c0fe9014a61e78054831690557f4e523af77f034e9810f1c94057f5e931fb3d16a51511a4c3add793617d18610580548316821790557ffb33122aa9f93cc639ebe80a7bc4784c11e6053dde89c6f4f7e268c6a623da1e805484166110001790557fc7694af312c4f286114180fd0ba6a52461fcee8a381636770b19a343af92538a80548316821790557f01112dd68e482ba8d68a7e828cff8b3abcea08eab88941953c180a7e650e9cd480548316821790557fc0a4a8be475dfebc377ebef2d7c4ff47656f572a08dd92b81017efcdba0febe1805484166110071790557f87e8a52529e8ece4ef759037313542a6429ff494a9fab9027fb79db90124eba680548316821790557f4c7666bbcb22d46469f7cc282f70764a7012dca2cce630ff8d83db9a9cdd48f080548316821790557f40f28f99a40bc9f6beea1013afdbc3cdcc689eb76b82c4de06c0acf1e1932ed58054909316611001179092557f0d9cf2cd531699eed8dd34e40ff2884a14a698c4898184fba85194e6f6772d248054821683179055600b60009081527f23f68c9bd22b8a93d06adabe17481c87c016bcbd20adc8bfd707a4d813a572176020527fdf0d5d05428057f5455c2dc8e810dd86d1e9350faa72f16bda8a45443c5b39328054831684179055603283556004805467ffffffffffffffff19166001600160401b031790556002819055600381905580549091169091179055565b6007602052600090815260409020546001600160401b031681565b60005460ff166124dc576040805162461bcd60e51b81526020600482015260196024820152781d1a194818dbdb9d1c9858dd081b9bdd081a5b9a5d081e595d603a1b604482015290519081900360640190fd5b33600090815260066020908152604080832060ff80891685529252909120548591166125395760405162461bcd60e51b8152600401808060200182810382526031815260200180612a976031913960400191505060405180910390fd5b60ff85166000908152600760209081526040808320548151601f88018490048402810184019092528682526001600160401b03169261259e9284928a9261115792909189918c908c908190840183828082843760009201919091525061080092505050565b60ff959095166000908152600760205260409020805467ffffffffffffffff191660019096016001600160401b03169590951790945550505050565b61100081565b600381565b61100481565b8051602090910191565b5b60208110612615578251825260209283019290910190601f19016125f6565b915181516020939093036101000a6000190180199091169216919091179052565b60408051600e808252818301909252606091630100380060ff851617918391602082018180368337505050600e818101969096526006810192909252509283525090919050565b60008561268c57506000612771565b606082518451865160800101016040519080825280601f01601f1916602001820160405280156126c3576020820181803683370190505b50905060006126d182612a72565b6020808901518252019050866000806126e9896125eb565b80865260209095019490925090506127028285836125f5565b9283019261270f886125eb565b80865260209095019490925090506127288285836125f5565b9283018a81526020019261273b876125eb565b909250905061274b8285836125f5565b508351602001612759612a78565b60208183886065600019fa5051600114955050505050505b95945050505050565b600080600060606021855110156127aa575050604080516000808252602082019092529092508291508190612823565b600185015160218601518651604080516020198301808252601f19600119909401939093168101602001909152604189019392916060919080156127f5576020820181803683370190505b5090506000612803826125eb565b509050612815858260218d51036125f5565b506001975091955093509150505b9193509193565b600254431115612869576004805467ffffffffffffffff1981166001600160401b036001600793840b810190930b1617909155600355436002556128aa565b600380546001908101918290555410156128aa576004805467ffffffffffffffff1981166001600160401b036001600793840b810190930b16179091556003555b8160ff16836001600160401b0316600460009054906101000a900460070b6001600160401b03167f3a6e0fc61675aa2a100bcba0568368bb92bcec91c97673391074f11138f0cffe603885604051808361ffff1661ffff16815260200180602001828103825283818151815260200191508051906020019080838360005b83811015612940578181015183820152602001612928565b50505050905090810190601f16801561296d5780820380516001836020036101000a031916815260200191505b50935050505060405180910390a4505050565b6000816040516020018082805190602001908083835b602083106129b55780518252601f199092019160209182019101612996565b6001836020036101000a03801982511681845116808217855250505050505090500191505060405160208183030381529060405280519060200120836040516020018082805190602001908083835b60208310612a235780518252601f199092019160209182019101612a04565b6001836020036101000a0380198251168184511680821785525050505050509050019150506040516020818303038152906040528051906020012014905092915050565b015190565b3b151590565b60200190565b6040518060200160405280600190602082028036833750919291505056fe74686520636f6e747261637420616e64206368616e6e656c2068617665206e6f74206265656e20726567697374657265646c656e677468206f662076616c756520666f72206164644f725570646174654368616e6e656c2073686f756c642062652032322c206368616e6e656c49643a697346726f6d53797374656d3a68616e646c657241646472657373746865206d6573736167652073656e646572206d75737420626520676f7665726e616e636520636f6e74726163746c656e677468206f662076616c756520666f7220656e61626c654f7244697361626c654368616e6e656c2073686f756c6420626520322c206368616e6e656c49643a6973456e61626c65746865206e6577426174636853697a65466f724f7261636c652073686f756c6420626520696e205b31302c2031303030305d6c6967687420636c69656e74206e6f742073796e632074686520626c6f636b20796574a264697066735822122083f6194f9a326fa5963aa39ffe11dcd28d1421a9f74fbe97a97f4853026e29ff64736f6c63430006040033" + }, + "b005741528b86F5952469d80A8614591E3c5B632": { + "balance": "0x1b1ae4d6e2ef500000" + }, + "446AA6E0DC65690403dF3F127750da1322941F3e": { + "balance": "0x1b1ae4d6e2ef500000" + } } \ No newline at end of file diff --git a/core/allocs/chapel.json b/core/allocs/chapel.json index 32990606d7e..1fc33004b6c 100644 --- a/core/allocs/chapel.json +++ b/core/allocs/chapel.json @@ -1,51 +1,51 @@ { - "0xffffFFFfFFffffffffffffffFfFFFfffFFFfFFfE": { - "balance": "0x0" - }, - "0x0000000000000000000000000000000000001000": { - "balance": "0x0", - "code": "0x6080604052600436106102675760003560e01c806396713da911610144578063c81b1662116100b6578063eb57e2021161007a578063eb57e20214610900578063eda5868c14610933578063f340fa0114610948578063f9a2bbc71461096e578063fc3e590814610983578063fd6a68791461099857610267565b8063c81b1662146108ac578063c8509d81146105f3578063d86222d5146108c1578063dc927faf146108d6578063e1c7392a146108eb57610267565b8063aaf5eb6811610108578063aaf5eb681461071f578063ab51bb9614610734578063ac43175114610749578063ad3c9da614610814578063b7ab4db514610847578063bf9f49951461040557610267565b806396713da9146106a25780639dc09262146106b7578063a1a11bf5146106cc578063a5422d5c146106e1578063a78abc16146106f657610267565b80635667515a116101dd57806375d47a0a116101a157806375d47a0a146105b45780637942fd05146105c957806381650b62146105de578063831d65d1146105f3578063853230aa14610678578063862498821461068d57610267565b80635667515a146104ea5780635d77156c146104ff5780636969a25c146105145780636e47b4821461058a57806370fd5bad1461059f57610267565b80633dffc3871161022f5780633dffc3871461040557806343756e5c14610430578063493279b1146104615780634bf6c8821461048d57806351e80672146104a2578063565c56b3146104b757610267565b80630bee7a671461026c5780631182b8751461029a5780631ff1806914610394578063219f22d5146103bb57806335409f7f146103d0575b600080fd5b34801561027857600080fd5b506102816109ad565b6040805163ffffffff9092168252519081900360200190f35b3480156102a657600080fd5b5061031f600480360360408110156102bd57600080fd5b60ff8235169190810190604081016020820135600160201b8111156102e157600080fd5b8201836020820111156102f357600080fd5b803590602001918460018302840111600160201b8311171561031457600080fd5b5090925090506109b2565b6040805160208082528351818301528351919283929083019185019080838360005b83811015610359578181015183820152602001610341565b50505050905090810190601f1680156103865780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b3480156103a057600080fd5b506103a9610b26565b60408051918252519081900360200190f35b3480156103c757600080fd5b50610281610b2c565b3480156103dc57600080fd5b50610403600480360360208110156103f357600080fd5b50356001600160a01b0316610b31565b005b34801561041157600080fd5b5061041a610e45565b6040805160ff9092168252519081900360200190f35b34801561043c57600080fd5b50610445610e4a565b604080516001600160a01b039092168252519081900360200190f35b34801561046d57600080fd5b50610476610e50565b6040805161ffff9092168252519081900360200190f35b34801561049957600080fd5b5061041a610e55565b3480156104ae57600080fd5b50610445610e5a565b3480156104c357600080fd5b506103a9600480360360208110156104da57600080fd5b50356001600160a01b0316610e60565b3480156104f657600080fd5b5061041a610eb2565b34801561050b57600080fd5b50610281610eb7565b34801561052057600080fd5b5061053e6004803603602081101561053757600080fd5b5035610ebc565b604080516001600160a01b039788168152958716602087015293909516848401526001600160401b0390911660608401521515608083015260a082019290925290519081900360c00190f35b34801561059657600080fd5b50610445610f20565b3480156105ab57600080fd5b5061041a610f26565b3480156105c057600080fd5b50610445610f2b565b3480156105d557600080fd5b5061041a610f31565b3480156105ea57600080fd5b50610281610f36565b3480156105ff57600080fd5b506104036004803603604081101561061657600080fd5b60ff8235169190810190604081016020820135600160201b81111561063a57600080fd5b82018360208201111561064c57600080fd5b803590602001918460018302840111600160201b8311171561066d57600080fd5b509092509050610f3b565b34801561068457600080fd5b506103a9610fee565b34801561069957600080fd5b506103a9610ff4565b3480156106ae57600080fd5b5061041a610ffa565b3480156106c357600080fd5b50610445610fff565b3480156106d857600080fd5b50610445611005565b3480156106ed57600080fd5b5061031f61100b565b34801561070257600080fd5b5061070b61102a565b604080519115158252519081900360200190f35b34801561072b57600080fd5b506103a9611033565b34801561074057600080fd5b50610281610eb2565b34801561075557600080fd5b506104036004803603604081101561076c57600080fd5b810190602081018135600160201b81111561078657600080fd5b82018360208201111561079857600080fd5b803590602001918460018302840111600160201b831117156107b957600080fd5b919390929091602081019035600160201b8111156107d657600080fd5b8201836020820111156107e857600080fd5b803590602001918460018302840111600160201b8311171561080957600080fd5b50909250905061103c565b34801561082057600080fd5b506103a96004803603602081101561083757600080fd5b50356001600160a01b03166112e3565b34801561085357600080fd5b5061085c6112f5565b60408051602080825283518183015283519192839290830191858101910280838360005b83811015610898578181015183820152602001610880565b505050509050019250505060405180910390f35b3480156108b857600080fd5b5061044561141b565b3480156108cd57600080fd5b506103a9611421565b3480156108e257600080fd5b5061044561142d565b3480156108f757600080fd5b50610403611433565b34801561090c57600080fd5b506104036004803603602081101561092357600080fd5b50356001600160a01b0316611636565b34801561093f57600080fd5b50610281611805565b6104036004803603602081101561095e57600080fd5b50356001600160a01b031661180a565b34801561097a57600080fd5b50610445611a20565b34801561098f57600080fd5b5061041a611a26565b3480156109a457600080fd5b50610445611a2b565b606481565b60005460609060ff16610a08576040805162461bcd60e51b81526020600482015260196024820152781d1a194818dbdb9d1c9858dd081b9bdd081a5b9a5d081e595d603a1b604482015290519081900360640190fd5b3361200014610a485760405162461bcd60e51b815260040180806020018281038252602f815260200180613f73602f913960400191505060405180910390fd5b610a50613c27565b6000610a9185858080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250611a3192505050565b9150915080610aad57610aa46064611b8a565b92505050610b1f565b815160009060ff16610acd57610ac68360200151611beb565b9050610aeb565b825160ff1660011415610ae757610ac683602001516129ec565b5060655b63ffffffff8116610b105750506040805160008152602081019091529150610b1f9050565b610b1981611b8a565b93505050505b9392505050565b60035481565b606881565b3361100114610b715760405162461bcd60e51b8152600401808060200182810382526029815260200180613fcf6029913960400191505060405180910390fd5b6001600160a01b03811660009081526004602052604090205480610b955750610e42565b600181039050600060018281548110610baa57fe5b60009182526020909120600360049092020101546001549091506000190180610bf957600060018481548110610bdc57fe5b906000526020600020906004020160030181905550505050610e42565b6040805183815290516001600160a01b038616917f3b6f9ef90462b512a1293ecec018670bf7b7f1876fb727590a8a6d7643130a70919081900360200190a26001600160a01b038416600090815260046020526040812055600154600019018314610d7b57600180546000198101908110610c7057fe5b906000526020600020906004020160018481548110610c8b57fe5b6000918252602082208354600492830290910180546001600160a01b03199081166001600160a01b0393841617825560018087015481840180548416918616919091179055600280880180549185018054909416919095161780835584546001600160401b03600160a01b91829004160267ffffffffffffffff60a01b1990911617808355935460ff600160e01b918290041615150260ff60e01b199094169390931790556003948501549401939093558254868401939192919087908110610d5057fe5b600091825260208083206004909202909101546001600160a01b031683528201929092526040019020555b6001805480610d8657fe5b60008281526020812060046000199093019283020180546001600160a01b0319908116825560018201805490911690556002810180546001600160e81b03191690556003018190559155818381610dd957fe5b0490508015610e3d5760015460005b81811015610e3a578260018281548110610dfe57fe5b9060005260206000209060040201600301540160018281548110610e1e57fe5b6000918252602090912060036004909202010155600101610de8565b50505b505050505b50565b600181565b61100181565b606181565b600881565b61200081565b6001600160a01b03811660009081526004602052604081205480610e88576000915050610ead565b600180820381548110610e9757fe5b9060005260206000209060040201600301549150505b919050565b600081565b606781565b60018181548110610ec957fe5b600091825260209091206004909102018054600182015460028301546003909301546001600160a01b0392831694509082169291821691600160a01b81046001600160401b031691600160e01b90910460ff169086565b61100581565b600281565b61100881565b600b81565b606681565b3361200014610f7b5760405162461bcd60e51b815260040180806020018281038252602f815260200180613f73602f913960400191505060405180910390fd5b7f41ce201247b6ceb957dcdb217d0b8acb50b9ea0e12af9af4f5e7f38902101605838383604051808460ff1660ff168152602001806020018281038252848482818152602001925080828437600083820152604051601f909101601f1916909201829003965090945050505050a1505050565b6103e881565b60025481565b600981565b61100781565b61100681565b604051806101e001604052806101b78152602001613d9b6101b7913981565b60005460ff1681565b6402540be40081565b60005460ff1661108f576040805162461bcd60e51b81526020600482015260196024820152781d1a194818dbdb9d1c9858dd081b9bdd081a5b9a5d081e595d603a1b604482015290519081900360640190fd5b33611007146110cf5760405162461bcd60e51b815260040180806020018281038252602e815260200180613d26602e913960400191505060405180910390fd5b61113984848080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525050604080518082019091526013815272065787069726554696d655365636f6e6447617606c1b60208201529150612c2a9050565b15611214576020811461117d5760405162461bcd60e51b8152600401808060200182810382526026815260200180613d756026913960400191505060405180910390fd5b604080516020601f84018190048102820181019092528281526000916111bb91858580838501838280828437600092019190915250612d1292505050565b9050606481101580156111d15750620186a08111155b61120c5760405162461bcd60e51b8152600401808060200182810382526027815260200180613cda6027913960400191505060405180910390fd5b600255611251565b6040805162461bcd60e51b815260206004820152600d60248201526c756e6b6e6f776e20706172616d60981b604482015290519081900360640190fd5b7f6cdb0ac70ab7f2e2d035cca5be60d89906f2dede7648ddbd7402189c1eeed17a848484846040518080602001806020018381038352878782818152602001925080828437600083820152601f01601f191690910184810383528581526020019050858580828437600083820152604051601f909101601f19169092018290039850909650505050505050a150505050565b60046020526000908152604090205481565b6001546060906000805b82811015611346576001818154811061131457fe5b9060005260206000209060040201600201601c9054906101000a900460ff1661133e576001909101905b6001016112ff565b50606081604051908082528060200260200182016040528015611373578160200160208202803683370190505b50600092509050815b83811015611413576001818154811061139157fe5b9060005260206000209060040201600201601c9054906101000a900460ff1661140b57600181815481106113c157fe5b600091825260209091206004909102015482516001600160a01b03909116908390859081106113ec57fe5b6001600160a01b03909216602092830291909101909101526001909201915b60010161137c565b509250505090565b61100281565b67016345785d8a000081565b61100381565b60005460ff161561148b576040805162461bcd60e51b815260206004820152601960248201527f74686520636f6e747261637420616c726561647920696e697400000000000000604482015290519081900360640190fd5b611493613c27565b60006114b9604051806101e001604052806101b78152602001613d9b6101b79139611a31565b91509150806114f95760405162461bcd60e51b8152600401808060200182810382526021815260200180613f526021913960400191505060405180910390fd5b60005b82602001515181101561161e5760018360200151828151811061151b57fe5b60209081029190910181015182546001818101855560009485528385208351600493840290910180546001600160a01b039283166001600160a01b03199182161782558587015182850180549185169183169190911790556040860151600283018054606089015160808a01511515600160e01b0260ff60e01b196001600160401b03909216600160a01b0267ffffffffffffffff60a01b199590981692909516919091179290921694909417161790915560a0909301516003909301929092559186015180519185019391859081106115f157fe5b602090810291909101810151516001600160a01b03168252810191909152604001600020556001016114fc565b50506103e8600255506000805460ff19166001179055565b33611001146116765760405162461bcd60e51b8152600401808060200182810382526029815260200180613fcf6029913960400191505060405180910390fd5b6001600160a01b0381166000908152600460205260409020548061169a5750610e42565b6001810390506000600182815481106116af57fe5b90600052602060002090600402016003015490506000600183815481106116d257fe5b906000526020600020906004020160030181905550600060018080549050039050836001600160a01b03167f8cd4e147d8af98a9e3b6724021b8bf6aed2e5dac71c38f2dce8161b82585b25d836040518082815260200191505060405180910390a28061174157505050610e42565b600081838161174c57fe5b0490508015610e3d5760005b848110156117aa57816001828154811061176e57fe5b906000526020600020906004020160030154016001828154811061178e57fe5b6000918252602090912060036004909202010155600101611758565b50600180549085015b81811015610e3a5782600182815481106117c957fe5b90600052602060002090600402016003015401600182815481106117e957fe5b60009182526020909120600360049092020101556001016117b3565b606581565b3341146118485760405162461bcd60e51b815260040180806020018281038252602d815260200180613fa2602d913960400191505060405180910390fd5b60005460ff1661189b576040805162461bcd60e51b81526020600482015260196024820152781d1a194818dbdb9d1c9858dd081b9bdd081a5b9a5d081e595d603a1b604482015290519081900360640190fd5b600034116118e8576040805162461bcd60e51b81526020600482015260156024820152746465706f7369742076616c7565206973207a65726f60581b604482015290519081900360640190fd5b6001600160a01b038116600090815260046020526040902054349080156119db57600060018083038154811061191a57fe5b9060005260206000209060040201905080600201601c9054906101000a900460ff1615611985576040805184815290516001600160a01b038616917ff177e5d6c5764d79c32883ed824111d9b13f5668cf6ab1cc12dd36791dd955b4919081900360200190a26119d5565b600380548401815581018054840190556040805184815290516001600160a01b038616917f93a090ecc682c002995fad3c85b30c5651d7fd29b0be5da9d784a3302aedc055919081900360200190a25b50611a1b565b6040805183815290516001600160a01b038516917ff177e5d6c5764d79c32883ed824111d9b13f5668cf6ab1cc12dd36791dd955b4919081900360200190a25b505050565b61100081565b600381565b61100481565b611a39613c27565b6000611a43613c27565b611a4b613c3f565b611a5c611a5786612d17565b612d3c565b90506000805b611a6b83612d86565b15611b7c5780611a9057611a86611a8184612da7565b612df5565b60ff168452611b74565b8060011415611b6f576060611aac611aa785612da7565b612e55565b90508051604051908082528060200260200182016040528015611ae957816020015b611ad6613c5f565b815260200190600190039081611ace5790505b50602086015260005b8151811015611b6457611b03613c5f565b6000611b21848481518110611b1457fe5b6020026020010151612f26565b9150915080611b3e57876000995099505050505050505050611b85565b8188602001518481518110611b4f57fe5b60209081029190910101525050600101611af2565b506001925050611b74565b611b7c565b600101611a62565b50919350909150505b915091565b604080516001808252818301909252606091829190816020015b6060815260200190600190039081611ba4579050509050611bca8363ffffffff16613003565b81600081518110611bd757fe5b6020026020010181905250610b1f81613016565b6000806060611bf9846130a0565b9150915081611ca6577f70e72399380dcfb0338abc03dc8d47f9f470ada8e769c9a78d644ea97385ecb2816040518080602001828103825283818151815260200191508051906020019080838360005b83811015611c61578181015183820152602001611c49565b50505050905090810190601f168015611c8e5780820380516001836020036101000a031916815260200191505b509250505060405180910390a1606692505050610ead565b600080805b600154811015611d235767016345785d8a000060018281548110611ccb57fe5b90600052602060002090600402016003015410611ced57600190920191611d1b565b600060018281548110611cfc57fe5b9060005260206000209060040201600301541115611d1b576001909101905b600101611cab565b50606082604051908082528060200260200182016040528015611d50578160200160208202803683370190505b509050606083604051908082528060200260200182016040528015611d7f578160200160208202803683370190505b509050606084604051908082528060200260200182016040528015611dae578160200160208202803683370190505b509050606085604051908082528060200260200182016040528015611ddd578160200160208202803683370190505b5090506000606086604051908082528060200260200182016040528015611e0e578160200160208202803683370190505b509050606087604051908082528060200260200182016040528015611e3d578160200160208202803683370190505b509050600098506000975060608d905060006110046001600160a01b031663149d14d96040518163ffffffff1660e01b815260040160206040518083038186803b158015611e8a57600080fd5b505afa158015611e9e573d6000803e3d6000fd5b505050506040513d6020811015611eb457600080fd5b5051905067016345785d8a0000811115611f29577f70e72399380dcfb0338abc03dc8d47f9f470ada8e769c9a78d644ea97385ecb2604051808060200182810382526021815260200180613d546021913960400191505060405180910390a160689d5050505050505050505050505050610ead565b60005b60015481101561219c5767016345785d8a000060018281548110611f4c57fe5b906000526020600020906004020160030154106120d25760018181548110611f7057fe5b906000526020600020906004020160020160009054906101000a90046001600160a01b03168a8d81518110611fa157fe5b60200260200101906001600160a01b031690816001600160a01b03168152505060006402540be40060018381548110611fd657fe5b90600052602060002090600402016003015481611fef57fe5b0660018381548110611ffd57fe5b906000526020600020906004020160030154039050612025838261315390919063ffffffff16565b8a8e8151811061203157fe5b6020026020010181815250506001828154811061204a57fe5b906000526020600020906004020160020160009054906101000a90046001600160a01b0316888e8151811061207b57fe5b60200260200101906001600160a01b031690816001600160a01b03168152505081898e815181106120a857fe5b60209081029190910101526120c3878263ffffffff61319516565b6001909d019c96506121949050565b6000600182815481106120e157fe5b9060005260206000209060040201600301541115612194576001818154811061210657fe5b906000526020600020906004020160010160009054906101000a90046001600160a01b0316858c8151811061213757fe5b60200260200101906001600160a01b031690816001600160a01b0316815250506001818154811061216457fe5b906000526020600020906004020160030154848c8151811061218257fe5b60209081029190910101526001909a01995b600101611f2c565b50600085156125da576110046001600160a01b0316636e056520878c8c8b60025442016040518663ffffffff1660e01b815260040180806020018060200180602001856001600160401b03166001600160401b03168152602001848103845288818151815260200191508051906020019060200280838360005b8381101561222e578181015183820152602001612216565b50505050905001848103835287818151815260200191508051906020019060200280838360005b8381101561226d578181015183820152602001612255565b50505050905001848103825286818151815260200191508051906020019060200280838360005b838110156122ac578181015183820152602001612294565b505050509050019750505050505050506020604051808303818588803b1580156122d557600080fd5b505af1935050505080156122fb57506040513d60208110156122f657600080fd5b505160015b612536576040516000815260443d1015612317575060006123b2565b60046000803e60005160e01c6308c379a081146123385760009150506123b2565b60043d036004833e81513d60248201116001600160401b0382111715612363576000925050506123b2565b80830180516001600160401b038111156123845760009450505050506123b2565b8060208301013d86018111156123a2576000955050505050506123b2565b601f01601f191660405250925050505b806123bd5750612461565b60019150867fa7cdeed7d0db45e3219a6e5d60838824c16f1d39991fcfe3f963029c844bf280826040518080602001828103825283818151815260200191508051906020019080838360005b83811015612421578181015183820152602001612409565b50505050905090810190601f16801561244e5780820380516001836020036101000a031916815260200191505b509250505060405180910390a250612531565b3d80801561248b576040519150601f19603f3d011682016040523d82523d6000602084013e612490565b606091505b5060019150867fbfa884552dd8921b6ce90bfe906952ae5b3b29be0cc1a951d4f62697635a3a45826040518080602001828103825283818151815260200191508051906020019080838360005b838110156124f55781810151838201526020016124dd565b50505050905090810190601f1680156125225780820380516001836020036101000a031916815260200191505b509250505060405180910390a2505b6125da565b8015612574576040805188815290517fa217d08e65f80c73121cd9db834d81652d544bfbf452f6d04922b16c90a37b709181900360200190a16125d8565b604080516020808252601b908201527f6261746368207472616e736665722072657475726e2066616c7365000000000081830152905188917fa7cdeed7d0db45e3219a6e5d60838824c16f1d39991fcfe3f963029c844bf280919081900360600190a25b505b80156127905760005b885181101561278e5760008982815181106125fa57fe5b6020026020010151905060006001828154811061261357fe5b60009182526020909120600160049092020181015481546001600160a01b03909116916108fc918590811061264457fe5b9060005260206000209060040201600301549081150290604051600060405180830381858888f1935050505090508015612700576001828154811061268557fe5b60009182526020909120600160049092020181015481546001600160a01b03909116917f6c61d60f69a7beb3e1c80db7f39f37b208537cbb19da3174511b477812b2fc7d91859081106126d457fe5b9060005260206000209060040201600301546040518082815260200191505060405180910390a2612784565b6001828154811061270d57fe5b60009182526020909120600160049092020181015481546001600160a01b03909116917f25d0ce7d2f0cec669a8c17efe49d195c13455bb8872b65fa610ac7f53fe4ca7d918590811061275c57fe5b9060005260206000209060040201600301546040518082815260200191505060405180910390a25b50506001016125e3565b505b8451156128da5760005b85518110156128d85760008682815181106127b157fe5b60200260200101516001600160a01b03166108fc8784815181106127d157fe5b60200260200101519081150290604051600060405180830381858888f19350505050905080156128675786828151811061280757fe5b60200260200101516001600160a01b03167f6c61d60f69a7beb3e1c80db7f39f37b208537cbb19da3174511b477812b2fc7d87848151811061284557fe5b60200260200101516040518082815260200191505060405180910390a26128cf565b86828151811061287357fe5b60200260200101516001600160a01b03167f25d0ce7d2f0cec669a8c17efe49d195c13455bb8872b65fa610ac7f53fe4ca7d8784815181106128b157fe5b60200260200101516040518082815260200191505060405180910390a25b5060010161279a565b505b4715612943576040805147815290517f6ecc855f9440a9282c90913bbc91619fd44f5ec0b462af28d127b116f130aa4d9181900360200190a1604051611002904780156108fc02916000818181858888f19350505050158015612941573d6000803e3d6000fd5b505b600060035582511561295857612958836131ef565b6110016001600160a01b031663fc4333cd6040518163ffffffff1660e01b8152600401600060405180830381600087803b15801561299557600080fd5b505af11580156129a9573d6000803e3d6000fd5b50506040517fedd8d7296956dd970ab4de3f2fc03be2b0ffc615d20cd4c72c6e44f928630ebf925060009150a15060009f9e505050505050505050505050505050565b60008151600114612a4a577f70e72399380dcfb0338abc03dc8d47f9f470ada8e769c9a78d644ea97385ecb2604051808060200182810382526025815260200180613d016025913960400191505060405180910390a1506067610ead565b612a52613c5f565b82600081518110612a5f57fe5b60209081029190910181015180516001600160a01b03166000908152600490925260409091205490915080612ad05781516040516001600160a01b03909116907fe209c46bebf57cf265d5d9009a00870e256d9150f3ed5281ab9d9eb3cec6e4be90600090a2600092505050610ead565b600154600090815b81811015612b625760018181548110612aed57fe5b9060005260206000209060040201600201601c9054906101000a900460ff16158015612b4c575084600001516001600160a01b031660018281548110612b2f57fe5b60009182526020909120600490910201546001600160a01b031614155b15612b5a5760019250612b62565b600101612ad8565b5081612bac5783516040516001600160a01b03909116907fe209c46bebf57cf265d5d9009a00870e256d9150f3ed5281ab9d9eb3cec6e4be90600090a26000945050505050610ead565b6001806001850381548110612bbd57fe5b6000918252602082206002600490920201018054921515600160e01b0260ff60e01b199093169290921790915584516040516001600160a01b03909116917ff226e7d8f547ff903d9d419cf5f54e0d7d07efa9584135a53a057c5f1f27f49a91a250600095945050505050565b6000816040516020018082805190602001908083835b60208310612c5f5780518252601f199092019160209182019101612c40565b6001836020036101000a03801982511681845116808217855250505050505090500191505060405160208183030381529060405280519060200120836040516020018082805190602001908083835b60208310612ccd5780518252601f199092019160209182019101612cae565b6001836020036101000a038019825116818451168082178552505050505050905001915050604051602081830303815290604052805190602001201490505b92915050565b015190565b612d1f613c94565b506040805180820190915281518152602082810190820152919050565b612d44613c3f565b612d4d826136b6565b612d5657600080fd5b6000612d6583602001516136f0565b60208085015160408051808201909152868152920190820152915050919050565b6000612d90613c94565b505080518051602091820151919092015191011190565b612daf613c94565b612db882612d86565b612dc157600080fd5b60208201516000612dd182613753565b80830160209586015260408051808201909152908152938401919091525090919050565b805160009015801590612e0a57508151602110155b612e1357600080fd5b6000612e2283602001516136f0565b83516020808601518301805193945091849003929190831015612e4c57826020036101000a820491505b50949350505050565b6060612e60826136b6565b612e6957600080fd5b6000612e74836137ec565b9050606081604051908082528060200260200182016040528015612eb257816020015b612e9f613c94565b815260200190600190039081612e975790505b5090506000612ec485602001516136f0565b60208601510190506000805b84811015612f1b57612ee183613753565b9150604051806040016040528083815260200184815250848281518110612f0457fe5b602090810291909101015291810191600101612ed0565b509195945050505050565b612f2e613c5f565b6000612f38613c5f565b612f40613c3f565b612f4985612d3c565b90506000805b612f5883612d86565b15611b7c5780612f8357612f73612f6e84612da7565b613848565b6001600160a01b03168452612ffb565b8060011415612fab57612f98612f6e84612da7565b6001600160a01b03166020850152612ffb565b8060021415612fd357612fc0612f6e84612da7565b6001600160a01b03166040850152612ffb565b8060031415611b6f57612fe8611a8184612da7565b6001600160401b03166060850152600191505b600101612f4f565b6060612d0c61301183613862565b613948565b60608151600014156130375750604080516000815260208101909152610ead565b60608260008151811061304657fe5b602002602001015190506000600190505b83518110156130875761307d8285838151811061307057fe5b602002602001015161399a565b9150600101613057565b50610b1f61309a825160c060ff16613a17565b8261399a565b60006060815b83518110156131395760005b81811015613130578481815181106130c657fe5b6020026020010151600001516001600160a01b03168583815181106130e757fe5b6020026020010151600001516001600160a01b031614156131285760006040518060600160405280602b8152602001613caf602b9139935093505050611b85565b6001016130b2565b506001016130a6565b505060408051602081019091526000815260019150915091565b6000610b1f83836040518060400160405280601e81526020017f536166654d6174683a207375627472616374696f6e206f766572666c6f770000815250613b0f565b600082820183811015610b1f576040805162461bcd60e51b815260206004820152601b60248201527f536166654d6174683a206164646974696f6e206f766572666c6f770000000000604482015290519081900360640190fd5b600154815160005b8281101561330c576001613209613c5f565b6001838154811061321657fe5b600091825260208083206040805160c08101825260049490940290910180546001600160a01b0390811685526001820154811693850193909352600281015492831691840191909152600160a01b82046001600160401b03166060840152600160e01b90910460ff16151560808301526003015460a082015291505b848110156132e0578681815181106132a657fe5b6020026020010151600001516001600160a01b031682600001516001600160a01b031614156132d857600092506132e0565b600101613292565b5081156133025780516001600160a01b03166000908152600460205260408120555b50506001016131f7565b508082111561338157805b8281101561337f57600180548061332a57fe5b60008281526020812060046000199093019283020180546001600160a01b03199081168255600182810180549092169091556002820180546001600160e81b0319169055600390910191909155915501613317565b505b60008183106133905781613392565b825b905060005b8181101561358c576134448582815181106133ae57fe5b6020026020010151600183815481106133c357fe5b60009182526020918290206040805160c08101825260049390930290910180546001600160a01b0390811684526001820154811694840194909452600281015493841691830191909152600160a01b83046001600160401b03166060830152600160e01b90920460ff161515608082015260039091015460a0820152613ba6565b61355f57806001016004600087848151811061345c57fe5b6020026020010151600001516001600160a01b03166001600160a01b031681526020019081526020016000208190555084818151811061349857fe5b6020026020010151600182815481106134ad57fe5b6000918252602091829020835160049092020180546001600160a01b039283166001600160a01b0319918216178255928401516001820180549184169185169190911790556040840151600282018054606087015160808801511515600160e01b0260ff60e01b196001600160401b03909216600160a01b0267ffffffffffffffff60a01b1995909716929097169190911792909216939093171692909217905560a090910151600390910155613584565b60006001828154811061356e57fe5b9060005260206000209060040201600301819055505b600101613397565b50828211156136b057825b82811015610e3d5760018582815181106135ad57fe5b60209081029190910181015182546001818101855560009485528385208351600493840290910180546001600160a01b039283166001600160a01b03199182161782559585015181840180549184169188169190911790556040850151600282018054606088015160808901511515600160e01b0260ff60e01b196001600160401b03909216600160a01b0267ffffffffffffffff60a01b199590971692909a169190911792909216939093171695909517905560a0909201516003909301929092558751908401929088908590811061368357fe5b602090810291909101810151516001600160a01b0316825281019190915260400160002055600101613597565b50505050565b80516000906136c757506000610ead565b6020820151805160001a9060c08210156136e657600092505050610ead565b5060019392505050565b8051600090811a608081101561370a576000915050610ead565b60b8811080613725575060c08110801590613725575060f881105b15613734576001915050610ead565b60c08110156137485760b519019050610ead565b60f519019050610ead565b80516000908190811a608081101561376e57600191506137e5565b60b881101561378357607e19810191506137e5565b60c08110156137b05760b78103600185019450806020036101000a855104600182018101935050506137e5565b60f88110156137c55760be19810191506137e5565b60f78103600185019450806020036101000a855104600182018101935050505b5092915050565b80516000906137fd57506000610ead565b6000809050600061381184602001516136f0565b602085015185519181019250015b8082101561383f5761383082613753565b6001909301929091019061381f565b50909392505050565b805160009060151461385957600080fd5b612d0c82612df5565b604080516020808252818301909252606091829190602082018180368337505050602081018490529050600067ffffffffffffffff1984166138a6575060186138ca565b6fffffffffffffffffffffffffffffffff1984166138c6575060106138ca565b5060005b6020811015613900578181815181106138df57fe5b01602001516001600160f81b031916156138f857613900565b6001016138ca565b60008160200390506060816040519080825280601f01601f191660200182016040528015613935576020820181803683370190505b5080830196909652508452509192915050565b60608151600114801561397a5750607f60f81b8260008151811061396857fe5b01602001516001600160f81b03191611155b15613986575080610ead565b612d0c6139988351608060ff16613a17565b835b6060806040519050835180825260208201818101602087015b818310156139cb5780518352602092830192016139b3565b50855184518101855292509050808201602086015b818310156139f85780518352602092830192016139e0565b508651929092011591909101601f01601f191660405250905092915050565b6060680100000000000000008310613a67576040805162461bcd60e51b815260206004820152600e60248201526d696e70757420746f6f206c6f6e6760901b604482015290519081900360640190fd5b60408051600180825281830190925260609160208201818036833701905050905060378411613ac15782840160f81b81600081518110613aa357fe5b60200101906001600160f81b031916908160001a9053509050612d0c565b6060613acc85613862565b90508381510160370160f81b82600081518110613ae557fe5b60200101906001600160f81b031916908160001a905350613b06828261399a565b95945050505050565b60008184841115613b9e5760405162461bcd60e51b81526004018080602001828103825283818151815260200191508051906020019080838360005b83811015613b63578181015183820152602001613b4b565b50505050905090810190601f168015613b905780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b505050900390565b805182516000916001600160a01b039182169116148015613be0575081602001516001600160a01b031683602001516001600160a01b0316145b8015613c05575081604001516001600160a01b031683604001516001600160a01b0316145b8015610b1f5750506060908101519101516001600160401b0390811691161490565b60408051808201909152600081526060602082015290565b6040518060400160405280613c52613c94565b8152602001600081525090565b6040805160c081018252600080825260208201819052918101829052606081018290526080810182905260a081019190915290565b60405180604001604052806000815260200160008152509056fe6475706c696361746520636f6e73656e7375732061646472657373206f662076616c696461746f725365747468652065787069726554696d655365636f6e64476170206973206f7574206f662072616e67656c656e677468206f66206a61696c2076616c696461746f7273206d757374206265206f6e65746865206d6573736167652073656e646572206d75737420626520676f7665726e616e636520636f6e7472616374666565206973206c6172676572207468616e2044555354595f494e434f4d494e476c656e677468206f662065787069726554696d655365636f6e64476170206d69736d61746368f901b480f901b0f846941284214b9b9c85549ab3d2b972df0deef66ac2c99477f066f3fb515bb97015e4b4afddbcb25c94286b946ddf42a51534fc98d0c0a3b42c963cace8441ddf86048c27395000f84694b71b214cb885500844365e95cd9942c7276e7fd894748c284f46ab87fd492326f1e2fe731d22ad2db394d22ca3ba2141d23adab65ce4940eb7665ea2b6a786048c27395000f84694a2959d3f95eae5dc7d70144ce1b73b403b7eb6e0940ce09b38374887cb564b7efa60be130d99ed5f95948081ef03f1d9e0bb4a5bf38f16285c879299f07f86048c27395000f84694980a75ecd1309ea12fa2ed87a8744fbfc9b863d59407eecf36cf0901fefe4bc505d6ba03c7480c7b5794cc6ac05c95a99c1f7b5f88de0e3486c82293b27086048c27395000f8469435552c16704d214347f29fa77f77da6d75d7c75294f57d36e129881a3a13a024fe8072507e5b2e70f894dc4973e838e3949c77aced16ac2315dc2d7ab11186048c27395000f84694f474cf03cceff28abc65c9cbae594f725c80e12d94ddfcaedf9bb451098c9917a45f02bd61342cca6694e61a183325a18a173319dd8e19c8d069459e217586048c273950006661696c656420746f20706172736520696e69742076616c696461746f72536574746865206d6573736167652073656e646572206d7573742062652063726f737320636861696e20636f6e7472616374746865206d6573736167652073656e646572206d7573742062652074686520626c6f636b2070726f6475636572746865206d6573736167652073656e646572206d75737420626520736c61736820636f6e7472616374a26469706673582212201a362ffe5872c7b034fe0bdf76cb3980b7a822a1eb1f36e261d39b52df28597164736f6c63430006040033" - }, - "0x0000000000000000000000000000000000001001": { - "balance": "0x0", - "code": "0x608060405234801561001057600080fd5b50600436106102065760003560e01c806396713da91161011a578063c81b1662116100ad578063e1c7392a1161007c578063e1c7392a1461064d578063f9a2bbc714610655578063fc3e59081461065d578063fc4333cd14610665578063fd6a68791461066d57610206565b8063c81b16621461059f578063c8509d81146105a7578063c96be4cb1461061f578063dc927faf1461064557610206565b8063a78abc16116100e9578063a78abc16146104b5578063ab51bb96146104d1578063ac431751146104d9578063c80d4b8f1461059757610206565b806396713da9146104955780639bc8e4f21461049d5780639dc09262146104a5578063a1a11bf5146104ad57610206565b806351e806721161019d57806370fd5bad1161016c57806370fd5bad146103fb57806375d47a0a146104035780637912a65d1461040b5780637942fd0514610413578063831d65d11461041b57610206565b806351e80672146103db578063567a372d146103e357806362b72cf5146103eb5780636e47b482146103f357610206565b80633dffc387116101d95780633dffc3871461037257806343756e5c14610390578063493279b1146103b45780634bf6c882146103d357610206565b80630bee7a671461020b5780631182b8751461022c57806337c8dab914610319578063389f4f7114610358575b600080fd5b610213610675565b6040805163ffffffff9092168252519081900360200190f35b6102a46004803603604081101561024257600080fd5b60ff8235169190810190604081016020820135600160201b81111561026657600080fd5b82018360208201111561027857600080fd5b803590602001918460018302840111600160201b8311171561029957600080fd5b50909250905061067a565b6040805160208082528351818301528351919283929083019185019080838360005b838110156102de5781810151838201526020016102c6565b50505050905090810190601f16801561030b5780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b61033f6004803603602081101561032f57600080fd5b50356001600160a01b0316610709565b6040805192835260208301919091528051918290030190f35b610360610760565b60408051918252519081900360200190f35b61037a610766565b6040805160ff9092168252519081900360200190f35b61039861076b565b604080516001600160a01b039092168252519081900360200190f35b6103bc610771565b6040805161ffff9092168252519081900360200190f35b61037a610776565b61039861077b565b610360610781565b610360610787565b61039861078d565b61037a610793565b610398610798565b61036061079e565b61037a6107a3565b6104936004803603604081101561043157600080fd5b60ff8235169190810190604081016020820135600160201b81111561045557600080fd5b82018360208201111561046757600080fd5b803590602001918460018302840111600160201b8311171561048857600080fd5b5090925090506107a8565b005b61037a61087e565b610360610883565b61039861088e565b610398610894565b6104bd61089a565b604080519115158252519081900360200190f35b6102136108a3565b610493600480360360408110156104ef57600080fd5b810190602081018135600160201b81111561050957600080fd5b82018360208201111561051b57600080fd5b803590602001918460018302840111600160201b8311171561053c57600080fd5b919390929091602081019035600160201b81111561055957600080fd5b82018360208201111561056b57600080fd5b803590602001918460018302840111600160201b8311171561058c57600080fd5b5090925090506108a8565b610360610ca3565b610398610ca8565b610493600480360360408110156105bd57600080fd5b60ff8235169190810190604081016020820135600160201b8111156105e157600080fd5b8201836020820111156105f357600080fd5b803590602001918460018302840111600160201b8311171561061457600080fd5b509092509050610cae565b6104936004803603602081101561063557600080fd5b50356001600160a01b0316610cdc565b6103986110e1565b6104936110e7565b610398611158565b61037a61115e565b610493611163565b6103986112b4565b606481565b606033612000146106bc5760405162461bcd60e51b815260040180806020018281038252602f815260200180611c1a602f913960400191505060405180910390fd5b6040805162461bcd60e51b815260206004820152601e60248201527f7265636569766520756e65787065637465642073796e207061636b6167650000604482015290519081900360640190fd5b600080610714611ade565b5050506001600160a01b0316600090815260026020818152604092839020835160608101855281548082526001830154938201849052919093015460ff16151592909301919091529091565b60055481565b600181565b61100181565b606181565b600881565b61200081565b60045481565b60035481565b61100581565b600281565b61100881565b603281565b600b81565b6107b0611b01565b60006107f184848080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152506112ba92505050565b91509150801561083b5781516040805163ffffffff9092168252517f7f0956d47419b9525356e7111652b653b530ec6f5096dccc04589bc38e6299679181900360200190a1610877565b81516040805163ffffffff9092168252517f7d45f62d17443dd4547bca8a8112c60e2385669318dc300ec61a5d2492f262e79181900360200190a15b5050505050565b600981565b662386f26fc1000081565b61100781565b61100681565b60005460ff1681565b600081565b60005460ff166108fb576040805162461bcd60e51b81526020600482015260196024820152781d1a194818dbdb9d1c9858dd081b9bdd081a5b9a5d081e595d603a1b604482015290519081900360640190fd5b336110071461093b5760405162461bcd60e51b815260040180806020018281038252602e815260200180611ba5602e913960400191505060405180910390fd5b6109a684848080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250506040805180820190915260148152731b5a5cd9195b59585b9bdc951a1c995cda1bdb1960621b6020820152915061133a9050565b15610a7f57602081146109ea5760405162461bcd60e51b8152600401808060200182810382526027815260200180611b4e6027913960400191505060405180910390fd5b604080516020601f8401819004810282018101909252828152600091610a289185858083850183828082843760009201919091525061142292505050565b9050600a8110158015610a3c575060055481105b610a775760405162461bcd60e51b8152600401808060200182810382526025815260200180611bf56025913960400191505060405180910390fd5b600455610c11565b610ae584848080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152505060408051808201909152600f81526e19995b1bdb9e551a1c995cda1bdb19608a1b6020820152915061133a9050565b15610bd45760208114610b295760405162461bcd60e51b8152600401808060200182810382526022815260200180611bd36022913960400191505060405180910390fd5b604080516020601f8401819004810282018101909252828152600091610b679185858083850183828082843760009201919091525061142292505050565b9050601481118015610b7b57506103e88111155b610bcc576040805162461bcd60e51b815260206004820181905260248201527f7468652066656c6f6e795468726573686f6c64206f7574206f662072616e6765604482015290519081900360640190fd5b600555610c11565b6040805162461bcd60e51b815260206004820152600d60248201526c756e6b6e6f776e20706172616d60981b604482015290519081900360640190fd5b7f6cdb0ac70ab7f2e2d035cca5be60d89906f2dede7648ddbd7402189c1eeed17a848484846040518080602001806020018381038352878782818152602001925080828437600083820152601f01601f191690910184810383528581526020019050858580828437600083820152604051601f909101601f19169092018290039850909650505050505050a150505050565b609681565b61100281565b6040517f07db600eebe2ac176be8dcebad61858c245a4961bb32ca2aa3d159b09aa0810e90600090a1505050565b334114610d1a5760405162461bcd60e51b815260040180806020018281038252602d815260200180611c49602d913960400191505060405180910390fd5b60005460ff16610d6d576040805162461bcd60e51b81526020600482015260196024820152781d1a194818dbdb9d1c9858dd081b9bdd081a5b9a5d081e595d603a1b604482015290519081900360640190fd5b6003544311610dc3576040805162461bcd60e51b815260206004820181905260248201527f63616e206e6f7420736c61736820747769636520696e206f6e6520626c6f636b604482015290519081900360640190fd5b610dcb611ade565b506001600160a01b0381166000908152600260208181526040928390208351606081018552815481526001820154928101929092529091015460ff161580159282019290925290610e26576020810180516001019052610e7f565b60016040820181905260208201819052805480820182556000919091527fb10e2d527612073b26eecdfd717e6a320cf44b4afac2b0732d9fcbe2b7fa0cf60180546001600160a01b0319166001600160a01b0384161790555b4381526001600160a01b038216600090815260026020818152604092839020845181559084015160018201819055928401519101805460ff19169115159190911790556005549081610ecd57fe5b0661102f57604080516335409f7f60e01b81526001600160a01b03841660048201529051611000916335409f7f91602480830192600092919082900301818387803b158015610f1b57600080fd5b505af1158015610f2f573d6000803e3d6000fd5b505050506120006001600160a01b031663f7a251d7600b610f4f85611427565b60006040518463ffffffff1660e01b8152600401808460ff1660ff16815260200180602001838152602001828103825284818151815260200191508051906020019080838360005b83811015610faf578181015183820152602001610f97565b50505050905090810190601f168015610fdc5780820380516001836020036101000a031916815260200191505b50945050505050602060405180830381600087803b158015610ffd57600080fd5b505af1158015611011573d6000803e3d6000fd5b505050506040513d602081101561102757600080fd5b506110a59050565b60045481602001518161103e57fe5b066110a557604080516375abf10160e11b81526001600160a01b038416600482015290516110009163eb57e20291602480830192600092919082900301818387803b15801561108c57600080fd5b505af11580156110a0573d6000803e3d6000fd5b505050505b6040516001600160a01b038316907fddb6012116e51abf5436d956a4f0ebd927e92c576ff96d7918290c8782291e3e90600090a2505043600355565b61100381565b60005460ff161561113f576040805162461bcd60e51b815260206004820152601960248201527f74686520636f6e747261637420616c726561647920696e697400000000000000604482015290519081900360640190fd5b603260045560966005556000805460ff19166001179055565b61100081565b600381565b33611000146111a35760405162461bcd60e51b8152600401808060200182810382526030815260200180611b756030913960400191505060405180910390fd5b60005460ff166111f6576040805162461bcd60e51b81526020600482015260196024820152781d1a194818dbdb9d1c9858dd081b9bdd081a5b9a5d081e595d603a1b604482015290519081900360640190fd5b60015460005b818110156112875760026000600180848603038154811061121957fe5b60009182526020808320909101546001600160a01b031683528201929092526040018120818155600181810192909255600201805460ff1916905580548061125d57fe5b600082815260209020810160001990810180546001600160a01b03191690550190556001016111fc565b506040517fcfdb3b6ccaeccbdc68be3c59c840e3b3c90f0a7c491f5fff1cf56cfda200dd9c90600090a150565b61100481565b6112c2611b01565b60006112cc611b01565b6112d4611b13565b6112e56112e0866114f9565b61151e565b90506000805b6112f483611568565b1561132d57806113205761130f61130a84611589565b6115d7565b63ffffffff16845260019150611325565b61132d565b6001016112eb565b5091935090915050915091565b6000816040516020018082805190602001908083835b6020831061136f5780518252601f199092019160209182019101611350565b6001836020036101000a03801982511681845116808217855250505050505090500191505060405160208183030381529060405280519060200120836040516020018082805190602001908083835b602083106113dd5780518252601f1990920191602091820191016113be565b6001836020036101000a038019825116818451168082178552505050505050905001915050604051602081830303815290604052805190602001201490505b92915050565b015190565b60408051600480825260a08201909252606091829190816020015b606081526020019060019003908161144257905050905061146b836001600160a01b0316611637565b8160008151811061147857fe5b602002602001018190525061148c4361165a565b8160018151811061149957fe5b60209081029190910101526114ae606161165a565b816002815181106114bb57fe5b60200260200101819052506114cf4261165a565b816003815181106114dc57fe5b60200260200101819052506114f08161166d565b9150505b919050565b611501611b33565b506040805180820190915281518152602082810190820152919050565b611526611b13565b61152f826116f7565b61153857600080fd5b60006115478360200151611731565b60208085015160408051808201909152868152920190820152915050919050565b6000611572611b33565b505080518051602091820151919092015191011190565b611591611b33565b61159a82611568565b6115a357600080fd5b602082015160006115b382611794565b80830160209586015260408051808201909152908152938401919091525090919050565b8051600090158015906115ec57508151602110155b6115f557600080fd5b60006116048360200151611731565b8351602080860151830180519394509184900392919083101561162e57826020036101000a820491505b50949350505050565b60408051600560a21b83186014820152603481019091526060906114f08161182d565b606061141c61166883611883565b61182d565b606081516000141561168e57506040805160008152602081019091526114f4565b60608260008151811061169d57fe5b602002602001015190506000600190505b83518110156116de576116d4828583815181106116c757fe5b6020026020010151611969565b91506001016116ae565b506114f06116f1825160c060ff166119e6565b82611969565b8051600090611708575060006114f4565b6020820151805160001a9060c0821015611727576000925050506114f4565b5060019392505050565b8051600090811a608081101561174b5760009150506114f4565b60b8811080611766575060c08110801590611766575060f881105b156117755760019150506114f4565b60c08110156117895760b5190190506114f4565b60f5190190506114f4565b80516000908190811a60808110156117af5760019150611826565b60b88110156117c457607e1981019150611826565b60c08110156117f15760b78103600185019450806020036101000a85510460018201810193505050611826565b60f88110156118065760be1981019150611826565b60f78103600185019450806020036101000a855104600182018101935050505b5092915050565b60608151600114801561185f5750607f60f81b8260008151811061184d57fe5b01602001516001600160f81b03191611155b1561186b5750806114f4565b61141c61187d8351608060ff166119e6565b83611969565b604080516020808252818301909252606091829190602082018180368337505050602081018490529050600067ffffffffffffffff1984166118c7575060186118eb565b6fffffffffffffffffffffffffffffffff1984166118e7575060106118eb565b5060005b60208110156119215781818151811061190057fe5b01602001516001600160f81b0319161561191957611921565b6001016118eb565b60008160200390506060816040519080825280601f01601f191660200182016040528015611956576020820181803683370190505b5080830196909652508452509192915050565b6060806040519050835180825260208201818101602087015b8183101561199a578051835260209283019201611982565b50855184518101855292509050808201602086015b818310156119c75780518352602092830192016119af565b508651929092011591909101601f01601f191660405250905092915050565b6060680100000000000000008310611a36576040805162461bcd60e51b815260206004820152600e60248201526d696e70757420746f6f206c6f6e6760901b604482015290519081900360640190fd5b60408051600180825281830190925260609160208201818036833701905050905060378411611a905782840160f81b81600081518110611a7257fe5b60200101906001600160f81b031916908160001a905350905061141c565b6060611a9b85611883565b90508381510160370160f81b82600081518110611ab457fe5b60200101906001600160f81b031916908160001a905350611ad58282611969565b95945050505050565b604051806060016040528060008152602001600081526020016000151581525090565b60408051602081019091526000815290565b6040518060400160405280611b26611b33565b8152602001600081525090565b60405180604001604052806000815260200160008152509056fe6c656e677468206f66206d697364656d65616e6f725468726573686f6c64206d69736d61746368746865206d6573736167652073656e646572206d7573742062652076616c696461746f7253657420636f6e7472616374746865206d6573736167652073656e646572206d75737420626520676f7665726e616e636520636f6e74726163746c656e677468206f662066656c6f6e795468726573686f6c64206d69736d61746368746865206d697364656d65616e6f725468726573686f6c64206f7574206f662072616e6765746865206d6573736167652073656e646572206d7573742062652063726f737320636861696e20636f6e7472616374746865206d6573736167652073656e646572206d7573742062652074686520626c6f636b2070726f6475636572a26469706673582212203c75feabfa95d80f8670bc9249ad2a813867311d79e6a0c9e3a1233d3c2c953964736f6c63430006040033" - }, - "0x0000000000000000000000000000000000001002": { - "balance": "0x0", - "code": "0x60806040526004361061014f5760003560e01c806396713da9116100b6578063c81b16621161006f578063c81b1662146103dc578063dc927faf146103f1578063f9a2bbc714610406578063fb5478b31461041b578063fc3e590814610430578063fd6a68791461044557610193565b806396713da91461033a5780639a99b4f01461034f5780639dc0926214610388578063a1a11bf51461039d578063a78abc16146103b2578063ab51bb96146103c757610193565b806351e806721161010857806351e806721461028a5780636d70f7ae1461029f5780636e47b482146102e657806370fd5bad146102fb57806375d47a0a146103105780637942fd051461032557610193565b80630bee7a67146101985780633a0b0eff146101c65780633dffc387146101ed57806343756e5c14610218578063493279b1146102495780634bf6c8821461027557610193565b366101935734156101915760408051348152905133917f6c98249d85d88c3753a04a22230f595e4dc8d3dc86c34af35deeeedc861b89db919081900360200190a25b005b600080fd5b3480156101a457600080fd5b506101ad61045a565b6040805163ffffffff9092168252519081900360200190f35b3480156101d257600080fd5b506101db61045f565b60408051918252519081900360200190f35b3480156101f957600080fd5b50610202610465565b6040805160ff9092168252519081900360200190f35b34801561022457600080fd5b5061022d61046a565b604080516001600160a01b039092168252519081900360200190f35b34801561025557600080fd5b5061025e610470565b6040805161ffff9092168252519081900360200190f35b34801561028157600080fd5b50610202610475565b34801561029657600080fd5b5061022d61047a565b3480156102ab57600080fd5b506102d2600480360360208110156102c257600080fd5b50356001600160a01b0316610480565b604080519115158252519081900360200190f35b3480156102f257600080fd5b5061022d61049e565b34801561030757600080fd5b506102026104a4565b34801561031c57600080fd5b5061022d6104a9565b34801561033157600080fd5b506102026104af565b34801561034657600080fd5b506102026104b4565b34801561035b57600080fd5b506101db6004803603604081101561037257600080fd5b506001600160a01b0381351690602001356104b9565b34801561039457600080fd5b5061022d610664565b3480156103a957600080fd5b5061022d61066a565b3480156103be57600080fd5b506102d2610670565b3480156103d357600080fd5b506101ad610679565b3480156103e857600080fd5b5061022d61067e565b3480156103fd57600080fd5b5061022d610684565b34801561041257600080fd5b5061022d61068a565b34801561042757600080fd5b506101db610690565b34801561043c57600080fd5b5061020261069c565b34801561045157600080fd5b5061022d6106a1565b606481565b60015481565b600181565b61100181565b606181565b600881565b61200081565b6001600160a01b031660009081526002602052604090205460ff1690565b61100581565b600281565b61100881565b600b81565b600981565b6000805460ff1661053657600260208190527fe57bda0a954a7c7381b17b2c763e646ba2c60f67292d287ba583603e2c1c41668054600160ff19918216811790925561100560009081527fe25235fc0de9d7165652bef0846fefda506174abb9a190f03d0f7bcc6146dbce80548316841790559282558254161790555b3360009081526002602052604090205460ff166105845760405162461bcd60e51b815260040180806020018281038252602d8152602001806106a8602d913960400191505060405180910390fd5b60004783106105935747610595565b825b9050670de0b6b3a76400008111156105b25750670de0b6b3a76400005b8015610633576040516001600160a01b0385169082156108fc029083906000818181858888f193505050501580156105ee573d6000803e3d6000fd5b506040805182815290516001600160a01b038616917ff8b71c64315fc33b2ead2adfa487955065152a8ac33d9d5193aafd7f45dc15a0919081900360200190a261065d565b6040517fe589651933c2457488cc0d8e0941518abf748e799435e4e396d9c4d0b2db2d4d90600090a15b9392505050565b61100781565b61100681565b60005460ff1681565b600081565b61100281565b61100381565b61100081565b670de0b6b3a764000081565b600381565b6110048156fe6f6e6c79206f70657261746f7220697320617661696c61626c6520746f2063616c6c20746865206d6574686f64a26469706673582212206e40023fb74e48dfc701bcc667e0729a8491ff7ddabd668e2c6383a508bb167764736f6c63430006040033" - }, - "0x0000000000000000000000000000000000001003": { - "balance": "0x0", - "code": "0x608060405234801561001057600080fd5b50600436106102115760003560e01c8063a78abc1611610125578063dda83148116100ad578063e405bbc31161007c578063e405bbc314610681578063ea54b2aa14610689578063f9a2bbc714610691578063fc3e590814610699578063fd6a6879146106a157610211565b8063dda8314814610609578063df5fe7041461062f578063e1c7392a14610655578063e2761af01461065d57610211565b8063c81b1662116100f4578063c81b166214610534578063cba510a91461053c578063d816987914610562578063da8d08f0146105db578063dc927faf1461060157610211565b8063a78abc1614610444578063ab51bb9614610460578063ac43175114610468578063adc879e91461052c57610211565b8063564b81ef116101a857806375d47a0a1161017757806375d47a0a1461041c5780637942fd051461042457806396713da91461042c5780639dc0926214610434578063a1a11bf51461043c57610211565b8063564b81ef146102ca5780635c5ae8db146103475780636e47b4821461040c57806370fd5bad1461041457610211565b806343756e5c116101e457806343756e5c14610277578063493279b11461029b5780634bf6c882146102ba57806351e80672146102c257610211565b80630bee7a67146102165780632657e9b61461023757806333f7798d146102515780633dffc38714610259575b600080fd5b61021e6106a9565b6040805163ffffffff9092168252519081900360200190f35b61023f6106ae565b60408051918252519081900360200190f35b61023f6106b9565b6102616106bf565b6040805160ff9092168252519081900360200190f35b61027f6106c4565b604080516001600160a01b039092168252519081900360200190f35b6102a36106ca565b6040805161ffff9092168252519081900360200190f35b6102616106cf565b61027f6106d4565b6102d26106da565b6040805160208082528351818301528351919283929083019185019080838360005b8381101561030c5781810151838201526020016102f4565b50505050905090810190601f1680156103395780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b61036d6004803603602081101561035d57600080fd5b50356001600160401b03166107e6565b60405180856001600160401b03166001600160401b0316815260200184815260200183815260200180602001828103825283818151815260200191508051906020019080838360005b838110156103ce5781810151838201526020016103b6565b50505050905090810190601f1680156103fb5780820380516001836020036101000a031916815260200191505b509550505050505060405180910390f35b61027f6108a1565b6102616108a7565b61027f6108ac565b6102616108b2565b6102616108b7565b61027f6108bc565b61027f6108c2565b61044c6108c8565b604080519115158252519081900360200190f35b61021e6108d1565b61052a6004803603604081101561047e57600080fd5b81019060208101813564010000000081111561049957600080fd5b8201836020820111156104ab57600080fd5b803590602001918460018302840111640100000000831117156104cd57600080fd5b9193909290916020810190356401000000008111156104eb57600080fd5b8201836020820111156104fd57600080fd5b8035906020019184600183028401116401000000008311171561051f57600080fd5b5090925090506108d6565b005b61023f610b8f565b61027f610b95565b61023f6004803603602081101561055257600080fd5b50356001600160401b0316610b9b565b61044c6004803603604081101561057857600080fd5b81019060208101813564010000000081111561059357600080fd5b8201836020820111156105a557600080fd5b803590602001918460018302840111640100000000831117156105c757600080fd5b9193509150356001600160401b0316610bba565b61027f600480360360208110156105f157600080fd5b50356001600160401b031661139a565b61027f6113b5565b61027f6004803603602081101561061f57600080fd5b50356001600160401b03166113bb565b61044c6004803603602081101561064557600080fd5b50356001600160401b03166113df565b61052a611421565b6106656115c6565b604080516001600160401b039092168252519081900360200190f35b6106656115d5565b6102d26115eb565b61027f611608565b61026161160e565b61027f611613565b606481565b662386f26fc1000081565b60055481565b600181565b61100181565b606181565b600881565b61200081565b604080516020808252818301909252606091829190602082018180368337505060045460208301525090506000805b60208160ff16101561075057828160ff168151811061072457fe5b01602001516001600160f81b0319161561074357600190910190610748565b610750565b600101610709565b5060608160ff166040519080825280601f01601f191660200182016040528015610781576020820181803683370190505b50905060005b8260ff168160ff1610156107dd57838160ff16815181106107a457fe5b602001015160f81c60f81b828260ff16815181106107be57fe5b60200101906001600160f81b031916908160001a905350600101610787565b50925050505b90565b60016020818152600092835260409283902080548184015460028084015460038501805489516101009982161599909902600019011692909204601f81018790048702880187019098528787526001600160401b0390931696919592949091908301828280156108975780601f1061086c57610100808354040283529160200191610897565b820191906000526020600020905b81548152906001019060200180831161087a57829003601f168201915b5050505050905084565b61100581565b600281565b61100881565b600b81565b600981565b61100781565b61100681565b60005460ff1681565b600081565b60005460ff1661092d576040805162461bcd60e51b815260206004820152601960248201527f74686520636f6e7472616374206e6f7420696e69742079657400000000000000604482015290519081900360640190fd5b336110071461096d5760405162461bcd60e51b815260040180806020018281038252602e815260200180611ac5602e913960400191505060405180910390fd5b6109e184848080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152505060408051808201909152601b81527f726577617264466f7256616c696461746f725365744368616e67650000000000602082015291506116199050565b15610ac05760208114610a255760405162461bcd60e51b815260040180806020018281038252602e815260200180611a64602e913960400191505060405180910390fd5b604080516020601f8401819004810282018101909252828152600091610a639185858083850183828082843760009201919091525061170092505050565b9050600081118015610a7d5750670de0b6b3a76400008111155b610ab85760405162461bcd60e51b815260040180806020018281038252602f815260200180611af3602f913960400191505060405180910390fd5b600555610afd565b6040805162461bcd60e51b815260206004820152600d60248201526c756e6b6e6f776e20706172616d60981b604482015290519081900360640190fd5b7f6cdb0ac70ab7f2e2d035cca5be60d89906f2dede7648ddbd7402189c1eeed17a848484846040518080602001806020018381038352878782818152602001925080828437600083820152601f01601f191690910184810383528581526020019050858580828437600083820152604051601f909101601f19169092018290039850909650505050505050a150505050565b60045481565b61100281565b6001600160401b03166000908152600160208190526040909120015490565b60408051630a83aaa960e31b815233600482015290516000916110069163541d554891602480820192602092909190829003018186803b158015610bfd57600080fd5b505afa158015610c11573d6000803e3d6000fd5b505050506040513d6020811015610c2757600080fd5b5051610c7a576040805162461bcd60e51b815260206004820152601f60248201527f746865206d73672073656e646572206973206e6f7420612072656c6179657200604482015290519081900360640190fd5b6001600160401b0382166000908152600260205260409020546001600160a01b031615610cee576040805162461bcd60e51b815260206004820152601c60248201527f63616e27742073796e63206475706c6963617465642068656164657200000000604482015290519081900360640190fd5b6003546001600160401b0390811690831611610d3b5760405162461bcd60e51b8152600401808060200182810382526026815260200180611b226026913960400191505060405180910390fd5b600354600160401b90046001600160401b0316610d56611862565b6001600160401b0382811660009081526001602081815260409283902083516080810185528154909516855280830154858301526002808201548686015260038201805486516101009682161596909602600019011691909104601f81018490048402850184019095528484529093606086019392830182828015610e1c5780601f10610df157610100808354040283529160200191610e1c565b820191906000526020600020905b815481529060010190602001808311610dff57829003601f168201915b50505050508152505090505b6003546001600160401b0390811690831610610f3957836001600160401b0316826001600160401b03161015610e5d57610f39565b80516001600160401b0380821660009081526001602081815260409283902083516080810185528154909516855280830154858301526002808201548686015260038201805486516101009682161596909602600019011691909104601f8101849004840285018401909552848452959750939460608601939091830182828015610f295780601f10610efe57610100808354040283529160200191610f29565b820191906000526020600020905b815481529060010190602001808311610f0c57829003601f168201915b5050505050815250509050610e28565b6060810151516110305780516001600160401b03811660009081526001602081815260409283902060030180548451600294821615610100026000190190911693909304601f810183900483028401830190945283835293955090929190830182828015610fe85780601f10610fbd57610100808354040283529160200191610fe8565b820191906000526020600020905b815481529060010190602001808311610fcb57829003601f168201915b505050506060830182905250516110305760405162461bcd60e51b8152600401808060200182810382526021815260200180611a436021913960400191505060405180910390fd5b6000816060015151608801905060608787905082016040519080825280601f01601f19166020018201604052801561106f576020820181803683370190505b509050600061107d82611705565b905061108b8486838661170b565b6110c65760405162461bcd60e51b81526004018080602001828103825260238152602001806119406023913960400191505060405180910390fd5b6000838201915061110c8a8a8080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061177792505050565b9450905061111b818386611781565b8251602001935061112a611888565b6110008186866064600019fa61113f57600080fd5b805194506000600160f81b8616156111ce5750600554604080516309a99b4f60e41b815233600482015260248101929092525160019161100291639a99b4f0916044808201926020929091908290030181600087803b1580156111a157600080fd5b505af11580156111b5573d6000803e3d6000fd5b505050506040513d60208110156111cb57600080fd5b50505b856001600160401b0316955060208201935060006111ee858884156117c2565b90985090506001600160401b03808216908c161461123d5760405162461bcd60e51b8152600401808060200182810382526033815260200180611a926033913960400191505060405180910390fd5b6001600160401b03808c16600081815260026020818152604080842080546001600160a01b031916331790558e86168e529383526001808252928490208d518154961667ffffffffffffffff199096169590951785558c81015192850192909255918b01519183019190915560608a015180518b93926112c49260038501929101906118a7565b50506003546001600160401b03600160401b9091048116908d161115905061130c576003805467ffffffffffffffff60401b1916600160401b6001600160401b038e16021790555b7f4042c1020a8f410fb1c8859d276ab436aeb2c3074960e48467299cf1c966d3b48b8a8a602001518560405180856001600160401b03166001600160401b03168152602001846001600160401b03166001600160401b031681526020018381526020018215151515815260200194505050505060405180910390a15060019c9b505050505050505050505050565b6002602052600090815260409020546001600160a01b031681565b61100381565b6001600160401b03166000908152600260205260409020546001600160a01b031690565b6001600160401b0381166000908152600260205260408120546001600160a01b031615158061141b57506003546001600160401b038381169116145b92915050565b60005460ff1615611479576040805162461bcd60e51b815260206004820152601960248201527f74686520636f6e747261637420616c726561647920696e697400000000000000604482015290519081900360640190fd5b60008061149e60405180610100016040528060e0815260200161196360e09139611777565b815160045590925090506114b0611862565b60006114be848460006117c2565b60008083526001600160401b038281168252600160208181526040938490208651815467ffffffffffffffff191694169390931783558086015191830191909155918401516002820155606084015180519496509294508593909261152a9260038501929101906118a7565b50506003805467ffffffffffffffff19166001600160401b0384811691821767ffffffffffffffff60401b1916600160401b9290920291909117918290556000805460ff19166001179055662386f26fc10000600555602085810151604080519490931684529083015280517f5ac9b37d571677b80957ca05693f371526c602fd08042b416a29fdab7efefa499350918290030190a150505050565b6003546001600160401b031681565b600354600160401b90046001600160401b031681565b60405180610100016040528060e0815260200161196360e0913981565b61100081565b600381565b61100481565b6000816040516020018082805190602001908083835b6020831061164e5780518252601f19909201916020918201910161162f565b6001836020036101000a03801982511681845116808217855250505050505090500191505060405160208183030381529060405280519060200120836040516020018082805190602001908083835b602083106116bc5780518252601f19909201916020918201910161169d565b6001836020036101000a0380198251168184511680821785525050505050509050019150506040516020818303038152906040528051906020012014905092915050565b015190565b60200190565b60008460600151518284010392506000806117298760600151611777565b9092509050611739828683611781565b5050506040840151601f1983810191909152602090940151603f19830152605f19820192909252600454606719820152910160871990910152600190565b8051602090910191565b5b602081106117a1578251825260209283019290910190601f1901611782565b915181516020939093036101000a6000190180199091169216919091179052565b6117ca611862565b60088401516028850151604890950180519095600092916117e9611862565b6020810183905260408101829052866118545760008060688a036040519080825280601f01601f19166020018201604052801561182d576020820181803683370190505b506060840181905261183e90611777565b909250905061185160208c018383611781565b50505b989297509195505050505050565b604080516080810182526000808252602082018190529181019190915260608082015290565b6040518061100001604052806080906020820280368337509192915050565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f106118e857805160ff1916838001178555611915565b82800160010185558215611915579182015b828111156119155782518255916020019190600101906118fa565b50611921929150611925565b5090565b6107e391905b80821115611921576000815560010161192b56fe6661696c656420746f2073657269616c697a6520636f6e73656e73757320737461746542696e616e63652d436861696e2d47616e67657300000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000aea1ac326886b992a991d21a6eb155f41b77867cbf659e78f31d89d8205122a84d1be64f0e9a466c2e66a53433928192783e29f8fa21beb2133499b5ef770f60000000e8d4a5100099308aa365c40554bc89982af505d85da95251445d5dd4a9bb37dd2584fd92d3000000e8d4a5100001776920ff0b0f38d78cf95c033c21adf7045785114e392a7544179652e0a612000000e8d4a510006661696c656420746f206c6f61642076616c696461746f722073657420646174616c656e677468206f6620726577617264466f7256616c696461746f725365744368616e6765206d69736d617463686865616465722068656967687420646f65736e277420657175616c20746f207468652073706563696669656420686569676874746865206d6573736167652073656e646572206d75737420626520676f7665726e616e636520636f6e7472616374746865206e6577526577617264466f7256616c696461746f725365744368616e6765206f7574206f662072616e676563616e27742073796e6320686561646572206265666f726520696e697469616c486569676874a264697066735822122054f539d4f9624b5b87ea3b4d66b04e31a6fa9de3789af1872d4cddc7acc2a79364736f6c63430006040033" - }, - "0x0000000000000000000000000000000000001004": { - "balance": "180000000000000000000000000", - "code": "0x6080604052600436106102cd5760003560e01c80639dc0926211610175578063bd466461116100dc578063ebf71d5311610095578063fc1a598f1161006f578063fc1a598f14610c23578063fc3e59081461094e578063fd6a687914610c56578063ff9c00271461074c57610315565b8063ebf71d5314610be4578063f014847214610bf9578063f9a2bbc714610c0e57610315565b8063bd46646114610aed578063c81b166214610b20578063c8509d8114610b35578063dc6f5e901461094e578063dc927faf14610bba578063e1c7392a14610bcf57610315565b8063aa7415f51161012e578063aa7415f514610963578063ab51bb96146109aa578063ac431751146109bf578063b770186114610a8a578063b99328c514610a9f578063b9fd21e314610ad857610315565b80639dc09262146108c7578063a1a11bf5146108dc578063a496fba2146108f1578063a5cd588b14610906578063a78abc1614610939578063a7c9f02d1461094e57610315565b806361368475116102345780637942fd05116101ed5780638eff336c116101c75780638eff336c1461082557806396713da9146108645780639a854bbd146108795780639a99b4f01461088e57610315565b80637942fd051461078b578063831d65d1146107a05780638b87b21f1461056157610315565b8063613684751461031a5780636e0565201461060b5780636e47b4821461073757806370fd5bad1461074c57806371d308631461076157806375d47a0a1461077657610315565b806343756e5c1161028657806343756e5c14610576578063493279b11461058b5780634bf6c8821461031a57806350432d32146105b757806351e80672146105cc57806359b92789146105e157610315565b8063077b8f351461031a5780630bee7a67146103455780631182b87514610373578063149d14d91461046d5780633d713223146104945780633dffc3871461056157610315565b36610315573415610313576040805133815234602082015281517f6c98249d85d88c3753a04a22230f595e4dc8d3dc86c34af35deeeedc861b89db929181900390910190a15b005b600080fd5b34801561032657600080fd5b5061032f610c6b565b6040805160ff9092168252519081900360200190f35b34801561035157600080fd5b5061035a610c70565b6040805163ffffffff9092168252519081900360200190f35b34801561037f57600080fd5b506103f86004803603604081101561039657600080fd5b60ff8235169190810190604081016020820135600160201b8111156103ba57600080fd5b8201836020820111156103cc57600080fd5b803590602001918460018302840111600160201b831117156103ed57600080fd5b509092509050610c75565b6040805160208082528351818301528351919283929083019185019080838360005b8381101561043257818101518382015260200161041a565b50505050905090810190601f16801561045f5780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b34801561047957600080fd5b50610482610da3565b60408051918252519081900360200190f35b3480156104a057600080fd5b50610545600480360360208110156104b757600080fd5b810190602081018135600160201b8111156104d157600080fd5b8201836020820111156104e357600080fd5b803590602001918460018302840111600160201b8311171561050457600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250929550610da9945050505050565b604080516001600160a01b039092168252519081900360200190f35b34801561056d57600080fd5b5061032f610dcd565b34801561058257600080fd5b50610545610dd2565b34801561059757600080fd5b506105a0610dd8565b6040805161ffff9092168252519081900360200190f35b3480156105c357600080fd5b50610482610ddd565b3480156105d857600080fd5b50610545610de8565b3480156105ed57600080fd5b506105456004803603602081101561060457600080fd5b5035610dee565b6107236004803603608081101561062157600080fd5b810190602081018135600160201b81111561063b57600080fd5b82018360208201111561064d57600080fd5b803590602001918460208302840111600160201b8311171561066e57600080fd5b919390929091602081019035600160201b81111561068b57600080fd5b82018360208201111561069d57600080fd5b803590602001918460208302840111600160201b831117156106be57600080fd5b919390929091602081019035600160201b8111156106db57600080fd5b8201836020820111156106ed57600080fd5b803590602001918460208302840111600160201b8311171561070e57600080fd5b91935091503567ffffffffffffffff16610e09565b604080519115158252519081900360200190f35b34801561074357600080fd5b506105456112f1565b34801561075857600080fd5b5061032f6112f7565b34801561076d57600080fd5b506104826112fc565b34801561078257600080fd5b50610545611302565b34801561079757600080fd5b5061032f611308565b3480156107ac57600080fd5b50610313600480360360408110156107c357600080fd5b60ff8235169190810190604081016020820135600160201b8111156107e757600080fd5b8201836020820111156107f957600080fd5b803590602001918460018302840111600160201b8311171561081a57600080fd5b50909250905061130d565b34801561083157600080fd5b506103136004803603606081101561084857600080fd5b508035906001600160a01b036020820135169060400135611456565b34801561087057600080fd5b5061032f6114dc565b34801561088557600080fd5b506104826114e1565b34801561089a57600080fd5b50610482600480360360408110156108b157600080fd5b506001600160a01b0381351690602001356114ed565b3480156108d357600080fd5b50610545611611565b3480156108e857600080fd5b50610545611617565b3480156108fd57600080fd5b5061032f61161d565b34801561091257600080fd5b506104826004803603602081101561092957600080fd5b50356001600160a01b0316611622565b34801561094557600080fd5b50610723611634565b34801561095a57600080fd5b5061032f61163d565b6107236004803603608081101561097957600080fd5b5080356001600160a01b03908116916020810135909116906040810135906060013567ffffffffffffffff16611642565b3480156109b657600080fd5b5061035a61161d565b3480156109cb57600080fd5b50610313600480360360408110156109e257600080fd5b810190602081018135600160201b8111156109fc57600080fd5b820183602082011115610a0e57600080fd5b803590602001918460018302840111600160201b83111715610a2f57600080fd5b919390929091602081019035600160201b811115610a4c57600080fd5b820183602082011115610a5e57600080fd5b803590602001918460018302840111600160201b83111715610a7f57600080fd5b509092509050611d16565b348015610a9657600080fd5b50610482611f85565b348015610aab57600080fd5b5061031360048036036040811015610ac257600080fd5b50803590602001356001600160a01b0316611f8b565b348015610ae457600080fd5b50610482612001565b348015610af957600080fd5b5061048260048036036020811015610b1057600080fd5b50356001600160a01b031661200b565b348015610b2c57600080fd5b50610545612026565b348015610b4157600080fd5b5061031360048036036040811015610b5857600080fd5b60ff8235169190810190604081016020820135600160201b811115610b7c57600080fd5b820183602082011115610b8e57600080fd5b803590602001918460018302840111600160201b83111715610baf57600080fd5b50909250905061202c565b348015610bc657600080fd5b506105456120fc565b348015610bdb57600080fd5b50610313612102565b348015610bf057600080fd5b5061032f6121a2565b348015610c0557600080fd5b5061032f6121a7565b348015610c1a57600080fd5b506105456121ac565b348015610c2f57600080fd5b506103f860048036036020811015610c4657600080fd5b50356001600160a01b03166121b2565b348015610c6257600080fd5b506105456122d9565b600881565b606481565b60005460609060ff16610cbd576040805162461bcd60e51b815260206004820152601960248201526000805160206145c7833981519152604482015290519081900360640190fd5b3361200014610cfd5760405162461bcd60e51b815260040180806020018281038252602f815260200180614575602f913960400191505060405180910390fd5b60ff841660021415610d4f57610d4883838080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152506122df92505050565b9050610d9c565b6040805162461bcd60e51b815260206004820152601860248201527f756e7265636f676e697a65642073796e207061636b6167650000000000000000604482015290519081900360640190fd5b9392505050565b60015490565b6020818101516000908152600490915260409020546001600160a01b03165b919050565b600181565b61100181565b606181565b662386f26fc1000081565b61200081565b6000908152600460205260409020546001600160a01b031690565b6000805460ff16610e4f576040805162461bcd60e51b815260206004820152601960248201526000805160206145c7833981519152604482015290519081900360640190fd5b868514610e8d5760405162461bcd60e51b815260040180806020018281038252603b81526020018061453a603b913960400191505060405180910390fd5b868314610ecb5760405162461bcd60e51b815260040180806020018281038252603f81526020018061440d603f913960400191505060405180910390fd5b426078018267ffffffffffffffff161015610f175760405162461bcd60e51b81526004018080602001828103825260248152602001806142fd6024913960400191505060405180910390fd5b6402540be400340615610f5b5760405162461bcd60e51b815260040180806020018281038252604081526020018061463d6040913960400191505060405180910390fd5b60408051868152602080880282010190915285906000908190606090848015610f8e578160200160208202803683370190505b50905060005b84811015611069576402540be4008b8b83818110610fae57fe5b9050602002013581610fbc57fe5b0615610ff95760405162461bcd60e51b815260040180806020018281038252603c81526020018061444c603c913960400191505060405180910390fd5b61101e8b8b8381811061100857fe5b905060200201358561240390919063ffffffff16565b935061104a6402540be4008c8c8481811061103557fe5b9050602002013561245d90919063ffffffff16565b82828151811061105657fe5b6020908102919091010152600101610f94565b5060015461108e90611081908663ffffffff61249f16565b849063ffffffff61240316565b3410156110cc5760405162461bcd60e51b81526004018080602001828103825260568152602001806145e76056913960600191505060405180910390fd5b6110dc348463ffffffff6124f816565b91506110e6614156565b6040518060c001604052806221272160e91b60001b815260200160006001600160a01b031681526020018381526020018e8e808060200260200160405190810160405280939291908181526020018383602002808284376000920191909152505050908252506040805160208c810282810182019093528c82529283019290918d918d91829185019084908082843760009201919091525050509082525067ffffffffffffffff8916602090910152905061200063f7a251d760036111aa8461253a565b6111bf876402540be40063ffffffff61245d16565b6040518463ffffffff1660e01b8152600401808460ff1660ff16815260200180602001838152602001828103825284818151815260200191508051906020019080838360005b8381101561121d578181015183820152602001611205565b50505050905090810190601f16801561124a5780820380516001836020036101000a031916815260200191505b50945050505050602060405180830381600087803b15801561126b57600080fd5b505af115801561127f573d6000803e3d6000fd5b505050506040513d602081101561129557600080fd5b505060408051600081523360208201528082018690526060810185905290517f74eab09b0e53aefc23f2e1b16da593f95c2dd49c6f5a23720463d10d9c330b2a9181900360800190a15060019c9b505050505050505050505050565b61100581565b600281565b60015481565b61100881565b600b81565b60005460ff16611352576040805162461bcd60e51b815260206004820152601960248201526000805160206145c7833981519152604482015290519081900360640190fd5b33612000146113925760405162461bcd60e51b815260040180806020018281038252602f815260200180614575602f913960400191505060405180910390fd5b60ff8316600314156113e2576113dd82828080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152506127f592505050565b611451565b7f41ce201247b6ceb957dcdb217d0b8acb50b9ea0e12af9af4f5e7f38902101605838383604051808460ff1660ff168152602001806020018281038252848482818152602001925080828437600083820152604051601f909101601f1916909201829003965090945050505050a15b505050565b33611008146114965760405162461bcd60e51b81526004018080602001828103825260238152602001806145a46023913960400191505060405180910390fd5b600083815260046020908152604080832080546001600160a01b039096166001600160a01b03199096168617905593825260038152838220949094556002909352912055565b600981565b677ce66c50e284000081565b6000805460ff16611533576040805162461bcd60e51b815260206004820152601960248201526000805160206145c7833981519152604482015290519081900360640190fd5b33611005146115735760405162461bcd60e51b815260040180806020018281038252602f815260200180614270602f913960400191505060405180910390fd5b60004783106115825747611584565b825b90508015611608576040516001600160a01b0385169082156108fc029083906000818181858888f193505050501580156115c2573d6000803e3d6000fd5b50604080516001600160a01b03861681526020810183905281517ff8b71c64315fc33b2ead2adfa487955065152a8ac33d9d5193aafd7f45dc15a0929181900390910190a15b90505b92915050565b61100781565b61100681565b600081565b60026020526000908152604090205481565b60005460ff1681565b600381565b6000805460ff16611688576040805162461bcd60e51b815260206004820152601960248201526000805160206145c7833981519152604482015290519081900360640190fd5b426078018267ffffffffffffffff1610156116d45760405162461bcd60e51b81526004018080602001828103825260248152602001806142fd6024913960400191505060405180910390fd5b6402540be4003406156117185760405162461bcd60e51b815260040180806020018281038252604081526020018061463d6040913960400191505060405180910390fd5b600080806001600160a01b0388166117f75760015461173e90879063ffffffff61240316565b34101561177c5760405162461bcd60e51b81526004018080602001828103825260618152602001806143876061913960800191505060405180910390fd5b6402540be4008606156117c05760405162461bcd60e51b815260040180806020018281038252603c81526020018061444c603c913960400191505060405180910390fd5b6117d0348763ffffffff6124f816565b90506117e7866402540be40063ffffffff61245d16565b6221272160e91b93509150611a9a565b6001600160a01b03881660009081526003602052604090205492508261184e5760405162461bcd60e51b81526004018080602001828103825260318152602001806143566031913960400191505060405180910390fd5b60015434101561188f5760405162461bcd60e51b815260040180806020018281038252603f8152602001806144a9603f913960400191505060405180910390fd5b506001600160a01b03871660009081526002602052604090205434906008811115806118da57506008811180156118da57506118d8876007198301600a0a63ffffffff61285116565b155b6119155760405162461bcd60e51b815260040180806020018281038252603c81526020018061444c603c913960400191505060405180910390fd5b61191f8782612893565b925061192a846128d3565b15611972576305f5e1008310156119725760405162461bcd60e51b815260040180806020018281038252603a81526020018061429f603a913960400191505060405180910390fd5b60088110158061198c575060088110801561198c57508683115b6119c75760405162461bcd60e51b81526004018080602001828103825260258152602001806143e86025913960400191505060405180910390fd5b677ce66c50e2840000831115611a0e5760405162461bcd60e51b81526004018080602001828103825260358152602001806143216035913960400191505060405180910390fd5b604080516323b872dd60e01b81523360048201523060248201526044810189905290516001600160a01b038b16916323b872dd9160648083019260209291908290030181600087803b158015611a6357600080fd5b505af1158015611a77573d6000803e3d6000fd5b505050506040513d6020811015611a8d57600080fd5b5051611a9857600080fd5b505b611aa2614156565b6040805160c0810182528581526001600160a01b038b166020820152815160018082528184018452919283019181602001602082028036833750505081526040805160018082528183019092526020928301929091908083019080368337505050815260408051600180825281830190925260209283019290919080830190803683370190505081526020018767ffffffffffffffff168152509050828160400151600081518110611b5057fe5b602002602001018181525050878160600151600081518110611b6e57fe5b60200260200101906001600160a01b031690816001600160a01b031681525050338160800151600081518110611ba057fe5b6001600160a01b039092166020928302919091019091015261200063f7a251d76003611bcb8461253a565b611be0866402540be40063ffffffff61245d16565b6040518463ffffffff1660e01b8152600401808460ff1660ff16815260200180602001838152602001828103825284818151815260200191508051906020019080838360005b83811015611c3e578181015183820152602001611c26565b50505050905090810190601f168015611c6b5780820380516001836020036101000a031916815260200191505b50945050505050602060405180830381600087803b158015611c8c57600080fd5b505af1158015611ca0573d6000803e3d6000fd5b505050506040513d6020811015611cb657600080fd5b5050604080516001600160a01b038b1681523360208201528082018990526060810184905290517f74eab09b0e53aefc23f2e1b16da593f95c2dd49c6f5a23720463d10d9c330b2a9181900360800190a150600198975050505050505050565b3361100714611d565760405162461bcd60e51b815260040180806020018281038252602e8152602001806144e8602e913960400191505060405180910390fd5b60208114611dab576040805162461bcd60e51b815260206004820152601b60248201527f65787065637465642076616c7565206c656e6774682069732033320000000000604482015290519081900360640190fd5b606084848080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525050604080516020601f8801819004810282018101909252868152939450606093925086915085908190840183828082843760009201919091525050505060208301519091506772656c617946656560c01b811415611eb3576020820151670de0b6b3a76400008111158015611e5a57506402540be4008106155b611eab576040805162461bcd60e51b815260206004820152601960248201527f7468652072656c6179466565206f7574206f662072616e676500000000000000604482015290519081900360640190fd5b600155611ef0565b6040805162461bcd60e51b815260206004820152600d60248201526c756e6b6e6f776e20706172616d60981b604482015290519081900360640190fd5b7f6cdb0ac70ab7f2e2d035cca5be60d89906f2dede7648ddbd7402189c1eeed17a878787876040518080602001806020018381038352878782818152602001925080828437600083820152601f01601f191690910184810383528581526020019050858580828437600083820152604051601f909101601f19169092018290039850909650505050505050a150505050505050565b61c35081565b3361100814611fcb5760405162461bcd60e51b81526004018080602001828103825260238152602001806145a46023913960400191505060405180910390fd5b600091825260046020908152604080842080546001600160a01b03191690556001600160a01b0392909216835260039052812055565b6221272160e91b81565b6001600160a01b031660009081526003602052604090205490565b61100281565b60005460ff16612071576040805162461bcd60e51b815260206004820152601960248201526000805160206145c7833981519152604482015290519081900360640190fd5b33612000146120b15760405162461bcd60e51b815260040180806020018281038252602f815260200180614575602f913960400191505060405180910390fd5b60ff8316600314156113e2576113dd82828080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152506129d992505050565b61100381565b60005460ff161561215a576040805162461bcd60e51b815260206004820152601960248201527f74686520636f6e747261637420616c726561647920696e697400000000000000604482015290519081900360640190fd5b662386f26fc1000060019081556000808052600260205260127fac33ff75c19e70fe83507db0d683fd3465c996598dc972688b7ace676c89077b55805460ff19169091179055565b600481565b600581565b61100081565b6001600160a01b03811660009081526003602090815260409182902054825182815280840190935260609290918391906020820181803683375050506020810183905290506000805b60208160ff16101561224257828160ff168151811061221657fe5b01602001516001600160f81b031916156122355760019091019061223a565b612242565b6001016121fb565b5060608160ff166040519080825280601f01601f191660200182016040528015612273576020820181803683370190505b50905060005b8260ff168160ff1610156122cf57838160ff168151811061229657fe5b602001015160f81c60f81b828260ff16815181106122b057fe5b60200101906001600160f81b031916908160001a905350600101612279565b5095945050505050565b61100481565b60606122e96141a2565b60006122f484612ad7565b915091508061234a576040805162461bcd60e51b815260206004820152601f60248201527f756e7265636f676e697a6564207472616e73666572496e207061636b61676500604482015290519081900360640190fd5b600061235583612c16565b905063ffffffff8116156123e9576040808401516020808601516001600160a01b031660009081526002909152918220546123909190612893565b905061239a6141d7565b60405180608001604052808660000151815260200183815260200186608001516001600160a01b031681526020018463ffffffff1681525090506123dd81612f2e565b95505050505050610dc8565b50506040805160008152602081019091529150610dc89050565b600082820183811015611608576040805162461bcd60e51b815260206004820152601b60248201527f536166654d6174683a206164646974696f6e206f766572666c6f770000000000604482015290519081900360640190fd5b600061160883836040518060400160405280601a81526020017f536166654d6174683a206469766973696f6e206279207a65726f00000000000081525061300a565b6000826124ae5750600061160b565b828202828482816124bb57fe5b04146116085760405162461bcd60e51b81526004018080602001828103825260218152602001806144886021913960400191505060405180910390fd5b600061160883836040518060400160405280601e81526020017f536166654d6174683a207375627472616374696f6e206f766572666c6f7700008152506130ac565b60408051600680825260e08201909252606091829190816020015b6060815260200190600190039081612555575050835190915061257790613106565b8160008151811061258457fe5b60200260200101819052506125a583602001516001600160a01b0316613119565b816001815181106125b257fe5b6020026020010181905250600083604001515190506060816040519080825280602002602001820160405280156125fd57816020015b60608152602001906001900390816125e85790505b50905060005b8281101561264a5761262b8660400151828151811061261e57fe5b6020026020010151613106565b82828151811061263757fe5b6020908102919091010152600101612603565b506126548161313c565b8360028151811061266157fe5b60200260200101819052506060826040519080825280602002602001820160405280156126a257816020015b606081526020019060019003908161268d5790505b50905060005b838110156126f8576126d9876060015182815181106126c357fe5b60200260200101516001600160a01b0316613119565b8282815181106126e557fe5b60209081029190910101526001016126a8565b506127028161313c565b8460038151811061270f57fe5b602002602001018190525060608360405190808252806020026020018201604052801561275057816020015b606081526020019060019003908161273b5790505b50905060005b8481101561279057612771886080015182815181106126c357fe5b82828151811061277d57fe5b6020908102919091010152600101612756565b5061279a8161313c565b856004815181106127a757fe5b60200260200101819052506127c98760a0015167ffffffffffffffff16613106565b856005815181106127d657fe5b60200260200101819052506127ea8561313c565b979650505050505050565b6127fd6141fe565b6000612808836131c6565b91509150806128485760405162461bcd60e51b81526004018080602001828103825260248152602001806145166024913960400191505060405180910390fd5b61145182613391565b600061160883836040518060400160405280601881526020017f536166654d6174683a206d6f64756c6f206279207a65726f00000000000000008152506137e2565b600060088211156128bc576128b5836007198401600a0a63ffffffff61245d16565b905061160b565b611608836008849003600a0a63ffffffff61249f16565b604080516020808252818301909252600091606091906020820181803683375050506020810184905290506000805b60208160ff16101561294957828160ff168151811061291d57fe5b01602001516001600160f81b0319161561293c57600190910190612941565b612949565b600101612902565b50600860ff8216101561296157600092505050610dc8565b816005820360ff168151811061297357fe5b6020910101516001600160f81b031916602d60f81b1461299857600092505050610dc8565b816001820360ff16815181106129aa57fe5b6020910101516001600160f81b031916604d60f81b146129cf57600092505050610dc8565b5060019392505050565b6129e1614156565b60006129ec83613844565b9150915080612a2c5760405162461bcd60e51b81526004018080602001828103825260248152602001806142d96024913960400191505060405180910390fd5b612a346141fe565b602080840180516001600160a01b0390811684526040808701518585015291511660009081526002909252812054905b846040015151811015612ab557612a9285604001518281518110612a8457fe5b602002602001015183613abf565b85604001518281518110612aa257fe5b6020908102919091010152600101612a64565b506080840151604083015260056060830152612ad082613391565b5050505050565b612adf6141a2565b6000612ae96141a2565b612af1614235565b612b02612afd86613af8565b613b1d565b90506000805b612b1183613b67565b15612c095780612b3357612b2c612b2784613b88565b613bd6565b8452612c01565b8060011415612b6057612b4d612b4884613b88565b613c36565b6001600160a01b03166020850152612c01565b8060021415612b7f57612b75612b2784613b88565b6040850152612c01565b8060031415612ba757612b94612b4884613b88565b6001600160a01b03166060850152612c01565b8060041415612bcf57612bbc612b4884613b88565b6001600160a01b03166080850152612c01565b8060051415612bfc57612be4612b2784613b88565b67ffffffffffffffff1660a085015260019150612c01565b612c09565b600101612b08565b5091935090915050915091565b60208101516000906001600160a01b0316612d18578160a0015167ffffffffffffffff16421115612c4957506001610dc8565b8160400151471015612c5d57506003610dc8565b81606001516001600160a01b03166108fc83604001519081150290604051600060405180830381858888f19350505050612c9957506004610dc8565b7f471eb9cc1ffe55ffadf15b32595415eb9d80f22e761d24bd6dffc607e1284d5982602001518360600151846040015160405180846001600160a01b03166001600160a01b03168152602001836001600160a01b03166001600160a01b03168152602001828152602001935050505060405180910390a1506000610dc8565b8160a0015167ffffffffffffffff16421115612d3657506001610dc8565b81516020808401516001600160a01b031660009081526003909152604090205414612d6357506002610dc8565b602080830151604080516370a0823160e01b815230600482015290516000936001600160a01b03909316926370a082319261c3509260248083019392829003018187803b158015612db357600080fd5b5086fa158015612dc7573d6000803e3d6000fd5b50505050506040513d6020811015612dde57600080fd5b50516040840151909150811015612df9575060039050610dc8565b600083602001516001600160a01b031663a9059cbb61c350866060015187604001516040518463ffffffff1660e01b815260040180836001600160a01b03166001600160a01b0316815260200182815260200192505050602060405180830381600088803b158015612e6a57600080fd5b5087f1158015612e7e573d6000803e3d6000fd5b50505050506040513d6020811015612e9557600080fd5b505190508015612f22577f471eb9cc1ffe55ffadf15b32595415eb9d80f22e761d24bd6dffc607e1284d5984602001518560600151866040015160405180846001600160a01b03166001600160a01b03168152602001836001600160a01b03166001600160a01b03168152602001828152602001935050505060405180910390a15060009150610dc89050565b5060059150610dc89050565b60408051600480825260a08201909252606091829190816020015b6060815260200190600190039081612f495750508351909150612f6b90613106565b81600081518110612f7857fe5b6020026020010181905250612f908360200151613106565b81600181518110612f9d57fe5b6020026020010181905250612fbe83604001516001600160a01b0316613119565b81600281518110612fcb57fe5b6020026020010181905250612fe9836060015163ffffffff16613106565b81600381518110612ff657fe5b6020026020010181905250610d9c8161313c565b600081836130965760405162461bcd60e51b81526004018080602001828103825283818151815260200191508051906020019080838360005b8381101561305b578181015183820152602001613043565b50505050905090810190601f1680156130885780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b5060008385816130a257fe5b0495945050505050565b600081848411156130fe5760405162461bcd60e51b815260206004820181815283516024840152835190928392604490910191908501908083836000831561305b578181015183820152602001613043565b505050900390565b606061160b61311483613c50565b613d36565b60408051600560a21b8318601482015260348101909152606090610d9c81613d36565b606081516000141561315d5750604080516000815260208101909152610dc8565b60608260008151811061316c57fe5b602002602001015190506000600190505b83518110156131ad576131a38285838151811061319657fe5b6020026020010151613d88565b915060010161317d565b50610d9c6131c0825160c060ff16613e05565b82613d88565b6131ce6141fe565b60006131d86141fe565b6131e0614235565b6131ec612afd86613af8565b90506000805b6131fb83613b67565b15612c09578061322157613211612b4884613b88565b6001600160a01b03168452613389565b80600114156132c257606061323d61323885613b88565b613efd565b9050805160405190808252806020026020018201604052801561326a578160200160208202803683370190505b50602086015260005b81518110156132bb5761329882828151811061328b57fe5b6020026020010151613bd6565b866020015182815181106132a857fe5b6020908102919091010152600101613273565b5050613389565b80600214156133645760606132d961323885613b88565b90508051604051908082528060200260200182016040528015613306578160200160208202803683370190505b50604086015260005b81518110156132bb5761333482828151811061332757fe5b6020026020010151613c36565b8660400151828151811061334457fe5b6001600160a01b039092166020928302919091019091015260010161330f565b8060031415612bfc57613379612b2784613b88565b63ffffffff166060850152600191505b6001016131f2565b80516001600160a01b03166135885760005b81602001515181101561358257816040015181815181106133c057fe5b60200260200101516001600160a01b03166108fc836020015183815181106133e457fe5b60200260200101519081150290604051600060405180830381858888f193505050506134c4577f203f9f67a785f4f81be4d48b109aa0c498d1bc8097ecc2627063f480cc5fe73e82600001518360400151838151811061344057fe5b60200260200101518460200151848151811061345857fe5b6020026020010151856060015160405180856001600160a01b03166001600160a01b03168152602001846001600160a01b03166001600160a01b031681526020018381526020018263ffffffff1663ffffffff16815260200194505050505060405180910390a161357a565b7fd468d4fa5e8fb4adc119b29a983fd0785e04af5cb8b7a3a69a47270c54b6901a8260000151836040015183815181106134fa57fe5b60200260200101518460200151848151811061351257fe5b6020026020010151856060015160405180856001600160a01b03166001600160a01b03168152602001846001600160a01b03166001600160a01b031681526020018381526020018263ffffffff1663ffffffff16815260200194505050505060405180910390a15b6001016133a3565b506137df565b60005b8160200151518110156137dd57600082600001516001600160a01b031663a9059cbb61c350856040015185815181106135c057fe5b6020026020010151866020015186815181106135d857fe5b60200260200101516040518463ffffffff1660e01b815260040180836001600160a01b03166001600160a01b0316815260200182815260200192505050602060405180830381600088803b15801561362f57600080fd5b5087f1158015613643573d6000803e3d6000fd5b50505050506040513d602081101561365a57600080fd5b50519050801561371e577fd468d4fa5e8fb4adc119b29a983fd0785e04af5cb8b7a3a69a47270c54b6901a83600001518460400151848151811061369a57fe5b6020026020010151856020015185815181106136b257fe5b6020026020010151866060015160405180856001600160a01b03166001600160a01b03168152602001846001600160a01b03166001600160a01b031681526020018381526020018263ffffffff1663ffffffff16815260200194505050505060405180910390a16137d4565b7f203f9f67a785f4f81be4d48b109aa0c498d1bc8097ecc2627063f480cc5fe73e83600001518460400151848151811061375457fe5b60200260200101518560200151858151811061376c57fe5b6020026020010151866060015160405180856001600160a01b03166001600160a01b03168152602001846001600160a01b03166001600160a01b031681526020018381526020018263ffffffff1663ffffffff16815260200194505050505060405180910390a15b5060010161358b565b505b50565b600081836138315760405162461bcd60e51b815260206004820181815283516024840152835190928392604490910191908501908083836000831561305b578181015183820152602001613043565b5082848161383b57fe5b06949350505050565b61384c614156565b6000613856614156565b61385e614235565b61386a612afd86613af8565b90506000805b61387983613b67565b15613ab157806138965761388f612b2784613b88565b8452613aa9565b80600114156138be576138ab612b4884613b88565b6001600160a01b03166020850152613aa9565b806002141561394d5760606138d561323885613b88565b90508051604051908082528060200260200182016040528015613902578160200160208202803683370190505b50604086015260005b81518110156139465761392382828151811061328b57fe5b8660400151828151811061393357fe5b602090810291909101015260010161390b565b5050613aa9565b80600314156139e257606061396461323885613b88565b90508051604051908082528060200260200182016040528015613991578160200160208202803683370190505b50606086015260005b8151811015613946576139b282828151811061332757fe5b866060015182815181106139c257fe5b6001600160a01b039092166020928302919091019091015260010161399a565b8060041415613a775760606139f961323885613b88565b90508051604051908082528060200260200182016040528015613a26578160200160208202803683370190505b50608086015260005b815181101561394657613a4782828151811061332757fe5b86608001518281518110613a5757fe5b6001600160a01b0390921660209283029190910190910152600101613a2f565b8060051415613aa457613a8c612b2784613b88565b67ffffffffffffffff1660a085015260019150613aa9565b613ab1565b600101613870565b509195600195509350505050565b60006008821115613ae1576128b5836007198401600a0a63ffffffff61249f16565b611608836008849003600a0a63ffffffff61245d16565b613b00614255565b506040805180820190915281518152602082810190820152919050565b613b25614235565b613b2e82613fce565b613b3757600080fd5b6000613b468360200151613ffe565b60208085015160408051808201909152868152920190820152915050919050565b6000613b71614255565b505080518051602091820151919092015191011190565b613b90614255565b613b9982613b67565b613ba257600080fd5b60208201516000613bb282614061565b80830160209586015260408051808201909152908152938401919091525090919050565b805160009015801590613beb57508151602110155b613bf457600080fd5b6000613c038360200151613ffe565b83516020808601518301805193945091849003929190831015613c2d57826020036101000a820491505b50949350505050565b8051600090601514613c4757600080fd5b61160b82613bd6565b604080516020808252818301909252606091829190602082018180368337505050602081018490529050600067ffffffffffffffff198416613c9457506018613cb8565b6fffffffffffffffffffffffffffffffff198416613cb457506010613cb8565b5060005b6020811015613cee57818181518110613ccd57fe5b01602001516001600160f81b03191615613ce657613cee565b600101613cb8565b60008160200390506060816040519080825280601f01601f191660200182016040528015613d23576020820181803683370190505b5080830196909652508452509192915050565b606081516001148015613d685750607f60f81b82600081518110613d5657fe5b01602001516001600160f81b03191611155b15613d74575080610dc8565b61160b613d868351608060ff16613e05565b835b6060806040519050835180825260208201818101602087015b81831015613db9578051835260209283019201613da1565b50855184518101855292509050808201602086015b81831015613de6578051835260209283019201613dce565b508651929092011591909101601f01601f191660405250905092915050565b6060680100000000000000008310613e55576040805162461bcd60e51b815260206004820152600e60248201526d696e70757420746f6f206c6f6e6760901b604482015290519081900360640190fd5b60408051600180825281830190925260609160208201818036833701905050905060378411613eaf5782840160f81b81600081518110613e9157fe5b60200101906001600160f81b031916908160001a905350905061160b565b6060613eba85613c50565b90508381510160370160f81b82600081518110613ed357fe5b60200101906001600160f81b031916908160001a905350613ef48282613d88565b95945050505050565b6060613f0882613fce565b613f1157600080fd5b6000613f1c836140fa565b9050606081604051908082528060200260200182016040528015613f5a57816020015b613f47614255565b815260200190600190039081613f3f5790505b5090506000613f6c8560200151613ffe565b60208601510190506000805b84811015613fc357613f8983614061565b9150604051806040016040528083815260200184815250848281518110613fac57fe5b602090810291909101015291810191600101613f78565b509195945050505050565b8051600090613fdf57506000610dc8565b6020820151805160001a9060c08210156129cf57600092505050610dc8565b8051600090811a6080811015614018576000915050610dc8565b60b8811080614033575060c08110801590614033575060f881105b15614042576001915050610dc8565b60c08110156140565760b519019050610dc8565b60f519019050610dc8565b80516000908190811a608081101561407c57600191506140f3565b60b881101561409157607e19810191506140f3565b60c08110156140be5760b78103600185019450806020036101000a855104600182018101935050506140f3565b60f88110156140d35760be19810191506140f3565b60f78103600185019450806020036101000a855104600182018101935050505b5092915050565b805160009061410b57506000610dc8565b6000809050600061411f8460200151613ffe565b602085015185519181019250015b8082101561414d5761413e82614061565b6001909301929091019061412d565b50909392505050565b6040518060c001604052806000801916815260200160006001600160a01b03168152602001606081526020016060815260200160608152602001600067ffffffffffffffff1681525090565b6040805160c081018252600080825260208201819052918101829052606081018290526080810182905260a081019190915290565b60408051608081018252600080825260208201819052918101829052606081019190915290565b604051806080016040528060006001600160a01b031681526020016060815260200160608152602001600063ffffffff1681525090565b6040518060400160405280614248614255565b8152602001600081525090565b60405180604001604052806000815260200160008152509056fe746865206d6573736167652073656e646572206d75737420626520696e63656e746976697a6520636f6e7472616374466f72206d696e69546f6b656e2c20746865207472616e7366657220616d6f756e74206d757374206e6f74206265206c657373207468616e2031756e7265636f676e697a6564207472616e736665724f75742073796e207061636b61676565787069726554696d65206d7573742062652074776f206d696e75746573206c61746572616d6f756e7420697320746f6f206c617267652c20657863656564206d6178696d756d206265703220746f6b656e20616d6f756e7474686520636f6e747261637420686173206e6f74206265656e20626f756e6420746f20616e79206265703220746f6b656e726563656976656420424e4220616d6f756e742073686f756c64206265206e6f206c657373207468616e207468652073756d206f66207472616e736665724f757420424e4220616d6f756e7420616e64206d696e696d756d2072656c6179466565616d6f756e7420697320746f6f206c617267652c2075696e74323536206f766572666c6f774c656e677468206f6620726563697069656e74416464727320646f65736e277420657175616c20746f206c656e677468206f6620726566756e644164647273696e76616c6964207472616e7366657220616d6f756e743a20707265636973696f6e206c6f737320696e20616d6f756e7420636f6e76657273696f6e536166654d6174683a206d756c7469706c69636174696f6e206f766572666c6f77726563656976656420424e4220616d6f756e742073686f756c64206265206e6f206c657373207468616e20746865206d696e696d756d2072656c6179466565746865206d6573736167652073656e646572206d75737420626520676f7665726e616e636520636f6e7472616374756e7265636f676e697a6564207472616e736665724f75742061636b207061636b6167654c656e677468206f6620726563697069656e74416464727320646f65736e277420657175616c20746f206c656e677468206f6620616d6f756e7473746865206d6573736167652073656e646572206d7573742062652063726f737320636861696e20636f6e7472616374746865206d73672073656e646572206d75737420626520746f6b656e4d616e6167657274686520636f6e7472616374206e6f7420696e69742079657400000000000000726563656976656420424e4220616d6f756e742073686f756c64206265206e6f206c657373207468616e207468652073756d206f66207472616e7366657220424e4220616d6f756e7420616e642072656c6179466565696e76616c696420726563656976656420424e4220616d6f756e743a20707265636973696f6e206c6f737320696e20616d6f756e7420636f6e76657273696f6ea2646970667358221220ee0772c728608488e6a5f5dfa5f29f8c4467aea7333c447ace15be38f4600ff464736f6c63430006040033" - }, - "0x0000000000000000000000000000000000001005": { - "balance": "0x0", - "code": "0x6080604052600436106102605760003560e01c80637942fd0511610144578063ac431751116100b6578063dc927faf1161007a578063dc927faf1461076a578063dcae76ab1461077f578063e1c7392a14610794578063f9a2bbc7146107a9578063fc3e5908146107be578063fd6a6879146107d357610267565b8063ac43175114610630578063af40068114610701578063bd4cc8301461072b578063c7d2b028146102eb578063c81b16621461075557610267565b8063a1a11bf511610108578063a1a11bf5146105b2578063a3c3c0ad146105c7578063a413aff6146105dc578063a60d770b146105f1578063a78abc1614610606578063ab51bb961461061b57610267565b80637942fd051461052b57806387c1830a14610540578063930e1b091461055557806396713da9146105885780639dc092621461059d57610267565b806343756e5c116101dd57806354133307116101a15780635413330714610445578063572120951461045a5780636e47b4821461048d5780636f93d2e6146104a257806370fd5bad1461050157806375d47a0a1461051657610267565b806343756e5c146103b0578063490dfdf7146103c5578063493279b1146103ef5780634bf6c8821461041b57806351e806721461043057610267565b8063189d817211610224578063189d8172146103005780631b20087c146103155780631c6433121461032a5780633dffc3871461037057806341b5f4e51461039b57610267565b806308f2ec061461026c5780630bee7a67146102935780630c732068146102c157806310e06a76146102d6578063117048d8146102eb57610267565b3661026757005b600080fd5b34801561027857600080fd5b506102816107e8565b60408051918252519081900360200190f35b34801561029f57600080fd5b506102a86107ee565b6040805163ffffffff9092168252519081900360200190f35b3480156102cd57600080fd5b506102816107f3565b3480156102e257600080fd5b506102816107f9565b3480156102f757600080fd5b506102816107ff565b34801561030c57600080fd5b50610281610804565b34801561032157600080fd5b5061028161080a565b34801561033657600080fd5b506103546004803603602081101561034d57600080fd5b5035610810565b604080516001600160a01b039092168252519081900360200190f35b34801561037c57600080fd5b506103856107ff565b6040805160ff9092168252519081900360200190f35b3480156103a757600080fd5b50610281610837565b3480156103bc57600080fd5b5061035461083c565b3480156103d157600080fd5b50610354600480360360208110156103e857600080fd5b5035610842565b3480156103fb57600080fd5b5061040461084f565b6040805161ffff9092168252519081900360200190f35b34801561042757600080fd5b50610385610854565b34801561043c57600080fd5b50610354610859565b34801561045157600080fd5b5061028161085f565b34801561046657600080fd5b506102816004803603602081101561047d57600080fd5b50356001600160a01b0316610865565b34801561049957600080fd5b50610354610877565b3480156104ae57600080fd5b506104ed600480360360808110156104c557600080fd5b506001600160a01b03813581169160208101359091169060408101359060600135151561087d565b604080519115158252519081900360200190f35b34801561050d57600080fd5b50610385610c21565b34801561052257600080fd5b50610354610c26565b34801561053757600080fd5b50610385610c2c565b34801561054c57600080fd5b50610281610c31565b34801561056157600080fd5b506102816004803603602081101561057857600080fd5b50356001600160a01b0316610c37565b34801561059457600080fd5b50610385610c49565b3480156105a957600080fd5b50610354610c4e565b3480156105be57600080fd5b50610354610c54565b3480156105d357600080fd5b50610281610c5a565b3480156105e857600080fd5b50610281610c60565b3480156105fd57600080fd5b50610281610c66565b34801561061257600080fd5b506104ed610c6b565b34801561062757600080fd5b506102a8610c74565b34801561063c57600080fd5b506106ff6004803603604081101561065357600080fd5b81019060208101813564010000000081111561066e57600080fd5b82018360208201111561068057600080fd5b803590602001918460018302840111640100000000831117156106a257600080fd5b9193909290916020810190356401000000008111156106c057600080fd5b8201836020820111156106d257600080fd5b803590602001918460018302840111640100000000831117156106f457600080fd5b509092509050610c79565b005b34801561070d57600080fd5b506102816004803603602081101561072457600080fd5b5035611237565b34801561073757600080fd5b506102816004803603602081101561074e57600080fd5b5035611299565b34801561076157600080fd5b506103546112b4565b34801561077657600080fd5b506103546112ba565b34801561078b57600080fd5b506102816112c0565b3480156107a057600080fd5b506106ff6112c6565b3480156107b557600080fd5b5061035461138f565b3480156107ca57600080fd5b50610385611395565b3480156107df57600080fd5b5061035461139a565b61019081565b606481565b60035481565b600b5481565b600181565b60045481565b600c5481565b6006818154811061081d57fe5b6000918252602090912001546001600160a01b0316905081565b605081565b61100181565b6008818154811061081d57fe5b606181565b600881565b61200081565b6103e881565b60076020526000908152604090205481565b61100581565b6000805460ff166108d5576040805162461bcd60e51b815260206004820152601960248201527f74686520636f6e7472616374206e6f7420696e69742079657400000000000000604482015290519081900360640190fd5b33612000146109155760405162461bcd60e51b815260040180806020018281038252602f815260200180611d2b602f913960400191505060405180910390fd5b6000821561099a57604080516309a99b4f60e41b8152611005600482015260248101869052905161100291639a99b4f09160448083019260209291908290030181600087803b15801561096757600080fd5b505af115801561097b573d6000803e3d6000fd5b505050506040513d602081101561099157600080fd5b50519050610a13565b604080516309a99b4f60e41b8152611005600482015260248101869052905161100491639a99b4f09160448083019260209291908290030181600087803b1580156109e457600080fd5b505af11580156109f8573d6000803e3d6000fd5b505050506040513d6020811015610a0e57600080fd5b505190505b600c805460010190556000610a27826113a0565b600954909150610a3d908263ffffffff6113cf16565b600955600a54610a65908290610a59908563ffffffff6113cf16565b9063ffffffff61143016565b600a556001600160a01b038716600090815260056020526040902054610ad157600680546001810182556000919091527ff652222313e28459528d920b65115c16c04f3efc82aaedc97be59f3f377c0d3f0180546001600160a01b0319166001600160a01b0389161790555b6001600160a01b038088166000908152600560209081526040808320805460010190559289168252600790522054610b4f57600880546001810182556000919091527ff3f7a9fe364faab93b216da50a3214154f22a0a2b415b23a84c8169e8b636ee30180546001600160a01b0319166001600160a01b0388161790555b6001600160a01b038616600090815260076020526040902080546001019055600c546103e81415610c1457600b54600954600a5460408051938452602084019290925282820152517f127fd0fd1fcf84c71c5c649625ef186be105a71ecc80c7cb3f96cd99ccae1e0f9181900360600190a1610bca86611472565b610bd38661171f565b6040516110029081904780156108fc02916000818181858888f19350505050158015610c03573d6000803e3d6000fd5b5050600b805460010190556000600c555b5060019695505050505050565b600281565b61100881565b600b81565b60015481565b60056020526000908152604090205481565b600981565b61100781565b61100681565b600a5481565b60025481565b600581565b60005460ff1681565b600081565b3361100714610cb95760405162461bcd60e51b815260040180806020018281038252602e815260200180611cdc602e913960400191505060405180910390fd5b60005460ff16610cfa5760405162461bcd60e51b8152600401808060200182810382526021815260200180611d0a6021913960400191505060405180910390fd5b610d6684848080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152505060408051808201909152601581527436b7b632b1bab632a432b0b232b92932b630bcb2b960591b6020820152915061199f9050565b15610df15760208114610daa5760405162461bcd60e51b8152600401808060200182810382526028815260200180611c656028913960400191505060405180910390fd5b604080516020601f8401819004810282018101909252828152600091610de891858580838501838280828437600092019190915250611a8692505050565b600155506111a5565b610e6584848080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152505060408051808201909152601881527f64656e6f6d696e61746f7248656164657252656c6179657200000000000000006020820152915061199f9050565b15610f2d5760208114610ea95760405162461bcd60e51b815260040180806020018281038252602e815260200180611c8d602e913960400191505060405180910390fd5b604080516020601f8401819004810282018101909252828152600091610ee791858580838501838280828437600092019190915250611a8692505050565b905080610f255760405162461bcd60e51b8152600401808060200182810382526030815260200180611d5a6030913960400191505060405180910390fd5b6002556111a5565b610fa184848080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152505060408051808201909152601a81527f6d6f6c6563756c6543616c6c6572436f6d70656e736174696f6e0000000000006020820152915061199f9050565b1561102c5760208114610fe55760405162461bcd60e51b815260040180806020018281038252602e815260200180611c8d602e913960400191505060405180910390fd5b604080516020601f840181900481028201810190925282815260009161102391858580838501838280828437600092019190915250611a8692505050565b600355506111a5565b6110a084848080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152505060408051808201909152601d81527f64656e6f6d696e61746f7243616c6c6572436f6d70656e736174696f6e0000006020820152915061199f9050565b1561116857602081146110e45760405162461bcd60e51b815260040180806020018281038252602e815260200180611c8d602e913960400191505060405180910390fd5b604080516020601f840181900481028201810190925282815260009161112291858580838501838280828437600092019190915250611a8692505050565b9050806111605760405162461bcd60e51b8152600401808060200182810382526035815260200180611d8a6035913960400191505060405180910390fd5b6004556111a5565b6040805162461bcd60e51b815260206004820152600d60248201526c756e6b6e6f776e20706172616d60981b604482015290519081900360640190fd5b7f6cdb0ac70ab7f2e2d035cca5be60d89906f2dede7648ddbd7402189c1eeed17a848484846040518080602001806020018381038352878782818152602001925080828437600083820152601f01601f191690910184810383528581526020019050858580828437600083820152604051601f909101601f19169092018290039850909650505050505050a150505050565b60006101908211611249575080611294565b8161019010801561125c57506103208211155b1561126a5750610190611294565b6103208211801561127d575061044c8211155b1561128e57506104b0819003611294565b50600481045b919050565b600061019082116112ab575080611294565b50610190611294565b61100281565b61100381565b60095481565b60005460ff161561131e576040805162461bcd60e51b815260206004820152601960248201527f74686520636f6e747261637420616c726561647920696e697400000000000000604482015290519081900360640190fd5b60005460ff161561136c576040805162461bcd60e51b8152602060048201526013602482015272185b1c9958591e481a5b9a5d1a585b1a5e9959606a1b604482015290519081900360640190fd5b60018080556005600255600381905560506004556000805460ff19169091179055565b61100081565b600381565b61100481565b60006113c96002546113bd60015485611a8b90919063ffffffff16565b9063ffffffff611ae416565b92915050565b600082820183811015611429576040805162461bcd60e51b815260206004820152601b60248201527f536166654d6174683a206164646974696f6e206f766572666c6f770000000000604482015290519081900360640190fd5b9392505050565b600061142983836040518060400160405280601e81526020017f536166654d6174683a207375627472616374696f6e206f766572666c6f770000815250611b26565b600954600680546040805160208084028201810190925282815260009360609391929091908301828280156114d057602002820191906000526020600020905b81546001600160a01b031681526001909101906020018083116114b2575b5050505050905060608151604051908082528060200260200182016040528015611504578160200160208202803683370190505b50905060005b825181101561159157600083828151811061152157fe5b60200260200101519050600061155b60056000846001600160a01b03166001600160a01b0316815260200190815260200160002054611299565b90508084848151811061156a57fe5b6020908102919091010152611585868263ffffffff6113cf16565b9550505060010161150a565b5060006115af6004546113bd60035488611a8b90919063ffffffff16565b90506115c1858263ffffffff61143016565b94508460015b84518110156116575760006115fc876113bd8a8886815181106115e657fe5b6020026020010151611a8b90919063ffffffff16565b905085828151811061160a57fe5b60200260200101516001600160a01b03166108fc829081150290604051600060405180830381858888f15061164c93508692508491505063ffffffff61143016565b9250506001016115c7565b508360008151811061166557fe5b60200260200101516001600160a01b03166108fc829081150290604051600060405180830381858888f150506040516001600160a01b038b16935085156108fc0292508591506000818181858888f1505060006009819055925050505b845181101561170957600560008683815181106116db57fe5b6020908102919091018101516001600160a01b031682528101919091526040016000908120556001016116c2565b5061171660066000611c22565b50505050505050565b600a546008805460408051602080840282018101909252828152600093606093919290919083018282801561177d57602002820191906000526020600020905b81546001600160a01b0316815260019091019060200180831161175f575b50505050509050606081516040519080825280602002602001820160405280156117b1578160200160208202803683370190505b50905060005b82518110156118305760008382815181106117ce57fe5b60200260200101519050600061180860076000846001600160a01b03166001600160a01b0316815260200190815260200160002054611237565b90508084848151811061181757fe5b60209081029190910101529490940193506001016117b7565b50600061184e6004546113bd60035488611a8b90919063ffffffff16565b9050611860858263ffffffff61143016565b94508460015b84518110156118e0576000611885876113bd8a8886815181106115e657fe5b905085828151811061189357fe5b60200260200101516001600160a01b03166108fc829081150290604051600060405180830381858888f1506118d593508692508491505063ffffffff61143016565b925050600101611866565b50836000815181106118ee57fe5b60200260200101516001600160a01b03166108fc829081150290604051600060405180830381858888f150506040516001600160a01b038b16935085156108fc0292508591506000818181858888f150506000600a819055925050505b8451811015611992576007600086838151811061196457fe5b6020908102919091018101516001600160a01b0316825281019190915260400160009081205560010161194b565b5061171660086000611c22565b6000816040516020018082805190602001908083835b602083106119d45780518252601f1990920191602091820191016119b5565b6001836020036101000a03801982511681845116808217855250505050505090500191505060405160208183030381529060405280519060200120836040516020018082805190602001908083835b60208310611a425780518252601f199092019160209182019101611a23565b6001836020036101000a0380198251168184511680821785525050505050509050019150506040516020818303038152906040528051906020012014905092915050565b015190565b600082611a9a575060006113c9565b82820282848281611aa757fe5b04146114295760405162461bcd60e51b8152600401808060200182810382526021815260200180611cbb6021913960400191505060405180910390fd5b600061142983836040518060400160405280601a81526020017f536166654d6174683a206469766973696f6e206279207a65726f000000000000815250611bbd565b60008184841115611bb55760405162461bcd60e51b81526004018080602001828103825283818151815260200191508051906020019080838360005b83811015611b7a578181015183820152602001611b62565b50505050905090810190601f168015611ba75780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b505050900390565b60008183611c0c5760405162461bcd60e51b8152602060048201818152835160248401528351909283926044909101919085019080838360008315611b7a578181015183820152602001611b62565b506000838581611c1857fe5b0495945050505050565b5080546000825590600052602060002090810190611c409190611c43565b50565b611c6191905b80821115611c5d5760008155600101611c49565b5090565b9056fe6c656e677468206f66206d6f6c6563756c6548656164657252656c61796572206d69736d617463686c656e677468206f6620726577617264466f7256616c696461746f725365744368616e6765206d69736d61746368536166654d6174683a206d756c7469706c69636174696f6e206f766572666c6f77746865206d6573736167652073656e646572206d75737420626520676f7665726e616e636520636f6e7472616374636f6e747261637420686173206e6f74206265656e20696e697469616c697a6564746865206d6573736167652073656e646572206d7573742062652063726f737320636861696e20636f6e7472616374746865206e657744656e6f6d696e61746f7248656164657252656c61796572206d757374206e6f74206265207a65726f746865206e657744656e6f6d696e61746f7243616c6c6572436f6d70656e736174696f6e206d757374206e6f74206265207a65726fa26469706673582212202548a56b68ed51ad6e9a1aa43899b24ae5df4a24a9f594232fc5392c443544fb64736f6c63430006040033" - }, - "0x0000000000000000000000000000000000001006": { - "balance": "0x0", - "code": "0x6080604052600436106101c25760003560e01c806395468d26116100f7578063c81b166211610095578063f9a2bbc711610064578063f9a2bbc714610529578063fb7cfdd71461053e578063fc3e590814610553578063fd6a687914610568576101c2565b8063c81b1662146104d5578063dc927faf146104ea578063e1c7392a146104ff578063e79a198f14610514576101c2565b8063a1a11bf5116100d1578063a1a11bf5146103c7578063a78abc16146103dc578063ab51bb96146103f1578063ac43175114610406576101c2565b806395468d261461038857806396713da91461039d5780639dc09262146103b2576101c2565b8063541d55481161016457806370fd5bad1161013e57806370fd5bad1461033457806375d47a0a146103495780637942fd051461035e5780637ae2308814610373576101c2565b8063541d5548146102b15780636a87d780146102f85780636e47b4821461031f576101c2565b806343756e5c116101a057806343756e5c1461022a578063493279b11461025b5780634bf6c8821461028757806351e806721461029c576101c2565b80630bee7a67146101c75780631aa3a008146101f55780633dffc387146101ff575b600080fd5b3480156101d357600080fd5b506101dc61057d565b6040805163ffffffff9092168252519081900360200190f35b6101fd610582565b005b34801561020b57600080fd5b50610214610733565b6040805160ff9092168252519081900360200190f35b34801561023657600080fd5b5061023f610738565b604080516001600160a01b039092168252519081900360200190f35b34801561026757600080fd5b5061027061073e565b6040805161ffff9092168252519081900360200190f35b34801561029357600080fd5b50610214610743565b3480156102a857600080fd5b5061023f610748565b3480156102bd57600080fd5b506102e4600480360360208110156102d457600080fd5b50356001600160a01b031661074e565b604080519115158252519081900360200190f35b34801561030457600080fd5b5061030d61076c565b60408051918252519081900360200190f35b34801561032b57600080fd5b5061023f610772565b34801561034057600080fd5b50610214610778565b34801561035557600080fd5b5061023f61077d565b34801561036a57600080fd5b50610214610783565b34801561037f57600080fd5b5061030d610788565b34801561039457600080fd5b5061030d610795565b3480156103a957600080fd5b506102146107a1565b3480156103be57600080fd5b5061023f6107a6565b3480156103d357600080fd5b5061023f6107ac565b3480156103e857600080fd5b506102e46107b2565b3480156103fd57600080fd5b506101dc6107bb565b34801561041257600080fd5b506101fd6004803603604081101561042957600080fd5b81019060208101813564010000000081111561044457600080fd5b82018360208201111561045657600080fd5b8035906020019184600183028401116401000000008311171561047857600080fd5b91939092909160208101903564010000000081111561049657600080fd5b8201836020820111156104a857600080fd5b803590602001918460018302840111640100000000831117156104ca57600080fd5b5090925090506107c0565b3480156104e157600080fd5b5061023f610bd6565b3480156104f657600080fd5b5061023f610bdc565b34801561050b57600080fd5b506101fd610be2565b34801561052057600080fd5b506101fd610c64565b34801561053557600080fd5b5061023f610e0b565b34801561054a57600080fd5b5061030d610e11565b34801561055f57600080fd5b50610214610e17565b34801561057457600080fd5b5061023f610e1c565b606481565b3360009081526004602052604090205460ff16156105df576040805162461bcd60e51b81526020600482015260156024820152741c995b185e595c88185b1c9958591e48195e1a5cdd605a1b604482015290519081900360640190fd5b60005460ff16610632576040805162461bcd60e51b81526020600482015260196024820152781d1a194818dbdb9d1c9858dd081b9bdd081a5b9a5d081e595d603a1b604482015290519081900360640190fd5b61063b33610e22565b156106775760405162461bcd60e51b8152600401808060200182810382526027815260200180610f546027913960400191505060405180910390fd5b60015434146106b75760405162461bcd60e51b8152600401808060200182810382526025815260200180610f2f6025913960400191505060405180910390fd5b604080518082018252600180548252600254602080840191825233600081815260038352868120955186559251948401949094556004815290849020805460ff1916909217909155825191825291517fdb33a09d38b59a8fa8b7d92a1d82c8015e99f05f67ae9c9ae623157767959496929181900390910190a1565b600181565b61100181565b606181565b600881565b61200081565b6001600160a01b031660009081526004602052604090205460ff1690565b60025481565b61100581565b600281565b61100881565b600b81565b68056bc75e2d6310000081565b67016345785d8a000081565b600981565b61100781565b61100681565b60005460ff1681565b600081565b60005460ff16610813576040805162461bcd60e51b81526020600482015260196024820152781d1a194818dbdb9d1c9858dd081b9bdd081a5b9a5d081e595d603a1b604482015290519081900360640190fd5b33611007146108535760405162461bcd60e51b815260040180806020018281038252602e815260200180610f7b602e913960400191505060405180910390fd5b6108b984848080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152505060408051808201909152600f81526e1c995c5d5a5c995911195c1bdcda5d608a1b60208201529150610e289050565b156109b057602081146108fd5760405162461bcd60e51b8152600401808060200182810382526022815260200180610fa96022913960400191505060405180910390fd5b604080516020601f840181900481028201810190925282815260009161093b91858580838501838280828437600092019190915250610f0f92505050565b9050600181101580156109575750683635c9adc5dea000008111155b6109a8576040805162461bcd60e51b815260206004820181905260248201527f7468652072657175697265644465706f736974206f7574206f662072616e6765604482015290519081900360640190fd5b600155610b44565b610a0b84848080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250506040805180820190915260048152636475657360e01b60208201529150610e289050565b15610b075760208114610a65576040805162461bcd60e51b815260206004820152601760248201527f6c656e677468206f662064756573206d69736d61746368000000000000000000604482015290519081900360640190fd5b604080516020601f8401819004810282018101909252828152600091610aa391858580838501838280828437600092019190915250610f0f92505050565b9050600081118015610ab6575060015481105b610aff576040805162461bcd60e51b81526020600482015260156024820152747468652064756573206f7574206f662072616e676560581b604482015290519081900360640190fd5b600255610b44565b6040805162461bcd60e51b815260206004820152600d60248201526c756e6b6e6f776e20706172616d60981b604482015290519081900360640190fd5b7f6cdb0ac70ab7f2e2d035cca5be60d89906f2dede7648ddbd7402189c1eeed17a848484846040518080602001806020018381038352878782818152602001925080828437600083820152601f01601f191690910184810383528581526020019050858580828437600083820152604051601f909101601f19169092018290039850909650505050505050a150505050565b61100281565b61100381565b60005460ff1615610c3a576040805162461bcd60e51b815260206004820152601960248201527f74686520636f6e747261637420616c726561647920696e697400000000000000604482015290519081900360640190fd5b68056bc75e2d63100000600190815567016345785d8a00006002556000805460ff19169091179055565b3360009081526004602052604090205460ff16610cbf576040805162461bcd60e51b81526020600482015260146024820152731c995b185e595c88191bc81b9bdd08195e1a5cdd60621b604482015290519081900360640190fd5b60005460ff16610d12576040805162461bcd60e51b81526020600482015260196024820152781d1a194818dbdb9d1c9858dd081b9bdd081a5b9a5d081e595d603a1b604482015290519081900360640190fd5b610d1a610f14565b50336000818152600360209081526040808320815180830183528154808252600190920154938101849052915191949392900380156108fc0292909190818181858888f19350505050158015610d74573d6000803e3d6000fd5b50602081015160405161100291829181156108fc0291906000818181858888f19350505050158015610daa573d6000803e3d6000fd5b50336000818152600460209081526040808320805460ff191690556003825280832083815560010192909255815192835290517fd17202129b83db7880d6b9f25df81c58ad46f7e0e2c92236b1aa10663a4876679281900390910190a15050565b61100081565b60015481565b600381565b61100481565b3b151590565b6000816040516020018082805190602001908083835b60208310610e5d5780518252601f199092019160209182019101610e3e565b6001836020036101000a03801982511681845116808217855250505050505090500191505060405160208183030381529060405280519060200120836040516020018082805190602001908083835b60208310610ecb5780518252601f199092019160209182019101610eac565b6001836020036101000a0380198251168184511680821785525050505050509050019150506040516020818303038152906040528051906020012014905092915050565b015190565b60405180604001604052806000815260200160008152509056fe6465706f7369742076616c7565206973206e6f742065786163746c79207468652073616d65636f6e7472616374206973206e6f7420616c6c6f77656420746f20626520612072656c61796572746865206d6573736167652073656e646572206d75737420626520676f7665726e616e636520636f6e74726163746c656e677468206f662072657175697265644465706f736974206d69736d61746368a2646970667358221220fb9552ef120a66e5db5b423b7f53133dfd781b3274938e279792aad5d583b27564736f6c63430006040033" - }, - "0x0000000000000000000000000000000000001007": { - "balance": "0x0", - "code": "0x608060405234801561001057600080fd5b506004361061018e5760003560e01c8063831d65d1116100de578063ab51bb9611610097578063dc927faf11610071578063dc927faf14610486578063f9a2bbc71461048e578063fc3e590814610496578063fd6a68791461049e5761018e565b8063ab51bb96146103fc578063c81b166214610404578063c8509d811461040c5761018e565b8063831d65d11461034457806396713da9146103c05780639ab1a373146103c85780639dc09262146103d0578063a1a11bf5146103d8578063a78abc16146103e05761018e565b8063493279b11161014b5780636e47b482116101255780636e47b4821461032457806370fd5bad1461032c57806375d47a0a146103345780637942fd051461033c5761018e565b8063493279b1146102f55780634bf6c8821461031457806351e806721461031c5761018e565b80630bee7a67146101935780631182b875146101b45780633a21baae146102a35780633dffc387146102ab57806343756e5c146102c95780634900c4ea146102ed575b600080fd5b61019b6104a6565b6040805163ffffffff9092168252519081900360200190f35b61022e600480360360408110156101ca57600080fd5b60ff82351691908101906040810160208201356401000000008111156101ef57600080fd5b82018360208201111561020157600080fd5b8035906020019184600183028401116401000000008311171561022357600080fd5b5090925090506104ab565b6040805160208082528351818301528351919283929083019185019080838360005b83811015610268578181015183820152602001610250565b50505050905090810190601f1680156102955780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b61019b61059a565b6102b361059f565b6040805160ff9092168252519081900360200190f35b6102d16105a4565b604080516001600160a01b039092168252519081900360200190f35b6102b36105aa565b6102fd6105af565b6040805161ffff9092168252519081900360200190f35b6102b36105b4565b6102d16105b9565b6102d16105bf565b6102b36105c5565b6102d16105ca565b6102b36105d0565b6103be6004803603604081101561035a57600080fd5b60ff823516919081019060408101602082013564010000000081111561037f57600080fd5b82018360208201111561039157600080fd5b803590602001918460018302840111640100000000831117156103b357600080fd5b5090925090506105d5565b005b6102b3610627565b61019b61062c565b6102d1610631565b6102d1610637565b6103e861063d565b604080519115158252519081900360200190f35b61019b6105aa565b6102d1610646565b6103be6004803603604081101561042257600080fd5b60ff823516919081019060408101602082013564010000000081111561044757600080fd5b82018360208201111561045957600080fd5b8035906020019184600183028401116401000000008311171561047b57600080fd5b50909250905061064c565b6102d1610683565b6102d1610689565b6102b361068f565b6102d1610694565b606481565b606033612000146104ed5760405162461bcd60e51b815260040180806020018281038252602f815260200180611276602f913960400191505060405180910390fd5b6104f5611211565b600061053685858080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061069a92505050565b9150915080610552576105496064610760565b92505050610593565b600061055d836107ca565b905063ffffffff811661058457505060408051600081526020810190915291506105939050565b61058d81610760565b93505050505b9392505050565b606681565b600181565b61100181565b600081565b606181565b600881565b61200081565b61100581565b600281565b61100881565b600b81565b6040805162461bcd60e51b815260206004820152601e60248201527f7265636569766520756e65787065637465642061636b207061636b6167650000604482015290519081900360640190fd5b505050565b600981565b606581565b61100781565b61100681565b60005460ff1681565b61100281565b60405162461bcd60e51b81526004018080602001828103825260238152602001806112a56023913960400191505060405180910390fd5b61100381565b61100081565b600381565b61100481565b6106a2611211565b60006106ac611211565b6106b461123b565b6106c56106c086610b6b565b610b90565b90506000805b6106d483610bda565b1561075357806106f6576106ef6106ea84610bfb565b610c49565b845261074b565b80600114156107155761070b6106ea84610bfb565b602085015261074b565b80600214156107465761072f61072a84610bfb565b610cc2565b6001600160a01b031660408501526001915061074b565b610753565b6001016106cb565b5091935090915050915091565b604080516001808252818301909252606091829190816020015b606081526020019060019003908161077a5790505090506107a08363ffffffff16610ce2565b816000815181106107ad57fe5b60200260200101819052506107c181610cf5565b9150505b919050565b60006107d98260400151610d7f565b61084557604080516020808252601c908201527f74686520746172676574206973206e6f74206120636f6e7472616374000000008183015290517f70e72399380dcfb0338abc03dc8d47f9f470ada8e769c9a78d644ea97385ecb29181900360600190a15060656107c5565b81604001516001600160a01b031663ac431751836000015184602001516040518363ffffffff1660e01b8152600401808060200180602001838103835285818151815260200191508051906020019080838360005b838110156108b257818101518382015260200161089a565b50505050905090810190601f1680156108df5780820380516001836020036101000a031916815260200191505b50838103825284518152845160209182019186019080838360005b838110156109125781810151838201526020016108fa565b50505050905090810190601f16801561093f5780820380516001836020036101000a031916815260200191505b50945050505050600060405180830381600087803b15801561096057600080fd5b505af1925050508015610971575060015b610b63576040516000815260443d101561098d57506000610a2a565b60046000803e60005160e01c6308c379a081146109ae576000915050610a2a565b60043d036004833e81513d602482011167ffffffffffffffff821117156109da57600092505050610a2a565b808301805167ffffffffffffffff8111156109fc576000945050505050610a2a565b8060208301013d8601811115610a1a57600095505050505050610a2a565b601f01601f191660405250925050505b80610a355750610ad8565b7f70e72399380dcfb0338abc03dc8d47f9f470ada8e769c9a78d644ea97385ecb2816040518080602001828103825283818151815260200191508051906020019080838360005b83811015610a94578181015183820152602001610a7c565b50505050905090810190601f168015610ac15780820380516001836020036101000a031916815260200191505b509250505060405180910390a160669150506107c5565b3d808015610b02576040519150601f19603f3d011682016040523d82523d6000602084013e610b07565b606091505b5060408051602080825283518183015283517f1279f84165b4fd69c35e1f338ff107231b036c655cd1688851e011ce617c4e8d938593928392918301919085019080838360008315610a94578181015183820152602001610a7c565b506000919050565b610b7361125b565b506040805180820190915281518152602082810190820152919050565b610b9861123b565b610ba182610d85565b610baa57600080fd5b6000610bb98360200151610dbf565b60208085015160408051808201909152868152920190820152915050919050565b6000610be461125b565b505080518051602091820151919092015191011190565b610c0361125b565b610c0c82610bda565b610c1557600080fd5b60208201516000610c2582610e22565b80830160209586015260408051808201909152908152938401919091525090919050565b8051606090610c5757600080fd5b6000610c668360200151610dbf565b83516040805191839003808352601f19601f8201168301602001909152919250606090828015610c9d576020820181803683370190505b5090506000816020019050610cb9848760200151018285610ebb565b50949350505050565b8051600090601514610cd357600080fd5b610cdc82610f06565b92915050565b6060610cdc610cf083610f64565b61104a565b6060815160001415610d1657506040805160008152602081019091526107c5565b606082600081518110610d2557fe5b602002602001015190506000600190505b8351811015610d6657610d5c82858381518110610d4f57fe5b602002602001015161109c565b9150600101610d36565b506107c1610d79825160c060ff16611119565b8261109c565b3b151590565b8051600090610d96575060006107c5565b6020820151805160001a9060c0821015610db5576000925050506107c5565b5060019392505050565b8051600090811a6080811015610dd95760009150506107c5565b60b8811080610df4575060c08110801590610df4575060f881105b15610e035760019150506107c5565b60c0811015610e175760b5190190506107c5565b60f5190190506107c5565b80516000908190811a6080811015610e3d5760019150610eb4565b60b8811015610e5257607e1981019150610eb4565b60c0811015610e7f5760b78103600185019450806020036101000a85510460018201810193505050610eb4565b60f8811015610e945760be1981019150610eb4565b60f78103600185019450806020036101000a855104600182018101935050505b5092915050565b80610ec557610622565b5b60208110610ee5578251825260209283019290910190601f1901610ec6565b915181516020939093036101000a6000190180199091169216919091179052565b805160009015801590610f1b57508151602110155b610f2457600080fd5b6000610f338360200151610dbf565b83516020808601518301805193945091849003929190831015610cb957506020919091036101000a90049392505050565b604080516020808252818301909252606091829190602082018180368337505050602081018490529050600067ffffffffffffffff198416610fa857506018610fcc565b6fffffffffffffffffffffffffffffffff198416610fc857506010610fcc565b5060005b602081101561100257818181518110610fe157fe5b01602001516001600160f81b03191615610ffa57611002565b600101610fcc565b60008160200390506060816040519080825280601f01601f191660200182016040528015611037576020820181803683370190505b5080830196909652508452509192915050565b60608151600114801561107c5750607f60f81b8260008151811061106a57fe5b01602001516001600160f81b03191611155b156110885750806107c5565b610cdc61109a8351608060ff16611119565b835b6060806040519050835180825260208201818101602087015b818310156110cd5780518352602092830192016110b5565b50855184518101855292509050808201602086015b818310156110fa5780518352602092830192016110e2565b508651929092011591909101601f01601f191660405250905092915050565b6060680100000000000000008310611169576040805162461bcd60e51b815260206004820152600e60248201526d696e70757420746f6f206c6f6e6760901b604482015290519081900360640190fd5b604080516001808252818301909252606091602082018180368337019050509050603784116111c35782840160f81b816000815181106111a557fe5b60200101906001600160f81b031916908160001a9053509050610cdc565b60606111ce85610f64565b90508381510160370160f81b826000815181106111e757fe5b60200101906001600160f81b031916908160001a905350611208828261109c565b95945050505050565b6040518060600160405280606081526020016060815260200160006001600160a01b031681525090565b604051806040016040528061124e61125b565b8152602001600081525090565b60405180604001604052806000815260200160008152509056fe746865206d6573736167652073656e646572206d7573742062652063726f737320636861696e20636f6e74726163747265636569766520756e6578706563746564206661696c2061636b207061636b616765a264697066735822122019628d70dd9ac62a7a85eb3f845d01808a095ab280a95e6dd5609e52788b4c5e64736f6c63430006040033" - }, - "0x0000000000000000000000000000000000001008": { - "balance": "0x0", - "code": "0x6080604052600436106102305760003560e01c806377d9dae81161012e578063c81b1662116100ab578063dc927faf1161006f578063dc927faf14610887578063f9a2bbc71461089c578063fc3e5908146107f1578063fd6a6879146108b1578063fe3a2af51461042457610230565b8063c81b1662146107dc578063c8509d81146106d7578063c8e704a4146107f1578063d117a11014610806578063dc6f5e90146107f157610230565b806396713da9116100f257806396713da9146107735780639dc0926214610788578063a1a11bf51461079d578063a78abc16146107b2578063ab51bb96146107c757610230565b806377d9dae81461060e5780637942fd05146106c25780637d078e13146103b2578063831d65d1146106d757806395b9ad261461075e57610230565b80634a688818116101bc5780636b3f1307116101805780636b3f1307146104785780636e47b4821461054057806370fd5bad1461046357806372c4e0861461055557806375d47a0a146105f957610230565b80634a688818146104245780634bc81c00146104395780634bf6c8821461023557806351e806721461044e5780635f558f861461046357610230565b80631f91600b116102035780631f91600b1461039d57806323996b53146103b25780633dffc387146103b257806343756e5c146103c7578063493279b1146103f857610230565b8063077b8f35146102355780630bee7a67146102605780630f212b1b1461028e5780631182b875146102a3575b600080fd5b34801561024157600080fd5b5061024a6108c6565b6040805160ff9092168252519081900360200190f35b34801561026c57600080fd5b506102756108cb565b6040805163ffffffff9092168252519081900360200190f35b34801561029a57600080fd5b5061024a6108d0565b3480156102af57600080fd5b50610328600480360360408110156102c657600080fd5b60ff8235169190810190604081016020820135600160201b8111156102ea57600080fd5b8201836020820111156102fc57600080fd5b803590602001918460018302840111600160201b8311171561031d57600080fd5b5090925090506108d5565b6040805160208082528351818301528351919283929083019185019080838360005b8381101561036257818101518382015260200161034a565b50505050905090810190601f16801561038f5780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b3480156103a957600080fd5b5061024a61095e565b3480156103be57600080fd5b5061024a610963565b3480156103d357600080fd5b506103dc610968565b604080516001600160a01b039092168252519081900360200190f35b34801561040457600080fd5b5061040d61096e565b6040805161ffff9092168252519081900360200190f35b34801561043057600080fd5b5061024a610973565b34801561044557600080fd5b5061024a610978565b34801561045a57600080fd5b506103dc61097d565b34801561046f57600080fd5b5061024a610983565b61052c6004803603604081101561048e57600080fd5b6001600160a01b038235169190810190604081016020820135600160201b8111156104b857600080fd5b8201836020820111156104ca57600080fd5b803590602001918460018302840111600160201b831117156104eb57600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250929550610988945050505050565b604080519115158252519081900360200190f35b34801561054c57600080fd5b506103dc61121e565b61052c6004803603602081101561056b57600080fd5b810190602081018135600160201b81111561058557600080fd5b82018360208201111561059757600080fd5b803590602001918460018302840111600160201b831117156105b857600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250929550611224945050505050565b34801561060557600080fd5b506103dc611683565b61052c6004803603604081101561062457600080fd5b6001600160a01b038235169190810190604081016020820135600160201b81111561064e57600080fd5b82018360208201111561066057600080fd5b803590602001918460018302840111600160201b8311171561068157600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250929550611689945050505050565b3480156106ce57600080fd5b5061024a611ba0565b3480156106e357600080fd5b5061075c600480360360408110156106fa57600080fd5b60ff8235169190810190604081016020820135600160201b81111561071e57600080fd5b82018360208201111561073057600080fd5b803590602001918460018302840111600160201b8311171561075157600080fd5b509092509050611ba5565b005b34801561076a57600080fd5b5061024a611c58565b34801561077f57600080fd5b5061024a611c5d565b34801561079457600080fd5b506103dc611c62565b3480156107a957600080fd5b506103dc611c68565b3480156107be57600080fd5b5061052c611c6e565b3480156107d357600080fd5b50610275610973565b3480156107e857600080fd5b506103dc611c77565b3480156107fd57600080fd5b5061024a611c7d565b34801561081257600080fd5b506108306004803603602081101561082957600080fd5b5035611c82565b6040805160ff988916815260208101979097526001600160a01b03909516868601526060860193909352608085019190915290931660a083015267ffffffffffffffff90921660c082015290519081900360e00190f35b34801561089357600080fd5b506103dc611cda565b3480156108a857600080fd5b506103dc611ce0565b3480156108bd57600080fd5b506103dc611ce6565b600881565b606481565b600681565b606033612000146109175760405162461bcd60e51b815260040180806020018281038252602f815260200180612f8e602f913960400191505060405180910390fd5b61095683838080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250611cec92505050565b949350505050565b600481565b600181565b61100181565b606181565b600081565b600581565b61200081565b600281565b60008061099483611f7d565b905061099e612e56565b50600081815260016020818152604092839020835160e081018552815460ff90811682529382015492810183905260028201546001600160a01b03169481019490945260038101546060850152600481015460808501526005015491821660a084015261010090910467ffffffffffffffff1660c0830152610a64576040805162461bcd60e51b815260206004820152601a602482015279189a5b99081c995c5d595cdd08191bd95cdb89dd08195e1a5cdd60321b604482015290519081900360640190fd5b6000610a8182608001518360600151611f8490919063ffffffff16565b905081604001516001600160a01b0316866001600160a01b031614610ad75760405162461bcd60e51b8152600401808060200182810382526045815260200180612f1b6045913960600191505060405180910390fd5b336001600160a01b0316866001600160a01b031663893d20e86040518163ffffffff1660e01b815260040160206040518083038186803b158015610b1a57600080fd5b505afa158015610b2e573d6000803e3d6000fd5b505050506040513d6020811015610b4457600080fd5b50516001600160a01b031614610b8b5760405162461bcd60e51b815260040180806020018281038252602e815260200180612f60602e913960400191505060405180910390fd5b604080516370a0823160e01b8152611004600482015290516000916001600160a01b038916916370a0823191602480820192602092909190829003018186803b158015610bd757600080fd5b505afa158015610beb573d6000803e3d6000fd5b505050506040513d6020811015610c0157600080fd5b505160408051636eb1769f60e11b815233600482015230602482015290519192508391610c929184916001600160a01b038c169163dd62ed3e916044808301926020929190829003018186803b158015610c5a57600080fd5b505afa158015610c6e573d6000803e3d6000fd5b505050506040513d6020811015610c8457600080fd5b50519063ffffffff611fcd16565b1015610ce5576040805162461bcd60e51b815260206004820152601760248201527f616c6c6f77616e6365206973206e6f7420656e6f756768000000000000000000604482015290519081900360640190fd5b600034905060006110046001600160a01b031663149d14d96040518163ffffffff1660e01b815260040160206040518083038186803b158015610d2757600080fd5b505afa158015610d3b573d6000803e3d6000fd5b505050506040513d6020811015610d5157600080fd5b50519050808210801590610d6a57506402540be4008206155b610da55760405162461bcd60e51b8152600401808060200182810382526037815260200180612ee46037913960400191505060405180910390fd5b6000610db1868b612027565b905063ffffffff8116610fb0576001600160a01b038a166323b872dd33611004610de1898963ffffffff611f8416565b6040518463ffffffff1660e01b815260040180846001600160a01b03166001600160a01b03168152602001836001600160a01b03166001600160a01b031681526020018281526020019350505050602060405180830381600087803b158015610e4957600080fd5b505af1158015610e5d573d6000803e3d6000fd5b505050506040513d6020811015610e7357600080fd5b5050602086015160408088015160a089015182516323bfccdb60e21b815260048101949094526001600160a01b03909116602484015260ff1660448301525161100491638eff336c91606480830192600092919082900301818387803b158015610edc57600080fd5b505af1158015610ef0573d6000803e3d6000fd5b50505050896001600160a01b03167f78e7dd9aefcdbf795c4936a66f7dc6d41bb56637b54f561a6bf7829dca3348a88a8860600151886040518080602001848152602001838152602001828103825285818151815260200191508051906020019080838360005b83811015610f6f578181015183820152602001610f57565b50505050905090810190601f168015610f9c5780820380516001836020036101000a031916815260200191505b5094505050505060405180910390a2611068565b896001600160a01b03167f831c0ef4d93bda3bce08b69ae3f29ef1a6e052b833200988554158494405a1078a8360405180806020018363ffffffff1663ffffffff168152602001828103825284818151815260200191508051906020019080838360005b8381101561102c578181015183820152602001611014565b50505050905090810190601f1680156110595780820380516001836020036101000a031916815260200191505b50935050505060405180910390a25b60008781526001602081905260408220805460ff191681559081018290556002810180546001600160a01b0319169055600381018290556004810191909155600501805468ffffffffffffffffff191690556110c2612e92565b5060408051808201825263ffffffff831681526020810189905290516110049085156108fc029086906000818181858888f1935050505015801561110a573d6000803e3d6000fd5b5061200063f7a251d7600161111e8461247e565b611133886402540be40063ffffffff61250816565b6040518463ffffffff1660e01b8152600401808460ff1660ff16815260200180602001838152602001828103825284818151815260200191508051906020019080838360005b83811015611191578181015183820152602001611179565b50505050905090810190601f1680156111be5780820380516001836020036101000a031916815260200191505b50945050505050602060405180830381600087803b1580156111df57600080fd5b505af11580156111f3573d6000803e3d6000fd5b505050506040513d602081101561120957600080fd5b50600199505050505050505050505b92915050565b61100581565b60008061123083611f7d565b905061123a612e56565b50600081815260016020818152604092839020835160e081018552815460ff90811682529382015492810183905260028201546001600160a01b03169481019490945260038101546060850152600481015460808501526005015491821660a084015261010090910467ffffffffffffffff1660c0830152611300576040805162461bcd60e51b815260206004820152601a602482015279189a5b99081c995c5d595cdd08191bd95cdb89dd08195e1a5cdd60321b604482015290519081900360640190fd5b428160c0015167ffffffffffffffff1610611362576040805162461bcd60e51b815260206004820152601b60248201527f62696e642072657175657374206973206e6f7420657870697265640000000000604482015290519081900360640190fd5b600034905060006110046001600160a01b031663149d14d96040518163ffffffff1660e01b815260040160206040518083038186803b1580156113a457600080fd5b505afa1580156113b8573d6000803e3d6000fd5b505050506040513d60208110156113ce57600080fd5b505190508082108015906113e757506402540be4008206155b6114225760405162461bcd60e51b8152600401808060200182810382526037815260200180612ee46037913960400191505060405180910390fd5b60008481526001602081905260408220805460ff191681559081018290556002810180546001600160a01b0319169055600381018290556004810191909155600501805468ffffffffffffffffff1916905561147c612e92565b50604080518082018252600181526020810186905290516110049084156108fc029085906000818181858888f193505050501580156114bf573d6000803e3d6000fd5b5061200063f7a251d760016114d38461247e565b6114e8876402540be40063ffffffff61250816565b6040518463ffffffff1660e01b8152600401808460ff1660ff16815260200180602001838152602001828103825284818151815260200191508051906020019080838360005b8381101561154657818101518382015260200161152e565b50505050905090810190601f1680156115735780820380516001836020036101000a031916815260200191505b50945050505050602060405180830381600087803b15801561159457600080fd5b505af11580156115a8573d6000803e3d6000fd5b505050506040513d60208110156115be57600080fd5b50506040808501518151600160208281018290528483528b51948301949094528a516001600160a01b03909316937f831c0ef4d93bda3bce08b69ae3f29ef1a6e052b833200988554158494405a107938c93918291606083019186019080838360005b83811015611639578181015183820152602001611621565b50505050905090810190601f1680156116665780820380516001836020036101000a031916815260200191505b50935050505060405180910390a26001955050505050505b919050565b61100881565b60008061169583611f7d565b905061169f612e56565b50600081815260016020818152604092839020835160e081018552815460ff90811682529382015492810183905260028201546001600160a01b03169481019490945260038101546060850152600481015460808501526005015491821660a084015261010090910467ffffffffffffffff1660c0830152611765576040805162461bcd60e51b815260206004820152601a602482015279189a5b99081c995c5d595cdd08191bd95cdb89dd08195e1a5cdd60321b604482015290519081900360640190fd5b80604001516001600160a01b0316856001600160a01b0316146117b95760405162461bcd60e51b8152600401808060200182810382526045815260200180612f1b6045913960600191505060405180910390fd5b336001600160a01b0316856001600160a01b031663893d20e86040518163ffffffff1660e01b815260040160206040518083038186803b1580156117fc57600080fd5b505afa158015611810573d6000803e3d6000fd5b505050506040513d602081101561182657600080fd5b50516001600160a01b031614611883576040805162461bcd60e51b815260206004820152601b60248201527f6f6e6c79206265703265206f776e65722063616e2072656a6563740000000000604482015290519081900360640190fd5b600034905060006110046001600160a01b031663149d14d96040518163ffffffff1660e01b815260040160206040518083038186803b1580156118c557600080fd5b505afa1580156118d9573d6000803e3d6000fd5b505050506040513d60208110156118ef57600080fd5b5051905080821080159061190857506402540be4008206155b6119435760405162461bcd60e51b8152600401808060200182810382526037815260200180612ee46037913960400191505060405180910390fd5b60008481526001602081905260408220805460ff191681559081018290556002810180546001600160a01b0319169055600381018290556004810191909155600501805468ffffffffffffffffff1916905561199d612e92565b50604080518082018252600781526020810186905290516110049084156108fc029085906000818181858888f193505050501580156119e0573d6000803e3d6000fd5b5061200063f7a251d760016119f48461247e565b611a09876402540be40063ffffffff61250816565b6040518463ffffffff1660e01b8152600401808460ff1660ff16815260200180602001838152602001828103825284818151815260200191508051906020019080838360005b83811015611a67578181015183820152602001611a4f565b50505050905090810190601f168015611a945780820380516001836020036101000a031916815260200191505b50945050505050602060405180830381600087803b158015611ab557600080fd5b505af1158015611ac9573d6000803e3d6000fd5b505050506040513d6020811015611adf57600080fd5b505060408051600760208281018290528383528a519383019390935289516001600160a01b038c16937f831c0ef4d93bda3bce08b69ae3f29ef1a6e052b833200988554158494405a107938c939290918291606083019186019080838360005b83811015611b57578181015183820152602001611b3f565b50505050905090810190601f168015611b845780820380516001836020036101000a031916815260200191505b50935050505060405180910390a2506001979650505050505050565b600b81565b3361200014611be55760405162461bcd60e51b815260040180806020018281038252602f815260200180612f8e602f913960400191505060405180910390fd5b7f41ce201247b6ceb957dcdb217d0b8acb50b9ea0e12af9af4f5e7f38902101605838383604051808460ff1660ff168152602001806020018281038252848482818152602001925080828437600083820152604051601f909101601f1916909201829003965090945050505050a1505050565b600781565b600981565b61100781565b61100681565b60005460ff1681565b61100281565b600381565b600160208190526000918252604090912080549181015460028201546003830154600484015460059094015460ff9586169593946001600160a01b0390931693919291811690610100900467ffffffffffffffff1687565b61100381565b61100081565b61100481565b6060611cf6612e56565b6000611d018461254a565b9150915080611d57576040805162461bcd60e51b815260206004820152601f60248201527f756e7265636f676e697a6564207472616e73666572496e207061636b61676500604482015290519081900360640190fd5b815160ff16611e0b576020828101805160009081526001928390526040908190208551815460ff1990811660ff928316178355935194820194909455908501516002820180546001600160a01b0319166001600160a01b03909216919091179055606085015160038201556080850151600482015560a08501516005909101805460c08701519316919093161768ffffffffffffffff00191661010067ffffffffffffffff90921691909102179055611f62565b815160ff1660011415611f155760006110046001600160a01b03166359b9278984602001516040518263ffffffff1660e01b81526004018082815260200191505060206040518083038186803b158015611e6457600080fd5b505afa158015611e78573d6000803e3d6000fd5b505050506040513d6020811015611e8e57600080fd5b505190506001600160a01b03811615611f0f5760208301516040805163b99328c560e01b815260048101929092526001600160a01b0383166024830152516110049163b99328c591604480830192600092919082900301818387803b158015611ef657600080fd5b505af1158015611f0a573d6000803e3d6000fd5b505050505b50611f62565b6040805162461bcd60e51b815260206004820152601960248201527f756e7265636f676e697a65642062696e64207061636b61676500000000000000604482015290519081900360640190fd5b60408051600080825260208201909252905b50949350505050565b6020015190565b6000611fc683836040518060400160405280601e81526020017f536166654d6174683a207375627472616374696f6e206f766572666c6f77000081525061269c565b9392505050565b600082820183811015611fc6576040805162461bcd60e51b815260206004820152601b60248201527f536166654d6174683a206164646974696f6e206f766572666c6f770000000000604482015290519081900360640190fd5b600080826001600160a01b031663313ce5676040518163ffffffff1660e01b815260040160206040518083038186803b15801561206357600080fd5b505afa158015612077573d6000803e3d6000fd5b505050506040513d602081101561208d57600080fd5b5051604080516395d89b4160e01b815290519192506060916001600160a01b038616916395d89b41916004808301926000929190829003018186803b1580156120d557600080fd5b505afa1580156120e9573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052602081101561211257600080fd5b8101908080516040519392919084600160201b82111561213157600080fd5b90830190602082018581111561214657600080fd5b8251600160201b81118282018810171561215f57600080fd5b82525081516020918201929091019080838360005b8381101561218c578181015183820152602001612174565b50505050905090810190601f1680156121b95780820380516001836020036101000a031916815260200191505b5060408181526370a0823160e01b82526110046004830152519495506000946001600160a01b038a1694506370a08231935060248083019350602092829003018186803b15801561220957600080fd5b505afa15801561221d573d6000803e3d6000fd5b505050506040513d602081101561223357600080fd5b5051608087015160608801519192506000916122549163ffffffff611f8416565b9050428760c0015167ffffffffffffffff16101561227a57506001935061121892505050565b612288838860200151612733565b61229a57506002935061121892505050565b808211156122b057506003935061121892505050565b866060015187604001516001600160a01b03166318160ddd6040518163ffffffff1660e01b815260040160206040518083038186803b1580156122f257600080fd5b505afa158015612306573d6000803e3d6000fd5b505050506040513d602081101561231c57600080fd5b50511461233157506004935061121892505050565b8660a0015160ff16841461234d57506005935061121892505050565b602080880151604080516359b9278960e01b8152600481019290925251600092611004926359b927899260248083019392829003018186803b15801561239257600080fd5b505afa1580156123a6573d6000803e3d6000fd5b505050506040513d60208110156123bc57600080fd5b50516001600160a01b031614158061245e57506000801b6110046001600160a01b031663bd46646189604001516040518263ffffffff1660e01b815260040180826001600160a01b03166001600160a01b0316815260200191505060206040518083038186803b15801561242f57600080fd5b505afa158015612443573d6000803e3d6000fd5b505050506040513d602081101561245957600080fd5b505114155b1561247157506006935061121892505050565b5060009695505050505050565b6040805160028082526060828101909352829190816020015b606081526020019060019003908161249757505083519091506124bf9063ffffffff1661281b565b816000815181106124cc57fe5b60200260200101819052506124e7836020015160001c61281b565b816001815181106124f457fe5b6020026020010181905250611fc68161282e565b6000611fc683836040518060400160405280601a81526020017f536166654d6174683a206469766973696f6e206279207a65726f0000000000008152506128b8565b612552612e56565b600061255c612e56565b612564612ea9565b6125756125708661291d565b612942565b90506000805b6125848361298c565b1561268f57806125a95761259f61259a846129ad565b6129fb565b60ff168452612687565b80600114156125c8576125be61259a846129ad565b6020850152612687565b80600214156125f5576125e26125dd846129ad565b612a59565b6001600160a01b03166040850152612687565b80600314156126145761260a61259a846129ad565b6060850152612687565b80600414156126335761262961259a846129ad565b6080850152612687565b80600514156126555761264861259a846129ad565b60ff1660a0850152612687565b80600614156126825761266a61259a846129ad565b67ffffffffffffffff1660c085015260019150612687565b61268f565b60010161257b565b5091935090915050915091565b6000818484111561272b5760405162461bcd60e51b81526004018080602001828103825283818151815260200191508051906020019080838360005b838110156126f05781810151838201526020016126d8565b50505050905090810190601f16801561271d5780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b505050900390565b8151600090839060081080612749575080516003115b15612758576000915050611218565b6040805160208082528183019092526060916020820181803683370190505090508360208201528082518151811061278c57fe5b6020910101516001600160f81b031916602d60f81b146127b157600092505050611218565b600160005b8351811015612811578281815181106127cb57fe5b602001015160f81c60f81b6001600160f81b0319168482815181106127ec57fe5b01602001516001600160f81b031916146128095760009150612811565b6001016127b6565b5095945050505050565b606061121861282983612a73565b612b59565b606081516000141561284f575060408051600081526020810190915261167e565b60608260008151811061285e57fe5b602002602001015190506000600190505b835181101561289f576128958285838151811061288857fe5b6020026020010151612bab565b915060010161286f565b50611fc66128b2825160c060ff16612c28565b82612bab565b600081836129075760405162461bcd60e51b81526020600482018181528351602484015283519092839260449091019190850190808383600083156126f05781810151838201526020016126d8565b50600083858161291357fe5b0495945050505050565b612925612ec9565b506040805180820190915281518152602082810190820152919050565b61294a612ea9565b61295382612d20565b61295c57600080fd5b600061296b8360200151612d5a565b60208085015160408051808201909152868152920190820152915050919050565b6000612996612ec9565b505080518051602091820151919092015191011190565b6129b5612ec9565b6129be8261298c565b6129c757600080fd5b602082015160006129d782612dbd565b80830160209586015260408051808201909152908152938401919091525090919050565b805160009015801590612a1057508151602110155b612a1957600080fd5b6000612a288360200151612d5a565b83516020808601518301805193945091849003929190831015611f7457506020919091036101000a90049392505050565b8051600090601514612a6a57600080fd5b611218826129fb565b604080516020808252818301909252606091829190602082018180368337505050602081018490529050600067ffffffffffffffff198416612ab757506018612adb565b6fffffffffffffffffffffffffffffffff198416612ad757506010612adb565b5060005b6020811015612b1157818181518110612af057fe5b01602001516001600160f81b03191615612b0957612b11565b600101612adb565b60008160200390506060816040519080825280601f01601f191660200182016040528015612b46576020820181803683370190505b5080830196909652508452509192915050565b606081516001148015612b8b5750607f60f81b82600081518110612b7957fe5b01602001516001600160f81b03191611155b15612b9757508061167e565b611218612ba98351608060ff16612c28565b835b6060806040519050835180825260208201818101602087015b81831015612bdc578051835260209283019201612bc4565b50855184518101855292509050808201602086015b81831015612c09578051835260209283019201612bf1565b508651929092011591909101601f01601f191660405250905092915050565b6060680100000000000000008310612c78576040805162461bcd60e51b815260206004820152600e60248201526d696e70757420746f6f206c6f6e6760901b604482015290519081900360640190fd5b60408051600180825281830190925260609160208201818036833701905050905060378411612cd25782840160f81b81600081518110612cb457fe5b60200101906001600160f81b031916908160001a9053509050611218565b6060612cdd85612a73565b90508381510160370160f81b82600081518110612cf657fe5b60200101906001600160f81b031916908160001a905350612d178282612bab565b95945050505050565b8051600090612d315750600061167e565b6020820151805160001a9060c0821015612d505760009250505061167e565b5060019392505050565b8051600090811a6080811015612d7457600091505061167e565b60b8811080612d8f575060c08110801590612d8f575060f881105b15612d9e57600191505061167e565b60c0811015612db25760b51901905061167e565b60f51901905061167e565b80516000908190811a6080811015612dd85760019150612e4f565b60b8811015612ded57607e1981019150612e4f565b60c0811015612e1a5760b78103600185019450806020036101000a85510460018201810193505050612e4f565b60f8811015612e2f5760be1981019150612e4f565b60f78103600185019450806020036101000a855104600182018101935050505b5092915050565b6040805160e081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c081019190915290565b604080518082019091526000808252602082015290565b6040518060400160405280612ebc612ec9565b8152602001600081525090565b60405180604001604052806000815260200160008152509056fe72656c6179466565206d757374206265204e202a203165313020616e642067726561746572207468616e206d696e6952656c6179466565636f6e74616374206164647265737320646f65736e277420657175616c20746f2074686520636f6e7472616374206164647265737320696e2062696e6420726571756573746f6e6c79206265703265206f776e65722063616e20617070726f766520746869732062696e642072657175657374746865206d6573736167652073656e646572206d7573742062652063726f737320636861696e20636f6e7472616374a26469706673582212208d24722e295c34fcc944dfda2183ee07fab7234ce8b7001a715c221bd92ef86e64736f6c63430006040033" - }, - "0x0000000000000000000000000000000000002000": { - "balance": "0x0", - "code": "0x608060405234801561001057600080fd5b50600436106102485760003560e01c8063863fe4ab1161013b578063c81b1662116100b8578063e3b048051161007c578063e3b048051461072c578063f7a251d71461074c578063f9a2bbc7146107c4578063fc3e5908146107cc578063fd6a6879146107d457610248565b8063c81b1662146106dd578063d31f968d146106e5578063d76a867514610714578063dc927faf1461071c578063e1c7392a1461072457610248565b8063a78abc16116100ff578063a78abc16146105d3578063ab51bb96146105db578063ac431751146105e3578063b0355f5b146103ff578063c27cdcfb146106a157610248565b8063863fe4ab146105b35780638cc8f561146104b657806396713da9146105bb5780639dc09262146105c3578063a1a11bf5146105cb57610248565b8063493279b1116101c957806370fd5bad1161018d57806370fd5bad146104b657806374f079b8146104be57806375d47a0a146104c65780637942fd05146104ce57806384013b6a146104d657610248565b8063493279b11461045f5780634bf6c8821461047e57806351e80672146104865780636e47a51a1461048e5780636e47b482146104ae57610248565b8063308325f411610210578063308325f4146102cf5780633bdc47a6146102d75780633dffc387146103ff578063422f90501461040757806343756e5c1461043b57610248565b806305e682581461024d5780630bee7a671461026b57806314b3023b1461028c57806322556cdc146102a65780632ff32aea146102ae575b600080fd5b6102556107dc565b6040805160ff9092168252519081900360200190f35b6102736107e1565b6040805163ffffffff9092168252519081900360200190f35b6102946107e6565b60408051918252519081900360200190f35b6102946107ec565b6102b66107f1565b60408051600792830b90920b8252519081900360200190f35b6102946107fa565b61038a600480360360608110156102ed57600080fd5b60ff82351691602081013591810190606081016040820135600160201b81111561031657600080fd5b82018360208201111561032857600080fd5b803590602001918460018302840111600160201b8311171561034957600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250929550610800945050505050565b6040805160208082528351818301528351919283929083019185019080838360005b838110156103c45781810151838201526020016103ac565b50505050905090810190601f1680156103f15780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b610255610876565b6104276004803603602081101561041d57600080fd5b503560ff1661087b565b604080519115158252519081900360200190f35b610443610890565b604080516001600160a01b039092168252519081900360200190f35b610467610896565b6040805161ffff9092168252519081900360200190f35b61025561089b565b6104436108a0565b610443600480360360208110156104a457600080fd5b503560ff166108a6565b6104436108c1565b6102556108c7565b6102946108cc565b6104436108d2565b6102556108d8565b6105b1600480360360a08110156104ec57600080fd5b810190602081018135600160201b81111561050657600080fd5b82018360208201111561051857600080fd5b803590602001918460018302840111600160201b8311171561053957600080fd5b919390929091602081019035600160201b81111561055657600080fd5b82018360208201111561056857600080fd5b803590602001918460018302840111600160201b8311171561058957600080fd5b919350915080356001600160401b03908116916020810135909116906040013560ff166108dd565b005b610294611a8d565b610255611a95565b610443611a9a565b610443611aa0565b610427611aa6565b6102736107dc565b6105b1600480360360408110156105f957600080fd5b810190602081018135600160201b81111561061357600080fd5b82018360208201111561062557600080fd5b803590602001918460018302840111600160201b8311171561064657600080fd5b919390929091602081019035600160201b81111561066357600080fd5b82018360208201111561067557600080fd5b803590602001918460018302840111600160201b8311171561069657600080fd5b509092509050611aaf565b6106c1600480360360208110156106b757600080fd5b503560ff16612046565b604080516001600160401b039092168252519081900360200190f35b610443612061565b610427600480360360408110156106fb57600080fd5b5080356001600160a01b0316906020013560ff16612067565b61038a612087565b6104436120a6565b6105b16120ac565b6106c16004803603602081101561074257600080fd5b503560ff16612463565b6104276004803603606081101561076257600080fd5b60ff8235169190810190604081016020820135600160201b81111561078657600080fd5b82018360208201111561079857600080fd5b803590602001918460018302840111600160201b831117156107b957600080fd5b91935091503561247e565b6104436125d0565b6102556125d6565b6104436125db565b600081565b606481565b60015481565b603281565b60045460070b81565b60025481565b60606000825160210190506060816040519080825280601f01601f191660200182016040528015610838576020820181803683370190505b506021810186905260018101879052828152905060418101600061085b866125e1565b50905061086a818388516125eb565b50909695505050505050565b600181565b60096020526000908152604090205460ff1681565b61100181565b606181565b600881565b61200081565b6005602052600090815260409020546001600160a01b031681565b61100581565b600281565b60035481565b61100881565b600b81565b60005460ff16610930576040805162461bcd60e51b81526020600482015260196024820152781d1a194818dbdb9d1c9858dd081b9bdd081a5b9a5d081e595d603a1b604482015290519081900360640190fd5b60408051630a83aaa960e31b815233600482015290516110069163541d5548916024808301926020929190829003018186803b15801561096f57600080fd5b505afa158015610983573d6000803e3d6000fd5b505050506040513d602081101561099957600080fd5b50516109ec576040805162461bcd60e51b815260206004820152601f60248201527f746865206d73672073656e646572206973206e6f7420612072656c6179657200604482015290519081900360640190fd5b60ff8116600090815260086020526040902054829082906001600160401b039081169083168114610a5c576040805162461bcd60e51b815260206004820152601560248201527439b2b8bab2b731b2903737ba1034b71037b93232b960591b604482015290519081900360640190fd5b60ff8216600090815260086020908152604091829020805467ffffffffffffffff1916600185016001600160401b039081169190911790915582516337d7f9c160e21b81529089166004820152915188926110039263df5fe70492602480840193829003018186803b158015610ad157600080fd5b505afa158015610ae5573d6000803e3d6000fd5b505050506040513d6020811015610afb57600080fd5b5051610b385760405162461bcd60e51b8152600401808060200182810382526023815260200180612b686023913960400191505060405180910390fd5b60ff851660009081526005602052604090205485906001600160a01b0316610ba7576040805162461bcd60e51b815260206004820152601860248201527f6368616e6e656c206973206e6f7420737570706f727465640000000000000000604482015290519081900360640190fd5b60608c8c8080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f82011690508083019250505050505050905060608b8b8080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250506040805163cba510a960e01b81526001600160401b038f1660048201529051939450610cce93611003935063cba510a992506024808301926020929190829003018186803b158015610c7757600080fd5b505afa158015610c8b573d6000803e3d6000fd5b505050506040513d6020811015610ca157600080fd5b505160408051808201909152600381526269626360e81b6020820152610cc78c8c61262c565b8585612673565b610d16576040805162461bcd60e51b815260206004820152601460248201527334b73b30b634b21036b2b935b63290383937b7b360611b604482015290519081900360640190fd5b60408051631bb5062960e31b81526001600160401b038c16600482015290516000916110039163dda8314891602480820192602092909190829003018186803b158015610d6257600080fd5b505afa158015610d76573d6000803e3d6000fd5b505050506040513d6020811015610d8c57600080fd5b5051905088600080806060610da088612770565b935093509350935083610e61578460ff168f6001600160401b03167ff7b2e42d694eb1100184aae86d4245d9e46966100b1dc7e723275b98326854ac8a6040518080602001828103825283818151815260200191508051906020019080838360005b83811015610e1a578181015183820152602001610e02565b50505050905090810190601f168015610e475780820380516001836020036101000a031916815260200191505b509250505060405180910390a35050505050505050611a7f565b8460ff168f6001600160401b03167f36afdaf439a8f43fe72135135d804ae620b37a474f0943b5b85f6788312cad4085604051808260ff1660ff16815260200191505060405180910390a360ff83166113ea5760ff85166000818152600560209081526040808320548151631182b87560e01b815260048101958652602481019283528651604482015286516001600160a01b03909216958695631182b875958d958a9593949093606490910192918601918190849084905b83811015610f32578181015183820152602001610f1a565b50505050905090810190601f168015610f5f5780820380516001836020036101000a031916815260200191505b509350505050600060405180830381600087803b158015610f7f57600080fd5b505af192505050801561106357506040513d6000823e601f3d908101601f191682016040526020811015610fb257600080fd5b8101908080516040519392919084600160201b821115610fd157600080fd5b908301906020820185811115610fe657600080fd5b8251600160201b811182820188101715610fff57600080fd5b82525081516020918201929091019080838360005b8381101561102c578181015183820152602001611014565b50505050905090810190601f1680156110595780820380516001836020036101000a031916815260200191505b5060405250505060015b611375576040516000815260443d101561107f5750600061111a565b60046000803e60005160e01c6308c379a081146110a057600091505061111a565b60043d036004833e81513d60248201116001600160401b03821117156110cb5760009250505061111a565b80830180516001600160401b038111156110ec57600094505050505061111a565b8060208301013d860181111561110a5760009550505050505061111a565b601f01601f191660405250925050505b806111255750611237565b60ff871660009081526007602052604081205461115c916001600160401b039091169089906111579060029088610800565b612820565b60ff8716600090815260076020908152604080832080546001600160401b038082166001011667ffffffffffffffff19909116179055805182815284518184015284516001600160a01b038716947ff91a8f63e5b3e0e89e5f93e1915a7805f3c52d9a73b3c09769785c2c7bf87acf948794849390840192918601918190849084905b838110156111f75781810151838201526020016111df565b50505050905090810190601f1680156112245780820380516001836020036101000a031916815260200191505b509250505060405180910390a250611370565b3d808015611261576040519150601f19603f3d011682016040523d82523d6000602084013e611266565b606091505b5060ff8716600090815260076020526040812054611299916001600160401b039091169089906111579060029088610800565b60ff8716600090815260076020908152604080832080546001600160401b038082166001011667ffffffffffffffff19909116179055805182815284518184015284516001600160a01b038716947f63ac299d6332d1cc4e61b81e59bc00c0ac7c798addadf33840f1307cd2977351948794849390840192918601918190849084905b8381101561133457818101518382015260200161131c565b50505050905090810190601f1680156113615780820380516001836020036101000a031916815260200191505b509250505060405180910390a2505b6113e4565b8051156113e25760ff87166000908152600760205260408120546113ae916001600160401b039091169089906111579060019086610800565b60ff8716600090815260076020526040902080546001600160401b038082166001011667ffffffffffffffff199091161790555b505b506119b8565b60ff83166001141561168e5760ff8516600081815260056020908152604080832054815163831d65d160e01b815260048101958652602481019283528651604482015286516001600160a01b0390921695869563831d65d1958d958a9593949093606490910192918601918190849084905b8381101561147457818101518382015260200161145c565b50505050905090810190601f1680156114a15780820380516001836020036101000a031916815260200191505b509350505050600060405180830381600087803b1580156114c157600080fd5b505af19250505080156114d2575060015b6113e4576040516000815260443d10156114ee57506000611589565b60046000803e60005160e01c6308c379a0811461150f576000915050611589565b60043d036004833e81513d60248201116001600160401b038211171561153a57600092505050611589565b80830180516001600160401b0381111561155b576000945050505050611589565b8060208301013d860181111561157957600095505050505050611589565b601f01601f191660405250925050505b8061159457506115f9565b60408051602080825283518183015283516001600160a01b038616937ff91a8f63e5b3e0e89e5f93e1915a7805f3c52d9a73b3c09769785c2c7bf87acf93869390928392830191850190808383600083156111f75781810151838201526020016111df565b3d808015611623576040519150601f19603f3d011682016040523d82523d6000602084013e611628565b606091505b5060408051602080825283518183015283516001600160a01b038616937f63ac299d6332d1cc4e61b81e59bc00c0ac7c798addadf33840f1307cd2977351938693909283928301918501908083836000831561133457818101518382015260200161131c565b60ff8316600214156119b85760ff8516600081815260056020908152604080832054815163c8509d8160e01b815260048101958652602481019283528651604482015286516001600160a01b0390921695869563c8509d81958d958a9593949093606490910192918601918190849084905b83811015611718578181015183820152602001611700565b50505050905090810190601f1680156117455780820380516001836020036101000a031916815260200191505b509350505050600060405180830381600087803b15801561176557600080fd5b505af1925050508015611776575060015b6119b6576040516000815260443d10156117925750600061182d565b60046000803e60005160e01c6308c379a081146117b357600091505061182d565b60043d036004833e81513d60248201116001600160401b03821117156117de5760009250505061182d565b80830180516001600160401b038111156117ff57600094505050505061182d565b8060208301013d860181111561181d5760009550505050505061182d565b601f01601f191660405250925050505b8061183857506118e1565b816001600160a01b03167ff91a8f63e5b3e0e89e5f93e1915a7805f3c52d9a73b3c09769785c2c7bf87acf826040518080602001828103825283818151815260200191508051906020019080838360005b838110156118a1578181015183820152602001611889565b50505050905090810190601f1680156118ce5780820380516001836020036101000a031916815260200191505b509250505060405180910390a2506119b6565b3d80801561190b576040519150601f19603f3d011682016040523d82523d6000602084013e611910565b606091505b50816001600160a01b03167f63ac299d6332d1cc4e61b81e59bc00c0ac7c798addadf33840f1307cd2977351826040518080602001828103825283818151815260200191508051906020019080838360005b8381101561197a578181015183820152602001611962565b50505050905090810190601f1680156119a75780820380516001836020036101000a031916815260200191505b509250505060405180910390a2505b505b60ff80861660009081526009602052604090205461100591636f93d2e69189913391879116806119ea575060ff881615155b604080516001600160e01b031960e088901b1681526001600160a01b039586166004820152939094166024840152604483019190915215156064820152905160848083019260209291908290030181600087803b158015611a4a57600080fd5b505af1158015611a5e573d6000803e3d6000fd5b505050506040513d6020811015611a7457600080fd5b505050505050505050505b505050505050505050505050565b630100610081565b600981565b61100781565b61100681565b60005460ff1681565b3361100714611aef5760405162461bcd60e51b815260040180806020018281038252602e815260200180612abe602e913960400191505060405180910390fd5b611b5884848080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525050604080518082019091526012815271626174636853697a65466f724f7261636c6560701b602082015291506129769050565b15611bf357604080516020601f8401819004810282018101909252828152600091611b9b91858580838501838280828437600092019190915250612a5d92505050565b90506127108111158015611bb05750600a8110155b611beb5760405162461bcd60e51b8152600401808060200182810382526032815260200180612b366032913960400191505060405180910390fd5b600155611fb4565b611c5484848080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152505060408051808201909152600a81526918591910da185b9b995b60b21b602082015291506129769050565b15611dd957606082828080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152505082519293505060169091149050611cd75760405162461bcd60e51b8152600401808060200182810382526052815260200180612b8b6052913960600191505060405180910390fd5b600181015160028201516016830151611cef81612a62565b611d40576040805162461bcd60e51b815260206004820152601960248201527f61646472657373206973206e6f74206120636f6e747261637400000000000000604482015290519081900360640190fd5b60ff808416600081815260056020908152604080832080546001600160a01b0388166001600160a01b03199091168117909155808452600683528184208585528352818420805460ff19908116600117909155600990935281842080549093169588161595909517909155517f7e3b6af43092577ee20e60eaa1d9b114a7031305c895ee7dd3ffe17196d2e1e09190a350505050611fb4565b611e4684848080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525050604080518082019091526016815275195b98589b1953dc911a5cd8589b1950da185b9b995b60521b602082015291506129769050565b15611f7757606082828080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152505082519293505060029091149050611ec95760405162461bcd60e51b815260040180806020018281038252604a815260200180612aec604a913960600191505060405180910390fd5b600181810151600283015160ff80831660009081526005602052604090205492939192908316909114906001600160a01b03168015611f6d576001600160a01b038116600090815260066020908152604080832060ff881680855290835292819020805460ff1916861515908117909155815190815290517fa3132e3f9819fbddc7f0ed6d38d7feef59aa95112090b7c592f5cb5bc4aa4adc929181900390910190a25b5050505050611fb4565b6040805162461bcd60e51b815260206004820152600d60248201526c756e6b6e6f776e20706172616d60981b604482015290519081900360640190fd5b7f6cdb0ac70ab7f2e2d035cca5be60d89906f2dede7648ddbd7402189c1eeed17a848484846040518080602001806020018381038352878782818152602001925080828437600083820152601f01601f191690910184810383528581526020019050858580828437600083820152604051601f909101601f19169092018290039850909650505050505050a150505050565b6008602052600090815260409020546001600160401b031681565b61100281565b600660209081526000928352604080842090915290825290205460ff1681565b6040518060400160405280600381526020016269626360e81b81525081565b61100381565b60005460ff1615612104576040805162461bcd60e51b815260206004820152601960248201527f74686520636f6e747261637420616c726561647920696e697400000000000000604482015290519081900360640190fd5b7f1471eb6eb2c5e789fc3de43f8ce62938c7d1836ec861730447e2ada8fd81017b80546001600160a01b0319908116611008179091557f92e85d02570a8092d09a6e3a57665bc3815a2699a4074001bf1ccabf660f5a36805460ff199081169091557fd8af288fc1c8680b4f4706064cf021e264efb6828fcaf7eb5ca36818eb365bcc8054821660019081179091557f89832631fb3c3307a103ba2c84ab569c64d6182a18893dcd163f0f1c2090733a805484166110049081179091557f6cde3cea4b3a3fb2488b2808bae7556f4a405e50f65e1794383bc026131b13c38054841690557f72e4efa1513b071517c6c74dba31b5934a81aa83cddd400e7081df5529c9943680548416831790557fa9bc9a3a348c357ba16b37005d7e6b3236198c0e939f4af8c5f19b8deeb8ebc08054851690911790557fc575c31fea594a6eb97c8e9d3f9caee4c16218c6ef37e923234c0fe9014a61e78054831690557f4e523af77f034e9810f1c94057f5e931fb3d16a51511a4c3add793617d18610580548316821790557ffb33122aa9f93cc639ebe80a7bc4784c11e6053dde89c6f4f7e268c6a623da1e805484166110001790557fc7694af312c4f286114180fd0ba6a52461fcee8a381636770b19a343af92538a80548316821790557f01112dd68e482ba8d68a7e828cff8b3abcea08eab88941953c180a7e650e9cd480548316821790557fc0a4a8be475dfebc377ebef2d7c4ff47656f572a08dd92b81017efcdba0febe1805484166110071790557f87e8a52529e8ece4ef759037313542a6429ff494a9fab9027fb79db90124eba680548316821790557f4c7666bbcb22d46469f7cc282f70764a7012dca2cce630ff8d83db9a9cdd48f080548316821790557f40f28f99a40bc9f6beea1013afdbc3cdcc689eb76b82c4de06c0acf1e1932ed58054909316611001179092557f0d9cf2cd531699eed8dd34e40ff2884a14a698c4898184fba85194e6f6772d248054821683179055600b60009081527f23f68c9bd22b8a93d06adabe17481c87c016bcbd20adc8bfd707a4d813a572176020527fdf0d5d05428057f5455c2dc8e810dd86d1e9350faa72f16bda8a45443c5b39328054831684179055603283556004805467ffffffffffffffff19166001600160401b031790556002819055600381905580549091169091179055565b6007602052600090815260409020546001600160401b031681565b6000805460ff166124d2576040805162461bcd60e51b81526020600482015260196024820152781d1a194818dbdb9d1c9858dd081b9bdd081a5b9a5d081e595d603a1b604482015290519081900360640190fd5b33600090815260066020908152604080832060ff808a16855292529091205486911661252f5760405162461bcd60e51b8152600401808060200182810382526031815260200180612a8d6031913960400191505060405180910390fd5b60ff86166000908152600760209081526040808320548151601f89018490048402810184019092528782526001600160401b0316926125949284928b926111579290918a918d908d908190840183828082843760009201919091525061080092505050565b60ff969096166000908152600760205260409020805467ffffffffffffffff191660019788016001600160401b03161790555093949350505050565b61100081565b600381565b61100481565b8051602090910191565b5b6020811061260b578251825260209283019290910190601f19016125ec565b915181516020939093036101000a6000190180199091169216919091179052565b60408051600e808252818301909252606091630100610060ff851617918391602082018180368337505050600e818101969096526006810192909252509283525090919050565b60008561268257506000612767565b606082518451865160800101016040519080825280601f01601f1916602001820160405280156126b9576020820181803683370190505b50905060006126c782612a68565b6020808901518252019050866000806126df896125e1565b80865260209095019490925090506126f88285836125eb565b92830192612705886125e1565b808652602090950194909250905061271e8285836125eb565b9283018a815260200192612731876125e1565b90925090506127418285836125eb565b50835160200161274f612a6e565b60208183886065600019fa5051600114955050505050505b95945050505050565b600080600060606021855110156127a0575050604080516000808252602082019092529092508291508190612819565b600185015160218601518651604080516020198301808252601f19600119909401939093168101602001909152604189019392916060919080156127eb576020820181803683370190505b50905060006127f9826125e1565b50905061280b858260218d51036125eb565b506001975091955093509150505b9193509193565b60025443111561285f576004805467ffffffffffffffff1981166001600160401b036001600793840b810190930b1617909155600355436002556128a0565b600380546001908101918290555410156128a0576004805467ffffffffffffffff1981166001600160401b036001600793840b810190930b16179091556003555b8160ff16836001600160401b0316600460009054906101000a900460070b6001600160401b03167f3a6e0fc61675aa2a100bcba0568368bb92bcec91c97673391074f11138f0cffe606185604051808361ffff1661ffff16815260200180602001828103825283818151815260200191508051906020019080838360005b8381101561293657818101518382015260200161291e565b50505050905090810190601f1680156129635780820380516001836020036101000a031916815260200191505b50935050505060405180910390a4505050565b6000816040516020018082805190602001908083835b602083106129ab5780518252601f19909201916020918201910161298c565b6001836020036101000a03801982511681845116808217855250505050505090500191505060405160208183030381529060405280519060200120836040516020018082805190602001908083835b60208310612a195780518252601f1990920191602091820191016129fa565b6001836020036101000a0380198251168184511680821785525050505050509050019150506040516020818303038152906040528051906020012014905092915050565b015190565b3b151590565b60200190565b6040518060200160405280600190602082028036833750919291505056fe74686520636f6e747261637420616e64206368616e6e656c2068617665206e6f74206265656e2072656769737465726564746865206d6573736167652073656e646572206d75737420626520676f7665726e616e636520636f6e74726163746c656e677468206f662076616c756520666f7220656e61626c654f7244697361626c654368616e6e656c2073686f756c6420626520322c206368616e6e656c49643a6973456e61626c65746865206e6577426174636853697a65466f724f7261636c652073686f756c6420626520696e205b31302c2031303030305d6c6967687420636c69656e74206e6f742073796e632074686520626c6f636b207965746c656e677468206f662076616c756520666f72206164644368616e6e656c2073686f756c642062652032322c206368616e6e656c49643a697346726f6d53797374656d3a68616e646c657241646472657373a2646970667358221220230d7e9288613f5afb55ab3692ab4b25169e86ce53da4ef6333e3703c1351f7864736f6c63430006040033" - }, - "9fB29AAc15b9A4B7F17c3385939b007540f4d791": { - "balance": "0x84595161401484a000000" - }, - "37B8516a0F88E65D677229b402ec6C1e0E333004": { - "balance": "0x84595161401484a000000" - } + "0xffffFFFfFFffffffffffffffFfFFFfffFFFfFFfE": { + "balance": "0x0" + }, + "0x0000000000000000000000000000000000001000": { + "balance": "0x0", + "code": "0x6080604052600436106102675760003560e01c806396713da911610144578063c81b1662116100b6578063eb57e2021161007a578063eb57e20214610900578063eda5868c14610933578063f340fa0114610948578063f9a2bbc71461096e578063fc3e590814610983578063fd6a68791461099857610267565b8063c81b1662146108ac578063c8509d81146105f3578063d86222d5146108c1578063dc927faf146108d6578063e1c7392a146108eb57610267565b8063aaf5eb6811610108578063aaf5eb681461071f578063ab51bb9614610734578063ac43175114610749578063ad3c9da614610814578063b7ab4db514610847578063bf9f49951461040557610267565b806396713da9146106a25780639dc09262146106b7578063a1a11bf5146106cc578063a5422d5c146106e1578063a78abc16146106f657610267565b80635667515a116101dd57806375d47a0a116101a157806375d47a0a146105b45780637942fd05146105c957806381650b62146105de578063831d65d1146105f3578063853230aa14610678578063862498821461068d57610267565b80635667515a146104ea5780635d77156c146104ff5780636969a25c146105145780636e47b4821461058a57806370fd5bad1461059f57610267565b80633dffc3871161022f5780633dffc3871461040557806343756e5c14610430578063493279b1146104615780634bf6c8821461048d57806351e80672146104a2578063565c56b3146104b757610267565b80630bee7a671461026c5780631182b8751461029a5780631ff1806914610394578063219f22d5146103bb57806335409f7f146103d0575b600080fd5b34801561027857600080fd5b506102816109ad565b6040805163ffffffff9092168252519081900360200190f35b3480156102a657600080fd5b5061031f600480360360408110156102bd57600080fd5b60ff8235169190810190604081016020820135600160201b8111156102e157600080fd5b8201836020820111156102f357600080fd5b803590602001918460018302840111600160201b8311171561031457600080fd5b5090925090506109b2565b6040805160208082528351818301528351919283929083019185019080838360005b83811015610359578181015183820152602001610341565b50505050905090810190601f1680156103865780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b3480156103a057600080fd5b506103a9610b26565b60408051918252519081900360200190f35b3480156103c757600080fd5b50610281610b2c565b3480156103dc57600080fd5b50610403600480360360208110156103f357600080fd5b50356001600160a01b0316610b31565b005b34801561041157600080fd5b5061041a610e45565b6040805160ff9092168252519081900360200190f35b34801561043c57600080fd5b50610445610e4a565b604080516001600160a01b039092168252519081900360200190f35b34801561046d57600080fd5b50610476610e50565b6040805161ffff9092168252519081900360200190f35b34801561049957600080fd5b5061041a610e55565b3480156104ae57600080fd5b50610445610e5a565b3480156104c357600080fd5b506103a9600480360360208110156104da57600080fd5b50356001600160a01b0316610e60565b3480156104f657600080fd5b5061041a610eb2565b34801561050b57600080fd5b50610281610eb7565b34801561052057600080fd5b5061053e6004803603602081101561053757600080fd5b5035610ebc565b604080516001600160a01b039788168152958716602087015293909516848401526001600160401b0390911660608401521515608083015260a082019290925290519081900360c00190f35b34801561059657600080fd5b50610445610f20565b3480156105ab57600080fd5b5061041a610f26565b3480156105c057600080fd5b50610445610f2b565b3480156105d557600080fd5b5061041a610f31565b3480156105ea57600080fd5b50610281610f36565b3480156105ff57600080fd5b506104036004803603604081101561061657600080fd5b60ff8235169190810190604081016020820135600160201b81111561063a57600080fd5b82018360208201111561064c57600080fd5b803590602001918460018302840111600160201b8311171561066d57600080fd5b509092509050610f3b565b34801561068457600080fd5b506103a9610fee565b34801561069957600080fd5b506103a9610ff4565b3480156106ae57600080fd5b5061041a610ffa565b3480156106c357600080fd5b50610445610fff565b3480156106d857600080fd5b50610445611005565b3480156106ed57600080fd5b5061031f61100b565b34801561070257600080fd5b5061070b61102a565b604080519115158252519081900360200190f35b34801561072b57600080fd5b506103a9611033565b34801561074057600080fd5b50610281610eb2565b34801561075557600080fd5b506104036004803603604081101561076c57600080fd5b810190602081018135600160201b81111561078657600080fd5b82018360208201111561079857600080fd5b803590602001918460018302840111600160201b831117156107b957600080fd5b919390929091602081019035600160201b8111156107d657600080fd5b8201836020820111156107e857600080fd5b803590602001918460018302840111600160201b8311171561080957600080fd5b50909250905061103c565b34801561082057600080fd5b506103a96004803603602081101561083757600080fd5b50356001600160a01b03166112e3565b34801561085357600080fd5b5061085c6112f5565b60408051602080825283518183015283519192839290830191858101910280838360005b83811015610898578181015183820152602001610880565b505050509050019250505060405180910390f35b3480156108b857600080fd5b5061044561141b565b3480156108cd57600080fd5b506103a9611421565b3480156108e257600080fd5b5061044561142d565b3480156108f757600080fd5b50610403611433565b34801561090c57600080fd5b506104036004803603602081101561092357600080fd5b50356001600160a01b0316611636565b34801561093f57600080fd5b50610281611805565b6104036004803603602081101561095e57600080fd5b50356001600160a01b031661180a565b34801561097a57600080fd5b50610445611a20565b34801561098f57600080fd5b5061041a611a26565b3480156109a457600080fd5b50610445611a2b565b606481565b60005460609060ff16610a08576040805162461bcd60e51b81526020600482015260196024820152781d1a194818dbdb9d1c9858dd081b9bdd081a5b9a5d081e595d603a1b604482015290519081900360640190fd5b3361200014610a485760405162461bcd60e51b815260040180806020018281038252602f815260200180613f73602f913960400191505060405180910390fd5b610a50613c27565b6000610a9185858080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250611a3192505050565b9150915080610aad57610aa46064611b8a565b92505050610b1f565b815160009060ff16610acd57610ac68360200151611beb565b9050610aeb565b825160ff1660011415610ae757610ac683602001516129ec565b5060655b63ffffffff8116610b105750506040805160008152602081019091529150610b1f9050565b610b1981611b8a565b93505050505b9392505050565b60035481565b606881565b3361100114610b715760405162461bcd60e51b8152600401808060200182810382526029815260200180613fcf6029913960400191505060405180910390fd5b6001600160a01b03811660009081526004602052604090205480610b955750610e42565b600181039050600060018281548110610baa57fe5b60009182526020909120600360049092020101546001549091506000190180610bf957600060018481548110610bdc57fe5b906000526020600020906004020160030181905550505050610e42565b6040805183815290516001600160a01b038616917f3b6f9ef90462b512a1293ecec018670bf7b7f1876fb727590a8a6d7643130a70919081900360200190a26001600160a01b038416600090815260046020526040812055600154600019018314610d7b57600180546000198101908110610c7057fe5b906000526020600020906004020160018481548110610c8b57fe5b6000918252602082208354600492830290910180546001600160a01b03199081166001600160a01b0393841617825560018087015481840180548416918616919091179055600280880180549185018054909416919095161780835584546001600160401b03600160a01b91829004160267ffffffffffffffff60a01b1990911617808355935460ff600160e01b918290041615150260ff60e01b199094169390931790556003948501549401939093558254868401939192919087908110610d5057fe5b600091825260208083206004909202909101546001600160a01b031683528201929092526040019020555b6001805480610d8657fe5b60008281526020812060046000199093019283020180546001600160a01b0319908116825560018201805490911690556002810180546001600160e81b03191690556003018190559155818381610dd957fe5b0490508015610e3d5760015460005b81811015610e3a578260018281548110610dfe57fe5b9060005260206000209060040201600301540160018281548110610e1e57fe5b6000918252602090912060036004909202010155600101610de8565b50505b505050505b50565b600181565b61100181565b606181565b600881565b61200081565b6001600160a01b03811660009081526004602052604081205480610e88576000915050610ead565b600180820381548110610e9757fe5b9060005260206000209060040201600301549150505b919050565b600081565b606781565b60018181548110610ec957fe5b600091825260209091206004909102018054600182015460028301546003909301546001600160a01b0392831694509082169291821691600160a01b81046001600160401b031691600160e01b90910460ff169086565b61100581565b600281565b61100881565b600b81565b606681565b3361200014610f7b5760405162461bcd60e51b815260040180806020018281038252602f815260200180613f73602f913960400191505060405180910390fd5b7f41ce201247b6ceb957dcdb217d0b8acb50b9ea0e12af9af4f5e7f38902101605838383604051808460ff1660ff168152602001806020018281038252848482818152602001925080828437600083820152604051601f909101601f1916909201829003965090945050505050a1505050565b6103e881565b60025481565b600981565b61100781565b61100681565b604051806101e001604052806101b78152602001613d9b6101b7913981565b60005460ff1681565b6402540be40081565b60005460ff1661108f576040805162461bcd60e51b81526020600482015260196024820152781d1a194818dbdb9d1c9858dd081b9bdd081a5b9a5d081e595d603a1b604482015290519081900360640190fd5b33611007146110cf5760405162461bcd60e51b815260040180806020018281038252602e815260200180613d26602e913960400191505060405180910390fd5b61113984848080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525050604080518082019091526013815272065787069726554696d655365636f6e6447617606c1b60208201529150612c2a9050565b15611214576020811461117d5760405162461bcd60e51b8152600401808060200182810382526026815260200180613d756026913960400191505060405180910390fd5b604080516020601f84018190048102820181019092528281526000916111bb91858580838501838280828437600092019190915250612d1292505050565b9050606481101580156111d15750620186a08111155b61120c5760405162461bcd60e51b8152600401808060200182810382526027815260200180613cda6027913960400191505060405180910390fd5b600255611251565b6040805162461bcd60e51b815260206004820152600d60248201526c756e6b6e6f776e20706172616d60981b604482015290519081900360640190fd5b7f6cdb0ac70ab7f2e2d035cca5be60d89906f2dede7648ddbd7402189c1eeed17a848484846040518080602001806020018381038352878782818152602001925080828437600083820152601f01601f191690910184810383528581526020019050858580828437600083820152604051601f909101601f19169092018290039850909650505050505050a150505050565b60046020526000908152604090205481565b6001546060906000805b82811015611346576001818154811061131457fe5b9060005260206000209060040201600201601c9054906101000a900460ff1661133e576001909101905b6001016112ff565b50606081604051908082528060200260200182016040528015611373578160200160208202803683370190505b50600092509050815b83811015611413576001818154811061139157fe5b9060005260206000209060040201600201601c9054906101000a900460ff1661140b57600181815481106113c157fe5b600091825260209091206004909102015482516001600160a01b03909116908390859081106113ec57fe5b6001600160a01b03909216602092830291909101909101526001909201915b60010161137c565b509250505090565b61100281565b67016345785d8a000081565b61100381565b60005460ff161561148b576040805162461bcd60e51b815260206004820152601960248201527f74686520636f6e747261637420616c726561647920696e697400000000000000604482015290519081900360640190fd5b611493613c27565b60006114b9604051806101e001604052806101b78152602001613d9b6101b79139611a31565b91509150806114f95760405162461bcd60e51b8152600401808060200182810382526021815260200180613f526021913960400191505060405180910390fd5b60005b82602001515181101561161e5760018360200151828151811061151b57fe5b60209081029190910181015182546001818101855560009485528385208351600493840290910180546001600160a01b039283166001600160a01b03199182161782558587015182850180549185169183169190911790556040860151600283018054606089015160808a01511515600160e01b0260ff60e01b196001600160401b03909216600160a01b0267ffffffffffffffff60a01b199590981692909516919091179290921694909417161790915560a0909301516003909301929092559186015180519185019391859081106115f157fe5b602090810291909101810151516001600160a01b03168252810191909152604001600020556001016114fc565b50506103e8600255506000805460ff19166001179055565b33611001146116765760405162461bcd60e51b8152600401808060200182810382526029815260200180613fcf6029913960400191505060405180910390fd5b6001600160a01b0381166000908152600460205260409020548061169a5750610e42565b6001810390506000600182815481106116af57fe5b90600052602060002090600402016003015490506000600183815481106116d257fe5b906000526020600020906004020160030181905550600060018080549050039050836001600160a01b03167f8cd4e147d8af98a9e3b6724021b8bf6aed2e5dac71c38f2dce8161b82585b25d836040518082815260200191505060405180910390a28061174157505050610e42565b600081838161174c57fe5b0490508015610e3d5760005b848110156117aa57816001828154811061176e57fe5b906000526020600020906004020160030154016001828154811061178e57fe5b6000918252602090912060036004909202010155600101611758565b50600180549085015b81811015610e3a5782600182815481106117c957fe5b90600052602060002090600402016003015401600182815481106117e957fe5b60009182526020909120600360049092020101556001016117b3565b606581565b3341146118485760405162461bcd60e51b815260040180806020018281038252602d815260200180613fa2602d913960400191505060405180910390fd5b60005460ff1661189b576040805162461bcd60e51b81526020600482015260196024820152781d1a194818dbdb9d1c9858dd081b9bdd081a5b9a5d081e595d603a1b604482015290519081900360640190fd5b600034116118e8576040805162461bcd60e51b81526020600482015260156024820152746465706f7369742076616c7565206973207a65726f60581b604482015290519081900360640190fd5b6001600160a01b038116600090815260046020526040902054349080156119db57600060018083038154811061191a57fe5b9060005260206000209060040201905080600201601c9054906101000a900460ff1615611985576040805184815290516001600160a01b038616917ff177e5d6c5764d79c32883ed824111d9b13f5668cf6ab1cc12dd36791dd955b4919081900360200190a26119d5565b600380548401815581018054840190556040805184815290516001600160a01b038616917f93a090ecc682c002995fad3c85b30c5651d7fd29b0be5da9d784a3302aedc055919081900360200190a25b50611a1b565b6040805183815290516001600160a01b038516917ff177e5d6c5764d79c32883ed824111d9b13f5668cf6ab1cc12dd36791dd955b4919081900360200190a25b505050565b61100081565b600381565b61100481565b611a39613c27565b6000611a43613c27565b611a4b613c3f565b611a5c611a5786612d17565b612d3c565b90506000805b611a6b83612d86565b15611b7c5780611a9057611a86611a8184612da7565b612df5565b60ff168452611b74565b8060011415611b6f576060611aac611aa785612da7565b612e55565b90508051604051908082528060200260200182016040528015611ae957816020015b611ad6613c5f565b815260200190600190039081611ace5790505b50602086015260005b8151811015611b6457611b03613c5f565b6000611b21848481518110611b1457fe5b6020026020010151612f26565b9150915080611b3e57876000995099505050505050505050611b85565b8188602001518481518110611b4f57fe5b60209081029190910101525050600101611af2565b506001925050611b74565b611b7c565b600101611a62565b50919350909150505b915091565b604080516001808252818301909252606091829190816020015b6060815260200190600190039081611ba4579050509050611bca8363ffffffff16613003565b81600081518110611bd757fe5b6020026020010181905250610b1f81613016565b6000806060611bf9846130a0565b9150915081611ca6577f70e72399380dcfb0338abc03dc8d47f9f470ada8e769c9a78d644ea97385ecb2816040518080602001828103825283818151815260200191508051906020019080838360005b83811015611c61578181015183820152602001611c49565b50505050905090810190601f168015611c8e5780820380516001836020036101000a031916815260200191505b509250505060405180910390a1606692505050610ead565b600080805b600154811015611d235767016345785d8a000060018281548110611ccb57fe5b90600052602060002090600402016003015410611ced57600190920191611d1b565b600060018281548110611cfc57fe5b9060005260206000209060040201600301541115611d1b576001909101905b600101611cab565b50606082604051908082528060200260200182016040528015611d50578160200160208202803683370190505b509050606083604051908082528060200260200182016040528015611d7f578160200160208202803683370190505b509050606084604051908082528060200260200182016040528015611dae578160200160208202803683370190505b509050606085604051908082528060200260200182016040528015611ddd578160200160208202803683370190505b5090506000606086604051908082528060200260200182016040528015611e0e578160200160208202803683370190505b509050606087604051908082528060200260200182016040528015611e3d578160200160208202803683370190505b509050600098506000975060608d905060006110046001600160a01b031663149d14d96040518163ffffffff1660e01b815260040160206040518083038186803b158015611e8a57600080fd5b505afa158015611e9e573d6000803e3d6000fd5b505050506040513d6020811015611eb457600080fd5b5051905067016345785d8a0000811115611f29577f70e72399380dcfb0338abc03dc8d47f9f470ada8e769c9a78d644ea97385ecb2604051808060200182810382526021815260200180613d546021913960400191505060405180910390a160689d5050505050505050505050505050610ead565b60005b60015481101561219c5767016345785d8a000060018281548110611f4c57fe5b906000526020600020906004020160030154106120d25760018181548110611f7057fe5b906000526020600020906004020160020160009054906101000a90046001600160a01b03168a8d81518110611fa157fe5b60200260200101906001600160a01b031690816001600160a01b03168152505060006402540be40060018381548110611fd657fe5b90600052602060002090600402016003015481611fef57fe5b0660018381548110611ffd57fe5b906000526020600020906004020160030154039050612025838261315390919063ffffffff16565b8a8e8151811061203157fe5b6020026020010181815250506001828154811061204a57fe5b906000526020600020906004020160020160009054906101000a90046001600160a01b0316888e8151811061207b57fe5b60200260200101906001600160a01b031690816001600160a01b03168152505081898e815181106120a857fe5b60209081029190910101526120c3878263ffffffff61319516565b6001909d019c96506121949050565b6000600182815481106120e157fe5b9060005260206000209060040201600301541115612194576001818154811061210657fe5b906000526020600020906004020160010160009054906101000a90046001600160a01b0316858c8151811061213757fe5b60200260200101906001600160a01b031690816001600160a01b0316815250506001818154811061216457fe5b906000526020600020906004020160030154848c8151811061218257fe5b60209081029190910101526001909a01995b600101611f2c565b50600085156125da576110046001600160a01b0316636e056520878c8c8b60025442016040518663ffffffff1660e01b815260040180806020018060200180602001856001600160401b03166001600160401b03168152602001848103845288818151815260200191508051906020019060200280838360005b8381101561222e578181015183820152602001612216565b50505050905001848103835287818151815260200191508051906020019060200280838360005b8381101561226d578181015183820152602001612255565b50505050905001848103825286818151815260200191508051906020019060200280838360005b838110156122ac578181015183820152602001612294565b505050509050019750505050505050506020604051808303818588803b1580156122d557600080fd5b505af1935050505080156122fb57506040513d60208110156122f657600080fd5b505160015b612536576040516000815260443d1015612317575060006123b2565b60046000803e60005160e01c6308c379a081146123385760009150506123b2565b60043d036004833e81513d60248201116001600160401b0382111715612363576000925050506123b2565b80830180516001600160401b038111156123845760009450505050506123b2565b8060208301013d86018111156123a2576000955050505050506123b2565b601f01601f191660405250925050505b806123bd5750612461565b60019150867fa7cdeed7d0db45e3219a6e5d60838824c16f1d39991fcfe3f963029c844bf280826040518080602001828103825283818151815260200191508051906020019080838360005b83811015612421578181015183820152602001612409565b50505050905090810190601f16801561244e5780820380516001836020036101000a031916815260200191505b509250505060405180910390a250612531565b3d80801561248b576040519150601f19603f3d011682016040523d82523d6000602084013e612490565b606091505b5060019150867fbfa884552dd8921b6ce90bfe906952ae5b3b29be0cc1a951d4f62697635a3a45826040518080602001828103825283818151815260200191508051906020019080838360005b838110156124f55781810151838201526020016124dd565b50505050905090810190601f1680156125225780820380516001836020036101000a031916815260200191505b509250505060405180910390a2505b6125da565b8015612574576040805188815290517fa217d08e65f80c73121cd9db834d81652d544bfbf452f6d04922b16c90a37b709181900360200190a16125d8565b604080516020808252601b908201527f6261746368207472616e736665722072657475726e2066616c7365000000000081830152905188917fa7cdeed7d0db45e3219a6e5d60838824c16f1d39991fcfe3f963029c844bf280919081900360600190a25b505b80156127905760005b885181101561278e5760008982815181106125fa57fe5b6020026020010151905060006001828154811061261357fe5b60009182526020909120600160049092020181015481546001600160a01b03909116916108fc918590811061264457fe5b9060005260206000209060040201600301549081150290604051600060405180830381858888f1935050505090508015612700576001828154811061268557fe5b60009182526020909120600160049092020181015481546001600160a01b03909116917f6c61d60f69a7beb3e1c80db7f39f37b208537cbb19da3174511b477812b2fc7d91859081106126d457fe5b9060005260206000209060040201600301546040518082815260200191505060405180910390a2612784565b6001828154811061270d57fe5b60009182526020909120600160049092020181015481546001600160a01b03909116917f25d0ce7d2f0cec669a8c17efe49d195c13455bb8872b65fa610ac7f53fe4ca7d918590811061275c57fe5b9060005260206000209060040201600301546040518082815260200191505060405180910390a25b50506001016125e3565b505b8451156128da5760005b85518110156128d85760008682815181106127b157fe5b60200260200101516001600160a01b03166108fc8784815181106127d157fe5b60200260200101519081150290604051600060405180830381858888f19350505050905080156128675786828151811061280757fe5b60200260200101516001600160a01b03167f6c61d60f69a7beb3e1c80db7f39f37b208537cbb19da3174511b477812b2fc7d87848151811061284557fe5b60200260200101516040518082815260200191505060405180910390a26128cf565b86828151811061287357fe5b60200260200101516001600160a01b03167f25d0ce7d2f0cec669a8c17efe49d195c13455bb8872b65fa610ac7f53fe4ca7d8784815181106128b157fe5b60200260200101516040518082815260200191505060405180910390a25b5060010161279a565b505b4715612943576040805147815290517f6ecc855f9440a9282c90913bbc91619fd44f5ec0b462af28d127b116f130aa4d9181900360200190a1604051611002904780156108fc02916000818181858888f19350505050158015612941573d6000803e3d6000fd5b505b600060035582511561295857612958836131ef565b6110016001600160a01b031663fc4333cd6040518163ffffffff1660e01b8152600401600060405180830381600087803b15801561299557600080fd5b505af11580156129a9573d6000803e3d6000fd5b50506040517fedd8d7296956dd970ab4de3f2fc03be2b0ffc615d20cd4c72c6e44f928630ebf925060009150a15060009f9e505050505050505050505050505050565b60008151600114612a4a577f70e72399380dcfb0338abc03dc8d47f9f470ada8e769c9a78d644ea97385ecb2604051808060200182810382526025815260200180613d016025913960400191505060405180910390a1506067610ead565b612a52613c5f565b82600081518110612a5f57fe5b60209081029190910181015180516001600160a01b03166000908152600490925260409091205490915080612ad05781516040516001600160a01b03909116907fe209c46bebf57cf265d5d9009a00870e256d9150f3ed5281ab9d9eb3cec6e4be90600090a2600092505050610ead565b600154600090815b81811015612b625760018181548110612aed57fe5b9060005260206000209060040201600201601c9054906101000a900460ff16158015612b4c575084600001516001600160a01b031660018281548110612b2f57fe5b60009182526020909120600490910201546001600160a01b031614155b15612b5a5760019250612b62565b600101612ad8565b5081612bac5783516040516001600160a01b03909116907fe209c46bebf57cf265d5d9009a00870e256d9150f3ed5281ab9d9eb3cec6e4be90600090a26000945050505050610ead565b6001806001850381548110612bbd57fe5b6000918252602082206002600490920201018054921515600160e01b0260ff60e01b199093169290921790915584516040516001600160a01b03909116917ff226e7d8f547ff903d9d419cf5f54e0d7d07efa9584135a53a057c5f1f27f49a91a250600095945050505050565b6000816040516020018082805190602001908083835b60208310612c5f5780518252601f199092019160209182019101612c40565b6001836020036101000a03801982511681845116808217855250505050505090500191505060405160208183030381529060405280519060200120836040516020018082805190602001908083835b60208310612ccd5780518252601f199092019160209182019101612cae565b6001836020036101000a038019825116818451168082178552505050505050905001915050604051602081830303815290604052805190602001201490505b92915050565b015190565b612d1f613c94565b506040805180820190915281518152602082810190820152919050565b612d44613c3f565b612d4d826136b6565b612d5657600080fd5b6000612d6583602001516136f0565b60208085015160408051808201909152868152920190820152915050919050565b6000612d90613c94565b505080518051602091820151919092015191011190565b612daf613c94565b612db882612d86565b612dc157600080fd5b60208201516000612dd182613753565b80830160209586015260408051808201909152908152938401919091525090919050565b805160009015801590612e0a57508151602110155b612e1357600080fd5b6000612e2283602001516136f0565b83516020808601518301805193945091849003929190831015612e4c57826020036101000a820491505b50949350505050565b6060612e60826136b6565b612e6957600080fd5b6000612e74836137ec565b9050606081604051908082528060200260200182016040528015612eb257816020015b612e9f613c94565b815260200190600190039081612e975790505b5090506000612ec485602001516136f0565b60208601510190506000805b84811015612f1b57612ee183613753565b9150604051806040016040528083815260200184815250848281518110612f0457fe5b602090810291909101015291810191600101612ed0565b509195945050505050565b612f2e613c5f565b6000612f38613c5f565b612f40613c3f565b612f4985612d3c565b90506000805b612f5883612d86565b15611b7c5780612f8357612f73612f6e84612da7565b613848565b6001600160a01b03168452612ffb565b8060011415612fab57612f98612f6e84612da7565b6001600160a01b03166020850152612ffb565b8060021415612fd357612fc0612f6e84612da7565b6001600160a01b03166040850152612ffb565b8060031415611b6f57612fe8611a8184612da7565b6001600160401b03166060850152600191505b600101612f4f565b6060612d0c61301183613862565b613948565b60608151600014156130375750604080516000815260208101909152610ead565b60608260008151811061304657fe5b602002602001015190506000600190505b83518110156130875761307d8285838151811061307057fe5b602002602001015161399a565b9150600101613057565b50610b1f61309a825160c060ff16613a17565b8261399a565b60006060815b83518110156131395760005b81811015613130578481815181106130c657fe5b6020026020010151600001516001600160a01b03168583815181106130e757fe5b6020026020010151600001516001600160a01b031614156131285760006040518060600160405280602b8152602001613caf602b9139935093505050611b85565b6001016130b2565b506001016130a6565b505060408051602081019091526000815260019150915091565b6000610b1f83836040518060400160405280601e81526020017f536166654d6174683a207375627472616374696f6e206f766572666c6f770000815250613b0f565b600082820183811015610b1f576040805162461bcd60e51b815260206004820152601b60248201527f536166654d6174683a206164646974696f6e206f766572666c6f770000000000604482015290519081900360640190fd5b600154815160005b8281101561330c576001613209613c5f565b6001838154811061321657fe5b600091825260208083206040805160c08101825260049490940290910180546001600160a01b0390811685526001820154811693850193909352600281015492831691840191909152600160a01b82046001600160401b03166060840152600160e01b90910460ff16151560808301526003015460a082015291505b848110156132e0578681815181106132a657fe5b6020026020010151600001516001600160a01b031682600001516001600160a01b031614156132d857600092506132e0565b600101613292565b5081156133025780516001600160a01b03166000908152600460205260408120555b50506001016131f7565b508082111561338157805b8281101561337f57600180548061332a57fe5b60008281526020812060046000199093019283020180546001600160a01b03199081168255600182810180549092169091556002820180546001600160e81b0319169055600390910191909155915501613317565b505b60008183106133905781613392565b825b905060005b8181101561358c576134448582815181106133ae57fe5b6020026020010151600183815481106133c357fe5b60009182526020918290206040805160c08101825260049390930290910180546001600160a01b0390811684526001820154811694840194909452600281015493841691830191909152600160a01b83046001600160401b03166060830152600160e01b90920460ff161515608082015260039091015460a0820152613ba6565b61355f57806001016004600087848151811061345c57fe5b6020026020010151600001516001600160a01b03166001600160a01b031681526020019081526020016000208190555084818151811061349857fe5b6020026020010151600182815481106134ad57fe5b6000918252602091829020835160049092020180546001600160a01b039283166001600160a01b0319918216178255928401516001820180549184169185169190911790556040840151600282018054606087015160808801511515600160e01b0260ff60e01b196001600160401b03909216600160a01b0267ffffffffffffffff60a01b1995909716929097169190911792909216939093171692909217905560a090910151600390910155613584565b60006001828154811061356e57fe5b9060005260206000209060040201600301819055505b600101613397565b50828211156136b057825b82811015610e3d5760018582815181106135ad57fe5b60209081029190910181015182546001818101855560009485528385208351600493840290910180546001600160a01b039283166001600160a01b03199182161782559585015181840180549184169188169190911790556040850151600282018054606088015160808901511515600160e01b0260ff60e01b196001600160401b03909216600160a01b0267ffffffffffffffff60a01b199590971692909a169190911792909216939093171695909517905560a0909201516003909301929092558751908401929088908590811061368357fe5b602090810291909101810151516001600160a01b0316825281019190915260400160002055600101613597565b50505050565b80516000906136c757506000610ead565b6020820151805160001a9060c08210156136e657600092505050610ead565b5060019392505050565b8051600090811a608081101561370a576000915050610ead565b60b8811080613725575060c08110801590613725575060f881105b15613734576001915050610ead565b60c08110156137485760b519019050610ead565b60f519019050610ead565b80516000908190811a608081101561376e57600191506137e5565b60b881101561378357607e19810191506137e5565b60c08110156137b05760b78103600185019450806020036101000a855104600182018101935050506137e5565b60f88110156137c55760be19810191506137e5565b60f78103600185019450806020036101000a855104600182018101935050505b5092915050565b80516000906137fd57506000610ead565b6000809050600061381184602001516136f0565b602085015185519181019250015b8082101561383f5761383082613753565b6001909301929091019061381f565b50909392505050565b805160009060151461385957600080fd5b612d0c82612df5565b604080516020808252818301909252606091829190602082018180368337505050602081018490529050600067ffffffffffffffff1984166138a6575060186138ca565b6fffffffffffffffffffffffffffffffff1984166138c6575060106138ca565b5060005b6020811015613900578181815181106138df57fe5b01602001516001600160f81b031916156138f857613900565b6001016138ca565b60008160200390506060816040519080825280601f01601f191660200182016040528015613935576020820181803683370190505b5080830196909652508452509192915050565b60608151600114801561397a5750607f60f81b8260008151811061396857fe5b01602001516001600160f81b03191611155b15613986575080610ead565b612d0c6139988351608060ff16613a17565b835b6060806040519050835180825260208201818101602087015b818310156139cb5780518352602092830192016139b3565b50855184518101855292509050808201602086015b818310156139f85780518352602092830192016139e0565b508651929092011591909101601f01601f191660405250905092915050565b6060680100000000000000008310613a67576040805162461bcd60e51b815260206004820152600e60248201526d696e70757420746f6f206c6f6e6760901b604482015290519081900360640190fd5b60408051600180825281830190925260609160208201818036833701905050905060378411613ac15782840160f81b81600081518110613aa357fe5b60200101906001600160f81b031916908160001a9053509050612d0c565b6060613acc85613862565b90508381510160370160f81b82600081518110613ae557fe5b60200101906001600160f81b031916908160001a905350613b06828261399a565b95945050505050565b60008184841115613b9e5760405162461bcd60e51b81526004018080602001828103825283818151815260200191508051906020019080838360005b83811015613b63578181015183820152602001613b4b565b50505050905090810190601f168015613b905780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b505050900390565b805182516000916001600160a01b039182169116148015613be0575081602001516001600160a01b031683602001516001600160a01b0316145b8015613c05575081604001516001600160a01b031683604001516001600160a01b0316145b8015610b1f5750506060908101519101516001600160401b0390811691161490565b60408051808201909152600081526060602082015290565b6040518060400160405280613c52613c94565b8152602001600081525090565b6040805160c081018252600080825260208201819052918101829052606081018290526080810182905260a081019190915290565b60405180604001604052806000815260200160008152509056fe6475706c696361746520636f6e73656e7375732061646472657373206f662076616c696461746f725365747468652065787069726554696d655365636f6e64476170206973206f7574206f662072616e67656c656e677468206f66206a61696c2076616c696461746f7273206d757374206265206f6e65746865206d6573736167652073656e646572206d75737420626520676f7665726e616e636520636f6e7472616374666565206973206c6172676572207468616e2044555354595f494e434f4d494e476c656e677468206f662065787069726554696d655365636f6e64476170206d69736d61746368f901b480f901b0f846941284214b9b9c85549ab3d2b972df0deef66ac2c99477f066f3fb515bb97015e4b4afddbcb25c94286b946ddf42a51534fc98d0c0a3b42c963cace8441ddf86048c27395000f84694b71b214cb885500844365e95cd9942c7276e7fd894748c284f46ab87fd492326f1e2fe731d22ad2db394d22ca3ba2141d23adab65ce4940eb7665ea2b6a786048c27395000f84694a2959d3f95eae5dc7d70144ce1b73b403b7eb6e0940ce09b38374887cb564b7efa60be130d99ed5f95948081ef03f1d9e0bb4a5bf38f16285c879299f07f86048c27395000f84694980a75ecd1309ea12fa2ed87a8744fbfc9b863d59407eecf36cf0901fefe4bc505d6ba03c7480c7b5794cc6ac05c95a99c1f7b5f88de0e3486c82293b27086048c27395000f8469435552c16704d214347f29fa77f77da6d75d7c75294f57d36e129881a3a13a024fe8072507e5b2e70f894dc4973e838e3949c77aced16ac2315dc2d7ab11186048c27395000f84694f474cf03cceff28abc65c9cbae594f725c80e12d94ddfcaedf9bb451098c9917a45f02bd61342cca6694e61a183325a18a173319dd8e19c8d069459e217586048c273950006661696c656420746f20706172736520696e69742076616c696461746f72536574746865206d6573736167652073656e646572206d7573742062652063726f737320636861696e20636f6e7472616374746865206d6573736167652073656e646572206d7573742062652074686520626c6f636b2070726f6475636572746865206d6573736167652073656e646572206d75737420626520736c61736820636f6e7472616374a26469706673582212201a362ffe5872c7b034fe0bdf76cb3980b7a822a1eb1f36e261d39b52df28597164736f6c63430006040033" + }, + "0x0000000000000000000000000000000000001001": { + "balance": "0x0", + "code": "0x608060405234801561001057600080fd5b50600436106102065760003560e01c806396713da91161011a578063c81b1662116100ad578063e1c7392a1161007c578063e1c7392a1461064d578063f9a2bbc714610655578063fc3e59081461065d578063fc4333cd14610665578063fd6a68791461066d57610206565b8063c81b16621461059f578063c8509d81146105a7578063c96be4cb1461061f578063dc927faf1461064557610206565b8063a78abc16116100e9578063a78abc16146104b5578063ab51bb96146104d1578063ac431751146104d9578063c80d4b8f1461059757610206565b806396713da9146104955780639bc8e4f21461049d5780639dc09262146104a5578063a1a11bf5146104ad57610206565b806351e806721161019d57806370fd5bad1161016c57806370fd5bad146103fb57806375d47a0a146104035780637912a65d1461040b5780637942fd0514610413578063831d65d11461041b57610206565b806351e80672146103db578063567a372d146103e357806362b72cf5146103eb5780636e47b482146103f357610206565b80633dffc387116101d95780633dffc3871461037257806343756e5c14610390578063493279b1146103b45780634bf6c882146103d357610206565b80630bee7a671461020b5780631182b8751461022c57806337c8dab914610319578063389f4f7114610358575b600080fd5b610213610675565b6040805163ffffffff9092168252519081900360200190f35b6102a46004803603604081101561024257600080fd5b60ff8235169190810190604081016020820135600160201b81111561026657600080fd5b82018360208201111561027857600080fd5b803590602001918460018302840111600160201b8311171561029957600080fd5b50909250905061067a565b6040805160208082528351818301528351919283929083019185019080838360005b838110156102de5781810151838201526020016102c6565b50505050905090810190601f16801561030b5780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b61033f6004803603602081101561032f57600080fd5b50356001600160a01b0316610709565b6040805192835260208301919091528051918290030190f35b610360610760565b60408051918252519081900360200190f35b61037a610766565b6040805160ff9092168252519081900360200190f35b61039861076b565b604080516001600160a01b039092168252519081900360200190f35b6103bc610771565b6040805161ffff9092168252519081900360200190f35b61037a610776565b61039861077b565b610360610781565b610360610787565b61039861078d565b61037a610793565b610398610798565b61036061079e565b61037a6107a3565b6104936004803603604081101561043157600080fd5b60ff8235169190810190604081016020820135600160201b81111561045557600080fd5b82018360208201111561046757600080fd5b803590602001918460018302840111600160201b8311171561048857600080fd5b5090925090506107a8565b005b61037a61087e565b610360610883565b61039861088e565b610398610894565b6104bd61089a565b604080519115158252519081900360200190f35b6102136108a3565b610493600480360360408110156104ef57600080fd5b810190602081018135600160201b81111561050957600080fd5b82018360208201111561051b57600080fd5b803590602001918460018302840111600160201b8311171561053c57600080fd5b919390929091602081019035600160201b81111561055957600080fd5b82018360208201111561056b57600080fd5b803590602001918460018302840111600160201b8311171561058c57600080fd5b5090925090506108a8565b610360610ca3565b610398610ca8565b610493600480360360408110156105bd57600080fd5b60ff8235169190810190604081016020820135600160201b8111156105e157600080fd5b8201836020820111156105f357600080fd5b803590602001918460018302840111600160201b8311171561061457600080fd5b509092509050610cae565b6104936004803603602081101561063557600080fd5b50356001600160a01b0316610cdc565b6103986110e1565b6104936110e7565b610398611158565b61037a61115e565b610493611163565b6103986112b4565b606481565b606033612000146106bc5760405162461bcd60e51b815260040180806020018281038252602f815260200180611c1a602f913960400191505060405180910390fd5b6040805162461bcd60e51b815260206004820152601e60248201527f7265636569766520756e65787065637465642073796e207061636b6167650000604482015290519081900360640190fd5b600080610714611ade565b5050506001600160a01b0316600090815260026020818152604092839020835160608101855281548082526001830154938201849052919093015460ff16151592909301919091529091565b60055481565b600181565b61100181565b606181565b600881565b61200081565b60045481565b60035481565b61100581565b600281565b61100881565b603281565b600b81565b6107b0611b01565b60006107f184848080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152506112ba92505050565b91509150801561083b5781516040805163ffffffff9092168252517f7f0956d47419b9525356e7111652b653b530ec6f5096dccc04589bc38e6299679181900360200190a1610877565b81516040805163ffffffff9092168252517f7d45f62d17443dd4547bca8a8112c60e2385669318dc300ec61a5d2492f262e79181900360200190a15b5050505050565b600981565b662386f26fc1000081565b61100781565b61100681565b60005460ff1681565b600081565b60005460ff166108fb576040805162461bcd60e51b81526020600482015260196024820152781d1a194818dbdb9d1c9858dd081b9bdd081a5b9a5d081e595d603a1b604482015290519081900360640190fd5b336110071461093b5760405162461bcd60e51b815260040180806020018281038252602e815260200180611ba5602e913960400191505060405180910390fd5b6109a684848080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250506040805180820190915260148152731b5a5cd9195b59585b9bdc951a1c995cda1bdb1960621b6020820152915061133a9050565b15610a7f57602081146109ea5760405162461bcd60e51b8152600401808060200182810382526027815260200180611b4e6027913960400191505060405180910390fd5b604080516020601f8401819004810282018101909252828152600091610a289185858083850183828082843760009201919091525061142292505050565b9050600a8110158015610a3c575060055481105b610a775760405162461bcd60e51b8152600401808060200182810382526025815260200180611bf56025913960400191505060405180910390fd5b600455610c11565b610ae584848080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152505060408051808201909152600f81526e19995b1bdb9e551a1c995cda1bdb19608a1b6020820152915061133a9050565b15610bd45760208114610b295760405162461bcd60e51b8152600401808060200182810382526022815260200180611bd36022913960400191505060405180910390fd5b604080516020601f8401819004810282018101909252828152600091610b679185858083850183828082843760009201919091525061142292505050565b9050601481118015610b7b57506103e88111155b610bcc576040805162461bcd60e51b815260206004820181905260248201527f7468652066656c6f6e795468726573686f6c64206f7574206f662072616e6765604482015290519081900360640190fd5b600555610c11565b6040805162461bcd60e51b815260206004820152600d60248201526c756e6b6e6f776e20706172616d60981b604482015290519081900360640190fd5b7f6cdb0ac70ab7f2e2d035cca5be60d89906f2dede7648ddbd7402189c1eeed17a848484846040518080602001806020018381038352878782818152602001925080828437600083820152601f01601f191690910184810383528581526020019050858580828437600083820152604051601f909101601f19169092018290039850909650505050505050a150505050565b609681565b61100281565b6040517f07db600eebe2ac176be8dcebad61858c245a4961bb32ca2aa3d159b09aa0810e90600090a1505050565b334114610d1a5760405162461bcd60e51b815260040180806020018281038252602d815260200180611c49602d913960400191505060405180910390fd5b60005460ff16610d6d576040805162461bcd60e51b81526020600482015260196024820152781d1a194818dbdb9d1c9858dd081b9bdd081a5b9a5d081e595d603a1b604482015290519081900360640190fd5b6003544311610dc3576040805162461bcd60e51b815260206004820181905260248201527f63616e206e6f7420736c61736820747769636520696e206f6e6520626c6f636b604482015290519081900360640190fd5b610dcb611ade565b506001600160a01b0381166000908152600260208181526040928390208351606081018552815481526001820154928101929092529091015460ff161580159282019290925290610e26576020810180516001019052610e7f565b60016040820181905260208201819052805480820182556000919091527fb10e2d527612073b26eecdfd717e6a320cf44b4afac2b0732d9fcbe2b7fa0cf60180546001600160a01b0319166001600160a01b0384161790555b4381526001600160a01b038216600090815260026020818152604092839020845181559084015160018201819055928401519101805460ff19169115159190911790556005549081610ecd57fe5b0661102f57604080516335409f7f60e01b81526001600160a01b03841660048201529051611000916335409f7f91602480830192600092919082900301818387803b158015610f1b57600080fd5b505af1158015610f2f573d6000803e3d6000fd5b505050506120006001600160a01b031663f7a251d7600b610f4f85611427565b60006040518463ffffffff1660e01b8152600401808460ff1660ff16815260200180602001838152602001828103825284818151815260200191508051906020019080838360005b83811015610faf578181015183820152602001610f97565b50505050905090810190601f168015610fdc5780820380516001836020036101000a031916815260200191505b50945050505050602060405180830381600087803b158015610ffd57600080fd5b505af1158015611011573d6000803e3d6000fd5b505050506040513d602081101561102757600080fd5b506110a59050565b60045481602001518161103e57fe5b066110a557604080516375abf10160e11b81526001600160a01b038416600482015290516110009163eb57e20291602480830192600092919082900301818387803b15801561108c57600080fd5b505af11580156110a0573d6000803e3d6000fd5b505050505b6040516001600160a01b038316907fddb6012116e51abf5436d956a4f0ebd927e92c576ff96d7918290c8782291e3e90600090a2505043600355565b61100381565b60005460ff161561113f576040805162461bcd60e51b815260206004820152601960248201527f74686520636f6e747261637420616c726561647920696e697400000000000000604482015290519081900360640190fd5b603260045560966005556000805460ff19166001179055565b61100081565b600381565b33611000146111a35760405162461bcd60e51b8152600401808060200182810382526030815260200180611b756030913960400191505060405180910390fd5b60005460ff166111f6576040805162461bcd60e51b81526020600482015260196024820152781d1a194818dbdb9d1c9858dd081b9bdd081a5b9a5d081e595d603a1b604482015290519081900360640190fd5b60015460005b818110156112875760026000600180848603038154811061121957fe5b60009182526020808320909101546001600160a01b031683528201929092526040018120818155600181810192909255600201805460ff1916905580548061125d57fe5b600082815260209020810160001990810180546001600160a01b03191690550190556001016111fc565b506040517fcfdb3b6ccaeccbdc68be3c59c840e3b3c90f0a7c491f5fff1cf56cfda200dd9c90600090a150565b61100481565b6112c2611b01565b60006112cc611b01565b6112d4611b13565b6112e56112e0866114f9565b61151e565b90506000805b6112f483611568565b1561132d57806113205761130f61130a84611589565b6115d7565b63ffffffff16845260019150611325565b61132d565b6001016112eb565b5091935090915050915091565b6000816040516020018082805190602001908083835b6020831061136f5780518252601f199092019160209182019101611350565b6001836020036101000a03801982511681845116808217855250505050505090500191505060405160208183030381529060405280519060200120836040516020018082805190602001908083835b602083106113dd5780518252601f1990920191602091820191016113be565b6001836020036101000a038019825116818451168082178552505050505050905001915050604051602081830303815290604052805190602001201490505b92915050565b015190565b60408051600480825260a08201909252606091829190816020015b606081526020019060019003908161144257905050905061146b836001600160a01b0316611637565b8160008151811061147857fe5b602002602001018190525061148c4361165a565b8160018151811061149957fe5b60209081029190910101526114ae606161165a565b816002815181106114bb57fe5b60200260200101819052506114cf4261165a565b816003815181106114dc57fe5b60200260200101819052506114f08161166d565b9150505b919050565b611501611b33565b506040805180820190915281518152602082810190820152919050565b611526611b13565b61152f826116f7565b61153857600080fd5b60006115478360200151611731565b60208085015160408051808201909152868152920190820152915050919050565b6000611572611b33565b505080518051602091820151919092015191011190565b611591611b33565b61159a82611568565b6115a357600080fd5b602082015160006115b382611794565b80830160209586015260408051808201909152908152938401919091525090919050565b8051600090158015906115ec57508151602110155b6115f557600080fd5b60006116048360200151611731565b8351602080860151830180519394509184900392919083101561162e57826020036101000a820491505b50949350505050565b60408051600560a21b83186014820152603481019091526060906114f08161182d565b606061141c61166883611883565b61182d565b606081516000141561168e57506040805160008152602081019091526114f4565b60608260008151811061169d57fe5b602002602001015190506000600190505b83518110156116de576116d4828583815181106116c757fe5b6020026020010151611969565b91506001016116ae565b506114f06116f1825160c060ff166119e6565b82611969565b8051600090611708575060006114f4565b6020820151805160001a9060c0821015611727576000925050506114f4565b5060019392505050565b8051600090811a608081101561174b5760009150506114f4565b60b8811080611766575060c08110801590611766575060f881105b156117755760019150506114f4565b60c08110156117895760b5190190506114f4565b60f5190190506114f4565b80516000908190811a60808110156117af5760019150611826565b60b88110156117c457607e1981019150611826565b60c08110156117f15760b78103600185019450806020036101000a85510460018201810193505050611826565b60f88110156118065760be1981019150611826565b60f78103600185019450806020036101000a855104600182018101935050505b5092915050565b60608151600114801561185f5750607f60f81b8260008151811061184d57fe5b01602001516001600160f81b03191611155b1561186b5750806114f4565b61141c61187d8351608060ff166119e6565b83611969565b604080516020808252818301909252606091829190602082018180368337505050602081018490529050600067ffffffffffffffff1984166118c7575060186118eb565b6fffffffffffffffffffffffffffffffff1984166118e7575060106118eb565b5060005b60208110156119215781818151811061190057fe5b01602001516001600160f81b0319161561191957611921565b6001016118eb565b60008160200390506060816040519080825280601f01601f191660200182016040528015611956576020820181803683370190505b5080830196909652508452509192915050565b6060806040519050835180825260208201818101602087015b8183101561199a578051835260209283019201611982565b50855184518101855292509050808201602086015b818310156119c75780518352602092830192016119af565b508651929092011591909101601f01601f191660405250905092915050565b6060680100000000000000008310611a36576040805162461bcd60e51b815260206004820152600e60248201526d696e70757420746f6f206c6f6e6760901b604482015290519081900360640190fd5b60408051600180825281830190925260609160208201818036833701905050905060378411611a905782840160f81b81600081518110611a7257fe5b60200101906001600160f81b031916908160001a905350905061141c565b6060611a9b85611883565b90508381510160370160f81b82600081518110611ab457fe5b60200101906001600160f81b031916908160001a905350611ad58282611969565b95945050505050565b604051806060016040528060008152602001600081526020016000151581525090565b60408051602081019091526000815290565b6040518060400160405280611b26611b33565b8152602001600081525090565b60405180604001604052806000815260200160008152509056fe6c656e677468206f66206d697364656d65616e6f725468726573686f6c64206d69736d61746368746865206d6573736167652073656e646572206d7573742062652076616c696461746f7253657420636f6e7472616374746865206d6573736167652073656e646572206d75737420626520676f7665726e616e636520636f6e74726163746c656e677468206f662066656c6f6e795468726573686f6c64206d69736d61746368746865206d697364656d65616e6f725468726573686f6c64206f7574206f662072616e6765746865206d6573736167652073656e646572206d7573742062652063726f737320636861696e20636f6e7472616374746865206d6573736167652073656e646572206d7573742062652074686520626c6f636b2070726f6475636572a26469706673582212203c75feabfa95d80f8670bc9249ad2a813867311d79e6a0c9e3a1233d3c2c953964736f6c63430006040033" + }, + "0x0000000000000000000000000000000000001002": { + "balance": "0x0", + "code": "0x60806040526004361061014f5760003560e01c806396713da9116100b6578063c81b16621161006f578063c81b1662146103dc578063dc927faf146103f1578063f9a2bbc714610406578063fb5478b31461041b578063fc3e590814610430578063fd6a68791461044557610193565b806396713da91461033a5780639a99b4f01461034f5780639dc0926214610388578063a1a11bf51461039d578063a78abc16146103b2578063ab51bb96146103c757610193565b806351e806721161010857806351e806721461028a5780636d70f7ae1461029f5780636e47b482146102e657806370fd5bad146102fb57806375d47a0a146103105780637942fd051461032557610193565b80630bee7a67146101985780633a0b0eff146101c65780633dffc387146101ed57806343756e5c14610218578063493279b1146102495780634bf6c8821461027557610193565b366101935734156101915760408051348152905133917f6c98249d85d88c3753a04a22230f595e4dc8d3dc86c34af35deeeedc861b89db919081900360200190a25b005b600080fd5b3480156101a457600080fd5b506101ad61045a565b6040805163ffffffff9092168252519081900360200190f35b3480156101d257600080fd5b506101db61045f565b60408051918252519081900360200190f35b3480156101f957600080fd5b50610202610465565b6040805160ff9092168252519081900360200190f35b34801561022457600080fd5b5061022d61046a565b604080516001600160a01b039092168252519081900360200190f35b34801561025557600080fd5b5061025e610470565b6040805161ffff9092168252519081900360200190f35b34801561028157600080fd5b50610202610475565b34801561029657600080fd5b5061022d61047a565b3480156102ab57600080fd5b506102d2600480360360208110156102c257600080fd5b50356001600160a01b0316610480565b604080519115158252519081900360200190f35b3480156102f257600080fd5b5061022d61049e565b34801561030757600080fd5b506102026104a4565b34801561031c57600080fd5b5061022d6104a9565b34801561033157600080fd5b506102026104af565b34801561034657600080fd5b506102026104b4565b34801561035b57600080fd5b506101db6004803603604081101561037257600080fd5b506001600160a01b0381351690602001356104b9565b34801561039457600080fd5b5061022d610664565b3480156103a957600080fd5b5061022d61066a565b3480156103be57600080fd5b506102d2610670565b3480156103d357600080fd5b506101ad610679565b3480156103e857600080fd5b5061022d61067e565b3480156103fd57600080fd5b5061022d610684565b34801561041257600080fd5b5061022d61068a565b34801561042757600080fd5b506101db610690565b34801561043c57600080fd5b5061020261069c565b34801561045157600080fd5b5061022d6106a1565b606481565b60015481565b600181565b61100181565b606181565b600881565b61200081565b6001600160a01b031660009081526002602052604090205460ff1690565b61100581565b600281565b61100881565b600b81565b600981565b6000805460ff1661053657600260208190527fe57bda0a954a7c7381b17b2c763e646ba2c60f67292d287ba583603e2c1c41668054600160ff19918216811790925561100560009081527fe25235fc0de9d7165652bef0846fefda506174abb9a190f03d0f7bcc6146dbce80548316841790559282558254161790555b3360009081526002602052604090205460ff166105845760405162461bcd60e51b815260040180806020018281038252602d8152602001806106a8602d913960400191505060405180910390fd5b60004783106105935747610595565b825b9050670de0b6b3a76400008111156105b25750670de0b6b3a76400005b8015610633576040516001600160a01b0385169082156108fc029083906000818181858888f193505050501580156105ee573d6000803e3d6000fd5b506040805182815290516001600160a01b038616917ff8b71c64315fc33b2ead2adfa487955065152a8ac33d9d5193aafd7f45dc15a0919081900360200190a261065d565b6040517fe589651933c2457488cc0d8e0941518abf748e799435e4e396d9c4d0b2db2d4d90600090a15b9392505050565b61100781565b61100681565b60005460ff1681565b600081565b61100281565b61100381565b61100081565b670de0b6b3a764000081565b600381565b6110048156fe6f6e6c79206f70657261746f7220697320617661696c61626c6520746f2063616c6c20746865206d6574686f64a26469706673582212206e40023fb74e48dfc701bcc667e0729a8491ff7ddabd668e2c6383a508bb167764736f6c63430006040033" + }, + "0x0000000000000000000000000000000000001003": { + "balance": "0x0", + "code": "0x608060405234801561001057600080fd5b50600436106102115760003560e01c8063a78abc1611610125578063dda83148116100ad578063e405bbc31161007c578063e405bbc314610681578063ea54b2aa14610689578063f9a2bbc714610691578063fc3e590814610699578063fd6a6879146106a157610211565b8063dda8314814610609578063df5fe7041461062f578063e1c7392a14610655578063e2761af01461065d57610211565b8063c81b1662116100f4578063c81b166214610534578063cba510a91461053c578063d816987914610562578063da8d08f0146105db578063dc927faf1461060157610211565b8063a78abc1614610444578063ab51bb9614610460578063ac43175114610468578063adc879e91461052c57610211565b8063564b81ef116101a857806375d47a0a1161017757806375d47a0a1461041c5780637942fd051461042457806396713da91461042c5780639dc0926214610434578063a1a11bf51461043c57610211565b8063564b81ef146102ca5780635c5ae8db146103475780636e47b4821461040c57806370fd5bad1461041457610211565b806343756e5c116101e457806343756e5c14610277578063493279b11461029b5780634bf6c882146102ba57806351e80672146102c257610211565b80630bee7a67146102165780632657e9b61461023757806333f7798d146102515780633dffc38714610259575b600080fd5b61021e6106a9565b6040805163ffffffff9092168252519081900360200190f35b61023f6106ae565b60408051918252519081900360200190f35b61023f6106b9565b6102616106bf565b6040805160ff9092168252519081900360200190f35b61027f6106c4565b604080516001600160a01b039092168252519081900360200190f35b6102a36106ca565b6040805161ffff9092168252519081900360200190f35b6102616106cf565b61027f6106d4565b6102d26106da565b6040805160208082528351818301528351919283929083019185019080838360005b8381101561030c5781810151838201526020016102f4565b50505050905090810190601f1680156103395780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b61036d6004803603602081101561035d57600080fd5b50356001600160401b03166107e6565b60405180856001600160401b03166001600160401b0316815260200184815260200183815260200180602001828103825283818151815260200191508051906020019080838360005b838110156103ce5781810151838201526020016103b6565b50505050905090810190601f1680156103fb5780820380516001836020036101000a031916815260200191505b509550505050505060405180910390f35b61027f6108a1565b6102616108a7565b61027f6108ac565b6102616108b2565b6102616108b7565b61027f6108bc565b61027f6108c2565b61044c6108c8565b604080519115158252519081900360200190f35b61021e6108d1565b61052a6004803603604081101561047e57600080fd5b81019060208101813564010000000081111561049957600080fd5b8201836020820111156104ab57600080fd5b803590602001918460018302840111640100000000831117156104cd57600080fd5b9193909290916020810190356401000000008111156104eb57600080fd5b8201836020820111156104fd57600080fd5b8035906020019184600183028401116401000000008311171561051f57600080fd5b5090925090506108d6565b005b61023f610b8f565b61027f610b95565b61023f6004803603602081101561055257600080fd5b50356001600160401b0316610b9b565b61044c6004803603604081101561057857600080fd5b81019060208101813564010000000081111561059357600080fd5b8201836020820111156105a557600080fd5b803590602001918460018302840111640100000000831117156105c757600080fd5b9193509150356001600160401b0316610bba565b61027f600480360360208110156105f157600080fd5b50356001600160401b031661139a565b61027f6113b5565b61027f6004803603602081101561061f57600080fd5b50356001600160401b03166113bb565b61044c6004803603602081101561064557600080fd5b50356001600160401b03166113df565b61052a611421565b6106656115c6565b604080516001600160401b039092168252519081900360200190f35b6106656115d5565b6102d26115eb565b61027f611608565b61026161160e565b61027f611613565b606481565b662386f26fc1000081565b60055481565b600181565b61100181565b606181565b600881565b61200081565b604080516020808252818301909252606091829190602082018180368337505060045460208301525090506000805b60208160ff16101561075057828160ff168151811061072457fe5b01602001516001600160f81b0319161561074357600190910190610748565b610750565b600101610709565b5060608160ff166040519080825280601f01601f191660200182016040528015610781576020820181803683370190505b50905060005b8260ff168160ff1610156107dd57838160ff16815181106107a457fe5b602001015160f81c60f81b828260ff16815181106107be57fe5b60200101906001600160f81b031916908160001a905350600101610787565b50925050505b90565b60016020818152600092835260409283902080548184015460028084015460038501805489516101009982161599909902600019011692909204601f81018790048702880187019098528787526001600160401b0390931696919592949091908301828280156108975780601f1061086c57610100808354040283529160200191610897565b820191906000526020600020905b81548152906001019060200180831161087a57829003601f168201915b5050505050905084565b61100581565b600281565b61100881565b600b81565b600981565b61100781565b61100681565b60005460ff1681565b600081565b60005460ff1661092d576040805162461bcd60e51b815260206004820152601960248201527f74686520636f6e7472616374206e6f7420696e69742079657400000000000000604482015290519081900360640190fd5b336110071461096d5760405162461bcd60e51b815260040180806020018281038252602e815260200180611ac5602e913960400191505060405180910390fd5b6109e184848080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152505060408051808201909152601b81527f726577617264466f7256616c696461746f725365744368616e67650000000000602082015291506116199050565b15610ac05760208114610a255760405162461bcd60e51b815260040180806020018281038252602e815260200180611a64602e913960400191505060405180910390fd5b604080516020601f8401819004810282018101909252828152600091610a639185858083850183828082843760009201919091525061170092505050565b9050600081118015610a7d5750670de0b6b3a76400008111155b610ab85760405162461bcd60e51b815260040180806020018281038252602f815260200180611af3602f913960400191505060405180910390fd5b600555610afd565b6040805162461bcd60e51b815260206004820152600d60248201526c756e6b6e6f776e20706172616d60981b604482015290519081900360640190fd5b7f6cdb0ac70ab7f2e2d035cca5be60d89906f2dede7648ddbd7402189c1eeed17a848484846040518080602001806020018381038352878782818152602001925080828437600083820152601f01601f191690910184810383528581526020019050858580828437600083820152604051601f909101601f19169092018290039850909650505050505050a150505050565b60045481565b61100281565b6001600160401b03166000908152600160208190526040909120015490565b60408051630a83aaa960e31b815233600482015290516000916110069163541d554891602480820192602092909190829003018186803b158015610bfd57600080fd5b505afa158015610c11573d6000803e3d6000fd5b505050506040513d6020811015610c2757600080fd5b5051610c7a576040805162461bcd60e51b815260206004820152601f60248201527f746865206d73672073656e646572206973206e6f7420612072656c6179657200604482015290519081900360640190fd5b6001600160401b0382166000908152600260205260409020546001600160a01b031615610cee576040805162461bcd60e51b815260206004820152601c60248201527f63616e27742073796e63206475706c6963617465642068656164657200000000604482015290519081900360640190fd5b6003546001600160401b0390811690831611610d3b5760405162461bcd60e51b8152600401808060200182810382526026815260200180611b226026913960400191505060405180910390fd5b600354600160401b90046001600160401b0316610d56611862565b6001600160401b0382811660009081526001602081815260409283902083516080810185528154909516855280830154858301526002808201548686015260038201805486516101009682161596909602600019011691909104601f81018490048402850184019095528484529093606086019392830182828015610e1c5780601f10610df157610100808354040283529160200191610e1c565b820191906000526020600020905b815481529060010190602001808311610dff57829003601f168201915b50505050508152505090505b6003546001600160401b0390811690831610610f3957836001600160401b0316826001600160401b03161015610e5d57610f39565b80516001600160401b0380821660009081526001602081815260409283902083516080810185528154909516855280830154858301526002808201548686015260038201805486516101009682161596909602600019011691909104601f8101849004840285018401909552848452959750939460608601939091830182828015610f295780601f10610efe57610100808354040283529160200191610f29565b820191906000526020600020905b815481529060010190602001808311610f0c57829003601f168201915b5050505050815250509050610e28565b6060810151516110305780516001600160401b03811660009081526001602081815260409283902060030180548451600294821615610100026000190190911693909304601f810183900483028401830190945283835293955090929190830182828015610fe85780601f10610fbd57610100808354040283529160200191610fe8565b820191906000526020600020905b815481529060010190602001808311610fcb57829003601f168201915b505050506060830182905250516110305760405162461bcd60e51b8152600401808060200182810382526021815260200180611a436021913960400191505060405180910390fd5b6000816060015151608801905060608787905082016040519080825280601f01601f19166020018201604052801561106f576020820181803683370190505b509050600061107d82611705565b905061108b8486838661170b565b6110c65760405162461bcd60e51b81526004018080602001828103825260238152602001806119406023913960400191505060405180910390fd5b6000838201915061110c8a8a8080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061177792505050565b9450905061111b818386611781565b8251602001935061112a611888565b6110008186866064600019fa61113f57600080fd5b805194506000600160f81b8616156111ce5750600554604080516309a99b4f60e41b815233600482015260248101929092525160019161100291639a99b4f0916044808201926020929091908290030181600087803b1580156111a157600080fd5b505af11580156111b5573d6000803e3d6000fd5b505050506040513d60208110156111cb57600080fd5b50505b856001600160401b0316955060208201935060006111ee858884156117c2565b90985090506001600160401b03808216908c161461123d5760405162461bcd60e51b8152600401808060200182810382526033815260200180611a926033913960400191505060405180910390fd5b6001600160401b03808c16600081815260026020818152604080842080546001600160a01b031916331790558e86168e529383526001808252928490208d518154961667ffffffffffffffff199096169590951785558c81015192850192909255918b01519183019190915560608a015180518b93926112c49260038501929101906118a7565b50506003546001600160401b03600160401b9091048116908d161115905061130c576003805467ffffffffffffffff60401b1916600160401b6001600160401b038e16021790555b7f4042c1020a8f410fb1c8859d276ab436aeb2c3074960e48467299cf1c966d3b48b8a8a602001518560405180856001600160401b03166001600160401b03168152602001846001600160401b03166001600160401b031681526020018381526020018215151515815260200194505050505060405180910390a15060019c9b505050505050505050505050565b6002602052600090815260409020546001600160a01b031681565b61100381565b6001600160401b03166000908152600260205260409020546001600160a01b031690565b6001600160401b0381166000908152600260205260408120546001600160a01b031615158061141b57506003546001600160401b038381169116145b92915050565b60005460ff1615611479576040805162461bcd60e51b815260206004820152601960248201527f74686520636f6e747261637420616c726561647920696e697400000000000000604482015290519081900360640190fd5b60008061149e60405180610100016040528060e0815260200161196360e09139611777565b815160045590925090506114b0611862565b60006114be848460006117c2565b60008083526001600160401b038281168252600160208181526040938490208651815467ffffffffffffffff191694169390931783558086015191830191909155918401516002820155606084015180519496509294508593909261152a9260038501929101906118a7565b50506003805467ffffffffffffffff19166001600160401b0384811691821767ffffffffffffffff60401b1916600160401b9290920291909117918290556000805460ff19166001179055662386f26fc10000600555602085810151604080519490931684529083015280517f5ac9b37d571677b80957ca05693f371526c602fd08042b416a29fdab7efefa499350918290030190a150505050565b6003546001600160401b031681565b600354600160401b90046001600160401b031681565b60405180610100016040528060e0815260200161196360e0913981565b61100081565b600381565b61100481565b6000816040516020018082805190602001908083835b6020831061164e5780518252601f19909201916020918201910161162f565b6001836020036101000a03801982511681845116808217855250505050505090500191505060405160208183030381529060405280519060200120836040516020018082805190602001908083835b602083106116bc5780518252601f19909201916020918201910161169d565b6001836020036101000a0380198251168184511680821785525050505050509050019150506040516020818303038152906040528051906020012014905092915050565b015190565b60200190565b60008460600151518284010392506000806117298760600151611777565b9092509050611739828683611781565b5050506040840151601f1983810191909152602090940151603f19830152605f19820192909252600454606719820152910160871990910152600190565b8051602090910191565b5b602081106117a1578251825260209283019290910190601f1901611782565b915181516020939093036101000a6000190180199091169216919091179052565b6117ca611862565b60088401516028850151604890950180519095600092916117e9611862565b6020810183905260408101829052866118545760008060688a036040519080825280601f01601f19166020018201604052801561182d576020820181803683370190505b506060840181905261183e90611777565b909250905061185160208c018383611781565b50505b989297509195505050505050565b604080516080810182526000808252602082018190529181019190915260608082015290565b6040518061100001604052806080906020820280368337509192915050565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f106118e857805160ff1916838001178555611915565b82800160010185558215611915579182015b828111156119155782518255916020019190600101906118fa565b50611921929150611925565b5090565b6107e391905b80821115611921576000815560010161192b56fe6661696c656420746f2073657269616c697a6520636f6e73656e73757320737461746542696e616e63652d436861696e2d47616e67657300000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000aea1ac326886b992a991d21a6eb155f41b77867cbf659e78f31d89d8205122a84d1be64f0e9a466c2e66a53433928192783e29f8fa21beb2133499b5ef770f60000000e8d4a5100099308aa365c40554bc89982af505d85da95251445d5dd4a9bb37dd2584fd92d3000000e8d4a5100001776920ff0b0f38d78cf95c033c21adf7045785114e392a7544179652e0a612000000e8d4a510006661696c656420746f206c6f61642076616c696461746f722073657420646174616c656e677468206f6620726577617264466f7256616c696461746f725365744368616e6765206d69736d617463686865616465722068656967687420646f65736e277420657175616c20746f207468652073706563696669656420686569676874746865206d6573736167652073656e646572206d75737420626520676f7665726e616e636520636f6e7472616374746865206e6577526577617264466f7256616c696461746f725365744368616e6765206f7574206f662072616e676563616e27742073796e6320686561646572206265666f726520696e697469616c486569676874a264697066735822122054f539d4f9624b5b87ea3b4d66b04e31a6fa9de3789af1872d4cddc7acc2a79364736f6c63430006040033" + }, + "0x0000000000000000000000000000000000001004": { + "balance": "180000000000000000000000000", + "code": "0x6080604052600436106102cd5760003560e01c80639dc0926211610175578063bd466461116100dc578063ebf71d5311610095578063fc1a598f1161006f578063fc1a598f14610c23578063fc3e59081461094e578063fd6a687914610c56578063ff9c00271461074c57610315565b8063ebf71d5314610be4578063f014847214610bf9578063f9a2bbc714610c0e57610315565b8063bd46646114610aed578063c81b166214610b20578063c8509d8114610b35578063dc6f5e901461094e578063dc927faf14610bba578063e1c7392a14610bcf57610315565b8063aa7415f51161012e578063aa7415f514610963578063ab51bb96146109aa578063ac431751146109bf578063b770186114610a8a578063b99328c514610a9f578063b9fd21e314610ad857610315565b80639dc09262146108c7578063a1a11bf5146108dc578063a496fba2146108f1578063a5cd588b14610906578063a78abc1614610939578063a7c9f02d1461094e57610315565b806361368475116102345780637942fd05116101ed5780638eff336c116101c75780638eff336c1461082557806396713da9146108645780639a854bbd146108795780639a99b4f01461088e57610315565b80637942fd051461078b578063831d65d1146107a05780638b87b21f1461056157610315565b8063613684751461031a5780636e0565201461060b5780636e47b4821461073757806370fd5bad1461074c57806371d308631461076157806375d47a0a1461077657610315565b806343756e5c1161028657806343756e5c14610576578063493279b11461058b5780634bf6c8821461031a57806350432d32146105b757806351e80672146105cc57806359b92789146105e157610315565b8063077b8f351461031a5780630bee7a67146103455780631182b87514610373578063149d14d91461046d5780633d713223146104945780633dffc3871461056157610315565b36610315573415610313576040805133815234602082015281517f6c98249d85d88c3753a04a22230f595e4dc8d3dc86c34af35deeeedc861b89db929181900390910190a15b005b600080fd5b34801561032657600080fd5b5061032f610c6b565b6040805160ff9092168252519081900360200190f35b34801561035157600080fd5b5061035a610c70565b6040805163ffffffff9092168252519081900360200190f35b34801561037f57600080fd5b506103f86004803603604081101561039657600080fd5b60ff8235169190810190604081016020820135600160201b8111156103ba57600080fd5b8201836020820111156103cc57600080fd5b803590602001918460018302840111600160201b831117156103ed57600080fd5b509092509050610c75565b6040805160208082528351818301528351919283929083019185019080838360005b8381101561043257818101518382015260200161041a565b50505050905090810190601f16801561045f5780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b34801561047957600080fd5b50610482610da3565b60408051918252519081900360200190f35b3480156104a057600080fd5b50610545600480360360208110156104b757600080fd5b810190602081018135600160201b8111156104d157600080fd5b8201836020820111156104e357600080fd5b803590602001918460018302840111600160201b8311171561050457600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250929550610da9945050505050565b604080516001600160a01b039092168252519081900360200190f35b34801561056d57600080fd5b5061032f610dcd565b34801561058257600080fd5b50610545610dd2565b34801561059757600080fd5b506105a0610dd8565b6040805161ffff9092168252519081900360200190f35b3480156105c357600080fd5b50610482610ddd565b3480156105d857600080fd5b50610545610de8565b3480156105ed57600080fd5b506105456004803603602081101561060457600080fd5b5035610dee565b6107236004803603608081101561062157600080fd5b810190602081018135600160201b81111561063b57600080fd5b82018360208201111561064d57600080fd5b803590602001918460208302840111600160201b8311171561066e57600080fd5b919390929091602081019035600160201b81111561068b57600080fd5b82018360208201111561069d57600080fd5b803590602001918460208302840111600160201b831117156106be57600080fd5b919390929091602081019035600160201b8111156106db57600080fd5b8201836020820111156106ed57600080fd5b803590602001918460208302840111600160201b8311171561070e57600080fd5b91935091503567ffffffffffffffff16610e09565b604080519115158252519081900360200190f35b34801561074357600080fd5b506105456112f1565b34801561075857600080fd5b5061032f6112f7565b34801561076d57600080fd5b506104826112fc565b34801561078257600080fd5b50610545611302565b34801561079757600080fd5b5061032f611308565b3480156107ac57600080fd5b50610313600480360360408110156107c357600080fd5b60ff8235169190810190604081016020820135600160201b8111156107e757600080fd5b8201836020820111156107f957600080fd5b803590602001918460018302840111600160201b8311171561081a57600080fd5b50909250905061130d565b34801561083157600080fd5b506103136004803603606081101561084857600080fd5b508035906001600160a01b036020820135169060400135611456565b34801561087057600080fd5b5061032f6114dc565b34801561088557600080fd5b506104826114e1565b34801561089a57600080fd5b50610482600480360360408110156108b157600080fd5b506001600160a01b0381351690602001356114ed565b3480156108d357600080fd5b50610545611611565b3480156108e857600080fd5b50610545611617565b3480156108fd57600080fd5b5061032f61161d565b34801561091257600080fd5b506104826004803603602081101561092957600080fd5b50356001600160a01b0316611622565b34801561094557600080fd5b50610723611634565b34801561095a57600080fd5b5061032f61163d565b6107236004803603608081101561097957600080fd5b5080356001600160a01b03908116916020810135909116906040810135906060013567ffffffffffffffff16611642565b3480156109b657600080fd5b5061035a61161d565b3480156109cb57600080fd5b50610313600480360360408110156109e257600080fd5b810190602081018135600160201b8111156109fc57600080fd5b820183602082011115610a0e57600080fd5b803590602001918460018302840111600160201b83111715610a2f57600080fd5b919390929091602081019035600160201b811115610a4c57600080fd5b820183602082011115610a5e57600080fd5b803590602001918460018302840111600160201b83111715610a7f57600080fd5b509092509050611d16565b348015610a9657600080fd5b50610482611f85565b348015610aab57600080fd5b5061031360048036036040811015610ac257600080fd5b50803590602001356001600160a01b0316611f8b565b348015610ae457600080fd5b50610482612001565b348015610af957600080fd5b5061048260048036036020811015610b1057600080fd5b50356001600160a01b031661200b565b348015610b2c57600080fd5b50610545612026565b348015610b4157600080fd5b5061031360048036036040811015610b5857600080fd5b60ff8235169190810190604081016020820135600160201b811115610b7c57600080fd5b820183602082011115610b8e57600080fd5b803590602001918460018302840111600160201b83111715610baf57600080fd5b50909250905061202c565b348015610bc657600080fd5b506105456120fc565b348015610bdb57600080fd5b50610313612102565b348015610bf057600080fd5b5061032f6121a2565b348015610c0557600080fd5b5061032f6121a7565b348015610c1a57600080fd5b506105456121ac565b348015610c2f57600080fd5b506103f860048036036020811015610c4657600080fd5b50356001600160a01b03166121b2565b348015610c6257600080fd5b506105456122d9565b600881565b606481565b60005460609060ff16610cbd576040805162461bcd60e51b815260206004820152601960248201526000805160206145c7833981519152604482015290519081900360640190fd5b3361200014610cfd5760405162461bcd60e51b815260040180806020018281038252602f815260200180614575602f913960400191505060405180910390fd5b60ff841660021415610d4f57610d4883838080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152506122df92505050565b9050610d9c565b6040805162461bcd60e51b815260206004820152601860248201527f756e7265636f676e697a65642073796e207061636b6167650000000000000000604482015290519081900360640190fd5b9392505050565b60015490565b6020818101516000908152600490915260409020546001600160a01b03165b919050565b600181565b61100181565b606181565b662386f26fc1000081565b61200081565b6000908152600460205260409020546001600160a01b031690565b6000805460ff16610e4f576040805162461bcd60e51b815260206004820152601960248201526000805160206145c7833981519152604482015290519081900360640190fd5b868514610e8d5760405162461bcd60e51b815260040180806020018281038252603b81526020018061453a603b913960400191505060405180910390fd5b868314610ecb5760405162461bcd60e51b815260040180806020018281038252603f81526020018061440d603f913960400191505060405180910390fd5b426078018267ffffffffffffffff161015610f175760405162461bcd60e51b81526004018080602001828103825260248152602001806142fd6024913960400191505060405180910390fd5b6402540be400340615610f5b5760405162461bcd60e51b815260040180806020018281038252604081526020018061463d6040913960400191505060405180910390fd5b60408051868152602080880282010190915285906000908190606090848015610f8e578160200160208202803683370190505b50905060005b84811015611069576402540be4008b8b83818110610fae57fe5b9050602002013581610fbc57fe5b0615610ff95760405162461bcd60e51b815260040180806020018281038252603c81526020018061444c603c913960400191505060405180910390fd5b61101e8b8b8381811061100857fe5b905060200201358561240390919063ffffffff16565b935061104a6402540be4008c8c8481811061103557fe5b9050602002013561245d90919063ffffffff16565b82828151811061105657fe5b6020908102919091010152600101610f94565b5060015461108e90611081908663ffffffff61249f16565b849063ffffffff61240316565b3410156110cc5760405162461bcd60e51b81526004018080602001828103825260568152602001806145e76056913960600191505060405180910390fd5b6110dc348463ffffffff6124f816565b91506110e6614156565b6040518060c001604052806221272160e91b60001b815260200160006001600160a01b031681526020018381526020018e8e808060200260200160405190810160405280939291908181526020018383602002808284376000920191909152505050908252506040805160208c810282810182019093528c82529283019290918d918d91829185019084908082843760009201919091525050509082525067ffffffffffffffff8916602090910152905061200063f7a251d760036111aa8461253a565b6111bf876402540be40063ffffffff61245d16565b6040518463ffffffff1660e01b8152600401808460ff1660ff16815260200180602001838152602001828103825284818151815260200191508051906020019080838360005b8381101561121d578181015183820152602001611205565b50505050905090810190601f16801561124a5780820380516001836020036101000a031916815260200191505b50945050505050602060405180830381600087803b15801561126b57600080fd5b505af115801561127f573d6000803e3d6000fd5b505050506040513d602081101561129557600080fd5b505060408051600081523360208201528082018690526060810185905290517f74eab09b0e53aefc23f2e1b16da593f95c2dd49c6f5a23720463d10d9c330b2a9181900360800190a15060019c9b505050505050505050505050565b61100581565b600281565b60015481565b61100881565b600b81565b60005460ff16611352576040805162461bcd60e51b815260206004820152601960248201526000805160206145c7833981519152604482015290519081900360640190fd5b33612000146113925760405162461bcd60e51b815260040180806020018281038252602f815260200180614575602f913960400191505060405180910390fd5b60ff8316600314156113e2576113dd82828080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152506127f592505050565b611451565b7f41ce201247b6ceb957dcdb217d0b8acb50b9ea0e12af9af4f5e7f38902101605838383604051808460ff1660ff168152602001806020018281038252848482818152602001925080828437600083820152604051601f909101601f1916909201829003965090945050505050a15b505050565b33611008146114965760405162461bcd60e51b81526004018080602001828103825260238152602001806145a46023913960400191505060405180910390fd5b600083815260046020908152604080832080546001600160a01b039096166001600160a01b03199096168617905593825260038152838220949094556002909352912055565b600981565b677ce66c50e284000081565b6000805460ff16611533576040805162461bcd60e51b815260206004820152601960248201526000805160206145c7833981519152604482015290519081900360640190fd5b33611005146115735760405162461bcd60e51b815260040180806020018281038252602f815260200180614270602f913960400191505060405180910390fd5b60004783106115825747611584565b825b90508015611608576040516001600160a01b0385169082156108fc029083906000818181858888f193505050501580156115c2573d6000803e3d6000fd5b50604080516001600160a01b03861681526020810183905281517ff8b71c64315fc33b2ead2adfa487955065152a8ac33d9d5193aafd7f45dc15a0929181900390910190a15b90505b92915050565b61100781565b61100681565b600081565b60026020526000908152604090205481565b60005460ff1681565b600381565b6000805460ff16611688576040805162461bcd60e51b815260206004820152601960248201526000805160206145c7833981519152604482015290519081900360640190fd5b426078018267ffffffffffffffff1610156116d45760405162461bcd60e51b81526004018080602001828103825260248152602001806142fd6024913960400191505060405180910390fd5b6402540be4003406156117185760405162461bcd60e51b815260040180806020018281038252604081526020018061463d6040913960400191505060405180910390fd5b600080806001600160a01b0388166117f75760015461173e90879063ffffffff61240316565b34101561177c5760405162461bcd60e51b81526004018080602001828103825260618152602001806143876061913960800191505060405180910390fd5b6402540be4008606156117c05760405162461bcd60e51b815260040180806020018281038252603c81526020018061444c603c913960400191505060405180910390fd5b6117d0348763ffffffff6124f816565b90506117e7866402540be40063ffffffff61245d16565b6221272160e91b93509150611a9a565b6001600160a01b03881660009081526003602052604090205492508261184e5760405162461bcd60e51b81526004018080602001828103825260318152602001806143566031913960400191505060405180910390fd5b60015434101561188f5760405162461bcd60e51b815260040180806020018281038252603f8152602001806144a9603f913960400191505060405180910390fd5b506001600160a01b03871660009081526002602052604090205434906008811115806118da57506008811180156118da57506118d8876007198301600a0a63ffffffff61285116565b155b6119155760405162461bcd60e51b815260040180806020018281038252603c81526020018061444c603c913960400191505060405180910390fd5b61191f8782612893565b925061192a846128d3565b15611972576305f5e1008310156119725760405162461bcd60e51b815260040180806020018281038252603a81526020018061429f603a913960400191505060405180910390fd5b60088110158061198c575060088110801561198c57508683115b6119c75760405162461bcd60e51b81526004018080602001828103825260258152602001806143e86025913960400191505060405180910390fd5b677ce66c50e2840000831115611a0e5760405162461bcd60e51b81526004018080602001828103825260358152602001806143216035913960400191505060405180910390fd5b604080516323b872dd60e01b81523360048201523060248201526044810189905290516001600160a01b038b16916323b872dd9160648083019260209291908290030181600087803b158015611a6357600080fd5b505af1158015611a77573d6000803e3d6000fd5b505050506040513d6020811015611a8d57600080fd5b5051611a9857600080fd5b505b611aa2614156565b6040805160c0810182528581526001600160a01b038b166020820152815160018082528184018452919283019181602001602082028036833750505081526040805160018082528183019092526020928301929091908083019080368337505050815260408051600180825281830190925260209283019290919080830190803683370190505081526020018767ffffffffffffffff168152509050828160400151600081518110611b5057fe5b602002602001018181525050878160600151600081518110611b6e57fe5b60200260200101906001600160a01b031690816001600160a01b031681525050338160800151600081518110611ba057fe5b6001600160a01b039092166020928302919091019091015261200063f7a251d76003611bcb8461253a565b611be0866402540be40063ffffffff61245d16565b6040518463ffffffff1660e01b8152600401808460ff1660ff16815260200180602001838152602001828103825284818151815260200191508051906020019080838360005b83811015611c3e578181015183820152602001611c26565b50505050905090810190601f168015611c6b5780820380516001836020036101000a031916815260200191505b50945050505050602060405180830381600087803b158015611c8c57600080fd5b505af1158015611ca0573d6000803e3d6000fd5b505050506040513d6020811015611cb657600080fd5b5050604080516001600160a01b038b1681523360208201528082018990526060810184905290517f74eab09b0e53aefc23f2e1b16da593f95c2dd49c6f5a23720463d10d9c330b2a9181900360800190a150600198975050505050505050565b3361100714611d565760405162461bcd60e51b815260040180806020018281038252602e8152602001806144e8602e913960400191505060405180910390fd5b60208114611dab576040805162461bcd60e51b815260206004820152601b60248201527f65787065637465642076616c7565206c656e6774682069732033320000000000604482015290519081900360640190fd5b606084848080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525050604080516020601f8801819004810282018101909252868152939450606093925086915085908190840183828082843760009201919091525050505060208301519091506772656c617946656560c01b811415611eb3576020820151670de0b6b3a76400008111158015611e5a57506402540be4008106155b611eab576040805162461bcd60e51b815260206004820152601960248201527f7468652072656c6179466565206f7574206f662072616e676500000000000000604482015290519081900360640190fd5b600155611ef0565b6040805162461bcd60e51b815260206004820152600d60248201526c756e6b6e6f776e20706172616d60981b604482015290519081900360640190fd5b7f6cdb0ac70ab7f2e2d035cca5be60d89906f2dede7648ddbd7402189c1eeed17a878787876040518080602001806020018381038352878782818152602001925080828437600083820152601f01601f191690910184810383528581526020019050858580828437600083820152604051601f909101601f19169092018290039850909650505050505050a150505050505050565b61c35081565b3361100814611fcb5760405162461bcd60e51b81526004018080602001828103825260238152602001806145a46023913960400191505060405180910390fd5b600091825260046020908152604080842080546001600160a01b03191690556001600160a01b0392909216835260039052812055565b6221272160e91b81565b6001600160a01b031660009081526003602052604090205490565b61100281565b60005460ff16612071576040805162461bcd60e51b815260206004820152601960248201526000805160206145c7833981519152604482015290519081900360640190fd5b33612000146120b15760405162461bcd60e51b815260040180806020018281038252602f815260200180614575602f913960400191505060405180910390fd5b60ff8316600314156113e2576113dd82828080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152506129d992505050565b61100381565b60005460ff161561215a576040805162461bcd60e51b815260206004820152601960248201527f74686520636f6e747261637420616c726561647920696e697400000000000000604482015290519081900360640190fd5b662386f26fc1000060019081556000808052600260205260127fac33ff75c19e70fe83507db0d683fd3465c996598dc972688b7ace676c89077b55805460ff19169091179055565b600481565b600581565b61100081565b6001600160a01b03811660009081526003602090815260409182902054825182815280840190935260609290918391906020820181803683375050506020810183905290506000805b60208160ff16101561224257828160ff168151811061221657fe5b01602001516001600160f81b031916156122355760019091019061223a565b612242565b6001016121fb565b5060608160ff166040519080825280601f01601f191660200182016040528015612273576020820181803683370190505b50905060005b8260ff168160ff1610156122cf57838160ff168151811061229657fe5b602001015160f81c60f81b828260ff16815181106122b057fe5b60200101906001600160f81b031916908160001a905350600101612279565b5095945050505050565b61100481565b60606122e96141a2565b60006122f484612ad7565b915091508061234a576040805162461bcd60e51b815260206004820152601f60248201527f756e7265636f676e697a6564207472616e73666572496e207061636b61676500604482015290519081900360640190fd5b600061235583612c16565b905063ffffffff8116156123e9576040808401516020808601516001600160a01b031660009081526002909152918220546123909190612893565b905061239a6141d7565b60405180608001604052808660000151815260200183815260200186608001516001600160a01b031681526020018463ffffffff1681525090506123dd81612f2e565b95505050505050610dc8565b50506040805160008152602081019091529150610dc89050565b600082820183811015611608576040805162461bcd60e51b815260206004820152601b60248201527f536166654d6174683a206164646974696f6e206f766572666c6f770000000000604482015290519081900360640190fd5b600061160883836040518060400160405280601a81526020017f536166654d6174683a206469766973696f6e206279207a65726f00000000000081525061300a565b6000826124ae5750600061160b565b828202828482816124bb57fe5b04146116085760405162461bcd60e51b81526004018080602001828103825260218152602001806144886021913960400191505060405180910390fd5b600061160883836040518060400160405280601e81526020017f536166654d6174683a207375627472616374696f6e206f766572666c6f7700008152506130ac565b60408051600680825260e08201909252606091829190816020015b6060815260200190600190039081612555575050835190915061257790613106565b8160008151811061258457fe5b60200260200101819052506125a583602001516001600160a01b0316613119565b816001815181106125b257fe5b6020026020010181905250600083604001515190506060816040519080825280602002602001820160405280156125fd57816020015b60608152602001906001900390816125e85790505b50905060005b8281101561264a5761262b8660400151828151811061261e57fe5b6020026020010151613106565b82828151811061263757fe5b6020908102919091010152600101612603565b506126548161313c565b8360028151811061266157fe5b60200260200101819052506060826040519080825280602002602001820160405280156126a257816020015b606081526020019060019003908161268d5790505b50905060005b838110156126f8576126d9876060015182815181106126c357fe5b60200260200101516001600160a01b0316613119565b8282815181106126e557fe5b60209081029190910101526001016126a8565b506127028161313c565b8460038151811061270f57fe5b602002602001018190525060608360405190808252806020026020018201604052801561275057816020015b606081526020019060019003908161273b5790505b50905060005b8481101561279057612771886080015182815181106126c357fe5b82828151811061277d57fe5b6020908102919091010152600101612756565b5061279a8161313c565b856004815181106127a757fe5b60200260200101819052506127c98760a0015167ffffffffffffffff16613106565b856005815181106127d657fe5b60200260200101819052506127ea8561313c565b979650505050505050565b6127fd6141fe565b6000612808836131c6565b91509150806128485760405162461bcd60e51b81526004018080602001828103825260248152602001806145166024913960400191505060405180910390fd5b61145182613391565b600061160883836040518060400160405280601881526020017f536166654d6174683a206d6f64756c6f206279207a65726f00000000000000008152506137e2565b600060088211156128bc576128b5836007198401600a0a63ffffffff61245d16565b905061160b565b611608836008849003600a0a63ffffffff61249f16565b604080516020808252818301909252600091606091906020820181803683375050506020810184905290506000805b60208160ff16101561294957828160ff168151811061291d57fe5b01602001516001600160f81b0319161561293c57600190910190612941565b612949565b600101612902565b50600860ff8216101561296157600092505050610dc8565b816005820360ff168151811061297357fe5b6020910101516001600160f81b031916602d60f81b1461299857600092505050610dc8565b816001820360ff16815181106129aa57fe5b6020910101516001600160f81b031916604d60f81b146129cf57600092505050610dc8565b5060019392505050565b6129e1614156565b60006129ec83613844565b9150915080612a2c5760405162461bcd60e51b81526004018080602001828103825260248152602001806142d96024913960400191505060405180910390fd5b612a346141fe565b602080840180516001600160a01b0390811684526040808701518585015291511660009081526002909252812054905b846040015151811015612ab557612a9285604001518281518110612a8457fe5b602002602001015183613abf565b85604001518281518110612aa257fe5b6020908102919091010152600101612a64565b506080840151604083015260056060830152612ad082613391565b5050505050565b612adf6141a2565b6000612ae96141a2565b612af1614235565b612b02612afd86613af8565b613b1d565b90506000805b612b1183613b67565b15612c095780612b3357612b2c612b2784613b88565b613bd6565b8452612c01565b8060011415612b6057612b4d612b4884613b88565b613c36565b6001600160a01b03166020850152612c01565b8060021415612b7f57612b75612b2784613b88565b6040850152612c01565b8060031415612ba757612b94612b4884613b88565b6001600160a01b03166060850152612c01565b8060041415612bcf57612bbc612b4884613b88565b6001600160a01b03166080850152612c01565b8060051415612bfc57612be4612b2784613b88565b67ffffffffffffffff1660a085015260019150612c01565b612c09565b600101612b08565b5091935090915050915091565b60208101516000906001600160a01b0316612d18578160a0015167ffffffffffffffff16421115612c4957506001610dc8565b8160400151471015612c5d57506003610dc8565b81606001516001600160a01b03166108fc83604001519081150290604051600060405180830381858888f19350505050612c9957506004610dc8565b7f471eb9cc1ffe55ffadf15b32595415eb9d80f22e761d24bd6dffc607e1284d5982602001518360600151846040015160405180846001600160a01b03166001600160a01b03168152602001836001600160a01b03166001600160a01b03168152602001828152602001935050505060405180910390a1506000610dc8565b8160a0015167ffffffffffffffff16421115612d3657506001610dc8565b81516020808401516001600160a01b031660009081526003909152604090205414612d6357506002610dc8565b602080830151604080516370a0823160e01b815230600482015290516000936001600160a01b03909316926370a082319261c3509260248083019392829003018187803b158015612db357600080fd5b5086fa158015612dc7573d6000803e3d6000fd5b50505050506040513d6020811015612dde57600080fd5b50516040840151909150811015612df9575060039050610dc8565b600083602001516001600160a01b031663a9059cbb61c350866060015187604001516040518463ffffffff1660e01b815260040180836001600160a01b03166001600160a01b0316815260200182815260200192505050602060405180830381600088803b158015612e6a57600080fd5b5087f1158015612e7e573d6000803e3d6000fd5b50505050506040513d6020811015612e9557600080fd5b505190508015612f22577f471eb9cc1ffe55ffadf15b32595415eb9d80f22e761d24bd6dffc607e1284d5984602001518560600151866040015160405180846001600160a01b03166001600160a01b03168152602001836001600160a01b03166001600160a01b03168152602001828152602001935050505060405180910390a15060009150610dc89050565b5060059150610dc89050565b60408051600480825260a08201909252606091829190816020015b6060815260200190600190039081612f495750508351909150612f6b90613106565b81600081518110612f7857fe5b6020026020010181905250612f908360200151613106565b81600181518110612f9d57fe5b6020026020010181905250612fbe83604001516001600160a01b0316613119565b81600281518110612fcb57fe5b6020026020010181905250612fe9836060015163ffffffff16613106565b81600381518110612ff657fe5b6020026020010181905250610d9c8161313c565b600081836130965760405162461bcd60e51b81526004018080602001828103825283818151815260200191508051906020019080838360005b8381101561305b578181015183820152602001613043565b50505050905090810190601f1680156130885780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b5060008385816130a257fe5b0495945050505050565b600081848411156130fe5760405162461bcd60e51b815260206004820181815283516024840152835190928392604490910191908501908083836000831561305b578181015183820152602001613043565b505050900390565b606061160b61311483613c50565b613d36565b60408051600560a21b8318601482015260348101909152606090610d9c81613d36565b606081516000141561315d5750604080516000815260208101909152610dc8565b60608260008151811061316c57fe5b602002602001015190506000600190505b83518110156131ad576131a38285838151811061319657fe5b6020026020010151613d88565b915060010161317d565b50610d9c6131c0825160c060ff16613e05565b82613d88565b6131ce6141fe565b60006131d86141fe565b6131e0614235565b6131ec612afd86613af8565b90506000805b6131fb83613b67565b15612c09578061322157613211612b4884613b88565b6001600160a01b03168452613389565b80600114156132c257606061323d61323885613b88565b613efd565b9050805160405190808252806020026020018201604052801561326a578160200160208202803683370190505b50602086015260005b81518110156132bb5761329882828151811061328b57fe5b6020026020010151613bd6565b866020015182815181106132a857fe5b6020908102919091010152600101613273565b5050613389565b80600214156133645760606132d961323885613b88565b90508051604051908082528060200260200182016040528015613306578160200160208202803683370190505b50604086015260005b81518110156132bb5761333482828151811061332757fe5b6020026020010151613c36565b8660400151828151811061334457fe5b6001600160a01b039092166020928302919091019091015260010161330f565b8060031415612bfc57613379612b2784613b88565b63ffffffff166060850152600191505b6001016131f2565b80516001600160a01b03166135885760005b81602001515181101561358257816040015181815181106133c057fe5b60200260200101516001600160a01b03166108fc836020015183815181106133e457fe5b60200260200101519081150290604051600060405180830381858888f193505050506134c4577f203f9f67a785f4f81be4d48b109aa0c498d1bc8097ecc2627063f480cc5fe73e82600001518360400151838151811061344057fe5b60200260200101518460200151848151811061345857fe5b6020026020010151856060015160405180856001600160a01b03166001600160a01b03168152602001846001600160a01b03166001600160a01b031681526020018381526020018263ffffffff1663ffffffff16815260200194505050505060405180910390a161357a565b7fd468d4fa5e8fb4adc119b29a983fd0785e04af5cb8b7a3a69a47270c54b6901a8260000151836040015183815181106134fa57fe5b60200260200101518460200151848151811061351257fe5b6020026020010151856060015160405180856001600160a01b03166001600160a01b03168152602001846001600160a01b03166001600160a01b031681526020018381526020018263ffffffff1663ffffffff16815260200194505050505060405180910390a15b6001016133a3565b506137df565b60005b8160200151518110156137dd57600082600001516001600160a01b031663a9059cbb61c350856040015185815181106135c057fe5b6020026020010151866020015186815181106135d857fe5b60200260200101516040518463ffffffff1660e01b815260040180836001600160a01b03166001600160a01b0316815260200182815260200192505050602060405180830381600088803b15801561362f57600080fd5b5087f1158015613643573d6000803e3d6000fd5b50505050506040513d602081101561365a57600080fd5b50519050801561371e577fd468d4fa5e8fb4adc119b29a983fd0785e04af5cb8b7a3a69a47270c54b6901a83600001518460400151848151811061369a57fe5b6020026020010151856020015185815181106136b257fe5b6020026020010151866060015160405180856001600160a01b03166001600160a01b03168152602001846001600160a01b03166001600160a01b031681526020018381526020018263ffffffff1663ffffffff16815260200194505050505060405180910390a16137d4565b7f203f9f67a785f4f81be4d48b109aa0c498d1bc8097ecc2627063f480cc5fe73e83600001518460400151848151811061375457fe5b60200260200101518560200151858151811061376c57fe5b6020026020010151866060015160405180856001600160a01b03166001600160a01b03168152602001846001600160a01b03166001600160a01b031681526020018381526020018263ffffffff1663ffffffff16815260200194505050505060405180910390a15b5060010161358b565b505b50565b600081836138315760405162461bcd60e51b815260206004820181815283516024840152835190928392604490910191908501908083836000831561305b578181015183820152602001613043565b5082848161383b57fe5b06949350505050565b61384c614156565b6000613856614156565b61385e614235565b61386a612afd86613af8565b90506000805b61387983613b67565b15613ab157806138965761388f612b2784613b88565b8452613aa9565b80600114156138be576138ab612b4884613b88565b6001600160a01b03166020850152613aa9565b806002141561394d5760606138d561323885613b88565b90508051604051908082528060200260200182016040528015613902578160200160208202803683370190505b50604086015260005b81518110156139465761392382828151811061328b57fe5b8660400151828151811061393357fe5b602090810291909101015260010161390b565b5050613aa9565b80600314156139e257606061396461323885613b88565b90508051604051908082528060200260200182016040528015613991578160200160208202803683370190505b50606086015260005b8151811015613946576139b282828151811061332757fe5b866060015182815181106139c257fe5b6001600160a01b039092166020928302919091019091015260010161399a565b8060041415613a775760606139f961323885613b88565b90508051604051908082528060200260200182016040528015613a26578160200160208202803683370190505b50608086015260005b815181101561394657613a4782828151811061332757fe5b86608001518281518110613a5757fe5b6001600160a01b0390921660209283029190910190910152600101613a2f565b8060051415613aa457613a8c612b2784613b88565b67ffffffffffffffff1660a085015260019150613aa9565b613ab1565b600101613870565b509195600195509350505050565b60006008821115613ae1576128b5836007198401600a0a63ffffffff61249f16565b611608836008849003600a0a63ffffffff61245d16565b613b00614255565b506040805180820190915281518152602082810190820152919050565b613b25614235565b613b2e82613fce565b613b3757600080fd5b6000613b468360200151613ffe565b60208085015160408051808201909152868152920190820152915050919050565b6000613b71614255565b505080518051602091820151919092015191011190565b613b90614255565b613b9982613b67565b613ba257600080fd5b60208201516000613bb282614061565b80830160209586015260408051808201909152908152938401919091525090919050565b805160009015801590613beb57508151602110155b613bf457600080fd5b6000613c038360200151613ffe565b83516020808601518301805193945091849003929190831015613c2d57826020036101000a820491505b50949350505050565b8051600090601514613c4757600080fd5b61160b82613bd6565b604080516020808252818301909252606091829190602082018180368337505050602081018490529050600067ffffffffffffffff198416613c9457506018613cb8565b6fffffffffffffffffffffffffffffffff198416613cb457506010613cb8565b5060005b6020811015613cee57818181518110613ccd57fe5b01602001516001600160f81b03191615613ce657613cee565b600101613cb8565b60008160200390506060816040519080825280601f01601f191660200182016040528015613d23576020820181803683370190505b5080830196909652508452509192915050565b606081516001148015613d685750607f60f81b82600081518110613d5657fe5b01602001516001600160f81b03191611155b15613d74575080610dc8565b61160b613d868351608060ff16613e05565b835b6060806040519050835180825260208201818101602087015b81831015613db9578051835260209283019201613da1565b50855184518101855292509050808201602086015b81831015613de6578051835260209283019201613dce565b508651929092011591909101601f01601f191660405250905092915050565b6060680100000000000000008310613e55576040805162461bcd60e51b815260206004820152600e60248201526d696e70757420746f6f206c6f6e6760901b604482015290519081900360640190fd5b60408051600180825281830190925260609160208201818036833701905050905060378411613eaf5782840160f81b81600081518110613e9157fe5b60200101906001600160f81b031916908160001a905350905061160b565b6060613eba85613c50565b90508381510160370160f81b82600081518110613ed357fe5b60200101906001600160f81b031916908160001a905350613ef48282613d88565b95945050505050565b6060613f0882613fce565b613f1157600080fd5b6000613f1c836140fa565b9050606081604051908082528060200260200182016040528015613f5a57816020015b613f47614255565b815260200190600190039081613f3f5790505b5090506000613f6c8560200151613ffe565b60208601510190506000805b84811015613fc357613f8983614061565b9150604051806040016040528083815260200184815250848281518110613fac57fe5b602090810291909101015291810191600101613f78565b509195945050505050565b8051600090613fdf57506000610dc8565b6020820151805160001a9060c08210156129cf57600092505050610dc8565b8051600090811a6080811015614018576000915050610dc8565b60b8811080614033575060c08110801590614033575060f881105b15614042576001915050610dc8565b60c08110156140565760b519019050610dc8565b60f519019050610dc8565b80516000908190811a608081101561407c57600191506140f3565b60b881101561409157607e19810191506140f3565b60c08110156140be5760b78103600185019450806020036101000a855104600182018101935050506140f3565b60f88110156140d35760be19810191506140f3565b60f78103600185019450806020036101000a855104600182018101935050505b5092915050565b805160009061410b57506000610dc8565b6000809050600061411f8460200151613ffe565b602085015185519181019250015b8082101561414d5761413e82614061565b6001909301929091019061412d565b50909392505050565b6040518060c001604052806000801916815260200160006001600160a01b03168152602001606081526020016060815260200160608152602001600067ffffffffffffffff1681525090565b6040805160c081018252600080825260208201819052918101829052606081018290526080810182905260a081019190915290565b60408051608081018252600080825260208201819052918101829052606081019190915290565b604051806080016040528060006001600160a01b031681526020016060815260200160608152602001600063ffffffff1681525090565b6040518060400160405280614248614255565b8152602001600081525090565b60405180604001604052806000815260200160008152509056fe746865206d6573736167652073656e646572206d75737420626520696e63656e746976697a6520636f6e7472616374466f72206d696e69546f6b656e2c20746865207472616e7366657220616d6f756e74206d757374206e6f74206265206c657373207468616e2031756e7265636f676e697a6564207472616e736665724f75742073796e207061636b61676565787069726554696d65206d7573742062652074776f206d696e75746573206c61746572616d6f756e7420697320746f6f206c617267652c20657863656564206d6178696d756d206265703220746f6b656e20616d6f756e7474686520636f6e747261637420686173206e6f74206265656e20626f756e6420746f20616e79206265703220746f6b656e726563656976656420424e4220616d6f756e742073686f756c64206265206e6f206c657373207468616e207468652073756d206f66207472616e736665724f757420424e4220616d6f756e7420616e64206d696e696d756d2072656c6179466565616d6f756e7420697320746f6f206c617267652c2075696e74323536206f766572666c6f774c656e677468206f6620726563697069656e74416464727320646f65736e277420657175616c20746f206c656e677468206f6620726566756e644164647273696e76616c6964207472616e7366657220616d6f756e743a20707265636973696f6e206c6f737320696e20616d6f756e7420636f6e76657273696f6e536166654d6174683a206d756c7469706c69636174696f6e206f766572666c6f77726563656976656420424e4220616d6f756e742073686f756c64206265206e6f206c657373207468616e20746865206d696e696d756d2072656c6179466565746865206d6573736167652073656e646572206d75737420626520676f7665726e616e636520636f6e7472616374756e7265636f676e697a6564207472616e736665724f75742061636b207061636b6167654c656e677468206f6620726563697069656e74416464727320646f65736e277420657175616c20746f206c656e677468206f6620616d6f756e7473746865206d6573736167652073656e646572206d7573742062652063726f737320636861696e20636f6e7472616374746865206d73672073656e646572206d75737420626520746f6b656e4d616e6167657274686520636f6e7472616374206e6f7420696e69742079657400000000000000726563656976656420424e4220616d6f756e742073686f756c64206265206e6f206c657373207468616e207468652073756d206f66207472616e7366657220424e4220616d6f756e7420616e642072656c6179466565696e76616c696420726563656976656420424e4220616d6f756e743a20707265636973696f6e206c6f737320696e20616d6f756e7420636f6e76657273696f6ea2646970667358221220ee0772c728608488e6a5f5dfa5f29f8c4467aea7333c447ace15be38f4600ff464736f6c63430006040033" + }, + "0x0000000000000000000000000000000000001005": { + "balance": "0x0", + "code": "0x6080604052600436106102605760003560e01c80637942fd0511610144578063ac431751116100b6578063dc927faf1161007a578063dc927faf1461076a578063dcae76ab1461077f578063e1c7392a14610794578063f9a2bbc7146107a9578063fc3e5908146107be578063fd6a6879146107d357610267565b8063ac43175114610630578063af40068114610701578063bd4cc8301461072b578063c7d2b028146102eb578063c81b16621461075557610267565b8063a1a11bf511610108578063a1a11bf5146105b2578063a3c3c0ad146105c7578063a413aff6146105dc578063a60d770b146105f1578063a78abc1614610606578063ab51bb961461061b57610267565b80637942fd051461052b57806387c1830a14610540578063930e1b091461055557806396713da9146105885780639dc092621461059d57610267565b806343756e5c116101dd57806354133307116101a15780635413330714610445578063572120951461045a5780636e47b4821461048d5780636f93d2e6146104a257806370fd5bad1461050157806375d47a0a1461051657610267565b806343756e5c146103b0578063490dfdf7146103c5578063493279b1146103ef5780634bf6c8821461041b57806351e806721461043057610267565b8063189d817211610224578063189d8172146103005780631b20087c146103155780631c6433121461032a5780633dffc3871461037057806341b5f4e51461039b57610267565b806308f2ec061461026c5780630bee7a67146102935780630c732068146102c157806310e06a76146102d6578063117048d8146102eb57610267565b3661026757005b600080fd5b34801561027857600080fd5b506102816107e8565b60408051918252519081900360200190f35b34801561029f57600080fd5b506102a86107ee565b6040805163ffffffff9092168252519081900360200190f35b3480156102cd57600080fd5b506102816107f3565b3480156102e257600080fd5b506102816107f9565b3480156102f757600080fd5b506102816107ff565b34801561030c57600080fd5b50610281610804565b34801561032157600080fd5b5061028161080a565b34801561033657600080fd5b506103546004803603602081101561034d57600080fd5b5035610810565b604080516001600160a01b039092168252519081900360200190f35b34801561037c57600080fd5b506103856107ff565b6040805160ff9092168252519081900360200190f35b3480156103a757600080fd5b50610281610837565b3480156103bc57600080fd5b5061035461083c565b3480156103d157600080fd5b50610354600480360360208110156103e857600080fd5b5035610842565b3480156103fb57600080fd5b5061040461084f565b6040805161ffff9092168252519081900360200190f35b34801561042757600080fd5b50610385610854565b34801561043c57600080fd5b50610354610859565b34801561045157600080fd5b5061028161085f565b34801561046657600080fd5b506102816004803603602081101561047d57600080fd5b50356001600160a01b0316610865565b34801561049957600080fd5b50610354610877565b3480156104ae57600080fd5b506104ed600480360360808110156104c557600080fd5b506001600160a01b03813581169160208101359091169060408101359060600135151561087d565b604080519115158252519081900360200190f35b34801561050d57600080fd5b50610385610c21565b34801561052257600080fd5b50610354610c26565b34801561053757600080fd5b50610385610c2c565b34801561054c57600080fd5b50610281610c31565b34801561056157600080fd5b506102816004803603602081101561057857600080fd5b50356001600160a01b0316610c37565b34801561059457600080fd5b50610385610c49565b3480156105a957600080fd5b50610354610c4e565b3480156105be57600080fd5b50610354610c54565b3480156105d357600080fd5b50610281610c5a565b3480156105e857600080fd5b50610281610c60565b3480156105fd57600080fd5b50610281610c66565b34801561061257600080fd5b506104ed610c6b565b34801561062757600080fd5b506102a8610c74565b34801561063c57600080fd5b506106ff6004803603604081101561065357600080fd5b81019060208101813564010000000081111561066e57600080fd5b82018360208201111561068057600080fd5b803590602001918460018302840111640100000000831117156106a257600080fd5b9193909290916020810190356401000000008111156106c057600080fd5b8201836020820111156106d257600080fd5b803590602001918460018302840111640100000000831117156106f457600080fd5b509092509050610c79565b005b34801561070d57600080fd5b506102816004803603602081101561072457600080fd5b5035611237565b34801561073757600080fd5b506102816004803603602081101561074e57600080fd5b5035611299565b34801561076157600080fd5b506103546112b4565b34801561077657600080fd5b506103546112ba565b34801561078b57600080fd5b506102816112c0565b3480156107a057600080fd5b506106ff6112c6565b3480156107b557600080fd5b5061035461138f565b3480156107ca57600080fd5b50610385611395565b3480156107df57600080fd5b5061035461139a565b61019081565b606481565b60035481565b600b5481565b600181565b60045481565b600c5481565b6006818154811061081d57fe5b6000918252602090912001546001600160a01b0316905081565b605081565b61100181565b6008818154811061081d57fe5b606181565b600881565b61200081565b6103e881565b60076020526000908152604090205481565b61100581565b6000805460ff166108d5576040805162461bcd60e51b815260206004820152601960248201527f74686520636f6e7472616374206e6f7420696e69742079657400000000000000604482015290519081900360640190fd5b33612000146109155760405162461bcd60e51b815260040180806020018281038252602f815260200180611d2b602f913960400191505060405180910390fd5b6000821561099a57604080516309a99b4f60e41b8152611005600482015260248101869052905161100291639a99b4f09160448083019260209291908290030181600087803b15801561096757600080fd5b505af115801561097b573d6000803e3d6000fd5b505050506040513d602081101561099157600080fd5b50519050610a13565b604080516309a99b4f60e41b8152611005600482015260248101869052905161100491639a99b4f09160448083019260209291908290030181600087803b1580156109e457600080fd5b505af11580156109f8573d6000803e3d6000fd5b505050506040513d6020811015610a0e57600080fd5b505190505b600c805460010190556000610a27826113a0565b600954909150610a3d908263ffffffff6113cf16565b600955600a54610a65908290610a59908563ffffffff6113cf16565b9063ffffffff61143016565b600a556001600160a01b038716600090815260056020526040902054610ad157600680546001810182556000919091527ff652222313e28459528d920b65115c16c04f3efc82aaedc97be59f3f377c0d3f0180546001600160a01b0319166001600160a01b0389161790555b6001600160a01b038088166000908152600560209081526040808320805460010190559289168252600790522054610b4f57600880546001810182556000919091527ff3f7a9fe364faab93b216da50a3214154f22a0a2b415b23a84c8169e8b636ee30180546001600160a01b0319166001600160a01b0388161790555b6001600160a01b038616600090815260076020526040902080546001019055600c546103e81415610c1457600b54600954600a5460408051938452602084019290925282820152517f127fd0fd1fcf84c71c5c649625ef186be105a71ecc80c7cb3f96cd99ccae1e0f9181900360600190a1610bca86611472565b610bd38661171f565b6040516110029081904780156108fc02916000818181858888f19350505050158015610c03573d6000803e3d6000fd5b5050600b805460010190556000600c555b5060019695505050505050565b600281565b61100881565b600b81565b60015481565b60056020526000908152604090205481565b600981565b61100781565b61100681565b600a5481565b60025481565b600581565b60005460ff1681565b600081565b3361100714610cb95760405162461bcd60e51b815260040180806020018281038252602e815260200180611cdc602e913960400191505060405180910390fd5b60005460ff16610cfa5760405162461bcd60e51b8152600401808060200182810382526021815260200180611d0a6021913960400191505060405180910390fd5b610d6684848080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152505060408051808201909152601581527436b7b632b1bab632a432b0b232b92932b630bcb2b960591b6020820152915061199f9050565b15610df15760208114610daa5760405162461bcd60e51b8152600401808060200182810382526028815260200180611c656028913960400191505060405180910390fd5b604080516020601f8401819004810282018101909252828152600091610de891858580838501838280828437600092019190915250611a8692505050565b600155506111a5565b610e6584848080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152505060408051808201909152601881527f64656e6f6d696e61746f7248656164657252656c6179657200000000000000006020820152915061199f9050565b15610f2d5760208114610ea95760405162461bcd60e51b815260040180806020018281038252602e815260200180611c8d602e913960400191505060405180910390fd5b604080516020601f8401819004810282018101909252828152600091610ee791858580838501838280828437600092019190915250611a8692505050565b905080610f255760405162461bcd60e51b8152600401808060200182810382526030815260200180611d5a6030913960400191505060405180910390fd5b6002556111a5565b610fa184848080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152505060408051808201909152601a81527f6d6f6c6563756c6543616c6c6572436f6d70656e736174696f6e0000000000006020820152915061199f9050565b1561102c5760208114610fe55760405162461bcd60e51b815260040180806020018281038252602e815260200180611c8d602e913960400191505060405180910390fd5b604080516020601f840181900481028201810190925282815260009161102391858580838501838280828437600092019190915250611a8692505050565b600355506111a5565b6110a084848080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152505060408051808201909152601d81527f64656e6f6d696e61746f7243616c6c6572436f6d70656e736174696f6e0000006020820152915061199f9050565b1561116857602081146110e45760405162461bcd60e51b815260040180806020018281038252602e815260200180611c8d602e913960400191505060405180910390fd5b604080516020601f840181900481028201810190925282815260009161112291858580838501838280828437600092019190915250611a8692505050565b9050806111605760405162461bcd60e51b8152600401808060200182810382526035815260200180611d8a6035913960400191505060405180910390fd5b6004556111a5565b6040805162461bcd60e51b815260206004820152600d60248201526c756e6b6e6f776e20706172616d60981b604482015290519081900360640190fd5b7f6cdb0ac70ab7f2e2d035cca5be60d89906f2dede7648ddbd7402189c1eeed17a848484846040518080602001806020018381038352878782818152602001925080828437600083820152601f01601f191690910184810383528581526020019050858580828437600083820152604051601f909101601f19169092018290039850909650505050505050a150505050565b60006101908211611249575080611294565b8161019010801561125c57506103208211155b1561126a5750610190611294565b6103208211801561127d575061044c8211155b1561128e57506104b0819003611294565b50600481045b919050565b600061019082116112ab575080611294565b50610190611294565b61100281565b61100381565b60095481565b60005460ff161561131e576040805162461bcd60e51b815260206004820152601960248201527f74686520636f6e747261637420616c726561647920696e697400000000000000604482015290519081900360640190fd5b60005460ff161561136c576040805162461bcd60e51b8152602060048201526013602482015272185b1c9958591e481a5b9a5d1a585b1a5e9959606a1b604482015290519081900360640190fd5b60018080556005600255600381905560506004556000805460ff19169091179055565b61100081565b600381565b61100481565b60006113c96002546113bd60015485611a8b90919063ffffffff16565b9063ffffffff611ae416565b92915050565b600082820183811015611429576040805162461bcd60e51b815260206004820152601b60248201527f536166654d6174683a206164646974696f6e206f766572666c6f770000000000604482015290519081900360640190fd5b9392505050565b600061142983836040518060400160405280601e81526020017f536166654d6174683a207375627472616374696f6e206f766572666c6f770000815250611b26565b600954600680546040805160208084028201810190925282815260009360609391929091908301828280156114d057602002820191906000526020600020905b81546001600160a01b031681526001909101906020018083116114b2575b5050505050905060608151604051908082528060200260200182016040528015611504578160200160208202803683370190505b50905060005b825181101561159157600083828151811061152157fe5b60200260200101519050600061155b60056000846001600160a01b03166001600160a01b0316815260200190815260200160002054611299565b90508084848151811061156a57fe5b6020908102919091010152611585868263ffffffff6113cf16565b9550505060010161150a565b5060006115af6004546113bd60035488611a8b90919063ffffffff16565b90506115c1858263ffffffff61143016565b94508460015b84518110156116575760006115fc876113bd8a8886815181106115e657fe5b6020026020010151611a8b90919063ffffffff16565b905085828151811061160a57fe5b60200260200101516001600160a01b03166108fc829081150290604051600060405180830381858888f15061164c93508692508491505063ffffffff61143016565b9250506001016115c7565b508360008151811061166557fe5b60200260200101516001600160a01b03166108fc829081150290604051600060405180830381858888f150506040516001600160a01b038b16935085156108fc0292508591506000818181858888f1505060006009819055925050505b845181101561170957600560008683815181106116db57fe5b6020908102919091018101516001600160a01b031682528101919091526040016000908120556001016116c2565b5061171660066000611c22565b50505050505050565b600a546008805460408051602080840282018101909252828152600093606093919290919083018282801561177d57602002820191906000526020600020905b81546001600160a01b0316815260019091019060200180831161175f575b50505050509050606081516040519080825280602002602001820160405280156117b1578160200160208202803683370190505b50905060005b82518110156118305760008382815181106117ce57fe5b60200260200101519050600061180860076000846001600160a01b03166001600160a01b0316815260200190815260200160002054611237565b90508084848151811061181757fe5b60209081029190910101529490940193506001016117b7565b50600061184e6004546113bd60035488611a8b90919063ffffffff16565b9050611860858263ffffffff61143016565b94508460015b84518110156118e0576000611885876113bd8a8886815181106115e657fe5b905085828151811061189357fe5b60200260200101516001600160a01b03166108fc829081150290604051600060405180830381858888f1506118d593508692508491505063ffffffff61143016565b925050600101611866565b50836000815181106118ee57fe5b60200260200101516001600160a01b03166108fc829081150290604051600060405180830381858888f150506040516001600160a01b038b16935085156108fc0292508591506000818181858888f150506000600a819055925050505b8451811015611992576007600086838151811061196457fe5b6020908102919091018101516001600160a01b0316825281019190915260400160009081205560010161194b565b5061171660086000611c22565b6000816040516020018082805190602001908083835b602083106119d45780518252601f1990920191602091820191016119b5565b6001836020036101000a03801982511681845116808217855250505050505090500191505060405160208183030381529060405280519060200120836040516020018082805190602001908083835b60208310611a425780518252601f199092019160209182019101611a23565b6001836020036101000a0380198251168184511680821785525050505050509050019150506040516020818303038152906040528051906020012014905092915050565b015190565b600082611a9a575060006113c9565b82820282848281611aa757fe5b04146114295760405162461bcd60e51b8152600401808060200182810382526021815260200180611cbb6021913960400191505060405180910390fd5b600061142983836040518060400160405280601a81526020017f536166654d6174683a206469766973696f6e206279207a65726f000000000000815250611bbd565b60008184841115611bb55760405162461bcd60e51b81526004018080602001828103825283818151815260200191508051906020019080838360005b83811015611b7a578181015183820152602001611b62565b50505050905090810190601f168015611ba75780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b505050900390565b60008183611c0c5760405162461bcd60e51b8152602060048201818152835160248401528351909283926044909101919085019080838360008315611b7a578181015183820152602001611b62565b506000838581611c1857fe5b0495945050505050565b5080546000825590600052602060002090810190611c409190611c43565b50565b611c6191905b80821115611c5d5760008155600101611c49565b5090565b9056fe6c656e677468206f66206d6f6c6563756c6548656164657252656c61796572206d69736d617463686c656e677468206f6620726577617264466f7256616c696461746f725365744368616e6765206d69736d61746368536166654d6174683a206d756c7469706c69636174696f6e206f766572666c6f77746865206d6573736167652073656e646572206d75737420626520676f7665726e616e636520636f6e7472616374636f6e747261637420686173206e6f74206265656e20696e697469616c697a6564746865206d6573736167652073656e646572206d7573742062652063726f737320636861696e20636f6e7472616374746865206e657744656e6f6d696e61746f7248656164657252656c61796572206d757374206e6f74206265207a65726f746865206e657744656e6f6d696e61746f7243616c6c6572436f6d70656e736174696f6e206d757374206e6f74206265207a65726fa26469706673582212202548a56b68ed51ad6e9a1aa43899b24ae5df4a24a9f594232fc5392c443544fb64736f6c63430006040033" + }, + "0x0000000000000000000000000000000000001006": { + "balance": "0x0", + "code": "0x6080604052600436106101c25760003560e01c806395468d26116100f7578063c81b166211610095578063f9a2bbc711610064578063f9a2bbc714610529578063fb7cfdd71461053e578063fc3e590814610553578063fd6a687914610568576101c2565b8063c81b1662146104d5578063dc927faf146104ea578063e1c7392a146104ff578063e79a198f14610514576101c2565b8063a1a11bf5116100d1578063a1a11bf5146103c7578063a78abc16146103dc578063ab51bb96146103f1578063ac43175114610406576101c2565b806395468d261461038857806396713da91461039d5780639dc09262146103b2576101c2565b8063541d55481161016457806370fd5bad1161013e57806370fd5bad1461033457806375d47a0a146103495780637942fd051461035e5780637ae2308814610373576101c2565b8063541d5548146102b15780636a87d780146102f85780636e47b4821461031f576101c2565b806343756e5c116101a057806343756e5c1461022a578063493279b11461025b5780634bf6c8821461028757806351e806721461029c576101c2565b80630bee7a67146101c75780631aa3a008146101f55780633dffc387146101ff575b600080fd5b3480156101d357600080fd5b506101dc61057d565b6040805163ffffffff9092168252519081900360200190f35b6101fd610582565b005b34801561020b57600080fd5b50610214610733565b6040805160ff9092168252519081900360200190f35b34801561023657600080fd5b5061023f610738565b604080516001600160a01b039092168252519081900360200190f35b34801561026757600080fd5b5061027061073e565b6040805161ffff9092168252519081900360200190f35b34801561029357600080fd5b50610214610743565b3480156102a857600080fd5b5061023f610748565b3480156102bd57600080fd5b506102e4600480360360208110156102d457600080fd5b50356001600160a01b031661074e565b604080519115158252519081900360200190f35b34801561030457600080fd5b5061030d61076c565b60408051918252519081900360200190f35b34801561032b57600080fd5b5061023f610772565b34801561034057600080fd5b50610214610778565b34801561035557600080fd5b5061023f61077d565b34801561036a57600080fd5b50610214610783565b34801561037f57600080fd5b5061030d610788565b34801561039457600080fd5b5061030d610795565b3480156103a957600080fd5b506102146107a1565b3480156103be57600080fd5b5061023f6107a6565b3480156103d357600080fd5b5061023f6107ac565b3480156103e857600080fd5b506102e46107b2565b3480156103fd57600080fd5b506101dc6107bb565b34801561041257600080fd5b506101fd6004803603604081101561042957600080fd5b81019060208101813564010000000081111561044457600080fd5b82018360208201111561045657600080fd5b8035906020019184600183028401116401000000008311171561047857600080fd5b91939092909160208101903564010000000081111561049657600080fd5b8201836020820111156104a857600080fd5b803590602001918460018302840111640100000000831117156104ca57600080fd5b5090925090506107c0565b3480156104e157600080fd5b5061023f610bd6565b3480156104f657600080fd5b5061023f610bdc565b34801561050b57600080fd5b506101fd610be2565b34801561052057600080fd5b506101fd610c64565b34801561053557600080fd5b5061023f610e0b565b34801561054a57600080fd5b5061030d610e11565b34801561055f57600080fd5b50610214610e17565b34801561057457600080fd5b5061023f610e1c565b606481565b3360009081526004602052604090205460ff16156105df576040805162461bcd60e51b81526020600482015260156024820152741c995b185e595c88185b1c9958591e48195e1a5cdd605a1b604482015290519081900360640190fd5b60005460ff16610632576040805162461bcd60e51b81526020600482015260196024820152781d1a194818dbdb9d1c9858dd081b9bdd081a5b9a5d081e595d603a1b604482015290519081900360640190fd5b61063b33610e22565b156106775760405162461bcd60e51b8152600401808060200182810382526027815260200180610f546027913960400191505060405180910390fd5b60015434146106b75760405162461bcd60e51b8152600401808060200182810382526025815260200180610f2f6025913960400191505060405180910390fd5b604080518082018252600180548252600254602080840191825233600081815260038352868120955186559251948401949094556004815290849020805460ff1916909217909155825191825291517fdb33a09d38b59a8fa8b7d92a1d82c8015e99f05f67ae9c9ae623157767959496929181900390910190a1565b600181565b61100181565b606181565b600881565b61200081565b6001600160a01b031660009081526004602052604090205460ff1690565b60025481565b61100581565b600281565b61100881565b600b81565b68056bc75e2d6310000081565b67016345785d8a000081565b600981565b61100781565b61100681565b60005460ff1681565b600081565b60005460ff16610813576040805162461bcd60e51b81526020600482015260196024820152781d1a194818dbdb9d1c9858dd081b9bdd081a5b9a5d081e595d603a1b604482015290519081900360640190fd5b33611007146108535760405162461bcd60e51b815260040180806020018281038252602e815260200180610f7b602e913960400191505060405180910390fd5b6108b984848080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152505060408051808201909152600f81526e1c995c5d5a5c995911195c1bdcda5d608a1b60208201529150610e289050565b156109b057602081146108fd5760405162461bcd60e51b8152600401808060200182810382526022815260200180610fa96022913960400191505060405180910390fd5b604080516020601f840181900481028201810190925282815260009161093b91858580838501838280828437600092019190915250610f0f92505050565b9050600181101580156109575750683635c9adc5dea000008111155b6109a8576040805162461bcd60e51b815260206004820181905260248201527f7468652072657175697265644465706f736974206f7574206f662072616e6765604482015290519081900360640190fd5b600155610b44565b610a0b84848080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250506040805180820190915260048152636475657360e01b60208201529150610e289050565b15610b075760208114610a65576040805162461bcd60e51b815260206004820152601760248201527f6c656e677468206f662064756573206d69736d61746368000000000000000000604482015290519081900360640190fd5b604080516020601f8401819004810282018101909252828152600091610aa391858580838501838280828437600092019190915250610f0f92505050565b9050600081118015610ab6575060015481105b610aff576040805162461bcd60e51b81526020600482015260156024820152747468652064756573206f7574206f662072616e676560581b604482015290519081900360640190fd5b600255610b44565b6040805162461bcd60e51b815260206004820152600d60248201526c756e6b6e6f776e20706172616d60981b604482015290519081900360640190fd5b7f6cdb0ac70ab7f2e2d035cca5be60d89906f2dede7648ddbd7402189c1eeed17a848484846040518080602001806020018381038352878782818152602001925080828437600083820152601f01601f191690910184810383528581526020019050858580828437600083820152604051601f909101601f19169092018290039850909650505050505050a150505050565b61100281565b61100381565b60005460ff1615610c3a576040805162461bcd60e51b815260206004820152601960248201527f74686520636f6e747261637420616c726561647920696e697400000000000000604482015290519081900360640190fd5b68056bc75e2d63100000600190815567016345785d8a00006002556000805460ff19169091179055565b3360009081526004602052604090205460ff16610cbf576040805162461bcd60e51b81526020600482015260146024820152731c995b185e595c88191bc81b9bdd08195e1a5cdd60621b604482015290519081900360640190fd5b60005460ff16610d12576040805162461bcd60e51b81526020600482015260196024820152781d1a194818dbdb9d1c9858dd081b9bdd081a5b9a5d081e595d603a1b604482015290519081900360640190fd5b610d1a610f14565b50336000818152600360209081526040808320815180830183528154808252600190920154938101849052915191949392900380156108fc0292909190818181858888f19350505050158015610d74573d6000803e3d6000fd5b50602081015160405161100291829181156108fc0291906000818181858888f19350505050158015610daa573d6000803e3d6000fd5b50336000818152600460209081526040808320805460ff191690556003825280832083815560010192909255815192835290517fd17202129b83db7880d6b9f25df81c58ad46f7e0e2c92236b1aa10663a4876679281900390910190a15050565b61100081565b60015481565b600381565b61100481565b3b151590565b6000816040516020018082805190602001908083835b60208310610e5d5780518252601f199092019160209182019101610e3e565b6001836020036101000a03801982511681845116808217855250505050505090500191505060405160208183030381529060405280519060200120836040516020018082805190602001908083835b60208310610ecb5780518252601f199092019160209182019101610eac565b6001836020036101000a0380198251168184511680821785525050505050509050019150506040516020818303038152906040528051906020012014905092915050565b015190565b60405180604001604052806000815260200160008152509056fe6465706f7369742076616c7565206973206e6f742065786163746c79207468652073616d65636f6e7472616374206973206e6f7420616c6c6f77656420746f20626520612072656c61796572746865206d6573736167652073656e646572206d75737420626520676f7665726e616e636520636f6e74726163746c656e677468206f662072657175697265644465706f736974206d69736d61746368a2646970667358221220fb9552ef120a66e5db5b423b7f53133dfd781b3274938e279792aad5d583b27564736f6c63430006040033" + }, + "0x0000000000000000000000000000000000001007": { + "balance": "0x0", + "code": "0x608060405234801561001057600080fd5b506004361061018e5760003560e01c8063831d65d1116100de578063ab51bb9611610097578063dc927faf11610071578063dc927faf14610486578063f9a2bbc71461048e578063fc3e590814610496578063fd6a68791461049e5761018e565b8063ab51bb96146103fc578063c81b166214610404578063c8509d811461040c5761018e565b8063831d65d11461034457806396713da9146103c05780639ab1a373146103c85780639dc09262146103d0578063a1a11bf5146103d8578063a78abc16146103e05761018e565b8063493279b11161014b5780636e47b482116101255780636e47b4821461032457806370fd5bad1461032c57806375d47a0a146103345780637942fd051461033c5761018e565b8063493279b1146102f55780634bf6c8821461031457806351e806721461031c5761018e565b80630bee7a67146101935780631182b875146101b45780633a21baae146102a35780633dffc387146102ab57806343756e5c146102c95780634900c4ea146102ed575b600080fd5b61019b6104a6565b6040805163ffffffff9092168252519081900360200190f35b61022e600480360360408110156101ca57600080fd5b60ff82351691908101906040810160208201356401000000008111156101ef57600080fd5b82018360208201111561020157600080fd5b8035906020019184600183028401116401000000008311171561022357600080fd5b5090925090506104ab565b6040805160208082528351818301528351919283929083019185019080838360005b83811015610268578181015183820152602001610250565b50505050905090810190601f1680156102955780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b61019b61059a565b6102b361059f565b6040805160ff9092168252519081900360200190f35b6102d16105a4565b604080516001600160a01b039092168252519081900360200190f35b6102b36105aa565b6102fd6105af565b6040805161ffff9092168252519081900360200190f35b6102b36105b4565b6102d16105b9565b6102d16105bf565b6102b36105c5565b6102d16105ca565b6102b36105d0565b6103be6004803603604081101561035a57600080fd5b60ff823516919081019060408101602082013564010000000081111561037f57600080fd5b82018360208201111561039157600080fd5b803590602001918460018302840111640100000000831117156103b357600080fd5b5090925090506105d5565b005b6102b3610627565b61019b61062c565b6102d1610631565b6102d1610637565b6103e861063d565b604080519115158252519081900360200190f35b61019b6105aa565b6102d1610646565b6103be6004803603604081101561042257600080fd5b60ff823516919081019060408101602082013564010000000081111561044757600080fd5b82018360208201111561045957600080fd5b8035906020019184600183028401116401000000008311171561047b57600080fd5b50909250905061064c565b6102d1610683565b6102d1610689565b6102b361068f565b6102d1610694565b606481565b606033612000146104ed5760405162461bcd60e51b815260040180806020018281038252602f815260200180611276602f913960400191505060405180910390fd5b6104f5611211565b600061053685858080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061069a92505050565b9150915080610552576105496064610760565b92505050610593565b600061055d836107ca565b905063ffffffff811661058457505060408051600081526020810190915291506105939050565b61058d81610760565b93505050505b9392505050565b606681565b600181565b61100181565b600081565b606181565b600881565b61200081565b61100581565b600281565b61100881565b600b81565b6040805162461bcd60e51b815260206004820152601e60248201527f7265636569766520756e65787065637465642061636b207061636b6167650000604482015290519081900360640190fd5b505050565b600981565b606581565b61100781565b61100681565b60005460ff1681565b61100281565b60405162461bcd60e51b81526004018080602001828103825260238152602001806112a56023913960400191505060405180910390fd5b61100381565b61100081565b600381565b61100481565b6106a2611211565b60006106ac611211565b6106b461123b565b6106c56106c086610b6b565b610b90565b90506000805b6106d483610bda565b1561075357806106f6576106ef6106ea84610bfb565b610c49565b845261074b565b80600114156107155761070b6106ea84610bfb565b602085015261074b565b80600214156107465761072f61072a84610bfb565b610cc2565b6001600160a01b031660408501526001915061074b565b610753565b6001016106cb565b5091935090915050915091565b604080516001808252818301909252606091829190816020015b606081526020019060019003908161077a5790505090506107a08363ffffffff16610ce2565b816000815181106107ad57fe5b60200260200101819052506107c181610cf5565b9150505b919050565b60006107d98260400151610d7f565b61084557604080516020808252601c908201527f74686520746172676574206973206e6f74206120636f6e7472616374000000008183015290517f70e72399380dcfb0338abc03dc8d47f9f470ada8e769c9a78d644ea97385ecb29181900360600190a15060656107c5565b81604001516001600160a01b031663ac431751836000015184602001516040518363ffffffff1660e01b8152600401808060200180602001838103835285818151815260200191508051906020019080838360005b838110156108b257818101518382015260200161089a565b50505050905090810190601f1680156108df5780820380516001836020036101000a031916815260200191505b50838103825284518152845160209182019186019080838360005b838110156109125781810151838201526020016108fa565b50505050905090810190601f16801561093f5780820380516001836020036101000a031916815260200191505b50945050505050600060405180830381600087803b15801561096057600080fd5b505af1925050508015610971575060015b610b63576040516000815260443d101561098d57506000610a2a565b60046000803e60005160e01c6308c379a081146109ae576000915050610a2a565b60043d036004833e81513d602482011167ffffffffffffffff821117156109da57600092505050610a2a565b808301805167ffffffffffffffff8111156109fc576000945050505050610a2a565b8060208301013d8601811115610a1a57600095505050505050610a2a565b601f01601f191660405250925050505b80610a355750610ad8565b7f70e72399380dcfb0338abc03dc8d47f9f470ada8e769c9a78d644ea97385ecb2816040518080602001828103825283818151815260200191508051906020019080838360005b83811015610a94578181015183820152602001610a7c565b50505050905090810190601f168015610ac15780820380516001836020036101000a031916815260200191505b509250505060405180910390a160669150506107c5565b3d808015610b02576040519150601f19603f3d011682016040523d82523d6000602084013e610b07565b606091505b5060408051602080825283518183015283517f1279f84165b4fd69c35e1f338ff107231b036c655cd1688851e011ce617c4e8d938593928392918301919085019080838360008315610a94578181015183820152602001610a7c565b506000919050565b610b7361125b565b506040805180820190915281518152602082810190820152919050565b610b9861123b565b610ba182610d85565b610baa57600080fd5b6000610bb98360200151610dbf565b60208085015160408051808201909152868152920190820152915050919050565b6000610be461125b565b505080518051602091820151919092015191011190565b610c0361125b565b610c0c82610bda565b610c1557600080fd5b60208201516000610c2582610e22565b80830160209586015260408051808201909152908152938401919091525090919050565b8051606090610c5757600080fd5b6000610c668360200151610dbf565b83516040805191839003808352601f19601f8201168301602001909152919250606090828015610c9d576020820181803683370190505b5090506000816020019050610cb9848760200151018285610ebb565b50949350505050565b8051600090601514610cd357600080fd5b610cdc82610f06565b92915050565b6060610cdc610cf083610f64565b61104a565b6060815160001415610d1657506040805160008152602081019091526107c5565b606082600081518110610d2557fe5b602002602001015190506000600190505b8351811015610d6657610d5c82858381518110610d4f57fe5b602002602001015161109c565b9150600101610d36565b506107c1610d79825160c060ff16611119565b8261109c565b3b151590565b8051600090610d96575060006107c5565b6020820151805160001a9060c0821015610db5576000925050506107c5565b5060019392505050565b8051600090811a6080811015610dd95760009150506107c5565b60b8811080610df4575060c08110801590610df4575060f881105b15610e035760019150506107c5565b60c0811015610e175760b5190190506107c5565b60f5190190506107c5565b80516000908190811a6080811015610e3d5760019150610eb4565b60b8811015610e5257607e1981019150610eb4565b60c0811015610e7f5760b78103600185019450806020036101000a85510460018201810193505050610eb4565b60f8811015610e945760be1981019150610eb4565b60f78103600185019450806020036101000a855104600182018101935050505b5092915050565b80610ec557610622565b5b60208110610ee5578251825260209283019290910190601f1901610ec6565b915181516020939093036101000a6000190180199091169216919091179052565b805160009015801590610f1b57508151602110155b610f2457600080fd5b6000610f338360200151610dbf565b83516020808601518301805193945091849003929190831015610cb957506020919091036101000a90049392505050565b604080516020808252818301909252606091829190602082018180368337505050602081018490529050600067ffffffffffffffff198416610fa857506018610fcc565b6fffffffffffffffffffffffffffffffff198416610fc857506010610fcc565b5060005b602081101561100257818181518110610fe157fe5b01602001516001600160f81b03191615610ffa57611002565b600101610fcc565b60008160200390506060816040519080825280601f01601f191660200182016040528015611037576020820181803683370190505b5080830196909652508452509192915050565b60608151600114801561107c5750607f60f81b8260008151811061106a57fe5b01602001516001600160f81b03191611155b156110885750806107c5565b610cdc61109a8351608060ff16611119565b835b6060806040519050835180825260208201818101602087015b818310156110cd5780518352602092830192016110b5565b50855184518101855292509050808201602086015b818310156110fa5780518352602092830192016110e2565b508651929092011591909101601f01601f191660405250905092915050565b6060680100000000000000008310611169576040805162461bcd60e51b815260206004820152600e60248201526d696e70757420746f6f206c6f6e6760901b604482015290519081900360640190fd5b604080516001808252818301909252606091602082018180368337019050509050603784116111c35782840160f81b816000815181106111a557fe5b60200101906001600160f81b031916908160001a9053509050610cdc565b60606111ce85610f64565b90508381510160370160f81b826000815181106111e757fe5b60200101906001600160f81b031916908160001a905350611208828261109c565b95945050505050565b6040518060600160405280606081526020016060815260200160006001600160a01b031681525090565b604051806040016040528061124e61125b565b8152602001600081525090565b60405180604001604052806000815260200160008152509056fe746865206d6573736167652073656e646572206d7573742062652063726f737320636861696e20636f6e74726163747265636569766520756e6578706563746564206661696c2061636b207061636b616765a264697066735822122019628d70dd9ac62a7a85eb3f845d01808a095ab280a95e6dd5609e52788b4c5e64736f6c63430006040033" + }, + "0x0000000000000000000000000000000000001008": { + "balance": "0x0", + "code": "0x6080604052600436106102305760003560e01c806377d9dae81161012e578063c81b1662116100ab578063dc927faf1161006f578063dc927faf14610887578063f9a2bbc71461089c578063fc3e5908146107f1578063fd6a6879146108b1578063fe3a2af51461042457610230565b8063c81b1662146107dc578063c8509d81146106d7578063c8e704a4146107f1578063d117a11014610806578063dc6f5e90146107f157610230565b806396713da9116100f257806396713da9146107735780639dc0926214610788578063a1a11bf51461079d578063a78abc16146107b2578063ab51bb96146107c757610230565b806377d9dae81461060e5780637942fd05146106c25780637d078e13146103b2578063831d65d1146106d757806395b9ad261461075e57610230565b80634a688818116101bc5780636b3f1307116101805780636b3f1307146104785780636e47b4821461054057806370fd5bad1461046357806372c4e0861461055557806375d47a0a146105f957610230565b80634a688818146104245780634bc81c00146104395780634bf6c8821461023557806351e806721461044e5780635f558f861461046357610230565b80631f91600b116102035780631f91600b1461039d57806323996b53146103b25780633dffc387146103b257806343756e5c146103c7578063493279b1146103f857610230565b8063077b8f35146102355780630bee7a67146102605780630f212b1b1461028e5780631182b875146102a3575b600080fd5b34801561024157600080fd5b5061024a6108c6565b6040805160ff9092168252519081900360200190f35b34801561026c57600080fd5b506102756108cb565b6040805163ffffffff9092168252519081900360200190f35b34801561029a57600080fd5b5061024a6108d0565b3480156102af57600080fd5b50610328600480360360408110156102c657600080fd5b60ff8235169190810190604081016020820135600160201b8111156102ea57600080fd5b8201836020820111156102fc57600080fd5b803590602001918460018302840111600160201b8311171561031d57600080fd5b5090925090506108d5565b6040805160208082528351818301528351919283929083019185019080838360005b8381101561036257818101518382015260200161034a565b50505050905090810190601f16801561038f5780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b3480156103a957600080fd5b5061024a61095e565b3480156103be57600080fd5b5061024a610963565b3480156103d357600080fd5b506103dc610968565b604080516001600160a01b039092168252519081900360200190f35b34801561040457600080fd5b5061040d61096e565b6040805161ffff9092168252519081900360200190f35b34801561043057600080fd5b5061024a610973565b34801561044557600080fd5b5061024a610978565b34801561045a57600080fd5b506103dc61097d565b34801561046f57600080fd5b5061024a610983565b61052c6004803603604081101561048e57600080fd5b6001600160a01b038235169190810190604081016020820135600160201b8111156104b857600080fd5b8201836020820111156104ca57600080fd5b803590602001918460018302840111600160201b831117156104eb57600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250929550610988945050505050565b604080519115158252519081900360200190f35b34801561054c57600080fd5b506103dc61121e565b61052c6004803603602081101561056b57600080fd5b810190602081018135600160201b81111561058557600080fd5b82018360208201111561059757600080fd5b803590602001918460018302840111600160201b831117156105b857600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250929550611224945050505050565b34801561060557600080fd5b506103dc611683565b61052c6004803603604081101561062457600080fd5b6001600160a01b038235169190810190604081016020820135600160201b81111561064e57600080fd5b82018360208201111561066057600080fd5b803590602001918460018302840111600160201b8311171561068157600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250929550611689945050505050565b3480156106ce57600080fd5b5061024a611ba0565b3480156106e357600080fd5b5061075c600480360360408110156106fa57600080fd5b60ff8235169190810190604081016020820135600160201b81111561071e57600080fd5b82018360208201111561073057600080fd5b803590602001918460018302840111600160201b8311171561075157600080fd5b509092509050611ba5565b005b34801561076a57600080fd5b5061024a611c58565b34801561077f57600080fd5b5061024a611c5d565b34801561079457600080fd5b506103dc611c62565b3480156107a957600080fd5b506103dc611c68565b3480156107be57600080fd5b5061052c611c6e565b3480156107d357600080fd5b50610275610973565b3480156107e857600080fd5b506103dc611c77565b3480156107fd57600080fd5b5061024a611c7d565b34801561081257600080fd5b506108306004803603602081101561082957600080fd5b5035611c82565b6040805160ff988916815260208101979097526001600160a01b03909516868601526060860193909352608085019190915290931660a083015267ffffffffffffffff90921660c082015290519081900360e00190f35b34801561089357600080fd5b506103dc611cda565b3480156108a857600080fd5b506103dc611ce0565b3480156108bd57600080fd5b506103dc611ce6565b600881565b606481565b600681565b606033612000146109175760405162461bcd60e51b815260040180806020018281038252602f815260200180612f8e602f913960400191505060405180910390fd5b61095683838080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250611cec92505050565b949350505050565b600481565b600181565b61100181565b606181565b600081565b600581565b61200081565b600281565b60008061099483611f7d565b905061099e612e56565b50600081815260016020818152604092839020835160e081018552815460ff90811682529382015492810183905260028201546001600160a01b03169481019490945260038101546060850152600481015460808501526005015491821660a084015261010090910467ffffffffffffffff1660c0830152610a64576040805162461bcd60e51b815260206004820152601a602482015279189a5b99081c995c5d595cdd08191bd95cdb89dd08195e1a5cdd60321b604482015290519081900360640190fd5b6000610a8182608001518360600151611f8490919063ffffffff16565b905081604001516001600160a01b0316866001600160a01b031614610ad75760405162461bcd60e51b8152600401808060200182810382526045815260200180612f1b6045913960600191505060405180910390fd5b336001600160a01b0316866001600160a01b031663893d20e86040518163ffffffff1660e01b815260040160206040518083038186803b158015610b1a57600080fd5b505afa158015610b2e573d6000803e3d6000fd5b505050506040513d6020811015610b4457600080fd5b50516001600160a01b031614610b8b5760405162461bcd60e51b815260040180806020018281038252602e815260200180612f60602e913960400191505060405180910390fd5b604080516370a0823160e01b8152611004600482015290516000916001600160a01b038916916370a0823191602480820192602092909190829003018186803b158015610bd757600080fd5b505afa158015610beb573d6000803e3d6000fd5b505050506040513d6020811015610c0157600080fd5b505160408051636eb1769f60e11b815233600482015230602482015290519192508391610c929184916001600160a01b038c169163dd62ed3e916044808301926020929190829003018186803b158015610c5a57600080fd5b505afa158015610c6e573d6000803e3d6000fd5b505050506040513d6020811015610c8457600080fd5b50519063ffffffff611fcd16565b1015610ce5576040805162461bcd60e51b815260206004820152601760248201527f616c6c6f77616e6365206973206e6f7420656e6f756768000000000000000000604482015290519081900360640190fd5b600034905060006110046001600160a01b031663149d14d96040518163ffffffff1660e01b815260040160206040518083038186803b158015610d2757600080fd5b505afa158015610d3b573d6000803e3d6000fd5b505050506040513d6020811015610d5157600080fd5b50519050808210801590610d6a57506402540be4008206155b610da55760405162461bcd60e51b8152600401808060200182810382526037815260200180612ee46037913960400191505060405180910390fd5b6000610db1868b612027565b905063ffffffff8116610fb0576001600160a01b038a166323b872dd33611004610de1898963ffffffff611f8416565b6040518463ffffffff1660e01b815260040180846001600160a01b03166001600160a01b03168152602001836001600160a01b03166001600160a01b031681526020018281526020019350505050602060405180830381600087803b158015610e4957600080fd5b505af1158015610e5d573d6000803e3d6000fd5b505050506040513d6020811015610e7357600080fd5b5050602086015160408088015160a089015182516323bfccdb60e21b815260048101949094526001600160a01b03909116602484015260ff1660448301525161100491638eff336c91606480830192600092919082900301818387803b158015610edc57600080fd5b505af1158015610ef0573d6000803e3d6000fd5b50505050896001600160a01b03167f78e7dd9aefcdbf795c4936a66f7dc6d41bb56637b54f561a6bf7829dca3348a88a8860600151886040518080602001848152602001838152602001828103825285818151815260200191508051906020019080838360005b83811015610f6f578181015183820152602001610f57565b50505050905090810190601f168015610f9c5780820380516001836020036101000a031916815260200191505b5094505050505060405180910390a2611068565b896001600160a01b03167f831c0ef4d93bda3bce08b69ae3f29ef1a6e052b833200988554158494405a1078a8360405180806020018363ffffffff1663ffffffff168152602001828103825284818151815260200191508051906020019080838360005b8381101561102c578181015183820152602001611014565b50505050905090810190601f1680156110595780820380516001836020036101000a031916815260200191505b50935050505060405180910390a25b60008781526001602081905260408220805460ff191681559081018290556002810180546001600160a01b0319169055600381018290556004810191909155600501805468ffffffffffffffffff191690556110c2612e92565b5060408051808201825263ffffffff831681526020810189905290516110049085156108fc029086906000818181858888f1935050505015801561110a573d6000803e3d6000fd5b5061200063f7a251d7600161111e8461247e565b611133886402540be40063ffffffff61250816565b6040518463ffffffff1660e01b8152600401808460ff1660ff16815260200180602001838152602001828103825284818151815260200191508051906020019080838360005b83811015611191578181015183820152602001611179565b50505050905090810190601f1680156111be5780820380516001836020036101000a031916815260200191505b50945050505050602060405180830381600087803b1580156111df57600080fd5b505af11580156111f3573d6000803e3d6000fd5b505050506040513d602081101561120957600080fd5b50600199505050505050505050505b92915050565b61100581565b60008061123083611f7d565b905061123a612e56565b50600081815260016020818152604092839020835160e081018552815460ff90811682529382015492810183905260028201546001600160a01b03169481019490945260038101546060850152600481015460808501526005015491821660a084015261010090910467ffffffffffffffff1660c0830152611300576040805162461bcd60e51b815260206004820152601a602482015279189a5b99081c995c5d595cdd08191bd95cdb89dd08195e1a5cdd60321b604482015290519081900360640190fd5b428160c0015167ffffffffffffffff1610611362576040805162461bcd60e51b815260206004820152601b60248201527f62696e642072657175657374206973206e6f7420657870697265640000000000604482015290519081900360640190fd5b600034905060006110046001600160a01b031663149d14d96040518163ffffffff1660e01b815260040160206040518083038186803b1580156113a457600080fd5b505afa1580156113b8573d6000803e3d6000fd5b505050506040513d60208110156113ce57600080fd5b505190508082108015906113e757506402540be4008206155b6114225760405162461bcd60e51b8152600401808060200182810382526037815260200180612ee46037913960400191505060405180910390fd5b60008481526001602081905260408220805460ff191681559081018290556002810180546001600160a01b0319169055600381018290556004810191909155600501805468ffffffffffffffffff1916905561147c612e92565b50604080518082018252600181526020810186905290516110049084156108fc029085906000818181858888f193505050501580156114bf573d6000803e3d6000fd5b5061200063f7a251d760016114d38461247e565b6114e8876402540be40063ffffffff61250816565b6040518463ffffffff1660e01b8152600401808460ff1660ff16815260200180602001838152602001828103825284818151815260200191508051906020019080838360005b8381101561154657818101518382015260200161152e565b50505050905090810190601f1680156115735780820380516001836020036101000a031916815260200191505b50945050505050602060405180830381600087803b15801561159457600080fd5b505af11580156115a8573d6000803e3d6000fd5b505050506040513d60208110156115be57600080fd5b50506040808501518151600160208281018290528483528b51948301949094528a516001600160a01b03909316937f831c0ef4d93bda3bce08b69ae3f29ef1a6e052b833200988554158494405a107938c93918291606083019186019080838360005b83811015611639578181015183820152602001611621565b50505050905090810190601f1680156116665780820380516001836020036101000a031916815260200191505b50935050505060405180910390a26001955050505050505b919050565b61100881565b60008061169583611f7d565b905061169f612e56565b50600081815260016020818152604092839020835160e081018552815460ff90811682529382015492810183905260028201546001600160a01b03169481019490945260038101546060850152600481015460808501526005015491821660a084015261010090910467ffffffffffffffff1660c0830152611765576040805162461bcd60e51b815260206004820152601a602482015279189a5b99081c995c5d595cdd08191bd95cdb89dd08195e1a5cdd60321b604482015290519081900360640190fd5b80604001516001600160a01b0316856001600160a01b0316146117b95760405162461bcd60e51b8152600401808060200182810382526045815260200180612f1b6045913960600191505060405180910390fd5b336001600160a01b0316856001600160a01b031663893d20e86040518163ffffffff1660e01b815260040160206040518083038186803b1580156117fc57600080fd5b505afa158015611810573d6000803e3d6000fd5b505050506040513d602081101561182657600080fd5b50516001600160a01b031614611883576040805162461bcd60e51b815260206004820152601b60248201527f6f6e6c79206265703265206f776e65722063616e2072656a6563740000000000604482015290519081900360640190fd5b600034905060006110046001600160a01b031663149d14d96040518163ffffffff1660e01b815260040160206040518083038186803b1580156118c557600080fd5b505afa1580156118d9573d6000803e3d6000fd5b505050506040513d60208110156118ef57600080fd5b5051905080821080159061190857506402540be4008206155b6119435760405162461bcd60e51b8152600401808060200182810382526037815260200180612ee46037913960400191505060405180910390fd5b60008481526001602081905260408220805460ff191681559081018290556002810180546001600160a01b0319169055600381018290556004810191909155600501805468ffffffffffffffffff1916905561199d612e92565b50604080518082018252600781526020810186905290516110049084156108fc029085906000818181858888f193505050501580156119e0573d6000803e3d6000fd5b5061200063f7a251d760016119f48461247e565b611a09876402540be40063ffffffff61250816565b6040518463ffffffff1660e01b8152600401808460ff1660ff16815260200180602001838152602001828103825284818151815260200191508051906020019080838360005b83811015611a67578181015183820152602001611a4f565b50505050905090810190601f168015611a945780820380516001836020036101000a031916815260200191505b50945050505050602060405180830381600087803b158015611ab557600080fd5b505af1158015611ac9573d6000803e3d6000fd5b505050506040513d6020811015611adf57600080fd5b505060408051600760208281018290528383528a519383019390935289516001600160a01b038c16937f831c0ef4d93bda3bce08b69ae3f29ef1a6e052b833200988554158494405a107938c939290918291606083019186019080838360005b83811015611b57578181015183820152602001611b3f565b50505050905090810190601f168015611b845780820380516001836020036101000a031916815260200191505b50935050505060405180910390a2506001979650505050505050565b600b81565b3361200014611be55760405162461bcd60e51b815260040180806020018281038252602f815260200180612f8e602f913960400191505060405180910390fd5b7f41ce201247b6ceb957dcdb217d0b8acb50b9ea0e12af9af4f5e7f38902101605838383604051808460ff1660ff168152602001806020018281038252848482818152602001925080828437600083820152604051601f909101601f1916909201829003965090945050505050a1505050565b600781565b600981565b61100781565b61100681565b60005460ff1681565b61100281565b600381565b600160208190526000918252604090912080549181015460028201546003830154600484015460059094015460ff9586169593946001600160a01b0390931693919291811690610100900467ffffffffffffffff1687565b61100381565b61100081565b61100481565b6060611cf6612e56565b6000611d018461254a565b9150915080611d57576040805162461bcd60e51b815260206004820152601f60248201527f756e7265636f676e697a6564207472616e73666572496e207061636b61676500604482015290519081900360640190fd5b815160ff16611e0b576020828101805160009081526001928390526040908190208551815460ff1990811660ff928316178355935194820194909455908501516002820180546001600160a01b0319166001600160a01b03909216919091179055606085015160038201556080850151600482015560a08501516005909101805460c08701519316919093161768ffffffffffffffff00191661010067ffffffffffffffff90921691909102179055611f62565b815160ff1660011415611f155760006110046001600160a01b03166359b9278984602001516040518263ffffffff1660e01b81526004018082815260200191505060206040518083038186803b158015611e6457600080fd5b505afa158015611e78573d6000803e3d6000fd5b505050506040513d6020811015611e8e57600080fd5b505190506001600160a01b03811615611f0f5760208301516040805163b99328c560e01b815260048101929092526001600160a01b0383166024830152516110049163b99328c591604480830192600092919082900301818387803b158015611ef657600080fd5b505af1158015611f0a573d6000803e3d6000fd5b505050505b50611f62565b6040805162461bcd60e51b815260206004820152601960248201527f756e7265636f676e697a65642062696e64207061636b61676500000000000000604482015290519081900360640190fd5b60408051600080825260208201909252905b50949350505050565b6020015190565b6000611fc683836040518060400160405280601e81526020017f536166654d6174683a207375627472616374696f6e206f766572666c6f77000081525061269c565b9392505050565b600082820183811015611fc6576040805162461bcd60e51b815260206004820152601b60248201527f536166654d6174683a206164646974696f6e206f766572666c6f770000000000604482015290519081900360640190fd5b600080826001600160a01b031663313ce5676040518163ffffffff1660e01b815260040160206040518083038186803b15801561206357600080fd5b505afa158015612077573d6000803e3d6000fd5b505050506040513d602081101561208d57600080fd5b5051604080516395d89b4160e01b815290519192506060916001600160a01b038616916395d89b41916004808301926000929190829003018186803b1580156120d557600080fd5b505afa1580156120e9573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052602081101561211257600080fd5b8101908080516040519392919084600160201b82111561213157600080fd5b90830190602082018581111561214657600080fd5b8251600160201b81118282018810171561215f57600080fd5b82525081516020918201929091019080838360005b8381101561218c578181015183820152602001612174565b50505050905090810190601f1680156121b95780820380516001836020036101000a031916815260200191505b5060408181526370a0823160e01b82526110046004830152519495506000946001600160a01b038a1694506370a08231935060248083019350602092829003018186803b15801561220957600080fd5b505afa15801561221d573d6000803e3d6000fd5b505050506040513d602081101561223357600080fd5b5051608087015160608801519192506000916122549163ffffffff611f8416565b9050428760c0015167ffffffffffffffff16101561227a57506001935061121892505050565b612288838860200151612733565b61229a57506002935061121892505050565b808211156122b057506003935061121892505050565b866060015187604001516001600160a01b03166318160ddd6040518163ffffffff1660e01b815260040160206040518083038186803b1580156122f257600080fd5b505afa158015612306573d6000803e3d6000fd5b505050506040513d602081101561231c57600080fd5b50511461233157506004935061121892505050565b8660a0015160ff16841461234d57506005935061121892505050565b602080880151604080516359b9278960e01b8152600481019290925251600092611004926359b927899260248083019392829003018186803b15801561239257600080fd5b505afa1580156123a6573d6000803e3d6000fd5b505050506040513d60208110156123bc57600080fd5b50516001600160a01b031614158061245e57506000801b6110046001600160a01b031663bd46646189604001516040518263ffffffff1660e01b815260040180826001600160a01b03166001600160a01b0316815260200191505060206040518083038186803b15801561242f57600080fd5b505afa158015612443573d6000803e3d6000fd5b505050506040513d602081101561245957600080fd5b505114155b1561247157506006935061121892505050565b5060009695505050505050565b6040805160028082526060828101909352829190816020015b606081526020019060019003908161249757505083519091506124bf9063ffffffff1661281b565b816000815181106124cc57fe5b60200260200101819052506124e7836020015160001c61281b565b816001815181106124f457fe5b6020026020010181905250611fc68161282e565b6000611fc683836040518060400160405280601a81526020017f536166654d6174683a206469766973696f6e206279207a65726f0000000000008152506128b8565b612552612e56565b600061255c612e56565b612564612ea9565b6125756125708661291d565b612942565b90506000805b6125848361298c565b1561268f57806125a95761259f61259a846129ad565b6129fb565b60ff168452612687565b80600114156125c8576125be61259a846129ad565b6020850152612687565b80600214156125f5576125e26125dd846129ad565b612a59565b6001600160a01b03166040850152612687565b80600314156126145761260a61259a846129ad565b6060850152612687565b80600414156126335761262961259a846129ad565b6080850152612687565b80600514156126555761264861259a846129ad565b60ff1660a0850152612687565b80600614156126825761266a61259a846129ad565b67ffffffffffffffff1660c085015260019150612687565b61268f565b60010161257b565b5091935090915050915091565b6000818484111561272b5760405162461bcd60e51b81526004018080602001828103825283818151815260200191508051906020019080838360005b838110156126f05781810151838201526020016126d8565b50505050905090810190601f16801561271d5780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b505050900390565b8151600090839060081080612749575080516003115b15612758576000915050611218565b6040805160208082528183019092526060916020820181803683370190505090508360208201528082518151811061278c57fe5b6020910101516001600160f81b031916602d60f81b146127b157600092505050611218565b600160005b8351811015612811578281815181106127cb57fe5b602001015160f81c60f81b6001600160f81b0319168482815181106127ec57fe5b01602001516001600160f81b031916146128095760009150612811565b6001016127b6565b5095945050505050565b606061121861282983612a73565b612b59565b606081516000141561284f575060408051600081526020810190915261167e565b60608260008151811061285e57fe5b602002602001015190506000600190505b835181101561289f576128958285838151811061288857fe5b6020026020010151612bab565b915060010161286f565b50611fc66128b2825160c060ff16612c28565b82612bab565b600081836129075760405162461bcd60e51b81526020600482018181528351602484015283519092839260449091019190850190808383600083156126f05781810151838201526020016126d8565b50600083858161291357fe5b0495945050505050565b612925612ec9565b506040805180820190915281518152602082810190820152919050565b61294a612ea9565b61295382612d20565b61295c57600080fd5b600061296b8360200151612d5a565b60208085015160408051808201909152868152920190820152915050919050565b6000612996612ec9565b505080518051602091820151919092015191011190565b6129b5612ec9565b6129be8261298c565b6129c757600080fd5b602082015160006129d782612dbd565b80830160209586015260408051808201909152908152938401919091525090919050565b805160009015801590612a1057508151602110155b612a1957600080fd5b6000612a288360200151612d5a565b83516020808601518301805193945091849003929190831015611f7457506020919091036101000a90049392505050565b8051600090601514612a6a57600080fd5b611218826129fb565b604080516020808252818301909252606091829190602082018180368337505050602081018490529050600067ffffffffffffffff198416612ab757506018612adb565b6fffffffffffffffffffffffffffffffff198416612ad757506010612adb565b5060005b6020811015612b1157818181518110612af057fe5b01602001516001600160f81b03191615612b0957612b11565b600101612adb565b60008160200390506060816040519080825280601f01601f191660200182016040528015612b46576020820181803683370190505b5080830196909652508452509192915050565b606081516001148015612b8b5750607f60f81b82600081518110612b7957fe5b01602001516001600160f81b03191611155b15612b9757508061167e565b611218612ba98351608060ff16612c28565b835b6060806040519050835180825260208201818101602087015b81831015612bdc578051835260209283019201612bc4565b50855184518101855292509050808201602086015b81831015612c09578051835260209283019201612bf1565b508651929092011591909101601f01601f191660405250905092915050565b6060680100000000000000008310612c78576040805162461bcd60e51b815260206004820152600e60248201526d696e70757420746f6f206c6f6e6760901b604482015290519081900360640190fd5b60408051600180825281830190925260609160208201818036833701905050905060378411612cd25782840160f81b81600081518110612cb457fe5b60200101906001600160f81b031916908160001a9053509050611218565b6060612cdd85612a73565b90508381510160370160f81b82600081518110612cf657fe5b60200101906001600160f81b031916908160001a905350612d178282612bab565b95945050505050565b8051600090612d315750600061167e565b6020820151805160001a9060c0821015612d505760009250505061167e565b5060019392505050565b8051600090811a6080811015612d7457600091505061167e565b60b8811080612d8f575060c08110801590612d8f575060f881105b15612d9e57600191505061167e565b60c0811015612db25760b51901905061167e565b60f51901905061167e565b80516000908190811a6080811015612dd85760019150612e4f565b60b8811015612ded57607e1981019150612e4f565b60c0811015612e1a5760b78103600185019450806020036101000a85510460018201810193505050612e4f565b60f8811015612e2f5760be1981019150612e4f565b60f78103600185019450806020036101000a855104600182018101935050505b5092915050565b6040805160e081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c081019190915290565b604080518082019091526000808252602082015290565b6040518060400160405280612ebc612ec9565b8152602001600081525090565b60405180604001604052806000815260200160008152509056fe72656c6179466565206d757374206265204e202a203165313020616e642067726561746572207468616e206d696e6952656c6179466565636f6e74616374206164647265737320646f65736e277420657175616c20746f2074686520636f6e7472616374206164647265737320696e2062696e6420726571756573746f6e6c79206265703265206f776e65722063616e20617070726f766520746869732062696e642072657175657374746865206d6573736167652073656e646572206d7573742062652063726f737320636861696e20636f6e7472616374a26469706673582212208d24722e295c34fcc944dfda2183ee07fab7234ce8b7001a715c221bd92ef86e64736f6c63430006040033" + }, + "0x0000000000000000000000000000000000002000": { + "balance": "0x0", + "code": "0x608060405234801561001057600080fd5b50600436106102485760003560e01c8063863fe4ab1161013b578063c81b1662116100b8578063e3b048051161007c578063e3b048051461072c578063f7a251d71461074c578063f9a2bbc7146107c4578063fc3e5908146107cc578063fd6a6879146107d457610248565b8063c81b1662146106dd578063d31f968d146106e5578063d76a867514610714578063dc927faf1461071c578063e1c7392a1461072457610248565b8063a78abc16116100ff578063a78abc16146105d3578063ab51bb96146105db578063ac431751146105e3578063b0355f5b146103ff578063c27cdcfb146106a157610248565b8063863fe4ab146105b35780638cc8f561146104b657806396713da9146105bb5780639dc09262146105c3578063a1a11bf5146105cb57610248565b8063493279b1116101c957806370fd5bad1161018d57806370fd5bad146104b657806374f079b8146104be57806375d47a0a146104c65780637942fd05146104ce57806384013b6a146104d657610248565b8063493279b11461045f5780634bf6c8821461047e57806351e80672146104865780636e47a51a1461048e5780636e47b482146104ae57610248565b8063308325f411610210578063308325f4146102cf5780633bdc47a6146102d75780633dffc387146103ff578063422f90501461040757806343756e5c1461043b57610248565b806305e682581461024d5780630bee7a671461026b57806314b3023b1461028c57806322556cdc146102a65780632ff32aea146102ae575b600080fd5b6102556107dc565b6040805160ff9092168252519081900360200190f35b6102736107e1565b6040805163ffffffff9092168252519081900360200190f35b6102946107e6565b60408051918252519081900360200190f35b6102946107ec565b6102b66107f1565b60408051600792830b90920b8252519081900360200190f35b6102946107fa565b61038a600480360360608110156102ed57600080fd5b60ff82351691602081013591810190606081016040820135600160201b81111561031657600080fd5b82018360208201111561032857600080fd5b803590602001918460018302840111600160201b8311171561034957600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250929550610800945050505050565b6040805160208082528351818301528351919283929083019185019080838360005b838110156103c45781810151838201526020016103ac565b50505050905090810190601f1680156103f15780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b610255610876565b6104276004803603602081101561041d57600080fd5b503560ff1661087b565b604080519115158252519081900360200190f35b610443610890565b604080516001600160a01b039092168252519081900360200190f35b610467610896565b6040805161ffff9092168252519081900360200190f35b61025561089b565b6104436108a0565b610443600480360360208110156104a457600080fd5b503560ff166108a6565b6104436108c1565b6102556108c7565b6102946108cc565b6104436108d2565b6102556108d8565b6105b1600480360360a08110156104ec57600080fd5b810190602081018135600160201b81111561050657600080fd5b82018360208201111561051857600080fd5b803590602001918460018302840111600160201b8311171561053957600080fd5b919390929091602081019035600160201b81111561055657600080fd5b82018360208201111561056857600080fd5b803590602001918460018302840111600160201b8311171561058957600080fd5b919350915080356001600160401b03908116916020810135909116906040013560ff166108dd565b005b610294611a8d565b610255611a95565b610443611a9a565b610443611aa0565b610427611aa6565b6102736107dc565b6105b1600480360360408110156105f957600080fd5b810190602081018135600160201b81111561061357600080fd5b82018360208201111561062557600080fd5b803590602001918460018302840111600160201b8311171561064657600080fd5b919390929091602081019035600160201b81111561066357600080fd5b82018360208201111561067557600080fd5b803590602001918460018302840111600160201b8311171561069657600080fd5b509092509050611aaf565b6106c1600480360360208110156106b757600080fd5b503560ff16612046565b604080516001600160401b039092168252519081900360200190f35b610443612061565b610427600480360360408110156106fb57600080fd5b5080356001600160a01b0316906020013560ff16612067565b61038a612087565b6104436120a6565b6105b16120ac565b6106c16004803603602081101561074257600080fd5b503560ff16612463565b6104276004803603606081101561076257600080fd5b60ff8235169190810190604081016020820135600160201b81111561078657600080fd5b82018360208201111561079857600080fd5b803590602001918460018302840111600160201b831117156107b957600080fd5b91935091503561247e565b6104436125d0565b6102556125d6565b6104436125db565b600081565b606481565b60015481565b603281565b60045460070b81565b60025481565b60606000825160210190506060816040519080825280601f01601f191660200182016040528015610838576020820181803683370190505b506021810186905260018101879052828152905060418101600061085b866125e1565b50905061086a818388516125eb565b50909695505050505050565b600181565b60096020526000908152604090205460ff1681565b61100181565b606181565b600881565b61200081565b6005602052600090815260409020546001600160a01b031681565b61100581565b600281565b60035481565b61100881565b600b81565b60005460ff16610930576040805162461bcd60e51b81526020600482015260196024820152781d1a194818dbdb9d1c9858dd081b9bdd081a5b9a5d081e595d603a1b604482015290519081900360640190fd5b60408051630a83aaa960e31b815233600482015290516110069163541d5548916024808301926020929190829003018186803b15801561096f57600080fd5b505afa158015610983573d6000803e3d6000fd5b505050506040513d602081101561099957600080fd5b50516109ec576040805162461bcd60e51b815260206004820152601f60248201527f746865206d73672073656e646572206973206e6f7420612072656c6179657200604482015290519081900360640190fd5b60ff8116600090815260086020526040902054829082906001600160401b039081169083168114610a5c576040805162461bcd60e51b815260206004820152601560248201527439b2b8bab2b731b2903737ba1034b71037b93232b960591b604482015290519081900360640190fd5b60ff8216600090815260086020908152604091829020805467ffffffffffffffff1916600185016001600160401b039081169190911790915582516337d7f9c160e21b81529089166004820152915188926110039263df5fe70492602480840193829003018186803b158015610ad157600080fd5b505afa158015610ae5573d6000803e3d6000fd5b505050506040513d6020811015610afb57600080fd5b5051610b385760405162461bcd60e51b8152600401808060200182810382526023815260200180612b686023913960400191505060405180910390fd5b60ff851660009081526005602052604090205485906001600160a01b0316610ba7576040805162461bcd60e51b815260206004820152601860248201527f6368616e6e656c206973206e6f7420737570706f727465640000000000000000604482015290519081900360640190fd5b60608c8c8080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f82011690508083019250505050505050905060608b8b8080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250506040805163cba510a960e01b81526001600160401b038f1660048201529051939450610cce93611003935063cba510a992506024808301926020929190829003018186803b158015610c7757600080fd5b505afa158015610c8b573d6000803e3d6000fd5b505050506040513d6020811015610ca157600080fd5b505160408051808201909152600381526269626360e81b6020820152610cc78c8c61262c565b8585612673565b610d16576040805162461bcd60e51b815260206004820152601460248201527334b73b30b634b21036b2b935b63290383937b7b360611b604482015290519081900360640190fd5b60408051631bb5062960e31b81526001600160401b038c16600482015290516000916110039163dda8314891602480820192602092909190829003018186803b158015610d6257600080fd5b505afa158015610d76573d6000803e3d6000fd5b505050506040513d6020811015610d8c57600080fd5b5051905088600080806060610da088612770565b935093509350935083610e61578460ff168f6001600160401b03167ff7b2e42d694eb1100184aae86d4245d9e46966100b1dc7e723275b98326854ac8a6040518080602001828103825283818151815260200191508051906020019080838360005b83811015610e1a578181015183820152602001610e02565b50505050905090810190601f168015610e475780820380516001836020036101000a031916815260200191505b509250505060405180910390a35050505050505050611a7f565b8460ff168f6001600160401b03167f36afdaf439a8f43fe72135135d804ae620b37a474f0943b5b85f6788312cad4085604051808260ff1660ff16815260200191505060405180910390a360ff83166113ea5760ff85166000818152600560209081526040808320548151631182b87560e01b815260048101958652602481019283528651604482015286516001600160a01b03909216958695631182b875958d958a9593949093606490910192918601918190849084905b83811015610f32578181015183820152602001610f1a565b50505050905090810190601f168015610f5f5780820380516001836020036101000a031916815260200191505b509350505050600060405180830381600087803b158015610f7f57600080fd5b505af192505050801561106357506040513d6000823e601f3d908101601f191682016040526020811015610fb257600080fd5b8101908080516040519392919084600160201b821115610fd157600080fd5b908301906020820185811115610fe657600080fd5b8251600160201b811182820188101715610fff57600080fd5b82525081516020918201929091019080838360005b8381101561102c578181015183820152602001611014565b50505050905090810190601f1680156110595780820380516001836020036101000a031916815260200191505b5060405250505060015b611375576040516000815260443d101561107f5750600061111a565b60046000803e60005160e01c6308c379a081146110a057600091505061111a565b60043d036004833e81513d60248201116001600160401b03821117156110cb5760009250505061111a565b80830180516001600160401b038111156110ec57600094505050505061111a565b8060208301013d860181111561110a5760009550505050505061111a565b601f01601f191660405250925050505b806111255750611237565b60ff871660009081526007602052604081205461115c916001600160401b039091169089906111579060029088610800565b612820565b60ff8716600090815260076020908152604080832080546001600160401b038082166001011667ffffffffffffffff19909116179055805182815284518184015284516001600160a01b038716947ff91a8f63e5b3e0e89e5f93e1915a7805f3c52d9a73b3c09769785c2c7bf87acf948794849390840192918601918190849084905b838110156111f75781810151838201526020016111df565b50505050905090810190601f1680156112245780820380516001836020036101000a031916815260200191505b509250505060405180910390a250611370565b3d808015611261576040519150601f19603f3d011682016040523d82523d6000602084013e611266565b606091505b5060ff8716600090815260076020526040812054611299916001600160401b039091169089906111579060029088610800565b60ff8716600090815260076020908152604080832080546001600160401b038082166001011667ffffffffffffffff19909116179055805182815284518184015284516001600160a01b038716947f63ac299d6332d1cc4e61b81e59bc00c0ac7c798addadf33840f1307cd2977351948794849390840192918601918190849084905b8381101561133457818101518382015260200161131c565b50505050905090810190601f1680156113615780820380516001836020036101000a031916815260200191505b509250505060405180910390a2505b6113e4565b8051156113e25760ff87166000908152600760205260408120546113ae916001600160401b039091169089906111579060019086610800565b60ff8716600090815260076020526040902080546001600160401b038082166001011667ffffffffffffffff199091161790555b505b506119b8565b60ff83166001141561168e5760ff8516600081815260056020908152604080832054815163831d65d160e01b815260048101958652602481019283528651604482015286516001600160a01b0390921695869563831d65d1958d958a9593949093606490910192918601918190849084905b8381101561147457818101518382015260200161145c565b50505050905090810190601f1680156114a15780820380516001836020036101000a031916815260200191505b509350505050600060405180830381600087803b1580156114c157600080fd5b505af19250505080156114d2575060015b6113e4576040516000815260443d10156114ee57506000611589565b60046000803e60005160e01c6308c379a0811461150f576000915050611589565b60043d036004833e81513d60248201116001600160401b038211171561153a57600092505050611589565b80830180516001600160401b0381111561155b576000945050505050611589565b8060208301013d860181111561157957600095505050505050611589565b601f01601f191660405250925050505b8061159457506115f9565b60408051602080825283518183015283516001600160a01b038616937ff91a8f63e5b3e0e89e5f93e1915a7805f3c52d9a73b3c09769785c2c7bf87acf93869390928392830191850190808383600083156111f75781810151838201526020016111df565b3d808015611623576040519150601f19603f3d011682016040523d82523d6000602084013e611628565b606091505b5060408051602080825283518183015283516001600160a01b038616937f63ac299d6332d1cc4e61b81e59bc00c0ac7c798addadf33840f1307cd2977351938693909283928301918501908083836000831561133457818101518382015260200161131c565b60ff8316600214156119b85760ff8516600081815260056020908152604080832054815163c8509d8160e01b815260048101958652602481019283528651604482015286516001600160a01b0390921695869563c8509d81958d958a9593949093606490910192918601918190849084905b83811015611718578181015183820152602001611700565b50505050905090810190601f1680156117455780820380516001836020036101000a031916815260200191505b509350505050600060405180830381600087803b15801561176557600080fd5b505af1925050508015611776575060015b6119b6576040516000815260443d10156117925750600061182d565b60046000803e60005160e01c6308c379a081146117b357600091505061182d565b60043d036004833e81513d60248201116001600160401b03821117156117de5760009250505061182d565b80830180516001600160401b038111156117ff57600094505050505061182d565b8060208301013d860181111561181d5760009550505050505061182d565b601f01601f191660405250925050505b8061183857506118e1565b816001600160a01b03167ff91a8f63e5b3e0e89e5f93e1915a7805f3c52d9a73b3c09769785c2c7bf87acf826040518080602001828103825283818151815260200191508051906020019080838360005b838110156118a1578181015183820152602001611889565b50505050905090810190601f1680156118ce5780820380516001836020036101000a031916815260200191505b509250505060405180910390a2506119b6565b3d80801561190b576040519150601f19603f3d011682016040523d82523d6000602084013e611910565b606091505b50816001600160a01b03167f63ac299d6332d1cc4e61b81e59bc00c0ac7c798addadf33840f1307cd2977351826040518080602001828103825283818151815260200191508051906020019080838360005b8381101561197a578181015183820152602001611962565b50505050905090810190601f1680156119a75780820380516001836020036101000a031916815260200191505b509250505060405180910390a2505b505b60ff80861660009081526009602052604090205461100591636f93d2e69189913391879116806119ea575060ff881615155b604080516001600160e01b031960e088901b1681526001600160a01b039586166004820152939094166024840152604483019190915215156064820152905160848083019260209291908290030181600087803b158015611a4a57600080fd5b505af1158015611a5e573d6000803e3d6000fd5b505050506040513d6020811015611a7457600080fd5b505050505050505050505b505050505050505050505050565b630100610081565b600981565b61100781565b61100681565b60005460ff1681565b3361100714611aef5760405162461bcd60e51b815260040180806020018281038252602e815260200180612abe602e913960400191505060405180910390fd5b611b5884848080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525050604080518082019091526012815271626174636853697a65466f724f7261636c6560701b602082015291506129769050565b15611bf357604080516020601f8401819004810282018101909252828152600091611b9b91858580838501838280828437600092019190915250612a5d92505050565b90506127108111158015611bb05750600a8110155b611beb5760405162461bcd60e51b8152600401808060200182810382526032815260200180612b366032913960400191505060405180910390fd5b600155611fb4565b611c5484848080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152505060408051808201909152600a81526918591910da185b9b995b60b21b602082015291506129769050565b15611dd957606082828080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152505082519293505060169091149050611cd75760405162461bcd60e51b8152600401808060200182810382526052815260200180612b8b6052913960600191505060405180910390fd5b600181015160028201516016830151611cef81612a62565b611d40576040805162461bcd60e51b815260206004820152601960248201527f61646472657373206973206e6f74206120636f6e747261637400000000000000604482015290519081900360640190fd5b60ff808416600081815260056020908152604080832080546001600160a01b0388166001600160a01b03199091168117909155808452600683528184208585528352818420805460ff19908116600117909155600990935281842080549093169588161595909517909155517f7e3b6af43092577ee20e60eaa1d9b114a7031305c895ee7dd3ffe17196d2e1e09190a350505050611fb4565b611e4684848080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525050604080518082019091526016815275195b98589b1953dc911a5cd8589b1950da185b9b995b60521b602082015291506129769050565b15611f7757606082828080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152505082519293505060029091149050611ec95760405162461bcd60e51b815260040180806020018281038252604a815260200180612aec604a913960600191505060405180910390fd5b600181810151600283015160ff80831660009081526005602052604090205492939192908316909114906001600160a01b03168015611f6d576001600160a01b038116600090815260066020908152604080832060ff881680855290835292819020805460ff1916861515908117909155815190815290517fa3132e3f9819fbddc7f0ed6d38d7feef59aa95112090b7c592f5cb5bc4aa4adc929181900390910190a25b5050505050611fb4565b6040805162461bcd60e51b815260206004820152600d60248201526c756e6b6e6f776e20706172616d60981b604482015290519081900360640190fd5b7f6cdb0ac70ab7f2e2d035cca5be60d89906f2dede7648ddbd7402189c1eeed17a848484846040518080602001806020018381038352878782818152602001925080828437600083820152601f01601f191690910184810383528581526020019050858580828437600083820152604051601f909101601f19169092018290039850909650505050505050a150505050565b6008602052600090815260409020546001600160401b031681565b61100281565b600660209081526000928352604080842090915290825290205460ff1681565b6040518060400160405280600381526020016269626360e81b81525081565b61100381565b60005460ff1615612104576040805162461bcd60e51b815260206004820152601960248201527f74686520636f6e747261637420616c726561647920696e697400000000000000604482015290519081900360640190fd5b7f1471eb6eb2c5e789fc3de43f8ce62938c7d1836ec861730447e2ada8fd81017b80546001600160a01b0319908116611008179091557f92e85d02570a8092d09a6e3a57665bc3815a2699a4074001bf1ccabf660f5a36805460ff199081169091557fd8af288fc1c8680b4f4706064cf021e264efb6828fcaf7eb5ca36818eb365bcc8054821660019081179091557f89832631fb3c3307a103ba2c84ab569c64d6182a18893dcd163f0f1c2090733a805484166110049081179091557f6cde3cea4b3a3fb2488b2808bae7556f4a405e50f65e1794383bc026131b13c38054841690557f72e4efa1513b071517c6c74dba31b5934a81aa83cddd400e7081df5529c9943680548416831790557fa9bc9a3a348c357ba16b37005d7e6b3236198c0e939f4af8c5f19b8deeb8ebc08054851690911790557fc575c31fea594a6eb97c8e9d3f9caee4c16218c6ef37e923234c0fe9014a61e78054831690557f4e523af77f034e9810f1c94057f5e931fb3d16a51511a4c3add793617d18610580548316821790557ffb33122aa9f93cc639ebe80a7bc4784c11e6053dde89c6f4f7e268c6a623da1e805484166110001790557fc7694af312c4f286114180fd0ba6a52461fcee8a381636770b19a343af92538a80548316821790557f01112dd68e482ba8d68a7e828cff8b3abcea08eab88941953c180a7e650e9cd480548316821790557fc0a4a8be475dfebc377ebef2d7c4ff47656f572a08dd92b81017efcdba0febe1805484166110071790557f87e8a52529e8ece4ef759037313542a6429ff494a9fab9027fb79db90124eba680548316821790557f4c7666bbcb22d46469f7cc282f70764a7012dca2cce630ff8d83db9a9cdd48f080548316821790557f40f28f99a40bc9f6beea1013afdbc3cdcc689eb76b82c4de06c0acf1e1932ed58054909316611001179092557f0d9cf2cd531699eed8dd34e40ff2884a14a698c4898184fba85194e6f6772d248054821683179055600b60009081527f23f68c9bd22b8a93d06adabe17481c87c016bcbd20adc8bfd707a4d813a572176020527fdf0d5d05428057f5455c2dc8e810dd86d1e9350faa72f16bda8a45443c5b39328054831684179055603283556004805467ffffffffffffffff19166001600160401b031790556002819055600381905580549091169091179055565b6007602052600090815260409020546001600160401b031681565b6000805460ff166124d2576040805162461bcd60e51b81526020600482015260196024820152781d1a194818dbdb9d1c9858dd081b9bdd081a5b9a5d081e595d603a1b604482015290519081900360640190fd5b33600090815260066020908152604080832060ff808a16855292529091205486911661252f5760405162461bcd60e51b8152600401808060200182810382526031815260200180612a8d6031913960400191505060405180910390fd5b60ff86166000908152600760209081526040808320548151601f89018490048402810184019092528782526001600160401b0316926125949284928b926111579290918a918d908d908190840183828082843760009201919091525061080092505050565b60ff969096166000908152600760205260409020805467ffffffffffffffff191660019788016001600160401b03161790555093949350505050565b61100081565b600381565b61100481565b8051602090910191565b5b6020811061260b578251825260209283019290910190601f19016125ec565b915181516020939093036101000a6000190180199091169216919091179052565b60408051600e808252818301909252606091630100610060ff851617918391602082018180368337505050600e818101969096526006810192909252509283525090919050565b60008561268257506000612767565b606082518451865160800101016040519080825280601f01601f1916602001820160405280156126b9576020820181803683370190505b50905060006126c782612a68565b6020808901518252019050866000806126df896125e1565b80865260209095019490925090506126f88285836125eb565b92830192612705886125e1565b808652602090950194909250905061271e8285836125eb565b9283018a815260200192612731876125e1565b90925090506127418285836125eb565b50835160200161274f612a6e565b60208183886065600019fa5051600114955050505050505b95945050505050565b600080600060606021855110156127a0575050604080516000808252602082019092529092508291508190612819565b600185015160218601518651604080516020198301808252601f19600119909401939093168101602001909152604189019392916060919080156127eb576020820181803683370190505b50905060006127f9826125e1565b50905061280b858260218d51036125eb565b506001975091955093509150505b9193509193565b60025443111561285f576004805467ffffffffffffffff1981166001600160401b036001600793840b810190930b1617909155600355436002556128a0565b600380546001908101918290555410156128a0576004805467ffffffffffffffff1981166001600160401b036001600793840b810190930b16179091556003555b8160ff16836001600160401b0316600460009054906101000a900460070b6001600160401b03167f3a6e0fc61675aa2a100bcba0568368bb92bcec91c97673391074f11138f0cffe606185604051808361ffff1661ffff16815260200180602001828103825283818151815260200191508051906020019080838360005b8381101561293657818101518382015260200161291e565b50505050905090810190601f1680156129635780820380516001836020036101000a031916815260200191505b50935050505060405180910390a4505050565b6000816040516020018082805190602001908083835b602083106129ab5780518252601f19909201916020918201910161298c565b6001836020036101000a03801982511681845116808217855250505050505090500191505060405160208183030381529060405280519060200120836040516020018082805190602001908083835b60208310612a195780518252601f1990920191602091820191016129fa565b6001836020036101000a0380198251168184511680821785525050505050509050019150506040516020818303038152906040528051906020012014905092915050565b015190565b3b151590565b60200190565b6040518060200160405280600190602082028036833750919291505056fe74686520636f6e747261637420616e64206368616e6e656c2068617665206e6f74206265656e2072656769737465726564746865206d6573736167652073656e646572206d75737420626520676f7665726e616e636520636f6e74726163746c656e677468206f662076616c756520666f7220656e61626c654f7244697361626c654368616e6e656c2073686f756c6420626520322c206368616e6e656c49643a6973456e61626c65746865206e6577426174636853697a65466f724f7261636c652073686f756c6420626520696e205b31302c2031303030305d6c6967687420636c69656e74206e6f742073796e632074686520626c6f636b207965746c656e677468206f662076616c756520666f72206164644368616e6e656c2073686f756c642062652032322c206368616e6e656c49643a697346726f6d53797374656d3a68616e646c657241646472657373a2646970667358221220230d7e9288613f5afb55ab3692ab4b25169e86ce53da4ef6333e3703c1351f7864736f6c63430006040033" + }, + "9fB29AAc15b9A4B7F17c3385939b007540f4d791": { + "balance": "0x84595161401484a000000" + }, + "37B8516a0F88E65D677229b402ec6C1e0E333004": { + "balance": "0x84595161401484a000000" + } } \ No newline at end of file diff --git a/core/allocs/sokol.json b/core/allocs/sokol.json deleted file mode 100644 index c09cf14041a..00000000000 --- a/core/allocs/sokol.json +++ /dev/null @@ -1,35 +0,0 @@ -{ - "0x0000000000000000000000000000000000000000": { - "balance": "0x0" - }, - "0x0000000000000000000000000000000000000001": { - "balance": "0x1" - }, - "0x0000000000000000000000000000000000000002": { - "balance": "0x1" - }, - "0x0000000000000000000000000000000000000003": { - "balance": "0x1" - }, - "0x0000000000000000000000000000000000000004": { - "balance": "0x1" - }, - "0xe8ddc5c7a2d2f0d7a9798459c0104fdf5e987aca": { - "balance": "252460800000000000000000000" - }, - "0x8bf38d4764929064f2d4d3a56520a76ab3df415b": { - "balance": "1", - "nonce": "1", - "code": "0x6060604052600436106100fc576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff16806303aca79214610101578063108552691461016457806340a141ff1461019d57806340c9cdeb146101d65780634110a489146101ff57806345199e0a1461025757806349285b58146102c15780634d238c8e14610316578063752862111461034f578063900eb5a8146103645780639a573786146103c7578063a26a47d21461041c578063ae4b1b5b14610449578063b3f05b971461049e578063b7ab4db5146104cb578063d3e848f114610535578063fa81b2001461058a578063facd743b146105df575b600080fd5b341561010c57600080fd5b6101226004808035906020019091905050610630565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b341561016f57600080fd5b61019b600480803573ffffffffffffffffffffffffffffffffffffffff1690602001909190505061066f565b005b34156101a857600080fd5b6101d4600480803573ffffffffffffffffffffffffffffffffffffffff16906020019091905050610807565b005b34156101e157600080fd5b6101e9610bb7565b6040518082815260200191505060405180910390f35b341561020a57600080fd5b610236600480803573ffffffffffffffffffffffffffffffffffffffff16906020019091905050610bbd565b60405180831515151581526020018281526020019250505060405180910390f35b341561026257600080fd5b61026a610bee565b6040518080602001828103825283818151815260200191508051906020019060200280838360005b838110156102ad578082015181840152602081019050610292565b505050509050019250505060405180910390f35b34156102cc57600080fd5b6102d4610c82565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b341561032157600080fd5b61034d600480803573ffffffffffffffffffffffffffffffffffffffff16906020019091905050610d32565b005b341561035a57600080fd5b610362610fcc565b005b341561036f57600080fd5b61038560048080359060200190919050506110fc565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b34156103d257600080fd5b6103da61113b565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b341561042757600080fd5b61042f6111eb565b604051808215151515815260200191505060405180910390f35b341561045457600080fd5b61045c6111fe565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b34156104a957600080fd5b6104b1611224565b604051808215151515815260200191505060405180910390f35b34156104d657600080fd5b6104de611237565b6040518080602001828103825283818151815260200191508051906020019060200280838360005b83811015610521578082015181840152602081019050610506565b505050509050019250505060405180910390f35b341561054057600080fd5b6105486112cb565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b341561059557600080fd5b61059d6112f1565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b34156105ea57600080fd5b610616600480803573ffffffffffffffffffffffffffffffffffffffff16906020019091905050611317565b604051808215151515815260200191505060405180910390f35b60078181548110151561063f57fe5b90600052602060002090016000915054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b600460029054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161415156106cb57600080fd5b600460019054906101000a900460ff161515156106e757600080fd5b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161415151561072357600080fd5b80600a60006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055506001600460016101000a81548160ff0219169083151502179055507f600bcf04a13e752d1e3670a5a9f1c21177ca2a93c6f5391d4f1298d098097c22600a60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390a150565b600080600061081461113b565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614151561084d57600080fd5b83600960008273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060000160009054906101000a900460ff1615156108a957600080fd5b600960008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600101549350600160078054905003925060078381548110151561090857fe5b906000526020600020900160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1691508160078581548110151561094657fe5b906000526020600020900160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555083600960008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600101819055506007838154811015156109e557fe5b906000526020600020900160006101000a81549073ffffffffffffffffffffffffffffffffffffffff02191690556000600780549050111515610a2757600080fd5b6007805480919060019003610a3c9190611370565b506000600960008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600101819055506000600960008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060000160006101000a81548160ff0219169083151502179055506000600460006101000a81548160ff0219169083151502179055506001430340600019167f55252fa6eee4741b4e24a74a70e9c11fd2c2281df8d6ea13126ff845f7825c89600760405180806020018281038252838181548152602001915080548015610ba257602002820191906000526020600020905b8160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019060010190808311610b58575b50509250505060405180910390a25050505050565b60085481565b60096020528060005260406000206000915090508060000160009054906101000a900460ff16908060010154905082565b610bf661139c565b6007805480602002602001604051908101604052809291908181526020018280548015610c7857602002820191906000526020600020905b8160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019060010190808311610c2e575b5050505050905090565b6000600a60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166349285b586000604051602001526040518163ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401602060405180830381600087803b1515610d1257600080fd5b6102c65a03f11515610d2357600080fd5b50505060405180519050905090565b610d3a61113b565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141515610d7357600080fd5b80600960008273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060000160009054906101000a900460ff16151515610dd057600080fd5b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1614151515610e0c57600080fd5b6040805190810160405280600115158152602001600780549050815250600960008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008201518160000160006101000a81548160ff0219169083151502179055506020820151816001015590505060078054806001018281610ea991906113b0565b9160005260206000209001600084909190916101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550506000600460006101000a81548160ff0219169083151502179055506001430340600019167f55252fa6eee4741b4e24a74a70e9c11fd2c2281df8d6ea13126ff845f7825c89600760405180806020018281038252838181548152602001915080548015610fba57602002820191906000526020600020905b8160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019060010190808311610f70575b50509250505060405180910390a25050565b600560009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161480156110365750600460009054906101000a900460ff16155b151561104157600080fd5b6001600460006101000a81548160ff0219169083151502179055506007600690805461106e9291906113dc565b506006805490506008819055507f8564cd629b15f47dc310d45bcbfc9bcf5420b0d51bf0659a16c67f91d27632536110a4611237565b6040518080602001828103825283818151815260200191508051906020019060200280838360005b838110156110e75780820151818401526020810190506110cc565b505050509050019250505060405180910390a1565b60068181548110151561110b57fe5b90600052602060002090016000915054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b6000600a60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16639a5737866000604051602001526040518163ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401602060405180830381600087803b15156111cb57600080fd5b6102c65a03f115156111dc57600080fd5b50505060405180519050905090565b600460019054906101000a900460ff1681565b600a60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b600460009054906101000a900460ff1681565b61123f61139c565b60068054806020026020016040519081016040528092919081815260200182805480156112c157602002820191906000526020600020905b8160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019060010190808311611277575b5050505050905090565b600560009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b600460029054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b6000600960008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060000160009054906101000a900460ff169050919050565b81548183558181151161139757818360005260206000209182019101611396919061142e565b5b505050565b602060405190810160405280600081525090565b8154818355818115116113d7578183600052602060002091820191016113d6919061142e565b5b505050565b82805482825590600052602060002090810192821561141d5760005260206000209182015b8281111561141c578254825591600101919060010190611401565b5b50905061142a9190611453565b5090565b61145091905b8082111561144c576000816000905550600101611434565b5090565b90565b61149391905b8082111561148f57600081816101000a81549073ffffffffffffffffffffffffffffffffffffffff021916905550600101611459565b5090565b905600a165627a7a7230582036ea35935c8246b68074adece2eab70c40e69a0193c08a6277ce06e5b25188510029", - "storage": { - "0x0000000000000000000000000000000000000000000000000000000000000005": "0x000000000000000000000000fffffffffffffffffffffffffffffffffffffffe", - "0x0000000000000000000000000000000000000000000000000000000000000008": "0x0000000000000000000000000000000000000000000000000000000000000001", - "0xf652222313e28459528d920b65115c16c04f3efc82aaedc97be59f3f377c0d3f": "0x000000000000000000000000e8ddc5c7a2d2f0d7a9798459c0104fdf5e987aca", - "0x4fcf3d5c1e81dc8f954cd15323063057ac2aee4dd974ed40298bac1fcd864d63": "0x0000000000000000000000000000000000000000000000000000000000000001", - "0x0000000000000000000000000000000000000000000000000000000000000007": "0x0000000000000000000000000000000000000000000000000000000000000001", - "0x0000000000000000000000000000000000000000000000000000000000000004": "0x00000000000000000000e8ddc5c7a2d2f0d7a9798459c0104fdf5e987aca0000", - "0x0000000000000000000000000000000000000000000000000000000000000006": "0x0000000000000000000000000000000000000000000000000000000000000001", - "0xa66cc928b5edb82af9bd49922954155ab7b0942694bea4ce44661d9a8736c688": "0x000000000000000000000000e8ddc5c7a2d2f0d7a9798459c0104fdf5e987aca" - } - } -} \ No newline at end of file diff --git a/core/blockchain.go b/core/blockchain.go index 3487283363d..3bd5b6f07d1 100644 --- a/core/blockchain.go +++ b/core/blockchain.go @@ -19,26 +19,26 @@ package core import ( "fmt" + "math/big" "time" - "github.com/ledgerwatch/erigon-lib/chain" - libcommon "github.com/ledgerwatch/erigon-lib/common" + metrics2 "github.com/VictoriaMetrics/metrics" "golang.org/x/crypto/sha3" "golang.org/x/exp/slices" - "github.com/ledgerwatch/erigon/core/systemcontracts" - "github.com/ledgerwatch/erigon/core/vm/evmtypes" - "github.com/ledgerwatch/erigon/rlp" - - metrics2 "github.com/VictoriaMetrics/metrics" + "github.com/ledgerwatch/erigon-lib/chain" + libcommon "github.com/ledgerwatch/erigon-lib/common" "github.com/ledgerwatch/erigon/common/math" "github.com/ledgerwatch/erigon/common/u256" "github.com/ledgerwatch/erigon/consensus" "github.com/ledgerwatch/erigon/consensus/misc" "github.com/ledgerwatch/erigon/core/state" + "github.com/ledgerwatch/erigon/core/systemcontracts" "github.com/ledgerwatch/erigon/core/types" "github.com/ledgerwatch/erigon/core/vm" + "github.com/ledgerwatch/erigon/core/vm/evmtypes" + "github.com/ledgerwatch/erigon/rlp" ) var ( @@ -75,13 +75,9 @@ func ExecuteBlockEphemerallyForBSC( chainConfig *chain.Config, vmConfig *vm.Config, blockHashFunc func(n uint64) libcommon.Hash, - engine consensus.Engine, - block *types.Block, - stateReader state.StateReader, - stateWriter state.WriterWithChangeSets, - epochReader consensus.EpochReader, - chainReader consensus.ChainHeaderReader, - getTracer func(txIndex int, txHash libcommon.Hash) (vm.EVMLogger, error), + engine consensus.Engine, block *types.Block, + stateReader state.StateReader, stateWriter state.WriterWithChangeSets, + chainReader consensus.ChainHeaderReader, getTracer func(txIndex int, txHash libcommon.Hash) (vm.EVMLogger, error), ) (*EphemeralExecResult, error) { defer BlockExecutionTimer.UpdateDuration(time.Now()) block.Uncles() @@ -97,13 +93,18 @@ func ExecuteBlockEphemerallyForBSC( receipts types.Receipts ) + var excessDataGas *big.Int + ph := chainReader.GetHeaderByHash(block.ParentHash()) + if ph != nil { + excessDataGas = ph.ExcessDataGas + } if !vmConfig.ReadOnly { - if err := InitializeBlockExecution(engine, chainReader, epochReader, block.Header(), block.Transactions(), block.Uncles(), chainConfig, ibs); err != nil { + if err := InitializeBlockExecution(engine, chainReader, block.Header(), block.Transactions(), block.Uncles(), chainConfig, ibs, nil); err != nil { return nil, err } } - if chainConfig.DAOForkSupport && chainConfig.DAOForkBlock != nil && chainConfig.DAOForkBlock.Cmp(block.Number()) == 0 { + if chainConfig.DAOForkBlock != nil && chainConfig.DAOForkBlock.Cmp(block.Number()) == 0 { misc.ApplyDAOHardFork(ibs) } systemcontracts.UpgradeBuildInSystemContract(chainConfig, header.Number, ibs) @@ -129,7 +130,7 @@ func ExecuteBlockEphemerallyForBSC( writeTrace = true } - receipt, _, err := ApplyTransaction(chainConfig, blockHashFunc, engine, nil, gp, ibs, noop, header, tx, usedGas, *vmConfig) + receipt, _, err := ApplyTransaction(chainConfig, blockHashFunc, engine, nil, gp, ibs, noop, header, tx, usedGas, *vmConfig, excessDataGas) if writeTrace { if ftracer, ok := vmConfig.Tracer.(vm.FlushableTracer); ok { ftracer.Flush(tx) @@ -161,9 +162,9 @@ func ExecuteBlockEphemerallyForBSC( // otherwise it causes block verification error. header.GasUsed = *usedGas syscall := func(contract libcommon.Address, data []byte) ([]byte, error) { - return SysCallContract(contract, data, *chainConfig, ibs, header, engine, false /* constCall */) + return SysCallContract(contract, data, *chainConfig, ibs, header, engine, false /* constCall */, excessDataGas) } - outTxs, outReceipts, err := engine.Finalize(chainConfig, header, ibs, block.Transactions(), block.Uncles(), receipts, block.Withdrawals(), epochReader, chainReader, syscall) + outTxs, outReceipts, err := engine.Finalize(chainConfig, header, ibs, block.Transactions(), block.Uncles(), receipts, block.Withdrawals(), chainReader, syscall) if err != nil { return nil, err } @@ -221,16 +222,11 @@ func ExecuteBlockEphemerallyForBSC( // ExecuteBlockEphemerally runs a block from provided stateReader and // writes the result to the provided stateWriter func ExecuteBlockEphemerally( - chainConfig *chain.Config, - vmConfig *vm.Config, + chainConfig *chain.Config, vmConfig *vm.Config, blockHashFunc func(n uint64) libcommon.Hash, - engine consensus.Engine, - block *types.Block, - stateReader state.StateReader, - stateWriter state.WriterWithChangeSets, - epochReader consensus.EpochReader, - chainReader consensus.ChainHeaderReader, - getTracer func(txIndex int, txHash libcommon.Hash) (vm.EVMLogger, error), + engine consensus.Engine, block *types.Block, + stateReader state.StateReader, stateWriter state.WriterWithChangeSets, + chainReader consensus.ChainHeaderReader, getTracer func(txIndex int, txHash libcommon.Hash) (vm.EVMLogger, error), ) (*EphemeralExecResult, error) { defer BlockExecutionTimer.UpdateDuration(time.Now()) @@ -248,13 +244,21 @@ func ExecuteBlockEphemerally( receipts types.Receipts ) + var excessDataGas *big.Int + if chainReader != nil { + // TODO(eip-4844): understand why chainReader is sometimes nil (e.g. certain test cases) + ph := chainReader.GetHeaderByHash(block.ParentHash()) + if ph != nil { + excessDataGas = ph.ExcessDataGas + } + } if !vmConfig.ReadOnly { - if err := InitializeBlockExecution(engine, chainReader, epochReader, block.Header(), block.Transactions(), block.Uncles(), chainConfig, ibs); err != nil { + if err := InitializeBlockExecution(engine, chainReader, block.Header(), block.Transactions(), block.Uncles(), chainConfig, ibs, excessDataGas); err != nil { return nil, err } } - if chainConfig.DAOForkSupport && chainConfig.DAOForkBlock != nil && chainConfig.DAOForkBlock.Cmp(block.Number()) == 0 { + if chainConfig.DAOForkBlock != nil && chainConfig.DAOForkBlock.Cmp(block.Number()) == 0 { misc.ApplyDAOHardFork(ibs) } noop := state.NewNoopWriter() @@ -271,7 +275,7 @@ func ExecuteBlockEphemerally( writeTrace = true } - receipt, _, err := ApplyTransaction(chainConfig, blockHashFunc, engine, nil, gp, ibs, noop, header, tx, usedGas, *vmConfig) + receipt, _, err := ApplyTransaction(chainConfig, blockHashFunc, engine, nil, gp, ibs, noop, header, tx, usedGas, *vmConfig, excessDataGas) if writeTrace { if ftracer, ok := vmConfig.Tracer.(vm.FlushableTracer); ok { ftracer.Flush(tx) @@ -310,7 +314,7 @@ func ExecuteBlockEphemerally( } if !vmConfig.ReadOnly { txs := block.Transactions() - if _, _, _, err := FinalizeBlockExecution(engine, stateReader, block.Header(), txs, block.Uncles(), stateWriter, chainConfig, ibs, receipts, block.Withdrawals(), epochReader, chainReader, false); err != nil { + if _, _, _, err := FinalizeBlockExecution(engine, stateReader, block.Header(), txs, block.Uncles(), stateWriter, chainConfig, ibs, receipts, block.Withdrawals(), chainReader, false, excessDataGas); err != nil { return nil, err } } @@ -332,16 +336,11 @@ func ExecuteBlockEphemerally( // ExecuteBlockEphemerallyBor runs a block from provided stateReader and // writes the result to the provided stateWriter func ExecuteBlockEphemerallyBor( - chainConfig *chain.Config, - vmConfig *vm.Config, + chainConfig *chain.Config, vmConfig *vm.Config, blockHashFunc func(n uint64) libcommon.Hash, - engine consensus.Engine, - block *types.Block, - stateReader state.StateReader, - stateWriter state.WriterWithChangeSets, - epochReader consensus.EpochReader, - chainReader consensus.ChainHeaderReader, - getTracer func(txIndex int, txHash libcommon.Hash) (vm.EVMLogger, error), + engine consensus.Engine, block *types.Block, + stateReader state.StateReader, stateWriter state.WriterWithChangeSets, + chainReader consensus.ChainHeaderReader, getTracer func(txIndex int, txHash libcommon.Hash) (vm.EVMLogger, error), ) (*EphemeralExecResult, error) { defer BlockExecutionTimer.UpdateDuration(time.Now()) @@ -359,13 +358,18 @@ func ExecuteBlockEphemerallyBor( receipts types.Receipts ) + var excessDataGas *big.Int + ph := chainReader.GetHeaderByHash(block.ParentHash()) + if ph != nil { + excessDataGas = ph.ExcessDataGas + } if !vmConfig.ReadOnly { - if err := InitializeBlockExecution(engine, chainReader, epochReader, block.Header(), block.Transactions(), block.Uncles(), chainConfig, ibs); err != nil { + if err := InitializeBlockExecution(engine, chainReader, block.Header(), block.Transactions(), block.Uncles(), chainConfig, ibs, excessDataGas); err != nil { return nil, err } } - if chainConfig.DAOForkSupport && chainConfig.DAOForkBlock != nil && chainConfig.DAOForkBlock.Cmp(block.Number()) == 0 { + if chainConfig.DAOForkBlock != nil && chainConfig.DAOForkBlock.Cmp(block.Number()) == 0 { misc.ApplyDAOHardFork(ibs) } noop := state.NewNoopWriter() @@ -382,7 +386,7 @@ func ExecuteBlockEphemerallyBor( writeTrace = true } - receipt, _, err := ApplyTransaction(chainConfig, blockHashFunc, engine, nil, gp, ibs, noop, header, tx, usedGas, *vmConfig) + receipt, _, err := ApplyTransaction(chainConfig, blockHashFunc, engine, nil, gp, ibs, noop, header, tx, usedGas, *vmConfig, excessDataGas) if writeTrace { if ftracer, ok := vmConfig.Tracer.(vm.FlushableTracer); ok { ftracer.Flush(tx) @@ -421,7 +425,7 @@ func ExecuteBlockEphemerallyBor( } if !vmConfig.ReadOnly { txs := block.Transactions() - if _, _, _, err := FinalizeBlockExecution(engine, stateReader, block.Header(), txs, block.Uncles(), stateWriter, chainConfig, ibs, receipts, block.Withdrawals(), epochReader, chainReader, false); err != nil { + if _, _, _, err := FinalizeBlockExecution(engine, stateReader, block.Header(), txs, block.Uncles(), stateWriter, chainConfig, ibs, receipts, block.Withdrawals(), chainReader, false, excessDataGas); err != nil { return nil, err } } @@ -467,11 +471,10 @@ func rlpHash(x interface{}) (h libcommon.Hash) { return h } -func SysCallContract(contract libcommon.Address, data []byte, chainConfig chain.Config, ibs *state.IntraBlockState, header *types.Header, engine consensus.EngineReader, constCall bool) (result []byte, err error) { - if chainConfig.DAOForkSupport && chainConfig.DAOForkBlock != nil && chainConfig.DAOForkBlock.Cmp(header.Number) == 0 { +func SysCallContract(contract libcommon.Address, data []byte, chainConfig chain.Config, ibs *state.IntraBlockState, header *types.Header, engine consensus.EngineReader, constCall bool, excessDataGas *big.Int) (result []byte, err error) { + if chainConfig.DAOForkBlock != nil && chainConfig.DAOForkBlock.Cmp(header.Number) == 0 { misc.ApplyDAOHardFork(ibs) } - msg := types.NewMessage( state.SystemAddress, &contract, @@ -480,6 +483,7 @@ func SysCallContract(contract libcommon.Address, data []byte, chainConfig chain. nil, nil, data, nil, false, true, // isFree + nil, // maxFeePerDataGas ) vmConfig := vm.Config{NoReceipts: true, RestoreState: constCall} // Create a new context to be used in the EVM environment @@ -493,7 +497,7 @@ func SysCallContract(contract libcommon.Address, data []byte, chainConfig chain. author = &state.SystemAddress txContext = NewEVMTxContext(msg) } - blockContext := NewEVMBlockContext(header, GetHashFn(header, nil), engine, author) + blockContext := NewEVMBlockContext(header, GetHashFn(header, nil), engine, author, excessDataGas) evm := vm.NewEVM(blockContext, txContext, ibs, &chainConfig, vmConfig) ret, _, err := evm.Call( @@ -511,11 +515,10 @@ func SysCallContract(contract libcommon.Address, data []byte, chainConfig chain. } // SysCreate is a special (system) contract creation methods for genesis constructors. -func SysCreate(contract libcommon.Address, data []byte, chainConfig chain.Config, ibs *state.IntraBlockState, header *types.Header) (result []byte, err error) { - if chainConfig.DAOForkSupport && chainConfig.DAOForkBlock != nil && chainConfig.DAOForkBlock.Cmp(header.Number) == 0 { +func SysCreate(contract libcommon.Address, data []byte, chainConfig chain.Config, ibs *state.IntraBlockState, header *types.Header, excessDataGas *big.Int) (result []byte, err error) { + if chainConfig.DAOForkBlock != nil && chainConfig.DAOForkBlock.Cmp(header.Number) == 0 { misc.ApplyDAOHardFork(ibs) } - msg := types.NewMessage( contract, nil, // to @@ -524,12 +527,13 @@ func SysCreate(contract libcommon.Address, data []byte, chainConfig chain.Config nil, nil, data, nil, false, true, // isFree + nil, // maxFeePerDataGas ) vmConfig := vm.Config{NoReceipts: true} // Create a new context to be used in the EVM environment author := &contract txContext := NewEVMTxContext(msg) - blockContext := NewEVMBlockContext(header, GetHashFn(header, nil), nil, author) + blockContext := NewEVMBlockContext(header, GetHashFn(header, nil), nil, author, excessDataGas) evm := vm.NewEVM(blockContext, txContext, ibs, &chainConfig, vmConfig) ret, _, err := evm.SysCreate( @@ -542,12 +546,11 @@ func SysCreate(contract libcommon.Address, data []byte, chainConfig chain.Config return ret, err } -func CallContract(contract libcommon.Address, data []byte, chainConfig chain.Config, ibs *state.IntraBlockState, header *types.Header, engine consensus.Engine) (result []byte, err error) { +func CallContract(contract libcommon.Address, data []byte, chainConfig chain.Config, ibs *state.IntraBlockState, header *types.Header, engine consensus.Engine, excessDataGas *big.Int) (result []byte, err error) { gp := new(GasPool) gp.AddGas(50_000_000) var gasUsed uint64 - - if chainConfig.DAOForkSupport && chainConfig.DAOForkBlock != nil && chainConfig.DAOForkBlock.Cmp(header.Number) == 0 { + if chainConfig.DAOForkBlock != nil && chainConfig.DAOForkBlock.Cmp(header.Number) == 0 { misc.ApplyDAOHardFork(ibs) } noop := state.NewNoopWriter() @@ -556,7 +559,7 @@ func CallContract(contract libcommon.Address, data []byte, chainConfig chain.Con return nil, fmt.Errorf("SysCallContract: %w ", err) } vmConfig := vm.Config{NoReceipts: true} - _, result, err = ApplyTransaction(&chainConfig, GetHashFn(header, nil), engine, &state.SystemAddress, gp, ibs, noop, header, tx, &gasUsed, vmConfig) + _, result, err = ApplyTransaction(&chainConfig, GetHashFn(header, nil), engine, &state.SystemAddress, gp, ibs, noop, header, tx, &gasUsed, vmConfig, excessDataGas) if err != nil { return result, fmt.Errorf("SysCallContract: %w ", err) } @@ -571,17 +574,21 @@ func CallContractTx(contract libcommon.Address, data []byte, ibs *state.IntraBlo return tx.FakeSign(from) } -func FinalizeBlockExecution(engine consensus.Engine, stateReader state.StateReader, header *types.Header, - txs types.Transactions, uncles []*types.Header, stateWriter state.WriterWithChangeSets, cc *chain.Config, ibs *state.IntraBlockState, - receipts types.Receipts, withdrawals []*types.Withdrawal, e consensus.EpochReader, headerReader consensus.ChainHeaderReader, isMining bool, +func FinalizeBlockExecution( + engine consensus.Engine, stateReader state.StateReader, + header *types.Header, txs types.Transactions, uncles []*types.Header, + stateWriter state.WriterWithChangeSets, cc *chain.Config, + ibs *state.IntraBlockState, receipts types.Receipts, + withdrawals []*types.Withdrawal, headerReader consensus.ChainHeaderReader, + isMining bool, excessDataGas *big.Int, ) (newBlock *types.Block, newTxs types.Transactions, newReceipt types.Receipts, err error) { syscall := func(contract libcommon.Address, data []byte) ([]byte, error) { - return SysCallContract(contract, data, *cc, ibs, header, engine, false /* constCall */) + return SysCallContract(contract, data, *cc, ibs, header, engine, false /* constCall */, excessDataGas) } if isMining { - newBlock, newTxs, newReceipt, err = engine.FinalizeAndAssemble(cc, header, ibs, txs, uncles, receipts, withdrawals, e, headerReader, syscall, nil) + newBlock, newTxs, newReceipt, err = engine.FinalizeAndAssemble(cc, header, ibs, txs, uncles, receipts, withdrawals, headerReader, syscall, nil) } else { - _, _, err = engine.Finalize(cc, header, ibs, txs, uncles, receipts, withdrawals, e, headerReader, syscall) + _, _, err = engine.Finalize(cc, header, ibs, txs, uncles, receipts, withdrawals, headerReader, syscall) } if err != nil { return nil, nil, nil, err @@ -597,9 +604,9 @@ func FinalizeBlockExecution(engine consensus.Engine, stateReader state.StateRead return newBlock, newTxs, newReceipt, nil } -func InitializeBlockExecution(engine consensus.Engine, chain consensus.ChainHeaderReader, epochReader consensus.EpochReader, header *types.Header, txs types.Transactions, uncles []*types.Header, cc *chain.Config, ibs *state.IntraBlockState) error { - engine.Initialize(cc, chain, epochReader, header, ibs, txs, uncles, func(contract libcommon.Address, data []byte) ([]byte, error) { - return SysCallContract(contract, data, *cc, ibs, header, engine, false /* constCall */) +func InitializeBlockExecution(engine consensus.Engine, chain consensus.ChainHeaderReader, header *types.Header, txs types.Transactions, uncles []*types.Header, cc *chain.Config, ibs *state.IntraBlockState, excessDataGas *big.Int) error { + engine.Initialize(cc, chain, header, ibs, txs, uncles, func(contract libcommon.Address, data []byte) ([]byte, error) { + return SysCallContract(contract, data, *cc, ibs, header, engine, false /* constCall */, excessDataGas) }) noop := state.NewNoopWriter() ibs.FinalizeTx(cc.Rules(header.Number.Uint64(), header.Time), noop) diff --git a/core/chain_makers.go b/core/chain_makers.go index 2899758f660..302d3ab7cd6 100644 --- a/core/chain_makers.go +++ b/core/chain_makers.go @@ -117,7 +117,7 @@ func (b *BlockGen) AddTxWithChain(getHeader func(hash libcommon.Hash, number uin b.SetCoinbase(libcommon.Address{}) } b.ibs.Prepare(tx.Hash(), libcommon.Hash{}, len(b.txs)) - receipt, _, err := ApplyTransaction(b.config, GetHashFn(b.header, getHeader), engine, &b.header.Coinbase, b.gasPool, b.ibs, state.NewNoopWriter(), b.header, tx, &b.header.GasUsed, vm.Config{}) + receipt, _, err := ApplyTransaction(b.config, GetHashFn(b.header, getHeader), engine, &b.header.Coinbase, b.gasPool, b.ibs, state.NewNoopWriter(), b.header, tx, &b.header.GasUsed, vm.Config{}, b.parent.ExcessDataGas()) if err != nil { panic(err) } @@ -130,7 +130,7 @@ func (b *BlockGen) AddFailedTxWithChain(getHeader func(hash libcommon.Hash, numb b.SetCoinbase(libcommon.Address{}) } b.ibs.Prepare(tx.Hash(), libcommon.Hash{}, len(b.txs)) - receipt, _, err := ApplyTransaction(b.config, GetHashFn(b.header, getHeader), engine, &b.header.Coinbase, b.gasPool, b.ibs, state.NewNoopWriter(), b.header, tx, &b.header.GasUsed, vm.Config{}) + receipt, _, err := ApplyTransaction(b.config, GetHashFn(b.header, getHeader), engine, &b.header.Coinbase, b.gasPool, b.ibs, state.NewNoopWriter(), b.header, tx, &b.header.GasUsed, vm.Config{}, b.parent.ExcessDataGas()) _ = err // accept failed transactions b.txs = append(b.txs, tx) b.receipts = append(b.receipts, receipt) @@ -333,7 +333,7 @@ func GenerateChain(config *chain.Config, parent *types.Block, engine consensus.E } if b.engine != nil { // Finalize and seal the block - if _, _, _, err := b.engine.FinalizeAndAssemble(config, b.header, ibs, b.txs, b.uncles, b.receipts, nil /* withdrawals */, nil, nil, nil, nil); err != nil { + if _, _, _, err := b.engine.FinalizeAndAssemble(config, b.header, ibs, b.txs, b.uncles, b.receipts, nil, nil, nil, nil); err != nil { return nil, nil, fmt.Errorf("call to FinaliseAndAssemble: %w", err) } // Write state changes to db diff --git a/core/evm.go b/core/evm.go index 7c03d5c43f5..1e023f68270 100644 --- a/core/evm.go +++ b/core/evm.go @@ -31,7 +31,9 @@ import ( ) // NewEVMBlockContext creates a new context for use in the EVM. -func NewEVMBlockContext(header *types.Header, blockHashFunc func(n uint64) libcommon.Hash, engine consensus.EngineReader, author *libcommon.Address) evmtypes.BlockContext { +// excessDataGas must be set to the excessDataGas value from the *parent* block header, and can be +// nil if the parent block is not of EIP-4844 type. It is read only. +func NewEVMBlockContext(header *types.Header, blockHashFunc func(n uint64) libcommon.Hash, engine consensus.EngineReader, author *libcommon.Address, excessDataGas *big.Int) evmtypes.BlockContext { // If we don't have an explicit author (i.e. not mining), extract from the header var beneficiary libcommon.Address if author == nil { @@ -59,18 +61,24 @@ func NewEVMBlockContext(header *types.Header, blockHashFunc func(n uint64) libco } else { transferFunc = Transfer } - + // In the event excessDataGas is nil (which happens if the parent block is pre-sharding), + // we bootstrap BlockContext.ExcessDataGas with the zero value. + edg := new(big.Int) + if excessDataGas != nil { + edg.Set(excessDataGas) + } return evmtypes.BlockContext{ - CanTransfer: CanTransfer, - Transfer: transferFunc, - GetHash: blockHashFunc, - Coinbase: beneficiary, - BlockNumber: header.Number.Uint64(), - Time: header.Time, - Difficulty: new(big.Int).Set(header.Difficulty), - BaseFee: &baseFee, - GasLimit: header.GasLimit, - PrevRanDao: prevRandDao, + CanTransfer: CanTransfer, + Transfer: transferFunc, + GetHash: blockHashFunc, + Coinbase: beneficiary, + BlockNumber: header.Number.Uint64(), + Time: header.Time, + Difficulty: new(big.Int).Set(header.Difficulty), + BaseFee: &baseFee, + GasLimit: header.GasLimit, + PrevRanDao: prevRandDao, + ExcessDataGas: edg, } } diff --git a/core/forkid/forkid.go b/core/forkid/forkid.go index ddb4ae2b839..f137c4815f6 100644 --- a/core/forkid/forkid.go +++ b/core/forkid/forkid.go @@ -243,6 +243,11 @@ func GatherForks(config *chain.Config) (heightForks []uint64, timeForks []uint64 } } } + + if config.Aura != nil && config.Aura.PosdaoTransition != nil { + heightForks = append(heightForks, *config.Aura.PosdaoTransition) + } + // Sort the fork block numbers & times to permit chronological XOR slices.Sort(heightForks) slices.Sort(timeForks) diff --git a/core/forkid/forkid_test.go b/core/forkid/forkid_test.go index 733e83877bf..a347cc227a4 100644 --- a/core/forkid/forkid_test.go +++ b/core/forkid/forkid_test.go @@ -19,7 +19,6 @@ package forkid import ( "bytes" "math" - "math/big" "testing" "github.com/ledgerwatch/erigon-lib/chain" @@ -32,6 +31,8 @@ import ( // TestCreation tests that different genesis and fork rule combinations result in // the correct fork ID. +// Forks before Shanghai are triggered by the block number, +// while Shanghai and later forks are triggered by the block time. func TestCreation(t *testing.T) { type testcase struct { head uint64 @@ -48,32 +49,34 @@ func TestCreation(t *testing.T) { params.MainnetChainConfig, params.MainnetGenesisHash, []testcase{ - {0, 0, ID{Hash: checksumToBytes(0xfc64ec04), Next: 1150000}}, // Unsynced - {1149999, 0, ID{Hash: checksumToBytes(0xfc64ec04), Next: 1150000}}, // Last Frontier block - {1150000, 0, ID{Hash: checksumToBytes(0x97c2c34c), Next: 1920000}}, // First Homestead block - {1919999, 0, ID{Hash: checksumToBytes(0x97c2c34c), Next: 1920000}}, // Last Homestead block - {1920000, 0, ID{Hash: checksumToBytes(0x91d1f948), Next: 2463000}}, // First DAO block - {2462999, 0, ID{Hash: checksumToBytes(0x91d1f948), Next: 2463000}}, // Last DAO block - {2463000, 0, ID{Hash: checksumToBytes(0x7a64da13), Next: 2675000}}, // First Tangerine block - {2674999, 0, ID{Hash: checksumToBytes(0x7a64da13), Next: 2675000}}, // Last Tangerine block - {2675000, 0, ID{Hash: checksumToBytes(0x3edd5b10), Next: 4370000}}, // First Spurious block - {4369999, 0, ID{Hash: checksumToBytes(0x3edd5b10), Next: 4370000}}, // Last Spurious block - {4370000, 0, ID{Hash: checksumToBytes(0xa00bc324), Next: 7280000}}, // First Byzantium block - {7279999, 0, ID{Hash: checksumToBytes(0xa00bc324), Next: 7280000}}, // Last Byzantium block - {7280000, 0, ID{Hash: checksumToBytes(0x668db0af), Next: 9069000}}, // First and last Constantinople, first Petersburg block - {9068999, 0, ID{Hash: checksumToBytes(0x668db0af), Next: 9069000}}, // Last Petersburg block - {9069000, 0, ID{Hash: checksumToBytes(0x879d6e30), Next: 9200000}}, // First Istanbul block - {9199999, 0, ID{Hash: checksumToBytes(0x879d6e30), Next: 9200000}}, // Last Istanbul block - {9200000, 0, ID{Hash: checksumToBytes(0xe029e991), Next: 12244000}}, // First Muir Glacier block - {12243999, 0, ID{Hash: checksumToBytes(0xe029e991), Next: 12244000}}, // Last Muir Glacier block - {12244000, 0, ID{Hash: checksumToBytes(0x0eb440f6), Next: 12965000}}, // First Berlin block - {12964999, 0, ID{Hash: checksumToBytes(0x0eb440f6), Next: 12965000}}, // Last Berlin block - {12965000, 0, ID{Hash: checksumToBytes(0xb715077d), Next: 13773000}}, // First London block - {13772999, 0, ID{Hash: checksumToBytes(0xb715077d), Next: 13773000}}, // Last London block - {13773000, 0, ID{Hash: checksumToBytes(0x20c327fc), Next: 15050000}}, // First Arrow Glacier block - {15049999, 0, ID{Hash: checksumToBytes(0x20c327fc), Next: 15050000}}, // Last Arrow Glacier block - {15050000, 0, ID{Hash: checksumToBytes(0xf0afd0e3), Next: 0}}, // First Gray Glacier block - {20000000, 0, ID{Hash: checksumToBytes(0xf0afd0e3), Next: 0}}, // Future Gray Glacier block + {0, 0, ID{Hash: checksumToBytes(0xfc64ec04), Next: 1150000}}, // Unsynced + {1149999, 1457981342, ID{Hash: checksumToBytes(0xfc64ec04), Next: 1150000}}, // Last Frontier block + {1150000, 1457981393, ID{Hash: checksumToBytes(0x97c2c34c), Next: 1920000}}, // First Homestead block + {1919999, 1469020838, ID{Hash: checksumToBytes(0x97c2c34c), Next: 1920000}}, // Last Homestead block + {1920000, 1469020840, ID{Hash: checksumToBytes(0x91d1f948), Next: 2463000}}, // First DAO block + {2462999, 1476796747, ID{Hash: checksumToBytes(0x91d1f948), Next: 2463000}}, // Last DAO block + {2463000, 1476796771, ID{Hash: checksumToBytes(0x7a64da13), Next: 2675000}}, // First Tangerine block + {2674999, 1479831337, ID{Hash: checksumToBytes(0x7a64da13), Next: 2675000}}, // Last Tangerine block + {2675000, 1479831344, ID{Hash: checksumToBytes(0x3edd5b10), Next: 4370000}}, // First Spurious block + {4369999, 1508131303, ID{Hash: checksumToBytes(0x3edd5b10), Next: 4370000}}, // Last Spurious block + {4370000, 1508131331, ID{Hash: checksumToBytes(0xa00bc324), Next: 7280000}}, // First Byzantium block + {7279999, 1551383501, ID{Hash: checksumToBytes(0xa00bc324), Next: 7280000}}, // Last Byzantium block + {7280000, 1551383524, ID{Hash: checksumToBytes(0x668db0af), Next: 9069000}}, // First and last Constantinople, first Petersburg block + {9068999, 1575764708, ID{Hash: checksumToBytes(0x668db0af), Next: 9069000}}, // Last Petersburg block + {9069000, 1575764709, ID{Hash: checksumToBytes(0x879d6e30), Next: 9200000}}, // First Istanbul block + {9199999, 1577953806, ID{Hash: checksumToBytes(0x879d6e30), Next: 9200000}}, // Last Istanbul block + {9200000, 1577953849, ID{Hash: checksumToBytes(0xe029e991), Next: 12244000}}, // First Muir Glacier block + {12243999, 1618481214, ID{Hash: checksumToBytes(0xe029e991), Next: 12244000}}, // Last Muir Glacier block + {12244000, 1618481223, ID{Hash: checksumToBytes(0x0eb440f6), Next: 12965000}}, // First Berlin block + {12964999, 1628166812, ID{Hash: checksumToBytes(0x0eb440f6), Next: 12965000}}, // Last Berlin block + {12965000, 1628166822, ID{Hash: checksumToBytes(0xb715077d), Next: 13773000}}, // First London block + {13772999, 1639079715, ID{Hash: checksumToBytes(0xb715077d), Next: 13773000}}, // Last London block + {13773000, 1639079723, ID{Hash: checksumToBytes(0x20c327fc), Next: 15050000}}, // First Arrow Glacier block + {15049999, 1656586434, ID{Hash: checksumToBytes(0x20c327fc), Next: 15050000}}, // Last Arrow Glacier block + {15050000, 1656586444, ID{Hash: checksumToBytes(0xf0afd0e3), Next: 1681338455}}, // First Gray Glacier block + {17037484, 1681338443, ID{Hash: checksumToBytes(0xf0afd0e3), Next: 1681338455}}, // Last pre-Shanghai block (approx) + {17037485, 1681338455, ID{Hash: checksumToBytes(0xdce96c2d), Next: 0}}, // First Shanghai block (approx) + {19000000, 1700000000, ID{Hash: checksumToBytes(0xdce96c2d), Next: 0}}, // Future Shanghai block (mock) }, }, // Rinkeby test cases @@ -112,8 +115,9 @@ func TestCreation(t *testing.T) { {4460644, 1616045391, ID{Hash: checksumToBytes(0x757a1c47), Next: 5062605}}, // First Berlin block {5062604, 1625109564, ID{Hash: checksumToBytes(0x757a1c47), Next: 5062605}}, // Last Berlin block {5062605, 1625109579, ID{Hash: checksumToBytes(0xB8C6299D), Next: 1678832736}}, // First London block - {8671878, 1678832724, ID{Hash: checksumToBytes(0xB8C6299D), Next: 1678832736}}, // Last pre-Shanghai block (approx height) - {8671879, 1678832736, ID{Hash: checksumToBytes(0xf9843abf), Next: 0}}, // First Shanghai block (approx height) + {8656122, 1678832724, ID{Hash: checksumToBytes(0xB8C6299D), Next: 1678832736}}, // Last pre-Shanghai block + {8656123, 1678832784, ID{Hash: checksumToBytes(0xf9843abf), Next: 0}}, // First Shanghai block + {9900000, 1700000000, ID{Hash: checksumToBytes(0xf9843abf), Next: 0}}, // Future Shanghai block (mock) }, }, // Sepolia test cases @@ -126,6 +130,7 @@ func TestCreation(t *testing.T) { {1735371, 1661130108, ID{Hash: checksumToBytes(0xb96cbd13), Next: 1677557088}}, // First MergeNetsplit block {2990907, 1677557076, ID{Hash: checksumToBytes(0xb96cbd13), Next: 1677557088}}, // Last pre-Shanghai block {2990908, 1677557088, ID{Hash: checksumToBytes(0xf7f9bc08), Next: 0}}, // First Shanghai block + {5000000, 1700000000, ID{Hash: checksumToBytes(0xf7f9bc08), Next: 0}}, // Future Shanghai block (mock) }, }, // Gnosis test cases @@ -167,104 +172,6 @@ func TestCreation(t *testing.T) { } } -// TestCreationWithTimestamps tests that different genesis and fork rule combinations result in -// the correct fork ID even for time based forks. -func TestCreationWithTimestamps(t *testing.T) { - mergeConfig := *params.MainnetChainConfig - mergeConfig.MergeNetsplitBlock = big.NewInt(18000000) - - withdrawalConfig := *params.MainnetChainConfig - withdrawalConfig.MergeNetsplitBlock = big.NewInt(18000000) - withdrawalConfig.ShanghaiTime = big.NewInt(1668000000) - type testcase struct { - head uint64 - time uint64 - want ID - } - tests := []struct { - config *chain.Config - genesis libcommon.Hash - cases []testcase - }{ - // Mainnet test cases - { - params.MainnetChainConfig, - params.MainnetGenesisHash, - []testcase{ - {0, 0, ID{Hash: checksumToBytes(0xfc64ec04), Next: 1150000}}, // Unsynced - {1149999, 0, ID{Hash: checksumToBytes(0xfc64ec04), Next: 1150000}}, // Last Frontier block - {1150000, 0, ID{Hash: checksumToBytes(0x97c2c34c), Next: 1920000}}, // First Homestead block - {1919999, 0, ID{Hash: checksumToBytes(0x97c2c34c), Next: 1920000}}, // Last Homestead block - {1920000, 0, ID{Hash: checksumToBytes(0x91d1f948), Next: 2463000}}, // First DAO block - {2462999, 0, ID{Hash: checksumToBytes(0x91d1f948), Next: 2463000}}, // Last DAO block - {2463000, 0, ID{Hash: checksumToBytes(0x7a64da13), Next: 2675000}}, // First Tangerine block - {2674999, 0, ID{Hash: checksumToBytes(0x7a64da13), Next: 2675000}}, // Last Tangerine block - {2675000, 0, ID{Hash: checksumToBytes(0x3edd5b10), Next: 4370000}}, // First Spurious block - {4369999, 0, ID{Hash: checksumToBytes(0x3edd5b10), Next: 4370000}}, // Last Spurious block - {4370000, 0, ID{Hash: checksumToBytes(0xa00bc324), Next: 7280000}}, // First Byzantium block - {7279999, 0, ID{Hash: checksumToBytes(0xa00bc324), Next: 7280000}}, // Last Byzantium block - {7280000, 0, ID{Hash: checksumToBytes(0x668db0af), Next: 9069000}}, // First and last Constantinople, first Petersburg block - {9068999, 0, ID{Hash: checksumToBytes(0x668db0af), Next: 9069000}}, // Last Petersburg block - {9069000, 0, ID{Hash: checksumToBytes(0x879d6e30), Next: 9200000}}, // First Istanbul and first Muir Glacier block - {9199999, 0, ID{Hash: checksumToBytes(0x879d6e30), Next: 9200000}}, // Last Istanbul and first Muir Glacier block - {9200000, 0, ID{Hash: checksumToBytes(0xe029e991), Next: 12244000}}, // First Muir Glacier block - {12243999, 0, ID{Hash: checksumToBytes(0xe029e991), Next: 12244000}}, // Last Muir Glacier block - {12244000, 0, ID{Hash: checksumToBytes(0x0eb440f6), Next: 12965000}}, // First Berlin block - {12964999, 0, ID{Hash: checksumToBytes(0x0eb440f6), Next: 12965000}}, // Last Berlin block - {12965000, 0, ID{Hash: checksumToBytes(0xb715077d), Next: 13773000}}, // First London block - {13772999, 0, ID{Hash: checksumToBytes(0xb715077d), Next: 13773000}}, // Last London block - {13773000, 0, ID{Hash: checksumToBytes(0x20c327fc), Next: 15050000}}, // First Arrow Glacier block - {15049999, 0, ID{Hash: checksumToBytes(0x20c327fc), Next: 15050000}}, // Last Arrow Glacier block - {15050000, 0, ID{Hash: checksumToBytes(0xf0afd0e3), Next: 0}}, // First Gray Glacier block - {20000000, 0, ID{Hash: checksumToBytes(0xf0afd0e3), Next: 0}}, // Future Gray Glacier block - }, - }, - // Withdrawal test cases - { - &withdrawalConfig, - params.MainnetGenesisHash, - []testcase{ - {0, 0, ID{Hash: checksumToBytes(0xfc64ec04), Next: 1150000}}, // Unsynced - {1149999, 0, ID{Hash: checksumToBytes(0xfc64ec04), Next: 1150000}}, // Last Frontier block - {1150000, 0, ID{Hash: checksumToBytes(0x97c2c34c), Next: 1920000}}, // First Homestead block - {1919999, 0, ID{Hash: checksumToBytes(0x97c2c34c), Next: 1920000}}, // Last Homestead block - {1920000, 0, ID{Hash: checksumToBytes(0x91d1f948), Next: 2463000}}, // First DAO block - {2462999, 0, ID{Hash: checksumToBytes(0x91d1f948), Next: 2463000}}, // Last DAO block - {2463000, 0, ID{Hash: checksumToBytes(0x7a64da13), Next: 2675000}}, // First Tangerine block - {2674999, 0, ID{Hash: checksumToBytes(0x7a64da13), Next: 2675000}}, // Last Tangerine block - {2675000, 0, ID{Hash: checksumToBytes(0x3edd5b10), Next: 4370000}}, // First Spurious block - {4369999, 0, ID{Hash: checksumToBytes(0x3edd5b10), Next: 4370000}}, // Last Spurious block - {4370000, 0, ID{Hash: checksumToBytes(0xa00bc324), Next: 7280000}}, // First Byzantium block - {7279999, 0, ID{Hash: checksumToBytes(0xa00bc324), Next: 7280000}}, // Last Byzantium block - {7280000, 0, ID{Hash: checksumToBytes(0x668db0af), Next: 9069000}}, // First and last Constantinople, first Petersburg block - {9068999, 0, ID{Hash: checksumToBytes(0x668db0af), Next: 9069000}}, // Last Petersburg block - {9069000, 0, ID{Hash: checksumToBytes(0x879d6e30), Next: 9200000}}, // First Istanbul and first Muir Glacier block - {9199999, 0, ID{Hash: checksumToBytes(0x879d6e30), Next: 9200000}}, // Last Istanbul and first Muir Glacier block - {9200000, 0, ID{Hash: checksumToBytes(0xe029e991), Next: 12244000}}, // First Muir Glacier block - {12243999, 0, ID{Hash: checksumToBytes(0xe029e991), Next: 12244000}}, // Last Muir Glacier block - {12244000, 0, ID{Hash: checksumToBytes(0x0eb440f6), Next: 12965000}}, // First Berlin block - {12964999, 0, ID{Hash: checksumToBytes(0x0eb440f6), Next: 12965000}}, // Last Berlin block - {12965000, 0, ID{Hash: checksumToBytes(0xb715077d), Next: 13773000}}, // First London block - {13772999, 0, ID{Hash: checksumToBytes(0xb715077d), Next: 13773000}}, // Last London block - {13773000, 0, ID{Hash: checksumToBytes(0x20c327fc), Next: 15050000}}, // First Arrow Glacier block - {15049999, 0, ID{Hash: checksumToBytes(0x20c327fc), Next: 15050000}}, // Last Arrow Glacier block - {15050000, 0, ID{Hash: checksumToBytes(0xf0afd0e3), Next: 18000000}}, // First Gray Glacier block - {18000000, 0, ID{Hash: checksumToBytes(0x4fb8a872), Next: 1668000000}}, // First Merge Start block - {20000000, 0, ID{Hash: checksumToBytes(0x4fb8a872), Next: 1668000000}}, // Last Merge Start block - {20000000, 1668000000, ID{Hash: checksumToBytes(0xc1fdf181), Next: 0}}, // First Merge Start block - {20000000, 2668000000, ID{Hash: checksumToBytes(0xc1fdf181), Next: 0}}, // Future Merge Start block - }, - }, - } - for i, tt := range tests { - for j, ttt := range tt.cases { - if have := NewID(tt.config, tt.genesis, ttt.head, ttt.time); have != ttt.want { - t.Errorf("test %d, case %d: fork ID mismatch: have %x, want %x", i, j, have, ttt.want) - } - } - } -} - // TestValidation tests that a local peer correctly validates and accepts a remote // fork ID. func TestValidation(t *testing.T) { diff --git a/core/gen_genesis.go b/core/gen_genesis.go index 2a51c5d45f6..cf933fe6a1b 100644 --- a/core/gen_genesis.go +++ b/core/gen_genesis.go @@ -9,9 +9,9 @@ import ( "github.com/ledgerwatch/erigon-lib/chain" libcommon "github.com/ledgerwatch/erigon-lib/common" + "github.com/ledgerwatch/erigon-lib/common/hexutility" "github.com/ledgerwatch/erigon/common" - "github.com/ledgerwatch/erigon/common/hexutil" "github.com/ledgerwatch/erigon/common/math" ) @@ -20,19 +20,22 @@ var _ = (*genesisSpecMarshaling)(nil) // MarshalJSON marshals as JSON. func (g Genesis) MarshalJSON() ([]byte, error) { type Genesis struct { - Config *chain.Config `json:"config"` - Nonce math.HexOrDecimal64 `json:"nonce"` - Timestamp math.HexOrDecimal64 `json:"timestamp"` - ExtraData hexutil.Bytes `json:"extraData"` - GasLimit math.HexOrDecimal64 `json:"gasLimit" gencodec:"required"` - Difficulty *math.HexOrDecimal256 `json:"difficulty" gencodec:"required"` - Mixhash libcommon.Hash `json:"mixHash"` - Coinbase libcommon.Address `json:"coinbase"` - Alloc map[common.UnprefixedAddress]GenesisAccount `json:"alloc" gencodec:"required"` - Number math.HexOrDecimal64 `json:"number"` - GasUsed math.HexOrDecimal64 `json:"gasUsed"` - ParentHash libcommon.Hash `json:"parentHash"` - BaseFee *math.HexOrDecimal256 `json:"baseFeePerGas"` + Config *chain.Config `json:"config"` + Nonce math.HexOrDecimal64 `json:"nonce"` + Timestamp math.HexOrDecimal64 `json:"timestamp"` + ExtraData hexutility.Bytes `json:"extraData"` + GasLimit math.HexOrDecimal64 `json:"gasLimit" gencodec:"required"` + Difficulty *math.HexOrDecimal256 `json:"difficulty" gencodec:"required"` + Mixhash libcommon.Hash `json:"mixHash"` + Coinbase libcommon.Address `json:"coinbase"` + BaseFee *math.HexOrDecimal256 `json:"baseFeePerGas"` + ExcessDataGas *math.HexOrDecimal256 `json:"excessDataGas"` + Alloc map[common.UnprefixedAddress]GenesisAccount `json:"alloc" gencodec:"required"` + AuRaStep math.HexOrDecimal64 `json:"auRaStep"` + AuRaSeal hexutility.Bytes `json:"auRaSeal"` + Number math.HexOrDecimal64 `json:"number"` + GasUsed math.HexOrDecimal64 `json:"gasUsed"` + ParentHash libcommon.Hash `json:"parentHash"` } var enc Genesis enc.Config = g.Config @@ -43,35 +46,41 @@ func (g Genesis) MarshalJSON() ([]byte, error) { enc.Difficulty = (*math.HexOrDecimal256)(g.Difficulty) enc.Mixhash = g.Mixhash enc.Coinbase = g.Coinbase + enc.BaseFee = (*math.HexOrDecimal256)(g.BaseFee) + enc.ExcessDataGas = (*math.HexOrDecimal256)(g.ExcessDataGas) if g.Alloc != nil { enc.Alloc = make(map[common.UnprefixedAddress]GenesisAccount, len(g.Alloc)) for k, v := range g.Alloc { enc.Alloc[common.UnprefixedAddress(k)] = v } } + enc.AuRaStep = math.HexOrDecimal64(g.AuRaStep) + enc.AuRaSeal = g.AuRaSeal enc.Number = math.HexOrDecimal64(g.Number) enc.GasUsed = math.HexOrDecimal64(g.GasUsed) enc.ParentHash = g.ParentHash - enc.BaseFee = (*math.HexOrDecimal256)(g.BaseFee) return json.Marshal(&enc) } // UnmarshalJSON unmarshals from JSON. func (g *Genesis) UnmarshalJSON(input []byte) error { type Genesis struct { - Config *chain.Config `json:"config"` - Nonce *math.HexOrDecimal64 `json:"nonce"` - Timestamp *math.HexOrDecimal64 `json:"timestamp"` - ExtraData *hexutil.Bytes `json:"extraData"` - GasLimit *math.HexOrDecimal64 `json:"gasLimit" gencodec:"required"` - Difficulty *math.HexOrDecimal256 `json:"difficulty" gencodec:"required"` - Mixhash *libcommon.Hash `json:"mixHash"` - Coinbase *libcommon.Address `json:"coinbase"` - Alloc map[common.UnprefixedAddress]GenesisAccount `json:"alloc" gencodec:"required"` - Number *math.HexOrDecimal64 `json:"number"` - GasUsed *math.HexOrDecimal64 `json:"gasUsed"` - ParentHash *libcommon.Hash `json:"parentHash"` - BaseFee *math.HexOrDecimal256 `json:"baseFeePerGas"` + Config *chain.Config `json:"config"` + Nonce *math.HexOrDecimal64 `json:"nonce"` + Timestamp *math.HexOrDecimal64 `json:"timestamp"` + ExtraData *hexutility.Bytes `json:"extraData"` + GasLimit *math.HexOrDecimal64 `json:"gasLimit" gencodec:"required"` + Difficulty *math.HexOrDecimal256 `json:"difficulty" gencodec:"required"` + Mixhash *libcommon.Hash `json:"mixHash"` + Coinbase *libcommon.Address `json:"coinbase"` + BaseFee *math.HexOrDecimal256 `json:"baseFeePerGas"` + ExcessDataGas *math.HexOrDecimal256 `json:"excessDataGas"` + Alloc map[common.UnprefixedAddress]GenesisAccount `json:"alloc" gencodec:"required"` + AuRaStep *math.HexOrDecimal64 `json:"auRaStep"` + AuRaSeal *hexutility.Bytes `json:"auRaSeal"` + Number *math.HexOrDecimal64 `json:"number"` + GasUsed *math.HexOrDecimal64 `json:"gasUsed"` + ParentHash *libcommon.Hash `json:"parentHash"` } var dec Genesis if err := json.Unmarshal(input, &dec); err != nil { @@ -103,6 +112,12 @@ func (g *Genesis) UnmarshalJSON(input []byte) error { if dec.Coinbase != nil { g.Coinbase = *dec.Coinbase } + if dec.BaseFee != nil { + g.BaseFee = (*big.Int)(dec.BaseFee) + } + if dec.ExcessDataGas != nil { + g.ExcessDataGas = (*big.Int)(dec.ExcessDataGas) + } if dec.Alloc == nil { return errors.New("missing required field 'alloc' for Genesis") } @@ -110,6 +125,12 @@ func (g *Genesis) UnmarshalJSON(input []byte) error { for k, v := range dec.Alloc { g.Alloc[libcommon.Address(k)] = v } + if dec.AuRaStep != nil { + g.AuRaStep = uint64(*dec.AuRaStep) + } + if dec.AuRaSeal != nil { + g.AuRaSeal = *dec.AuRaSeal + } if dec.Number != nil { g.Number = uint64(*dec.Number) } @@ -119,8 +140,5 @@ func (g *Genesis) UnmarshalJSON(input []byte) error { if dec.ParentHash != nil { g.ParentHash = *dec.ParentHash } - if dec.BaseFee != nil { - g.BaseFee = (*big.Int)(dec.BaseFee) - } return nil } diff --git a/core/gen_genesis_account.go b/core/gen_genesis_account.go index 49abcea1cba..c9422b403a2 100644 --- a/core/gen_genesis_account.go +++ b/core/gen_genesis_account.go @@ -8,8 +8,8 @@ import ( "math/big" libcommon "github.com/ledgerwatch/erigon-lib/common" + "github.com/ledgerwatch/erigon-lib/common/hexutility" - "github.com/ledgerwatch/erigon/common/hexutil" "github.com/ledgerwatch/erigon/common/math" ) @@ -18,12 +18,12 @@ var _ = (*genesisAccountMarshaling)(nil) // MarshalJSON marshals as JSON. func (g GenesisAccount) MarshalJSON() ([]byte, error) { type GenesisAccount struct { - Constructor hexutil.Bytes `json:"constructor,omitempty"` - Code hexutil.Bytes `json:"code,omitempty"` + Constructor hexutility.Bytes `json:"constructor,omitempty"` + Code hexutility.Bytes `json:"code,omitempty"` Storage map[storageJSON]storageJSON `json:"storage,omitempty"` Balance *math.HexOrDecimal256 `json:"balance" gencodec:"required"` Nonce math.HexOrDecimal64 `json:"nonce,omitempty"` - PrivateKey hexutil.Bytes `json:"secretKey,omitempty"` + PrivateKey hexutility.Bytes `json:"secretKey,omitempty"` } var enc GenesisAccount enc.Constructor = g.Constructor @@ -43,12 +43,12 @@ func (g GenesisAccount) MarshalJSON() ([]byte, error) { // UnmarshalJSON unmarshals from JSON. func (g *GenesisAccount) UnmarshalJSON(input []byte) error { type GenesisAccount struct { - Constructor *hexutil.Bytes `json:"constructor,omitempty"` - Code *hexutil.Bytes `json:"code,omitempty"` + Constructor *hexutility.Bytes `json:"constructor,omitempty"` + Code *hexutility.Bytes `json:"code,omitempty"` Storage map[storageJSON]storageJSON `json:"storage,omitempty"` Balance *math.HexOrDecimal256 `json:"balance" gencodec:"required"` Nonce *math.HexOrDecimal64 `json:"nonce,omitempty"` - PrivateKey *hexutil.Bytes `json:"secretKey,omitempty"` + PrivateKey *hexutility.Bytes `json:"secretKey,omitempty"` } var dec GenesisAccount if err := json.Unmarshal(input, &dec); err != nil { diff --git a/core/genesis.go b/core/genesis.go index 3aa8bb9628c..660ab28fe36 100644 --- a/core/genesis.go +++ b/core/genesis.go @@ -17,13 +17,10 @@ package core import ( - "bytes" "context" "embed" "encoding/binary" - "encoding/hex" "encoding/json" - "errors" "fmt" "math/big" "sync" @@ -37,13 +34,13 @@ import ( "github.com/ledgerwatch/erigon-lib/kv/rawdbv3" "github.com/ledgerwatch/erigon/common" "github.com/ledgerwatch/erigon/common/hexutil" - "github.com/ledgerwatch/erigon/common/math" "github.com/ledgerwatch/erigon/consensus/ethash" "github.com/ledgerwatch/erigon/consensus/serenity" "github.com/ledgerwatch/erigon/core/rawdb" "github.com/ledgerwatch/erigon/core/state" "github.com/ledgerwatch/erigon/core/types" "github.com/ledgerwatch/erigon/crypto" + "github.com/ledgerwatch/erigon/eth/ethconfig" "github.com/ledgerwatch/erigon/params" "github.com/ledgerwatch/erigon/params/networkname" "github.com/ledgerwatch/erigon/turbo/trie" @@ -51,135 +48,12 @@ import ( "golang.org/x/exp/slices" ) -//go:generate gencodec -type Genesis -field-override genesisSpecMarshaling -out gen_genesis.go -//go:generate gencodec -type GenesisAccount -field-override genesisAccountMarshaling -out gen_genesis_account.go - -//go:embed allocs -var allocs embed.FS - -var ErrGenesisNoConfig = errors.New("genesis has no chain configuration") - -// Genesis specifies the header fields, state of a genesis block. It also defines hard -// fork switch-over blocks through the chain configuration. -type Genesis struct { - Config *chain.Config `json:"config"` - Nonce uint64 `json:"nonce"` - Timestamp uint64 `json:"timestamp"` - ExtraData []byte `json:"extraData"` - GasLimit uint64 `json:"gasLimit" gencodec:"required"` - Difficulty *big.Int `json:"difficulty" gencodec:"required"` - Mixhash libcommon.Hash `json:"mixHash"` - Coinbase libcommon.Address `json:"coinbase"` - Alloc GenesisAlloc `json:"alloc" gencodec:"required"` - AuRaStep uint64 `json:"auRaStep"` - AuRaSeal []byte `json:"auRaSeal"` - - // These fields are used for consensus tests. Please don't use them - // in actual genesis blocks. - Number uint64 `json:"number"` - GasUsed uint64 `json:"gasUsed"` - ParentHash libcommon.Hash `json:"parentHash"` - BaseFee *big.Int `json:"baseFeePerGas"` -} - -// GenesisAlloc specifies the initial state that is part of the genesis block. -type GenesisAlloc map[libcommon.Address]GenesisAccount - -type AuthorityRoundSeal struct { - /// Seal step. - Step uint64 `json:"step"` - /// Seal signature. - Signature libcommon.Hash `json:"signature"` -} - -var genesisTmpDB kv.RwDB -var genesisDBLock sync.Mutex - -func (ga *GenesisAlloc) UnmarshalJSON(data []byte) error { - m := make(map[common.UnprefixedAddress]GenesisAccount) - if err := json.Unmarshal(data, &m); err != nil { - return err - } - *ga = make(GenesisAlloc) - for addr, a := range m { - (*ga)[libcommon.Address(addr)] = a - } - return nil -} - -// GenesisAccount is an account in the state of the genesis block. -// Either use "constructor" for deployment code or "code" directly for the final code. -type GenesisAccount struct { - Constructor []byte `json:"constructor,omitempty"` // deployment code - Code []byte `json:"code,omitempty"` // final contract code - Storage map[libcommon.Hash]libcommon.Hash `json:"storage,omitempty"` - Balance *big.Int `json:"balance" gencodec:"required"` - Nonce uint64 `json:"nonce,omitempty"` - PrivateKey []byte `json:"secretKey,omitempty"` // for tests -} - -// field type overrides for gencodec -type genesisSpecMarshaling struct { - Nonce math.HexOrDecimal64 - Timestamp math.HexOrDecimal64 - ExtraData hexutil.Bytes - GasLimit math.HexOrDecimal64 - GasUsed math.HexOrDecimal64 - Number math.HexOrDecimal64 - Difficulty *math.HexOrDecimal256 - BaseFee *math.HexOrDecimal256 - Alloc map[common.UnprefixedAddress]GenesisAccount -} - -type genesisAccountMarshaling struct { - Constructor hexutil.Bytes - Code hexutil.Bytes - Balance *math.HexOrDecimal256 - Nonce math.HexOrDecimal64 - Storage map[storageJSON]storageJSON - PrivateKey hexutil.Bytes -} - -// storageJSON represents a 256 bit byte array, but allows less than 256 bits when -// unmarshaling from hex. -type storageJSON libcommon.Hash - -func (h *storageJSON) UnmarshalText(text []byte) error { - text = bytes.TrimPrefix(text, []byte("0x")) - if len(text) > 64 { - return fmt.Errorf("too many hex characters in storage key/value %q", text) - } - offset := len(h) - len(text)/2 // pad on the left - if _, err := hex.Decode(h[offset:], text); err != nil { - return fmt.Errorf("invalid hex storage key/value %q", text) - } - return nil -} - -func (h storageJSON) MarshalText() ([]byte, error) { - return hexutil.Bytes(h[:]).MarshalText() -} - -// GenesisMismatchError is raised when trying to overwrite an existing -// genesis block with an incompatible one. -type GenesisMismatchError struct { - Stored, New libcommon.Hash -} - -func (e *GenesisMismatchError) Error() string { - config := params.ChainConfigByGenesisHash(e.Stored) - if config == nil { - return fmt.Sprintf("database contains incompatible genesis (have %x, new %x)", e.Stored, e.New) - } - return fmt.Sprintf("database contains incompatible genesis (try with --chain=%s)", config.ChainName) -} - // CommitGenesisBlock writes or updates the genesis block in db. // The block that will be used is: // // genesis == nil genesis != nil // +------------------------------------------ -// db has no genesis | main-net default | genesis +// db has no genesis | main-net | genesis // db has genesis | from DB | genesis (if compatible) // // The stored chain configuration will be updated if it is compatible (i.e. does not @@ -187,11 +61,11 @@ func (e *GenesisMismatchError) Error() string { // error is a *params.ConfigCompatError and the new, unwritten config is returned. // // The returned chain configuration is never nil. -func CommitGenesisBlock(db kv.RwDB, genesis *Genesis, tmpDir string) (*chain.Config, *types.Block, error) { +func CommitGenesisBlock(db kv.RwDB, genesis *types.Genesis, tmpDir string) (*chain.Config, *types.Block, error) { return CommitGenesisBlockWithOverride(db, genesis, nil, tmpDir) } -func CommitGenesisBlockWithOverride(db kv.RwDB, genesis *Genesis, overrideShanghaiTime *big.Int, tmpDir string) (*chain.Config, *types.Block, error) { +func CommitGenesisBlockWithOverride(db kv.RwDB, genesis *types.Genesis, overrideShanghaiTime *big.Int, tmpDir string) (*chain.Config, *types.Block, error) { tx, err := db.BeginRw(context.Background()) if err != nil { return nil, nil, err @@ -208,20 +82,12 @@ func CommitGenesisBlockWithOverride(db kv.RwDB, genesis *Genesis, overrideShangh return c, b, nil } -func MustCommitGenesisBlock(db kv.RwDB, genesis *Genesis, tmpDir string) (*chain.Config, *types.Block) { - c, b, err := CommitGenesisBlock(db, genesis, tmpDir) - if err != nil { - panic(err) - } - return c, b -} - -func WriteGenesisBlock(db kv.RwTx, genesis *Genesis, overrideShanghaiTime *big.Int, tmpDir string) (*chain.Config, *types.Block, error) { +func WriteGenesisBlock(tx kv.RwTx, genesis *types.Genesis, overrideShanghaiTime *big.Int, tmpDir string) (*chain.Config, *types.Block, error) { if genesis != nil && genesis.Config == nil { - return params.AllProtocolChanges, nil, ErrGenesisNoConfig + return params.AllProtocolChanges, nil, types.ErrGenesisNoConfig } // Just commit the new block if there is no stored genesis block. - storedHash, storedErr := rawdb.ReadCanonicalHash(db, 0) + storedHash, storedErr := rawdb.ReadCanonicalHash(tx, 0) if storedErr != nil { return nil, nil, storedErr } @@ -235,12 +101,12 @@ func WriteGenesisBlock(db kv.RwTx, genesis *Genesis, overrideShanghaiTime *big.I if (storedHash == libcommon.Hash{}) { custom := true if genesis == nil { - log.Info("Writing default main-net genesis block") - genesis = DefaultGenesisBlock() + log.Info("Writing main-net genesis block") + genesis = MainnetGenesisBlock() custom = false } applyOverrides(genesis.Config) - block, _, err1 := genesis.Write(db, tmpDir) + block, _, err1 := write(tx, genesis, tmpDir) if err1 != nil { return genesis.Config, nil, err1 } @@ -252,32 +118,32 @@ func WriteGenesisBlock(db kv.RwTx, genesis *Genesis, overrideShanghaiTime *big.I // Check whether the genesis block is already written. if genesis != nil { - block, _, err1 := genesis.ToBlock(tmpDir) + block, _, err1 := GenesisToBlock(genesis, tmpDir) if err1 != nil { return genesis.Config, nil, err1 } hash := block.Hash() if hash != storedHash { - return genesis.Config, block, &GenesisMismatchError{storedHash, hash} + return genesis.Config, block, &types.GenesisMismatchError{Stored: storedHash, New: hash} } } - storedBlock, err := rawdb.ReadBlockByHash(db, storedHash) + storedBlock, err := rawdb.ReadBlockByHash(tx, storedHash) if err != nil { return genesis.Config, nil, err } // Get the existing chain configuration. - newCfg := genesis.configOrDefault(storedHash) + newCfg := genesis.ConfigOrDefault(storedHash) applyOverrides(newCfg) if err := newCfg.CheckConfigForkOrder(); err != nil { return newCfg, nil, err } - storedCfg, storedErr := rawdb.ReadChainConfig(db, storedHash) + storedCfg, storedErr := rawdb.ReadChainConfig(tx, storedHash) if storedErr != nil && newCfg.Bor == nil { return newCfg, nil, storedErr } if storedCfg == nil { log.Warn("Found genesis block without chain config") - err1 := rawdb.WriteChainConfig(db, storedHash, newCfg) + err1 := rawdb.WriteChainConfig(tx, storedHash, newCfg) if err1 != nil { return newCfg, nil, err1 } @@ -292,206 +158,82 @@ func WriteGenesisBlock(db kv.RwTx, genesis *Genesis, overrideShanghaiTime *big.I } // Check config compatibility and write the config. Compatibility errors // are returned to the caller unless we're already at block zero. - height := rawdb.ReadHeaderNumber(db, rawdb.ReadHeadHeaderHash(db)) + height := rawdb.ReadHeaderNumber(tx, rawdb.ReadHeadHeaderHash(tx)) if height != nil { compatibilityErr := storedCfg.CheckCompatible(newCfg, *height) if compatibilityErr != nil && *height != 0 && compatibilityErr.RewindTo != 0 { return newCfg, storedBlock, compatibilityErr } } - if err := rawdb.WriteChainConfig(db, storedHash, newCfg); err != nil { + if err := rawdb.WriteChainConfig(tx, storedHash, newCfg); err != nil { return newCfg, nil, err } return newCfg, storedBlock, nil } -func (g *Genesis) configOrDefault(genesisHash libcommon.Hash) *chain.Config { - if g != nil { - return g.Config - } - - config := params.ChainConfigByGenesisHash(genesisHash) - if config != nil { - return config - } else { - return params.AllProtocolChanges - } -} - -func sortedAllocKeys(m GenesisAlloc) []string { - keys := make([]string, len(m)) - i := 0 - for k := range m { - keys[i] = string(k.Bytes()) - i++ - } - slices.Sort(keys) - return keys -} - -// ToBlock creates the genesis block and writes state of a genesis specification -// to the given database (or discards it if nil). -func (g *Genesis) ToBlock(tmpDir string) (*types.Block, *state.IntraBlockState, error) { - _ = g.Alloc //nil-check - - head := &types.Header{ - Number: new(big.Int).SetUint64(g.Number), - Nonce: types.EncodeNonce(g.Nonce), - Time: g.Timestamp, - ParentHash: g.ParentHash, - Extra: g.ExtraData, - GasLimit: g.GasLimit, - GasUsed: g.GasUsed, - Difficulty: g.Difficulty, - MixDigest: g.Mixhash, - Coinbase: g.Coinbase, - BaseFee: g.BaseFee, - AuRaStep: g.AuRaStep, - AuRaSeal: g.AuRaSeal, - } - if g.GasLimit == 0 { - head.GasLimit = params.GenesisGasLimit - } - if g.Difficulty == nil { - head.Difficulty = params.GenesisDifficulty - } - if g.Config != nil && (g.Config.IsLondon(0)) { - if g.BaseFee != nil { - head.BaseFee = g.BaseFee - } else { - head.BaseFee = new(big.Int).SetUint64(params.InitialBaseFee) - } - } - - var withdrawals []*types.Withdrawal - if g.Config != nil && (g.Config.IsShanghai(g.Timestamp)) { - withdrawals = []*types.Withdrawal{} - } - - var root libcommon.Hash - var statedb *state.IntraBlockState - wg := sync.WaitGroup{} - wg.Add(1) - var err error - go func() { // we may run inside write tx, can't open 2nd write tx in same goroutine - // TODO(yperbasis): use memdb.MemoryMutation instead - defer wg.Done() - genesisDBLock.Lock() - defer genesisDBLock.Unlock() - if genesisTmpDB == nil { - genesisTmpDB = mdbx.NewMDBX(log.New()).InMem(tmpDir).MapSize(2 * datasize.GB).PageSize(2 * 4096).MustOpen() - } - var tx kv.RwTx - if tx, err = genesisTmpDB.BeginRw(context.Background()); err != nil { - return - } - defer tx.Rollback() - r, w := state.NewDbStateReader(tx), state.NewDbStateWriter(tx, 0) - statedb = state.New(r) - - hasConstructorAllocation := false - for _, account := range g.Alloc { - if len(account.Constructor) > 0 { - hasConstructorAllocation = true - break - } - } - // See https://github.com/NethermindEth/nethermind/blob/master/src/Nethermind/Nethermind.Consensus.AuRa/InitializationSteps/LoadGenesisBlockAuRa.cs - if hasConstructorAllocation && g.Config.Aura != nil { - statedb.CreateAccount(libcommon.Address{}, false) - } - - keys := sortedAllocKeys(g.Alloc) - for _, key := range keys { - addr := libcommon.BytesToAddress([]byte(key)) - account := g.Alloc[addr] - - balance, overflow := uint256.FromBig(account.Balance) - if overflow { - panic("overflow at genesis allocs") - } - statedb.AddBalance(addr, balance) - statedb.SetCode(addr, account.Code) - statedb.SetNonce(addr, account.Nonce) - for key, value := range account.Storage { - key := key - val := uint256.NewInt(0).SetBytes(value.Bytes()) - statedb.SetState(addr, &key, *val) - } - - if len(account.Constructor) > 0 { - if _, err = SysCreate(addr, account.Constructor, *g.Config, statedb, head); err != nil { - return - } - } - - if len(account.Code) > 0 || len(account.Storage) > 0 || len(account.Constructor) > 0 { - statedb.SetIncarnation(addr, state.FirstContractIncarnation) - } - } - if err = statedb.FinalizeTx(&chain.Rules{}, w); err != nil { - return - } - if root, err = trie.CalcRoot("genesis", tx); err != nil { - return - } - }() - wg.Wait() +func WriteGenesisState(g *types.Genesis, tx kv.RwTx, tmpDir string) (*types.Block, *state.IntraBlockState, error) { + block, statedb, err := GenesisToBlock(g, tmpDir) if err != nil { return nil, nil, err } - - head.Root = root - - return types.NewBlock(head, nil, nil, nil, withdrawals), statedb, nil -} - -func (g *Genesis) WriteGenesisState(tx kv.RwTx, tmpDir string) (*types.Block, *state.IntraBlockState, error) { - block, statedb, err := g.ToBlock(tmpDir) - if err != nil { - return nil, nil, err - } - for addr, account := range g.Alloc { - if len(account.Code) > 0 || len(account.Storage) > 0 { - // Special case for weird tests - inaccessible storage - var b [8]byte - binary.BigEndian.PutUint64(b[:], state.FirstContractIncarnation) - if err := tx.Put(kv.IncarnationMap, addr[:], b[:]); err != nil { - return nil, nil, err + var stateWriter state.StateWriter + if ethconfig.EnableHistoryV4InTest { + panic("implement me") + //tx.(*temporal.Tx).Agg().SetTxNum(0) + //stateWriter = state.NewWriterV4(tx.(kv.TemporalTx)) + //defer tx.(*temporal.Tx).Agg().StartUnbufferedWrites().FinishWrites() + } else { + for addr, account := range g.Alloc { + if len(account.Code) > 0 || len(account.Storage) > 0 { + // Special case for weird tests - inaccessible storage + var b [8]byte + binary.BigEndian.PutUint64(b[:], state.FirstContractIncarnation) + if err := tx.Put(kv.IncarnationMap, addr[:], b[:]); err != nil { + return nil, nil, err + } } } + stateWriter = state.NewPlainStateWriter(tx, tx, 0) } if block.Number().Sign() != 0 { return nil, statedb, fmt.Errorf("can't commit genesis block with number > 0") } - blockWriter := state.NewPlainStateWriter(tx, tx, 0) - - if err := statedb.CommitBlock(&chain.Rules{}, blockWriter); err != nil { + if err := statedb.CommitBlock(&chain.Rules{}, stateWriter); err != nil { return nil, statedb, fmt.Errorf("cannot write state: %w", err) } - if err := blockWriter.WriteChangeSets(); err != nil { - return nil, statedb, fmt.Errorf("cannot write change sets: %w", err) - } - if err := blockWriter.WriteHistory(); err != nil { - return nil, statedb, fmt.Errorf("cannot write history: %w", err) + if csw, ok := stateWriter.(state.WriterWithChangeSets); ok { + if err := csw.WriteChangeSets(); err != nil { + return nil, statedb, fmt.Errorf("cannot write change sets: %w", err) + } + if err := csw.WriteHistory(); err != nil { + return nil, statedb, fmt.Errorf("cannot write history: %w", err) + } } return block, statedb, nil } - -func (g *Genesis) MustWrite(tx kv.RwTx, tmpDir string, history bool) (*types.Block, *state.IntraBlockState) { - b, s, err := g.Write(tx, tmpDir) +func MustCommitGenesis(g *types.Genesis, db kv.RwDB, tmpDir string) *types.Block { + tx, err := db.BeginRw(context.Background()) if err != nil { panic(err) } - return b, s + defer tx.Rollback() + block, _, err := write(tx, g, tmpDir) + if err != nil { + panic(err) + } + err = tx.Commit() + if err != nil { + panic(err) + } + return block } // Write writes the block and state of a genesis specification to the database. // The block is committed as the canonical head block. -func (g *Genesis) Write(tx kv.RwTx, tmpDir string) (*types.Block, *state.IntraBlockState, error) { - block, statedb, err2 := g.WriteGenesisState(tx, tmpDir) +func write(tx kv.RwTx, g *types.Genesis, tmpDir string) (*types.Block, *state.IntraBlockState, error) { + block, statedb, err2 := WriteGenesisState(g, tx, tmpDir) if err2 != nil { return block, statedb, err2 } @@ -551,26 +293,10 @@ func (g *Genesis) Write(tx kv.RwTx, tmpDir string) (*types.Block, *state.IntraBl return block, statedb, rawdb.WriteTotalBurnt(tx, 0, libcommon.Big0) } -// MustCommit writes the genesis block and state to db, panicking on error. -// The block is committed as the canonical head block. -func (g *Genesis) MustCommit(db kv.RwDB, tmpDir string) *types.Block { - tx, err := db.BeginRw(context.Background()) - if err != nil { - panic(err) - } - defer tx.Rollback() - block, _ := g.MustWrite(tx, tmpDir, true) - err = tx.Commit() - if err != nil { - panic(err) - } - return block -} - // GenesisBlockForTesting creates and writes a block in which addr has the given wei balance. func GenesisBlockForTesting(db kv.RwDB, addr libcommon.Address, balance *big.Int, tmpDir string) *types.Block { - g := Genesis{Alloc: GenesisAlloc{addr: {Balance: balance}}, Config: params.TestChainConfig} - block := g.MustCommit(db, tmpDir) + g := types.Genesis{Alloc: types.GenesisAlloc{addr: {Balance: balance}}, Config: params.TestChainConfig} + block := MustCommitGenesis(&g, db, tmpDir) return block } @@ -580,19 +306,19 @@ type GenAccount struct { } func GenesisWithAccounts(db kv.RwDB, accs []GenAccount, tmpDir string) *types.Block { - g := Genesis{Config: params.TestChainConfig} - allocs := make(map[libcommon.Address]GenesisAccount) + g := types.Genesis{Config: params.TestChainConfig} + allocs := make(map[libcommon.Address]types.GenesisAccount) for _, acc := range accs { - allocs[acc.Addr] = GenesisAccount{Balance: acc.Balance} + allocs[acc.Addr] = types.GenesisAccount{Balance: acc.Balance} } g.Alloc = allocs - block := g.MustCommit(db, tmpDir) + block := MustCommitGenesis(&g, db, tmpDir) return block } -// DefaultGenesisBlock returns the Ethereum main net genesis block. -func DefaultGenesisBlock() *Genesis { - return &Genesis{ +// MainnetGenesisBlock returns the Ethereum main net genesis block. +func MainnetGenesisBlock() *types.Genesis { + return &types.Genesis{ Config: params.MainnetChainConfig, Nonce: 66, ExtraData: hexutil.MustDecode("0x11bbe8db4e347b4e8c937c1c8370e4b5ed33adb3db69cbdb7a38e1e50b1b82fa"), @@ -602,9 +328,9 @@ func DefaultGenesisBlock() *Genesis { } } -// DefaultSepoliaGenesisBlock returns the Sepolia network genesis block. -func DefaultSepoliaGenesisBlock() *Genesis { - return &Genesis{ +// SepoliaGenesisBlock returns the Sepolia network genesis block. +func SepoliaGenesisBlock() *types.Genesis { + return &types.Genesis{ Config: params.SepoliaChainConfig, Nonce: 0, ExtraData: []byte("Sepolia, Athens, Attica, Greece!"), @@ -615,9 +341,9 @@ func DefaultSepoliaGenesisBlock() *Genesis { } } -// DefaultRinkebyGenesisBlock returns the Rinkeby network genesis block. -func DefaultRinkebyGenesisBlock() *Genesis { - return &Genesis{ +// RinkebyGenesisBlock returns the Rinkeby network genesis block. +func RinkebyGenesisBlock() *types.Genesis { + return &types.Genesis{ Config: params.RinkebyChainConfig, Timestamp: 1492009146, ExtraData: hexutil.MustDecode("0x52657370656374206d7920617574686f7269746168207e452e436172746d616e42eb768f2244c8811c63729a21a3569731535f067ffc57839b00206d1ad20c69a1981b489f772031b279182d99e65703f0076e4812653aab85fca0f00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"), @@ -627,9 +353,9 @@ func DefaultRinkebyGenesisBlock() *Genesis { } } -// DefaultGoerliGenesisBlock returns the Görli network genesis block. -func DefaultGoerliGenesisBlock() *Genesis { - return &Genesis{ +// GoerliGenesisBlock returns the Görli network genesis block. +func GoerliGenesisBlock() *types.Genesis { + return &types.Genesis{ Config: params.GoerliChainConfig, Timestamp: 1548854791, ExtraData: hexutil.MustDecode("0x22466c6578692069732061207468696e6722202d204166726900000000000000e0a2bd4258d2768837baa26a28fe71dc079f84c70000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"), @@ -639,22 +365,8 @@ func DefaultGoerliGenesisBlock() *Genesis { } } -func DefaultSokolGenesisBlock() *Genesis { - /* - header rlp: f9020da00000000000000000000000000000000000000000000000000000000000000000a01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347940000000000000000000000000000000000000000a0fad4af258fd11939fae0c6c6eec9d340b1caac0b0196fd9a1bc3f489c5bf00b3a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421b9010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000830200008083663be080808080b8410000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 - */ - return &Genesis{ - Config: params.SokolChainConfig, - Timestamp: 0x0, - AuRaSeal: common.FromHex("0x0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"), - GasLimit: 0x663BE0, - Difficulty: big.NewInt(0x20000), - Alloc: readPrealloc("allocs/sokol.json"), - } -} - -func DefaultBSCGenesisBlock() *Genesis { - return &Genesis{ +func BSCGenesisBlock() *types.Genesis { + return &types.Genesis{ Config: params.BSCChainConfig, Nonce: 0x00, Timestamp: 0x5e9da7ce, @@ -669,8 +381,8 @@ func DefaultBSCGenesisBlock() *Genesis { } } -func DefaultChapelGenesisBlock() *Genesis { - return &Genesis{ +func ChapelGenesisBlock() *types.Genesis { + return &types.Genesis{ Config: params.ChapelChainConfig, Nonce: 0x00, Timestamp: 0x5e9da7ce, @@ -685,8 +397,8 @@ func DefaultChapelGenesisBlock() *Genesis { } } -func DefaultRialtoGenesisBlock() *Genesis { - return &Genesis{ +func RialtoGenesisBlock() *types.Genesis { + return &types.Genesis{ Config: params.RialtoChainConfig, Nonce: 0x00, Timestamp: 0x5e9da7ce, @@ -701,8 +413,8 @@ func DefaultRialtoGenesisBlock() *Genesis { } } -func DefaultMumbaiGenesisBlock() *Genesis { - return &Genesis{ +func MumbaiGenesisBlock() *types.Genesis { + return &types.Genesis{ Config: params.MumbaiChainConfig, Nonce: 0, Timestamp: 1558348305, @@ -714,9 +426,9 @@ func DefaultMumbaiGenesisBlock() *Genesis { } } -// DefaultBorMainnet returns the Bor Mainnet network gensis block. -func DefaultBorMainnetGenesisBlock() *Genesis { - return &Genesis{ +// BorMainnetGenesisBlock returns the Bor Mainnet network genesis block. +func BorMainnetGenesisBlock() *types.Genesis { + return &types.Genesis{ Config: params.BorMainnetChainConfig, Nonce: 0, Timestamp: 1590824836, @@ -728,8 +440,8 @@ func DefaultBorMainnetGenesisBlock() *Genesis { } } -func DefaultBorDevnetGenesisBlock() *Genesis { - return &Genesis{ +func BorDevnetGenesisBlock() *types.Genesis { + return &types.Genesis{ Config: params.BorDevnetChainConfig, Nonce: 0, Timestamp: 1558348305, @@ -741,8 +453,8 @@ func DefaultBorDevnetGenesisBlock() *Genesis { } } -func DefaultGnosisGenesisBlock() *Genesis { - return &Genesis{ +func GnosisGenesisBlock() *types.Genesis { + return &types.Genesis{ Config: params.GnosisChainConfig, Timestamp: 0, AuRaSeal: common.FromHex("0x0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"), @@ -752,8 +464,8 @@ func DefaultGnosisGenesisBlock() *Genesis { } } -func DefaultChiadoGenesisBlock() *Genesis { - return &Genesis{ +func ChiadoGenesisBlock() *types.Genesis { + return &types.Genesis{ Config: params.ChiadoChainConfig, Timestamp: 0, AuRaSeal: common.FromHex("0x0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"), @@ -771,13 +483,13 @@ var DevnetSignPrivateKey, _ = crypto.HexToECDSA("26e86e45f6fc45ec6e2ecd128cec80f var DevnetEtherbase = libcommon.HexToAddress("67b1d87101671b127f5f8714789c7192f7ad340e") // DeveloperGenesisBlock returns the 'geth --dev' genesis block. -func DeveloperGenesisBlock(period uint64, faucet libcommon.Address) *Genesis { +func DeveloperGenesisBlock(period uint64, faucet libcommon.Address) *types.Genesis { // Override the default period to the user requested one config := *params.AllCliqueProtocolChanges config.Clique.Period = period // Assemble and return the genesis with the precompiles and faucet pre-funded - return &Genesis{ + return &types.Genesis{ Config: &config, ExtraData: append(append(make([]byte, 32), faucet[:]...), make([]byte, crypto.SignatureLength)...), GasLimit: 11500000, @@ -786,14 +498,149 @@ func DeveloperGenesisBlock(period uint64, faucet libcommon.Address) *Genesis { } } -func readPrealloc(filename string) GenesisAlloc { +var genesisTmpDB kv.RwDB +var genesisDBLock sync.Mutex + +// ToBlock creates the genesis block and writes state of a genesis specification +// to the given database (or discards it if nil). +func GenesisToBlock(g *types.Genesis, tmpDir string) (*types.Block, *state.IntraBlockState, error) { + _ = g.Alloc //nil-check + + head := &types.Header{ + Number: new(big.Int).SetUint64(g.Number), + Nonce: types.EncodeNonce(g.Nonce), + Time: g.Timestamp, + ParentHash: g.ParentHash, + Extra: g.ExtraData, + GasLimit: g.GasLimit, + GasUsed: g.GasUsed, + Difficulty: g.Difficulty, + MixDigest: g.Mixhash, + Coinbase: g.Coinbase, + BaseFee: g.BaseFee, + ExcessDataGas: g.ExcessDataGas, + AuRaStep: g.AuRaStep, + AuRaSeal: g.AuRaSeal, + } + if g.GasLimit == 0 { + head.GasLimit = params.GenesisGasLimit + } + if g.Difficulty == nil { + head.Difficulty = params.GenesisDifficulty + } + if g.Config != nil && (g.Config.IsLondon(0)) { + if g.BaseFee != nil { + head.BaseFee = g.BaseFee + } else { + head.BaseFee = new(big.Int).SetUint64(params.InitialBaseFee) + } + } + + var withdrawals []*types.Withdrawal + if g.Config != nil && (g.Config.IsShanghai(g.Timestamp)) { + withdrawals = []*types.Withdrawal{} + } + + var root libcommon.Hash + var statedb *state.IntraBlockState + wg := sync.WaitGroup{} + wg.Add(1) + var err error + go func() { // we may run inside write tx, can't open 2nd write tx in same goroutine + // TODO(yperbasis): use memdb.MemoryMutation instead + defer wg.Done() + genesisDBLock.Lock() + defer genesisDBLock.Unlock() + if genesisTmpDB == nil { + genesisTmpDB = mdbx.NewMDBX(log.New()).InMem(tmpDir).MapSize(2 * datasize.GB).MustOpen() + } + var tx kv.RwTx + if tx, err = genesisTmpDB.BeginRw(context.Background()); err != nil { + return + } + defer tx.Rollback() + r, w := state.NewDbStateReader(tx), state.NewDbStateWriter(tx, 0) + statedb = state.New(r) + + hasConstructorAllocation := false + for _, account := range g.Alloc { + if len(account.Constructor) > 0 { + hasConstructorAllocation = true + break + } + } + // See https://github.com/NethermindEth/nethermind/blob/master/src/Nethermind/Nethermind.Consensus.AuRa/InitializationSteps/LoadGenesisBlockAuRa.cs + if hasConstructorAllocation && g.Config.Aura != nil { + statedb.CreateAccount(libcommon.Address{}, false) + } + + keys := sortedAllocKeys(g.Alloc) + for _, key := range keys { + addr := libcommon.BytesToAddress([]byte(key)) + account := g.Alloc[addr] + + balance, overflow := uint256.FromBig(account.Balance) + if overflow { + panic("overflow at genesis allocs") + } + statedb.AddBalance(addr, balance) + statedb.SetCode(addr, account.Code) + statedb.SetNonce(addr, account.Nonce) + for key, value := range account.Storage { + key := key + val := uint256.NewInt(0).SetBytes(value.Bytes()) + statedb.SetState(addr, &key, *val) + } + + if len(account.Constructor) > 0 { + if _, err = SysCreate(addr, account.Constructor, *g.Config, statedb, head, g.ExcessDataGas); err != nil { + return + } + } + + if len(account.Code) > 0 || len(account.Storage) > 0 || len(account.Constructor) > 0 { + statedb.SetIncarnation(addr, state.FirstContractIncarnation) + } + } + if err = statedb.FinalizeTx(&chain.Rules{}, w); err != nil { + return + } + if root, err = trie.CalcRoot("genesis", tx); err != nil { + return + } + }() + wg.Wait() + if err != nil { + return nil, nil, err + } + + head.Root = root + + return types.NewBlock(head, nil, nil, nil, withdrawals), statedb, nil +} + +func sortedAllocKeys(m types.GenesisAlloc) []string { + keys := make([]string, len(m)) + i := 0 + for k := range m { + keys[i] = string(k.Bytes()) + i++ + } + slices.Sort(keys) + return keys +} + +//go:embed allocs +var allocs embed.FS + +func readPrealloc(filename string) types.GenesisAlloc { f, err := allocs.Open(filename) if err != nil { panic(fmt.Sprintf("Could not open genesis preallocation for %s: %v", filename, err)) } defer f.Close() decoder := json.NewDecoder(f) - ga := make(GenesisAlloc) + ga := make(types.GenesisAlloc) err = decoder.Decode(&ga) if err != nil { panic(fmt.Sprintf("Could not parse genesis preallocation for %s: %v", filename, err)) @@ -801,34 +648,32 @@ func readPrealloc(filename string) GenesisAlloc { return ga } -func DefaultGenesisBlockByChainName(chain string) *Genesis { +func GenesisBlockByChainName(chain string) *types.Genesis { switch chain { case networkname.MainnetChainName: - return DefaultGenesisBlock() + return MainnetGenesisBlock() case networkname.SepoliaChainName: - return DefaultSepoliaGenesisBlock() + return SepoliaGenesisBlock() case networkname.RinkebyChainName: - return DefaultRinkebyGenesisBlock() + return RinkebyGenesisBlock() case networkname.GoerliChainName: - return DefaultGoerliGenesisBlock() - case networkname.SokolChainName: - return DefaultSokolGenesisBlock() + return GoerliGenesisBlock() case networkname.BSCChainName: - return DefaultBSCGenesisBlock() + return BSCGenesisBlock() case networkname.ChapelChainName: - return DefaultChapelGenesisBlock() + return ChapelGenesisBlock() case networkname.RialtoChainName: - return DefaultRialtoGenesisBlock() + return RialtoGenesisBlock() case networkname.MumbaiChainName: - return DefaultMumbaiGenesisBlock() + return MumbaiGenesisBlock() case networkname.BorMainnetChainName: - return DefaultBorMainnetGenesisBlock() + return BorMainnetGenesisBlock() case networkname.BorDevnetChainName: - return DefaultBorDevnetGenesisBlock() + return BorDevnetGenesisBlock() case networkname.GnosisChainName: - return DefaultGnosisGenesisBlock() + return GnosisGenesisBlock() case networkname.ChiadoChainName: - return DefaultChiadoGenesisBlock() + return ChiadoGenesisBlock() default: return nil } diff --git a/core/genesis_test.go b/core/genesis_test.go index 2bfb531674c..bd714cd82f4 100644 --- a/core/genesis_test.go +++ b/core/genesis_test.go @@ -19,13 +19,12 @@ import ( "github.com/ledgerwatch/erigon/core/types" "github.com/ledgerwatch/erigon/params" "github.com/ledgerwatch/erigon/params/networkname" - "github.com/ledgerwatch/erigon/rlp" ) -func TestDefaultGenesisBlockHashes(t *testing.T) { +func TestGenesisBlockHashes(t *testing.T) { db := memdb.NewTestDB(t) check := func(network string) { - genesis := core.DefaultGenesisBlockByChainName(network) + genesis := core.GenesisBlockByChainName(network) tx, err := db.BeginRw(context.Background()) if err != nil { t.Fatal(err) @@ -42,25 +41,16 @@ func TestDefaultGenesisBlockHashes(t *testing.T) { } } -func TestDefaultGenesisBlockRoots(t *testing.T) { +func TestGenesisBlockRoots(t *testing.T) { require := require.New(t) var err error - block, _, _ := core.DefaultGenesisBlock().ToBlock("") + block, _, _ := core.GenesisToBlock(core.MainnetGenesisBlock(), "") if block.Hash() != params.MainnetGenesisHash { t.Errorf("wrong mainnet genesis hash, got %v, want %v", block.Hash(), params.MainnetGenesisHash) } - block, _, err = core.DefaultSokolGenesisBlock().ToBlock("") - require.NoError(err) - if block.Root() != params.SokolGenesisStateRoot { - t.Errorf("wrong Sokol genesis state root, got %v, want %v", block.Root(), params.SokolGenesisStateRoot) - } - if block.Hash() != params.SokolGenesisHash { - t.Errorf("wrong Sokol genesis hash, got %v, want %v", block.Hash(), params.SokolGenesisHash) - } - - block, _, err = core.DefaultGnosisGenesisBlock().ToBlock("") + block, _, err = core.GenesisToBlock(core.GnosisGenesisBlock(), "") require.NoError(err) if block.Root() != params.GnosisGenesisStateRoot { t.Errorf("wrong Gnosis Chain genesis state root, got %v, want %v", block.Root(), params.GnosisGenesisStateRoot) @@ -69,7 +59,7 @@ func TestDefaultGenesisBlockRoots(t *testing.T) { t.Errorf("wrong Gnosis Chain genesis hash, got %v, want %v", block.Hash(), params.GnosisGenesisHash) } - block, _, err = core.DefaultChiadoGenesisBlock().ToBlock("") + block, _, err = core.GenesisToBlock(core.ChiadoGenesisBlock(), "") require.NoError(err) if block.Root() != params.ChiadoGenesisStateRoot { t.Errorf("wrong Chiado genesis state root, got %v, want %v", block.Root(), params.ChiadoGenesisStateRoot) @@ -81,7 +71,7 @@ func TestDefaultGenesisBlockRoots(t *testing.T) { func TestCommitGenesisIdempotency(t *testing.T) { _, tx := memdb.NewTestTx(t) - genesis := core.DefaultGenesisBlockByChainName(networkname.MainnetChainName) + genesis := core.GenesisBlockByChainName(networkname.MainnetChainName) _, _, err := core.WriteGenesisBlock(tx, genesis, nil, "") require.NoError(t, err) seq, err := tx.ReadSequence(kv.EthTx) @@ -95,55 +85,6 @@ func TestCommitGenesisIdempotency(t *testing.T) { require.Equal(t, uint64(2), seq) } -func TestSokolHeaderRLP(t *testing.T) { - require := require.New(t) - { //sokol - expect := common.FromHex("f9020da00000000000000000000000000000000000000000000000000000000000000000a01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347940000000000000000000000000000000000000000a0fad4af258fd11939fae0c6c6eec9d340b1caac0b0196fd9a1bc3f489c5bf00b3a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421b9010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000830200008083663be080808080b8410000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000") - block, _, err := core.DefaultSokolGenesisBlock().ToBlock("") - require.NoError(err) - b, err := rlp.EncodeToBytes(block.Header()) - require.NoError(err) - require.Equal(expect, b) - h := &types.Header{} - err = rlp.DecodeBytes(expect, h) - require.NoError(err) - - expectSeal := common.FromHex("0x0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000") - require.Equal(uint64(0), h.AuRaStep) - require.Equal(expectSeal, h.AuRaSeal) - - enc, err := rlp.EncodeToBytes(h) - require.NoError(err) - require.Equal(expect, enc) - } - - { // sokol, more seals - h := &types.Header{} - enc := common.FromHex("f9020da00000000000000000000000000000000000000000000000000000000000000000a01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347940000000000000000000000000000000000000000a0fad4af258fd11939fae0c6c6eec9d340b1caac0b0196fd9a1bc3f489c5bf00b3a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421b9010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000830200008083663be080808002b8410000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001") - err := rlp.DecodeBytes(enc, h) - require.NoError(err) - require.Equal(uint64(2), h.AuRaStep) - - expectSeal := common.FromHex("0x0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001") - require.Equal(expectSeal, h.AuRaSeal) - - res, err := rlp.EncodeToBytes(h) // after encode getting source bytes - require.NoError(err) - require.Equal(enc, res) - } - - { // ethash - expect := common.FromHex("f901f9a0d405da4e66f1445d455195229624e133f5baafe72b5cf7b3c36c12c8146e98b7a01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347948888f1f195afa192cfee860698584c030f4c9db1a05fb2b4bfdef7b314451cb138a534d225c922fc0e5fbe25e451142732c3e25c25a088d2ec6b9860aae1a2c3b299f72b6a5d70d7f7ba4722c78f2c49ba96273c2158a007c6fdfa8eea7e86b81f5b0fc0f78f90cc19f4aa60d323151e0cac660199e9a1b90100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008302008003832fefba82524d84568e932a80a0a0349d8c3df71f1a48a9df7d03fd5f14aeee7d91332c009ecaff0a71ead405bd88ab4e252a7e8c2a23") - h := &types.Header{} - err := rlp.DecodeBytes(expect, h) - require.NoError(err) - - res, err := rlp.EncodeToBytes(h) // after encode getting source bytes - require.NoError(err) - require.Equal(expect, res) - } -} - func TestAllocConstructor(t *testing.T) { require := require.New(t) assert := assert.New(t) @@ -154,9 +95,9 @@ func TestAllocConstructor(t *testing.T) { funds := big.NewInt(1000000000) address := libcommon.HexToAddress("0x1000000000000000000000000000000000000001") - genSpec := &core.Genesis{ + genSpec := &types.Genesis{ Config: params.AllProtocolChanges, - Alloc: core.GenesisAlloc{ + Alloc: types.GenesisAlloc{ address: {Constructor: deploymentCode, Balance: funds}, }, } diff --git a/core/state/database_test.go b/core/state/database_test.go index e498b97fecf..086955691eb 100644 --- a/core/state/database_test.go +++ b/core/state/database_test.go @@ -31,11 +31,9 @@ import ( "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" - "github.com/ledgerwatch/erigon/turbo/stages" - "github.com/ledgerwatch/erigon/turbo/trie" - "github.com/ledgerwatch/erigon/accounts/abi/bind" "github.com/ledgerwatch/erigon/accounts/abi/bind/backends" + "github.com/ledgerwatch/erigon/common" "github.com/ledgerwatch/erigon/core" "github.com/ledgerwatch/erigon/core/rawdb" @@ -45,6 +43,8 @@ import ( "github.com/ledgerwatch/erigon/core/types/accounts" "github.com/ledgerwatch/erigon/crypto" "github.com/ledgerwatch/erigon/params" + "github.com/ledgerwatch/erigon/turbo/stages" + "github.com/ledgerwatch/erigon/turbo/trie" ) // Create revival problem diff --git a/core/state/dump.go b/core/state/dump.go index 6eaaa5fc9b0..d2ccec5c174 100644 --- a/core/state/dump.go +++ b/core/state/dump.go @@ -22,14 +22,14 @@ import ( "fmt" libcommon "github.com/ledgerwatch/erigon-lib/common" + "github.com/ledgerwatch/erigon-lib/common/hexutility" "github.com/ledgerwatch/erigon-lib/kv" "github.com/ledgerwatch/erigon-lib/kv/order" "github.com/ledgerwatch/erigon-lib/kv/rawdbv3" - "github.com/ledgerwatch/erigon/core/state/temporal" "github.com/ledgerwatch/erigon/common" "github.com/ledgerwatch/erigon/common/dbutils" - "github.com/ledgerwatch/erigon/common/hexutil" + "github.com/ledgerwatch/erigon/core/state/temporal" "github.com/ledgerwatch/erigon/core/types/accounts" "github.com/ledgerwatch/erigon/crypto" "github.com/ledgerwatch/erigon/turbo/trie" @@ -46,12 +46,12 @@ type Dumper struct { type DumpAccount struct { Balance string `json:"balance"` Nonce uint64 `json:"nonce"` - Root hexutil.Bytes `json:"root"` - CodeHash hexutil.Bytes `json:"codeHash"` - Code hexutil.Bytes `json:"code,omitempty"` + Root hexutility.Bytes `json:"root"` + CodeHash hexutility.Bytes `json:"codeHash"` + Code hexutility.Bytes `json:"code,omitempty"` Storage map[string]string `json:"storage,omitempty"` Address *libcommon.Address `json:"address,omitempty"` // Address only present in iterative (line-by-line) mode - SecureKey *hexutil.Bytes `json:"key,omitempty"` // If we don't have address, we can output the key + SecureKey *hexutility.Bytes `json:"key,omitempty"` // If we don't have address, we can output the key } // Dump represents the full dump in a collected format, as one large map. @@ -190,8 +190,8 @@ func (d *Dumper) DumpToCollector(c DumpCollector, excludeCode, excludeStorage bo account := DumpAccount{ Balance: acc.Balance.ToBig().String(), Nonce: acc.Nonce, - Root: hexutil.Bytes(emptyHash[:]), // We cannot provide historical storage hash - CodeHash: hexutil.Bytes(emptyCodeHash[:]), + Root: hexutility.Bytes(emptyHash[:]), // We cannot provide historical storage hash + CodeHash: hexutility.Bytes(emptyCodeHash[:]), Storage: make(map[string]string), } accountList = append(accountList, &account) @@ -219,8 +219,8 @@ func (d *Dumper) DumpToCollector(c DumpCollector, excludeCode, excludeStorage bo account := DumpAccount{ Balance: acc.Balance.ToBig().String(), Nonce: acc.Nonce, - Root: hexutil.Bytes(emptyHash[:]), // We cannot provide historical storage hash - CodeHash: hexutil.Bytes(emptyCodeHash[:]), + Root: hexutility.Bytes(emptyHash[:]), // We cannot provide historical storage hash + CodeHash: hexutility.Bytes(emptyCodeHash[:]), Storage: make(map[string]string), } accountList = append(accountList, &account) diff --git a/core/state/rw_v3.go b/core/state/rw_v3.go index e81aac9718f..b89fa3bba8f 100644 --- a/core/state/rw_v3.go +++ b/core/state/rw_v3.go @@ -2,7 +2,6 @@ package state import ( "bytes" - "container/heap" "context" "encoding/binary" "encoding/hex" @@ -11,6 +10,7 @@ import ( "time" "unsafe" + "github.com/VictoriaMetrics/metrics" "github.com/holiman/uint256" "github.com/ledgerwatch/erigon-lib/common" "github.com/ledgerwatch/erigon-lib/common/dbg" @@ -24,130 +24,227 @@ import ( "github.com/ledgerwatch/erigon/turbo/shards" "github.com/ledgerwatch/log/v3" btree2 "github.com/tidwall/btree" - atomic2 "go.uber.org/atomic" ) const CodeSizeTable = "CodeSize" +const StorageTable = "Storage" + +var ExecTxsDone = metrics.NewCounter(`exec_txs_done`) type StateV3 struct { - lock sync.RWMutex - receiveWork *sync.Cond + lock sync.RWMutex + sizeEstimate int + chCode map[string][]byte + chAccs map[string][]byte + chStorage *btree2.Map[string, []byte] + chIncs map[string][]byte + chContractCode map[string][]byte + triggers map[uint64]*exec22.TxTask senderTxNums map[common.Address]uint64 triggerLock sync.Mutex - queue exec22.TxTaskQueue - queueLock sync.Mutex - changes map[string]*btree2.Map[string, []byte] - sizeEstimate int - txsDone *atomic2.Uint64 - finished atomic2.Bool + + tmpdir string + applyPrevAccountBuf []byte // buffer for ApplyState. Doesn't need mutex because Apply is single-threaded + addrIncBuf []byte // buffer for ApplyState. Doesn't need mutex because Apply is single-threaded } -func NewStateV3() *StateV3 { +func NewStateV3(tmpdir string) *StateV3 { rs := &StateV3{ - triggers: map[uint64]*exec22.TxTask{}, - senderTxNums: map[common.Address]uint64{}, - changes: map[string]*btree2.Map[string, []byte]{ - kv.PlainState: btree2.NewMap[string, []byte](128), - kv.Code: btree2.NewMap[string, []byte](128), - kv.IncarnationMap: btree2.NewMap[string, []byte](128), - kv.PlainContractCode: btree2.NewMap[string, []byte](128), - }, - txsDone: atomic2.NewUint64(0), - } - rs.receiveWork = sync.NewCond(&rs.queueLock) + tmpdir: tmpdir, + triggers: map[uint64]*exec22.TxTask{}, + senderTxNums: map[common.Address]uint64{}, + chCode: map[string][]byte{}, + chAccs: map[string][]byte{}, + chStorage: btree2.NewMap[string, []byte](128), + chIncs: map[string][]byte{}, + chContractCode: map[string][]byte{}, + + applyPrevAccountBuf: make([]byte, 256), + addrIncBuf: make([]byte, 20+8), + } return rs } func (rs *StateV3) put(table string, key, val []byte) { - old, ok := rs.changes[table].Set(string(key), val) - if ok { - rs.sizeEstimate += len(val) - len(old) - } else { - rs.sizeEstimate += len(key) + len(val) - } + rs.puts(table, string(key), val) } func (rs *StateV3) puts(table string, key string, val []byte) { - old, ok := rs.changes[table].Set(key, val) - if ok { - rs.sizeEstimate += len(val) - len(old) - } else { - rs.sizeEstimate += len(key) + len(val) + switch table { + case StorageTable: + if old, ok := rs.chStorage.Set(key, val); ok { + rs.sizeEstimate += len(val) - len(old) + } else { + rs.sizeEstimate += len(key) + len(val) + } + case kv.PlainState: + if old, ok := rs.chAccs[key]; ok { + rs.sizeEstimate += len(val) - len(old) + } else { + rs.sizeEstimate += len(key) + len(val) + } + rs.chAccs[key] = val + case kv.Code: + if old, ok := rs.chCode[key]; ok { + rs.sizeEstimate += len(val) - len(old) + } else { + rs.sizeEstimate += len(key) + len(val) + } + rs.chCode[key] = val + case kv.IncarnationMap: + if old, ok := rs.chIncs[key]; ok { + rs.sizeEstimate += len(val) - len(old) + } else { + rs.sizeEstimate += len(key) + len(val) + } + rs.chIncs[key] = val + case kv.PlainContractCode: + if old, ok := rs.chContractCode[key]; ok { + rs.sizeEstimate += len(val) - len(old) + } else { + rs.sizeEstimate += len(key) + len(val) + } + rs.chContractCode[key] = val + default: + panic(table) } } -func (rs *StateV3) Get(table string, key []byte) []byte { +func (rs *StateV3) Get(table string, key []byte) (v []byte, ok bool) { rs.lock.RLock() - v := rs.get(table, key) + v, ok = rs.get(table, key) rs.lock.RUnlock() - return v + return v, ok +} + +func (rs *StateV3) get(table string, key []byte) (v []byte, ok bool) { + keyS := *(*string)(unsafe.Pointer(&key)) + switch table { + case StorageTable: + v, ok = rs.chStorage.Get(keyS) + case kv.PlainState: + v, ok = rs.chAccs[keyS] + case kv.Code: + v, ok = rs.chCode[keyS] + case kv.IncarnationMap: + v, ok = rs.chIncs[keyS] + case kv.PlainContractCode: + v, ok = rs.chContractCode[keyS] + default: + panic(table) + } + return v, ok +} + +func (rs *StateV3) flushMap(ctx context.Context, rwTx kv.RwTx, table string, m map[string][]byte, logPrefix string, logEvery *time.Ticker) error { + collector := etl.NewCollector(logPrefix, "", etl.NewSortableBuffer(etl.BufferOptimalSize)) + defer collector.Close() + + var count int + total := len(m) + for k, v := range m { + if err := collector.Collect([]byte(k), v); err != nil { + return err + } + count++ + select { + default: + case <-logEvery.C: + progress := fmt.Sprintf("%.1fM/%.1fM", float64(count)/1_000_000, float64(total)/1_000_000) + log.Info("Write to db", "progress", progress, "current table", table) + rwTx.CollectMetrics() + } + } + if err := collector.Load(rwTx, table, etl.IdentityLoadFunc, etl.TransformArgs{Quit: ctx.Done()}); err != nil { + return err + } + return nil } +func (rs *StateV3) flushBtree(ctx context.Context, rwTx kv.RwTx, table string, m *btree2.Map[string, []byte], logPrefix string, logEvery *time.Ticker) error { + c, err := rwTx.RwCursor(table) + if err != nil { + return err + } + defer c.Close() + iter := m.Iter() + for ok := iter.First(); ok; ok = iter.Next() { + if len(iter.Value()) == 0 { + if err = c.Delete([]byte(iter.Key())); err != nil { + return err + } + } else { + if err = c.Put([]byte(iter.Key()), iter.Value()); err != nil { + return err + } + } -func (rs *StateV3) get(table string, key []byte) (v []byte) { - v, _ = rs.changes[table].Get(*(*string)(unsafe.Pointer(&key))) - return v + select { + case <-logEvery.C: + log.Info(fmt.Sprintf("[%s] Flush", logPrefix), "table", table, "current_prefix", hex.EncodeToString([]byte(iter.Key())[:4])) + case <-ctx.Done(): + return ctx.Err() + default: + } + } + return nil } func (rs *StateV3) Flush(ctx context.Context, rwTx kv.RwTx, logPrefix string, logEvery *time.Ticker) error { rs.lock.Lock() defer rs.lock.Unlock() - for table, t := range rs.changes { - c, err := rwTx.RwCursor(table) - if err != nil { - return err - } - - iter := t.Iter() - for ok := iter.First(); ok; ok = iter.Next() { - if len(iter.Value()) == 0 { - if err = c.Delete([]byte(iter.Key())); err != nil { - return err - } - //fmt.Printf("Flush [%x]=>\n", item.key) - } else { - if err = c.Put([]byte(iter.Key()), iter.Value()); err != nil { - return err - } - //fmt.Printf("Flush [%x]=>[%x]\n", item.key, item.val) - } - select { - case <-logEvery.C: - log.Info(fmt.Sprintf("[%s] Flush", logPrefix), "table", table, "current_prefix", hex.EncodeToString([]byte(iter.Key())[:4])) - case <-ctx.Done(): - return ctx.Err() - default: - } - } - if err != nil { - return err - } - t.Clear() + if err := rs.flushMap(ctx, rwTx, kv.PlainState, rs.chAccs, logPrefix, logEvery); err != nil { + return err + } + rs.chAccs = map[string][]byte{} + if err := rs.flushBtree(ctx, rwTx, kv.PlainState, rs.chStorage, logPrefix, logEvery); err != nil { + return err } + rs.chStorage.Clear() + if err := rs.flushMap(ctx, rwTx, kv.Code, rs.chCode, logPrefix, logEvery); err != nil { + return err + } + rs.chCode = map[string][]byte{} + if err := rs.flushMap(ctx, rwTx, kv.PlainContractCode, rs.chContractCode, logPrefix, logEvery); err != nil { + return err + } + rs.chContractCode = map[string][]byte{} + if err := rs.flushMap(ctx, rwTx, kv.IncarnationMap, rs.chIncs, logPrefix, logEvery); err != nil { + return err + } + rs.chIncs = map[string][]byte{} + rs.sizeEstimate = 0 return nil } -func (rs *StateV3) QueueLen() int { - rs.queueLock.Lock() - defer rs.queueLock.Unlock() - return rs.queue.Len() +func (rs *StateV3) ReTry(txTask *exec22.TxTask, in *exec22.QueueWithRetry) { + rs.resetTxTask(txTask) + in.ReTry(txTask) } +func (rs *StateV3) AddWork(ctx context.Context, txTask *exec22.TxTask, in *exec22.QueueWithRetry) { + rs.resetTxTask(txTask) + in.Add(ctx, txTask) +} +func (rs *StateV3) resetTxTask(txTask *exec22.TxTask) { + txTask.BalanceIncreaseSet = nil + returnReadList(txTask.ReadLists) + txTask.ReadLists = nil + returnWriteList(txTask.WriteLists) + txTask.WriteLists = nil + txTask.Logs = nil + txTask.TraceFroms = nil + txTask.TraceTos = nil -func (rs *StateV3) Schedule() (*exec22.TxTask, bool) { - rs.queueLock.Lock() - defer rs.queueLock.Unlock() - for !rs.finished.Load() && rs.queue.Len() == 0 { - rs.receiveWork.Wait() - } - if rs.finished.Load() { - return nil, false - } - if rs.queue.Len() > 0 { - return heap.Pop(&rs.queue).(*exec22.TxTask), true - } - return nil, false + /* + txTask.ReadLists = nil + txTask.WriteLists = nil + txTask.AccountPrevs = nil + txTask.AccountDels = nil + txTask.StoragePrevs = nil + txTask.CodePrevs = nil + */ } func (rs *StateV3) RegisterSender(txTask *exec22.TxTask) bool { @@ -172,15 +269,13 @@ func (rs *StateV3) RegisterSender(txTask *exec22.TxTask) bool { return !deferral } -func (rs *StateV3) CommitTxNum(sender *common.Address, txNum uint64) uint64 { - rs.txsDone.Add(1) +func (rs *StateV3) CommitTxNum(sender *common.Address, txNum uint64, in *exec22.QueueWithRetry) (count int) { + ExecTxsDone.Inc() rs.triggerLock.Lock() defer rs.triggerLock.Unlock() - count := uint64(0) if triggered, ok := rs.triggers[txNum]; ok { - rs.queuePush(triggered) - rs.receiveWork.Signal() + in.ReTry(triggered) count++ delete(rs.triggers, txNum) } @@ -193,44 +288,7 @@ func (rs *StateV3) CommitTxNum(sender *common.Address, txNum uint64) uint64 { return count } -func (rs *StateV3) queuePush(t *exec22.TxTask) int { - rs.queueLock.Lock() - heap.Push(&rs.queue, t) - l := len(rs.queue) - rs.queueLock.Unlock() - return l -} - -func (rs *StateV3) AddWork(txTask *exec22.TxTask) (queueLen int) { - txTask.BalanceIncreaseSet = nil - returnReadList(txTask.ReadLists) - txTask.ReadLists = nil - returnWriteList(txTask.WriteLists) - txTask.WriteLists = nil - txTask.ResultsSize = 0 - txTask.Logs = nil - txTask.TraceFroms = nil - txTask.TraceTos = nil - - /* - txTask.ReadLists = nil - txTask.WriteLists = nil - txTask.AccountPrevs = nil - txTask.AccountDels = nil - txTask.StoragePrevs = nil - txTask.CodePrevs = nil - */ - queueLen = rs.queuePush(txTask) - rs.receiveWork.Signal() - return queueLen -} - -func (rs *StateV3) Finish() { - rs.finished.Store(true) - rs.receiveWork.Broadcast() -} - -func (rs *StateV3) appplyState1(roTx kv.Tx, txTask *exec22.TxTask, agg *libstate.AggregatorV3) error { +func (rs *StateV3) writeStateHistory(roTx kv.Tx, txTask *exec22.TxTask, agg *libstate.AggregatorV3) error { rs.lock.RLock() defer rs.lock.RUnlock() @@ -240,20 +298,20 @@ func (rs *StateV3) appplyState1(roTx kv.Tx, txTask *exec22.TxTask, agg *libstate return err } defer cursor.Close() - addr1 := make([]byte, 20+8) - psChanges := rs.changes[kv.PlainState] + addr1 := rs.addrIncBuf for addrS, original := range txTask.AccountDels { addr := []byte(addrS) copy(addr1, addr) binary.BigEndian.PutUint64(addr1[len(addr):], original.Incarnation) - prev := accounts.SerialiseV3(original) + prev := rs.applyPrevAccountBuf[:accounts.SerialiseV3Len(original)] + accounts.SerialiseV3To(original, prev) if err := agg.AddAccountPrev(addr, prev); err != nil { return err } codeHashBytes := original.CodeHash.Bytes() - codePrev := rs.get(kv.Code, codeHashBytes) - if codePrev == nil { + codePrev, ok := rs.get(kv.Code, codeHashBytes) + if !ok || codePrev == nil { var err error codePrev, err = roTx.GetOne(kv.Code, codeHashBytes) if err != nil { @@ -273,28 +331,26 @@ func (rs *StateV3) appplyState1(roTx kv.Tx, txTask *exec22.TxTask, agg *libstate if !bytes.HasPrefix(k, addr1) { k = nil } - if psChanges != nil { - //TODO: try full-scan, then can replace btree by map - iter := psChanges.Iter() - for ok := iter.Seek(string(addr1)); ok; ok = iter.Next() { - key := []byte(iter.Key()) - if !bytes.HasPrefix(key, addr1) { - break - } - for ; e == nil && k != nil && bytes.HasPrefix(k, addr1) && bytes.Compare(k, key) <= 0; k, v, e = cursor.Next() { - if !bytes.Equal(k, key) { - // Skip the cursor item when the key is equal, i.e. prefer the item from the changes tree - if e = agg.AddStoragePrev(addr, k[28:], v); e != nil { - return e - } + //TODO: try full-scan, then can replace btree by map + iter := rs.chStorage.Iter() + for ok := iter.Seek(string(addr1)); ok; ok = iter.Next() { + key := []byte(iter.Key()) + if !bytes.HasPrefix(key, addr1) { + break + } + for ; e == nil && k != nil && bytes.HasPrefix(k, addr1) && bytes.Compare(k, key) <= 0; k, v, e = cursor.Next() { + if !bytes.Equal(k, key) { + // Skip the cursor item when the key is equal, i.e. prefer the item from the changes tree + if e = agg.AddStoragePrev(addr, k[28:], v); e != nil { + return e } } - if e != nil { - return e - } - if e = agg.AddStoragePrev(addr, key[28:], iter.Value()); e != nil { - break - } + } + if e != nil { + return e + } + if e = agg.AddStoragePrev(addr, key[28:], iter.Value()); e != nil { + break } } for ; e == nil && k != nil && bytes.HasPrefix(k, addr1); k, v, e = cursor.Next() { @@ -308,14 +364,14 @@ func (rs *StateV3) appplyState1(roTx kv.Tx, txTask *exec22.TxTask, agg *libstate } } - k := make([]byte, 20+8) + k := rs.addrIncBuf for addrS, incarnation := range txTask.CodePrevs { addr := []byte(addrS) copy(k, addr) binary.BigEndian.PutUint64(k[20:], incarnation) - codeHash := rs.get(kv.PlainContractCode, k) - if codeHash == nil { + codeHash, ok := rs.get(kv.PlainContractCode, k) + if !ok || codeHash == nil { var err error codeHash, err = roTx.GetOne(kv.PlainContractCode, k) if err != nil { @@ -324,8 +380,8 @@ func (rs *StateV3) appplyState1(roTx kv.Tx, txTask *exec22.TxTask, agg *libstate } var codePrev []byte if codeHash != nil { - codePrev = rs.get(kv.Code, codeHash) - if codePrev == nil { + codePrev, ok = rs.get(kv.Code, codeHash) + if !ok || codePrev == nil { var err error codePrev, err = roTx.GetOne(kv.Code, codeHash) if err != nil { @@ -340,7 +396,7 @@ func (rs *StateV3) appplyState1(roTx kv.Tx, txTask *exec22.TxTask, agg *libstate return nil } -func (rs *StateV3) appplyState(roTx kv.Tx, txTask *exec22.TxTask, agg *libstate.AggregatorV3) error { +func (rs *StateV3) applyState(roTx kv.Tx, txTask *exec22.TxTask, agg *libstate.AggregatorV3) error { emptyRemoval := txTask.Rules.IsSpuriousDragon rs.lock.Lock() defer rs.lock.Unlock() @@ -348,8 +404,8 @@ func (rs *StateV3) appplyState(roTx kv.Tx, txTask *exec22.TxTask, agg *libstate. for addr, increase := range txTask.BalanceIncreaseSet { increase := increase addrBytes := addr.Bytes() - enc0 := rs.get(kv.PlainState, addrBytes) - if enc0 == nil { + enc0, ok := rs.get(kv.PlainState, addrBytes) + if !ok { var err error enc0, err = roTx.GetOne(kv.PlainState, addrBytes) if err != nil { @@ -367,7 +423,7 @@ func (rs *StateV3) appplyState(roTx kv.Tx, txTask *exec22.TxTask, agg *libstate. a.Balance.Add(&a.Balance, &increase) var enc1 []byte if emptyRemoval && a.Nonce == 0 && a.Balance.IsZero() && a.IsEmptyCodeHash() { - enc1 = []byte{} + enc1 = nil } else { enc1 = make([]byte, a.EncodingLengthForStorage()) a.EncodeForStorage(enc1) @@ -392,10 +448,10 @@ func (rs *StateV3) ApplyState(roTx kv.Tx, txTask *exec22.TxTask, agg *libstate.A defer agg.BatchHistoryWriteStart().BatchHistoryWriteEnd() agg.SetTxNum(txTask.TxNum) - if err := rs.appplyState1(roTx, txTask, agg); err != nil { + if err := rs.writeStateHistory(roTx, txTask, agg); err != nil { return err } - if err := rs.appplyState(roTx, txTask, agg); err != nil { + if err := rs.applyState(roTx, txTask, agg); err != nil { return err } @@ -545,39 +601,59 @@ func (rs *StateV3) Unwind(ctx context.Context, tx kv.RwTx, txUnwindTo uint64, ag return nil } -func (rs *StateV3) DoneCount() uint64 { return rs.txsDone.Load() } +func (rs *StateV3) DoneCount() uint64 { return ExecTxsDone.Get() } -func (rs *StateV3) SizeEstimate() uint64 { +func (rs *StateV3) SizeEstimate() (r uint64) { rs.lock.RLock() - r := rs.sizeEstimate + r = uint64(rs.sizeEstimate) rs.lock.RUnlock() - return uint64(r) + return r * 2 // multiply 2 here, to cover data-structures overhead. more precise accounting - expensive. } func (rs *StateV3) ReadsValid(readLists map[string]*exec22.KvList) bool { - var t *btree2.Map[string, []byte] - rs.lock.RLock() defer rs.lock.RUnlock() - //fmt.Printf("ValidReads\n") for table, list := range readLists { - //fmt.Printf("Table %s\n", table) - var ok bool - if table == CodeSizeTable { - t, ok = rs.changes[kv.Code] - } else { - t, ok = rs.changes[table] + switch table { + case kv.PlainState: + if !rs.readsValidMap(table, list, rs.chAccs) { + return false + } + case CodeSizeTable: + if !rs.readsValidMap(table, list, rs.chCode) { + return false + } + case StorageTable: + if !rs.readsValidBtree(table, list, rs.chStorage) { + return false + } + case kv.Code: + if !rs.readsValidMap(table, list, rs.chCode) { + return false + } + case kv.IncarnationMap: + if !rs.readsValidMap(table, list, rs.chIncs) { + return false + } } - if !ok { - continue + } + return true +} + +func (rs *StateV3) readsValidMap(table string, list *exec22.KvList, m map[string][]byte) bool { + switch table { + case CodeSizeTable: + for i, key := range list.Keys { + if val, ok := m[key]; ok { + if binary.BigEndian.Uint64(list.Vals[i]) != uint64(len(val)) { + return false + } + } } + default: for i, key := range list.Keys { - if val, ok := t.Get(key); ok { - if table == CodeSizeTable { - if binary.BigEndian.Uint64(list.Vals[i]) != uint64(len(val)) { - return false - } - } else if !bytes.Equal(list.Vals[i], val) { + if val, ok := m[key]; ok { + if !bytes.Equal(list.Vals[i], val) { return false } } @@ -586,6 +662,17 @@ func (rs *StateV3) ReadsValid(readLists map[string]*exec22.KvList) bool { return true } +func (rs *StateV3) readsValidBtree(table string, list *exec22.KvList, m *btree2.Map[string, []byte]) bool { + for i, key := range list.Keys { + if val, ok := m.Get(key); ok { + if !bytes.Equal(list.Vals[i], val) { + return false + } + } + } + return true +} + type StateWriterV3 struct { rs *StateV3 txNum uint64 @@ -661,7 +748,7 @@ func (w *StateWriterV3) UpdateAccountCode(address common.Address, incarnation ui func (w *StateWriterV3) DeleteAccount(address common.Address, original *accounts.Account) error { addressBytes := address.Bytes() w.writeLists[kv.PlainState].Keys = append(w.writeLists[kv.PlainState].Keys, string(addressBytes)) - w.writeLists[kv.PlainState].Vals = append(w.writeLists[kv.PlainState].Vals, []byte{}) + w.writeLists[kv.PlainState].Vals = append(w.writeLists[kv.PlainState].Vals, nil) if original.Incarnation > 0 { var b [8]byte binary.BigEndian.PutUint64(b[:], original.Incarnation) @@ -683,8 +770,8 @@ func (w *StateWriterV3) WriteAccountStorage(address common.Address, incarnation } composite := dbutils.PlainGenerateCompositeStorageKey(address[:], incarnation, key.Bytes()) cmpositeS := string(composite) - w.writeLists[kv.PlainState].Keys = append(w.writeLists[kv.PlainState].Keys, cmpositeS) - w.writeLists[kv.PlainState].Vals = append(w.writeLists[kv.PlainState].Vals, value.Bytes()) + w.writeLists[StorageTable].Keys = append(w.writeLists[StorageTable].Keys, cmpositeS) + w.writeLists[StorageTable].Vals = append(w.writeLists[StorageTable].Vals, value.Bytes()) //fmt.Printf("storage [%x] [%x] => [%x], txNum: %d\n", address, *key, v, w.txNum) if w.storagePrevs == nil { w.storagePrevs = map[string][]byte{} @@ -724,8 +811,8 @@ func (r *StateReaderV3) ResetReadSet() { r.readLists = newR func (r *StateReaderV3) ReadAccountData(address common.Address) (*accounts.Account, error) { addr := address.Bytes() - enc := r.rs.Get(kv.PlainState, addr) - if enc == nil { + enc, ok := r.rs.Get(kv.PlainState, addr) + if !ok { var err error enc, err = r.tx.GetOne(kv.PlainState, addr) if err != nil { @@ -752,8 +839,8 @@ func (r *StateReaderV3) ReadAccountData(address common.Address) (*accounts.Accou func (r *StateReaderV3) ReadAccountStorage(address common.Address, incarnation uint64, key *common.Hash) ([]byte, error) { composite := dbutils.PlainGenerateCompositeStorageKey(address.Bytes(), incarnation, key.Bytes()) - enc := r.rs.Get(kv.PlainState, composite) - if enc == nil { + enc, ok := r.rs.Get(StorageTable, composite) + if !ok || enc == nil { var err error enc, err = r.tx.GetOne(kv.PlainState, composite) if err != nil { @@ -761,8 +848,8 @@ func (r *StateReaderV3) ReadAccountStorage(address common.Address, incarnation u } } if !r.discardReadList { - r.readLists[kv.PlainState].Keys = append(r.readLists[kv.PlainState].Keys, string(composite)) - r.readLists[kv.PlainState].Vals = append(r.readLists[kv.PlainState].Vals, enc) + r.readLists[StorageTable].Keys = append(r.readLists[StorageTable].Keys, string(composite)) + r.readLists[StorageTable].Vals = append(r.readLists[StorageTable].Vals, enc) } if r.trace { if enc == nil { @@ -779,8 +866,8 @@ func (r *StateReaderV3) ReadAccountStorage(address common.Address, incarnation u func (r *StateReaderV3) ReadAccountCode(address common.Address, incarnation uint64, codeHash common.Hash) ([]byte, error) { addr, codeHashBytes := address.Bytes(), codeHash.Bytes() - enc := r.rs.Get(kv.Code, codeHashBytes) - if enc == nil { + enc, ok := r.rs.Get(kv.Code, codeHashBytes) + if !ok || enc == nil { var err error enc, err = r.tx.GetOne(kv.Code, codeHashBytes) if err != nil { @@ -799,8 +886,8 @@ func (r *StateReaderV3) ReadAccountCode(address common.Address, incarnation uint func (r *StateReaderV3) ReadAccountCodeSize(address common.Address, incarnation uint64, codeHash common.Hash) (int, error) { codeHashBytes := codeHash.Bytes() - enc := r.rs.Get(kv.Code, codeHashBytes) - if enc == nil { + enc, ok := r.rs.Get(kv.Code, codeHashBytes) + if !ok || enc == nil { var err error enc, err = r.tx.GetOne(kv.Code, codeHashBytes) if err != nil { @@ -822,8 +909,8 @@ func (r *StateReaderV3) ReadAccountCodeSize(address common.Address, incarnation func (r *StateReaderV3) ReadAccountIncarnation(address common.Address) (uint64, error) { addrBytes := address[:] - enc := r.rs.Get(kv.IncarnationMap, addrBytes) - if enc == nil { + enc, ok := r.rs.Get(kv.IncarnationMap, addrBytes) + if !ok || enc == nil { var err error enc, err = r.tx.GetOne(kv.IncarnationMap, addrBytes) if err != nil { @@ -844,6 +931,7 @@ var writeListPool = sync.Pool{ New: func() any { return map[string]*exec22.KvList{ kv.PlainState: {}, + StorageTable: {}, kv.Code: {}, kv.PlainContractCode: {}, kv.IncarnationMap: {}, @@ -871,6 +959,7 @@ var readListPool = sync.Pool{ kv.PlainState: {}, kv.Code: {}, CodeSizeTable: {}, + StorageTable: {}, kv.IncarnationMap: {}, } }, diff --git a/core/state/temporal/kv_temporal.go b/core/state/temporal/kv_temporal.go index 38cad43c2e5..feb35cc428c 100644 --- a/core/state/temporal/kv_temporal.go +++ b/core/state/temporal/kv_temporal.go @@ -11,9 +11,11 @@ import ( "github.com/ledgerwatch/erigon-lib/kv" "github.com/ledgerwatch/erigon-lib/kv/iter" "github.com/ledgerwatch/erigon-lib/kv/kvcfg" + "github.com/ledgerwatch/erigon-lib/kv/mdbx" "github.com/ledgerwatch/erigon-lib/kv/order" "github.com/ledgerwatch/erigon-lib/kv/rawdbv3" "github.com/ledgerwatch/erigon-lib/state" + "github.com/ledgerwatch/erigon/eth/ethconfig" ) //Variables Naming: @@ -69,12 +71,15 @@ func New(db kv.RwDB, agg *state.AggregatorV3, cb1 tConvertV3toV2, cb2 tRestoreCo return &DB{RwDB: db, agg: agg, convertV3toV2: cb1, restoreCodeHash: cb2, parseInc: cb3, systemContractLookup: systemContractLookup}, nil } +func (db *DB) Agg() *state.AggregatorV3 { return db.agg } +func (db *DB) InternalDB() kv.RwDB { return db.RwDB } + func (db *DB) BeginTemporalRo(ctx context.Context) (kv.TemporalTx, error) { kvTx, err := db.RwDB.BeginRo(ctx) if err != nil { return nil, err } - tx := &Tx{Tx: kvTx, db: db} + tx := &Tx{MdbxTx: kvTx.(*mdbx.MdbxTx), db: db} tx.agg = db.agg.MakeContext() return tx, nil @@ -101,13 +106,65 @@ func (db *DB) View(ctx context.Context, f func(tx kv.Tx) error) error { return f(tx) } +//func (db *DB) BeginTemporalRw(ctx context.Context) (kv.RwTx, error) { +// kvTx, err := db.RwDB.BeginRw(ctx) //nolint:gocritic +// if err != nil { +// return nil, err +// } +// tx := &Tx{MdbxTx: kvTx.(*mdbx.MdbxTx), db: db} +// +// //tx.agg = db.agg.MakeContext() +// return tx, nil +//} +//func (db *DB) BeginRw(ctx context.Context) (kv.RwTx, error) { +// return db.BeginTemporalRw(ctx) +//} +//func (db *DB) Update(ctx context.Context, f func(tx kv.RwTx) error) error { +// tx, err := db.BeginTemporalRw(ctx) +// if err != nil { +// return err +// } +// defer tx.Rollback() +// if err = f(tx); err != nil { +// return err +// } +// return tx.Commit() +//} + +//func (db *DB) BeginTemporalRwNosync(ctx context.Context) (kv.RwTx, error) { +// kvTx, err := db.RwDB.BeginRwNosync(ctx) //nolint:gocritic +// if err != nil { +// return nil, err +// } +// tx := &Tx{MdbxTx: kvTx.(*mdbx.MdbxTx), db: db} +// +// //tx.agg = db.agg.MakeContext() +// return tx, nil +//} +//func (db *DB) BeginRwNosync(ctx context.Context) (kv.RwTx, error) { +// return db.BeginTemporalRwNosync(ctx) //nolint:gocritic +//} +//func (db *DB) UpdateNosync(ctx context.Context, f func(tx kv.RwTx) error) error { +// tx, err := db.BeginTemporalRwNosync(ctx) +// if err != nil { +// return err +// } +// defer tx.Rollback() +// if err = f(tx); err != nil { +// return err +// } +// return tx.Commit() +//} + type Tx struct { - kv.Tx + *mdbx.MdbxTx db *DB agg *state.AggregatorV3Context resourcesToClose []kv.Closer } +func (tx *Tx) AggCtx() *state.AggregatorV3Context { return tx.agg } +func (tx *Tx) Agg() *state.AggregatorV3 { return tx.db.agg } func (tx *Tx) Rollback() { for _, closer := range tx.resourcesToClose { closer.Close() @@ -115,14 +172,14 @@ func (tx *Tx) Rollback() { if tx.agg != nil { tx.agg.Close() } - tx.Tx.Rollback() + tx.MdbxTx.Rollback() } func (tx *Tx) Commit() error { for _, closer := range tx.resourcesToClose { closer.Close() } - return tx.Tx.Commit() + return tx.MdbxTx.Commit() } const ( @@ -148,13 +205,13 @@ const ( TracesToIdx kv.InvertedIdx = "TracesToIdx" ) -func (tx *Tx) DomainRange(name kv.Domain, k1, k2 []byte, asOfTs uint64, asc order.By, limit int) (it iter.KV, err error) { +func (tx *Tx) DomainRange(name kv.Domain, fromKey, toKey []byte, asOfTs uint64, asc order.By, limit int) (it iter.KV, err error) { if asc == order.Desc { panic("not supported yet") } switch name { case AccountsDomain: - histStateIt := tx.agg.AccountHistoricalStateRange(asOfTs, k1, nil, -1, tx) + histStateIt := tx.agg.AccountHistoricalStateRange(asOfTs, fromKey, toKey, limit, tx) // TODO: somehow avoid common.Copy(k) - WalkAsOfIter is not zero-copy // Is histStateIt possible to increase keys lifetime to: 2 .Next() calls?? histStateIt2 := iter.TransformKV(histStateIt, func(k, v []byte) ([]byte, []byte, error) { @@ -175,13 +232,13 @@ func (tx *Tx) DomainRange(name kv.Domain, k1, k2 []byte, asOfTs uint64, asc orde force = &hash } } - v, err = tx.db.restoreCodeHash(tx.Tx, k, v, force) + v, err = tx.db.restoreCodeHash(tx.MdbxTx, k, v, force) if err != nil { return nil, nil, err } return k[:20], v, nil }) - lastestStateIt, err := tx.RangeAscend(kv.PlainState, k1, nil, -1) + lastestStateIt, err := tx.RangeAscend(kv.PlainState, fromKey, toKey, -1) // don't apply limit, because need filter if err != nil { return nil, err } @@ -189,17 +246,14 @@ func (tx *Tx) DomainRange(name kv.Domain, k1, k2 []byte, asOfTs uint64, asc orde latestStateIt2 := iter.FilterKV(lastestStateIt, func(k, v []byte) bool { return len(k) == 20 }) - //TODO: seems UnionKV can't handle "amount" request - return iter.UnionKV(histStateIt2, latestStateIt2), nil + it = iter.UnionKV(histStateIt2, latestStateIt2, limit) case StorageDomain: - toKey, _ := kv.NextSubtree(k1) - fromKey2 := append(common.Copy(k1), k2...) - it := tx.agg.StorageHistoricalStateRange(asOfTs, fromKey2, toKey, limit, tx) - it11 := iter.TransformKV(it, func(k, v []byte) ([]byte, []byte, error) { + storageIt := tx.agg.StorageHistoricalStateRange(asOfTs, fromKey, toKey, limit, tx) + storageIt1 := iter.TransformKV(storageIt, func(k, v []byte) ([]byte, []byte, error) { return k, v, nil }) - accData, err := tx.GetOne(kv.PlainState, k1) + accData, err := tx.GetOne(kv.PlainState, fromKey[:20]) if err != nil { return nil, err } @@ -208,12 +262,12 @@ func (tx *Tx) DomainRange(name kv.Domain, k1, k2 []byte, asOfTs uint64, asc orde return nil, err } startkey := make([]byte, length.Addr+length.Incarnation+length.Hash) - copy(startkey, k1) + copy(startkey, fromKey[:20]) binary.BigEndian.PutUint64(startkey[length.Addr:], inc) - copy(startkey[length.Addr+length.Incarnation:], k2) + copy(startkey[length.Addr+length.Incarnation:], fromKey[20:]) toPrefix := make([]byte, length.Addr+length.Incarnation) - copy(toPrefix, k1) + copy(toPrefix, fromKey[:20]) binary.BigEndian.PutUint64(toPrefix[length.Addr:], inc+1) it2, err := tx.RangeAscend(kv.PlainState, startkey, toPrefix, limit) @@ -223,15 +277,41 @@ func (tx *Tx) DomainRange(name kv.Domain, k1, k2 []byte, asOfTs uint64, asc orde it3 := iter.TransformKV(it2, func(k, v []byte) ([]byte, []byte, error) { return append(append([]byte{}, k[:20]...), k[28:]...), v, nil }) - //TODO: seems MergePairs can't handle "amount" request - return iter.UnionKV(it11, it3), nil + it = iter.UnionKV(storageIt1, it3, limit) case CodeDomain: panic("not implemented yet") default: panic(fmt.Sprintf("unexpected: %s", name)) } + + if closer, ok := it.(kv.Closer); ok { + tx.resourcesToClose = append(tx.resourcesToClose, closer) + } + + return it, nil } -func (tx *Tx) DomainGet(name kv.Domain, key, key2 []byte, ts uint64) (v []byte, ok bool, err error) { +func (tx *Tx) DomainGet(name kv.Domain, key, key2 []byte) (v []byte, ok bool, err error) { + if ethconfig.EnableHistoryV4InTest { + panic("implement me") + } + switch name { + case AccountsDomain: + v, err = tx.GetOne(kv.PlainState, key) + return v, v != nil, err + case StorageDomain: + v, err = tx.GetOne(kv.PlainState, append(common.Copy(key), key2...)) + return v, v != nil, err + case CodeDomain: + v, err = tx.GetOne(kv.Code, key2) + return v, v != nil, err + default: + panic(fmt.Sprintf("unexpected: %s", name)) + } +} +func (tx *Tx) DomainGetAsOf(name kv.Domain, key, key2 []byte, ts uint64) (v []byte, ok bool, err error) { + if ethconfig.EnableHistoryV4InTest { + panic("implement me") + } switch name { case AccountsDomain: v, ok, err = tx.HistoryGet(AccountsHistory, key, ts) @@ -271,7 +351,7 @@ func (tx *Tx) DomainGet(name kv.Domain, key, key2 []byte, ts uint64) (v []byte, func (tx *Tx) HistoryGet(name kv.History, key []byte, ts uint64) (v []byte, ok bool, err error) { switch name { case AccountsHistory: - v, ok, err = tx.agg.ReadAccountDataNoStateWithRecent(key, ts, tx.Tx) + v, ok, err = tx.agg.ReadAccountDataNoStateWithRecent(key, ts, tx.MdbxTx) if err != nil { return nil, false, err } @@ -292,15 +372,15 @@ func (tx *Tx) HistoryGet(name kv.History, key []byte, ts uint64) (v []byte, ok b force = &hash } } - v, err = tx.db.restoreCodeHash(tx.Tx, key, v, force) + v, err = tx.db.restoreCodeHash(tx.MdbxTx, key, v, force) if err != nil { return nil, false, err } return v, true, nil case StorageHistory: - return tx.agg.ReadAccountStorageNoStateWithRecent2(key, ts, tx.Tx) + return tx.agg.ReadAccountStorageNoStateWithRecent2(key, ts, tx.MdbxTx) case CodeHistory: - return tx.agg.ReadAccountCodeNoStateWithRecent(key, ts, tx.Tx) + return tx.agg.ReadAccountCodeNoStateWithRecent(key, ts, tx.MdbxTx) default: panic(fmt.Sprintf("unexpected: %s", name)) } @@ -309,19 +389,19 @@ func (tx *Tx) HistoryGet(name kv.History, key []byte, ts uint64) (v []byte, ok b func (tx *Tx) IndexRange(name kv.InvertedIdx, k []byte, fromTs, toTs int, asc order.By, limit int) (timestamps iter.U64, err error) { switch name { case AccountsHistoryIdx: - timestamps, err = tx.agg.AccountHistoyIdxIterator(k, fromTs, toTs, asc, limit, tx) + timestamps, err = tx.agg.AccountHistoyIdxRange(k, fromTs, toTs, asc, limit, tx) case StorageHistoryIdx: - timestamps, err = tx.agg.StorageHistoyIdxIterator(k, fromTs, toTs, asc, limit, tx) + timestamps, err = tx.agg.StorageHistoyIdxRange(k, fromTs, toTs, asc, limit, tx) case CodeHistoryIdx: - timestamps, err = tx.agg.CodeHistoyIdxIterator(k, fromTs, toTs, asc, limit, tx) + timestamps, err = tx.agg.CodeHistoyIdxRange(k, fromTs, toTs, asc, limit, tx) case LogTopicIdx: - timestamps, err = tx.agg.LogTopicIterator(k, fromTs, toTs, asc, limit, tx) + timestamps, err = tx.agg.LogTopicRange(k, fromTs, toTs, asc, limit, tx) case LogAddrIdx: - timestamps, err = tx.agg.LogAddrIterator(k, fromTs, toTs, asc, limit, tx) + timestamps, err = tx.agg.LogAddrRange(k, fromTs, toTs, asc, limit, tx) case TracesFromIdx: - timestamps, err = tx.agg.TraceFromIterator(k, fromTs, toTs, asc, limit, tx) + timestamps, err = tx.agg.TraceFromRange(k, fromTs, toTs, asc, limit, tx) case TracesToIdx: - timestamps, err = tx.agg.TraceToIterator(k, fromTs, toTs, asc, limit, tx) + timestamps, err = tx.agg.TraceToRange(k, fromTs, toTs, asc, limit, tx) default: return nil, fmt.Errorf("unexpected history name: %s", name) } @@ -343,15 +423,19 @@ func (tx *Tx) HistoryRange(name kv.History, fromTs, toTs int, asc order.By, limi } switch name { case AccountsHistory: - it = tx.agg.AccountHistoryIterateChanged(fromTs, toTs, asc, limit, tx) - return it, nil + it, err = tx.agg.AccountHistoryRange(fromTs, toTs, asc, limit, tx) case StorageHistory: - it = tx.agg.StorageHistoryIterateChanged(fromTs, toTs, asc, limit, tx) - return it, nil + it, err = tx.agg.StorageHistoryRange(fromTs, toTs, asc, limit, tx) case CodeHistory: - it = tx.agg.CodeHistoryIterateChanged(fromTs, toTs, asc, limit, tx) - return it, nil + it, err = tx.agg.CodeHistoryRange(fromTs, toTs, asc, limit, tx) default: return nil, fmt.Errorf("unexpected history name: %s", name) } + if err != nil { + return nil, err + } + if closer, ok := it.(kv.Closer); ok { + tx.resourcesToClose = append(tx.resourcesToClose, closer) + } + return it, err } diff --git a/core/state_processor.go b/core/state_processor.go index 37497315eeb..8faa4e37074 100644 --- a/core/state_processor.go +++ b/core/state_processor.go @@ -17,6 +17,8 @@ package core import ( + "math/big" + "github.com/ledgerwatch/erigon-lib/chain" libcommon "github.com/ledgerwatch/erigon-lib/common" @@ -43,7 +45,7 @@ func applyTransaction(config *chain.Config, engine consensus.EngineReader, gp *G if msg.FeeCap().IsZero() && engine != nil { // Only zero-gas transactions may be service ones syscall := func(contract libcommon.Address, data []byte) ([]byte, error) { - return SysCallContract(contract, data, *config, ibs, header, engine, true /* constCall */) + return SysCallContract(contract, data, *config, ibs, header, engine, true /* constCall */, nil /*excessDataGas*/) } msg.SetIsFree(engine.IsServiceTransaction(msg.From(), syscall)) } @@ -97,14 +99,14 @@ func applyTransaction(config *chain.Config, engine consensus.EngineReader, gp *G // and uses the input parameters for its environment. It returns the receipt // for the transaction, gas used and an error if the transaction failed, // indicating the block was invalid. -func ApplyTransaction(config *chain.Config, blockHashFunc func(n uint64) libcommon.Hash, engine consensus.EngineReader, author *libcommon.Address, gp *GasPool, ibs *state.IntraBlockState, stateWriter state.StateWriter, header *types.Header, tx types.Transaction, usedGas *uint64, cfg vm.Config) (*types.Receipt, []byte, error) { +func ApplyTransaction(config *chain.Config, blockHashFunc func(n uint64) libcommon.Hash, engine consensus.EngineReader, author *libcommon.Address, gp *GasPool, ibs *state.IntraBlockState, stateWriter state.StateWriter, header *types.Header, tx types.Transaction, usedGas *uint64, cfg vm.Config, excessDataGas *big.Int) (*types.Receipt, []byte, error) { // Create a new context to be used in the EVM environment // Add addresses to access list if applicable // about the transaction and calling mechanisms. cfg.SkipAnalysis = SkipAnalysis(config, header.Number.Uint64()) - blockContext := NewEVMBlockContext(header, blockHashFunc, engine, author) + blockContext := NewEVMBlockContext(header, blockHashFunc, engine, author, excessDataGas) vmenv := vm.NewEVM(blockContext, evmtypes.TxContext{}, ibs, config, cfg) return applyTransaction(config, engine, gp, ibs, stateWriter, header, tx, usedGas, vmenv, cfg) diff --git a/core/state_transition.go b/core/state_transition.go index 30c78260df7..35f4e791527 100644 --- a/core/state_transition.go +++ b/core/state_transition.go @@ -20,6 +20,7 @@ import ( "fmt" "github.com/holiman/uint256" + libcommon "github.com/ledgerwatch/erigon-lib/common" "github.com/ledgerwatch/erigon-lib/txpool" types2 "github.com/ledgerwatch/erigon-lib/types" @@ -28,6 +29,7 @@ import ( cmath "github.com/ledgerwatch/erigon/common/math" "github.com/ledgerwatch/erigon/common/u256" "github.com/ledgerwatch/erigon/consensus" + "github.com/ledgerwatch/erigon/consensus/misc" "github.com/ledgerwatch/erigon/core/types" "github.com/ledgerwatch/erigon/core/vm" "github.com/ledgerwatch/erigon/core/vm/evmtypes" @@ -86,12 +88,15 @@ type Message interface { FeeCap() *uint256.Int Tip() *uint256.Int Gas() uint64 + DataGas() uint64 + MaxFeePerDataGas() *uint256.Int Value() *uint256.Int Nonce() uint64 CheckNonce() bool Data() []byte AccessList() types2.AccessList + DataHashes() []libcommon.Hash IsFree() bool } @@ -474,3 +479,7 @@ func (st *StateTransition) refundGas(refundQuotient uint64) { func (st *StateTransition) gasUsed() uint64 { return st.initialGas - st.gas } + +func (st *StateTransition) dataGasUsed() uint64 { + return misc.GetDataGasUsed(len(st.msg.DataHashes())) +} diff --git a/core/systemcontracts/upgrade.go b/core/systemcontracts/upgrade.go index d89533b3052..a464e021b79 100644 --- a/core/systemcontracts/upgrade.go +++ b/core/systemcontracts/upgrade.go @@ -44,6 +44,10 @@ var ( MoranUpgrade = make(map[string]*Upgrade) + PlanckUpgrade = make(map[string]*Upgrade) + + LubanUpgrade = make(map[string]*Upgrade) + CalcuttaUpgrade = make(map[string]*Upgrade) // SystemContractCodeLookup is used to address a flaw in the upgrade logic of the system contracts. Since they are updated directly, without first being self-destructed @@ -463,7 +467,7 @@ func init() { { ContractAddr: RelayerHubContract, CommitUrl: "https://github.com/bnb-chain/bsc-genesis-contract/commit/c184a00160b6a2d884b4d6efebe1358a047e9e57", - Code: "6080604052600436106101d85760003560e01c80637ae2308811610102578063c81b166211610095578063f9a2bbc711610064578063f9a2bbc714610569578063fb7cfdd71461057e578063fc3e590814610593578063fd6a6879146105a8576101d8565b8063c81b166214610515578063dc927faf1461052a578063e1c7392a1461053f578063e79a198f14610554576101d8565b8063a1a11bf5116100d1578063a1a11bf514610407578063a78abc161461041c578063ab51bb9614610431578063ac43175114610446576101d8565b80637ae23088146103b357806395468d26146103c857806396713da9146103dd5780639dc09262146103f2576101d8565b806351e806721161017a57806370fd5bad1161014957806370fd5bad1461035f578063718a8aa81461037457806375d47a0a146103895780637942fd051461039e576101d8565b806351e80672146102c7578063541d5548146102dc5780636a87d780146103235780636e47b4821461034a576101d8565b80633dffc387116101b65780633dffc3871461024657806343756e5c14610271578063493279b1146102865780634bf6c882146102b2576101d8565b80630bee7a67146101dd5780630e2374a51461020b5780631aa3a0081461023c575b600080fd5b3480156101e957600080fd5b506101f26105bd565b6040805163ffffffff9092168252519081900360200190f35b34801561021757600080fd5b506102206105c2565b604080516001600160a01b039092168252519081900360200190f35b6102446105c8565b005b34801561025257600080fd5b5061025b610749565b6040805160ff9092168252519081900360200190f35b34801561027d57600080fd5b5061022061074e565b34801561029257600080fd5b5061029b610754565b6040805161ffff9092168252519081900360200190f35b3480156102be57600080fd5b5061025b61075a565b3480156102d357600080fd5b5061022061075f565b3480156102e857600080fd5b5061030f600480360360208110156102ff57600080fd5b50356001600160a01b0316610765565b604080519115158252519081900360200190f35b34801561032f57600080fd5b50610338610783565b60408051918252519081900360200190f35b34801561035657600080fd5b50610220610789565b34801561036b57600080fd5b5061025b61078f565b34801561038057600080fd5b5061025b610794565b34801561039557600080fd5b50610220610799565b3480156103aa57600080fd5b5061025b61079f565b3480156103bf57600080fd5b506103386107a4565b3480156103d457600080fd5b506103386107b1565b3480156103e957600080fd5b5061025b6107bd565b3480156103fe57600080fd5b506102206107c2565b34801561041357600080fd5b506102206107c8565b34801561042857600080fd5b5061030f6107ce565b34801561043d57600080fd5b506101f26107d7565b34801561045257600080fd5b506102446004803603604081101561046957600080fd5b81019060208101813564010000000081111561048457600080fd5b82018360208201111561049657600080fd5b803590602001918460018302840111640100000000831117156104b857600080fd5b9193909290916020810190356401000000008111156104d657600080fd5b8201836020820111156104e857600080fd5b8035906020019184600183028401116401000000008311171561050a57600080fd5b5090925090506107dc565b34801561052157600080fd5b50610220610bfe565b34801561053657600080fd5b50610220610c04565b34801561054b57600080fd5b50610244610c0a565b34801561056057600080fd5b50610244610c8c565b34801561057557600080fd5b50610220610e45565b34801561058a57600080fd5b50610338610e4b565b34801561059f57600080fd5b5061025b610e51565b3480156105b457600080fd5b50610220610e56565b606481565b61200181565b3360009081526004602052604090205460ff1615610625576040805162461bcd60e51b81526020600482015260156024820152741c995b185e595c88185b1c9958591e48195e1a5cdd605a1b604482015290519081900360640190fd5b60005460ff16610678576040805162461bcd60e51b81526020600482015260196024820152781d1a194818dbdb9d1c9858dd081b9bdd081a5b9a5d081e595d603a1b604482015290519081900360640190fd5b61068133610e5c565b156106bd5760405162461bcd60e51b81526004018080602001828103825260278152602001806110496027913960400191505060405180910390fd5b333214610707576040805162461bcd60e51b81526020600482015260136024820152721b9bc81c1c9bde1e481a5cc8185b1b1bddd959606a1b604482015290519081900360640190fd5b6040805162461bcd60e51b81526020600482015260126024820152711c9959da5cdd195c881cdd5cdc195b99195960721b604482015290519081900360640190fd5b600181565b61100181565b6102ca81565b600881565b61200081565b6001600160a01b031660009081526004602052604090205460ff1690565b60025481565b61100581565b600281565b601081565b61100881565b600b81565b68056bc75e2d6310000081565b67016345785d8a000081565b600981565b61100781565b61100681565b60005460ff1681565b600081565b60005460ff1661082f576040805162461bcd60e51b81526020600482015260196024820152781d1a194818dbdb9d1c9858dd081b9bdd081a5b9a5d081e595d603a1b604482015290519081900360640190fd5b336110071461086f5760405162461bcd60e51b815260040180806020018281038252602e815260200180611070602e913960400191505060405180910390fd5b6108d584848080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152505060408051808201909152600f81526e1c995c5d5a5c995911195c1bdcda5d608a1b60208201529150610e629050565b156109d857602081146109195760405162461bcd60e51b815260040180806020018281038252602281526020018061109e6022913960400191505060405180910390fd5b604080516020601f840181900481028201810190925282815260009161095791858580838501838280828437600092019190915250610f4992505050565b90506001811180156109725750683635c9adc5dea000008111155b801561097f575060025481115b6109d0576040805162461bcd60e51b815260206004820181905260248201527f7468652072657175697265644465706f736974206f7574206f662072616e6765604482015290519081900360640190fd5b600155610b6c565b610a3384848080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250506040805180820190915260048152636475657360e01b60208201529150610e629050565b15610b2f5760208114610a8d576040805162461bcd60e51b815260206004820152601760248201527f6c656e677468206f662064756573206d69736d61746368000000000000000000604482015290519081900360640190fd5b604080516020601f8401819004810282018101909252828152600091610acb91858580838501838280828437600092019190915250610f4992505050565b9050600081118015610ade575060015481105b610b27576040805162461bcd60e51b81526020600482015260156024820152747468652064756573206f7574206f662072616e676560581b604482015290519081900360640190fd5b600255610b6c565b6040805162461bcd60e51b815260206004820152600d60248201526c756e6b6e6f776e20706172616d60981b604482015290519081900360640190fd5b7f6cdb0ac70ab7f2e2d035cca5be60d89906f2dede7648ddbd7402189c1eeed17a848484846040518080602001806020018381038352878782818152602001925080828437600083820152601f01601f191690910184810383528581526020019050858580828437600083820152604051601f909101601f19169092018290039850909650505050505050a150505050565b61100281565b61100381565b60005460ff1615610c62576040805162461bcd60e51b815260206004820152601960248201527f74686520636f6e747261637420616c726561647920696e697400000000000000604482015290519081900360640190fd5b68056bc75e2d63100000600190815567016345785d8a00006002556000805460ff19169091179055565b3360009081526004602052604090205460ff16610ce7576040805162461bcd60e51b81526020600482015260146024820152731c995b185e595c88191bc81b9bdd08195e1a5cdd60621b604482015290519081900360640190fd5b60005460ff16610d3a576040805162461bcd60e51b81526020600482015260196024820152781d1a194818dbdb9d1c9858dd081b9bdd081a5b9a5d081e595d603a1b604482015290519081900360640190fd5b610d4261102e565b5033600081815260036020908152604091829020825180840190935280548084526001909101549183018290529192916108fc91610d86919063ffffffff610f4e16565b6040518115909202916000818181858888f19350505050158015610dae573d6000803e3d6000fd5b50602081015160405161100291829181156108fc0291906000818181858888f19350505050158015610de4573d6000803e3d6000fd5b50336000818152600460209081526040808320805460ff191690556003825280832083815560010192909255815192835290517fd17202129b83db7880d6b9f25df81c58ad46f7e0e2c92236b1aa10663a4876679281900390910190a15050565b61100081565b60015481565b600381565b61100481565b3b151590565b6000816040516020018082805190602001908083835b60208310610e975780518252601f199092019160209182019101610e78565b6001836020036101000a03801982511681845116808217855250505050505090500191505060405160208183030381529060405280519060200120836040516020018082805190602001908083835b60208310610f055780518252601f199092019160209182019101610ee6565b6001836020036101000a0380198251168184511680821785525050505050509050019150506040516020818303038152906040528051906020012014905092915050565b015190565b6000610f9083836040518060400160405280601e81526020017f536166654d6174683a207375627472616374696f6e206f766572666c6f770000815250610f97565b9392505050565b600081848411156110265760405162461bcd60e51b81526004018080602001828103825283818151815260200191508051906020019080838360005b83811015610feb578181015183820152602001610fd3565b50505050905090810190601f1680156110185780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b505050900390565b60405180604001604052806000815260200160008152509056fe636f6e7472616374206973206e6f7420616c6c6f77656420746f20626520612072656c61796572746865206d6573736167652073656e646572206d75737420626520676f7665726e616e636520636f6e74726163746c656e677468206f662072657175697265644465706f736974206d69736d61746368a2646970667358221220e7298bdd332800983f84daa6af4f7dfac92b01db35dc27e899b3d13982f2ccbd64736f6c63430006040033", + Code: "6080604052600436106101d85760003560e01c80637ae2308811610102578063c81b166211610095578063f9a2bbc711610064578063f9a2bbc714610569578063fb7cfdd71461057e578063fc3e590814610593578063fd6a6879146105a8576101d8565b8063c81b166214610515578063dc927faf1461052a578063e1c7392a1461053f578063e79a198f14610554576101d8565b8063a1a11bf5116100d1578063a1a11bf514610407578063a78abc161461041c578063ab51bb9614610431578063ac43175114610446576101d8565b80637ae23088146103b357806395468d26146103c857806396713da9146103dd5780639dc09262146103f2576101d8565b806351e806721161017a57806370fd5bad1161014957806370fd5bad1461035f578063718a8aa81461037457806375d47a0a146103895780637942fd051461039e576101d8565b806351e80672146102c7578063541d5548146102dc5780636a87d780146103235780636e47b4821461034a576101d8565b80633dffc387116101b65780633dffc3871461024657806343756e5c14610271578063493279b1146102865780634bf6c882146102b2576101d8565b80630bee7a67146101dd5780630e2374a51461020b5780631aa3a0081461023c575b600080fd5b3480156101e957600080fd5b506101f26105bd565b6040805163ffffffff9092168252519081900360200190f35b34801561021757600080fd5b506102206105c2565b604080516001600160a01b039092168252519081900360200190f35b6102446105c8565b005b34801561025257600080fd5b5061025b610749565b6040805160ff9092168252519081900360200190f35b34801561027d57600080fd5b5061022061074e565b34801561029257600080fd5b5061029b610754565b6040805161ffff9092168252519081900360200190f35b3480156102be57600080fd5b5061025b61075a565b3480156102d357600080fd5b5061022061075f565b3480156102e857600080fd5b5061030f600480360360208110156102ff57600080fd5b50356001600160a01b0316610765565b604080519115158252519081900360200190f35b34801561032f57600080fd5b50610338610783565b60408051918252519081900360200190f35b34801561035657600080fd5b50610220610789565b34801561036b57600080fd5b5061025b61078f565b34801561038057600080fd5b5061025b610794565b34801561039557600080fd5b50610220610799565b3480156103aa57600080fd5b5061025b61079f565b3480156103bf57600080fd5b506103386107a4565b3480156103d457600080fd5b506103386107b1565b3480156103e957600080fd5b5061025b6107bd565b3480156103fe57600080fd5b506102206107c2565b34801561041357600080fd5b506102206107c8565b34801561042857600080fd5b5061030f6107ce565b34801561043d57600080fd5b506101f26107d7565b34801561045257600080fd5b506102446004803603604081101561046957600080fd5b81019060208101813564010000000081111561048457600080fd5b82018360208201111561049657600080fd5b803590602001918460018302840111640100000000831117156104b857600080fd5b9193909290916020810190356401000000008111156104d657600080fd5b8201836020820111156104e857600080fd5b8035906020019184600183028401116401000000008311171561050a57600080fd5b5090925090506107dc565b34801561052157600080fd5b50610220610bfe565b34801561053657600080fd5b50610220610c04565b34801561054b57600080fd5b50610244610c0a565b34801561056057600080fd5b50610244610c8c565b34801561057557600080fd5b50610220610e45565b34801561058a57600080fd5b50610338610e4b565b34801561059f57600080fd5b5061025b610e51565b3480156105b457600080fd5b50610220610e56565b606481565b61200181565b3360009081526004602052604090205460ff1615610625576040805162461bcd60e51b81526020600482015260156024820152741c995b185e595c88185b1c9958591e48195e1a5cdd605a1b604482015290519081900360640190fd5b60005460ff16610678576040805162461bcd60e51b81526020600482015260196024820152781d1a194818dbdb9d1c9858dd081b9bdd081a5b9a5d081e595d603a1b604482015290519081900360640190fd5b61068133610e5c565b156106bd5760405162461bcd60e51b81526004018080602001828103825260278152602001806110496027913960400191505060405180910390fd5b333214610707576040805162461bcd60e51b81526020600482015260136024820152721b9bc81c1c9bde1e481a5cc8185b1b1bddd959606a1b604482015290519081900360640190fd5b6040805162461bcd60e51b81526020600482015260126024820152711c9959da5cdd195c881cdd5cdc195b99195960721b604482015290519081900360640190fd5b600181565b61100181565b6102ca81565b600881565b61200081565b6001600160a01b031660009081526004602052604090205460ff1690565b60025481565b61100581565b600281565b601081565b61100881565b600b81565b68056bc75e2d6310000081565b67016345785d8a000081565b600981565b61100781565b61100681565b60005460ff1681565b600081565b60005460ff1661082f576040805162461bcd60e51b81526020600482015260196024820152781d1a194818dbdb9d1c9858dd081b9bdd081a5b9a5d081e595d603a1b604482015290519081900360640190fd5b336110071461086f5760405162461bcd60e51b815260040180806020018281038252602e815260200180611070602e913960400191505060405180910390fd5b6108d584848080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152505060408051808201909152600f81526e1c995c5d5a5c995911195c1bdcda5d608a1b60208201529150610e629050565b156109d857602081146109195760405162461bcd60e51b815260040180806020018281038252602281526020018061109e6022913960400191505060405180910390fd5b604080516020601f840181900481028201810190925282815260009161095791858580838501838280828437600092019190915250610f4992505050565b9f0506001811180156109725750683635c9adc5dea000008111155b801561097f575060025481115b6109d0576040805162461bcd60e51b815260206004820181905260248201527f7468652072657175697265644465706f736974206f7574206f662072616e6765604482015290519081900360640190fd5b600155610b6c565b610a3384848080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250506040805180820190915260048152636475657360e01b60208201529150610e629050565b15610b2f5760208114610a8d576040805162461bcd60e51b815260206004820152601760248201527f6c656e677468206f662064756573206d69736d61746368000000000000000000604482015290519081900360640190fd5b604080516020601f8401819004810282018101909252828152600091610acb91858580838501838280828437600092019190915250610f4992505050565b9050600081118015610ade575060015481105b610b27576040805162461bcd60e51b81526020600482015260156024820152747468652064756573206f7574206f662072616e676560581b604482015290519081900360640190fd5b600255610b6c565b6040805162461bcd60e51b815260206004820152600d60248201526c756e6b6e6f776e20706172616d60981b604482015290519081900360640190fd5b7f6cdb0ac70ab7f2e2d035cca5be60d89906f2dede7648ddbd7402189c1eeed17a848484846040518080602001806020018381038352878782818152602001925080828437600083820152601f01601f191690910184810383528581526020019050858580828437600083820152604051601f909101601f19169092018290039850909650505050505050a150505050565b61100281565b61100381565b60005460ff1615610c62576040805162461bcd60e51b815260206004820152601960248201527f74686520636f6e747261637420616c726561647920696e697400000000000000604482015290519081900360640190fd5b68056bc75e2d63100000600190815567016345785d8a00006002556000805460ff19169091179055565b3360009081526004602052604090205460ff16610ce7576040805162461bcd60e51b81526020600482015260146024820152731c995b185e595c88191bc81b9bdd08195e1a5cdd60621b604482015290519081900360640190fd5b60005460ff16610d3a576040805162461bcd60e51b81526020600482015260196024820152781d1a194818dbdb9d1c9858dd081b9bdd081a5b9a5d081e595d603a1b604482015290519081900360640190fd5b610d4261102e565b5033600081815260036020908152604091829020825180840190935280548084526001909101549183018290529192916108fc91610d86919063ffffffff610f4e16565b6040518115909202916000818181858888f19350505050158015610dae573d6000803e3d6000fd5b50602081015160405161100291829181156108fc0291906000818181858888f19350505050158015610de4573d6000803e3d6000fd5b50336000818152600460209081526040808320805460ff191690556003825280832083815560010192909255815192835290517fd17202129b83db7880d6b9f25df81c58ad46f7e0e2c92236b1aa10663a4876679281900390910190a15050565b61100081565b60015481565b600381565b61100481565b3b151590565b6000816040516020018082805190602001908083835b60208310610e975780518252601f199092019160209182019101610e78565b6001836020036101000a03801982511681845116808217855250505050505090500191505060405160208183030381529060405280519060200120836040516020018082805190602001908083835b60208310610f055780518252601f199092019160209182019101610ee6565b6001836020036101000a0380198251168184511680821785525050505050509050019150506040516020818303038152906040528051906020012014905092915050565b015190565b6000610f9083836040518060400160405280601e81526020017f536166654d6174683a207375627472616374696f6e206f766572666c6f770000815250610f97565b9392505050565b600081848411156110265760405162461bcd60e51b81526004018080602001828103825283818151815260200191508051906020019080838360005b83811015610feb578181015183820152602001610fd3565b50505050905090810190601f1680156110185780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b505050900390565b60405180604001604052806000815260200160008152509056fe636f6e7472616374206973206e6f7420616c6c6f77656420746f20626520612072656c61796572746865206d6573736167652073656e646572206d75737420626520676f7665726e616e636520636f6e74726163746c656e677468206f662072657175697265644465706f736974206d69736d61746368a2646970667358221220e7298bdd332800983f84daa6af4f7dfac92b01db35dc27e899b3d13982f2ccbd64736f6c63430006040033", }, { ContractAddr: LightClientContract, @@ -478,6 +482,74 @@ func init() { }, } + PlanckUpgrade[networkname.BSCChainName] = &Upgrade{ + UpgradeName: "planck", + Configs: []*UpgradeConfig{ + { + ContractAddr: SlashContract, + CommitUrl: "https://github.com/bnb-chain/bsc-genesis-contract/commit/78e13b1d3a5a1b08c9208af94a9b14fc1efda213", + Code: "608060405234801561001057600080fd5b50600436106102535760003560e01c80637942fd0511610146578063ac431751116100c3578063dc927faf11610087578063dc927faf1461073b578063e1c7392a14610743578063f9a2bbc71461074b578063fc3e590814610753578063fc4333cd1461075b578063fd6a68791461076357610253565b8063ac431751146105cf578063c80d4b8f1461068d578063c81b166214610695578063c8509d811461069d578063c96be4cb1461071557610253565b80639dc092621161010a5780639dc0926214610593578063a1a11bf51461059b578063a78abc16146105a3578063ab51bb96146105bf578063ac0af629146105c757610253565b80637942fd05146104fb5780638256ace614610503578063831d65d11461050b57806396713da9146105835780639bc8e4f21461058b57610253565b80634bf6c882116101d45780636e47b482116101985780636e47b482146104d357806370fd5bad146104db578063718a8aa8146104e357806375d47a0a146104eb5780637912a65d146104f357610253565b80634bf6c8821461048b57806351e8067214610493578063567a372d1461049b5780635bfb4990146104a357806362b72cf5146104cb57610253565b806337c8dab91161021b57806337c8dab9146103ed578063389f4f711461042c5780633dffc3871461044657806343756e5c14610464578063493279b11461046c57610253565b80630bee7a67146102585780630e2374a5146102795780631182b8751461029d57806323bac5a21461038a57806335aa2e44146103d0575b600080fd5b61026061076b565b6040805163ffffffff9092168252519081900360200190f35b610281610770565b604080516001600160a01b039092168252519081900360200190f35b610315600480360360408110156102b357600080fd5b60ff8235169190810190604081016020820135600160201b8111156102d757600080fd5b8201836020820111156102e957600080fd5b803590602001918460018302840111600160201b8311171561030a57600080fd5b509092509050610776565b6040805160208082528351818301528351919283929083019185019080838360005b8381101561034f578181015183820152602001610337565b50505050905090810190601f16801561037c5780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b6103b0600480360360208110156103a057600080fd5b50356001600160a01b031661084a565b604080519384526020840192909252151582820152519081900360600190f35b610281600480360360208110156103e657600080fd5b503561086d565b6104136004803603602081101561040357600080fd5b50356001600160a01b0316610894565b6040805192835260208301919091528051918290030190f35b6104346108eb565b60408051918252519081900360200190f35b61044e6108f1565b6040805160ff9092168252519081900360200190f35b6102816108f6565b6104746108fc565b6040805161ffff9092168252519081900360200190f35b61044e610901565b610281610906565b61043461090c565b6104c9600480360360208110156104b957600080fd5b50356001600160a01b0316610912565b005b610434610a73565b610281610a79565b61044e610a7f565b61044e610a84565b610281610a89565b610434610a8f565b61044e610a94565b610413610a99565b6104c96004803603604081101561052157600080fd5b60ff8235169190810190604081016020820135600160201b81111561054557600080fd5b82018360208201111561055757600080fd5b803590602001918460018302840111600160201b8311171561057857600080fd5b509092509050610aa3565b61044e610bfd565b610434610c02565b610281610c0d565b610281610c13565b6105ab610c19565b604080519115158252519081900360200190f35b610260610c22565b610434610c27565b6104c9600480360360408110156105e557600080fd5b810190602081018135600160201b8111156105ff57600080fd5b82018360208201111561061157600080fd5b803590602001918460018302840111600160201b8311171561063257600080fd5b919390929091602081019035600160201b81111561064f57600080fd5b82018360208201111561066157600080fd5b803590602001918460018302840111600160201b8311171561068257600080fd5b509092509050610c2c565b61043461101a565b61028161101f565b6104c9600480360360408110156106b357600080fd5b60ff8235169190810190604081016020820135600160201b8111156106d757600080fd5b8201836020820111156106e957600080fd5b803590602001918460018302840111600160201b8311171561070a57600080fd5b509092509050611025565b6104c96004803603602081101561072b57600080fd5b50356001600160a01b03166110d8565b610281611659565b6104c961165f565b6102816116d0565b61044e6116d6565b6104c96116db565b610281611b66565b606481565b61200181565b606033612000146107b85760405162461bcd60e51b815260040180806020018281038252602f8152602001806125bd602f913960400191505060405180910390fd5b60005460ff166107fd576040805162461bcd60e51b81526020600482015260196024820152600080516020612619833981519152604482015290519081900360640190fd5b6040805162461bcd60e51b815260206004820152601e60248201527f7265636569766520756e65787065637465642073796e207061636b6167650000604482015290519081900360640190fd5b600260208190526000918252604090912080546001820154919092015460ff1683565b6001818154811061087a57fe5b6000918252602090912001546001600160a01b0316905081565b60008061089f612481565b5050506001600160a01b0316600090815260026020818152604092839020835160608101855281548082526001830154938201849052919093015460ff16151592909301919091529091565b60055481565b600181565b61100181565b603881565b600881565b61200081565b60045481565b33611000146109525760405162461bcd60e51b81526004018080602001828103825260308152602001806125186030913960400191505060405180910390fd5b60005460ff16610997576040805162461bcd60e51b81526020600482015260196024820152600080516020612619833981519152604482015290519081900360640190fd5b61200063f7a251d7600b6109aa84611b6c565b60006040518463ffffffff1660e01b8152600401808460ff1660ff16815260200180602001838152602001828103825284818151815260200191508051906020019080838360005b83811015610a0a5781810151838201526020016109f2565b50505050905090810190601f168015610a375780820380516001836020036101000a031916815260200191505b50945050505050600060405180830381600087803b158015610a5857600080fd5b505af1158015610a6c573d6000803e3d6000fd5b5050505050565b60035481565b61100581565b600281565b601081565b61100881565b603281565b600b81565b6004546005549091565b3361200014610ae35760405162461bcd60e51b815260040180806020018281038252602f8152602001806125bd602f913960400191505060405180910390fd5b60005460ff16610b28576040805162461bcd60e51b81526020600482015260196024820152600080516020612619833981519152604482015290519081900360640190fd5b610b306124a4565b6000610b7184848080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250611c3e92505050565b915091508015610bbb5781516040805163ffffffff9092168252517f7f0956d47419b9525356e7111652b653b530ec6f5096dccc04589bc38e6299679181900360200190a1610a6c565b81516040805163ffffffff9092168252517f7d45f62d17443dd4547bca8a8112c60e2385669318dc300ec61a5d2492f262e79181900360200190a15050505050565b600981565b662386f26fc1000081565b61100781565b61100681565b60005460ff1681565b600081565b600481565b60005460ff16610c71576040805162461bcd60e51b81526020600482015260196024820152600080516020612619833981519152604482015290519081900360640190fd5b3361100714610cb15760405162461bcd60e51b815260040180806020018281038252602e815260200180612548602e913960400191505060405180910390fd5b610d1c84848080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250506040805180820190915260148152731b5a5cd9195b59585b9bdc951a1c995cda1bdb1960621b60208201529150611cbe9050565b15610df55760208114610d605760405162461bcd60e51b81526004018080602001828103825260278152602001806124f16027913960400191505060405180910390fd5b604080516020601f8401819004810282018101909252828152600091610d9e91858580838501838280828437600092019190915250611da692505050565b905060018110158015610db2575060055481105b610ded5760405162461bcd60e51b81526004018080602001828103825260258152602001806125986025913960400191505060405180910390fd5b600455610f88565b610e5b84848080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152505060408051808201909152600f81526e19995b1bdb9e551a1c995cda1bdb19608a1b60208201529150611cbe9050565b15610f4b5760208114610e9f5760405162461bcd60e51b81526004018080602001828103825260228152602001806125766022913960400191505060405180910390fd5b604080516020601f8401819004810282018101909252828152600091610edd91858580838501838280828437600092019190915250611da692505050565b90506103e88111158015610ef2575060045481115b610f43576040805162461bcd60e51b815260206004820181905260248201527f7468652066656c6f6e795468726573686f6c64206f7574206f662072616e6765604482015290519081900360640190fd5b600555610f88565b6040805162461bcd60e51b815260206004820152600d60248201526c756e6b6e6f776e20706172616d60981b604482015290519081900360640190fd5b7f6cdb0ac70ab7f2e2d035cca5be60d89906f2dede7648ddbd7402189c1eeed17a848484846040518080602001806020018381038352878782818152602001925080828437600083820152601f01601f191690910184810383528581526020019050858580828437600083820152604051601f909101601f19169092018290039850909650505050505050a150505050565b609681565b61100281565b33612000146110655760405162461bcd60e51b815260040180806020018281038252602f8152602001806125bd602f913960400191505060405180910390fd5b60005460ff166110aa576040805162461bcd60e51b81526020600482015260196024820152600080516020612619833981519152604482015290519081900360640190fd5b6040517f07db600eebe2ac176be8dcebad61858c245a4961bb32ca2aa3d159b09aa0810e90600090a1505050565b3341146111165760405162461bcd60e51b815260040180806020018281038252602d8152602001806125ec602d913960400191505060405180910390fd5b60005460ff1661115b576040805162461bcd60e51b81526020600482015260196024820152600080516020612619833981519152604482015290519081900360640190fd5b60035443116111b1576040805162461bcd60e51b815260206004820181905260248201527f63616e206e6f7420736c61736820747769636520696e206f6e6520626c6f636b604482015290519081900360640190fd5b3a156111fb576040805162461bcd60e51b81526020600482015260146024820152736761737072696365206973206e6f74207a65726f60601b604482015290519081900360640190fd5b6040805163155853f360e21b81526001600160a01b03831660048201529051611000916355614fcc916024808301926020929190829003018186803b15801561124357600080fd5b505afa158015611257573d6000803e3d6000fd5b505050506040513d602081101561126d57600080fd5b505161127857611652565b611280612481565b506001600160a01b0381166000908152600260208181526040928390208351606081018552815481526001820154928101929092529091015460ff1615801592820192909252906112db576020810180516001019052611334565b60016040820181905260208201819052805480820182556000919091527fb10e2d527612073b26eecdfd717e6a320cf44b4afac2b0732d9fcbe2b7fa0cf60180546001600160a01b0319166001600160a01b0384161790555b43815260055460208201518161134657fe5b0661157657600060208201819052604080516335409f7f60e01b81526001600160a01b03851660048201529051611000926335409f7f926024808201939182900301818387803b15801561139957600080fd5b505af11580156113ad573d6000803e3d6000fd5b505050506120006001600160a01b031663f7a251d7600b6113cd85611b6c565b60006040518463ffffffff1660e01b8152600401808460ff1660ff16815260200180602001838152602001828103825284818151815260200191508051906020019080838360005b8381101561142d578181015183820152602001611415565b50505050905090810190601f16801561145a5780820380516001836020036101000a031916815260200191505b50945050505050600060405180830381600087803b15801561147b57600080fd5b505af192505050801561148c575060015b611571573d8080156114ba576040519150601f19603f3d011682016040523d82523d6000602084013e6114bf565b606091505b50826001600160a01b03167fd7bc86ff5d08c8ab043edec743302aba2520e6635172a428bc956721db9e2d1c8360200151836040518083815260200180602001828103825283818151815260200191508051906020019080838360005b8381101561153457818101518382015260200161151c565b50505050905090810190601f1680156115615780820380516001836020036101000a031916815260200191505b50935050505060405180910390a2505b6115ec565b60045481602001518161158557fe5b066115ec57604080516375abf10160e11b81526001600160a01b038416600482015290516110009163eb57e20291602480830192600092919082900301818387803b1580156115d357600080fd5b505af11580156115e7573d6000803e3d6000fd5b505050505b6001600160a01b0382166000818152600260208181526040808420865181559186015160018301558581015191909201805460ff1916911515919091179055517fddb6012116e51abf5436d956a4f0ebd927e92c576ff96d7918290c8782291e3e9190a2505b5043600355565b61100381565b60005460ff16156116b7576040805162461bcd60e51b815260206004820152601960248201527f74686520636f6e747261637420616c726561647920696e697400000000000000604482015290519081900360640190fd5b603260045560966005556000805460ff19166001179055565b61100081565b600381565b336110001461171b5760405162461bcd60e51b81526004018080602001828103825260308152602001806125186030913960400191505060405180910390fd5b60005460ff16611760576040805162461bcd60e51b81526020600482015260196024820152600080516020612619833981519152604482015290519081900360640190fd5b60015461176c57611b64565b600154600090600019015b808211611b38576000805b8284101561189b57611792612481565b60026000600187815481106117a357fe5b60009182526020808320909101546001600160a01b0316835282810193909352604091820190208151606081018352815481526001820154938101939093526002015460ff1615159082015260055490915060049004816020015111156118855760046005548161181057fe5b0481602001510381602001818152505080600260006001888154811061183257fe5b6000918252602080832091909101546001600160a01b0316835282810193909352604091820190208351815591830151600183015591909101516002909101805460ff191691151591909117905561188f565b600192505061189b565b50600190930192611782565b828411611a32576118aa612481565b60026000600186815481106118bb57fe5b60009182526020808320909101546001600160a01b0316835282810193909352604091820190208151606081018352815481526001820154938101939093526002015460ff1615159082015260055490915060049004816020015111156119a35760046005548161192857fe5b0481602001510381602001818152505080600260006001878154811061194a57fe5b6000918252602080832091909101546001600160a01b03168352828101939093526040918201902083518155918301516001808401919091559201516002909101805460ff19169115159190911790559150611a329050565b60026000600186815481106119b457fe5b60009182526020808320909101546001600160a01b031683528201929092526040018120818155600181810192909255600201805460ff191690558054806119f857fe5b600082815260209020810160001990810180546001600160a01b031916905501905583611a255750611a32565b506000199092019161189b565b818015611a3c5750805b15611b1b576002600060018681548110611a5257fe5b60009182526020808320909101546001600160a01b031683528201929092526040018120818155600181810192909255600201805460ff19169055805484908110611a9957fe5b600091825260209091200154600180546001600160a01b039092169186908110611abf57fe5b9060005260206000200160006101000a8154816001600160a01b0302191690836001600160a01b031602179055506001805480611af857fe5b600082815260209020810160001990810180546001600160a01b03191690550190555b82611b27575050611b38565b505060019091019060001901611777565b6040517fcfdb3b6ccaeccbdc68be3c59c840e3b3c90f0a7c491f5fff1cf56cfda200dd9c90600090a150505b565b61100481565b60408051600480825260a08201909252606091829190816020015b6060815260200190600190039081611b87579050509050611bb0836001600160a01b0316611dab565b81600081518110611bbd57fe5b6020026020010181905250611bd143611dce565b81600181518110611bde57fe5b6020908102919091010152611bf36038611dce565b81600281518110611c0057fe5b6020026020010181905250611c1442611dce565b81600381518110611c2157fe5b6020026020010181905250611c3581611de1565b9150505b919050565b611c466124a4565b6000611c506124a4565b611c586124b6565b611c69611c6486611e6b565b611e90565b90506000805b611c7883611eda565b15611cb15780611ca457611c93611c8e84611efb565b611f49565b63ffffffff16845260019150611ca9565b611cb1565b600101611c6f565b5091935090915050915091565b6000816040516020018082805190602001908083835b60208310611cf35780518252601f199092019160209182019101611cd4565b6001836020036101000a03801982511681845116808217855250505050505090500191505060405160208183030381529060405280519060200120836040516020018082805190602001908083835b60208310611d615780518252601f199092019160209182019101611d42565b6001836020036101000a038019825116818451168082178552505050505050905001915050604051602081830303815290604052805190602001201490505b92915050565b015190565b60408051600560a21b8318601482015260348101909152606090611c3581612000565b6060611da0611ddc83612056565b612000565b6060815160001415611e025750604080516000815260208101909152611c39565b606082600081518110611e1157fe5b602002602001015190506000600190505b8351811015611e5257611e4882858381518110611e3b57fe5b602002602001015161213c565b9150600101611e22565b50611c35611e65825160c060ff166121b9565b8261213c565b611e736124d6565b506040805180820190915281518152602082810190820152919050565b611e986124b6565b611ea1826122b1565b611eaa57600080fd5b6000611eb983602001516122eb565b60208085015160408051808201909152868152920190820152915050919050565b6000611ee46124d6565b505080518051602091820151919092015191011190565b611f036124d6565b611f0c82611eda565b611f1557600080fd5b60208201516000611f258261234e565b80830160209586015260408051808201909152908152938401919091525090919050565b805160009015801590611f5e57508151602110155b611f6757600080fd5b6000611f7683602001516122eb565b90508083600001511015611fd1576040805162461bcd60e51b815260206004820152601a60248201527f6c656e677468206973206c657373207468616e206f6666736574000000000000604482015290519081900360640190fd5b825160208085015183018051928490039291831015611ff757826020036101000a820491505b50949350505050565b6060815160011480156120325750607f60f81b8260008151811061202057fe5b01602001516001600160f81b03191611155b1561203e575080611c39565b611da06120508351608060ff166121b9565b8361213c565b604080516020808252818301909252606091829190602082018180368337505050602081018490529050600067ffffffffffffffff19841661209a575060186120be565b6fffffffffffffffffffffffffffffffff1984166120ba575060106120be565b5060005b60208110156120f4578181815181106120d357fe5b01602001516001600160f81b031916156120ec576120f4565b6001016120be565b60008160200390506060816040519080825280601f01601f191660200182016040528015612129576020820181803683370190505b5080830196909652508452509192915050565b6060806040519050835180825260208201818101602087015b8183101561216d578051835260209283019201612155565b50855184518101855292509050808201602086015b8183101561219a578051835260209283019201612182565b508651929092011591909101601f01601f191660405250905092915050565b6060680100000000000000008310612209576040805162461bcd60e51b815260206004820152600e60248201526d696e70757420746f6f206c6f6e6760901b604482015290519081900360640190fd5b604080516001808252818301909252606091602082018180368337019050509050603784116122635782840160f81b8160008151811061224557fe5b60200101906001600160f81b031916908160001a9053509050611da0565b606061226e85612056565b90508381510160370160f81b8260008151811061228757fe5b60200101906001600160f81b031916908160001a9053506122a8828261213c565b95945050505050565b80516000906122c257506000611c39565b6020820151805160001a9060c08210156122e157600092505050611c39565b5060019392505050565b8051600090811a6080811015612305576000915050611c39565b60b8811080612320575060c08110801590612320575060f881105b1561232f576001915050611c39565b60c08110156123435760b519019050611c39565b60f519019050611c39565b80516000908190811a6080811015612369576001915061247a565b60b881101561237e57607e198101915061247a565b60c08110156123f857600060b78203600186019550806020036101000a8651049150600181018201935050808310156123f2576040805162461bcd60e51b81526020600482015260116024820152706164646974696f6e206f766572666c6f7760781b604482015290519081900360640190fd5b5061247a565b60f881101561240d5760be198101915061247a565b600060f78203600186019550806020036101000a865104915060018101820193505080831015612478576040805162461bcd60e51b81526020600482015260116024820152706164646974696f6e206f766572666c6f7760781b604482015290519081900360640190fd5b505b5092915050565b604051806060016040528060008152602001600081526020016000151581525090565b60408051602081019091526000815290565b60405180604001604052806124c96124d6565b8152602001600081525090565b60405180604001604052806000815260200160008152509056fe6c656e677468206f66206d697364656d65616e6f725468726573686f6c64206d69736d61746368746865206d6573736167652073656e646572206d7573742062652076616c696461746f7253657420636f6e7472616374746865206d6573736167652073656e646572206d75737420626520676f7665726e616e636520636f6e74726163746c656e677468206f662066656c6f6e795468726573686f6c64206d69736d61746368746865206d697364656d65616e6f725468726573686f6c64206f7574206f662072616e6765746865206d6573736167652073656e646572206d7573742062652063726f737320636861696e20636f6e7472616374746865206d6573736167652073656e646572206d7573742062652074686520626c6f636b2070726f647563657274686520636f6e7472616374206e6f7420696e69742079657400000000000000a2646970667358221220638a87b280b96494e110d626ea9527bb15cb9cf42454fbab93839017affa9a8564736f6c63430006040033", + }, + { + ContractAddr: TokenHubContract, + CommitUrl: "https://github.com/bnb-chain/bsc-genesis-contract/commit/78e13b1d3a5a1b08c9208af94a9b14fc1efda213", + Code: "6080604052600436106103c75760003560e01c806396713da9116101f2578063c81b16621161010d578063f0148472116100a0578063fc1a598f1161006f578063fc1a598f14610f25578063fc3e590814610b85578063fd6a687914610f58578063ff9c0027146107fd5761040f565b8063f014847214610ed1578063f9a2bbc714610ee6578063fa9e915914610efb578063fb063e8f14610f105761040f565b8063dc927faf116100dc578063dc927faf14610e5f578063e1c7392a14610e74578063e8f35cea14610e89578063ebf71d5314610ebc5761040f565b8063c81b166214610d8a578063c8509d8114610d9f578063cf41984414610e24578063d9e6dae91461077f5761040f565b8063aa7415f511610185578063b9fd21e311610154578063b9fd21e314610cfa578063ba35ead614610d0f578063bbface1f14610d24578063bd46646114610d575761040f565b8063aa7415f514610b9a578063ab51bb9614610be1578063ac43175114610bf6578063b99328c514610cc15761040f565b8063a1a11bf5116101c1578063a1a11bf514610b46578063a496fba214610b5b578063a78abc1614610b70578063a7c9f02d14610b855761040f565b806396713da914610ace5780639a854bbd14610ae35780639a99b4f014610af85780639dc0926214610b315761040f565b806359b92789116102e257806371d3086311610275578063831d65d111610244578063831d65d1146109d15780638b87b21f146106d45780638eff336c14610a565780639509b98014610a955761040f565b806371d3086314610968578063727be1f81461097d57806375d47a0a146109a75780637942fd05146109bc5761040f565b80636e056520116102b15780636e056520146108125780636e47b4821461093e57806370fd5bad146107fd578063718a8aa8146109535761040f565b806359b92789146107be5780635d499b1b146107e8578063613684751461077f57806366dea52a146107fd5761040f565b80633fd8b02f1161035a5780634a3acdf4116103295780634a3acdf41461076a5780634bf6c8821461077f57806350432d321461079457806351e80672146107a95761040f565b80633fd8b02f146106ff57806343756e5c1461071457806343a368b914610729578063493279b11461073e5761040f565b8063149d14d911610396578063149d14d9146105a85780632ae45483146105cf5780633d713223146106235780633dffc387146106d45761040f565b80630bee7a67146104145780630e2374a5146104425780631182b87514610473578063122345821461056d5761040f565b3661040f57341561040d576040805133815234602082015281517f6c98249d85d88c3753a04a22230f595e4dc8d3dc86c34af35deeeedc861b89db929181900390910190a15b005b600080fd5b34801561042057600080fd5b50610429610f6d565b6040805163ffffffff9092168252519081900360200190f35b34801561044e57600080fd5b50610457610f72565b604080516001600160a01b039092168252519081900360200190f35b34801561047f57600080fd5b506104f86004803603604081101561049657600080fd5b60ff8235169190810190604081016020820135600160201b8111156104ba57600080fd5b8201836020820111156104cc57600080fd5b803590602001918460018302840111600160201b831117156104ed57600080fd5b509092509050610f78565b6040805160208082528351818301528351919283929083019185019080838360005b8381101561053257818101518382015260200161051a565b50505050905090810190601f16801561055f5780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b34801561057957600080fd5b5061040d6004803603604081101561059057600080fd5b506001600160a01b03813581169160200135166110a6565b3480156105b457600080fd5b506105bd6111a0565b60408051918252519081900360200190f35b3480156105db57600080fd5b5061060a600480360360408110156105f257600080fd5b506001600160a01b03813581169160200135166111a6565b6040805192835260208301919091528051918290030190f35b34801561062f57600080fd5b506104576004803603602081101561064657600080fd5b810190602081018135600160201b81111561066057600080fd5b82018360208201111561067257600080fd5b803590602001918460018302840111600160201b8311171561069357600080fd5b91908080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152509295506111ca945050505050565b3480156106e057600080fd5b506106e96111ee565b6040805160ff9092168252519081900360200190f35b34801561070b57600080fd5b506105bd6111f3565b34801561072057600080fd5b506104576111f9565b34801561073557600080fd5b506105bd6111ff565b34801561074a57600080fd5b5061075361120b565b6040805161ffff9092168252519081900360200190f35b34801561077657600080fd5b506105bd611210565b34801561078b57600080fd5b506106e9611216565b3480156107a057600080fd5b506105bd61121b565b3480156107b557600080fd5b50610457611226565b3480156107ca57600080fd5b50610457600480360360208110156107e157600080fd5b503561122c565b3480156107f457600080fd5b506105bd611247565b34801561080957600080fd5b506106e9611250565b61092a6004803603608081101561082857600080fd5b810190602081018135600160201b81111561084257600080fd5b82018360208201111561085457600080fd5b803590602001918460208302840111600160201b8311171561087557600080fd5b919390929091602081019035600160201b81111561089257600080fd5b8201836020820111156108a457600080fd5b803590602001918460208302840111600160201b831117156108c557600080fd5b919390929091602081019035600160201b8111156108e257600080fd5b8201836020820111156108f457600080fd5b803590602001918460208302840111600160201b8311171561091557600080fd5b91935091503567ffffffffffffffff16611255565b604080519115158252519081900360200190f35b34801561094a57600080fd5b5061045761172a565b34801561095f57600080fd5b506106e9611730565b34801561097457600080fd5b506105bd611735565b34801561098957600080fd5b5061092a600480360360208110156109a057600080fd5b503561173b565b3480156109b357600080fd5b506104576117bc565b3480156109c857600080fd5b506106e96117c2565b3480156109dd57600080fd5b5061040d600480360360408110156109f457600080fd5b60ff8235169190810190604081016020820135600160201b811115610a1857600080fd5b820183602082011115610a2a57600080fd5b803590602001918460018302840111600160201b83111715610a4b57600080fd5b5090925090506117c7565b348015610a6257600080fd5b5061040d60048036036060811015610a7957600080fd5b508035906001600160a01b036020820135169060400135611910565b348015610aa157600080fd5b5061040d60048036036040811015610ab857600080fd5b506001600160a01b038135169060200135611996565b348015610ada57600080fd5b506106e9611b53565b348015610aef57600080fd5b506105bd611b58565b348015610b0457600080fd5b506105bd60048036036040811015610b1b57600080fd5b506001600160a01b038135169060200135611b64565b348015610b3d57600080fd5b50610457611ca2565b348015610b5257600080fd5b50610457611ca8565b348015610b6757600080fd5b506106e9611cae565b348015610b7c57600080fd5b5061092a611cb3565b348015610b9157600080fd5b506106e9611cbc565b61092a60048036036080811015610bb057600080fd5b5080356001600160a01b03908116916020810135909116906040810135906060013567ffffffffffffffff16611cc1565b348015610bed57600080fd5b50610429611cae565b348015610c0257600080fd5b5061040d60048036036040811015610c1957600080fd5b810190602081018135600160201b811115610c3357600080fd5b820183602082011115610c4557600080fd5b803590602001918460018302840111600160201b83111715610c6657600080fd5b919390929091602081019035600160201b811115610c8357600080fd5b820183602082011115610c9557600080fd5b803590602001918460018302840111600160201b83111715610cb657600080fd5b509092509050612382565b348015610ccd57600080fd5b5061040d60048036036040811015610ce457600080fd5b50803590602001356001600160a01b031661282a565b348015610d0657600080fd5b506105bd6128a0565b348015610d1b57600080fd5b506105bd6128aa565b348015610d3057600080fd5b506105bd60048036036020811015610d4757600080fd5b50356001600160a01b03166128b0565b348015610d6357600080fd5b506105bd60048036036020811015610d7a57600080fd5b50356001600160a01b03166128c2565b348015610d9657600080fd5b506104576128dd565b348015610dab57600080fd5b5061040d60048036036040811015610dc257600080fd5b60ff8235169190810190604081016020820135600160201b811115610de657600080fd5b820183602082011115610df857600080fd5b803590602001918460018302840111600160201b83111715610e1957600080fd5b5090925090506128e3565b348015610e3057600080fd5b5061040d60048036036040811015610e4757600080fd5b506001600160a01b03813581169160200135166129b3565b348015610e6b57600080fd5b50610457612c87565b348015610e8057600080fd5b5061040d612c8d565b348015610e9557600080fd5b506105bd60048036036020811015610eac57600080fd5b50356001600160a01b0316612d2d565b348015610ec857600080fd5b506106e9612d3f565b348015610edd57600080fd5b506106e9612d44565b348015610ef257600080fd5b50610457612d49565b348015610f0757600080fd5b506105bd612d4f565b348015610f1c57600080fd5b506105bd612d55565b348015610f3157600080fd5b506104f860048036036020811015610f4857600080fd5b50356001600160a01b0316612d63565b348015610f6457600080fd5b50610457612e8a565b606481565b61200181565b60005460609060ff16610fc0576040805162461bcd60e51b81526020600482015260196024820152600080516020615582833981519152604482015290519081900360640190fd5b33612000146110005760405162461bcd60e51b815260040180806020018281038252602f815260200180615530602f913960400191505060405180910390fd5b60ff8416600214156110525761104b83838080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250612e9092505050565b905061109f565b6040805162461bcd60e51b815260206004820152601860248201527f756e7265636f676e697a65642073796e207061636b6167650000000000000000604482015290519081900360640190fd5b9392505050565b33612000146110e65760405162461bcd60e51b815260040180806020018281038252602f815260200180615530602f913960400191505060405180910390fd5b6001600160a01b0380831660009081526007602090815260408083209385168352929052208054611151576040805162461bcd60e51b815260206004820152601060248201526f1b9bc81b1bd8dad95908185b5bdd5b9d60821b604482015290519081900360640190fd5b8054600082556040805182815290516001600160a01b0380861692908716917f152fb15aa5d80f843e1e4bd5f2fc9161714f169945024decec7e84fb910fdd519181900360200190a350505050565b60015490565b60076020908152600092835260408084209091529082529020805460019091015482565b6020818101516000908152600490915260409020546001600160a01b03165b919050565b600181565b60055481565b61100181565b670de0b6b3a764000081565b603881565b61a8c081565b600881565b66071afd498d000081565b61200081565b6000908152600460205260409020546001600160a01b031690565b6402540be40081565b600281565b6000805460ff1661129b576040805162461bcd60e51b81526020600482015260196024820152600080516020615582833981519152604482015290519081900360640190fd5b8685146112d95760405162461bcd60e51b815260040180806020018281038252603b8152602001806154f5603b913960400191505060405180910390fd5b8683146113175760405162461bcd60e51b815260040180806020018281038252603f8152602001806153c8603f913960400191505060405180910390fd5b426078018267ffffffffffffffff1610156113635760405162461bcd60e51b81526004018080602001828103825260248152602001806152b86024913960400191505060405180910390fd5b6402540be4003406156113a75760405162461bcd60e51b81526004018080602001828103825260408152602001806155f86040913960400191505060405180910390fd5b604080518681526020808802820101909152859060009081906060908480156113da578160200160208202803683370190505b50905060005b848110156114b5576402540be4008b8b838181106113fa57fe5b905060200201358161140857fe5b06156114455760405162461bcd60e51b815260040180806020018281038252603c815260200180615407603c913960400191505060405180910390fd5b61146a8b8b8381811061145457fe5b9050602002013585612fb490919063ffffffff16565b93506114966402540be4008c8c8481811061148157fe5b9050602002013561300e90919063ffffffff16565b8282815181106114a257fe5b60209081029190910101526001016113e0565b506001546114da906114cd908663ffffffff61305016565b849063ffffffff612fb416565b3410156115185760405162461bcd60e51b81526004018080602001828103825260568152602001806155a26056913960600191505060405180910390fd5b611528348463ffffffff6130a916565b91506115326150bc565b6040518060c001604052806221272160e91b60001b815260200160006001600160a01b031681526020018381526020018e8e808060200260200160405190810160405280939291908181526020018383602002808284376000920191909152505050908252506040805160208c810282810182019093528c82529283019290918d918d91829185019084908082843760009201919091525050509082525067ffffffffffffffff8916602090910152905061200063f7a251d760036115f6846130eb565b61160b876402540be40063ffffffff61300e16565b6040518463ffffffff1660e01b8152600401808460ff1660ff16815260200180602001838152602001828103825284818151815260200191508051906020019080838360005b83811015611669578181015183820152602001611651565b50505050905090810190601f1680156116965780820380516001836020036101000a031916815260200191505b50945050505050600060405180830381600087803b1580156116b757600080fd5b505af11580156116cb573d6000803e3d6000fd5b505060408051600081523360208201528082018890526060810187905290517f74eab09b0e53aefc23f2e1b16da593f95c2dd49c6f5a23720463d10d9c330b2a9350908190036080019150a15060019c9b505050505050505050505050565b61100581565b601081565b60015481565b6000336120011461177d5760405162461bcd60e51b81526004018080602001828103825260338152602001806151d66033913960400191505060405180910390fd5b81156117b4576040516120019083156108fc029084906000818181858888f193505050501580156117b2573d6000803e3d6000fd5b505b506001919050565b61100881565b600b81565b60005460ff1661180c576040805162461bcd60e51b81526020600482015260196024820152600080516020615582833981519152604482015290519081900360640190fd5b336120001461184c5760405162461bcd60e51b815260040180806020018281038252602f815260200180615530602f913960400191505060405180910390fd5b60ff83166003141561189c5761189782828080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152506133a692505050565b61190b565b7f41ce201247b6ceb957dcdb217d0b8acb50b9ea0e12af9af4f5e7f38902101605838383604051808460ff1660ff168152602001806020018281038252848482818152602001925080828437600083820152604051601f909101601f1916909201829003965090945050505050a15b505050565b33611008146119505760405162461bcd60e51b815260040180806020018281038252602381526020018061555f6023913960400191505060405180910390fd5b600083815260046020908152604080832080546001600160a01b039096166001600160a01b03199096168617905593825260038152838220949094556002909352912055565b81806001600160a01b031663893d20e86040518163ffffffff1660e01b815260040160206040518083038186803b1580156119d057600080fd5b505afa1580156119e4573d6000803e3d6000fd5b505050506040513d60208110156119fa57600080fd5b50516001600160a01b03163314611a58576040805162461bcd60e51b815260206004820152601860248201527f6e6f74206f776e6572206f6620424550323020746f6b656e0000000000000000604482015290519081900360640190fd5b60008211611aa6576040805162461bcd60e51b81526020600482015260166024820152751e995c9bc81b1a5b5a5d081b9bdd08185b1b1bddd95960521b604482015290519081900360640190fd5b6001600160a01b038316600090815260036020526040902054611afc576040805162461bcd60e51b81526020600482015260096024820152681b9bdd08189bdd5b9960ba1b604482015290519081900360640190fd5b6001600160a01b038316600081815260066020908152604091829020859055815185815291513393927f9df3a90730dbf23b5cc18dbbd5f4af3fa94a0dffb6ff6841f98a9a9a6ac626a892908290030190a3505050565b600981565b677ce66c50e284000081565b6000805460ff16611baa576040805162461bcd60e51b81526020600482015260196024820152600080516020615582833981519152604482015290519081900360640190fd5b3361100514611bea5760405162461bcd60e51b815260040180806020018281038252602f815260200180615209602f913960400191505060405180910390fd5b6000478310611bf95747611bfb565b825b9050670de0b6b3a7640000811115611c17576000915050611c9c565b8015611c99576040516001600160a01b0385169082156108fc029083906000818181858888f19350505050158015611c53573d6000803e3d6000fd5b50604080516001600160a01b03861681526020810183905281517ff8b71c64315fc33b2ead2adfa487955065152a8ac33d9d5193aafd7f45dc15a0929181900390910190a15b90505b92915050565b61100781565b61100681565b600081565b60005460ff1681565b600381565b6000805460ff16611d07576040805162461bcd60e51b81526020600482015260196024820152600080516020615582833981519152604482015290519081900360640190fd5b426078018267ffffffffffffffff161015611d535760405162461bcd60e51b81526004018080602001828103825260248152602001806152b86024913960400191505060405180910390fd5b6402540be400340615611d975760405162461bcd60e51b81526004018080602001828103825260408152602001806155f86040913960400191505060405180910390fd5b600080806001600160a01b038816611e7657600154611dbd90879063ffffffff612fb416565b341015611dfb5760405162461bcd60e51b81526004018080602001828103825260618152602001806153426061913960800191505060405180910390fd5b6402540be400860615611e3f5760405162461bcd60e51b815260040180806020018281038252603c815260200180615407603c913960400191505060405180910390fd5b611e4f348763ffffffff6130a916565b9050611e66866402540be40063ffffffff61300e16565b6221272160e91b93509150612119565b6001600160a01b038816600090815260036020526040902054925082611ecd5760405162461bcd60e51b81526004018080602001828103825260318152602001806153116031913960400191505060405180910390fd5b600154341015611f0e5760405162461bcd60e51b815260040180806020018281038252603f815260200180615464603f913960400191505060405180910390fd5b506001600160a01b0387166000908152600260205260409020543490600881111580611f595750600881118015611f595750611f57876007198301600a0a63ffffffff61340216565b155b611f945760405162461bcd60e51b815260040180806020018281038252603c815260200180615407603c913960400191505060405180910390fd5b611f9e8782613444565b9250611fa984613484565b15611ff1576305f5e100831015611ff15760405162461bcd60e51b815260040180806020018281038252603a81526020018061525a603a913960400191505060405180910390fd5b60088110158061200b575060088110801561200b57508683115b6120465760405162461bcd60e51b81526004018080602001828103825260258152602001806153a36025913960400191505060405180910390fd5b677ce66c50e284000083111561208d5760405162461bcd60e51b81526004018080602001828103825260358152602001806152dc6035913960400191505060405180910390fd5b604080516323b872dd60e01b81523360048201523060248201526044810189905290516001600160a01b038b16916323b872dd9160648083019260209291908290030181600087803b1580156120e257600080fd5b505af11580156120f6573d6000803e3d6000fd5b505050506040513d602081101561210c57600080fd5b505161211757600080fd5b505b6121216150bc565b6040805160c0810182528581526001600160a01b038b166020820152815160018082528184018452919283019181602001602082028036833750505081526040805160018082528183019092526020928301929091908083019080368337505050815260408051600180825281830190925260209283019290919080830190803683370190505081526020018767ffffffffffffffff1681525090508281604001516000815181106121cf57fe5b6020026020010181815250508781606001516000815181106121ed57fe5b60200260200101906001600160a01b031690816001600160a01b03168152505033816080015160008151811061221f57fe5b6001600160a01b039092166020928302919091019091015261200063f7a251d7600361224a846130eb565b61225f866402540be40063ffffffff61300e16565b6040518463ffffffff1660e01b8152600401808460ff1660ff16815260200180602001838152602001828103825284818151815260200191508051906020019080838360005b838110156122bd5781810151838201526020016122a5565b50505050905090810190601f1680156122ea5780820380516001836020036101000a031916815260200191505b50945050505050600060405180830381600087803b15801561230b57600080fd5b505af115801561231f573d6000803e3d6000fd5b5050604080516001600160a01b038d1681523360208201528082018b90526060810186905290517f74eab09b0e53aefc23f2e1b16da593f95c2dd49c6f5a23720463d10d9c330b2a9350908190036080019150a150600198975050505050505050565b33611007146123c25760405162461bcd60e51b815260040180806020018281038252602e8152602001806154a3602e913960400191505060405180910390fd5b60208114612417576040805162461bcd60e51b815260206004820152601b60248201527f65787065637465642076616c7565206c656e6774682069732033320000000000604482015290519081900360640190fd5b606084848080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525050604080516020601f8801819004810282018101909252868152939450606093925086915085908190840183828082843760009201919091525050505060208301519091506772656c617946656560c01b81141561251f576020820151670de0b6b3a764000081118015906124c657506402540be4008106155b612517576040805162461bcd60e51b815260206004820152601960248201527f7468652072656c6179466565206f7574206f662072616e676500000000000000604482015290519081900360640190fd5b600155612795565b61259387878080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152505060408051808201909152601781527f6c617267655472616e736665724c6f636b506572696f640000000000000000006020820152915061358a9050565b1561262f57604080516020601f87018190048102820181019092528581526000916125d69188888083850183828082843760009201919091525061367192505050565b905062093a80811115612627576040805162461bcd60e51b81526020600482015260146024820152736c6f636b20706572696f6420746f6f206c6f6e6760601b604482015290519081900360640190fd5b600555612795565b61269b87878080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525050604080518082019091526015815274189b9893185c99d9551c985b9cd9995c931a5b5a5d605a1b6020820152915061358a9050565b1561275857604080516020601f87018190048102820181019092528581526000916126de9188888083850183828082843760009201919091525061367192505050565b905068056bc75e2d631000008110156127285760405162461bcd60e51b81526004018080602001828103825260228152602001806152386022913960400191505060405180910390fd5b6000805260066020527f54cdd369e4e8a8515e52ca72ec816c2101831ad1f18bf44102ed171459c9b4f855612795565b6040805162461bcd60e51b815260206004820152600d60248201526c756e6b6e6f776e20706172616d60981b604482015290519081900360640190fd5b7f6cdb0ac70ab7f2e2d035cca5be60d89906f2dede7648ddbd7402189c1eeed17a878787876040518080602001806020018381038352878782818152602001925080828437600083820152601f01601f191690910184810383528581526020019050858580828437600083820152604051601f909101601f19169092018290039850909650505050505050a150505050505050565b336110081461286a5760405162461bcd60e51b815260040180806020018281038252602381526020018061555f6023913960400191505060405180910390fd5b600091825260046020908152604080842080546001600160a01b03191690556001600160a01b0392909216835260039052812055565b6221272160e91b81565b61c35081565b60026020526000908152604090205481565b6001600160a01b031660009081526003602052604090205490565b61100281565b60005460ff16612928576040805162461bcd60e51b81526020600482015260196024820152600080516020615582833981519152604482015290519081900360640190fd5b33612000146129685760405162461bcd60e51b815260040180806020018281038252602f815260200180615530602f913960400191505060405180910390fd5b60ff83166003141561189c5761189782828080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061367692505050565b60085460ff16600214156129ff576040805162461bcd60e51b815260206004820152600e60248201526d4e6f2072652d656e7472616e637960901b604482015290519081900360640190fd5b6008805460ff191660021790556001600160a01b0380831660009081526007602090815260408083209385168352929052208054612a77576040805162461bcd60e51b815260206004820152601060248201526f1b9bc81b1bd8dad95908185b5bdd5b9d60821b604482015290519081900360640190fd5b8060010154421015612ad0576040805162461bcd60e51b815260206004820152601760248201527f7374696c6c206f6e206c6f636b696e6720706572696f64000000000000000000604482015290519081900360640190fd5b805460008083556001600160a01b038516612b43576040516001600160a01b038516906127109084906000818181858888f193505050503d8060008114612b33576040519150601f19603f3d011682016040523d82523d6000602084013e612b38565b606091505b505080915050612bd6565b846001600160a01b031663a9059cbb61c35086856040518463ffffffff1660e01b815260040180836001600160a01b03166001600160a01b0316815260200182815260200192505050602060405180830381600088803b158015612ba657600080fd5b5087f1158015612bba573d6000803e3d6000fd5b50505050506040513d6020811015612bd157600080fd5b505190505b80612c28576040805162461bcd60e51b815260206004820152601e60248201527f776974686472617720756e6c6f636b656420746f6b656e206661696c65640000604482015290519081900360640190fd5b836001600160a01b0316856001600160a01b03167f832fc3e25f2b3e6fb0eb59419a73cba405f2a249fce75f7e31ea5a457a0323f1846040518082815260200191505060405180910390a350506008805460ff19166001179055505050565b61100381565b60005460ff1615612ce5576040805162461bcd60e51b815260206004820152601960248201527f74686520636f6e747261637420616c726561647920696e697400000000000000604482015290519081900360640190fd5b66071afd498d000060019081556000808052600260205260127fac33ff75c19e70fe83507db0d683fd3465c996598dc972688b7ace676c89077b55805460ff19169091179055565b60066020526000908152604090205481565b600481565b600581565b61100081565b61271081565b69021e19e0c9bab240000081565b6001600160a01b03811660009081526003602090815260409182902054825182815280840190935260609290918391906020820181803683375050506020810183905290506000805b60208160ff161015612df357828160ff1681518110612dc757fe5b01602001516001600160f81b03191615612de657600190910190612deb565b612df3565b600101612dac565b5060608160ff166040519080825280601f01601f191660200182016040528015612e24576020820181803683370190505b50905060005b8260ff168160ff161015612e8057838160ff1681518110612e4757fe5b602001015160f81c60f81b828260ff1681518110612e6157fe5b60200101906001600160f81b031916908160001a905350600101612e2a565b5095945050505050565b61100481565b6060612e9a615108565b6000612ea584613774565b9150915080612efb576040805162461bcd60e51b815260206004820152601f60248201527f756e7265636f676e697a6564207472616e73666572496e207061636b61676500604482015290519081900360640190fd5b6000612f06836138b3565b905063ffffffff811615612f9a576040808401516020808601516001600160a01b03166000908152600290915291822054612f419190613444565b9050612f4b61513d565b60405180608001604052808660000151815260200183815260200186608001516001600160a01b031681526020018463ffffffff168152509050612f8e81613c19565b955050505050506111e9565b505060408051600081526020810190915291506111e99050565b600082820183811015611c99576040805162461bcd60e51b815260206004820152601b60248201527f536166654d6174683a206164646974696f6e206f766572666c6f770000000000604482015290519081900360640190fd5b6000611c9983836040518060400160405280601a81526020017f536166654d6174683a206469766973696f6e206279207a65726f000000000000815250613cf5565b60008261305f57506000611c9c565b8282028284828161306c57fe5b0414611c995760405162461bcd60e51b81526004018080602001828103825260218152602001806154436021913960400191505060405180910390fd5b6000611c9983836040518060400160405280601e81526020017f536166654d6174683a207375627472616374696f6e206f766572666c6f770000815250613d97565b60408051600680825260e08201909252606091829190816020015b6060815260200190600190039081613106575050835190915061312890613df1565b8160008151811061313557fe5b602002602001018190525061315683602001516001600160a01b0316613e04565b8160018151811061316357fe5b6020026020010181905250600083604001515190506060816040519080825280602002602001820160405280156131ae57816020015b60608152602001906001900390816131995790505b50905060005b828110156131fb576131dc866040015182815181106131cf57fe5b6020026020010151613df1565b8282815181106131e857fe5b60209081029190910101526001016131b4565b5061320581613e27565b8360028151811061321257fe5b602002602001018190525060608260405190808252806020026020018201604052801561325357816020015b606081526020019060019003908161323e5790505b50905060005b838110156132a95761328a8760600151828151811061327457fe5b60200260200101516001600160a01b0316613e04565b82828151811061329657fe5b6020908102919091010152600101613259565b506132b381613e27565b846003815181106132c057fe5b602002602001018190525060608360405190808252806020026020018201604052801561330157816020015b60608152602001906001900390816132ec5790505b50905060005b84811015613341576133228860800151828151811061327457fe5b82828151811061332e57fe5b6020908102919091010152600101613307565b5061334b81613e27565b8560048151811061335857fe5b602002602001018190525061337a8760a0015167ffffffffffffffff16613df1565b8560058151811061338757fe5b602002602001018190525061339b85613e27565b979650505050505050565b6133ae615164565b60006133b983613eb1565b91509150806133f95760405162461bcd60e51b81526004018080602001828103825260248152602001806154d16024913960400191505060405180910390fd5b61190b8261407c565b6000611c9983836040518060400160405280601881526020017f536166654d6174683a206d6f64756c6f206279207a65726f0000000000000000815250614500565b6000600882111561346d57613466836007198401600a0a63ffffffff61300e16565b9050611c9c565b611c99836008849003600a0a63ffffffff61305016565b604080516020808252818301909252600091606091906020820181803683375050506020810184905290506000805b60208160ff1610156134fa57828160ff16815181106134ce57fe5b01602001516001600160f81b031916156134ed576001909101906134f2565b6134fa565b6001016134b3565b50600760ff82161015613512576000925050506111e9565b816005820360ff168151811061352457fe5b6020910101516001600160f81b031916602d60f81b14613549576000925050506111e9565b816001820360ff168151811061355b57fe5b6020910101516001600160f81b031916604d60f81b14613580576000925050506111e9565b5060019392505050565b6000816040516020018082805190602001908083835b602083106135bf5780518252601f1990920191602091820191016135a0565b6001836020036101000a03801982511681845116808217855250505050505090500191505060405160208183030381529060405280519060200120836040516020018082805190602001908083835b6020831061362d5780518252601f19909201916020918201910161360e565b6001836020036101000a0380198251168184511680821785525050505050509050019150506040516020818303038152906040528051906020012014905092915050565b015190565b61367e6150bc565b600061368983614562565b91509150806136c95760405162461bcd60e51b81526004018080602001828103825260248152602001806152946024913960400191505060405180910390fd5b6136d1615164565b602080840180516001600160a01b0390811684526040808701518585015291511660009081526002909252812054905b8460400151518110156137525761372f8560400151828151811061372157fe5b6020026020010151836147c6565b8560400151828151811061373f57fe5b6020908102919091010152600101613701565b50608084015160408301526005606083015261376d8261407c565b5050505050565b61377c615108565b6000613786615108565b61378e61519b565b61379f61379a866147ff565b614824565b90506000805b6137ae8361486e565b156138a657806137d0576137c96137c48461488f565b6148dd565b845261389e565b80600114156137fd576137ea6137e58461488f565b614994565b6001600160a01b0316602085015261389e565b806002141561381c576138126137c48461488f565b604085015261389e565b8060031415613844576138316137e58461488f565b6001600160a01b0316606085015261389e565b806004141561386c576138596137e58461488f565b6001600160a01b0316608085015261389e565b8060051415613899576138816137c48461488f565b67ffffffffffffffff1660a08501526001915061389e565b6138a6565b6001016137a5565b5091935090915050915091565b60208101516000906001600160a01b03166139f7578160a0015167ffffffffffffffff164211156138e6575060016111e9565b81604001514710156138fa575060036111e9565b613903826149ae565b61397857606082015160408084015190516000926001600160a01b0316916127109184818181858888f193505050503d806000811461395e576040519150601f19603f3d011682016040523d82523d6000602084013e613963565b606091505b50509050806139765750600490506111e9565b505b7f471eb9cc1ffe55ffadf15b32595415eb9d80f22e761d24bd6dffc607e1284d5982602001518360600151846040015160405180846001600160a01b03166001600160a01b03168152602001836001600160a01b03166001600160a01b03168152602001828152602001935050505060405180910390a15060006111e9565b8160a0015167ffffffffffffffff16421115613a15575060016111e9565b81516020808401516001600160a01b031660009081526003909152604090205414613a42575060026111e9565b602080830151604080516370a0823160e01b815230600482015290516000936001600160a01b03909316926370a082319261c3509260248083019392829003018187803b158015613a9257600080fd5b5086fa158015613aa6573d6000803e3d6000fd5b50505050506040513d6020811015613abd57600080fd5b50516040840151909150811015613ad85750600390506111e9565b613ae1836149ae565b613b9857600083602001516001600160a01b031663a9059cbb61c350866060015187604001516040518463ffffffff1660e01b815260040180836001600160a01b03166001600160a01b0316815260200182815260200192505050602060405180830381600088803b158015613b5657600080fd5b5087f1158015613b6a573d6000803e3d6000fd5b50505050506040513d6020811015613b8157600080fd5b5051905080613b965750600591506111e99050565b505b7f471eb9cc1ffe55ffadf15b32595415eb9d80f22e761d24bd6dffc607e1284d5983602001518460600151856040015160405180846001600160a01b03166001600160a01b03168152602001836001600160a01b03166001600160a01b03168152602001828152602001935050505060405180910390a150600090506111e9565b60408051600480825260a08201909252606091829190816020015b6060815260200190600190039081613c345750508351909150613c5690613df1565b81600081518110613c6357fe5b6020026020010181905250613c7b8360200151613df1565b81600181518110613c8857fe5b6020026020010181905250613ca983604001516001600160a01b0316613e04565b81600281518110613cb657fe5b6020026020010181905250613cd4836060015163ffffffff16613df1565b81600381518110613ce157fe5b602002602001018190525061109f81613e27565b60008183613d815760405162461bcd60e51b81526004018080602001828103825283818151815260200191508051906020019080838360005b83811015613d46578181015183820152602001613d2e565b50505050905090810190601f168015613d735780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b506000838581613d8d57fe5b0495945050505050565b60008184841115613de95760405162461bcd60e51b8152602060048201818152835160248401528351909283926044909101919085019080838360008315613d46578181015183820152602001613d2e565b505050900390565b6060611c9c613dff83614b1c565b614c02565b60408051600560a21b831860148201526034810190915260609061109f81614c02565b6060815160001415613e4857506040805160008152602081019091526111e9565b606082600081518110613e5757fe5b602002602001015190506000600190505b8351811015613e9857613e8e82858381518110613e8157fe5b6020026020010151614c54565b9150600101613e68565b5061109f613eab825160c060ff16614cd1565b82614c54565b613eb9615164565b6000613ec3615164565b613ecb61519b565b613ed761379a866147ff565b90506000805b613ee68361486e565b156138a65780613f0c57613efc6137e58461488f565b6001600160a01b03168452614074565b8060011415613fad576060613f28613f238561488f565b614dc9565b90508051604051908082528060200260200182016040528015613f55578160200160208202803683370190505b50602086015260005b8151811015613fa657613f83828281518110613f7657fe5b60200260200101516148dd565b86602001518281518110613f9357fe5b6020908102919091010152600101613f5e565b5050614074565b806002141561404f576060613fc4613f238561488f565b90508051604051908082528060200260200182016040528015613ff1578160200160208202803683370190505b50604086015260005b8151811015613fa65761401f82828151811061401257fe5b6020026020010151614994565b8660400151828151811061402f57fe5b6001600160a01b0390921660209283029190910190910152600101613ffa565b8060031415613899576140646137c48461488f565b63ffffffff166060850152600191505b600101613edd565b80516001600160a01b03166142a65760005b8160200151518110156142a0576000826040015182815181106140ad57fe5b60200260200101516001600160a01b0316612710846020015184815181106140d157fe5b60209081029190910101516040516000818181858888f193505050503d8060008114614119576040519150601f19603f3d011682016040523d82523d6000602084013e61411e565b606091505b50509050806141e1577f203f9f67a785f4f81be4d48b109aa0c498d1bc8097ecc2627063f480cc5fe73e83600001518460400151848151811061415d57fe5b60200260200101518560200151858151811061417557fe5b6020026020010151866060015160405180856001600160a01b03166001600160a01b03168152602001846001600160a01b03166001600160a01b031681526020018381526020018263ffffffff1663ffffffff16815260200194505050505060405180910390a1614297565b7fd468d4fa5e8fb4adc119b29a983fd0785e04af5cb8b7a3a69a47270c54b6901a83600001518460400151848151811061421757fe5b60200260200101518560200151858151811061422f57fe5b6020026020010151866060015160405180856001600160a01b03166001600160a01b03168152602001846001600160a01b03166001600160a01b031681526020018381526020018263ffffffff1663ffffffff16815260200194505050505060405180910390a15b5060010161408e565b506144fd565b60005b8160200151518110156144fb57600082600001516001600160a01b031663a9059cbb61c350856040015185815181106142de57fe5b6020026020010151866020015186815181106142f657fe5b60200260200101516040518463ffffffff1660e01b815260040180836001600160a01b03166001600160a01b0316815260200182815260200192505050602060405180830381600088803b15801561434d57600080fd5b5087f1158015614361573d6000803e3d6000fd5b50505050506040513d602081101561437857600080fd5b50519050801561443c577fd468d4fa5e8fb4adc119b29a983fd0785e04af5cb8b7a3a69a47270c54b6901a8360000151846040015184815181106143b857fe5b6020026020010151856020015185815181106143d057fe5b6020026020010151866060015160405180856001600160a01b03166001600160a01b03168152602001846001600160a01b03166001600160a01b031681526020018381526020018263ffffffff1663ffffffff16815260200194505050505060405180910390a16144f2565b7f203f9f67a785f4f81be4d48b109aa0c498d1bc8097ecc2627063f480cc5fe73e83600001518460400151848151811061447257fe5b60200260200101518560200151858151811061448a57fe5b6020026020010151866060015160405180856001600160a01b03166001600160a01b03168152602001846001600160a01b03166001600160a01b031681526020018381526020018263ffffffff1663ffffffff16815260200194505050505060405180910390a15b506001016142a9565b505b50565b6000818361454f5760405162461bcd60e51b8152602060048201818152835160248401528351909283926044909101919085019080838360008315613d46578181015183820152602001613d2e565b5082848161455957fe5b06949350505050565b61456a6150bc565b60006145746150bc565b61457c61519b565b61458861379a866147ff565b90506000805b6145978361486e565b156138a657806145b4576145ad6137c48461488f565b84526147be565b80600114156145dc576145c96137e58461488f565b6001600160a01b031660208501526147be565b806002141561466b5760606145f3613f238561488f565b90508051604051908082528060200260200182016040528015614620578160200160208202803683370190505b50604086015260005b815181101561466457614641828281518110613f7657fe5b8660400151828151811061465157fe5b6020908102919091010152600101614629565b50506147be565b8060031415614700576060614682613f238561488f565b905080516040519080825280602002602001820160405280156146af578160200160208202803683370190505b50606086015260005b8151811015614664576146d082828151811061401257fe5b866060015182815181106146e057fe5b6001600160a01b03909216602092830291909101909101526001016146b8565b8060041415614795576060614717613f238561488f565b90508051604051908082528060200260200182016040528015614744578160200160208202803683370190505b50608086015260005b81518110156146645761476582828151811061401257fe5b8660800151828151811061477557fe5b6001600160a01b039092166020928302919091019091015260010161474d565b8060051415613899576147aa6137c48461488f565b67ffffffffffffffff1660a0850152600191505b60010161458e565b600060088211156147e857613466836007198401600a0a63ffffffff61305016565b611c99836008849003600a0a63ffffffff61300e16565b6148076151bb565b506040805180820190915281518152602082810190820152919050565b61482c61519b565b61483582614e9a565b61483e57600080fd5b600061484d8360200151614eca565b60208085015160408051808201909152868152920190820152915050919050565b60006148786151bb565b505080518051602091820151919092015191011190565b6148976151bb565b6148a08261486e565b6148a957600080fd5b602082015160006148b982614f2d565b80830160209586015260408051808201909152908152938401919091525090919050565b8051600090158015906148f257508151602110155b6148fb57600080fd5b600061490a8360200151614eca565b90508083600001511015614965576040805162461bcd60e51b815260206004820152601a60248201527f6c656e677468206973206c657373207468616e206f6666736574000000000000604482015290519081900360640190fd5b82516020808501518301805192849003929183101561498b57826020036101000a820491505b50949350505050565b80516000906015146149a557600080fd5b611c9c826148dd565b600080805260066020527f54cdd369e4e8a8515e52ca72ec816c2101831ad1f18bf44102ed171459c9b4f8541580156149e75750600554155b15614a295760008052600660205269021e19e0c9bab24000007f54cdd369e4e8a8515e52ca72ec816c2101831ad1f18bf44102ed171459c9b4f85561a8c06005555b6020808301516001600160a01b0316600090815260069091526040902054801580614a575750808360400151105b15614a665760009150506111e9565b6020808401516001600160a01b039081166000908152600783526040808220606088015190931682529190925290819020908401518154614aac9163ffffffff612fb416565b8155600554420160018201819055606085015160208087015160408089015181519081529283019490945283516001600160a01b039384169493909116927f3fb83143cd331170da18fb1e8564d97e8ec39264b6ecb1ba248ea7596ab07258928290030190a35060019392505050565b604080516020808252818301909252606091829190602082018180368337505050602081018490529050600067ffffffffffffffff198416614b6057506018614b84565b6fffffffffffffffffffffffffffffffff198416614b8057506010614b84565b5060005b6020811015614bba57818181518110614b9957fe5b01602001516001600160f81b03191615614bb257614bba565b600101614b84565b60008160200390506060816040519080825280601f01601f191660200182016040528015614bef576020820181803683370190505b5080830196909652508452509192915050565b606081516001148015614c345750607f60f81b82600081518110614c2257fe5b01602001516001600160f81b03191611155b15614c405750806111e9565b611c9c614c528351608060ff16614cd1565b835b6060806040519050835180825260208201818101602087015b81831015614c85578051835260209283019201614c6d565b50855184518101855292509050808201602086015b81831015614cb2578051835260209283019201614c9a565b508651929092011591909101601f01601f191660405250905092915050565b6060680100000000000000008310614d21576040805162461bcd60e51b815260206004820152600e60248201526d696e70757420746f6f206c6f6e6760901b604482015290519081900360640190fd5b60408051600180825281830190925260609160208201818036833701905050905060378411614d7b5782840160f81b81600081518110614d5d57fe5b60200101906001600160f81b031916908160001a9053509050611c9c565b6060614d8685614b1c565b90508381510160370160f81b82600081518110614d9f57fe5b60200101906001600160f81b031916908160001a905350614dc08282614c54565b95945050505050565b6060614dd482614e9a565b614ddd57600080fd5b6000614de883615060565b9050606081604051908082528060200260200182016040528015614e2657816020015b614e136151bb565b815260200190600190039081614e0b5790505b5090506000614e388560200151614eca565b60208601510190506000805b84811015614e8f57614e5583614f2d565b9150604051806040016040528083815260200184815250848281518110614e7857fe5b602090810291909101015291810191600101614e44565b509195945050505050565b8051600090614eab575060006111e9565b6020820151805160001a9060c0821015613580576000925050506111e9565b8051600090811a6080811015614ee45760009150506111e9565b60b8811080614eff575060c08110801590614eff575060f881105b15614f0e5760019150506111e9565b60c0811015614f225760b5190190506111e9565b60f5190190506111e9565b80516000908190811a6080811015614f485760019150615059565b60b8811015614f5d57607e1981019150615059565b60c0811015614fd757600060b78203600186019550806020036101000a865104915060018101820193505080831015614fd1576040805162461bcd60e51b81526020600482015260116024820152706164646974696f6e206f766572666c6f7760781b604482015290519081900360640190fd5b50615059565b60f8811015614fec5760be1981019150615059565b600060f78203600186019550806020036101000a865104915060018101820193505080831015615057576040805162461bcd60e51b81526020600482015260116024820152706164646974696f6e206f766572666c6f7760781b604482015290519081900360640190fd5b505b5092915050565b8051600090615071575060006111e9565b600080905060006150858460200151614eca565b602085015185519181019250015b808210156150b3576150a482614f2d565b60019093019290910190615093565b50909392505050565b6040518060c001604052806000801916815260200160006001600160a01b03168152602001606081526020016060815260200160608152602001600067ffffffffffffffff1681525090565b6040805160c081018252600080825260208201819052918101829052606081018290526080810182905260a081019190915290565b60408051608081018252600080825260208201819052918101829052606081019190915290565b604051806080016040528060006001600160a01b031681526020016060815260200160608152602001600063ffffffff1681525090565b60405180604001604052806151ae6151bb565b8152602001600081525090565b60405180604001604052806000815260200160008152509056fe6f6e6c79207374616b696e672073797374656d20636f6e74726163742063616e2063616c6c20746869732066756e6374696f6e746865206d6573736167652073656e646572206d75737420626520696e63656e746976697a6520636f6e7472616374626e62206c61726765207472616e73666572206c696d697420746f6f20736d616c6c466f72206d696e69546f6b656e2c20746865207472616e7366657220616d6f756e74206d757374206e6f74206265206c657373207468616e2031756e7265636f676e697a6564207472616e736665724f75742073796e207061636b61676565787069726554696d65206d7573742062652074776f206d696e75746573206c61746572616d6f756e7420697320746f6f206c617267652c20657863656564206d6178696d756d206265703220746f6b656e20616d6f756e7474686520636f6e747261637420686173206e6f74206265656e20626f756e6420746f20616e79206265703220746f6b656e726563656976656420424e4220616d6f756e742073686f756c64206265206e6f206c657373207468616e207468652073756d206f66207472616e736665724f757420424e4220616d6f756e7420616e64206d696e696d756d2072656c6179466565616d6f756e7420697320746f6f206c617267652c2075696e74323536206f766572666c6f774c656e677468206f6620726563697069656e74416464727320646f65736e277420657175616c20746f206c656e677468206f6620726566756e644164647273696e76616c6964207472616e7366657220616d6f756e743a20707265636973696f6e206c6f737320696e20616d6f756e7420636f6e76657273696f6e536166654d6174683a206d756c7469706c69636174696f6e206f766572666c6f77726563656976656420424e4220616d6f756e742073686f756c64206265206e6f206c657373207468616e20746865206d696e696d756d2072656c6179466565746865206d6573736167652073656e646572206d75737420626520676f7665726e616e636520636f6e7472616374756e7265636f676e697a6564207472616e736665724f75742061636b207061636b6167654c656e677468206f6620726563697069656e74416464727320646f65736e277420657175616c20746f206c656e677468206f6620616d6f756e7473746865206d6573736167652073656e646572206d7573742062652063726f737320636861696e20636f6e7472616374746865206d73672073656e646572206d75737420626520746f6b656e4d616e6167657274686520636f6e7472616374206e6f7420696e69742079657400000000000000726563656976656420424e4220616d6f756e742073686f756c64206265206e6f206c657373207468616e207468652073756d206f66207472616e7366657220424e4220616d6f756e7420616e642072656c6179466565696e76616c696420726563656976656420424e4220616d6f756e743a20707265636973696f6e206c6f737320696e20616d6f756e7420636f6e76657273696f6ea2646970667358221220b559cd4e3125714f2f5ec5e81bc7a26f9ea28156afc15d661cb954c3ea9a53d864736f6c63430006040033", + }, + { + ContractAddr: CrossChainContract, + CommitUrl: "https://github.com/bnb-chain/bsc-genesis-contract/commit/78e13b1d3a5a1b08c9208af94a9b14fc1efda213", + Code: "608060405234801561001057600080fd5b50600436106103995760003560e01c8063718a8aa8116101e9578063c27cdcfb1161010f578063dc927faf116100ad578063f7a251d71161007c578063f7a251d714610b2f578063f9a2bbc714610ba7578063fc3e590814610baf578063fd6a687914610bb757610399565b8063dc927faf14610af7578063e1c7392a14610aff578063e3b0480514610b07578063e6400bbe14610b2757610399565b8063ccc108d7116100e9578063ccc108d714610ab0578063d31f968d14610ab8578063d76a867514610ae7578063dc40433114610aef57610399565b8063c27cdcfb14610a80578063c780e9de14610aa0578063c81b166214610aa857610399565b80638cc8f56111610187578063a78abc1611610156578063a78abc16146109b2578063ab51bb96146109ba578063ac431751146109c2578063b0355f5b1461078157610399565b80638cc8f5611461088757806396713da91461099a5780639dc09262146109a2578063a1a11bf5146109aa57610399565b806375d47a0a116101c357806375d47a0a146108a75780637942fd05146108af57806384013b6a146108b7578063863fe4ab1461099257610399565b8063718a8aa81461088f578063719482d51461089757806374f079b81461089f57610399565b8063422f9050116102ce57806363e1394e1161026c5780636de380bd1161023b5780636de380bd146108575780636e47a51a1461085f5780636e47b4821461087f57806370fd5bad1461088757610399565b806363e1394e146107ff5780636a3cb34d146108075780636bacff2c1461080f5780636c46aa681461080757610399565b80634bf6c882116102a85780634bf6c882146107b957806351e80672146107c15780635692ddd3146107c95780635f832177146107d157610399565b8063422f90501461078957806343756e5c146107a9578063493279b1146107b157610399565b8063299b533d1161033b578063308325f411610315578063308325f4146106155780633a648b151461061d5780633bdc47a6146106595780633dffc3871461078157610399565b8063299b533d146105a35780632af6f399146105d75780632ff32aea146105f457610399565b806314b3023b1161037757806314b3023b146104015780631d1309351461041b5780631e275ae11461043757806322556cdc1461059b57610399565b806305e682581461039e5780630bee7a67146103bc5780630e2374a5146103dd575b600080fd5b6103a6610bbf565b6040805160ff9092168252519081900360200190f35b6103c4610bc4565b6040805163ffffffff9092168252519081900360200190f35b6103e5610bc9565b604080516001600160a01b039092168252519081900360200190f35b610409610bcf565b60408051918252519081900360200190f35b610423610bd5565b604080519115158252519081900360200190f35b610599600480360361010081101561044e57600080fd5b81018160a081016080820135600160201b81111561046b57600080fd5b82018360208201111561047d57600080fd5b803590602001918460018302840111600160201b8311171561049e57600080fd5b919390929091602081019035600160201b8111156104bb57600080fd5b8201836020820111156104cd57600080fd5b803590602001918460018302840111600160201b831117156104ee57600080fd5b919390929091602081019035600160201b81111561050b57600080fd5b82018360208201111561051d57600080fd5b803590602001918460018302840111600160201b8311171561053e57600080fd5b919390929091602081019035600160201b81111561055b57600080fd5b82018360208201111561056d57600080fd5b803590602001918460018302840111600160201b8311171561058e57600080fd5b509092509050610bde565b005b6104096112c2565b6105c0600480360360208110156105b957600080fd5b50356112c7565b6040805161ffff9092168252519081900360200190f35b610423600480360360208110156105ed57600080fd5b50356112dd565b6105fc6112f2565b60408051600792830b90920b8252519081900360200190f35b6104096112fb565b61063d6004803603602081101561063357600080fd5b503560ff16611301565b604080516001600160401b039092168252519081900360200190f35b61070c6004803603606081101561066f57600080fd5b60ff82351691602081013591810190606081016040820135600160201b81111561069857600080fd5b8201836020820111156106aa57600080fd5b803590602001918460018302840111600160201b831117156106cb57600080fd5b91908080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525092955061131c945050505050565b6040805160208082528351818301528351919283929083019185019080838360005b8381101561074657818101518382015260200161072e565b50505050905090810190601f1680156107735780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b6103a6611392565b6104236004803603602081101561079f57600080fd5b503560ff16611397565b6103e56113ac565b6105c06113b2565b6103a66113b7565b6103e56113bc565b6104096113c2565b610599600480360360408110156107e757600080fd5b506001600160a01b03813581169160200135166113f2565b610409611652565b6105c061167a565b61082c6004803603602081101561082557600080fd5b503561167f565b6040805161ffff90941684526001600160801b03909216602084015282820152519081900360600190f35b6104096116ae565b6103e56004803603602081101561087557600080fd5b503560ff166116d5565b6103e56116f0565b6103a661167a565b6103a66116f6565b6105c0611392565b6104096116fb565b6103e5611701565b6103a6611707565b610599600480360360a08110156108cd57600080fd5b810190602081018135600160201b8111156108e757600080fd5b8201836020820111156108f957600080fd5b803590602001918460018302840111600160201b8311171561091a57600080fd5b919390929091602081019035600160201b81111561093757600080fd5b82018360208201111561094957600080fd5b803590602001918460018302840111600160201b8311171561096a57600080fd5b919350915080356001600160401b03908116916020810135909116906040013560ff1661170c565b610409612a36565b6103a6612a3e565b6103e5612a43565b6103e5612a49565b610423612a4f565b6103c4610bbf565b610599600480360360408110156109d857600080fd5b810190602081018135600160201b8111156109f257600080fd5b820183602082011115610a0457600080fd5b803590602001918460018302840111600160201b83111715610a2557600080fd5b919390929091602081019035600160201b811115610a4257600080fd5b820183602082011115610a5457600080fd5b803590602001918460018302840111600160201b83111715610a7557600080fd5b509092509050612a58565b61063d60048036036020811015610a9657600080fd5b503560ff1661351c565b610409613537565b6103e561355b565b610599613561565b61042360048036036040811015610ace57600080fd5b5080356001600160a01b0316906020013560ff166137b5565b61070c6137d5565b6104096137f4565b6103e56137fa565b610599613800565b61063d60048036036020811015610b1d57600080fd5b503560ff16613bb7565b610599613bd2565b61059960048036036060811015610b4557600080fd5b60ff8235169190810190604081016020820135600160201b811115610b6957600080fd5b820183602082011115610b7b57600080fd5b803590602001918460018302840111600160201b83111715610b9c57600080fd5b919350915035613df1565b6103e5613f34565b6103a6613f3a565b6103e5613f3f565b600081565b606481565b61200181565b60015481565b600b5460ff1681565b60005460ff16610c23576040805162461bcd60e51b81526020600482015260196024820152600080516020614a4c833981519152604482015290519081900360640190fd5b604080516337d7f9c160e21b81526001600160401b038b35166004820181905291516110039163df5fe704916024808301926020929190829003018186803b158015610c6e57600080fd5b505afa158015610c82573d6000803e3d6000fd5b505050506040513d6020811015610c9857600080fd5b5051610cd55760405162461bcd60e51b8152600401808060200182810382526023815260200180614a6c6023913960400191505060405180910390fd5b604080516337d7f9c160e21b815260208c8101356001600160401b03166004830181905292516110039263df5fe704926024808301939192829003018186803b158015610d2157600080fd5b505afa158015610d35573d6000803e3d6000fd5b505050506040513d6020811015610d4b57600080fd5b5051610d885760405162461bcd60e51b8152600401808060200182810382526023815260200180614a6c6023913960400191505060405180910390fd5b60608b013560ff81166000908152600560205260409020546001600160401b03909116906001600160a01b0316610e01576040805162461bcd60e51b815260206004820152601860248201527718da185b9b995b081a5cc81b9bdd081cdd5c1c1bdc9d195960421b604482015290519081900360640190fd5b600b5460ff1615610e45576040805162461bcd60e51b81526020600482015260096024820152681cdd5cdc195b99195960ba1b604482015290519081900360640190fd5b8888604051808383808284376040519201829003822094508f93508e9250819050838380828437808301925050509250505060405180910390201415610ec1576040805162461bcd60e51b815260206004820152600c60248201526b1cd85b59481c185e5b1bd85960a21b604482015290519081900360640190fd5b60606001600160401b0360408e01358116908e83013516610ee28282613f45565b80516020808301919091206000818152600e9092526040909120549194509060ff1615610f4b576040805162461bcd60e51b8152602060048201526012602482015271185b1c9958591e4818da185b1b195b99d95960721b604482015290519081900360640190fd5b6000908152600e60205260408120805460ff191660011790558f8160200201356001600160401b0316905060608f8f8080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f82011690508083019250505050505050905060608c8c8080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201829052506040805163cba510a960e01b81526001600160401b038a16600482015290519596509094611003945063cba510a9935060248083019350602092829003018186803b15801561104157600080fd5b505afa158015611055573d6000803e3d6000fd5b505050506040513d602081101561106b57600080fd5b505160408051808201909152600381526269626360e81b6020820152909150611098908290898686613f8d565b6110e1576040805162461bcd60e51b81526020600482015260156024820152740696e76616c6964206d65726b6c652070726f6f663605c1b604482015290519081900360640190fd5b5050505060008f6001600481106110f457fe5b60200201356001600160401b0316905060608d8d8080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525050604080516020601f8f018190048102820181019092528d815293945060609392508d91508c908190840183828082843760009201829052506040805163cba510a960e01b81526001600160401b038a16600482015290519596509094611003945063cba510a9935060248083019350602092829003018186803b1580156111c057600080fd5b505afa1580156111d4573d6000803e3d6000fd5b505050506040513d60208110156111ea57600080fd5b505160408051808201909152600381526269626360e81b6020820152909150611217908290898686613f8d565b611260576040805162461bcd60e51b8152602060048201526015602482015274696e76616c6964206d65726b6c652070726f6f663160581b604482015290519081900360640190fd5b5050505061126c61408a565b604080516001600160401b038416815260ff83166020820152815133927f039eb91179ffd7d3b6e97f8ea106e748e827f910b872375dbc9c14a362319c3c928290030190a2505050505050505050505050505050565b603281565b600d6020526000908152604090205461ffff1681565b600e6020526000908152604090205460ff1681565b60045460070b81565b60025481565b600a602052600090815260409020546001600160401b031681565b60606000825160210190506060816040519080825280601f01601f191660200182016040528015611354576020820181803683370190505b506021810186905260018101879052828152905060418101600061137786614108565b50905061138681838851614112565b50909695505050505050565b600181565b60096020526000908152604090205460ff1681565b61100181565b603881565b600881565b61200081565b604080517710d05390d15317d514905394d1915497d41493d413d4d05360421b8152905190819003601801902081565b60005460ff16611437576040805162461bcd60e51b81526020600482015260196024820152600080516020614a4c833981519152604482015290519081900360640190fd5b6040805163569e4ed360e11b815233600482015290516000916110009163ad3c9da691602480820192602092909190829003018186803b15801561147a57600080fd5b505afa15801561148e573d6000803e3d6000fd5b505050506040513d60208110156114a457600080fd5b505160408051633d42651560e11b8152905191925060009161100091637a84ca2a916004808301926020929190829003018186803b1580156114e557600080fd5b505afa1580156114f9573d6000803e3d6000fd5b505050506040513d602081101561150f57600080fd5b505190508061151c575060155b60008211801561152c5750808211155b61156b576040805162461bcd60e51b815260206004820152600b60248201526a1b9bdd0818d8589a5b995d60aa1b604482015290519081900360640190fd5b604080516001600160a01b038087166020808401919091529086168284015282518083038401815260608301808552815191909201207710d05390d15317d514905394d1915497d41493d413d4d05360421b90915291519081900360780190206000906115d89083614153565b9050801561164a5760408051630911a2c160e11b81526001600160a01b03888116600483015287166024820152905161100491631223458291604480830192600092919082900301818387803b15801561163157600080fd5b505af1158015611645573d6000803e3d6000fd5b505050505b505050505050565b604080516f14d554d411539117d41493d413d4d05360821b8152905190819003601001902081565b600281565b600c602052600090815260409020805460019091015461ffff8216916201000090046001600160801b03169083565b604080516e149153d4115397d41493d413d4d053608a1b8152905190819003600f01902081565b6005602052600090815260409020546001600160a01b031681565b61100581565b601081565b60035481565b61100881565b600b81565b60005460ff16611751576040805162461bcd60e51b81526020600482015260196024820152600080516020614a4c833981519152604482015290519081900360640190fd5b60408051630a83aaa960e31b815233600482015290516110069163541d5548916024808301926020929190829003018186803b15801561179057600080fd5b505afa1580156117a4573d6000803e3d6000fd5b505050506040513d60208110156117ba57600080fd5b505161180d576040805162461bcd60e51b815260206004820152601f60248201527f746865206d73672073656e646572206973206e6f7420612072656c6179657200604482015290519081900360640190fd5b73b005741528b86f5952469d80a8614591e3c5b632331480611842575073446aa6e0dc65690403df3f127750da1322941f3e33145b61187d5760405162461bcd60e51b815260040180806020018281038252602a8152602001806149f0602a913960400191505060405180910390fd5b60ff8116600090815260086020526040902054829082906001600160401b0390811690831681146118ed576040805162461bcd60e51b815260206004820152601560248201527439b2b8bab2b731b2903737ba1034b71037b93232b960591b604482015290519081900360640190fd5b60ff8216600090815260086020908152604091829020805467ffffffffffffffff1916600185016001600160401b039081169190911790915582516337d7f9c160e21b81529089166004820152915188926110039263df5fe70492602480840193829003018186803b15801561196257600080fd5b505afa158015611976573d6000803e3d6000fd5b505050506040513d602081101561198c57600080fd5b50516119c95760405162461bcd60e51b8152600401808060200182810382526023815260200180614a6c6023913960400191505060405180910390fd5b60ff851660009081526005602052604090205485906001600160a01b0316611a33576040805162461bcd60e51b815260206004820152601860248201527718da185b9b995b081a5cc81b9bdd081cdd5c1c1bdc9d195960421b604482015290519081900360640190fd5b60ff86166000908152600a6020526040902054889087906001600160401b039081169083161015611a9c576040805162461bcd60e51b815260206004820152600e60248201526d3a37b79037b632103432b0b232b960911b604482015290519081900360640190fd5b60ff81166000908152600a60205260409020546001600160401b03838116911614611aee5760ff81166000908152600a60205260409020805467ffffffffffffffff19166001600160401b0384161790555b600b5460ff1615611b32576040805162461bcd60e51b81526020600482015260096024820152681cdd5cdc195b99195960ba1b604482015290519081900360640190fd5b60608e8e8080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f82011690508083019250505050505050905060608d8d8080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f820116905080830192505050505050509050611c766110036001600160a01b031663cba510a98e6040518263ffffffff1660e01b815260040180826001600160401b03166001600160401b0316815260200191505060206040518083038186803b158015611c1f57600080fd5b505afa158015611c33573d6000803e3d6000fd5b505050506040513d6020811015611c4957600080fd5b505160408051808201909152600381526269626360e81b6020820152611c6f8e8e613f45565b8585613f8d565b611cbe576040805162461bcd60e51b815260206004820152601460248201527334b73b30b634b21036b2b935b63290383937b7b360611b604482015290519081900360640190fd5b60408051631bb5062960e31b81526001600160401b038e16600482015290516000916110039163dda8314891602480820192602092909190829003018186803b158015611d0a57600080fd5b505afa158015611d1e573d6000803e3d6000fd5b505050506040513d6020811015611d3457600080fd5b505190508b8b600080806060611d4989614438565b935093509350935083611e0b578460ff16866001600160401b03167ff7b2e42d694eb1100184aae86d4245d9e46966100b1dc7e723275b98326854ac8b6040518080602001828103825283818151815260200191508051906020019080838360005b83811015611dc3578181015183820152602001611dab565b50505050905090810190601f168015611df05780820380516001836020036101000a031916815260200191505b509250505060405180910390a3505050505050505050612a26565b6040805160ff85811682529151918716916001600160401b038916917f36afdaf439a8f43fe72135135d804ae620b37a474f0943b5b85f6788312cad40919081900360200190a360ff83166123905760ff85166000818152600560209081526040808320548151631182b87560e01b815260048101958652602481019283528651604482015286516001600160a01b03909216958695631182b875958d958a9593949093606490910192918601918190849084905b83811015611ed8578181015183820152602001611ec0565b50505050905090810190601f168015611f055780820380516001836020036101000a031916815260200191505b509350505050600060405180830381600087803b158015611f2557600080fd5b505af192505050801561200957506040513d6000823e601f3d908101601f191682016040526020811015611f5857600080fd5b8101908080516040519392919084600160201b821115611f7757600080fd5b908301906020820185811115611f8c57600080fd5b8251600160201b811182820188101715611fa557600080fd5b82525081516020918201929091019080838360005b83811015611fd2578181015183820152602001611fba565b50505050905090810190601f168015611fff5780820380516001836020036101000a031916815260200191505b5060405250505060015b61231b576040516000815260443d1015612025575060006120c0565b60046000803e60005160e01c6308c379a081146120465760009150506120c0565b60043d036004833e81513d60248201116001600160401b0382111715612071576000925050506120c0565b80830180516001600160401b038111156120925760009450505050506120c0565b8060208301013d86018111156120b0576000955050505050506120c0565b601f01601f191660405250925050505b806120cb57506121dd565b60ff8716600090815260076020526040812054612102916001600160401b039091169089906120fd906002908861131c565b6144e8565b60ff8716600090815260076020908152604080832080546001600160401b038082166001011667ffffffffffffffff19909116179055805182815284518184015284516001600160a01b038716947ff91a8f63e5b3e0e89e5f93e1915a7805f3c52d9a73b3c09769785c2c7bf87acf948794849390840192918601918190849084905b8381101561219d578181015183820152602001612185565b50505050905090810190601f1680156121ca5780820380516001836020036101000a031916815260200191505b509250505060405180910390a250612316565b3d808015612207576040519150601f19603f3d011682016040523d82523d6000602084013e61220c565b606091505b5060ff871660009081526007602052604081205461223f916001600160401b039091169089906120fd906002908861131c565b60ff8716600090815260076020908152604080832080546001600160401b038082166001011667ffffffffffffffff19909116179055805182815284518184015284516001600160a01b038716947f63ac299d6332d1cc4e61b81e59bc00c0ac7c798addadf33840f1307cd2977351948794849390840192918601918190849084905b838110156122da5781810151838201526020016122c2565b50505050905090810190601f1680156123075780820380516001836020036101000a031916815260200191505b509250505060405180910390a2505b61238a565b8051156123885760ff8716600090815260076020526040812054612354916001600160401b039091169089906120fd906001908661131c565b60ff8716600090815260076020526040902080546001600160401b038082166001011667ffffffffffffffff199091161790555b505b5061295e565b60ff8316600114156126345760ff8516600081815260056020908152604080832054815163831d65d160e01b815260048101958652602481019283528651604482015286516001600160a01b0390921695869563831d65d1958d958a9593949093606490910192918601918190849084905b8381101561241a578181015183820152602001612402565b50505050905090810190601f1680156124475780820380516001836020036101000a031916815260200191505b509350505050600060405180830381600087803b15801561246757600080fd5b505af1925050508015612478575060015b61238a576040516000815260443d10156124945750600061252f565b60046000803e60005160e01c6308c379a081146124b557600091505061252f565b60043d036004833e81513d60248201116001600160401b03821117156124e05760009250505061252f565b80830180516001600160401b0381111561250157600094505050505061252f565b8060208301013d860181111561251f5760009550505050505061252f565b601f01601f191660405250925050505b8061253a575061259f565b60408051602080825283518183015283516001600160a01b038616937ff91a8f63e5b3e0e89e5f93e1915a7805f3c52d9a73b3c09769785c2c7bf87acf938693909283928301918501908083836000831561219d578181015183820152602001612185565b3d8080156125c9576040519150601f19603f3d011682016040523d82523d6000602084013e6125ce565b606091505b5060408051602080825283518183015283516001600160a01b038616937f63ac299d6332d1cc4e61b81e59bc00c0ac7c798addadf33840f1307cd297735193869390928392830191850190808383600083156122da5781810151838201526020016122c2565b60ff83166002141561295e5760ff8516600081815260056020908152604080832054815163c8509d8160e01b815260048101958652602481019283528651604482015286516001600160a01b0390921695869563c8509d81958d958a9593949093606490910192918601918190849084905b838110156126be5781810151838201526020016126a6565b50505050905090810190601f1680156126eb5780820380516001836020036101000a031916815260200191505b509350505050600060405180830381600087803b15801561270b57600080fd5b505af192505050801561271c575060015b61295c576040516000815260443d1015612738575060006127d3565b60046000803e60005160e01c6308c379a081146127595760009150506127d3565b60043d036004833e81513d60248201116001600160401b0382111715612784576000925050506127d3565b80830180516001600160401b038111156127a55760009450505050506127d3565b8060208301013d86018111156127c3576000955050505050506127d3565b601f01601f191660405250925050505b806127de5750612887565b816001600160a01b03167ff91a8f63e5b3e0e89e5f93e1915a7805f3c52d9a73b3c09769785c2c7bf87acf826040518080602001828103825283818151815260200191508051906020019080838360005b8381101561284757818101518382015260200161282f565b50505050905090810190601f1680156128745780820380516001836020036101000a031916815260200191505b509250505060405180910390a25061295c565b3d8080156128b1576040519150601f19603f3d011682016040523d82523d6000602084013e6128b6565b606091505b50816001600160a01b03167f63ac299d6332d1cc4e61b81e59bc00c0ac7c798addadf33840f1307cd2977351826040518080602001828103825283818151815260200191508051906020019080838360005b83811015612920578181015183820152602001612908565b50505050905090810190601f16801561294d5780820380516001836020036101000a031916815260200191505b509250505060405180910390a2505b505b60ff80861660009081526009602052604090205461100591636f93d2e6918a91339187911680612990575060ff881615155b604080516001600160e01b031960e088901b1681526001600160a01b039586166004820152939094166024840152604483019190915215156064820152905160848083019260209291908290030181600087803b1580156129f057600080fd5b505af1158015612a04573d6000803e3d6000fd5b505050506040513d6020811015612a1a57600080fd5b50505050505050505050505b5050505050505050505050505050565b630100380081565b600981565b61100781565b61100681565b60005460ff1681565b3361100714612a985760405162461bcd60e51b815260040180806020018281038252602e815260200180614978602e913960400191505060405180910390fd5b600b5460ff1615612adc576040805162461bcd60e51b81526020600482015260096024820152681cdd5cdc195b99195960ba1b604482015290519081900360640190fd5b612b4584848080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525050604080518082019091526012815271626174636853697a65466f724f7261636c6560701b602082015291506146829050565b15612be057604080516020601f8401819004810282018101909252828152600091612b889185858083850183828082843760009201919091525061476992505050565b90506127108111158015612b9d5750600a8110155b612bd85760405162461bcd60e51b8152600401808060200182810382526032815260200180614a1a6032913960400191505060405180910390fd5b60015561348a565b612c4984848080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152505060408051808201909152601281527118591913dc955c19185d1950da185b9b995b60721b602082015291506146829050565b15612dd157606082828080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152505082519293505060169091149050612ccc5760405162461bcd60e51b815260040180806020018281038252605a815260200180614891605a913960600191505060405180910390fd5b60018101516002820151601683015160ff82161590612cea8161476e565b612d3b576040805162461bcd60e51b815260206004820152601960248201527f61646472657373206973206e6f74206120636f6e747261637400000000000000604482015290519081900360640190fd5b60ff8416600081815260056020908152604080832080546001600160a01b0319166001600160a01b038716908117909155808452600683528184208585528352818420805460ff199081166001179091556009909352818420805490931687151517909255519092917f7e3b6af43092577ee20e60eaa1d9b114a7031305c895ee7dd3ffe17196d2e1e091a3505050505061348a565b612e3e84848080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525050604080518082019091526016815275195b98589b1953dc911a5cd8589b1950da185b9b995b60521b602082015291506146829050565b15612f6f57606082828080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152505082519293505060029091149050612ec15760405162461bcd60e51b815260040180806020018281038252604a8152602001806149a6604a913960600191505060405180910390fd5b600181810151600283015160ff80831660009081526005602052604090205492939192908316909114906001600160a01b03168015612f65576001600160a01b038116600090815260066020908152604080832060ff881680855290835292819020805460ff1916861515908117909155815190815290517fa3132e3f9819fbddc7f0ed6d38d7feef59aa95112090b7c592f5cb5bc4aa4adc929181900390910190a25b505050505061348a565b612fd384848080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152505060408051808201909152600d81526c73757370656e6451756f72756d60981b602082015291506146829050565b1561310857600281146130175760405162461bcd60e51b815260040180806020018281038252602d81526020018061491f602d913960400191505060405180910390fd5b600061305a600284848080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061476992505050565b905060008161ffff16118015613074575060648161ffff16105b6130be576040805162461bcd60e51b8152602060048201526016602482015275696e76616c69642073757370656e642071756f72756d60501b604482015290519081900360640190fd5b604080516f14d554d411539117d41493d413d4d05360821b815281519081900360100190206000908152600d60205220805461ffff90921661ffff1990921691909117905561348a565b61316b84848080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152505060408051808201909152600c81526b72656f70656e51756f72756d60a01b602082015291506146829050565b1561329e57600281146131af5760405162461bcd60e51b815260040180806020018281038252602c81526020018061494c602c913960400191505060405180910390fd5b60006131f2600284848080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061476992505050565b905060008161ffff1611801561320c575060648161ffff16105b613255576040805162461bcd60e51b8152602060048201526015602482015274696e76616c69642072656f70656e2071756f72756d60581b604482015290519081900360640190fd5b604080516e149153d4115397d41493d413d4d053608a1b8152815190819003600f0190206000908152600d60205220805461ffff90921661ffff1990921691909117905561348a565b61330984848080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152505060408051808201909152601481527363616e63656c5472616e7366657251756f72756d60601b602082015291506146829050565b1561344d576002811461334d5760405162461bcd60e51b81526004018080602001828103825260348152602001806148eb6034913960400191505060405180910390fd5b6000613390600284848080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061476992505050565b905060008161ffff161180156133aa575060648161ffff16105b6133fb576040805162461bcd60e51b815260206004820152601e60248201527f696e76616c69642063616e63656c207472616e736665722071756f72756d0000604482015290519081900360640190fd5b604080517710d05390d15317d514905394d1915497d41493d413d4d05360421b815281519081900360180190206000908152600d60205220805461ffff90921661ffff1990921691909117905561348a565b6040805162461bcd60e51b815260206004820152600d60248201526c756e6b6e6f776e20706172616d60981b604482015290519081900360640190fd5b7f6cdb0ac70ab7f2e2d035cca5be60d89906f2dede7648ddbd7402189c1eeed17a848484846040518080602001806020018381038352878782818152602001925080828437600083820152601f01601f191690910184810383528581526020019050858580828437600083820152604051601f909101601f19169092018290039850909650505050505050a150505050565b6008602052600090815260409020546001600160401b031681565b7fc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a47081565b61100281565b60005460ff166135a6576040805162461bcd60e51b81526020600482015260196024820152600080516020614a4c833981519152604482015290519081900360640190fd5b6040805163569e4ed360e11b815233600482015290516000916110009163ad3c9da691602480820192602092909190829003018186803b1580156135e957600080fd5b505afa1580156135fd573d6000803e3d6000fd5b505050506040513d602081101561361357600080fd5b505160408051633d42651560e11b8152905191925060009161100091637a84ca2a916004808301926020929190829003018186803b15801561365457600080fd5b505afa158015613668573d6000803e3d6000fd5b505050506040513d602081101561367e57600080fd5b505190508061368b575060155b60008211801561369b5750808211155b6136da576040805162461bcd60e51b815260206004820152600b60248201526a1b9bdd0818d8589a5b995d60aa1b604482015290519081900360640190fd5b600b5460ff16613721576040805162461bcd60e51b815260206004820152600d60248201526c1b9bdd081cdd5cdc195b991959609a1b604482015290519081900360640190fd5b604080516e149153d4115397d41493d413d4d053608a1b8152905190819003600f019020600090613772907fc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470614153565b905080156137b057600b805460ff1916905560405133907f899fe8c37dc61708a3aaa99c4bf143346c1d1da69af79be9e8920c0a6785b75290600090a25b505050565b600660209081526000928352604080842090915290825290205460ff1681565b6040518060400160405280600381526020016269626360e81b81525081565b610e1081565b61100381565b60005460ff1615613858576040805162461bcd60e51b815260206004820152601960248201527f74686520636f6e747261637420616c726561647920696e697400000000000000604482015290519081900360640190fd5b7f1471eb6eb2c5e789fc3de43f8ce62938c7d1836ec861730447e2ada8fd81017b80546001600160a01b0319908116611008179091557f92e85d02570a8092d09a6e3a57665bc3815a2699a4074001bf1ccabf660f5a36805460ff199081169091557fd8af288fc1c8680b4f4706064cf021e264efb6828fcaf7eb5ca36818eb365bcc8054821660019081179091557f89832631fb3c3307a103ba2c84ab569c64d6182a18893dcd163f0f1c2090733a805484166110049081179091557f6cde3cea4b3a3fb2488b2808bae7556f4a405e50f65e1794383bc026131b13c38054841690557f72e4efa1513b071517c6c74dba31b5934a81aa83cddd400e7081df5529c9943680548416831790557fa9bc9a3a348c357ba16b37005d7e6b3236198c0e939f4af8c5f19b8deeb8ebc08054851690911790557fc575c31fea594a6eb97c8e9d3f9caee4c16218c6ef37e923234c0fe9014a61e78054831690557f4e523af77f034e9810f1c94057f5e931fb3d16a51511a4c3add793617d18610580548316821790557ffb33122aa9f93cc639ebe80a7bc4784c11e6053dde89c6f4f7e268c6a623da1e805484166110001790557fc7694af312c4f286114180fd0ba6a52461fcee8a381636770b19a343af92538a80548316821790557f01112dd68e482ba8d68a7e828cff8b3abcea08eab88941953c180a7e650e9cd480548316821790557fc0a4a8be475dfebc377ebef2d7c4ff47656f572a08dd92b81017efcdba0febe1805484166110071790557f87e8a52529e8ece4ef759037313542a6429ff494a9fab9027fb79db90124eba680548316821790557f4c7666bbcb22d46469f7cc282f70764a7012dca2cce630ff8d83db9a9cdd48f080548316821790557f40f28f99a40bc9f6beea1013afdbc3cdcc689eb76b82c4de06c0acf1e1932ed58054909316611001179092557f0d9cf2cd531699eed8dd34e40ff2884a14a698c4898184fba85194e6f6772d248054821683179055600b60009081527f23f68c9bd22b8a93d06adabe17481c87c016bcbd20adc8bfd707a4d813a572176020527fdf0d5d05428057f5455c2dc8e810dd86d1e9350faa72f16bda8a45443c5b39328054831684179055603283556004805467ffffffffffffffff19166001600160401b031790556002819055600381905580549091169091179055565b6007602052600090815260409020546001600160401b031681565b60005460ff16613c17576040805162461bcd60e51b81526020600482015260196024820152600080516020614a4c833981519152604482015290519081900360640190fd5b6040805163569e4ed360e11b815233600482015290516000916110009163ad3c9da691602480820192602092909190829003018186803b158015613c5a57600080fd5b505afa158015613c6e573d6000803e3d6000fd5b505050506040513d6020811015613c8457600080fd5b505160408051633d42651560e11b8152905191925060009161100091637a84ca2a916004808301926020929190829003018186803b158015613cc557600080fd5b505afa158015613cd9573d6000803e3d6000fd5b505050506040513d6020811015613cef57600080fd5b5051905080613cfc575060155b600082118015613d0c5750808211155b613d4b576040805162461bcd60e51b815260206004820152600b60248201526a1b9bdd0818d8589a5b995d60aa1b604482015290519081900360640190fd5b600b5460ff1615613d8f576040805162461bcd60e51b81526020600482015260096024820152681cdd5cdc195b99195960ba1b604482015290519081900360640190fd5b604080516f14d554d411539117d41493d413d4d05360821b81529051908190036010019020600090613de1907fc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470614153565b905080156137b0576137b061408a565b60005460ff16613e36576040805162461bcd60e51b81526020600482015260196024820152600080516020614a4c833981519152604482015290519081900360640190fd5b33600090815260066020908152604080832060ff8089168552925290912054859116613e935760405162461bcd60e51b81526004018080602001828103825260318152602001806148606031913960400191505060405180910390fd5b60ff85166000908152600760209081526040808320548151601f88018490048402810184019092528682526001600160401b031692613ef89284928a926120fd92909189918c908c908190840183828082843760009201919091525061131c92505050565b60ff959095166000908152600760205260409020805467ffffffffffffffff191660019096016001600160401b03169590951790945550505050565b61100081565b600381565b61100481565b60408051600e808252818301909252606091630100380060ff851617918391602082018180368337505050600e81810187905260068201939093529182525090505b92915050565b600085613f9c57506000614081565b606082518451865160800101016040519080825280601f01601f191660200182016040528015613fd3576020820181803683370190505b5090506000613fe182614774565b602080890151825201905086600080613ff989614108565b8086526020909501949092509050614012828583614112565b9283019261401f88614108565b8086526020909501949092509050614038828583614112565b9283018a81526020019261404b87614108565b909250905061405b828583614112565b50835160200161406961477a565b60208183886065600019fa5051600114955050505050505b95945050505050565b600b5460ff16156140ce576040805162461bcd60e51b81526020600482015260096024820152681cdd5cdc195b99195960ba1b604482015290519081900360640190fd5b600b805460ff1916600117905560405133907f6f123d3d54c84a7960a573b31c221dcd86e13fd849c5adb0c6ca851468cc1ae490600090a2565b8051602090910191565b5b60208110614132578251825260209283019290910190601f1901614113565b915181516020939093036101000a6000190180199091169216919091179052565b6000828152600d602052604081205461ffff1661421c57604080516f14d554d411539117d41493d413d4d05360821b815281519081900360100181206000908152600d6020818152848320805461ffff199081166001179091556e149153d4115397d41493d413d4d053608a1b8552855194859003600f01852084528282528584208054821660029081179091557710d05390d15317d514905394d1915497d41493d413d4d05360421b8652865195869003601801909520845291905292902080549092161790555b6000838152600c6020526040902080546201000090046001600160801b03164210158061424d575082816001015414155b15614320576000848152600d602090815260409182902054835461ffff90911661ffff199091161771ffffffffffffffffffffffffffffffff0000191662010000610e1042016001600160801b031602178355600180840186905582519182019092523381526142c291600284019190614798565b5080546040805161ffff83168152620100009092046001600160801b0316602083015281810185905251339186917f9e109f0e55ef32e99e4880be2ec357f1ddb3469c79d0747ef4762da6e89fabe5916060908290030190a36143d4565b60005b60028201548110156143ab57336001600160a01b031682600201828154811061434857fe5b6000918252602090912001546001600160a01b031614156143a3576040805162461bcd60e51b815260206004820152601060248201526f185b1c9958591e48185c1c1c9bdd995960821b604482015290519081900360640190fd5b600101614323565b50600281018054600181018255600091825260209091200180546001600160a01b031916331790555b8054600282015461ffff9091161161442e576000848152600c60205260408120805471ffffffffffffffffffffffffffffffffffff19168155600181018290559061442260028301826147fd565b50506001915050613f87565b5060009392505050565b600080600060606021855110156144685750506040805160008082526020820190925290925082915081906144e1565b600185015160218601518651604080516020198301808252601f19600119909401939093168101602001909152604189019392916060919080156144b3576020820181803683370190505b50905060006144c182614108565b5090506144d3858260218d5103614112565b506001975091955093509150505b9193509193565b600b5460ff161561452c576040805162461bcd60e51b81526020600482015260096024820152681cdd5cdc195b99195960ba1b604482015290519081900360640190fd5b60025443111561456b576004805467ffffffffffffffff1981166001600160401b036001600793840b810190930b1617909155600355436002556145ac565b600380546001908101918290555410156145ac576004805467ffffffffffffffff1981166001600160401b036001600793840b810190930b16179091556003555b8160ff16836001600160401b0316600460009054906101000a900460070b6001600160401b03167f3a6e0fc61675aa2a100bcba0568368bb92bcec91c97673391074f11138f0cffe603885604051808361ffff1661ffff16815260200180602001828103825283818151815260200191508051906020019080838360005b8381101561464257818101518382015260200161462a565b50505050905090810190601f16801561466f5780820380516001836020036101000a031916815260200191505b50935050505060405180910390a4505050565b6000816040516020018082805190602001908083835b602083106146b75780518252601f199092019160209182019101614698565b6001836020036101000a03801982511681845116808217855250505050505090500191505060405160208183030381529060405280519060200120836040516020018082805190602001908083835b602083106147255780518252601f199092019160209182019101614706565b6001836020036101000a0380198251168184511680821785525050505050509050019150506040516020818303038152906040528051906020012014905092915050565b015190565b3b151590565b60200190565b60405180602001604052806001906020820280368337509192915050565b8280548282559060005260206000209081019282156147ed579160200282015b828111156147ed57825182546001600160a01b0319166001600160a01b039091161782556020909201916001909101906147b8565b506147f992915061481e565b5090565b508054600082559060005260206000209081019061481b9190614845565b50565b61484291905b808211156147f95780546001600160a01b0319168155600101614824565b90565b61484291905b808211156147f9576000815560010161484b56fe74686520636f6e747261637420616e64206368616e6e656c2068617665206e6f74206265656e20726567697374657265646c656e677468206f662076616c756520666f72206164644f725570646174654368616e6e656c2073686f756c642062652032322c206368616e6e656c49643a697346726f6d53797374656d3a68616e646c6572416464726573736c656e677468206f662076616c756520666f722063616e63656c5472616e7366657251756f72756d2073686f756c6420626520326c656e677468206f662076616c756520666f722073757370656e6451756f72756d2073686f756c6420626520326c656e677468206f662076616c756520666f722072656f70656e51756f72756d2073686f756c642062652032746865206d6573736167652073656e646572206d75737420626520676f7665726e616e636520636f6e74726163746c656e677468206f662076616c756520666f7220656e61626c654f7244697361626c654368616e6e656c2073686f756c6420626520322c206368616e6e656c49643a6973456e61626c65746865206d73672073656e646572206973206e6f7420612077686974656c6162656c2072656c61796572746865206e6577426174636853697a65466f724f7261636c652073686f756c6420626520696e205b31302c2031303030305d74686520636f6e7472616374206e6f7420696e697420796574000000000000006c6967687420636c69656e74206e6f742073796e632074686520626c6f636b20796574a264697066735822122041ff13fe956e0a3b951862bdc1d377a102e361a8960c89b2a595749204aba3ed64736f6c63430006040033", + }, + }, + } + + PlanckUpgrade[networkname.ChapelChainName] = &Upgrade{ + UpgradeName: "planck", + Configs: []*UpgradeConfig{ + { + ContractAddr: SlashContract, + CommitUrl: "https://github.com/bnb-chain/bsc-genesis-contract/commit/78e13b1d3a5a1b08c9208af94a9b14fc1efda213", + Code: "608060405234801561001057600080fd5b50600436106102535760003560e01c80637942fd0511610146578063ac431751116100c3578063dc927faf11610087578063dc927faf1461073b578063e1c7392a14610743578063f9a2bbc71461074b578063fc3e590814610753578063fc4333cd1461075b578063fd6a68791461076357610253565b8063ac431751146105cf578063c80d4b8f1461068d578063c81b166214610695578063c8509d811461069d578063c96be4cb1461071557610253565b80639dc092621161010a5780639dc0926214610593578063a1a11bf51461059b578063a78abc16146105a3578063ab51bb96146105bf578063ac0af629146105c757610253565b80637942fd05146104fb5780638256ace614610503578063831d65d11461050b57806396713da9146105835780639bc8e4f21461058b57610253565b80634bf6c882116101d45780636e47b482116101985780636e47b482146104d357806370fd5bad146104db578063718a8aa8146104e357806375d47a0a146104eb5780637912a65d146104f357610253565b80634bf6c8821461048b57806351e8067214610493578063567a372d1461049b5780635bfb4990146104a357806362b72cf5146104cb57610253565b806337c8dab91161021b57806337c8dab9146103ed578063389f4f711461042c5780633dffc3871461044657806343756e5c14610464578063493279b11461046c57610253565b80630bee7a67146102585780630e2374a5146102795780631182b8751461029d57806323bac5a21461038a57806335aa2e44146103d0575b600080fd5b61026061076b565b6040805163ffffffff9092168252519081900360200190f35b610281610770565b604080516001600160a01b039092168252519081900360200190f35b610315600480360360408110156102b357600080fd5b60ff8235169190810190604081016020820135600160201b8111156102d757600080fd5b8201836020820111156102e957600080fd5b803590602001918460018302840111600160201b8311171561030a57600080fd5b509092509050610776565b6040805160208082528351818301528351919283929083019185019080838360005b8381101561034f578181015183820152602001610337565b50505050905090810190601f16801561037c5780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b6103b0600480360360208110156103a057600080fd5b50356001600160a01b031661084a565b604080519384526020840192909252151582820152519081900360600190f35b610281600480360360208110156103e657600080fd5b503561086d565b6104136004803603602081101561040357600080fd5b50356001600160a01b0316610894565b6040805192835260208301919091528051918290030190f35b6104346108eb565b60408051918252519081900360200190f35b61044e6108f1565b6040805160ff9092168252519081900360200190f35b6102816108f6565b6104746108fc565b6040805161ffff9092168252519081900360200190f35b61044e610901565b610281610906565b61043461090c565b6104c9600480360360208110156104b957600080fd5b50356001600160a01b0316610912565b005b610434610a73565b610281610a79565b61044e610a7f565b61044e610a84565b610281610a89565b610434610a8f565b61044e610a94565b610413610a99565b6104c96004803603604081101561052157600080fd5b60ff8235169190810190604081016020820135600160201b81111561054557600080fd5b82018360208201111561055757600080fd5b803590602001918460018302840111600160201b8311171561057857600080fd5b509092509050610aa3565b61044e610bfd565b610434610c02565b610281610c0d565b610281610c13565b6105ab610c19565b604080519115158252519081900360200190f35b610260610c22565b610434610c27565b6104c9600480360360408110156105e557600080fd5b810190602081018135600160201b8111156105ff57600080fd5b82018360208201111561061157600080fd5b803590602001918460018302840111600160201b8311171561063257600080fd5b919390929091602081019035600160201b81111561064f57600080fd5b82018360208201111561066157600080fd5b803590602001918460018302840111600160201b8311171561068257600080fd5b509092509050610c2c565b61043461101a565b61028161101f565b6104c9600480360360408110156106b357600080fd5b60ff8235169190810190604081016020820135600160201b8111156106d757600080fd5b8201836020820111156106e957600080fd5b803590602001918460018302840111600160201b8311171561070a57600080fd5b509092509050611025565b6104c96004803603602081101561072b57600080fd5b50356001600160a01b03166110d8565b610281611659565b6104c961165f565b6102816116d0565b61044e6116d6565b6104c96116db565b610281611b66565b606481565b61200181565b606033612000146107b85760405162461bcd60e51b815260040180806020018281038252602f8152602001806125bd602f913960400191505060405180910390fd5b60005460ff166107fd576040805162461bcd60e51b81526020600482015260196024820152600080516020612619833981519152604482015290519081900360640190fd5b6040805162461bcd60e51b815260206004820152601e60248201527f7265636569766520756e65787065637465642073796e207061636b6167650000604482015290519081900360640190fd5b600260208190526000918252604090912080546001820154919092015460ff1683565b6001818154811061087a57fe5b6000918252602090912001546001600160a01b0316905081565b60008061089f612481565b5050506001600160a01b0316600090815260026020818152604092839020835160608101855281548082526001830154938201849052919093015460ff16151592909301919091529091565b60055481565b600181565b61100181565b606181565b600881565b61200081565b60045481565b33611000146109525760405162461bcd60e51b81526004018080602001828103825260308152602001806125186030913960400191505060405180910390fd5b60005460ff16610997576040805162461bcd60e51b81526020600482015260196024820152600080516020612619833981519152604482015290519081900360640190fd5b61200063f7a251d7600b6109aa84611b6c565b60006040518463ffffffff1660e01b8152600401808460ff1660ff16815260200180602001838152602001828103825284818151815260200191508051906020019080838360005b83811015610a0a5781810151838201526020016109f2565b50505050905090810190601f168015610a375780820380516001836020036101000a031916815260200191505b50945050505050600060405180830381600087803b158015610a5857600080fd5b505af1158015610a6c573d6000803e3d6000fd5b5050505050565b60035481565b61100581565b600281565b601081565b61100881565b603281565b600b81565b6004546005549091565b3361200014610ae35760405162461bcd60e51b815260040180806020018281038252602f8152602001806125bd602f913960400191505060405180910390fd5b60005460ff16610b28576040805162461bcd60e51b81526020600482015260196024820152600080516020612619833981519152604482015290519081900360640190fd5b610b306124a4565b6000610b7184848080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250611c3e92505050565b915091508015610bbb5781516040805163ffffffff9092168252517f7f0956d47419b9525356e7111652b653b530ec6f5096dccc04589bc38e6299679181900360200190a1610a6c565b81516040805163ffffffff9092168252517f7d45f62d17443dd4547bca8a8112c60e2385669318dc300ec61a5d2492f262e79181900360200190a15050505050565b600981565b662386f26fc1000081565b61100781565b61100681565b60005460ff1681565b600081565b600481565b60005460ff16610c71576040805162461bcd60e51b81526020600482015260196024820152600080516020612619833981519152604482015290519081900360640190fd5b3361100714610cb15760405162461bcd60e51b815260040180806020018281038252602e815260200180612548602e913960400191505060405180910390fd5b610d1c84848080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250506040805180820190915260148152731b5a5cd9195b59585b9bdc951a1c995cda1bdb1960621b60208201529150611cbe9050565b15610df55760208114610d605760405162461bcd60e51b81526004018080602001828103825260278152602001806124f16027913960400191505060405180910390fd5b604080516020601f8401819004810282018101909252828152600091610d9e91858580838501838280828437600092019190915250611da692505050565b905060018110158015610db2575060055481105b610ded5760405162461bcd60e51b81526004018080602001828103825260258152602001806125986025913960400191505060405180910390fd5b600455610f88565b610e5b84848080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152505060408051808201909152600f81526e19995b1bdb9e551a1c995cda1bdb19608a1b60208201529150611cbe9050565b15610f4b5760208114610e9f5760405162461bcd60e51b81526004018080602001828103825260228152602001806125766022913960400191505060405180910390fd5b604080516020601f8401819004810282018101909252828152600091610edd91858580838501838280828437600092019190915250611da692505050565b90506103e88111158015610ef2575060045481115b610f43576040805162461bcd60e51b815260206004820181905260248201527f7468652066656c6f6e795468726573686f6c64206f7574206f662072616e6765604482015290519081900360640190fd5b600555610f88565b6040805162461bcd60e51b815260206004820152600d60248201526c756e6b6e6f776e20706172616d60981b604482015290519081900360640190fd5b7f6cdb0ac70ab7f2e2d035cca5be60d89906f2dede7648ddbd7402189c1eeed17a848484846040518080602001806020018381038352878782818152602001925080828437600083820152601f01601f191690910184810383528581526020019050858580828437600083820152604051601f909101601f19169092018290039850909650505050505050a150505050565b609681565b61100281565b33612000146110655760405162461bcd60e51b815260040180806020018281038252602f8152602001806125bd602f913960400191505060405180910390fd5b60005460ff166110aa576040805162461bcd60e51b81526020600482015260196024820152600080516020612619833981519152604482015290519081900360640190fd5b6040517f07db600eebe2ac176be8dcebad61858c245a4961bb32ca2aa3d159b09aa0810e90600090a1505050565b3341146111165760405162461bcd60e51b815260040180806020018281038252602d8152602001806125ec602d913960400191505060405180910390fd5b60005460ff1661115b576040805162461bcd60e51b81526020600482015260196024820152600080516020612619833981519152604482015290519081900360640190fd5b60035443116111b1576040805162461bcd60e51b815260206004820181905260248201527f63616e206e6f7420736c61736820747769636520696e206f6e6520626c6f636b604482015290519081900360640190fd5b3a156111fb576040805162461bcd60e51b81526020600482015260146024820152736761737072696365206973206e6f74207a65726f60601b604482015290519081900360640190fd5b6040805163155853f360e21b81526001600160a01b03831660048201529051611000916355614fcc916024808301926020929190829003018186803b15801561124357600080fd5b505afa158015611257573d6000803e3d6000fd5b505050506040513d602081101561126d57600080fd5b505161127857611652565b611280612481565b506001600160a01b0381166000908152600260208181526040928390208351606081018552815481526001820154928101929092529091015460ff1615801592820192909252906112db576020810180516001019052611334565b60016040820181905260208201819052805480820182556000919091527fb10e2d527612073b26eecdfd717e6a320cf44b4afac2b0732d9fcbe2b7fa0cf60180546001600160a01b0319166001600160a01b0384161790555b43815260055460208201518161134657fe5b0661157657600060208201819052604080516335409f7f60e01b81526001600160a01b03851660048201529051611000926335409f7f926024808201939182900301818387803b15801561139957600080fd5b505af11580156113ad573d6000803e3d6000fd5b505050506120006001600160a01b031663f7a251d7600b6113cd85611b6c565b60006040518463ffffffff1660e01b8152600401808460ff1660ff16815260200180602001838152602001828103825284818151815260200191508051906020019080838360005b8381101561142d578181015183820152602001611415565b50505050905090810190601f16801561145a5780820380516001836020036101000a031916815260200191505b50945050505050600060405180830381600087803b15801561147b57600080fd5b505af192505050801561148c575060015b611571573d8080156114ba576040519150601f19603f3d011682016040523d82523d6000602084013e6114bf565b606091505b50826001600160a01b03167fd7bc86ff5d08c8ab043edec743302aba2520e6635172a428bc956721db9e2d1c8360200151836040518083815260200180602001828103825283818151815260200191508051906020019080838360005b8381101561153457818101518382015260200161151c565b50505050905090810190601f1680156115615780820380516001836020036101000a031916815260200191505b50935050505060405180910390a2505b6115ec565b60045481602001518161158557fe5b066115ec57604080516375abf10160e11b81526001600160a01b038416600482015290516110009163eb57e20291602480830192600092919082900301818387803b1580156115d357600080fd5b505af11580156115e7573d6000803e3d6000fd5b505050505b6001600160a01b0382166000818152600260208181526040808420865181559186015160018301558581015191909201805460ff1916911515919091179055517fddb6012116e51abf5436d956a4f0ebd927e92c576ff96d7918290c8782291e3e9190a2505b5043600355565b61100381565b60005460ff16156116b7576040805162461bcd60e51b815260206004820152601960248201527f74686520636f6e747261637420616c726561647920696e697400000000000000604482015290519081900360640190fd5b603260045560966005556000805460ff19166001179055565b61100081565b600381565b336110001461171b5760405162461bcd60e51b81526004018080602001828103825260308152602001806125186030913960400191505060405180910390fd5b60005460ff16611760576040805162461bcd60e51b81526020600482015260196024820152600080516020612619833981519152604482015290519081900360640190fd5b60015461176c57611b64565b600154600090600019015b808211611b38576000805b8284101561189b57611792612481565b60026000600187815481106117a357fe5b60009182526020808320909101546001600160a01b0316835282810193909352604091820190208151606081018352815481526001820154938101939093526002015460ff1615159082015260055490915060049004816020015111156118855760046005548161181057fe5b0481602001510381602001818152505080600260006001888154811061183257fe5b6000918252602080832091909101546001600160a01b0316835282810193909352604091820190208351815591830151600183015591909101516002909101805460ff191691151591909117905561188f565b600192505061189b565b50600190930192611782565b828411611a32576118aa612481565b60026000600186815481106118bb57fe5b60009182526020808320909101546001600160a01b0316835282810193909352604091820190208151606081018352815481526001820154938101939093526002015460ff1615159082015260055490915060049004816020015111156119a35760046005548161192857fe5b0481602001510381602001818152505080600260006001878154811061194a57fe5b6000918252602080832091909101546001600160a01b03168352828101939093526040918201902083518155918301516001808401919091559201516002909101805460ff19169115159190911790559150611a329050565b60026000600186815481106119b457fe5b60009182526020808320909101546001600160a01b031683528201929092526040018120818155600181810192909255600201805460ff191690558054806119f857fe5b600082815260209020810160001990810180546001600160a01b031916905501905583611a255750611a32565b506000199092019161189b565b818015611a3c5750805b15611b1b576002600060018681548110611a5257fe5b60009182526020808320909101546001600160a01b031683528201929092526040018120818155600181810192909255600201805460ff19169055805484908110611a9957fe5b600091825260209091200154600180546001600160a01b039092169186908110611abf57fe5b9060005260206000200160006101000a8154816001600160a01b0302191690836001600160a01b031602179055506001805480611af857fe5b600082815260209020810160001990810180546001600160a01b03191690550190555b82611b27575050611b38565b505060019091019060001901611777565b6040517fcfdb3b6ccaeccbdc68be3c59c840e3b3c90f0a7c491f5fff1cf56cfda200dd9c90600090a150505b565b61100481565b60408051600480825260a08201909252606091829190816020015b6060815260200190600190039081611b87579050509050611bb0836001600160a01b0316611dab565b81600081518110611bbd57fe5b6020026020010181905250611bd143611dce565b81600181518110611bde57fe5b6020908102919091010152611bf36061611dce565b81600281518110611c0057fe5b6020026020010181905250611c1442611dce565b81600381518110611c2157fe5b6020026020010181905250611c3581611de1565b9150505b919050565b611c466124a4565b6000611c506124a4565b611c586124b6565b611c69611c6486611e6b565b611e90565b90506000805b611c7883611eda565b15611cb15780611ca457611c93611c8e84611efb565b611f49565b63ffffffff16845260019150611ca9565b611cb1565b600101611c6f565b5091935090915050915091565b6000816040516020018082805190602001908083835b60208310611cf35780518252601f199092019160209182019101611cd4565b6001836020036101000a03801982511681845116808217855250505050505090500191505060405160208183030381529060405280519060200120836040516020018082805190602001908083835b60208310611d615780518252601f199092019160209182019101611d42565b6001836020036101000a038019825116818451168082178552505050505050905001915050604051602081830303815290604052805190602001201490505b92915050565b015190565b60408051600560a21b8318601482015260348101909152606090611c3581612000565b6060611da0611ddc83612056565b612000565b6060815160001415611e025750604080516000815260208101909152611c39565b606082600081518110611e1157fe5b602002602001015190506000600190505b8351811015611e5257611e4882858381518110611e3b57fe5b602002602001015161213c565b9150600101611e22565b50611c35611e65825160c060ff166121b9565b8261213c565b611e736124d6565b506040805180820190915281518152602082810190820152919050565b611e986124b6565b611ea1826122b1565b611eaa57600080fd5b6000611eb983602001516122eb565b60208085015160408051808201909152868152920190820152915050919050565b6000611ee46124d6565b505080518051602091820151919092015191011190565b611f036124d6565b611f0c82611eda565b611f1557600080fd5b60208201516000611f258261234e565b80830160209586015260408051808201909152908152938401919091525090919050565b805160009015801590611f5e57508151602110155b611f6757600080fd5b6000611f7683602001516122eb565b90508083600001511015611fd1576040805162461bcd60e51b815260206004820152601a60248201527f6c656e677468206973206c657373207468616e206f6666736574000000000000604482015290519081900360640190fd5b825160208085015183018051928490039291831015611ff757826020036101000a820491505b50949350505050565b6060815160011480156120325750607f60f81b8260008151811061202057fe5b01602001516001600160f81b03191611155b1561203e575080611c39565b611da06120508351608060ff166121b9565b8361213c565b604080516020808252818301909252606091829190602082018180368337505050602081018490529050600067ffffffffffffffff19841661209a575060186120be565b6fffffffffffffffffffffffffffffffff1984166120ba575060106120be565b5060005b60208110156120f4578181815181106120d357fe5b01602001516001600160f81b031916156120ec576120f4565b6001016120be565b60008160200390506060816040519080825280601f01601f191660200182016040528015612129576020820181803683370190505b5080830196909652508452509192915050565b6060806040519050835180825260208201818101602087015b8183101561216d578051835260209283019201612155565b50855184518101855292509050808201602086015b8183101561219a578051835260209283019201612182565b508651929092011591909101601f01601f191660405250905092915050565b6060680100000000000000008310612209576040805162461bcd60e51b815260206004820152600e60248201526d696e70757420746f6f206c6f6e6760901b604482015290519081900360640190fd5b604080516001808252818301909252606091602082018180368337019050509050603784116122635782840160f81b8160008151811061224557fe5b60200101906001600160f81b031916908160001a9053509050611da0565b606061226e85612056565b90508381510160370160f81b8260008151811061228757fe5b60200101906001600160f81b031916908160001a9053506122a8828261213c565b95945050505050565b80516000906122c257506000611c39565b6020820151805160001a9060c08210156122e157600092505050611c39565b5060019392505050565b8051600090811a6080811015612305576000915050611c39565b60b8811080612320575060c08110801590612320575060f881105b1561232f576001915050611c39565b60c08110156123435760b519019050611c39565b60f519019050611c39565b80516000908190811a6080811015612369576001915061247a565b60b881101561237e57607e198101915061247a565b60c08110156123f857600060b78203600186019550806020036101000a8651049150600181018201935050808310156123f2576040805162461bcd60e51b81526020600482015260116024820152706164646974696f6e206f766572666c6f7760781b604482015290519081900360640190fd5b5061247a565b60f881101561240d5760be198101915061247a565b600060f78203600186019550806020036101000a865104915060018101820193505080831015612478576040805162461bcd60e51b81526020600482015260116024820152706164646974696f6e206f766572666c6f7760781b604482015290519081900360640190fd5b505b5092915050565b604051806060016040528060008152602001600081526020016000151581525090565b60408051602081019091526000815290565b60405180604001604052806124c96124d6565b8152602001600081525090565b60405180604001604052806000815260200160008152509056fe6c656e677468206f66206d697364656d65616e6f725468726573686f6c64206d69736d61746368746865206d6573736167652073656e646572206d7573742062652076616c696461746f7253657420636f6e7472616374746865206d6573736167652073656e646572206d75737420626520676f7665726e616e636520636f6e74726163746c656e677468206f662066656c6f6e795468726573686f6c64206d69736d61746368746865206d697364656d65616e6f725468726573686f6c64206f7574206f662072616e6765746865206d6573736167652073656e646572206d7573742062652063726f737320636861696e20636f6e7472616374746865206d6573736167652073656e646572206d7573742062652074686520626c6f636b2070726f647563657274686520636f6e7472616374206e6f7420696e69742079657400000000000000a264697066735822122073e63503ac4253c326fb17904c6564f8471e21693509513fe7dc5277fcd239a364736f6c63430006040033", + }, + { + ContractAddr: TokenHubContract, + CommitUrl: "https://github.com/bnb-chain/bsc-genesis-contract/commit/78e13b1d3a5a1b08c9208af94a9b14fc1efda213", + Code: "6080604052600436106103c75760003560e01c806396713da9116101f2578063c81b16621161010d578063f0148472116100a0578063fc1a598f1161006f578063fc1a598f14610f25578063fc3e590814610b85578063fd6a687914610f58578063ff9c0027146107fd5761040f565b8063f014847214610ed1578063f9a2bbc714610ee6578063fa9e915914610efb578063fb063e8f14610f105761040f565b8063dc927faf116100dc578063dc927faf14610e5f578063e1c7392a14610e74578063e8f35cea14610e89578063ebf71d5314610ebc5761040f565b8063c81b166214610d8a578063c8509d8114610d9f578063cf41984414610e24578063d9e6dae91461077f5761040f565b8063aa7415f511610185578063b9fd21e311610154578063b9fd21e314610cfa578063ba35ead614610d0f578063bbface1f14610d24578063bd46646114610d575761040f565b8063aa7415f514610b9a578063ab51bb9614610be1578063ac43175114610bf6578063b99328c514610cc15761040f565b8063a1a11bf5116101c1578063a1a11bf514610b46578063a496fba214610b5b578063a78abc1614610b70578063a7c9f02d14610b855761040f565b806396713da914610ace5780639a854bbd14610ae35780639a99b4f014610af85780639dc0926214610b315761040f565b806359b92789116102e257806371d3086311610275578063831d65d111610244578063831d65d1146109d15780638b87b21f146106d45780638eff336c14610a565780639509b98014610a955761040f565b806371d3086314610968578063727be1f81461097d57806375d47a0a146109a75780637942fd05146109bc5761040f565b80636e056520116102b15780636e056520146108125780636e47b4821461093e57806370fd5bad146107fd578063718a8aa8146109535761040f565b806359b92789146107be5780635d499b1b146107e8578063613684751461077f57806366dea52a146107fd5761040f565b80633fd8b02f1161035a5780634a3acdf4116103295780634a3acdf41461076a5780634bf6c8821461077f57806350432d321461079457806351e80672146107a95761040f565b80633fd8b02f146106ff57806343756e5c1461071457806343a368b914610729578063493279b11461073e5761040f565b8063149d14d911610396578063149d14d9146105a85780632ae45483146105cf5780633d713223146106235780633dffc387146106d45761040f565b80630bee7a67146104145780630e2374a5146104425780631182b87514610473578063122345821461056d5761040f565b3661040f57341561040d576040805133815234602082015281517f6c98249d85d88c3753a04a22230f595e4dc8d3dc86c34af35deeeedc861b89db929181900390910190a15b005b600080fd5b34801561042057600080fd5b50610429610f6d565b6040805163ffffffff9092168252519081900360200190f35b34801561044e57600080fd5b50610457610f72565b604080516001600160a01b039092168252519081900360200190f35b34801561047f57600080fd5b506104f86004803603604081101561049657600080fd5b60ff8235169190810190604081016020820135600160201b8111156104ba57600080fd5b8201836020820111156104cc57600080fd5b803590602001918460018302840111600160201b831117156104ed57600080fd5b509092509050610f78565b6040805160208082528351818301528351919283929083019185019080838360005b8381101561053257818101518382015260200161051a565b50505050905090810190601f16801561055f5780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b34801561057957600080fd5b5061040d6004803603604081101561059057600080fd5b506001600160a01b03813581169160200135166110a6565b3480156105b457600080fd5b506105bd6111a0565b60408051918252519081900360200190f35b3480156105db57600080fd5b5061060a600480360360408110156105f257600080fd5b506001600160a01b03813581169160200135166111a6565b6040805192835260208301919091528051918290030190f35b34801561062f57600080fd5b506104576004803603602081101561064657600080fd5b810190602081018135600160201b81111561066057600080fd5b82018360208201111561067257600080fd5b803590602001918460018302840111600160201b8311171561069357600080fd5b91908080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152509295506111ca945050505050565b3480156106e057600080fd5b506106e96111ee565b6040805160ff9092168252519081900360200190f35b34801561070b57600080fd5b506105bd6111f3565b34801561072057600080fd5b506104576111f9565b34801561073557600080fd5b506105bd6111ff565b34801561074a57600080fd5b5061075361120b565b6040805161ffff9092168252519081900360200190f35b34801561077657600080fd5b506105bd611210565b34801561078b57600080fd5b506106e9611216565b3480156107a057600080fd5b506105bd61121b565b3480156107b557600080fd5b50610457611226565b3480156107ca57600080fd5b50610457600480360360208110156107e157600080fd5b503561122c565b3480156107f457600080fd5b506105bd611247565b34801561080957600080fd5b506106e9611250565b61092a6004803603608081101561082857600080fd5b810190602081018135600160201b81111561084257600080fd5b82018360208201111561085457600080fd5b803590602001918460208302840111600160201b8311171561087557600080fd5b919390929091602081019035600160201b81111561089257600080fd5b8201836020820111156108a457600080fd5b803590602001918460208302840111600160201b831117156108c557600080fd5b919390929091602081019035600160201b8111156108e257600080fd5b8201836020820111156108f457600080fd5b803590602001918460208302840111600160201b8311171561091557600080fd5b91935091503567ffffffffffffffff16611255565b604080519115158252519081900360200190f35b34801561094a57600080fd5b5061045761172a565b34801561095f57600080fd5b506106e9611730565b34801561097457600080fd5b506105bd611735565b34801561098957600080fd5b5061092a600480360360208110156109a057600080fd5b503561173b565b3480156109b357600080fd5b506104576117bc565b3480156109c857600080fd5b506106e96117c2565b3480156109dd57600080fd5b5061040d600480360360408110156109f457600080fd5b60ff8235169190810190604081016020820135600160201b811115610a1857600080fd5b820183602082011115610a2a57600080fd5b803590602001918460018302840111600160201b83111715610a4b57600080fd5b5090925090506117c7565b348015610a6257600080fd5b5061040d60048036036060811015610a7957600080fd5b508035906001600160a01b036020820135169060400135611910565b348015610aa157600080fd5b5061040d60048036036040811015610ab857600080fd5b506001600160a01b038135169060200135611996565b348015610ada57600080fd5b506106e9611b53565b348015610aef57600080fd5b506105bd611b58565b348015610b0457600080fd5b506105bd60048036036040811015610b1b57600080fd5b506001600160a01b038135169060200135611b64565b348015610b3d57600080fd5b50610457611ca2565b348015610b5257600080fd5b50610457611ca8565b348015610b6757600080fd5b506106e9611cae565b348015610b7c57600080fd5b5061092a611cb3565b348015610b9157600080fd5b506106e9611cbc565b61092a60048036036080811015610bb057600080fd5b5080356001600160a01b03908116916020810135909116906040810135906060013567ffffffffffffffff16611cc1565b348015610bed57600080fd5b50610429611cae565b348015610c0257600080fd5b5061040d60048036036040811015610c1957600080fd5b810190602081018135600160201b811115610c3357600080fd5b820183602082011115610c4557600080fd5b803590602001918460018302840111600160201b83111715610c6657600080fd5b919390929091602081019035600160201b811115610c8357600080fd5b820183602082011115610c9557600080fd5b803590602001918460018302840111600160201b83111715610cb657600080fd5b509092509050612382565b348015610ccd57600080fd5b5061040d60048036036040811015610ce457600080fd5b50803590602001356001600160a01b031661282a565b348015610d0657600080fd5b506105bd6128a0565b348015610d1b57600080fd5b506105bd6128aa565b348015610d3057600080fd5b506105bd60048036036020811015610d4757600080fd5b50356001600160a01b03166128b0565b348015610d6357600080fd5b506105bd60048036036020811015610d7a57600080fd5b50356001600160a01b03166128c2565b348015610d9657600080fd5b506104576128dd565b348015610dab57600080fd5b5061040d60048036036040811015610dc257600080fd5b60ff8235169190810190604081016020820135600160201b811115610de657600080fd5b820183602082011115610df857600080fd5b803590602001918460018302840111600160201b83111715610e1957600080fd5b5090925090506128e3565b348015610e3057600080fd5b5061040d60048036036040811015610e4757600080fd5b506001600160a01b03813581169160200135166129b3565b348015610e6b57600080fd5b50610457612c87565b348015610e8057600080fd5b5061040d612c8d565b348015610e9557600080fd5b506105bd60048036036020811015610eac57600080fd5b50356001600160a01b0316612d2d565b348015610ec857600080fd5b506106e9612d3f565b348015610edd57600080fd5b506106e9612d44565b348015610ef257600080fd5b50610457612d49565b348015610f0757600080fd5b506105bd612d4f565b348015610f1c57600080fd5b506105bd612d55565b348015610f3157600080fd5b506104f860048036036020811015610f4857600080fd5b50356001600160a01b0316612d63565b348015610f6457600080fd5b50610457612e8a565b606481565b61200181565b60005460609060ff16610fc0576040805162461bcd60e51b81526020600482015260196024820152600080516020615582833981519152604482015290519081900360640190fd5b33612000146110005760405162461bcd60e51b815260040180806020018281038252602f815260200180615530602f913960400191505060405180910390fd5b60ff8416600214156110525761104b83838080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250612e9092505050565b905061109f565b6040805162461bcd60e51b815260206004820152601860248201527f756e7265636f676e697a65642073796e207061636b6167650000000000000000604482015290519081900360640190fd5b9392505050565b33612000146110e65760405162461bcd60e51b815260040180806020018281038252602f815260200180615530602f913960400191505060405180910390fd5b6001600160a01b0380831660009081526007602090815260408083209385168352929052208054611151576040805162461bcd60e51b815260206004820152601060248201526f1b9bc81b1bd8dad95908185b5bdd5b9d60821b604482015290519081900360640190fd5b8054600082556040805182815290516001600160a01b0380861692908716917f152fb15aa5d80f843e1e4bd5f2fc9161714f169945024decec7e84fb910fdd519181900360200190a350505050565b60015490565b60076020908152600092835260408084209091529082529020805460019091015482565b6020818101516000908152600490915260409020546001600160a01b03165b919050565b600181565b60055481565b61100181565b670de0b6b3a764000081565b606181565b61a8c081565b600881565b66071afd498d000081565b61200081565b6000908152600460205260409020546001600160a01b031690565b6402540be40081565b600281565b6000805460ff1661129b576040805162461bcd60e51b81526020600482015260196024820152600080516020615582833981519152604482015290519081900360640190fd5b8685146112d95760405162461bcd60e51b815260040180806020018281038252603b8152602001806154f5603b913960400191505060405180910390fd5b8683146113175760405162461bcd60e51b815260040180806020018281038252603f8152602001806153c8603f913960400191505060405180910390fd5b426078018267ffffffffffffffff1610156113635760405162461bcd60e51b81526004018080602001828103825260248152602001806152b86024913960400191505060405180910390fd5b6402540be4003406156113a75760405162461bcd60e51b81526004018080602001828103825260408152602001806155f86040913960400191505060405180910390fd5b604080518681526020808802820101909152859060009081906060908480156113da578160200160208202803683370190505b50905060005b848110156114b5576402540be4008b8b838181106113fa57fe5b905060200201358161140857fe5b06156114455760405162461bcd60e51b815260040180806020018281038252603c815260200180615407603c913960400191505060405180910390fd5b61146a8b8b8381811061145457fe5b9050602002013585612fb490919063ffffffff16565b93506114966402540be4008c8c8481811061148157fe5b9050602002013561300e90919063ffffffff16565b8282815181106114a257fe5b60209081029190910101526001016113e0565b506001546114da906114cd908663ffffffff61305016565b849063ffffffff612fb416565b3410156115185760405162461bcd60e51b81526004018080602001828103825260568152602001806155a26056913960600191505060405180910390fd5b611528348463ffffffff6130a916565b91506115326150bc565b6040518060c001604052806221272160e91b60001b815260200160006001600160a01b031681526020018381526020018e8e808060200260200160405190810160405280939291908181526020018383602002808284376000920191909152505050908252506040805160208c810282810182019093528c82529283019290918d918d91829185019084908082843760009201919091525050509082525067ffffffffffffffff8916602090910152905061200063f7a251d760036115f6846130eb565b61160b876402540be40063ffffffff61300e16565b6040518463ffffffff1660e01b8152600401808460ff1660ff16815260200180602001838152602001828103825284818151815260200191508051906020019080838360005b83811015611669578181015183820152602001611651565b50505050905090810190601f1680156116965780820380516001836020036101000a031916815260200191505b50945050505050600060405180830381600087803b1580156116b757600080fd5b505af11580156116cb573d6000803e3d6000fd5b505060408051600081523360208201528082018890526060810187905290517f74eab09b0e53aefc23f2e1b16da593f95c2dd49c6f5a23720463d10d9c330b2a9350908190036080019150a15060019c9b505050505050505050505050565b61100581565b601081565b60015481565b6000336120011461177d5760405162461bcd60e51b81526004018080602001828103825260338152602001806151d66033913960400191505060405180910390fd5b81156117b4576040516120019083156108fc029084906000818181858888f193505050501580156117b2573d6000803e3d6000fd5b505b506001919050565b61100881565b600b81565b60005460ff1661180c576040805162461bcd60e51b81526020600482015260196024820152600080516020615582833981519152604482015290519081900360640190fd5b336120001461184c5760405162461bcd60e51b815260040180806020018281038252602f815260200180615530602f913960400191505060405180910390fd5b60ff83166003141561189c5761189782828080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152506133a692505050565b61190b565b7f41ce201247b6ceb957dcdb217d0b8acb50b9ea0e12af9af4f5e7f38902101605838383604051808460ff1660ff168152602001806020018281038252848482818152602001925080828437600083820152604051601f909101601f1916909201829003965090945050505050a15b505050565b33611008146119505760405162461bcd60e51b815260040180806020018281038252602381526020018061555f6023913960400191505060405180910390fd5b600083815260046020908152604080832080546001600160a01b039096166001600160a01b03199096168617905593825260038152838220949094556002909352912055565b81806001600160a01b031663893d20e86040518163ffffffff1660e01b815260040160206040518083038186803b1580156119d057600080fd5b505afa1580156119e4573d6000803e3d6000fd5b505050506040513d60208110156119fa57600080fd5b50516001600160a01b03163314611a58576040805162461bcd60e51b815260206004820152601860248201527f6e6f74206f776e6572206f6620424550323020746f6b656e0000000000000000604482015290519081900360640190fd5b60008211611aa6576040805162461bcd60e51b81526020600482015260166024820152751e995c9bc81b1a5b5a5d081b9bdd08185b1b1bddd95960521b604482015290519081900360640190fd5b6001600160a01b038316600090815260036020526040902054611afc576040805162461bcd60e51b81526020600482015260096024820152681b9bdd08189bdd5b9960ba1b604482015290519081900360640190fd5b6001600160a01b038316600081815260066020908152604091829020859055815185815291513393927f9df3a90730dbf23b5cc18dbbd5f4af3fa94a0dffb6ff6841f98a9a9a6ac626a892908290030190a3505050565b600981565b677ce66c50e284000081565b6000805460ff16611baa576040805162461bcd60e51b81526020600482015260196024820152600080516020615582833981519152604482015290519081900360640190fd5b3361100514611bea5760405162461bcd60e51b815260040180806020018281038252602f815260200180615209602f913960400191505060405180910390fd5b6000478310611bf95747611bfb565b825b9050670de0b6b3a7640000811115611c17576000915050611c9c565b8015611c99576040516001600160a01b0385169082156108fc029083906000818181858888f19350505050158015611c53573d6000803e3d6000fd5b50604080516001600160a01b03861681526020810183905281517ff8b71c64315fc33b2ead2adfa487955065152a8ac33d9d5193aafd7f45dc15a0929181900390910190a15b90505b92915050565b61100781565b61100681565b600081565b60005460ff1681565b600381565b6000805460ff16611d07576040805162461bcd60e51b81526020600482015260196024820152600080516020615582833981519152604482015290519081900360640190fd5b426078018267ffffffffffffffff161015611d535760405162461bcd60e51b81526004018080602001828103825260248152602001806152b86024913960400191505060405180910390fd5b6402540be400340615611d975760405162461bcd60e51b81526004018080602001828103825260408152602001806155f86040913960400191505060405180910390fd5b600080806001600160a01b038816611e7657600154611dbd90879063ffffffff612fb416565b341015611dfb5760405162461bcd60e51b81526004018080602001828103825260618152602001806153426061913960800191505060405180910390fd5b6402540be400860615611e3f5760405162461bcd60e51b815260040180806020018281038252603c815260200180615407603c913960400191505060405180910390fd5b611e4f348763ffffffff6130a916565b9050611e66866402540be40063ffffffff61300e16565b6221272160e91b93509150612119565b6001600160a01b038816600090815260036020526040902054925082611ecd5760405162461bcd60e51b81526004018080602001828103825260318152602001806153116031913960400191505060405180910390fd5b600154341015611f0e5760405162461bcd60e51b815260040180806020018281038252603f815260200180615464603f913960400191505060405180910390fd5b506001600160a01b0387166000908152600260205260409020543490600881111580611f595750600881118015611f595750611f57876007198301600a0a63ffffffff61340216565b155b611f945760405162461bcd60e51b815260040180806020018281038252603c815260200180615407603c913960400191505060405180910390fd5b611f9e8782613444565b9250611fa984613484565b15611ff1576305f5e100831015611ff15760405162461bcd60e51b815260040180806020018281038252603a81526020018061525a603a913960400191505060405180910390fd5b60088110158061200b575060088110801561200b57508683115b6120465760405162461bcd60e51b81526004018080602001828103825260258152602001806153a36025913960400191505060405180910390fd5b677ce66c50e284000083111561208d5760405162461bcd60e51b81526004018080602001828103825260358152602001806152dc6035913960400191505060405180910390fd5b604080516323b872dd60e01b81523360048201523060248201526044810189905290516001600160a01b038b16916323b872dd9160648083019260209291908290030181600087803b1580156120e257600080fd5b505af11580156120f6573d6000803e3d6000fd5b505050506040513d602081101561210c57600080fd5b505161211757600080fd5b505b6121216150bc565b6040805160c0810182528581526001600160a01b038b166020820152815160018082528184018452919283019181602001602082028036833750505081526040805160018082528183019092526020928301929091908083019080368337505050815260408051600180825281830190925260209283019290919080830190803683370190505081526020018767ffffffffffffffff1681525090508281604001516000815181106121cf57fe5b6020026020010181815250508781606001516000815181106121ed57fe5b60200260200101906001600160a01b031690816001600160a01b03168152505033816080015160008151811061221f57fe5b6001600160a01b039092166020928302919091019091015261200063f7a251d7600361224a846130eb565b61225f866402540be40063ffffffff61300e16565b6040518463ffffffff1660e01b8152600401808460ff1660ff16815260200180602001838152602001828103825284818151815260200191508051906020019080838360005b838110156122bd5781810151838201526020016122a5565b50505050905090810190601f1680156122ea5780820380516001836020036101000a031916815260200191505b50945050505050600060405180830381600087803b15801561230b57600080fd5b505af115801561231f573d6000803e3d6000fd5b5050604080516001600160a01b038d1681523360208201528082018b90526060810186905290517f74eab09b0e53aefc23f2e1b16da593f95c2dd49c6f5a23720463d10d9c330b2a9350908190036080019150a150600198975050505050505050565b33611007146123c25760405162461bcd60e51b815260040180806020018281038252602e8152602001806154a3602e913960400191505060405180910390fd5b60208114612417576040805162461bcd60e51b815260206004820152601b60248201527f65787065637465642076616c7565206c656e6774682069732033320000000000604482015290519081900360640190fd5b606084848080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525050604080516020601f8801819004810282018101909252868152939450606093925086915085908190840183828082843760009201919091525050505060208301519091506772656c617946656560c01b81141561251f576020820151670de0b6b3a764000081118015906124c657506402540be4008106155b612517576040805162461bcd60e51b815260206004820152601960248201527f7468652072656c6179466565206f7574206f662072616e676500000000000000604482015290519081900360640190fd5b600155612795565b61259387878080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152505060408051808201909152601781527f6c617267655472616e736665724c6f636b506572696f640000000000000000006020820152915061358a9050565b1561262f57604080516020601f87018190048102820181019092528581526000916125d69188888083850183828082843760009201919091525061367192505050565b905062093a80811115612627576040805162461bcd60e51b81526020600482015260146024820152736c6f636b20706572696f6420746f6f206c6f6e6760601b604482015290519081900360640190fd5b600555612795565b61269b87878080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525050604080518082019091526015815274189b9893185c99d9551c985b9cd9995c931a5b5a5d605a1b6020820152915061358a9050565b1561275857604080516020601f87018190048102820181019092528581526000916126de9188888083850183828082843760009201919091525061367192505050565b905068056bc75e2d631000008110156127285760405162461bcd60e51b81526004018080602001828103825260228152602001806152386022913960400191505060405180910390fd5b6000805260066020527f54cdd369e4e8a8515e52ca72ec816c2101831ad1f18bf44102ed171459c9b4f855612795565b6040805162461bcd60e51b815260206004820152600d60248201526c756e6b6e6f776e20706172616d60981b604482015290519081900360640190fd5b7f6cdb0ac70ab7f2e2d035cca5be60d89906f2dede7648ddbd7402189c1eeed17a878787876040518080602001806020018381038352878782818152602001925080828437600083820152601f01601f191690910184810383528581526020019050858580828437600083820152604051601f909101601f19169092018290039850909650505050505050a150505050505050565b336110081461286a5760405162461bcd60e51b815260040180806020018281038252602381526020018061555f6023913960400191505060405180910390fd5b600091825260046020908152604080842080546001600160a01b03191690556001600160a01b0392909216835260039052812055565b6221272160e91b81565b61c35081565b60026020526000908152604090205481565b6001600160a01b031660009081526003602052604090205490565b61100281565b60005460ff16612928576040805162461bcd60e51b81526020600482015260196024820152600080516020615582833981519152604482015290519081900360640190fd5b33612000146129685760405162461bcd60e51b815260040180806020018281038252602f815260200180615530602f913960400191505060405180910390fd5b60ff83166003141561189c5761189782828080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061367692505050565b60085460ff16600214156129ff576040805162461bcd60e51b815260206004820152600e60248201526d4e6f2072652d656e7472616e637960901b604482015290519081900360640190fd5b6008805460ff191660021790556001600160a01b0380831660009081526007602090815260408083209385168352929052208054612a77576040805162461bcd60e51b815260206004820152601060248201526f1b9bc81b1bd8dad95908185b5bdd5b9d60821b604482015290519081900360640190fd5b8060010154421015612ad0576040805162461bcd60e51b815260206004820152601760248201527f7374696c6c206f6e206c6f636b696e6720706572696f64000000000000000000604482015290519081900360640190fd5b805460008083556001600160a01b038516612b43576040516001600160a01b038516906127109084906000818181858888f193505050503d8060008114612b33576040519150601f19603f3d011682016040523d82523d6000602084013e612b38565b606091505b505080915050612bd6565b846001600160a01b031663a9059cbb61c35086856040518463ffffffff1660e01b815260040180836001600160a01b03166001600160a01b0316815260200182815260200192505050602060405180830381600088803b158015612ba657600080fd5b5087f1158015612bba573d6000803e3d6000fd5b50505050506040513d6020811015612bd157600080fd5b505190505b80612c28576040805162461bcd60e51b815260206004820152601e60248201527f776974686472617720756e6c6f636b656420746f6b656e206661696c65640000604482015290519081900360640190fd5b836001600160a01b0316856001600160a01b03167f832fc3e25f2b3e6fb0eb59419a73cba405f2a249fce75f7e31ea5a457a0323f1846040518082815260200191505060405180910390a350506008805460ff19166001179055505050565b61100381565b60005460ff1615612ce5576040805162461bcd60e51b815260206004820152601960248201527f74686520636f6e747261637420616c726561647920696e697400000000000000604482015290519081900360640190fd5b66071afd498d000060019081556000808052600260205260127fac33ff75c19e70fe83507db0d683fd3465c996598dc972688b7ace676c89077b55805460ff19169091179055565b60066020526000908152604090205481565b600481565b600581565b61100081565b61271081565b69021e19e0c9bab240000081565b6001600160a01b03811660009081526003602090815260409182902054825182815280840190935260609290918391906020820181803683375050506020810183905290506000805b60208160ff161015612df357828160ff1681518110612dc757fe5b01602001516001600160f81b03191615612de657600190910190612deb565b612df3565b600101612dac565b5060608160ff166040519080825280601f01601f191660200182016040528015612e24576020820181803683370190505b50905060005b8260ff168160ff161015612e8057838160ff1681518110612e4757fe5b602001015160f81c60f81b828260ff1681518110612e6157fe5b60200101906001600160f81b031916908160001a905350600101612e2a565b5095945050505050565b61100481565b6060612e9a615108565b6000612ea584613774565b9150915080612efb576040805162461bcd60e51b815260206004820152601f60248201527f756e7265636f676e697a6564207472616e73666572496e207061636b61676500604482015290519081900360640190fd5b6000612f06836138b3565b905063ffffffff811615612f9a576040808401516020808601516001600160a01b03166000908152600290915291822054612f419190613444565b9050612f4b61513d565b60405180608001604052808660000151815260200183815260200186608001516001600160a01b031681526020018463ffffffff168152509050612f8e81613c19565b955050505050506111e9565b505060408051600081526020810190915291506111e99050565b600082820183811015611c99576040805162461bcd60e51b815260206004820152601b60248201527f536166654d6174683a206164646974696f6e206f766572666c6f770000000000604482015290519081900360640190fd5b6000611c9983836040518060400160405280601a81526020017f536166654d6174683a206469766973696f6e206279207a65726f000000000000815250613cf5565b60008261305f57506000611c9c565b8282028284828161306c57fe5b0414611c995760405162461bcd60e51b81526004018080602001828103825260218152602001806154436021913960400191505060405180910390fd5b6000611c9983836040518060400160405280601e81526020017f536166654d6174683a207375627472616374696f6e206f766572666c6f770000815250613d97565b60408051600680825260e08201909252606091829190816020015b6060815260200190600190039081613106575050835190915061312890613df1565b8160008151811061313557fe5b602002602001018190525061315683602001516001600160a01b0316613e04565b8160018151811061316357fe5b6020026020010181905250600083604001515190506060816040519080825280602002602001820160405280156131ae57816020015b60608152602001906001900390816131995790505b50905060005b828110156131fb576131dc866040015182815181106131cf57fe5b6020026020010151613df1565b8282815181106131e857fe5b60209081029190910101526001016131b4565b5061320581613e27565b8360028151811061321257fe5b602002602001018190525060608260405190808252806020026020018201604052801561325357816020015b606081526020019060019003908161323e5790505b50905060005b838110156132a95761328a8760600151828151811061327457fe5b60200260200101516001600160a01b0316613e04565b82828151811061329657fe5b6020908102919091010152600101613259565b506132b381613e27565b846003815181106132c057fe5b602002602001018190525060608360405190808252806020026020018201604052801561330157816020015b60608152602001906001900390816132ec5790505b50905060005b84811015613341576133228860800151828151811061327457fe5b82828151811061332e57fe5b6020908102919091010152600101613307565b5061334b81613e27565b8560048151811061335857fe5b602002602001018190525061337a8760a0015167ffffffffffffffff16613df1565b8560058151811061338757fe5b602002602001018190525061339b85613e27565b979650505050505050565b6133ae615164565b60006133b983613eb1565b91509150806133f95760405162461bcd60e51b81526004018080602001828103825260248152602001806154d16024913960400191505060405180910390fd5b61190b8261407c565b6000611c9983836040518060400160405280601881526020017f536166654d6174683a206d6f64756c6f206279207a65726f0000000000000000815250614500565b6000600882111561346d57613466836007198401600a0a63ffffffff61300e16565b9050611c9c565b611c99836008849003600a0a63ffffffff61305016565b604080516020808252818301909252600091606091906020820181803683375050506020810184905290506000805b60208160ff1610156134fa57828160ff16815181106134ce57fe5b01602001516001600160f81b031916156134ed576001909101906134f2565b6134fa565b6001016134b3565b50600760ff82161015613512576000925050506111e9565b816005820360ff168151811061352457fe5b6020910101516001600160f81b031916602d60f81b14613549576000925050506111e9565b816001820360ff168151811061355b57fe5b6020910101516001600160f81b031916604d60f81b14613580576000925050506111e9565b5060019392505050565b6000816040516020018082805190602001908083835b602083106135bf5780518252601f1990920191602091820191016135a0565b6001836020036101000a03801982511681845116808217855250505050505090500191505060405160208183030381529060405280519060200120836040516020018082805190602001908083835b6020831061362d5780518252601f19909201916020918201910161360e565b6001836020036101000a0380198251168184511680821785525050505050509050019150506040516020818303038152906040528051906020012014905092915050565b015190565b61367e6150bc565b600061368983614562565b91509150806136c95760405162461bcd60e51b81526004018080602001828103825260248152602001806152946024913960400191505060405180910390fd5b6136d1615164565b602080840180516001600160a01b0390811684526040808701518585015291511660009081526002909252812054905b8460400151518110156137525761372f8560400151828151811061372157fe5b6020026020010151836147c6565b8560400151828151811061373f57fe5b6020908102919091010152600101613701565b50608084015160408301526005606083015261376d8261407c565b5050505050565b61377c615108565b6000613786615108565b61378e61519b565b61379f61379a866147ff565b614824565b90506000805b6137ae8361486e565b156138a657806137d0576137c96137c48461488f565b6148dd565b845261389e565b80600114156137fd576137ea6137e58461488f565b614994565b6001600160a01b0316602085015261389e565b806002141561381c576138126137c48461488f565b604085015261389e565b8060031415613844576138316137e58461488f565b6001600160a01b0316606085015261389e565b806004141561386c576138596137e58461488f565b6001600160a01b0316608085015261389e565b8060051415613899576138816137c48461488f565b67ffffffffffffffff1660a08501526001915061389e565b6138a6565b6001016137a5565b5091935090915050915091565b60208101516000906001600160a01b03166139f7578160a0015167ffffffffffffffff164211156138e6575060016111e9565b81604001514710156138fa575060036111e9565b613903826149ae565b61397857606082015160408084015190516000926001600160a01b0316916127109184818181858888f193505050503d806000811461395e576040519150601f19603f3d011682016040523d82523d6000602084013e613963565b606091505b50509050806139765750600490506111e9565b505b7f471eb9cc1ffe55ffadf15b32595415eb9d80f22e761d24bd6dffc607e1284d5982602001518360600151846040015160405180846001600160a01b03166001600160a01b03168152602001836001600160a01b03166001600160a01b03168152602001828152602001935050505060405180910390a15060006111e9565b8160a0015167ffffffffffffffff16421115613a15575060016111e9565b81516020808401516001600160a01b031660009081526003909152604090205414613a42575060026111e9565b602080830151604080516370a0823160e01b815230600482015290516000936001600160a01b03909316926370a082319261c3509260248083019392829003018187803b158015613a9257600080fd5b5086fa158015613aa6573d6000803e3d6000fd5b50505050506040513d6020811015613abd57600080fd5b50516040840151909150811015613ad85750600390506111e9565b613ae1836149ae565b613b9857600083602001516001600160a01b031663a9059cbb61c350866060015187604001516040518463ffffffff1660e01b815260040180836001600160a01b03166001600160a01b0316815260200182815260200192505050602060405180830381600088803b158015613b5657600080fd5b5087f1158015613b6a573d6000803e3d6000fd5b50505050506040513d6020811015613b8157600080fd5b5051905080613b965750600591506111e99050565b505b7f471eb9cc1ffe55ffadf15b32595415eb9d80f22e761d24bd6dffc607e1284d5983602001518460600151856040015160405180846001600160a01b03166001600160a01b03168152602001836001600160a01b03166001600160a01b03168152602001828152602001935050505060405180910390a150600090506111e9565b60408051600480825260a08201909252606091829190816020015b6060815260200190600190039081613c345750508351909150613c5690613df1565b81600081518110613c6357fe5b6020026020010181905250613c7b8360200151613df1565b81600181518110613c8857fe5b6020026020010181905250613ca983604001516001600160a01b0316613e04565b81600281518110613cb657fe5b6020026020010181905250613cd4836060015163ffffffff16613df1565b81600381518110613ce157fe5b602002602001018190525061109f81613e27565b60008183613d815760405162461bcd60e51b81526004018080602001828103825283818151815260200191508051906020019080838360005b83811015613d46578181015183820152602001613d2e565b50505050905090810190601f168015613d735780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b506000838581613d8d57fe5b0495945050505050565b60008184841115613de95760405162461bcd60e51b8152602060048201818152835160248401528351909283926044909101919085019080838360008315613d46578181015183820152602001613d2e565b505050900390565b6060611c9c613dff83614b1c565b614c02565b60408051600560a21b831860148201526034810190915260609061109f81614c02565b6060815160001415613e4857506040805160008152602081019091526111e9565b606082600081518110613e5757fe5b602002602001015190506000600190505b8351811015613e9857613e8e82858381518110613e8157fe5b6020026020010151614c54565b9150600101613e68565b5061109f613eab825160c060ff16614cd1565b82614c54565b613eb9615164565b6000613ec3615164565b613ecb61519b565b613ed761379a866147ff565b90506000805b613ee68361486e565b156138a65780613f0c57613efc6137e58461488f565b6001600160a01b03168452614074565b8060011415613fad576060613f28613f238561488f565b614dc9565b90508051604051908082528060200260200182016040528015613f55578160200160208202803683370190505b50602086015260005b8151811015613fa657613f83828281518110613f7657fe5b60200260200101516148dd565b86602001518281518110613f9357fe5b6020908102919091010152600101613f5e565b5050614074565b806002141561404f576060613fc4613f238561488f565b90508051604051908082528060200260200182016040528015613ff1578160200160208202803683370190505b50604086015260005b8151811015613fa65761401f82828151811061401257fe5b6020026020010151614994565b8660400151828151811061402f57fe5b6001600160a01b0390921660209283029190910190910152600101613ffa565b8060031415613899576140646137c48461488f565b63ffffffff166060850152600191505b600101613edd565b80516001600160a01b03166142a65760005b8160200151518110156142a0576000826040015182815181106140ad57fe5b60200260200101516001600160a01b0316612710846020015184815181106140d157fe5b60209081029190910101516040516000818181858888f193505050503d8060008114614119576040519150601f19603f3d011682016040523d82523d6000602084013e61411e565b606091505b50509050806141e1577f203f9f67a785f4f81be4d48b109aa0c498d1bc8097ecc2627063f480cc5fe73e83600001518460400151848151811061415d57fe5b60200260200101518560200151858151811061417557fe5b6020026020010151866060015160405180856001600160a01b03166001600160a01b03168152602001846001600160a01b03166001600160a01b031681526020018381526020018263ffffffff1663ffffffff16815260200194505050505060405180910390a1614297565b7fd468d4fa5e8fb4adc119b29a983fd0785e04af5cb8b7a3a69a47270c54b6901a83600001518460400151848151811061421757fe5b60200260200101518560200151858151811061422f57fe5b6020026020010151866060015160405180856001600160a01b03166001600160a01b03168152602001846001600160a01b03166001600160a01b031681526020018381526020018263ffffffff1663ffffffff16815260200194505050505060405180910390a15b5060010161408e565b506144fd565b60005b8160200151518110156144fb57600082600001516001600160a01b031663a9059cbb61c350856040015185815181106142de57fe5b6020026020010151866020015186815181106142f657fe5b60200260200101516040518463ffffffff1660e01b815260040180836001600160a01b03166001600160a01b0316815260200182815260200192505050602060405180830381600088803b15801561434d57600080fd5b5087f1158015614361573d6000803e3d6000fd5b50505050506040513d602081101561437857600080fd5b50519050801561443c577fd468d4fa5e8fb4adc119b29a983fd0785e04af5cb8b7a3a69a47270c54b6901a8360000151846040015184815181106143b857fe5b6020026020010151856020015185815181106143d057fe5b6020026020010151866060015160405180856001600160a01b03166001600160a01b03168152602001846001600160a01b03166001600160a01b031681526020018381526020018263ffffffff1663ffffffff16815260200194505050505060405180910390a16144f2565b7f203f9f67a785f4f81be4d48b109aa0c498d1bc8097ecc2627063f480cc5fe73e83600001518460400151848151811061447257fe5b60200260200101518560200151858151811061448a57fe5b6020026020010151866060015160405180856001600160a01b03166001600160a01b03168152602001846001600160a01b03166001600160a01b031681526020018381526020018263ffffffff1663ffffffff16815260200194505050505060405180910390a15b506001016142a9565b505b50565b6000818361454f5760405162461bcd60e51b8152602060048201818152835160248401528351909283926044909101919085019080838360008315613d46578181015183820152602001613d2e565b5082848161455957fe5b06949350505050565b61456a6150bc565b60006145746150bc565b61457c61519b565b61458861379a866147ff565b90506000805b6145978361486e565b156138a657806145b4576145ad6137c48461488f565b84526147be565b80600114156145dc576145c96137e58461488f565b6001600160a01b031660208501526147be565b806002141561466b5760606145f3613f238561488f565b90508051604051908082528060200260200182016040528015614620578160200160208202803683370190505b50604086015260005b815181101561466457614641828281518110613f7657fe5b8660400151828151811061465157fe5b6020908102919091010152600101614629565b50506147be565b8060031415614700576060614682613f238561488f565b905080516040519080825280602002602001820160405280156146af578160200160208202803683370190505b50606086015260005b8151811015614664576146d082828151811061401257fe5b866060015182815181106146e057fe5b6001600160a01b03909216602092830291909101909101526001016146b8565b8060041415614795576060614717613f238561488f565b90508051604051908082528060200260200182016040528015614744578160200160208202803683370190505b50608086015260005b81518110156146645761476582828151811061401257fe5b8660800151828151811061477557fe5b6001600160a01b039092166020928302919091019091015260010161474d565b8060051415613899576147aa6137c48461488f565b67ffffffffffffffff1660a0850152600191505b60010161458e565b600060088211156147e857613466836007198401600a0a63ffffffff61305016565b611c99836008849003600a0a63ffffffff61300e16565b6148076151bb565b506040805180820190915281518152602082810190820152919050565b61482c61519b565b61483582614e9a565b61483e57600080fd5b600061484d8360200151614eca565b60208085015160408051808201909152868152920190820152915050919050565b60006148786151bb565b505080518051602091820151919092015191011190565b6148976151bb565b6148a08261486e565b6148a957600080fd5b602082015160006148b982614f2d565b80830160209586015260408051808201909152908152938401919091525090919050565b8051600090158015906148f257508151602110155b6148fb57600080fd5b600061490a8360200151614eca565b90508083600001511015614965576040805162461bcd60e51b815260206004820152601a60248201527f6c656e677468206973206c657373207468616e206f6666736574000000000000604482015290519081900360640190fd5b82516020808501518301805192849003929183101561498b57826020036101000a820491505b50949350505050565b80516000906015146149a557600080fd5b611c9c826148dd565b600080805260066020527f54cdd369e4e8a8515e52ca72ec816c2101831ad1f18bf44102ed171459c9b4f8541580156149e75750600554155b15614a295760008052600660205269021e19e0c9bab24000007f54cdd369e4e8a8515e52ca72ec816c2101831ad1f18bf44102ed171459c9b4f85561a8c06005555b6020808301516001600160a01b0316600090815260069091526040902054801580614a575750808360400151105b15614a665760009150506111e9565b6020808401516001600160a01b039081166000908152600783526040808220606088015190931682529190925290819020908401518154614aac9163ffffffff612fb416565b8155600554420160018201819055606085015160208087015160408089015181519081529283019490945283516001600160a01b039384169493909116927f3fb83143cd331170da18fb1e8564d97e8ec39264b6ecb1ba248ea7596ab07258928290030190a35060019392505050565b604080516020808252818301909252606091829190602082018180368337505050602081018490529050600067ffffffffffffffff198416614b6057506018614b84565b6fffffffffffffffffffffffffffffffff198416614b8057506010614b84565b5060005b6020811015614bba57818181518110614b9957fe5b01602001516001600160f81b03191615614bb257614bba565b600101614b84565b60008160200390506060816040519080825280601f01601f191660200182016040528015614bef576020820181803683370190505b5080830196909652508452509192915050565b606081516001148015614c345750607f60f81b82600081518110614c2257fe5b01602001516001600160f81b03191611155b15614c405750806111e9565b611c9c614c528351608060ff16614cd1565b835b6060806040519050835180825260208201818101602087015b81831015614c85578051835260209283019201614c6d565b50855184518101855292509050808201602086015b81831015614cb2578051835260209283019201614c9a565b508651929092011591909101601f01601f191660405250905092915050565b6060680100000000000000008310614d21576040805162461bcd60e51b815260206004820152600e60248201526d696e70757420746f6f206c6f6e6760901b604482015290519081900360640190fd5b60408051600180825281830190925260609160208201818036833701905050905060378411614d7b5782840160f81b81600081518110614d5d57fe5b60200101906001600160f81b031916908160001a9053509050611c9c565b6060614d8685614b1c565b90508381510160370160f81b82600081518110614d9f57fe5b60200101906001600160f81b031916908160001a905350614dc08282614c54565b95945050505050565b6060614dd482614e9a565b614ddd57600080fd5b6000614de883615060565b9050606081604051908082528060200260200182016040528015614e2657816020015b614e136151bb565b815260200190600190039081614e0b5790505b5090506000614e388560200151614eca565b60208601510190506000805b84811015614e8f57614e5583614f2d565b9150604051806040016040528083815260200184815250848281518110614e7857fe5b602090810291909101015291810191600101614e44565b509195945050505050565b8051600090614eab575060006111e9565b6020820151805160001a9060c0821015613580576000925050506111e9565b8051600090811a6080811015614ee45760009150506111e9565b60b8811080614eff575060c08110801590614eff575060f881105b15614f0e5760019150506111e9565b60c0811015614f225760b5190190506111e9565b60f5190190506111e9565b80516000908190811a6080811015614f485760019150615059565b60b8811015614f5d57607e1981019150615059565b60c0811015614fd757600060b78203600186019550806020036101000a865104915060018101820193505080831015614fd1576040805162461bcd60e51b81526020600482015260116024820152706164646974696f6e206f766572666c6f7760781b604482015290519081900360640190fd5b50615059565b60f8811015614fec5760be1981019150615059565b600060f78203600186019550806020036101000a865104915060018101820193505080831015615057576040805162461bcd60e51b81526020600482015260116024820152706164646974696f6e206f766572666c6f7760781b604482015290519081900360640190fd5b505b5092915050565b8051600090615071575060006111e9565b600080905060006150858460200151614eca565b602085015185519181019250015b808210156150b3576150a482614f2d565b60019093019290910190615093565b50909392505050565b6040518060c001604052806000801916815260200160006001600160a01b03168152602001606081526020016060815260200160608152602001600067ffffffffffffffff1681525090565b6040805160c081018252600080825260208201819052918101829052606081018290526080810182905260a081019190915290565b60408051608081018252600080825260208201819052918101829052606081019190915290565b604051806080016040528060006001600160a01b031681526020016060815260200160608152602001600063ffffffff1681525090565b60405180604001604052806151ae6151bb565b8152602001600081525090565b60405180604001604052806000815260200160008152509056fe6f6e6c79207374616b696e672073797374656d20636f6e74726163742063616e2063616c6c20746869732066756e6374696f6e746865206d6573736167652073656e646572206d75737420626520696e63656e746976697a6520636f6e7472616374626e62206c61726765207472616e73666572206c696d697420746f6f20736d616c6c466f72206d696e69546f6b656e2c20746865207472616e7366657220616d6f756e74206d757374206e6f74206265206c657373207468616e2031756e7265636f676e697a6564207472616e736665724f75742073796e207061636b61676565787069726554696d65206d7573742062652074776f206d696e75746573206c61746572616d6f756e7420697320746f6f206c617267652c20657863656564206d6178696d756d206265703220746f6b656e20616d6f756e7474686520636f6e747261637420686173206e6f74206265656e20626f756e6420746f20616e79206265703220746f6b656e726563656976656420424e4220616d6f756e742073686f756c64206265206e6f206c657373207468616e207468652073756d206f66207472616e736665724f757420424e4220616d6f756e7420616e64206d696e696d756d2072656c6179466565616d6f756e7420697320746f6f206c617267652c2075696e74323536206f766572666c6f774c656e677468206f6620726563697069656e74416464727320646f65736e277420657175616c20746f206c656e677468206f6620726566756e644164647273696e76616c6964207472616e7366657220616d6f756e743a20707265636973696f6e206c6f737320696e20616d6f756e7420636f6e76657273696f6e536166654d6174683a206d756c7469706c69636174696f6e206f766572666c6f77726563656976656420424e4220616d6f756e742073686f756c64206265206e6f206c657373207468616e20746865206d696e696d756d2072656c6179466565746865206d6573736167652073656e646572206d75737420626520676f7665726e616e636520636f6e7472616374756e7265636f676e697a6564207472616e736665724f75742061636b207061636b6167654c656e677468206f6620726563697069656e74416464727320646f65736e277420657175616c20746f206c656e677468206f6620616d6f756e7473746865206d6573736167652073656e646572206d7573742062652063726f737320636861696e20636f6e7472616374746865206d73672073656e646572206d75737420626520746f6b656e4d616e6167657274686520636f6e7472616374206e6f7420696e69742079657400000000000000726563656976656420424e4220616d6f756e742073686f756c64206265206e6f206c657373207468616e207468652073756d206f66207472616e7366657220424e4220616d6f756e7420616e642072656c6179466565696e76616c696420726563656976656420424e4220616d6f756e743a20707265636973696f6e206c6f737320696e20616d6f756e7420636f6e76657273696f6ea2646970667358221220ef72e8713245ba000d1e9efd85d005317b64710a26d7b67a7649bda481a927d064736f6c63430006040033", + }, + { + ContractAddr: CrossChainContract, + CommitUrl: "https://github.com/bnb-chain/bsc-genesis-contract/commit/78e13b1d3a5a1b08c9208af94a9b14fc1efda213", + Code: "608060405234801561001057600080fd5b50600436106103995760003560e01c8063718a8aa8116101e9578063c27cdcfb1161010f578063dc927faf116100ad578063f7a251d71161007c578063f7a251d714610b2f578063f9a2bbc714610ba7578063fc3e590814610baf578063fd6a687914610bb757610399565b8063dc927faf14610af7578063e1c7392a14610aff578063e3b0480514610b07578063e6400bbe14610b2757610399565b8063ccc108d7116100e9578063ccc108d714610ab0578063d31f968d14610ab8578063d76a867514610ae7578063dc40433114610aef57610399565b8063c27cdcfb14610a80578063c780e9de14610aa0578063c81b166214610aa857610399565b80638cc8f56111610187578063a78abc1611610156578063a78abc16146109b2578063ab51bb96146109ba578063ac431751146109c2578063b0355f5b1461078157610399565b80638cc8f5611461088757806396713da91461099a5780639dc09262146109a2578063a1a11bf5146109aa57610399565b806375d47a0a116101c357806375d47a0a146108a75780637942fd05146108af57806384013b6a146108b7578063863fe4ab1461099257610399565b8063718a8aa81461088f578063719482d51461089757806374f079b81461089f57610399565b8063422f9050116102ce57806363e1394e1161026c5780636de380bd1161023b5780636de380bd146108575780636e47a51a1461085f5780636e47b4821461087f57806370fd5bad1461088757610399565b806363e1394e146107ff5780636a3cb34d146108075780636bacff2c1461080f5780636c46aa681461080757610399565b80634bf6c882116102a85780634bf6c882146107b957806351e80672146107c15780635692ddd3146107c95780635f832177146107d157610399565b8063422f90501461078957806343756e5c146107a9578063493279b1146107b157610399565b8063299b533d1161033b578063308325f411610315578063308325f4146106155780633a648b151461061d5780633bdc47a6146106595780633dffc3871461078157610399565b8063299b533d146105a35780632af6f399146105d75780632ff32aea146105f457610399565b806314b3023b1161037757806314b3023b146104015780631d1309351461041b5780631e275ae11461043757806322556cdc1461059b57610399565b806305e682581461039e5780630bee7a67146103bc5780630e2374a5146103dd575b600080fd5b6103a6610bbf565b6040805160ff9092168252519081900360200190f35b6103c4610bc4565b6040805163ffffffff9092168252519081900360200190f35b6103e5610bc9565b604080516001600160a01b039092168252519081900360200190f35b610409610bcf565b60408051918252519081900360200190f35b610423610bd5565b604080519115158252519081900360200190f35b610599600480360361010081101561044e57600080fd5b81018160a081016080820135600160201b81111561046b57600080fd5b82018360208201111561047d57600080fd5b803590602001918460018302840111600160201b8311171561049e57600080fd5b919390929091602081019035600160201b8111156104bb57600080fd5b8201836020820111156104cd57600080fd5b803590602001918460018302840111600160201b831117156104ee57600080fd5b919390929091602081019035600160201b81111561050b57600080fd5b82018360208201111561051d57600080fd5b803590602001918460018302840111600160201b8311171561053e57600080fd5b919390929091602081019035600160201b81111561055b57600080fd5b82018360208201111561056d57600080fd5b803590602001918460018302840111600160201b8311171561058e57600080fd5b509092509050610bde565b005b6104096112c2565b6105c0600480360360208110156105b957600080fd5b50356112c7565b6040805161ffff9092168252519081900360200190f35b610423600480360360208110156105ed57600080fd5b50356112dd565b6105fc6112f2565b60408051600792830b90920b8252519081900360200190f35b6104096112fb565b61063d6004803603602081101561063357600080fd5b503560ff16611301565b604080516001600160401b039092168252519081900360200190f35b61070c6004803603606081101561066f57600080fd5b60ff82351691602081013591810190606081016040820135600160201b81111561069857600080fd5b8201836020820111156106aa57600080fd5b803590602001918460018302840111600160201b831117156106cb57600080fd5b91908080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525092955061131c945050505050565b6040805160208082528351818301528351919283929083019185019080838360005b8381101561074657818101518382015260200161072e565b50505050905090810190601f1680156107735780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b6103a6611392565b6104236004803603602081101561079f57600080fd5b503560ff16611397565b6103e56113ac565b6105c06113b2565b6103a66113b7565b6103e56113bc565b6104096113c2565b610599600480360360408110156107e757600080fd5b506001600160a01b03813581169160200135166113f2565b610409611652565b6105c061167a565b61082c6004803603602081101561082557600080fd5b503561167f565b6040805161ffff90941684526001600160801b03909216602084015282820152519081900360600190f35b6104096116ae565b6103e56004803603602081101561087557600080fd5b503560ff166116d5565b6103e56116f0565b6103a661167a565b6103a66116f6565b6105c0611392565b6104096116fb565b6103e5611701565b6103a6611707565b610599600480360360a08110156108cd57600080fd5b810190602081018135600160201b8111156108e757600080fd5b8201836020820111156108f957600080fd5b803590602001918460018302840111600160201b8311171561091a57600080fd5b919390929091602081019035600160201b81111561093757600080fd5b82018360208201111561094957600080fd5b803590602001918460018302840111600160201b8311171561096a57600080fd5b919350915080356001600160401b03908116916020810135909116906040013560ff1661170c565b610409612a36565b6103a6612a3e565b6103e5612a43565b6103e5612a49565b610423612a4f565b6103c4610bbf565b610599600480360360408110156109d857600080fd5b810190602081018135600160201b8111156109f257600080fd5b820183602082011115610a0457600080fd5b803590602001918460018302840111600160201b83111715610a2557600080fd5b919390929091602081019035600160201b811115610a4257600080fd5b820183602082011115610a5457600080fd5b803590602001918460018302840111600160201b83111715610a7557600080fd5b509092509050612a58565b61063d60048036036020811015610a9657600080fd5b503560ff1661351c565b610409613537565b6103e561355b565b610599613561565b61042360048036036040811015610ace57600080fd5b5080356001600160a01b0316906020013560ff166137b5565b61070c6137d5565b6104096137f4565b6103e56137fa565b610599613800565b61063d60048036036020811015610b1d57600080fd5b503560ff16613bb7565b610599613bd2565b61059960048036036060811015610b4557600080fd5b60ff8235169190810190604081016020820135600160201b811115610b6957600080fd5b820183602082011115610b7b57600080fd5b803590602001918460018302840111600160201b83111715610b9c57600080fd5b919350915035613df1565b6103e5613f34565b6103a6613f3a565b6103e5613f3f565b600081565b606481565b61200181565b60015481565b600b5460ff1681565b60005460ff16610c23576040805162461bcd60e51b81526020600482015260196024820152600080516020614a4c833981519152604482015290519081900360640190fd5b604080516337d7f9c160e21b81526001600160401b038b35166004820181905291516110039163df5fe704916024808301926020929190829003018186803b158015610c6e57600080fd5b505afa158015610c82573d6000803e3d6000fd5b505050506040513d6020811015610c9857600080fd5b5051610cd55760405162461bcd60e51b8152600401808060200182810382526023815260200180614a6c6023913960400191505060405180910390fd5b604080516337d7f9c160e21b815260208c8101356001600160401b03166004830181905292516110039263df5fe704926024808301939192829003018186803b158015610d2157600080fd5b505afa158015610d35573d6000803e3d6000fd5b505050506040513d6020811015610d4b57600080fd5b5051610d885760405162461bcd60e51b8152600401808060200182810382526023815260200180614a6c6023913960400191505060405180910390fd5b60608b013560ff81166000908152600560205260409020546001600160401b03909116906001600160a01b0316610e01576040805162461bcd60e51b815260206004820152601860248201527718da185b9b995b081a5cc81b9bdd081cdd5c1c1bdc9d195960421b604482015290519081900360640190fd5b600b5460ff1615610e45576040805162461bcd60e51b81526020600482015260096024820152681cdd5cdc195b99195960ba1b604482015290519081900360640190fd5b8888604051808383808284376040519201829003822094508f93508e9250819050838380828437808301925050509250505060405180910390201415610ec1576040805162461bcd60e51b815260206004820152600c60248201526b1cd85b59481c185e5b1bd85960a21b604482015290519081900360640190fd5b60606001600160401b0360408e01358116908e83013516610ee28282613f45565b80516020808301919091206000818152600e9092526040909120549194509060ff1615610f4b576040805162461bcd60e51b8152602060048201526012602482015271185b1c9958591e4818da185b1b195b99d95960721b604482015290519081900360640190fd5b6000908152600e60205260408120805460ff191660011790558f8160200201356001600160401b0316905060608f8f8080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f82011690508083019250505050505050905060608c8c8080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201829052506040805163cba510a960e01b81526001600160401b038a16600482015290519596509094611003945063cba510a9935060248083019350602092829003018186803b15801561104157600080fd5b505afa158015611055573d6000803e3d6000fd5b505050506040513d602081101561106b57600080fd5b505160408051808201909152600381526269626360e81b6020820152909150611098908290898686613f8d565b6110e1576040805162461bcd60e51b81526020600482015260156024820152740696e76616c6964206d65726b6c652070726f6f663605c1b604482015290519081900360640190fd5b5050505060008f6001600481106110f457fe5b60200201356001600160401b0316905060608d8d8080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525050604080516020601f8f018190048102820181019092528d815293945060609392508d91508c908190840183828082843760009201829052506040805163cba510a960e01b81526001600160401b038a16600482015290519596509094611003945063cba510a9935060248083019350602092829003018186803b1580156111c057600080fd5b505afa1580156111d4573d6000803e3d6000fd5b505050506040513d60208110156111ea57600080fd5b505160408051808201909152600381526269626360e81b6020820152909150611217908290898686613f8d565b611260576040805162461bcd60e51b8152602060048201526015602482015274696e76616c6964206d65726b6c652070726f6f663160581b604482015290519081900360640190fd5b5050505061126c61408a565b604080516001600160401b038416815260ff83166020820152815133927f039eb91179ffd7d3b6e97f8ea106e748e827f910b872375dbc9c14a362319c3c928290030190a2505050505050505050505050505050565b603281565b600d6020526000908152604090205461ffff1681565b600e6020526000908152604090205460ff1681565b60045460070b81565b60025481565b600a602052600090815260409020546001600160401b031681565b60606000825160210190506060816040519080825280601f01601f191660200182016040528015611354576020820181803683370190505b506021810186905260018101879052828152905060418101600061137786614108565b50905061138681838851614112565b50909695505050505050565b600181565b60096020526000908152604090205460ff1681565b61100181565b606181565b600881565b61200081565b604080517710d05390d15317d514905394d1915497d41493d413d4d05360421b8152905190819003601801902081565b60005460ff16611437576040805162461bcd60e51b81526020600482015260196024820152600080516020614a4c833981519152604482015290519081900360640190fd5b6040805163569e4ed360e11b815233600482015290516000916110009163ad3c9da691602480820192602092909190829003018186803b15801561147a57600080fd5b505afa15801561148e573d6000803e3d6000fd5b505050506040513d60208110156114a457600080fd5b505160408051633d42651560e11b8152905191925060009161100091637a84ca2a916004808301926020929190829003018186803b1580156114e557600080fd5b505afa1580156114f9573d6000803e3d6000fd5b505050506040513d602081101561150f57600080fd5b505190508061151c575060155b60008211801561152c5750808211155b61156b576040805162461bcd60e51b815260206004820152600b60248201526a1b9bdd0818d8589a5b995d60aa1b604482015290519081900360640190fd5b604080516001600160a01b038087166020808401919091529086168284015282518083038401815260608301808552815191909201207710d05390d15317d514905394d1915497d41493d413d4d05360421b90915291519081900360780190206000906115d89083614153565b9050801561164a5760408051630911a2c160e11b81526001600160a01b03888116600483015287166024820152905161100491631223458291604480830192600092919082900301818387803b15801561163157600080fd5b505af1158015611645573d6000803e3d6000fd5b505050505b505050505050565b604080516f14d554d411539117d41493d413d4d05360821b8152905190819003601001902081565b600281565b600c602052600090815260409020805460019091015461ffff8216916201000090046001600160801b03169083565b604080516e149153d4115397d41493d413d4d053608a1b8152905190819003600f01902081565b6005602052600090815260409020546001600160a01b031681565b61100581565b601081565b60035481565b61100881565b600b81565b60005460ff16611751576040805162461bcd60e51b81526020600482015260196024820152600080516020614a4c833981519152604482015290519081900360640190fd5b60408051630a83aaa960e31b815233600482015290516110069163541d5548916024808301926020929190829003018186803b15801561179057600080fd5b505afa1580156117a4573d6000803e3d6000fd5b505050506040513d60208110156117ba57600080fd5b505161180d576040805162461bcd60e51b815260206004820152601f60248201527f746865206d73672073656e646572206973206e6f7420612072656c6179657200604482015290519081900360640190fd5b739fb29aac15b9a4b7f17c3385939b007540f4d79133148061184257507337b8516a0f88e65d677229b402ec6c1e0e33300433145b61187d5760405162461bcd60e51b815260040180806020018281038252602a8152602001806149f0602a913960400191505060405180910390fd5b60ff8116600090815260086020526040902054829082906001600160401b0390811690831681146118ed576040805162461bcd60e51b815260206004820152601560248201527439b2b8bab2b731b2903737ba1034b71037b93232b960591b604482015290519081900360640190fd5b60ff8216600090815260086020908152604091829020805467ffffffffffffffff1916600185016001600160401b039081169190911790915582516337d7f9c160e21b81529089166004820152915188926110039263df5fe70492602480840193829003018186803b15801561196257600080fd5b505afa158015611976573d6000803e3d6000fd5b505050506040513d602081101561198c57600080fd5b50516119c95760405162461bcd60e51b8152600401808060200182810382526023815260200180614a6c6023913960400191505060405180910390fd5b60ff851660009081526005602052604090205485906001600160a01b0316611a33576040805162461bcd60e51b815260206004820152601860248201527718da185b9b995b081a5cc81b9bdd081cdd5c1c1bdc9d195960421b604482015290519081900360640190fd5b60ff86166000908152600a6020526040902054889087906001600160401b039081169083161015611a9c576040805162461bcd60e51b815260206004820152600e60248201526d3a37b79037b632103432b0b232b960911b604482015290519081900360640190fd5b60ff81166000908152600a60205260409020546001600160401b03838116911614611aee5760ff81166000908152600a60205260409020805467ffffffffffffffff19166001600160401b0384161790555b600b5460ff1615611b32576040805162461bcd60e51b81526020600482015260096024820152681cdd5cdc195b99195960ba1b604482015290519081900360640190fd5b60608e8e8080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f82011690508083019250505050505050905060608d8d8080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f820116905080830192505050505050509050611c766110036001600160a01b031663cba510a98e6040518263ffffffff1660e01b815260040180826001600160401b03166001600160401b0316815260200191505060206040518083038186803b158015611c1f57600080fd5b505afa158015611c33573d6000803e3d6000fd5b505050506040513d6020811015611c4957600080fd5b505160408051808201909152600381526269626360e81b6020820152611c6f8e8e613f45565b8585613f8d565b611cbe576040805162461bcd60e51b815260206004820152601460248201527334b73b30b634b21036b2b935b63290383937b7b360611b604482015290519081900360640190fd5b60408051631bb5062960e31b81526001600160401b038e16600482015290516000916110039163dda8314891602480820192602092909190829003018186803b158015611d0a57600080fd5b505afa158015611d1e573d6000803e3d6000fd5b505050506040513d6020811015611d3457600080fd5b505190508b8b600080806060611d4989614438565b935093509350935083611e0b578460ff16866001600160401b03167ff7b2e42d694eb1100184aae86d4245d9e46966100b1dc7e723275b98326854ac8b6040518080602001828103825283818151815260200191508051906020019080838360005b83811015611dc3578181015183820152602001611dab565b50505050905090810190601f168015611df05780820380516001836020036101000a031916815260200191505b509250505060405180910390a3505050505050505050612a26565b6040805160ff85811682529151918716916001600160401b038916917f36afdaf439a8f43fe72135135d804ae620b37a474f0943b5b85f6788312cad40919081900360200190a360ff83166123905760ff85166000818152600560209081526040808320548151631182b87560e01b815260048101958652602481019283528651604482015286516001600160a01b03909216958695631182b875958d958a9593949093606490910192918601918190849084905b83811015611ed8578181015183820152602001611ec0565b50505050905090810190601f168015611f055780820380516001836020036101000a031916815260200191505b509350505050600060405180830381600087803b158015611f2557600080fd5b505af192505050801561200957506040513d6000823e601f3d908101601f191682016040526020811015611f5857600080fd5b8101908080516040519392919084600160201b821115611f7757600080fd5b908301906020820185811115611f8c57600080fd5b8251600160201b811182820188101715611fa557600080fd5b82525081516020918201929091019080838360005b83811015611fd2578181015183820152602001611fba565b50505050905090810190601f168015611fff5780820380516001836020036101000a031916815260200191505b5060405250505060015b61231b576040516000815260443d1015612025575060006120c0565b60046000803e60005160e01c6308c379a081146120465760009150506120c0565b60043d036004833e81513d60248201116001600160401b0382111715612071576000925050506120c0565b80830180516001600160401b038111156120925760009450505050506120c0565b8060208301013d86018111156120b0576000955050505050506120c0565b601f01601f191660405250925050505b806120cb57506121dd565b60ff8716600090815260076020526040812054612102916001600160401b039091169089906120fd906002908861131c565b6144e8565b60ff8716600090815260076020908152604080832080546001600160401b038082166001011667ffffffffffffffff19909116179055805182815284518184015284516001600160a01b038716947ff91a8f63e5b3e0e89e5f93e1915a7805f3c52d9a73b3c09769785c2c7bf87acf948794849390840192918601918190849084905b8381101561219d578181015183820152602001612185565b50505050905090810190601f1680156121ca5780820380516001836020036101000a031916815260200191505b509250505060405180910390a250612316565b3d808015612207576040519150601f19603f3d011682016040523d82523d6000602084013e61220c565b606091505b5060ff871660009081526007602052604081205461223f916001600160401b039091169089906120fd906002908861131c565b60ff8716600090815260076020908152604080832080546001600160401b038082166001011667ffffffffffffffff19909116179055805182815284518184015284516001600160a01b038716947f63ac299d6332d1cc4e61b81e59bc00c0ac7c798addadf33840f1307cd2977351948794849390840192918601918190849084905b838110156122da5781810151838201526020016122c2565b50505050905090810190601f1680156123075780820380516001836020036101000a031916815260200191505b509250505060405180910390a2505b61238a565b8051156123885760ff8716600090815260076020526040812054612354916001600160401b039091169089906120fd906001908661131c565b60ff8716600090815260076020526040902080546001600160401b038082166001011667ffffffffffffffff199091161790555b505b5061295e565b60ff8316600114156126345760ff8516600081815260056020908152604080832054815163831d65d160e01b815260048101958652602481019283528651604482015286516001600160a01b0390921695869563831d65d1958d958a9593949093606490910192918601918190849084905b8381101561241a578181015183820152602001612402565b50505050905090810190601f1680156124475780820380516001836020036101000a031916815260200191505b509350505050600060405180830381600087803b15801561246757600080fd5b505af1925050508015612478575060015b61238a576040516000815260443d10156124945750600061252f565b60046000803e60005160e01c6308c379a081146124b557600091505061252f565b60043d036004833e81513d60248201116001600160401b03821117156124e05760009250505061252f565b80830180516001600160401b0381111561250157600094505050505061252f565b8060208301013d860181111561251f5760009550505050505061252f565b601f01601f191660405250925050505b8061253a575061259f565b60408051602080825283518183015283516001600160a01b038616937ff91a8f63e5b3e0e89e5f93e1915a7805f3c52d9a73b3c09769785c2c7bf87acf938693909283928301918501908083836000831561219d578181015183820152602001612185565b3d8080156125c9576040519150601f19603f3d011682016040523d82523d6000602084013e6125ce565b606091505b5060408051602080825283518183015283516001600160a01b038616937f63ac299d6332d1cc4e61b81e59bc00c0ac7c798addadf33840f1307cd297735193869390928392830191850190808383600083156122da5781810151838201526020016122c2565b60ff83166002141561295e5760ff8516600081815260056020908152604080832054815163c8509d8160e01b815260048101958652602481019283528651604482015286516001600160a01b0390921695869563c8509d81958d958a9593949093606490910192918601918190849084905b838110156126be5781810151838201526020016126a6565b50505050905090810190601f1680156126eb5780820380516001836020036101000a031916815260200191505b509350505050600060405180830381600087803b15801561270b57600080fd5b505af192505050801561271c575060015b61295c576040516000815260443d1015612738575060006127d3565b60046000803e60005160e01c6308c379a081146127595760009150506127d3565b60043d036004833e81513d60248201116001600160401b0382111715612784576000925050506127d3565b80830180516001600160401b038111156127a55760009450505050506127d3565b8060208301013d86018111156127c3576000955050505050506127d3565b601f01601f191660405250925050505b806127de5750612887565b816001600160a01b03167ff91a8f63e5b3e0e89e5f93e1915a7805f3c52d9a73b3c09769785c2c7bf87acf826040518080602001828103825283818151815260200191508051906020019080838360005b8381101561284757818101518382015260200161282f565b50505050905090810190601f1680156128745780820380516001836020036101000a031916815260200191505b509250505060405180910390a25061295c565b3d8080156128b1576040519150601f19603f3d011682016040523d82523d6000602084013e6128b6565b606091505b50816001600160a01b03167f63ac299d6332d1cc4e61b81e59bc00c0ac7c798addadf33840f1307cd2977351826040518080602001828103825283818151815260200191508051906020019080838360005b83811015612920578181015183820152602001612908565b50505050905090810190601f16801561294d5780820380516001836020036101000a031916815260200191505b509250505060405180910390a2505b505b60ff80861660009081526009602052604090205461100591636f93d2e6918a91339187911680612990575060ff881615155b604080516001600160e01b031960e088901b1681526001600160a01b039586166004820152939094166024840152604483019190915215156064820152905160848083019260209291908290030181600087803b1580156129f057600080fd5b505af1158015612a04573d6000803e3d6000fd5b505050506040513d6020811015612a1a57600080fd5b50505050505050505050505b5050505050505050505050505050565b630100610081565b600981565b61100781565b61100681565b60005460ff1681565b3361100714612a985760405162461bcd60e51b815260040180806020018281038252602e815260200180614978602e913960400191505060405180910390fd5b600b5460ff1615612adc576040805162461bcd60e51b81526020600482015260096024820152681cdd5cdc195b99195960ba1b604482015290519081900360640190fd5b612b4584848080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525050604080518082019091526012815271626174636853697a65466f724f7261636c6560701b602082015291506146829050565b15612be057604080516020601f8401819004810282018101909252828152600091612b889185858083850183828082843760009201919091525061476992505050565b90506127108111158015612b9d5750600a8110155b612bd85760405162461bcd60e51b8152600401808060200182810382526032815260200180614a1a6032913960400191505060405180910390fd5b60015561348a565b612c4984848080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152505060408051808201909152601281527118591913dc955c19185d1950da185b9b995b60721b602082015291506146829050565b15612dd157606082828080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152505082519293505060169091149050612ccc5760405162461bcd60e51b815260040180806020018281038252605a815260200180614891605a913960600191505060405180910390fd5b60018101516002820151601683015160ff82161590612cea8161476e565b612d3b576040805162461bcd60e51b815260206004820152601960248201527f61646472657373206973206e6f74206120636f6e747261637400000000000000604482015290519081900360640190fd5b60ff8416600081815260056020908152604080832080546001600160a01b0319166001600160a01b038716908117909155808452600683528184208585528352818420805460ff199081166001179091556009909352818420805490931687151517909255519092917f7e3b6af43092577ee20e60eaa1d9b114a7031305c895ee7dd3ffe17196d2e1e091a3505050505061348a565b612e3e84848080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525050604080518082019091526016815275195b98589b1953dc911a5cd8589b1950da185b9b995b60521b602082015291506146829050565b15612f6f57606082828080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152505082519293505060029091149050612ec15760405162461bcd60e51b815260040180806020018281038252604a8152602001806149a6604a913960600191505060405180910390fd5b600181810151600283015160ff80831660009081526005602052604090205492939192908316909114906001600160a01b03168015612f65576001600160a01b038116600090815260066020908152604080832060ff881680855290835292819020805460ff1916861515908117909155815190815290517fa3132e3f9819fbddc7f0ed6d38d7feef59aa95112090b7c592f5cb5bc4aa4adc929181900390910190a25b505050505061348a565b612fd384848080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152505060408051808201909152600d81526c73757370656e6451756f72756d60981b602082015291506146829050565b1561310857600281146130175760405162461bcd60e51b815260040180806020018281038252602d81526020018061491f602d913960400191505060405180910390fd5b600061305a600284848080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061476992505050565b905060008161ffff16118015613074575060648161ffff16105b6130be576040805162461bcd60e51b8152602060048201526016602482015275696e76616c69642073757370656e642071756f72756d60501b604482015290519081900360640190fd5b604080516f14d554d411539117d41493d413d4d05360821b815281519081900360100190206000908152600d60205220805461ffff90921661ffff1990921691909117905561348a565b61316b84848080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152505060408051808201909152600c81526b72656f70656e51756f72756d60a01b602082015291506146829050565b1561329e57600281146131af5760405162461bcd60e51b815260040180806020018281038252602c81526020018061494c602c913960400191505060405180910390fd5b60006131f2600284848080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061476992505050565b905060008161ffff1611801561320c575060648161ffff16105b613255576040805162461bcd60e51b8152602060048201526015602482015274696e76616c69642072656f70656e2071756f72756d60581b604482015290519081900360640190fd5b604080516e149153d4115397d41493d413d4d053608a1b8152815190819003600f0190206000908152600d60205220805461ffff90921661ffff1990921691909117905561348a565b61330984848080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152505060408051808201909152601481527363616e63656c5472616e7366657251756f72756d60601b602082015291506146829050565b1561344d576002811461334d5760405162461bcd60e51b81526004018080602001828103825260348152602001806148eb6034913960400191505060405180910390fd5b6000613390600284848080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061476992505050565b905060008161ffff161180156133aa575060648161ffff16105b6133fb576040805162461bcd60e51b815260206004820152601e60248201527f696e76616c69642063616e63656c207472616e736665722071756f72756d0000604482015290519081900360640190fd5b604080517710d05390d15317d514905394d1915497d41493d413d4d05360421b815281519081900360180190206000908152600d60205220805461ffff90921661ffff1990921691909117905561348a565b6040805162461bcd60e51b815260206004820152600d60248201526c756e6b6e6f776e20706172616d60981b604482015290519081900360640190fd5b7f6cdb0ac70ab7f2e2d035cca5be60d89906f2dede7648ddbd7402189c1eeed17a848484846040518080602001806020018381038352878782818152602001925080828437600083820152601f01601f191690910184810383528581526020019050858580828437600083820152604051601f909101601f19169092018290039850909650505050505050a150505050565b6008602052600090815260409020546001600160401b031681565b7fc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a47081565b61100281565b60005460ff166135a6576040805162461bcd60e51b81526020600482015260196024820152600080516020614a4c833981519152604482015290519081900360640190fd5b6040805163569e4ed360e11b815233600482015290516000916110009163ad3c9da691602480820192602092909190829003018186803b1580156135e957600080fd5b505afa1580156135fd573d6000803e3d6000fd5b505050506040513d602081101561361357600080fd5b505160408051633d42651560e11b8152905191925060009161100091637a84ca2a916004808301926020929190829003018186803b15801561365457600080fd5b505afa158015613668573d6000803e3d6000fd5b505050506040513d602081101561367e57600080fd5b505190508061368b575060155b60008211801561369b5750808211155b6136da576040805162461bcd60e51b815260206004820152600b60248201526a1b9bdd0818d8589a5b995d60aa1b604482015290519081900360640190fd5b600b5460ff16613721576040805162461bcd60e51b815260206004820152600d60248201526c1b9bdd081cdd5cdc195b991959609a1b604482015290519081900360640190fd5b604080516e149153d4115397d41493d413d4d053608a1b8152905190819003600f019020600090613772907fc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470614153565b905080156137b057600b805460ff1916905560405133907f899fe8c37dc61708a3aaa99c4bf143346c1d1da69af79be9e8920c0a6785b75290600090a25b505050565b600660209081526000928352604080842090915290825290205460ff1681565b6040518060400160405280600381526020016269626360e81b81525081565b610e1081565b61100381565b60005460ff1615613858576040805162461bcd60e51b815260206004820152601960248201527f74686520636f6e747261637420616c726561647920696e697400000000000000604482015290519081900360640190fd5b7f1471eb6eb2c5e789fc3de43f8ce62938c7d1836ec861730447e2ada8fd81017b80546001600160a01b0319908116611008179091557f92e85d02570a8092d09a6e3a57665bc3815a2699a4074001bf1ccabf660f5a36805460ff199081169091557fd8af288fc1c8680b4f4706064cf021e264efb6828fcaf7eb5ca36818eb365bcc8054821660019081179091557f89832631fb3c3307a103ba2c84ab569c64d6182a18893dcd163f0f1c2090733a805484166110049081179091557f6cde3cea4b3a3fb2488b2808bae7556f4a405e50f65e1794383bc026131b13c38054841690557f72e4efa1513b071517c6c74dba31b5934a81aa83cddd400e7081df5529c9943680548416831790557fa9bc9a3a348c357ba16b37005d7e6b3236198c0e939f4af8c5f19b8deeb8ebc08054851690911790557fc575c31fea594a6eb97c8e9d3f9caee4c16218c6ef37e923234c0fe9014a61e78054831690557f4e523af77f034e9810f1c94057f5e931fb3d16a51511a4c3add793617d18610580548316821790557ffb33122aa9f93cc639ebe80a7bc4784c11e6053dde89c6f4f7e268c6a623da1e805484166110001790557fc7694af312c4f286114180fd0ba6a52461fcee8a381636770b19a343af92538a80548316821790557f01112dd68e482ba8d68a7e828cff8b3abcea08eab88941953c180a7e650e9cd480548316821790557fc0a4a8be475dfebc377ebef2d7c4ff47656f572a08dd92b81017efcdba0febe1805484166110071790557f87e8a52529e8ece4ef759037313542a6429ff494a9fab9027fb79db90124eba680548316821790557f4c7666bbcb22d46469f7cc282f70764a7012dca2cce630ff8d83db9a9cdd48f080548316821790557f40f28f99a40bc9f6beea1013afdbc3cdcc689eb76b82c4de06c0acf1e1932ed58054909316611001179092557f0d9cf2cd531699eed8dd34e40ff2884a14a698c4898184fba85194e6f6772d248054821683179055600b60009081527f23f68c9bd22b8a93d06adabe17481c87c016bcbd20adc8bfd707a4d813a572176020527fdf0d5d05428057f5455c2dc8e810dd86d1e9350faa72f16bda8a45443c5b39328054831684179055603283556004805467ffffffffffffffff19166001600160401b031790556002819055600381905580549091169091179055565b6007602052600090815260409020546001600160401b031681565b60005460ff16613c17576040805162461bcd60e51b81526020600482015260196024820152600080516020614a4c833981519152604482015290519081900360640190fd5b6040805163569e4ed360e11b815233600482015290516000916110009163ad3c9da691602480820192602092909190829003018186803b158015613c5a57600080fd5b505afa158015613c6e573d6000803e3d6000fd5b505050506040513d6020811015613c8457600080fd5b505160408051633d42651560e11b8152905191925060009161100091637a84ca2a916004808301926020929190829003018186803b158015613cc557600080fd5b505afa158015613cd9573d6000803e3d6000fd5b505050506040513d6020811015613cef57600080fd5b5051905080613cfc575060155b600082118015613d0c5750808211155b613d4b576040805162461bcd60e51b815260206004820152600b60248201526a1b9bdd0818d8589a5b995d60aa1b604482015290519081900360640190fd5b600b5460ff1615613d8f576040805162461bcd60e51b81526020600482015260096024820152681cdd5cdc195b99195960ba1b604482015290519081900360640190fd5b604080516f14d554d411539117d41493d413d4d05360821b81529051908190036010019020600090613de1907fc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470614153565b905080156137b0576137b061408a565b60005460ff16613e36576040805162461bcd60e51b81526020600482015260196024820152600080516020614a4c833981519152604482015290519081900360640190fd5b33600090815260066020908152604080832060ff8089168552925290912054859116613e935760405162461bcd60e51b81526004018080602001828103825260318152602001806148606031913960400191505060405180910390fd5b60ff85166000908152600760209081526040808320548151601f88018490048402810184019092528682526001600160401b031692613ef89284928a926120fd92909189918c908c908190840183828082843760009201919091525061131c92505050565b60ff959095166000908152600760205260409020805467ffffffffffffffff191660019096016001600160401b03169590951790945550505050565b61100081565b600381565b61100481565b60408051600e808252818301909252606091630100610060ff851617918391602082018180368337505050600e81810187905260068201939093529182525090505b92915050565b600085613f9c57506000614081565b606082518451865160800101016040519080825280601f01601f191660200182016040528015613fd3576020820181803683370190505b5090506000613fe182614774565b602080890151825201905086600080613ff989614108565b8086526020909501949092509050614012828583614112565b9283019261401f88614108565b8086526020909501949092509050614038828583614112565b9283018a81526020019261404b87614108565b909250905061405b828583614112565b50835160200161406961477a565b60208183886065600019fa5051600114955050505050505b95945050505050565b600b5460ff16156140ce576040805162461bcd60e51b81526020600482015260096024820152681cdd5cdc195b99195960ba1b604482015290519081900360640190fd5b600b805460ff1916600117905560405133907f6f123d3d54c84a7960a573b31c221dcd86e13fd849c5adb0c6ca851468cc1ae490600090a2565b8051602090910191565b5b60208110614132578251825260209283019290910190601f1901614113565b915181516020939093036101000a6000190180199091169216919091179052565b6000828152600d602052604081205461ffff1661421c57604080516f14d554d411539117d41493d413d4d05360821b815281519081900360100181206000908152600d6020818152848320805461ffff199081166001179091556e149153d4115397d41493d413d4d053608a1b8552855194859003600f01852084528282528584208054821660029081179091557710d05390d15317d514905394d1915497d41493d413d4d05360421b8652865195869003601801909520845291905292902080549092161790555b6000838152600c6020526040902080546201000090046001600160801b03164210158061424d575082816001015414155b15614320576000848152600d602090815260409182902054835461ffff90911661ffff199091161771ffffffffffffffffffffffffffffffff0000191662010000610e1042016001600160801b031602178355600180840186905582519182019092523381526142c291600284019190614798565b5080546040805161ffff83168152620100009092046001600160801b0316602083015281810185905251339186917f9e109f0e55ef32e99e4880be2ec357f1ddb3469c79d0747ef4762da6e89fabe5916060908290030190a36143d4565b60005b60028201548110156143ab57336001600160a01b031682600201828154811061434857fe5b6000918252602090912001546001600160a01b031614156143a3576040805162461bcd60e51b815260206004820152601060248201526f185b1c9958591e48185c1c1c9bdd995960821b604482015290519081900360640190fd5b600101614323565b50600281018054600181018255600091825260209091200180546001600160a01b031916331790555b8054600282015461ffff9091161161442e576000848152600c60205260408120805471ffffffffffffffffffffffffffffffffffff19168155600181018290559061442260028301826147fd565b50506001915050613f87565b5060009392505050565b600080600060606021855110156144685750506040805160008082526020820190925290925082915081906144e1565b600185015160218601518651604080516020198301808252601f19600119909401939093168101602001909152604189019392916060919080156144b3576020820181803683370190505b50905060006144c182614108565b5090506144d3858260218d5103614112565b506001975091955093509150505b9193509193565b600b5460ff161561452c576040805162461bcd60e51b81526020600482015260096024820152681cdd5cdc195b99195960ba1b604482015290519081900360640190fd5b60025443111561456b576004805467ffffffffffffffff1981166001600160401b036001600793840b810190930b1617909155600355436002556145ac565b600380546001908101918290555410156145ac576004805467ffffffffffffffff1981166001600160401b036001600793840b810190930b16179091556003555b8160ff16836001600160401b0316600460009054906101000a900460070b6001600160401b03167f3a6e0fc61675aa2a100bcba0568368bb92bcec91c97673391074f11138f0cffe606185604051808361ffff1661ffff16815260200180602001828103825283818151815260200191508051906020019080838360005b8381101561464257818101518382015260200161462a565b50505050905090810190601f16801561466f5780820380516001836020036101000a031916815260200191505b50935050505060405180910390a4505050565b6000816040516020018082805190602001908083835b602083106146b75780518252601f199092019160209182019101614698565b6001836020036101000a03801982511681845116808217855250505050505090500191505060405160208183030381529060405280519060200120836040516020018082805190602001908083835b602083106147255780518252601f199092019160209182019101614706565b6001836020036101000a0380198251168184511680821785525050505050509050019150506040516020818303038152906040528051906020012014905092915050565b015190565b3b151590565b60200190565b60405180602001604052806001906020820280368337509192915050565b8280548282559060005260206000209081019282156147ed579160200282015b828111156147ed57825182546001600160a01b0319166001600160a01b039091161782556020909201916001909101906147b8565b506147f992915061481e565b5090565b508054600082559060005260206000209081019061481b9190614845565b50565b61484291905b808211156147f95780546001600160a01b0319168155600101614824565b90565b61484291905b808211156147f9576000815560010161484b56fe74686520636f6e747261637420616e64206368616e6e656c2068617665206e6f74206265656e20726567697374657265646c656e677468206f662076616c756520666f72206164644f725570646174654368616e6e656c2073686f756c642062652032322c206368616e6e656c49643a697346726f6d53797374656d3a68616e646c6572416464726573736c656e677468206f662076616c756520666f722063616e63656c5472616e7366657251756f72756d2073686f756c6420626520326c656e677468206f662076616c756520666f722073757370656e6451756f72756d2073686f756c6420626520326c656e677468206f662076616c756520666f722072656f70656e51756f72756d2073686f756c642062652032746865206d6573736167652073656e646572206d75737420626520676f7665726e616e636520636f6e74726163746c656e677468206f662076616c756520666f7220656e61626c654f7244697361626c654368616e6e656c2073686f756c6420626520322c206368616e6e656c49643a6973456e61626c65746865206d73672073656e646572206973206e6f7420612077686974656c6162656c2072656c61796572746865206e6577426174636853697a65466f724f7261636c652073686f756c6420626520696e205b31302c2031303030305d74686520636f6e7472616374206e6f7420696e697420796574000000000000006c6967687420636c69656e74206e6f742073796e632074686520626c6f636b20796574a264697066735822122026f49f5b5d33882588ea53bac8a0f154c6a6d2ff32bdfdb114fc8cfcf13f710f64736f6c63430006040033", + }, + { + ContractAddr: StakingContract, + CommitUrl: "https://github.com/bnb-chain/bsc-genesis-contract/commit/78e13b1d3a5a1b08c9208af94a9b14fc1efda213", + Code: "6080604052600436106103855760003560e01c806370fd5bad116101d1578063b88a802f11610102578063d7ecfcb6116100a0578063f9a2bbc71161006f578063f9a2bbc714610c40578063fa03f79714610c55578063fc3e590814610671578063fd6a687914610c6a5761038c565b8063d7ecfcb614610819578063dc927faf14610bd1578063edc1a5b014610be6578063f45fd80b14610bfb5761038c565b8063c2117d82116100dc578063c2117d8214610ae7578063c81b166214610afc578063c8509d8114610b11578063d61b9b9314610b965761038c565b8063b88a802f14610a82578063baaafd3b14610a97578063bf8546ca14610aac5761038c565b806396713da91161016f578063a78abc1611610149578063a78abc1614610964578063ab51bb961461098d578063ac431751146109a2578063b14315df14610a6d5761038c565b806396713da9146109255780639dc092621461093a578063a1a11bf51461094f5761038c565b806375d47a0a116101ab57806375d47a0a146108765780637942fd051461088b578063831d65d1146108a057806392b888a41461061d5761038c565b806370fd5bad14610819578063718a8aa81461082e57806375aca593146108435761038c565b80633fdfa7e4116102b6578063552aaf931161025457806369b635b61161022357806369b635b6146107865780636bd8f8041461079b5780636e47b482146107d15780636fb7f7eb146107e65761038c565b8063552aaf93146107325780635d17c8bd146107475780635d499b1b1461075c57806362b171d2146107715761038c565b8063493279b111610290578063493279b1146106b05780634bf6c882146106dc5780634d99dd16146106f157806351e806721461071d5761038c565b80633fdfa7e414610671578063413d9c3a1461068657806343756e5c1461069b5761038c565b806311fe9ec6116103235780632fdeb111116102fd5780632fdeb11114610632578063333ad3e71461064757806334c433541461065c5780633dffc3871461061d5761038c565b806311fe9ec6146105bf578063151817e3146105f257806317c9efb01461061d5761038c565b80630bee7a671161035f5780630bee7a67146104515780630c7957151461047f5780630e2374a5146104945780631182b875146104c55761038c565b8063026e402b1461039157806302985992146103bf578063047636d1146103e65761038c565b3661038c57005b600080fd5b6103bd600480360360408110156103a757600080fd5b506001600160a01b038135169060200135610c7f565b005b3480156103cb57600080fd5b506103d46111bc565b60408051918252519081900360200190f35b3480156103f257600080fd5b506104196004803603602081101561040957600080fd5b50356001600160a01b03166111c2565b6040518082606080838360005b8381101561043e578181015183820152602001610426565b5050505090500191505060405180910390f35b34801561045d57600080fd5b50610466611216565b6040805163ffffffff9092168252519081900360200190f35b34801561048b57600080fd5b506103d461121b565b3480156104a057600080fd5b506104a9611221565b604080516001600160a01b039092168252519081900360200190f35b3480156104d157600080fd5b5061054a600480360360408110156104e857600080fd5b60ff8235169190810190604081016020820135600160201b81111561050c57600080fd5b82018360208201111561051e57600080fd5b803590602001918460018302840111600160201b8311171561053f57600080fd5b509092509050611227565b6040805160208082528351818301528351919283929083019185019080838360005b8381101561058457818101518382015260200161056c565b50505050905090810190601f1680156105b15780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b3480156105cb57600080fd5b506103d4600480360360208110156105e257600080fd5b50356001600160a01b03166113e3565b3480156105fe57600080fd5b506106076113fe565b6040805160ff9092168252519081900360200190f35b34801561062957600080fd5b50610607611403565b34801561063e57600080fd5b506103d4611408565b34801561065357600080fd5b5061046661140e565b34801561066857600080fd5b506103d4611413565b34801561067d57600080fd5b5061060761141e565b34801561069257600080fd5b506103d4611423565b3480156106a757600080fd5b506104a961142a565b3480156106bc57600080fd5b506106c5611430565b6040805161ffff9092168252519081900360200190f35b3480156106e857600080fd5b50610607611435565b6103bd6004803603604081101561070757600080fd5b506001600160a01b03813516906020013561143a565b34801561072957600080fd5b506104a9611a62565b34801561073e57600080fd5b50610607611a68565b34801561075357600080fd5b506103d4611a6d565b34801561076857600080fd5b506103d4611a73565b34801561077d57600080fd5b506103d4611a7c565b34801561079257600080fd5b506103d4611c1c565b6103bd600480360360608110156107b157600080fd5b506001600160a01b03813581169160208101359091169060400135611c22565b3480156107dd57600080fd5b506104a961230b565b3480156107f257600080fd5b506103d46004803603602081101561080957600080fd5b50356001600160a01b0316612311565b34801561082557600080fd5b5061060761232c565b34801561083a57600080fd5b50610607612331565b34801561084f57600080fd5b506103d46004803603602081101561086657600080fd5b50356001600160a01b0316612336565b34801561088257600080fd5b506104a9612351565b34801561089757600080fd5b50610607612357565b3480156108ac57600080fd5b506103bd600480360360408110156108c357600080fd5b60ff8235169190810190604081016020820135600160201b8111156108e757600080fd5b8201836020820111156108f957600080fd5b803590602001918460018302840111600160201b8311171561091a57600080fd5b50909250905061235c565b34801561093157600080fd5b50610607612624565b34801561094657600080fd5b506104a9612629565b34801561095b57600080fd5b506104a961262f565b34801561097057600080fd5b50610979612635565b604080519115158252519081900360200190f35b34801561099957600080fd5b50610466611a68565b3480156109ae57600080fd5b506103bd600480360360408110156109c557600080fd5b810190602081018135600160201b8111156109df57600080fd5b8201836020820111156109f157600080fd5b803590602001918460018302840111600160201b83111715610a1257600080fd5b919390929091602081019035600160201b811115610a2f57600080fd5b820183602082011115610a4157600080fd5b803590602001918460018302840111600160201b83111715610a6257600080fd5b50909250905061263e565b348015610a7957600080fd5b50610607612dd0565b348015610a8e57600080fd5b506103d4612dd5565b348015610aa357600080fd5b506103d4612f72565b348015610ab857600080fd5b506103d460048036036040811015610acf57600080fd5b506001600160a01b0381358116916020013516612f7d565b348015610af357600080fd5b506103d4612faa565b348015610b0857600080fd5b506104a9612fb0565b348015610b1d57600080fd5b506103bd60048036036040811015610b3457600080fd5b60ff8235169190810190604081016020820135600160201b811115610b5857600080fd5b820183602082011115610b6a57600080fd5b803590602001918460018302840111600160201b83111715610b8b57600080fd5b509092509050612fb6565b348015610ba257600080fd5b506103d460048036036040811015610bb957600080fd5b506001600160a01b03813581169160200135166131d9565b348015610bdd57600080fd5b506104a9613204565b348015610bf257600080fd5b506103d461320a565b348015610c0757600080fd5b506103d460048036036060811015610c1e57600080fd5b506001600160a01b038135811691602081013582169160409091013516613217565b348015610c4c57600080fd5b506104a961324c565b348015610c6157600080fd5b506103d4613252565b348015610c7657600080fd5b506104a9613258565b60105460ff1660021415610ccb576040805162461bcd60e51b815260206004820152600e60248201526d4e6f2072652d656e7472616e637960901b604482015290519081900360640190fd5b6010805460ff19166002179055806402540be4003406158015610cf357506402540be4008106155b610d44576040805162461bcd60e51b815260206004820152601c60248201527f707265636973696f6e206c6f737320696e20636f6e76657273696f6e00000000604482015290519081900360640190fd5b60005460ff16610d87576638d7ea4c6800006001908155662386f26fc1000060025568056bc75e2d631000006003556108fc6011556000805460ff191690911790555b600354821015610dde576040805162461bcd60e51b815260206004820152601760248201527f696e76616c69642064656c656761746520616d6f756e74000000000000000000604482015290519081900360640190fd5b600154610df290839063ffffffff61325e16565b341015610e3d576040805162461bcd60e51b81526020600482015260146024820152736e6f7420656e6f756768206d73672076616c756560601b604482015290519081900360640190fd5b601154604051600091339183818181818787f1925050503d8060008114610e80576040519150601f19603f3d011682016040523d82523d6000602084013e610e85565b606091505b5050905080610ecf576040805162461bcd60e51b815260206004820152601160248201527034b73b30b634b2103232b632b3b0ba37b960791b604482015290519081900360640190fd5b6000610ee6846402540be40063ffffffff6132bf16565b90506000610efa348663ffffffff61330116565b90506000610f136002548361330190919063ffffffff16565b6040805160038082526080820190925291925060609190816020015b6060815260200190600190039081610f2f579050509050610f4f33613343565b81600081518110610f5c57fe5b6020026020010181905250610f79886001600160a01b0316613343565b81600181518110610f8657fe5b6020026020010181905250610f9a84613366565b81600281518110610fa757fe5b60200260200101819052506060610fc76001610fc284613379565b613403565b8051602080830191909120600f80546000908152600a845260408082209390935581546001908101909255338152600b909352912080549091019055905061200063f7a251d7601083611025876402540be40063ffffffff6132bf16565b6040518463ffffffff1660e01b8152600401808460ff1660ff16815260200180602001838152602001828103825284818151815260200191508051906020019080838360005b8381101561108357818101518382015260200161106b565b50505050905090810190601f1680156110b05780820380516001836020036101000a031916815260200191505b50945050505050600060405180830381600087803b1580156110d157600080fd5b505af11580156110e5573d6000803e3d6000fd5b5061100492506108fc915061110290508a8663ffffffff61325e16565b6040518115909202916000818181858888f1935050505015801561112a573d6000803e3d6000fd5b506002546040516110029180156108fc02916000818181858888f1935050505015801561115b573d6000803e3d6000fd5b50604080518981526020810185905281516001600160a01b038c169233927f5f32ed2794e2e72d19e3cb2320e8820a499c4204887372beba51f5e61c040867929081900390910190a350506010805460ff1916600117905550505050505050565b60035481565b6111ca615193565b6111d2615193565b6001600160a01b0383166000818152600b60209081526040808320548552838352600c82528083205485830152928252600d9052819020549082015290505b919050565b606481565b6108fc81565b61200181565b606033612000146112695760405162461bcd60e51b815260040180806020018281038252602f81526020018061539b602f913960400191505060405180910390fd5b60005460ff166112ac576638d7ea4c6800006001908155662386f26fc1000060025568056bc75e2d631000006003556108fc6011556000805460ff191690911790555b6112b46151b1565b6112fb6112f685858080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061348992505050565b6134ae565b9050600061131061130b836134f8565b613546565b90506000606060ff8316600414156113355761132b846135fd565b909250905061138c565b60ff83166005141561134a5761132b846137dd565b6040805162461bcd60e51b8152602060048201526012602482015271756e6b6e6f776e206576656e74207479706560701b604482015290519081900360640190fd5b63ffffffff8216156113d8576040805163ffffffff84168152905160ff8516917f391d6e5ea6ab6c49b9a0abb1782cae5def8d711f973b00c729658c0b2a80b31b919081900360200190a25b979650505050505050565b6001600160a01b031660009081526006602052604090205490565b600581565b600181565b60015481565b606581565b662386f26fc1000081565b600381565b620a8c0081565b61100181565b606181565b600881565b60105460ff1660021415611486576040805162461bcd60e51b815260206004820152600e60248201526d4e6f2072652d656e7472616e637960901b604482015290519081900360640190fd5b6010805460ff19166002179055806402540be40034061580156114ae57506402540be4008106155b6114ff576040805162461bcd60e51b815260206004820152601c60248201527f707265636973696f6e206c6f737320696e20636f6e76657273696f6e00000000604482015290519081900360640190fd5b60005460ff16611542576638d7ea4c6800006001908155662386f26fc1000060025568056bc75e2d631000006003556108fc6011556000805460ff191690911790555b600154341015611590576040805162461bcd60e51b81526020600482015260146024820152736e6f7420656e6f7567682072656c61792066656560601b604482015290519081900360640190fd5b60035482101561164b573360009081526005602090815260408083206001600160a01b03871684529091529020548214611602576040805162461bcd60e51b815260206004820152600e60248201526d1a5b9d985b1a5908185b5bdd5b9d60921b604482015290519081900360640190fd5b600254821161164b576040805162461bcd60e51b815260206004820152601060248201526f6e6f7420656e6f7567682066756e647360801b604482015290519081900360640190fd5b3360009081526007602090815260408083206001600160a01b03871684529091529020544210156116c3576040805162461bcd60e51b815260206004820152601a60248201527f70656e64696e6720756e64656c65676174696f6e206578697374000000000000604482015290519081900360640190fd5b604080518082018252601081526f6e6f7420656e6f7567682066756e647360801b602080830191909152336000908152600582528381206001600160a01b03881682529091529182205461171e91859063ffffffff6139f916565b905080156117665760025481116117665760405162461bcd60e51b81526004018080602001828103825260258152602001806153766025913960400191505060405180910390fd5b600061177d846402540be40063ffffffff6132bf16565b600254909150349060009061179990839063ffffffff61330116565b6040805160038082526080820190925291925060609190816020015b60608152602001906001900390816117b55790505090506117d533613343565b816000815181106117e257fe5b60200260200101819052506117ff886001600160a01b0316613343565b8160018151811061180c57fe5b602002602001018190525061182084613366565b8160028151811061182d57fe5b602002602001018190525060606118486002610fc284613379565b8051602080830191909120600f80546000908152600a845260408082209390935581546001908101909255338152600c909352912080549091019055905061189942620a8c0063ffffffff61325e16565b3360009081526007602090815260408083206001600160a01b038e16845290915290205561200063f7a251d76010836118dd876402540be40063ffffffff6132bf16565b6040518463ffffffff1660e01b8152600401808460ff1660ff16815260200180602001838152602001828103825284818151815260200191508051906020019080838360005b8381101561193b578181015183820152602001611923565b50505050905090810190601f1680156119685780820380516001836020036101000a031916815260200191505b50945050505050600060405180830381600087803b15801561198957600080fd5b505af115801561199d573d6000803e3d6000fd5b5050604051611004925085156108fc02915085906000818181858888f193505050501580156119d0573d6000803e3d6000fd5b506002546040516110029180156108fc02916000818181858888f19350505050158015611a01573d6000803e3d6000fd5b50604080518981526020810185905281516001600160a01b038c169233927fdf0b6ac27f3f3bb31cee3dab0f4fe40cc19c6a3f8daaec52e06b261e58a12519929081900390910190a350506010805460ff1916600117905550505050505050565b61200081565b600081565b60025481565b6402540be40081565b60105460009060ff1660021415611acb576040805162461bcd60e51b815260206004820152600e60248201526d4e6f2072652d656e7472616e637960901b604482015290519081900360640190fd5b506010805460ff191660021790553360009081526008602052604090205480611b32576040805162461bcd60e51b81526020600482015260146024820152736e6f20756e64656c6567617465642066756e647360601b604482015290519081900360640190fd5b336000818152600860205260408082208290556011549051919291849084818181858888f193505050503d8060008114611b88576040519150601f19603f3d011682016040523d82523d6000602084013e611b8d565b606091505b5050905080611bd5576040805162461bcd60e51b815260206004820152600f60248201526e1d1c985b9cd9995c8819985a5b1959608a1b604482015290519081900360640190fd5b60408051838152905133917fc712d133b8d448221aaed2198ed1f0db6dfc860fb01bc3a630916fe6cbef946f919081900360200190a2506010805460ff1916600117905590565b60035490565b60105460ff1660021415611c6e576040805162461bcd60e51b815260206004820152600e60248201526d4e6f2072652d656e7472616e637960901b604482015290519081900360640190fd5b6010805460ff19166002179055806402540be4003406158015611c9657506402540be4008106155b611ce7576040805162461bcd60e51b815260206004820152601c60248201527f707265636973696f6e206c6f737320696e20636f6e76657273696f6e00000000604482015290519081900360640190fd5b60005460ff16611d2a576638d7ea4c6800006001908155662386f26fc1000060025568056bc75e2d631000006003556108fc6011556000805460ff191690911790555b826001600160a01b0316846001600160a01b03161415611d88576040805162461bcd60e51b815260206004820152601460248201527334b73b30b634b2103932b232b632b3b0ba34b7b760611b604482015290519081900360640190fd5b600154341015611dd6576040805162461bcd60e51b81526020600482015260146024820152736e6f7420656e6f7567682072656c61792066656560601b604482015290519081900360640190fd5b600354821015611e1e576040805162461bcd60e51b815260206004820152600e60248201526d1a5b9d985b1a5908185b5bdd5b9d60921b604482015290519081900360640190fd5b3360009081526009602090815260408083206001600160a01b03888116855290835281842090871684529091529020544210801590611e8c57503360009081526009602090815260408083206001600160a01b03878116855290835281842090881684529091529020544210155b611edd576040805162461bcd60e51b815260206004820152601a60248201527f70656e64696e6720726564656c65676174696f6e206578697374000000000000604482015290519081900360640190fd5b604080518082018252601081526f6e6f7420656e6f7567682066756e647360801b602080830191909152336000908152600582528381206001600160a01b038916825290915291822054611f3891859063ffffffff6139f916565b90508015611f80576002548111611f805760405162461bcd60e51b815260040180806020018281038252602581526020018061527a6025913960400191505060405180910390fd5b6000611f97846402540be40063ffffffff6132bf16565b6002549091503490600090611fb390839063ffffffff61330116565b60408051600480825260a0820190925291925060609190816020015b6060815260200190600190039081611fcf579050509050611fef33613343565b81600081518110611ffc57fe5b6020026020010181905250612019896001600160a01b0316613343565b8160018151811061202657fe5b6020026020010181905250612043886001600160a01b0316613343565b8160028151811061205057fe5b602002602001018190525061206484613366565b8160038151811061207157fe5b6020026020010181905250606061208c6003610fc284613379565b8051602080830191909120600f80546000908152600a845260408082209390935581546001908101909255338152600d90935291208054909101905590506120dd42620a8c0063ffffffff61325e16565b3360009081526009602090815260408083206001600160a01b038e81168552908352818420908f16845290915290205561212042620a8c0063ffffffff61325e16565b3360009081526009602090815260408083206001600160a01b038f81168552908352818420908e16845290915290205561200063f7a251d7601083612170876402540be40063ffffffff6132bf16565b6040518463ffffffff1660e01b8152600401808460ff1660ff16815260200180602001838152602001828103825284818151815260200191508051906020019080838360005b838110156121ce5781810151838201526020016121b6565b50505050905090810190601f1680156121fb5780820380516001836020036101000a031916815260200191505b50945050505050600060405180830381600087803b15801561221c57600080fd5b505af1158015612230573d6000803e3d6000fd5b5050604051611004925085156108fc02915085906000818181858888f19350505050158015612263573d6000803e3d6000fd5b506002546040516110029180156108fc02916000818181858888f19350505050158015612294573d6000803e3d6000fd5b50886001600160a01b03168a6001600160a01b0316336001600160a01b03167fdb0d03fdfcb145c486c442659e6a341a8828985505097cb5190afcf541e840158b87604051808381526020018281526020019250505060405180910390a450506010805460ff191660011790555050505050505050565b61100581565b6001600160a01b031660009081526004602052604090205490565b600281565b601081565b6001600160a01b031660009081526008602052604090205490565b61100881565b600b81565b336120001461239c5760405162461bcd60e51b815260040180806020018281038252602f81526020018061539b602f913960400191505060405180910390fd5b60005460ff166123df576638d7ea4c6800006001908155662386f26fc1000060025568056bc75e2d631000006003556108fc6011556000805460ff191690911790555b6123e76151b1565b6124296112f684848080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061348992505050565b905060008060606000805b61243d86613a90565b156124a8578061245a5761245361130b876134f8565b94506124a0565b80600114156124765761246f61130b876134f8565b93506124a0565b806002141561249b5761249061248b876134f8565b613ab1565b9250600191506124a0565b6124a8565b600101612434565b816124ee576040805162461bcd60e51b81526020600482015260116024820152701c9b1c08191958dbd9194819985a5b1959607a1b604482015290519081900360640190fd5b6124f783613b21565b61253a576040805162461bcd60e51b815260206004820152600f60248201526e0eee4dedcce40e0c2c6d640d0c2e6d608b1b604482015290519081900360640190fd5b6125466112f684613489565b9550600061255661130b886134f8565b90506125606151b1565b61256988613a90565b1561258c576125856112f661258061248b8b6134f8565b613489565b90506125cd565b6040805162461bcd60e51b8152602060048201526011602482015270656d7074792061636b207061636b61676560781b604482015290519081900360640190fd5b60ff8216600114156125e9576125e4818888613b75565b612617565b60ff821660021415612600576125e4818888613f2c565b60ff82166003141561134a576125e48188886141f9565b5050505050505050505050565b600981565b61100781565b61100681565b60005460ff1681565b60005460ff16612695576040805162461bcd60e51b815260206004820152601960248201527f74686520636f6e7472616374206e6f7420696e69742079657400000000000000604482015290519081900360640190fd5b33611007146126d55760405162461bcd60e51b815260040180806020018281038252602e8152602001806152ec602e913960400191505060405180910390fd5b61273684848080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152505060408051808201909152600a81526972656c6179657246656560b01b6020820152915061455e9050565b1561289c5760208114612790576040805162461bcd60e51b815260206004820152601d60248201527f6c656e677468206f662072656c61796572466565206d69736d61746368000000604482015290519081900360640190fd5b604080516020601f84018190048102820181019092528281526000916127ce9185858083850183828082843760009201919091525061464592505050565b905060035481106128105760405162461bcd60e51b815260040180806020018281038252602e81526020018061531a602e913960400191505060405180910390fd5b60025481116128505760405162461bcd60e51b815260040180806020018281038252602e815260200180615348602e913960400191505060405180910390fd5b6402540be4008106156128945760405162461bcd60e51b815260040180806020018281038252602c8152602001806152c0602c913960400191505060405180910390fd5b600155612d3e565b61290084848080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152505060408051808201909152600d81526c62534352656c6179657246656560981b6020820152915061455e9050565b15612a62576020811461295a576040805162461bcd60e51b815260206004820181905260248201527f6c656e677468206f662062534352656c61796572466565206d69736d61746368604482015290519081900360640190fd5b604080516020601f84018190048102820181019092528281526000916129989185858083850183828082843760009201919091525061464592505050565b9050806129d65760405162461bcd60e51b81526004018080602001828103825260228152602001806153ca6022913960400191505060405180910390fd5b6001548110612a165760405162461bcd60e51b815260040180806020018281038252602e81526020018061521b602e913960400191505060405180910390fd5b6402540be400810615612a5a5760405162461bcd60e51b815260040180806020018281038252602f8152602001806151ec602f913960400191505060405180910390fd5b600255612d3e565b612ac684848080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152505060408051808201909152600d81526c36b4b72232b632b3b0ba34b7b760991b6020820152915061455e9050565b15612ba85760208114612b20576040805162461bcd60e51b815260206004820181905260248201527f6c656e677468206f66206d696e44656c65676174696f6e206d69736d61746368604482015290519081900360640190fd5b604080516020601f8401819004810282018101909252828152600091612b5e9185858083850183828082843760009201919091525061464592505050565b90506001548111612ba05760405162461bcd60e51b81526004018080602001828103825260318152602001806152496031913960400191505060405180910390fd5b600355612d3e565b612c0a84848080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152505060408051808201909152600b81526a7472616e7366657247617360a81b6020820152915061455e9050565b15612d015760208114612c64576040805162461bcd60e51b815260206004820152601e60248201527f6c656e677468206f66207472616e73666572476173206d69736d617463680000604482015290519081900360640190fd5b604080516020601f8401819004810282018101909252828152600091612ca29185858083850183828082843760009201919091525061464592505050565b905060008111612cf9576040805162461bcd60e51b815260206004820152601e60248201527f746865207472616e736665724761732063616e6e6f74206265207a65726f0000604482015290519081900360640190fd5b601155612d3e565b6040805162461bcd60e51b815260206004820152600d60248201526c756e6b6e6f776e20706172616d60981b604482015290519081900360640190fd5b7f6cdb0ac70ab7f2e2d035cca5be60d89906f2dede7648ddbd7402189c1eeed17a848484846040518080602001806020018381038352878782818152602001925080828437600083820152601f01601f191690910184810383528581526020019050858580828437600083820152604051601f909101601f19169092018290039850909650505050505050a150505050565b600481565b60105460009060ff1660021415612e24576040805162461bcd60e51b815260206004820152600e60248201526d4e6f2072652d656e7472616e637960901b604482015290519081900360640190fd5b506010805460ff191660021790553360009081526006602052604090205480612e88576040805162461bcd60e51b81526020600482015260116024820152701b9bc81c195b991a5b99c81c995dd85c99607a1b604482015290519081900360640190fd5b336000818152600660205260408082208290556011549051919291849084818181858888f193505050503d8060008114612ede576040519150601f19603f3d011682016040523d82523d6000602084013e612ee3565b606091505b5050905080612f2b576040805162461bcd60e51b815260206004820152600f60248201526e1d1c985b9cd9995c8819985a5b1959608a1b604482015290519081900360640190fd5b60408051838152905133917f83b78188b13346b2ffb484da70d42ee27de7fbf9f2bd8045269e10ed643ccd76919081900360200190a2506010805460ff1916600117905590565b6638d7ea4c68000081565b6001600160a01b038083166000908152600760209081526040808320938516835292905220545b92915050565b60015490565b61100281565b3361200014612ff65760405162461bcd60e51b815260040180806020018281038252602f81526020018061539b602f913960400191505060405180910390fd5b60005460ff16613039576638d7ea4c6800006001908155662386f26fc1000060025568056bc75e2d631000006003556108fc6011556000805460ff191690911790555b61307882828080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250613b2192505050565b6130bb576040805162461bcd60e51b815260206004820152600f60248201526e0eee4dedcce40e0c2c6d640d0c2e6d608b1b604482015290519081900360640190fd5b6130c36151b1565b6131056112f684848080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061348992505050565b9050600061311561130b836134f8565b905061311f6151b1565b61312883613a90565b156131465761313f6112f661258061248b866134f8565b905061318c565b6040805162461bcd60e51b8152602060048201526016602482015275656d707479206661696c2061636b207061636b61676560501b604482015290519081900360640190fd5b60ff8216600114156131a6576131a18161464a565b6131d0565b60ff8216600214156131bb576131a181614864565b60ff82166003141561134a576131a18161498e565b5050505b505050565b6001600160a01b03918216600090815260056020908152604080832093909416825291909152205490565b61100381565b68056bc75e2d6310000081565b6001600160a01b0392831660009081526009602090815260408083209486168352938152838220929094168152925290205490565b61100081565b60115481565b61100481565b6000828201838110156132b8576040805162461bcd60e51b815260206004820152601b60248201527f536166654d6174683a206164646974696f6e206f766572666c6f770000000000604482015290519081900360640190fd5b9392505050565b60006132b883836040518060400160405280601a81526020017f536166654d6174683a206469766973696f6e206279207a65726f000000000000815250614af3565b60006132b883836040518060400160405280601e81526020017f536166654d6174683a207375627472616374696f6e206f766572666c6f7700008152506139f9565b60408051600560a21b83186014820152603481019091526060906132b881614b58565b6060612fa461337483614bae565b614b58565b606081516000141561339a5750604080516000815260208101909152611211565b6060826000815181106133a957fe5b602002602001015190506000600190505b83518110156133ea576133e0828583815181106133d357fe5b6020026020010151614c94565b91506001016133ba565b506132b86133fd825160c060ff16614d11565b82614c94565b6040805160028082526060828101909352829190816020015b606081526020019060019003908161341c57905050905061343f8460ff16613366565b8160008151811061344c57fe5b602002602001018190525061346083614b58565b8160018151811061346d57fe5b602002602001018190525061348181613379565b949350505050565b6134916151d1565b506040805180820190915281518152602082810190820152919050565b6134b66151b1565b6134bf82614e09565b6134c857600080fd5b60006134d78360200151614e43565b60208085015160408051808201909152868152920190820152915050919050565b6135006151d1565b61350982613a90565b61351257600080fd5b6020820151600061352282614ea6565b80830160209586015260408051808201909152908152938401919091525090919050565b80516000901580159061355b57508151602110155b61356457600080fd5b60006135738360200151614e43565b905080836000015110156135ce576040805162461bcd60e51b815260206004820152601a60248201527f6c656e677468206973206c657373207468616e206f6666736574000000000000604482015290519081900360640190fd5b8251602080850151830180519284900392918310156135f457826020036101000a820491505b50949350505050565b600060606000806000805b61361187613a90565b1561366357826136335761362c613627886134f8565b614fd9565b9150613658565b82600114156136535761364861130b886134f8565b905060019350613658565b613663565b826001019250613608565b836136a9576040805162461bcd60e51b81526020600482015260116024820152701c9b1c08191958dbd9194819985a5b1959607a1b604482015290519081900360640190fd5b60006110046001600160a01b031663727be1f8836040518263ffffffff1660e01b815260040180828152602001915050602060405180830381600087803b1580156136f357600080fd5b505af1158015613707573d6000803e3d6000fd5b505050506040513d602081101561371d57600080fd5b505190508061374257613734600484846065614ff3565b9650965050505050506137d8565b6001600160a01b03831660009081526006602052604090205461376b908363ffffffff61325e16565b6001600160a01b038416600081815260066020908152604091829020939093558051858152905191927f7cc266c7b444f808013fa187f7b904d470a051a6564e78f482aa496581ba4bf892918290030190a260408051600080825260208201909252909750955050505050505b915091565b6000606060008060008060005b6137f388613a90565b1561385c578361381057613809613627896134f8565b9250613851565b836001141561382c57613825613627896134f8565b9150613851565b836002141561384c5761384161130b896134f8565b905060019450613851565b61385c565b8360010193506137ea565b846138a2576040805162461bcd60e51b81526020600482015260116024820152701c9b1c08191958dbd9194819985a5b1959607a1b604482015290519081900360640190fd5b60006110046001600160a01b031663727be1f8836040518263ffffffff1660e01b815260040180828152602001915050602060405180830381600087803b1580156138ec57600080fd5b505af1158015613900573d6000803e3d6000fd5b505050506040513d602081101561391657600080fd5b505190508061393c5761392d600585846065614ff3565b975097505050505050506137d8565b6001600160a01b038085166000818152600760209081526040808320948816835293815283822082905591815260089091522054613980908363ffffffff61325e16565b6001600160a01b0380861660008181526008602090815260409182902094909455805186815290519287169391927f35a799836f74fac7eccf5c73902823b970543d2274d3b93d8da3d37a255772a2929181900390910190a3604080516000808252602082019092529098509650505050505050915091565b60008184841115613a885760405162461bcd60e51b81526004018080602001828103825283818151815260200191508051906020019080838360005b83811015613a4d578181015183820152602001613a35565b50505050905090810190601f168015613a7a5780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b505050900390565b6000613a9a6151d1565b505080518051602091820151919092015191011190565b8051606090613abf57600080fd5b6000613ace8360200151614e43565b83516040805191839003808352601f19601f8201168301602001909152919250606090828015613b05576020820181803683370190505b50905060008160200190506135f48487602001510182856150ef565b8051602080830191909120600e546000908152600a9092526040822054808214613b5057600092505050611211565b5050600e80546000908152600a60205260408120558054600190810190915592915050565b60008060008060005b613b8788613a90565b15613bf05783613ba457613b9d613627896134f8565b9250613be5565b8360011415613bc057613bb9613627896134f8565b9150613be5565b8360021415613be057613bd561130b896134f8565b905060019450613be5565b613bf0565b836001019350613b7e565b84613c36576040805162461bcd60e51b81526020600482015260116024820152701c9b1c08191958dbd9194819985a5b1959607a1b604482015290519081900360640190fd5b6000613c4d826402540be40063ffffffff61513a16565b6001600160a01b0385166000908152600b602052604090208054600019019055905060ff881660011415613d935760ff871615613cc0576040805162461bcd60e51b815260206004820152600c60248201526b77726f6e672073746174757360a01b604482015290519081900360640190fd5b6001600160a01b038416600090815260046020526040902054613ce9908263ffffffff61325e16565b6001600160a01b03808616600090815260046020908152604080832094909455600581528382209287168252919091522054613d2b908263ffffffff61325e16565b6001600160a01b038086166000818152600560209081526040808320948916808452948252918290209490945580518581529051929391927f9a57c81564ab02642f34fd87e41baa9b074c18342cec3b7268b62bf752018fd1929181900390910190a3613f21565b60ff8816613ee5576001600160a01b038416600090815260086020526040902054613dc4908263ffffffff61325e16565b6001600160a01b0385166000908152600860209081526040808320939093558251630e4f7c3f60e31b81526004810185905292516110049363727be1f89360248083019493928390030190829087803b158015613e2057600080fd5b505af1158015613e34573d6000803e3d6000fd5b505050506040513d6020811015613e4a57600080fd5b5051613e93576040805162461bcd60e51b81526020600482015260136024820152721dda5d1a191c985dc8189b988819985a5b1959606a1b604482015290519081900360640190fd5b6040805182815260ff8916602082015281516001600160a01b0380871693908816927fcbd481ae600289fad8c0484d07ce0ffe4f010d7c844ecfdeaf2a13fead52886e929081900390910190a3613f21565b6040805162461bcd60e51b815260206004820152600c60248201526b77726f6e672073746174757360a01b604482015290519081900360640190fd5b505050505050505050565b60008060008060005b613f3e88613a90565b15613fa75783613f5b57613f54613627896134f8565b9250613f9c565b8360011415613f7757613f70613627896134f8565b9150613f9c565b8360021415613f9757613f8c61130b896134f8565b905060019450613f9c565b613fa7565b836001019350613f35565b84613fed576040805162461bcd60e51b81526020600482015260116024820152701c9b1c08191958dbd9194819985a5b1959607a1b604482015290519081900360640190fd5b6000614004826402540be40063ffffffff61513a16565b6001600160a01b0385166000908152600c602052604090208054600019019055905060ff8816600114156141835760ff871615614077576040805162461bcd60e51b815260206004820152600c60248201526b77726f6e672073746174757360a01b604482015290519081900360640190fd5b6001600160a01b0384166000908152600460205260409020546140a0908263ffffffff61330116565b6001600160a01b038086166000908152600460209081526040808320949094556005815283822092871682529190915220546140e2908263ffffffff61330116565b6001600160a01b0380861660009081526005602090815260408083209388168352929052205561411b42620a8c0063ffffffff61325e16565b6001600160a01b038086166000818152600760209081526040808320948916808452948252918290209490945580518581529051929391927fd6f878a5bcbbe79a64e6418bb0d56aaa20b9a60587d45749819df88dfc7c3c44929181900390910190a3613f21565b60ff8816613ee5576001600160a01b03808516600081815260076020908152604080832094881680845294825280832092909255815185815260ff8c169181019190915281517f4417d10c1e33efa83a770b8d4f47176e78c08c1298d534901ad3b16bb585fa2e929181900390910190a3613f21565b6000806000806000805b61420c89613a90565b156142915784614229576142226136278a6134f8565b9350614286565b84600114156142455761423e6136278a6134f8565b9250614286565b84600214156142615761425a6136278a6134f8565b9150614286565b84600314156142815761427661130b8a6134f8565b905060019550614286565b614291565b846001019450614203565b856142d7576040805162461bcd60e51b81526020600482015260116024820152701c9b1c08191958dbd9194819985a5b1959607a1b604482015290519081900360640190fd5b60006142ee826402540be40063ffffffff61513a16565b6001600160a01b0386166000908152600d602052604090208054600019019055905060ff8916600114156144c15760ff881615614361576040805162461bcd60e51b815260206004820152600c60248201526b77726f6e672073746174757360a01b604482015290519081900360640190fd5b6001600160a01b03808616600090815260056020908152604080832093881683529290522054614397908263ffffffff61330116565b6001600160a01b038681166000908152600560209081526040808320898516845290915280822093909355908516815220546143d3908261325e565b6001600160a01b0380871660009081526005602090815260408083209388168352929052205561440c42620a8c0063ffffffff61325e16565b6001600160a01b038087166000908152600960209081526040808320898516845282528083209388168352929052205561444f42620a8c0063ffffffff61325e16565b6001600160a01b038087166000818152600960209081526040808320898616808552908352818420958b1680855295835292819020959095558451868152945191947f78bffae3f8c6691ac7fc1a3bff800cb2d612f5ad9ae5b0444cfe2eb15c189e18929081900390910190a4614552565b60ff8916613ee5576001600160a01b038581166000818152600960209081526040808320898616808552818452828520968a16808652968452828520859055908352818420818552835281842093909355805186815260ff8e169281019290925280519293927fb93bee5c59f85ede6b074a99f4ffcd3e3fc0d5c3d8156de331de89a49e0ce77c9281900390910190a45b50505050505050505050565b6000816040516020018082805190602001908083835b602083106145935780518252601f199092019160209182019101614574565b6001836020036101000a03801982511681845116808217855250505050505090500191505060405160208183030381529060405280519060200120836040516020018082805190602001908083835b602083106146015780518252601f1990920191602091820191016145e2565b6001836020036101000a0380198251168184511680821785525050505050509050019150506040516020818303038152906040528051906020012014905092915050565b015190565b60008060008060005b61465c86613a90565b156146c5578361467957614672613627876134f8565b92506146ba565b83600114156146955761468e613627876134f8565b91506146ba565b83600214156146b5576146aa61130b876134f8565b9050600194506146ba565b6146c5565b836001019350614653565b8461470b576040805162461bcd60e51b81526020600482015260116024820152701c9b1c08191958dbd9194819985a5b1959607a1b604482015290519081900360640190fd5b6000614722826402540be40063ffffffff61513a16565b6001600160a01b0385166000908152600b6020908152604080832080546000190190556008909152902054909150614760908263ffffffff61325e16565b6001600160a01b0385166000908152600860209081526040808320939093558251630e4f7c3f60e31b81526004810185905292516110049363727be1f89360248083019493928390030190829087803b1580156147bc57600080fd5b505af11580156147d0573d6000803e3d6000fd5b505050506040513d60208110156147e657600080fd5b505161482f576040805162461bcd60e51b81526020600482015260136024820152721dda5d1a191c985dc8189b988819985a5b1959606a1b604482015290519081900360640190fd5b6040516001907ff83de021914a4585482db5ca47d520a5657165b443fa2c7ef8ed4635f054da9b90600090a250505050505050565b60008060008060005b61487686613a90565b156148df57836148935761488c613627876134f8565b92506148d4565b83600114156148af576148a8613627876134f8565b91506148d4565b83600214156148cf576148c461130b876134f8565b9050600194506148d4565b6148df565b83600101935061486d565b84614925576040805162461bcd60e51b81526020600482015260116024820152701c9b1c08191958dbd9194819985a5b1959607a1b604482015290519081900360640190fd5b6001600160a01b038084166000908152600c60209081526040808320805460001901905560078252808320938616835292905281812081905590516002917ff83de021914a4585482db5ca47d520a5657165b443fa2c7ef8ed4635f054da9b91a2505050505050565b6000806000806000805b6149a187613a90565b15614a2657846149be576149b7613627886134f8565b9350614a1b565b84600114156149da576149d3613627886134f8565b9250614a1b565b84600214156149f6576149ef613627886134f8565b9150614a1b565b8460031415614a1657614a0b61130b886134f8565b905060019550614a1b565b614a26565b846001019450614998565b85614a6c576040805162461bcd60e51b81526020600482015260116024820152701c9b1c08191958dbd9194819985a5b1959607a1b604482015290519081900360640190fd5b6001600160a01b038481166000908152600d602090815260408083208054600019019055600982528083208785168085528184528285209588168552948352818420849055825280832093835292905281812081905590516003917ff83de021914a4585482db5ca47d520a5657165b443fa2c7ef8ed4635f054da9b91a250505050505050565b60008183614b425760405162461bcd60e51b8152602060048201818152835160248401528351909283926044909101919085019080838360008315613a4d578181015183820152602001613a35565b506000838581614b4e57fe5b0495945050505050565b606081516001148015614b8a5750607f60f81b82600081518110614b7857fe5b01602001516001600160f81b03191611155b15614b96575080611211565b612fa4614ba88351608060ff16614d11565b83614c94565b604080516020808252818301909252606091829190602082018180368337505050602081018490529050600067ffffffffffffffff198416614bf257506018614c16565b6fffffffffffffffffffffffffffffffff198416614c1257506010614c16565b5060005b6020811015614c4c57818181518110614c2b57fe5b01602001516001600160f81b03191615614c4457614c4c565b600101614c16565b60008160200390506060816040519080825280601f01601f191660200182016040528015614c81576020820181803683370190505b5080830196909652508452509192915050565b6060806040519050835180825260208201818101602087015b81831015614cc5578051835260209283019201614cad565b50855184518101855292509050808201602086015b81831015614cf2578051835260209283019201614cda565b508651929092011591909101601f01601f191660405250905092915050565b6060680100000000000000008310614d61576040805162461bcd60e51b815260206004820152600e60248201526d696e70757420746f6f206c6f6e6760901b604482015290519081900360640190fd5b60408051600180825281830190925260609160208201818036833701905050905060378411614dbb5782840160f81b81600081518110614d9d57fe5b60200101906001600160f81b031916908160001a9053509050612fa4565b6060614dc685614bae565b90508381510160370160f81b82600081518110614ddf57fe5b60200101906001600160f81b031916908160001a905350614e008282614c94565b95945050505050565b8051600090614e1a57506000611211565b6020820151805160001a9060c0821015614e3957600092505050611211565b5060019392505050565b8051600090811a6080811015614e5d576000915050611211565b60b8811080614e78575060c08110801590614e78575060f881105b15614e87576001915050611211565b60c0811015614e9b5760b519019050611211565b60f519019050611211565b80516000908190811a6080811015614ec15760019150614fd2565b60b8811015614ed657607e1981019150614fd2565b60c0811015614f5057600060b78203600186019550806020036101000a865104915060018101820193505080831015614f4a576040805162461bcd60e51b81526020600482015260116024820152706164646974696f6e206f766572666c6f7760781b604482015290519081900360640190fd5b50614fd2565b60f8811015614f655760be1981019150614fd2565b600060f78203600186019550806020036101000a865104915060018101820193505080831015614fd0576040805162461bcd60e51b81526020600482015260116024820152706164646974696f6e206f766572666c6f7760781b604482015290519081900360640190fd5b505b5092915050565b8051600090601514614fea57600080fd5b612fa482613546565b6000606061500c846402540be40063ffffffff6132bf16565b60408051600480825260a0820190925291955060609190816020015b606081526020019060019003908161502857905050905061504b8760ff16613366565b8160008151811061505857fe5b6020026020010181905250615075866001600160a01b0316613343565b8160018151811061508257fe5b602002602001018190525061509685613366565b816002815181106150a357fe5b60200260200101819052506150bd8463ffffffff16613366565b816003815181106150ca57fe5b602002602001018190525060606150e082613379565b94989497509395505050505050565b806150f9576131d4565b5b60208110615119578251825260209283019290910190601f19016150fa565b915181516020939093036101000a6000190180199091169216919091179052565b60008261514957506000612fa4565b8282028284828161515657fe5b04146132b85760405162461bcd60e51b815260040180806020018281038252602181526020018061529f6021913960400191505060405180910390fd5b60405180606001604052806003906020820280368337509192915050565b60405180604001604052806151c46151d1565b8152602001600081525090565b60405180604001604052806000815260200160008152509056fe7468652042534352656c61796572466565206d6f642074656e20646563696d616c73206d757374206265207a65726f7468652042534352656c61796572466565206d757374206265206c657373207468616e2072656c61796572466565746865206d696e44656c65676174696f6e206d7573742062652067726561746572207468616e2072656c61796572466565696e73756666696369656e742062616c616e636520616674657220726564656c6567617465536166654d6174683a206d756c7469706c69636174696f6e206f766572666c6f777468652072656c61796572466565206d6f642074656e20646563696d616c73206d757374206265207a65726f746865206d6573736167652073656e646572206d75737420626520676f7665726e616e636520636f6e74726163747468652072656c61796572466565206d757374206265206c657373207468616e206d696e44656c65676174696f6e7468652072656c61796572466565206d757374206265206d6f7265207468616e2042534352656c61796572466565696e73756666696369656e742062616c616e636520616674657220756e64656c6567617465746865206d6573736167652073656e646572206d7573742062652063726f737320636861696e20636f6e74726163747468652042534352656c61796572466565206d757374206e6f74206265207a65726fa2646970667358221220de1a90a99417952bd5d4f424161817780a15ff9f30026401fbf3cc2b00ccc44464736f6c63430006040033", + }, + }, + } + + PlanckUpgrade[networkname.RialtoChainName] = &Upgrade{ + UpgradeName: "planck", + Configs: []*UpgradeConfig{ + { + ContractAddr: SlashContract, + CommitUrl: "https://github.com/bnb-chain/bsc-genesis-contract/commit/78e13b1d3a5a1b08c9208af94a9b14fc1efda213", + Code: "608060405234801561001057600080fd5b50600436106102535760003560e01c80637942fd0511610146578063ac431751116100c3578063dc927faf11610087578063dc927faf1461073b578063e1c7392a14610743578063f9a2bbc71461074b578063fc3e590814610753578063fc4333cd1461075b578063fd6a68791461076357610253565b8063ac431751146105cf578063c80d4b8f1461068d578063c81b166214610695578063c8509d811461069d578063c96be4cb1461071557610253565b80639dc092621161010a5780639dc0926214610593578063a1a11bf51461059b578063a78abc16146105a3578063ab51bb96146105bf578063ac0af629146105c757610253565b80637942fd05146104fb5780638256ace614610503578063831d65d11461050b57806396713da9146105835780639bc8e4f21461058b57610253565b80634bf6c882116101d45780636e47b482116101985780636e47b482146104d357806370fd5bad146104db578063718a8aa8146104e357806375d47a0a146104eb5780637912a65d146104f357610253565b80634bf6c8821461048b57806351e8067214610493578063567a372d1461049b5780635bfb4990146104a357806362b72cf5146104cb57610253565b806337c8dab91161021b57806337c8dab9146103ed578063389f4f711461042c5780633dffc3871461044657806343756e5c14610464578063493279b11461046c57610253565b80630bee7a67146102585780630e2374a5146102795780631182b8751461029d57806323bac5a21461038a57806335aa2e44146103d0575b600080fd5b61026061076b565b6040805163ffffffff9092168252519081900360200190f35b610281610770565b604080516001600160a01b039092168252519081900360200190f35b610315600480360360408110156102b357600080fd5b60ff8235169190810190604081016020820135600160201b8111156102d757600080fd5b8201836020820111156102e957600080fd5b803590602001918460018302840111600160201b8311171561030a57600080fd5b509092509050610776565b6040805160208082528351818301528351919283929083019185019080838360005b8381101561034f578181015183820152602001610337565b50505050905090810190601f16801561037c5780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b6103b0600480360360208110156103a057600080fd5b50356001600160a01b031661084a565b604080519384526020840192909252151582820152519081900360600190f35b610281600480360360208110156103e657600080fd5b503561086d565b6104136004803603602081101561040357600080fd5b50356001600160a01b0316610894565b6040805192835260208301919091528051918290030190f35b6104346108eb565b60408051918252519081900360200190f35b61044e6108f1565b6040805160ff9092168252519081900360200190f35b6102816108f6565b6104746108fc565b6040805161ffff9092168252519081900360200190f35b61044e610902565b610281610907565b61043461090d565b6104c9600480360360208110156104b957600080fd5b50356001600160a01b0316610913565b005b610434610a74565b610281610a7a565b61044e610a80565b61044e610a85565b610281610a8a565b610434610a90565b61044e610a95565b610413610a9a565b6104c96004803603604081101561052157600080fd5b60ff8235169190810190604081016020820135600160201b81111561054557600080fd5b82018360208201111561055757600080fd5b803590602001918460018302840111600160201b8311171561057857600080fd5b509092509050610aa4565b61044e610bfe565b610434610c03565b610281610c0e565b610281610c14565b6105ab610c1a565b604080519115158252519081900360200190f35b610260610c23565b610434610c28565b6104c9600480360360408110156105e557600080fd5b810190602081018135600160201b8111156105ff57600080fd5b82018360208201111561061157600080fd5b803590602001918460018302840111600160201b8311171561063257600080fd5b919390929091602081019035600160201b81111561064f57600080fd5b82018360208201111561066157600080fd5b803590602001918460018302840111600160201b8311171561068257600080fd5b509092509050610c2d565b61043461101b565b610281611020565b6104c9600480360360408110156106b357600080fd5b60ff8235169190810190604081016020820135600160201b8111156106d757600080fd5b8201836020820111156106e957600080fd5b803590602001918460018302840111600160201b8311171561070a57600080fd5b509092509050611026565b6104c96004803603602081101561072b57600080fd5b50356001600160a01b03166110d9565b61028161165a565b6104c9611660565b6102816116d1565b61044e6116d7565b6104c96116dc565b610281611b67565b606481565b61200181565b606033612000146107b85760405162461bcd60e51b815260040180806020018281038252602f8152602001806125bf602f913960400191505060405180910390fd5b60005460ff166107fd576040805162461bcd60e51b8152602060048201526019602482015260008051602061261b833981519152604482015290519081900360640190fd5b6040805162461bcd60e51b815260206004820152601e60248201527f7265636569766520756e65787065637465642073796e207061636b6167650000604482015290519081900360640190fd5b600260208190526000918252604090912080546001820154919092015460ff1683565b6001818154811061087a57fe5b6000918252602090912001546001600160a01b0316905081565b60008061089f612483565b5050506001600160a01b0316600090815260026020818152604092839020835160608101855281548082526001830154938201849052919093015460ff16151592909301919091529091565b60055481565b600181565b61100181565b6102ca81565b600881565b61200081565b60045481565b33611000146109535760405162461bcd60e51b815260040180806020018281038252603081526020018061251a6030913960400191505060405180910390fd5b60005460ff16610998576040805162461bcd60e51b8152602060048201526019602482015260008051602061261b833981519152604482015290519081900360640190fd5b61200063f7a251d7600b6109ab84611b6d565b60006040518463ffffffff1660e01b8152600401808460ff1660ff16815260200180602001838152602001828103825284818151815260200191508051906020019080838360005b83811015610a0b5781810151838201526020016109f3565b50505050905090810190601f168015610a385780820380516001836020036101000a031916815260200191505b50945050505050600060405180830381600087803b158015610a5957600080fd5b505af1158015610a6d573d6000803e3d6000fd5b5050505050565b60035481565b61100581565b600281565b601081565b61100881565b603281565b600b81565b6004546005549091565b3361200014610ae45760405162461bcd60e51b815260040180806020018281038252602f8152602001806125bf602f913960400191505060405180910390fd5b60005460ff16610b29576040805162461bcd60e51b8152602060048201526019602482015260008051602061261b833981519152604482015290519081900360640190fd5b610b316124a6565b6000610b7284848080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250611c4092505050565b915091508015610bbc5781516040805163ffffffff9092168252517f7f0956d47419b9525356e7111652b653b530ec6f5096dccc04589bc38e6299679181900360200190a1610a6d565b81516040805163ffffffff9092168252517f7d45f62d17443dd4547bca8a8112c60e2385669318dc300ec61a5d2492f262e79181900360200190a15050505050565b600981565b662386f26fc1000081565b61100781565b61100681565b60005460ff1681565b600081565b600481565b60005460ff16610c72576040805162461bcd60e51b8152602060048201526019602482015260008051602061261b833981519152604482015290519081900360640190fd5b3361100714610cb25760405162461bcd60e51b815260040180806020018281038252602e81526020018061254a602e913960400191505060405180910390fd5b610d1d84848080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250506040805180820190915260148152731b5a5cd9195b59585b9bdc951a1c995cda1bdb1960621b60208201529150611cc09050565b15610df65760208114610d615760405162461bcd60e51b81526004018080602001828103825260278152602001806124f36027913960400191505060405180910390fd5b604080516020601f8401819004810282018101909252828152600091610d9f91858580838501838280828437600092019190915250611da892505050565b905060018110158015610db3575060055481105b610dee5760405162461bcd60e51b815260040180806020018281038252602581526020018061259a6025913960400191505060405180910390fd5b600455610f89565b610e5c84848080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152505060408051808201909152600f81526e19995b1bdb9e551a1c995cda1bdb19608a1b60208201529150611cc09050565b15610f4c5760208114610ea05760405162461bcd60e51b81526004018080602001828103825260228152602001806125786022913960400191505060405180910390fd5b604080516020601f8401819004810282018101909252828152600091610ede91858580838501838280828437600092019190915250611da892505050565b90506103e88111158015610ef3575060045481115b610f44576040805162461bcd60e51b815260206004820181905260248201527f7468652066656c6f6e795468726573686f6c64206f7574206f662072616e6765604482015290519081900360640190fd5b600555610f89565b6040805162461bcd60e51b815260206004820152600d60248201526c756e6b6e6f776e20706172616d60981b604482015290519081900360640190fd5b7f6cdb0ac70ab7f2e2d035cca5be60d89906f2dede7648ddbd7402189c1eeed17a848484846040518080602001806020018381038352878782818152602001925080828437600083820152601f01601f191690910184810383528581526020019050858580828437600083820152604051601f909101601f19169092018290039850909650505050505050a150505050565b609681565b61100281565b33612000146110665760405162461bcd60e51b815260040180806020018281038252602f8152602001806125bf602f913960400191505060405180910390fd5b60005460ff166110ab576040805162461bcd60e51b8152602060048201526019602482015260008051602061261b833981519152604482015290519081900360640190fd5b6040517f07db600eebe2ac176be8dcebad61858c245a4961bb32ca2aa3d159b09aa0810e90600090a1505050565b3341146111175760405162461bcd60e51b815260040180806020018281038252602d8152602001806125ee602d913960400191505060405180910390fd5b60005460ff1661115c576040805162461bcd60e51b8152602060048201526019602482015260008051602061261b833981519152604482015290519081900360640190fd5b60035443116111b2576040805162461bcd60e51b815260206004820181905260248201527f63616e206e6f7420736c61736820747769636520696e206f6e6520626c6f636b604482015290519081900360640190fd5b3a156111fc576040805162461bcd60e51b81526020600482015260146024820152736761737072696365206973206e6f74207a65726f60601b604482015290519081900360640190fd5b6040805163155853f360e21b81526001600160a01b03831660048201529051611000916355614fcc916024808301926020929190829003018186803b15801561124457600080fd5b505afa158015611258573d6000803e3d6000fd5b505050506040513d602081101561126e57600080fd5b505161127957611653565b611281612483565b506001600160a01b0381166000908152600260208181526040928390208351606081018552815481526001820154928101929092529091015460ff1615801592820192909252906112dc576020810180516001019052611335565b60016040820181905260208201819052805480820182556000919091527fb10e2d527612073b26eecdfd717e6a320cf44b4afac2b0732d9fcbe2b7fa0cf60180546001600160a01b0319166001600160a01b0384161790555b43815260055460208201518161134757fe5b0661157757600060208201819052604080516335409f7f60e01b81526001600160a01b03851660048201529051611000926335409f7f926024808201939182900301818387803b15801561139a57600080fd5b505af11580156113ae573d6000803e3d6000fd5b505050506120006001600160a01b031663f7a251d7600b6113ce85611b6d565b60006040518463ffffffff1660e01b8152600401808460ff1660ff16815260200180602001838152602001828103825284818151815260200191508051906020019080838360005b8381101561142e578181015183820152602001611416565b50505050905090810190601f16801561145b5780820380516001836020036101000a031916815260200191505b50945050505050600060405180830381600087803b15801561147c57600080fd5b505af192505050801561148d575060015b611572573d8080156114bb576040519150601f19603f3d011682016040523d82523d6000602084013e6114c0565b606091505b50826001600160a01b03167fd7bc86ff5d08c8ab043edec743302aba2520e6635172a428bc956721db9e2d1c8360200151836040518083815260200180602001828103825283818151815260200191508051906020019080838360005b8381101561153557818101518382015260200161151d565b50505050905090810190601f1680156115625780820380516001836020036101000a031916815260200191505b50935050505060405180910390a2505b6115ed565b60045481602001518161158657fe5b066115ed57604080516375abf10160e11b81526001600160a01b038416600482015290516110009163eb57e20291602480830192600092919082900301818387803b1580156115d457600080fd5b505af11580156115e8573d6000803e3d6000fd5b505050505b6001600160a01b0382166000818152600260208181526040808420865181559186015160018301558581015191909201805460ff1916911515919091179055517fddb6012116e51abf5436d956a4f0ebd927e92c576ff96d7918290c8782291e3e9190a2505b5043600355565b61100381565b60005460ff16156116b8576040805162461bcd60e51b815260206004820152601960248201527f74686520636f6e747261637420616c726561647920696e697400000000000000604482015290519081900360640190fd5b603260045560966005556000805460ff19166001179055565b61100081565b600381565b336110001461171c5760405162461bcd60e51b815260040180806020018281038252603081526020018061251a6030913960400191505060405180910390fd5b60005460ff16611761576040805162461bcd60e51b8152602060048201526019602482015260008051602061261b833981519152604482015290519081900360640190fd5b60015461176d57611b65565b600154600090600019015b808211611b39576000805b8284101561189c57611793612483565b60026000600187815481106117a457fe5b60009182526020808320909101546001600160a01b0316835282810193909352604091820190208151606081018352815481526001820154938101939093526002015460ff1615159082015260055490915060049004816020015111156118865760046005548161181157fe5b0481602001510381602001818152505080600260006001888154811061183357fe5b6000918252602080832091909101546001600160a01b0316835282810193909352604091820190208351815591830151600183015591909101516002909101805460ff1916911515919091179055611890565b600192505061189c565b50600190930192611783565b828411611a33576118ab612483565b60026000600186815481106118bc57fe5b60009182526020808320909101546001600160a01b0316835282810193909352604091820190208151606081018352815481526001820154938101939093526002015460ff1615159082015260055490915060049004816020015111156119a45760046005548161192957fe5b0481602001510381602001818152505080600260006001878154811061194b57fe5b6000918252602080832091909101546001600160a01b03168352828101939093526040918201902083518155918301516001808401919091559201516002909101805460ff19169115159190911790559150611a339050565b60026000600186815481106119b557fe5b60009182526020808320909101546001600160a01b031683528201929092526040018120818155600181810192909255600201805460ff191690558054806119f957fe5b600082815260209020810160001990810180546001600160a01b031916905501905583611a265750611a33565b506000199092019161189c565b818015611a3d5750805b15611b1c576002600060018681548110611a5357fe5b60009182526020808320909101546001600160a01b031683528201929092526040018120818155600181810192909255600201805460ff19169055805484908110611a9a57fe5b600091825260209091200154600180546001600160a01b039092169186908110611ac057fe5b9060005260206000200160006101000a8154816001600160a01b0302191690836001600160a01b031602179055506001805480611af957fe5b600082815260209020810160001990810180546001600160a01b03191690550190555b82611b28575050611b39565b505060019091019060001901611778565b6040517fcfdb3b6ccaeccbdc68be3c59c840e3b3c90f0a7c491f5fff1cf56cfda200dd9c90600090a150505b565b61100481565b60408051600480825260a08201909252606091829190816020015b6060815260200190600190039081611b88579050509050611bb1836001600160a01b0316611dad565b81600081518110611bbe57fe5b6020026020010181905250611bd243611dd0565b81600181518110611bdf57fe5b6020908102919091010152611bf56102ca611dd0565b81600281518110611c0257fe5b6020026020010181905250611c1642611dd0565b81600381518110611c2357fe5b6020026020010181905250611c3781611de3565b9150505b919050565b611c486124a6565b6000611c526124a6565b611c5a6124b8565b611c6b611c6686611e6d565b611e92565b90506000805b611c7a83611edc565b15611cb35780611ca657611c95611c9084611efd565b611f4b565b63ffffffff16845260019150611cab565b611cb3565b600101611c71565b5091935090915050915091565b6000816040516020018082805190602001908083835b60208310611cf55780518252601f199092019160209182019101611cd6565b6001836020036101000a03801982511681845116808217855250505050505090500191505060405160208183030381529060405280519060200120836040516020018082805190602001908083835b60208310611d635780518252601f199092019160209182019101611d44565b6001836020036101000a038019825116818451168082178552505050505050905001915050604051602081830303815290604052805190602001201490505b92915050565b015190565b60408051600560a21b8318601482015260348101909152606090611c3781612002565b6060611da2611dde83612058565b612002565b6060815160001415611e045750604080516000815260208101909152611c3b565b606082600081518110611e1357fe5b602002602001015190506000600190505b8351811015611e5457611e4a82858381518110611e3d57fe5b602002602001015161213e565b9150600101611e24565b50611c37611e67825160c060ff166121bb565b8261213e565b611e756124d8565b506040805180820190915281518152602082810190820152919050565b611e9a6124b8565b611ea3826122b3565b611eac57600080fd5b6000611ebb83602001516122ed565b60208085015160408051808201909152868152920190820152915050919050565b6000611ee66124d8565b505080518051602091820151919092015191011190565b611f056124d8565b611f0e82611edc565b611f1757600080fd5b60208201516000611f2782612350565b80830160209586015260408051808201909152908152938401919091525090919050565b805160009015801590611f6057508151602110155b611f6957600080fd5b6000611f7883602001516122ed565b90508083600001511015611fd3576040805162461bcd60e51b815260206004820152601a60248201527f6c656e677468206973206c657373207468616e206f6666736574000000000000604482015290519081900360640190fd5b825160208085015183018051928490039291831015611ff957826020036101000a820491505b50949350505050565b6060815160011480156120345750607f60f81b8260008151811061202257fe5b01602001516001600160f81b03191611155b15612040575080611c3b565b611da26120528351608060ff166121bb565b8361213e565b604080516020808252818301909252606091829190602082018180368337505050602081018490529050600067ffffffffffffffff19841661209c575060186120c0565b6fffffffffffffffffffffffffffffffff1984166120bc575060106120c0565b5060005b60208110156120f6578181815181106120d557fe5b01602001516001600160f81b031916156120ee576120f6565b6001016120c0565b60008160200390506060816040519080825280601f01601f19166020018201604052801561212b576020820181803683370190505b5080830196909652508452509192915050565b6060806040519050835180825260208201818101602087015b8183101561216f578051835260209283019201612157565b50855184518101855292509050808201602086015b8183101561219c578051835260209283019201612184565b508651929092011591909101601f01601f191660405250905092915050565b606068010000000000000000831061220b576040805162461bcd60e51b815260206004820152600e60248201526d696e70757420746f6f206c6f6e6760901b604482015290519081900360640190fd5b604080516001808252818301909252606091602082018180368337019050509050603784116122655782840160f81b8160008151811061224757fe5b60200101906001600160f81b031916908160001a9053509050611da2565b606061227085612058565b90508381510160370160f81b8260008151811061228957fe5b60200101906001600160f81b031916908160001a9053506122aa828261213e565b95945050505050565b80516000906122c457506000611c3b565b6020820151805160001a9060c08210156122e357600092505050611c3b565b5060019392505050565b8051600090811a6080811015612307576000915050611c3b565b60b8811080612322575060c08110801590612322575060f881105b15612331576001915050611c3b565b60c08110156123455760b519019050611c3b565b60f519019050611c3b565b80516000908190811a608081101561236b576001915061247c565b60b881101561238057607e198101915061247c565b60c08110156123fa57600060b78203600186019550806020036101000a8651049150600181018201935050808310156123f4576040805162461bcd60e51b81526020600482015260116024820152706164646974696f6e206f766572666c6f7760781b604482015290519081900360640190fd5b5061247c565b60f881101561240f5760be198101915061247c565b600060f78203600186019550806020036101000a86510491506001810182019350508083101561247a576040805162461bcd60e51b81526020600482015260116024820152706164646974696f6e206f766572666c6f7760781b604482015290519081900360640190fd5b505b5092915050565b604051806060016040528060008152602001600081526020016000151581525090565b60408051602081019091526000815290565b60405180604001604052806124cb6124d8565b8152602001600081525090565b60405180604001604052806000815260200160008152509056fe6c656e677468206f66206d697364656d65616e6f725468726573686f6c64206d69736d61746368746865206d6573736167652073656e646572206d7573742062652076616c696461746f7253657420636f6e7472616374746865206d6573736167652073656e646572206d75737420626520676f7665726e616e636520636f6e74726163746c656e677468206f662066656c6f6e795468726573686f6c64206d69736d61746368746865206d697364656d65616e6f725468726573686f6c64206f7574206f662072616e6765746865206d6573736167652073656e646572206d7573742062652063726f737320636861696e20636f6e7472616374746865206d6573736167652073656e646572206d7573742062652074686520626c6f636b2070726f647563657274686520636f6e7472616374206e6f7420696e69742079657400000000000000a2646970667358221220cc9198ce38d8be4b5a181b087111399299cbd68d44ed3c4d165ee1288b79e17164736f6c63430006040033", + }, + { + ContractAddr: TokenHubContract, + CommitUrl: "https://github.com/bnb-chain/bsc-genesis-contract/commit/78e13b1d3a5a1b08c9208af94a9b14fc1efda213", + Code: "6080604052600436106103c75760003560e01c806396713da9116101f2578063c81b16621161010d578063f0148472116100a0578063fc1a598f1161006f578063fc1a598f14610f25578063fc3e590814610b85578063fd6a687914610f58578063ff9c0027146107fd5761040f565b8063f014847214610ed1578063f9a2bbc714610ee6578063fa9e915914610efb578063fb063e8f14610f105761040f565b8063dc927faf116100dc578063dc927faf14610e5f578063e1c7392a14610e74578063e8f35cea14610e89578063ebf71d5314610ebc5761040f565b8063c81b166214610d8a578063c8509d8114610d9f578063cf41984414610e24578063d9e6dae91461077f5761040f565b8063aa7415f511610185578063b9fd21e311610154578063b9fd21e314610cfa578063ba35ead614610d0f578063bbface1f14610d24578063bd46646114610d575761040f565b8063aa7415f514610b9a578063ab51bb9614610be1578063ac43175114610bf6578063b99328c514610cc15761040f565b8063a1a11bf5116101c1578063a1a11bf514610b46578063a496fba214610b5b578063a78abc1614610b70578063a7c9f02d14610b855761040f565b806396713da914610ace5780639a854bbd14610ae35780639a99b4f014610af85780639dc0926214610b315761040f565b806359b92789116102e257806371d3086311610275578063831d65d111610244578063831d65d1146109d15780638b87b21f146106d45780638eff336c14610a565780639509b98014610a955761040f565b806371d3086314610968578063727be1f81461097d57806375d47a0a146109a75780637942fd05146109bc5761040f565b80636e056520116102b15780636e056520146108125780636e47b4821461093e57806370fd5bad146107fd578063718a8aa8146109535761040f565b806359b92789146107be5780635d499b1b146107e8578063613684751461077f57806366dea52a146107fd5761040f565b80633fd8b02f1161035a5780634a3acdf4116103295780634a3acdf41461076a5780634bf6c8821461077f57806350432d321461079457806351e80672146107a95761040f565b80633fd8b02f146106ff57806343756e5c1461071457806343a368b914610729578063493279b11461073e5761040f565b8063149d14d911610396578063149d14d9146105a85780632ae45483146105cf5780633d713223146106235780633dffc387146106d45761040f565b80630bee7a67146104145780630e2374a5146104425780631182b87514610473578063122345821461056d5761040f565b3661040f57341561040d576040805133815234602082015281517f6c98249d85d88c3753a04a22230f595e4dc8d3dc86c34af35deeeedc861b89db929181900390910190a15b005b600080fd5b34801561042057600080fd5b50610429610f6d565b6040805163ffffffff9092168252519081900360200190f35b34801561044e57600080fd5b50610457610f72565b604080516001600160a01b039092168252519081900360200190f35b34801561047f57600080fd5b506104f86004803603604081101561049657600080fd5b60ff8235169190810190604081016020820135600160201b8111156104ba57600080fd5b8201836020820111156104cc57600080fd5b803590602001918460018302840111600160201b831117156104ed57600080fd5b509092509050610f78565b6040805160208082528351818301528351919283929083019185019080838360005b8381101561053257818101518382015260200161051a565b50505050905090810190601f16801561055f5780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b34801561057957600080fd5b5061040d6004803603604081101561059057600080fd5b506001600160a01b03813581169160200135166110a6565b3480156105b457600080fd5b506105bd6111a0565b60408051918252519081900360200190f35b3480156105db57600080fd5b5061060a600480360360408110156105f257600080fd5b506001600160a01b03813581169160200135166111a6565b6040805192835260208301919091528051918290030190f35b34801561062f57600080fd5b506104576004803603602081101561064657600080fd5b810190602081018135600160201b81111561066057600080fd5b82018360208201111561067257600080fd5b803590602001918460018302840111600160201b8311171561069357600080fd5b91908080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152509295506111ca945050505050565b3480156106e057600080fd5b506106e96111ee565b6040805160ff9092168252519081900360200190f35b34801561070b57600080fd5b506105bd6111f3565b34801561072057600080fd5b506104576111f9565b34801561073557600080fd5b506105bd6111ff565b34801561074a57600080fd5b5061075361120b565b6040805161ffff9092168252519081900360200190f35b34801561077657600080fd5b506105bd611211565b34801561078b57600080fd5b506106e9611217565b3480156107a057600080fd5b506105bd61121c565b3480156107b557600080fd5b50610457611227565b3480156107ca57600080fd5b50610457600480360360208110156107e157600080fd5b503561122d565b3480156107f457600080fd5b506105bd611248565b34801561080957600080fd5b506106e9611251565b61092a6004803603608081101561082857600080fd5b810190602081018135600160201b81111561084257600080fd5b82018360208201111561085457600080fd5b803590602001918460208302840111600160201b8311171561087557600080fd5b919390929091602081019035600160201b81111561089257600080fd5b8201836020820111156108a457600080fd5b803590602001918460208302840111600160201b831117156108c557600080fd5b919390929091602081019035600160201b8111156108e257600080fd5b8201836020820111156108f457600080fd5b803590602001918460208302840111600160201b8311171561091557600080fd5b91935091503567ffffffffffffffff16611256565b604080519115158252519081900360200190f35b34801561094a57600080fd5b5061045761172b565b34801561095f57600080fd5b506106e9611731565b34801561097457600080fd5b506105bd611736565b34801561098957600080fd5b5061092a600480360360208110156109a057600080fd5b503561173c565b3480156109b357600080fd5b506104576117bd565b3480156109c857600080fd5b506106e96117c3565b3480156109dd57600080fd5b5061040d600480360360408110156109f457600080fd5b60ff8235169190810190604081016020820135600160201b811115610a1857600080fd5b820183602082011115610a2a57600080fd5b803590602001918460018302840111600160201b83111715610a4b57600080fd5b5090925090506117c8565b348015610a6257600080fd5b5061040d60048036036060811015610a7957600080fd5b508035906001600160a01b036020820135169060400135611911565b348015610aa157600080fd5b5061040d60048036036040811015610ab857600080fd5b506001600160a01b038135169060200135611997565b348015610ada57600080fd5b506106e9611b54565b348015610aef57600080fd5b506105bd611b59565b348015610b0457600080fd5b506105bd60048036036040811015610b1b57600080fd5b506001600160a01b038135169060200135611b65565b348015610b3d57600080fd5b50610457611ca3565b348015610b5257600080fd5b50610457611ca9565b348015610b6757600080fd5b506106e9611caf565b348015610b7c57600080fd5b5061092a611cb4565b348015610b9157600080fd5b506106e9611cbd565b61092a60048036036080811015610bb057600080fd5b5080356001600160a01b03908116916020810135909116906040810135906060013567ffffffffffffffff16611cc2565b348015610bed57600080fd5b50610429611caf565b348015610c0257600080fd5b5061040d60048036036040811015610c1957600080fd5b810190602081018135600160201b811115610c3357600080fd5b820183602082011115610c4557600080fd5b803590602001918460018302840111600160201b83111715610c6657600080fd5b919390929091602081019035600160201b811115610c8357600080fd5b820183602082011115610c9557600080fd5b803590602001918460018302840111600160201b83111715610cb657600080fd5b509092509050612383565b348015610ccd57600080fd5b5061040d60048036036040811015610ce457600080fd5b50803590602001356001600160a01b031661282b565b348015610d0657600080fd5b506105bd6128a1565b348015610d1b57600080fd5b506105bd6128ab565b348015610d3057600080fd5b506105bd60048036036020811015610d4757600080fd5b50356001600160a01b03166128b1565b348015610d6357600080fd5b506105bd60048036036020811015610d7a57600080fd5b50356001600160a01b03166128c3565b348015610d9657600080fd5b506104576128de565b348015610dab57600080fd5b5061040d60048036036040811015610dc257600080fd5b60ff8235169190810190604081016020820135600160201b811115610de657600080fd5b820183602082011115610df857600080fd5b803590602001918460018302840111600160201b83111715610e1957600080fd5b5090925090506128e4565b348015610e3057600080fd5b5061040d60048036036040811015610e4757600080fd5b506001600160a01b03813581169160200135166129b4565b348015610e6b57600080fd5b50610457612c88565b348015610e8057600080fd5b5061040d612c8e565b348015610e9557600080fd5b506105bd60048036036020811015610eac57600080fd5b50356001600160a01b0316612d2e565b348015610ec857600080fd5b506106e9612d40565b348015610edd57600080fd5b506106e9612d45565b348015610ef257600080fd5b50610457612d4a565b348015610f0757600080fd5b506105bd612d50565b348015610f1c57600080fd5b506105bd612d56565b348015610f3157600080fd5b506104f860048036036020811015610f4857600080fd5b50356001600160a01b0316612d64565b348015610f6457600080fd5b50610457612e8b565b606481565b61200181565b60005460609060ff16610fc0576040805162461bcd60e51b81526020600482015260196024820152600080516020615583833981519152604482015290519081900360640190fd5b33612000146110005760405162461bcd60e51b815260040180806020018281038252602f815260200180615531602f913960400191505060405180910390fd5b60ff8416600214156110525761104b83838080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250612e9192505050565b905061109f565b6040805162461bcd60e51b815260206004820152601860248201527f756e7265636f676e697a65642073796e207061636b6167650000000000000000604482015290519081900360640190fd5b9392505050565b33612000146110e65760405162461bcd60e51b815260040180806020018281038252602f815260200180615531602f913960400191505060405180910390fd5b6001600160a01b0380831660009081526007602090815260408083209385168352929052208054611151576040805162461bcd60e51b815260206004820152601060248201526f1b9bc81b1bd8dad95908185b5bdd5b9d60821b604482015290519081900360640190fd5b8054600082556040805182815290516001600160a01b0380861692908716917f152fb15aa5d80f843e1e4bd5f2fc9161714f169945024decec7e84fb910fdd519181900360200190a350505050565b60015490565b60076020908152600092835260408084209091529082529020805460019091015482565b6020818101516000908152600490915260409020546001600160a01b03165b919050565b600181565b60055481565b61100181565b670de0b6b3a764000081565b6102ca81565b61a8c081565b600881565b66071afd498d000081565b61200081565b6000908152600460205260409020546001600160a01b031690565b6402540be40081565b600281565b6000805460ff1661129c576040805162461bcd60e51b81526020600482015260196024820152600080516020615583833981519152604482015290519081900360640190fd5b8685146112da5760405162461bcd60e51b815260040180806020018281038252603b8152602001806154f6603b913960400191505060405180910390fd5b8683146113185760405162461bcd60e51b815260040180806020018281038252603f8152602001806153c9603f913960400191505060405180910390fd5b426078018267ffffffffffffffff1610156113645760405162461bcd60e51b81526004018080602001828103825260248152602001806152b96024913960400191505060405180910390fd5b6402540be4003406156113a85760405162461bcd60e51b81526004018080602001828103825260408152602001806155f96040913960400191505060405180910390fd5b604080518681526020808802820101909152859060009081906060908480156113db578160200160208202803683370190505b50905060005b848110156114b6576402540be4008b8b838181106113fb57fe5b905060200201358161140957fe5b06156114465760405162461bcd60e51b815260040180806020018281038252603c815260200180615408603c913960400191505060405180910390fd5b61146b8b8b8381811061145557fe5b9050602002013585612fb590919063ffffffff16565b93506114976402540be4008c8c8481811061148257fe5b9050602002013561300f90919063ffffffff16565b8282815181106114a357fe5b60209081029190910101526001016113e1565b506001546114db906114ce908663ffffffff61305116565b849063ffffffff612fb516565b3410156115195760405162461bcd60e51b81526004018080602001828103825260568152602001806155a36056913960600191505060405180910390fd5b611529348463ffffffff6130aa16565b91506115336150bd565b6040518060c001604052806221272160e91b60001b815260200160006001600160a01b031681526020018381526020018e8e808060200260200160405190810160405280939291908181526020018383602002808284376000920191909152505050908252506040805160208c810282810182019093528c82529283019290918d918d91829185019084908082843760009201919091525050509082525067ffffffffffffffff8916602090910152905061200063f7a251d760036115f7846130ec565b61160c876402540be40063ffffffff61300f16565b6040518463ffffffff1660e01b8152600401808460ff1660ff16815260200180602001838152602001828103825284818151815260200191508051906020019080838360005b8381101561166a578181015183820152602001611652565b50505050905090810190601f1680156116975780820380516001836020036101000a031916815260200191505b50945050505050600060405180830381600087803b1580156116b857600080fd5b505af11580156116cc573d6000803e3d6000fd5b505060408051600081523360208201528082018890526060810187905290517f74eab09b0e53aefc23f2e1b16da593f95c2dd49c6f5a23720463d10d9c330b2a9350908190036080019150a15060019c9b505050505050505050505050565b61100581565b601081565b60015481565b6000336120011461177e5760405162461bcd60e51b81526004018080602001828103825260338152602001806151d76033913960400191505060405180910390fd5b81156117b5576040516120019083156108fc029084906000818181858888f193505050501580156117b3573d6000803e3d6000fd5b505b506001919050565b61100881565b600b81565b60005460ff1661180d576040805162461bcd60e51b81526020600482015260196024820152600080516020615583833981519152604482015290519081900360640190fd5b336120001461184d5760405162461bcd60e51b815260040180806020018281038252602f815260200180615531602f913960400191505060405180910390fd5b60ff83166003141561189d5761189882828080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152506133a792505050565b61190c565b7f41ce201247b6ceb957dcdb217d0b8acb50b9ea0e12af9af4f5e7f38902101605838383604051808460ff1660ff168152602001806020018281038252848482818152602001925080828437600083820152604051601f909101601f1916909201829003965090945050505050a15b505050565b33611008146119515760405162461bcd60e51b81526004018080602001828103825260238152602001806155606023913960400191505060405180910390fd5b600083815260046020908152604080832080546001600160a01b039096166001600160a01b03199096168617905593825260038152838220949094556002909352912055565b81806001600160a01b031663893d20e86040518163ffffffff1660e01b815260040160206040518083038186803b1580156119d157600080fd5b505afa1580156119e5573d6000803e3d6000fd5b505050506040513d60208110156119fb57600080fd5b50516001600160a01b03163314611a59576040805162461bcd60e51b815260206004820152601860248201527f6e6f74206f776e6572206f6620424550323020746f6b656e0000000000000000604482015290519081900360640190fd5b60008211611aa7576040805162461bcd60e51b81526020600482015260166024820152751e995c9bc81b1a5b5a5d081b9bdd08185b1b1bddd95960521b604482015290519081900360640190fd5b6001600160a01b038316600090815260036020526040902054611afd576040805162461bcd60e51b81526020600482015260096024820152681b9bdd08189bdd5b9960ba1b604482015290519081900360640190fd5b6001600160a01b038316600081815260066020908152604091829020859055815185815291513393927f9df3a90730dbf23b5cc18dbbd5f4af3fa94a0dffb6ff6841f98a9a9a6ac626a892908290030190a3505050565b600981565b677ce66c50e284000081565b6000805460ff16611bab576040805162461bcd60e51b81526020600482015260196024820152600080516020615583833981519152604482015290519081900360640190fd5b3361100514611beb5760405162461bcd60e51b815260040180806020018281038252602f81526020018061520a602f913960400191505060405180910390fd5b6000478310611bfa5747611bfc565b825b9050670de0b6b3a7640000811115611c18576000915050611c9d565b8015611c9a576040516001600160a01b0385169082156108fc029083906000818181858888f19350505050158015611c54573d6000803e3d6000fd5b50604080516001600160a01b03861681526020810183905281517ff8b71c64315fc33b2ead2adfa487955065152a8ac33d9d5193aafd7f45dc15a0929181900390910190a15b90505b92915050565b61100781565b61100681565b600081565b60005460ff1681565b600381565b6000805460ff16611d08576040805162461bcd60e51b81526020600482015260196024820152600080516020615583833981519152604482015290519081900360640190fd5b426078018267ffffffffffffffff161015611d545760405162461bcd60e51b81526004018080602001828103825260248152602001806152b96024913960400191505060405180910390fd5b6402540be400340615611d985760405162461bcd60e51b81526004018080602001828103825260408152602001806155f96040913960400191505060405180910390fd5b600080806001600160a01b038816611e7757600154611dbe90879063ffffffff612fb516565b341015611dfc5760405162461bcd60e51b81526004018080602001828103825260618152602001806153436061913960800191505060405180910390fd5b6402540be400860615611e405760405162461bcd60e51b815260040180806020018281038252603c815260200180615408603c913960400191505060405180910390fd5b611e50348763ffffffff6130aa16565b9050611e67866402540be40063ffffffff61300f16565b6221272160e91b9350915061211a565b6001600160a01b038816600090815260036020526040902054925082611ece5760405162461bcd60e51b81526004018080602001828103825260318152602001806153126031913960400191505060405180910390fd5b600154341015611f0f5760405162461bcd60e51b815260040180806020018281038252603f815260200180615465603f913960400191505060405180910390fd5b506001600160a01b0387166000908152600260205260409020543490600881111580611f5a5750600881118015611f5a5750611f58876007198301600a0a63ffffffff61340316565b155b611f955760405162461bcd60e51b815260040180806020018281038252603c815260200180615408603c913960400191505060405180910390fd5b611f9f8782613445565b9250611faa84613485565b15611ff2576305f5e100831015611ff25760405162461bcd60e51b815260040180806020018281038252603a81526020018061525b603a913960400191505060405180910390fd5b60088110158061200c575060088110801561200c57508683115b6120475760405162461bcd60e51b81526004018080602001828103825260258152602001806153a46025913960400191505060405180910390fd5b677ce66c50e284000083111561208e5760405162461bcd60e51b81526004018080602001828103825260358152602001806152dd6035913960400191505060405180910390fd5b604080516323b872dd60e01b81523360048201523060248201526044810189905290516001600160a01b038b16916323b872dd9160648083019260209291908290030181600087803b1580156120e357600080fd5b505af11580156120f7573d6000803e3d6000fd5b505050506040513d602081101561210d57600080fd5b505161211857600080fd5b505b6121226150bd565b6040805160c0810182528581526001600160a01b038b166020820152815160018082528184018452919283019181602001602082028036833750505081526040805160018082528183019092526020928301929091908083019080368337505050815260408051600180825281830190925260209283019290919080830190803683370190505081526020018767ffffffffffffffff1681525090508281604001516000815181106121d057fe5b6020026020010181815250508781606001516000815181106121ee57fe5b60200260200101906001600160a01b031690816001600160a01b03168152505033816080015160008151811061222057fe5b6001600160a01b039092166020928302919091019091015261200063f7a251d7600361224b846130ec565b612260866402540be40063ffffffff61300f16565b6040518463ffffffff1660e01b8152600401808460ff1660ff16815260200180602001838152602001828103825284818151815260200191508051906020019080838360005b838110156122be5781810151838201526020016122a6565b50505050905090810190601f1680156122eb5780820380516001836020036101000a031916815260200191505b50945050505050600060405180830381600087803b15801561230c57600080fd5b505af1158015612320573d6000803e3d6000fd5b5050604080516001600160a01b038d1681523360208201528082018b90526060810186905290517f74eab09b0e53aefc23f2e1b16da593f95c2dd49c6f5a23720463d10d9c330b2a9350908190036080019150a150600198975050505050505050565b33611007146123c35760405162461bcd60e51b815260040180806020018281038252602e8152602001806154a4602e913960400191505060405180910390fd5b60208114612418576040805162461bcd60e51b815260206004820152601b60248201527f65787065637465642076616c7565206c656e6774682069732033320000000000604482015290519081900360640190fd5b606084848080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525050604080516020601f8801819004810282018101909252868152939450606093925086915085908190840183828082843760009201919091525050505060208301519091506772656c617946656560c01b811415612520576020820151670de0b6b3a764000081118015906124c757506402540be4008106155b612518576040805162461bcd60e51b815260206004820152601960248201527f7468652072656c6179466565206f7574206f662072616e676500000000000000604482015290519081900360640190fd5b600155612796565b61259487878080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152505060408051808201909152601781527f6c617267655472616e736665724c6f636b506572696f640000000000000000006020820152915061358b9050565b1561263057604080516020601f87018190048102820181019092528581526000916125d79188888083850183828082843760009201919091525061367292505050565b905062093a80811115612628576040805162461bcd60e51b81526020600482015260146024820152736c6f636b20706572696f6420746f6f206c6f6e6760601b604482015290519081900360640190fd5b600555612796565b61269c87878080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525050604080518082019091526015815274189b9893185c99d9551c985b9cd9995c931a5b5a5d605a1b6020820152915061358b9050565b1561275957604080516020601f87018190048102820181019092528581526000916126df9188888083850183828082843760009201919091525061367292505050565b905068056bc75e2d631000008110156127295760405162461bcd60e51b81526004018080602001828103825260228152602001806152396022913960400191505060405180910390fd5b6000805260066020527f54cdd369e4e8a8515e52ca72ec816c2101831ad1f18bf44102ed171459c9b4f855612796565b6040805162461bcd60e51b815260206004820152600d60248201526c756e6b6e6f776e20706172616d60981b604482015290519081900360640190fd5b7f6cdb0ac70ab7f2e2d035cca5be60d89906f2dede7648ddbd7402189c1eeed17a878787876040518080602001806020018381038352878782818152602001925080828437600083820152601f01601f191690910184810383528581526020019050858580828437600083820152604051601f909101601f19169092018290039850909650505050505050a150505050505050565b336110081461286b5760405162461bcd60e51b81526004018080602001828103825260238152602001806155606023913960400191505060405180910390fd5b600091825260046020908152604080842080546001600160a01b03191690556001600160a01b0392909216835260039052812055565b6221272160e91b81565b61c35081565b60026020526000908152604090205481565b6001600160a01b031660009081526003602052604090205490565b61100281565b60005460ff16612929576040805162461bcd60e51b81526020600482015260196024820152600080516020615583833981519152604482015290519081900360640190fd5b33612000146129695760405162461bcd60e51b815260040180806020018281038252602f815260200180615531602f913960400191505060405180910390fd5b60ff83166003141561189d5761189882828080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061367792505050565b60085460ff1660021415612a00576040805162461bcd60e51b815260206004820152600e60248201526d4e6f2072652d656e7472616e637960901b604482015290519081900360640190fd5b6008805460ff191660021790556001600160a01b0380831660009081526007602090815260408083209385168352929052208054612a78576040805162461bcd60e51b815260206004820152601060248201526f1b9bc81b1bd8dad95908185b5bdd5b9d60821b604482015290519081900360640190fd5b8060010154421015612ad1576040805162461bcd60e51b815260206004820152601760248201527f7374696c6c206f6e206c6f636b696e6720706572696f64000000000000000000604482015290519081900360640190fd5b805460008083556001600160a01b038516612b44576040516001600160a01b038516906127109084906000818181858888f193505050503d8060008114612b34576040519150601f19603f3d011682016040523d82523d6000602084013e612b39565b606091505b505080915050612bd7565b846001600160a01b031663a9059cbb61c35086856040518463ffffffff1660e01b815260040180836001600160a01b03166001600160a01b0316815260200182815260200192505050602060405180830381600088803b158015612ba757600080fd5b5087f1158015612bbb573d6000803e3d6000fd5b50505050506040513d6020811015612bd257600080fd5b505190505b80612c29576040805162461bcd60e51b815260206004820152601e60248201527f776974686472617720756e6c6f636b656420746f6b656e206661696c65640000604482015290519081900360640190fd5b836001600160a01b0316856001600160a01b03167f832fc3e25f2b3e6fb0eb59419a73cba405f2a249fce75f7e31ea5a457a0323f1846040518082815260200191505060405180910390a350506008805460ff19166001179055505050565b61100381565b60005460ff1615612ce6576040805162461bcd60e51b815260206004820152601960248201527f74686520636f6e747261637420616c726561647920696e697400000000000000604482015290519081900360640190fd5b66071afd498d000060019081556000808052600260205260127fac33ff75c19e70fe83507db0d683fd3465c996598dc972688b7ace676c89077b55805460ff19169091179055565b60066020526000908152604090205481565b600481565b600581565b61100081565b61271081565b69021e19e0c9bab240000081565b6001600160a01b03811660009081526003602090815260409182902054825182815280840190935260609290918391906020820181803683375050506020810183905290506000805b60208160ff161015612df457828160ff1681518110612dc857fe5b01602001516001600160f81b03191615612de757600190910190612dec565b612df4565b600101612dad565b5060608160ff166040519080825280601f01601f191660200182016040528015612e25576020820181803683370190505b50905060005b8260ff168160ff161015612e8157838160ff1681518110612e4857fe5b602001015160f81c60f81b828260ff1681518110612e6257fe5b60200101906001600160f81b031916908160001a905350600101612e2b565b5095945050505050565b61100481565b6060612e9b615109565b6000612ea684613775565b9150915080612efc576040805162461bcd60e51b815260206004820152601f60248201527f756e7265636f676e697a6564207472616e73666572496e207061636b61676500604482015290519081900360640190fd5b6000612f07836138b4565b905063ffffffff811615612f9b576040808401516020808601516001600160a01b03166000908152600290915291822054612f429190613445565b9050612f4c61513e565b60405180608001604052808660000151815260200183815260200186608001516001600160a01b031681526020018463ffffffff168152509050612f8f81613c1a565b955050505050506111e9565b505060408051600081526020810190915291506111e99050565b600082820183811015611c9a576040805162461bcd60e51b815260206004820152601b60248201527f536166654d6174683a206164646974696f6e206f766572666c6f770000000000604482015290519081900360640190fd5b6000611c9a83836040518060400160405280601a81526020017f536166654d6174683a206469766973696f6e206279207a65726f000000000000815250613cf6565b60008261306057506000611c9d565b8282028284828161306d57fe5b0414611c9a5760405162461bcd60e51b81526004018080602001828103825260218152602001806154446021913960400191505060405180910390fd5b6000611c9a83836040518060400160405280601e81526020017f536166654d6174683a207375627472616374696f6e206f766572666c6f770000815250613d98565b60408051600680825260e08201909252606091829190816020015b6060815260200190600190039081613107575050835190915061312990613df2565b8160008151811061313657fe5b602002602001018190525061315783602001516001600160a01b0316613e05565b8160018151811061316457fe5b6020026020010181905250600083604001515190506060816040519080825280602002602001820160405280156131af57816020015b606081526020019060019003908161319a5790505b50905060005b828110156131fc576131dd866040015182815181106131d057fe5b6020026020010151613df2565b8282815181106131e957fe5b60209081029190910101526001016131b5565b5061320681613e28565b8360028151811061321357fe5b602002602001018190525060608260405190808252806020026020018201604052801561325457816020015b606081526020019060019003908161323f5790505b50905060005b838110156132aa5761328b8760600151828151811061327557fe5b60200260200101516001600160a01b0316613e05565b82828151811061329757fe5b602090810291909101015260010161325a565b506132b481613e28565b846003815181106132c157fe5b602002602001018190525060608360405190808252806020026020018201604052801561330257816020015b60608152602001906001900390816132ed5790505b50905060005b84811015613342576133238860800151828151811061327557fe5b82828151811061332f57fe5b6020908102919091010152600101613308565b5061334c81613e28565b8560048151811061335957fe5b602002602001018190525061337b8760a0015167ffffffffffffffff16613df2565b8560058151811061338857fe5b602002602001018190525061339c85613e28565b979650505050505050565b6133af615165565b60006133ba83613eb2565b91509150806133fa5760405162461bcd60e51b81526004018080602001828103825260248152602001806154d26024913960400191505060405180910390fd5b61190c8261407d565b6000611c9a83836040518060400160405280601881526020017f536166654d6174683a206d6f64756c6f206279207a65726f0000000000000000815250614501565b6000600882111561346e57613467836007198401600a0a63ffffffff61300f16565b9050611c9d565b611c9a836008849003600a0a63ffffffff61305116565b604080516020808252818301909252600091606091906020820181803683375050506020810184905290506000805b60208160ff1610156134fb57828160ff16815181106134cf57fe5b01602001516001600160f81b031916156134ee576001909101906134f3565b6134fb565b6001016134b4565b50600760ff82161015613513576000925050506111e9565b816005820360ff168151811061352557fe5b6020910101516001600160f81b031916602d60f81b1461354a576000925050506111e9565b816001820360ff168151811061355c57fe5b6020910101516001600160f81b031916604d60f81b14613581576000925050506111e9565b5060019392505050565b6000816040516020018082805190602001908083835b602083106135c05780518252601f1990920191602091820191016135a1565b6001836020036101000a03801982511681845116808217855250505050505090500191505060405160208183030381529060405280519060200120836040516020018082805190602001908083835b6020831061362e5780518252601f19909201916020918201910161360f565b6001836020036101000a0380198251168184511680821785525050505050509050019150506040516020818303038152906040528051906020012014905092915050565b015190565b61367f6150bd565b600061368a83614563565b91509150806136ca5760405162461bcd60e51b81526004018080602001828103825260248152602001806152956024913960400191505060405180910390fd5b6136d2615165565b602080840180516001600160a01b0390811684526040808701518585015291511660009081526002909252812054905b846040015151811015613753576137308560400151828151811061372257fe5b6020026020010151836147c7565b8560400151828151811061374057fe5b6020908102919091010152600101613702565b50608084015160408301526005606083015261376e8261407d565b5050505050565b61377d615109565b6000613787615109565b61378f61519c565b6137a061379b86614800565b614825565b90506000805b6137af8361486f565b156138a757806137d1576137ca6137c584614890565b6148de565b845261389f565b80600114156137fe576137eb6137e684614890565b614995565b6001600160a01b0316602085015261389f565b806002141561381d576138136137c584614890565b604085015261389f565b8060031415613845576138326137e684614890565b6001600160a01b0316606085015261389f565b806004141561386d5761385a6137e684614890565b6001600160a01b0316608085015261389f565b806005141561389a576138826137c584614890565b67ffffffffffffffff1660a08501526001915061389f565b6138a7565b6001016137a6565b5091935090915050915091565b60208101516000906001600160a01b03166139f8578160a0015167ffffffffffffffff164211156138e7575060016111e9565b81604001514710156138fb575060036111e9565b613904826149af565b61397957606082015160408084015190516000926001600160a01b0316916127109184818181858888f193505050503d806000811461395f576040519150601f19603f3d011682016040523d82523d6000602084013e613964565b606091505b50509050806139775750600490506111e9565b505b7f471eb9cc1ffe55ffadf15b32595415eb9d80f22e761d24bd6dffc607e1284d5982602001518360600151846040015160405180846001600160a01b03166001600160a01b03168152602001836001600160a01b03166001600160a01b03168152602001828152602001935050505060405180910390a15060006111e9565b8160a0015167ffffffffffffffff16421115613a16575060016111e9565b81516020808401516001600160a01b031660009081526003909152604090205414613a43575060026111e9565b602080830151604080516370a0823160e01b815230600482015290516000936001600160a01b03909316926370a082319261c3509260248083019392829003018187803b158015613a9357600080fd5b5086fa158015613aa7573d6000803e3d6000fd5b50505050506040513d6020811015613abe57600080fd5b50516040840151909150811015613ad95750600390506111e9565b613ae2836149af565b613b9957600083602001516001600160a01b031663a9059cbb61c350866060015187604001516040518463ffffffff1660e01b815260040180836001600160a01b03166001600160a01b0316815260200182815260200192505050602060405180830381600088803b158015613b5757600080fd5b5087f1158015613b6b573d6000803e3d6000fd5b50505050506040513d6020811015613b8257600080fd5b5051905080613b975750600591506111e99050565b505b7f471eb9cc1ffe55ffadf15b32595415eb9d80f22e761d24bd6dffc607e1284d5983602001518460600151856040015160405180846001600160a01b03166001600160a01b03168152602001836001600160a01b03166001600160a01b03168152602001828152602001935050505060405180910390a150600090506111e9565b60408051600480825260a08201909252606091829190816020015b6060815260200190600190039081613c355750508351909150613c5790613df2565b81600081518110613c6457fe5b6020026020010181905250613c7c8360200151613df2565b81600181518110613c8957fe5b6020026020010181905250613caa83604001516001600160a01b0316613e05565b81600281518110613cb757fe5b6020026020010181905250613cd5836060015163ffffffff16613df2565b81600381518110613ce257fe5b602002602001018190525061109f81613e28565b60008183613d825760405162461bcd60e51b81526004018080602001828103825283818151815260200191508051906020019080838360005b83811015613d47578181015183820152602001613d2f565b50505050905090810190601f168015613d745780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b506000838581613d8e57fe5b0495945050505050565b60008184841115613dea5760405162461bcd60e51b8152602060048201818152835160248401528351909283926044909101919085019080838360008315613d47578181015183820152602001613d2f565b505050900390565b6060611c9d613e0083614b1d565b614c03565b60408051600560a21b831860148201526034810190915260609061109f81614c03565b6060815160001415613e4957506040805160008152602081019091526111e9565b606082600081518110613e5857fe5b602002602001015190506000600190505b8351811015613e9957613e8f82858381518110613e8257fe5b6020026020010151614c55565b9150600101613e69565b5061109f613eac825160c060ff16614cd2565b82614c55565b613eba615165565b6000613ec4615165565b613ecc61519c565b613ed861379b86614800565b90506000805b613ee78361486f565b156138a75780613f0d57613efd6137e684614890565b6001600160a01b03168452614075565b8060011415613fae576060613f29613f2485614890565b614dca565b90508051604051908082528060200260200182016040528015613f56578160200160208202803683370190505b50602086015260005b8151811015613fa757613f84828281518110613f7757fe5b60200260200101516148de565b86602001518281518110613f9457fe5b6020908102919091010152600101613f5f565b5050614075565b8060021415614050576060613fc5613f2485614890565b90508051604051908082528060200260200182016040528015613ff2578160200160208202803683370190505b50604086015260005b8151811015613fa75761402082828151811061401357fe5b6020026020010151614995565b8660400151828151811061403057fe5b6001600160a01b0390921660209283029190910190910152600101613ffb565b806003141561389a576140656137c584614890565b63ffffffff166060850152600191505b600101613ede565b80516001600160a01b03166142a75760005b8160200151518110156142a1576000826040015182815181106140ae57fe5b60200260200101516001600160a01b0316612710846020015184815181106140d257fe5b60209081029190910101516040516000818181858888f193505050503d806000811461411a576040519150601f19603f3d011682016040523d82523d6000602084013e61411f565b606091505b50509050806141e2577f203f9f67a785f4f81be4d48b109aa0c498d1bc8097ecc2627063f480cc5fe73e83600001518460400151848151811061415e57fe5b60200260200101518560200151858151811061417657fe5b6020026020010151866060015160405180856001600160a01b03166001600160a01b03168152602001846001600160a01b03166001600160a01b031681526020018381526020018263ffffffff1663ffffffff16815260200194505050505060405180910390a1614298565b7fd468d4fa5e8fb4adc119b29a983fd0785e04af5cb8b7a3a69a47270c54b6901a83600001518460400151848151811061421857fe5b60200260200101518560200151858151811061423057fe5b6020026020010151866060015160405180856001600160a01b03166001600160a01b03168152602001846001600160a01b03166001600160a01b031681526020018381526020018263ffffffff1663ffffffff16815260200194505050505060405180910390a15b5060010161408f565b506144fe565b60005b8160200151518110156144fc57600082600001516001600160a01b031663a9059cbb61c350856040015185815181106142df57fe5b6020026020010151866020015186815181106142f757fe5b60200260200101516040518463ffffffff1660e01b815260040180836001600160a01b03166001600160a01b0316815260200182815260200192505050602060405180830381600088803b15801561434e57600080fd5b5087f1158015614362573d6000803e3d6000fd5b50505050506040513d602081101561437957600080fd5b50519050801561443d577fd468d4fa5e8fb4adc119b29a983fd0785e04af5cb8b7a3a69a47270c54b6901a8360000151846040015184815181106143b957fe5b6020026020010151856020015185815181106143d157fe5b6020026020010151866060015160405180856001600160a01b03166001600160a01b03168152602001846001600160a01b03166001600160a01b031681526020018381526020018263ffffffff1663ffffffff16815260200194505050505060405180910390a16144f3565b7f203f9f67a785f4f81be4d48b109aa0c498d1bc8097ecc2627063f480cc5fe73e83600001518460400151848151811061447357fe5b60200260200101518560200151858151811061448b57fe5b6020026020010151866060015160405180856001600160a01b03166001600160a01b03168152602001846001600160a01b03166001600160a01b031681526020018381526020018263ffffffff1663ffffffff16815260200194505050505060405180910390a15b506001016142aa565b505b50565b600081836145505760405162461bcd60e51b8152602060048201818152835160248401528351909283926044909101919085019080838360008315613d47578181015183820152602001613d2f565b5082848161455a57fe5b06949350505050565b61456b6150bd565b60006145756150bd565b61457d61519c565b61458961379b86614800565b90506000805b6145988361486f565b156138a757806145b5576145ae6137c584614890565b84526147bf565b80600114156145dd576145ca6137e684614890565b6001600160a01b031660208501526147bf565b806002141561466c5760606145f4613f2485614890565b90508051604051908082528060200260200182016040528015614621578160200160208202803683370190505b50604086015260005b815181101561466557614642828281518110613f7757fe5b8660400151828151811061465257fe5b602090810291909101015260010161462a565b50506147bf565b8060031415614701576060614683613f2485614890565b905080516040519080825280602002602001820160405280156146b0578160200160208202803683370190505b50606086015260005b8151811015614665576146d182828151811061401357fe5b866060015182815181106146e157fe5b6001600160a01b03909216602092830291909101909101526001016146b9565b8060041415614796576060614718613f2485614890565b90508051604051908082528060200260200182016040528015614745578160200160208202803683370190505b50608086015260005b81518110156146655761476682828151811061401357fe5b8660800151828151811061477657fe5b6001600160a01b039092166020928302919091019091015260010161474e565b806005141561389a576147ab6137c584614890565b67ffffffffffffffff1660a0850152600191505b60010161458f565b600060088211156147e957613467836007198401600a0a63ffffffff61305116565b611c9a836008849003600a0a63ffffffff61300f16565b6148086151bc565b506040805180820190915281518152602082810190820152919050565b61482d61519c565b61483682614e9b565b61483f57600080fd5b600061484e8360200151614ecb565b60208085015160408051808201909152868152920190820152915050919050565b60006148796151bc565b505080518051602091820151919092015191011190565b6148986151bc565b6148a18261486f565b6148aa57600080fd5b602082015160006148ba82614f2e565b80830160209586015260408051808201909152908152938401919091525090919050565b8051600090158015906148f357508151602110155b6148fc57600080fd5b600061490b8360200151614ecb565b90508083600001511015614966576040805162461bcd60e51b815260206004820152601a60248201527f6c656e677468206973206c657373207468616e206f6666736574000000000000604482015290519081900360640190fd5b82516020808501518301805192849003929183101561498c57826020036101000a820491505b50949350505050565b80516000906015146149a657600080fd5b611c9d826148de565b600080805260066020527f54cdd369e4e8a8515e52ca72ec816c2101831ad1f18bf44102ed171459c9b4f8541580156149e85750600554155b15614a2a5760008052600660205269021e19e0c9bab24000007f54cdd369e4e8a8515e52ca72ec816c2101831ad1f18bf44102ed171459c9b4f85561a8c06005555b6020808301516001600160a01b0316600090815260069091526040902054801580614a585750808360400151105b15614a675760009150506111e9565b6020808401516001600160a01b039081166000908152600783526040808220606088015190931682529190925290819020908401518154614aad9163ffffffff612fb516565b8155600554420160018201819055606085015160208087015160408089015181519081529283019490945283516001600160a01b039384169493909116927f3fb83143cd331170da18fb1e8564d97e8ec39264b6ecb1ba248ea7596ab07258928290030190a35060019392505050565b604080516020808252818301909252606091829190602082018180368337505050602081018490529050600067ffffffffffffffff198416614b6157506018614b85565b6fffffffffffffffffffffffffffffffff198416614b8157506010614b85565b5060005b6020811015614bbb57818181518110614b9a57fe5b01602001516001600160f81b03191615614bb357614bbb565b600101614b85565b60008160200390506060816040519080825280601f01601f191660200182016040528015614bf0576020820181803683370190505b5080830196909652508452509192915050565b606081516001148015614c355750607f60f81b82600081518110614c2357fe5b01602001516001600160f81b03191611155b15614c415750806111e9565b611c9d614c538351608060ff16614cd2565b835b6060806040519050835180825260208201818101602087015b81831015614c86578051835260209283019201614c6e565b50855184518101855292509050808201602086015b81831015614cb3578051835260209283019201614c9b565b508651929092011591909101601f01601f191660405250905092915050565b6060680100000000000000008310614d22576040805162461bcd60e51b815260206004820152600e60248201526d696e70757420746f6f206c6f6e6760901b604482015290519081900360640190fd5b60408051600180825281830190925260609160208201818036833701905050905060378411614d7c5782840160f81b81600081518110614d5e57fe5b60200101906001600160f81b031916908160001a9053509050611c9d565b6060614d8785614b1d565b90508381510160370160f81b82600081518110614da057fe5b60200101906001600160f81b031916908160001a905350614dc18282614c55565b95945050505050565b6060614dd582614e9b565b614dde57600080fd5b6000614de983615061565b9050606081604051908082528060200260200182016040528015614e2757816020015b614e146151bc565b815260200190600190039081614e0c5790505b5090506000614e398560200151614ecb565b60208601510190506000805b84811015614e9057614e5683614f2e565b9150604051806040016040528083815260200184815250848281518110614e7957fe5b602090810291909101015291810191600101614e45565b509195945050505050565b8051600090614eac575060006111e9565b6020820151805160001a9060c0821015613581576000925050506111e9565b8051600090811a6080811015614ee55760009150506111e9565b60b8811080614f00575060c08110801590614f00575060f881105b15614f0f5760019150506111e9565b60c0811015614f235760b5190190506111e9565b60f5190190506111e9565b80516000908190811a6080811015614f49576001915061505a565b60b8811015614f5e57607e198101915061505a565b60c0811015614fd857600060b78203600186019550806020036101000a865104915060018101820193505080831015614fd2576040805162461bcd60e51b81526020600482015260116024820152706164646974696f6e206f766572666c6f7760781b604482015290519081900360640190fd5b5061505a565b60f8811015614fed5760be198101915061505a565b600060f78203600186019550806020036101000a865104915060018101820193505080831015615058576040805162461bcd60e51b81526020600482015260116024820152706164646974696f6e206f766572666c6f7760781b604482015290519081900360640190fd5b505b5092915050565b8051600090615072575060006111e9565b600080905060006150868460200151614ecb565b602085015185519181019250015b808210156150b4576150a582614f2e565b60019093019290910190615094565b50909392505050565b6040518060c001604052806000801916815260200160006001600160a01b03168152602001606081526020016060815260200160608152602001600067ffffffffffffffff1681525090565b6040805160c081018252600080825260208201819052918101829052606081018290526080810182905260a081019190915290565b60408051608081018252600080825260208201819052918101829052606081019190915290565b604051806080016040528060006001600160a01b031681526020016060815260200160608152602001600063ffffffff1681525090565b60405180604001604052806151af6151bc565b8152602001600081525090565b60405180604001604052806000815260200160008152509056fe6f6e6c79207374616b696e672073797374656d20636f6e74726163742063616e2063616c6c20746869732066756e6374696f6e746865206d6573736167652073656e646572206d75737420626520696e63656e746976697a6520636f6e7472616374626e62206c61726765207472616e73666572206c696d697420746f6f20736d616c6c466f72206d696e69546f6b656e2c20746865207472616e7366657220616d6f756e74206d757374206e6f74206265206c657373207468616e2031756e7265636f676e697a6564207472616e736665724f75742073796e207061636b61676565787069726554696d65206d7573742062652074776f206d696e75746573206c61746572616d6f756e7420697320746f6f206c617267652c20657863656564206d6178696d756d206265703220746f6b656e20616d6f756e7474686520636f6e747261637420686173206e6f74206265656e20626f756e6420746f20616e79206265703220746f6b656e726563656976656420424e4220616d6f756e742073686f756c64206265206e6f206c657373207468616e207468652073756d206f66207472616e736665724f757420424e4220616d6f756e7420616e64206d696e696d756d2072656c6179466565616d6f756e7420697320746f6f206c617267652c2075696e74323536206f766572666c6f774c656e677468206f6620726563697069656e74416464727320646f65736e277420657175616c20746f206c656e677468206f6620726566756e644164647273696e76616c6964207472616e7366657220616d6f756e743a20707265636973696f6e206c6f737320696e20616d6f756e7420636f6e76657273696f6e536166654d6174683a206d756c7469706c69636174696f6e206f766572666c6f77726563656976656420424e4220616d6f756e742073686f756c64206265206e6f206c657373207468616e20746865206d696e696d756d2072656c6179466565746865206d6573736167652073656e646572206d75737420626520676f7665726e616e636520636f6e7472616374756e7265636f676e697a6564207472616e736665724f75742061636b207061636b6167654c656e677468206f6620726563697069656e74416464727320646f65736e277420657175616c20746f206c656e677468206f6620616d6f756e7473746865206d6573736167652073656e646572206d7573742062652063726f737320636861696e20636f6e7472616374746865206d73672073656e646572206d75737420626520746f6b656e4d616e6167657274686520636f6e7472616374206e6f7420696e69742079657400000000000000726563656976656420424e4220616d6f756e742073686f756c64206265206e6f206c657373207468616e207468652073756d206f66207472616e7366657220424e4220616d6f756e7420616e642072656c6179466565696e76616c696420726563656976656420424e4220616d6f756e743a20707265636973696f6e206c6f737320696e20616d6f756e7420636f6e76657273696f6ea264697066735822122055e131816f7cd763bf5ca5ef344219b7a6ec4dab5c7d1c50f4bccc7f17fe5d4664736f6c63430006040033", + }, + { + ContractAddr: CrossChainContract, + CommitUrl: "https://github.com/bnb-chain/bsc-genesis-contract/commit/78e13b1d3a5a1b08c9208af94a9b14fc1efda213", + Code: "608060405234801561001057600080fd5b50600436106103995760003560e01c8063718a8aa8116101e9578063c27cdcfb1161010f578063dc927faf116100ad578063f7a251d71161007c578063f7a251d714610b2f578063f9a2bbc714610ba7578063fc3e590814610baf578063fd6a687914610bb757610399565b8063dc927faf14610af7578063e1c7392a14610aff578063e3b0480514610b07578063e6400bbe14610b2757610399565b8063ccc108d7116100e9578063ccc108d714610ab0578063d31f968d14610ab8578063d76a867514610ae7578063dc40433114610aef57610399565b8063c27cdcfb14610a80578063c780e9de14610aa0578063c81b166214610aa857610399565b80638cc8f56111610187578063a78abc1611610156578063a78abc16146109b2578063ab51bb96146109ba578063ac431751146109c2578063b0355f5b1461078157610399565b80638cc8f5611461088757806396713da91461099a5780639dc09262146109a2578063a1a11bf5146109aa57610399565b806375d47a0a116101c357806375d47a0a146108a75780637942fd05146108af57806384013b6a146108b7578063863fe4ab1461099257610399565b8063718a8aa81461088f578063719482d51461089757806374f079b81461089f57610399565b8063422f9050116102ce57806363e1394e1161026c5780636de380bd1161023b5780636de380bd146108575780636e47a51a1461085f5780636e47b4821461087f57806370fd5bad1461088757610399565b806363e1394e146107ff5780636a3cb34d146108075780636bacff2c1461080f5780636c46aa681461080757610399565b80634bf6c882116102a85780634bf6c882146107b957806351e80672146107c15780635692ddd3146107c95780635f832177146107d157610399565b8063422f90501461078957806343756e5c146107a9578063493279b1146107b157610399565b8063299b533d1161033b578063308325f411610315578063308325f4146106155780633a648b151461061d5780633bdc47a6146106595780633dffc3871461078157610399565b8063299b533d146105a35780632af6f399146105d75780632ff32aea146105f457610399565b806314b3023b1161037757806314b3023b146104015780631d1309351461041b5780631e275ae11461043757806322556cdc1461059b57610399565b806305e682581461039e5780630bee7a67146103bc5780630e2374a5146103dd575b600080fd5b6103a6610bbf565b6040805160ff9092168252519081900360200190f35b6103c4610bc4565b6040805163ffffffff9092168252519081900360200190f35b6103e5610bc9565b604080516001600160a01b039092168252519081900360200190f35b610409610bcf565b60408051918252519081900360200190f35b610423610bd5565b604080519115158252519081900360200190f35b610599600480360361010081101561044e57600080fd5b81018160a081016080820135600160201b81111561046b57600080fd5b82018360208201111561047d57600080fd5b803590602001918460018302840111600160201b8311171561049e57600080fd5b919390929091602081019035600160201b8111156104bb57600080fd5b8201836020820111156104cd57600080fd5b803590602001918460018302840111600160201b831117156104ee57600080fd5b919390929091602081019035600160201b81111561050b57600080fd5b82018360208201111561051d57600080fd5b803590602001918460018302840111600160201b8311171561053e57600080fd5b919390929091602081019035600160201b81111561055b57600080fd5b82018360208201111561056d57600080fd5b803590602001918460018302840111600160201b8311171561058e57600080fd5b509092509050610bde565b005b6104096112c2565b6105c0600480360360208110156105b957600080fd5b50356112c7565b6040805161ffff9092168252519081900360200190f35b610423600480360360208110156105ed57600080fd5b50356112dd565b6105fc6112f2565b60408051600792830b90920b8252519081900360200190f35b6104096112fb565b61063d6004803603602081101561063357600080fd5b503560ff16611301565b604080516001600160401b039092168252519081900360200190f35b61070c6004803603606081101561066f57600080fd5b60ff82351691602081013591810190606081016040820135600160201b81111561069857600080fd5b8201836020820111156106aa57600080fd5b803590602001918460018302840111600160201b831117156106cb57600080fd5b91908080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525092955061131c945050505050565b6040805160208082528351818301528351919283929083019185019080838360005b8381101561074657818101518382015260200161072e565b50505050905090810190601f1680156107735780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b6103a6611392565b6104236004803603602081101561079f57600080fd5b503560ff16611397565b6103e56113ac565b6105c06113b2565b6103a66113b8565b6103e56113bd565b6104096113c3565b610599600480360360408110156107e757600080fd5b506001600160a01b03813581169160200135166113f3565b610409611653565b6105c061167b565b61082c6004803603602081101561082557600080fd5b5035611680565b6040805161ffff90941684526001600160801b03909216602084015282820152519081900360600190f35b6104096116af565b6103e56004803603602081101561087557600080fd5b503560ff166116d6565b6103e56116f1565b6103a661167b565b6103a66116f7565b6105c0611392565b6104096116fc565b6103e5611702565b6103a6611708565b610599600480360360a08110156108cd57600080fd5b810190602081018135600160201b8111156108e757600080fd5b8201836020820111156108f957600080fd5b803590602001918460018302840111600160201b8311171561091a57600080fd5b919390929091602081019035600160201b81111561093757600080fd5b82018360208201111561094957600080fd5b803590602001918460018302840111600160201b8311171561096a57600080fd5b919350915080356001600160401b03908116916020810135909116906040013560ff1661170d565b610409612a37565b6103a6612a3f565b6103e5612a44565b6103e5612a4a565b610423612a50565b6103c4610bbf565b610599600480360360408110156109d857600080fd5b810190602081018135600160201b8111156109f257600080fd5b820183602082011115610a0457600080fd5b803590602001918460018302840111600160201b83111715610a2557600080fd5b919390929091602081019035600160201b811115610a4257600080fd5b820183602082011115610a5457600080fd5b803590602001918460018302840111600160201b83111715610a7557600080fd5b509092509050612a59565b61063d60048036036020811015610a9657600080fd5b503560ff1661351d565b610409613538565b6103e561355c565b610599613562565b61042360048036036040811015610ace57600080fd5b5080356001600160a01b0316906020013560ff166137b6565b61070c6137d6565b6104096137f5565b6103e56137fb565b610599613801565b61063d60048036036020811015610b1d57600080fd5b503560ff16613bb8565b610599613bd3565b61059960048036036060811015610b4557600080fd5b60ff8235169190810190604081016020820135600160201b811115610b6957600080fd5b820183602082011115610b7b57600080fd5b803590602001918460018302840111600160201b83111715610b9c57600080fd5b919350915035613df2565b6103e5613f35565b6103a6613f3b565b6103e5613f40565b600081565b606481565b61200181565b60015481565b600b5460ff1681565b60005460ff16610c23576040805162461bcd60e51b81526020600482015260196024820152600080516020614a4e833981519152604482015290519081900360640190fd5b604080516337d7f9c160e21b81526001600160401b038b35166004820181905291516110039163df5fe704916024808301926020929190829003018186803b158015610c6e57600080fd5b505afa158015610c82573d6000803e3d6000fd5b505050506040513d6020811015610c9857600080fd5b5051610cd55760405162461bcd60e51b8152600401808060200182810382526023815260200180614a6e6023913960400191505060405180910390fd5b604080516337d7f9c160e21b815260208c8101356001600160401b03166004830181905292516110039263df5fe704926024808301939192829003018186803b158015610d2157600080fd5b505afa158015610d35573d6000803e3d6000fd5b505050506040513d6020811015610d4b57600080fd5b5051610d885760405162461bcd60e51b8152600401808060200182810382526023815260200180614a6e6023913960400191505060405180910390fd5b60608b013560ff81166000908152600560205260409020546001600160401b03909116906001600160a01b0316610e01576040805162461bcd60e51b815260206004820152601860248201527718da185b9b995b081a5cc81b9bdd081cdd5c1c1bdc9d195960421b604482015290519081900360640190fd5b600b5460ff1615610e45576040805162461bcd60e51b81526020600482015260096024820152681cdd5cdc195b99195960ba1b604482015290519081900360640190fd5b8888604051808383808284376040519201829003822094508f93508e9250819050838380828437808301925050509250505060405180910390201415610ec1576040805162461bcd60e51b815260206004820152600c60248201526b1cd85b59481c185e5b1bd85960a21b604482015290519081900360640190fd5b60606001600160401b0360408e01358116908e83013516610ee28282613f46565b80516020808301919091206000818152600e9092526040909120549194509060ff1615610f4b576040805162461bcd60e51b8152602060048201526012602482015271185b1c9958591e4818da185b1b195b99d95960721b604482015290519081900360640190fd5b6000908152600e60205260408120805460ff191660011790558f8160200201356001600160401b0316905060608f8f8080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f82011690508083019250505050505050905060608c8c8080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201829052506040805163cba510a960e01b81526001600160401b038a16600482015290519596509094611003945063cba510a9935060248083019350602092829003018186803b15801561104157600080fd5b505afa158015611055573d6000803e3d6000fd5b505050506040513d602081101561106b57600080fd5b505160408051808201909152600381526269626360e81b6020820152909150611098908290898686613f8e565b6110e1576040805162461bcd60e51b81526020600482015260156024820152740696e76616c6964206d65726b6c652070726f6f663605c1b604482015290519081900360640190fd5b5050505060008f6001600481106110f457fe5b60200201356001600160401b0316905060608d8d8080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525050604080516020601f8f018190048102820181019092528d815293945060609392508d91508c908190840183828082843760009201829052506040805163cba510a960e01b81526001600160401b038a16600482015290519596509094611003945063cba510a9935060248083019350602092829003018186803b1580156111c057600080fd5b505afa1580156111d4573d6000803e3d6000fd5b505050506040513d60208110156111ea57600080fd5b505160408051808201909152600381526269626360e81b6020820152909150611217908290898686613f8e565b611260576040805162461bcd60e51b8152602060048201526015602482015274696e76616c6964206d65726b6c652070726f6f663160581b604482015290519081900360640190fd5b5050505061126c61408b565b604080516001600160401b038416815260ff83166020820152815133927f039eb91179ffd7d3b6e97f8ea106e748e827f910b872375dbc9c14a362319c3c928290030190a2505050505050505050505050505050565b603281565b600d6020526000908152604090205461ffff1681565b600e6020526000908152604090205460ff1681565b60045460070b81565b60025481565b600a602052600090815260409020546001600160401b031681565b60606000825160210190506060816040519080825280601f01601f191660200182016040528015611354576020820181803683370190505b506021810186905260018101879052828152905060418101600061137786614109565b50905061138681838851614113565b50909695505050505050565b600181565b60096020526000908152604090205460ff1681565b61100181565b6102ca81565b600881565b61200081565b604080517710d05390d15317d514905394d1915497d41493d413d4d05360421b8152905190819003601801902081565b60005460ff16611438576040805162461bcd60e51b81526020600482015260196024820152600080516020614a4e833981519152604482015290519081900360640190fd5b6040805163569e4ed360e11b815233600482015290516000916110009163ad3c9da691602480820192602092909190829003018186803b15801561147b57600080fd5b505afa15801561148f573d6000803e3d6000fd5b505050506040513d60208110156114a557600080fd5b505160408051633d42651560e11b8152905191925060009161100091637a84ca2a916004808301926020929190829003018186803b1580156114e657600080fd5b505afa1580156114fa573d6000803e3d6000fd5b505050506040513d602081101561151057600080fd5b505190508061151d575060155b60008211801561152d5750808211155b61156c576040805162461bcd60e51b815260206004820152600b60248201526a1b9bdd0818d8589a5b995d60aa1b604482015290519081900360640190fd5b604080516001600160a01b038087166020808401919091529086168284015282518083038401815260608301808552815191909201207710d05390d15317d514905394d1915497d41493d413d4d05360421b90915291519081900360780190206000906115d99083614154565b9050801561164b5760408051630911a2c160e11b81526001600160a01b03888116600483015287166024820152905161100491631223458291604480830192600092919082900301818387803b15801561163257600080fd5b505af1158015611646573d6000803e3d6000fd5b505050505b505050505050565b604080516f14d554d411539117d41493d413d4d05360821b8152905190819003601001902081565b600281565b600c602052600090815260409020805460019091015461ffff8216916201000090046001600160801b03169083565b604080516e149153d4115397d41493d413d4d053608a1b8152905190819003600f01902081565b6005602052600090815260409020546001600160a01b031681565b61100581565b601081565b60035481565b61100881565b600b81565b60005460ff16611752576040805162461bcd60e51b81526020600482015260196024820152600080516020614a4e833981519152604482015290519081900360640190fd5b60408051630a83aaa960e31b815233600482015290516110069163541d5548916024808301926020929190829003018186803b15801561179157600080fd5b505afa1580156117a5573d6000803e3d6000fd5b505050506040513d60208110156117bb57600080fd5b505161180e576040805162461bcd60e51b815260206004820152601f60248201527f746865206d73672073656e646572206973206e6f7420612072656c6179657200604482015290519081900360640190fd5b7388cb4d8f77742c24d647bef8049d3f3c56067cdd33148061184357507342d596440775c90db8d9187b47650986e106349333145b61187e5760405162461bcd60e51b815260040180806020018281038252602a8152602001806149f2602a913960400191505060405180910390fd5b60ff8116600090815260086020526040902054829082906001600160401b0390811690831681146118ee576040805162461bcd60e51b815260206004820152601560248201527439b2b8bab2b731b2903737ba1034b71037b93232b960591b604482015290519081900360640190fd5b60ff8216600090815260086020908152604091829020805467ffffffffffffffff1916600185016001600160401b039081169190911790915582516337d7f9c160e21b81529089166004820152915188926110039263df5fe70492602480840193829003018186803b15801561196357600080fd5b505afa158015611977573d6000803e3d6000fd5b505050506040513d602081101561198d57600080fd5b50516119ca5760405162461bcd60e51b8152600401808060200182810382526023815260200180614a6e6023913960400191505060405180910390fd5b60ff851660009081526005602052604090205485906001600160a01b0316611a34576040805162461bcd60e51b815260206004820152601860248201527718da185b9b995b081a5cc81b9bdd081cdd5c1c1bdc9d195960421b604482015290519081900360640190fd5b60ff86166000908152600a6020526040902054889087906001600160401b039081169083161015611a9d576040805162461bcd60e51b815260206004820152600e60248201526d3a37b79037b632103432b0b232b960911b604482015290519081900360640190fd5b60ff81166000908152600a60205260409020546001600160401b03838116911614611aef5760ff81166000908152600a60205260409020805467ffffffffffffffff19166001600160401b0384161790555b600b5460ff1615611b33576040805162461bcd60e51b81526020600482015260096024820152681cdd5cdc195b99195960ba1b604482015290519081900360640190fd5b60608e8e8080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f82011690508083019250505050505050905060608d8d8080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f820116905080830192505050505050509050611c776110036001600160a01b031663cba510a98e6040518263ffffffff1660e01b815260040180826001600160401b03166001600160401b0316815260200191505060206040518083038186803b158015611c2057600080fd5b505afa158015611c34573d6000803e3d6000fd5b505050506040513d6020811015611c4a57600080fd5b505160408051808201909152600381526269626360e81b6020820152611c708e8e613f46565b8585613f8e565b611cbf576040805162461bcd60e51b815260206004820152601460248201527334b73b30b634b21036b2b935b63290383937b7b360611b604482015290519081900360640190fd5b60408051631bb5062960e31b81526001600160401b038e16600482015290516000916110039163dda8314891602480820192602092909190829003018186803b158015611d0b57600080fd5b505afa158015611d1f573d6000803e3d6000fd5b505050506040513d6020811015611d3557600080fd5b505190508b8b600080806060611d4a89614439565b935093509350935083611e0c578460ff16866001600160401b03167ff7b2e42d694eb1100184aae86d4245d9e46966100b1dc7e723275b98326854ac8b6040518080602001828103825283818151815260200191508051906020019080838360005b83811015611dc4578181015183820152602001611dac565b50505050905090810190601f168015611df15780820380516001836020036101000a031916815260200191505b509250505060405180910390a3505050505050505050612a27565b6040805160ff85811682529151918716916001600160401b038916917f36afdaf439a8f43fe72135135d804ae620b37a474f0943b5b85f6788312cad40919081900360200190a360ff83166123915760ff85166000818152600560209081526040808320548151631182b87560e01b815260048101958652602481019283528651604482015286516001600160a01b03909216958695631182b875958d958a9593949093606490910192918601918190849084905b83811015611ed9578181015183820152602001611ec1565b50505050905090810190601f168015611f065780820380516001836020036101000a031916815260200191505b509350505050600060405180830381600087803b158015611f2657600080fd5b505af192505050801561200a57506040513d6000823e601f3d908101601f191682016040526020811015611f5957600080fd5b8101908080516040519392919084600160201b821115611f7857600080fd5b908301906020820185811115611f8d57600080fd5b8251600160201b811182820188101715611fa657600080fd5b82525081516020918201929091019080838360005b83811015611fd3578181015183820152602001611fbb565b50505050905090810190601f1680156120005780820380516001836020036101000a031916815260200191505b5060405250505060015b61231c576040516000815260443d1015612026575060006120c1565b60046000803e60005160e01c6308c379a081146120475760009150506120c1565b60043d036004833e81513d60248201116001600160401b0382111715612072576000925050506120c1565b80830180516001600160401b038111156120935760009450505050506120c1565b8060208301013d86018111156120b1576000955050505050506120c1565b601f01601f191660405250925050505b806120cc57506121de565b60ff8716600090815260076020526040812054612103916001600160401b039091169089906120fe906002908861131c565b6144e9565b60ff8716600090815260076020908152604080832080546001600160401b038082166001011667ffffffffffffffff19909116179055805182815284518184015284516001600160a01b038716947ff91a8f63e5b3e0e89e5f93e1915a7805f3c52d9a73b3c09769785c2c7bf87acf948794849390840192918601918190849084905b8381101561219e578181015183820152602001612186565b50505050905090810190601f1680156121cb5780820380516001836020036101000a031916815260200191505b509250505060405180910390a250612317565b3d808015612208576040519150601f19603f3d011682016040523d82523d6000602084013e61220d565b606091505b5060ff8716600090815260076020526040812054612240916001600160401b039091169089906120fe906002908861131c565b60ff8716600090815260076020908152604080832080546001600160401b038082166001011667ffffffffffffffff19909116179055805182815284518184015284516001600160a01b038716947f63ac299d6332d1cc4e61b81e59bc00c0ac7c798addadf33840f1307cd2977351948794849390840192918601918190849084905b838110156122db5781810151838201526020016122c3565b50505050905090810190601f1680156123085780820380516001836020036101000a031916815260200191505b509250505060405180910390a2505b61238b565b8051156123895760ff8716600090815260076020526040812054612355916001600160401b039091169089906120fe906001908661131c565b60ff8716600090815260076020526040902080546001600160401b038082166001011667ffffffffffffffff199091161790555b505b5061295f565b60ff8316600114156126355760ff8516600081815260056020908152604080832054815163831d65d160e01b815260048101958652602481019283528651604482015286516001600160a01b0390921695869563831d65d1958d958a9593949093606490910192918601918190849084905b8381101561241b578181015183820152602001612403565b50505050905090810190601f1680156124485780820380516001836020036101000a031916815260200191505b509350505050600060405180830381600087803b15801561246857600080fd5b505af1925050508015612479575060015b61238b576040516000815260443d101561249557506000612530565b60046000803e60005160e01c6308c379a081146124b6576000915050612530565b60043d036004833e81513d60248201116001600160401b03821117156124e157600092505050612530565b80830180516001600160401b03811115612502576000945050505050612530565b8060208301013d860181111561252057600095505050505050612530565b601f01601f191660405250925050505b8061253b57506125a0565b60408051602080825283518183015283516001600160a01b038616937ff91a8f63e5b3e0e89e5f93e1915a7805f3c52d9a73b3c09769785c2c7bf87acf938693909283928301918501908083836000831561219e578181015183820152602001612186565b3d8080156125ca576040519150601f19603f3d011682016040523d82523d6000602084013e6125cf565b606091505b5060408051602080825283518183015283516001600160a01b038616937f63ac299d6332d1cc4e61b81e59bc00c0ac7c798addadf33840f1307cd297735193869390928392830191850190808383600083156122db5781810151838201526020016122c3565b60ff83166002141561295f5760ff8516600081815260056020908152604080832054815163c8509d8160e01b815260048101958652602481019283528651604482015286516001600160a01b0390921695869563c8509d81958d958a9593949093606490910192918601918190849084905b838110156126bf5781810151838201526020016126a7565b50505050905090810190601f1680156126ec5780820380516001836020036101000a031916815260200191505b509350505050600060405180830381600087803b15801561270c57600080fd5b505af192505050801561271d575060015b61295d576040516000815260443d1015612739575060006127d4565b60046000803e60005160e01c6308c379a0811461275a5760009150506127d4565b60043d036004833e81513d60248201116001600160401b0382111715612785576000925050506127d4565b80830180516001600160401b038111156127a65760009450505050506127d4565b8060208301013d86018111156127c4576000955050505050506127d4565b601f01601f191660405250925050505b806127df5750612888565b816001600160a01b03167ff91a8f63e5b3e0e89e5f93e1915a7805f3c52d9a73b3c09769785c2c7bf87acf826040518080602001828103825283818151815260200191508051906020019080838360005b83811015612848578181015183820152602001612830565b50505050905090810190601f1680156128755780820380516001836020036101000a031916815260200191505b509250505060405180910390a25061295d565b3d8080156128b2576040519150601f19603f3d011682016040523d82523d6000602084013e6128b7565b606091505b50816001600160a01b03167f63ac299d6332d1cc4e61b81e59bc00c0ac7c798addadf33840f1307cd2977351826040518080602001828103825283818151815260200191508051906020019080838360005b83811015612921578181015183820152602001612909565b50505050905090810190601f16801561294e5780820380516001836020036101000a031916815260200191505b509250505060405180910390a2505b505b60ff80861660009081526009602052604090205461100591636f93d2e6918a91339187911680612991575060ff881615155b604080516001600160e01b031960e088901b1681526001600160a01b039586166004820152939094166024840152604483019190915215156064820152905160848083019260209291908290030181600087803b1580156129f157600080fd5b505af1158015612a05573d6000803e3d6000fd5b505050506040513d6020811015612a1b57600080fd5b50505050505050505050505b5050505050505050505050505050565b630102ca0081565b600981565b61100781565b61100681565b60005460ff1681565b3361100714612a995760405162461bcd60e51b815260040180806020018281038252602e81526020018061497a602e913960400191505060405180910390fd5b600b5460ff1615612add576040805162461bcd60e51b81526020600482015260096024820152681cdd5cdc195b99195960ba1b604482015290519081900360640190fd5b612b4684848080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525050604080518082019091526012815271626174636853697a65466f724f7261636c6560701b602082015291506146849050565b15612be157604080516020601f8401819004810282018101909252828152600091612b899185858083850183828082843760009201919091525061476b92505050565b90506127108111158015612b9e5750600a8110155b612bd95760405162461bcd60e51b8152600401808060200182810382526032815260200180614a1c6032913960400191505060405180910390fd5b60015561348b565b612c4a84848080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152505060408051808201909152601281527118591913dc955c19185d1950da185b9b995b60721b602082015291506146849050565b15612dd257606082828080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152505082519293505060169091149050612ccd5760405162461bcd60e51b815260040180806020018281038252605a815260200180614893605a913960600191505060405180910390fd5b60018101516002820151601683015160ff82161590612ceb81614770565b612d3c576040805162461bcd60e51b815260206004820152601960248201527f61646472657373206973206e6f74206120636f6e747261637400000000000000604482015290519081900360640190fd5b60ff8416600081815260056020908152604080832080546001600160a01b0319166001600160a01b038716908117909155808452600683528184208585528352818420805460ff199081166001179091556009909352818420805490931687151517909255519092917f7e3b6af43092577ee20e60eaa1d9b114a7031305c895ee7dd3ffe17196d2e1e091a3505050505061348b565b612e3f84848080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525050604080518082019091526016815275195b98589b1953dc911a5cd8589b1950da185b9b995b60521b602082015291506146849050565b15612f7057606082828080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152505082519293505060029091149050612ec25760405162461bcd60e51b815260040180806020018281038252604a8152602001806149a8604a913960600191505060405180910390fd5b600181810151600283015160ff80831660009081526005602052604090205492939192908316909114906001600160a01b03168015612f66576001600160a01b038116600090815260066020908152604080832060ff881680855290835292819020805460ff1916861515908117909155815190815290517fa3132e3f9819fbddc7f0ed6d38d7feef59aa95112090b7c592f5cb5bc4aa4adc929181900390910190a25b505050505061348b565b612fd484848080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152505060408051808201909152600d81526c73757370656e6451756f72756d60981b602082015291506146849050565b1561310957600281146130185760405162461bcd60e51b815260040180806020018281038252602d815260200180614921602d913960400191505060405180910390fd5b600061305b600284848080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061476b92505050565b905060008161ffff16118015613075575060648161ffff16105b6130bf576040805162461bcd60e51b8152602060048201526016602482015275696e76616c69642073757370656e642071756f72756d60501b604482015290519081900360640190fd5b604080516f14d554d411539117d41493d413d4d05360821b815281519081900360100190206000908152600d60205220805461ffff90921661ffff1990921691909117905561348b565b61316c84848080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152505060408051808201909152600c81526b72656f70656e51756f72756d60a01b602082015291506146849050565b1561329f57600281146131b05760405162461bcd60e51b815260040180806020018281038252602c81526020018061494e602c913960400191505060405180910390fd5b60006131f3600284848080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061476b92505050565b905060008161ffff1611801561320d575060648161ffff16105b613256576040805162461bcd60e51b8152602060048201526015602482015274696e76616c69642072656f70656e2071756f72756d60581b604482015290519081900360640190fd5b604080516e149153d4115397d41493d413d4d053608a1b8152815190819003600f0190206000908152600d60205220805461ffff90921661ffff1990921691909117905561348b565b61330a84848080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152505060408051808201909152601481527363616e63656c5472616e7366657251756f72756d60601b602082015291506146849050565b1561344e576002811461334e5760405162461bcd60e51b81526004018080602001828103825260348152602001806148ed6034913960400191505060405180910390fd5b6000613391600284848080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061476b92505050565b905060008161ffff161180156133ab575060648161ffff16105b6133fc576040805162461bcd60e51b815260206004820152601e60248201527f696e76616c69642063616e63656c207472616e736665722071756f72756d0000604482015290519081900360640190fd5b604080517710d05390d15317d514905394d1915497d41493d413d4d05360421b815281519081900360180190206000908152600d60205220805461ffff90921661ffff1990921691909117905561348b565b6040805162461bcd60e51b815260206004820152600d60248201526c756e6b6e6f776e20706172616d60981b604482015290519081900360640190fd5b7f6cdb0ac70ab7f2e2d035cca5be60d89906f2dede7648ddbd7402189c1eeed17a848484846040518080602001806020018381038352878782818152602001925080828437600083820152601f01601f191690910184810383528581526020019050858580828437600083820152604051601f909101601f19169092018290039850909650505050505050a150505050565b6008602052600090815260409020546001600160401b031681565b7fc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a47081565b61100281565b60005460ff166135a7576040805162461bcd60e51b81526020600482015260196024820152600080516020614a4e833981519152604482015290519081900360640190fd5b6040805163569e4ed360e11b815233600482015290516000916110009163ad3c9da691602480820192602092909190829003018186803b1580156135ea57600080fd5b505afa1580156135fe573d6000803e3d6000fd5b505050506040513d602081101561361457600080fd5b505160408051633d42651560e11b8152905191925060009161100091637a84ca2a916004808301926020929190829003018186803b15801561365557600080fd5b505afa158015613669573d6000803e3d6000fd5b505050506040513d602081101561367f57600080fd5b505190508061368c575060155b60008211801561369c5750808211155b6136db576040805162461bcd60e51b815260206004820152600b60248201526a1b9bdd0818d8589a5b995d60aa1b604482015290519081900360640190fd5b600b5460ff16613722576040805162461bcd60e51b815260206004820152600d60248201526c1b9bdd081cdd5cdc195b991959609a1b604482015290519081900360640190fd5b604080516e149153d4115397d41493d413d4d053608a1b8152905190819003600f019020600090613773907fc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470614154565b905080156137b157600b805460ff1916905560405133907f899fe8c37dc61708a3aaa99c4bf143346c1d1da69af79be9e8920c0a6785b75290600090a25b505050565b600660209081526000928352604080842090915290825290205460ff1681565b6040518060400160405280600381526020016269626360e81b81525081565b610e1081565b61100381565b60005460ff1615613859576040805162461bcd60e51b815260206004820152601960248201527f74686520636f6e747261637420616c726561647920696e697400000000000000604482015290519081900360640190fd5b7f1471eb6eb2c5e789fc3de43f8ce62938c7d1836ec861730447e2ada8fd81017b80546001600160a01b0319908116611008179091557f92e85d02570a8092d09a6e3a57665bc3815a2699a4074001bf1ccabf660f5a36805460ff199081169091557fd8af288fc1c8680b4f4706064cf021e264efb6828fcaf7eb5ca36818eb365bcc8054821660019081179091557f89832631fb3c3307a103ba2c84ab569c64d6182a18893dcd163f0f1c2090733a805484166110049081179091557f6cde3cea4b3a3fb2488b2808bae7556f4a405e50f65e1794383bc026131b13c38054841690557f72e4efa1513b071517c6c74dba31b5934a81aa83cddd400e7081df5529c9943680548416831790557fa9bc9a3a348c357ba16b37005d7e6b3236198c0e939f4af8c5f19b8deeb8ebc08054851690911790557fc575c31fea594a6eb97c8e9d3f9caee4c16218c6ef37e923234c0fe9014a61e78054831690557f4e523af77f034e9810f1c94057f5e931fb3d16a51511a4c3add793617d18610580548316821790557ffb33122aa9f93cc639ebe80a7bc4784c11e6053dde89c6f4f7e268c6a623da1e805484166110001790557fc7694af312c4f286114180fd0ba6a52461fcee8a381636770b19a343af92538a80548316821790557f01112dd68e482ba8d68a7e828cff8b3abcea08eab88941953c180a7e650e9cd480548316821790557fc0a4a8be475dfebc377ebef2d7c4ff47656f572a08dd92b81017efcdba0febe1805484166110071790557f87e8a52529e8ece4ef759037313542a6429ff494a9fab9027fb79db90124eba680548316821790557f4c7666bbcb22d46469f7cc282f70764a7012dca2cce630ff8d83db9a9cdd48f080548316821790557f40f28f99a40bc9f6beea1013afdbc3cdcc689eb76b82c4de06c0acf1e1932ed58054909316611001179092557f0d9cf2cd531699eed8dd34e40ff2884a14a698c4898184fba85194e6f6772d248054821683179055600b60009081527f23f68c9bd22b8a93d06adabe17481c87c016bcbd20adc8bfd707a4d813a572176020527fdf0d5d05428057f5455c2dc8e810dd86d1e9350faa72f16bda8a45443c5b39328054831684179055603283556004805467ffffffffffffffff19166001600160401b031790556002819055600381905580549091169091179055565b6007602052600090815260409020546001600160401b031681565b60005460ff16613c18576040805162461bcd60e51b81526020600482015260196024820152600080516020614a4e833981519152604482015290519081900360640190fd5b6040805163569e4ed360e11b815233600482015290516000916110009163ad3c9da691602480820192602092909190829003018186803b158015613c5b57600080fd5b505afa158015613c6f573d6000803e3d6000fd5b505050506040513d6020811015613c8557600080fd5b505160408051633d42651560e11b8152905191925060009161100091637a84ca2a916004808301926020929190829003018186803b158015613cc657600080fd5b505afa158015613cda573d6000803e3d6000fd5b505050506040513d6020811015613cf057600080fd5b5051905080613cfd575060155b600082118015613d0d5750808211155b613d4c576040805162461bcd60e51b815260206004820152600b60248201526a1b9bdd0818d8589a5b995d60aa1b604482015290519081900360640190fd5b600b5460ff1615613d90576040805162461bcd60e51b81526020600482015260096024820152681cdd5cdc195b99195960ba1b604482015290519081900360640190fd5b604080516f14d554d411539117d41493d413d4d05360821b81529051908190036010019020600090613de2907fc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470614154565b905080156137b1576137b161408b565b60005460ff16613e37576040805162461bcd60e51b81526020600482015260196024820152600080516020614a4e833981519152604482015290519081900360640190fd5b33600090815260066020908152604080832060ff8089168552925290912054859116613e945760405162461bcd60e51b81526004018080602001828103825260318152602001806148626031913960400191505060405180910390fd5b60ff85166000908152600760209081526040808320548151601f88018490048402810184019092528682526001600160401b031692613ef99284928a926120fe92909189918c908c908190840183828082843760009201919091525061131c92505050565b60ff959095166000908152600760205260409020805467ffffffffffffffff191660019096016001600160401b03169590951790945550505050565b61100081565b600381565b61100481565b60408051600e808252818301909252606091630102ca0060ff851617918391602082018180368337505050600e81810187905260068201939093529182525090505b92915050565b600085613f9d57506000614082565b606082518451865160800101016040519080825280601f01601f191660200182016040528015613fd4576020820181803683370190505b5090506000613fe282614776565b602080890151825201905086600080613ffa89614109565b8086526020909501949092509050614013828583614113565b9283019261402088614109565b8086526020909501949092509050614039828583614113565b9283018a81526020019261404c87614109565b909250905061405c828583614113565b50835160200161406a61477c565b60208183886065600019fa5051600114955050505050505b95945050505050565b600b5460ff16156140cf576040805162461bcd60e51b81526020600482015260096024820152681cdd5cdc195b99195960ba1b604482015290519081900360640190fd5b600b805460ff1916600117905560405133907f6f123d3d54c84a7960a573b31c221dcd86e13fd849c5adb0c6ca851468cc1ae490600090a2565b8051602090910191565b5b60208110614133578251825260209283019290910190601f1901614114565b915181516020939093036101000a6000190180199091169216919091179052565b6000828152600d602052604081205461ffff1661421d57604080516f14d554d411539117d41493d413d4d05360821b815281519081900360100181206000908152600d6020818152848320805461ffff199081166001179091556e149153d4115397d41493d413d4d053608a1b8552855194859003600f01852084528282528584208054821660029081179091557710d05390d15317d514905394d1915497d41493d413d4d05360421b8652865195869003601801909520845291905292902080549092161790555b6000838152600c6020526040902080546201000090046001600160801b03164210158061424e575082816001015414155b15614321576000848152600d602090815260409182902054835461ffff90911661ffff199091161771ffffffffffffffffffffffffffffffff0000191662010000610e1042016001600160801b031602178355600180840186905582519182019092523381526142c39160028401919061479a565b5080546040805161ffff83168152620100009092046001600160801b0316602083015281810185905251339186917f9e109f0e55ef32e99e4880be2ec357f1ddb3469c79d0747ef4762da6e89fabe5916060908290030190a36143d5565b60005b60028201548110156143ac57336001600160a01b031682600201828154811061434957fe5b6000918252602090912001546001600160a01b031614156143a4576040805162461bcd60e51b815260206004820152601060248201526f185b1c9958591e48185c1c1c9bdd995960821b604482015290519081900360640190fd5b600101614324565b50600281018054600181018255600091825260209091200180546001600160a01b031916331790555b8054600282015461ffff9091161161442f576000848152600c60205260408120805471ffffffffffffffffffffffffffffffffffff19168155600181018290559061442360028301826147ff565b50506001915050613f88565b5060009392505050565b600080600060606021855110156144695750506040805160008082526020820190925290925082915081906144e2565b600185015160218601518651604080516020198301808252601f19600119909401939093168101602001909152604189019392916060919080156144b4576020820181803683370190505b50905060006144c282614109565b5090506144d4858260218d5103614113565b506001975091955093509150505b9193509193565b600b5460ff161561452d576040805162461bcd60e51b81526020600482015260096024820152681cdd5cdc195b99195960ba1b604482015290519081900360640190fd5b60025443111561456c576004805467ffffffffffffffff1981166001600160401b036001600793840b810190930b1617909155600355436002556145ad565b600380546001908101918290555410156145ad576004805467ffffffffffffffff1981166001600160401b036001600793840b810190930b16179091556003555b8160ff16836001600160401b0316600460009054906101000a900460070b6001600160401b03167f3a6e0fc61675aa2a100bcba0568368bb92bcec91c97673391074f11138f0cffe6102ca85604051808361ffff1661ffff16815260200180602001828103825283818151815260200191508051906020019080838360005b8381101561464457818101518382015260200161462c565b50505050905090810190601f1680156146715780820380516001836020036101000a031916815260200191505b50935050505060405180910390a4505050565b6000816040516020018082805190602001908083835b602083106146b95780518252601f19909201916020918201910161469a565b6001836020036101000a03801982511681845116808217855250505050505090500191505060405160208183030381529060405280519060200120836040516020018082805190602001908083835b602083106147275780518252601f199092019160209182019101614708565b6001836020036101000a0380198251168184511680821785525050505050509050019150506040516020818303038152906040528051906020012014905092915050565b015190565b3b151590565b60200190565b60405180602001604052806001906020820280368337509192915050565b8280548282559060005260206000209081019282156147ef579160200282015b828111156147ef57825182546001600160a01b0319166001600160a01b039091161782556020909201916001909101906147ba565b506147fb929150614820565b5090565b508054600082559060005260206000209081019061481d9190614847565b50565b61484491905b808211156147fb5780546001600160a01b0319168155600101614826565b90565b61484491905b808211156147fb576000815560010161484d56fe74686520636f6e747261637420616e64206368616e6e656c2068617665206e6f74206265656e20726567697374657265646c656e677468206f662076616c756520666f72206164644f725570646174654368616e6e656c2073686f756c642062652032322c206368616e6e656c49643a697346726f6d53797374656d3a68616e646c6572416464726573736c656e677468206f662076616c756520666f722063616e63656c5472616e7366657251756f72756d2073686f756c6420626520326c656e677468206f662076616c756520666f722073757370656e6451756f72756d2073686f756c6420626520326c656e677468206f662076616c756520666f722072656f70656e51756f72756d2073686f756c642062652032746865206d6573736167652073656e646572206d75737420626520676f7665726e616e636520636f6e74726163746c656e677468206f662076616c756520666f7220656e61626c654f7244697361626c654368616e6e656c2073686f756c6420626520322c206368616e6e656c49643a6973456e61626c65746865206d73672073656e646572206973206e6f7420612077686974656c6162656c2072656c61796572746865206e6577426174636853697a65466f724f7261636c652073686f756c6420626520696e205b31302c2031303030305d74686520636f6e7472616374206e6f7420696e697420796574000000000000006c6967687420636c69656e74206e6f742073796e632074686520626c6f636b20796574a2646970667358221220008ae508df631c7bfc8d3fe4ef823eddaef63a15d5e7aa54865ae501fe6fc38164736f6c63430006040033", + }, + }, + } + CalcuttaUpgrade[networkname.BorMainnetChainName] = &Upgrade{ UpgradeName: "calcutta", Configs: []*UpgradeConfig{ @@ -507,6 +579,99 @@ func init() { }, }, } + + LubanUpgrade[networkname.BSCChainName] = &Upgrade{ + UpgradeName: "luban", + Configs: []*UpgradeConfig{ + { + ContractAddr: ValidatorContract, + CommitUrl: "https://github.com/bnb-chain/bsc-genesis-contract/commit/b144718e94d7a1ebb24a7103202300f08826f369", + Code: "60806040526004361061046c5760003560e01c8063862498821161024a578063c6d3394511610139578063e40716a1116100b6578063f9a2bbc71161007a578063f9a2bbc714610b6b578063fc3e590814610b80578063fccc281314610b95578063fd4ad81f14610baa578063fd6a687914610bd957610473565b8063e40716a114610af9578063eb57e20214610b0e578063eda5868c14610b2e578063f340fa0114610b43578063f92eb86b14610b5657610473565b8063d86222d5116100fd578063d86222d514610a90578063daacdb6614610aa5578063dc927faf14610aba578063e086c7b114610acf578063e1c7392a14610ae457610473565b8063c6d3394514610a3c578063c81b166214610a51578063c8509d811461085f578063d04aa99614610a66578063d68fb56a14610a7b57610473565b8063a5422d5c116101c7578063ad3c9da61161018b578063ad3c9da6146109d0578063aef198a9146109f0578063b7ab4db514610a05578063b8cf4ef114610a27578063bf9f49951461062f57610473565b8063a5422d5c1461095c578063a78abc1614610971578063aaf5eb6814610986578063ab51bb961461099b578063ac431751146109b057610473565b806396713da91161020e57806396713da9146108f35780639dc09262146109085780639fe0f8161461091d578063a0dc275814610932578063a1a11bf51461094757610473565b8063862498821461087f57806388b32f11146108945780638b5ad0c9146108a95780638d19a410146108be5780639369d7de146108de57610473565b80634df6e0c3116103665780636e47b482116102e35780637942fd05116102a75780637942fd05146108205780637a84ca2a1461083557806381650b621461084a578063831d65d11461085f578063853230aa1461080b57610473565b80636e47b482146107b757806370fd5bad146107cc578063718a8aa8146107e157806375d47a0a146107f657806378dfed4a1461080b57610473565b8063565c56b31161032a578063565c56b3146107265780635667515a146107465780635d77156c1461075b57806362b72cf5146107705780636969a25c1461078557610473565b80634df6e0c3146106b25780635192c82c146106c757806351e80672146106dc578063549b03f2146106f157806355614fcc1461070657610473565b8063321d398a116103f45780633dffc387116103b85780633dffc3871461062f57806343756e5c1461065157806345cf9daf14610666578063493279b11461067b5780634bf6c8821461069d57610473565b8063321d398a146105975780633365af3a146105b757806335409f7f146105d75780633b071dcc146105f75780633de0f0d81461061a57610473565b80631182b8751161043b5780631182b875146104fe578063152ad3b81461052b5780631ff180691461054d578063219f22d514610562578063300c35671461057757610473565b806304c4fec61461047857806307a568471461048f5780630bee7a67146104ba5780630e2374a5146104dc57610473565b3661047357005b600080fd5b34801561048457600080fd5b5061048d610bee565b005b34801561049b57600080fd5b506104a4610c60565b6040516104b19190616ef0565b60405180910390f35b3480156104c657600080fd5b506104cf610c66565b6040516104b19190616f1a565b3480156104e857600080fd5b506104f1610c6b565b6040516104b191906162f7565b34801561050a57600080fd5b5061051e6105193660046161dd565b610c71565b6040516104b1919061646e565b34801561053757600080fd5b50610540610ea9565b6040516104b19190616463565b34801561055957600080fd5b506104a4610eb2565b34801561056e57600080fd5b506104cf610eb8565b34801561058357600080fd5b5061048d6105923660046160a6565b610ebd565b3480156105a357600080fd5b506105406105b236600461618a565b611241565b3480156105c357600080fd5b506105406105d236600461618a565b611310565b3480156105e357600080fd5b5061048d6105f236600461607f565b6113c1565b34801561060357600080fd5b5061060c61151a565b6040516104b1929190616379565b34801561062657600080fd5b506104a46117f6565b34801561063b57600080fd5b506106446117fc565b6040516104b19190616f2b565b34801561065d57600080fd5b506104f1611801565b34801561067257600080fd5b506104a4611807565b34801561068757600080fd5b5061069061180d565b6040516104b19190616ee1565b3480156106a957600080fd5b50610644611812565b3480156106be57600080fd5b5061060c611817565b3480156106d357600080fd5b506104a4611995565b3480156106e857600080fd5b506104f161199b565b3480156106fd57600080fd5b506104a46119a1565b34801561071257600080fd5b5061054061072136600461607f565b6119a7565b34801561073257600080fd5b506104a461074136600461607f565b6119dc565b34801561075257600080fd5b50610644611a2d565b34801561076757600080fd5b506104cf611a32565b34801561077c57600080fd5b506104a4611a37565b34801561079157600080fd5b506107a56107a036600461618a565b611a3d565b6040516104b196959493929190616324565b3480156107c357600080fd5b506104f1611aa1565b3480156107d857600080fd5b50610644611aa7565b3480156107ed57600080fd5b50610644611aac565b34801561080257600080fd5b506104f1611ab1565b34801561081757600080fd5b506104a4611ab7565b34801561082c57600080fd5b50610644611abd565b34801561084157600080fd5b506104a4611ac2565b34801561085657600080fd5b506104cf611ac8565b34801561086b57600080fd5b5061048d61087a3660046161dd565b611acd565b34801561088b57600080fd5b506104a4611b2e565b3480156108a057600080fd5b506104a4611b34565b3480156108b557600080fd5b506104a4611b3a565b3480156108ca57600080fd5b506104a46108d936600461607f565b611b40565b3480156108ea57600080fd5b5061048d611b80565b3480156108ff57600080fd5b50610644611c94565b34801561091457600080fd5b506104f1611c99565b34801561092957600080fd5b506104a4611c9f565b34801561093e57600080fd5b506104a4611ca4565b34801561095357600080fd5b506104f1611ca9565b34801561096857600080fd5b5061051e611caf565b34801561097d57600080fd5b50610540611cce565b34801561099257600080fd5b506104a4611cd7565b3480156109a757600080fd5b506104cf611a2d565b3480156109bc57600080fd5b5061048d6109cb36600461612e565b611ce0565b3480156109dc57600080fd5b506104a46109eb36600461607f565b61258c565b3480156109fc57600080fd5b506104a461259e565b348015610a1157600080fd5b50610a1a6125ab565b6040516104b19190616366565b348015610a3357600080fd5b506104a4612697565b348015610a4857600080fd5b506104a4611aa7565b348015610a5d57600080fd5b506104f161269c565b348015610a7257600080fd5b506104a46126a2565b348015610a8757600080fd5b506104a46126a7565b348015610a9c57600080fd5b506104a46126e6565b348015610ab157600080fd5b506104a46126f2565b348015610ac657600080fd5b506104f16126f8565b348015610adb57600080fd5b506104a46126fe565b348015610af057600080fd5b5061048d612703565b348015610b0557600080fd5b506104a46128b2565b348015610b1a57600080fd5b5061048d610b2936600461607f565b6128b8565b348015610b3a57600080fd5b506104cf6129c0565b61048d610b5136600461607f565b6129c5565b348015610b6257600080fd5b506104a4612c4d565b348015610b7757600080fd5b506104f1612c53565b348015610b8c57600080fd5b50610644611c9f565b348015610ba157600080fd5b506104f1612c59565b348015610bb657600080fd5b50610bca610bc536600461618a565b612c5f565b6040516104b193929190616ef9565b348015610be557600080fd5b506104f1612d21565b6000610bf933611b40565b9050600b8181548110610c0857fe5b600091825260209091206001601690920201015460ff16610c445760405162461bcd60e51b8152600401610c3b90616b99565b60405180910390fd5b6000610c4e6126a7565b9050610c5b338383612d27565b505050565b60095481565b606481565b61200181565b60005460609060ff16610c965760405162461bcd60e51b8152600401610c3b9061662d565b3361200014610cb75760405162461bcd60e51b8152600401610c3b90616d78565b600b54610d7557610cc6615d6b565b60015460005b81811015610d7157600b80546001810182556000919091528351600080516020616fa383398151915260169092029182019081556020808601516000805160206175d28339815191528401805460ff1916911515919091179055604086015180518794610d4d93600080516020616fc3833981519152909101920190615d9a565b506060820151610d639060038301906013615e14565b505050806001019050610ccc565b5050505b610d7d615e41565b6000610dbe85858080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250612f1392505050565b9150915080610dda57610dd160646130cf565b92505050610ea2565b815160009060ff16610dff57610df883602001518460400151613130565b9050610e6e565b825160ff1660011415610e6a57826020015151600114610e4457600080516020616f83833981519152604051610e3490616a80565b60405180910390a1506067610e65565b610df88360200151600081518110610e5857fe5b6020026020010151613d84565b610e6e565b5060655b63ffffffff8116610e935750506040805160008152602081019091529150610ea29050565b610e9c816130cf565b93505050505b9392505050565b60075460ff1681565b60035481565b606881565b334114610edc5760405162461bcd60e51b8152600401610c3b90616dc7565b6010544311610efd5760405162461bcd60e51b8152600401610c3b90616789565b60005460ff16610f1f5760405162461bcd60e51b8152600401610c3b9061662d565b600f54610f37576032600f5561100231601155611237565b60006110023168056bc75e2d63100000811115610f6657610f5f81606463ffffffff613efb16565b9150610faf565b601154811115610fa857610f5f6064610f9c600f54610f9060115486613f3d90919063ffffffff16565b9063ffffffff613f7f16565b9063ffffffff613efb16565b5050611237565b6040516309a99b4f60e41b815261100290639a99b4f090610fd6903090869060040161630b565b602060405180830381600087803b158015610ff057600080fd5b505af1158015611004573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061102891906161a2565b6110023160115591508161103d575050611237565b6000805b8481101561106b5785858281811061105557fe5b9050602002013582019150806001019050611041565b508061107957505050611237565b6000806000805b8981101561122f578489898381811061109557fe5b905060200201358802816110a557fe5b0493508a8a828181106110b457fe5b90506020020160208101906110c9919061607f565b6001600160a01b038116600090815260046020526040902054909350915081156111e55760006001808403815481106110fe57fe5b9060005260206000209060040201905080600201601c9054906101000a900460ff161561116b57836001600160a01b03167fb9c75cbbfde137c4281689580799ef5f52144e78858f776a5979b2b212137d858660405161115e9190616ef0565b60405180910390a26111df565b60035461117e908663ffffffff613fb916565b6003908155810154611196908663ffffffff613fb916565b60038201556040516001600160a01b038516907fcb0aad6cf9cd03bdf6137e359f541c42f38b39f007cae8e89e88aa7d8c6617b2906111d6908890616ef0565b60405180910390a25b50611227565b826001600160a01b03167fb9c75cbbfde137c4281689580799ef5f52144e78858f776a5979b2b212137d858560405161121e9190616ef0565b60405180910390a25b600101611080565b505050505050505b5050436010555050565b60015460009082106112555750600061130b565b60006001600160a01b03166001838154811061126d57fe5b60009182526020909120600490910201546001600160a01b0316148061129d5750600854158061129d5750600a54155b806112ac575060085460095410155b806112bd57506112bb82611310565b155b806112e657506000600b83815481106112d257fe5b906000526020600020906016020160000154115b806112fa575060016112f66125ab565b5111155b156113075750600061130b565b5060015b919050565b60015460009082106113245750600061130b565b600b548210611361576001828154811061133a57fe5b9060005260206000209060040201600201601c9054906101000a900460ff1615905061130b565b6001828154811061136e57fe5b9060005260206000209060040201600201601c9054906101000a900460ff161580156113bb5750600b82815481106113a257fe5b600091825260209091206001601690920201015460ff16155b92915050565b33611001146113e25760405162461bcd60e51b8152600401610c3b90616e98565b600b546114a0576113f1615d6b565b60015460005b8181101561149c57600b80546001810182556000919091528351600080516020616fa383398151915260169092029182019081556020808601516000805160206175d28339815191528401805460ff191691151591909117905560408601518051879461147893600080516020616fc3833981519152909101920190615d9a565b50606082015161148e9060038301906013615e14565b5050508060010190506113f7565b5050505b6001600160a01b038116600090815260046020526040902054806114c45750611517565b6001810390506000600b82815481106114d957fe5b600091825260209091206001601690920201015460ff1690506114fc8383613fde565b80156115055750805b15610c5b576009805460001901905550505b50565b60015460609081906000805b8281101561156d576001818154811061153b57fe5b9060005260206000209060040201600201601c9054906101000a900460ff16611565576001909101905b600101611526565b5060608160405190808252806020026020018201604052801561159a578160200160208202803683370190505b5090506060826040519080825280602002602001820160405280156115d357816020015b60608152602001906001900390816115be5790505b50600b546000945090915084141561174e5760005b8481101561174857600181815481106115fd57fe5b9060005260206000209060040201600201601c9054906101000a900460ff16611740576001818154811061162d57fe5b600091825260209091206004909102015483516001600160a01b039091169084908690811061165857fe5b60200260200101906001600160a01b031690816001600160a01b031681525050600b818154811061168557fe5b600091825260209182902060026016909202018101805460408051601f60001961010060018616150201909316949094049182018590048502840185019052808352919290919083018282801561171d5780601f106116f25761010080835404028352916020019161171d565b820191906000526020600020905b81548152906001019060200180831161170057829003601f168201915b505050505082858151811061172e57fe5b60209081029190910101526001909301925b6001016115e8565b506117ea565b60005b848110156117e8576001818154811061176657fe5b9060005260206000209060040201600201601c9054906101000a900460ff166117e0576001818154811061179657fe5b600091825260209091206004909102015483516001600160a01b03909116908490869081106117c157fe5b6001600160a01b03909216602092830291909101909101526001909301925b600101611751565b505b909450925050505b9091565b61271081565b600181565b61100181565b60085481565b603881565b600881565b600e54600c5460609182918061182b575060155b60606118356125ab565b9050606061184282614391565b9050828251116118595790945092506117f2915050565b8383835103101561186b578282510393505b83156118a15760c8430461188783838388880360008a8a6144ff565b61189f8383838888038989038a8b8b8b5103016144ff565b505b6060836040519080825280602002602001820160405280156118cd578160200160208202803683370190505b50905060608460405190808252806020026020018201604052801561190657816020015b60608152602001906001900390816118f15790505b50905060005b858110156119875784818151811061192057fe5b602002602001015183828151811061193457fe5b60200260200101906001600160a01b031690816001600160a01b03168152505083818151811061196057fe5b602002602001015182828151811061197457fe5b602090810291909101015260010161190c565b509096509450505050509091565b60065481565b61200081565b600f5481565b6001600160a01b038116600090815260046020526040812054806119cf57600091505061130b565b60001901610ea281611310565b6001600160a01b03811660009081526004602052604081205480611a0457600091505061130b565b600180820381548110611a1357fe5b906000526020600020906004020160030154915050919050565b600081565b606781565b60105481565b60018181548110611a4a57fe5b600091825260209091206004909102018054600182015460028301546003909301546001600160a01b0392831694509082169291821691600160a01b81046001600160401b031691600160e01b90910460ff169086565b61100581565b600281565b601081565b61100881565b6103e881565b600b81565b600c5481565b606681565b3361200014611aee5760405162461bcd60e51b8152600401610c3b90616d78565b7f41ce201247b6ceb957dcdb217d0b8acb50b9ea0e12af9af4f5e7f38902101605838383604051611b2193929190616f39565b60405180910390a1505050565b60025481565b60115481565b600a5481565b6001600160a01b03811660009081526004602052604081205480611b765760405162461bcd60e51b8152600401610c3b90616d00565b6000190192915050565b600b54611c3e57611b8f615d6b565b60015460005b81811015611c3a57600b80546001810182556000919091528351600080516020616fa383398151915260169092029182019081556020808601516000805160206175d28339815191528401805460ff1916911515919091179055604086015180518794611c1693600080516020616fc3833981519152909101920190615d9a565b506060820151611c2c9060038301906013615e14565b505050806001019050611b95565b5050505b600854611c4b5760036008555b600a54611c58576002600a555b6000611c6333611b40565b9050611c6e81611241565b611c8a5760405162461bcd60e51b8152600401610c3b90616a3d565b6115173382614656565b600981565b61100781565b600381565b60c881565b61100681565b6040518061062001604052806105ef8152602001616fe36105ef913981565b60005460ff1681565b6402540be40081565b60005460ff16611d025760405162461bcd60e51b8152600401610c3b9061662d565b3361100714611d235760405162461bcd60e51b8152600401610c3b90616b06565b611d8d84848080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525050604080518082019091526013815272065787069726554696d655365636f6e6447617606c1b602082015291506146ee9050565b15611e2a5760208114611db25760405162461bcd60e51b8152600401610c3b90616cba565b604080516020601f8401819004810282018101909252828152600091611df09185858083850183828082843760009201919091525061474792505050565b905060648110158015611e065750620186a08111155b611e225760405162461bcd60e51b8152600401610c3b906168e6565b600255612549565b611e8a84848080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250506040805180820190915260098152686275726e526174696f60b81b602082015291506146ee9050565b15611f265760208114611eaf5760405162461bcd60e51b8152600401610c3b906164b3565b604080516020601f8401819004810282018101909252828152600091611eed9185858083850183828082843760009201919091525061474792505050565b9050612710811115611f115760405162461bcd60e51b8152600401610c3b906167cb565b6006556007805460ff19166001179055612549565b611f9084848080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250506040805180820190915260138152726d61784e756d4f664d61696e7461696e696e6760681b602082015291506146ee9050565b1561202a5760208114611fb55760405162461bcd60e51b8152600401610c3b906164ea565b604080516020601f8401819004810282018101909252828152600091611ff39185858083850183828082843760009201919091525061474792505050565b600c5490915080612002575060155b8082106120215760405162461bcd60e51b8152600401610c3b9061683e565b50600855612549565b61209384848080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250506040805180820190915260128152716d61696e7461696e536c6173685363616c6560701b602082015291506146ee9050565b1561212c57602081146120b85760405162461bcd60e51b8152600401610c3b906165b3565b604080516020601f84018190048102820181019092528281526000916120f69185858083850183828082843760009201919091525061474792505050565b90506000811180156121085750600a81105b6121245760405162461bcd60e51b8152600401610c3b90616e14565b600a55612549565b6121a084848080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152505060408051808201909152601981527f6d61784e756d4f66576f726b696e6743616e6469646174657300000000000000602082015291506146ee9050565b1561222f57602081146121c55760405162461bcd60e51b8152600401610c3b90616567565b604080516020601f84018190048102820181019092528281526000916122039185858083850183828082843760009201919091525061474792505050565b9050600d548111156122275760405162461bcd60e51b8152600401610c3b9061695c565b600e55612549565b61229884848080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250506040805180820190915260128152716d61784e756d4f6643616e6469646174657360701b602082015291506146ee9050565b1561231a57602081146122bd5760405162461bcd60e51b8152600401610c3b90616b54565b604080516020601f84018190048102820181019092528281526000916122fb9185858083850183828082843760009201919091525061474792505050565b600d819055600e5490915081101561231457600d54600e555b50612549565b61237e84848080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152505060408051808201909152600d81526c6e756d4f66436162696e65747360981b602082015291506146ee9050565b1561242c57602081146123a35760405162461bcd60e51b8152600401610c3b906165f8565b604080516020601f84018190048102820181019092528281526000916123e19185858083850183828082843760009201919091525061474792505050565b9050600081116124035760405162461bcd60e51b8152600401610c3b9061669b565b60298111156124245760405162461bcd60e51b8152600401610c3b906166e3565b600c55612549565b61249684848080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152505060408051808201909152601381527266696e616c697479526577617264526174696f60681b602082015291506146ee9050565b1561253157602081146124bb5760405162461bcd60e51b8152600401610c3b90616c3d565b604080516020601f84018190048102820181019092528281526000916124f99185858083850183828082843760009201919091525061474792505050565b90506001811015801561250d575060648111155b6125295760405162461bcd60e51b8152600401610c3b906169cb565b600f55612549565b60405162461bcd60e51b8152600401610c3b90616e71565b7f6cdb0ac70ab7f2e2d035cca5be60d89906f2dede7648ddbd7402189c1eeed17a8484848460405161257e9493929190616481565b60405180910390a150505050565b60046020526000908152604090205481565b68056bc75e2d6310000081565b6001546060906000805b828110156125da576125c681611310565b156125d2578160010191505b6001016125b5565b50606081604051908082528060200260200182016040528015612607578160200160208202803683370190505b5090506000915060005b8381101561268e5761262281611310565b15612686576001818154811061263457fe5b600091825260209091206004909102015482516001600160a01b039091169083908590811061265f57fe5b60200260200101906001600160a01b031690816001600160a01b0316815250508260010192505b600101612611565b50925050505b90565b601581565b61100281565b603281565b60006126b16125ab565b519050600080600c54116126c65760156126ca565b600c545b9050808211156126d8578091505b816126e257600191505b5090565b67016345785d8a000081565b60055481565b61100381565b602981565b60005460ff16156127265760405162461bcd60e51b8152600401610c3b90616c06565b61272e615e41565b60006127546040518061062001604052806105ef8152602001616fe36105ef9139612f13565b91509150806127755760405162461bcd60e51b8152600401610c3b90616d37565b60005b82602001515181101561289a5760018360200151828151811061279757fe5b60209081029190910181015182546001818101855560009485528385208351600493840290910180546001600160a01b039283166001600160a01b03199182161782558587015182850180549185169183169190911790556040860151600283018054606089015160808a01511515600160e01b0260ff60e01b196001600160401b03909216600160a01b0267ffffffffffffffff60a01b199590981692909516919091179290921694909417161790915560a09093015160039093019290925591860151805191850193918590811061286d57fe5b602090810291909101810151516001600160a01b0316825281019190915260400160002055600101612778565b50506103e8600255506000805460ff19166001179055565b600d5481565b33611001146128d95760405162461bcd60e51b8152600401610c3b90616e98565b600b54612997576128e8615d6b565b60015460005b8181101561299357600b80546001810182556000919091528351600080516020616fa383398151915260169092029182019081556020808601516000805160206175d28339815191528401805460ff191691151591909117905560408601518051879461296f93600080516020616fc3833981519152909101920190615d9a565b5060608201516129859060038301906013615e14565b5050508060010190506128ee565b5050505b60006129a28261474c565b90506129ad81611241565b156129bc576129bc8282614656565b5050565b606581565b3341146129e45760405162461bcd60e51b8152600401610c3b90616dc7565b60005460ff16612a065760405162461bcd60e51b8152600401610c3b9061662d565b60003411612a265760405162461bcd60e51b8152600401610c3b9061692d565b6001600160a01b0381166000908152600460205260409020546007543491906103e89060ff1615612a5657506006545b600083118015612a665750600081115b15612b07576000612a83612710610f9c868563ffffffff613f7f16565b90508015612b055760405161dead9082156108fc029083906000818181858888f19350505050158015612aba573d6000803e3d6000fd5b507f627059660ea01c4733a328effb2294d2f86905bf806da763a89cee254de8bee581604051612aea9190616ef0565b60405180910390a1612b02848263ffffffff613f3d16565b93505b505b8115612c05576000600180840381548110612b1e57fe5b9060005260206000209060040201905080600201601c9054906101000a900460ff1615612b8b57846001600160a01b03167ff177e5d6c5764d79c32883ed824111d9b13f5668cf6ab1cc12dd36791dd955b485604051612b7e9190616ef0565b60405180910390a2612bff565b600354612b9e908563ffffffff613fb916565b6003908155810154612bb6908563ffffffff613fb916565b60038201556040516001600160a01b038616907f93a090ecc682c002995fad3c85b30c5651d7fd29b0be5da9d784a3302aedc05590612bf6908790616ef0565b60405180910390a25b50612c47565b836001600160a01b03167ff177e5d6c5764d79c32883ed824111d9b13f5668cf6ab1cc12dd36791dd955b484604051612c3e9190616ef0565b60405180910390a25b50505050565b600e5481565b61100081565b61dead81565b600b8181548110612c6c57fe5b6000918252602091829020601691909102018054600180830154600280850180546040805161010096831615969096026000190190911692909204601f810188900488028501880190925281845293965060ff90911694919291830182828015612d175780601f10612cec57610100808354040283529160200191612d17565b820191906000526020600020905b815481529060010190602001808311612cfa57829003601f168201915b5050505050905083565b61100481565b6000600a5460001480612d38575081155b80612d435750600954155b15612d5057506000610ea2565b60096000815460019003919050819055506000612d9b600a54610f9c85610f9c600b8981548110612d7d57fe5b6000918252602090912060169091020154439063ffffffff613f3d16565b90506000600b8581548110612dac57fe5b906000526020600020906016020160010160006101000a81548160ff0219169083151502179055506000806110016001600160a01b0316638256ace66040518163ffffffff1660e01b8152600401604080518083038186803b158015612e1157600080fd5b505afa158015612e25573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612e4991906161ba565b9150915060009350808310612ec357612e628787613fde565b506040516305bfb49960e41b815261100190635bfb499090612e88908a906004016162f7565b600060405180830381600087803b158015612ea257600080fd5b505af1158015612eb6573d6000803e3d6000fd5b5050505060019350612ed5565b818310612ed557612ed38761474c565b505b6040516001600160a01b038816907fb9d38178dc641ff1817967a63c9078cbcd955a9f1fcd75e0e3636de615d44d3b90600090a25050509392505050565b612f1b615e41565b6000612f25615e41565b612f2d615e65565b612f3e612f39866148ef565b614914565b90506000805b612f4d8361495e565b156130c15780612f7257612f68612f638461497f565b6149cd565b60ff1684526130b9565b80600114156130b4576060612f8e612f898561497f565b614a4d565b90508051604051908082528060200260200182016040528015612fcb57816020015b612fb8615e85565b815260200190600190039081612fb05790505b508560200181905250805160405190808252806020026020018201604052801561300957816020015b6060815260200190600190039081612ff45790505b50604086015260005b81518110156130a957613023615e85565b6060600061304385858151811061303657fe5b6020026020010151614b1e565b92509250925080613063578860009a509a505050505050505050506130ca565b828960200151858151811061307457fe5b6020026020010181905250818960400151858151811061309057fe5b6020026020010181905250505050806001019050613012565b5060019250506130b9565b6130c1565b600101612f44565b50919350909150505b915091565b604080516001808252818301909252606091829190816020015b60608152602001906001900390816130e957905050905061310f8363ffffffff16614c38565b8160008151811061311c57fe5b6020026020010181905250610ea281614c4b565b600060298351111561316757600080516020616f8383398151915260405161315790616740565b60405180910390a15060666113bb565b60005b83518110156132055760005b818110156131fc5784818151811061318a57fe5b6020026020010151600001516001600160a01b03168583815181106131ab57fe5b6020026020010151600001516001600160a01b031614156131f457600080516020616f838339815191526040516131e19061689b565b60405180910390a16066925050506113bb565b600101613176565b5060010161316a565b506060806132138585614cd5565b60015491935091506000908190815b818110156132985767016345785d8a00006001828154811061324057fe5b9060005260206000209060040201600301541061326257836001019350613290565b60006001828154811061327157fe5b9060005260206000209060040201600301541115613290578260010192505b600101613222565b506060836040519080825280602002602001820160405280156132c5578160200160208202803683370190505b5090506060846040519080825280602002602001820160405280156132f4578160200160208202803683370190505b509050606085604051908082528060200260200182016040528015613323578160200160208202803683370190505b509050606086604051908082528060200260200182016040528015613352578160200160208202803683370190505b5090506000606087604051908082528060200260200182016040528015613383578160200160208202803683370190505b5090506060886040519080825280602002602001820160405280156133b2578160200160208202803683370190505b509050600099506000985060006110046001600160a01b031663149d14d96040518163ffffffff1660e01b815260040160206040518083038186803b1580156133fa57600080fd5b505afa15801561340e573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061343291906161a2565b905067016345785d8a000081111561347d57600080516020616f8383398151915260405161345f90616bc5565b60405180910390a160689d50505050505050505050505050506113bb565b60005b898110156136ee5767016345785d8a00006001828154811061349e57fe5b9060005260206000209060040201600301541061362357600181815481106134c257fe5b906000526020600020906004020160020160009054906101000a90046001600160a01b0316898d815181106134f357fe5b60200260200101906001600160a01b031690816001600160a01b03168152505060006402540be4006001838154811061352857fe5b9060005260206000209060040201600301548161354157fe5b066001838154811061354f57fe5b9060005260206000209060040201600301540390506135778382613f3d90919063ffffffff16565b898e8151811061358357fe5b6020026020010181815250506001828154811061359c57fe5b906000526020600020906004020160020160009054906101000a90046001600160a01b0316878e815181106135cd57fe5b60200260200101906001600160a01b031690816001600160a01b03168152505081888e815181106135fa57fe5b6020908102919091010152613615868263ffffffff613fb916565b95508c6001019c50506136e6565b60006001828154811061363257fe5b90600052602060002090600402016003015411156136e6576001818154811061365757fe5b906000526020600020906004020160010160009054906101000a90046001600160a01b0316848c8151811061368857fe5b60200260200101906001600160a01b031690816001600160a01b031681525050600181815481106136b557fe5b906000526020600020906004020160030154838c815181106136d357fe5b6020026020010181815250508a6001019a505b600101613480565b5060008415613964576002546040516303702b2960e51b815261100491636e056520918891613728918e918e918d914201906004016163e9565b6020604051808303818588803b15801561374157600080fd5b505af193505050508015613772575060408051601f3d908101601f1916820190925261376f9181019061610e565b60015b6138e9576040516000815260443d101561378e57506000613829565b60046000803e60005160e01c6308c379a081146137af576000915050613829565b60043d036004833e81513d60248201116001600160401b03821117156137da57600092505050613829565b80830180516001600160401b038111156137fb576000945050505050613829565b8060208301013d860181111561381957600095505050505050613829565b601f01601f191660405250925050505b806138345750613876565b60019150857fa7cdeed7d0db45e3219a6e5d60838824c16f1d39991fcfe3f963029c844bf28082604051613868919061646e565b60405180910390a2506138e4565b3d8080156138a0576040519150601f19603f3d011682016040523d82523d6000602084013e6138a5565b606091505b5060019150857fbfa884552dd8921b6ce90bfe906952ae5b3b29be0cc1a951d4f62697635a3a45826040516138da919061646e565b60405180910390a2505b613964565b801561392b577fa217d08e65f80c73121cd9db834d81652d544bfbf452f6d04922b16c90a37b708660405161391e9190616ef0565b60405180910390a1613962565b857fa7cdeed7d0db45e3219a6e5d60838824c16f1d39991fcfe3f963029c844bf28060405161395990616530565b60405180910390a25b505b8015613b1a5760005b8751811015613b1857600088828151811061398457fe5b6020026020010151905060006001828154811061399d57fe5b60009182526020909120600160049092020181015481546001600160a01b03909116916108fc91859081106139ce57fe5b9060005260206000209060040201600301549081150290604051600060405180830381858888f1935050505090508015613a8a5760018281548110613a0f57fe5b60009182526020909120600160049092020181015481546001600160a01b03909116917f6c61d60f69a7beb3e1c80db7f39f37b208537cbb19da3174511b477812b2fc7d9185908110613a5e57fe5b906000526020600020906004020160030154604051613a7d9190616ef0565b60405180910390a2613b0e565b60018281548110613a9757fe5b60009182526020909120600160049092020181015481546001600160a01b03909116917f25d0ce7d2f0cec669a8c17efe49d195c13455bb8872b65fa610ac7f53fe4ca7d9185908110613ae657fe5b906000526020600020906004020160030154604051613b059190616ef0565b60405180910390a25b505060010161396d565b505b835115613c645760005b8451811015613c62576000858281518110613b3b57fe5b60200260200101516001600160a01b03166108fc868481518110613b5b57fe5b60200260200101519081150290604051600060405180830381858888f1935050505090508015613bf157858281518110613b9157fe5b60200260200101516001600160a01b03167f6c61d60f69a7beb3e1c80db7f39f37b208537cbb19da3174511b477812b2fc7d868481518110613bcf57fe5b6020026020010151604051613be49190616ef0565b60405180910390a2613c59565b858281518110613bfd57fe5b60200260200101516001600160a01b03167f25d0ce7d2f0cec669a8c17efe49d195c13455bb8872b65fa610ac7f53fe4ca7d868481518110613c3b57fe5b6020026020010151604051613c509190616ef0565b60405180910390a25b50600101613b24565b505b5050505050505050505050506000471115613ce0577f6ecc855f9440a9282c90913bbc91619fd44f5ec0b462af28d127b116f130aa4d47604051613ca89190616ef0565b60405180910390a1604051611002904780156108fc02916000818181858888f19350505050158015613cde573d6000803e3d6000fd5b505b60006003819055600555815115613cfb57613cfb8282614f0e565b6110016001600160a01b031663fc4333cd6040518163ffffffff1660e01b8152600401600060405180830381600087803b158015613d3857600080fd5b505af1158015613d4c573d6000803e3d6000fd5b50506040517fedd8d7296956dd970ab4de3f2fc03be2b0ffc615d20cd4c72c6e44f928630ebf925060009150a1506000949350505050565b80516001600160a01b0316600090815260046020526040812054801580613dd55750600180820381548110613db557fe5b9060005260206000209060040201600201601c9054906101000a900460ff165b15613e1b5782516040516001600160a01b03909116907fe209c46bebf57cf265d5d9009a00870e256d9150f3ed5281ab9d9eb3cec6e4be90600090a2600091505061130b565b600154600554600019820111801590613e715784516040516001600160a01b03909116907fe209c46bebf57cf265d5d9009a00870e256d9150f3ed5281ab9d9eb3cec6e4be90600090a26000935050505061130b565b600580546001908101909155805481906000198601908110613e8f57fe5b6000918252602082206002600490920201018054921515600160e01b0260ff60e01b199093169290921790915585516040516001600160a01b03909116917ff226e7d8f547ff903d9d419cf5f54e0d7d07efa9584135a53a057c5f1f27f49a91a2506000949350505050565b6000610ea283836040518060400160405280601a81526020017f536166654d6174683a206469766973696f6e206279207a65726f0000000000008152506156ed565b6000610ea283836040518060400160405280601e81526020017f536166654d6174683a207375627472616374696f6e206f766572666c6f770000815250615724565b600082613f8e575060006113bb565b82820282848281613f9b57fe5b0414610ea25760405162461bcd60e51b8152600401610c3b90616ac5565b600082820183811015610ea25760405162461bcd60e51b8152600401610c3b90616664565b60008060018381548110613fee57fe5b906000526020600020906004020160030154905060006001808054905003905060016140186125ab565b511161404d5760006001858154811061402d57fe5b9060005260206000209060040201600301819055506000925050506113bb565b846001600160a01b03167f3b6f9ef90462b512a1293ecec018670bf7b7f1876fb727590a8a6d7643130a70836040516140869190616ef0565b60405180910390a26001600160a01b038516600090815260046020526040812055835b6001546000190181101561427357600181600101815481106140c757fe5b9060005260206000209060040201600182815481106140e257fe5b60009182526020909120825460049092020180546001600160a01b03199081166001600160a01b0393841617825560018085015481840180548416918616919091179055600280860180549185018054909416919095161780835584546001600160401b03600160a01b91829004160267ffffffffffffffff60a01b1990911617808355935460ff600160e01b918290041615150260ff60e01b19909416939093179055600392830154920191909155600b8054909183019081106141a357fe5b9060005260206000209060160201600b82815481106141be57fe5b600091825260209091208254601690920201908155600180830154818301805460ff909216151560ff1990921691909117905560028084018054614215938386019390821615610100026000190190911604615eba565b5061422860038281019084016013615f2f565b5090505080600101600460006001848154811061424157fe5b600091825260208083206004909202909101546001600160a01b031683528201929092526040019020556001016140a9565b50600180548061427f57fe5b60008281526020812060046000199093019283020180546001600160a01b0319908116825560018201805490911690556002810180546001600160e81b0319169055600301559055600b8054806142d257fe5b60008281526020812060166000199093019283020181815560018101805460ff19169055906143046002830182615f59565b614312600383016000615f9d565b50509055600081838161432157fe5b04905080156143855760015460005b8181101561438257826001828154811061434657fe5b906000526020600020906004020160030154016001828154811061436657fe5b6000918252602090912060036004909202010155600101614330565b50505b50600195945050505050565b6001548151604080518281526020808402820101909152606092919083908280156143d057816020015b60608152602001906001900390816143bb5790505b50600b5490915083146143e757925061130b915050565b60005b828110156144f657600b60016004600089858151811061440657fe5b60200260200101516001600160a01b03166001600160a01b0316815260200190815260200160002054038154811061443a57fe5b600091825260209182902060026016909202018101805460408051601f6000196101006001861615020190931694909404918201859004850284018501905280835291929091908301828280156144d25780601f106144a7576101008083540402835291602001916144d2565b820191906000526020600020905b8154815290600101906020018083116144b557829003601f168201915b50505050508282815181106144e357fe5b60209081029190910101526001016143ea565b50949350505050565b60005b8281101561464c57600082878388016040516020016145229291906162e9565b6040516020818303038152906040528051906020012060001c8161454257fe5b06905080850182870114614643576000898388018151811061456057fe5b602002602001015190506060898489018151811061457a57fe5b602002602001015190508a8388018151811061459257fe5b60200260200101518b858a01815181106145a857fe5b60200260200101906001600160a01b031690816001600160a01b031681525050818b848901815181106145d757fe5b60200260200101906001600160a01b031690816001600160a01b031681525050898388018151811061460557fe5b60200260200101518a858a018151811061461b57fe5b6020026020010181905250808a8489018151811061463557fe5b602002602001018190525050505b50600101614502565b5050505050505050565b600980546001908101909155600b80548390811061467057fe5b906000526020600020906016020160010160006101000a81548160ff02191690831515021790555043600b82815481106146a657fe5b600091825260208220601690910201919091556040516001600160a01b038416917ff62981a567ec3cec866c6fa93c55bcdf841d6292d18b8d522ececa769375d82d91a25050565b60008160405160200161470191906162cd565b604051602081830303815290604052805190602001208360405160200161472891906162cd565b6040516020818303038152906040528051906020012014905092915050565b015190565b6001600160a01b038116600090815260046020526040812054806147755750600019905061130b565b60018103905060006001828154811061478a57fe5b90600052602060002090600402016003015490506000600183815481106147ad57fe5b6000918252602090912060036004909202010155600154604051600019909101906001600160a01b038616907f8cd4e147d8af98a9e3b6724021b8bf6aed2e5dac71c38f2dce8161b82585b25d90614806908590616ef0565b60405180910390a28061481e5782935050505061130b565b600081838161482957fe5b04905080156148e55760005b8481101561488757816001828154811061484b57fe5b906000526020600020906004020160030154016001828154811061486b57fe5b6000918252602090912060036004909202010155600101614835565b50600180549085015b818110156148e25782600182815481106148a657fe5b90600052602060002090600402016003015401600182815481106148c657fe5b6000918252602090912060036004909202010155600101614890565b50505b5091949350505050565b6148f7615fac565b506040805180820190915281518152602082810190820152919050565b61491c615e65565b61492582615750565b61492e57600080fd5b600061493d836020015161578a565b60208085015160408051808201909152868152920190820152915050919050565b6000614968615fac565b505080518051602091820151919092015191011190565b614987615fac565b6149908261495e565b61499957600080fd5b602082015160006149a9826157ed565b80830160209586015260408051808201909152908152938401919091525090919050565b8051600090158015906149e257508151602110155b6149eb57600080fd5b60006149fa836020015161578a565b90508083600001511015614a205760405162461bcd60e51b8152600401610c3b90616c83565b8251602080850151830180519284900392918310156144f657506020919091036101000a90049392505050565b6060614a5882615750565b614a6157600080fd5b6000614a6c836158ce565b9050606081604051908082528060200260200182016040528015614aaa57816020015b614a97615fac565b815260200190600190039081614a8f5790505b5090506000614abc856020015161578a565b60208601510190506000805b84811015614b1357614ad9836157ed565b9150604051806040016040528083815260200184815250848281518110614afc57fe5b602090810291909101015291810191600101614ac8565b509195945050505050565b614b26615e85565b60606000614b32615e85565b6060614b3c615e65565b614b4587614914565b90506000805b614b548361495e565b15614c295780614b7f57614b6f614b6a8461497f565b61592a565b6001600160a01b03168552614c21565b8060011415614ba757614b94614b6a8461497f565b6001600160a01b03166020860152614c21565b8060021415614bcf57614bbc614b6a8461497f565b6001600160a01b03166040860152614c21565b8060031415614bfb57614be4612f638461497f565b6001600160401b0316606086015260019150614c21565b8060041415614c1c57614c15614c108461497f565b615944565b9350614c21565b614c29565b600101614b4b565b50929791965091945092505050565b60606113bb614c46836159b4565b615a9a565b6060815160001415614c6c575060408051600081526020810190915261130b565b606082600081518110614c7b57fe5b602002602001015190506000600190505b8351811015614cbc57614cb282858381518110614ca557fe5b6020026020010151615aec565b9150600101614c8c565b50610ea2614ccf825160c060ff16615b69565b82615aec565b606080600080808080614ce66126a7565b6001549091505b8015614df457600181039250600b8381548110614d0657fe5b600091825260209091206001601690920201015460ff16614d2657614deb565b60018381548110614d3357fe5b60009182526020909120600490910201546001600160a01b03169450614d5a858484612d27565b9350831580614d6d575060018a51038610155b15614d7757614deb565b60005b8a51811015614de957856001600160a01b03168b8281518110614d9957fe5b6020026020010151600001516001600160a01b03161415614de15760018b8281518110614dc257fe5b6020908102919091010151901515608090910152600190960195614de9565b600101614d7a565b505b60001901614ced565b5084895103604051908082528060200260200182016040528015614e3257816020015b614e1f615e85565b815260200190600190039081614e175790505b50965084895103604051908082528060200260200182016040528015614e6c57816020015b6060815260200190600190039081614e575790505b5095506000915060005b8951811015614f0057898181518110614e8b57fe5b602002602001015160800151614ef857898181518110614ea757fe5b6020026020010151888481518110614ebb57fe5b6020026020010181905250888181518110614ed257fe5b6020026020010151878481518110614ee657fe5b60200260200101819052508260010192505b600101614e76565b5050505050505b9250929050565b600154825160005b8281101561502b576001614f28615e85565b60018381548110614f3557fe5b600091825260208083206040805160c08101825260049490940290910180546001600160a01b0390811685526001820154811693850193909352600281015492831691840191909152600160a01b82046001600160401b03166060840152600160e01b90910460ff16151560808301526003015460a082015291505b84811015614fff57878181518110614fc557fe5b6020026020010151600001516001600160a01b031682600001516001600160a01b03161415614ff75760009250614fff565b600101614fb1565b5081156150215780516001600160a01b03166000908152600460205260408120555b5050600101614f16565b50808211156150ea57805b828110156150e857600180548061504957fe5b60008281526020812060046000199093019283020180546001600160a01b0319908116825560018201805490911690556002810180546001600160e81b0319169055600301559055600b80548061509c57fe5b60008281526020812060166000199093019283020181815560018101805460ff19169055906150ce6002830182615f59565b6150dc600383016000615f9d565b50509055600101615036565b505b60008183106150f957816150fb565b825b905060005b8181101561549f576151ad86828151811061511757fe5b60200260200101516001838154811061512c57fe5b60009182526020918290206040805160c08101825260049390930290910180546001600160a01b0390811684526001820154811694840194909452600281015493841691830191909152600160a01b83046001600160401b03166060830152600160e01b90920460ff161515608082015260039091015460a0820152615c3b565b6153615780600101600460008884815181106151c557fe5b6020026020010151600001516001600160a01b03166001600160a01b031681526020019081526020016000208190555085818151811061520157fe5b60200260200101516001828154811061521657fe5b6000918252602091829020835160049092020180546001600160a01b039283166001600160a01b0319918216178255928401516001820180549184169185169190911790556040840151600282018054606087015160808801511515600160e01b0260ff60e01b196001600160401b03909216600160a01b0267ffffffffffffffff60a01b1995909716929097169190911792909216939093171692909217905560a09091015160039091015584518590829081106152d157fe5b6020026020010151600b82815481106152e657fe5b9060005260206000209060160201600201908051906020019061530a929190615d9a565b506000600b828154811061531a57fe5b60009182526020822060169190910201600101805460ff191692151592909217909155600b80548390811061534b57fe5b6000918252602090912060169091020155615497565b61542785828151811061537057fe5b6020026020010151600b838154811061538557fe5b600091825260209182902060026016909202018101805460408051601f60001961010060018616150201909316949094049182018590048502840185019052808352919290919083018282801561541d5780601f106153f25761010080835404028352916020019161541d565b820191906000526020600020905b81548152906001019060200180831161540057829003601f168201915b5050505050615cbc565b6154725784818151811061543757fe5b6020026020010151600b828154811061544c57fe5b90600052602060002090601602016002019080519060200190615470929190615d9a565b505b60006001828154811061548157fe5b9060005260206000209060040201600301819055505b600101615100565b5082821115615677576154b0615d6b565b835b83811015615674578581815181106154c657fe5b6020026020010151826040018190525060018782815181106154e457fe5b6020908102919091018101518254600181810185556000948552838520835160049093020180546001600160a01b039384166001600160a01b0319918216178255848601518284018054918616918316919091179055604080860151600284018054606089015160808a01511515600160e01b0260ff60e01b196001600160401b03909216600160a01b0267ffffffffffffffff60a01b1995909a1692909616919091179290921696909617169190911790935560a090930151600390930192909255600b8054928301815590935284516016909102600080516020616fa38339815191528101918255858301516000805160206175d28339815191528201805491151560ff199092169190911790559285015180518694929361561a93600080516020616fc383398151915201920190615d9a565b5060608201516156309060038301906013615e14565b505050806001016004600089848151811061564757fe5b602090810291909101810151516001600160a01b03168252810191909152604001600020556001016154b2565b50505b6000600981905560015493505b838110156156e5576000600b828154811061569b57fe5b60009182526020822060169190910201600101805460ff191692151592909217909155600b8054839081106156cc57fe5b6000918252602090912060169091020155600101615684565b505050505050565b6000818361570e5760405162461bcd60e51b8152600401610c3b919061646e565b50600083858161571a57fe5b0495945050505050565b600081848411156157485760405162461bcd60e51b8152600401610c3b919061646e565b505050900390565b80516000906157615750600061130b565b6020820151805160001a9060c08210156157805760009250505061130b565b5060019392505050565b8051600090811a60808110156157a457600091505061130b565b60b88110806157bf575060c081108015906157bf575060f881105b156157ce57600191505061130b565b60c08110156157e25760b51901905061130b565b60f51901905061130b565b80516000908190811a608081101561580857600191506158c7565b60b881101561581d57607e19810191506158c7565b60c081101561586e57600060b78203600186019550806020036101000a8651049150600181018201935050808310156158685760405162461bcd60e51b8152600401610c3b90616a12565b506158c7565b60f88110156158835760be19810191506158c7565b600060f78203600186019550806020036101000a8651049150600181018201935050808310156158c55760405162461bcd60e51b8152600401610c3b90616a12565b505b5092915050565b80516000906158df5750600061130b565b600080905060006158f3846020015161578a565b602085015185519181019250015b8082101561592157615912826157ed565b82019150826001019250615901565b50909392505050565b805160009060151461593b57600080fd5b6113bb826149cd565b805160609061595257600080fd5b6000615961836020015161578a565b83516040805191839003808352601f19601f8201168301602001909152919250606090828015615998576020820181803683370190505b50905060008160200190506144f6848760200151018285615d20565b604080516020808252818301909252606091829190602082018180368337505050602081018490529050600067ffffffffffffffff1984166159f857506018615a1c565b6fffffffffffffffffffffffffffffffff198416615a1857506010615a1c565b5060005b6020811015615a5257818181518110615a3157fe5b01602001516001600160f81b03191615615a4a57615a52565b600101615a1c565b60008160200390506060816040519080825280601f01601f191660200182016040528015615a87576020820181803683370190505b5080830196909652508452509192915050565b606081516001148015615acc5750607f60f81b82600081518110615aba57fe5b01602001516001600160f81b03191611155b15615ad857508061130b565b6113bb615aea8351608060ff16615b69565b835b6060806040519050835180825260208201818101602087015b81831015615b1d578051835260209283019201615b05565b50855184518101855292509050808201602086015b81831015615b4a578051835260209283019201615b32565b508651929092011591909101601f01601f191660405250905092915050565b6060680100000000000000008310615b935760405162461bcd60e51b8152600401610c3b90616816565b60408051600180825281830190925260609160208201818036833701905050905060378411615bed5782840160f81b81600081518110615bcf57fe5b60200101906001600160f81b031916908160001a90535090506113bb565b6060615bf8856159b4565b90508381510160370160f81b82600081518110615c1157fe5b60200101906001600160f81b031916908160001a905350615c328282615aec565b95945050505050565b805182516000916001600160a01b039182169116148015615c75575081602001516001600160a01b031683602001516001600160a01b0316145b8015615c9a575081604001516001600160a01b031683604001516001600160a01b0316145b8015610ea25750506060908101519101516001600160401b0390811691161490565b815181516000916001918114808314615cd85760009250615d16565b600160208701838101602088015b600284838510011415615d11578051835114615d055760009650600093505b60209283019201615ce6565b505050505b5090949350505050565b80615d2a57610c5b565b5b60208110615d4a578251825260209283019290910190601f1901615d2b565b915181516020939093036101000a6000190180199091169216919091179052565b60405180608001604052806000815260200160001515815260200160608152602001615d95615fc6565b905290565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f10615ddb57805160ff1916838001178555615e08565b82800160010185558215615e08579182015b82811115615e08578251825591602001919060010190615ded565b506126e2929150615fe5565b8260138101928215615e085791602002820182811115615e08578251825591602001919060010190615ded565b6040518060600160405280600060ff16815260200160608152602001606081525090565b6040518060400160405280615e78615fac565b8152602001600081525090565b6040805160c081018252600080825260208201819052918101829052606081018290526080810182905260a081019190915290565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f10615ef35780548555615e08565b82800160010185558215615e0857600052602060002091601f016020900482015b82811115615e08578254825591600101919060010190615f14565b8260138101928215615e085791820182811115615e08578254825591600101919060010190615f14565b50805460018160011615610100020316600290046000825580601f10615f7f5750611517565b601f0160209004906000526020600020908101906115179190615fe5565b50611517906013810190615fe5565b604051806040016040528060008152602001600081525090565b6040518061026001604052806013906020820280368337509192915050565b61269491905b808211156126e25760008155600101615feb565b60008083601f840112616010578182fd5b5081356001600160401b03811115616026578182fd5b6020830191508360208083028501011115614f0757600080fd5b60008083601f840112616051578182fd5b5081356001600160401b03811115616067578182fd5b602083019150836020828501011115614f0757600080fd5b600060208284031215616090578081fd5b81356001600160a01b0381168114610ea2578182fd5b600080600080604085870312156160bb578283fd5b84356001600160401b03808211156160d1578485fd5b6160dd88838901615fff565b909650945060208701359150808211156160f5578384fd5b5061610287828801615fff565b95989497509550505050565b60006020828403121561611f578081fd5b81518015158114610ea2578182fd5b60008060008060408587031215616143578384fd5b84356001600160401b0380821115616159578586fd5b61616588838901616040565b9096509450602087013591508082111561617d578384fd5b5061610287828801616040565b60006020828403121561619b578081fd5b5035919050565b6000602082840312156161b3578081fd5b5051919050565b600080604083850312156161cc578182fd5b505080516020909101519092909150565b6000806000604084860312156161f1578283fd5b833560ff81168114616201578384fd5b925060208401356001600160401b0381111561621b578283fd5b61622786828701616040565b9497909650939450505050565b6000815180845260208085019450808401835b8381101561626c5781516001600160a01b031687529582019590820190600101616247565b509495945050505050565b60008284528282602086013780602084860101526020601f19601f85011685010190509392505050565b600081518084526162b9816020860160208601616f56565b601f01601f19169290920160200192915050565b600082516162df818460208701616f56565b9190910192915050565b918252602082015260400190565b6001600160a01b0391909116815260200190565b6001600160a01b03929092168252602082015260400190565b6001600160a01b03968716815294861660208601529290941660408401526001600160401b03166060830152911515608082015260a081019190915260c00190565b600060208252610ea26020830184616234565b60006040825261638c6040830185616234565b602083820381850152818551808452828401915082838202850101838801865b838110156163da57601f198784030185526163c88383516162a1565b948601949250908501906001016163ac565b50909998505050505050505050565b6000608082526163fc6080830187616234565b828103602084810191909152865180835287820192820190845b8181101561643257845183529383019391830191600101616416565b505084810360408601526164468188616234565b93505050506001600160401b038316606083015295945050505050565b901515815260200190565b600060208252610ea260208301846162a1565b600060408252616495604083018688616277565b82810360208401526164a8818587616277565b979650505050505050565b6020808252601c908201527f6c656e677468206f66206275726e526174696f206d69736d6174636800000000604082015260600190565b60208082526026908201527f6c656e677468206f66206d61784e756d4f664d61696e7461696e696e67206d696040820152650e6dac2e8c6d60d31b606082015260800190565b6020808252601b908201527f6261746368207472616e736665722072657475726e2066616c73650000000000604082015260600190565b6020808252602c908201527f6c656e677468206f66206d61784e756d4f66576f726b696e6743616e6469646160408201526b0e8cae640dad2e6dac2e8c6d60a31b606082015260800190565b60208082526025908201527f6c656e677468206f66206d61696e7461696e536c6173685363616c65206d69736040820152640dac2e8c6d60db1b606082015260800190565b6020808252818101527f6c656e677468206f66206e756d4f66436162696e657473206d69736d61746368604082015260600190565b60208082526019908201527f74686520636f6e7472616374206e6f7420696e69742079657400000000000000604082015260600190565b6020808252601b908201527f536166654d6174683a206164646974696f6e206f766572666c6f770000000000604082015260600190565b60208082526028908201527f746865206e756d4f66436162696e657473206d75737420626520677265617465604082015267072207468616e20360c41b606082015260800190565b60208082526039908201527f746865206e756d4f66436162696e657473206d757374206265206c657373207460408201527f68616e204d41585f4e554d5f4f465f56414c494441544f525300000000000000606082015260800190565b60208082526029908201527f746865206e756d626572206f662076616c696461746f727320657863656564206040820152681d1a19481b1a5b5a5d60ba1b606082015260800190565b60208082526022908201527f63616e206e6f7420646f207468697320747769636520696e206f6e6520626c6f604082015261636b60f01b606082015260800190565b6020808252602b908201527f746865206275726e526174696f206d757374206265206e6f206772656174657260408201526a0207468616e2031303030360ac1b606082015260800190565b6020808252600e908201526d696e70757420746f6f206c6f6e6760901b604082015260600190565b60208082526037908201527f746865206d61784e756d4f664d61696e7461696e696e67206d7573742062652060408201527f6c657373207468616e206e756d4f66436162696e657473000000000000000000606082015260800190565b6020808252602b908201527f6475706c696361746520636f6e73656e7375732061646472657373206f66207660408201526a185b1a59185d1bdc94d95d60aa1b606082015260800190565b60208082526027908201527f7468652065787069726554696d655365636f6e64476170206973206f7574206f604082015266662072616e676560c81b606082015260800190565b6020808252601590820152746465706f7369742076616c7565206973207a65726f60581b604082015260600190565b60208082526049908201527f746865206d61784e756d4f66576f726b696e6743616e64696461746573206d7560408201527f7374206265206e6f742067726561746572207468616e206d61784e756d4f6643606082015268616e6469646174657360b81b608082015260a00190565b60208082526027908201527f7468652066696e616c697479526577617264526174696f206973206f7574206f604082015266662072616e676560c81b606082015260800190565b6020808252601190820152706164646974696f6e206f766572666c6f7760781b604082015260600190565b60208082526023908201527f63616e206e6f7420656e7465722054656d706f72617279204d61696e74656e616040820152626e636560e81b606082015260800190565b60208082526025908201527f6c656e677468206f66206a61696c2076616c696461746f7273206d757374206260408201526465206f6e6560d81b606082015260800190565b60208082526021908201527f536166654d6174683a206d756c7469706c69636174696f6e206f766572666c6f6040820152607760f81b606082015260800190565b6020808252602e908201527f746865206d6573736167652073656e646572206d75737420626520676f76657260408201526d1b985b98d94818dbdb9d1c9858dd60921b606082015260800190565b60208082526025908201527f6c656e677468206f66206d61784e756d4f6643616e64696461746573206d69736040820152640dac2e8c6d60db1b606082015260800190565b6020808252601290820152716e6f7420696e206d61696e74656e616e636560701b604082015260600190565b60208082526021908201527f666565206973206c6172676572207468616e2044555354595f494e434f4d494e6040820152604760f81b606082015260800190565b60208082526019908201527f74686520636f6e747261637420616c726561647920696e697400000000000000604082015260600190565b60208082526026908201527f6c656e677468206f662066696e616c697479526577617264526174696f206d696040820152650e6dac2e8c6d60d31b606082015260800190565b6020808252601a908201527f6c656e677468206973206c657373207468616e206f6666736574000000000000604082015260600190565b60208082526026908201527f6c656e677468206f662065787069726554696d655365636f6e64476170206d696040820152650e6dac2e8c6d60d31b606082015260800190565b60208082526017908201527f6f6e6c792063757272656e742076616c696461746f7273000000000000000000604082015260600190565b60208082526021908201527f6661696c656420746f20706172736520696e69742076616c696461746f7253656040820152601d60fa1b606082015260800190565b6020808252602f908201527f746865206d6573736167652073656e646572206d7573742062652063726f737360408201526e0818da185a5b8818dbdb9d1c9858dd608a1b606082015260800190565b6020808252602d908201527f746865206d6573736167652073656e646572206d75737420626520746865206260408201526c3637b1b590383937b23ab1b2b960991b606082015260800190565b6020808252603e908201527f746865206d61696e7461696e536c6173685363616c65206d757374206265206760408201527f726561746572207468616e203020616e64206c657373207468616e2031300000606082015260800190565b6020808252600d908201526c756e6b6e6f776e20706172616d60981b604082015260600190565b60208082526029908201527f746865206d6573736167652073656e646572206d75737420626520736c6173686040820152680818dbdb9d1c9858dd60ba1b606082015260800190565b61ffff91909116815260200190565b90815260200190565b6000848252831515602083015260606040830152615c3260608301846162a1565b63ffffffff91909116815260200190565b60ff91909116815260200190565b600060ff8516825260406020830152615c32604083018486616277565b60005b83811015616f71578181015183820152602001616f59565b83811115612c47575050600091015256fe70e72399380dcfb0338abc03dc8d47f9f470ada8e769c9a78d644ea97385ecb20175b7a638427703f0dbe7bb9bbf987a2551717b34e79f33b5b1008d1fa01db90175b7a638427703f0dbe7bb9bbf987a2551717b34e79f33b5b1008d1fa01dbbf905ec80f905e8f846942a7cdd959bfe8d9487b2a43b33565295a698f7e294b6a7edd747c0554875d3fc531d19ba1497992c5e941ff80f3f7f110ffd8920a3ac38fdef318fe94a3f86048c27395000f846946488aa4d1955ee33403f8ccb1d4de5fb97c7ade294220f003d8bdfaadf52aa1e55ae4cc485e6794875941a87e90e440a39c99aa9cb5cea0ad6a3f0b2407b86048c27395000f846949ef9f4360c606c7ab4db26b016007d3ad0ab86a0946103af86a874b705854033438383c82575f25bc29418e2db06cbff3e3c5f856410a1838649e760175786048c27395000f84694ee01c3b1283aa067c58eab4709f85e99d46de5fe94ee4b9bfb1871c64e2bcabb1dc382dc8b7c4218a29415904ab26ab0e99d70b51c220ccdcccabee6e29786048c27395000f84694685b1ded8013785d6623cc18d214320b6bb6475994a20ef4e5e4e7e36258dbf51f4d905114cb1b34bc9413e39085dc88704f4394d35209a02b1a9520320c86048c27395000f8469478f3adfc719c99674c072166708589033e2d9afe9448a30d5eaa7b64492a160f139e2da2800ec3834e94055838358c29edf4dcc1ba1985ad58aedbb6be2b86048c27395000f84694c2be4ec20253b8642161bc3f444f53679c1f3d479466f50c616d737e60d7ca6311ff0d9c434197898a94d1d678a2506eeaa365056fe565df8bc8659f28b086048c27395000f846942f7be8361c80a4c1e7e9aaf001d0877f1cfde218945f93992ac37f3e61db2ef8a587a436a161fd210b94ecbc4fb1a97861344dad0867ca3cba2b860411f086048c27395000f84694ce2fd7544e0b2cc94692d4a704debef7bcb613289444abc67b4b2fba283c582387f54c9cba7c34bafa948acc2ab395ded08bb75ce85bf0f95ad2abc51ad586048c27395000f84694b8f7166496996a7da21cf1f1b04d9b3e26a3d077946770572763289aac606e4f327c2f6cc1aa3b3e3b94882d745ed97d4422ca8da1c22ec49d880c4c097286048c27395000f846942d4c407bbe49438ed859fe965b140dcf1aab71a9943ad0939e120f33518fbba04631afe7a3ed6327b194b2bbb170ca4e499a2b0f3cc85ebfa6e8c4dfcbea86048c27395000f846946bbad7cf34b5fa511d8e963dbba288b1960e75d694853b0f6c324d1f4e76c8266942337ac1b0af1a229442498946a51ca5924552ead6fc2af08b94fcba648601d1a94a2000f846944430b3230294d12c6ab2aac5c2cd68e80b16b581947b107f4976a252a6939b771202c28e64e03f52d694795811a7f214084116949fc4f53cedbf189eeab28601d1a94a2000f84694ea0a6e3c511bbd10f4519ece37dc24887e11b55d946811ca77acfb221a49393c193f3a22db829fcc8e9464feb7c04830dd9ace164fc5c52b3f5a29e5018a8601d1a94a2000f846947ae2f5b9e386cd1b50a4550696d957cb4900f03a94e83bcc5077e6b873995c24bac871b5ad856047e19464e48d4057a90b233e026c1041e6012ada897fe88601d1a94a2000f8469482012708dafc9e1b880fd083b32182b869be8e09948e5adc73a2d233a1b496ed3115464dd6c7b887509428b383d324bc9a37f4e276190796ba5a8947f5ed8601d1a94a2000f8469422b81f8e175ffde54d797fe11eb03f9e3bf75f1d94a1c3ef7ca38d8ba80cce3bfc53ebd2903ed21658942767f7447f7b9b70313d4147b795414aecea54718601d1a94a2000f8469468bf0b8b6fb4e317a0f9d6f03eaf8ce6675bc60d94675cfe570b7902623f47e7f59c9664b5f5065dcf94d84f0d2e50bcf00f2fc476e1c57f5ca2d57f625b8601d1a94a2000f846948c4d90829ce8f72d0163c1d5cf348a862d5506309485c42a7b34309bee2ed6a235f86d16f059deec5894cc2cedc53f0fa6d376336efb67e43d167169f3b78601d1a94a2000f8469435e7a025f4da968de7e4d7e4004197917f4070f194b1182abaeeb3b4d8eba7e6a4162eac7ace23d57394c4fd0d870da52e73de2dd8ded19fe3d26f43a1138601d1a94a2000f84694d6caa02bbebaebb5d7e581e4b66559e635f805ff94c07335cf083c1c46a487f0325769d88e163b653694efaff03b42e41f953a925fc43720e45fb61a19938601d1a94a20000175b7a638427703f0dbe7bb9bbf987a2551717b34e79f33b5b1008d1fa01dbaa26469706673582212206cf6e773ca0b0d999abe4e586cd00abd836c1f2e74f76626269d55c8fc09634364736f6c63430006040033", + }, + { + ContractAddr: SlashContract, + CommitUrl: "https://github.com/bnb-chain/bsc-genesis-contract/commit/b144718e94d7a1ebb24a7103202300f08826f369", + Code: "608060405234801561001057600080fd5b506004361061027f5760003560e01c80637942fd051161015c578063c80d4b8f116100ce578063dc927faf11610087578063dc927faf146104ad578063e1c7392a146104b5578063f9a2bbc7146104bd578063fc3e5908146104c5578063fc4333cd146104cd578063fd6a6879146104d55761027f565b8063c80d4b8f1461045c578063c81b166214610464578063c8509d811461046c578063c96be4cb1461047f578063cc844b7314610492578063d2a42e4b146104a55761027f565b80639dc09262116101205780639dc0926214610421578063a1a11bf514610429578063a78abc1614610431578063ab51bb9614610439578063ac0af62914610441578063ac431751146104495761027f565b80637942fd05146103ee5780638256ace6146103f6578063831d65d1146103fe57806396713da9146104115780639bc8e4f2146104195761027f565b8063493279b1116101f557806362b72cf5116101b957806362b72cf5146103be5780636e47b482146103c657806370fd5bad146103ce578063718a8aa8146103d657806375d47a0a146103de5780637912a65d146103e65761027f565b8063493279b11461037c5780634bf6c8821461039157806351e8067214610399578063567a372d146103a15780635bfb4990146103a95761027f565b806335aa2e441161024757806335aa2e441461030e57806337c8dab914610321578063389f4f71146103425780633a63f4b1146103575780633dffc3871461035f57806343756e5c146103745761027f565b80630bee7a67146102845780630e2374a5146102a25780631182b875146102b757806322d1e80b146102d757806323bac5a2146102ec575b600080fd5b61028c6104dd565b60405161029991906132a4565b60405180910390f35b6102aa6104e2565b6040516102999190612b82565b6102ca6102c5366004612ab8565b6104e8565b6040516102999190612bba565b6102df61054e565b6040516102999190612baf565b6102ff6102fa366004612866565b610557565b6040516102999392919061328c565b6102aa61031c366004612a88565b61057a565b61033461032f366004612866565b6105a1565b60405161029992919061327e565b61034a6105f8565b6040516102999190613254565b61034a6105fe565b610367610604565b60405161029991906132b5565b6102aa610609565b61038461060f565b6040516102999190613245565b610367610614565b6102aa610619565b61034a61061f565b6103bc6103b7366004612866565b610625565b005b61034a6106d0565b6102aa6106d6565b6103676106dc565b6103676106e1565b6102aa6106e6565b61034a6106ec565b6103676106f1565b6103346106f6565b6103bc61040c366004612ab8565b610700565b610367610812565b61034a610817565b6102aa610822565b6102aa610828565b6102df61082e565b61028c610837565b61034a61083c565b6103bc61045736600461296c565b610841565b61034a610ce0565b6102aa610ce5565b6103bc61047a366004612ab8565b610ceb565b6103bc61048d366004612866565b610d5c565b6103bc6104a03660046129d5565b61114d565b61034a61169a565b6102aa61169f565b6103bc6116a5565b6102aa6116e1565b6103676116e7565b6103bc6116ec565b6102aa611b35565b606481565b61200181565b606033612000146105145760405162461bcd60e51b815260040161050b906130cb565b60405180910390fd5b60005460ff166105365760405162461bcd60e51b815260040161050b90612c9b565b60405162461bcd60e51b815260040161050b9061318e565b60075460ff1681565b600260208190526000918252604090912080546001820154919092015460ff1683565b6001818154811061058757fe5b6000918252602090912001546001600160a01b0316905081565b6000806105ac61264d565b5050506001600160a01b0316600090815260026020818152604092839020835160608101855281548082526001830154938201849052919093015460ff16151592909301919091529091565b60055481565b60065481565b600181565b61100181565b603881565b600881565b61200081565b60045481565b33611000146106465760405162461bcd60e51b815260040161050b90612edf565b60005460ff166106685760405162461bcd60e51b815260040161050b90612c9b565b61200063f7a251d7600b61067b84611b3b565b60006040518463ffffffff1660e01b815260040161069b939291906132c3565b600060405180830381600087803b1580156106b557600080fd5b505af11580156106c9573d6000803e3d6000fd5b5050505050565b60035481565b61100581565b600281565b601081565b61100881565b603281565b600b81565b6004546005549091565b33612000146107215760405162461bcd60e51b815260040161050b906130cb565b60005460ff166107435760405162461bcd60e51b815260040161050b90612c9b565b61074b612670565b600061078c84848080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250611c0d92505050565b9150915080156107d35781516040517f7f0956d47419b9525356e7111652b653b530ec6f5096dccc04589bc38e629967916107c6916132a4565b60405180910390a16106c9565b81516040517f7d45f62d17443dd4547bca8a8112c60e2385669318dc300ec61a5d2492f262e791610803916132a4565b60405180910390a15050505050565b600981565b662386f26fc1000081565b61100781565b61100681565b60005460ff1681565b600081565b600481565b60005460ff166108635760405162461bcd60e51b815260040161050b90612c9b565b33611007146108845760405162461bcd60e51b815260040161050b90612f88565b6108ef84848080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250506040805180820190915260148152731b5a5cd9195b59585b9bdc951a1c995cda1bdb1960621b60208201529150611c8d9050565b1561098a57602081146109145760405162461bcd60e51b815260040161050b90612e6b565b604080516020601f840181900481028201810190925282815260009161095291858580838501838280828437600092019190915250611ce792505050565b905060018110158015610966575060055481105b6109825760405162461bcd60e51b815260040161050b90613086565b600455610c9d565b6109f084848080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152505060408051808201909152600f81526e19995b1bdb9e551a1c995cda1bdb19608a1b60208201529150611c8d9050565b15610a8c5760208114610a155760405162461bcd60e51b815260040161050b90612fd6565b604080516020601f8401819004810282018101909252828152600091610a5391858580838501838280828437600092019190915250611ce792505050565b90506103e88111158015610a68575060045481115b610a845760405162461bcd60e51b815260040161050b90612d09565b600555610c9d565b610b0084848080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152505060408051808201909152601881527f66696e616c697479536c617368526577617264526174696f000000000000000060208201529150611c8d9050565b15610b9a5760208114610b255760405162461bcd60e51b815260040161050b906131c5565b604080516020601f8401819004810282018101909252828152600091610b6391858580838501838280828437600092019190915250611ce792505050565b9050600a8110158015610b765750606481105b610b925760405162461bcd60e51b815260040161050b90612e1f565b600655610c9d565b610c0e84848080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152505060408051808201909152601881527f656e61626c654d616c6963696f7573566f7465536c617368000000000000000060208201529150611c8d9050565b15610c855760208114610c335760405162461bcd60e51b815260040161050b90612d3e565b604080516020601f8401819004810282018101909252828152610c6f9190848480838501838280828437600092019190915250611cec92505050565b6007805460ff1916911515919091179055610c9d565b60405162461bcd60e51b815260040161050b90613167565b7f6cdb0ac70ab7f2e2d035cca5be60d89906f2dede7648ddbd7402189c1eeed17a84848484604051610cd29493929190612bcd565b60405180910390a150505050565b609681565b61100281565b3361200014610d0c5760405162461bcd60e51b815260040161050b906130cb565b60005460ff16610d2e5760405162461bcd60e51b815260040161050b90612c9b565b6040517f07db600eebe2ac176be8dcebad61858c245a4961bb32ca2aa3d159b09aa0810e90600090a1505050565b334114610d7b5760405162461bcd60e51b815260040161050b9061311a565b60005460ff16610d9d5760405162461bcd60e51b815260040161050b90612c9b565b6003544311610dbe5760405162461bcd60e51b815260040161050b90613210565b3a15610ddc5760405162461bcd60e51b815260040161050b90612f5a565b60405163155853f360e21b8152611000906355614fcc90610e01908490600401612b82565b60206040518083038186803b158015610e1957600080fd5b505afa158015610e2d573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610e51919061294c565b610e5a57611146565b610e6261264d565b506001600160a01b0381166000908152600260208181526040928390208351606081018552815481526001820154928101929092529091015460ff161580159282019290925290610ebd576020810180516001019052610f16565b60016040820181905260208201819052805480820182556000919091527fb10e2d527612073b26eecdfd717e6a320cf44b4afac2b0732d9fcbe2b7fa0cf60180546001600160a01b0319166001600160a01b0384161790555b438152600554602082015181610f2857fe5b0661107457600060208201526040516335409f7f60e01b8152611000906335409f7f90610f59908590600401612b82565b600060405180830381600087803b158015610f7357600080fd5b505af1158015610f87573d6000803e3d6000fd5b505050506120006001600160a01b031663f7a251d7600b610fa785611b3b565b60006040518463ffffffff1660e01b8152600401610fc7939291906132c3565b600060405180830381600087803b158015610fe157600080fd5b505af1925050508015610ff2575060015b61106f573d808015611020576040519150601f19603f3d011682016040523d82523d6000602084013e611025565b606091505b50826001600160a01b03167fd7bc86ff5d08c8ab043edec743302aba2520e6635172a428bc956721db9e2d1c83602001518360405161106592919061325d565b60405180910390a2505b6110e0565b60045481602001518161108357fe5b066110e0576040516375abf10160e11b81526110009063eb57e202906110ad908590600401612b82565b600060405180830381600087803b1580156110c757600080fd5b505af11580156110db573d6000803e3d6000fd5b505050505b6001600160a01b0382166000818152600260208181526040808420865181559186015160018301558581015191909201805460ff1916911515919091179055517fddb6012116e51abf5436d956a4f0ebd927e92c576ff96d7918290c8782291e3e9190a2505b5043600355565b60005460ff1661116f5760405162461bcd60e51b815260040161050b90612c9b565b604051630a83aaa960e31b81526110069063541d554890611194903390600401612b82565b60206040518083038186803b1580156111ac57600080fd5b505afa1580156111c0573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906111e4919061294c565b6112005760405162461bcd60e51b815260040161050b90612bff565b60075460ff166112225760405162461bcd60e51b815260040161050b90612c66565b60065461122f5760146006555b8051514361010090910111801561125157504381602001516000015161010001115b61126d5760405162461bcd60e51b815260040161050b90612c36565b80602001516020015181600001516020015114801561129b5750806020015160600151816000015160600151145b156112b85760405162461bcd60e51b815260040161050b90612eb2565b8051604081015190511080156112d75750602081015160408101519051105b6112f35760405162461bcd60e51b815260040161050b90612de8565b6020810151518151511080156113185750806000015160400151816020015160400151105b8061134357508051516020820151511080156113435750806020015160400151816000015160400151105b8061135d5750806020015160400151816000015160400151145b6113795760405162461bcd60e51b815260040161050b90612cd2565b61138b81600001518260400151611d14565b80156113a457506113a481602001518260400151611d14565b6113c05760405162461bcd60e51b815260040161050b90612d89565b6060806110006001600160a01b0316633b071dcc6040518163ffffffff1660e01b815260040160006040518083038186803b1580156113fe57600080fd5b505afa158015611412573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f1916820160405261143a9190810190612889565b9150915060005b81518110156115775761146b82828151811061145957fe5b60200260200101518560400151611eec565b1561156f576006546040516309a99b4f60e41b815260646110028031909302049190639a99b4f0906114a39033908590600401612b96565b602060405180830381600087803b1580156114bd57600080fd5b505af11580156114d1573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906114f59190612aa0565b506110006001600160a01b03166335409f7f85848151811061151357fe5b60200260200101516040518263ffffffff1660e01b81526004016115379190612b82565b600060405180830381600087803b15801561155157600080fd5b505af1158015611565573d6000803e3d6000fd5b5050505050611577565b600101611441565b50600061158984604001516000611f50565b90506120006001600160a01b031663f7a251d7600b6115ab8760400151611f6c565b60006040518463ffffffff1660e01b81526004016115cb939291906132c3565b600060405180830381600087803b1580156115e557600080fd5b505af19250505080156115f6575060015b611668573d808015611624576040519150601f19603f3d011682016040523d82523d6000602084013e611629565b606091505b50817fd58d1183100bd0932c0588f31c4205d6bc6168909765a96c41adbed3115f36288260405161165a9190612bba565b60405180910390a250611694565b60405181907f7b78aadacff901d8b63d0dba4f86283d4db8aef27f9ed70413dd860f1c9532b690600090a25b50505050565b601481565b61100381565b60005460ff16156116c85760405162461bcd60e51b815260040161050b90613018565b603260045560966005556000805460ff19166001179055565b61100081565b600381565b336110001461170d5760405162461bcd60e51b815260040161050b90612edf565b60005460ff1661172f5760405162461bcd60e51b815260040161050b90612c9b565b60015461173b57611b33565b600154600090600019015b808211611b07576000805b8284101561186a5761176161264d565b600260006001878154811061177257fe5b60009182526020808320909101546001600160a01b0316835282810193909352604091820190208151606081018352815481526001820154938101939093526002015460ff161515908201526005549091506004900481602001511115611854576004600554816117df57fe5b0481602001510381602001818152505080600260006001888154811061180157fe5b6000918252602080832091909101546001600160a01b0316835282810193909352604091820190208351815591830151600183015591909101516002909101805460ff191691151591909117905561185e565b600192505061186a565b50836001019350611751565b828411611a015761187961264d565b600260006001868154811061188a57fe5b60009182526020808320909101546001600160a01b0316835282810193909352604091820190208151606081018352815481526001820154938101939093526002015460ff161515908201526005549091506004900481602001511115611972576004600554816118f757fe5b0481602001510381602001818152505080600260006001878154811061191957fe5b6000918252602080832091909101546001600160a01b03168352828101939093526040918201902083518155918301516001808401919091559201516002909101805460ff19169115159190911790559150611a019050565b600260006001868154811061198357fe5b60009182526020808320909101546001600160a01b031683528201929092526040018120818155600181810192909255600201805460ff191690558054806119c757fe5b600082815260209020810160001990810180546001600160a01b0319169055019055836119f45750611a01565b506000199092019161186a565b818015611a0b5750805b15611aea576002600060018681548110611a2157fe5b60009182526020808320909101546001600160a01b031683528201929092526040018120818155600181810192909255600201805460ff19169055805484908110611a6857fe5b600091825260209091200154600180546001600160a01b039092169186908110611a8e57fe5b9060005260206000200160006101000a8154816001600160a01b0302191690836001600160a01b031602179055506001805480611ac757fe5b600082815260209020810160001990810180546001600160a01b03191690550190555b82611af6575050611b07565b505060019091019060001901611746565b6040517fcfdb3b6ccaeccbdc68be3c59c840e3b3c90f0a7c491f5fff1cf56cfda200dd9c90600090a150505b565b61100481565b60408051600480825260a08201909252606091829190816020015b6060815260200190600190039081611b56579050509050611b7f836001600160a01b0316611fa7565b81600081518110611b8c57fe5b6020026020010181905250611ba043611fca565b81600181518110611bad57fe5b6020908102919091010152611bc26038611fca565b81600281518110611bcf57fe5b6020026020010181905250611be342611fca565b81600381518110611bf057fe5b6020026020010181905250611c0481611fdd565b9150505b919050565b611c15612670565b6000611c1f612670565b611c27612682565b611c38611c3386612067565b61208c565b90506000805b611c47836120d6565b15611c805780611c7357611c62611c5d846120f7565b612145565b63ffffffff16845260019150611c78565b611c80565b600101611c3e565b5091935090915050915091565b600081604051602001611ca09190612b66565b6040516020818303038152906040528051906020012083604051602001611cc79190612b66565b604051602081830303815290604052805190602001201490505b92915050565b015190565b8082015160009060ff811615611d06576001915081611d0c565b60009150815b505092915050565b60408051600480825260a0820190925260009160609190816020015b6060815260200190600190039081611d30575050604080516020808252818301909252919250606091908082018180368337019050509050611d758560000151611fca565b82600081518110611d8257fe5b6020026020010181905250611d9d60208660200151836121c7565b611da6816121d7565b82600181518110611db357fe5b6020026020010181905250611dcb8560400151611fca565b82600281518110611dd857fe5b6020026020010181905250611df360208660600151836121c7565b611dfc816121d7565b82600381518110611e0957fe5b6020026020010181905250611e2f6020611e2284611fdd565b80519060200120836121c7565b6040805160b080825260e08201909252606091602082018180368337019050509050611e5f81836000602061222d565b611e718187608001516020606061222d565b611e7f81866080603061222d565b604080516001808252818301909252606091602082018180368337019050509050815160016020830182602086016066600019fa611ebc57600080fd5b506001611eca826000612280565b60ff1614611edf576000945050505050611ce1565b5060019695505050505050565b815181516000916001918114808314611f085760009250611f46565b600160208701838101602088015b600284838510011415611f41578051835114611f355760009650600093505b60209283019201611f16565b505050505b5090949350505050565b60008160200183511015611f6357600080fd5b50016020015190565b60408051600480825260a08201909252606091829190816020015b6060815260200190600190039081611f87579050509050611b7f836121d7565b60408051600560a21b8318601482015260348101909152606090611c04816121d7565b6060611ce1611fd88361229c565b6121d7565b6060815160001415611ffe5750604080516000815260208101909152611c08565b60608260008151811061200d57fe5b602002602001015190506000600190505b835181101561204e576120448285838151811061203757fe5b6020026020010151612382565b915060010161201e565b50611c04612061825160c060ff166123ff565b82612382565b61206f6126a2565b506040805180820190915281518152602082810190820152919050565b612094612682565b61209d826124d1565b6120a657600080fd5b60006120b5836020015161250b565b60208085015160408051808201909152868152920190820152915050919050565b60006120e06126a2565b505080518051602091820151919092015191011190565b6120ff6126a2565b612108826120d6565b61211157600080fd5b602082015160006121218261256e565b80830160209586015260408051808201909152908152938401919091525090919050565b80516000901580159061215a57508151602110155b61216357600080fd5b6000612172836020015161250b565b905080836000015110156121985760405162461bcd60e51b815260040161050b9061304f565b8251602080850151830180519284900392918310156121be57826020036101000a820491505b50949350505050565b9091018181526020918201910152565b6060815160011480156122095750607f60f81b826000815181106121f757fe5b01602001516001600160f81b03191611155b15612215575080611c08565b611ce16122278351608060ff166123ff565b83612382565b60005b818110156106c95783818151811061224457fe5b602001015160f81c60f81b85848060010195508151811061226157fe5b60200101906001600160f81b031916908160001a905350600101612230565b6000816001018351101561229357600080fd5b50016001015190565b604080516020808252818301909252606091829190602082018180368337505050602081018490529050600067ffffffffffffffff1984166122e057506018612304565b6fffffffffffffffffffffffffffffffff19841661230057506010612304565b5060005b602081101561233a5781818151811061231957fe5b01602001516001600160f81b031916156123325761233a565b600101612304565b60008160200390506060816040519080825280601f01601f19166020018201604052801561236f576020820181803683370190505b5080830196909652508452509192915050565b6060806040519050835180825260208201818101602087015b818310156123b357805183526020928301920161239b565b50855184518101855292509050808201602086015b818310156123e05780518352602092830192016123c8565b508651929092011591909101601f01601f191660405250905092915050565b60606801000000000000000083106124295760405162461bcd60e51b815260040161050b90612dc0565b604080516001808252818301909252606091602082018180368337019050509050603784116124835782840160f81b8160008151811061246557fe5b60200101906001600160f81b031916908160001a9053509050611ce1565b606061248e8561229c565b90508381510160370160f81b826000815181106124a757fe5b60200101906001600160f81b031916908160001a9053506124c88282612382565b95945050505050565b80516000906124e257506000611c08565b6020820151805160001a9060c082101561250157600092505050611c08565b5060019392505050565b8051600090811a6080811015612525576000915050611c08565b60b8811080612540575060c08110801590612540575060f881105b1561254f576001915050611c08565b60c08110156125635760b519019050611c08565b60f519019050611c08565b80516000908190811a60808110156125895760019150612646565b60b881101561259e57607e1981019150612646565b60c08110156125ef57600060b78203600186019550806020036101000a8651049150600181018201935050808310156125e95760405162461bcd60e51b815260040161050b90612f2f565b50612646565b60f88110156126045760be1981019150612646565b600060f78203600186019550806020036101000a865104915060018101820193505080831015611d0c5760405162461bcd60e51b815260040161050b90612f2f565b5092915050565b604051806060016040528060008152602001600081526020016000151581525090565b60408051602081019091526000815290565b60405180604001604052806126956126a2565b8152602001600081525090565b604051806040016040528060008152602001600081525090565b600082601f8301126126cc578081fd5b81516126df6126da82613316565b6132ef565b818152915060208083019084810160005b84811015612755578151870188603f82011261270b57600080fd5b8381015161271b6126da82613336565b81815260408b8184860101111561273157600080fd5b6127408388840183870161335a565b508652505092820192908201906001016126f0565b505050505092915050565b60008083601f840112612771578182fd5b50813567ffffffffffffffff811115612788578182fd5b6020830191508360208285010111156127a057600080fd5b9250929050565b600082601f8301126127b7578081fd5b81356127c56126da82613336565b91508082528360208285010111156127dc57600080fd5b8060208401602084013760009082016020015292915050565b600060a08284031215612806578081fd5b61281060a06132ef565b905081358152602082013560208201526040820135604082015260608201356060820152608082013567ffffffffffffffff81111561284e57600080fd5b61285a848285016127a7565b60808301525092915050565b600060208284031215612877578081fd5b813561288281613386565b9392505050565b6000806040838503121561289b578081fd5b825167ffffffffffffffff808211156128b2578283fd5b81850186601f8201126128c3578384fd5b805192506128d36126da84613316565b80848252602080830192508084018a8283890287010111156128f3578788fd5b8794505b8685101561291e57805161290a81613386565b8452600194909401939281019281016128f7565b508801519096509350505080821115612935578283fd5b50612942858286016126bc565b9150509250929050565b60006020828403121561295d578081fd5b81518015158114612882578182fd5b60008060008060408587031215612981578182fd5b843567ffffffffffffffff80821115612998578384fd5b6129a488838901612760565b909650945060208701359150808211156129bc578384fd5b506129c987828801612760565b95989497509550505050565b6000602082840312156129e6578081fd5b813567ffffffffffffffff808211156129fd578283fd5b81840160608187031215612a0f578384fd5b612a1960606132ef565b9250803582811115612a29578485fd5b612a35878284016127f5565b845250602081013582811115612a49578485fd5b612a55878284016127f5565b602085015250604081013582811115612a6c578485fd5b612a78878284016127a7565b6040850152509195945050505050565b600060208284031215612a99578081fd5b5035919050565b600060208284031215612ab1578081fd5b5051919050565b600080600060408486031215612acc578283fd5b833560ff81168114612adc578384fd5b9250602084013567ffffffffffffffff811115612af7578283fd5b612b0386828701612760565b9497909650939450505050565b60008284528282602086013780602084860101526020601f19601f85011685010190509392505050565b60008151808452612b5281602086016020860161335a565b601f01601f19169290920160200192915050565b60008251612b7881846020870161335a565b9190910192915050565b6001600160a01b0391909116815260200190565b6001600160a01b03929092168252602082015260400190565b901515815260200190565b6000602082526128826020830184612b3a565b600060408252612be1604083018688612b10565b8281036020840152612bf4818587612b10565b979650505050505050565b6020808252601f908201527f746865206d73672073656e646572206973206e6f7420612072656c6179657200604082015260600190565b6020808252601690820152751d1bdbc81bdb1908189b1bd8dac81a5b9d9bdb1d995960521b604082015260600190565b6020808252818101527f6d616c6963696f757320766f746520736c617368206e6f7420656e61626c6564604082015260600190565b60208082526019908201527f74686520636f6e7472616374206e6f7420696e69742079657400000000000000604082015260600190565b6020808252601a908201527f6e6f2076696f6c6174696f6e206f6620766f74652072756c6573000000000000604082015260600190565b6020808252818101527f7468652066656c6f6e795468726573686f6c64206f7574206f662072616e6765604082015260600190565b6020808252602b908201527f6c656e677468206f6620656e61626c654d616c6963696f7573566f7465536c6160408201526a0e6d040dad2e6dac2e8c6d60ab1b606082015260800190565b60208082526017908201527f766572696679207369676e6174757265206661696c6564000000000000000000604082015260600190565b6020808252600e908201526d696e70757420746f6f206c6f6e6760901b604082015260600190565b60208082526019908201527f7372634e756d20626967676572207468616e207461724e756d00000000000000604082015260600190565b6020808252602c908201527f7468652066696e616c69747920736c6173682072657761726420726174696f2060408201526b6f7574206f662072616e676560a01b606082015260800190565b60208082526027908201527f6c656e677468206f66206d697364656d65616e6f725468726573686f6c64206d6040820152660d2e6dac2e8c6d60cb1b606082015260800190565b60208082526013908201527274776f206964656e746963616c20766f74657360681b604082015260600190565b60208082526030908201527f746865206d6573736167652073656e646572206d7573742062652076616c696460408201526f185d1bdc94d95d0818dbdb9d1c9858dd60821b606082015260800190565b6020808252601190820152706164646974696f6e206f766572666c6f7760781b604082015260600190565b6020808252601490820152736761737072696365206973206e6f74207a65726f60601b604082015260600190565b6020808252602e908201527f746865206d6573736167652073656e646572206d75737420626520676f76657260408201526d1b985b98d94818dbdb9d1c9858dd60921b606082015260800190565b60208082526022908201527f6c656e677468206f662066656c6f6e795468726573686f6c64206d69736d61746040820152610c6d60f31b606082015260800190565b60208082526019908201527f74686520636f6e747261637420616c726561647920696e697400000000000000604082015260600190565b6020808252601a908201527f6c656e677468206973206c657373207468616e206f6666736574000000000000604082015260600190565b60208082526025908201527f746865206d697364656d65616e6f725468726573686f6c64206f7574206f662060408201526472616e676560d81b606082015260800190565b6020808252602f908201527f746865206d6573736167652073656e646572206d7573742062652063726f737360408201526e0818da185a5b8818dbdb9d1c9858dd608a1b606082015260800190565b6020808252602d908201527f746865206d6573736167652073656e646572206d75737420626520746865206260408201526c3637b1b590383937b23ab1b2b960991b606082015260800190565b6020808252600d908201526c756e6b6e6f776e20706172616d60981b604082015260600190565b6020808252601e908201527f7265636569766520756e65787065637465642073796e207061636b6167650000604082015260600190565b6020808252602b908201527f6c656e677468206f662066696e616c697479536c61736852657761726452617460408201526a0d2de40dad2e6dac2e8c6d60ab1b606082015260800190565b6020808252818101527f63616e206e6f7420736c61736820747769636520696e206f6e6520626c6f636b604082015260600190565b61ffff91909116815260200190565b90815260200190565b6000838252604060208301526132766040830184612b3a565b949350505050565b918252602082015260400190565b92835260208301919091521515604082015260600190565b63ffffffff91909116815260200190565b60ff91909116815260200190565b600060ff85168252606060208301526132df6060830185612b3a565b9050826040830152949350505050565b60405181810167ffffffffffffffff8111828210171561330e57600080fd5b604052919050565b600067ffffffffffffffff82111561332c578081fd5b5060209081020190565b600067ffffffffffffffff82111561334c578081fd5b50601f01601f191660200190565b60005b8381101561337557818101518382015260200161335d565b838111156116945750506000910152565b6001600160a01b038116811461339b57600080fd5b5056fea26469706673582212207e6be46f5e0281709e9788d33be4928c51610752d8a32e78d1c8c64bea3df55764736f6c63430006040033", + }, + { + ContractAddr: SystemRewardContract, + CommitUrl: "https://github.com/bnb-chain/bsc-genesis-contract/commit/b144718e94d7a1ebb24a7103202300f08826f369", + Code: "6080604052600436106101a05760003560e01c80637942fd05116100ec578063ac4317511161008a578063f9a2bbc711610064578063f9a2bbc714610550578063fb5478b314610565578063fc3e59081461057a578063fd6a68791461058f576101e4565b8063ac43175114610457578063c81b166214610526578063dc927faf1461053b576101e4565b80639dc09262116100c65780639dc0926214610403578063a1a11bf514610418578063a78abc161461042d578063ab51bb9614610442576101e4565b80637942fd05146103a057806396713da9146103b55780639a99b4f0146103ca576101e4565b80634bf6c882116101595780636e47b482116101335780636e47b4821461034c57806370fd5bad14610361578063718a8aa81461037657806375d47a0a1461038b576101e4565b80634bf6c882146102db57806351e80672146102f05780636d70f7ae14610305576101e4565b80630bee7a67146101e95780630e2374a5146102175780633a0b0eff146102485780633dffc3871461026f57806343756e5c1461029a578063493279b1146102af576101e4565b366101e45734156101e25760408051348152905133917f6c98249d85d88c3753a04a22230f595e4dc8d3dc86c34af35deeeedc861b89db919081900360200190a25b005b600080fd5b3480156101f557600080fd5b506101fe6105a4565b6040805163ffffffff9092168252519081900360200190f35b34801561022357600080fd5b5061022c6105a9565b604080516001600160a01b039092168252519081900360200190f35b34801561025457600080fd5b5061025d6105af565b60408051918252519081900360200190f35b34801561027b57600080fd5b506102846105b5565b6040805160ff9092168252519081900360200190f35b3480156102a657600080fd5b5061022c6105ba565b3480156102bb57600080fd5b506102c46105c0565b6040805161ffff9092168252519081900360200190f35b3480156102e757600080fd5b506102846105c5565b3480156102fc57600080fd5b5061022c6105ca565b34801561031157600080fd5b506103386004803603602081101561032857600080fd5b50356001600160a01b03166105d0565b604080519115158252519081900360200190f35b34801561035857600080fd5b5061022c6105ee565b34801561036d57600080fd5b506102846105f4565b34801561038257600080fd5b506102846105f9565b34801561039757600080fd5b5061022c6105fe565b3480156103ac57600080fd5b50610284610604565b3480156103c157600080fd5b50610284610609565b3480156103d657600080fd5b5061025d600480360360408110156103ed57600080fd5b506001600160a01b03813516906020013561060e565b34801561040f57600080fd5b5061022c6107b9565b34801561042457600080fd5b5061022c6107bf565b34801561043957600080fd5b506103386107c5565b34801561044e57600080fd5b506101fe6107ce565b34801561046357600080fd5b506101e26004803603604081101561047a57600080fd5b81019060208101813564010000000081111561049557600080fd5b8201836020820111156104a757600080fd5b803590602001918460018302840111640100000000831117156104c957600080fd5b9193909290916020810190356401000000008111156104e757600080fd5b8201836020820111156104f957600080fd5b8035906020019184600183028401116401000000008311171561051b57600080fd5b5090925090506107d3565b34801561053257600080fd5b5061022c610b56565b34801561054757600080fd5b5061022c610b5c565b34801561055c57600080fd5b5061022c610b62565b34801561057157600080fd5b5061025d610b68565b34801561058657600080fd5b50610284610b74565b34801561059b57600080fd5b5061022c610b79565b606481565b61200181565b60015481565b600181565b61100181565b603881565b600881565b61200081565b6001600160a01b031660009081526002602052604090205460ff1690565b61100581565b600281565b601081565b61100881565b600b81565b600981565b6000805460ff1661068b57600260208190527fe57bda0a954a7c7381b17b2c763e646ba2c60f67292d287ba583603e2c1c41668054600160ff19918216811790925561100560009081527fe25235fc0de9d7165652bef0846fefda506174abb9a190f03d0f7bcc6146dbce80548316841790559282558254161790555b3360009081526002602052604090205460ff166106d95760405162461bcd60e51b815260040180806020018281038252602b815260200180610c67602b913960400191505060405180910390fd5b60004783106106e857476106ea565b825b9050670de0b6b3a76400008111156107075750670de0b6b3a76400005b8015610788576040516001600160a01b0385169082156108fc029083906000818181858888f19350505050158015610743573d6000803e3d6000fd5b506040805182815290516001600160a01b038616917ff8b71c64315fc33b2ead2adfa487955065152a8ac33d9d5193aafd7f45dc15a0919081900360200190a26107b2565b6040517fe589651933c2457488cc0d8e0941518abf748e799435e4e396d9c4d0b2db2d4d90600090a15b9392505050565b61100781565b61100681565b60005460ff1681565b600081565b33611007146108135760405162461bcd60e51b815260040180806020018281038252602e815260200180610cc1602e913960400191505060405180910390fd5b61087584848080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152505060408051808201909152600b81526a30b23227b832b930ba37b960a91b60208201529150610b7f9050565b1561094d57606082828080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525050825192935050601490911490506108f85760405162461bcd60e51b815260040180806020018281038252602c815260200180610cef602c913960400191505060405180910390fd5b60148101516001600160a01b038116600081815260026020526040808220805460ff19166001179055517f9870d7fe5d112134c55844951dedf365363006d9c588db07c4c85af6322a06199190a25050610ac4565b6109b284848080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152505060408051808201909152600e81526d3232b632ba32a7b832b930ba37b960911b60208201529150610b7f9050565b15610a8757606082828080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152505082519293505060149091149050610a355760405162461bcd60e51b815260040180806020018281038252602f815260200180610c92602f913960400191505060405180910390fd5b60148101516001600160a01b038116600081815260026020526040808220805460ff19169055517fb40992a19dba61ea600e87fce607102bf5908dc89076217b6ca6ae195224f7029190a25050610ac4565b6040805162461bcd60e51b815260206004820152600d60248201526c756e6b6e6f776e20706172616d60981b604482015290519081900360640190fd5b7f6cdb0ac70ab7f2e2d035cca5be60d89906f2dede7648ddbd7402189c1eeed17a848484846040518080602001806020018381038352878782818152602001925080828437600083820152601f01601f191690910184810383528581526020019050858580828437600083820152604051601f909101601f19169092018290039850909650505050505050a150505050565b61100281565b61100381565b61100081565b670de0b6b3a764000081565b600381565b61100481565b6000816040516020018082805190602001908083835b60208310610bb45780518252601f199092019160209182019101610b95565b6001836020036101000a03801982511681845116808217855250505050505090500191505060405160208183030381529060405280519060200120836040516020018082805190602001908083835b60208310610c225780518252601f199092019160209182019101610c03565b6001836020036101000a038019825116818451168082178552505050505050905001915050604051602081830303815290604052805190602001201490509291505056fe6f6e6c79206f70657261746f7220697320616c6c6f77656420746f2063616c6c20746865206d6574686f646c656e677468206f662076616c756520666f722064656c6574654f70657261746f722073686f756c64206265203230746865206d6573736167652073656e646572206d75737420626520676f7665726e616e636520636f6e74726163746c656e677468206f662076616c756520666f72206164644f70657261746f722073686f756c64206265203230a264697066735822122078be72e2672a87e28d3e6849bea141a139b304a089fceb003c016dabd5f556fb64736f6c63430006040033", + }, + { + ContractAddr: RelayerHubContract, + CommitUrl: "https://github.com/bnb-chain/bsc-genesis-contract/commit/b144718e94d7a1ebb24a7103202300f08826f369", + Code: "608060405234801561001057600080fd5b50600436106102275760003560e01c80638f83ab1311610130578063c81b1662116100b8578063f3ae24151161007c578063f3ae2415146104e8578063f9a2bbc71461050e578063fc3e590814610516578063fd30d9b81461051e578063fd6a68791461052657610227565b8063c81b1662146104c0578063dc927faf146104c8578063dd91d1c5146104d0578063e1c7392a146104d8578063e79a198f146104e057610227565b8063a1a11bf5116100ff578063a1a11bf5146103de578063a74b83ca146103e6578063a78abc16146103ee578063ab51bb96146103f6578063ac431751146103fe57610227565b80638f83ab13146103a057806395468d26146103c657806396713da9146103ce5780639dc09262146103d657610227565b8063541d5548116101b3578063718a8aa811610182578063718a8aa81461034857806375d47a0a1461035057806378beee67146103585780637942fd051461037e5780637ae230881461038657610227565b8063541d5548146102d85780636a6a419e146103125780636e47b4821461033857806370fd5bad1461034057610227565b80633dffc387116101fa5780633dffc3871461028357806343756e5c146102a1578063493279b1146102a95780634bf6c882146102c857806351e80672146102d057610227565b806303aff02b1461022c578063049a5716146102365780630bee7a671461025a5780630e2374a51461027b575b600080fd5b61023461052e565b005b61023e610539565b604080516001600160a01b039092168252519081900360200190f35b610262610551565b6040805163ffffffff9092168252519081900360200190f35b61023e610556565b61028b61055c565b6040805160ff9092168252519081900360200190f35b61023e610561565b6102b1610567565b6040805161ffff9092168252519081900360200190f35b61028b61056c565b61023e610571565b6102fe600480360360208110156102ee57600080fd5b50356001600160a01b0316610577565b604080519115158252519081900360200190f35b6102fe6004803603602081101561032857600080fd5b50356001600160a01b0316610595565b61023e6105b3565b61028b6105b9565b61028b6105be565b61023e6105c3565b6102346004803603602081101561036e57600080fd5b50356001600160a01b03166105c9565b61028b6107b1565b61038e6107b6565b60408051918252519081900360200190f35b610234600480360360208110156103b657600080fd5b50356001600160a01b03166107c3565b61038e610a02565b61028b610a0e565b61023e610a13565b61023e610a19565b61023e610a1f565b6102fe610a37565b610262610a40565b6102346004803603604081101561041457600080fd5b81019060208101813564010000000081111561042f57600080fd5b82018360208201111561044157600080fd5b8035906020019184600183028401116401000000008311171561046357600080fd5b91939092909160208101903564010000000081111561048157600080fd5b82018360208201111561049357600080fd5b803590602001918460018302840111640100000000831117156104b557600080fd5b509092509050610a45565b61023e610d96565b61023e610d9c565b610234610da2565b610234610e43565b610234610ec5565b6102fe600480360360208110156104fe57600080fd5b50356001600160a01b031661107e565b61023e61109c565b61028b6110a2565b6102fe6110a7565b61023e6110b0565b610537336110b6565b565b73b005741528b86f5952469d80a8614591e3c5b63281565b606481565b61200181565b600181565b61100181565b603881565b600881565b61200081565b6001600160a01b031660009081526007602052604090205460ff1690565b6001600160a01b031660009081526008602052604090205460ff1690565b61100581565b600281565b601081565b61100881565b3360009081526008602052604090205460ff166106175760405162461bcd60e51b81526004018080602001828103825260248152602001806115c26024913960400191505060405180910390fd5b61062033611218565b1561065c5760405162461bcd60e51b815260040180806020018281038252602181526020018061157f6021913960400191505060405180910390fd5b3233146106b0576040805162461bcd60e51b815260206004820152601e60248201527f70726f766973696f6e616c2072656c6179657220697320612070726f78790000604482015290519081900360640190fd5b6001600160a01b038181166000908152600960205260409020541633146107085760405162461bcd60e51b815260040180806020018281038252602781526020018061163b6027913960400191505060405180910390fd5b6001600160a01b03818116600081815260066020908152604080832080543380865260078086528487208054600160ff199182161790915584546001600160a01b031990811684179095556008875285882080548216905597875260098652848720805490941690935596168085529083529281902080549094169093558251828152908101939093528151909260008051602061166283398151915292908290030190a15050565b600b81565b68056bc75e2d6310000081565b3360009081526005602052604090205460ff16610820576040805162461bcd60e51b81526020600482015260166024820152751b585b9859d95c88191bd95cc81b9bdd08195e1a5cdd60521b604482015290519081900360640190fd5b61082981611218565b156108655760405162461bcd60e51b81526004018080602001828103825260278152602001806115e66027913960400191505060405180910390fd5b6001600160a01b03811615610921576001600160a01b03811660009081526007602052604090205460ff16156108db576040805162461bcd60e51b815260206004820152601660248201527572656c6179657220616c72656164792065786973747360501b604482015290519081900360640190fd5b6001600160a01b0381166000818152600860209081526040808320805460ff191660011790553383526009909152902080546001600160a01b03191690911790556109c2565b3360008181526006602090815260408083208054600980855283862080546001600160a01b03198085169095556001600160a01b0393841680895260078852868920805460ff19908116909155918516808a5260088952878a20805490931690925598909752908552805490921690915581518581529086169281019290925280516000805160206116628339815191529281900390910190a150506109ff565b604080516001600160a01b038316815290517ffba56633276570c7d3120d4535bf3bce26523da53958e40734210b9fd99b36939181900360200190a15b50565b67016345785d8a000081565b600981565b61100781565b61100681565b73446aa6e0dc65690403df3f127750da1322941f3e81565b60005460ff1681565b600081565b60005460ff16610a98576040805162461bcd60e51b81526020600482015260196024820152781d1a194818dbdb9d1c9858dd081b9bdd081a5b9a5d081e595d603a1b604482015290519081900360640190fd5b3361100714610ad85760405162461bcd60e51b815260040180806020018281038252602e81526020018061160d602e913960400191505060405180910390fd5b610b3984848080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152505060408051808201909152600a81526930b23226b0b730b3b2b960b11b6020820152915061121e9050565b15610bd15760148114610b7d5760405162461bcd60e51b81526004018080602001828103825260228152602001806115a06022913960400191505060405180910390fd5b6000610bc0601484848080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061130592505050565b9050610bcb8161130a565b50610d04565b610c3584848080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152505060408051808201909152600d81526c3932b6b7bb32a6b0b730b3b2b960991b6020820152915061121e9050565b15610cc75760148114610c795760405162461bcd60e51b81526004018080602001828103825260228152602001806115a06022913960400191505060405180910390fd5b6000610cbc601484848080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061130592505050565b9050610bcb816110b6565b6040805162461bcd60e51b815260206004820152600d60248201526c756e6b6e6f776e20706172616d60981b604482015290519081900360640190fd5b7f6cdb0ac70ab7f2e2d035cca5be60d89906f2dede7648ddbd7402189c1eeed17a848484846040518080602001806020018381038352878782818152602001925080828437600083820152601f01601f191690910184810383528581526020019050858580828437600083820152604051601f909101601f19169092018290039850909650505050505050a150505050565b61100281565b61100381565b600a5460ff1615610dfa576040805162461bcd60e51b815260206004820152601e60248201527f7468652077686974656c6973747320616c726561647920757064617465640000604482015290519081900360640190fd5b610e1773b005741528b86f5952469d80a8614591e3c5b6326113cc565b610e3473446aa6e0dc65690403df3f127750da1322941f3e6113cc565b600a805460ff19166001179055565b60005460ff1615610e9b576040805162461bcd60e51b815260206004820152601960248201527f74686520636f6e747261637420616c726561647920696e697400000000000000604482015290519081900360640190fd5b68056bc75e2d63100000600190815567016345785d8a00006002556000805460ff19169091179055565b3360009081526004602052604090205460ff16610f20576040805162461bcd60e51b81526020600482015260146024820152731c995b185e595c88191bc81b9bdd08195e1a5cdd60621b604482015290519081900360640190fd5b60005460ff16610f73576040805162461bcd60e51b81526020600482015260196024820152781d1a194818dbdb9d1c9858dd081b9bdd081a5b9a5d081e595d603a1b604482015290519081900360640190fd5b610f7b611564565b5033600081815260036020908152604091829020825180840190935280548084526001909101549183018290529192916108fc91610fbf919063ffffffff61148416565b6040518115909202916000818181858888f19350505050158015610fe7573d6000803e3d6000fd5b50602081015160405161100291829181156108fc0291906000818181858888f1935050505015801561101d573d6000803e3d6000fd5b50336000818152600460209081526040808320805460ff191690556003825280832083815560010192909255815192835290517fd17202129b83db7880d6b9f25df81c58ad46f7e0e2c92236b1aa10663a4876679281900390910190a15050565b6001600160a01b031660009081526005602052604090205460ff1690565b61100081565b600381565b600a5460ff1681565b61100481565b6001600160a01b03811660009081526005602052604090205460ff1661111b576040805162461bcd60e51b81526020600482015260156024820152741b585b9859d95c88191bd95cdb89dd08195e1a5cdd605a1b604482015290519081900360640190fd5b6001600160a01b038082166000818152600660209081526040808320805460058452828520805460ff1990811690915582546001600160a01b0319908116909355600980865284872080548a16885260088752858820805490931690925595879052948452845490911690935580519384525191909316927f2002866d443ac6c241fecaaa2af4895828c7de2cc423b9d01f7969650f557c76928290030190a16001600160a01b03811615611214576001600160a01b0381166000818152600760209081526040808320805460ff1916905580519384529083019190915280516000805160206116628339815191529281900390910190a15b5050565b3b151590565b6000816040516020018082805190602001908083835b602083106112535780518252601f199092019160209182019101611234565b6001836020036101000a03801982511681845116808217855250505050505090500191505060405160208183030381529060405280519060200120836040516020018082805190602001908083835b602083106112c15780518252601f1990920191602091820191016112a2565b6001836020036101000a0380198251168184511680821785525050505050509050019150506040516020818303038152906040528051906020012014905092915050565b015190565b6001600160a01b03811660009081526005602052604090205460ff1615611371576040805162461bcd60e51b81526020600482015260166024820152756d616e6167657220616c72656164792065786973747360501b604482015290519081900360640190fd5b6001600160a01b038116600081815260056020908152604091829020805460ff19166001179055815192835290517fe0de8e71a22c046647f4ef744348fa126ad6d052d4ce070999481f69d45575179281900390910190a150565b6001600160a01b03811660008181526005602090815260408083208054600160ff1991821681179092556006845282852080546001600160a01b031916871790556007845293829020805490941617909255815192835290517fe0de8e71a22c046647f4ef744348fa126ad6d052d4ce070999481f69d45575179281900390910190a160408051600081526001600160a01b03831660208201528151600080516020611662833981519152929181900390910190a150565b60006114c683836040518060400160405280601e81526020017f536166654d6174683a207375627472616374696f6e206f766572666c6f7700008152506114cd565b9392505050565b6000818484111561155c5760405162461bcd60e51b81526004018080602001828103825283818151815260200191508051906020019080838360005b83811015611521578181015183820152602001611509565b50505050905090810190601f16801561154e5780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b505050900390565b60405180604001604052806000815260200160008152509056fe70726f766973696f6e616c2072656c61796572206973206120636f6e74726163746c656e677468206f66206d616e616765722061646472657373206d69736d6174636872656c61796572206973206e6f7420612070726f766973696f6e616c2072656c61796572636f6e7472616374206973206e6f7420616c6c6f77656420746f20626520612072656c61796572746865206d6573736167652073656e646572206d75737420626520676f7665726e616e636520636f6e747261637470726f766973696f6e616c206973206e6f742073657420666f722074686973206d616e61676572a5a19d7e9dab30a215022382d7abe782b579986fcbedec9942ecd0db9510a148a2646970667358221220ca640b19c40787a49d8b8b52c563d76e0125386bfdf94825087004f989e9989d64736f6c63430006040033", + }, + { + ContractAddr: CrossChainContract, + CommitUrl: "https://github.com/bnb-chain/bsc-genesis-contract/commit/b144718e94d7a1ebb24a7103202300f08826f369", + Code: "608060405234801561001057600080fd5b50600436106103995760003560e01c8063718a8aa8116101e9578063c27cdcfb1161010f578063dc927faf116100ad578063f7a251d71161007c578063f7a251d714610b2f578063f9a2bbc714610ba7578063fc3e590814610baf578063fd6a687914610bb757610399565b8063dc927faf14610af7578063e1c7392a14610aff578063e3b0480514610b07578063e6400bbe14610b2757610399565b8063ccc108d7116100e9578063ccc108d714610ab0578063d31f968d14610ab8578063d76a867514610ae7578063dc40433114610aef57610399565b8063c27cdcfb14610a80578063c780e9de14610aa0578063c81b166214610aa857610399565b80638cc8f56111610187578063a78abc1611610156578063a78abc16146109b2578063ab51bb96146109ba578063ac431751146109c2578063b0355f5b1461078157610399565b80638cc8f5611461088757806396713da91461099a5780639dc09262146109a2578063a1a11bf5146109aa57610399565b806375d47a0a116101c357806375d47a0a146108a75780637942fd05146108af57806384013b6a146108b7578063863fe4ab1461099257610399565b8063718a8aa81461088f578063719482d51461089757806374f079b81461089f57610399565b8063422f9050116102ce57806363e1394e1161026c5780636de380bd1161023b5780636de380bd146108575780636e47a51a1461085f5780636e47b4821461087f57806370fd5bad1461088757610399565b806363e1394e146107ff5780636a3cb34d146108075780636bacff2c1461080f5780636c46aa681461080757610399565b80634bf6c882116102a85780634bf6c882146107b957806351e80672146107c15780635692ddd3146107c95780635f832177146107d157610399565b8063422f90501461078957806343756e5c146107a9578063493279b1146107b157610399565b8063299b533d1161033b578063308325f411610315578063308325f4146106155780633a648b151461061d5780633bdc47a6146106595780633dffc3871461078157610399565b8063299b533d146105a35780632af6f399146105d75780632ff32aea146105f457610399565b806314b3023b1161037757806314b3023b146104015780631d1309351461041b5780631e275ae11461043757806322556cdc1461059b57610399565b806305e682581461039e5780630bee7a67146103bc5780630e2374a5146103dd575b600080fd5b6103a6610bbf565b6040805160ff9092168252519081900360200190f35b6103c4610bc4565b6040805163ffffffff9092168252519081900360200190f35b6103e5610bc9565b604080516001600160a01b039092168252519081900360200190f35b610409610bcf565b60408051918252519081900360200190f35b610423610bd5565b604080519115158252519081900360200190f35b610599600480360361010081101561044e57600080fd5b81018160a081016080820135600160201b81111561046b57600080fd5b82018360208201111561047d57600080fd5b803590602001918460018302840111600160201b8311171561049e57600080fd5b919390929091602081019035600160201b8111156104bb57600080fd5b8201836020820111156104cd57600080fd5b803590602001918460018302840111600160201b831117156104ee57600080fd5b919390929091602081019035600160201b81111561050b57600080fd5b82018360208201111561051d57600080fd5b803590602001918460018302840111600160201b8311171561053e57600080fd5b919390929091602081019035600160201b81111561055b57600080fd5b82018360208201111561056d57600080fd5b803590602001918460018302840111600160201b8311171561058e57600080fd5b509092509050610bde565b005b6104096112c2565b6105c0600480360360208110156105b957600080fd5b50356112c7565b6040805161ffff9092168252519081900360200190f35b610423600480360360208110156105ed57600080fd5b50356112dd565b6105fc6112f2565b60408051600792830b90920b8252519081900360200190f35b6104096112fb565b61063d6004803603602081101561063357600080fd5b503560ff16611301565b604080516001600160401b039092168252519081900360200190f35b61070c6004803603606081101561066f57600080fd5b60ff82351691602081013591810190606081016040820135600160201b81111561069857600080fd5b8201836020820111156106aa57600080fd5b803590602001918460018302840111600160201b831117156106cb57600080fd5b91908080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525092955061131c945050505050565b6040805160208082528351818301528351919283929083019185019080838360005b8381101561074657818101518382015260200161072e565b50505050905090810190601f1680156107735780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b6103a6611392565b6104236004803603602081101561079f57600080fd5b503560ff16611397565b6103e56113ac565b6105c06113b2565b6103a66113b7565b6103e56113bc565b6104096113c2565b610599600480360360408110156107e757600080fd5b506001600160a01b03813581169160200135166113f2565b610409611652565b6105c061167a565b61082c6004803603602081101561082557600080fd5b503561167f565b6040805161ffff90941684526001600160801b03909216602084015282820152519081900360600190f35b6104096116ae565b6103e56004803603602081101561087557600080fd5b503560ff166116d5565b6103e56116f0565b6103a661167a565b6103a66116f6565b6105c0611392565b6104096116fb565b6103e5611701565b6103a6611707565b610599600480360360a08110156108cd57600080fd5b810190602081018135600160201b8111156108e757600080fd5b8201836020820111156108f957600080fd5b803590602001918460018302840111600160201b8311171561091a57600080fd5b919390929091602081019035600160201b81111561093757600080fd5b82018360208201111561094957600080fd5b803590602001918460018302840111600160201b8311171561096a57600080fd5b919350915080356001600160401b03908116916020810135909116906040013560ff1661170c565b6104096129c6565b6103a66129ce565b6103e56129d3565b6103e56129d9565b6104236129df565b6103c4610bbf565b610599600480360360408110156109d857600080fd5b810190602081018135600160201b8111156109f257600080fd5b820183602082011115610a0457600080fd5b803590602001918460018302840111600160201b83111715610a2557600080fd5b919390929091602081019035600160201b811115610a4257600080fd5b820183602082011115610a5457600080fd5b803590602001918460018302840111600160201b83111715610a7557600080fd5b5090925090506129e8565b61063d60048036036020811015610a9657600080fd5b503560ff166134ac565b6104096134c7565b6103e56134eb565b6105996134f1565b61042360048036036040811015610ace57600080fd5b5080356001600160a01b0316906020013560ff16613745565b61070c613765565b610409613784565b6103e561378a565b610599613790565b61063d60048036036020811015610b1d57600080fd5b503560ff16613b47565b610599613b62565b61059960048036036060811015610b4557600080fd5b60ff8235169190810190604081016020820135600160201b811115610b6957600080fd5b820183602082011115610b7b57600080fd5b803590602001918460018302840111600160201b83111715610b9c57600080fd5b919350915035613d81565b6103e5613ec4565b6103a6613eca565b6103e5613ecf565b600081565b606481565b61200181565b60015481565b600b5460ff1681565b60005460ff16610c23576040805162461bcd60e51b815260206004820152601960248201526000805160206149b2833981519152604482015290519081900360640190fd5b604080516337d7f9c160e21b81526001600160401b038b35166004820181905291516110039163df5fe704916024808301926020929190829003018186803b158015610c6e57600080fd5b505afa158015610c82573d6000803e3d6000fd5b505050506040513d6020811015610c9857600080fd5b5051610cd55760405162461bcd60e51b81526004018080602001828103825260238152602001806149d26023913960400191505060405180910390fd5b604080516337d7f9c160e21b815260208c8101356001600160401b03166004830181905292516110039263df5fe704926024808301939192829003018186803b158015610d2157600080fd5b505afa158015610d35573d6000803e3d6000fd5b505050506040513d6020811015610d4b57600080fd5b5051610d885760405162461bcd60e51b81526004018080602001828103825260238152602001806149d26023913960400191505060405180910390fd5b60608b013560ff81166000908152600560205260409020546001600160401b03909116906001600160a01b0316610e01576040805162461bcd60e51b815260206004820152601860248201527718da185b9b995b081a5cc81b9bdd081cdd5c1c1bdc9d195960421b604482015290519081900360640190fd5b600b5460ff1615610e45576040805162461bcd60e51b81526020600482015260096024820152681cdd5cdc195b99195960ba1b604482015290519081900360640190fd5b8888604051808383808284376040519201829003822094508f93508e9250819050838380828437808301925050509250505060405180910390201415610ec1576040805162461bcd60e51b815260206004820152600c60248201526b1cd85b59481c185e5b1bd85960a21b604482015290519081900360640190fd5b60606001600160401b0360408e01358116908e83013516610ee28282613ed5565b80516020808301919091206000818152600e9092526040909120549194509060ff1615610f4b576040805162461bcd60e51b8152602060048201526012602482015271185b1c9958591e4818da185b1b195b99d95960721b604482015290519081900360640190fd5b6000908152600e60205260408120805460ff191660011790558f8160200201356001600160401b0316905060608f8f8080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f82011690508083019250505050505050905060608c8c8080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201829052506040805163cba510a960e01b81526001600160401b038a16600482015290519596509094611003945063cba510a9935060248083019350602092829003018186803b15801561104157600080fd5b505afa158015611055573d6000803e3d6000fd5b505050506040513d602081101561106b57600080fd5b505160408051808201909152600381526269626360e81b6020820152909150611098908290898686613f1d565b6110e1576040805162461bcd60e51b81526020600482015260156024820152740696e76616c6964206d65726b6c652070726f6f663605c1b604482015290519081900360640190fd5b5050505060008f6001600481106110f457fe5b60200201356001600160401b0316905060608d8d8080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525050604080516020601f8f018190048102820181019092528d815293945060609392508d91508c908190840183828082843760009201829052506040805163cba510a960e01b81526001600160401b038a16600482015290519596509094611003945063cba510a9935060248083019350602092829003018186803b1580156111c057600080fd5b505afa1580156111d4573d6000803e3d6000fd5b505050506040513d60208110156111ea57600080fd5b505160408051808201909152600381526269626360e81b6020820152909150611217908290898686613f1d565b611260576040805162461bcd60e51b8152602060048201526015602482015274696e76616c6964206d65726b6c652070726f6f663160581b604482015290519081900360640190fd5b5050505061126c61401a565b604080516001600160401b038416815260ff83166020820152815133927f039eb91179ffd7d3b6e97f8ea106e748e827f910b872375dbc9c14a362319c3c928290030190a2505050505050505050505050505050565b603281565b600d6020526000908152604090205461ffff1681565b600e6020526000908152604090205460ff1681565b60045460070b81565b60025481565b600a602052600090815260409020546001600160401b031681565b60606000825160210190506060816040519080825280601f01601f191660200182016040528015611354576020820181803683370190505b506021810186905260018101879052828152905060418101600061137786614098565b509050611386818388516140a2565b50909695505050505050565b600181565b60096020526000908152604090205460ff1681565b61100181565b603881565b600881565b61200081565b604080517710d05390d15317d514905394d1915497d41493d413d4d05360421b8152905190819003601801902081565b60005460ff16611437576040805162461bcd60e51b815260206004820152601960248201526000805160206149b2833981519152604482015290519081900360640190fd5b6040805163569e4ed360e11b815233600482015290516000916110009163ad3c9da691602480820192602092909190829003018186803b15801561147a57600080fd5b505afa15801561148e573d6000803e3d6000fd5b505050506040513d60208110156114a457600080fd5b505160408051633d42651560e11b8152905191925060009161100091637a84ca2a916004808301926020929190829003018186803b1580156114e557600080fd5b505afa1580156114f9573d6000803e3d6000fd5b505050506040513d602081101561150f57600080fd5b505190508061151c575060155b60008211801561152c5750808211155b61156b576040805162461bcd60e51b815260206004820152600b60248201526a1b9bdd0818d8589a5b995d60aa1b604482015290519081900360640190fd5b604080516001600160a01b038087166020808401919091529086168284015282518083038401815260608301808552815191909201207710d05390d15317d514905394d1915497d41493d413d4d05360421b90915291519081900360780190206000906115d890836140e3565b9050801561164a5760408051630911a2c160e11b81526001600160a01b03888116600483015287166024820152905161100491631223458291604480830192600092919082900301818387803b15801561163157600080fd5b505af1158015611645573d6000803e3d6000fd5b505050505b505050505050565b604080516f14d554d411539117d41493d413d4d05360821b8152905190819003601001902081565b600281565b600c602052600090815260409020805460019091015461ffff8216916201000090046001600160801b03169083565b604080516e149153d4115397d41493d413d4d053608a1b8152905190819003600f01902081565b6005602052600090815260409020546001600160a01b031681565b61100581565b601081565b60035481565b61100881565b600b81565b60005460ff16611751576040805162461bcd60e51b815260206004820152601960248201526000805160206149b2833981519152604482015290519081900360640190fd5b60408051630a83aaa960e31b815233600482015290516110069163541d5548916024808301926020929190829003018186803b15801561179057600080fd5b505afa1580156117a4573d6000803e3d6000fd5b505050506040513d60208110156117ba57600080fd5b505161180d576040805162461bcd60e51b815260206004820152601f60248201527f746865206d73672073656e646572206973206e6f7420612072656c6179657200604482015290519081900360640190fd5b60ff8116600090815260086020526040902054829082906001600160401b03908116908316811461187d576040805162461bcd60e51b815260206004820152601560248201527439b2b8bab2b731b2903737ba1034b71037b93232b960591b604482015290519081900360640190fd5b60ff8216600090815260086020908152604091829020805467ffffffffffffffff1916600185016001600160401b039081169190911790915582516337d7f9c160e21b81529089166004820152915188926110039263df5fe70492602480840193829003018186803b1580156118f257600080fd5b505afa158015611906573d6000803e3d6000fd5b505050506040513d602081101561191c57600080fd5b50516119595760405162461bcd60e51b81526004018080602001828103825260238152602001806149d26023913960400191505060405180910390fd5b60ff851660009081526005602052604090205485906001600160a01b03166119c3576040805162461bcd60e51b815260206004820152601860248201527718da185b9b995b081a5cc81b9bdd081cdd5c1c1bdc9d195960421b604482015290519081900360640190fd5b60ff86166000908152600a6020526040902054889087906001600160401b039081169083161015611a2c576040805162461bcd60e51b815260206004820152600e60248201526d3a37b79037b632103432b0b232b960911b604482015290519081900360640190fd5b60ff81166000908152600a60205260409020546001600160401b03838116911614611a7e5760ff81166000908152600a60205260409020805467ffffffffffffffff19166001600160401b0384161790555b600b5460ff1615611ac2576040805162461bcd60e51b81526020600482015260096024820152681cdd5cdc195b99195960ba1b604482015290519081900360640190fd5b60608e8e8080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f82011690508083019250505050505050905060608d8d8080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f820116905080830192505050505050509050611c066110036001600160a01b031663cba510a98e6040518263ffffffff1660e01b815260040180826001600160401b03166001600160401b0316815260200191505060206040518083038186803b158015611baf57600080fd5b505afa158015611bc3573d6000803e3d6000fd5b505050506040513d6020811015611bd957600080fd5b505160408051808201909152600381526269626360e81b6020820152611bff8e8e613ed5565b8585613f1d565b611c4e576040805162461bcd60e51b815260206004820152601460248201527334b73b30b634b21036b2b935b63290383937b7b360611b604482015290519081900360640190fd5b60408051631bb5062960e31b81526001600160401b038e16600482015290516000916110039163dda8314891602480820192602092909190829003018186803b158015611c9a57600080fd5b505afa158015611cae573d6000803e3d6000fd5b505050506040513d6020811015611cc457600080fd5b505190508b8b600080806060611cd9896143c8565b935093509350935083611d9b578460ff16866001600160401b03167ff7b2e42d694eb1100184aae86d4245d9e46966100b1dc7e723275b98326854ac8b6040518080602001828103825283818151815260200191508051906020019080838360005b83811015611d53578181015183820152602001611d3b565b50505050905090810190601f168015611d805780820380516001836020036101000a031916815260200191505b509250505060405180910390a35050505050505050506129b6565b6040805160ff85811682529151918716916001600160401b038916917f36afdaf439a8f43fe72135135d804ae620b37a474f0943b5b85f6788312cad40919081900360200190a360ff83166123205760ff85166000818152600560209081526040808320548151631182b87560e01b815260048101958652602481019283528651604482015286516001600160a01b03909216958695631182b875958d958a9593949093606490910192918601918190849084905b83811015611e68578181015183820152602001611e50565b50505050905090810190601f168015611e955780820380516001836020036101000a031916815260200191505b509350505050600060405180830381600087803b158015611eb557600080fd5b505af1925050508015611f9957506040513d6000823e601f3d908101601f191682016040526020811015611ee857600080fd5b8101908080516040519392919084600160201b821115611f0757600080fd5b908301906020820185811115611f1c57600080fd5b8251600160201b811182820188101715611f3557600080fd5b82525081516020918201929091019080838360005b83811015611f62578181015183820152602001611f4a565b50505050905090810190601f168015611f8f5780820380516001836020036101000a031916815260200191505b5060405250505060015b6122ab576040516000815260443d1015611fb557506000612050565b60046000803e60005160e01c6308c379a08114611fd6576000915050612050565b60043d036004833e81513d60248201116001600160401b038211171561200157600092505050612050565b80830180516001600160401b03811115612022576000945050505050612050565b8060208301013d860181111561204057600095505050505050612050565b601f01601f191660405250925050505b8061205b575061216d565b60ff8716600090815260076020526040812054612092916001600160401b0390911690899061208d906002908861131c565b614478565b60ff8716600090815260076020908152604080832080546001600160401b038082166001011667ffffffffffffffff19909116179055805182815284518184015284516001600160a01b038716947ff91a8f63e5b3e0e89e5f93e1915a7805f3c52d9a73b3c09769785c2c7bf87acf948794849390840192918601918190849084905b8381101561212d578181015183820152602001612115565b50505050905090810190601f16801561215a5780820380516001836020036101000a031916815260200191505b509250505060405180910390a2506122a6565b3d808015612197576040519150601f19603f3d011682016040523d82523d6000602084013e61219c565b606091505b5060ff87166000908152600760205260408120546121cf916001600160401b0390911690899061208d906002908861131c565b60ff8716600090815260076020908152604080832080546001600160401b038082166001011667ffffffffffffffff19909116179055805182815284518184015284516001600160a01b038716947f63ac299d6332d1cc4e61b81e59bc00c0ac7c798addadf33840f1307cd2977351948794849390840192918601918190849084905b8381101561226a578181015183820152602001612252565b50505050905090810190601f1680156122975780820380516001836020036101000a031916815260200191505b509250505060405180910390a2505b61231a565b8051156123185760ff87166000908152600760205260408120546122e4916001600160401b0390911690899061208d906001908661131c565b60ff8716600090815260076020526040902080546001600160401b038082166001011667ffffffffffffffff199091161790555b505b506128ee565b60ff8316600114156125c45760ff8516600081815260056020908152604080832054815163831d65d160e01b815260048101958652602481019283528651604482015286516001600160a01b0390921695869563831d65d1958d958a9593949093606490910192918601918190849084905b838110156123aa578181015183820152602001612392565b50505050905090810190601f1680156123d75780820380516001836020036101000a031916815260200191505b509350505050600060405180830381600087803b1580156123f757600080fd5b505af1925050508015612408575060015b61231a576040516000815260443d1015612424575060006124bf565b60046000803e60005160e01c6308c379a081146124455760009150506124bf565b60043d036004833e81513d60248201116001600160401b0382111715612470576000925050506124bf565b80830180516001600160401b038111156124915760009450505050506124bf565b8060208301013d86018111156124af576000955050505050506124bf565b601f01601f191660405250925050505b806124ca575061252f565b60408051602080825283518183015283516001600160a01b038616937ff91a8f63e5b3e0e89e5f93e1915a7805f3c52d9a73b3c09769785c2c7bf87acf938693909283928301918501908083836000831561212d578181015183820152602001612115565b3d808015612559576040519150601f19603f3d011682016040523d82523d6000602084013e61255e565b606091505b5060408051602080825283518183015283516001600160a01b038616937f63ac299d6332d1cc4e61b81e59bc00c0ac7c798addadf33840f1307cd2977351938693909283928301918501908083836000831561226a578181015183820152602001612252565b60ff8316600214156128ee5760ff8516600081815260056020908152604080832054815163c8509d8160e01b815260048101958652602481019283528651604482015286516001600160a01b0390921695869563c8509d81958d958a9593949093606490910192918601918190849084905b8381101561264e578181015183820152602001612636565b50505050905090810190601f16801561267b5780820380516001836020036101000a031916815260200191505b509350505050600060405180830381600087803b15801561269b57600080fd5b505af19250505080156126ac575060015b6128ec576040516000815260443d10156126c857506000612763565b60046000803e60005160e01c6308c379a081146126e9576000915050612763565b60043d036004833e81513d60248201116001600160401b038211171561271457600092505050612763565b80830180516001600160401b03811115612735576000945050505050612763565b8060208301013d860181111561275357600095505050505050612763565b601f01601f191660405250925050505b8061276e5750612817565b816001600160a01b03167ff91a8f63e5b3e0e89e5f93e1915a7805f3c52d9a73b3c09769785c2c7bf87acf826040518080602001828103825283818151815260200191508051906020019080838360005b838110156127d75781810151838201526020016127bf565b50505050905090810190601f1680156128045780820380516001836020036101000a031916815260200191505b509250505060405180910390a2506128ec565b3d808015612841576040519150601f19603f3d011682016040523d82523d6000602084013e612846565b606091505b50816001600160a01b03167f63ac299d6332d1cc4e61b81e59bc00c0ac7c798addadf33840f1307cd2977351826040518080602001828103825283818151815260200191508051906020019080838360005b838110156128b0578181015183820152602001612898565b50505050905090810190601f1680156128dd5780820380516001836020036101000a031916815260200191505b509250505060405180910390a2505b505b60ff80861660009081526009602052604090205461100591636f93d2e6918a91339187911680612920575060ff881615155b604080516001600160e01b031960e088901b1681526001600160a01b039586166004820152939094166024840152604483019190915215156064820152905160848083019260209291908290030181600087803b15801561298057600080fd5b505af1158015612994573d6000803e3d6000fd5b505050506040513d60208110156129aa57600080fd5b50505050505050505050505b5050505050505050505050505050565b630100380081565b600981565b61100781565b61100681565b60005460ff1681565b3361100714612a285760405162461bcd60e51b815260040180806020018281038252602e815260200180614908602e913960400191505060405180910390fd5b600b5460ff1615612a6c576040805162461bcd60e51b81526020600482015260096024820152681cdd5cdc195b99195960ba1b604482015290519081900360640190fd5b612ad584848080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525050604080518082019091526012815271626174636853697a65466f724f7261636c6560701b602082015291506146129050565b15612b7057604080516020601f8401819004810282018101909252828152600091612b18918585808385018382808284376000920191909152506146f992505050565b90506127108111158015612b2d5750600a8110155b612b685760405162461bcd60e51b81526004018080602001828103825260328152602001806149806032913960400191505060405180910390fd5b60015561341a565b612bd984848080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152505060408051808201909152601281527118591913dc955c19185d1950da185b9b995b60721b602082015291506146129050565b15612d6157606082828080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152505082519293505060169091149050612c5c5760405162461bcd60e51b815260040180806020018281038252605a815260200180614821605a913960600191505060405180910390fd5b60018101516002820151601683015160ff82161590612c7a816146fe565b612ccb576040805162461bcd60e51b815260206004820152601960248201527f61646472657373206973206e6f74206120636f6e747261637400000000000000604482015290519081900360640190fd5b60ff8416600081815260056020908152604080832080546001600160a01b0319166001600160a01b038716908117909155808452600683528184208585528352818420805460ff199081166001179091556009909352818420805490931687151517909255519092917f7e3b6af43092577ee20e60eaa1d9b114a7031305c895ee7dd3ffe17196d2e1e091a3505050505061341a565b612dce84848080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525050604080518082019091526016815275195b98589b1953dc911a5cd8589b1950da185b9b995b60521b602082015291506146129050565b15612eff57606082828080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152505082519293505060029091149050612e515760405162461bcd60e51b815260040180806020018281038252604a815260200180614936604a913960600191505060405180910390fd5b600181810151600283015160ff80831660009081526005602052604090205492939192908316909114906001600160a01b03168015612ef5576001600160a01b038116600090815260066020908152604080832060ff881680855290835292819020805460ff1916861515908117909155815190815290517fa3132e3f9819fbddc7f0ed6d38d7feef59aa95112090b7c592f5cb5bc4aa4adc929181900390910190a25b505050505061341a565b612f6384848080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152505060408051808201909152600d81526c73757370656e6451756f72756d60981b602082015291506146129050565b156130985760028114612fa75760405162461bcd60e51b815260040180806020018281038252602d8152602001806148af602d913960400191505060405180910390fd5b6000612fea600284848080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152506146f992505050565b905060008161ffff16118015613004575060648161ffff16105b61304e576040805162461bcd60e51b8152602060048201526016602482015275696e76616c69642073757370656e642071756f72756d60501b604482015290519081900360640190fd5b604080516f14d554d411539117d41493d413d4d05360821b815281519081900360100190206000908152600d60205220805461ffff90921661ffff1990921691909117905561341a565b6130fb84848080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152505060408051808201909152600c81526b72656f70656e51756f72756d60a01b602082015291506146129050565b1561322e576002811461313f5760405162461bcd60e51b815260040180806020018281038252602c8152602001806148dc602c913960400191505060405180910390fd5b6000613182600284848080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152506146f992505050565b905060008161ffff1611801561319c575060648161ffff16105b6131e5576040805162461bcd60e51b8152602060048201526015602482015274696e76616c69642072656f70656e2071756f72756d60581b604482015290519081900360640190fd5b604080516e149153d4115397d41493d413d4d053608a1b8152815190819003600f0190206000908152600d60205220805461ffff90921661ffff1990921691909117905561341a565b61329984848080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152505060408051808201909152601481527363616e63656c5472616e7366657251756f72756d60601b602082015291506146129050565b156133dd57600281146132dd5760405162461bcd60e51b815260040180806020018281038252603481526020018061487b6034913960400191505060405180910390fd5b6000613320600284848080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152506146f992505050565b905060008161ffff1611801561333a575060648161ffff16105b61338b576040805162461bcd60e51b815260206004820152601e60248201527f696e76616c69642063616e63656c207472616e736665722071756f72756d0000604482015290519081900360640190fd5b604080517710d05390d15317d514905394d1915497d41493d413d4d05360421b815281519081900360180190206000908152600d60205220805461ffff90921661ffff1990921691909117905561341a565b6040805162461bcd60e51b815260206004820152600d60248201526c756e6b6e6f776e20706172616d60981b604482015290519081900360640190fd5b7f6cdb0ac70ab7f2e2d035cca5be60d89906f2dede7648ddbd7402189c1eeed17a848484846040518080602001806020018381038352878782818152602001925080828437600083820152601f01601f191690910184810383528581526020019050858580828437600083820152604051601f909101601f19169092018290039850909650505050505050a150505050565b6008602052600090815260409020546001600160401b031681565b7fc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a47081565b61100281565b60005460ff16613536576040805162461bcd60e51b815260206004820152601960248201526000805160206149b2833981519152604482015290519081900360640190fd5b6040805163569e4ed360e11b815233600482015290516000916110009163ad3c9da691602480820192602092909190829003018186803b15801561357957600080fd5b505afa15801561358d573d6000803e3d6000fd5b505050506040513d60208110156135a357600080fd5b505160408051633d42651560e11b8152905191925060009161100091637a84ca2a916004808301926020929190829003018186803b1580156135e457600080fd5b505afa1580156135f8573d6000803e3d6000fd5b505050506040513d602081101561360e57600080fd5b505190508061361b575060155b60008211801561362b5750808211155b61366a576040805162461bcd60e51b815260206004820152600b60248201526a1b9bdd0818d8589a5b995d60aa1b604482015290519081900360640190fd5b600b5460ff166136b1576040805162461bcd60e51b815260206004820152600d60248201526c1b9bdd081cdd5cdc195b991959609a1b604482015290519081900360640190fd5b604080516e149153d4115397d41493d413d4d053608a1b8152905190819003600f019020600090613702907fc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a4706140e3565b9050801561374057600b805460ff1916905560405133907f899fe8c37dc61708a3aaa99c4bf143346c1d1da69af79be9e8920c0a6785b75290600090a25b505050565b600660209081526000928352604080842090915290825290205460ff1681565b6040518060400160405280600381526020016269626360e81b81525081565b610e1081565b61100381565b60005460ff16156137e8576040805162461bcd60e51b815260206004820152601960248201527f74686520636f6e747261637420616c726561647920696e697400000000000000604482015290519081900360640190fd5b7f1471eb6eb2c5e789fc3de43f8ce62938c7d1836ec861730447e2ada8fd81017b80546001600160a01b0319908116611008179091557f92e85d02570a8092d09a6e3a57665bc3815a2699a4074001bf1ccabf660f5a36805460ff199081169091557fd8af288fc1c8680b4f4706064cf021e264efb6828fcaf7eb5ca36818eb365bcc8054821660019081179091557f89832631fb3c3307a103ba2c84ab569c64d6182a18893dcd163f0f1c2090733a805484166110049081179091557f6cde3cea4b3a3fb2488b2808bae7556f4a405e50f65e1794383bc026131b13c38054841690557f72e4efa1513b071517c6c74dba31b5934a81aa83cddd400e7081df5529c9943680548416831790557fa9bc9a3a348c357ba16b37005d7e6b3236198c0e939f4af8c5f19b8deeb8ebc08054851690911790557fc575c31fea594a6eb97c8e9d3f9caee4c16218c6ef37e923234c0fe9014a61e78054831690557f4e523af77f034e9810f1c94057f5e931fb3d16a51511a4c3add793617d18610580548316821790557ffb33122aa9f93cc639ebe80a7bc4784c11e6053dde89c6f4f7e268c6a623da1e805484166110001790557fc7694af312c4f286114180fd0ba6a52461fcee8a381636770b19a343af92538a80548316821790557f01112dd68e482ba8d68a7e828cff8b3abcea08eab88941953c180a7e650e9cd480548316821790557fc0a4a8be475dfebc377ebef2d7c4ff47656f572a08dd92b81017efcdba0febe1805484166110071790557f87e8a52529e8ece4ef759037313542a6429ff494a9fab9027fb79db90124eba680548316821790557f4c7666bbcb22d46469f7cc282f70764a7012dca2cce630ff8d83db9a9cdd48f080548316821790557f40f28f99a40bc9f6beea1013afdbc3cdcc689eb76b82c4de06c0acf1e1932ed58054909316611001179092557f0d9cf2cd531699eed8dd34e40ff2884a14a698c4898184fba85194e6f6772d248054821683179055600b60009081527f23f68c9bd22b8a93d06adabe17481c87c016bcbd20adc8bfd707a4d813a572176020527fdf0d5d05428057f5455c2dc8e810dd86d1e9350faa72f16bda8a45443c5b39328054831684179055603283556004805467ffffffffffffffff19166001600160401b031790556002819055600381905580549091169091179055565b6007602052600090815260409020546001600160401b031681565b60005460ff16613ba7576040805162461bcd60e51b815260206004820152601960248201526000805160206149b2833981519152604482015290519081900360640190fd5b6040805163569e4ed360e11b815233600482015290516000916110009163ad3c9da691602480820192602092909190829003018186803b158015613bea57600080fd5b505afa158015613bfe573d6000803e3d6000fd5b505050506040513d6020811015613c1457600080fd5b505160408051633d42651560e11b8152905191925060009161100091637a84ca2a916004808301926020929190829003018186803b158015613c5557600080fd5b505afa158015613c69573d6000803e3d6000fd5b505050506040513d6020811015613c7f57600080fd5b5051905080613c8c575060155b600082118015613c9c5750808211155b613cdb576040805162461bcd60e51b815260206004820152600b60248201526a1b9bdd0818d8589a5b995d60aa1b604482015290519081900360640190fd5b600b5460ff1615613d1f576040805162461bcd60e51b81526020600482015260096024820152681cdd5cdc195b99195960ba1b604482015290519081900360640190fd5b604080516f14d554d411539117d41493d413d4d05360821b81529051908190036010019020600090613d71907fc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a4706140e3565b905080156137405761374061401a565b60005460ff16613dc6576040805162461bcd60e51b815260206004820152601960248201526000805160206149b2833981519152604482015290519081900360640190fd5b33600090815260066020908152604080832060ff8089168552925290912054859116613e235760405162461bcd60e51b81526004018080602001828103825260318152602001806147f06031913960400191505060405180910390fd5b60ff85166000908152600760209081526040808320548151601f88018490048402810184019092528682526001600160401b031692613e889284928a9261208d92909189918c908c908190840183828082843760009201919091525061131c92505050565b60ff959095166000908152600760205260409020805467ffffffffffffffff191660019096016001600160401b03169590951790945550505050565b61100081565b600381565b61100481565b60408051600e808252818301909252606091630100380060ff851617918391602082018180368337505050600e81810187905260068201939093529182525090505b92915050565b600085613f2c57506000614011565b606082518451865160800101016040519080825280601f01601f191660200182016040528015613f63576020820181803683370190505b5090506000613f7182614704565b602080890151825201905086600080613f8989614098565b8086526020909501949092509050613fa28285836140a2565b92830192613faf88614098565b8086526020909501949092509050613fc88285836140a2565b9283018a815260200192613fdb87614098565b9092509050613feb8285836140a2565b508351602001613ff961470a565b60208183886065600019fa5051600114955050505050505b95945050505050565b600b5460ff161561405e576040805162461bcd60e51b81526020600482015260096024820152681cdd5cdc195b99195960ba1b604482015290519081900360640190fd5b600b805460ff1916600117905560405133907f6f123d3d54c84a7960a573b31c221dcd86e13fd849c5adb0c6ca851468cc1ae490600090a2565b8051602090910191565b5b602081106140c2578251825260209283019290910190601f19016140a3565b915181516020939093036101000a6000190180199091169216919091179052565b6000828152600d602052604081205461ffff166141ac57604080516f14d554d411539117d41493d413d4d05360821b815281519081900360100181206000908152600d6020818152848320805461ffff199081166001179091556e149153d4115397d41493d413d4d053608a1b8552855194859003600f01852084528282528584208054821660029081179091557710d05390d15317d514905394d1915497d41493d413d4d05360421b8652865195869003601801909520845291905292902080549092161790555b6000838152600c6020526040902080546201000090046001600160801b0316421015806141dd575082816001015414155b156142b0576000848152600d602090815260409182902054835461ffff90911661ffff199091161771ffffffffffffffffffffffffffffffff0000191662010000610e1042016001600160801b0316021783556001808401869055825191820190925233815261425291600284019190614728565b5080546040805161ffff83168152620100009092046001600160801b0316602083015281810185905251339186917f9e109f0e55ef32e99e4880be2ec357f1ddb3469c79d0747ef4762da6e89fabe5916060908290030190a3614364565b60005b600282015481101561433b57336001600160a01b03168260020182815481106142d857fe5b6000918252602090912001546001600160a01b03161415614333576040805162461bcd60e51b815260206004820152601060248201526f185b1c9958591e48185c1c1c9bdd995960821b604482015290519081900360640190fd5b6001016142b3565b50600281018054600181018255600091825260209091200180546001600160a01b031916331790555b8054600282015461ffff909116116143be576000848152600c60205260408120805471ffffffffffffffffffffffffffffffffffff1916815560018101829055906143b2600283018261478d565b50506001915050613f17565b5060009392505050565b600080600060606021855110156143f8575050604080516000808252602082019092529092508291508190614471565b600185015160218601518651604080516020198301808252601f1960011990940193909316810160200190915260418901939291606091908015614443576020820181803683370190505b509050600061445182614098565b509050614463858260218d51036140a2565b506001975091955093509150505b9193509193565b600b5460ff16156144bc576040805162461bcd60e51b81526020600482015260096024820152681cdd5cdc195b99195960ba1b604482015290519081900360640190fd5b6002544311156144fb576004805467ffffffffffffffff1981166001600160401b036001600793840b810190930b16179091556003554360025561453c565b6003805460019081019182905554101561453c576004805467ffffffffffffffff1981166001600160401b036001600793840b810190930b16179091556003555b8160ff16836001600160401b0316600460009054906101000a900460070b6001600160401b03167f3a6e0fc61675aa2a100bcba0568368bb92bcec91c97673391074f11138f0cffe603885604051808361ffff1661ffff16815260200180602001828103825283818151815260200191508051906020019080838360005b838110156145d25781810151838201526020016145ba565b50505050905090810190601f1680156145ff5780820380516001836020036101000a031916815260200191505b50935050505060405180910390a4505050565b6000816040516020018082805190602001908083835b602083106146475780518252601f199092019160209182019101614628565b6001836020036101000a03801982511681845116808217855250505050505090500191505060405160208183030381529060405280519060200120836040516020018082805190602001908083835b602083106146b55780518252601f199092019160209182019101614696565b6001836020036101000a0380198251168184511680821785525050505050509050019150506040516020818303038152906040528051906020012014905092915050565b015190565b3b151590565b60200190565b60405180602001604052806001906020820280368337509192915050565b82805482825590600052602060002090810192821561477d579160200282015b8281111561477d57825182546001600160a01b0319166001600160a01b03909116178255602090920191600190910190614748565b506147899291506147ae565b5090565b50805460008255906000526020600020908101906147ab91906147d5565b50565b6147d291905b808211156147895780546001600160a01b03191681556001016147b4565b90565b6147d291905b8082111561478957600081556001016147db56fe74686520636f6e747261637420616e64206368616e6e656c2068617665206e6f74206265656e20726567697374657265646c656e677468206f662076616c756520666f72206164644f725570646174654368616e6e656c2073686f756c642062652032322c206368616e6e656c49643a697346726f6d53797374656d3a68616e646c6572416464726573736c656e677468206f662076616c756520666f722063616e63656c5472616e7366657251756f72756d2073686f756c6420626520326c656e677468206f662076616c756520666f722073757370656e6451756f72756d2073686f756c6420626520326c656e677468206f662076616c756520666f722072656f70656e51756f72756d2073686f756c642062652032746865206d6573736167652073656e646572206d75737420626520676f7665726e616e636520636f6e74726163746c656e677468206f662076616c756520666f7220656e61626c654f7244697361626c654368616e6e656c2073686f756c6420626520322c206368616e6e656c49643a6973456e61626c65746865206e6577426174636853697a65466f724f7261636c652073686f756c6420626520696e205b31302c2031303030305d74686520636f6e7472616374206e6f7420696e697420796574000000000000006c6967687420636c69656e74206e6f742073796e632074686520626c6f636b20796574a2646970667358221220622dd2ff8c5505e7bf8251c7cfe63da6bfa7891c3682ca46b6d6bf796895609f64736f6c63430006040033", + }, + }, + } + + LubanUpgrade[networkname.ChapelChainName] = &Upgrade{ + UpgradeName: "luban", + Configs: []*UpgradeConfig{ + { + ContractAddr: ValidatorContract, + CommitUrl: "https://github.com/bnb-chain/bsc-genesis-contract/commit/b144718e94d7a1ebb24a7103202300f08826f369", + Code: "60806040526004361061046c5760003560e01c8063862498821161024a578063c6d3394511610139578063e40716a1116100b6578063f9a2bbc71161007a578063f9a2bbc714610b6b578063fc3e590814610b80578063fccc281314610b95578063fd4ad81f14610baa578063fd6a687914610bd957610473565b8063e40716a114610af9578063eb57e20214610b0e578063eda5868c14610b2e578063f340fa0114610b43578063f92eb86b14610b5657610473565b8063d86222d5116100fd578063d86222d514610a90578063daacdb6614610aa5578063dc927faf14610aba578063e086c7b114610acf578063e1c7392a14610ae457610473565b8063c6d3394514610a3c578063c81b166214610a51578063c8509d811461085f578063d04aa99614610a66578063d68fb56a14610a7b57610473565b8063a5422d5c116101c7578063ad3c9da61161018b578063ad3c9da6146109d0578063aef198a9146109f0578063b7ab4db514610a05578063b8cf4ef114610a27578063bf9f49951461062f57610473565b8063a5422d5c1461095c578063a78abc1614610971578063aaf5eb6814610986578063ab51bb961461099b578063ac431751146109b057610473565b806396713da91161020e57806396713da9146108f35780639dc09262146109085780639fe0f8161461091d578063a0dc275814610932578063a1a11bf51461094757610473565b8063862498821461087f57806388b32f11146108945780638b5ad0c9146108a95780638d19a410146108be5780639369d7de146108de57610473565b80634df6e0c3116103665780636e47b482116102e35780637942fd05116102a75780637942fd05146108205780637a84ca2a1461083557806381650b621461084a578063831d65d11461085f578063853230aa1461080b57610473565b80636e47b482146107b757806370fd5bad146107cc578063718a8aa8146107e157806375d47a0a146107f657806378dfed4a1461080b57610473565b8063565c56b31161032a578063565c56b3146107265780635667515a146107465780635d77156c1461075b57806362b72cf5146107705780636969a25c1461078557610473565b80634df6e0c3146106b25780635192c82c146106c757806351e80672146106dc578063549b03f2146106f157806355614fcc1461070657610473565b8063321d398a116103f45780633dffc387116103b85780633dffc3871461062f57806343756e5c1461065157806345cf9daf14610666578063493279b11461067b5780634bf6c8821461069d57610473565b8063321d398a146105975780633365af3a146105b757806335409f7f146105d75780633b071dcc146105f75780633de0f0d81461061a57610473565b80631182b8751161043b5780631182b875146104fe578063152ad3b81461052b5780631ff180691461054d578063219f22d514610562578063300c35671461057757610473565b806304c4fec61461047857806307a568471461048f5780630bee7a67146104ba5780630e2374a5146104dc57610473565b3661047357005b600080fd5b34801561048457600080fd5b5061048d610bee565b005b34801561049b57600080fd5b506104a4610c60565b6040516104b19190616ef0565b60405180910390f35b3480156104c657600080fd5b506104cf610c66565b6040516104b19190616f1a565b3480156104e857600080fd5b506104f1610c6b565b6040516104b191906162f7565b34801561050a57600080fd5b5061051e6105193660046161dd565b610c71565b6040516104b1919061646e565b34801561053757600080fd5b50610540610ea9565b6040516104b19190616463565b34801561055957600080fd5b506104a4610eb2565b34801561056e57600080fd5b506104cf610eb8565b34801561058357600080fd5b5061048d6105923660046160a6565b610ebd565b3480156105a357600080fd5b506105406105b236600461618a565b611241565b3480156105c357600080fd5b506105406105d236600461618a565b611310565b3480156105e357600080fd5b5061048d6105f236600461607f565b6113c1565b34801561060357600080fd5b5061060c61151a565b6040516104b1929190616379565b34801561062657600080fd5b506104a46117f6565b34801561063b57600080fd5b506106446117fc565b6040516104b19190616f2b565b34801561065d57600080fd5b506104f1611801565b34801561067257600080fd5b506104a4611807565b34801561068757600080fd5b5061069061180d565b6040516104b19190616ee1565b3480156106a957600080fd5b50610644611812565b3480156106be57600080fd5b5061060c611817565b3480156106d357600080fd5b506104a4611995565b3480156106e857600080fd5b506104f161199b565b3480156106fd57600080fd5b506104a46119a1565b34801561071257600080fd5b5061054061072136600461607f565b6119a7565b34801561073257600080fd5b506104a461074136600461607f565b6119dc565b34801561075257600080fd5b50610644611a2d565b34801561076757600080fd5b506104cf611a32565b34801561077c57600080fd5b506104a4611a37565b34801561079157600080fd5b506107a56107a036600461618a565b611a3d565b6040516104b196959493929190616324565b3480156107c357600080fd5b506104f1611aa1565b3480156107d857600080fd5b50610644611aa7565b3480156107ed57600080fd5b50610644611aac565b34801561080257600080fd5b506104f1611ab1565b34801561081757600080fd5b506104a4611ab7565b34801561082c57600080fd5b50610644611abd565b34801561084157600080fd5b506104a4611ac2565b34801561085657600080fd5b506104cf611ac8565b34801561086b57600080fd5b5061048d61087a3660046161dd565b611acd565b34801561088b57600080fd5b506104a4611b2e565b3480156108a057600080fd5b506104a4611b34565b3480156108b557600080fd5b506104a4611b3a565b3480156108ca57600080fd5b506104a46108d936600461607f565b611b40565b3480156108ea57600080fd5b5061048d611b80565b3480156108ff57600080fd5b50610644611c94565b34801561091457600080fd5b506104f1611c99565b34801561092957600080fd5b506104a4611c9f565b34801561093e57600080fd5b506104a4611ca4565b34801561095357600080fd5b506104f1611ca9565b34801561096857600080fd5b5061051e611caf565b34801561097d57600080fd5b50610540611cce565b34801561099257600080fd5b506104a4611cd7565b3480156109a757600080fd5b506104cf611a2d565b3480156109bc57600080fd5b5061048d6109cb36600461612e565b611ce0565b3480156109dc57600080fd5b506104a46109eb36600461607f565b61258c565b3480156109fc57600080fd5b506104a461259e565b348015610a1157600080fd5b50610a1a6125ab565b6040516104b19190616366565b348015610a3357600080fd5b506104a4612697565b348015610a4857600080fd5b506104a4611aa7565b348015610a5d57600080fd5b506104f161269c565b348015610a7257600080fd5b506104a46126a2565b348015610a8757600080fd5b506104a46126a7565b348015610a9c57600080fd5b506104a46126e6565b348015610ab157600080fd5b506104a46126f2565b348015610ac657600080fd5b506104f16126f8565b348015610adb57600080fd5b506104a46126fe565b348015610af057600080fd5b5061048d612703565b348015610b0557600080fd5b506104a46128b2565b348015610b1a57600080fd5b5061048d610b2936600461607f565b6128b8565b348015610b3a57600080fd5b506104cf6129c0565b61048d610b5136600461607f565b6129c5565b348015610b6257600080fd5b506104a4612c4d565b348015610b7757600080fd5b506104f1612c53565b348015610b8c57600080fd5b50610644611c9f565b348015610ba157600080fd5b506104f1612c59565b348015610bb657600080fd5b50610bca610bc536600461618a565b612c5f565b6040516104b193929190616ef9565b348015610be557600080fd5b506104f1612d21565b6000610bf933611b40565b9050600b8181548110610c0857fe5b600091825260209091206001601690920201015460ff16610c445760405162461bcd60e51b8152600401610c3b90616b99565b60405180910390fd5b6000610c4e6126a7565b9050610c5b338383612d27565b505050565b60095481565b606481565b61200181565b60005460609060ff16610c965760405162461bcd60e51b8152600401610c3b9061662d565b3361200014610cb75760405162461bcd60e51b8152600401610c3b90616d78565b600b54610d7557610cc6615d6b565b60015460005b81811015610d7157600b8054600181018255600091909152835160008051602061714e833981519152601690920291820190815560208086015160008051602061718e8339815191528401805460ff1916911515919091179055604086015180518794610d4d9360008051602061716e833981519152909101920190615d9a565b506060820151610d639060038301906013615e14565b505050806001019050610ccc565b5050505b610d7d615e41565b6000610dbe85858080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250612f1392505050565b9150915080610dda57610dd160646130cf565b92505050610ea2565b815160009060ff16610dff57610df883602001518460400151613130565b9050610e6e565b825160ff1660011415610e6a57826020015151600114610e445760008051602061712e833981519152604051610e3490616a80565b60405180910390a1506067610e65565b610df88360200151600081518110610e5857fe5b6020026020010151613d84565b610e6e565b5060655b63ffffffff8116610e935750506040805160008152602081019091529150610ea29050565b610e9c816130cf565b93505050505b9392505050565b60075460ff1681565b60035481565b606881565b334114610edc5760405162461bcd60e51b8152600401610c3b90616dc7565b6010544311610efd5760405162461bcd60e51b8152600401610c3b90616789565b60005460ff16610f1f5760405162461bcd60e51b8152600401610c3b9061662d565b600f54610f37576032600f5561100231601155611237565b60006110023168056bc75e2d63100000811115610f6657610f5f81606463ffffffff613efb16565b9150610faf565b601154811115610fa857610f5f6064610f9c600f54610f9060115486613f3d90919063ffffffff16565b9063ffffffff613f7f16565b9063ffffffff613efb16565b5050611237565b6040516309a99b4f60e41b815261100290639a99b4f090610fd6903090869060040161630b565b602060405180830381600087803b158015610ff057600080fd5b505af1158015611004573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061102891906161a2565b6110023160115591508161103d575050611237565b6000805b8481101561106b5785858281811061105557fe5b9050602002013582019150806001019050611041565b508061107957505050611237565b6000806000805b8981101561122f578489898381811061109557fe5b905060200201358802816110a557fe5b0493508a8a828181106110b457fe5b90506020020160208101906110c9919061607f565b6001600160a01b038116600090815260046020526040902054909350915081156111e55760006001808403815481106110fe57fe5b9060005260206000209060040201905080600201601c9054906101000a900460ff161561116b57836001600160a01b03167fb9c75cbbfde137c4281689580799ef5f52144e78858f776a5979b2b212137d858660405161115e9190616ef0565b60405180910390a26111df565b60035461117e908663ffffffff613fb916565b6003908155810154611196908663ffffffff613fb916565b60038201556040516001600160a01b038516907fcb0aad6cf9cd03bdf6137e359f541c42f38b39f007cae8e89e88aa7d8c6617b2906111d6908890616ef0565b60405180910390a25b50611227565b826001600160a01b03167fb9c75cbbfde137c4281689580799ef5f52144e78858f776a5979b2b212137d858560405161121e9190616ef0565b60405180910390a25b600101611080565b505050505050505b5050436010555050565b60015460009082106112555750600061130b565b60006001600160a01b03166001838154811061126d57fe5b60009182526020909120600490910201546001600160a01b0316148061129d5750600854158061129d5750600a54155b806112ac575060085460095410155b806112bd57506112bb82611310565b155b806112e657506000600b83815481106112d257fe5b906000526020600020906016020160000154115b806112fa575060016112f66125ab565b5111155b156113075750600061130b565b5060015b919050565b60015460009082106113245750600061130b565b600b548210611361576001828154811061133a57fe5b9060005260206000209060040201600201601c9054906101000a900460ff1615905061130b565b6001828154811061136e57fe5b9060005260206000209060040201600201601c9054906101000a900460ff161580156113bb5750600b82815481106113a257fe5b600091825260209091206001601690920201015460ff16155b92915050565b33611001146113e25760405162461bcd60e51b8152600401610c3b90616e98565b600b546114a0576113f1615d6b565b60015460005b8181101561149c57600b8054600181018255600091909152835160008051602061714e833981519152601690920291820190815560208086015160008051602061718e8339815191528401805460ff19169115159190911790556040860151805187946114789360008051602061716e833981519152909101920190615d9a565b50606082015161148e9060038301906013615e14565b5050508060010190506113f7565b5050505b6001600160a01b038116600090815260046020526040902054806114c45750611517565b6001810390506000600b82815481106114d957fe5b600091825260209091206001601690920201015460ff1690506114fc8383613fde565b80156115055750805b15610c5b576009805460001901905550505b50565b60015460609081906000805b8281101561156d576001818154811061153b57fe5b9060005260206000209060040201600201601c9054906101000a900460ff16611565576001909101905b600101611526565b5060608160405190808252806020026020018201604052801561159a578160200160208202803683370190505b5090506060826040519080825280602002602001820160405280156115d357816020015b60608152602001906001900390816115be5790505b50600b546000945090915084141561174e5760005b8481101561174857600181815481106115fd57fe5b9060005260206000209060040201600201601c9054906101000a900460ff16611740576001818154811061162d57fe5b600091825260209091206004909102015483516001600160a01b039091169084908690811061165857fe5b60200260200101906001600160a01b031690816001600160a01b031681525050600b818154811061168557fe5b600091825260209182902060026016909202018101805460408051601f60001961010060018616150201909316949094049182018590048502840185019052808352919290919083018282801561171d5780601f106116f25761010080835404028352916020019161171d565b820191906000526020600020905b81548152906001019060200180831161170057829003601f168201915b505050505082858151811061172e57fe5b60209081029190910101526001909301925b6001016115e8565b506117ea565b60005b848110156117e8576001818154811061176657fe5b9060005260206000209060040201600201601c9054906101000a900460ff166117e0576001818154811061179657fe5b600091825260209091206004909102015483516001600160a01b03909116908490869081106117c157fe5b6001600160a01b03909216602092830291909101909101526001909301925b600101611751565b505b909450925050505b9091565b61271081565b600181565b61100181565b60085481565b606181565b600881565b600e54600c5460609182918061182b575060155b60606118356125ab565b9050606061184282614391565b9050828251116118595790945092506117f2915050565b8383835103101561186b578282510393505b83156118a15760c8430461188783838388880360008a8a6144ff565b61189f8383838888038989038a8b8b8b5103016144ff565b505b6060836040519080825280602002602001820160405280156118cd578160200160208202803683370190505b50905060608460405190808252806020026020018201604052801561190657816020015b60608152602001906001900390816118f15790505b50905060005b858110156119875784818151811061192057fe5b602002602001015183828151811061193457fe5b60200260200101906001600160a01b031690816001600160a01b03168152505083818151811061196057fe5b602002602001015182828151811061197457fe5b602090810291909101015260010161190c565b509096509450505050509091565b60065481565b61200081565b600f5481565b6001600160a01b038116600090815260046020526040812054806119cf57600091505061130b565b60001901610ea281611310565b6001600160a01b03811660009081526004602052604081205480611a0457600091505061130b565b600180820381548110611a1357fe5b906000526020600020906004020160030154915050919050565b600081565b606781565b60105481565b60018181548110611a4a57fe5b600091825260209091206004909102018054600182015460028301546003909301546001600160a01b0392831694509082169291821691600160a01b81046001600160401b031691600160e01b90910460ff169086565b61100581565b600281565b601081565b61100881565b6103e881565b600b81565b600c5481565b606681565b3361200014611aee5760405162461bcd60e51b8152600401610c3b90616d78565b7f41ce201247b6ceb957dcdb217d0b8acb50b9ea0e12af9af4f5e7f38902101605838383604051611b2193929190616f39565b60405180910390a1505050565b60025481565b60115481565b600a5481565b6001600160a01b03811660009081526004602052604081205480611b765760405162461bcd60e51b8152600401610c3b90616d00565b6000190192915050565b600b54611c3e57611b8f615d6b565b60015460005b81811015611c3a57600b8054600181018255600091909152835160008051602061714e833981519152601690920291820190815560208086015160008051602061718e8339815191528401805460ff1916911515919091179055604086015180518794611c169360008051602061716e833981519152909101920190615d9a565b506060820151611c2c9060038301906013615e14565b505050806001019050611b95565b5050505b600854611c4b5760036008555b600a54611c58576002600a555b6000611c6333611b40565b9050611c6e81611241565b611c8a5760405162461bcd60e51b8152600401610c3b90616a3d565b6115173382614656565b600981565b61100781565b600381565b60c881565b61100681565b604051806101e001604052806101ab8152602001616f836101ab913981565b60005460ff1681565b6402540be40081565b60005460ff16611d025760405162461bcd60e51b8152600401610c3b9061662d565b3361100714611d235760405162461bcd60e51b8152600401610c3b90616b06565b611d8d84848080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525050604080518082019091526013815272065787069726554696d655365636f6e6447617606c1b602082015291506146ee9050565b15611e2a5760208114611db25760405162461bcd60e51b8152600401610c3b90616cba565b604080516020601f8401819004810282018101909252828152600091611df09185858083850183828082843760009201919091525061474792505050565b905060648110158015611e065750620186a08111155b611e225760405162461bcd60e51b8152600401610c3b906168e6565b600255612549565b611e8a84848080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250506040805180820190915260098152686275726e526174696f60b81b602082015291506146ee9050565b15611f265760208114611eaf5760405162461bcd60e51b8152600401610c3b906164b3565b604080516020601f8401819004810282018101909252828152600091611eed9185858083850183828082843760009201919091525061474792505050565b9050612710811115611f115760405162461bcd60e51b8152600401610c3b906167cb565b6006556007805460ff19166001179055612549565b611f9084848080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250506040805180820190915260138152726d61784e756d4f664d61696e7461696e696e6760681b602082015291506146ee9050565b1561202a5760208114611fb55760405162461bcd60e51b8152600401610c3b906164ea565b604080516020601f8401819004810282018101909252828152600091611ff39185858083850183828082843760009201919091525061474792505050565b600c5490915080612002575060155b8082106120215760405162461bcd60e51b8152600401610c3b9061683e565b50600855612549565b61209384848080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250506040805180820190915260128152716d61696e7461696e536c6173685363616c6560701b602082015291506146ee9050565b1561212c57602081146120b85760405162461bcd60e51b8152600401610c3b906165b3565b604080516020601f84018190048102820181019092528281526000916120f69185858083850183828082843760009201919091525061474792505050565b90506000811180156121085750600a81105b6121245760405162461bcd60e51b8152600401610c3b90616e14565b600a55612549565b6121a084848080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152505060408051808201909152601981527f6d61784e756d4f66576f726b696e6743616e6469646174657300000000000000602082015291506146ee9050565b1561222f57602081146121c55760405162461bcd60e51b8152600401610c3b90616567565b604080516020601f84018190048102820181019092528281526000916122039185858083850183828082843760009201919091525061474792505050565b9050600d548111156122275760405162461bcd60e51b8152600401610c3b9061695c565b600e55612549565b61229884848080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250506040805180820190915260128152716d61784e756d4f6643616e6469646174657360701b602082015291506146ee9050565b1561231a57602081146122bd5760405162461bcd60e51b8152600401610c3b90616b54565b604080516020601f84018190048102820181019092528281526000916122fb9185858083850183828082843760009201919091525061474792505050565b600d819055600e5490915081101561231457600d54600e555b50612549565b61237e84848080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152505060408051808201909152600d81526c6e756d4f66436162696e65747360981b602082015291506146ee9050565b1561242c57602081146123a35760405162461bcd60e51b8152600401610c3b906165f8565b604080516020601f84018190048102820181019092528281526000916123e19185858083850183828082843760009201919091525061474792505050565b9050600081116124035760405162461bcd60e51b8152600401610c3b9061669b565b60298111156124245760405162461bcd60e51b8152600401610c3b906166e3565b600c55612549565b61249684848080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152505060408051808201909152601381527266696e616c697479526577617264526174696f60681b602082015291506146ee9050565b1561253157602081146124bb5760405162461bcd60e51b8152600401610c3b90616c3d565b604080516020601f84018190048102820181019092528281526000916124f99185858083850183828082843760009201919091525061474792505050565b90506001811015801561250d575060648111155b6125295760405162461bcd60e51b8152600401610c3b906169cb565b600f55612549565b60405162461bcd60e51b8152600401610c3b90616e71565b7f6cdb0ac70ab7f2e2d035cca5be60d89906f2dede7648ddbd7402189c1eeed17a8484848460405161257e9493929190616481565b60405180910390a150505050565b60046020526000908152604090205481565b68056bc75e2d6310000081565b6001546060906000805b828110156125da576125c681611310565b156125d2578160010191505b6001016125b5565b50606081604051908082528060200260200182016040528015612607578160200160208202803683370190505b5090506000915060005b8381101561268e5761262281611310565b15612686576001818154811061263457fe5b600091825260209091206004909102015482516001600160a01b039091169083908590811061265f57fe5b60200260200101906001600160a01b031690816001600160a01b0316815250508260010192505b600101612611565b50925050505b90565b601581565b61100281565b603281565b60006126b16125ab565b519050600080600c54116126c65760156126ca565b600c545b9050808211156126d8578091505b816126e257600191505b5090565b67016345785d8a000081565b60055481565b61100381565b602981565b60005460ff16156127265760405162461bcd60e51b8152600401610c3b90616c06565b61272e615e41565b6000612754604051806101e001604052806101ab8152602001616f836101ab9139612f13565b91509150806127755760405162461bcd60e51b8152600401610c3b90616d37565b60005b82602001515181101561289a5760018360200151828151811061279757fe5b60209081029190910181015182546001818101855560009485528385208351600493840290910180546001600160a01b039283166001600160a01b03199182161782558587015182850180549185169183169190911790556040860151600283018054606089015160808a01511515600160e01b0260ff60e01b196001600160401b03909216600160a01b0267ffffffffffffffff60a01b199590981692909516919091179290921694909417161790915560a09093015160039093019290925591860151805191850193918590811061286d57fe5b602090810291909101810151516001600160a01b0316825281019190915260400160002055600101612778565b50506103e8600255506000805460ff19166001179055565b600d5481565b33611001146128d95760405162461bcd60e51b8152600401610c3b90616e98565b600b54612997576128e8615d6b565b60015460005b8181101561299357600b8054600181018255600091909152835160008051602061714e833981519152601690920291820190815560208086015160008051602061718e8339815191528401805460ff191691151591909117905560408601518051879461296f9360008051602061716e833981519152909101920190615d9a565b5060608201516129859060038301906013615e14565b5050508060010190506128ee565b5050505b60006129a28261474c565b90506129ad81611241565b156129bc576129bc8282614656565b5050565b606581565b3341146129e45760405162461bcd60e51b8152600401610c3b90616dc7565b60005460ff16612a065760405162461bcd60e51b8152600401610c3b9061662d565b60003411612a265760405162461bcd60e51b8152600401610c3b9061692d565b6001600160a01b0381166000908152600460205260409020546007543491906103e89060ff1615612a5657506006545b600083118015612a665750600081115b15612b07576000612a83612710610f9c868563ffffffff613f7f16565b90508015612b055760405161dead9082156108fc029083906000818181858888f19350505050158015612aba573d6000803e3d6000fd5b507f627059660ea01c4733a328effb2294d2f86905bf806da763a89cee254de8bee581604051612aea9190616ef0565b60405180910390a1612b02848263ffffffff613f3d16565b93505b505b8115612c05576000600180840381548110612b1e57fe5b9060005260206000209060040201905080600201601c9054906101000a900460ff1615612b8b57846001600160a01b03167ff177e5d6c5764d79c32883ed824111d9b13f5668cf6ab1cc12dd36791dd955b485604051612b7e9190616ef0565b60405180910390a2612bff565b600354612b9e908563ffffffff613fb916565b6003908155810154612bb6908563ffffffff613fb916565b60038201556040516001600160a01b038616907f93a090ecc682c002995fad3c85b30c5651d7fd29b0be5da9d784a3302aedc05590612bf6908790616ef0565b60405180910390a25b50612c47565b836001600160a01b03167ff177e5d6c5764d79c32883ed824111d9b13f5668cf6ab1cc12dd36791dd955b484604051612c3e9190616ef0565b60405180910390a25b50505050565b600e5481565b61100081565b61dead81565b600b8181548110612c6c57fe5b6000918252602091829020601691909102018054600180830154600280850180546040805161010096831615969096026000190190911692909204601f810188900488028501880190925281845293965060ff90911694919291830182828015612d175780601f10612cec57610100808354040283529160200191612d17565b820191906000526020600020905b815481529060010190602001808311612cfa57829003601f168201915b5050505050905083565b61100481565b6000600a5460001480612d38575081155b80612d435750600954155b15612d5057506000610ea2565b60096000815460019003919050819055506000612d9b600a54610f9c85610f9c600b8981548110612d7d57fe5b6000918252602090912060169091020154439063ffffffff613f3d16565b90506000600b8581548110612dac57fe5b906000526020600020906016020160010160006101000a81548160ff0219169083151502179055506000806110016001600160a01b0316638256ace66040518163ffffffff1660e01b8152600401604080518083038186803b158015612e1157600080fd5b505afa158015612e25573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612e4991906161ba565b9150915060009350808310612ec357612e628787613fde565b506040516305bfb49960e41b815261100190635bfb499090612e88908a906004016162f7565b600060405180830381600087803b158015612ea257600080fd5b505af1158015612eb6573d6000803e3d6000fd5b5050505060019350612ed5565b818310612ed557612ed38761474c565b505b6040516001600160a01b038816907fb9d38178dc641ff1817967a63c9078cbcd955a9f1fcd75e0e3636de615d44d3b90600090a25050509392505050565b612f1b615e41565b6000612f25615e41565b612f2d615e65565b612f3e612f39866148ef565b614914565b90506000805b612f4d8361495e565b156130c15780612f7257612f68612f638461497f565b6149cd565b60ff1684526130b9565b80600114156130b4576060612f8e612f898561497f565b614a4d565b90508051604051908082528060200260200182016040528015612fcb57816020015b612fb8615e85565b815260200190600190039081612fb05790505b508560200181905250805160405190808252806020026020018201604052801561300957816020015b6060815260200190600190039081612ff45790505b50604086015260005b81518110156130a957613023615e85565b6060600061304385858151811061303657fe5b6020026020010151614b1e565b92509250925080613063578860009a509a505050505050505050506130ca565b828960200151858151811061307457fe5b6020026020010181905250818960400151858151811061309057fe5b6020026020010181905250505050806001019050613012565b5060019250506130b9565b6130c1565b600101612f44565b50919350909150505b915091565b604080516001808252818301909252606091829190816020015b60608152602001906001900390816130e957905050905061310f8363ffffffff16614c38565b8160008151811061311c57fe5b6020026020010181905250610ea281614c4b565b60006029835111156131675760008051602061712e83398151915260405161315790616740565b60405180910390a15060666113bb565b60005b83518110156132055760005b818110156131fc5784818151811061318a57fe5b6020026020010151600001516001600160a01b03168583815181106131ab57fe5b6020026020010151600001516001600160a01b031614156131f45760008051602061712e8339815191526040516131e19061689b565b60405180910390a16066925050506113bb565b600101613176565b5060010161316a565b506060806132138585614cd5565b60015491935091506000908190815b818110156132985767016345785d8a00006001828154811061324057fe5b9060005260206000209060040201600301541061326257836001019350613290565b60006001828154811061327157fe5b9060005260206000209060040201600301541115613290578260010192505b600101613222565b506060836040519080825280602002602001820160405280156132c5578160200160208202803683370190505b5090506060846040519080825280602002602001820160405280156132f4578160200160208202803683370190505b509050606085604051908082528060200260200182016040528015613323578160200160208202803683370190505b509050606086604051908082528060200260200182016040528015613352578160200160208202803683370190505b5090506000606087604051908082528060200260200182016040528015613383578160200160208202803683370190505b5090506060886040519080825280602002602001820160405280156133b2578160200160208202803683370190505b509050600099506000985060006110046001600160a01b031663149d14d96040518163ffffffff1660e01b815260040160206040518083038186803b1580156133fa57600080fd5b505afa15801561340e573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061343291906161a2565b905067016345785d8a000081111561347d5760008051602061712e83398151915260405161345f90616bc5565b60405180910390a160689d50505050505050505050505050506113bb565b60005b898110156136ee5767016345785d8a00006001828154811061349e57fe5b9060005260206000209060040201600301541061362357600181815481106134c257fe5b906000526020600020906004020160020160009054906101000a90046001600160a01b0316898d815181106134f357fe5b60200260200101906001600160a01b031690816001600160a01b03168152505060006402540be4006001838154811061352857fe5b9060005260206000209060040201600301548161354157fe5b066001838154811061354f57fe5b9060005260206000209060040201600301540390506135778382613f3d90919063ffffffff16565b898e8151811061358357fe5b6020026020010181815250506001828154811061359c57fe5b906000526020600020906004020160020160009054906101000a90046001600160a01b0316878e815181106135cd57fe5b60200260200101906001600160a01b031690816001600160a01b03168152505081888e815181106135fa57fe5b6020908102919091010152613615868263ffffffff613fb916565b95508c6001019c50506136e6565b60006001828154811061363257fe5b90600052602060002090600402016003015411156136e6576001818154811061365757fe5b906000526020600020906004020160010160009054906101000a90046001600160a01b0316848c8151811061368857fe5b60200260200101906001600160a01b031690816001600160a01b031681525050600181815481106136b557fe5b906000526020600020906004020160030154838c815181106136d357fe5b6020026020010181815250508a6001019a505b600101613480565b5060008415613964576002546040516303702b2960e51b815261100491636e056520918891613728918e918e918d914201906004016163e9565b6020604051808303818588803b15801561374157600080fd5b505af193505050508015613772575060408051601f3d908101601f1916820190925261376f9181019061610e565b60015b6138e9576040516000815260443d101561378e57506000613829565b60046000803e60005160e01c6308c379a081146137af576000915050613829565b60043d036004833e81513d60248201116001600160401b03821117156137da57600092505050613829565b80830180516001600160401b038111156137fb576000945050505050613829565b8060208301013d860181111561381957600095505050505050613829565b601f01601f191660405250925050505b806138345750613876565b60019150857fa7cdeed7d0db45e3219a6e5d60838824c16f1d39991fcfe3f963029c844bf28082604051613868919061646e565b60405180910390a2506138e4565b3d8080156138a0576040519150601f19603f3d011682016040523d82523d6000602084013e6138a5565b606091505b5060019150857fbfa884552dd8921b6ce90bfe906952ae5b3b29be0cc1a951d4f62697635a3a45826040516138da919061646e565b60405180910390a2505b613964565b801561392b577fa217d08e65f80c73121cd9db834d81652d544bfbf452f6d04922b16c90a37b708660405161391e9190616ef0565b60405180910390a1613962565b857fa7cdeed7d0db45e3219a6e5d60838824c16f1d39991fcfe3f963029c844bf28060405161395990616530565b60405180910390a25b505b8015613b1a5760005b8751811015613b1857600088828151811061398457fe5b6020026020010151905060006001828154811061399d57fe5b60009182526020909120600160049092020181015481546001600160a01b03909116916108fc91859081106139ce57fe5b9060005260206000209060040201600301549081150290604051600060405180830381858888f1935050505090508015613a8a5760018281548110613a0f57fe5b60009182526020909120600160049092020181015481546001600160a01b03909116917f6c61d60f69a7beb3e1c80db7f39f37b208537cbb19da3174511b477812b2fc7d9185908110613a5e57fe5b906000526020600020906004020160030154604051613a7d9190616ef0565b60405180910390a2613b0e565b60018281548110613a9757fe5b60009182526020909120600160049092020181015481546001600160a01b03909116917f25d0ce7d2f0cec669a8c17efe49d195c13455bb8872b65fa610ac7f53fe4ca7d9185908110613ae657fe5b906000526020600020906004020160030154604051613b059190616ef0565b60405180910390a25b505060010161396d565b505b835115613c645760005b8451811015613c62576000858281518110613b3b57fe5b60200260200101516001600160a01b03166108fc868481518110613b5b57fe5b60200260200101519081150290604051600060405180830381858888f1935050505090508015613bf157858281518110613b9157fe5b60200260200101516001600160a01b03167f6c61d60f69a7beb3e1c80db7f39f37b208537cbb19da3174511b477812b2fc7d868481518110613bcf57fe5b6020026020010151604051613be49190616ef0565b60405180910390a2613c59565b858281518110613bfd57fe5b60200260200101516001600160a01b03167f25d0ce7d2f0cec669a8c17efe49d195c13455bb8872b65fa610ac7f53fe4ca7d868481518110613c3b57fe5b6020026020010151604051613c509190616ef0565b60405180910390a25b50600101613b24565b505b5050505050505050505050506000471115613ce0577f6ecc855f9440a9282c90913bbc91619fd44f5ec0b462af28d127b116f130aa4d47604051613ca89190616ef0565b60405180910390a1604051611002904780156108fc02916000818181858888f19350505050158015613cde573d6000803e3d6000fd5b505b60006003819055600555815115613cfb57613cfb8282614f0e565b6110016001600160a01b031663fc4333cd6040518163ffffffff1660e01b8152600401600060405180830381600087803b158015613d3857600080fd5b505af1158015613d4c573d6000803e3d6000fd5b50506040517fedd8d7296956dd970ab4de3f2fc03be2b0ffc615d20cd4c72c6e44f928630ebf925060009150a1506000949350505050565b80516001600160a01b0316600090815260046020526040812054801580613dd55750600180820381548110613db557fe5b9060005260206000209060040201600201601c9054906101000a900460ff165b15613e1b5782516040516001600160a01b03909116907fe209c46bebf57cf265d5d9009a00870e256d9150f3ed5281ab9d9eb3cec6e4be90600090a2600091505061130b565b600154600554600019820111801590613e715784516040516001600160a01b03909116907fe209c46bebf57cf265d5d9009a00870e256d9150f3ed5281ab9d9eb3cec6e4be90600090a26000935050505061130b565b600580546001908101909155805481906000198601908110613e8f57fe5b6000918252602082206002600490920201018054921515600160e01b0260ff60e01b199093169290921790915585516040516001600160a01b03909116917ff226e7d8f547ff903d9d419cf5f54e0d7d07efa9584135a53a057c5f1f27f49a91a2506000949350505050565b6000610ea283836040518060400160405280601a81526020017f536166654d6174683a206469766973696f6e206279207a65726f0000000000008152506156ed565b6000610ea283836040518060400160405280601e81526020017f536166654d6174683a207375627472616374696f6e206f766572666c6f770000815250615724565b600082613f8e575060006113bb565b82820282848281613f9b57fe5b0414610ea25760405162461bcd60e51b8152600401610c3b90616ac5565b600082820183811015610ea25760405162461bcd60e51b8152600401610c3b90616664565b60008060018381548110613fee57fe5b906000526020600020906004020160030154905060006001808054905003905060016140186125ab565b511161404d5760006001858154811061402d57fe5b9060005260206000209060040201600301819055506000925050506113bb565b846001600160a01b03167f3b6f9ef90462b512a1293ecec018670bf7b7f1876fb727590a8a6d7643130a70836040516140869190616ef0565b60405180910390a26001600160a01b038516600090815260046020526040812055835b6001546000190181101561427357600181600101815481106140c757fe5b9060005260206000209060040201600182815481106140e257fe5b60009182526020909120825460049092020180546001600160a01b03199081166001600160a01b0393841617825560018085015481840180548416918616919091179055600280860180549185018054909416919095161780835584546001600160401b03600160a01b91829004160267ffffffffffffffff60a01b1990911617808355935460ff600160e01b918290041615150260ff60e01b19909416939093179055600392830154920191909155600b8054909183019081106141a357fe5b9060005260206000209060160201600b82815481106141be57fe5b600091825260209091208254601690920201908155600180830154818301805460ff909216151560ff1990921691909117905560028084018054614215938386019390821615610100026000190190911604615eba565b5061422860038281019084016013615f2f565b5090505080600101600460006001848154811061424157fe5b600091825260208083206004909202909101546001600160a01b031683528201929092526040019020556001016140a9565b50600180548061427f57fe5b60008281526020812060046000199093019283020180546001600160a01b0319908116825560018201805490911690556002810180546001600160e81b0319169055600301559055600b8054806142d257fe5b60008281526020812060166000199093019283020181815560018101805460ff19169055906143046002830182615f59565b614312600383016000615f9d565b50509055600081838161432157fe5b04905080156143855760015460005b8181101561438257826001828154811061434657fe5b906000526020600020906004020160030154016001828154811061436657fe5b6000918252602090912060036004909202010155600101614330565b50505b50600195945050505050565b6001548151604080518281526020808402820101909152606092919083908280156143d057816020015b60608152602001906001900390816143bb5790505b50600b5490915083146143e757925061130b915050565b60005b828110156144f657600b60016004600089858151811061440657fe5b60200260200101516001600160a01b03166001600160a01b0316815260200190815260200160002054038154811061443a57fe5b600091825260209182902060026016909202018101805460408051601f6000196101006001861615020190931694909404918201859004850284018501905280835291929091908301828280156144d25780601f106144a7576101008083540402835291602001916144d2565b820191906000526020600020905b8154815290600101906020018083116144b557829003601f168201915b50505050508282815181106144e357fe5b60209081029190910101526001016143ea565b50949350505050565b60005b8281101561464c57600082878388016040516020016145229291906162e9565b6040516020818303038152906040528051906020012060001c8161454257fe5b06905080850182870114614643576000898388018151811061456057fe5b602002602001015190506060898489018151811061457a57fe5b602002602001015190508a8388018151811061459257fe5b60200260200101518b858a01815181106145a857fe5b60200260200101906001600160a01b031690816001600160a01b031681525050818b848901815181106145d757fe5b60200260200101906001600160a01b031690816001600160a01b031681525050898388018151811061460557fe5b60200260200101518a858a018151811061461b57fe5b6020026020010181905250808a8489018151811061463557fe5b602002602001018190525050505b50600101614502565b5050505050505050565b600980546001908101909155600b80548390811061467057fe5b906000526020600020906016020160010160006101000a81548160ff02191690831515021790555043600b82815481106146a657fe5b600091825260208220601690910201919091556040516001600160a01b038416917ff62981a567ec3cec866c6fa93c55bcdf841d6292d18b8d522ececa769375d82d91a25050565b60008160405160200161470191906162cd565b604051602081830303815290604052805190602001208360405160200161472891906162cd565b6040516020818303038152906040528051906020012014905092915050565b015190565b6001600160a01b038116600090815260046020526040812054806147755750600019905061130b565b60018103905060006001828154811061478a57fe5b90600052602060002090600402016003015490506000600183815481106147ad57fe5b6000918252602090912060036004909202010155600154604051600019909101906001600160a01b038616907f8cd4e147d8af98a9e3b6724021b8bf6aed2e5dac71c38f2dce8161b82585b25d90614806908590616ef0565b60405180910390a28061481e5782935050505061130b565b600081838161482957fe5b04905080156148e55760005b8481101561488757816001828154811061484b57fe5b906000526020600020906004020160030154016001828154811061486b57fe5b6000918252602090912060036004909202010155600101614835565b50600180549085015b818110156148e25782600182815481106148a657fe5b90600052602060002090600402016003015401600182815481106148c657fe5b6000918252602090912060036004909202010155600101614890565b50505b5091949350505050565b6148f7615fac565b506040805180820190915281518152602082810190820152919050565b61491c615e65565b61492582615750565b61492e57600080fd5b600061493d836020015161578a565b60208085015160408051808201909152868152920190820152915050919050565b6000614968615fac565b505080518051602091820151919092015191011190565b614987615fac565b6149908261495e565b61499957600080fd5b602082015160006149a9826157ed565b80830160209586015260408051808201909152908152938401919091525090919050565b8051600090158015906149e257508151602110155b6149eb57600080fd5b60006149fa836020015161578a565b90508083600001511015614a205760405162461bcd60e51b8152600401610c3b90616c83565b8251602080850151830180519284900392918310156144f657506020919091036101000a90049392505050565b6060614a5882615750565b614a6157600080fd5b6000614a6c836158ce565b9050606081604051908082528060200260200182016040528015614aaa57816020015b614a97615fac565b815260200190600190039081614a8f5790505b5090506000614abc856020015161578a565b60208601510190506000805b84811015614b1357614ad9836157ed565b9150604051806040016040528083815260200184815250848281518110614afc57fe5b602090810291909101015291810191600101614ac8565b509195945050505050565b614b26615e85565b60606000614b32615e85565b6060614b3c615e65565b614b4587614914565b90506000805b614b548361495e565b15614c295780614b7f57614b6f614b6a8461497f565b61592a565b6001600160a01b03168552614c21565b8060011415614ba757614b94614b6a8461497f565b6001600160a01b03166020860152614c21565b8060021415614bcf57614bbc614b6a8461497f565b6001600160a01b03166040860152614c21565b8060031415614bfb57614be4612f638461497f565b6001600160401b0316606086015260019150614c21565b8060041415614c1c57614c15614c108461497f565b615944565b9350614c21565b614c29565b600101614b4b565b50929791965091945092505050565b60606113bb614c46836159b4565b615a9a565b6060815160001415614c6c575060408051600081526020810190915261130b565b606082600081518110614c7b57fe5b602002602001015190506000600190505b8351811015614cbc57614cb282858381518110614ca557fe5b6020026020010151615aec565b9150600101614c8c565b50610ea2614ccf825160c060ff16615b69565b82615aec565b606080600080808080614ce66126a7565b6001549091505b8015614df457600181039250600b8381548110614d0657fe5b600091825260209091206001601690920201015460ff16614d2657614deb565b60018381548110614d3357fe5b60009182526020909120600490910201546001600160a01b03169450614d5a858484612d27565b9350831580614d6d575060018a51038610155b15614d7757614deb565b60005b8a51811015614de957856001600160a01b03168b8281518110614d9957fe5b6020026020010151600001516001600160a01b03161415614de15760018b8281518110614dc257fe5b6020908102919091010151901515608090910152600190960195614de9565b600101614d7a565b505b60001901614ced565b5084895103604051908082528060200260200182016040528015614e3257816020015b614e1f615e85565b815260200190600190039081614e175790505b50965084895103604051908082528060200260200182016040528015614e6c57816020015b6060815260200190600190039081614e575790505b5095506000915060005b8951811015614f0057898181518110614e8b57fe5b602002602001015160800151614ef857898181518110614ea757fe5b6020026020010151888481518110614ebb57fe5b6020026020010181905250888181518110614ed257fe5b6020026020010151878481518110614ee657fe5b60200260200101819052508260010192505b600101614e76565b5050505050505b9250929050565b600154825160005b8281101561502b576001614f28615e85565b60018381548110614f3557fe5b600091825260208083206040805160c08101825260049490940290910180546001600160a01b0390811685526001820154811693850193909352600281015492831691840191909152600160a01b82046001600160401b03166060840152600160e01b90910460ff16151560808301526003015460a082015291505b84811015614fff57878181518110614fc557fe5b6020026020010151600001516001600160a01b031682600001516001600160a01b03161415614ff75760009250614fff565b600101614fb1565b5081156150215780516001600160a01b03166000908152600460205260408120555b5050600101614f16565b50808211156150ea57805b828110156150e857600180548061504957fe5b60008281526020812060046000199093019283020180546001600160a01b0319908116825560018201805490911690556002810180546001600160e81b0319169055600301559055600b80548061509c57fe5b60008281526020812060166000199093019283020181815560018101805460ff19169055906150ce6002830182615f59565b6150dc600383016000615f9d565b50509055600101615036565b505b60008183106150f957816150fb565b825b905060005b8181101561549f576151ad86828151811061511757fe5b60200260200101516001838154811061512c57fe5b60009182526020918290206040805160c08101825260049390930290910180546001600160a01b0390811684526001820154811694840194909452600281015493841691830191909152600160a01b83046001600160401b03166060830152600160e01b90920460ff161515608082015260039091015460a0820152615c3b565b6153615780600101600460008884815181106151c557fe5b6020026020010151600001516001600160a01b03166001600160a01b031681526020019081526020016000208190555085818151811061520157fe5b60200260200101516001828154811061521657fe5b6000918252602091829020835160049092020180546001600160a01b039283166001600160a01b0319918216178255928401516001820180549184169185169190911790556040840151600282018054606087015160808801511515600160e01b0260ff60e01b196001600160401b03909216600160a01b0267ffffffffffffffff60a01b1995909716929097169190911792909216939093171692909217905560a09091015160039091015584518590829081106152d157fe5b6020026020010151600b82815481106152e657fe5b9060005260206000209060160201600201908051906020019061530a929190615d9a565b506000600b828154811061531a57fe5b60009182526020822060169190910201600101805460ff191692151592909217909155600b80548390811061534b57fe5b6000918252602090912060169091020155615497565b61542785828151811061537057fe5b6020026020010151600b838154811061538557fe5b600091825260209182902060026016909202018101805460408051601f60001961010060018616150201909316949094049182018590048502840185019052808352919290919083018282801561541d5780601f106153f25761010080835404028352916020019161541d565b820191906000526020600020905b81548152906001019060200180831161540057829003601f168201915b5050505050615cbc565b6154725784818151811061543757fe5b6020026020010151600b828154811061544c57fe5b90600052602060002090601602016002019080519060200190615470929190615d9a565b505b60006001828154811061548157fe5b9060005260206000209060040201600301819055505b600101615100565b5082821115615677576154b0615d6b565b835b83811015615674578581815181106154c657fe5b6020026020010151826040018190525060018782815181106154e457fe5b6020908102919091018101518254600181810185556000948552838520835160049093020180546001600160a01b039384166001600160a01b0319918216178255848601518284018054918616918316919091179055604080860151600284018054606089015160808a01511515600160e01b0260ff60e01b196001600160401b03909216600160a01b0267ffffffffffffffff60a01b1995909a1692909616919091179290921696909617169190911790935560a090930151600390930192909255600b805492830181559093528451601690910260008051602061714e83398151915281019182558583015160008051602061718e8339815191528201805491151560ff199092169190911790559285015180518694929361561a9360008051602061716e83398151915201920190615d9a565b5060608201516156309060038301906013615e14565b505050806001016004600089848151811061564757fe5b602090810291909101810151516001600160a01b03168252810191909152604001600020556001016154b2565b50505b6000600981905560015493505b838110156156e5576000600b828154811061569b57fe5b60009182526020822060169190910201600101805460ff191692151592909217909155600b8054839081106156cc57fe5b6000918252602090912060169091020155600101615684565b505050505050565b6000818361570e5760405162461bcd60e51b8152600401610c3b919061646e565b50600083858161571a57fe5b0495945050505050565b600081848411156157485760405162461bcd60e51b8152600401610c3b919061646e565b505050900390565b80516000906157615750600061130b565b6020820151805160001a9060c08210156157805760009250505061130b565b5060019392505050565b8051600090811a60808110156157a457600091505061130b565b60b88110806157bf575060c081108015906157bf575060f881105b156157ce57600191505061130b565b60c08110156157e25760b51901905061130b565b60f51901905061130b565b80516000908190811a608081101561580857600191506158c7565b60b881101561581d57607e19810191506158c7565b60c081101561586e57600060b78203600186019550806020036101000a8651049150600181018201935050808310156158685760405162461bcd60e51b8152600401610c3b90616a12565b506158c7565b60f88110156158835760be19810191506158c7565b600060f78203600186019550806020036101000a8651049150600181018201935050808310156158c55760405162461bcd60e51b8152600401610c3b90616a12565b505b5092915050565b80516000906158df5750600061130b565b600080905060006158f3846020015161578a565b602085015185519181019250015b8082101561592157615912826157ed565b82019150826001019250615901565b50909392505050565b805160009060151461593b57600080fd5b6113bb826149cd565b805160609061595257600080fd5b6000615961836020015161578a565b83516040805191839003808352601f19601f8201168301602001909152919250606090828015615998576020820181803683370190505b50905060008160200190506144f6848760200151018285615d20565b604080516020808252818301909252606091829190602082018180368337505050602081018490529050600067ffffffffffffffff1984166159f857506018615a1c565b6fffffffffffffffffffffffffffffffff198416615a1857506010615a1c565b5060005b6020811015615a5257818181518110615a3157fe5b01602001516001600160f81b03191615615a4a57615a52565b600101615a1c565b60008160200390506060816040519080825280601f01601f191660200182016040528015615a87576020820181803683370190505b5080830196909652508452509192915050565b606081516001148015615acc5750607f60f81b82600081518110615aba57fe5b01602001516001600160f81b03191611155b15615ad857508061130b565b6113bb615aea8351608060ff16615b69565b835b6060806040519050835180825260208201818101602087015b81831015615b1d578051835260209283019201615b05565b50855184518101855292509050808201602086015b81831015615b4a578051835260209283019201615b32565b508651929092011591909101601f01601f191660405250905092915050565b6060680100000000000000008310615b935760405162461bcd60e51b8152600401610c3b90616816565b60408051600180825281830190925260609160208201818036833701905050905060378411615bed5782840160f81b81600081518110615bcf57fe5b60200101906001600160f81b031916908160001a90535090506113bb565b6060615bf8856159b4565b90508381510160370160f81b82600081518110615c1157fe5b60200101906001600160f81b031916908160001a905350615c328282615aec565b95945050505050565b805182516000916001600160a01b039182169116148015615c75575081602001516001600160a01b031683602001516001600160a01b0316145b8015615c9a575081604001516001600160a01b031683604001516001600160a01b0316145b8015610ea25750506060908101519101516001600160401b0390811691161490565b815181516000916001918114808314615cd85760009250615d16565b600160208701838101602088015b600284838510011415615d11578051835114615d055760009650600093505b60209283019201615ce6565b505050505b5090949350505050565b80615d2a57610c5b565b5b60208110615d4a578251825260209283019290910190601f1901615d2b565b915181516020939093036101000a6000190180199091169216919091179052565b60405180608001604052806000815260200160001515815260200160608152602001615d95615fc6565b905290565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f10615ddb57805160ff1916838001178555615e08565b82800160010185558215615e08579182015b82811115615e08578251825591602001919060010190615ded565b506126e2929150615fe5565b8260138101928215615e085791602002820182811115615e08578251825591602001919060010190615ded565b6040518060600160405280600060ff16815260200160608152602001606081525090565b6040518060400160405280615e78615fac565b8152602001600081525090565b6040805160c081018252600080825260208201819052918101829052606081018290526080810182905260a081019190915290565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f10615ef35780548555615e08565b82800160010185558215615e0857600052602060002091601f016020900482015b82811115615e08578254825591600101919060010190615f14565b8260138101928215615e085791820182811115615e08578254825591600101919060010190615f14565b50805460018160011615610100020316600290046000825580601f10615f7f5750611517565b601f0160209004906000526020600020908101906115179190615fe5565b50611517906013810190615fe5565b604051806040016040528060008152602001600081525090565b6040518061026001604052806013906020820280368337509192915050565b61269491905b808211156126e25760008155600101615feb565b60008083601f840112616010578182fd5b5081356001600160401b03811115616026578182fd5b6020830191508360208083028501011115614f0757600080fd5b60008083601f840112616051578182fd5b5081356001600160401b03811115616067578182fd5b602083019150836020828501011115614f0757600080fd5b600060208284031215616090578081fd5b81356001600160a01b0381168114610ea2578182fd5b600080600080604085870312156160bb578283fd5b84356001600160401b03808211156160d1578485fd5b6160dd88838901615fff565b909650945060208701359150808211156160f5578384fd5b5061610287828801615fff565b95989497509550505050565b60006020828403121561611f578081fd5b81518015158114610ea2578182fd5b60008060008060408587031215616143578384fd5b84356001600160401b0380821115616159578586fd5b61616588838901616040565b9096509450602087013591508082111561617d578384fd5b5061610287828801616040565b60006020828403121561619b578081fd5b5035919050565b6000602082840312156161b3578081fd5b5051919050565b600080604083850312156161cc578182fd5b505080516020909101519092909150565b6000806000604084860312156161f1578283fd5b833560ff81168114616201578384fd5b925060208401356001600160401b0381111561621b578283fd5b61622786828701616040565b9497909650939450505050565b6000815180845260208085019450808401835b8381101561626c5781516001600160a01b031687529582019590820190600101616247565b509495945050505050565b60008284528282602086013780602084860101526020601f19601f85011685010190509392505050565b600081518084526162b9816020860160208601616f56565b601f01601f19169290920160200192915050565b600082516162df818460208701616f56565b9190910192915050565b918252602082015260400190565b6001600160a01b0391909116815260200190565b6001600160a01b03929092168252602082015260400190565b6001600160a01b03968716815294861660208601529290941660408401526001600160401b03166060830152911515608082015260a081019190915260c00190565b600060208252610ea26020830184616234565b60006040825261638c6040830185616234565b602083820381850152818551808452828401915082838202850101838801865b838110156163da57601f198784030185526163c88383516162a1565b948601949250908501906001016163ac565b50909998505050505050505050565b6000608082526163fc6080830187616234565b828103602084810191909152865180835287820192820190845b8181101561643257845183529383019391830191600101616416565b505084810360408601526164468188616234565b93505050506001600160401b038316606083015295945050505050565b901515815260200190565b600060208252610ea260208301846162a1565b600060408252616495604083018688616277565b82810360208401526164a8818587616277565b979650505050505050565b6020808252601c908201527f6c656e677468206f66206275726e526174696f206d69736d6174636800000000604082015260600190565b60208082526026908201527f6c656e677468206f66206d61784e756d4f664d61696e7461696e696e67206d696040820152650e6dac2e8c6d60d31b606082015260800190565b6020808252601b908201527f6261746368207472616e736665722072657475726e2066616c73650000000000604082015260600190565b6020808252602c908201527f6c656e677468206f66206d61784e756d4f66576f726b696e6743616e6469646160408201526b0e8cae640dad2e6dac2e8c6d60a31b606082015260800190565b60208082526025908201527f6c656e677468206f66206d61696e7461696e536c6173685363616c65206d69736040820152640dac2e8c6d60db1b606082015260800190565b6020808252818101527f6c656e677468206f66206e756d4f66436162696e657473206d69736d61746368604082015260600190565b60208082526019908201527f74686520636f6e7472616374206e6f7420696e69742079657400000000000000604082015260600190565b6020808252601b908201527f536166654d6174683a206164646974696f6e206f766572666c6f770000000000604082015260600190565b60208082526028908201527f746865206e756d4f66436162696e657473206d75737420626520677265617465604082015267072207468616e20360c41b606082015260800190565b60208082526039908201527f746865206e756d4f66436162696e657473206d757374206265206c657373207460408201527f68616e204d41585f4e554d5f4f465f56414c494441544f525300000000000000606082015260800190565b60208082526029908201527f746865206e756d626572206f662076616c696461746f727320657863656564206040820152681d1a19481b1a5b5a5d60ba1b606082015260800190565b60208082526022908201527f63616e206e6f7420646f207468697320747769636520696e206f6e6520626c6f604082015261636b60f01b606082015260800190565b6020808252602b908201527f746865206275726e526174696f206d757374206265206e6f206772656174657260408201526a0207468616e2031303030360ac1b606082015260800190565b6020808252600e908201526d696e70757420746f6f206c6f6e6760901b604082015260600190565b60208082526037908201527f746865206d61784e756d4f664d61696e7461696e696e67206d7573742062652060408201527f6c657373207468616e206e756d4f66436162696e657473000000000000000000606082015260800190565b6020808252602b908201527f6475706c696361746520636f6e73656e7375732061646472657373206f66207660408201526a185b1a59185d1bdc94d95d60aa1b606082015260800190565b60208082526027908201527f7468652065787069726554696d655365636f6e64476170206973206f7574206f604082015266662072616e676560c81b606082015260800190565b6020808252601590820152746465706f7369742076616c7565206973207a65726f60581b604082015260600190565b60208082526049908201527f746865206d61784e756d4f66576f726b696e6743616e64696461746573206d7560408201527f7374206265206e6f742067726561746572207468616e206d61784e756d4f6643606082015268616e6469646174657360b81b608082015260a00190565b60208082526027908201527f7468652066696e616c697479526577617264526174696f206973206f7574206f604082015266662072616e676560c81b606082015260800190565b6020808252601190820152706164646974696f6e206f766572666c6f7760781b604082015260600190565b60208082526023908201527f63616e206e6f7420656e7465722054656d706f72617279204d61696e74656e616040820152626e636560e81b606082015260800190565b60208082526025908201527f6c656e677468206f66206a61696c2076616c696461746f7273206d757374206260408201526465206f6e6560d81b606082015260800190565b60208082526021908201527f536166654d6174683a206d756c7469706c69636174696f6e206f766572666c6f6040820152607760f81b606082015260800190565b6020808252602e908201527f746865206d6573736167652073656e646572206d75737420626520676f76657260408201526d1b985b98d94818dbdb9d1c9858dd60921b606082015260800190565b60208082526025908201527f6c656e677468206f66206d61784e756d4f6643616e64696461746573206d69736040820152640dac2e8c6d60db1b606082015260800190565b6020808252601290820152716e6f7420696e206d61696e74656e616e636560701b604082015260600190565b60208082526021908201527f666565206973206c6172676572207468616e2044555354595f494e434f4d494e6040820152604760f81b606082015260800190565b60208082526019908201527f74686520636f6e747261637420616c726561647920696e697400000000000000604082015260600190565b60208082526026908201527f6c656e677468206f662066696e616c697479526577617264526174696f206d696040820152650e6dac2e8c6d60d31b606082015260800190565b6020808252601a908201527f6c656e677468206973206c657373207468616e206f6666736574000000000000604082015260600190565b60208082526026908201527f6c656e677468206f662065787069726554696d655365636f6e64476170206d696040820152650e6dac2e8c6d60d31b606082015260800190565b60208082526017908201527f6f6e6c792063757272656e742076616c696461746f7273000000000000000000604082015260600190565b60208082526021908201527f6661696c656420746f20706172736520696e69742076616c696461746f7253656040820152601d60fa1b606082015260800190565b6020808252602f908201527f746865206d6573736167652073656e646572206d7573742062652063726f737360408201526e0818da185a5b8818dbdb9d1c9858dd608a1b606082015260800190565b6020808252602d908201527f746865206d6573736167652073656e646572206d75737420626520746865206260408201526c3637b1b590383937b23ab1b2b960991b606082015260800190565b6020808252603e908201527f746865206d61696e7461696e536c6173685363616c65206d757374206265206760408201527f726561746572207468616e203020616e64206c657373207468616e2031300000606082015260800190565b6020808252600d908201526c756e6b6e6f776e20706172616d60981b604082015260600190565b60208082526029908201527f746865206d6573736167652073656e646572206d75737420626520736c6173686040820152680818dbdb9d1c9858dd60ba1b606082015260800190565b61ffff91909116815260200190565b90815260200190565b6000848252831515602083015260606040830152615c3260608301846162a1565b63ffffffff91909116815260200190565b60ff91909116815260200190565b600060ff8516825260406020830152615c32604083018486616277565b60005b83811015616f71578181015183820152602001616f59565b83811115612c47575050600091015256fef901a880f901a4f844941284214b9b9c85549ab3d2b972df0deef66ac2c9946ddf42a51534fc98d0c0a3b42c963cace8441ddf946ddf42a51534fc98d0c0a3b42c963cace8441ddf8410000000f84494a2959d3f95eae5dc7d70144ce1b73b403b7eb6e0948081ef03f1d9e0bb4a5bf38f16285c879299f07f948081ef03f1d9e0bb4a5bf38f16285c879299f07f8410000000f8449435552c16704d214347f29fa77f77da6d75d7c75294dc4973e838e3949c77aced16ac2315dc2d7ab11194dc4973e838e3949c77aced16ac2315dc2d7ab1118410000000f84494980a75ecd1309ea12fa2ed87a8744fbfc9b863d594cc6ac05c95a99c1f7b5f88de0e3486c82293b27094cc6ac05c95a99c1f7b5f88de0e3486c82293b2708410000000f84494f474cf03cceff28abc65c9cbae594f725c80e12d94e61a183325a18a173319dd8e19c8d069459e217594e61a183325a18a173319dd8e19c8d069459e21758410000000f84494b71b214cb885500844365e95cd9942c7276e7fd894d22ca3ba2141d23adab65ce4940eb7665ea2b6a794d22ca3ba2141d23adab65ce4940eb7665ea2b6a7841000000070e72399380dcfb0338abc03dc8d47f9f470ada8e769c9a78d644ea97385ecb20175b7a638427703f0dbe7bb9bbf987a2551717b34e79f33b5b1008d1fa01db90175b7a638427703f0dbe7bb9bbf987a2551717b34e79f33b5b1008d1fa01dbb0175b7a638427703f0dbe7bb9bbf987a2551717b34e79f33b5b1008d1fa01dbaa2646970667358221220df3b2f2afc524f6a9eb81529e8bd736333e37b7197419580d4e42bd858b6b14264736f6c63430006040033", + }, + { + ContractAddr: SlashContract, + CommitUrl: "https://github.com/bnb-chain/bsc-genesis-contract/commit/b144718e94d7a1ebb24a7103202300f08826f369", + Code: "608060405234801561001057600080fd5b506004361061027f5760003560e01c80637942fd051161015c578063c80d4b8f116100ce578063dc927faf11610087578063dc927faf146104ad578063e1c7392a146104b5578063f9a2bbc7146104bd578063fc3e5908146104c5578063fc4333cd146104cd578063fd6a6879146104d55761027f565b8063c80d4b8f1461045c578063c81b166214610464578063c8509d811461046c578063c96be4cb1461047f578063cc844b7314610492578063d2a42e4b146104a55761027f565b80639dc09262116101205780639dc0926214610421578063a1a11bf514610429578063a78abc1614610431578063ab51bb9614610439578063ac0af62914610441578063ac431751146104495761027f565b80637942fd05146103ee5780638256ace6146103f6578063831d65d1146103fe57806396713da9146104115780639bc8e4f2146104195761027f565b8063493279b1116101f557806362b72cf5116101b957806362b72cf5146103be5780636e47b482146103c657806370fd5bad146103ce578063718a8aa8146103d657806375d47a0a146103de5780637912a65d146103e65761027f565b8063493279b11461037c5780634bf6c8821461039157806351e8067214610399578063567a372d146103a15780635bfb4990146103a95761027f565b806335aa2e441161024757806335aa2e441461030e57806337c8dab914610321578063389f4f71146103425780633a63f4b1146103575780633dffc3871461035f57806343756e5c146103745761027f565b80630bee7a67146102845780630e2374a5146102a25780631182b875146102b757806322d1e80b146102d757806323bac5a2146102ec575b600080fd5b61028c6104dd565b60405161029991906132a4565b60405180910390f35b6102aa6104e2565b6040516102999190612b82565b6102ca6102c5366004612ab8565b6104e8565b6040516102999190612bba565b6102df61054e565b6040516102999190612baf565b6102ff6102fa366004612866565b610557565b6040516102999392919061328c565b6102aa61031c366004612a88565b61057a565b61033461032f366004612866565b6105a1565b60405161029992919061327e565b61034a6105f8565b6040516102999190613254565b61034a6105fe565b610367610604565b60405161029991906132b5565b6102aa610609565b61038461060f565b6040516102999190613245565b610367610614565b6102aa610619565b61034a61061f565b6103bc6103b7366004612866565b610625565b005b61034a6106d0565b6102aa6106d6565b6103676106dc565b6103676106e1565b6102aa6106e6565b61034a6106ec565b6103676106f1565b6103346106f6565b6103bc61040c366004612ab8565b610700565b610367610812565b61034a610817565b6102aa610822565b6102aa610828565b6102df61082e565b61028c610837565b61034a61083c565b6103bc61045736600461296c565b610841565b61034a610ce0565b6102aa610ce5565b6103bc61047a366004612ab8565b610ceb565b6103bc61048d366004612866565b610d5c565b6103bc6104a03660046129d5565b61114d565b61034a61169a565b6102aa61169f565b6103bc6116a5565b6102aa6116e1565b6103676116e7565b6103bc6116ec565b6102aa611b35565b606481565b61200181565b606033612000146105145760405162461bcd60e51b815260040161050b906130cb565b60405180910390fd5b60005460ff166105365760405162461bcd60e51b815260040161050b90612c9b565b60405162461bcd60e51b815260040161050b9061318e565b60075460ff1681565b600260208190526000918252604090912080546001820154919092015460ff1683565b6001818154811061058757fe5b6000918252602090912001546001600160a01b0316905081565b6000806105ac61264d565b5050506001600160a01b0316600090815260026020818152604092839020835160608101855281548082526001830154938201849052919093015460ff16151592909301919091529091565b60055481565b60065481565b600181565b61100181565b606181565b600881565b61200081565b60045481565b33611000146106465760405162461bcd60e51b815260040161050b90612edf565b60005460ff166106685760405162461bcd60e51b815260040161050b90612c9b565b61200063f7a251d7600b61067b84611b3b565b60006040518463ffffffff1660e01b815260040161069b939291906132c3565b600060405180830381600087803b1580156106b557600080fd5b505af11580156106c9573d6000803e3d6000fd5b5050505050565b60035481565b61100581565b600281565b601081565b61100881565b603281565b600b81565b6004546005549091565b33612000146107215760405162461bcd60e51b815260040161050b906130cb565b60005460ff166107435760405162461bcd60e51b815260040161050b90612c9b565b61074b612670565b600061078c84848080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250611c0d92505050565b9150915080156107d35781516040517f7f0956d47419b9525356e7111652b653b530ec6f5096dccc04589bc38e629967916107c6916132a4565b60405180910390a16106c9565b81516040517f7d45f62d17443dd4547bca8a8112c60e2385669318dc300ec61a5d2492f262e791610803916132a4565b60405180910390a15050505050565b600981565b662386f26fc1000081565b61100781565b61100681565b60005460ff1681565b600081565b600481565b60005460ff166108635760405162461bcd60e51b815260040161050b90612c9b565b33611007146108845760405162461bcd60e51b815260040161050b90612f88565b6108ef84848080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250506040805180820190915260148152731b5a5cd9195b59585b9bdc951a1c995cda1bdb1960621b60208201529150611c8d9050565b1561098a57602081146109145760405162461bcd60e51b815260040161050b90612e6b565b604080516020601f840181900481028201810190925282815260009161095291858580838501838280828437600092019190915250611ce792505050565b905060018110158015610966575060055481105b6109825760405162461bcd60e51b815260040161050b90613086565b600455610c9d565b6109f084848080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152505060408051808201909152600f81526e19995b1bdb9e551a1c995cda1bdb19608a1b60208201529150611c8d9050565b15610a8c5760208114610a155760405162461bcd60e51b815260040161050b90612fd6565b604080516020601f8401819004810282018101909252828152600091610a5391858580838501838280828437600092019190915250611ce792505050565b90506103e88111158015610a68575060045481115b610a845760405162461bcd60e51b815260040161050b90612d09565b600555610c9d565b610b0084848080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152505060408051808201909152601881527f66696e616c697479536c617368526577617264526174696f000000000000000060208201529150611c8d9050565b15610b9a5760208114610b255760405162461bcd60e51b815260040161050b906131c5565b604080516020601f8401819004810282018101909252828152600091610b6391858580838501838280828437600092019190915250611ce792505050565b9050600a8110158015610b765750606481105b610b925760405162461bcd60e51b815260040161050b90612e1f565b600655610c9d565b610c0e84848080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152505060408051808201909152601881527f656e61626c654d616c6963696f7573566f7465536c617368000000000000000060208201529150611c8d9050565b15610c855760208114610c335760405162461bcd60e51b815260040161050b90612d3e565b604080516020601f8401819004810282018101909252828152610c6f9190848480838501838280828437600092019190915250611cec92505050565b6007805460ff1916911515919091179055610c9d565b60405162461bcd60e51b815260040161050b90613167565b7f6cdb0ac70ab7f2e2d035cca5be60d89906f2dede7648ddbd7402189c1eeed17a84848484604051610cd29493929190612bcd565b60405180910390a150505050565b609681565b61100281565b3361200014610d0c5760405162461bcd60e51b815260040161050b906130cb565b60005460ff16610d2e5760405162461bcd60e51b815260040161050b90612c9b565b6040517f07db600eebe2ac176be8dcebad61858c245a4961bb32ca2aa3d159b09aa0810e90600090a1505050565b334114610d7b5760405162461bcd60e51b815260040161050b9061311a565b60005460ff16610d9d5760405162461bcd60e51b815260040161050b90612c9b565b6003544311610dbe5760405162461bcd60e51b815260040161050b90613210565b3a15610ddc5760405162461bcd60e51b815260040161050b90612f5a565b60405163155853f360e21b8152611000906355614fcc90610e01908490600401612b82565b60206040518083038186803b158015610e1957600080fd5b505afa158015610e2d573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610e51919061294c565b610e5a57611146565b610e6261264d565b506001600160a01b0381166000908152600260208181526040928390208351606081018552815481526001820154928101929092529091015460ff161580159282019290925290610ebd576020810180516001019052610f16565b60016040820181905260208201819052805480820182556000919091527fb10e2d527612073b26eecdfd717e6a320cf44b4afac2b0732d9fcbe2b7fa0cf60180546001600160a01b0319166001600160a01b0384161790555b438152600554602082015181610f2857fe5b0661107457600060208201526040516335409f7f60e01b8152611000906335409f7f90610f59908590600401612b82565b600060405180830381600087803b158015610f7357600080fd5b505af1158015610f87573d6000803e3d6000fd5b505050506120006001600160a01b031663f7a251d7600b610fa785611b3b565b60006040518463ffffffff1660e01b8152600401610fc7939291906132c3565b600060405180830381600087803b158015610fe157600080fd5b505af1925050508015610ff2575060015b61106f573d808015611020576040519150601f19603f3d011682016040523d82523d6000602084013e611025565b606091505b50826001600160a01b03167fd7bc86ff5d08c8ab043edec743302aba2520e6635172a428bc956721db9e2d1c83602001518360405161106592919061325d565b60405180910390a2505b6110e0565b60045481602001518161108357fe5b066110e0576040516375abf10160e11b81526110009063eb57e202906110ad908590600401612b82565b600060405180830381600087803b1580156110c757600080fd5b505af11580156110db573d6000803e3d6000fd5b505050505b6001600160a01b0382166000818152600260208181526040808420865181559186015160018301558581015191909201805460ff1916911515919091179055517fddb6012116e51abf5436d956a4f0ebd927e92c576ff96d7918290c8782291e3e9190a2505b5043600355565b60005460ff1661116f5760405162461bcd60e51b815260040161050b90612c9b565b604051630a83aaa960e31b81526110069063541d554890611194903390600401612b82565b60206040518083038186803b1580156111ac57600080fd5b505afa1580156111c0573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906111e4919061294c565b6112005760405162461bcd60e51b815260040161050b90612bff565b60075460ff166112225760405162461bcd60e51b815260040161050b90612c66565b60065461122f5760146006555b8051514361010090910111801561125157504381602001516000015161010001115b61126d5760405162461bcd60e51b815260040161050b90612c36565b80602001516020015181600001516020015114801561129b5750806020015160600151816000015160600151145b156112b85760405162461bcd60e51b815260040161050b90612eb2565b8051604081015190511080156112d75750602081015160408101519051105b6112f35760405162461bcd60e51b815260040161050b90612de8565b6020810151518151511080156113185750806000015160400151816020015160400151105b8061134357508051516020820151511080156113435750806020015160400151816000015160400151105b8061135d5750806020015160400151816000015160400151145b6113795760405162461bcd60e51b815260040161050b90612cd2565b61138b81600001518260400151611d14565b80156113a457506113a481602001518260400151611d14565b6113c05760405162461bcd60e51b815260040161050b90612d89565b6060806110006001600160a01b0316633b071dcc6040518163ffffffff1660e01b815260040160006040518083038186803b1580156113fe57600080fd5b505afa158015611412573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f1916820160405261143a9190810190612889565b9150915060005b81518110156115775761146b82828151811061145957fe5b60200260200101518560400151611eec565b1561156f576006546040516309a99b4f60e41b815260646110028031909302049190639a99b4f0906114a39033908590600401612b96565b602060405180830381600087803b1580156114bd57600080fd5b505af11580156114d1573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906114f59190612aa0565b506110006001600160a01b03166335409f7f85848151811061151357fe5b60200260200101516040518263ffffffff1660e01b81526004016115379190612b82565b600060405180830381600087803b15801561155157600080fd5b505af1158015611565573d6000803e3d6000fd5b5050505050611577565b600101611441565b50600061158984604001516000611f50565b90506120006001600160a01b031663f7a251d7600b6115ab8760400151611f6c565b60006040518463ffffffff1660e01b81526004016115cb939291906132c3565b600060405180830381600087803b1580156115e557600080fd5b505af19250505080156115f6575060015b611668573d808015611624576040519150601f19603f3d011682016040523d82523d6000602084013e611629565b606091505b50817fd58d1183100bd0932c0588f31c4205d6bc6168909765a96c41adbed3115f36288260405161165a9190612bba565b60405180910390a250611694565b60405181907f7b78aadacff901d8b63d0dba4f86283d4db8aef27f9ed70413dd860f1c9532b690600090a25b50505050565b601481565b61100381565b60005460ff16156116c85760405162461bcd60e51b815260040161050b90613018565b603260045560966005556000805460ff19166001179055565b61100081565b600381565b336110001461170d5760405162461bcd60e51b815260040161050b90612edf565b60005460ff1661172f5760405162461bcd60e51b815260040161050b90612c9b565b60015461173b57611b33565b600154600090600019015b808211611b07576000805b8284101561186a5761176161264d565b600260006001878154811061177257fe5b60009182526020808320909101546001600160a01b0316835282810193909352604091820190208151606081018352815481526001820154938101939093526002015460ff161515908201526005549091506004900481602001511115611854576004600554816117df57fe5b0481602001510381602001818152505080600260006001888154811061180157fe5b6000918252602080832091909101546001600160a01b0316835282810193909352604091820190208351815591830151600183015591909101516002909101805460ff191691151591909117905561185e565b600192505061186a565b50836001019350611751565b828411611a015761187961264d565b600260006001868154811061188a57fe5b60009182526020808320909101546001600160a01b0316835282810193909352604091820190208151606081018352815481526001820154938101939093526002015460ff161515908201526005549091506004900481602001511115611972576004600554816118f757fe5b0481602001510381602001818152505080600260006001878154811061191957fe5b6000918252602080832091909101546001600160a01b03168352828101939093526040918201902083518155918301516001808401919091559201516002909101805460ff19169115159190911790559150611a019050565b600260006001868154811061198357fe5b60009182526020808320909101546001600160a01b031683528201929092526040018120818155600181810192909255600201805460ff191690558054806119c757fe5b600082815260209020810160001990810180546001600160a01b0319169055019055836119f45750611a01565b506000199092019161186a565b818015611a0b5750805b15611aea576002600060018681548110611a2157fe5b60009182526020808320909101546001600160a01b031683528201929092526040018120818155600181810192909255600201805460ff19169055805484908110611a6857fe5b600091825260209091200154600180546001600160a01b039092169186908110611a8e57fe5b9060005260206000200160006101000a8154816001600160a01b0302191690836001600160a01b031602179055506001805480611ac757fe5b600082815260209020810160001990810180546001600160a01b03191690550190555b82611af6575050611b07565b505060019091019060001901611746565b6040517fcfdb3b6ccaeccbdc68be3c59c840e3b3c90f0a7c491f5fff1cf56cfda200dd9c90600090a150505b565b61100481565b60408051600480825260a08201909252606091829190816020015b6060815260200190600190039081611b56579050509050611b7f836001600160a01b0316611fa7565b81600081518110611b8c57fe5b6020026020010181905250611ba043611fca565b81600181518110611bad57fe5b6020908102919091010152611bc26061611fca565b81600281518110611bcf57fe5b6020026020010181905250611be342611fca565b81600381518110611bf057fe5b6020026020010181905250611c0481611fdd565b9150505b919050565b611c15612670565b6000611c1f612670565b611c27612682565b611c38611c3386612067565b61208c565b90506000805b611c47836120d6565b15611c805780611c7357611c62611c5d846120f7565b612145565b63ffffffff16845260019150611c78565b611c80565b600101611c3e565b5091935090915050915091565b600081604051602001611ca09190612b66565b6040516020818303038152906040528051906020012083604051602001611cc79190612b66565b604051602081830303815290604052805190602001201490505b92915050565b015190565b8082015160009060ff811615611d06576001915081611d0c565b60009150815b505092915050565b60408051600480825260a0820190925260009160609190816020015b6060815260200190600190039081611d30575050604080516020808252818301909252919250606091908082018180368337019050509050611d758560000151611fca565b82600081518110611d8257fe5b6020026020010181905250611d9d60208660200151836121c7565b611da6816121d7565b82600181518110611db357fe5b6020026020010181905250611dcb8560400151611fca565b82600281518110611dd857fe5b6020026020010181905250611df360208660600151836121c7565b611dfc816121d7565b82600381518110611e0957fe5b6020026020010181905250611e2f6020611e2284611fdd565b80519060200120836121c7565b6040805160b080825260e08201909252606091602082018180368337019050509050611e5f81836000602061222d565b611e718187608001516020606061222d565b611e7f81866080603061222d565b604080516001808252818301909252606091602082018180368337019050509050815160016020830182602086016066600019fa611ebc57600080fd5b506001611eca826000612280565b60ff1614611edf576000945050505050611ce1565b5060019695505050505050565b815181516000916001918114808314611f085760009250611f46565b600160208701838101602088015b600284838510011415611f41578051835114611f355760009650600093505b60209283019201611f16565b505050505b5090949350505050565b60008160200183511015611f6357600080fd5b50016020015190565b60408051600480825260a08201909252606091829190816020015b6060815260200190600190039081611f87579050509050611b7f836121d7565b60408051600560a21b8318601482015260348101909152606090611c04816121d7565b6060611ce1611fd88361229c565b6121d7565b6060815160001415611ffe5750604080516000815260208101909152611c08565b60608260008151811061200d57fe5b602002602001015190506000600190505b835181101561204e576120448285838151811061203757fe5b6020026020010151612382565b915060010161201e565b50611c04612061825160c060ff166123ff565b82612382565b61206f6126a2565b506040805180820190915281518152602082810190820152919050565b612094612682565b61209d826124d1565b6120a657600080fd5b60006120b5836020015161250b565b60208085015160408051808201909152868152920190820152915050919050565b60006120e06126a2565b505080518051602091820151919092015191011190565b6120ff6126a2565b612108826120d6565b61211157600080fd5b602082015160006121218261256e565b80830160209586015260408051808201909152908152938401919091525090919050565b80516000901580159061215a57508151602110155b61216357600080fd5b6000612172836020015161250b565b905080836000015110156121985760405162461bcd60e51b815260040161050b9061304f565b8251602080850151830180519284900392918310156121be57826020036101000a820491505b50949350505050565b9091018181526020918201910152565b6060815160011480156122095750607f60f81b826000815181106121f757fe5b01602001516001600160f81b03191611155b15612215575080611c08565b611ce16122278351608060ff166123ff565b83612382565b60005b818110156106c95783818151811061224457fe5b602001015160f81c60f81b85848060010195508151811061226157fe5b60200101906001600160f81b031916908160001a905350600101612230565b6000816001018351101561229357600080fd5b50016001015190565b604080516020808252818301909252606091829190602082018180368337505050602081018490529050600067ffffffffffffffff1984166122e057506018612304565b6fffffffffffffffffffffffffffffffff19841661230057506010612304565b5060005b602081101561233a5781818151811061231957fe5b01602001516001600160f81b031916156123325761233a565b600101612304565b60008160200390506060816040519080825280601f01601f19166020018201604052801561236f576020820181803683370190505b5080830196909652508452509192915050565b6060806040519050835180825260208201818101602087015b818310156123b357805183526020928301920161239b565b50855184518101855292509050808201602086015b818310156123e05780518352602092830192016123c8565b508651929092011591909101601f01601f191660405250905092915050565b60606801000000000000000083106124295760405162461bcd60e51b815260040161050b90612dc0565b604080516001808252818301909252606091602082018180368337019050509050603784116124835782840160f81b8160008151811061246557fe5b60200101906001600160f81b031916908160001a9053509050611ce1565b606061248e8561229c565b90508381510160370160f81b826000815181106124a757fe5b60200101906001600160f81b031916908160001a9053506124c88282612382565b95945050505050565b80516000906124e257506000611c08565b6020820151805160001a9060c082101561250157600092505050611c08565b5060019392505050565b8051600090811a6080811015612525576000915050611c08565b60b8811080612540575060c08110801590612540575060f881105b1561254f576001915050611c08565b60c08110156125635760b519019050611c08565b60f519019050611c08565b80516000908190811a60808110156125895760019150612646565b60b881101561259e57607e1981019150612646565b60c08110156125ef57600060b78203600186019550806020036101000a8651049150600181018201935050808310156125e95760405162461bcd60e51b815260040161050b90612f2f565b50612646565b60f88110156126045760be1981019150612646565b600060f78203600186019550806020036101000a865104915060018101820193505080831015611d0c5760405162461bcd60e51b815260040161050b90612f2f565b5092915050565b604051806060016040528060008152602001600081526020016000151581525090565b60408051602081019091526000815290565b60405180604001604052806126956126a2565b8152602001600081525090565b604051806040016040528060008152602001600081525090565b600082601f8301126126cc578081fd5b81516126df6126da82613316565b6132ef565b818152915060208083019084810160005b84811015612755578151870188603f82011261270b57600080fd5b8381015161271b6126da82613336565b81815260408b8184860101111561273157600080fd5b6127408388840183870161335a565b508652505092820192908201906001016126f0565b505050505092915050565b60008083601f840112612771578182fd5b50813567ffffffffffffffff811115612788578182fd5b6020830191508360208285010111156127a057600080fd5b9250929050565b600082601f8301126127b7578081fd5b81356127c56126da82613336565b91508082528360208285010111156127dc57600080fd5b8060208401602084013760009082016020015292915050565b600060a08284031215612806578081fd5b61281060a06132ef565b905081358152602082013560208201526040820135604082015260608201356060820152608082013567ffffffffffffffff81111561284e57600080fd5b61285a848285016127a7565b60808301525092915050565b600060208284031215612877578081fd5b813561288281613386565b9392505050565b6000806040838503121561289b578081fd5b825167ffffffffffffffff808211156128b2578283fd5b81850186601f8201126128c3578384fd5b805192506128d36126da84613316565b80848252602080830192508084018a8283890287010111156128f3578788fd5b8794505b8685101561291e57805161290a81613386565b8452600194909401939281019281016128f7565b508801519096509350505080821115612935578283fd5b50612942858286016126bc565b9150509250929050565b60006020828403121561295d578081fd5b81518015158114612882578182fd5b60008060008060408587031215612981578182fd5b843567ffffffffffffffff80821115612998578384fd5b6129a488838901612760565b909650945060208701359150808211156129bc578384fd5b506129c987828801612760565b95989497509550505050565b6000602082840312156129e6578081fd5b813567ffffffffffffffff808211156129fd578283fd5b81840160608187031215612a0f578384fd5b612a1960606132ef565b9250803582811115612a29578485fd5b612a35878284016127f5565b845250602081013582811115612a49578485fd5b612a55878284016127f5565b602085015250604081013582811115612a6c578485fd5b612a78878284016127a7565b6040850152509195945050505050565b600060208284031215612a99578081fd5b5035919050565b600060208284031215612ab1578081fd5b5051919050565b600080600060408486031215612acc578283fd5b833560ff81168114612adc578384fd5b9250602084013567ffffffffffffffff811115612af7578283fd5b612b0386828701612760565b9497909650939450505050565b60008284528282602086013780602084860101526020601f19601f85011685010190509392505050565b60008151808452612b5281602086016020860161335a565b601f01601f19169290920160200192915050565b60008251612b7881846020870161335a565b9190910192915050565b6001600160a01b0391909116815260200190565b6001600160a01b03929092168252602082015260400190565b901515815260200190565b6000602082526128826020830184612b3a565b600060408252612be1604083018688612b10565b8281036020840152612bf4818587612b10565b979650505050505050565b6020808252601f908201527f746865206d73672073656e646572206973206e6f7420612072656c6179657200604082015260600190565b6020808252601690820152751d1bdbc81bdb1908189b1bd8dac81a5b9d9bdb1d995960521b604082015260600190565b6020808252818101527f6d616c6963696f757320766f746520736c617368206e6f7420656e61626c6564604082015260600190565b60208082526019908201527f74686520636f6e7472616374206e6f7420696e69742079657400000000000000604082015260600190565b6020808252601a908201527f6e6f2076696f6c6174696f6e206f6620766f74652072756c6573000000000000604082015260600190565b6020808252818101527f7468652066656c6f6e795468726573686f6c64206f7574206f662072616e6765604082015260600190565b6020808252602b908201527f6c656e677468206f6620656e61626c654d616c6963696f7573566f7465536c6160408201526a0e6d040dad2e6dac2e8c6d60ab1b606082015260800190565b60208082526017908201527f766572696679207369676e6174757265206661696c6564000000000000000000604082015260600190565b6020808252600e908201526d696e70757420746f6f206c6f6e6760901b604082015260600190565b60208082526019908201527f7372634e756d20626967676572207468616e207461724e756d00000000000000604082015260600190565b6020808252602c908201527f7468652066696e616c69747920736c6173682072657761726420726174696f2060408201526b6f7574206f662072616e676560a01b606082015260800190565b60208082526027908201527f6c656e677468206f66206d697364656d65616e6f725468726573686f6c64206d6040820152660d2e6dac2e8c6d60cb1b606082015260800190565b60208082526013908201527274776f206964656e746963616c20766f74657360681b604082015260600190565b60208082526030908201527f746865206d6573736167652073656e646572206d7573742062652076616c696460408201526f185d1bdc94d95d0818dbdb9d1c9858dd60821b606082015260800190565b6020808252601190820152706164646974696f6e206f766572666c6f7760781b604082015260600190565b6020808252601490820152736761737072696365206973206e6f74207a65726f60601b604082015260600190565b6020808252602e908201527f746865206d6573736167652073656e646572206d75737420626520676f76657260408201526d1b985b98d94818dbdb9d1c9858dd60921b606082015260800190565b60208082526022908201527f6c656e677468206f662066656c6f6e795468726573686f6c64206d69736d61746040820152610c6d60f31b606082015260800190565b60208082526019908201527f74686520636f6e747261637420616c726561647920696e697400000000000000604082015260600190565b6020808252601a908201527f6c656e677468206973206c657373207468616e206f6666736574000000000000604082015260600190565b60208082526025908201527f746865206d697364656d65616e6f725468726573686f6c64206f7574206f662060408201526472616e676560d81b606082015260800190565b6020808252602f908201527f746865206d6573736167652073656e646572206d7573742062652063726f737360408201526e0818da185a5b8818dbdb9d1c9858dd608a1b606082015260800190565b6020808252602d908201527f746865206d6573736167652073656e646572206d75737420626520746865206260408201526c3637b1b590383937b23ab1b2b960991b606082015260800190565b6020808252600d908201526c756e6b6e6f776e20706172616d60981b604082015260600190565b6020808252601e908201527f7265636569766520756e65787065637465642073796e207061636b6167650000604082015260600190565b6020808252602b908201527f6c656e677468206f662066696e616c697479536c61736852657761726452617460408201526a0d2de40dad2e6dac2e8c6d60ab1b606082015260800190565b6020808252818101527f63616e206e6f7420736c61736820747769636520696e206f6e6520626c6f636b604082015260600190565b61ffff91909116815260200190565b90815260200190565b6000838252604060208301526132766040830184612b3a565b949350505050565b918252602082015260400190565b92835260208301919091521515604082015260600190565b63ffffffff91909116815260200190565b60ff91909116815260200190565b600060ff85168252606060208301526132df6060830185612b3a565b9050826040830152949350505050565b60405181810167ffffffffffffffff8111828210171561330e57600080fd5b604052919050565b600067ffffffffffffffff82111561332c578081fd5b5060209081020190565b600067ffffffffffffffff82111561334c578081fd5b50601f01601f191660200190565b60005b8381101561337557818101518382015260200161335d565b838111156116945750506000910152565b6001600160a01b038116811461339b57600080fd5b5056fea2646970667358221220f826c2f80c6807c5df53c6cfe5be2e59ad7e87dad138f63f83dd1caf79118d6064736f6c63430006040033", + }, + { + ContractAddr: SystemRewardContract, + CommitUrl: "https://github.com/bnb-chain/bsc-genesis-contract/commit/b144718e94d7a1ebb24a7103202300f08826f369", + Code: "6080604052600436106101a05760003560e01c80637942fd05116100ec578063ac4317511161008a578063f9a2bbc711610064578063f9a2bbc714610550578063fb5478b314610565578063fc3e59081461057a578063fd6a68791461058f576101e4565b8063ac43175114610457578063c81b166214610526578063dc927faf1461053b576101e4565b80639dc09262116100c65780639dc0926214610403578063a1a11bf514610418578063a78abc161461042d578063ab51bb9614610442576101e4565b80637942fd05146103a057806396713da9146103b55780639a99b4f0146103ca576101e4565b80634bf6c882116101595780636e47b482116101335780636e47b4821461034c57806370fd5bad14610361578063718a8aa81461037657806375d47a0a1461038b576101e4565b80634bf6c882146102db57806351e80672146102f05780636d70f7ae14610305576101e4565b80630bee7a67146101e95780630e2374a5146102175780633a0b0eff146102485780633dffc3871461026f57806343756e5c1461029a578063493279b1146102af576101e4565b366101e45734156101e25760408051348152905133917f6c98249d85d88c3753a04a22230f595e4dc8d3dc86c34af35deeeedc861b89db919081900360200190a25b005b600080fd5b3480156101f557600080fd5b506101fe6105a4565b6040805163ffffffff9092168252519081900360200190f35b34801561022357600080fd5b5061022c6105a9565b604080516001600160a01b039092168252519081900360200190f35b34801561025457600080fd5b5061025d6105af565b60408051918252519081900360200190f35b34801561027b57600080fd5b506102846105b5565b6040805160ff9092168252519081900360200190f35b3480156102a657600080fd5b5061022c6105ba565b3480156102bb57600080fd5b506102c46105c0565b6040805161ffff9092168252519081900360200190f35b3480156102e757600080fd5b506102846105c5565b3480156102fc57600080fd5b5061022c6105ca565b34801561031157600080fd5b506103386004803603602081101561032857600080fd5b50356001600160a01b03166105d0565b604080519115158252519081900360200190f35b34801561035857600080fd5b5061022c6105ee565b34801561036d57600080fd5b506102846105f4565b34801561038257600080fd5b506102846105f9565b34801561039757600080fd5b5061022c6105fe565b3480156103ac57600080fd5b50610284610604565b3480156103c157600080fd5b50610284610609565b3480156103d657600080fd5b5061025d600480360360408110156103ed57600080fd5b506001600160a01b03813516906020013561060e565b34801561040f57600080fd5b5061022c6107b9565b34801561042457600080fd5b5061022c6107bf565b34801561043957600080fd5b506103386107c5565b34801561044e57600080fd5b506101fe6107ce565b34801561046357600080fd5b506101e26004803603604081101561047a57600080fd5b81019060208101813564010000000081111561049557600080fd5b8201836020820111156104a757600080fd5b803590602001918460018302840111640100000000831117156104c957600080fd5b9193909290916020810190356401000000008111156104e757600080fd5b8201836020820111156104f957600080fd5b8035906020019184600183028401116401000000008311171561051b57600080fd5b5090925090506107d3565b34801561053257600080fd5b5061022c610b56565b34801561054757600080fd5b5061022c610b5c565b34801561055c57600080fd5b5061022c610b62565b34801561057157600080fd5b5061025d610b68565b34801561058657600080fd5b50610284610b74565b34801561059b57600080fd5b5061022c610b79565b606481565b61200181565b60015481565b600181565b61100181565b606181565b600881565b61200081565b6001600160a01b031660009081526002602052604090205460ff1690565b61100581565b600281565b601081565b61100881565b600b81565b600981565b6000805460ff1661068b57600260208190527fe57bda0a954a7c7381b17b2c763e646ba2c60f67292d287ba583603e2c1c41668054600160ff19918216811790925561100560009081527fe25235fc0de9d7165652bef0846fefda506174abb9a190f03d0f7bcc6146dbce80548316841790559282558254161790555b3360009081526002602052604090205460ff166106d95760405162461bcd60e51b815260040180806020018281038252602b815260200180610c67602b913960400191505060405180910390fd5b60004783106106e857476106ea565b825b9050670de0b6b3a76400008111156107075750670de0b6b3a76400005b8015610788576040516001600160a01b0385169082156108fc029083906000818181858888f19350505050158015610743573d6000803e3d6000fd5b506040805182815290516001600160a01b038616917ff8b71c64315fc33b2ead2adfa487955065152a8ac33d9d5193aafd7f45dc15a0919081900360200190a26107b2565b6040517fe589651933c2457488cc0d8e0941518abf748e799435e4e396d9c4d0b2db2d4d90600090a15b9392505050565b61100781565b61100681565b60005460ff1681565b600081565b33611007146108135760405162461bcd60e51b815260040180806020018281038252602e815260200180610cc1602e913960400191505060405180910390fd5b61087584848080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152505060408051808201909152600b81526a30b23227b832b930ba37b960a91b60208201529150610b7f9050565b1561094d57606082828080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525050825192935050601490911490506108f85760405162461bcd60e51b815260040180806020018281038252602c815260200180610cef602c913960400191505060405180910390fd5b60148101516001600160a01b038116600081815260026020526040808220805460ff19166001179055517f9870d7fe5d112134c55844951dedf365363006d9c588db07c4c85af6322a06199190a25050610ac4565b6109b284848080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152505060408051808201909152600e81526d3232b632ba32a7b832b930ba37b960911b60208201529150610b7f9050565b15610a8757606082828080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152505082519293505060149091149050610a355760405162461bcd60e51b815260040180806020018281038252602f815260200180610c92602f913960400191505060405180910390fd5b60148101516001600160a01b038116600081815260026020526040808220805460ff19169055517fb40992a19dba61ea600e87fce607102bf5908dc89076217b6ca6ae195224f7029190a25050610ac4565b6040805162461bcd60e51b815260206004820152600d60248201526c756e6b6e6f776e20706172616d60981b604482015290519081900360640190fd5b7f6cdb0ac70ab7f2e2d035cca5be60d89906f2dede7648ddbd7402189c1eeed17a848484846040518080602001806020018381038352878782818152602001925080828437600083820152601f01601f191690910184810383528581526020019050858580828437600083820152604051601f909101601f19169092018290039850909650505050505050a150505050565b61100281565b61100381565b61100081565b670de0b6b3a764000081565b600381565b61100481565b6000816040516020018082805190602001908083835b60208310610bb45780518252601f199092019160209182019101610b95565b6001836020036101000a03801982511681845116808217855250505050505090500191505060405160208183030381529060405280519060200120836040516020018082805190602001908083835b60208310610c225780518252601f199092019160209182019101610c03565b6001836020036101000a038019825116818451168082178552505050505050905001915050604051602081830303815290604052805190602001201490509291505056fe6f6e6c79206f70657261746f7220697320616c6c6f77656420746f2063616c6c20746865206d6574686f646c656e677468206f662076616c756520666f722064656c6574654f70657261746f722073686f756c64206265203230746865206d6573736167652073656e646572206d75737420626520676f7665726e616e636520636f6e74726163746c656e677468206f662076616c756520666f72206164644f70657261746f722073686f756c64206265203230a26469706673582212205c998ac20925f17d8af20803f32be2cf1698c9a844de45001ca5ed8c879cc93f64736f6c63430006040033", + }, + { + ContractAddr: RelayerHubContract, + CommitUrl: "https://github.com/bnb-chain/bsc-genesis-contract/commit/b144718e94d7a1ebb24a7103202300f08826f369", + Code: "608060405234801561001057600080fd5b50600436106102275760003560e01c80638f83ab1311610130578063c81b1662116100b8578063f3ae24151161007c578063f3ae2415146104e8578063f9a2bbc71461050e578063fc3e590814610516578063fd30d9b81461051e578063fd6a68791461052657610227565b8063c81b1662146104c0578063dc927faf146104c8578063dd91d1c5146104d0578063e1c7392a146104d8578063e79a198f146104e057610227565b8063a1a11bf5116100ff578063a1a11bf5146103de578063a74b83ca146103e6578063a78abc16146103ee578063ab51bb96146103f6578063ac431751146103fe57610227565b80638f83ab13146103a057806395468d26146103c657806396713da9146103ce5780639dc09262146103d657610227565b8063541d5548116101b3578063718a8aa811610182578063718a8aa81461034857806375d47a0a1461035057806378beee67146103585780637942fd051461037e5780637ae230881461038657610227565b8063541d5548146102d85780636a6a419e146103125780636e47b4821461033857806370fd5bad1461034057610227565b80633dffc387116101fa5780633dffc3871461028357806343756e5c146102a1578063493279b1146102a95780634bf6c882146102c857806351e80672146102d057610227565b806303aff02b1461022c578063049a5716146102365780630bee7a671461025a5780630e2374a51461027b575b600080fd5b61023461052e565b005b61023e610539565b604080516001600160a01b039092168252519081900360200190f35b610262610551565b6040805163ffffffff9092168252519081900360200190f35b61023e610556565b61028b61055c565b6040805160ff9092168252519081900360200190f35b61023e610561565b6102b1610567565b6040805161ffff9092168252519081900360200190f35b61028b61056c565b61023e610571565b6102fe600480360360208110156102ee57600080fd5b50356001600160a01b0316610577565b604080519115158252519081900360200190f35b6102fe6004803603602081101561032857600080fd5b50356001600160a01b0316610595565b61023e6105b3565b61028b6105b9565b61028b6105be565b61023e6105c3565b6102346004803603602081101561036e57600080fd5b50356001600160a01b03166105c9565b61028b6107b1565b61038e6107b6565b60408051918252519081900360200190f35b610234600480360360208110156103b657600080fd5b50356001600160a01b03166107c3565b61038e610a02565b61028b610a0e565b61023e610a13565b61023e610a19565b61023e610a1f565b6102fe610a37565b610262610a40565b6102346004803603604081101561041457600080fd5b81019060208101813564010000000081111561042f57600080fd5b82018360208201111561044157600080fd5b8035906020019184600183028401116401000000008311171561046357600080fd5b91939092909160208101903564010000000081111561048157600080fd5b82018360208201111561049357600080fd5b803590602001918460018302840111640100000000831117156104b557600080fd5b509092509050610a45565b61023e610d96565b61023e610d9c565b610234610da2565b610234610e43565b610234610ec5565b6102fe600480360360208110156104fe57600080fd5b50356001600160a01b031661107e565b61023e61109c565b61028b6110a2565b6102fe6110a7565b61023e6110b0565b610537336110b6565b565b739fb29aac15b9a4b7f17c3385939b007540f4d79181565b606481565b61200181565b600181565b61100181565b606181565b600881565b61200081565b6001600160a01b031660009081526007602052604090205460ff1690565b6001600160a01b031660009081526008602052604090205460ff1690565b61100581565b600281565b601081565b61100881565b3360009081526008602052604090205460ff166106175760405162461bcd60e51b81526004018080602001828103825260248152602001806115c26024913960400191505060405180910390fd5b61062033611218565b1561065c5760405162461bcd60e51b815260040180806020018281038252602181526020018061157f6021913960400191505060405180910390fd5b3233146106b0576040805162461bcd60e51b815260206004820152601e60248201527f70726f766973696f6e616c2072656c6179657220697320612070726f78790000604482015290519081900360640190fd5b6001600160a01b038181166000908152600960205260409020541633146107085760405162461bcd60e51b815260040180806020018281038252602781526020018061163b6027913960400191505060405180910390fd5b6001600160a01b03818116600081815260066020908152604080832080543380865260078086528487208054600160ff199182161790915584546001600160a01b031990811684179095556008875285882080548216905597875260098652848720805490941690935596168085529083529281902080549094169093558251828152908101939093528151909260008051602061166283398151915292908290030190a15050565b600b81565b68056bc75e2d6310000081565b3360009081526005602052604090205460ff16610820576040805162461bcd60e51b81526020600482015260166024820152751b585b9859d95c88191bd95cc81b9bdd08195e1a5cdd60521b604482015290519081900360640190fd5b61082981611218565b156108655760405162461bcd60e51b81526004018080602001828103825260278152602001806115e66027913960400191505060405180910390fd5b6001600160a01b03811615610921576001600160a01b03811660009081526007602052604090205460ff16156108db576040805162461bcd60e51b815260206004820152601660248201527572656c6179657220616c72656164792065786973747360501b604482015290519081900360640190fd5b6001600160a01b0381166000818152600860209081526040808320805460ff191660011790553383526009909152902080546001600160a01b03191690911790556109c2565b3360008181526006602090815260408083208054600980855283862080546001600160a01b03198085169095556001600160a01b0393841680895260078852868920805460ff19908116909155918516808a5260088952878a20805490931690925598909752908552805490921690915581518581529086169281019290925280516000805160206116628339815191529281900390910190a150506109ff565b604080516001600160a01b038316815290517ffba56633276570c7d3120d4535bf3bce26523da53958e40734210b9fd99b36939181900360200190a15b50565b67016345785d8a000081565b600981565b61100781565b61100681565b7337b8516a0f88e65d677229b402ec6c1e0e33300481565b60005460ff1681565b600081565b60005460ff16610a98576040805162461bcd60e51b81526020600482015260196024820152781d1a194818dbdb9d1c9858dd081b9bdd081a5b9a5d081e595d603a1b604482015290519081900360640190fd5b3361100714610ad85760405162461bcd60e51b815260040180806020018281038252602e81526020018061160d602e913960400191505060405180910390fd5b610b3984848080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152505060408051808201909152600a81526930b23226b0b730b3b2b960b11b6020820152915061121e9050565b15610bd15760148114610b7d5760405162461bcd60e51b81526004018080602001828103825260228152602001806115a06022913960400191505060405180910390fd5b6000610bc0601484848080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061130592505050565b9050610bcb8161130a565b50610d04565b610c3584848080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152505060408051808201909152600d81526c3932b6b7bb32a6b0b730b3b2b960991b6020820152915061121e9050565b15610cc75760148114610c795760405162461bcd60e51b81526004018080602001828103825260228152602001806115a06022913960400191505060405180910390fd5b6000610cbc601484848080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061130592505050565b9050610bcb816110b6565b6040805162461bcd60e51b815260206004820152600d60248201526c756e6b6e6f776e20706172616d60981b604482015290519081900360640190fd5b7f6cdb0ac70ab7f2e2d035cca5be60d89906f2dede7648ddbd7402189c1eeed17a848484846040518080602001806020018381038352878782818152602001925080828437600083820152601f01601f191690910184810383528581526020019050858580828437600083820152604051601f909101601f19169092018290039850909650505050505050a150505050565b61100281565b61100381565b600a5460ff1615610dfa576040805162461bcd60e51b815260206004820152601e60248201527f7468652077686974656c6973747320616c726561647920757064617465640000604482015290519081900360640190fd5b610e17739fb29aac15b9a4b7f17c3385939b007540f4d7916113cc565b610e347337b8516a0f88e65d677229b402ec6c1e0e3330046113cc565b600a805460ff19166001179055565b60005460ff1615610e9b576040805162461bcd60e51b815260206004820152601960248201527f74686520636f6e747261637420616c726561647920696e697400000000000000604482015290519081900360640190fd5b68056bc75e2d63100000600190815567016345785d8a00006002556000805460ff19169091179055565b3360009081526004602052604090205460ff16610f20576040805162461bcd60e51b81526020600482015260146024820152731c995b185e595c88191bc81b9bdd08195e1a5cdd60621b604482015290519081900360640190fd5b60005460ff16610f73576040805162461bcd60e51b81526020600482015260196024820152781d1a194818dbdb9d1c9858dd081b9bdd081a5b9a5d081e595d603a1b604482015290519081900360640190fd5b610f7b611564565b5033600081815260036020908152604091829020825180840190935280548084526001909101549183018290529192916108fc91610fbf919063ffffffff61148416565b6040518115909202916000818181858888f19350505050158015610fe7573d6000803e3d6000fd5b50602081015160405161100291829181156108fc0291906000818181858888f1935050505015801561101d573d6000803e3d6000fd5b50336000818152600460209081526040808320805460ff191690556003825280832083815560010192909255815192835290517fd17202129b83db7880d6b9f25df81c58ad46f7e0e2c92236b1aa10663a4876679281900390910190a15050565b6001600160a01b031660009081526005602052604090205460ff1690565b61100081565b600381565b600a5460ff1681565b61100481565b6001600160a01b03811660009081526005602052604090205460ff1661111b576040805162461bcd60e51b81526020600482015260156024820152741b585b9859d95c88191bd95cdb89dd08195e1a5cdd605a1b604482015290519081900360640190fd5b6001600160a01b038082166000818152600660209081526040808320805460058452828520805460ff1990811690915582546001600160a01b0319908116909355600980865284872080548a16885260088752858820805490931690925595879052948452845490911690935580519384525191909316927f2002866d443ac6c241fecaaa2af4895828c7de2cc423b9d01f7969650f557c76928290030190a16001600160a01b03811615611214576001600160a01b0381166000818152600760209081526040808320805460ff1916905580519384529083019190915280516000805160206116628339815191529281900390910190a15b5050565b3b151590565b6000816040516020018082805190602001908083835b602083106112535780518252601f199092019160209182019101611234565b6001836020036101000a03801982511681845116808217855250505050505090500191505060405160208183030381529060405280519060200120836040516020018082805190602001908083835b602083106112c15780518252601f1990920191602091820191016112a2565b6001836020036101000a0380198251168184511680821785525050505050509050019150506040516020818303038152906040528051906020012014905092915050565b015190565b6001600160a01b03811660009081526005602052604090205460ff1615611371576040805162461bcd60e51b81526020600482015260166024820152756d616e6167657220616c72656164792065786973747360501b604482015290519081900360640190fd5b6001600160a01b038116600081815260056020908152604091829020805460ff19166001179055815192835290517fe0de8e71a22c046647f4ef744348fa126ad6d052d4ce070999481f69d45575179281900390910190a150565b6001600160a01b03811660008181526005602090815260408083208054600160ff1991821681179092556006845282852080546001600160a01b031916871790556007845293829020805490941617909255815192835290517fe0de8e71a22c046647f4ef744348fa126ad6d052d4ce070999481f69d45575179281900390910190a160408051600081526001600160a01b03831660208201528151600080516020611662833981519152929181900390910190a150565b60006114c683836040518060400160405280601e81526020017f536166654d6174683a207375627472616374696f6e206f766572666c6f7700008152506114cd565b9392505050565b6000818484111561155c5760405162461bcd60e51b81526004018080602001828103825283818151815260200191508051906020019080838360005b83811015611521578181015183820152602001611509565b50505050905090810190601f16801561154e5780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b505050900390565b60405180604001604052806000815260200160008152509056fe70726f766973696f6e616c2072656c61796572206973206120636f6e74726163746c656e677468206f66206d616e616765722061646472657373206d69736d6174636872656c61796572206973206e6f7420612070726f766973696f6e616c2072656c61796572636f6e7472616374206973206e6f7420616c6c6f77656420746f20626520612072656c61796572746865206d6573736167652073656e646572206d75737420626520676f7665726e616e636520636f6e747261637470726f766973696f6e616c206973206e6f742073657420666f722074686973206d616e61676572a5a19d7e9dab30a215022382d7abe782b579986fcbedec9942ecd0db9510a148a2646970667358221220e87e5b6ca8388e14d2ec9c2453581b5e2346a0aaa8fa61707f4d522357ac45d464736f6c63430006040033", + }, + { + ContractAddr: CrossChainContract, + CommitUrl: "https://github.com/bnb-chain/bsc-genesis-contract/commit/b144718e94d7a1ebb24a7103202300f08826f369", + Code: "608060405234801561001057600080fd5b50600436106103995760003560e01c8063718a8aa8116101e9578063c27cdcfb1161010f578063dc927faf116100ad578063f7a251d71161007c578063f7a251d714610b2f578063f9a2bbc714610ba7578063fc3e590814610baf578063fd6a687914610bb757610399565b8063dc927faf14610af7578063e1c7392a14610aff578063e3b0480514610b07578063e6400bbe14610b2757610399565b8063ccc108d7116100e9578063ccc108d714610ab0578063d31f968d14610ab8578063d76a867514610ae7578063dc40433114610aef57610399565b8063c27cdcfb14610a80578063c780e9de14610aa0578063c81b166214610aa857610399565b80638cc8f56111610187578063a78abc1611610156578063a78abc16146109b2578063ab51bb96146109ba578063ac431751146109c2578063b0355f5b1461078157610399565b80638cc8f5611461088757806396713da91461099a5780639dc09262146109a2578063a1a11bf5146109aa57610399565b806375d47a0a116101c357806375d47a0a146108a75780637942fd05146108af57806384013b6a146108b7578063863fe4ab1461099257610399565b8063718a8aa81461088f578063719482d51461089757806374f079b81461089f57610399565b8063422f9050116102ce57806363e1394e1161026c5780636de380bd1161023b5780636de380bd146108575780636e47a51a1461085f5780636e47b4821461087f57806370fd5bad1461088757610399565b806363e1394e146107ff5780636a3cb34d146108075780636bacff2c1461080f5780636c46aa681461080757610399565b80634bf6c882116102a85780634bf6c882146107b957806351e80672146107c15780635692ddd3146107c95780635f832177146107d157610399565b8063422f90501461078957806343756e5c146107a9578063493279b1146107b157610399565b8063299b533d1161033b578063308325f411610315578063308325f4146106155780633a648b151461061d5780633bdc47a6146106595780633dffc3871461078157610399565b8063299b533d146105a35780632af6f399146105d75780632ff32aea146105f457610399565b806314b3023b1161037757806314b3023b146104015780631d1309351461041b5780631e275ae11461043757806322556cdc1461059b57610399565b806305e682581461039e5780630bee7a67146103bc5780630e2374a5146103dd575b600080fd5b6103a6610bbf565b6040805160ff9092168252519081900360200190f35b6103c4610bc4565b6040805163ffffffff9092168252519081900360200190f35b6103e5610bc9565b604080516001600160a01b039092168252519081900360200190f35b610409610bcf565b60408051918252519081900360200190f35b610423610bd5565b604080519115158252519081900360200190f35b610599600480360361010081101561044e57600080fd5b81018160a081016080820135600160201b81111561046b57600080fd5b82018360208201111561047d57600080fd5b803590602001918460018302840111600160201b8311171561049e57600080fd5b919390929091602081019035600160201b8111156104bb57600080fd5b8201836020820111156104cd57600080fd5b803590602001918460018302840111600160201b831117156104ee57600080fd5b919390929091602081019035600160201b81111561050b57600080fd5b82018360208201111561051d57600080fd5b803590602001918460018302840111600160201b8311171561053e57600080fd5b919390929091602081019035600160201b81111561055b57600080fd5b82018360208201111561056d57600080fd5b803590602001918460018302840111600160201b8311171561058e57600080fd5b509092509050610bde565b005b6104096112c2565b6105c0600480360360208110156105b957600080fd5b50356112c7565b6040805161ffff9092168252519081900360200190f35b610423600480360360208110156105ed57600080fd5b50356112dd565b6105fc6112f2565b60408051600792830b90920b8252519081900360200190f35b6104096112fb565b61063d6004803603602081101561063357600080fd5b503560ff16611301565b604080516001600160401b039092168252519081900360200190f35b61070c6004803603606081101561066f57600080fd5b60ff82351691602081013591810190606081016040820135600160201b81111561069857600080fd5b8201836020820111156106aa57600080fd5b803590602001918460018302840111600160201b831117156106cb57600080fd5b91908080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525092955061131c945050505050565b6040805160208082528351818301528351919283929083019185019080838360005b8381101561074657818101518382015260200161072e565b50505050905090810190601f1680156107735780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b6103a6611392565b6104236004803603602081101561079f57600080fd5b503560ff16611397565b6103e56113ac565b6105c06113b2565b6103a66113b7565b6103e56113bc565b6104096113c2565b610599600480360360408110156107e757600080fd5b506001600160a01b03813581169160200135166113f2565b610409611652565b6105c061167a565b61082c6004803603602081101561082557600080fd5b503561167f565b6040805161ffff90941684526001600160801b03909216602084015282820152519081900360600190f35b6104096116ae565b6103e56004803603602081101561087557600080fd5b503560ff166116d5565b6103e56116f0565b6103a661167a565b6103a66116f6565b6105c0611392565b6104096116fb565b6103e5611701565b6103a6611707565b610599600480360360a08110156108cd57600080fd5b810190602081018135600160201b8111156108e757600080fd5b8201836020820111156108f957600080fd5b803590602001918460018302840111600160201b8311171561091a57600080fd5b919390929091602081019035600160201b81111561093757600080fd5b82018360208201111561094957600080fd5b803590602001918460018302840111600160201b8311171561096a57600080fd5b919350915080356001600160401b03908116916020810135909116906040013560ff1661170c565b6104096129c6565b6103a66129ce565b6103e56129d3565b6103e56129d9565b6104236129df565b6103c4610bbf565b610599600480360360408110156109d857600080fd5b810190602081018135600160201b8111156109f257600080fd5b820183602082011115610a0457600080fd5b803590602001918460018302840111600160201b83111715610a2557600080fd5b919390929091602081019035600160201b811115610a4257600080fd5b820183602082011115610a5457600080fd5b803590602001918460018302840111600160201b83111715610a7557600080fd5b5090925090506129e8565b61063d60048036036020811015610a9657600080fd5b503560ff166134ac565b6104096134c7565b6103e56134eb565b6105996134f1565b61042360048036036040811015610ace57600080fd5b5080356001600160a01b0316906020013560ff16613745565b61070c613765565b610409613784565b6103e561378a565b610599613790565b61063d60048036036020811015610b1d57600080fd5b503560ff16613b47565b610599613b62565b61059960048036036060811015610b4557600080fd5b60ff8235169190810190604081016020820135600160201b811115610b6957600080fd5b820183602082011115610b7b57600080fd5b803590602001918460018302840111600160201b83111715610b9c57600080fd5b919350915035613d81565b6103e5613ec4565b6103a6613eca565b6103e5613ecf565b600081565b606481565b61200181565b60015481565b600b5460ff1681565b60005460ff16610c23576040805162461bcd60e51b815260206004820152601960248201526000805160206149b2833981519152604482015290519081900360640190fd5b604080516337d7f9c160e21b81526001600160401b038b35166004820181905291516110039163df5fe704916024808301926020929190829003018186803b158015610c6e57600080fd5b505afa158015610c82573d6000803e3d6000fd5b505050506040513d6020811015610c9857600080fd5b5051610cd55760405162461bcd60e51b81526004018080602001828103825260238152602001806149d26023913960400191505060405180910390fd5b604080516337d7f9c160e21b815260208c8101356001600160401b03166004830181905292516110039263df5fe704926024808301939192829003018186803b158015610d2157600080fd5b505afa158015610d35573d6000803e3d6000fd5b505050506040513d6020811015610d4b57600080fd5b5051610d885760405162461bcd60e51b81526004018080602001828103825260238152602001806149d26023913960400191505060405180910390fd5b60608b013560ff81166000908152600560205260409020546001600160401b03909116906001600160a01b0316610e01576040805162461bcd60e51b815260206004820152601860248201527718da185b9b995b081a5cc81b9bdd081cdd5c1c1bdc9d195960421b604482015290519081900360640190fd5b600b5460ff1615610e45576040805162461bcd60e51b81526020600482015260096024820152681cdd5cdc195b99195960ba1b604482015290519081900360640190fd5b8888604051808383808284376040519201829003822094508f93508e9250819050838380828437808301925050509250505060405180910390201415610ec1576040805162461bcd60e51b815260206004820152600c60248201526b1cd85b59481c185e5b1bd85960a21b604482015290519081900360640190fd5b60606001600160401b0360408e01358116908e83013516610ee28282613ed5565b80516020808301919091206000818152600e9092526040909120549194509060ff1615610f4b576040805162461bcd60e51b8152602060048201526012602482015271185b1c9958591e4818da185b1b195b99d95960721b604482015290519081900360640190fd5b6000908152600e60205260408120805460ff191660011790558f8160200201356001600160401b0316905060608f8f8080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f82011690508083019250505050505050905060608c8c8080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201829052506040805163cba510a960e01b81526001600160401b038a16600482015290519596509094611003945063cba510a9935060248083019350602092829003018186803b15801561104157600080fd5b505afa158015611055573d6000803e3d6000fd5b505050506040513d602081101561106b57600080fd5b505160408051808201909152600381526269626360e81b6020820152909150611098908290898686613f1d565b6110e1576040805162461bcd60e51b81526020600482015260156024820152740696e76616c6964206d65726b6c652070726f6f663605c1b604482015290519081900360640190fd5b5050505060008f6001600481106110f457fe5b60200201356001600160401b0316905060608d8d8080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525050604080516020601f8f018190048102820181019092528d815293945060609392508d91508c908190840183828082843760009201829052506040805163cba510a960e01b81526001600160401b038a16600482015290519596509094611003945063cba510a9935060248083019350602092829003018186803b1580156111c057600080fd5b505afa1580156111d4573d6000803e3d6000fd5b505050506040513d60208110156111ea57600080fd5b505160408051808201909152600381526269626360e81b6020820152909150611217908290898686613f1d565b611260576040805162461bcd60e51b8152602060048201526015602482015274696e76616c6964206d65726b6c652070726f6f663160581b604482015290519081900360640190fd5b5050505061126c61401a565b604080516001600160401b038416815260ff83166020820152815133927f039eb91179ffd7d3b6e97f8ea106e748e827f910b872375dbc9c14a362319c3c928290030190a2505050505050505050505050505050565b603281565b600d6020526000908152604090205461ffff1681565b600e6020526000908152604090205460ff1681565b60045460070b81565b60025481565b600a602052600090815260409020546001600160401b031681565b60606000825160210190506060816040519080825280601f01601f191660200182016040528015611354576020820181803683370190505b506021810186905260018101879052828152905060418101600061137786614098565b509050611386818388516140a2565b50909695505050505050565b600181565b60096020526000908152604090205460ff1681565b61100181565b606181565b600881565b61200081565b604080517710d05390d15317d514905394d1915497d41493d413d4d05360421b8152905190819003601801902081565b60005460ff16611437576040805162461bcd60e51b815260206004820152601960248201526000805160206149b2833981519152604482015290519081900360640190fd5b6040805163569e4ed360e11b815233600482015290516000916110009163ad3c9da691602480820192602092909190829003018186803b15801561147a57600080fd5b505afa15801561148e573d6000803e3d6000fd5b505050506040513d60208110156114a457600080fd5b505160408051633d42651560e11b8152905191925060009161100091637a84ca2a916004808301926020929190829003018186803b1580156114e557600080fd5b505afa1580156114f9573d6000803e3d6000fd5b505050506040513d602081101561150f57600080fd5b505190508061151c575060155b60008211801561152c5750808211155b61156b576040805162461bcd60e51b815260206004820152600b60248201526a1b9bdd0818d8589a5b995d60aa1b604482015290519081900360640190fd5b604080516001600160a01b038087166020808401919091529086168284015282518083038401815260608301808552815191909201207710d05390d15317d514905394d1915497d41493d413d4d05360421b90915291519081900360780190206000906115d890836140e3565b9050801561164a5760408051630911a2c160e11b81526001600160a01b03888116600483015287166024820152905161100491631223458291604480830192600092919082900301818387803b15801561163157600080fd5b505af1158015611645573d6000803e3d6000fd5b505050505b505050505050565b604080516f14d554d411539117d41493d413d4d05360821b8152905190819003601001902081565b600281565b600c602052600090815260409020805460019091015461ffff8216916201000090046001600160801b03169083565b604080516e149153d4115397d41493d413d4d053608a1b8152905190819003600f01902081565b6005602052600090815260409020546001600160a01b031681565b61100581565b601081565b60035481565b61100881565b600b81565b60005460ff16611751576040805162461bcd60e51b815260206004820152601960248201526000805160206149b2833981519152604482015290519081900360640190fd5b60408051630a83aaa960e31b815233600482015290516110069163541d5548916024808301926020929190829003018186803b15801561179057600080fd5b505afa1580156117a4573d6000803e3d6000fd5b505050506040513d60208110156117ba57600080fd5b505161180d576040805162461bcd60e51b815260206004820152601f60248201527f746865206d73672073656e646572206973206e6f7420612072656c6179657200604482015290519081900360640190fd5b60ff8116600090815260086020526040902054829082906001600160401b03908116908316811461187d576040805162461bcd60e51b815260206004820152601560248201527439b2b8bab2b731b2903737ba1034b71037b93232b960591b604482015290519081900360640190fd5b60ff8216600090815260086020908152604091829020805467ffffffffffffffff1916600185016001600160401b039081169190911790915582516337d7f9c160e21b81529089166004820152915188926110039263df5fe70492602480840193829003018186803b1580156118f257600080fd5b505afa158015611906573d6000803e3d6000fd5b505050506040513d602081101561191c57600080fd5b50516119595760405162461bcd60e51b81526004018080602001828103825260238152602001806149d26023913960400191505060405180910390fd5b60ff851660009081526005602052604090205485906001600160a01b03166119c3576040805162461bcd60e51b815260206004820152601860248201527718da185b9b995b081a5cc81b9bdd081cdd5c1c1bdc9d195960421b604482015290519081900360640190fd5b60ff86166000908152600a6020526040902054889087906001600160401b039081169083161015611a2c576040805162461bcd60e51b815260206004820152600e60248201526d3a37b79037b632103432b0b232b960911b604482015290519081900360640190fd5b60ff81166000908152600a60205260409020546001600160401b03838116911614611a7e5760ff81166000908152600a60205260409020805467ffffffffffffffff19166001600160401b0384161790555b600b5460ff1615611ac2576040805162461bcd60e51b81526020600482015260096024820152681cdd5cdc195b99195960ba1b604482015290519081900360640190fd5b60608e8e8080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f82011690508083019250505050505050905060608d8d8080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f820116905080830192505050505050509050611c066110036001600160a01b031663cba510a98e6040518263ffffffff1660e01b815260040180826001600160401b03166001600160401b0316815260200191505060206040518083038186803b158015611baf57600080fd5b505afa158015611bc3573d6000803e3d6000fd5b505050506040513d6020811015611bd957600080fd5b505160408051808201909152600381526269626360e81b6020820152611bff8e8e613ed5565b8585613f1d565b611c4e576040805162461bcd60e51b815260206004820152601460248201527334b73b30b634b21036b2b935b63290383937b7b360611b604482015290519081900360640190fd5b60408051631bb5062960e31b81526001600160401b038e16600482015290516000916110039163dda8314891602480820192602092909190829003018186803b158015611c9a57600080fd5b505afa158015611cae573d6000803e3d6000fd5b505050506040513d6020811015611cc457600080fd5b505190508b8b600080806060611cd9896143c8565b935093509350935083611d9b578460ff16866001600160401b03167ff7b2e42d694eb1100184aae86d4245d9e46966100b1dc7e723275b98326854ac8b6040518080602001828103825283818151815260200191508051906020019080838360005b83811015611d53578181015183820152602001611d3b565b50505050905090810190601f168015611d805780820380516001836020036101000a031916815260200191505b509250505060405180910390a35050505050505050506129b6565b6040805160ff85811682529151918716916001600160401b038916917f36afdaf439a8f43fe72135135d804ae620b37a474f0943b5b85f6788312cad40919081900360200190a360ff83166123205760ff85166000818152600560209081526040808320548151631182b87560e01b815260048101958652602481019283528651604482015286516001600160a01b03909216958695631182b875958d958a9593949093606490910192918601918190849084905b83811015611e68578181015183820152602001611e50565b50505050905090810190601f168015611e955780820380516001836020036101000a031916815260200191505b509350505050600060405180830381600087803b158015611eb557600080fd5b505af1925050508015611f9957506040513d6000823e601f3d908101601f191682016040526020811015611ee857600080fd5b8101908080516040519392919084600160201b821115611f0757600080fd5b908301906020820185811115611f1c57600080fd5b8251600160201b811182820188101715611f3557600080fd5b82525081516020918201929091019080838360005b83811015611f62578181015183820152602001611f4a565b50505050905090810190601f168015611f8f5780820380516001836020036101000a031916815260200191505b5060405250505060015b6122ab576040516000815260443d1015611fb557506000612050565b60046000803e60005160e01c6308c379a08114611fd6576000915050612050565b60043d036004833e81513d60248201116001600160401b038211171561200157600092505050612050565b80830180516001600160401b03811115612022576000945050505050612050565b8060208301013d860181111561204057600095505050505050612050565b601f01601f191660405250925050505b8061205b575061216d565b60ff8716600090815260076020526040812054612092916001600160401b0390911690899061208d906002908861131c565b614478565b60ff8716600090815260076020908152604080832080546001600160401b038082166001011667ffffffffffffffff19909116179055805182815284518184015284516001600160a01b038716947ff91a8f63e5b3e0e89e5f93e1915a7805f3c52d9a73b3c09769785c2c7bf87acf948794849390840192918601918190849084905b8381101561212d578181015183820152602001612115565b50505050905090810190601f16801561215a5780820380516001836020036101000a031916815260200191505b509250505060405180910390a2506122a6565b3d808015612197576040519150601f19603f3d011682016040523d82523d6000602084013e61219c565b606091505b5060ff87166000908152600760205260408120546121cf916001600160401b0390911690899061208d906002908861131c565b60ff8716600090815260076020908152604080832080546001600160401b038082166001011667ffffffffffffffff19909116179055805182815284518184015284516001600160a01b038716947f63ac299d6332d1cc4e61b81e59bc00c0ac7c798addadf33840f1307cd2977351948794849390840192918601918190849084905b8381101561226a578181015183820152602001612252565b50505050905090810190601f1680156122975780820380516001836020036101000a031916815260200191505b509250505060405180910390a2505b61231a565b8051156123185760ff87166000908152600760205260408120546122e4916001600160401b0390911690899061208d906001908661131c565b60ff8716600090815260076020526040902080546001600160401b038082166001011667ffffffffffffffff199091161790555b505b506128ee565b60ff8316600114156125c45760ff8516600081815260056020908152604080832054815163831d65d160e01b815260048101958652602481019283528651604482015286516001600160a01b0390921695869563831d65d1958d958a9593949093606490910192918601918190849084905b838110156123aa578181015183820152602001612392565b50505050905090810190601f1680156123d75780820380516001836020036101000a031916815260200191505b509350505050600060405180830381600087803b1580156123f757600080fd5b505af1925050508015612408575060015b61231a576040516000815260443d1015612424575060006124bf565b60046000803e60005160e01c6308c379a081146124455760009150506124bf565b60043d036004833e81513d60248201116001600160401b0382111715612470576000925050506124bf565b80830180516001600160401b038111156124915760009450505050506124bf565b8060208301013d86018111156124af576000955050505050506124bf565b601f01601f191660405250925050505b806124ca575061252f565b60408051602080825283518183015283516001600160a01b038616937ff91a8f63e5b3e0e89e5f93e1915a7805f3c52d9a73b3c09769785c2c7bf87acf938693909283928301918501908083836000831561212d578181015183820152602001612115565b3d808015612559576040519150601f19603f3d011682016040523d82523d6000602084013e61255e565b606091505b5060408051602080825283518183015283516001600160a01b038616937f63ac299d6332d1cc4e61b81e59bc00c0ac7c798addadf33840f1307cd2977351938693909283928301918501908083836000831561226a578181015183820152602001612252565b60ff8316600214156128ee5760ff8516600081815260056020908152604080832054815163c8509d8160e01b815260048101958652602481019283528651604482015286516001600160a01b0390921695869563c8509d81958d958a9593949093606490910192918601918190849084905b8381101561264e578181015183820152602001612636565b50505050905090810190601f16801561267b5780820380516001836020036101000a031916815260200191505b509350505050600060405180830381600087803b15801561269b57600080fd5b505af19250505080156126ac575060015b6128ec576040516000815260443d10156126c857506000612763565b60046000803e60005160e01c6308c379a081146126e9576000915050612763565b60043d036004833e81513d60248201116001600160401b038211171561271457600092505050612763565b80830180516001600160401b03811115612735576000945050505050612763565b8060208301013d860181111561275357600095505050505050612763565b601f01601f191660405250925050505b8061276e5750612817565b816001600160a01b03167ff91a8f63e5b3e0e89e5f93e1915a7805f3c52d9a73b3c09769785c2c7bf87acf826040518080602001828103825283818151815260200191508051906020019080838360005b838110156127d75781810151838201526020016127bf565b50505050905090810190601f1680156128045780820380516001836020036101000a031916815260200191505b509250505060405180910390a2506128ec565b3d808015612841576040519150601f19603f3d011682016040523d82523d6000602084013e612846565b606091505b50816001600160a01b03167f63ac299d6332d1cc4e61b81e59bc00c0ac7c798addadf33840f1307cd2977351826040518080602001828103825283818151815260200191508051906020019080838360005b838110156128b0578181015183820152602001612898565b50505050905090810190601f1680156128dd5780820380516001836020036101000a031916815260200191505b509250505060405180910390a2505b505b60ff80861660009081526009602052604090205461100591636f93d2e6918a91339187911680612920575060ff881615155b604080516001600160e01b031960e088901b1681526001600160a01b039586166004820152939094166024840152604483019190915215156064820152905160848083019260209291908290030181600087803b15801561298057600080fd5b505af1158015612994573d6000803e3d6000fd5b505050506040513d60208110156129aa57600080fd5b50505050505050505050505b5050505050505050505050505050565b630100610081565b600981565b61100781565b61100681565b60005460ff1681565b3361100714612a285760405162461bcd60e51b815260040180806020018281038252602e815260200180614908602e913960400191505060405180910390fd5b600b5460ff1615612a6c576040805162461bcd60e51b81526020600482015260096024820152681cdd5cdc195b99195960ba1b604482015290519081900360640190fd5b612ad584848080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525050604080518082019091526012815271626174636853697a65466f724f7261636c6560701b602082015291506146129050565b15612b7057604080516020601f8401819004810282018101909252828152600091612b18918585808385018382808284376000920191909152506146f992505050565b90506127108111158015612b2d5750600a8110155b612b685760405162461bcd60e51b81526004018080602001828103825260328152602001806149806032913960400191505060405180910390fd5b60015561341a565b612bd984848080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152505060408051808201909152601281527118591913dc955c19185d1950da185b9b995b60721b602082015291506146129050565b15612d6157606082828080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152505082519293505060169091149050612c5c5760405162461bcd60e51b815260040180806020018281038252605a815260200180614821605a913960600191505060405180910390fd5b60018101516002820151601683015160ff82161590612c7a816146fe565b612ccb576040805162461bcd60e51b815260206004820152601960248201527f61646472657373206973206e6f74206120636f6e747261637400000000000000604482015290519081900360640190fd5b60ff8416600081815260056020908152604080832080546001600160a01b0319166001600160a01b038716908117909155808452600683528184208585528352818420805460ff199081166001179091556009909352818420805490931687151517909255519092917f7e3b6af43092577ee20e60eaa1d9b114a7031305c895ee7dd3ffe17196d2e1e091a3505050505061341a565b612dce84848080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525050604080518082019091526016815275195b98589b1953dc911a5cd8589b1950da185b9b995b60521b602082015291506146129050565b15612eff57606082828080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152505082519293505060029091149050612e515760405162461bcd60e51b815260040180806020018281038252604a815260200180614936604a913960600191505060405180910390fd5b600181810151600283015160ff80831660009081526005602052604090205492939192908316909114906001600160a01b03168015612ef5576001600160a01b038116600090815260066020908152604080832060ff881680855290835292819020805460ff1916861515908117909155815190815290517fa3132e3f9819fbddc7f0ed6d38d7feef59aa95112090b7c592f5cb5bc4aa4adc929181900390910190a25b505050505061341a565b612f6384848080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152505060408051808201909152600d81526c73757370656e6451756f72756d60981b602082015291506146129050565b156130985760028114612fa75760405162461bcd60e51b815260040180806020018281038252602d8152602001806148af602d913960400191505060405180910390fd5b6000612fea600284848080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152506146f992505050565b905060008161ffff16118015613004575060648161ffff16105b61304e576040805162461bcd60e51b8152602060048201526016602482015275696e76616c69642073757370656e642071756f72756d60501b604482015290519081900360640190fd5b604080516f14d554d411539117d41493d413d4d05360821b815281519081900360100190206000908152600d60205220805461ffff90921661ffff1990921691909117905561341a565b6130fb84848080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152505060408051808201909152600c81526b72656f70656e51756f72756d60a01b602082015291506146129050565b1561322e576002811461313f5760405162461bcd60e51b815260040180806020018281038252602c8152602001806148dc602c913960400191505060405180910390fd5b6000613182600284848080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152506146f992505050565b905060008161ffff1611801561319c575060648161ffff16105b6131e5576040805162461bcd60e51b8152602060048201526015602482015274696e76616c69642072656f70656e2071756f72756d60581b604482015290519081900360640190fd5b604080516e149153d4115397d41493d413d4d053608a1b8152815190819003600f0190206000908152600d60205220805461ffff90921661ffff1990921691909117905561341a565b61329984848080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152505060408051808201909152601481527363616e63656c5472616e7366657251756f72756d60601b602082015291506146129050565b156133dd57600281146132dd5760405162461bcd60e51b815260040180806020018281038252603481526020018061487b6034913960400191505060405180910390fd5b6000613320600284848080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152506146f992505050565b905060008161ffff1611801561333a575060648161ffff16105b61338b576040805162461bcd60e51b815260206004820152601e60248201527f696e76616c69642063616e63656c207472616e736665722071756f72756d0000604482015290519081900360640190fd5b604080517710d05390d15317d514905394d1915497d41493d413d4d05360421b815281519081900360180190206000908152600d60205220805461ffff90921661ffff1990921691909117905561341a565b6040805162461bcd60e51b815260206004820152600d60248201526c756e6b6e6f776e20706172616d60981b604482015290519081900360640190fd5b7f6cdb0ac70ab7f2e2d035cca5be60d89906f2dede7648ddbd7402189c1eeed17a848484846040518080602001806020018381038352878782818152602001925080828437600083820152601f01601f191690910184810383528581526020019050858580828437600083820152604051601f909101601f19169092018290039850909650505050505050a150505050565b6008602052600090815260409020546001600160401b031681565b7fc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a47081565b61100281565b60005460ff16613536576040805162461bcd60e51b815260206004820152601960248201526000805160206149b2833981519152604482015290519081900360640190fd5b6040805163569e4ed360e11b815233600482015290516000916110009163ad3c9da691602480820192602092909190829003018186803b15801561357957600080fd5b505afa15801561358d573d6000803e3d6000fd5b505050506040513d60208110156135a357600080fd5b505160408051633d42651560e11b8152905191925060009161100091637a84ca2a916004808301926020929190829003018186803b1580156135e457600080fd5b505afa1580156135f8573d6000803e3d6000fd5b505050506040513d602081101561360e57600080fd5b505190508061361b575060155b60008211801561362b5750808211155b61366a576040805162461bcd60e51b815260206004820152600b60248201526a1b9bdd0818d8589a5b995d60aa1b604482015290519081900360640190fd5b600b5460ff166136b1576040805162461bcd60e51b815260206004820152600d60248201526c1b9bdd081cdd5cdc195b991959609a1b604482015290519081900360640190fd5b604080516e149153d4115397d41493d413d4d053608a1b8152905190819003600f019020600090613702907fc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a4706140e3565b9050801561374057600b805460ff1916905560405133907f899fe8c37dc61708a3aaa99c4bf143346c1d1da69af79be9e8920c0a6785b75290600090a25b505050565b600660209081526000928352604080842090915290825290205460ff1681565b6040518060400160405280600381526020016269626360e81b81525081565b610e1081565b61100381565b60005460ff16156137e8576040805162461bcd60e51b815260206004820152601960248201527f74686520636f6e747261637420616c726561647920696e697400000000000000604482015290519081900360640190fd5b7f1471eb6eb2c5e789fc3de43f8ce62938c7d1836ec861730447e2ada8fd81017b80546001600160a01b0319908116611008179091557f92e85d02570a8092d09a6e3a57665bc3815a2699a4074001bf1ccabf660f5a36805460ff199081169091557fd8af288fc1c8680b4f4706064cf021e264efb6828fcaf7eb5ca36818eb365bcc8054821660019081179091557f89832631fb3c3307a103ba2c84ab569c64d6182a18893dcd163f0f1c2090733a805484166110049081179091557f6cde3cea4b3a3fb2488b2808bae7556f4a405e50f65e1794383bc026131b13c38054841690557f72e4efa1513b071517c6c74dba31b5934a81aa83cddd400e7081df5529c9943680548416831790557fa9bc9a3a348c357ba16b37005d7e6b3236198c0e939f4af8c5f19b8deeb8ebc08054851690911790557fc575c31fea594a6eb97c8e9d3f9caee4c16218c6ef37e923234c0fe9014a61e78054831690557f4e523af77f034e9810f1c94057f5e931fb3d16a51511a4c3add793617d18610580548316821790557ffb33122aa9f93cc639ebe80a7bc4784c11e6053dde89c6f4f7e268c6a623da1e805484166110001790557fc7694af312c4f286114180fd0ba6a52461fcee8a381636770b19a343af92538a80548316821790557f01112dd68e482ba8d68a7e828cff8b3abcea08eab88941953c180a7e650e9cd480548316821790557fc0a4a8be475dfebc377ebef2d7c4ff47656f572a08dd92b81017efcdba0febe1805484166110071790557f87e8a52529e8ece4ef759037313542a6429ff494a9fab9027fb79db90124eba680548316821790557f4c7666bbcb22d46469f7cc282f70764a7012dca2cce630ff8d83db9a9cdd48f080548316821790557f40f28f99a40bc9f6beea1013afdbc3cdcc689eb76b82c4de06c0acf1e1932ed58054909316611001179092557f0d9cf2cd531699eed8dd34e40ff2884a14a698c4898184fba85194e6f6772d248054821683179055600b60009081527f23f68c9bd22b8a93d06adabe17481c87c016bcbd20adc8bfd707a4d813a572176020527fdf0d5d05428057f5455c2dc8e810dd86d1e9350faa72f16bda8a45443c5b39328054831684179055603283556004805467ffffffffffffffff19166001600160401b031790556002819055600381905580549091169091179055565b6007602052600090815260409020546001600160401b031681565b60005460ff16613ba7576040805162461bcd60e51b815260206004820152601960248201526000805160206149b2833981519152604482015290519081900360640190fd5b6040805163569e4ed360e11b815233600482015290516000916110009163ad3c9da691602480820192602092909190829003018186803b158015613bea57600080fd5b505afa158015613bfe573d6000803e3d6000fd5b505050506040513d6020811015613c1457600080fd5b505160408051633d42651560e11b8152905191925060009161100091637a84ca2a916004808301926020929190829003018186803b158015613c5557600080fd5b505afa158015613c69573d6000803e3d6000fd5b505050506040513d6020811015613c7f57600080fd5b5051905080613c8c575060155b600082118015613c9c5750808211155b613cdb576040805162461bcd60e51b815260206004820152600b60248201526a1b9bdd0818d8589a5b995d60aa1b604482015290519081900360640190fd5b600b5460ff1615613d1f576040805162461bcd60e51b81526020600482015260096024820152681cdd5cdc195b99195960ba1b604482015290519081900360640190fd5b604080516f14d554d411539117d41493d413d4d05360821b81529051908190036010019020600090613d71907fc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a4706140e3565b905080156137405761374061401a565b60005460ff16613dc6576040805162461bcd60e51b815260206004820152601960248201526000805160206149b2833981519152604482015290519081900360640190fd5b33600090815260066020908152604080832060ff8089168552925290912054859116613e235760405162461bcd60e51b81526004018080602001828103825260318152602001806147f06031913960400191505060405180910390fd5b60ff85166000908152600760209081526040808320548151601f88018490048402810184019092528682526001600160401b031692613e889284928a9261208d92909189918c908c908190840183828082843760009201919091525061131c92505050565b60ff959095166000908152600760205260409020805467ffffffffffffffff191660019096016001600160401b03169590951790945550505050565b61100081565b600381565b61100481565b60408051600e808252818301909252606091630100610060ff851617918391602082018180368337505050600e81810187905260068201939093529182525090505b92915050565b600085613f2c57506000614011565b606082518451865160800101016040519080825280601f01601f191660200182016040528015613f63576020820181803683370190505b5090506000613f7182614704565b602080890151825201905086600080613f8989614098565b8086526020909501949092509050613fa28285836140a2565b92830192613faf88614098565b8086526020909501949092509050613fc88285836140a2565b9283018a815260200192613fdb87614098565b9092509050613feb8285836140a2565b508351602001613ff961470a565b60208183886065600019fa5051600114955050505050505b95945050505050565b600b5460ff161561405e576040805162461bcd60e51b81526020600482015260096024820152681cdd5cdc195b99195960ba1b604482015290519081900360640190fd5b600b805460ff1916600117905560405133907f6f123d3d54c84a7960a573b31c221dcd86e13fd849c5adb0c6ca851468cc1ae490600090a2565b8051602090910191565b5b602081106140c2578251825260209283019290910190601f19016140a3565b915181516020939093036101000a6000190180199091169216919091179052565b6000828152600d602052604081205461ffff166141ac57604080516f14d554d411539117d41493d413d4d05360821b815281519081900360100181206000908152600d6020818152848320805461ffff199081166001179091556e149153d4115397d41493d413d4d053608a1b8552855194859003600f01852084528282528584208054821660029081179091557710d05390d15317d514905394d1915497d41493d413d4d05360421b8652865195869003601801909520845291905292902080549092161790555b6000838152600c6020526040902080546201000090046001600160801b0316421015806141dd575082816001015414155b156142b0576000848152600d602090815260409182902054835461ffff90911661ffff199091161771ffffffffffffffffffffffffffffffff0000191662010000610e1042016001600160801b0316021783556001808401869055825191820190925233815261425291600284019190614728565b5080546040805161ffff83168152620100009092046001600160801b0316602083015281810185905251339186917f9e109f0e55ef32e99e4880be2ec357f1ddb3469c79d0747ef4762da6e89fabe5916060908290030190a3614364565b60005b600282015481101561433b57336001600160a01b03168260020182815481106142d857fe5b6000918252602090912001546001600160a01b03161415614333576040805162461bcd60e51b815260206004820152601060248201526f185b1c9958591e48185c1c1c9bdd995960821b604482015290519081900360640190fd5b6001016142b3565b50600281018054600181018255600091825260209091200180546001600160a01b031916331790555b8054600282015461ffff909116116143be576000848152600c60205260408120805471ffffffffffffffffffffffffffffffffffff1916815560018101829055906143b2600283018261478d565b50506001915050613f17565b5060009392505050565b600080600060606021855110156143f8575050604080516000808252602082019092529092508291508190614471565b600185015160218601518651604080516020198301808252601f1960011990940193909316810160200190915260418901939291606091908015614443576020820181803683370190505b509050600061445182614098565b509050614463858260218d51036140a2565b506001975091955093509150505b9193509193565b600b5460ff16156144bc576040805162461bcd60e51b81526020600482015260096024820152681cdd5cdc195b99195960ba1b604482015290519081900360640190fd5b6002544311156144fb576004805467ffffffffffffffff1981166001600160401b036001600793840b810190930b16179091556003554360025561453c565b6003805460019081019182905554101561453c576004805467ffffffffffffffff1981166001600160401b036001600793840b810190930b16179091556003555b8160ff16836001600160401b0316600460009054906101000a900460070b6001600160401b03167f3a6e0fc61675aa2a100bcba0568368bb92bcec91c97673391074f11138f0cffe606185604051808361ffff1661ffff16815260200180602001828103825283818151815260200191508051906020019080838360005b838110156145d25781810151838201526020016145ba565b50505050905090810190601f1680156145ff5780820380516001836020036101000a031916815260200191505b50935050505060405180910390a4505050565b6000816040516020018082805190602001908083835b602083106146475780518252601f199092019160209182019101614628565b6001836020036101000a03801982511681845116808217855250505050505090500191505060405160208183030381529060405280519060200120836040516020018082805190602001908083835b602083106146b55780518252601f199092019160209182019101614696565b6001836020036101000a0380198251168184511680821785525050505050509050019150506040516020818303038152906040528051906020012014905092915050565b015190565b3b151590565b60200190565b60405180602001604052806001906020820280368337509192915050565b82805482825590600052602060002090810192821561477d579160200282015b8281111561477d57825182546001600160a01b0319166001600160a01b03909116178255602090920191600190910190614748565b506147899291506147ae565b5090565b50805460008255906000526020600020908101906147ab91906147d5565b50565b6147d291905b808211156147895780546001600160a01b03191681556001016147b4565b90565b6147d291905b8082111561478957600081556001016147db56fe74686520636f6e747261637420616e64206368616e6e656c2068617665206e6f74206265656e20726567697374657265646c656e677468206f662076616c756520666f72206164644f725570646174654368616e6e656c2073686f756c642062652032322c206368616e6e656c49643a697346726f6d53797374656d3a68616e646c6572416464726573736c656e677468206f662076616c756520666f722063616e63656c5472616e7366657251756f72756d2073686f756c6420626520326c656e677468206f662076616c756520666f722073757370656e6451756f72756d2073686f756c6420626520326c656e677468206f662076616c756520666f722072656f70656e51756f72756d2073686f756c642062652032746865206d6573736167652073656e646572206d75737420626520676f7665726e616e636520636f6e74726163746c656e677468206f662076616c756520666f7220656e61626c654f7244697361626c654368616e6e656c2073686f756c6420626520322c206368616e6e656c49643a6973456e61626c65746865206e6577426174636853697a65466f724f7261636c652073686f756c6420626520696e205b31302c2031303030305d74686520636f6e7472616374206e6f7420696e697420796574000000000000006c6967687420636c69656e74206e6f742073796e632074686520626c6f636b20796574a26469706673582212200822a3bd79df610f758cc9702e0be636463b002fc0089f5e09cf86383a7f79fc64736f6c63430006040033", + }, + }, + } + + LubanUpgrade[networkname.RialtoChainName] = &Upgrade{ + UpgradeName: "luban", + Configs: []*UpgradeConfig{ + { + ContractAddr: ValidatorContract, + CommitUrl: "https://github.com/bnb-chain/bsc-genesis-contract/commit/b144718e94d7a1ebb24a7103202300f08826f369", + Code: "60806040526004361061046c5760003560e01c8063862498821161024a578063c6d3394511610139578063e40716a1116100b6578063f9a2bbc71161007a578063f9a2bbc714610b6b578063fc3e590814610b80578063fccc281314610b95578063fd4ad81f14610baa578063fd6a687914610bd957610473565b8063e40716a114610af9578063eb57e20214610b0e578063eda5868c14610b2e578063f340fa0114610b43578063f92eb86b14610b5657610473565b8063d86222d5116100fd578063d86222d514610a90578063daacdb6614610aa5578063dc927faf14610aba578063e086c7b114610acf578063e1c7392a14610ae457610473565b8063c6d3394514610a3c578063c81b166214610a51578063c8509d811461085f578063d04aa99614610a66578063d68fb56a14610a7b57610473565b8063a5422d5c116101c7578063ad3c9da61161018b578063ad3c9da6146109d0578063aef198a9146109f0578063b7ab4db514610a05578063b8cf4ef114610a27578063bf9f49951461062f57610473565b8063a5422d5c1461095c578063a78abc1614610971578063aaf5eb6814610986578063ab51bb961461099b578063ac431751146109b057610473565b806396713da91161020e57806396713da9146108f35780639dc09262146109085780639fe0f8161461091d578063a0dc275814610932578063a1a11bf51461094757610473565b8063862498821461087f57806388b32f11146108945780638b5ad0c9146108a95780638d19a410146108be5780639369d7de146108de57610473565b80634df6e0c3116103665780636e47b482116102e35780637942fd05116102a75780637942fd05146108205780637a84ca2a1461083557806381650b621461084a578063831d65d11461085f578063853230aa1461080b57610473565b80636e47b482146107b757806370fd5bad146107cc578063718a8aa8146107e157806375d47a0a146107f657806378dfed4a1461080b57610473565b8063565c56b31161032a578063565c56b3146107265780635667515a146107465780635d77156c1461075b57806362b72cf5146107705780636969a25c1461078557610473565b80634df6e0c3146106b25780635192c82c146106c757806351e80672146106dc578063549b03f2146106f157806355614fcc1461070657610473565b8063321d398a116103f45780633dffc387116103b85780633dffc3871461062f57806343756e5c1461065157806345cf9daf14610666578063493279b11461067b5780634bf6c8821461069d57610473565b8063321d398a146105975780633365af3a146105b757806335409f7f146105d75780633b071dcc146105f75780633de0f0d81461061a57610473565b80631182b8751161043b5780631182b875146104fe578063152ad3b81461052b5780631ff180691461054d578063219f22d514610562578063300c35671461057757610473565b806304c4fec61461047857806307a568471461048f5780630bee7a67146104ba5780630e2374a5146104dc57610473565b3661047357005b600080fd5b34801561048457600080fd5b5061048d610bee565b005b34801561049b57600080fd5b506104a4610c60565b6040516104b19190616ef1565b60405180910390f35b3480156104c657600080fd5b506104cf610c66565b6040516104b19190616f1b565b3480156104e857600080fd5b506104f1610c6b565b6040516104b191906162f8565b34801561050a57600080fd5b5061051e6105193660046161de565b610c71565b6040516104b1919061646f565b34801561053757600080fd5b50610540610ea9565b6040516104b19190616464565b34801561055957600080fd5b506104a4610eb2565b34801561056e57600080fd5b506104cf610eb8565b34801561058357600080fd5b5061048d6105923660046160a7565b610ebd565b3480156105a357600080fd5b506105406105b236600461618b565b611241565b3480156105c357600080fd5b506105406105d236600461618b565b611310565b3480156105e357600080fd5b5061048d6105f2366004616080565b6113c1565b34801561060357600080fd5b5061060c61151a565b6040516104b192919061637a565b34801561062657600080fd5b506104a46117f6565b34801561063b57600080fd5b506106446117fc565b6040516104b19190616f2c565b34801561065d57600080fd5b506104f1611801565b34801561067257600080fd5b506104a4611807565b34801561068757600080fd5b5061069061180d565b6040516104b19190616ee2565b3480156106a957600080fd5b50610644611813565b3480156106be57600080fd5b5061060c611818565b3480156106d357600080fd5b506104a4611996565b3480156106e857600080fd5b506104f161199c565b3480156106fd57600080fd5b506104a46119a2565b34801561071257600080fd5b50610540610721366004616080565b6119a8565b34801561073257600080fd5b506104a4610741366004616080565b6119dd565b34801561075257600080fd5b50610644611a2e565b34801561076757600080fd5b506104cf611a33565b34801561077c57600080fd5b506104a4611a38565b34801561079157600080fd5b506107a56107a036600461618b565b611a3e565b6040516104b196959493929190616325565b3480156107c357600080fd5b506104f1611aa2565b3480156107d857600080fd5b50610644611aa8565b3480156107ed57600080fd5b50610644611aad565b34801561080257600080fd5b506104f1611ab2565b34801561081757600080fd5b506104a4611ab8565b34801561082c57600080fd5b50610644611abe565b34801561084157600080fd5b506104a4611ac3565b34801561085657600080fd5b506104cf611ac9565b34801561086b57600080fd5b5061048d61087a3660046161de565b611ace565b34801561088b57600080fd5b506104a4611b2f565b3480156108a057600080fd5b506104a4611b35565b3480156108b557600080fd5b506104a4611b3b565b3480156108ca57600080fd5b506104a46108d9366004616080565b611b41565b3480156108ea57600080fd5b5061048d611b81565b3480156108ff57600080fd5b50610644611c95565b34801561091457600080fd5b506104f1611c9a565b34801561092957600080fd5b506104a4611ca0565b34801561093e57600080fd5b506104a4611ca5565b34801561095357600080fd5b506104f1611caa565b34801561096857600080fd5b5061051e611cb0565b34801561097d57600080fd5b50610540611ccf565b34801561099257600080fd5b506104a4611cd8565b3480156109a757600080fd5b506104cf611a2e565b3480156109bc57600080fd5b5061048d6109cb36600461612f565b611ce1565b3480156109dc57600080fd5b506104a46109eb366004616080565b61258d565b3480156109fc57600080fd5b506104a461259f565b348015610a1157600080fd5b50610a1a6125ac565b6040516104b19190616367565b348015610a3357600080fd5b506104a4612698565b348015610a4857600080fd5b506104a4611aa8565b348015610a5d57600080fd5b506104f161269d565b348015610a7257600080fd5b506104a46126a3565b348015610a8757600080fd5b506104a46126a8565b348015610a9c57600080fd5b506104a46126e7565b348015610ab157600080fd5b506104a46126f3565b348015610ac657600080fd5b506104f16126f9565b348015610adb57600080fd5b506104a46126ff565b348015610af057600080fd5b5061048d612704565b348015610b0557600080fd5b506104a46128b3565b348015610b1a57600080fd5b5061048d610b29366004616080565b6128b9565b348015610b3a57600080fd5b506104cf6129c1565b61048d610b51366004616080565b6129c6565b348015610b6257600080fd5b506104a4612c4e565b348015610b7757600080fd5b506104f1612c54565b348015610b8c57600080fd5b50610644611ca0565b348015610ba157600080fd5b506104f1612c5a565b348015610bb657600080fd5b50610bca610bc536600461618b565b612c60565b6040516104b193929190616efa565b348015610be557600080fd5b506104f1612d22565b6000610bf933611b41565b9050600b8181548110610c0857fe5b600091825260209091206001601690920201015460ff16610c445760405162461bcd60e51b8152600401610c3b90616b9a565b60405180910390fd5b6000610c4e6126a8565b9050610c5b338383612d28565b505050565b60095481565b606481565b61200181565b60005460609060ff16610c965760405162461bcd60e51b8152600401610c3b9061662e565b3361200014610cb75760405162461bcd60e51b8152600401610c3b90616d79565b600b54610d7557610cc6615d6c565b60015460005b81811015610d7157600b8054600181018255600091909152835160008051602061714f833981519152601690920291820190815560208086015160008051602061718f8339815191528401805460ff1916911515919091179055604086015180518794610d4d9360008051602061716f833981519152909101920190615d9b565b506060820151610d639060038301906013615e15565b505050806001019050610ccc565b5050505b610d7d615e42565b6000610dbe85858080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250612f1492505050565b9150915080610dda57610dd160646130d0565b92505050610ea2565b815160009060ff16610dff57610df883602001518460400151613131565b9050610e6e565b825160ff1660011415610e6a57826020015151600114610e445760008051602061712f833981519152604051610e3490616a81565b60405180910390a1506067610e65565b610df88360200151600081518110610e5857fe5b6020026020010151613d85565b610e6e565b5060655b63ffffffff8116610e935750506040805160008152602081019091529150610ea29050565b610e9c816130d0565b93505050505b9392505050565b60075460ff1681565b60035481565b606881565b334114610edc5760405162461bcd60e51b8152600401610c3b90616dc8565b6010544311610efd5760405162461bcd60e51b8152600401610c3b9061678a565b60005460ff16610f1f5760405162461bcd60e51b8152600401610c3b9061662e565b600f54610f37576032600f5561100231601155611237565b60006110023168056bc75e2d63100000811115610f6657610f5f81606463ffffffff613efc16565b9150610faf565b601154811115610fa857610f5f6064610f9c600f54610f9060115486613f3e90919063ffffffff16565b9063ffffffff613f8016565b9063ffffffff613efc16565b5050611237565b6040516309a99b4f60e41b815261100290639a99b4f090610fd6903090869060040161630c565b602060405180830381600087803b158015610ff057600080fd5b505af1158015611004573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061102891906161a3565b6110023160115591508161103d575050611237565b6000805b8481101561106b5785858281811061105557fe5b9050602002013582019150806001019050611041565b508061107957505050611237565b6000806000805b8981101561122f578489898381811061109557fe5b905060200201358802816110a557fe5b0493508a8a828181106110b457fe5b90506020020160208101906110c99190616080565b6001600160a01b038116600090815260046020526040902054909350915081156111e55760006001808403815481106110fe57fe5b9060005260206000209060040201905080600201601c9054906101000a900460ff161561116b57836001600160a01b03167fb9c75cbbfde137c4281689580799ef5f52144e78858f776a5979b2b212137d858660405161115e9190616ef1565b60405180910390a26111df565b60035461117e908663ffffffff613fba16565b6003908155810154611196908663ffffffff613fba16565b60038201556040516001600160a01b038516907fcb0aad6cf9cd03bdf6137e359f541c42f38b39f007cae8e89e88aa7d8c6617b2906111d6908890616ef1565b60405180910390a25b50611227565b826001600160a01b03167fb9c75cbbfde137c4281689580799ef5f52144e78858f776a5979b2b212137d858560405161121e9190616ef1565b60405180910390a25b600101611080565b505050505050505b5050436010555050565b60015460009082106112555750600061130b565b60006001600160a01b03166001838154811061126d57fe5b60009182526020909120600490910201546001600160a01b0316148061129d5750600854158061129d5750600a54155b806112ac575060085460095410155b806112bd57506112bb82611310565b155b806112e657506000600b83815481106112d257fe5b906000526020600020906016020160000154115b806112fa575060016112f66125ac565b5111155b156113075750600061130b565b5060015b919050565b60015460009082106113245750600061130b565b600b548210611361576001828154811061133a57fe5b9060005260206000209060040201600201601c9054906101000a900460ff1615905061130b565b6001828154811061136e57fe5b9060005260206000209060040201600201601c9054906101000a900460ff161580156113bb5750600b82815481106113a257fe5b600091825260209091206001601690920201015460ff16155b92915050565b33611001146113e25760405162461bcd60e51b8152600401610c3b90616e99565b600b546114a0576113f1615d6c565b60015460005b8181101561149c57600b8054600181018255600091909152835160008051602061714f833981519152601690920291820190815560208086015160008051602061718f8339815191528401805460ff19169115159190911790556040860151805187946114789360008051602061716f833981519152909101920190615d9b565b50606082015161148e9060038301906013615e15565b5050508060010190506113f7565b5050505b6001600160a01b038116600090815260046020526040902054806114c45750611517565b6001810390506000600b82815481106114d957fe5b600091825260209091206001601690920201015460ff1690506114fc8383613fdf565b80156115055750805b15610c5b576009805460001901905550505b50565b60015460609081906000805b8281101561156d576001818154811061153b57fe5b9060005260206000209060040201600201601c9054906101000a900460ff16611565576001909101905b600101611526565b5060608160405190808252806020026020018201604052801561159a578160200160208202803683370190505b5090506060826040519080825280602002602001820160405280156115d357816020015b60608152602001906001900390816115be5790505b50600b546000945090915084141561174e5760005b8481101561174857600181815481106115fd57fe5b9060005260206000209060040201600201601c9054906101000a900460ff16611740576001818154811061162d57fe5b600091825260209091206004909102015483516001600160a01b039091169084908690811061165857fe5b60200260200101906001600160a01b031690816001600160a01b031681525050600b818154811061168557fe5b600091825260209182902060026016909202018101805460408051601f60001961010060018616150201909316949094049182018590048502840185019052808352919290919083018282801561171d5780601f106116f25761010080835404028352916020019161171d565b820191906000526020600020905b81548152906001019060200180831161170057829003601f168201915b505050505082858151811061172e57fe5b60209081029190910101526001909301925b6001016115e8565b506117ea565b60005b848110156117e8576001818154811061176657fe5b9060005260206000209060040201600201601c9054906101000a900460ff166117e0576001818154811061179657fe5b600091825260209091206004909102015483516001600160a01b03909116908490869081106117c157fe5b6001600160a01b03909216602092830291909101909101526001909301925b600101611751565b505b909450925050505b9091565b61271081565b600181565b61100181565b60085481565b6102ca81565b600881565b600e54600c5460609182918061182c575060155b60606118366125ac565b9050606061184382614392565b90508282511161185a5790945092506117f2915050565b8383835103101561186c578282510393505b83156118a25760c8430461188883838388880360008a8a614500565b6118a08383838888038989038a8b8b8b510301614500565b505b6060836040519080825280602002602001820160405280156118ce578160200160208202803683370190505b50905060608460405190808252806020026020018201604052801561190757816020015b60608152602001906001900390816118f25790505b50905060005b858110156119885784818151811061192157fe5b602002602001015183828151811061193557fe5b60200260200101906001600160a01b031690816001600160a01b03168152505083818151811061196157fe5b602002602001015182828151811061197557fe5b602090810291909101015260010161190d565b509096509450505050509091565b60065481565b61200081565b600f5481565b6001600160a01b038116600090815260046020526040812054806119d057600091505061130b565b60001901610ea281611310565b6001600160a01b03811660009081526004602052604081205480611a0557600091505061130b565b600180820381548110611a1457fe5b906000526020600020906004020160030154915050919050565b600081565b606781565b60105481565b60018181548110611a4b57fe5b600091825260209091206004909102018054600182015460028301546003909301546001600160a01b0392831694509082169291821691600160a01b81046001600160401b031691600160e01b90910460ff169086565b61100581565b600281565b601081565b61100881565b6103e881565b600b81565b600c5481565b606681565b3361200014611aef5760405162461bcd60e51b8152600401610c3b90616d79565b7f41ce201247b6ceb957dcdb217d0b8acb50b9ea0e12af9af4f5e7f38902101605838383604051611b2293929190616f3a565b60405180910390a1505050565b60025481565b60115481565b600a5481565b6001600160a01b03811660009081526004602052604081205480611b775760405162461bcd60e51b8152600401610c3b90616d01565b6000190192915050565b600b54611c3f57611b90615d6c565b60015460005b81811015611c3b57600b8054600181018255600091909152835160008051602061714f833981519152601690920291820190815560208086015160008051602061718f8339815191528401805460ff1916911515919091179055604086015180518794611c179360008051602061716f833981519152909101920190615d9b565b506060820151611c2d9060038301906013615e15565b505050806001019050611b96565b5050505b600854611c4c5760036008555b600a54611c59576002600a555b6000611c6433611b41565b9050611c6f81611241565b611c8b5760405162461bcd60e51b8152600401610c3b90616a3e565b6115173382614657565b600981565b61100781565b600381565b60c881565b61100681565b604051806101e001604052806101ab8152602001616f846101ab913981565b60005460ff1681565b6402540be40081565b60005460ff16611d035760405162461bcd60e51b8152600401610c3b9061662e565b3361100714611d245760405162461bcd60e51b8152600401610c3b90616b07565b611d8e84848080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525050604080518082019091526013815272065787069726554696d655365636f6e6447617606c1b602082015291506146ef9050565b15611e2b5760208114611db35760405162461bcd60e51b8152600401610c3b90616cbb565b604080516020601f8401819004810282018101909252828152600091611df19185858083850183828082843760009201919091525061474892505050565b905060648110158015611e075750620186a08111155b611e235760405162461bcd60e51b8152600401610c3b906168e7565b60025561254a565b611e8b84848080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250506040805180820190915260098152686275726e526174696f60b81b602082015291506146ef9050565b15611f275760208114611eb05760405162461bcd60e51b8152600401610c3b906164b4565b604080516020601f8401819004810282018101909252828152600091611eee9185858083850183828082843760009201919091525061474892505050565b9050612710811115611f125760405162461bcd60e51b8152600401610c3b906167cc565b6006556007805460ff1916600117905561254a565b611f9184848080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250506040805180820190915260138152726d61784e756d4f664d61696e7461696e696e6760681b602082015291506146ef9050565b1561202b5760208114611fb65760405162461bcd60e51b8152600401610c3b906164eb565b604080516020601f8401819004810282018101909252828152600091611ff49185858083850183828082843760009201919091525061474892505050565b600c5490915080612003575060155b8082106120225760405162461bcd60e51b8152600401610c3b9061683f565b5060085561254a565b61209484848080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250506040805180820190915260128152716d61696e7461696e536c6173685363616c6560701b602082015291506146ef9050565b1561212d57602081146120b95760405162461bcd60e51b8152600401610c3b906165b4565b604080516020601f84018190048102820181019092528281526000916120f79185858083850183828082843760009201919091525061474892505050565b90506000811180156121095750600a81105b6121255760405162461bcd60e51b8152600401610c3b90616e15565b600a5561254a565b6121a184848080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152505060408051808201909152601981527f6d61784e756d4f66576f726b696e6743616e6469646174657300000000000000602082015291506146ef9050565b1561223057602081146121c65760405162461bcd60e51b8152600401610c3b90616568565b604080516020601f84018190048102820181019092528281526000916122049185858083850183828082843760009201919091525061474892505050565b9050600d548111156122285760405162461bcd60e51b8152600401610c3b9061695d565b600e5561254a565b61229984848080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250506040805180820190915260128152716d61784e756d4f6643616e6469646174657360701b602082015291506146ef9050565b1561231b57602081146122be5760405162461bcd60e51b8152600401610c3b90616b55565b604080516020601f84018190048102820181019092528281526000916122fc9185858083850183828082843760009201919091525061474892505050565b600d819055600e5490915081101561231557600d54600e555b5061254a565b61237f84848080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152505060408051808201909152600d81526c6e756d4f66436162696e65747360981b602082015291506146ef9050565b1561242d57602081146123a45760405162461bcd60e51b8152600401610c3b906165f9565b604080516020601f84018190048102820181019092528281526000916123e29185858083850183828082843760009201919091525061474892505050565b9050600081116124045760405162461bcd60e51b8152600401610c3b9061669c565b60298111156124255760405162461bcd60e51b8152600401610c3b906166e4565b600c5561254a565b61249784848080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152505060408051808201909152601381527266696e616c697479526577617264526174696f60681b602082015291506146ef9050565b1561253257602081146124bc5760405162461bcd60e51b8152600401610c3b90616c3e565b604080516020601f84018190048102820181019092528281526000916124fa9185858083850183828082843760009201919091525061474892505050565b90506001811015801561250e575060648111155b61252a5760405162461bcd60e51b8152600401610c3b906169cc565b600f5561254a565b60405162461bcd60e51b8152600401610c3b90616e72565b7f6cdb0ac70ab7f2e2d035cca5be60d89906f2dede7648ddbd7402189c1eeed17a8484848460405161257f9493929190616482565b60405180910390a150505050565b60046020526000908152604090205481565b68056bc75e2d6310000081565b6001546060906000805b828110156125db576125c781611310565b156125d3578160010191505b6001016125b6565b50606081604051908082528060200260200182016040528015612608578160200160208202803683370190505b5090506000915060005b8381101561268f5761262381611310565b15612687576001818154811061263557fe5b600091825260209091206004909102015482516001600160a01b039091169083908590811061266057fe5b60200260200101906001600160a01b031690816001600160a01b0316815250508260010192505b600101612612565b50925050505b90565b601581565b61100281565b603281565b60006126b26125ac565b519050600080600c54116126c75760156126cb565b600c545b9050808211156126d9578091505b816126e357600191505b5090565b67016345785d8a000081565b60055481565b61100381565b602981565b60005460ff16156127275760405162461bcd60e51b8152600401610c3b90616c07565b61272f615e42565b6000612755604051806101e001604052806101ab8152602001616f846101ab9139612f14565b91509150806127765760405162461bcd60e51b8152600401610c3b90616d38565b60005b82602001515181101561289b5760018360200151828151811061279857fe5b60209081029190910181015182546001818101855560009485528385208351600493840290910180546001600160a01b039283166001600160a01b03199182161782558587015182850180549185169183169190911790556040860151600283018054606089015160808a01511515600160e01b0260ff60e01b196001600160401b03909216600160a01b0267ffffffffffffffff60a01b199590981692909516919091179290921694909417161790915560a09093015160039093019290925591860151805191850193918590811061286e57fe5b602090810291909101810151516001600160a01b0316825281019190915260400160002055600101612779565b50506103e8600255506000805460ff19166001179055565b600d5481565b33611001146128da5760405162461bcd60e51b8152600401610c3b90616e99565b600b54612998576128e9615d6c565b60015460005b8181101561299457600b8054600181018255600091909152835160008051602061714f833981519152601690920291820190815560208086015160008051602061718f8339815191528401805460ff19169115159190911790556040860151805187946129709360008051602061716f833981519152909101920190615d9b565b5060608201516129869060038301906013615e15565b5050508060010190506128ef565b5050505b60006129a38261474d565b90506129ae81611241565b156129bd576129bd8282614657565b5050565b606581565b3341146129e55760405162461bcd60e51b8152600401610c3b90616dc8565b60005460ff16612a075760405162461bcd60e51b8152600401610c3b9061662e565b60003411612a275760405162461bcd60e51b8152600401610c3b9061692e565b6001600160a01b0381166000908152600460205260409020546007543491906103e89060ff1615612a5757506006545b600083118015612a675750600081115b15612b08576000612a84612710610f9c868563ffffffff613f8016565b90508015612b065760405161dead9082156108fc029083906000818181858888f19350505050158015612abb573d6000803e3d6000fd5b507f627059660ea01c4733a328effb2294d2f86905bf806da763a89cee254de8bee581604051612aeb9190616ef1565b60405180910390a1612b03848263ffffffff613f3e16565b93505b505b8115612c06576000600180840381548110612b1f57fe5b9060005260206000209060040201905080600201601c9054906101000a900460ff1615612b8c57846001600160a01b03167ff177e5d6c5764d79c32883ed824111d9b13f5668cf6ab1cc12dd36791dd955b485604051612b7f9190616ef1565b60405180910390a2612c00565b600354612b9f908563ffffffff613fba16565b6003908155810154612bb7908563ffffffff613fba16565b60038201556040516001600160a01b038616907f93a090ecc682c002995fad3c85b30c5651d7fd29b0be5da9d784a3302aedc05590612bf7908790616ef1565b60405180910390a25b50612c48565b836001600160a01b03167ff177e5d6c5764d79c32883ed824111d9b13f5668cf6ab1cc12dd36791dd955b484604051612c3f9190616ef1565b60405180910390a25b50505050565b600e5481565b61100081565b61dead81565b600b8181548110612c6d57fe5b6000918252602091829020601691909102018054600180830154600280850180546040805161010096831615969096026000190190911692909204601f810188900488028501880190925281845293965060ff90911694919291830182828015612d185780601f10612ced57610100808354040283529160200191612d18565b820191906000526020600020905b815481529060010190602001808311612cfb57829003601f168201915b5050505050905083565b61100481565b6000600a5460001480612d39575081155b80612d445750600954155b15612d5157506000610ea2565b60096000815460019003919050819055506000612d9c600a54610f9c85610f9c600b8981548110612d7e57fe5b6000918252602090912060169091020154439063ffffffff613f3e16565b90506000600b8581548110612dad57fe5b906000526020600020906016020160010160006101000a81548160ff0219169083151502179055506000806110016001600160a01b0316638256ace66040518163ffffffff1660e01b8152600401604080518083038186803b158015612e1257600080fd5b505afa158015612e26573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612e4a91906161bb565b9150915060009350808310612ec457612e638787613fdf565b506040516305bfb49960e41b815261100190635bfb499090612e89908a906004016162f8565b600060405180830381600087803b158015612ea357600080fd5b505af1158015612eb7573d6000803e3d6000fd5b5050505060019350612ed6565b818310612ed657612ed48761474d565b505b6040516001600160a01b038816907fb9d38178dc641ff1817967a63c9078cbcd955a9f1fcd75e0e3636de615d44d3b90600090a25050509392505050565b612f1c615e42565b6000612f26615e42565b612f2e615e66565b612f3f612f3a866148f0565b614915565b90506000805b612f4e8361495f565b156130c25780612f7357612f69612f6484614980565b6149ce565b60ff1684526130ba565b80600114156130b5576060612f8f612f8a85614980565b614a4e565b90508051604051908082528060200260200182016040528015612fcc57816020015b612fb9615e86565b815260200190600190039081612fb15790505b508560200181905250805160405190808252806020026020018201604052801561300a57816020015b6060815260200190600190039081612ff55790505b50604086015260005b81518110156130aa57613024615e86565b6060600061304485858151811061303757fe5b6020026020010151614b1f565b92509250925080613064578860009a509a505050505050505050506130cb565b828960200151858151811061307557fe5b6020026020010181905250818960400151858151811061309157fe5b6020026020010181905250505050806001019050613013565b5060019250506130ba565b6130c2565b600101612f45565b50919350909150505b915091565b604080516001808252818301909252606091829190816020015b60608152602001906001900390816130ea5790505090506131108363ffffffff16614c39565b8160008151811061311d57fe5b6020026020010181905250610ea281614c4c565b60006029835111156131685760008051602061712f83398151915260405161315890616741565b60405180910390a15060666113bb565b60005b83518110156132065760005b818110156131fd5784818151811061318b57fe5b6020026020010151600001516001600160a01b03168583815181106131ac57fe5b6020026020010151600001516001600160a01b031614156131f55760008051602061712f8339815191526040516131e29061689c565b60405180910390a16066925050506113bb565b600101613177565b5060010161316b565b506060806132148585614cd6565b60015491935091506000908190815b818110156132995767016345785d8a00006001828154811061324157fe5b9060005260206000209060040201600301541061326357836001019350613291565b60006001828154811061327257fe5b9060005260206000209060040201600301541115613291578260010192505b600101613223565b506060836040519080825280602002602001820160405280156132c6578160200160208202803683370190505b5090506060846040519080825280602002602001820160405280156132f5578160200160208202803683370190505b509050606085604051908082528060200260200182016040528015613324578160200160208202803683370190505b509050606086604051908082528060200260200182016040528015613353578160200160208202803683370190505b5090506000606087604051908082528060200260200182016040528015613384578160200160208202803683370190505b5090506060886040519080825280602002602001820160405280156133b3578160200160208202803683370190505b509050600099506000985060006110046001600160a01b031663149d14d96040518163ffffffff1660e01b815260040160206040518083038186803b1580156133fb57600080fd5b505afa15801561340f573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061343391906161a3565b905067016345785d8a000081111561347e5760008051602061712f83398151915260405161346090616bc6565b60405180910390a160689d50505050505050505050505050506113bb565b60005b898110156136ef5767016345785d8a00006001828154811061349f57fe5b9060005260206000209060040201600301541061362457600181815481106134c357fe5b906000526020600020906004020160020160009054906101000a90046001600160a01b0316898d815181106134f457fe5b60200260200101906001600160a01b031690816001600160a01b03168152505060006402540be4006001838154811061352957fe5b9060005260206000209060040201600301548161354257fe5b066001838154811061355057fe5b9060005260206000209060040201600301540390506135788382613f3e90919063ffffffff16565b898e8151811061358457fe5b6020026020010181815250506001828154811061359d57fe5b906000526020600020906004020160020160009054906101000a90046001600160a01b0316878e815181106135ce57fe5b60200260200101906001600160a01b031690816001600160a01b03168152505081888e815181106135fb57fe5b6020908102919091010152613616868263ffffffff613fba16565b95508c6001019c50506136e7565b60006001828154811061363357fe5b90600052602060002090600402016003015411156136e7576001818154811061365857fe5b906000526020600020906004020160010160009054906101000a90046001600160a01b0316848c8151811061368957fe5b60200260200101906001600160a01b031690816001600160a01b031681525050600181815481106136b657fe5b906000526020600020906004020160030154838c815181106136d457fe5b6020026020010181815250508a6001019a505b600101613481565b5060008415613965576002546040516303702b2960e51b815261100491636e056520918891613729918e918e918d914201906004016163ea565b6020604051808303818588803b15801561374257600080fd5b505af193505050508015613773575060408051601f3d908101601f191682019092526137709181019061610f565b60015b6138ea576040516000815260443d101561378f5750600061382a565b60046000803e60005160e01c6308c379a081146137b057600091505061382a565b60043d036004833e81513d60248201116001600160401b03821117156137db5760009250505061382a565b80830180516001600160401b038111156137fc57600094505050505061382a565b8060208301013d860181111561381a5760009550505050505061382a565b601f01601f191660405250925050505b806138355750613877565b60019150857fa7cdeed7d0db45e3219a6e5d60838824c16f1d39991fcfe3f963029c844bf28082604051613869919061646f565b60405180910390a2506138e5565b3d8080156138a1576040519150601f19603f3d011682016040523d82523d6000602084013e6138a6565b606091505b5060019150857fbfa884552dd8921b6ce90bfe906952ae5b3b29be0cc1a951d4f62697635a3a45826040516138db919061646f565b60405180910390a2505b613965565b801561392c577fa217d08e65f80c73121cd9db834d81652d544bfbf452f6d04922b16c90a37b708660405161391f9190616ef1565b60405180910390a1613963565b857fa7cdeed7d0db45e3219a6e5d60838824c16f1d39991fcfe3f963029c844bf28060405161395a90616531565b60405180910390a25b505b8015613b1b5760005b8751811015613b1957600088828151811061398557fe5b6020026020010151905060006001828154811061399e57fe5b60009182526020909120600160049092020181015481546001600160a01b03909116916108fc91859081106139cf57fe5b9060005260206000209060040201600301549081150290604051600060405180830381858888f1935050505090508015613a8b5760018281548110613a1057fe5b60009182526020909120600160049092020181015481546001600160a01b03909116917f6c61d60f69a7beb3e1c80db7f39f37b208537cbb19da3174511b477812b2fc7d9185908110613a5f57fe5b906000526020600020906004020160030154604051613a7e9190616ef1565b60405180910390a2613b0f565b60018281548110613a9857fe5b60009182526020909120600160049092020181015481546001600160a01b03909116917f25d0ce7d2f0cec669a8c17efe49d195c13455bb8872b65fa610ac7f53fe4ca7d9185908110613ae757fe5b906000526020600020906004020160030154604051613b069190616ef1565b60405180910390a25b505060010161396e565b505b835115613c655760005b8451811015613c63576000858281518110613b3c57fe5b60200260200101516001600160a01b03166108fc868481518110613b5c57fe5b60200260200101519081150290604051600060405180830381858888f1935050505090508015613bf257858281518110613b9257fe5b60200260200101516001600160a01b03167f6c61d60f69a7beb3e1c80db7f39f37b208537cbb19da3174511b477812b2fc7d868481518110613bd057fe5b6020026020010151604051613be59190616ef1565b60405180910390a2613c5a565b858281518110613bfe57fe5b60200260200101516001600160a01b03167f25d0ce7d2f0cec669a8c17efe49d195c13455bb8872b65fa610ac7f53fe4ca7d868481518110613c3c57fe5b6020026020010151604051613c519190616ef1565b60405180910390a25b50600101613b25565b505b5050505050505050505050506000471115613ce1577f6ecc855f9440a9282c90913bbc91619fd44f5ec0b462af28d127b116f130aa4d47604051613ca99190616ef1565b60405180910390a1604051611002904780156108fc02916000818181858888f19350505050158015613cdf573d6000803e3d6000fd5b505b60006003819055600555815115613cfc57613cfc8282614f0f565b6110016001600160a01b031663fc4333cd6040518163ffffffff1660e01b8152600401600060405180830381600087803b158015613d3957600080fd5b505af1158015613d4d573d6000803e3d6000fd5b50506040517fedd8d7296956dd970ab4de3f2fc03be2b0ffc615d20cd4c72c6e44f928630ebf925060009150a1506000949350505050565b80516001600160a01b0316600090815260046020526040812054801580613dd65750600180820381548110613db657fe5b9060005260206000209060040201600201601c9054906101000a900460ff165b15613e1c5782516040516001600160a01b03909116907fe209c46bebf57cf265d5d9009a00870e256d9150f3ed5281ab9d9eb3cec6e4be90600090a2600091505061130b565b600154600554600019820111801590613e725784516040516001600160a01b03909116907fe209c46bebf57cf265d5d9009a00870e256d9150f3ed5281ab9d9eb3cec6e4be90600090a26000935050505061130b565b600580546001908101909155805481906000198601908110613e9057fe5b6000918252602082206002600490920201018054921515600160e01b0260ff60e01b199093169290921790915585516040516001600160a01b03909116917ff226e7d8f547ff903d9d419cf5f54e0d7d07efa9584135a53a057c5f1f27f49a91a2506000949350505050565b6000610ea283836040518060400160405280601a81526020017f536166654d6174683a206469766973696f6e206279207a65726f0000000000008152506156ee565b6000610ea283836040518060400160405280601e81526020017f536166654d6174683a207375627472616374696f6e206f766572666c6f770000815250615725565b600082613f8f575060006113bb565b82820282848281613f9c57fe5b0414610ea25760405162461bcd60e51b8152600401610c3b90616ac6565b600082820183811015610ea25760405162461bcd60e51b8152600401610c3b90616665565b60008060018381548110613fef57fe5b906000526020600020906004020160030154905060006001808054905003905060016140196125ac565b511161404e5760006001858154811061402e57fe5b9060005260206000209060040201600301819055506000925050506113bb565b846001600160a01b03167f3b6f9ef90462b512a1293ecec018670bf7b7f1876fb727590a8a6d7643130a70836040516140879190616ef1565b60405180910390a26001600160a01b038516600090815260046020526040812055835b6001546000190181101561427457600181600101815481106140c857fe5b9060005260206000209060040201600182815481106140e357fe5b60009182526020909120825460049092020180546001600160a01b03199081166001600160a01b0393841617825560018085015481840180548416918616919091179055600280860180549185018054909416919095161780835584546001600160401b03600160a01b91829004160267ffffffffffffffff60a01b1990911617808355935460ff600160e01b918290041615150260ff60e01b19909416939093179055600392830154920191909155600b8054909183019081106141a457fe5b9060005260206000209060160201600b82815481106141bf57fe5b600091825260209091208254601690920201908155600180830154818301805460ff909216151560ff1990921691909117905560028084018054614216938386019390821615610100026000190190911604615ebb565b5061422960038281019084016013615f30565b5090505080600101600460006001848154811061424257fe5b600091825260208083206004909202909101546001600160a01b031683528201929092526040019020556001016140aa565b50600180548061428057fe5b60008281526020812060046000199093019283020180546001600160a01b0319908116825560018201805490911690556002810180546001600160e81b0319169055600301559055600b8054806142d357fe5b60008281526020812060166000199093019283020181815560018101805460ff19169055906143056002830182615f5a565b614313600383016000615f9e565b50509055600081838161432257fe5b04905080156143865760015460005b8181101561438357826001828154811061434757fe5b906000526020600020906004020160030154016001828154811061436757fe5b6000918252602090912060036004909202010155600101614331565b50505b50600195945050505050565b6001548151604080518281526020808402820101909152606092919083908280156143d157816020015b60608152602001906001900390816143bc5790505b50600b5490915083146143e857925061130b915050565b60005b828110156144f757600b60016004600089858151811061440757fe5b60200260200101516001600160a01b03166001600160a01b0316815260200190815260200160002054038154811061443b57fe5b600091825260209182902060026016909202018101805460408051601f6000196101006001861615020190931694909404918201859004850284018501905280835291929091908301828280156144d35780601f106144a8576101008083540402835291602001916144d3565b820191906000526020600020905b8154815290600101906020018083116144b657829003601f168201915b50505050508282815181106144e457fe5b60209081029190910101526001016143eb565b50949350505050565b60005b8281101561464d57600082878388016040516020016145239291906162ea565b6040516020818303038152906040528051906020012060001c8161454357fe5b06905080850182870114614644576000898388018151811061456157fe5b602002602001015190506060898489018151811061457b57fe5b602002602001015190508a8388018151811061459357fe5b60200260200101518b858a01815181106145a957fe5b60200260200101906001600160a01b031690816001600160a01b031681525050818b848901815181106145d857fe5b60200260200101906001600160a01b031690816001600160a01b031681525050898388018151811061460657fe5b60200260200101518a858a018151811061461c57fe5b6020026020010181905250808a8489018151811061463657fe5b602002602001018190525050505b50600101614503565b5050505050505050565b600980546001908101909155600b80548390811061467157fe5b906000526020600020906016020160010160006101000a81548160ff02191690831515021790555043600b82815481106146a757fe5b600091825260208220601690910201919091556040516001600160a01b038416917ff62981a567ec3cec866c6fa93c55bcdf841d6292d18b8d522ececa769375d82d91a25050565b60008160405160200161470291906162ce565b604051602081830303815290604052805190602001208360405160200161472991906162ce565b6040516020818303038152906040528051906020012014905092915050565b015190565b6001600160a01b038116600090815260046020526040812054806147765750600019905061130b565b60018103905060006001828154811061478b57fe5b90600052602060002090600402016003015490506000600183815481106147ae57fe5b6000918252602090912060036004909202010155600154604051600019909101906001600160a01b038616907f8cd4e147d8af98a9e3b6724021b8bf6aed2e5dac71c38f2dce8161b82585b25d90614807908590616ef1565b60405180910390a28061481f5782935050505061130b565b600081838161482a57fe5b04905080156148e65760005b8481101561488857816001828154811061484c57fe5b906000526020600020906004020160030154016001828154811061486c57fe5b6000918252602090912060036004909202010155600101614836565b50600180549085015b818110156148e35782600182815481106148a757fe5b90600052602060002090600402016003015401600182815481106148c757fe5b6000918252602090912060036004909202010155600101614891565b50505b5091949350505050565b6148f8615fad565b506040805180820190915281518152602082810190820152919050565b61491d615e66565b61492682615751565b61492f57600080fd5b600061493e836020015161578b565b60208085015160408051808201909152868152920190820152915050919050565b6000614969615fad565b505080518051602091820151919092015191011190565b614988615fad565b6149918261495f565b61499a57600080fd5b602082015160006149aa826157ee565b80830160209586015260408051808201909152908152938401919091525090919050565b8051600090158015906149e357508151602110155b6149ec57600080fd5b60006149fb836020015161578b565b90508083600001511015614a215760405162461bcd60e51b8152600401610c3b90616c84565b8251602080850151830180519284900392918310156144f757506020919091036101000a90049392505050565b6060614a5982615751565b614a6257600080fd5b6000614a6d836158cf565b9050606081604051908082528060200260200182016040528015614aab57816020015b614a98615fad565b815260200190600190039081614a905790505b5090506000614abd856020015161578b565b60208601510190506000805b84811015614b1457614ada836157ee565b9150604051806040016040528083815260200184815250848281518110614afd57fe5b602090810291909101015291810191600101614ac9565b509195945050505050565b614b27615e86565b60606000614b33615e86565b6060614b3d615e66565b614b4687614915565b90506000805b614b558361495f565b15614c2a5780614b8057614b70614b6b84614980565b61592b565b6001600160a01b03168552614c22565b8060011415614ba857614b95614b6b84614980565b6001600160a01b03166020860152614c22565b8060021415614bd057614bbd614b6b84614980565b6001600160a01b03166040860152614c22565b8060031415614bfc57614be5612f6484614980565b6001600160401b0316606086015260019150614c22565b8060041415614c1d57614c16614c1184614980565b615945565b9350614c22565b614c2a565b600101614b4c565b50929791965091945092505050565b60606113bb614c47836159b5565b615a9b565b6060815160001415614c6d575060408051600081526020810190915261130b565b606082600081518110614c7c57fe5b602002602001015190506000600190505b8351811015614cbd57614cb382858381518110614ca657fe5b6020026020010151615aed565b9150600101614c8d565b50610ea2614cd0825160c060ff16615b6a565b82615aed565b606080600080808080614ce76126a8565b6001549091505b8015614df557600181039250600b8381548110614d0757fe5b600091825260209091206001601690920201015460ff16614d2757614dec565b60018381548110614d3457fe5b60009182526020909120600490910201546001600160a01b03169450614d5b858484612d28565b9350831580614d6e575060018a51038610155b15614d7857614dec565b60005b8a51811015614dea57856001600160a01b03168b8281518110614d9a57fe5b6020026020010151600001516001600160a01b03161415614de25760018b8281518110614dc357fe5b6020908102919091010151901515608090910152600190960195614dea565b600101614d7b565b505b60001901614cee565b5084895103604051908082528060200260200182016040528015614e3357816020015b614e20615e86565b815260200190600190039081614e185790505b50965084895103604051908082528060200260200182016040528015614e6d57816020015b6060815260200190600190039081614e585790505b5095506000915060005b8951811015614f0157898181518110614e8c57fe5b602002602001015160800151614ef957898181518110614ea857fe5b6020026020010151888481518110614ebc57fe5b6020026020010181905250888181518110614ed357fe5b6020026020010151878481518110614ee757fe5b60200260200101819052508260010192505b600101614e77565b5050505050505b9250929050565b600154825160005b8281101561502c576001614f29615e86565b60018381548110614f3657fe5b600091825260208083206040805160c08101825260049490940290910180546001600160a01b0390811685526001820154811693850193909352600281015492831691840191909152600160a01b82046001600160401b03166060840152600160e01b90910460ff16151560808301526003015460a082015291505b8481101561500057878181518110614fc657fe5b6020026020010151600001516001600160a01b031682600001516001600160a01b03161415614ff85760009250615000565b600101614fb2565b5081156150225780516001600160a01b03166000908152600460205260408120555b5050600101614f17565b50808211156150eb57805b828110156150e957600180548061504a57fe5b60008281526020812060046000199093019283020180546001600160a01b0319908116825560018201805490911690556002810180546001600160e81b0319169055600301559055600b80548061509d57fe5b60008281526020812060166000199093019283020181815560018101805460ff19169055906150cf6002830182615f5a565b6150dd600383016000615f9e565b50509055600101615037565b505b60008183106150fa57816150fc565b825b905060005b818110156154a0576151ae86828151811061511857fe5b60200260200101516001838154811061512d57fe5b60009182526020918290206040805160c08101825260049390930290910180546001600160a01b0390811684526001820154811694840194909452600281015493841691830191909152600160a01b83046001600160401b03166060830152600160e01b90920460ff161515608082015260039091015460a0820152615c3c565b6153625780600101600460008884815181106151c657fe5b6020026020010151600001516001600160a01b03166001600160a01b031681526020019081526020016000208190555085818151811061520257fe5b60200260200101516001828154811061521757fe5b6000918252602091829020835160049092020180546001600160a01b039283166001600160a01b0319918216178255928401516001820180549184169185169190911790556040840151600282018054606087015160808801511515600160e01b0260ff60e01b196001600160401b03909216600160a01b0267ffffffffffffffff60a01b1995909716929097169190911792909216939093171692909217905560a09091015160039091015584518590829081106152d257fe5b6020026020010151600b82815481106152e757fe5b9060005260206000209060160201600201908051906020019061530b929190615d9b565b506000600b828154811061531b57fe5b60009182526020822060169190910201600101805460ff191692151592909217909155600b80548390811061534c57fe5b6000918252602090912060169091020155615498565b61542885828151811061537157fe5b6020026020010151600b838154811061538657fe5b600091825260209182902060026016909202018101805460408051601f60001961010060018616150201909316949094049182018590048502840185019052808352919290919083018282801561541e5780601f106153f35761010080835404028352916020019161541e565b820191906000526020600020905b81548152906001019060200180831161540157829003601f168201915b5050505050615cbd565b6154735784818151811061543857fe5b6020026020010151600b828154811061544d57fe5b90600052602060002090601602016002019080519060200190615471929190615d9b565b505b60006001828154811061548257fe5b9060005260206000209060040201600301819055505b600101615101565b5082821115615678576154b1615d6c565b835b83811015615675578581815181106154c757fe5b6020026020010151826040018190525060018782815181106154e557fe5b6020908102919091018101518254600181810185556000948552838520835160049093020180546001600160a01b039384166001600160a01b0319918216178255848601518284018054918616918316919091179055604080860151600284018054606089015160808a01511515600160e01b0260ff60e01b196001600160401b03909216600160a01b0267ffffffffffffffff60a01b1995909a1692909616919091179290921696909617169190911790935560a090930151600390930192909255600b805492830181559093528451601690910260008051602061714f83398151915281019182558583015160008051602061718f8339815191528201805491151560ff199092169190911790559285015180518694929361561b9360008051602061716f83398151915201920190615d9b565b5060608201516156319060038301906013615e15565b505050806001016004600089848151811061564857fe5b602090810291909101810151516001600160a01b03168252810191909152604001600020556001016154b3565b50505b6000600981905560015493505b838110156156e6576000600b828154811061569c57fe5b60009182526020822060169190910201600101805460ff191692151592909217909155600b8054839081106156cd57fe5b6000918252602090912060169091020155600101615685565b505050505050565b6000818361570f5760405162461bcd60e51b8152600401610c3b919061646f565b50600083858161571b57fe5b0495945050505050565b600081848411156157495760405162461bcd60e51b8152600401610c3b919061646f565b505050900390565b80516000906157625750600061130b565b6020820151805160001a9060c08210156157815760009250505061130b565b5060019392505050565b8051600090811a60808110156157a557600091505061130b565b60b88110806157c0575060c081108015906157c0575060f881105b156157cf57600191505061130b565b60c08110156157e35760b51901905061130b565b60f51901905061130b565b80516000908190811a608081101561580957600191506158c8565b60b881101561581e57607e19810191506158c8565b60c081101561586f57600060b78203600186019550806020036101000a8651049150600181018201935050808310156158695760405162461bcd60e51b8152600401610c3b90616a13565b506158c8565b60f88110156158845760be19810191506158c8565b600060f78203600186019550806020036101000a8651049150600181018201935050808310156158c65760405162461bcd60e51b8152600401610c3b90616a13565b505b5092915050565b80516000906158e05750600061130b565b600080905060006158f4846020015161578b565b602085015185519181019250015b8082101561592257615913826157ee565b82019150826001019250615902565b50909392505050565b805160009060151461593c57600080fd5b6113bb826149ce565b805160609061595357600080fd5b6000615962836020015161578b565b83516040805191839003808352601f19601f8201168301602001909152919250606090828015615999576020820181803683370190505b50905060008160200190506144f7848760200151018285615d21565b604080516020808252818301909252606091829190602082018180368337505050602081018490529050600067ffffffffffffffff1984166159f957506018615a1d565b6fffffffffffffffffffffffffffffffff198416615a1957506010615a1d565b5060005b6020811015615a5357818181518110615a3257fe5b01602001516001600160f81b03191615615a4b57615a53565b600101615a1d565b60008160200390506060816040519080825280601f01601f191660200182016040528015615a88576020820181803683370190505b5080830196909652508452509192915050565b606081516001148015615acd5750607f60f81b82600081518110615abb57fe5b01602001516001600160f81b03191611155b15615ad957508061130b565b6113bb615aeb8351608060ff16615b6a565b835b6060806040519050835180825260208201818101602087015b81831015615b1e578051835260209283019201615b06565b50855184518101855292509050808201602086015b81831015615b4b578051835260209283019201615b33565b508651929092011591909101601f01601f191660405250905092915050565b6060680100000000000000008310615b945760405162461bcd60e51b8152600401610c3b90616817565b60408051600180825281830190925260609160208201818036833701905050905060378411615bee5782840160f81b81600081518110615bd057fe5b60200101906001600160f81b031916908160001a90535090506113bb565b6060615bf9856159b5565b90508381510160370160f81b82600081518110615c1257fe5b60200101906001600160f81b031916908160001a905350615c338282615aed565b95945050505050565b805182516000916001600160a01b039182169116148015615c76575081602001516001600160a01b031683602001516001600160a01b0316145b8015615c9b575081604001516001600160a01b031683604001516001600160a01b0316145b8015610ea25750506060908101519101516001600160401b0390811691161490565b815181516000916001918114808314615cd95760009250615d17565b600160208701838101602088015b600284838510011415615d12578051835114615d065760009650600093505b60209283019201615ce7565b505050505b5090949350505050565b80615d2b57610c5b565b5b60208110615d4b578251825260209283019290910190601f1901615d2c565b915181516020939093036101000a6000190180199091169216919091179052565b60405180608001604052806000815260200160001515815260200160608152602001615d96615fc7565b905290565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f10615ddc57805160ff1916838001178555615e09565b82800160010185558215615e09579182015b82811115615e09578251825591602001919060010190615dee565b506126e3929150615fe6565b8260138101928215615e095791602002820182811115615e09578251825591602001919060010190615dee565b6040518060600160405280600060ff16815260200160608152602001606081525090565b6040518060400160405280615e79615fad565b8152602001600081525090565b6040805160c081018252600080825260208201819052918101829052606081018290526080810182905260a081019190915290565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f10615ef45780548555615e09565b82800160010185558215615e0957600052602060002091601f016020900482015b82811115615e09578254825591600101919060010190615f15565b8260138101928215615e095791820182811115615e09578254825591600101919060010190615f15565b50805460018160011615610100020316600290046000825580601f10615f805750611517565b601f0160209004906000526020600020908101906115179190615fe6565b50611517906013810190615fe6565b604051806040016040528060008152602001600081525090565b6040518061026001604052806013906020820280368337509192915050565b61269591905b808211156126e35760008155600101615fec565b60008083601f840112616011578182fd5b5081356001600160401b03811115616027578182fd5b6020830191508360208083028501011115614f0857600080fd5b60008083601f840112616052578182fd5b5081356001600160401b03811115616068578182fd5b602083019150836020828501011115614f0857600080fd5b600060208284031215616091578081fd5b81356001600160a01b0381168114610ea2578182fd5b600080600080604085870312156160bc578283fd5b84356001600160401b03808211156160d2578485fd5b6160de88838901616000565b909650945060208701359150808211156160f6578384fd5b5061610387828801616000565b95989497509550505050565b600060208284031215616120578081fd5b81518015158114610ea2578182fd5b60008060008060408587031215616144578384fd5b84356001600160401b038082111561615a578586fd5b61616688838901616041565b9096509450602087013591508082111561617e578384fd5b5061610387828801616041565b60006020828403121561619c578081fd5b5035919050565b6000602082840312156161b4578081fd5b5051919050565b600080604083850312156161cd578182fd5b505080516020909101519092909150565b6000806000604084860312156161f2578283fd5b833560ff81168114616202578384fd5b925060208401356001600160401b0381111561621c578283fd5b61622886828701616041565b9497909650939450505050565b6000815180845260208085019450808401835b8381101561626d5781516001600160a01b031687529582019590820190600101616248565b509495945050505050565b60008284528282602086013780602084860101526020601f19601f85011685010190509392505050565b600081518084526162ba816020860160208601616f57565b601f01601f19169290920160200192915050565b600082516162e0818460208701616f57565b9190910192915050565b918252602082015260400190565b6001600160a01b0391909116815260200190565b6001600160a01b03929092168252602082015260400190565b6001600160a01b03968716815294861660208601529290941660408401526001600160401b03166060830152911515608082015260a081019190915260c00190565b600060208252610ea26020830184616235565b60006040825261638d6040830185616235565b602083820381850152818551808452828401915082838202850101838801865b838110156163db57601f198784030185526163c98383516162a2565b948601949250908501906001016163ad565b50909998505050505050505050565b6000608082526163fd6080830187616235565b828103602084810191909152865180835287820192820190845b8181101561643357845183529383019391830191600101616417565b505084810360408601526164478188616235565b93505050506001600160401b038316606083015295945050505050565b901515815260200190565b600060208252610ea260208301846162a2565b600060408252616496604083018688616278565b82810360208401526164a9818587616278565b979650505050505050565b6020808252601c908201527f6c656e677468206f66206275726e526174696f206d69736d6174636800000000604082015260600190565b60208082526026908201527f6c656e677468206f66206d61784e756d4f664d61696e7461696e696e67206d696040820152650e6dac2e8c6d60d31b606082015260800190565b6020808252601b908201527f6261746368207472616e736665722072657475726e2066616c73650000000000604082015260600190565b6020808252602c908201527f6c656e677468206f66206d61784e756d4f66576f726b696e6743616e6469646160408201526b0e8cae640dad2e6dac2e8c6d60a31b606082015260800190565b60208082526025908201527f6c656e677468206f66206d61696e7461696e536c6173685363616c65206d69736040820152640dac2e8c6d60db1b606082015260800190565b6020808252818101527f6c656e677468206f66206e756d4f66436162696e657473206d69736d61746368604082015260600190565b60208082526019908201527f74686520636f6e7472616374206e6f7420696e69742079657400000000000000604082015260600190565b6020808252601b908201527f536166654d6174683a206164646974696f6e206f766572666c6f770000000000604082015260600190565b60208082526028908201527f746865206e756d4f66436162696e657473206d75737420626520677265617465604082015267072207468616e20360c41b606082015260800190565b60208082526039908201527f746865206e756d4f66436162696e657473206d757374206265206c657373207460408201527f68616e204d41585f4e554d5f4f465f56414c494441544f525300000000000000606082015260800190565b60208082526029908201527f746865206e756d626572206f662076616c696461746f727320657863656564206040820152681d1a19481b1a5b5a5d60ba1b606082015260800190565b60208082526022908201527f63616e206e6f7420646f207468697320747769636520696e206f6e6520626c6f604082015261636b60f01b606082015260800190565b6020808252602b908201527f746865206275726e526174696f206d757374206265206e6f206772656174657260408201526a0207468616e2031303030360ac1b606082015260800190565b6020808252600e908201526d696e70757420746f6f206c6f6e6760901b604082015260600190565b60208082526037908201527f746865206d61784e756d4f664d61696e7461696e696e67206d7573742062652060408201527f6c657373207468616e206e756d4f66436162696e657473000000000000000000606082015260800190565b6020808252602b908201527f6475706c696361746520636f6e73656e7375732061646472657373206f66207660408201526a185b1a59185d1bdc94d95d60aa1b606082015260800190565b60208082526027908201527f7468652065787069726554696d655365636f6e64476170206973206f7574206f604082015266662072616e676560c81b606082015260800190565b6020808252601590820152746465706f7369742076616c7565206973207a65726f60581b604082015260600190565b60208082526049908201527f746865206d61784e756d4f66576f726b696e6743616e64696461746573206d7560408201527f7374206265206e6f742067726561746572207468616e206d61784e756d4f6643606082015268616e6469646174657360b81b608082015260a00190565b60208082526027908201527f7468652066696e616c697479526577617264526174696f206973206f7574206f604082015266662072616e676560c81b606082015260800190565b6020808252601190820152706164646974696f6e206f766572666c6f7760781b604082015260600190565b60208082526023908201527f63616e206e6f7420656e7465722054656d706f72617279204d61696e74656e616040820152626e636560e81b606082015260800190565b60208082526025908201527f6c656e677468206f66206a61696c2076616c696461746f7273206d757374206260408201526465206f6e6560d81b606082015260800190565b60208082526021908201527f536166654d6174683a206d756c7469706c69636174696f6e206f766572666c6f6040820152607760f81b606082015260800190565b6020808252602e908201527f746865206d6573736167652073656e646572206d75737420626520676f76657260408201526d1b985b98d94818dbdb9d1c9858dd60921b606082015260800190565b60208082526025908201527f6c656e677468206f66206d61784e756d4f6643616e64696461746573206d69736040820152640dac2e8c6d60db1b606082015260800190565b6020808252601290820152716e6f7420696e206d61696e74656e616e636560701b604082015260600190565b60208082526021908201527f666565206973206c6172676572207468616e2044555354595f494e434f4d494e6040820152604760f81b606082015260800190565b60208082526019908201527f74686520636f6e747261637420616c726561647920696e697400000000000000604082015260600190565b60208082526026908201527f6c656e677468206f662066696e616c697479526577617264526174696f206d696040820152650e6dac2e8c6d60d31b606082015260800190565b6020808252601a908201527f6c656e677468206973206c657373207468616e206f6666736574000000000000604082015260600190565b60208082526026908201527f6c656e677468206f662065787069726554696d655365636f6e64476170206d696040820152650e6dac2e8c6d60d31b606082015260800190565b60208082526017908201527f6f6e6c792063757272656e742076616c696461746f7273000000000000000000604082015260600190565b60208082526021908201527f6661696c656420746f20706172736520696e69742076616c696461746f7253656040820152601d60fa1b606082015260800190565b6020808252602f908201527f746865206d6573736167652073656e646572206d7573742062652063726f737360408201526e0818da185a5b8818dbdb9d1c9858dd608a1b606082015260800190565b6020808252602d908201527f746865206d6573736167652073656e646572206d75737420626520746865206260408201526c3637b1b590383937b23ab1b2b960991b606082015260800190565b6020808252603e908201527f746865206d61696e7461696e536c6173685363616c65206d757374206265206760408201527f726561746572207468616e203020616e64206c657373207468616e2031300000606082015260800190565b6020808252600d908201526c756e6b6e6f776e20706172616d60981b604082015260600190565b60208082526029908201527f746865206d6573736167652073656e646572206d75737420626520736c6173686040820152680818dbdb9d1c9858dd60ba1b606082015260800190565b61ffff91909116815260200190565b90815260200190565b6000848252831515602083015260606040830152615c3360608301846162a2565b63ffffffff91909116815260200190565b60ff91909116815260200190565b600060ff8516825260406020830152615c33604083018486616278565b60005b83811015616f72578181015183820152602001616f5a565b83811115612c48575050600091015256fef901a880f901a4f844941284214b9b9c85549ab3d2b972df0deef66ac2c9946ddf42a51534fc98d0c0a3b42c963cace8441ddf946ddf42a51534fc98d0c0a3b42c963cace8441ddf8410000000f84494a2959d3f95eae5dc7d70144ce1b73b403b7eb6e0948081ef03f1d9e0bb4a5bf38f16285c879299f07f948081ef03f1d9e0bb4a5bf38f16285c879299f07f8410000000f8449435552c16704d214347f29fa77f77da6d75d7c75294dc4973e838e3949c77aced16ac2315dc2d7ab11194dc4973e838e3949c77aced16ac2315dc2d7ab1118410000000f84494980a75ecd1309ea12fa2ed87a8744fbfc9b863d594cc6ac05c95a99c1f7b5f88de0e3486c82293b27094cc6ac05c95a99c1f7b5f88de0e3486c82293b2708410000000f84494f474cf03cceff28abc65c9cbae594f725c80e12d94e61a183325a18a173319dd8e19c8d069459e217594e61a183325a18a173319dd8e19c8d069459e21758410000000f84494b71b214cb885500844365e95cd9942c7276e7fd894d22ca3ba2141d23adab65ce4940eb7665ea2b6a794d22ca3ba2141d23adab65ce4940eb7665ea2b6a7841000000070e72399380dcfb0338abc03dc8d47f9f470ada8e769c9a78d644ea97385ecb20175b7a638427703f0dbe7bb9bbf987a2551717b34e79f33b5b1008d1fa01db90175b7a638427703f0dbe7bb9bbf987a2551717b34e79f33b5b1008d1fa01dbb0175b7a638427703f0dbe7bb9bbf987a2551717b34e79f33b5b1008d1fa01dbaa2646970667358221220bc53b84b66ec5288714012f6e0e7cdc85eb3fd6718cf69ef36b3579924bc204664736f6c63430006040033", + }, + { + ContractAddr: SlashContract, + CommitUrl: "https://github.com/bnb-chain/bsc-genesis-contract/commit/b144718e94d7a1ebb24a7103202300f08826f369", + Code: "608060405234801561001057600080fd5b506004361061027f5760003560e01c80637942fd051161015c578063c80d4b8f116100ce578063dc927faf11610087578063dc927faf146104ad578063e1c7392a146104b5578063f9a2bbc7146104bd578063fc3e5908146104c5578063fc4333cd146104cd578063fd6a6879146104d55761027f565b8063c80d4b8f1461045c578063c81b166214610464578063c8509d811461046c578063c96be4cb1461047f578063cc844b7314610492578063d2a42e4b146104a55761027f565b80639dc09262116101205780639dc0926214610421578063a1a11bf514610429578063a78abc1614610431578063ab51bb9614610439578063ac0af62914610441578063ac431751146104495761027f565b80637942fd05146103ee5780638256ace6146103f6578063831d65d1146103fe57806396713da9146104115780639bc8e4f2146104195761027f565b8063493279b1116101f557806362b72cf5116101b957806362b72cf5146103be5780636e47b482146103c657806370fd5bad146103ce578063718a8aa8146103d657806375d47a0a146103de5780637912a65d146103e65761027f565b8063493279b11461037c5780634bf6c8821461039157806351e8067214610399578063567a372d146103a15780635bfb4990146103a95761027f565b806335aa2e441161024757806335aa2e441461030e57806337c8dab914610321578063389f4f71146103425780633a63f4b1146103575780633dffc3871461035f57806343756e5c146103745761027f565b80630bee7a67146102845780630e2374a5146102a25780631182b875146102b757806322d1e80b146102d757806323bac5a2146102ec575b600080fd5b61028c6104dd565b60405161029991906132a6565b60405180910390f35b6102aa6104e2565b6040516102999190612b84565b6102ca6102c5366004612aba565b6104e8565b6040516102999190612bbc565b6102df61054e565b6040516102999190612bb1565b6102ff6102fa366004612868565b610557565b6040516102999392919061328e565b6102aa61031c366004612a8a565b61057a565b61033461032f366004612868565b6105a1565b604051610299929190613280565b61034a6105f8565b6040516102999190613256565b61034a6105fe565b610367610604565b60405161029991906132b7565b6102aa610609565b61038461060f565b6040516102999190613247565b610367610615565b6102aa61061a565b61034a610620565b6103bc6103b7366004612868565b610626565b005b61034a6106d1565b6102aa6106d7565b6103676106dd565b6103676106e2565b6102aa6106e7565b61034a6106ed565b6103676106f2565b6103346106f7565b6103bc61040c366004612aba565b610701565b610367610813565b61034a610818565b6102aa610823565b6102aa610829565b6102df61082f565b61028c610838565b61034a61083d565b6103bc61045736600461296e565b610842565b61034a610ce1565b6102aa610ce6565b6103bc61047a366004612aba565b610cec565b6103bc61048d366004612868565b610d5d565b6103bc6104a03660046129d7565b61114e565b61034a61169b565b6102aa6116a0565b6103bc6116a6565b6102aa6116e2565b6103676116e8565b6103bc6116ed565b6102aa611b36565b606481565b61200181565b606033612000146105145760405162461bcd60e51b815260040161050b906130cd565b60405180910390fd5b60005460ff166105365760405162461bcd60e51b815260040161050b90612c9d565b60405162461bcd60e51b815260040161050b90613190565b60075460ff1681565b600260208190526000918252604090912080546001820154919092015460ff1683565b6001818154811061058757fe5b6000918252602090912001546001600160a01b0316905081565b6000806105ac61264f565b5050506001600160a01b0316600090815260026020818152604092839020835160608101855281548082526001830154938201849052919093015460ff16151592909301919091529091565b60055481565b60065481565b600181565b61100181565b6102ca81565b600881565b61200081565b60045481565b33611000146106475760405162461bcd60e51b815260040161050b90612ee1565b60005460ff166106695760405162461bcd60e51b815260040161050b90612c9d565b61200063f7a251d7600b61067c84611b3c565b60006040518463ffffffff1660e01b815260040161069c939291906132c5565b600060405180830381600087803b1580156106b657600080fd5b505af11580156106ca573d6000803e3d6000fd5b5050505050565b60035481565b61100581565b600281565b601081565b61100881565b603281565b600b81565b6004546005549091565b33612000146107225760405162461bcd60e51b815260040161050b906130cd565b60005460ff166107445760405162461bcd60e51b815260040161050b90612c9d565b61074c612672565b600061078d84848080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250611c0f92505050565b9150915080156107d45781516040517f7f0956d47419b9525356e7111652b653b530ec6f5096dccc04589bc38e629967916107c7916132a6565b60405180910390a16106ca565b81516040517f7d45f62d17443dd4547bca8a8112c60e2385669318dc300ec61a5d2492f262e791610804916132a6565b60405180910390a15050505050565b600981565b662386f26fc1000081565b61100781565b61100681565b60005460ff1681565b600081565b600481565b60005460ff166108645760405162461bcd60e51b815260040161050b90612c9d565b33611007146108855760405162461bcd60e51b815260040161050b90612f8a565b6108f084848080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250506040805180820190915260148152731b5a5cd9195b59585b9bdc951a1c995cda1bdb1960621b60208201529150611c8f9050565b1561098b57602081146109155760405162461bcd60e51b815260040161050b90612e6d565b604080516020601f840181900481028201810190925282815260009161095391858580838501838280828437600092019190915250611ce992505050565b905060018110158015610967575060055481105b6109835760405162461bcd60e51b815260040161050b90613088565b600455610c9e565b6109f184848080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152505060408051808201909152600f81526e19995b1bdb9e551a1c995cda1bdb19608a1b60208201529150611c8f9050565b15610a8d5760208114610a165760405162461bcd60e51b815260040161050b90612fd8565b604080516020601f8401819004810282018101909252828152600091610a5491858580838501838280828437600092019190915250611ce992505050565b90506103e88111158015610a69575060045481115b610a855760405162461bcd60e51b815260040161050b90612d0b565b600555610c9e565b610b0184848080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152505060408051808201909152601881527f66696e616c697479536c617368526577617264526174696f000000000000000060208201529150611c8f9050565b15610b9b5760208114610b265760405162461bcd60e51b815260040161050b906131c7565b604080516020601f8401819004810282018101909252828152600091610b6491858580838501838280828437600092019190915250611ce992505050565b9050600a8110158015610b775750606481105b610b935760405162461bcd60e51b815260040161050b90612e21565b600655610c9e565b610c0f84848080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152505060408051808201909152601881527f656e61626c654d616c6963696f7573566f7465536c617368000000000000000060208201529150611c8f9050565b15610c865760208114610c345760405162461bcd60e51b815260040161050b90612d40565b604080516020601f8401819004810282018101909252828152610c709190848480838501838280828437600092019190915250611cee92505050565b6007805460ff1916911515919091179055610c9e565b60405162461bcd60e51b815260040161050b90613169565b7f6cdb0ac70ab7f2e2d035cca5be60d89906f2dede7648ddbd7402189c1eeed17a84848484604051610cd39493929190612bcf565b60405180910390a150505050565b609681565b61100281565b3361200014610d0d5760405162461bcd60e51b815260040161050b906130cd565b60005460ff16610d2f5760405162461bcd60e51b815260040161050b90612c9d565b6040517f07db600eebe2ac176be8dcebad61858c245a4961bb32ca2aa3d159b09aa0810e90600090a1505050565b334114610d7c5760405162461bcd60e51b815260040161050b9061311c565b60005460ff16610d9e5760405162461bcd60e51b815260040161050b90612c9d565b6003544311610dbf5760405162461bcd60e51b815260040161050b90613212565b3a15610ddd5760405162461bcd60e51b815260040161050b90612f5c565b60405163155853f360e21b8152611000906355614fcc90610e02908490600401612b84565b60206040518083038186803b158015610e1a57600080fd5b505afa158015610e2e573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610e52919061294e565b610e5b57611147565b610e6361264f565b506001600160a01b0381166000908152600260208181526040928390208351606081018552815481526001820154928101929092529091015460ff161580159282019290925290610ebe576020810180516001019052610f17565b60016040820181905260208201819052805480820182556000919091527fb10e2d527612073b26eecdfd717e6a320cf44b4afac2b0732d9fcbe2b7fa0cf60180546001600160a01b0319166001600160a01b0384161790555b438152600554602082015181610f2957fe5b0661107557600060208201526040516335409f7f60e01b8152611000906335409f7f90610f5a908590600401612b84565b600060405180830381600087803b158015610f7457600080fd5b505af1158015610f88573d6000803e3d6000fd5b505050506120006001600160a01b031663f7a251d7600b610fa885611b3c565b60006040518463ffffffff1660e01b8152600401610fc8939291906132c5565b600060405180830381600087803b158015610fe257600080fd5b505af1925050508015610ff3575060015b611070573d808015611021576040519150601f19603f3d011682016040523d82523d6000602084013e611026565b606091505b50826001600160a01b03167fd7bc86ff5d08c8ab043edec743302aba2520e6635172a428bc956721db9e2d1c83602001518360405161106692919061325f565b60405180910390a2505b6110e1565b60045481602001518161108457fe5b066110e1576040516375abf10160e11b81526110009063eb57e202906110ae908590600401612b84565b600060405180830381600087803b1580156110c857600080fd5b505af11580156110dc573d6000803e3d6000fd5b505050505b6001600160a01b0382166000818152600260208181526040808420865181559186015160018301558581015191909201805460ff1916911515919091179055517fddb6012116e51abf5436d956a4f0ebd927e92c576ff96d7918290c8782291e3e9190a2505b5043600355565b60005460ff166111705760405162461bcd60e51b815260040161050b90612c9d565b604051630a83aaa960e31b81526110069063541d554890611195903390600401612b84565b60206040518083038186803b1580156111ad57600080fd5b505afa1580156111c1573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906111e5919061294e565b6112015760405162461bcd60e51b815260040161050b90612c01565b60075460ff166112235760405162461bcd60e51b815260040161050b90612c68565b6006546112305760146006555b8051514361010090910111801561125257504381602001516000015161010001115b61126e5760405162461bcd60e51b815260040161050b90612c38565b80602001516020015181600001516020015114801561129c5750806020015160600151816000015160600151145b156112b95760405162461bcd60e51b815260040161050b90612eb4565b8051604081015190511080156112d85750602081015160408101519051105b6112f45760405162461bcd60e51b815260040161050b90612dea565b6020810151518151511080156113195750806000015160400151816020015160400151105b8061134457508051516020820151511080156113445750806020015160400151816000015160400151105b8061135e5750806020015160400151816000015160400151145b61137a5760405162461bcd60e51b815260040161050b90612cd4565b61138c81600001518260400151611d16565b80156113a557506113a581602001518260400151611d16565b6113c15760405162461bcd60e51b815260040161050b90612d8b565b6060806110006001600160a01b0316633b071dcc6040518163ffffffff1660e01b815260040160006040518083038186803b1580156113ff57600080fd5b505afa158015611413573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f1916820160405261143b919081019061288b565b9150915060005b81518110156115785761146c82828151811061145a57fe5b60200260200101518560400151611eee565b15611570576006546040516309a99b4f60e41b815260646110028031909302049190639a99b4f0906114a49033908590600401612b98565b602060405180830381600087803b1580156114be57600080fd5b505af11580156114d2573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906114f69190612aa2565b506110006001600160a01b03166335409f7f85848151811061151457fe5b60200260200101516040518263ffffffff1660e01b81526004016115389190612b84565b600060405180830381600087803b15801561155257600080fd5b505af1158015611566573d6000803e3d6000fd5b5050505050611578565b600101611442565b50600061158a84604001516000611f52565b90506120006001600160a01b031663f7a251d7600b6115ac8760400151611f6e565b60006040518463ffffffff1660e01b81526004016115cc939291906132c5565b600060405180830381600087803b1580156115e657600080fd5b505af19250505080156115f7575060015b611669573d808015611625576040519150601f19603f3d011682016040523d82523d6000602084013e61162a565b606091505b50817fd58d1183100bd0932c0588f31c4205d6bc6168909765a96c41adbed3115f36288260405161165b9190612bbc565b60405180910390a250611695565b60405181907f7b78aadacff901d8b63d0dba4f86283d4db8aef27f9ed70413dd860f1c9532b690600090a25b50505050565b601481565b61100381565b60005460ff16156116c95760405162461bcd60e51b815260040161050b9061301a565b603260045560966005556000805460ff19166001179055565b61100081565b600381565b336110001461170e5760405162461bcd60e51b815260040161050b90612ee1565b60005460ff166117305760405162461bcd60e51b815260040161050b90612c9d565b60015461173c57611b34565b600154600090600019015b808211611b08576000805b8284101561186b5761176261264f565b600260006001878154811061177357fe5b60009182526020808320909101546001600160a01b0316835282810193909352604091820190208151606081018352815481526001820154938101939093526002015460ff161515908201526005549091506004900481602001511115611855576004600554816117e057fe5b0481602001510381602001818152505080600260006001888154811061180257fe5b6000918252602080832091909101546001600160a01b0316835282810193909352604091820190208351815591830151600183015591909101516002909101805460ff191691151591909117905561185f565b600192505061186b565b50836001019350611752565b828411611a025761187a61264f565b600260006001868154811061188b57fe5b60009182526020808320909101546001600160a01b0316835282810193909352604091820190208151606081018352815481526001820154938101939093526002015460ff161515908201526005549091506004900481602001511115611973576004600554816118f857fe5b0481602001510381602001818152505080600260006001878154811061191a57fe5b6000918252602080832091909101546001600160a01b03168352828101939093526040918201902083518155918301516001808401919091559201516002909101805460ff19169115159190911790559150611a029050565b600260006001868154811061198457fe5b60009182526020808320909101546001600160a01b031683528201929092526040018120818155600181810192909255600201805460ff191690558054806119c857fe5b600082815260209020810160001990810180546001600160a01b0319169055019055836119f55750611a02565b506000199092019161186b565b818015611a0c5750805b15611aeb576002600060018681548110611a2257fe5b60009182526020808320909101546001600160a01b031683528201929092526040018120818155600181810192909255600201805460ff19169055805484908110611a6957fe5b600091825260209091200154600180546001600160a01b039092169186908110611a8f57fe5b9060005260206000200160006101000a8154816001600160a01b0302191690836001600160a01b031602179055506001805480611ac857fe5b600082815260209020810160001990810180546001600160a01b03191690550190555b82611af7575050611b08565b505060019091019060001901611747565b6040517fcfdb3b6ccaeccbdc68be3c59c840e3b3c90f0a7c491f5fff1cf56cfda200dd9c90600090a150505b565b61100481565b60408051600480825260a08201909252606091829190816020015b6060815260200190600190039081611b57579050509050611b80836001600160a01b0316611fa9565b81600081518110611b8d57fe5b6020026020010181905250611ba143611fcc565b81600181518110611bae57fe5b6020908102919091010152611bc46102ca611fcc565b81600281518110611bd157fe5b6020026020010181905250611be542611fcc565b81600381518110611bf257fe5b6020026020010181905250611c0681611fdf565b9150505b919050565b611c17612672565b6000611c21612672565b611c29612684565b611c3a611c3586612069565b61208e565b90506000805b611c49836120d8565b15611c825780611c7557611c64611c5f846120f9565b612147565b63ffffffff16845260019150611c7a565b611c82565b600101611c40565b5091935090915050915091565b600081604051602001611ca29190612b68565b6040516020818303038152906040528051906020012083604051602001611cc99190612b68565b604051602081830303815290604052805190602001201490505b92915050565b015190565b8082015160009060ff811615611d08576001915081611d0e565b60009150815b505092915050565b60408051600480825260a0820190925260009160609190816020015b6060815260200190600190039081611d32575050604080516020808252818301909252919250606091908082018180368337019050509050611d778560000151611fcc565b82600081518110611d8457fe5b6020026020010181905250611d9f60208660200151836121c9565b611da8816121d9565b82600181518110611db557fe5b6020026020010181905250611dcd8560400151611fcc565b82600281518110611dda57fe5b6020026020010181905250611df560208660600151836121c9565b611dfe816121d9565b82600381518110611e0b57fe5b6020026020010181905250611e316020611e2484611fdf565b80519060200120836121c9565b6040805160b080825260e08201909252606091602082018180368337019050509050611e6181836000602061222f565b611e738187608001516020606061222f565b611e8181866080603061222f565b604080516001808252818301909252606091602082018180368337019050509050815160016020830182602086016066600019fa611ebe57600080fd5b506001611ecc826000612282565b60ff1614611ee1576000945050505050611ce3565b5060019695505050505050565b815181516000916001918114808314611f0a5760009250611f48565b600160208701838101602088015b600284838510011415611f43578051835114611f375760009650600093505b60209283019201611f18565b505050505b5090949350505050565b60008160200183511015611f6557600080fd5b50016020015190565b60408051600480825260a08201909252606091829190816020015b6060815260200190600190039081611f89579050509050611b80836121d9565b60408051600560a21b8318601482015260348101909152606090611c06816121d9565b6060611ce3611fda8361229e565b6121d9565b60608151600014156120005750604080516000815260208101909152611c0a565b60608260008151811061200f57fe5b602002602001015190506000600190505b8351811015612050576120468285838151811061203957fe5b6020026020010151612384565b9150600101612020565b50611c06612063825160c060ff16612401565b82612384565b6120716126a4565b506040805180820190915281518152602082810190820152919050565b612096612684565b61209f826124d3565b6120a857600080fd5b60006120b7836020015161250d565b60208085015160408051808201909152868152920190820152915050919050565b60006120e26126a4565b505080518051602091820151919092015191011190565b6121016126a4565b61210a826120d8565b61211357600080fd5b6020820151600061212382612570565b80830160209586015260408051808201909152908152938401919091525090919050565b80516000901580159061215c57508151602110155b61216557600080fd5b6000612174836020015161250d565b9050808360000151101561219a5760405162461bcd60e51b815260040161050b90613051565b8251602080850151830180519284900392918310156121c057826020036101000a820491505b50949350505050565b9091018181526020918201910152565b60608151600114801561220b5750607f60f81b826000815181106121f957fe5b01602001516001600160f81b03191611155b15612217575080611c0a565b611ce36122298351608060ff16612401565b83612384565b60005b818110156106ca5783818151811061224657fe5b602001015160f81c60f81b85848060010195508151811061226357fe5b60200101906001600160f81b031916908160001a905350600101612232565b6000816001018351101561229557600080fd5b50016001015190565b604080516020808252818301909252606091829190602082018180368337505050602081018490529050600067ffffffffffffffff1984166122e257506018612306565b6fffffffffffffffffffffffffffffffff19841661230257506010612306565b5060005b602081101561233c5781818151811061231b57fe5b01602001516001600160f81b031916156123345761233c565b600101612306565b60008160200390506060816040519080825280601f01601f191660200182016040528015612371576020820181803683370190505b5080830196909652508452509192915050565b6060806040519050835180825260208201818101602087015b818310156123b557805183526020928301920161239d565b50855184518101855292509050808201602086015b818310156123e25780518352602092830192016123ca565b508651929092011591909101601f01601f191660405250905092915050565b606068010000000000000000831061242b5760405162461bcd60e51b815260040161050b90612dc2565b604080516001808252818301909252606091602082018180368337019050509050603784116124855782840160f81b8160008151811061246757fe5b60200101906001600160f81b031916908160001a9053509050611ce3565b60606124908561229e565b90508381510160370160f81b826000815181106124a957fe5b60200101906001600160f81b031916908160001a9053506124ca8282612384565b95945050505050565b80516000906124e457506000611c0a565b6020820151805160001a9060c082101561250357600092505050611c0a565b5060019392505050565b8051600090811a6080811015612527576000915050611c0a565b60b8811080612542575060c08110801590612542575060f881105b15612551576001915050611c0a565b60c08110156125655760b519019050611c0a565b60f519019050611c0a565b80516000908190811a608081101561258b5760019150612648565b60b88110156125a057607e1981019150612648565b60c08110156125f157600060b78203600186019550806020036101000a8651049150600181018201935050808310156125eb5760405162461bcd60e51b815260040161050b90612f31565b50612648565b60f88110156126065760be1981019150612648565b600060f78203600186019550806020036101000a865104915060018101820193505080831015611d0e5760405162461bcd60e51b815260040161050b90612f31565b5092915050565b604051806060016040528060008152602001600081526020016000151581525090565b60408051602081019091526000815290565b60405180604001604052806126976126a4565b8152602001600081525090565b604051806040016040528060008152602001600081525090565b600082601f8301126126ce578081fd5b81516126e16126dc82613318565b6132f1565b818152915060208083019084810160005b84811015612757578151870188603f82011261270d57600080fd5b8381015161271d6126dc82613338565b81815260408b8184860101111561273357600080fd5b6127428388840183870161335c565b508652505092820192908201906001016126f2565b505050505092915050565b60008083601f840112612773578182fd5b50813567ffffffffffffffff81111561278a578182fd5b6020830191508360208285010111156127a257600080fd5b9250929050565b600082601f8301126127b9578081fd5b81356127c76126dc82613338565b91508082528360208285010111156127de57600080fd5b8060208401602084013760009082016020015292915050565b600060a08284031215612808578081fd5b61281260a06132f1565b905081358152602082013560208201526040820135604082015260608201356060820152608082013567ffffffffffffffff81111561285057600080fd5b61285c848285016127a9565b60808301525092915050565b600060208284031215612879578081fd5b813561288481613388565b9392505050565b6000806040838503121561289d578081fd5b825167ffffffffffffffff808211156128b4578283fd5b81850186601f8201126128c5578384fd5b805192506128d56126dc84613318565b80848252602080830192508084018a8283890287010111156128f5578788fd5b8794505b8685101561292057805161290c81613388565b8452600194909401939281019281016128f9565b508801519096509350505080821115612937578283fd5b50612944858286016126be565b9150509250929050565b60006020828403121561295f578081fd5b81518015158114612884578182fd5b60008060008060408587031215612983578182fd5b843567ffffffffffffffff8082111561299a578384fd5b6129a688838901612762565b909650945060208701359150808211156129be578384fd5b506129cb87828801612762565b95989497509550505050565b6000602082840312156129e8578081fd5b813567ffffffffffffffff808211156129ff578283fd5b81840160608187031215612a11578384fd5b612a1b60606132f1565b9250803582811115612a2b578485fd5b612a37878284016127f7565b845250602081013582811115612a4b578485fd5b612a57878284016127f7565b602085015250604081013582811115612a6e578485fd5b612a7a878284016127a9565b6040850152509195945050505050565b600060208284031215612a9b578081fd5b5035919050565b600060208284031215612ab3578081fd5b5051919050565b600080600060408486031215612ace578283fd5b833560ff81168114612ade578384fd5b9250602084013567ffffffffffffffff811115612af9578283fd5b612b0586828701612762565b9497909650939450505050565b60008284528282602086013780602084860101526020601f19601f85011685010190509392505050565b60008151808452612b5481602086016020860161335c565b601f01601f19169290920160200192915050565b60008251612b7a81846020870161335c565b9190910192915050565b6001600160a01b0391909116815260200190565b6001600160a01b03929092168252602082015260400190565b901515815260200190565b6000602082526128846020830184612b3c565b600060408252612be3604083018688612b12565b8281036020840152612bf6818587612b12565b979650505050505050565b6020808252601f908201527f746865206d73672073656e646572206973206e6f7420612072656c6179657200604082015260600190565b6020808252601690820152751d1bdbc81bdb1908189b1bd8dac81a5b9d9bdb1d995960521b604082015260600190565b6020808252818101527f6d616c6963696f757320766f746520736c617368206e6f7420656e61626c6564604082015260600190565b60208082526019908201527f74686520636f6e7472616374206e6f7420696e69742079657400000000000000604082015260600190565b6020808252601a908201527f6e6f2076696f6c6174696f6e206f6620766f74652072756c6573000000000000604082015260600190565b6020808252818101527f7468652066656c6f6e795468726573686f6c64206f7574206f662072616e6765604082015260600190565b6020808252602b908201527f6c656e677468206f6620656e61626c654d616c6963696f7573566f7465536c6160408201526a0e6d040dad2e6dac2e8c6d60ab1b606082015260800190565b60208082526017908201527f766572696679207369676e6174757265206661696c6564000000000000000000604082015260600190565b6020808252600e908201526d696e70757420746f6f206c6f6e6760901b604082015260600190565b60208082526019908201527f7372634e756d20626967676572207468616e207461724e756d00000000000000604082015260600190565b6020808252602c908201527f7468652066696e616c69747920736c6173682072657761726420726174696f2060408201526b6f7574206f662072616e676560a01b606082015260800190565b60208082526027908201527f6c656e677468206f66206d697364656d65616e6f725468726573686f6c64206d6040820152660d2e6dac2e8c6d60cb1b606082015260800190565b60208082526013908201527274776f206964656e746963616c20766f74657360681b604082015260600190565b60208082526030908201527f746865206d6573736167652073656e646572206d7573742062652076616c696460408201526f185d1bdc94d95d0818dbdb9d1c9858dd60821b606082015260800190565b6020808252601190820152706164646974696f6e206f766572666c6f7760781b604082015260600190565b6020808252601490820152736761737072696365206973206e6f74207a65726f60601b604082015260600190565b6020808252602e908201527f746865206d6573736167652073656e646572206d75737420626520676f76657260408201526d1b985b98d94818dbdb9d1c9858dd60921b606082015260800190565b60208082526022908201527f6c656e677468206f662066656c6f6e795468726573686f6c64206d69736d61746040820152610c6d60f31b606082015260800190565b60208082526019908201527f74686520636f6e747261637420616c726561647920696e697400000000000000604082015260600190565b6020808252601a908201527f6c656e677468206973206c657373207468616e206f6666736574000000000000604082015260600190565b60208082526025908201527f746865206d697364656d65616e6f725468726573686f6c64206f7574206f662060408201526472616e676560d81b606082015260800190565b6020808252602f908201527f746865206d6573736167652073656e646572206d7573742062652063726f737360408201526e0818da185a5b8818dbdb9d1c9858dd608a1b606082015260800190565b6020808252602d908201527f746865206d6573736167652073656e646572206d75737420626520746865206260408201526c3637b1b590383937b23ab1b2b960991b606082015260800190565b6020808252600d908201526c756e6b6e6f776e20706172616d60981b604082015260600190565b6020808252601e908201527f7265636569766520756e65787065637465642073796e207061636b6167650000604082015260600190565b6020808252602b908201527f6c656e677468206f662066696e616c697479536c61736852657761726452617460408201526a0d2de40dad2e6dac2e8c6d60ab1b606082015260800190565b6020808252818101527f63616e206e6f7420736c61736820747769636520696e206f6e6520626c6f636b604082015260600190565b61ffff91909116815260200190565b90815260200190565b6000838252604060208301526132786040830184612b3c565b949350505050565b918252602082015260400190565b92835260208301919091521515604082015260600190565b63ffffffff91909116815260200190565b60ff91909116815260200190565b600060ff85168252606060208301526132e16060830185612b3c565b9050826040830152949350505050565b60405181810167ffffffffffffffff8111828210171561331057600080fd5b604052919050565b600067ffffffffffffffff82111561332e578081fd5b5060209081020190565b600067ffffffffffffffff82111561334e578081fd5b50601f01601f191660200190565b60005b8381101561337757818101518382015260200161335f565b838111156116955750506000910152565b6001600160a01b038116811461339d57600080fd5b5056fea2646970667358221220425f90ada15339392881582f35a21b784186e12ed634c463af0e608e49de659064736f6c63430006040033", + }, + { + ContractAddr: SystemRewardContract, + CommitUrl: "https://github.com/bnb-chain/bsc-genesis-contract/commit/b144718e94d7a1ebb24a7103202300f08826f369", + Code: "6080604052600436106101a05760003560e01c80637942fd05116100ec578063ac4317511161008a578063f9a2bbc711610064578063f9a2bbc714610550578063fb5478b314610565578063fc3e59081461057a578063fd6a68791461058f576101e4565b8063ac43175114610457578063c81b166214610526578063dc927faf1461053b576101e4565b80639dc09262116100c65780639dc0926214610403578063a1a11bf514610418578063a78abc161461042d578063ab51bb9614610442576101e4565b80637942fd05146103a057806396713da9146103b55780639a99b4f0146103ca576101e4565b80634bf6c882116101595780636e47b482116101335780636e47b4821461034c57806370fd5bad14610361578063718a8aa81461037657806375d47a0a1461038b576101e4565b80634bf6c882146102db57806351e80672146102f05780636d70f7ae14610305576101e4565b80630bee7a67146101e95780630e2374a5146102175780633a0b0eff146102485780633dffc3871461026f57806343756e5c1461029a578063493279b1146102af576101e4565b366101e45734156101e25760408051348152905133917f6c98249d85d88c3753a04a22230f595e4dc8d3dc86c34af35deeeedc861b89db919081900360200190a25b005b600080fd5b3480156101f557600080fd5b506101fe6105a4565b6040805163ffffffff9092168252519081900360200190f35b34801561022357600080fd5b5061022c6105a9565b604080516001600160a01b039092168252519081900360200190f35b34801561025457600080fd5b5061025d6105af565b60408051918252519081900360200190f35b34801561027b57600080fd5b506102846105b5565b6040805160ff9092168252519081900360200190f35b3480156102a657600080fd5b5061022c6105ba565b3480156102bb57600080fd5b506102c46105c0565b6040805161ffff9092168252519081900360200190f35b3480156102e757600080fd5b506102846105c6565b3480156102fc57600080fd5b5061022c6105cb565b34801561031157600080fd5b506103386004803603602081101561032857600080fd5b50356001600160a01b03166105d1565b604080519115158252519081900360200190f35b34801561035857600080fd5b5061022c6105ef565b34801561036d57600080fd5b506102846105f5565b34801561038257600080fd5b506102846105fa565b34801561039757600080fd5b5061022c6105ff565b3480156103ac57600080fd5b50610284610605565b3480156103c157600080fd5b5061028461060a565b3480156103d657600080fd5b5061025d600480360360408110156103ed57600080fd5b506001600160a01b03813516906020013561060f565b34801561040f57600080fd5b5061022c6107ba565b34801561042457600080fd5b5061022c6107c0565b34801561043957600080fd5b506103386107c6565b34801561044e57600080fd5b506101fe6107cf565b34801561046357600080fd5b506101e26004803603604081101561047a57600080fd5b81019060208101813564010000000081111561049557600080fd5b8201836020820111156104a757600080fd5b803590602001918460018302840111640100000000831117156104c957600080fd5b9193909290916020810190356401000000008111156104e757600080fd5b8201836020820111156104f957600080fd5b8035906020019184600183028401116401000000008311171561051b57600080fd5b5090925090506107d4565b34801561053257600080fd5b5061022c610b57565b34801561054757600080fd5b5061022c610b5d565b34801561055c57600080fd5b5061022c610b63565b34801561057157600080fd5b5061025d610b69565b34801561058657600080fd5b50610284610b75565b34801561059b57600080fd5b5061022c610b7a565b606481565b61200181565b60015481565b600181565b61100181565b6102ca81565b600881565b61200081565b6001600160a01b031660009081526002602052604090205460ff1690565b61100581565b600281565b601081565b61100881565b600b81565b600981565b6000805460ff1661068c57600260208190527fe57bda0a954a7c7381b17b2c763e646ba2c60f67292d287ba583603e2c1c41668054600160ff19918216811790925561100560009081527fe25235fc0de9d7165652bef0846fefda506174abb9a190f03d0f7bcc6146dbce80548316841790559282558254161790555b3360009081526002602052604090205460ff166106da5760405162461bcd60e51b815260040180806020018281038252602b815260200180610c68602b913960400191505060405180910390fd5b60004783106106e957476106eb565b825b9050670de0b6b3a76400008111156107085750670de0b6b3a76400005b8015610789576040516001600160a01b0385169082156108fc029083906000818181858888f19350505050158015610744573d6000803e3d6000fd5b506040805182815290516001600160a01b038616917ff8b71c64315fc33b2ead2adfa487955065152a8ac33d9d5193aafd7f45dc15a0919081900360200190a26107b3565b6040517fe589651933c2457488cc0d8e0941518abf748e799435e4e396d9c4d0b2db2d4d90600090a15b9392505050565b61100781565b61100681565b60005460ff1681565b600081565b33611007146108145760405162461bcd60e51b815260040180806020018281038252602e815260200180610cc2602e913960400191505060405180910390fd5b61087684848080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152505060408051808201909152600b81526a30b23227b832b930ba37b960a91b60208201529150610b809050565b1561094e57606082828080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525050825192935050601490911490506108f95760405162461bcd60e51b815260040180806020018281038252602c815260200180610cf0602c913960400191505060405180910390fd5b60148101516001600160a01b038116600081815260026020526040808220805460ff19166001179055517f9870d7fe5d112134c55844951dedf365363006d9c588db07c4c85af6322a06199190a25050610ac5565b6109b384848080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152505060408051808201909152600e81526d3232b632ba32a7b832b930ba37b960911b60208201529150610b809050565b15610a8857606082828080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152505082519293505060149091149050610a365760405162461bcd60e51b815260040180806020018281038252602f815260200180610c93602f913960400191505060405180910390fd5b60148101516001600160a01b038116600081815260026020526040808220805460ff19169055517fb40992a19dba61ea600e87fce607102bf5908dc89076217b6ca6ae195224f7029190a25050610ac5565b6040805162461bcd60e51b815260206004820152600d60248201526c756e6b6e6f776e20706172616d60981b604482015290519081900360640190fd5b7f6cdb0ac70ab7f2e2d035cca5be60d89906f2dede7648ddbd7402189c1eeed17a848484846040518080602001806020018381038352878782818152602001925080828437600083820152601f01601f191690910184810383528581526020019050858580828437600083820152604051601f909101601f19169092018290039850909650505050505050a150505050565b61100281565b61100381565b61100081565b670de0b6b3a764000081565b600381565b61100481565b6000816040516020018082805190602001908083835b60208310610bb55780518252601f199092019160209182019101610b96565b6001836020036101000a03801982511681845116808217855250505050505090500191505060405160208183030381529060405280519060200120836040516020018082805190602001908083835b60208310610c235780518252601f199092019160209182019101610c04565b6001836020036101000a038019825116818451168082178552505050505050905001915050604051602081830303815290604052805190602001201490509291505056fe6f6e6c79206f70657261746f7220697320616c6c6f77656420746f2063616c6c20746865206d6574686f646c656e677468206f662076616c756520666f722064656c6574654f70657261746f722073686f756c64206265203230746865206d6573736167652073656e646572206d75737420626520676f7665726e616e636520636f6e74726163746c656e677468206f662076616c756520666f72206164644f70657261746f722073686f756c64206265203230a2646970667358221220dfab8b447e80ff45b4921032d6fc749c076c81bafdd35dc3adbf21cb41cdac7964736f6c63430006040033", + }, + { + ContractAddr: RelayerHubContract, + CommitUrl: "https://github.com/bnb-chain/bsc-genesis-contract/commit/b144718e94d7a1ebb24a7103202300f08826f369", + Code: "608060405234801561001057600080fd5b50600436106102275760003560e01c80638f83ab1311610130578063c81b1662116100b8578063f3ae24151161007c578063f3ae2415146104e8578063f9a2bbc71461050e578063fc3e590814610516578063fd30d9b81461051e578063fd6a68791461052657610227565b8063c81b1662146104c0578063dc927faf146104c8578063dd91d1c5146104d0578063e1c7392a146104d8578063e79a198f146104e057610227565b8063a1a11bf5116100ff578063a1a11bf5146103de578063a74b83ca146103e6578063a78abc16146103ee578063ab51bb96146103f6578063ac431751146103fe57610227565b80638f83ab13146103a057806395468d26146103c657806396713da9146103ce5780639dc09262146103d657610227565b8063541d5548116101b3578063718a8aa811610182578063718a8aa81461034857806375d47a0a1461035057806378beee67146103585780637942fd051461037e5780637ae230881461038657610227565b8063541d5548146102d85780636a6a419e146103125780636e47b4821461033857806370fd5bad1461034057610227565b80633dffc387116101fa5780633dffc3871461028357806343756e5c146102a1578063493279b1146102a95780634bf6c882146102c857806351e80672146102d057610227565b806303aff02b1461022c578063049a5716146102365780630bee7a671461025a5780630e2374a51461027b575b600080fd5b61023461052e565b005b61023e610539565b604080516001600160a01b039092168252519081900360200190f35b610262610551565b6040805163ffffffff9092168252519081900360200190f35b61023e610556565b61028b61055c565b6040805160ff9092168252519081900360200190f35b61023e610561565b6102b1610567565b6040805161ffff9092168252519081900360200190f35b61028b61056d565b61023e610572565b6102fe600480360360208110156102ee57600080fd5b50356001600160a01b0316610578565b604080519115158252519081900360200190f35b6102fe6004803603602081101561032857600080fd5b50356001600160a01b0316610596565b61023e6105b4565b61028b6105ba565b61028b6105bf565b61023e6105c4565b6102346004803603602081101561036e57600080fd5b50356001600160a01b03166105ca565b61028b6107b2565b61038e6107b7565b60408051918252519081900360200190f35b610234600480360360208110156103b657600080fd5b50356001600160a01b03166107c4565b61038e610a03565b61028b610a0f565b61023e610a14565b61023e610a1a565b61023e610a20565b6102fe610a38565b610262610a41565b6102346004803603604081101561041457600080fd5b81019060208101813564010000000081111561042f57600080fd5b82018360208201111561044157600080fd5b8035906020019184600183028401116401000000008311171561046357600080fd5b91939092909160208101903564010000000081111561048157600080fd5b82018360208201111561049357600080fd5b803590602001918460018302840111640100000000831117156104b557600080fd5b509092509050610a46565b61023e610d97565b61023e610d9d565b610234610da3565b610234610e44565b610234610ec6565b6102fe600480360360208110156104fe57600080fd5b50356001600160a01b031661107f565b61023e61109d565b61028b6110a3565b6102fe6110a8565b61023e6110b1565b610537336110b7565b565b7388cb4d8f77742c24d647bef8049d3f3c56067cdd81565b606481565b61200181565b600181565b61100181565b6102ca81565b600881565b61200081565b6001600160a01b031660009081526007602052604090205460ff1690565b6001600160a01b031660009081526008602052604090205460ff1690565b61100581565b600281565b601081565b61100881565b3360009081526008602052604090205460ff166106185760405162461bcd60e51b81526004018080602001828103825260248152602001806115c36024913960400191505060405180910390fd5b61062133611219565b1561065d5760405162461bcd60e51b81526004018080602001828103825260218152602001806115806021913960400191505060405180910390fd5b3233146106b1576040805162461bcd60e51b815260206004820152601e60248201527f70726f766973696f6e616c2072656c6179657220697320612070726f78790000604482015290519081900360640190fd5b6001600160a01b038181166000908152600960205260409020541633146107095760405162461bcd60e51b815260040180806020018281038252602781526020018061163c6027913960400191505060405180910390fd5b6001600160a01b03818116600081815260066020908152604080832080543380865260078086528487208054600160ff199182161790915584546001600160a01b031990811684179095556008875285882080548216905597875260098652848720805490941690935596168085529083529281902080549094169093558251828152908101939093528151909260008051602061166383398151915292908290030190a15050565b600b81565b68056bc75e2d6310000081565b3360009081526005602052604090205460ff16610821576040805162461bcd60e51b81526020600482015260166024820152751b585b9859d95c88191bd95cc81b9bdd08195e1a5cdd60521b604482015290519081900360640190fd5b61082a81611219565b156108665760405162461bcd60e51b81526004018080602001828103825260278152602001806115e76027913960400191505060405180910390fd5b6001600160a01b03811615610922576001600160a01b03811660009081526007602052604090205460ff16156108dc576040805162461bcd60e51b815260206004820152601660248201527572656c6179657220616c72656164792065786973747360501b604482015290519081900360640190fd5b6001600160a01b0381166000818152600860209081526040808320805460ff191660011790553383526009909152902080546001600160a01b03191690911790556109c3565b3360008181526006602090815260408083208054600980855283862080546001600160a01b03198085169095556001600160a01b0393841680895260078852868920805460ff19908116909155918516808a5260088952878a20805490931690925598909752908552805490921690915581518581529086169281019290925280516000805160206116638339815191529281900390910190a15050610a00565b604080516001600160a01b038316815290517ffba56633276570c7d3120d4535bf3bce26523da53958e40734210b9fd99b36939181900360200190a15b50565b67016345785d8a000081565b600981565b61100781565b61100681565b7342d596440775c90db8d9187b47650986e106349381565b60005460ff1681565b600081565b60005460ff16610a99576040805162461bcd60e51b81526020600482015260196024820152781d1a194818dbdb9d1c9858dd081b9bdd081a5b9a5d081e595d603a1b604482015290519081900360640190fd5b3361100714610ad95760405162461bcd60e51b815260040180806020018281038252602e81526020018061160e602e913960400191505060405180910390fd5b610b3a84848080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152505060408051808201909152600a81526930b23226b0b730b3b2b960b11b6020820152915061121f9050565b15610bd25760148114610b7e5760405162461bcd60e51b81526004018080602001828103825260228152602001806115a16022913960400191505060405180910390fd5b6000610bc1601484848080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061130692505050565b9050610bcc8161130b565b50610d05565b610c3684848080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152505060408051808201909152600d81526c3932b6b7bb32a6b0b730b3b2b960991b6020820152915061121f9050565b15610cc85760148114610c7a5760405162461bcd60e51b81526004018080602001828103825260228152602001806115a16022913960400191505060405180910390fd5b6000610cbd601484848080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061130692505050565b9050610bcc816110b7565b6040805162461bcd60e51b815260206004820152600d60248201526c756e6b6e6f776e20706172616d60981b604482015290519081900360640190fd5b7f6cdb0ac70ab7f2e2d035cca5be60d89906f2dede7648ddbd7402189c1eeed17a848484846040518080602001806020018381038352878782818152602001925080828437600083820152601f01601f191690910184810383528581526020019050858580828437600083820152604051601f909101601f19169092018290039850909650505050505050a150505050565b61100281565b61100381565b600a5460ff1615610dfb576040805162461bcd60e51b815260206004820152601e60248201527f7468652077686974656c6973747320616c726561647920757064617465640000604482015290519081900360640190fd5b610e187388cb4d8f77742c24d647bef8049d3f3c56067cdd6113cd565b610e357342d596440775c90db8d9187b47650986e10634936113cd565b600a805460ff19166001179055565b60005460ff1615610e9c576040805162461bcd60e51b815260206004820152601960248201527f74686520636f6e747261637420616c726561647920696e697400000000000000604482015290519081900360640190fd5b68056bc75e2d63100000600190815567016345785d8a00006002556000805460ff19169091179055565b3360009081526004602052604090205460ff16610f21576040805162461bcd60e51b81526020600482015260146024820152731c995b185e595c88191bc81b9bdd08195e1a5cdd60621b604482015290519081900360640190fd5b60005460ff16610f74576040805162461bcd60e51b81526020600482015260196024820152781d1a194818dbdb9d1c9858dd081b9bdd081a5b9a5d081e595d603a1b604482015290519081900360640190fd5b610f7c611565565b5033600081815260036020908152604091829020825180840190935280548084526001909101549183018290529192916108fc91610fc0919063ffffffff61148516565b6040518115909202916000818181858888f19350505050158015610fe8573d6000803e3d6000fd5b50602081015160405161100291829181156108fc0291906000818181858888f1935050505015801561101e573d6000803e3d6000fd5b50336000818152600460209081526040808320805460ff191690556003825280832083815560010192909255815192835290517fd17202129b83db7880d6b9f25df81c58ad46f7e0e2c92236b1aa10663a4876679281900390910190a15050565b6001600160a01b031660009081526005602052604090205460ff1690565b61100081565b600381565b600a5460ff1681565b61100481565b6001600160a01b03811660009081526005602052604090205460ff1661111c576040805162461bcd60e51b81526020600482015260156024820152741b585b9859d95c88191bd95cdb89dd08195e1a5cdd605a1b604482015290519081900360640190fd5b6001600160a01b038082166000818152600660209081526040808320805460058452828520805460ff1990811690915582546001600160a01b0319908116909355600980865284872080548a16885260088752858820805490931690925595879052948452845490911690935580519384525191909316927f2002866d443ac6c241fecaaa2af4895828c7de2cc423b9d01f7969650f557c76928290030190a16001600160a01b03811615611215576001600160a01b0381166000818152600760209081526040808320805460ff1916905580519384529083019190915280516000805160206116638339815191529281900390910190a15b5050565b3b151590565b6000816040516020018082805190602001908083835b602083106112545780518252601f199092019160209182019101611235565b6001836020036101000a03801982511681845116808217855250505050505090500191505060405160208183030381529060405280519060200120836040516020018082805190602001908083835b602083106112c25780518252601f1990920191602091820191016112a3565b6001836020036101000a0380198251168184511680821785525050505050509050019150506040516020818303038152906040528051906020012014905092915050565b015190565b6001600160a01b03811660009081526005602052604090205460ff1615611372576040805162461bcd60e51b81526020600482015260166024820152756d616e6167657220616c72656164792065786973747360501b604482015290519081900360640190fd5b6001600160a01b038116600081815260056020908152604091829020805460ff19166001179055815192835290517fe0de8e71a22c046647f4ef744348fa126ad6d052d4ce070999481f69d45575179281900390910190a150565b6001600160a01b03811660008181526005602090815260408083208054600160ff1991821681179092556006845282852080546001600160a01b031916871790556007845293829020805490941617909255815192835290517fe0de8e71a22c046647f4ef744348fa126ad6d052d4ce070999481f69d45575179281900390910190a160408051600081526001600160a01b03831660208201528151600080516020611663833981519152929181900390910190a150565b60006114c783836040518060400160405280601e81526020017f536166654d6174683a207375627472616374696f6e206f766572666c6f7700008152506114ce565b9392505050565b6000818484111561155d5760405162461bcd60e51b81526004018080602001828103825283818151815260200191508051906020019080838360005b8381101561152257818101518382015260200161150a565b50505050905090810190601f16801561154f5780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b505050900390565b60405180604001604052806000815260200160008152509056fe70726f766973696f6e616c2072656c61796572206973206120636f6e74726163746c656e677468206f66206d616e616765722061646472657373206d69736d6174636872656c61796572206973206e6f7420612070726f766973696f6e616c2072656c61796572636f6e7472616374206973206e6f7420616c6c6f77656420746f20626520612072656c61796572746865206d6573736167652073656e646572206d75737420626520676f7665726e616e636520636f6e747261637470726f766973696f6e616c206973206e6f742073657420666f722074686973206d616e61676572a5a19d7e9dab30a215022382d7abe782b579986fcbedec9942ecd0db9510a148a2646970667358221220243ef96c0e2d17d4e167cfcbcb6a51b4b92c1ac27fcb61400a87275f5128b4ab64736f6c63430006040033", + }, + { + ContractAddr: CrossChainContract, + CommitUrl: "https://github.com/bnb-chain/bsc-genesis-contract/commit/b144718e94d7a1ebb24a7103202300f08826f369", + Code: "608060405234801561001057600080fd5b50600436106103995760003560e01c8063718a8aa8116101e9578063c27cdcfb1161010f578063dc927faf116100ad578063f7a251d71161007c578063f7a251d714610b2f578063f9a2bbc714610ba7578063fc3e590814610baf578063fd6a687914610bb757610399565b8063dc927faf14610af7578063e1c7392a14610aff578063e3b0480514610b07578063e6400bbe14610b2757610399565b8063ccc108d7116100e9578063ccc108d714610ab0578063d31f968d14610ab8578063d76a867514610ae7578063dc40433114610aef57610399565b8063c27cdcfb14610a80578063c780e9de14610aa0578063c81b166214610aa857610399565b80638cc8f56111610187578063a78abc1611610156578063a78abc16146109b2578063ab51bb96146109ba578063ac431751146109c2578063b0355f5b1461078157610399565b80638cc8f5611461088757806396713da91461099a5780639dc09262146109a2578063a1a11bf5146109aa57610399565b806375d47a0a116101c357806375d47a0a146108a75780637942fd05146108af57806384013b6a146108b7578063863fe4ab1461099257610399565b8063718a8aa81461088f578063719482d51461089757806374f079b81461089f57610399565b8063422f9050116102ce57806363e1394e1161026c5780636de380bd1161023b5780636de380bd146108575780636e47a51a1461085f5780636e47b4821461087f57806370fd5bad1461088757610399565b806363e1394e146107ff5780636a3cb34d146108075780636bacff2c1461080f5780636c46aa681461080757610399565b80634bf6c882116102a85780634bf6c882146107b957806351e80672146107c15780635692ddd3146107c95780635f832177146107d157610399565b8063422f90501461078957806343756e5c146107a9578063493279b1146107b157610399565b8063299b533d1161033b578063308325f411610315578063308325f4146106155780633a648b151461061d5780633bdc47a6146106595780633dffc3871461078157610399565b8063299b533d146105a35780632af6f399146105d75780632ff32aea146105f457610399565b806314b3023b1161037757806314b3023b146104015780631d1309351461041b5780631e275ae11461043757806322556cdc1461059b57610399565b806305e682581461039e5780630bee7a67146103bc5780630e2374a5146103dd575b600080fd5b6103a6610bbf565b6040805160ff9092168252519081900360200190f35b6103c4610bc4565b6040805163ffffffff9092168252519081900360200190f35b6103e5610bc9565b604080516001600160a01b039092168252519081900360200190f35b610409610bcf565b60408051918252519081900360200190f35b610423610bd5565b604080519115158252519081900360200190f35b610599600480360361010081101561044e57600080fd5b81018160a081016080820135600160201b81111561046b57600080fd5b82018360208201111561047d57600080fd5b803590602001918460018302840111600160201b8311171561049e57600080fd5b919390929091602081019035600160201b8111156104bb57600080fd5b8201836020820111156104cd57600080fd5b803590602001918460018302840111600160201b831117156104ee57600080fd5b919390929091602081019035600160201b81111561050b57600080fd5b82018360208201111561051d57600080fd5b803590602001918460018302840111600160201b8311171561053e57600080fd5b919390929091602081019035600160201b81111561055b57600080fd5b82018360208201111561056d57600080fd5b803590602001918460018302840111600160201b8311171561058e57600080fd5b509092509050610bde565b005b6104096112c2565b6105c0600480360360208110156105b957600080fd5b50356112c7565b6040805161ffff9092168252519081900360200190f35b610423600480360360208110156105ed57600080fd5b50356112dd565b6105fc6112f2565b60408051600792830b90920b8252519081900360200190f35b6104096112fb565b61063d6004803603602081101561063357600080fd5b503560ff16611301565b604080516001600160401b039092168252519081900360200190f35b61070c6004803603606081101561066f57600080fd5b60ff82351691602081013591810190606081016040820135600160201b81111561069857600080fd5b8201836020820111156106aa57600080fd5b803590602001918460018302840111600160201b831117156106cb57600080fd5b91908080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525092955061131c945050505050565b6040805160208082528351818301528351919283929083019185019080838360005b8381101561074657818101518382015260200161072e565b50505050905090810190601f1680156107735780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b6103a6611392565b6104236004803603602081101561079f57600080fd5b503560ff16611397565b6103e56113ac565b6105c06113b2565b6103a66113b8565b6103e56113bd565b6104096113c3565b610599600480360360408110156107e757600080fd5b506001600160a01b03813581169160200135166113f3565b610409611653565b6105c061167b565b61082c6004803603602081101561082557600080fd5b5035611680565b6040805161ffff90941684526001600160801b03909216602084015282820152519081900360600190f35b6104096116af565b6103e56004803603602081101561087557600080fd5b503560ff166116d6565b6103e56116f1565b6103a661167b565b6103a66116f7565b6105c0611392565b6104096116fc565b6103e5611702565b6103a6611708565b610599600480360360a08110156108cd57600080fd5b810190602081018135600160201b8111156108e757600080fd5b8201836020820111156108f957600080fd5b803590602001918460018302840111600160201b8311171561091a57600080fd5b919390929091602081019035600160201b81111561093757600080fd5b82018360208201111561094957600080fd5b803590602001918460018302840111600160201b8311171561096a57600080fd5b919350915080356001600160401b03908116916020810135909116906040013560ff1661170d565b6104096129c7565b6103a66129cf565b6103e56129d4565b6103e56129da565b6104236129e0565b6103c4610bbf565b610599600480360360408110156109d857600080fd5b810190602081018135600160201b8111156109f257600080fd5b820183602082011115610a0457600080fd5b803590602001918460018302840111600160201b83111715610a2557600080fd5b919390929091602081019035600160201b811115610a4257600080fd5b820183602082011115610a5457600080fd5b803590602001918460018302840111600160201b83111715610a7557600080fd5b5090925090506129e9565b61063d60048036036020811015610a9657600080fd5b503560ff166134ad565b6104096134c8565b6103e56134ec565b6105996134f2565b61042360048036036040811015610ace57600080fd5b5080356001600160a01b0316906020013560ff16613746565b61070c613766565b610409613785565b6103e561378b565b610599613791565b61063d60048036036020811015610b1d57600080fd5b503560ff16613b48565b610599613b63565b61059960048036036060811015610b4557600080fd5b60ff8235169190810190604081016020820135600160201b811115610b6957600080fd5b820183602082011115610b7b57600080fd5b803590602001918460018302840111600160201b83111715610b9c57600080fd5b919350915035613d82565b6103e5613ec5565b6103a6613ecb565b6103e5613ed0565b600081565b606481565b61200181565b60015481565b600b5460ff1681565b60005460ff16610c23576040805162461bcd60e51b815260206004820152601960248201526000805160206149b4833981519152604482015290519081900360640190fd5b604080516337d7f9c160e21b81526001600160401b038b35166004820181905291516110039163df5fe704916024808301926020929190829003018186803b158015610c6e57600080fd5b505afa158015610c82573d6000803e3d6000fd5b505050506040513d6020811015610c9857600080fd5b5051610cd55760405162461bcd60e51b81526004018080602001828103825260238152602001806149d46023913960400191505060405180910390fd5b604080516337d7f9c160e21b815260208c8101356001600160401b03166004830181905292516110039263df5fe704926024808301939192829003018186803b158015610d2157600080fd5b505afa158015610d35573d6000803e3d6000fd5b505050506040513d6020811015610d4b57600080fd5b5051610d885760405162461bcd60e51b81526004018080602001828103825260238152602001806149d46023913960400191505060405180910390fd5b60608b013560ff81166000908152600560205260409020546001600160401b03909116906001600160a01b0316610e01576040805162461bcd60e51b815260206004820152601860248201527718da185b9b995b081a5cc81b9bdd081cdd5c1c1bdc9d195960421b604482015290519081900360640190fd5b600b5460ff1615610e45576040805162461bcd60e51b81526020600482015260096024820152681cdd5cdc195b99195960ba1b604482015290519081900360640190fd5b8888604051808383808284376040519201829003822094508f93508e9250819050838380828437808301925050509250505060405180910390201415610ec1576040805162461bcd60e51b815260206004820152600c60248201526b1cd85b59481c185e5b1bd85960a21b604482015290519081900360640190fd5b60606001600160401b0360408e01358116908e83013516610ee28282613ed6565b80516020808301919091206000818152600e9092526040909120549194509060ff1615610f4b576040805162461bcd60e51b8152602060048201526012602482015271185b1c9958591e4818da185b1b195b99d95960721b604482015290519081900360640190fd5b6000908152600e60205260408120805460ff191660011790558f8160200201356001600160401b0316905060608f8f8080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f82011690508083019250505050505050905060608c8c8080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201829052506040805163cba510a960e01b81526001600160401b038a16600482015290519596509094611003945063cba510a9935060248083019350602092829003018186803b15801561104157600080fd5b505afa158015611055573d6000803e3d6000fd5b505050506040513d602081101561106b57600080fd5b505160408051808201909152600381526269626360e81b6020820152909150611098908290898686613f1e565b6110e1576040805162461bcd60e51b81526020600482015260156024820152740696e76616c6964206d65726b6c652070726f6f663605c1b604482015290519081900360640190fd5b5050505060008f6001600481106110f457fe5b60200201356001600160401b0316905060608d8d8080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525050604080516020601f8f018190048102820181019092528d815293945060609392508d91508c908190840183828082843760009201829052506040805163cba510a960e01b81526001600160401b038a16600482015290519596509094611003945063cba510a9935060248083019350602092829003018186803b1580156111c057600080fd5b505afa1580156111d4573d6000803e3d6000fd5b505050506040513d60208110156111ea57600080fd5b505160408051808201909152600381526269626360e81b6020820152909150611217908290898686613f1e565b611260576040805162461bcd60e51b8152602060048201526015602482015274696e76616c6964206d65726b6c652070726f6f663160581b604482015290519081900360640190fd5b5050505061126c61401b565b604080516001600160401b038416815260ff83166020820152815133927f039eb91179ffd7d3b6e97f8ea106e748e827f910b872375dbc9c14a362319c3c928290030190a2505050505050505050505050505050565b603281565b600d6020526000908152604090205461ffff1681565b600e6020526000908152604090205460ff1681565b60045460070b81565b60025481565b600a602052600090815260409020546001600160401b031681565b60606000825160210190506060816040519080825280601f01601f191660200182016040528015611354576020820181803683370190505b506021810186905260018101879052828152905060418101600061137786614099565b509050611386818388516140a3565b50909695505050505050565b600181565b60096020526000908152604090205460ff1681565b61100181565b6102ca81565b600881565b61200081565b604080517710d05390d15317d514905394d1915497d41493d413d4d05360421b8152905190819003601801902081565b60005460ff16611438576040805162461bcd60e51b815260206004820152601960248201526000805160206149b4833981519152604482015290519081900360640190fd5b6040805163569e4ed360e11b815233600482015290516000916110009163ad3c9da691602480820192602092909190829003018186803b15801561147b57600080fd5b505afa15801561148f573d6000803e3d6000fd5b505050506040513d60208110156114a557600080fd5b505160408051633d42651560e11b8152905191925060009161100091637a84ca2a916004808301926020929190829003018186803b1580156114e657600080fd5b505afa1580156114fa573d6000803e3d6000fd5b505050506040513d602081101561151057600080fd5b505190508061151d575060155b60008211801561152d5750808211155b61156c576040805162461bcd60e51b815260206004820152600b60248201526a1b9bdd0818d8589a5b995d60aa1b604482015290519081900360640190fd5b604080516001600160a01b038087166020808401919091529086168284015282518083038401815260608301808552815191909201207710d05390d15317d514905394d1915497d41493d413d4d05360421b90915291519081900360780190206000906115d990836140e4565b9050801561164b5760408051630911a2c160e11b81526001600160a01b03888116600483015287166024820152905161100491631223458291604480830192600092919082900301818387803b15801561163257600080fd5b505af1158015611646573d6000803e3d6000fd5b505050505b505050505050565b604080516f14d554d411539117d41493d413d4d05360821b8152905190819003601001902081565b600281565b600c602052600090815260409020805460019091015461ffff8216916201000090046001600160801b03169083565b604080516e149153d4115397d41493d413d4d053608a1b8152905190819003600f01902081565b6005602052600090815260409020546001600160a01b031681565b61100581565b601081565b60035481565b61100881565b600b81565b60005460ff16611752576040805162461bcd60e51b815260206004820152601960248201526000805160206149b4833981519152604482015290519081900360640190fd5b60408051630a83aaa960e31b815233600482015290516110069163541d5548916024808301926020929190829003018186803b15801561179157600080fd5b505afa1580156117a5573d6000803e3d6000fd5b505050506040513d60208110156117bb57600080fd5b505161180e576040805162461bcd60e51b815260206004820152601f60248201527f746865206d73672073656e646572206973206e6f7420612072656c6179657200604482015290519081900360640190fd5b60ff8116600090815260086020526040902054829082906001600160401b03908116908316811461187e576040805162461bcd60e51b815260206004820152601560248201527439b2b8bab2b731b2903737ba1034b71037b93232b960591b604482015290519081900360640190fd5b60ff8216600090815260086020908152604091829020805467ffffffffffffffff1916600185016001600160401b039081169190911790915582516337d7f9c160e21b81529089166004820152915188926110039263df5fe70492602480840193829003018186803b1580156118f357600080fd5b505afa158015611907573d6000803e3d6000fd5b505050506040513d602081101561191d57600080fd5b505161195a5760405162461bcd60e51b81526004018080602001828103825260238152602001806149d46023913960400191505060405180910390fd5b60ff851660009081526005602052604090205485906001600160a01b03166119c4576040805162461bcd60e51b815260206004820152601860248201527718da185b9b995b081a5cc81b9bdd081cdd5c1c1bdc9d195960421b604482015290519081900360640190fd5b60ff86166000908152600a6020526040902054889087906001600160401b039081169083161015611a2d576040805162461bcd60e51b815260206004820152600e60248201526d3a37b79037b632103432b0b232b960911b604482015290519081900360640190fd5b60ff81166000908152600a60205260409020546001600160401b03838116911614611a7f5760ff81166000908152600a60205260409020805467ffffffffffffffff19166001600160401b0384161790555b600b5460ff1615611ac3576040805162461bcd60e51b81526020600482015260096024820152681cdd5cdc195b99195960ba1b604482015290519081900360640190fd5b60608e8e8080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f82011690508083019250505050505050905060608d8d8080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f820116905080830192505050505050509050611c076110036001600160a01b031663cba510a98e6040518263ffffffff1660e01b815260040180826001600160401b03166001600160401b0316815260200191505060206040518083038186803b158015611bb057600080fd5b505afa158015611bc4573d6000803e3d6000fd5b505050506040513d6020811015611bda57600080fd5b505160408051808201909152600381526269626360e81b6020820152611c008e8e613ed6565b8585613f1e565b611c4f576040805162461bcd60e51b815260206004820152601460248201527334b73b30b634b21036b2b935b63290383937b7b360611b604482015290519081900360640190fd5b60408051631bb5062960e31b81526001600160401b038e16600482015290516000916110039163dda8314891602480820192602092909190829003018186803b158015611c9b57600080fd5b505afa158015611caf573d6000803e3d6000fd5b505050506040513d6020811015611cc557600080fd5b505190508b8b600080806060611cda896143c9565b935093509350935083611d9c578460ff16866001600160401b03167ff7b2e42d694eb1100184aae86d4245d9e46966100b1dc7e723275b98326854ac8b6040518080602001828103825283818151815260200191508051906020019080838360005b83811015611d54578181015183820152602001611d3c565b50505050905090810190601f168015611d815780820380516001836020036101000a031916815260200191505b509250505060405180910390a35050505050505050506129b7565b6040805160ff85811682529151918716916001600160401b038916917f36afdaf439a8f43fe72135135d804ae620b37a474f0943b5b85f6788312cad40919081900360200190a360ff83166123215760ff85166000818152600560209081526040808320548151631182b87560e01b815260048101958652602481019283528651604482015286516001600160a01b03909216958695631182b875958d958a9593949093606490910192918601918190849084905b83811015611e69578181015183820152602001611e51565b50505050905090810190601f168015611e965780820380516001836020036101000a031916815260200191505b509350505050600060405180830381600087803b158015611eb657600080fd5b505af1925050508015611f9a57506040513d6000823e601f3d908101601f191682016040526020811015611ee957600080fd5b8101908080516040519392919084600160201b821115611f0857600080fd5b908301906020820185811115611f1d57600080fd5b8251600160201b811182820188101715611f3657600080fd5b82525081516020918201929091019080838360005b83811015611f63578181015183820152602001611f4b565b50505050905090810190601f168015611f905780820380516001836020036101000a031916815260200191505b5060405250505060015b6122ac576040516000815260443d1015611fb657506000612051565b60046000803e60005160e01c6308c379a08114611fd7576000915050612051565b60043d036004833e81513d60248201116001600160401b038211171561200257600092505050612051565b80830180516001600160401b03811115612023576000945050505050612051565b8060208301013d860181111561204157600095505050505050612051565b601f01601f191660405250925050505b8061205c575061216e565b60ff8716600090815260076020526040812054612093916001600160401b0390911690899061208e906002908861131c565b614479565b60ff8716600090815260076020908152604080832080546001600160401b038082166001011667ffffffffffffffff19909116179055805182815284518184015284516001600160a01b038716947ff91a8f63e5b3e0e89e5f93e1915a7805f3c52d9a73b3c09769785c2c7bf87acf948794849390840192918601918190849084905b8381101561212e578181015183820152602001612116565b50505050905090810190601f16801561215b5780820380516001836020036101000a031916815260200191505b509250505060405180910390a2506122a7565b3d808015612198576040519150601f19603f3d011682016040523d82523d6000602084013e61219d565b606091505b5060ff87166000908152600760205260408120546121d0916001600160401b0390911690899061208e906002908861131c565b60ff8716600090815260076020908152604080832080546001600160401b038082166001011667ffffffffffffffff19909116179055805182815284518184015284516001600160a01b038716947f63ac299d6332d1cc4e61b81e59bc00c0ac7c798addadf33840f1307cd2977351948794849390840192918601918190849084905b8381101561226b578181015183820152602001612253565b50505050905090810190601f1680156122985780820380516001836020036101000a031916815260200191505b509250505060405180910390a2505b61231b565b8051156123195760ff87166000908152600760205260408120546122e5916001600160401b0390911690899061208e906001908661131c565b60ff8716600090815260076020526040902080546001600160401b038082166001011667ffffffffffffffff199091161790555b505b506128ef565b60ff8316600114156125c55760ff8516600081815260056020908152604080832054815163831d65d160e01b815260048101958652602481019283528651604482015286516001600160a01b0390921695869563831d65d1958d958a9593949093606490910192918601918190849084905b838110156123ab578181015183820152602001612393565b50505050905090810190601f1680156123d85780820380516001836020036101000a031916815260200191505b509350505050600060405180830381600087803b1580156123f857600080fd5b505af1925050508015612409575060015b61231b576040516000815260443d1015612425575060006124c0565b60046000803e60005160e01c6308c379a081146124465760009150506124c0565b60043d036004833e81513d60248201116001600160401b0382111715612471576000925050506124c0565b80830180516001600160401b038111156124925760009450505050506124c0565b8060208301013d86018111156124b0576000955050505050506124c0565b601f01601f191660405250925050505b806124cb5750612530565b60408051602080825283518183015283516001600160a01b038616937ff91a8f63e5b3e0e89e5f93e1915a7805f3c52d9a73b3c09769785c2c7bf87acf938693909283928301918501908083836000831561212e578181015183820152602001612116565b3d80801561255a576040519150601f19603f3d011682016040523d82523d6000602084013e61255f565b606091505b5060408051602080825283518183015283516001600160a01b038616937f63ac299d6332d1cc4e61b81e59bc00c0ac7c798addadf33840f1307cd2977351938693909283928301918501908083836000831561226b578181015183820152602001612253565b60ff8316600214156128ef5760ff8516600081815260056020908152604080832054815163c8509d8160e01b815260048101958652602481019283528651604482015286516001600160a01b0390921695869563c8509d81958d958a9593949093606490910192918601918190849084905b8381101561264f578181015183820152602001612637565b50505050905090810190601f16801561267c5780820380516001836020036101000a031916815260200191505b509350505050600060405180830381600087803b15801561269c57600080fd5b505af19250505080156126ad575060015b6128ed576040516000815260443d10156126c957506000612764565b60046000803e60005160e01c6308c379a081146126ea576000915050612764565b60043d036004833e81513d60248201116001600160401b038211171561271557600092505050612764565b80830180516001600160401b03811115612736576000945050505050612764565b8060208301013d860181111561275457600095505050505050612764565b601f01601f191660405250925050505b8061276f5750612818565b816001600160a01b03167ff91a8f63e5b3e0e89e5f93e1915a7805f3c52d9a73b3c09769785c2c7bf87acf826040518080602001828103825283818151815260200191508051906020019080838360005b838110156127d85781810151838201526020016127c0565b50505050905090810190601f1680156128055780820380516001836020036101000a031916815260200191505b509250505060405180910390a2506128ed565b3d808015612842576040519150601f19603f3d011682016040523d82523d6000602084013e612847565b606091505b50816001600160a01b03167f63ac299d6332d1cc4e61b81e59bc00c0ac7c798addadf33840f1307cd2977351826040518080602001828103825283818151815260200191508051906020019080838360005b838110156128b1578181015183820152602001612899565b50505050905090810190601f1680156128de5780820380516001836020036101000a031916815260200191505b509250505060405180910390a2505b505b60ff80861660009081526009602052604090205461100591636f93d2e6918a91339187911680612921575060ff881615155b604080516001600160e01b031960e088901b1681526001600160a01b039586166004820152939094166024840152604483019190915215156064820152905160848083019260209291908290030181600087803b15801561298157600080fd5b505af1158015612995573d6000803e3d6000fd5b505050506040513d60208110156129ab57600080fd5b50505050505050505050505b5050505050505050505050505050565b630102ca0081565b600981565b61100781565b61100681565b60005460ff1681565b3361100714612a295760405162461bcd60e51b815260040180806020018281038252602e81526020018061490a602e913960400191505060405180910390fd5b600b5460ff1615612a6d576040805162461bcd60e51b81526020600482015260096024820152681cdd5cdc195b99195960ba1b604482015290519081900360640190fd5b612ad684848080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525050604080518082019091526012815271626174636853697a65466f724f7261636c6560701b602082015291506146149050565b15612b7157604080516020601f8401819004810282018101909252828152600091612b19918585808385018382808284376000920191909152506146fb92505050565b90506127108111158015612b2e5750600a8110155b612b695760405162461bcd60e51b81526004018080602001828103825260328152602001806149826032913960400191505060405180910390fd5b60015561341b565b612bda84848080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152505060408051808201909152601281527118591913dc955c19185d1950da185b9b995b60721b602082015291506146149050565b15612d6257606082828080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152505082519293505060169091149050612c5d5760405162461bcd60e51b815260040180806020018281038252605a815260200180614823605a913960600191505060405180910390fd5b60018101516002820151601683015160ff82161590612c7b81614700565b612ccc576040805162461bcd60e51b815260206004820152601960248201527f61646472657373206973206e6f74206120636f6e747261637400000000000000604482015290519081900360640190fd5b60ff8416600081815260056020908152604080832080546001600160a01b0319166001600160a01b038716908117909155808452600683528184208585528352818420805460ff199081166001179091556009909352818420805490931687151517909255519092917f7e3b6af43092577ee20e60eaa1d9b114a7031305c895ee7dd3ffe17196d2e1e091a3505050505061341b565b612dcf84848080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525050604080518082019091526016815275195b98589b1953dc911a5cd8589b1950da185b9b995b60521b602082015291506146149050565b15612f0057606082828080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152505082519293505060029091149050612e525760405162461bcd60e51b815260040180806020018281038252604a815260200180614938604a913960600191505060405180910390fd5b600181810151600283015160ff80831660009081526005602052604090205492939192908316909114906001600160a01b03168015612ef6576001600160a01b038116600090815260066020908152604080832060ff881680855290835292819020805460ff1916861515908117909155815190815290517fa3132e3f9819fbddc7f0ed6d38d7feef59aa95112090b7c592f5cb5bc4aa4adc929181900390910190a25b505050505061341b565b612f6484848080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152505060408051808201909152600d81526c73757370656e6451756f72756d60981b602082015291506146149050565b156130995760028114612fa85760405162461bcd60e51b815260040180806020018281038252602d8152602001806148b1602d913960400191505060405180910390fd5b6000612feb600284848080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152506146fb92505050565b905060008161ffff16118015613005575060648161ffff16105b61304f576040805162461bcd60e51b8152602060048201526016602482015275696e76616c69642073757370656e642071756f72756d60501b604482015290519081900360640190fd5b604080516f14d554d411539117d41493d413d4d05360821b815281519081900360100190206000908152600d60205220805461ffff90921661ffff1990921691909117905561341b565b6130fc84848080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152505060408051808201909152600c81526b72656f70656e51756f72756d60a01b602082015291506146149050565b1561322f57600281146131405760405162461bcd60e51b815260040180806020018281038252602c8152602001806148de602c913960400191505060405180910390fd5b6000613183600284848080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152506146fb92505050565b905060008161ffff1611801561319d575060648161ffff16105b6131e6576040805162461bcd60e51b8152602060048201526015602482015274696e76616c69642072656f70656e2071756f72756d60581b604482015290519081900360640190fd5b604080516e149153d4115397d41493d413d4d053608a1b8152815190819003600f0190206000908152600d60205220805461ffff90921661ffff1990921691909117905561341b565b61329a84848080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152505060408051808201909152601481527363616e63656c5472616e7366657251756f72756d60601b602082015291506146149050565b156133de57600281146132de5760405162461bcd60e51b815260040180806020018281038252603481526020018061487d6034913960400191505060405180910390fd5b6000613321600284848080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152506146fb92505050565b905060008161ffff1611801561333b575060648161ffff16105b61338c576040805162461bcd60e51b815260206004820152601e60248201527f696e76616c69642063616e63656c207472616e736665722071756f72756d0000604482015290519081900360640190fd5b604080517710d05390d15317d514905394d1915497d41493d413d4d05360421b815281519081900360180190206000908152600d60205220805461ffff90921661ffff1990921691909117905561341b565b6040805162461bcd60e51b815260206004820152600d60248201526c756e6b6e6f776e20706172616d60981b604482015290519081900360640190fd5b7f6cdb0ac70ab7f2e2d035cca5be60d89906f2dede7648ddbd7402189c1eeed17a848484846040518080602001806020018381038352878782818152602001925080828437600083820152601f01601f191690910184810383528581526020019050858580828437600083820152604051601f909101601f19169092018290039850909650505050505050a150505050565b6008602052600090815260409020546001600160401b031681565b7fc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a47081565b61100281565b60005460ff16613537576040805162461bcd60e51b815260206004820152601960248201526000805160206149b4833981519152604482015290519081900360640190fd5b6040805163569e4ed360e11b815233600482015290516000916110009163ad3c9da691602480820192602092909190829003018186803b15801561357a57600080fd5b505afa15801561358e573d6000803e3d6000fd5b505050506040513d60208110156135a457600080fd5b505160408051633d42651560e11b8152905191925060009161100091637a84ca2a916004808301926020929190829003018186803b1580156135e557600080fd5b505afa1580156135f9573d6000803e3d6000fd5b505050506040513d602081101561360f57600080fd5b505190508061361c575060155b60008211801561362c5750808211155b61366b576040805162461bcd60e51b815260206004820152600b60248201526a1b9bdd0818d8589a5b995d60aa1b604482015290519081900360640190fd5b600b5460ff166136b2576040805162461bcd60e51b815260206004820152600d60248201526c1b9bdd081cdd5cdc195b991959609a1b604482015290519081900360640190fd5b604080516e149153d4115397d41493d413d4d053608a1b8152905190819003600f019020600090613703907fc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a4706140e4565b9050801561374157600b805460ff1916905560405133907f899fe8c37dc61708a3aaa99c4bf143346c1d1da69af79be9e8920c0a6785b75290600090a25b505050565b600660209081526000928352604080842090915290825290205460ff1681565b6040518060400160405280600381526020016269626360e81b81525081565b610e1081565b61100381565b60005460ff16156137e9576040805162461bcd60e51b815260206004820152601960248201527f74686520636f6e747261637420616c726561647920696e697400000000000000604482015290519081900360640190fd5b7f1471eb6eb2c5e789fc3de43f8ce62938c7d1836ec861730447e2ada8fd81017b80546001600160a01b0319908116611008179091557f92e85d02570a8092d09a6e3a57665bc3815a2699a4074001bf1ccabf660f5a36805460ff199081169091557fd8af288fc1c8680b4f4706064cf021e264efb6828fcaf7eb5ca36818eb365bcc8054821660019081179091557f89832631fb3c3307a103ba2c84ab569c64d6182a18893dcd163f0f1c2090733a805484166110049081179091557f6cde3cea4b3a3fb2488b2808bae7556f4a405e50f65e1794383bc026131b13c38054841690557f72e4efa1513b071517c6c74dba31b5934a81aa83cddd400e7081df5529c9943680548416831790557fa9bc9a3a348c357ba16b37005d7e6b3236198c0e939f4af8c5f19b8deeb8ebc08054851690911790557fc575c31fea594a6eb97c8e9d3f9caee4c16218c6ef37e923234c0fe9014a61e78054831690557f4e523af77f034e9810f1c94057f5e931fb3d16a51511a4c3add793617d18610580548316821790557ffb33122aa9f93cc639ebe80a7bc4784c11e6053dde89c6f4f7e268c6a623da1e805484166110001790557fc7694af312c4f286114180fd0ba6a52461fcee8a381636770b19a343af92538a80548316821790557f01112dd68e482ba8d68a7e828cff8b3abcea08eab88941953c180a7e650e9cd480548316821790557fc0a4a8be475dfebc377ebef2d7c4ff47656f572a08dd92b81017efcdba0febe1805484166110071790557f87e8a52529e8ece4ef759037313542a6429ff494a9fab9027fb79db90124eba680548316821790557f4c7666bbcb22d46469f7cc282f70764a7012dca2cce630ff8d83db9a9cdd48f080548316821790557f40f28f99a40bc9f6beea1013afdbc3cdcc689eb76b82c4de06c0acf1e1932ed58054909316611001179092557f0d9cf2cd531699eed8dd34e40ff2884a14a698c4898184fba85194e6f6772d248054821683179055600b60009081527f23f68c9bd22b8a93d06adabe17481c87c016bcbd20adc8bfd707a4d813a572176020527fdf0d5d05428057f5455c2dc8e810dd86d1e9350faa72f16bda8a45443c5b39328054831684179055603283556004805467ffffffffffffffff19166001600160401b031790556002819055600381905580549091169091179055565b6007602052600090815260409020546001600160401b031681565b60005460ff16613ba8576040805162461bcd60e51b815260206004820152601960248201526000805160206149b4833981519152604482015290519081900360640190fd5b6040805163569e4ed360e11b815233600482015290516000916110009163ad3c9da691602480820192602092909190829003018186803b158015613beb57600080fd5b505afa158015613bff573d6000803e3d6000fd5b505050506040513d6020811015613c1557600080fd5b505160408051633d42651560e11b8152905191925060009161100091637a84ca2a916004808301926020929190829003018186803b158015613c5657600080fd5b505afa158015613c6a573d6000803e3d6000fd5b505050506040513d6020811015613c8057600080fd5b5051905080613c8d575060155b600082118015613c9d5750808211155b613cdc576040805162461bcd60e51b815260206004820152600b60248201526a1b9bdd0818d8589a5b995d60aa1b604482015290519081900360640190fd5b600b5460ff1615613d20576040805162461bcd60e51b81526020600482015260096024820152681cdd5cdc195b99195960ba1b604482015290519081900360640190fd5b604080516f14d554d411539117d41493d413d4d05360821b81529051908190036010019020600090613d72907fc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a4706140e4565b905080156137415761374161401b565b60005460ff16613dc7576040805162461bcd60e51b815260206004820152601960248201526000805160206149b4833981519152604482015290519081900360640190fd5b33600090815260066020908152604080832060ff8089168552925290912054859116613e245760405162461bcd60e51b81526004018080602001828103825260318152602001806147f26031913960400191505060405180910390fd5b60ff85166000908152600760209081526040808320548151601f88018490048402810184019092528682526001600160401b031692613e899284928a9261208e92909189918c908c908190840183828082843760009201919091525061131c92505050565b60ff959095166000908152600760205260409020805467ffffffffffffffff191660019096016001600160401b03169590951790945550505050565b61100081565b600381565b61100481565b60408051600e808252818301909252606091630102ca0060ff851617918391602082018180368337505050600e81810187905260068201939093529182525090505b92915050565b600085613f2d57506000614012565b606082518451865160800101016040519080825280601f01601f191660200182016040528015613f64576020820181803683370190505b5090506000613f7282614706565b602080890151825201905086600080613f8a89614099565b8086526020909501949092509050613fa38285836140a3565b92830192613fb088614099565b8086526020909501949092509050613fc98285836140a3565b9283018a815260200192613fdc87614099565b9092509050613fec8285836140a3565b508351602001613ffa61470c565b60208183886065600019fa5051600114955050505050505b95945050505050565b600b5460ff161561405f576040805162461bcd60e51b81526020600482015260096024820152681cdd5cdc195b99195960ba1b604482015290519081900360640190fd5b600b805460ff1916600117905560405133907f6f123d3d54c84a7960a573b31c221dcd86e13fd849c5adb0c6ca851468cc1ae490600090a2565b8051602090910191565b5b602081106140c3578251825260209283019290910190601f19016140a4565b915181516020939093036101000a6000190180199091169216919091179052565b6000828152600d602052604081205461ffff166141ad57604080516f14d554d411539117d41493d413d4d05360821b815281519081900360100181206000908152600d6020818152848320805461ffff199081166001179091556e149153d4115397d41493d413d4d053608a1b8552855194859003600f01852084528282528584208054821660029081179091557710d05390d15317d514905394d1915497d41493d413d4d05360421b8652865195869003601801909520845291905292902080549092161790555b6000838152600c6020526040902080546201000090046001600160801b0316421015806141de575082816001015414155b156142b1576000848152600d602090815260409182902054835461ffff90911661ffff199091161771ffffffffffffffffffffffffffffffff0000191662010000610e1042016001600160801b031602178355600180840186905582519182019092523381526142539160028401919061472a565b5080546040805161ffff83168152620100009092046001600160801b0316602083015281810185905251339186917f9e109f0e55ef32e99e4880be2ec357f1ddb3469c79d0747ef4762da6e89fabe5916060908290030190a3614365565b60005b600282015481101561433c57336001600160a01b03168260020182815481106142d957fe5b6000918252602090912001546001600160a01b03161415614334576040805162461bcd60e51b815260206004820152601060248201526f185b1c9958591e48185c1c1c9bdd995960821b604482015290519081900360640190fd5b6001016142b4565b50600281018054600181018255600091825260209091200180546001600160a01b031916331790555b8054600282015461ffff909116116143bf576000848152600c60205260408120805471ffffffffffffffffffffffffffffffffffff1916815560018101829055906143b3600283018261478f565b50506001915050613f18565b5060009392505050565b600080600060606021855110156143f9575050604080516000808252602082019092529092508291508190614472565b600185015160218601518651604080516020198301808252601f1960011990940193909316810160200190915260418901939291606091908015614444576020820181803683370190505b509050600061445282614099565b509050614464858260218d51036140a3565b506001975091955093509150505b9193509193565b600b5460ff16156144bd576040805162461bcd60e51b81526020600482015260096024820152681cdd5cdc195b99195960ba1b604482015290519081900360640190fd5b6002544311156144fc576004805467ffffffffffffffff1981166001600160401b036001600793840b810190930b16179091556003554360025561453d565b6003805460019081019182905554101561453d576004805467ffffffffffffffff1981166001600160401b036001600793840b810190930b16179091556003555b8160ff16836001600160401b0316600460009054906101000a900460070b6001600160401b03167f3a6e0fc61675aa2a100bcba0568368bb92bcec91c97673391074f11138f0cffe6102ca85604051808361ffff1661ffff16815260200180602001828103825283818151815260200191508051906020019080838360005b838110156145d45781810151838201526020016145bc565b50505050905090810190601f1680156146015780820380516001836020036101000a031916815260200191505b50935050505060405180910390a4505050565b6000816040516020018082805190602001908083835b602083106146495780518252601f19909201916020918201910161462a565b6001836020036101000a03801982511681845116808217855250505050505090500191505060405160208183030381529060405280519060200120836040516020018082805190602001908083835b602083106146b75780518252601f199092019160209182019101614698565b6001836020036101000a0380198251168184511680821785525050505050509050019150506040516020818303038152906040528051906020012014905092915050565b015190565b3b151590565b60200190565b60405180602001604052806001906020820280368337509192915050565b82805482825590600052602060002090810192821561477f579160200282015b8281111561477f57825182546001600160a01b0319166001600160a01b0390911617825560209092019160019091019061474a565b5061478b9291506147b0565b5090565b50805460008255906000526020600020908101906147ad91906147d7565b50565b6147d491905b8082111561478b5780546001600160a01b03191681556001016147b6565b90565b6147d491905b8082111561478b57600081556001016147dd56fe74686520636f6e747261637420616e64206368616e6e656c2068617665206e6f74206265656e20726567697374657265646c656e677468206f662076616c756520666f72206164644f725570646174654368616e6e656c2073686f756c642062652032322c206368616e6e656c49643a697346726f6d53797374656d3a68616e646c6572416464726573736c656e677468206f662076616c756520666f722063616e63656c5472616e7366657251756f72756d2073686f756c6420626520326c656e677468206f662076616c756520666f722073757370656e6451756f72756d2073686f756c6420626520326c656e677468206f662076616c756520666f722072656f70656e51756f72756d2073686f756c642062652032746865206d6573736167652073656e646572206d75737420626520676f7665726e616e636520636f6e74726163746c656e677468206f662076616c756520666f7220656e61626c654f7244697361626c654368616e6e656c2073686f756c6420626520322c206368616e6e656c49643a6973456e61626c65746865206e6577426174636853697a65466f724f7261636c652073686f756c6420626520696e205b31302c2031303030305d74686520636f6e7472616374206e6f7420696e697420796574000000000000006c6967687420636c69656e74206e6f742073796e632074686520626c6f636b20796574a264697066735822122020f10a3f6af250b9c5c16c5020f1b83db8bc64ed4363d8712e2b85f20f56251164736f6c63430006040033", + }, + }, + } } func UpgradeBuildInSystemContract(config *chain.Config, blockNumber *big.Int, statedb *state.IntraBlockState) { @@ -539,6 +704,10 @@ func UpgradeBuildInSystemContract(config *chain.Config, blockNumber *big.Int, st applySystemContractUpgrade(MoranUpgrade[config.ChainName], blockNumber, statedb, logger) } + if config.IsOnPlanck(blockNumber) { + applySystemContractUpgrade(PlanckUpgrade[config.ChainName], blockNumber, statedb, logger) + } + if config.IsOnGibbs(blockNumber) { applySystemContractUpgrade(GibbsUpgrade[config.ChainName], blockNumber, statedb, logger) } @@ -547,6 +716,10 @@ func UpgradeBuildInSystemContract(config *chain.Config, blockNumber *big.Int, st applySystemContractUpgrade(CalcuttaUpgrade[config.ChainName], blockNumber, statedb, logger) } + if config.IsOnLuban(blockNumber) { + applySystemContractUpgrade(LubanUpgrade[config.ChainName], blockNumber, statedb, logger) + } + /* apply other upgrades */ diff --git a/core/types/accounts/account_proof.go b/core/types/accounts/account_proof.go new file mode 100644 index 00000000000..7653445d1d1 --- /dev/null +++ b/core/types/accounts/account_proof.go @@ -0,0 +1,24 @@ +package accounts + +import ( + libcommon "github.com/ledgerwatch/erigon-lib/common" + "github.com/ledgerwatch/erigon-lib/common/hexutility" + + "github.com/ledgerwatch/erigon/common/hexutil" +) + +// Result structs for GetProof +type AccProofResult struct { + Address libcommon.Address `json:"address"` + AccountProof []hexutility.Bytes `json:"accountProof"` + Balance *hexutil.Big `json:"balance"` + CodeHash libcommon.Hash `json:"codeHash"` + Nonce hexutil.Uint64 `json:"nonce"` + StorageHash libcommon.Hash `json:"storageHash"` + StorageProof []StorProofResult `json:"storageProof"` +} +type StorProofResult struct { + Key libcommon.Hash `json:"key"` + Value *hexutil.Big `json:"value"` + Proof []hexutility.Bytes `json:"proof"` +} diff --git a/core/types/blob_tx_wrapper.go b/core/types/blob_tx_wrapper.go new file mode 100644 index 00000000000..fe036c683b3 --- /dev/null +++ b/core/types/blob_tx_wrapper.go @@ -0,0 +1,439 @@ +package types + +import ( + "bytes" + "encoding/hex" + "errors" + "fmt" + "io" + "math/big" + "time" + + "github.com/holiman/uint256" + "github.com/ledgerwatch/erigon-lib/chain" + libcommon "github.com/ledgerwatch/erigon-lib/common" + "github.com/ledgerwatch/erigon-lib/common/hexutility" + types2 "github.com/ledgerwatch/erigon-lib/types" + + gokzg4844 "github.com/crate-crypto/go-kzg-4844" + "github.com/protolambda/ztyp/codec" + + "github.com/ledgerwatch/erigon/crypto/kzg" + "github.com/ledgerwatch/erigon/params" + "github.com/ledgerwatch/erigon/rlp" +) + +// Compressed BLS12-381 G1 element +type KZGCommitment [48]byte + +func (p *KZGCommitment) Deserialize(dr *codec.DecodingReader) error { + if p == nil { + return errors.New("nil pubkey") + } + _, err := dr.Read(p[:]) + return err +} + +func (p *KZGCommitment) Serialize(w *codec.EncodingWriter) error { + return w.Write(p[:]) +} + +func (KZGCommitment) ByteLength() uint64 { + return 48 +} + +func (KZGCommitment) FixedLength() uint64 { + return 48 +} + +func (p KZGCommitment) MarshalText() ([]byte, error) { + return []byte("0x" + hex.EncodeToString(p[:])), nil +} + +func (p KZGCommitment) String() string { + return "0x" + hex.EncodeToString(p[:]) +} + +func (p *KZGCommitment) UnmarshalText(text []byte) error { + return hexutility.UnmarshalFixedText("KZGCommitment", text, p[:]) +} + +func (c KZGCommitment) ComputeVersionedHash() libcommon.Hash { + return libcommon.Hash(kzg.KZGToVersionedHash(gokzg4844.KZGCommitment(c))) +} + +// Compressed BLS12-381 G1 element +type KZGProof [48]byte + +func (p *KZGProof) Deserialize(dr *codec.DecodingReader) error { + if p == nil { + return errors.New("nil pubkey") + } + _, err := dr.Read(p[:]) + return err +} + +func (p *KZGProof) Serialize(w *codec.EncodingWriter) error { + return w.Write(p[:]) +} + +func (KZGProof) ByteLength() uint64 { + return 48 +} + +func (KZGProof) FixedLength() uint64 { + return 48 +} + +func (p KZGProof) MarshalText() ([]byte, error) { + return []byte("0x" + hex.EncodeToString(p[:])), nil +} + +func (p KZGProof) String() string { + return "0x" + hex.EncodeToString(p[:]) +} + +func (p *KZGProof) UnmarshalText(text []byte) error { + return hexutility.UnmarshalFixedText("KZGProof", text, p[:]) +} + +// BLSFieldElement is the raw bytes representation of a field element +type BLSFieldElement [32]byte + +func (p BLSFieldElement) MarshalText() ([]byte, error) { + return []byte("0x" + hex.EncodeToString(p[:])), nil +} + +func (p BLSFieldElement) String() string { + return "0x" + hex.EncodeToString(p[:]) +} + +func (p *BLSFieldElement) UnmarshalText(text []byte) error { + return hexutility.UnmarshalFixedText("BLSFieldElement", text, p[:]) +} + +// Blob data +type Blob [params.FieldElementsPerBlob * 32]byte + +func (blob *Blob) Deserialize(dr *codec.DecodingReader) error { + if blob == nil { + return errors.New("cannot decode ssz into nil Blob") + } + + // We treat the blob as an opaque sequence of bytes + // and therefore we do not do any validation related to field + // elements + if _, err := dr.Read(blob[:]); err != nil { + return err + } + + return nil +} + +func (blob *Blob) Serialize(w *codec.EncodingWriter) error { + return w.Write(blob[:]) +} + +func (blob *Blob) ByteLength() (out uint64) { + return params.FieldElementsPerBlob * 32 +} + +func (blob *Blob) FixedLength() uint64 { + return params.FieldElementsPerBlob * 32 +} + +func (blob *Blob) MarshalText() ([]byte, error) { + out := make([]byte, 2+params.FieldElementsPerBlob*32*2) + copy(out[:2], "0x") + hex.Encode(out[2:], blob[:]) + + return out, nil +} + +func (blob *Blob) String() string { + v, err := blob.MarshalText() + if err != nil { + return "" + } + return string(v) +} + +func (blob *Blob) UnmarshalText(text []byte) error { + if blob == nil { + return errors.New("cannot decode text into nil Blob") + } + l := 2 + params.FieldElementsPerBlob*32*2 + if len(text) != l { + return fmt.Errorf("expected %d characters but got %d", l, len(text)) + } + if !(text[0] == '0' && text[1] == 'x') { + return fmt.Errorf("expected '0x' prefix in Blob string") + } + if _, err := hex.Decode(blob[:], text[2:]); err != nil { + return fmt.Errorf("blob is not formatted correctly: %v", err) + } + + return nil +} + +type BlobKzgs []KZGCommitment + +func (li *BlobKzgs) Deserialize(dr *codec.DecodingReader) error { + return dr.List(func() codec.Deserializable { + i := len(*li) + *li = append(*li, KZGCommitment{}) + return &(*li)[i] + }, 48, params.MaxBlobsPerBlock) +} + +func (li BlobKzgs) Serialize(w *codec.EncodingWriter) error { + return w.List(func(i uint64) codec.Serializable { + return &li[i] + }, 48, uint64(len(li))) +} + +func (li BlobKzgs) ByteLength() uint64 { + return uint64(len(li)) * 48 +} + +func (li BlobKzgs) FixedLength() uint64 { + return 0 +} + +func (li BlobKzgs) copy() BlobKzgs { + cpy := make(BlobKzgs, len(li)) + copy(cpy, li) + return cpy +} + +type KZGProofs []KZGProof + +func (li *KZGProofs) Deserialize(dr *codec.DecodingReader) error { + return dr.List(func() codec.Deserializable { + i := len(*li) + *li = append(*li, KZGProof{}) + return &(*li)[i] + }, 48, params.MaxBlobsPerBlock) +} + +func (li KZGProofs) Serialize(w *codec.EncodingWriter) error { + return w.List(func(i uint64) codec.Serializable { + return &li[i] + }, 48, uint64(len(li))) +} + +func (li KZGProofs) ByteLength() uint64 { + return uint64(len(li)) * 48 +} + +func (li KZGProofs) FixedLength() uint64 { + return 0 +} + +func (li KZGProofs) copy() KZGProofs { + cpy := make(KZGProofs, len(li)) + copy(cpy, li) + return cpy +} + +type Blobs []Blob + +func (a *Blobs) Deserialize(dr *codec.DecodingReader) error { + return dr.List(func() codec.Deserializable { + i := len(*a) + *a = append(*a, Blob{}) + return &(*a)[i] + }, params.FieldElementsPerBlob*32, params.FieldElementsPerBlob) +} + +func (a Blobs) Serialize(w *codec.EncodingWriter) error { + return w.List(func(i uint64) codec.Serializable { + return &a[i] + }, params.FieldElementsPerBlob*32, uint64(len(a))) +} + +func (a Blobs) ByteLength() (out uint64) { + return uint64(len(a)) * params.FieldElementsPerBlob * 32 +} + +func (a *Blobs) FixedLength() uint64 { + return 0 // it's a list, no fixed length +} + +func (blobs Blobs) copy() Blobs { + cpy := make(Blobs, len(blobs)) + copy(cpy, blobs) // each blob element is an array and gets deep-copied + return cpy +} + +// Return KZG commitments, versioned hashes and the proofs that correspond to these blobs +func (blobs Blobs) ComputeCommitmentsAndProofs() (commitments []KZGCommitment, versionedHashes []libcommon.Hash, proofs []KZGProof, err error) { + commitments = make([]KZGCommitment, len(blobs)) + proofs = make([]KZGProof, len(blobs)) + versionedHashes = make([]libcommon.Hash, len(blobs)) + + cryptoCtx := kzg.CrpytoCtx() + for i, blob := range blobs { + commitment, err := cryptoCtx.BlobToKZGCommitment(gokzg4844.Blob(blob)) + if err != nil { + return nil, nil, nil, fmt.Errorf("could not convert blob to commitment: %v", err) + } + + proof, err := cryptoCtx.ComputeBlobKZGProof(gokzg4844.Blob(blob), commitment) + if err != nil { + return nil, nil, nil, fmt.Errorf("could not compute proof for blob: %v", err) + } + commitments[i] = KZGCommitment(commitment) + proofs[i] = KZGProof(proof) + versionedHashes[i] = libcommon.Hash(kzg.KZGToVersionedHash(commitment)) + } + + return commitments, versionedHashes, proofs, nil +} + +func toBlobs(_blobs Blobs) []gokzg4844.Blob { + blobs := make([]gokzg4844.Blob, len(_blobs)) + for i, _blob := range _blobs { + blobs[i] = gokzg4844.Blob(_blob) + } + return blobs +} +func toComms(_comms BlobKzgs) []gokzg4844.KZGCommitment { + comms := make([]gokzg4844.KZGCommitment, len(_comms)) + for i, _comm := range _comms { + comms[i] = gokzg4844.KZGCommitment(_comm) + } + return comms +} +func toProofs(_proofs KZGProofs) []gokzg4844.KZGProof { + proofs := make([]gokzg4844.KZGProof, len(_proofs)) + for i, _proof := range _proofs { + proofs[i] = gokzg4844.KZGProof(_proof) + } + return proofs +} + +// BlobTxWrapper is the "network representation" of a Blob transaction, that is it includes not +// only the SignedBlobTx but also all the associated blob data. +type BlobTxWrapper struct { + Tx SignedBlobTx + BlobKzgs BlobKzgs + Blobs Blobs + Proofs KZGProofs +} + +func (txw *BlobTxWrapper) Deserialize(dr *codec.DecodingReader) error { + return dr.Container(&txw.Tx, &txw.BlobKzgs, &txw.Blobs, &txw.Proofs) +} + +func (txw *BlobTxWrapper) Serialize(w *codec.EncodingWriter) error { + return w.Container(&txw.Tx, &txw.BlobKzgs, &txw.Blobs, &txw.Proofs) +} + +func (txw *BlobTxWrapper) ByteLength() uint64 { + return codec.ContainerLength(&txw.Tx, &txw.BlobKzgs, &txw.Blobs, &txw.Proofs) +} + +func (txw *BlobTxWrapper) FixedLength() uint64 { + return 0 +} + +// validateBlobTransactionWrapper implements validate_blob_transaction_wrapper from EIP-4844 +func (txw *BlobTxWrapper) ValidateBlobTransactionWrapper() error { + blobTx := txw.Tx.Message + l1 := len(blobTx.BlobVersionedHashes) + if l1 == 0 { + return fmt.Errorf("a blob tx must contain at least one blob") + } + l2 := len(txw.BlobKzgs) + l3 := len(txw.Blobs) + l4 := len(txw.Proofs) + if l1 != l2 || l2 != l3 || l1 != l4 { + return fmt.Errorf("lengths don't match %v %v %v %v", l1, l2, l3, l4) + } + // the following check isn't strictly necessary as it would be caught by data gas processing + // (and hence it is not explicitly in the spec for this function), but it doesn't hurt to fail + // early in case we are getting spammed with too many blobs or there is a bug somewhere: + if l1 > params.MaxBlobsPerBlock { + return fmt.Errorf("number of blobs exceeds max: %v", l1) + } + cryptoCtx := kzg.CrpytoCtx() + err := cryptoCtx.VerifyBlobKZGProofBatch(toBlobs(txw.Blobs), toComms(txw.BlobKzgs), toProofs(txw.Proofs)) + if err != nil { + return fmt.Errorf("error during proof verification: %v", err) + } + for i, h := range blobTx.BlobVersionedHashes { + if computed := txw.BlobKzgs[i].ComputeVersionedHash(); computed != h { + return fmt.Errorf("versioned hash %d supposedly %s but does not match computed %s", i, h, computed) + } + } + return nil +} + +// Implement transaction interface +func (txw *BlobTxWrapper) Type() byte { return txw.Tx.Type() } +func (txw *BlobTxWrapper) GetChainID() *uint256.Int { return txw.Tx.GetChainID() } +func (txw *BlobTxWrapper) GetNonce() uint64 { return txw.Tx.GetNonce() } +func (txw *BlobTxWrapper) GetPrice() *uint256.Int { return txw.Tx.GetPrice() } +func (txw *BlobTxWrapper) GetTip() *uint256.Int { return txw.Tx.GetTip() } +func (txw *BlobTxWrapper) GetEffectiveGasTip(baseFee *uint256.Int) *uint256.Int { + return txw.Tx.GetEffectiveGasTip(baseFee) +} +func (txw *BlobTxWrapper) GetFeeCap() *uint256.Int { return txw.Tx.GetFeeCap() } +func (txw *BlobTxWrapper) Cost() *uint256.Int { return txw.Tx.GetFeeCap() } +func (txw *BlobTxWrapper) GetDataHashes() []libcommon.Hash { return txw.Tx.GetDataHashes() } +func (txw *BlobTxWrapper) GetGas() uint64 { return txw.Tx.GetGas() } +func (txw *BlobTxWrapper) GetDataGas() uint64 { return txw.Tx.GetDataGas() } +func (txw *BlobTxWrapper) GetValue() *uint256.Int { return txw.Tx.GetValue() } +func (txw *BlobTxWrapper) Time() time.Time { return txw.Tx.Time() } +func (txw *BlobTxWrapper) GetTo() *libcommon.Address { return txw.Tx.GetTo() } +func (txw *BlobTxWrapper) AsMessage(s Signer, baseFee *big.Int, rules *chain.Rules) (Message, error) { + return txw.Tx.AsMessage(s, baseFee, rules) +} +func (txw *BlobTxWrapper) WithSignature(signer Signer, sig []byte) (Transaction, error) { + return txw.Tx.WithSignature(signer, sig) +} +func (txw *BlobTxWrapper) FakeSign(address libcommon.Address) (Transaction, error) { + return txw.Tx.FakeSign(address) +} +func (txw *BlobTxWrapper) Hash() libcommon.Hash { return txw.Tx.Hash() } +func (txw *BlobTxWrapper) SigningHash(chainID *big.Int) libcommon.Hash { + return txw.Tx.SigningHash(chainID) +} +func (txw *BlobTxWrapper) GetData() []byte { return txw.Tx.GetData() } +func (txw *BlobTxWrapper) GetAccessList() types2.AccessList { return txw.Tx.GetAccessList() } +func (txw *BlobTxWrapper) Protected() bool { return txw.Tx.Protected() } +func (txw *BlobTxWrapper) RawSignatureValues() (*uint256.Int, *uint256.Int, *uint256.Int) { + return txw.Tx.RawSignatureValues() +} +func (txw *BlobTxWrapper) Sender(s Signer) (libcommon.Address, error) { return txw.Tx.Sender(s) } +func (txw *BlobTxWrapper) GetSender() (libcommon.Address, bool) { return txw.Tx.GetSender() } +func (txw *BlobTxWrapper) SetSender(address libcommon.Address) { txw.Tx.SetSender(address) } +func (txw *BlobTxWrapper) IsContractDeploy() bool { return txw.Tx.IsContractDeploy() } +func (txw *BlobTxWrapper) Unwrap() Transaction { return &txw.Tx } + +func (txw BlobTxWrapper) EncodingSize() int { + envelopeSize := int(codec.ContainerLength(&txw.Tx, &txw.BlobKzgs, &txw.Blobs, &txw.Proofs)) + // Add type byte + envelopeSize++ + return envelopeSize +} + +func (txw *BlobTxWrapper) MarshalBinary(w io.Writer) error { + var b [33]byte + // encode TxType + b[0] = BlobTxType + if _, err := w.Write(b[:1]); err != nil { + return err + } + wcodec := codec.NewEncodingWriter(w) + return txw.Serialize(wcodec) +} + +func (txw BlobTxWrapper) EncodeRLP(w io.Writer) error { + var buf bytes.Buffer + if err := txw.MarshalBinary(&buf); err != nil { + return err + } + return rlp.Encode(w, buf.Bytes()) +} diff --git a/core/types/block.go b/core/types/block.go index 64c61a909b6..aea6a42ed3d 100644 --- a/core/types/block.go +++ b/core/types/block.go @@ -33,9 +33,6 @@ import ( "github.com/ledgerwatch/erigon-lib/common/hexutility" rlp2 "github.com/ledgerwatch/erigon-lib/rlp" - "github.com/ledgerwatch/erigon/cl/clparams" - "github.com/ledgerwatch/erigon/cl/cltypes/ssz_utils" - "github.com/ledgerwatch/erigon/cl/merkle_tree" "github.com/ledgerwatch/erigon/common" "github.com/ledgerwatch/erigon/common/hexutil" "github.com/ledgerwatch/erigon/rlp" @@ -65,7 +62,7 @@ func (n BlockNonce) Uint64() uint64 { // MarshalText encodes n as a hex string with 0x prefix. func (n BlockNonce) MarshalText() ([]byte, error) { - return hexutil.Bytes(n[:]).MarshalText() + return hexutility.Bytes(n[:]).MarshalText() } // UnmarshalText implements encoding.TextUnmarshaler. @@ -99,15 +96,24 @@ type Header struct { BaseFee *big.Int `json:"baseFeePerGas"` // EIP-1559 WithdrawalsHash *libcommon.Hash `json:"withdrawalsRoot"` // EIP-4895 + // ExcessDataGas was added by EIP-4844 and is ignored in legacy headers. + ExcessDataGas *big.Int `json:"excessDataGas"` // The verkle proof is ignored in legacy headers Verkle bool VerkleProof []byte VerkleKeyVals []verkle.KeyValuePair - // ETH2 fields - // This is the block hash given by the CL,we cannot validate in the context of the state. - BlockHashCL libcommon.Hash - TxHashSSZ libcommon.Hash // They decided to hash txs differently than EL :( +} + +// ParentExcessDataGas is a helper that returns the excess data gas value of the parent block. It +// returns nil if the parent header could not be fetched, or if the parent block's excess data gas +// is nil. +func (h *Header) ParentExcessDataGas(getHeader func(hash libcommon.Hash, number uint64) *Header) *big.Int { + p := getHeader(h.ParentHash, h.Number.Uint64()) + if p != nil { + return p.ExcessDataGas + } + return nil } func bitsToBytes(bitLen int) (byteLen int) { @@ -165,6 +171,11 @@ func (h *Header) EncodingSize() int { encodingSize += 33 } + if h.ExcessDataGas != nil { + encodingSize++ + encodingSize += rlp.BigIntLenExcludingHead(h.ExcessDataGas) + } + if h.Verkle { // Encoding of Verkle Proof encodingSize++ @@ -307,6 +318,12 @@ func (h *Header) EncodeRLP(w io.Writer) error { } } + if h.ExcessDataGas != nil { + if err := rlp.EncodeBigInt(h.ExcessDataGas, w, b[:]); err != nil { + return err + } + } + if h.Verkle { if err := rlp.EncodeString(h.VerkleProof, w, b[:]); err != nil { return err @@ -452,6 +469,19 @@ func (h *Header) DecodeRLP(s *rlp.Stream) error { h.WithdrawalsHash = new(libcommon.Hash) h.WithdrawalsHash.SetBytes(b) + // ExcessDataGas + if b, err = s.Uint256Bytes(); err != nil { + if errors.Is(err, rlp.EOL) { + h.ExcessDataGas = nil + if err := s.ListEnd(); err != nil { + return fmt.Errorf("close header struct (no ExcessDataGas): %w", err) + } + return nil + } + return fmt.Errorf("read ExcessDataGas: %w", err) + } + h.ExcessDataGas = new(big.Int).SetBytes(b) + if h.Verkle { if h.VerkleProof, err = s.Bytes(); err != nil { return fmt.Errorf("read VerkleProof: %w", err) @@ -471,14 +501,27 @@ func (h *Header) DecodeRLP(s *rlp.Stream) error { // field type overrides for gencodec type headerMarshaling struct { - Difficulty *hexutil.Big - Number *hexutil.Big - GasLimit hexutil.Uint64 - GasUsed hexutil.Uint64 - Time hexutil.Uint64 - Extra hexutil.Bytes - BaseFee *hexutil.Big - Hash libcommon.Hash `json:"hash"` // adds call to Hash() in MarshalJSON + Difficulty *hexutil.Big + Number *hexutil.Big + GasLimit hexutil.Uint64 + GasUsed hexutil.Uint64 + Time hexutil.Uint64 + Extra hexutility.Bytes + BaseFee *hexutil.Big + ExcessDataGas *hexutil.Big + Hash libcommon.Hash `json:"hash"` // adds call to Hash() in MarshalJSON +} + +// SetExcessDataGas sets the excess_data_gas field in the header +func (h *Header) SetExcessDataGas(v *big.Int) { + h.ExcessDataGas = new(big.Int) + if v != nil { + h.ExcessDataGas.Set(v) + } + if h.WithdrawalsHash == nil { + // leaving this nil would result in a buggy encoding + h.WithdrawalsHash = &EmptyRootHash + } } // Hash returns the block hash of the header, which is simply the keccak256 hash of its @@ -499,6 +542,9 @@ func (h *Header) Size() common.StorageSize { if h.WithdrawalsHash != nil { s += common.StorageSize(32) } + if h.ExcessDataGas != nil { + s += common.StorageSize(bitsToBytes(h.ExcessDataGas.BitLen())) + } return s } @@ -523,189 +569,15 @@ func (h *Header) SanityCheck() error { return fmt.Errorf("too large base fee: bitlen %d", bfLen) } } - return nil -} - -func (h *Header) EncodeHeaderMetadataForSSZ(dst []byte, extraDataOffset int) ([]byte, error) { - buf := dst - buf = append(buf, h.ParentHash[:]...) - buf = append(buf, h.Coinbase[:]...) - buf = append(buf, h.Root[:]...) - buf = append(buf, h.ReceiptHash[:]...) - buf = append(buf, h.Bloom[:]...) - buf = append(buf, h.MixDigest[:]...) - buf = append(buf, ssz_utils.Uint64SSZ(h.Number.Uint64())...) - buf = append(buf, ssz_utils.Uint64SSZ(h.GasLimit)...) - buf = append(buf, ssz_utils.Uint64SSZ(h.GasUsed)...) - buf = append(buf, ssz_utils.Uint64SSZ(h.Time)...) - buf = append(buf, ssz_utils.OffsetSSZ(uint32(extraDataOffset))...) - - // Add Base Fee - var baseFeeBytes32 [32]byte // Base fee is padded. - baseFeeBytes := h.BaseFee.Bytes() - for i, j := 0, len(baseFeeBytes)-1; i < j; i, j = i+1, j-1 { - baseFeeBytes[i], baseFeeBytes[j] = baseFeeBytes[j], baseFeeBytes[i] - } - copy(baseFeeBytes32[:], baseFeeBytes) - buf = append(buf, baseFeeBytes32[:]...) - buf = append(buf, h.BlockHashCL[:]...) - return buf, nil -} - -func (h *Header) EncodeSSZ(dst []byte) (buf []byte, err error) { - buf = dst - offset := ssz_utils.BaseExtraDataSSZOffsetHeader - - if h.WithdrawalsHash != nil { - offset += 32 - } - - buf, err = h.EncodeHeaderMetadataForSSZ(buf, offset) - if err != nil { - return nil, err - } - buf = append(buf, h.TxHashSSZ[:]...) - - if h.WithdrawalsHash != nil { - buf = append(buf, h.WithdrawalsHash[:]...) - } - - buf = append(buf, h.Extra...) - return -} - -// NOTE: it is skipping extra data -func (h *Header) DecodeHeaderMetadataForSSZ(buf []byte) (pos int, extraDataOffset int) { - h.UncleHash = EmptyUncleHash - h.Difficulty = libcommon.Big0 - - copy(h.ParentHash[:], buf) - pos = len(h.ParentHash) - - copy(h.Coinbase[:], buf[pos:]) - pos += len(h.Coinbase) - - copy(h.Root[:], buf[pos:]) - pos += len(h.Root) - - copy(h.ReceiptHash[:], buf[pos:]) - pos += len(h.ReceiptHash) - - h.Bloom.SetBytes(buf[pos : pos+BloomByteLength]) - pos += BloomByteLength - - copy(h.MixDigest[:], buf[pos:]) - pos += len(h.MixDigest) - - h.Number = new(big.Int).SetUint64(ssz_utils.UnmarshalUint64SSZ(buf[pos:])) - h.GasLimit = ssz_utils.UnmarshalUint64SSZ(buf[pos+8:]) - h.GasUsed = ssz_utils.UnmarshalUint64SSZ(buf[pos+16:]) - h.Time = ssz_utils.UnmarshalUint64SSZ(buf[pos+24:]) - pos += 32 - extraDataOffset = int(ssz_utils.DecodeOffset(buf[pos:])) - pos += 4 - // Add Base Fee - baseFeeBytes := common.CopyBytes(buf[pos : pos+32]) - for i, j := 0, len(baseFeeBytes)-1; i < j; i, j = i+1, j-1 { - baseFeeBytes[i], baseFeeBytes[j] = baseFeeBytes[j], baseFeeBytes[i] - } - h.BaseFee = new(big.Int).SetBytes(baseFeeBytes) - pos += 32 - copy(h.BlockHashCL[:], buf[pos:pos+32]) - pos += 32 - return -} - -func (h *Header) DecodeSSZ(buf []byte, version clparams.StateVersion) error { - if len(buf) < h.EncodingSizeSSZ(version) { - return ssz_utils.ErrLowBufferSize + if h.ExcessDataGas != nil { + if bfLen := h.ExcessDataGas.BitLen(); bfLen > 256 { + return fmt.Errorf("too large excess data gas: bitlen %d", bfLen) + } } - pos, _ := h.DecodeHeaderMetadataForSSZ(buf) - copy(h.TxHashSSZ[:], buf[pos:pos+32]) - pos += len(h.TxHashSSZ) - if version >= clparams.CapellaVersion { - h.WithdrawalsHash = new(libcommon.Hash) - copy((*h.WithdrawalsHash)[:], buf[pos:]) - pos += len(h.WithdrawalsHash) - } else { - h.WithdrawalsHash = nil - } - h.Extra = common.CopyBytes(buf[pos:]) return nil } -// EncodingSizeSSZ returns the ssz encoded size in bytes for the Header object -func (h *Header) EncodingSizeSSZ(version clparams.StateVersion) int { - size := 536 - - if h.WithdrawalsHash != nil || version >= clparams.CapellaVersion { - size += 32 - } - - return size + len(h.Extra) -} - -func (h *Header) HashSSZ() ([32]byte, error) { - // Compute coinbase leaf - var coinbase32 [32]byte - copy(coinbase32[:], h.Coinbase[:]) - // Compute Bloom leaf - bloomLeaf, err := merkle_tree.ArraysRoot([][32]byte{ - libcommon.BytesToHash(h.Bloom[:32]), - libcommon.BytesToHash(h.Bloom[32:64]), - libcommon.BytesToHash(h.Bloom[64:96]), - libcommon.BytesToHash(h.Bloom[96:128]), - libcommon.BytesToHash(h.Bloom[128:160]), - libcommon.BytesToHash(h.Bloom[160:192]), - libcommon.BytesToHash(h.Bloom[192:224]), - libcommon.BytesToHash(h.Bloom[224:]), - }, 8) - if err != nil { - return [32]byte{}, err - } - // Compute baseFee leaf - baseFeeBytes := h.BaseFee.Bytes() - for i, j := 0, len(baseFeeBytes)-1; i < j; i, j = i+1, j-1 { - baseFeeBytes[i], baseFeeBytes[j] = baseFeeBytes[j], baseFeeBytes[i] - } - var baseFeeLeaf libcommon.Hash - copy(baseFeeLeaf[:], baseFeeBytes) - // Compute extra data leaf - var extraLeaf libcommon.Hash - - var baseExtraLeaf [32]byte - copy(baseExtraLeaf[:], h.Extra) - - extraLeaf, err = merkle_tree.ArraysRoot([][32]byte{ - baseExtraLeaf, - merkle_tree.Uint64Root(uint64(len(h.Extra)))}, 2) - if err != nil { - return [32]byte{}, err - } - - leaves := [][32]byte{ - h.ParentHash, - coinbase32, - h.Root, - h.ReceiptHash, - bloomLeaf, - h.MixDigest, - merkle_tree.Uint64Root(h.Number.Uint64()), - merkle_tree.Uint64Root(h.GasLimit), - merkle_tree.Uint64Root(h.GasUsed), - merkle_tree.Uint64Root(h.Time), - extraLeaf, - baseFeeLeaf, - h.BlockHashCL, - h.TxHashSSZ, - } - if h.WithdrawalsHash != nil { - leaves = append(leaves, *h.WithdrawalsHash) - } - return merkle_tree.ArraysRoot(leaves, 16) -} - // Body is a simple (mutable, non-safe) data container for storing and moving // a block's data contents (transactions and uncles) together. type Body struct { @@ -1360,6 +1232,10 @@ func CopyHeader(h *Header) *Header { cpy.WithdrawalsHash = new(libcommon.Hash) cpy.WithdrawalsHash.SetBytes(h.WithdrawalsHash.Bytes()) } + if h.ExcessDataGas != nil { + cpy.ExcessDataGas = new(big.Int) + cpy.ExcessDataGas.Set(h.ExcessDataGas) + } return &cpy } @@ -1587,6 +1463,13 @@ func (b *Block) BaseFee() *big.Int { func (b *Block) WithdrawalsHash() *libcommon.Hash { return b.header.WithdrawalsHash } func (b *Block) Withdrawals() Withdrawals { return b.withdrawals } +func (b *Block) ExcessDataGas() *big.Int { + if b.header.ExcessDataGas == nil { + return nil + } + return new(big.Int).Set(b.header.ExcessDataGas) +} + // Header returns a deep-copy of the entire block header using CopyHeader() func (b *Block) Header() *Header { return CopyHeader(b.header) } func (b *Block) HeaderNoCopy() *Header { return b.header } diff --git a/core/types/bloom9.go b/core/types/bloom9.go index b0e499ad9dc..07ba1f9583b 100644 --- a/core/types/bloom9.go +++ b/core/types/bloom9.go @@ -23,7 +23,6 @@ import ( "github.com/ledgerwatch/erigon-lib/common/hexutility" - "github.com/ledgerwatch/erigon/common/hexutil" "github.com/ledgerwatch/erigon/crypto" "github.com/ledgerwatch/erigon/crypto/cryptopool" ) @@ -95,7 +94,7 @@ func (b Bloom) Test(topic []byte) bool { // MarshalText encodes b as a hex string with 0x prefix. func (b Bloom) MarshalText() ([]byte, error) { - return hexutil.Bytes(b[:]).MarshalText() + return hexutility.Bytes(b[:]).MarshalText() } // UnmarshalText b as a hex string with 0x prefix. diff --git a/core/types/gen_erigon_log_json.go b/core/types/gen_erigon_log_json.go index 5b800456c18..2360e2fdba0 100644 --- a/core/types/gen_erigon_log_json.go +++ b/core/types/gen_erigon_log_json.go @@ -7,6 +7,7 @@ import ( "errors" libcommon "github.com/ledgerwatch/erigon-lib/common" + "github.com/ledgerwatch/erigon-lib/common/hexutility" "github.com/ledgerwatch/erigon/common/hexutil" ) @@ -18,7 +19,7 @@ func (l ErigonLog) MarshalJSON() ([]byte, error) { type ErigonLog struct { Address libcommon.Address `json:"address" gencodec:"required"` Topics []libcommon.Hash `json:"topics" gencodec:"required"` - Data hexutil.Bytes `json:"data" gencodec:"required"` + Data hexutility.Bytes `json:"data" gencodec:"required"` BlockNumber hexutil.Uint64 `json:"blockNumber"` TxHash libcommon.Hash `json:"transactionHash" gencodec:"required"` TxIndex hexutil.Uint `json:"transactionIndex"` @@ -48,7 +49,7 @@ func (l *ErigonLog) UnmarshalJSON(input []byte) error { type ErigonLog struct { Address *libcommon.Address `json:"address" gencodec:"required"` Topics []libcommon.Hash `json:"topics" gencodec:"required"` - Data *hexutil.Bytes `json:"data" gencodec:"required"` + Data *hexutility.Bytes `json:"data" gencodec:"required"` BlockNumber *hexutil.Uint64 `json:"blockNumber"` TxHash *libcommon.Hash `json:"transactionHash" gencodec:"required"` TxIndex *hexutil.Uint `json:"transactionIndex"` diff --git a/core/types/gen_header_json.go b/core/types/gen_header_json.go index fb8194348e6..17b70798b48 100644 --- a/core/types/gen_header_json.go +++ b/core/types/gen_header_json.go @@ -8,6 +8,7 @@ import ( "math/big" libcommon "github.com/ledgerwatch/erigon-lib/common" + "github.com/ledgerwatch/erigon-lib/common/hexutility" "github.com/ledgerwatch/erigon/common/hexutil" ) @@ -29,7 +30,7 @@ func (h Header) MarshalJSON() ([]byte, error) { GasLimit hexutil.Uint64 `json:"gasLimit" gencodec:"required"` GasUsed hexutil.Uint64 `json:"gasUsed" gencodec:"required"` Time hexutil.Uint64 `json:"timestamp" gencodec:"required"` - Extra hexutil.Bytes `json:"extraData" gencodec:"required"` + Extra hexutility.Bytes `json:"extraData" gencodec:"required"` MixDigest libcommon.Hash `json:"mixHash"` Nonce BlockNonce `json:"nonce"` BaseFee *hexutil.Big `json:"baseFeePerGas"` @@ -73,7 +74,7 @@ func (h *Header) UnmarshalJSON(input []byte) error { GasLimit *hexutil.Uint64 `json:"gasLimit" gencodec:"required"` GasUsed *hexutil.Uint64 `json:"gasUsed" gencodec:"required"` Time *hexutil.Uint64 `json:"timestamp" gencodec:"required"` - Extra *hexutil.Bytes `json:"extraData" gencodec:"required"` + Extra *hexutility.Bytes `json:"extraData" gencodec:"required"` MixDigest *libcommon.Hash `json:"mixHash"` Nonce *BlockNonce `json:"nonce"` BaseFee *hexutil.Big `json:"baseFeePerGas"` diff --git a/core/types/gen_log_json.go b/core/types/gen_log_json.go index 6b61925936e..e3db5873dc4 100644 --- a/core/types/gen_log_json.go +++ b/core/types/gen_log_json.go @@ -7,6 +7,7 @@ import ( "errors" libcommon "github.com/ledgerwatch/erigon-lib/common" + "github.com/ledgerwatch/erigon-lib/common/hexutility" "github.com/ledgerwatch/erigon/common/hexutil" ) @@ -18,7 +19,7 @@ func (l Log) MarshalJSON() ([]byte, error) { type Log struct { Address libcommon.Address `json:"address" gencodec:"required"` Topics []libcommon.Hash `json:"topics" gencodec:"required"` - Data hexutil.Bytes `json:"data" gencodec:"required"` + Data hexutility.Bytes `json:"data" gencodec:"required"` BlockNumber hexutil.Uint64 `json:"blockNumber"` TxHash libcommon.Hash `json:"transactionHash" gencodec:"required"` TxIndex hexutil.Uint `json:"transactionIndex"` @@ -44,7 +45,7 @@ func (l *Log) UnmarshalJSON(input []byte) error { type Log struct { Address *libcommon.Address `json:"address" gencodec:"required"` Topics []libcommon.Hash `json:"topics" gencodec:"required"` - Data *hexutil.Bytes `json:"data" gencodec:"required"` + Data *hexutility.Bytes `json:"data" gencodec:"required"` BlockNumber *hexutil.Uint64 `json:"blockNumber"` TxHash *libcommon.Hash `json:"transactionHash" gencodec:"required"` TxIndex *hexutil.Uint `json:"transactionIndex"` diff --git a/core/types/gen_receipt_json.go b/core/types/gen_receipt_json.go index aae54fecc3b..8a898648386 100644 --- a/core/types/gen_receipt_json.go +++ b/core/types/gen_receipt_json.go @@ -8,6 +8,7 @@ import ( "math/big" libcommon "github.com/ledgerwatch/erigon-lib/common" + "github.com/ledgerwatch/erigon-lib/common/hexutility" "github.com/ledgerwatch/erigon/common/hexutil" ) @@ -18,7 +19,7 @@ var _ = (*receiptMarshaling)(nil) func (r Receipt) MarshalJSON() ([]byte, error) { type Receipt struct { Type hexutil.Uint64 `json:"type,omitempty"` - PostState hexutil.Bytes `json:"root"` + PostState hexutility.Bytes `json:"root"` Status hexutil.Uint64 `json:"status"` CumulativeGasUsed hexutil.Uint64 `json:"cumulativeGasUsed" gencodec:"required"` Bloom Bloom `json:"logsBloom" gencodec:"required"` @@ -50,7 +51,7 @@ func (r Receipt) MarshalJSON() ([]byte, error) { func (r *Receipt) UnmarshalJSON(input []byte) error { type Receipt struct { Type *hexutil.Uint64 `json:"type,omitempty"` - PostState *hexutil.Bytes `json:"root"` + PostState *hexutility.Bytes `json:"root"` Status *hexutil.Uint64 `json:"status"` CumulativeGasUsed *hexutil.Uint64 `json:"cumulativeGasUsed" gencodec:"required"` Bloom *Bloom `json:"logsBloom" gencodec:"required"` diff --git a/core/types/genesis.go b/core/types/genesis.go new file mode 100644 index 00000000000..8c2d800ae83 --- /dev/null +++ b/core/types/genesis.go @@ -0,0 +1,165 @@ +// Copyright 2014 The go-ethereum Authors +// This file is part of the go-ethereum library. +// +// The go-ethereum library is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// The go-ethereum library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with the go-ethereum library. If not, see . + +package types + +import ( + "bytes" + "encoding/hex" + "encoding/json" + "errors" + "fmt" + "math/big" + + "github.com/ledgerwatch/erigon-lib/chain" + "github.com/ledgerwatch/erigon-lib/common" + "github.com/ledgerwatch/erigon-lib/common/hexutility" + + common2 "github.com/ledgerwatch/erigon/common" + "github.com/ledgerwatch/erigon/common/math" + "github.com/ledgerwatch/erigon/params" +) + +//go:generate gencodec -type Genesis -field-override genesisSpecMarshaling -out gen_genesis.go +//go:generate gencodec -type GenesisAccount -field-override genesisAccountMarshaling -out gen_genesis_account.go + +var ErrGenesisNoConfig = errors.New("genesis has no chain configuration") + +// Genesis specifies the header fields, state of a genesis block. It also defines hard +// fork switch-over blocks through the chain configuration. +type Genesis struct { + Config *chain.Config `json:"config"` + Nonce uint64 `json:"nonce"` + Timestamp uint64 `json:"timestamp"` + ExtraData []byte `json:"extraData"` + GasLimit uint64 `json:"gasLimit" gencodec:"required"` + Difficulty *big.Int `json:"difficulty" gencodec:"required"` + Mixhash common.Hash `json:"mixHash"` + Coinbase common.Address `json:"coinbase"` + BaseFee *big.Int `json:"baseFeePerGas"` + ExcessDataGas *big.Int `json:"excessDataGas"` + Alloc GenesisAlloc `json:"alloc" gencodec:"required"` + AuRaStep uint64 `json:"auRaStep"` + AuRaSeal []byte `json:"auRaSeal"` + + // These fields are used for consensus tests. Please don't use them + // in actual genesis blocks. + Number uint64 `json:"number"` + GasUsed uint64 `json:"gasUsed"` + ParentHash common.Hash `json:"parentHash"` +} + +// GenesisAlloc specifies the initial state that is part of the genesis block. +type GenesisAlloc map[common.Address]GenesisAccount + +type AuthorityRoundSeal struct { + /// Seal step. + Step uint64 `json:"step"` + /// Seal signature. + Signature common.Hash `json:"signature"` +} + +func (ga *GenesisAlloc) UnmarshalJSON(data []byte) error { + m := make(map[common2.UnprefixedAddress]GenesisAccount) + if err := json.Unmarshal(data, &m); err != nil { + return err + } + *ga = make(GenesisAlloc) + for addr, a := range m { + (*ga)[common.Address(addr)] = a + } + return nil +} + +// GenesisAccount is an account in the state of the genesis block. +// Either use "constructor" for deployment code or "code" directly for the final code. +type GenesisAccount struct { + Constructor []byte `json:"constructor,omitempty"` // deployment code + Code []byte `json:"code,omitempty"` // final contract code + Storage map[common.Hash]common.Hash `json:"storage,omitempty"` + Balance *big.Int `json:"balance" gencodec:"required"` + Nonce uint64 `json:"nonce,omitempty"` + PrivateKey []byte `json:"secretKey,omitempty"` // for tests +} + +// field type overrides for gencodec +type genesisSpecMarshaling struct { + Nonce math.HexOrDecimal64 + Timestamp math.HexOrDecimal64 + ExtraData hexutility.Bytes + GasLimit math.HexOrDecimal64 + GasUsed math.HexOrDecimal64 + Number math.HexOrDecimal64 + Difficulty *math.HexOrDecimal256 + BaseFee *math.HexOrDecimal256 + ExcessDataGas *math.HexOrDecimal256 + Alloc map[common2.UnprefixedAddress]GenesisAccount +} + +type genesisAccountMarshaling struct { + Constructor hexutility.Bytes + Code hexutility.Bytes + Balance *math.HexOrDecimal256 + Nonce math.HexOrDecimal64 + Storage map[storageJSON]storageJSON + PrivateKey hexutility.Bytes +} + +// storageJSON represents a 256 bit byte array, but allows less than 256 bits when +// unmarshaling from hex. +type storageJSON common.Hash + +func (h *storageJSON) UnmarshalText(text []byte) error { + text = bytes.TrimPrefix(text, []byte("0x")) + if len(text) > 64 { + return fmt.Errorf("too many hex characters in storage key/value %q", text) + } + offset := len(h) - len(text)/2 // pad on the left + if _, err := hex.Decode(h[offset:], text); err != nil { + return fmt.Errorf("invalid hex storage key/value %q", text) + } + return nil +} + +func (h storageJSON) MarshalText() ([]byte, error) { + return hexutility.Bytes(h[:]).MarshalText() +} + +// GenesisMismatchError is raised when trying to overwrite an existing +// genesis block with an incompatible one. +type GenesisMismatchError struct { + Stored, New common.Hash +} + +func (e *GenesisMismatchError) Error() string { + config := params.ChainConfigByGenesisHash(e.Stored) + if config == nil { + return fmt.Sprintf("database contains incompatible genesis (have %x, new %x)", e.Stored, e.New) + } + return fmt.Sprintf("database contains incompatible genesis (try with --chain=%s)", config.ChainName) +} +func (g *Genesis) ConfigOrDefault(genesisHash common.Hash) *chain.Config { + if g != nil { + return g.Config + } + + config := params.ChainConfigByGenesisHash(genesisHash) + if config != nil { + return config + } else { + return params.AllProtocolChanges + } +} diff --git a/core/types/hashing.go b/core/types/hashing.go index d473c3c5f51..eb363872531 100644 --- a/core/types/hashing.go +++ b/core/types/hashing.go @@ -22,6 +22,7 @@ import ( "io" libcommon "github.com/ledgerwatch/erigon-lib/common" + "github.com/protolambda/ztyp/codec" "github.com/ledgerwatch/erigon/crypto" "github.com/ledgerwatch/erigon/crypto/cryptopool" @@ -190,3 +191,13 @@ func prefixedRlpHash(prefix byte, x interface{}) (h libcommon.Hash) { cryptopool.ReturnToPoolKeccak256(sha) return h } + +// prefixedSSZHash writes the prefix into the hasher before SSZ encoding x. It's used for +// computing the tx id & signing hashes of signed blob transactions. +func prefixedSSZHash(prefix byte, obj codec.Serializable) (h libcommon.Hash) { + sha := crypto.NewKeccakState() + sha.Write([]byte{prefix}) + EncodeSSZ(sha, obj) + sha.Read(h[:]) + return h +} diff --git a/core/types/log.go b/core/types/log.go index 892b8cf34a6..552300f49a6 100644 --- a/core/types/log.go +++ b/core/types/log.go @@ -20,6 +20,7 @@ import ( "io" libcommon "github.com/ledgerwatch/erigon-lib/common" + "github.com/ledgerwatch/erigon-lib/common/hexutility" "github.com/ledgerwatch/erigon/common/hexutil" "github.com/ledgerwatch/erigon/rlp" @@ -189,7 +190,7 @@ Logs: } type logMarshaling struct { - Data hexutil.Bytes + Data hexutility.Bytes BlockNumber hexutil.Uint64 TxIndex hexutil.Uint Index hexutil.Uint diff --git a/core/types/receipt.go b/core/types/receipt.go index 32092fbe236..a8605e5676e 100644 --- a/core/types/receipt.go +++ b/core/types/receipt.go @@ -24,6 +24,7 @@ import ( "math/big" libcommon "github.com/ledgerwatch/erigon-lib/common" + "github.com/ledgerwatch/erigon-lib/common/hexutility" "github.com/ledgerwatch/erigon/common/hexutil" "github.com/ledgerwatch/erigon/crypto" @@ -72,7 +73,7 @@ type Receipt struct { type receiptMarshaling struct { Type hexutil.Uint64 - PostState hexutil.Bytes + PostState hexutility.Bytes Status hexutil.Uint64 CumulativeGasUsed hexutil.Uint64 GasUsed hexutil.Uint64 diff --git a/core/types/signed_blob_tx.go b/core/types/signed_blob_tx.go new file mode 100644 index 00000000000..ca8354ecef9 --- /dev/null +++ b/core/types/signed_blob_tx.go @@ -0,0 +1,596 @@ +package types + +import ( + "bytes" + "encoding/hex" + "errors" + "fmt" + "io" + "math/big" + + "github.com/holiman/uint256" + "github.com/protolambda/ztyp/codec" + "github.com/protolambda/ztyp/conv" + . "github.com/protolambda/ztyp/view" + + "github.com/ledgerwatch/erigon-lib/chain" + libcommon "github.com/ledgerwatch/erigon-lib/common" + types2 "github.com/ledgerwatch/erigon-lib/types" + "github.com/ledgerwatch/erigon/common" + "github.com/ledgerwatch/erigon/common/u256" + "github.com/ledgerwatch/erigon/params" + "github.com/ledgerwatch/erigon/rlp" +) + +type ECDSASignature struct { + V Uint8View + R Uint256View + S Uint256View +} + +func (sig *ECDSASignature) GetV() *uint256.Int { + bytes := uint256.Int([4]uint64{uint64(sig.V), 0, 0, 0}) + return &bytes +} + +func (sig *ECDSASignature) GetR() *uint256.Int { + r := uint256.Int(sig.R) + return &r +} + +func (sig *ECDSASignature) GetS() *uint256.Int { + s := uint256.Int(sig.S) + return &s +} + +func (sig *ECDSASignature) Deserialize(dr *codec.DecodingReader) error { + return dr.FixedLenContainer(&sig.V, &sig.R, &sig.S) +} + +func (sig *ECDSASignature) Serialize(w *codec.EncodingWriter) error { + return w.FixedLenContainer(&sig.V, &sig.R, &sig.S) +} + +func (*ECDSASignature) ByteLength() uint64 { + return 1 + 32 + 32 +} + +func (*ECDSASignature) FixedLength() uint64 { + return 1 + 32 + 32 +} + +type AddressSSZ libcommon.Address + +func (addr *AddressSSZ) Deserialize(dr *codec.DecodingReader) error { + if addr == nil { + return errors.New("cannot deserialize into nil Address") + } + _, err := dr.Read(addr[:]) + return err +} + +func (addr *AddressSSZ) Serialize(w *codec.EncodingWriter) error { + return w.Write(addr[:]) +} + +func (*AddressSSZ) ByteLength() uint64 { + return 20 +} + +func (*AddressSSZ) FixedLength() uint64 { + return 20 +} + +// AddressOptionalSSZ implements Union[None, Address] +type AddressOptionalSSZ struct { + Address *AddressSSZ +} + +func (ao *AddressOptionalSSZ) Deserialize(dr *codec.DecodingReader) error { + if ao == nil { + return errors.New("cannot deserialize into nil Address") + } + if v, err := dr.ReadByte(); err != nil { + return err + } else if v == 0 { + ao.Address = nil + return nil + } else if v == 1 { + ao.Address = new(AddressSSZ) + if err := ao.Address.Deserialize(dr); err != nil { + return err + } + return nil + } else { + return fmt.Errorf("invalid union selector for Union[None, Address]: %d", v) + } +} + +func (ao *AddressOptionalSSZ) Serialize(w *codec.EncodingWriter) error { + if ao.Address == nil { + return w.WriteByte(0) + } else { + if err := w.WriteByte(1); err != nil { + return err + } + return ao.Address.Serialize(w) + } +} + +func (ao *AddressOptionalSSZ) ByteLength() uint64 { + if ao.Address == nil { + return 1 + } else { + return 1 + 20 + } +} + +func (*AddressOptionalSSZ) FixedLength() uint64 { + return 0 +} + +type TxDataView []byte + +func (tdv *TxDataView) Deserialize(dr *codec.DecodingReader) error { + return dr.ByteList((*[]byte)(tdv), MAX_CALLDATA_SIZE) +} + +func (tdv TxDataView) Serialize(w *codec.EncodingWriter) error { + return w.Write(tdv) +} + +func (tdv TxDataView) ByteLength() (out uint64) { + return uint64(len(tdv)) +} + +func (tdv *TxDataView) FixedLength() uint64 { + return 0 +} + +func (tdv TxDataView) MarshalText() ([]byte, error) { + return conv.BytesMarshalText(tdv[:]) +} + +func (tdv TxDataView) String() string { + return "0x" + hex.EncodeToString(tdv[:]) +} + +func (tdv *TxDataView) UnmarshalText(text []byte) error { + if tdv == nil { + return errors.New("cannot decode into nil blob data") + } + return conv.DynamicBytesUnmarshalText((*[]byte)(tdv), text) +} + +func ReadHashes(dr *codec.DecodingReader, hashes *[]libcommon.Hash, length uint64) error { + if uint64(len(*hashes)) != length { + // re-use space if available (for recycling old state objects) + if uint64(cap(*hashes)) >= length { + *hashes = (*hashes)[:length] + } else { + *hashes = make([]libcommon.Hash, length) + } + } else if *hashes == nil { + // make sure the output is never nil + *hashes = []libcommon.Hash{} + } + dst := *hashes + for i := uint64(0); i < length; i++ { + if _, err := dr.Read(dst[i][:]); err != nil { + return err + } + } + return nil +} + +func ReadHashesLimited(dr *codec.DecodingReader, hashes *[]libcommon.Hash, limit uint64) error { + scope := dr.Scope() + if scope%32 != 0 { + return fmt.Errorf("bad deserialization scope, cannot decode hashes list") + } + length := scope / 32 + if length > limit { + return fmt.Errorf("too many hashes: %d > %d", length, limit) + } + return ReadHashes(dr, hashes, length) +} + +func WriteHashes(ew *codec.EncodingWriter, hashes []libcommon.Hash) error { + for i := range hashes { + if err := ew.Write(hashes[i][:]); err != nil { + return err + } + } + return nil +} + +type VersionedHashesView []libcommon.Hash + +func (vhv *VersionedHashesView) Deserialize(dr *codec.DecodingReader) error { + return ReadHashesLimited(dr, (*[]libcommon.Hash)(vhv), MAX_VERSIONED_HASHES_LIST_SIZE) +} + +func (vhv VersionedHashesView) Serialize(w *codec.EncodingWriter) error { + return WriteHashes(w, vhv) +} + +func (vhv VersionedHashesView) ByteLength() (out uint64) { + return uint64(len(vhv)) * 32 +} + +func (vhv *VersionedHashesView) FixedLength() uint64 { + return 0 // it's a list, no fixed length +} + +type StorageKeysView []libcommon.Hash + +func (skv *StorageKeysView) Deserialize(dr *codec.DecodingReader) error { + return ReadHashesLimited(dr, (*[]libcommon.Hash)(skv), MAX_ACCESS_LIST_STORAGE_KEYS) +} + +func (skv StorageKeysView) Serialize(w *codec.EncodingWriter) error { + return WriteHashes(w, skv) +} + +func (skv StorageKeysView) ByteLength() (out uint64) { + return uint64(len(skv)) * 32 +} + +func (skv *StorageKeysView) FixedLength() uint64 { + return 0 // it's a list, no fixed length +} + +type AccessTupleView types2.AccessTuple + +func (atv *AccessTupleView) Deserialize(dr *codec.DecodingReader) error { + return dr.Container((*AddressSSZ)(&atv.Address), (*StorageKeysView)(&atv.StorageKeys)) +} + +func (atv *AccessTupleView) Serialize(w *codec.EncodingWriter) error { + return w.Container((*AddressSSZ)(&atv.Address), (*StorageKeysView)(&atv.StorageKeys)) +} + +func (atv *AccessTupleView) ByteLength() uint64 { + return codec.ContainerLength((*AddressSSZ)(&atv.Address), (*StorageKeysView)(&atv.StorageKeys)) +} + +func (atv *AccessTupleView) FixedLength() uint64 { + return 0 +} + +type AccessListView types2.AccessList + +func (alv *AccessListView) Deserialize(dr *codec.DecodingReader) error { + *alv = AccessListView([]types2.AccessTuple{}) + return dr.List(func() codec.Deserializable { + i := len(*alv) + *alv = append(*alv, types2.AccessTuple{}) + return (*AccessTupleView)(&((*alv)[i])) + }, 0, MAX_ACCESS_LIST_SIZE) +} + +func (alv AccessListView) Serialize(w *codec.EncodingWriter) error { + return w.List(func(i uint64) codec.Serializable { + return (*AccessTupleView)(&alv[i]) + }, 0, uint64(len(alv))) +} + +func (alv AccessListView) ByteLength() (out uint64) { + for idx := range alv { + out += (*AccessTupleView)(&alv[idx]).ByteLength() + codec.OFFSET_SIZE + } + return +} + +func (alv *AccessListView) FixedLength() uint64 { + return 0 +} + +type BlobTxMessage struct { + ChainID Uint256View + Nonce Uint64View + GasTipCap Uint256View // a.k.a. maxPriorityFeePerGas + GasFeeCap Uint256View // a.k.a. maxFeePerGas + Gas Uint64View + To AddressOptionalSSZ // nil means contract creation + Value Uint256View + Data TxDataView + AccessList AccessListView + MaxFeePerDataGas Uint256View + + BlobVersionedHashes VersionedHashesView +} + +func (tx *BlobTxMessage) Deserialize(dr *codec.DecodingReader) error { + err := dr.Container(&tx.ChainID, &tx.Nonce, &tx.GasTipCap, &tx.GasFeeCap, &tx.Gas, &tx.To, &tx.Value, &tx.Data, &tx.AccessList, &tx.MaxFeePerDataGas, &tx.BlobVersionedHashes) + return err +} + +func (tx *BlobTxMessage) Serialize(w *codec.EncodingWriter) error { + return w.Container(&tx.ChainID, &tx.Nonce, &tx.GasTipCap, &tx.GasFeeCap, &tx.Gas, &tx.To, &tx.Value, &tx.Data, &tx.AccessList, &tx.MaxFeePerDataGas, &tx.BlobVersionedHashes) +} + +func (tx *BlobTxMessage) ByteLength() uint64 { + return codec.ContainerLength(&tx.ChainID, &tx.Nonce, &tx.GasTipCap, &tx.GasFeeCap, &tx.Gas, &tx.To, &tx.Value, &tx.Data, &tx.AccessList, &tx.MaxFeePerDataGas, &tx.BlobVersionedHashes) +} + +func (tx *BlobTxMessage) FixedLength() uint64 { + return 0 +} + +// copy creates a deep copy of the transaction data and initializes all fields. +func (tx *BlobTxMessage) copy() *BlobTxMessage { + cpy := &BlobTxMessage{ + ChainID: tx.ChainID, + Nonce: tx.Nonce, + GasTipCap: tx.GasTipCap, + GasFeeCap: tx.GasFeeCap, + Gas: tx.Gas, + To: AddressOptionalSSZ{Address: (*AddressSSZ)(copyAddressPtr((*libcommon.Address)(tx.To.Address)))}, + Value: tx.Value, + Data: common.CopyBytes(tx.Data), + AccessList: make([]types2.AccessTuple, len(tx.AccessList)), + MaxFeePerDataGas: tx.MaxFeePerDataGas, + BlobVersionedHashes: make([]libcommon.Hash, len(tx.BlobVersionedHashes)), + } + copy(cpy.AccessList, tx.AccessList) + copy(cpy.BlobVersionedHashes, tx.BlobVersionedHashes) + + return cpy +} + +type SignedBlobTx struct { + TransactionMisc + + Message BlobTxMessage + Signature ECDSASignature +} + +var _ Transaction = &SignedBlobTx{} + +const ( + MAX_CALLDATA_SIZE = 1 << 24 + MAX_ACCESS_LIST_SIZE = 1 << 24 + MAX_ACCESS_LIST_STORAGE_KEYS = 1 << 24 + MAX_VERSIONED_HASHES_LIST_SIZE = 1 << 24 +) + +// copy creates a deep copy of the transaction data and initializes all fields. +func (stx SignedBlobTx) copy() *SignedBlobTx { + cpy := &SignedBlobTx{ + Message: *stx.Message.copy(), + Signature: stx.Signature, + } + + return cpy +} + +func (stx SignedBlobTx) Type() byte { return BlobTxType } + +func (stx SignedBlobTx) GetChainID() *uint256.Int { + chainID := uint256.Int(stx.Message.ChainID) + return &chainID +} + +func (stx SignedBlobTx) GetNonce() uint64 { return uint64(stx.Message.Nonce) } +func (stx SignedBlobTx) GetGas() uint64 { return uint64(stx.Message.Gas) } +func (stx SignedBlobTx) GetDataGas() uint64 { + return params.DataGasPerBlob * uint64(len(stx.Message.BlobVersionedHashes)) +} +func (stx SignedBlobTx) GetTo() *libcommon.Address { + return (*libcommon.Address)(stx.Message.To.Address) +} +func (stx SignedBlobTx) GetAmount() uint256.Int { return uint256.Int(stx.Message.Value) } +func (stx SignedBlobTx) GetData() []byte { return stx.Message.Data } +func (stx SignedBlobTx) GetValue() *uint256.Int { + value := uint256.Int(stx.Message.Value) + return &value +} + +func (stx SignedBlobTx) GetPrice() *uint256.Int { + tip := (uint256.Int)(stx.Message.GasTipCap) + return &tip +} +func (stx SignedBlobTx) GetFeeCap() *uint256.Int { + feeCap := (uint256.Int)(stx.Message.GasFeeCap) + return &feeCap +} + +func (stx *SignedBlobTx) GetTip() *uint256.Int { + tip := (uint256.Int)(stx.Message.GasTipCap) + return &tip +} + +func (stx *SignedBlobTx) GetEffectiveGasTip(baseFee *uint256.Int) *uint256.Int { + if baseFee == nil { + return stx.GetTip() + } + gasFeeCap := stx.GetFeeCap() + // return 0 because effectiveFee cant be < 0 + if gasFeeCap.Lt(baseFee) { + return uint256.NewInt(0) + } + effectiveFee := new(uint256.Int).Sub(gasFeeCap, baseFee) + if stx.GetTip().Lt(effectiveFee) { + return stx.GetTip() + } else { + return effectiveFee + } +} + +func (stx *SignedBlobTx) Cost() *uint256.Int { + total := new(uint256.Int).SetUint64(uint64(stx.Message.Gas)) + tip := uint256.Int(stx.Message.GasTipCap) + total.Mul(total, &tip) + + value := uint256.Int(stx.Message.Value) + total.Add(total, &value) + return total +} + +func (stx *SignedBlobTx) GetMaxFeePerDataGas() *uint256.Int { + fee := (uint256.Int)(stx.Message.MaxFeePerDataGas) + return &fee +} + +func (stx *SignedBlobTx) GetDataHashes() []libcommon.Hash { + return []libcommon.Hash(stx.Message.BlobVersionedHashes) +} + +// TODO +func (stx *SignedBlobTx) Sender(signer Signer) (libcommon.Address, error) { + if sc := stx.from.Load(); sc != nil { + return sc.(libcommon.Address), nil + } + + addr, err := signer.Sender(stx) + if err != nil { + return libcommon.Address{}, err + } + + stx.from.Store(addr) + return addr, nil +} + +func (stx *SignedBlobTx) GetSender() (libcommon.Address, bool) { + if sc := stx.from.Load(); sc != nil { + return sc.(libcommon.Address), true + } + return libcommon.Address{}, false +} + +func (stx *SignedBlobTx) SetSender(addr libcommon.Address) { + stx.from.Store(addr) +} + +func (stx *SignedBlobTx) IsContractDeploy() bool { + return stx.GetTo() == nil +} + +func (stx *SignedBlobTx) Unwrap() Transaction { + return stx +} + +func (stx SignedBlobTx) Protected() bool { + return true +} + +func (stx *SignedBlobTx) WithSignature(signer Signer, sig []byte) (Transaction, error) { + cpy := stx.copy() + r, s, v, err := signer.SignatureValues(stx, sig) + if err != nil { + return nil, err + } + + cpy.Signature.R = Uint256View(*r) + cpy.Signature.V = Uint8View([4]uint64(*v)[0]) + cpy.Signature.S = Uint256View(*s) + cpy.Message.ChainID = Uint256View(*signer.ChainID()) + return cpy, nil +} + +func (tx *SignedBlobTx) FakeSign(address libcommon.Address) (Transaction, error) { + cpy := tx.copy() + cpy.Signature.R = Uint256View(*u256.Num1) + cpy.Signature.S = Uint256View(*u256.Num1) + cpy.Signature.V = Uint8View([4]uint64(*u256.Num4)[0]) + + cpy.from.Store(address) + return cpy, nil +} + +func (tx *SignedBlobTx) GetAccessList() types2.AccessList { + return types2.AccessList(tx.Message.AccessList) +} + +func (stx SignedBlobTx) AsMessage(s Signer, baseFee *big.Int, rules *chain.Rules) (Message, error) { + msg := Message{ + nonce: stx.GetNonce(), + gasLimit: stx.GetGas(), + tip: *stx.GetTip(), + feeCap: *stx.GetFeeCap(), + to: stx.GetTo(), + amount: stx.GetAmount(), + data: stx.Message.Data, + accessList: stx.GetAccessList(), + maxFeePerDataGas: *stx.GetMaxFeePerDataGas(), + dataHashes: stx.GetDataHashes(), + checkNonce: true, + } + + if baseFee != nil { + overflow := msg.gasPrice.SetFromBig(baseFee) + if overflow { + return msg, fmt.Errorf("gasPrice higher than 2^256-1") + } + } + msg.gasPrice.Add(&msg.gasPrice, stx.GetTip()) + if msg.gasPrice.Gt(stx.GetFeeCap()) { + msg.gasPrice.Set(stx.GetFeeCap()) + } + + var err error + msg.from, err = stx.Sender(s) + return msg, err +} + +// Hash computes the hash (but not for signatures!) +func (stx *SignedBlobTx) Hash() libcommon.Hash { + return prefixedSSZHash(BlobTxType, stx) +} + +// MarshalBinary returns the canonical encoding of the transaction. +// For legacy transactions, it returns the RLP encoding. For EIP-2718 typed +// transactions, it returns the type and payload. +func (tx SignedBlobTx) MarshalBinary(w io.Writer) error { + var b [33]byte + // encode TxType + b[0] = BlobTxType + if _, err := w.Write(b[:1]); err != nil { + return err + } + wcodec := codec.NewEncodingWriter(w) + return tx.Serialize(wcodec) +} + +func (stx SignedBlobTx) EncodeRLP(w io.Writer) error { + var buf bytes.Buffer + if err := stx.MarshalBinary(&buf); err != nil { + return err + } + return rlp.Encode(w, buf.Bytes()) +} + +func (tx SignedBlobTx) RawSignatureValues() (v *uint256.Int, r *uint256.Int, s *uint256.Int) { + return tx.Signature.GetV(), tx.Signature.GetR(), tx.Signature.GetS() +} + +func (stx SignedBlobTx) SigningHash(chainID *big.Int) libcommon.Hash { + // stx is a shallow copy of the tx so we can modify ChainID without mutating the input + stx.Message.ChainID.SetFromBig(chainID) + return prefixedSSZHash(BlobTxType, &stx.Message) +} + +func (tx SignedBlobTx) EncodingSize() int { + envelopeSize := int(codec.ContainerLength(&tx.Message, &tx.Signature)) + // Add type byte + envelopeSize++ + return envelopeSize +} + +func (stx *SignedBlobTx) Deserialize(dr *codec.DecodingReader) error { + err := dr.Container(&stx.Message, &stx.Signature) + return err +} + +func (stx *SignedBlobTx) Serialize(w *codec.EncodingWriter) error { + return w.Container(&stx.Message, &stx.Signature) +} + +func (stx *SignedBlobTx) ByteLength() uint64 { + return codec.ContainerLength(&stx.Message, &stx.Signature) +} + +func (stx *SignedBlobTx) FixedLength() uint64 { + return 0 +} diff --git a/core/types/transaction.go b/core/types/transaction.go index 8df16bf4526..a556964d032 100644 --- a/core/types/transaction.go +++ b/core/types/transaction.go @@ -31,10 +31,12 @@ import ( libcommon "github.com/ledgerwatch/erigon-lib/common" types2 "github.com/ledgerwatch/erigon-lib/types" "github.com/ledgerwatch/log/v3" + "github.com/protolambda/ztyp/codec" "github.com/ledgerwatch/erigon/common" "github.com/ledgerwatch/erigon/common/math" "github.com/ledgerwatch/erigon/crypto" + "github.com/ledgerwatch/erigon/params" "github.com/ledgerwatch/erigon/rlp" ) @@ -50,6 +52,7 @@ const ( LegacyTxType = iota AccessListTxType DynamicFeeTxType + BlobTxType ) // Transaction is an Ethereum transaction. @@ -62,6 +65,7 @@ type Transaction interface { GetEffectiveGasTip(baseFee *uint256.Int) *uint256.Int GetFeeCap() *uint256.Int Cost() *uint256.Int + GetDataHashes() []libcommon.Hash GetGas() uint64 GetValue() *uint256.Int Time() time.Time @@ -453,21 +457,23 @@ func (t *TransactionsFixedOrder) Pop() { // Message is a fully derived transaction and implements core.Message type Message struct { - to *libcommon.Address - from libcommon.Address - nonce uint64 - amount uint256.Int - gasLimit uint64 - gasPrice uint256.Int - feeCap uint256.Int - tip uint256.Int - data []byte - accessList types2.AccessList - checkNonce bool - isFree bool -} - -func NewMessage(from libcommon.Address, to *libcommon.Address, nonce uint64, amount *uint256.Int, gasLimit uint64, gasPrice *uint256.Int, feeCap, tip *uint256.Int, data []byte, accessList types2.AccessList, checkNonce bool, isFree bool) Message { + to *libcommon.Address + from libcommon.Address + nonce uint64 + amount uint256.Int + gasLimit uint64 + gasPrice uint256.Int + feeCap uint256.Int + tip uint256.Int + maxFeePerDataGas uint256.Int + data []byte + accessList types2.AccessList + checkNonce bool + isFree bool + dataHashes []libcommon.Hash +} + +func NewMessage(from libcommon.Address, to *libcommon.Address, nonce uint64, amount *uint256.Int, gasLimit uint64, gasPrice *uint256.Int, feeCap, tip *uint256.Int, data []byte, accessList types2.AccessList, checkNonce bool, isFree bool, maxFeePerDataGas *uint256.Int) Message { m := Message{ from: from, to: to, @@ -488,6 +494,9 @@ func NewMessage(from libcommon.Address, to *libcommon.Address, nonce uint64, amo if feeCap != nil { m.feeCap.Set(feeCap) } + if maxFeePerDataGas != nil { + m.maxFeePerDataGas.Set(maxFeePerDataGas) + } return m } @@ -525,3 +534,28 @@ func (m *Message) ChangeGas(globalGasCap, desiredGas uint64) { m.gasLimit = gas } + +func (m Message) DataGas() uint64 { return params.DataGasPerBlob * uint64(len(m.dataHashes)) } +func (m Message) MaxFeePerDataGas() *uint256.Int { + return &m.maxFeePerDataGas +} + +func (m Message) DataHashes() []libcommon.Hash { return m.dataHashes } + +func DecodeSSZ(data []byte, dest codec.Deserializable) error { + err := dest.Deserialize(codec.NewDecodingReader(bytes.NewReader(data), uint64(len(data)))) + return err +} + +func EncodeSSZ(w io.Writer, obj codec.Serializable) error { + return obj.Serialize(codec.NewEncodingWriter(w)) +} + +// copyAddressPtr copies an address. +func copyAddressPtr(a *libcommon.Address) *libcommon.Address { + if a == nil { + return nil + } + cpy := *a + return &cpy +} diff --git a/core/types/transaction_marshalling.go b/core/types/transaction_marshalling.go index b1188293458..f66134f6fd4 100644 --- a/core/types/transaction_marshalling.go +++ b/core/types/transaction_marshalling.go @@ -6,9 +6,11 @@ import ( "fmt" "github.com/holiman/uint256" + "github.com/valyala/fastjson" + libcommon "github.com/ledgerwatch/erigon-lib/common" + "github.com/ledgerwatch/erigon-lib/common/hexutility" types2 "github.com/ledgerwatch/erigon-lib/types" - "github.com/valyala/fastjson" "github.com/ledgerwatch/erigon/common/hexutil" ) @@ -24,7 +26,7 @@ type txJSON struct { Tip *hexutil.Big `json:"maxPriorityFeePerGas"` Gas *hexutil.Uint64 `json:"gas"` Value *hexutil.Big `json:"value"` - Data *hexutil.Bytes `json:"input"` + Data *hexutility.Bytes `json:"input"` V *hexutil.Big `json:"v"` R *hexutil.Big `json:"r"` S *hexutil.Big `json:"s"` @@ -47,7 +49,7 @@ func (tx LegacyTx) MarshalJSON() ([]byte, error) { enc.Gas = (*hexutil.Uint64)(&tx.Gas) enc.GasPrice = (*hexutil.Big)(tx.GasPrice.ToBig()) enc.Value = (*hexutil.Big)(tx.Value.ToBig()) - enc.Data = (*hexutil.Bytes)(&tx.Data) + enc.Data = (*hexutility.Bytes)(&tx.Data) enc.To = tx.To enc.V = (*hexutil.Big)(tx.V.ToBig()) enc.R = (*hexutil.Big)(tx.R.ToBig()) @@ -66,7 +68,7 @@ func (tx AccessListTx) MarshalJSON() ([]byte, error) { enc.Gas = (*hexutil.Uint64)(&tx.Gas) enc.GasPrice = (*hexutil.Big)(tx.GasPrice.ToBig()) enc.Value = (*hexutil.Big)(tx.Value.ToBig()) - enc.Data = (*hexutil.Bytes)(&tx.Data) + enc.Data = (*hexutility.Bytes)(&tx.Data) enc.To = tx.To enc.V = (*hexutil.Big)(tx.V.ToBig()) enc.R = (*hexutil.Big)(tx.R.ToBig()) @@ -86,7 +88,7 @@ func (tx DynamicFeeTransaction) MarshalJSON() ([]byte, error) { enc.FeeCap = (*hexutil.Big)(tx.FeeCap.ToBig()) enc.Tip = (*hexutil.Big)(tx.Tip.ToBig()) enc.Value = (*hexutil.Big)(tx.Value.ToBig()) - enc.Data = (*hexutil.Bytes)(&tx.Data) + enc.Data = (*hexutility.Bytes)(&tx.Data) enc.To = tx.To enc.V = (*hexutil.Big)(tx.V.ToBig()) enc.R = (*hexutil.Big)(tx.R.ToBig()) diff --git a/core/types/vote.go b/core/types/vote.go new file mode 100644 index 00000000000..8c4882243ce --- /dev/null +++ b/core/types/vote.go @@ -0,0 +1,91 @@ +package types + +import ( + "sync/atomic" + + libcommon "github.com/ledgerwatch/erigon-lib/common" + "github.com/pkg/errors" + "github.com/prysmaticlabs/prysm/v4/crypto/bls" +) + +const ( + BLSPublicKeyLength = 48 + BLSSignatureLength = 96 + + MaxAttestationExtraLength = 256 + NaturallyFinalizedDist = 21 // The distance to naturally finalized a block +) + +type BLSPublicKey [BLSPublicKeyLength]byte +type BLSSignature [BLSSignatureLength]byte +type ValidatorsBitSet uint64 + +// VoteData represents the vote range that validator voted for fast finality. +type VoteData struct { + SourceNumber uint64 // The source block number should be the latest justified block number. + SourceHash libcommon.Hash // The block hash of the source block. + TargetNumber uint64 // The target block number which validator wants to vote for. + TargetHash libcommon.Hash // The block hash of the target block. +} + +// Hash returns the hash of the vote data. +func (d *VoteData) Hash() libcommon.Hash { return rlpHash(d) } + +// VoteEnvelope represents the vote of a single validator. +type VoteEnvelope struct { + VoteAddress BLSPublicKey // The BLS public key of the validator. + Signature BLSSignature // Validator's signature for the vote data. + Data *VoteData // The vote data for fast finality. + + // caches + hash atomic.Value +} + +// VoteAttestation represents the votes of super majority validators. +type VoteAttestation struct { + VoteAddressSet ValidatorsBitSet // The bitset marks the voted validators. + AggSignature BLSSignature // The aggregated BLS signature of the voted validators' signatures. + Data *VoteData // The vote data for fast finality. + Extra []byte // Reserved for future usage. +} + +// Hash returns the vote's hash. +func (v *VoteEnvelope) Hash() libcommon.Hash { + if hash := v.hash.Load(); hash != nil { + return hash.(libcommon.Hash) + } + + h := v.calcVoteHash() + v.hash.Store(h) + return h +} + +func (v *VoteEnvelope) calcVoteHash() libcommon.Hash { + vote := struct { + VoteAddress BLSPublicKey + Signature BLSSignature + Data *VoteData + }{v.VoteAddress, v.Signature, v.Data} + return rlpHash(vote) +} + +func (b BLSPublicKey) Bytes() []byte { return b[:] } + +// Verify vote using BLS. +func (vote *VoteEnvelope) Verify() error { + blsPubKey, err := bls.PublicKeyFromBytes(vote.VoteAddress[:]) + if err != nil { + return errors.Wrap(err, "convert public key from bytes to bls failed") + } + + sig, err := bls.SignatureFromBytes(vote.Signature[:]) + if err != nil { + return errors.Wrap(err, "invalid signature") + } + + voteDataHash := vote.Data.Hash() + if !sig.Verify(blsPubKey, voteDataHash[:]) { + return errors.New("verify bls signature failed.") + } + return nil +} diff --git a/core/vm/contracts.go b/core/vm/contracts.go index c3a4beb2327..2485f41381c 100644 --- a/core/vm/contracts.go +++ b/core/vm/contracts.go @@ -17,11 +17,14 @@ package vm import ( - "crypto/sha256" "encoding/binary" "errors" "math/big" + "github.com/ledgerwatch/log/v3" + "github.com/minio/sha256-simd" + "github.com/prysmaticlabs/prysm/v4/crypto/bls" + "github.com/holiman/uint256" "github.com/ledgerwatch/erigon-lib/chain" libcommon "github.com/ledgerwatch/erigon-lib/common" @@ -155,7 +158,43 @@ var PrecompiledContractsBLS = map[libcommon.Address]PrecompiledContract{ libcommon.BytesToAddress([]byte{18}): &bls12381MapG2{}, } +var PrecompiledContractsPlanck = map[libcommon.Address]PrecompiledContract{ + libcommon.BytesToAddress([]byte{1}): &ecrecover{}, + libcommon.BytesToAddress([]byte{2}): &sha256hash{}, + libcommon.BytesToAddress([]byte{3}): &ripemd160hash{}, + libcommon.BytesToAddress([]byte{4}): &dataCopy{}, + libcommon.BytesToAddress([]byte{5}): &bigModExp{}, + libcommon.BytesToAddress([]byte{6}): &bn256AddIstanbul{}, + libcommon.BytesToAddress([]byte{7}): &bn256ScalarMulIstanbul{}, + libcommon.BytesToAddress([]byte{8}): &bn256PairingIstanbul{}, + libcommon.BytesToAddress([]byte{9}): &blake2F{}, + + libcommon.BytesToAddress([]byte{100}): &tmHeaderValidate{}, + libcommon.BytesToAddress([]byte{101}): &iavlMerkleProofValidatePlanck{}, +} + +// PrecompiledContractsLuban contains the default set of pre-compiled Ethereum +// contracts used in the Luban release. +var PrecompiledContractsLuban = map[libcommon.Address]PrecompiledContract{ + libcommon.BytesToAddress([]byte{1}): &ecrecover{}, + libcommon.BytesToAddress([]byte{2}): &sha256hash{}, + libcommon.BytesToAddress([]byte{3}): &ripemd160hash{}, + libcommon.BytesToAddress([]byte{4}): &dataCopy{}, + libcommon.BytesToAddress([]byte{5}): &bigModExp{}, + libcommon.BytesToAddress([]byte{6}): &bn256AddIstanbul{}, + libcommon.BytesToAddress([]byte{7}): &bn256ScalarMulIstanbul{}, + libcommon.BytesToAddress([]byte{8}): &bn256PairingIstanbul{}, + libcommon.BytesToAddress([]byte{9}): &blake2F{}, + + libcommon.BytesToAddress([]byte{100}): &tmHeaderValidate{}, + libcommon.BytesToAddress([]byte{101}): &iavlMerkleProofValidatePlanck{}, + libcommon.BytesToAddress([]byte{102}): &blsSignatureVerify{}, + libcommon.BytesToAddress([]byte{103}): &cometBFTLightBlockValidate{}, +} + var ( + PrecompiledAddressesLuban []libcommon.Address + PrecompiledAddressesPlanck []libcommon.Address PrecompiledAddressesMoran []libcommon.Address PrecompiledAddressesNano []libcommon.Address PrecompiledAddressesBerlin []libcommon.Address @@ -187,11 +226,22 @@ func init() { for k := range PrecompiledContractsIsMoran { PrecompiledAddressesMoran = append(PrecompiledAddressesMoran, k) } + for k := range PrecompiledContractsPlanck { + PrecompiledAddressesPlanck = append(PrecompiledAddressesPlanck, k) + } + + for k := range PrecompiledContractsLuban { + PrecompiledAddressesLuban = append(PrecompiledAddressesLuban, k) + } } // ActivePrecompiles returns the precompiles enabled with the current configuration. func ActivePrecompiles(rules *chain.Rules) []libcommon.Address { switch { + case rules.IsLuban: + return PrecompiledAddressesLuban + case rules.IsPlanck: + return PrecompiledAddressesPlanck case rules.IsMoran: return PrecompiledAddressesMoran case rules.IsNano: @@ -314,6 +364,7 @@ type bigModExp struct { } var ( + big0 = big.NewInt(0) big1 = big.NewInt(1) big3 = big.NewInt(3) big4 = big.NewInt(4) @@ -1126,3 +1177,72 @@ func (c *bls12381MapG2) Run(input []byte) ([]byte, error) { // Encode the G2 point to 256 bytes return g.EncodePoint(r), nil } + +// blsSignatureVerify implements bls signature verification precompile. +type blsSignatureVerify struct{} + +const ( + msgHashLength = uint64(32) + signatureLength = uint64(96) + singleBlsPubkeyLength = uint64(48) +) + +// RequiredGas returns the gas required to execute the pre-compiled contract. +func (c *blsSignatureVerify) RequiredGas(input []byte) uint64 { + msgAndSigLength := msgHashLength + signatureLength + inputLen := uint64(len(input)) + if inputLen <= msgAndSigLength || + (inputLen-msgAndSigLength)%singleBlsPubkeyLength != 0 { + return params.BlsSignatureVerifyBaseGas + } + pubKeyNumber := (inputLen - msgAndSigLength) / singleBlsPubkeyLength + return params.BlsSignatureVerifyBaseGas + pubKeyNumber*params.BlsSignatureVerifyPerKeyGas +} + +// Run input: +// msg | signature | [{bls pubkey}] | +// 32 bytes | 96 bytes | [{48 bytes}] | +func (c *blsSignatureVerify) Run(input []byte) ([]byte, error) { + msgAndSigLength := msgHashLength + signatureLength + inputLen := uint64(len(input)) + if inputLen <= msgAndSigLength || + (inputLen-msgAndSigLength)%singleBlsPubkeyLength != 0 { + log.Debug("blsSignatureVerify input size wrong", "inputLen", inputLen) + return nil, ErrExecutionReverted + } + + var msg [32]byte + msgBytes := getData(input, 0, msgHashLength) + copy(msg[:], msgBytes) + + signatureBytes := getData(input, msgHashLength, signatureLength) + sig, err := bls.SignatureFromBytes(signatureBytes) + if err != nil { + log.Debug("blsSignatureVerify invalid signature", "err", err) + return nil, ErrExecutionReverted + } + + pubKeyNumber := (inputLen - msgAndSigLength) / singleBlsPubkeyLength + pubKeys := make([]bls.PublicKey, pubKeyNumber) + for i := uint64(0); i < pubKeyNumber; i++ { + pubKeyBytes := getData(input, msgAndSigLength+i*singleBlsPubkeyLength, singleBlsPubkeyLength) + pubKey, err := bls.PublicKeyFromBytes(pubKeyBytes) + if err != nil { + log.Debug("blsSignatureVerify invalid pubKey", "err", err) + return nil, ErrExecutionReverted + } + pubKeys[i] = pubKey + } + + if pubKeyNumber > 1 { + if !sig.FastAggregateVerify(pubKeys, msg) { + return big0.Bytes(), nil + } + } else { + if !sig.Verify(pubKeys[0], msgBytes) { + return big0.Bytes(), nil + } + } + + return big1.Bytes(), nil +} diff --git a/core/vm/contracts_lightclient.go b/core/vm/contracts_lightclient.go index e6b11d5e7b0..f914f7ce48f 100644 --- a/core/vm/contracts_lightclient.go +++ b/core/vm/contracts_lightclient.go @@ -3,10 +3,14 @@ package vm import ( "encoding/binary" "fmt" + "net/url" + "strings" + "github.com/ledgerwatch/erigon/core/vm/lightclient/iavl" cmn "github.com/tendermint/tendermint/libs/common" - "github.com/ledgerwatch/erigon/core/vm/lightclient" + v1 "github.com/ledgerwatch/erigon/core/vm/lightclient/v1" + v2 "github.com/ledgerwatch/erigon/core/vm/lightclient/v2" "github.com/ledgerwatch/erigon/params" "github.com/tendermint/tendermint/crypto/merkle" ) @@ -23,17 +27,22 @@ const ( // input: // consensus state length | consensus state | tendermint header | // 32 bytes | | | -func decodeTendermintHeaderValidationInput(input []byte) (*lightclient.ConsensusState, *lightclient.Header, error) { +func decodeTendermintHeaderValidationInput(input []byte) (*v1.ConsensusState, *v1.Header, error) { csLen := binary.BigEndian.Uint64(input[consensusStateLengthBytesLength-uint64TypeLength : consensusStateLengthBytesLength]) + + if consensusStateLengthBytesLength+csLen < consensusStateLengthBytesLength { + return nil, nil, fmt.Errorf("integer overflow, csLen: %d", csLen) + } + if uint64(len(input)) <= consensusStateLengthBytesLength+csLen { return nil, nil, fmt.Errorf("expected payload size %d, actual size: %d", consensusStateLengthBytesLength+csLen, len(input)) } - cs, err := lightclient.DecodeConsensusState(input[consensusStateLengthBytesLength : consensusStateLengthBytesLength+csLen]) + cs, err := v1.DecodeConsensusState(input[consensusStateLengthBytesLength : consensusStateLengthBytesLength+csLen]) if err != nil { return nil, nil, err } - header, err := lightclient.DecodeHeader(input[consensusStateLengthBytesLength+csLen:]) + header, err := v1.DecodeHeader(input[consensusStateLengthBytesLength+csLen:]) if err != nil { return nil, nil, err } @@ -41,7 +50,8 @@ func decodeTendermintHeaderValidationInput(input []byte) (*lightclient.Consensus return &cs, header, nil } -// tmHeaderValidate implemented as a native contract. +// tmHeaderValidate implemented as a native contract. Used to validate the light +// client's new header for tendermint v0.31.12 and its compatible version.type tmHeaderValidate struct{} type tmHeaderValidate struct{} func (c *tmHeaderValidate) RequiredGas(input []byte) uint64 { @@ -152,8 +162,38 @@ func (c *iavlMerkleProofValidateMoran) Run(input []byte) (result []byte, err err return c.basicIavlMerkleProofValidate.Run(input) } +type iavlMerkleProofValidatePlanck struct { + basicIavlMerkleProofValidate +} + +func (c *iavlMerkleProofValidatePlanck) RequiredGas(_ []byte) uint64 { + return params.IAVLMerkleProofValidateGas +} + +func (c *iavlMerkleProofValidatePlanck) Run(input []byte) (result []byte, err error) { + c.basicIavlMerkleProofValidate.proofRuntime = v1.Ics23CompatibleProofRuntime() + c.basicIavlMerkleProofValidate.verifiers = []merkle.ProofOpVerifier{ + forbiddenAbsenceOpVerifier, + singleValueOpVerifier, + multiStoreOpVerifier, + forbiddenSimpleValueOpVerifier, + } + c.basicIavlMerkleProofValidate.keyVerifier = keyVerifier + c.basicIavlMerkleProofValidate.opsVerifier = proofOpsVerifier + return c.basicIavlMerkleProofValidate.Run(input) +} + +func successfulMerkleResult() []byte { + result := make([]byte, merkleProofValidateResultLength) + binary.BigEndian.PutUint64(result[merkleProofValidateResultLength-uint64TypeLength:], 0x01) + return result +} + type basicIavlMerkleProofValidate struct { - verifiers []merkle.ProofOpVerifier + keyVerifier v1.KeyVerifier + opsVerifier merkle.ProofOpsVerifier + verifiers []merkle.ProofOpVerifier + proofRuntime *merkle.ProofRuntime } func (c *basicIavlMerkleProofValidate) Run(input []byte) (result []byte, err error) { @@ -172,20 +212,26 @@ func (c *basicIavlMerkleProofValidate) Run(input []byte) (result []byte, err err return nil, fmt.Errorf("invalid input: input size should be %d, actual the size is %d", payloadLength+precompileContractInputMetaDataLength, len(input)) } - kvmp, err := lightclient.DecodeKeyValueMerkleProof(input[precompileContractInputMetaDataLength:]) + kvmp, err := v1.DecodeKeyValueMerkleProof(input[precompileContractInputMetaDataLength:]) if err != nil { return nil, err } + if c.proofRuntime == nil { + kvmp.SetProofRuntime(v1.DefaultProofRuntime()) + } else { + kvmp.SetProofRuntime(c.proofRuntime) + } kvmp.SetVerifiers(c.verifiers) + kvmp.SetOpsVerifier(c.opsVerifier) + kvmp.SetKeyVerifier(c.keyVerifier) + valid := kvmp.Validate() if !valid { return nil, fmt.Errorf("invalid merkle proof") } - result = make([]byte, merkleProofValidateResultLength) - binary.BigEndian.PutUint64(result[merkleProofValidateResultLength-uint64TypeLength:], 0x01) - return result, nil + return successfulMerkleResult(), nil } func forbiddenAbsenceOpVerifier(op merkle.ProofOperator) error { if op == nil { @@ -211,7 +257,7 @@ func multiStoreOpVerifier(op merkle.ProofOperator) error { if op == nil { return nil } - if mop, ok := op.(lightclient.MultiStoreProofOp); ok { + if mop, ok := op.(v1.MultiStoreProofOp); ok { storeNames := make(map[string]bool, len(mop.Proof.StoreInfos)) for _, store := range mop.Proof.StoreInfos { if exist := storeNames[store.Name]; exist { @@ -240,3 +286,81 @@ func singleValueOpVerifier(op merkle.ProofOperator) error { } return nil } + +func proofOpsVerifier(poz merkle.ProofOperators) error { + if len(poz) != 2 { + return cmn.NewError("proof ops should be 2") + } + + // for legacy proof type + if _, ok := poz[1].(v1.MultiStoreProofOp); ok { + if _, ok := poz[0].(iavl.IAVLValueOp); !ok { + return cmn.NewError("invalid proof op") + } + return nil + } + + // for ics23 proof type + if op2, ok := poz[1].(v1.CommitmentOp); ok { + if op2.Type != v1.ProofOpSimpleMerkleCommitment { + return cmn.NewError("invalid proof op") + } + + op1, ok := poz[0].(v1.CommitmentOp) + if !ok { + return cmn.NewError("invalid proof op") + } + + if op1.Type != v1.ProofOpIAVLCommitment { + return cmn.NewError("invalid proof op") + } + return nil + } + + return cmn.NewError("invalid proof type") +} + +func keyVerifier(key string) error { + // https://github.com/bnb-chain/tendermint/blob/72375a6f3d4a72831cc65e73363db89a0073db38/crypto/merkle/proof_key_path.go#L88 + // since the upper function is ambiguous, `x:00` can be decoded to both kind of key type + // we check the key here to make sure the key will not start from `x:` + if strings.HasPrefix(url.PathEscape(key), "x:") { + return cmn.NewError("key should not start with x:") + } + return nil +} + +// cometBFTLightBlockValidate implemented as a native contract. Used to validate the light blocks for CometBFT v0.37.0 +// and its compatible version. Besides, in order to support the BLS cross-chain infrastructure, the SetRelayerAddress +// and SetBlsKey methods should be implemented for the validator. +type cometBFTLightBlockValidate struct{} + +func (c *cometBFTLightBlockValidate) RequiredGas(input []byte) uint64 { + return params.CometBFTLightBlockValidateGas +} + +func (c *cometBFTLightBlockValidate) Run(input []byte) (result []byte, err error) { + defer func() { + if r := recover(); r != nil { + err = fmt.Errorf("internal error: %v\n", r) + } + }() + + cs, block, err := v2.DecodeLightBlockValidationInput(input) + if err != nil { + return nil, err + } + + validatorSetChanged, err := cs.ApplyLightBlock(block) + if err != nil { + return nil, err + } + + consensusStateBytes, err := cs.EncodeConsensusState() + if err != nil { + return nil, err + } + + result = v2.EncodeLightBlockValidationResult(validatorSetChanged, consensusStateBytes) + return result, nil +} diff --git a/core/vm/contracts_lightclient_test.go b/core/vm/contracts_lightclient_test.go index ef58579041d..2327c831614 100644 --- a/core/vm/contracts_lightclient_test.go +++ b/core/vm/contracts_lightclient_test.go @@ -3,12 +3,16 @@ package vm import ( "encoding/binary" "encoding/hex" - "github.com/stretchr/testify/assert" + "github.com/ledgerwatch/erigon/core/vm/lightclient/v1" "testing" + "github.com/stretchr/testify/assert" + "github.com/tendermint/tendermint/crypto/merkle" + cmn "github.com/tendermint/tendermint/libs/common" + "github.com/stretchr/testify/require" - "github.com/ledgerwatch/erigon/core/vm/lightclient" + "github.com/ledgerwatch/erigon/core/vm/lightclient/iavl" ) const ( @@ -28,7 +32,7 @@ func TestTmHeaderValidateAndMerkleProofValidate(t *testing.T) { "da8a0bf13b1abaeee7a8f9383542099a554d219b93d0ce69e3970e8000000174876e800") require.NoError(t, err) - cs, err := lightclient.DecodeConsensusState(consensusStateBytes) + cs, err := v1.DecodeConsensusState(consensusStateBytes) require.NoError(t, err) headerBytes, err := hex.DecodeString("e3210a92130abb020a02080a121242696e616e63652d436861696e2d4e696c6518e38bf01f220c08e191aef20510f5f4e4c70230dae0c7173a480a20102b54820dd8fb5bc2c4e875ee573fa294d9b7b7ceb362aa8fd21b33dee41b1c12240801122082f341511f3e6b89d6177fd31f8a106013ba09d6e12ef40a7dec885d81b687634220b1b77e6977e0cd0177e3102a78833c9e152aa646ed4fb5a77e8af58c9867eec0522080d9ab0fc10d18ca0e0832d5f4c063c5489ec1443dfb738252d038a82131b27a5a2080d9ab0fc10d18ca0e0832d5f4c063c5489ec1443dfb738252d038a82131b27a6220294d8fbd0b94b767a7eba9840f299a3586da7fe6b5dead3b7eecba193c400f936a20a3e248bc209955054d880e4d89ff3c0419c0cd77681f4b4c6649ead5545054b982011462633d9db7ed78e951f79913fdc8231aa77ec12b12d1100a480a207eaabf7df1081377e06e08efe7ad17974049380bdd65a9b053c099ef80ff6e6f122408011220d153cc308d9cb96ca43ffeceaae1ee85794c83d17408ff76cfee92f5e91d0be212b601080210e38bf01f22480a207eaabf7df1081377e06e08efe7ad17974049380bdd65a9b053c099ef80ff6e6f122408011220d153cc308d9cb96ca43ffeceaae1ee85794c83d17408ff76cfee92f5e91d0be22a0b08e291aef20510cebfe23e321406fd60078eb4c2356137dd50036597db267cf61642409276f20ad4b152f91c344bd63ac691bad66e04e228a8b58dca293ff0bd10f8aef6dfbcecae49e32b09d89e10b771a6c01628628596a95e126b04763560c66c0f12b801080210e38bf01f22480a207eaabf7df1081377e06e08efe7ad17974049380bdd65a9b053c099ef80ff6e6f122408011220d153cc308d9cb96ca43ffeceaae1ee85794c83d17408ff76cfee92f5e91d0be22a0b08e291aef20510a4caa532321418e69cc672973992bb5f76d049a5b2c5ddf77436380142409ed2b74fa835296d552e68c439dd4ee3fa94fb197282edcc1cc815c863ca42a2c9a73475ff6be9064371a61655a3c31d2f0acc89c3a4489ad4c2671aef52360512b801080210e38bf01f22480a207eaabf7df1081377e06e08efe7ad17974049380bdd65a9b053c099ef80ff6e6f122408011220d153cc308d9cb96ca43ffeceaae1ee85794c83d17408ff76cfee92f5e91d0be22a0b08e291aef20510a69eca2f3214344c39bb8f4512d6cab1f6aafac1811ef9d8afdf38024240de2768ead90011bcbb1914abc1572749ab7b81382eb81cff3b41c56edc12470a7b8a4d61f8b4ca7b2cb7e24706edd219455796b4db74cd36965859f91dc8910312b801080210e38bf01f22480a207eaabf7df1081377e06e08efe7ad17974049380bdd65a9b053c099ef80ff6e6f122408011220d153cc308d9cb96ca43ffeceaae1ee85794c83d17408ff76cfee92f5e91d0be22a0b08e291aef20510dcdd833b321437ef19af29679b368d2b9e9de3f8769b357866763803424072ddfe0aeb13616b3f17eb60b19a923ec51fcc726625094aa069255c829c8cdd9e242080a1e559b0030fe9a0db19fd34e392bd78df12a9caff9f2b811bc1ac0a12b801080210e38bf01f22480a207eaabf7df1081377e06e08efe7ad17974049380bdd65a9b053c099ef80ff6e6f122408011220d153cc308d9cb96ca43ffeceaae1ee85794c83d17408ff76cfee92f5e91d0be22a0b08e291aef20510e9f2f859321462633d9db7ed78e951f79913fdc8231aa77ec12b38044240f5f61c640ab2402b44936de0d24e7b439df78bc3ef15467ecb29b92ece4aa0550790d5ce80761f2ac4b0e3283969725c42343749d9b44b179b2d4fced66c5d0412b801080210e38bf01f22480a207eaabf7df1081377e06e08efe7ad17974049380bdd65a9b053c099ef80ff6e6f122408011220d153cc308d9cb96ca43ffeceaae1ee85794c83d17408ff76cfee92f5e91d0be22a0b08e291aef20510ff90f55532147b343e041ca130000a8bc00c35152bd7e774003738054240df6e298b3efd42eb536e68a0210bc921e8b5dc145fe965f63f4d3490064f239f2a54a6db16c96086e4ae52280c04ad8b32b44f5ff3d41f0c364949ccb628c50312b801080210e38bf01f22480a207eaabf7df1081377e06e08efe7ad17974049380bdd65a9b053c099ef80ff6e6f122408011220d153cc308d9cb96ca43ffeceaae1ee85794c83d17408ff76cfee92f5e91d0be22a0b08e291aef20510cad7c931321491844d296bd8e591448efc65fd6ad51a888d58fa3806424030298627da1afd28229aac150f553724b594989e59136d6a175d84e45a4dee344ff9e0eeb69fdf29abb6d833adc3e1ccdc87b2a65019ef5fb627c44d9d132c0012b801080210e38bf01f22480a207eaabf7df1081377e06e08efe7ad17974049380bdd65a9b053c099ef80ff6e6f122408011220d153cc308d9cb96ca43ffeceaae1ee85794c83d17408ff76cfee92f5e91d0be22a0b08e291aef20510c8c296323214b3727172ce6473bc780298a2d66c12f1a14f5b2a38074240918491100730b4523f0c85409f6d1cca9ebc4b8ca6df8d55fe3d85158fa43286608693c50332953e1d3b93e3e78b24e158d6a2275ce8c6c7c07a7a646a19200312b801080210e38bf01f22480a207eaabf7df1081377e06e08efe7ad17974049380bdd65a9b053c099ef80ff6e6f122408011220d153cc308d9cb96ca43ffeceaae1ee85794c83d17408ff76cfee92f5e91d0be22a0b08e291aef2051086f1a2403214b6f20c7faa2b2f6f24518fa02b71cb5f4a09fba338084240ca59c9fc7f6ab660e9970fc03e5ed588ccb8be43fe5a3e8450287b726f29d039e53fe888438f178ac63c3d2ca969cd8c2fbc8606f067634339b6a94a7382960212b801080210e38bf01f22480a207eaabf7df1081377e06e08efe7ad17974049380bdd65a9b053c099ef80ff6e6f122408011220d153cc308d9cb96ca43ffeceaae1ee85794c83d17408ff76cfee92f5e91d0be22a0b08e291aef2051080efbb543214e0dd72609cc106210d1aa13936cb67b93a0aee2138094240e787a21f5cb7052624160759a9d379dd9db144f2b498bca026375c9ce8ecdc2a0936af1c309b3a0f686c92bf5578b595a4ca99036a19c9fc50d3718fd454b30012b801080210e38bf01f22480a207eaabf7df1081377e06e08efe7ad17974049380bdd65a9b053c099ef80ff6e6f122408011220d153cc308d9cb96ca43ffeceaae1ee85794c83d17408ff76cfee92f5e91d0be22a0b08e291aef20510ddf8d85a3214fc3108dc3814888f4187452182bc1baf83b71bc9380a4240d51ea31f6449eed71de22339722af1edbb0b21401037d85882b32a2ed8ae9127f2df4d1da2092729e582812856227ed6cdf98a3f60203d1ff80bd635fb03bb0912a4070a4f0a1406fd60078eb4c2356137dd50036597db267cf61612251624de6420e17cbe9c20cdcfdf876b3b12978d3264a007fcaaa71c4cdb701d9ebc0323f44f1880d0dbc3f4022080e0ebdaf2e2ffffff010a4b0a1418e69cc672973992bb5f76d049a5b2c5ddf7743612251624de6420184e7b103d34c41003f9b864d5f8c1adda9bd0436b253bb3c844bc739c1e77c91880d0dbc3f4022080d0dbc3f4020a4b0a14344c39bb8f4512d6cab1f6aafac1811ef9d8afdf12251624de64204d420aea843e92a0cfe69d89696dff6827769f9cb52a249af537ce89bf2a4b741880d0dbc3f4022080d0dbc3f4020a4b0a1437ef19af29679b368d2b9e9de3f8769b3578667612251624de6420bd03de9f8ab29e2800094e153fac6f696cfa512536c9c2f804dcb2c2c4e4aed61880d0dbc3f4022080d0dbc3f4020a4b0a1462633d9db7ed78e951f79913fdc8231aa77ec12b12251624de64208f4a74a07351895ddf373057b98fae6dfaf2cd21f37a063e19601078fe470d531880d0dbc3f4022080d0dbc3f4020a4b0a147b343e041ca130000a8bc00c35152bd7e774003712251624de64204a5d4753eb79f92e80efe22df7aca4f666a4f44bf81c536c4a09d4b9c5b654b51880d0dbc3f4022080d0dbc3f4020a4b0a1491844d296bd8e591448efc65fd6ad51a888d58fa12251624de6420c80e9abef7ff439c10c68fe8f1303deddfc527718c3b37d8ba6807446e3c827a1880d0dbc3f4022080d0dbc3f4020a4b0a14b3727172ce6473bc780298a2d66c12f1a14f5b2a12251624de64209142afcc691b7cc05d26c7b0be0c8b46418294171730e079f384fde2fa50bafc1880d0dbc3f4022080d0dbc3f4020a4b0a14b6f20c7faa2b2f6f24518fa02b71cb5f4a09fba312251624de642049b288e4ebbb3a281c2d546fc30253d5baf08993b6e5d295fb787a5b314a298e1880d0dbc3f4022080d0dbc3f4020a4b0a14e0dd72609cc106210d1aa13936cb67b93a0aee2112251624de642004224339688f012e649de48e241880092eaa8f6aa0f4f14bfcf9e0c76917c0b61880d0dbc3f4022080d0dbc3f4020a4b0a14fc3108dc3814888f4187452182bc1baf83b71bc912251624de64204034b37ceda8a0bf13b1abaeee7a8f9383542099a554d219b93d0ce69e3970e81880d0dbc3f4022080d0dbc3f402124f0a1406fd60078eb4c2356137dd50036597db267cf61612251624de6420e17cbe9c20cdcfdf876b3b12978d3264a007fcaaa71c4cdb701d9ebc0323f44f1880d0dbc3f4022080e0ebdaf2e2ffffff011aa4070a4f0a1406fd60078eb4c2356137dd50036597db267cf61612251624de6420e17cbe9c20cdcfdf876b3b12978d3264a007fcaaa71c4cdb701d9ebc0323f44f1880d0dbc3f4022080e0ebdaf2e2ffffff010a4b0a1418e69cc672973992bb5f76d049a5b2c5ddf7743612251624de6420184e7b103d34c41003f9b864d5f8c1adda9bd0436b253bb3c844bc739c1e77c91880d0dbc3f4022080d0dbc3f4020a4b0a14344c39bb8f4512d6cab1f6aafac1811ef9d8afdf12251624de64204d420aea843e92a0cfe69d89696dff6827769f9cb52a249af537ce89bf2a4b741880d0dbc3f4022080d0dbc3f4020a4b0a1437ef19af29679b368d2b9e9de3f8769b3578667612251624de6420bd03de9f8ab29e2800094e153fac6f696cfa512536c9c2f804dcb2c2c4e4aed61880d0dbc3f4022080d0dbc3f4020a4b0a1462633d9db7ed78e951f79913fdc8231aa77ec12b12251624de64208f4a74a07351895ddf373057b98fae6dfaf2cd21f37a063e19601078fe470d531880d0dbc3f4022080d0dbc3f4020a4b0a147b343e041ca130000a8bc00c35152bd7e774003712251624de64204a5d4753eb79f92e80efe22df7aca4f666a4f44bf81c536c4a09d4b9c5b654b51880d0dbc3f4022080d0dbc3f4020a4b0a1491844d296bd8e591448efc65fd6ad51a888d58fa12251624de6420c80e9abef7ff439c10c68fe8f1303deddfc527718c3b37d8ba6807446e3c827a1880d0dbc3f4022080d0dbc3f4020a4b0a14b3727172ce6473bc780298a2d66c12f1a14f5b2a12251624de64209142afcc691b7cc05d26c7b0be0c8b46418294171730e079f384fde2fa50bafc1880d0dbc3f4022080d0dbc3f4020a4b0a14b6f20c7faa2b2f6f24518fa02b71cb5f4a09fba312251624de642049b288e4ebbb3a281c2d546fc30253d5baf08993b6e5d295fb787a5b314a298e1880d0dbc3f4022080d0dbc3f4020a4b0a14e0dd72609cc106210d1aa13936cb67b93a0aee2112251624de642004224339688f012e649de48e241880092eaa8f6aa0f4f14bfcf9e0c76917c0b61880d0dbc3f4022080d0dbc3f4020a4b0a14fc3108dc3814888f4187452182bc1baf83b71bc912251624de64204034b37ceda8a0bf13b1abaeee7a8f9383542099a554d219b93d0ce69e3970e81880d0dbc3f4022080d0dbc3f402124f0a1406fd60078eb4c2356137dd50036597db267cf61612251624de6420e17cbe9c20cdcfdf876b3b12978d3264a007fcaaa71c4cdb701d9ebc0323f44f1880d0dbc3f4022080e0ebdaf2e2ffffff01") @@ -49,7 +53,7 @@ func TestTmHeaderValidateAndMerkleProofValidate(t *testing.T) { var tmHeaderValidateContract tmHeaderValidate syncedConsensusStateBytes, err := tmHeaderValidateContract.Run(input) require.NoError(t, err) - syncedConsensusState, err := lightclient.DecodeConsensusState(syncedConsensusStateBytes[32:]) + syncedConsensusState, err := v1.DecodeConsensusState(syncedConsensusStateBytes[32:]) require.NoError(t, err) require.Equal(t, testHeight+1, syncedConsensusState.Height) require.Equal(t, cs.ChainID, syncedConsensusState.ChainID) @@ -69,7 +73,7 @@ func TestTmHeaderValidateAndMerkleProofValidate(t *testing.T) { syncedAgainConsensusStateBytes, err := tmHeaderValidateContract.Run(input) require.NoError(t, err) - syncedAgainConsensusState, err := lightclient.DecodeConsensusState(syncedAgainConsensusStateBytes[32:]) + syncedAgainConsensusState, err := v1.DecodeConsensusState(syncedAgainConsensusStateBytes[32:]) require.NoError(t, err) newAppHash := syncedAgainConsensusState.AppHash @@ -113,6 +117,43 @@ func TestTmHeaderValidateAndMerkleProofValidate(t *testing.T) { require.Equal(t, expectedResult, success) } +func TestIcs23Proof(t *testing.T) { + appHash, err := hex.DecodeString("ae6d1123fc362b3297bfb19c9f9fabbcbd1e2555b923dead261905b8a2ff6db6") + require.NoError(t, err) + key, err := hex.DecodeString("77696e64") + require.NoError(t, err) + value, err := hex.DecodeString("626c6f7773") + require.NoError(t, err) + proofBytes, err := hex.DecodeString("0a300a0a69637332333a6961766c120477696e641a1c0a1a0a0477696e641205626c6f77731a0b0801180120012a030002040a9d010a0c69637332333a73696d706c6512036962631a87010a84010a036962631220141acb8632cfb808f293f2649cb9aabaca74fc18640900ffd0d48e2994b2a1521a090801180120012a0100222708011201011a205f0ba08283de309300409486e978a3ea59d82bccc838b07c7d39bd87c16a5034222708011201011a20455b81ef5591150bd24d3e57a769f65518b16de93487f0fab02271b3d69e2852") + require.NoError(t, err) + + merkleProofInput := make([]byte, 32+32+len(key)+32+len(value)+32+len(proofBytes)) + copy(merkleProofInput[:32], "ibc") + binary.BigEndian.PutUint64(merkleProofInput[32+24:32+32], uint64(len(key))) + copy(merkleProofInput[32+32:32+32+len(key)], key) + + binary.BigEndian.PutUint64(merkleProofInput[32+32+len(key)+24:32+32+len(key)+32], uint64(len(value))) + copy(merkleProofInput[32+32+len(key)+32:32+32+len(key)+32+len(value)], value) + + copy(merkleProofInput[32+32+len(key)+32+len(value):32+32+len(key)+32+len(value)+32], appHash) + copy(merkleProofInput[32+32+len(key)+32+len(value)+32:], proofBytes) + + totalLengthPrefix := make([]byte, 32) + binary.BigEndian.PutUint64(totalLengthPrefix[0:8], 0) + binary.BigEndian.PutUint64(totalLengthPrefix[8:16], 0) + binary.BigEndian.PutUint64(totalLengthPrefix[16:24], 0) + binary.BigEndian.PutUint64(totalLengthPrefix[24:], uint64(len(merkleProofInput))) + + input := append(totalLengthPrefix, merkleProofInput...) + + validator := iavlMerkleProofValidatePlanck{} + success, err := validator.Run(input) + require.NoError(t, err) + expectedResult := make([]byte, 32) + binary.BigEndian.PutUint64(expectedResult[24:], 0x01) + require.Equal(t, expectedResult, success) +} + func TestMerkleProofValidateMoran(t *testing.T) { // Bytest1 is the inputs of exploit tx 0x05356fd06ce56a9ec5b4eaf9c075abd740cae4c21eab1676440ab5cd2fe5c57a bytest1, _ := hex.DecodeString("00000000000000000000000000000000000000000000000000000000000005086962630000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000e00000100380200000000010dd9ac0000000000000000000000000000000000000000000000000000000000000093000000000000000000000000000000000000000000000000000000000000000000f870a0424e4200000000000000000000000000000000000000000000000000000000009400000000000000000000000000000000000000008ad3c21bcecceda100000094489a8756c18c0b8b24ec2a2b9ff3d4d447f79bec94489a8756c18c0b8b24ec2a2b9ff3d4d447f79bec846553f10072cda827a83531ca0fd7ac917a6b65649719aab0836722caafe0603147a523180a8d020a066961766c3a76120e00000100380200000000010dd9ac1af201f0010aed010a2b0802100318b091c73422200c10f902d266c238a4ca9e26fa9bc36483cd3ebee4e263012f5e7f40c22ee4d20a4d0801100218b091c7342220e4fd47bffd1c06e67edad92b2bf9ca63631978676288a2aa99f95c459436ef632a20121a1f9c4eca726c725796c5375fc4158986ced08e498dc8268ef94d8ed1891612001a370a0e0000010038020000000000000002122011056c6919f02d966991c10721684a8d1542e44003f9ffb47032c18995d4ac7f18b091c7341a340a0e00000100380200000000010dd9ac12202c3a561458f8527b002b5ec3cab2d308662798d6245d4588a4e6a80ebdfe30ac18010ad4050a0a6d756c746973746f726512036962631ac005be050abb050a110a066f7261636c6512070a0508b891c7340a0f0a046d61696e12070a0508b891c7340a350a08736c617368696e6712290a2708b891c7341220c8ccf341e6e695e7e1cb0ce4bf347eea0cc16947d8b4e934ec400b57c59d6f860a380a0b61746f6d69635f7377617012290a2708b891c734122042d4ecc9468f71a70288a95d46564bfcaf2c9f811051dcc5593dbef152976b010a110a0662726964676512070a0508b891c7340a300a0364657812290a2708b891c73412201773be443c27f61075cecdc050ce22eb4990c54679089e90afdc4e0e88182a230a2f0a02736312290a2708b891c7341220df7a0484b7244f76861b1642cfb7a61d923794bd2e076c8dbd05fc4ee29f3a670a330a06746f6b656e7312290a2708b891c734122064958c2f76fec1fa5d1828296e51264c259fa264f499724795a740f48fc4731b0a320a057374616b6512290a2708b891c734122015d2c302143bdf029d58fe381cc3b54cedf77ecb8834dfc5dc3e1555d68f19ab0a330a06706172616d7312290a2708b891c734122050abddcb7c115123a5a4247613ab39e6ba935a3d4f4b9123c4fedfa0895c040a0a300a0361636312290a2708b891c734122079fb5aecc4a9b87e56231103affa5e515a1bdf3d0366490a73e087980b7f1f260a0e0a0376616c12070a0508b891c7340a300a0369626312290a2708b891c7341220e09159530585455058cf1785f411ea44230f39334e6e0f6a3c54dbf069df2b620a300a03676f7612290a2708b891c7341220db85ddd37470983b14186e975a175dfb0bf301b43de685ced0aef18d28b4e0420a320a05706169727312290a2708b891c7341220a78b556bc9e73d86b4c63ceaf146db71b12ac80e4c10dd0ce6eb09c99b0c7cfe0a360a0974696d655f6c6f636b12290a2708b891c73412204775dbe01d41cab018c21ba5c2af94720e4d7119baf693670e70a40ba2a52143") @@ -142,12 +183,12 @@ func TestAbsenceMerkleProofValidateMoran(t *testing.T) { } func TestMultiStore(t *testing.T) { - goodProof := lightclient.NewMultiStoreProofOp([]byte("legit"), &lightclient.MultiStoreProof{ - StoreInfos: []lightclient.StoreInfo{ + goodProof := v1.NewMultiStoreProofOp([]byte("legit"), &v1.MultiStoreProof{ + StoreInfos: []v1.StoreInfo{ { Name: "legit", - Core: lightclient.StoreCore{ - CommitID: lightclient.CommitID{ + Core: v1.StoreCore{ + CommitID: v1.CommitID{ Version: 1, Hash: []byte("legithash"), }, @@ -162,12 +203,12 @@ func TestMultiStore(t *testing.T) { _, err = goodProof.Run([][]byte{[]byte("evilhash")}) assert.Error(t, err, "hash mismatch for substore") - badProof := lightclient.NewMultiStoreProofOp([]byte("legit"), &lightclient.MultiStoreProof{ - StoreInfos: []lightclient.StoreInfo{ + badProof := v1.NewMultiStoreProofOp([]byte("legit"), &v1.MultiStoreProof{ + StoreInfos: []v1.StoreInfo{ { Name: "legit", - Core: lightclient.StoreCore{ - CommitID: lightclient.CommitID{ + Core: v1.StoreCore{ + CommitID: v1.CommitID{ Version: 1, Hash: []byte("evilhash"), }, @@ -175,8 +216,8 @@ func TestMultiStore(t *testing.T) { }, { Name: "legit", - Core: lightclient.StoreCore{ - CommitID: lightclient.CommitID{ + Core: v1.StoreCore{ + CommitID: v1.CommitID{ Version: 1, Hash: []byte("legithash"), }, @@ -195,3 +236,91 @@ func TestMultiStore(t *testing.T) { err = multiStoreOpVerifier(badProof) assert.Error(t, err, "duplicated store") } + +func TestProofOpsVerifier(t *testing.T) { + tests := []struct { + ops merkle.ProofOperators + err error + }{ + { + merkle.ProofOperators{ + iavl.IAVLValueOp{}, + }, + cmn.NewError("proof ops should be 2"), + }, + { + merkle.ProofOperators{ + v1.MultiStoreProofOp{}, + v1.MultiStoreProofOp{}, + }, + cmn.NewError("invalid proof op"), + }, + { + merkle.ProofOperators{ + iavl.IAVLValueOp{}, + v1.MultiStoreProofOp{}, + }, + nil, + }, + { + merkle.ProofOperators{ + v1.CommitmentOp{Type: v1.ProofOpIAVLCommitment}, + v1.CommitmentOp{Type: v1.ProofOpSimpleMerkleCommitment}, + }, + nil, + }, + { + merkle.ProofOperators{ + v1.CommitmentOp{Type: v1.ProofOpSimpleMerkleCommitment}, + v1.CommitmentOp{Type: v1.ProofOpSimpleMerkleCommitment}, + }, + cmn.NewError("invalid proof op"), + }, + { + merkle.ProofOperators{ + v1.MultiStoreProofOp{}, + iavl.IAVLValueOp{}, + }, + cmn.NewError("invalid proof type"), + }, + } + + for _, testCase := range tests { + err := proofOpsVerifier(testCase.ops) + assert.Equal(t, err, testCase.err) + } +} + +func TestKeyVerifier(t *testing.T) { + tests := []struct { + key string + err error + }{ + { + "x:sdfdfdsd", + cmn.NewError("key should not start with x:"), + }, + { + "sdfxdfxs", + nil, + }, + } + + for _, testCase := range tests { + err := keyVerifier(testCase.key) + assert.Equal(t, err, testCase.err) + } +} + +func TestCometBFTLightBlockValidate(t *testing.T) { + inputStr := "000000000000000000000000000000000000000000000000000000000000018c677265656e6669656c645f393030302d3132310000000000000000000000000000000000000000013c350cd55b99dc6c2b7da9bef5410fbfb869fede858e7b95bf7ca294e228bb40e33f6e876d63791ebd05ff617a1b4f4ad1aa2ce65e3c3a9cdfb33e0ffa7e8423000000000098968015154514f68ce65a0d9eecc578c0ab12da0a2a28a0805521b5b7ae56eb3fb24555efbfe59e1622bfe9f7be8c9022e9b3f2442739c1ce870b9adee169afe60f674edd7c86451c5363d89052fde8351895eeea166ce5373c36e31b518ed191d0c599aa0f5b0000000000989680432f6c4908a9aa5f3444421f466b11645235c99b831b2a2de9e504d7ea299e52a202ce529808618eb3bfc0addf13d8c5f2df821d81e18f9bc61583510b322d067d46323b0a572635c06a049c0a2a929e3c8184a50cf6a8b95708c25834ade456f399015a0000000000989680864cb9828254d712f8e59b164fc6a9402dc4e6c59065e38cff24f5323c8c5da888a0f97e5ee4ba1e11b0674b0a0d06204c1dfa247c370cd4be3e799fc4f6f48d977ac7ca0aeb060adb030a02080b1213677265656e6669656c645f393030302d3132311802220c08b2d7f3a10610e8d2adb3032a480a20ec6ecb5db4ffb17fabe40c60ca7b8441e9c5d77585d0831186f3c37aa16e9c15122408011220a2ab9e1eb9ea52812f413526e424b326aff2f258a56e00d690db9f805b60fe7e32200f40aeff672e8309b7b0aefbb9a1ae3d4299b5c445b7d54e8ff398488467f0053a20e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b85542203c350cd55b99dc6c2b7da9bef5410fbfb869fede858e7b95bf7ca294e228bb404a203c350cd55b99dc6c2b7da9bef5410fbfb869fede858e7b95bf7ca294e228bb405220294d8fbd0b94b767a7eba9840f299a3586da7fe6b5dead3b7eecba193c400f935a20bc50557c12d7392b0d07d75df0b61232d48f86a74fdea6d1485d9be6317d268c6220e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b8556a20e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b85572146699336aa109d1beab3946198c8e59f3b2cbd92f7a4065e3cd89e315ca39d87dee92835b98f8b8ec0861d6d9bb2c60156df5d375b3ceb1fbe71af6a244907d62548a694165caa660fec7a9b4e7b9198191361c71be0b128a0308021a480a20726abd0fdbfb6f779b0483e6e4b4b6f12241f6ea2bf374233ab1a316692b6415122408011220159f10ff15a8b58fc67a92ffd7f33c8cd407d4ce81b04ca79177dfd00ca19a67226808021214050cff76cc632760ba9db796c046004c900967361a0c08b3d7f3a10610808cadba03224080713027ffb776a702d78fd0406205c629ba473e1f8d6af646190f6eb9262cd67d69be90d10e597b91e06d7298eb6fa4b8f1eb7752ebf352a1f51560294548042268080212146699336aa109d1beab3946198c8e59f3b2cbd92f1a0c08b3d7f3a10610b087c1c00322405e2ddb70acfe4904438be3d9f4206c0ace905ac4fc306a42cfc9e86268950a0fbfd6ec5f526d3e41a3ef52bf9f9f358e3cb4c3feac76c762fa3651c1244fe004226808021214c55765fd2d0570e869f6ac22e7f2916a35ea300d1a0c08b3d7f3a10610f0b3d492032240ca17898bd22232fc9374e1188636ee321a396444a5b1a79f7628e4a11f265734b2ab50caf21e8092c55d701248e82b2f011426cb35ba22043b497a6b4661930612a0050aa8010a14050cff76cc632760ba9db796c046004c9009673612220a20e33f6e876d63791ebd05ff617a1b4f4ad1aa2ce65e3c3a9cdfb33e0ffa7e84231880ade2042080a6bbf6ffffffffff012a30a0805521b5b7ae56eb3fb24555efbfe59e1622bfe9f7be8c9022e9b3f2442739c1ce870b9adee169afe60f674edd7c86321415154514f68ce65a0d9eecc578c0ab12da0a2a283a14ee7a2a6a44d427f6949eeb8f12ea9fbb2501da880aa2010a146699336aa109d1beab3946198c8e59f3b2cbd92f12220a20451c5363d89052fde8351895eeea166ce5373c36e31b518ed191d0c599aa0f5b1880ade2042080ade2042a30831b2a2de9e504d7ea299e52a202ce529808618eb3bfc0addf13d8c5f2df821d81e18f9bc61583510b322d067d46323b3214432f6c4908a9aa5f3444421f466b11645235c99b3a14a0a7769429468054e19059af4867da0a495567e50aa2010a14c55765fd2d0570e869f6ac22e7f2916a35ea300d12220a200a572635c06a049c0a2a929e3c8184a50cf6a8b95708c25834ade456f399015a1880ade2042080ade2042a309065e38cff24f5323c8c5da888a0f97e5ee4ba1e11b0674b0a0d06204c1dfa247c370cd4be3e799fc4f6f48d977ac7ca3214864cb9828254d712f8e59b164fc6a9402dc4e6c53a143139916d97df0c589312b89950b6ab9795f34d1a12a8010a14050cff76cc632760ba9db796c046004c9009673612220a20e33f6e876d63791ebd05ff617a1b4f4ad1aa2ce65e3c3a9cdfb33e0ffa7e84231880ade2042080a6bbf6ffffffffff012a30a0805521b5b7ae56eb3fb24555efbfe59e1622bfe9f7be8c9022e9b3f2442739c1ce870b9adee169afe60f674edd7c86321415154514f68ce65a0d9eecc578c0ab12da0a2a283a14ee7a2a6a44d427f6949eeb8f12ea9fbb2501da88" + expectOutputStr := "000000000000000000000000000000000000000000000000000000000000018c677265656e6669656c645f393030302d3132310000000000000000000000000000000000000000023c350cd55b99dc6c2b7da9bef5410fbfb869fede858e7b95bf7ca294e228bb40e33f6e876d63791ebd05ff617a1b4f4ad1aa2ce65e3c3a9cdfb33e0ffa7e8423000000000098968015154514f68ce65a0d9eecc578c0ab12da0a2a28a0805521b5b7ae56eb3fb24555efbfe59e1622bfe9f7be8c9022e9b3f2442739c1ce870b9adee169afe60f674edd7c86451c5363d89052fde8351895eeea166ce5373c36e31b518ed191d0c599aa0f5b0000000000989680432f6c4908a9aa5f3444421f466b11645235c99b831b2a2de9e504d7ea299e52a202ce529808618eb3bfc0addf13d8c5f2df821d81e18f9bc61583510b322d067d46323b0a572635c06a049c0a2a929e3c8184a50cf6a8b95708c25834ade456f399015a0000000000989680864cb9828254d712f8e59b164fc6a9402dc4e6c59065e38cff24f5323c8c5da888a0f97e5ee4ba1e11b0674b0a0d06204c1dfa247c370cd4be3e799fc4f6f48d977ac7ca" + + input, err := hex.DecodeString(inputStr) + require.NoError(t, err) + + contract := &cometBFTLightBlockValidate{} + res, err := contract.Run(input) + require.NoError(t, err) + require.Equal(t, expectOutputStr, hex.EncodeToString(res)) +} diff --git a/core/vm/eips.go b/core/vm/eips.go index 292f5c7d07a..1109aa5148a 100644 --- a/core/vm/eips.go +++ b/core/vm/eips.go @@ -198,3 +198,26 @@ func enable3860(jt *JumpTable) { jt[CREATE].dynamicGas = gasCreateEip3860 jt[CREATE2].dynamicGas = gasCreate2Eip3860 } + +// enableSharding applies mini-danksharding (DATAHASH Opcode) +// - Adds an opcode that returns the versioned data hash of the tx at a index. +func enableSharding(jt *JumpTable) { + jt[DATAHASH] = &operation{ + execute: opDataHash, + constantGas: GasFastestStep, + numPop: 0, + numPush: 1, + } +} + +// opDataHash implements DATAHASH opcode +func opDataHash(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) { + idx := scope.Stack.Peek() + if idx.LtUint64(uint64(len(interpreter.evm.TxContext().DataHashes))) { + hash := interpreter.evm.TxContext().DataHashes[idx.Uint64()] + idx.SetBytes(hash.Bytes()) + } else { + idx.Clear() + } + return nil, nil +} diff --git a/core/vm/evm.go b/core/vm/evm.go index 8d6cdd736e3..9ddd4909d33 100644 --- a/core/vm/evm.go +++ b/core/vm/evm.go @@ -37,6 +37,10 @@ var emptyCodeHash = crypto.Keccak256Hash(nil) func (evm *EVM) precompile(addr libcommon.Address) (PrecompiledContract, bool) { var precompiles map[libcommon.Address]PrecompiledContract switch { + case evm.chainRules.IsLuban: + precompiles = PrecompiledContractsLuban + case evm.chainRules.IsPlanck: + precompiles = PrecompiledContractsPlanck case evm.chainRules.IsMoran: precompiles = PrecompiledContractsIsMoran case evm.chainRules.IsNano: @@ -165,11 +169,13 @@ func (evm *EVM) Interpreter() Interpreter { } func (evm *EVM) call(typ OpCode, caller ContractRef, addr libcommon.Address, input []byte, gas uint64, value *uint256.Int, bailout bool) (ret []byte, leftOverGas uint64, err error) { - if evm.config.NoRecursion && evm.interpreter.Depth() > 0 { + depth := evm.interpreter.Depth() + + if evm.config.NoRecursion && depth > 0 { return nil, gas, nil } // Fail if we're trying to execute above the call depth limit - if evm.interpreter.Depth() > int(params.CallCreateDepth) { + if depth > int(params.CallCreateDepth) { return nil, gas, ErrDepth } if typ == CALL || typ == CALLCODE { @@ -197,16 +203,12 @@ func (evm *EVM) call(typ OpCode, caller ContractRef, addr libcommon.Address, inp v = nil } // Calling a non existing account, don't do anything, but ping the tracer - if evm.interpreter.Depth() == 0 { + if depth == 0 { evm.config.Tracer.CaptureStart(evm, caller.Address(), addr, isPrecompile, false /* create */, input, gas, v, code) - defer func(startGas uint64) { // Lazy evaluation of the parameters - evm.config.Tracer.CaptureEnd(ret, 0, err) - }(gas) + evm.config.Tracer.CaptureEnd(ret, 0, nil) } else { evm.config.Tracer.CaptureEnter(typ, caller.Address(), addr, isPrecompile, false /* create */, input, gas, v, code) - defer func(startGas uint64) { // Lazy evaluation of the parameters - evm.config.Tracer.CaptureExit(ret, 0, err) - }(gas) + evm.config.Tracer.CaptureExit(ret, 0, nil) } } return nil, gas, nil @@ -226,7 +228,7 @@ func (evm *EVM) call(typ OpCode, caller ContractRef, addr libcommon.Address, inp if typ == STATICCALL { v = nil } - if evm.interpreter.Depth() == 0 { + if depth == 0 { evm.config.Tracer.CaptureStart(evm, caller.Address(), addr, isPrecompile, false /* create */, input, gas, v, code) defer func(startGas uint64) { // Lazy evaluation of the parameters evm.config.Tracer.CaptureEnd(ret, startGas-gas, err) @@ -338,9 +340,10 @@ func (evm *EVM) create(caller ContractRef, codeAndHash *codeAndHash, gas uint64, var ret []byte var err error var gasConsumption uint64 + depth := evm.interpreter.Depth() if evm.config.Debug { - if evm.interpreter.Depth() == 0 { + if depth == 0 { evm.config.Tracer.CaptureStart(evm, caller.Address(), address, false /* precompile */, true /* create */, codeAndHash.code, gas, value, nil) defer func() { evm.config.Tracer.CaptureEnd(ret, gasConsumption, err) @@ -355,7 +358,7 @@ func (evm *EVM) create(caller ContractRef, codeAndHash *codeAndHash, gas uint64, // Depth check execution. Fail if we're trying to execute above the // limit. - if evm.interpreter.Depth() > int(params.CallCreateDepth) { + if depth > int(params.CallCreateDepth) { err = ErrDepth return nil, libcommon.Address{}, gas, err } @@ -395,7 +398,7 @@ func (evm *EVM) create(caller ContractRef, codeAndHash *codeAndHash, gas uint64, contract := NewContract(caller, AccountRef(address), value, gas, evm.config.SkipAnalysis) contract.SetCodeOptionalHash(&address, codeAndHash) - if evm.config.NoRecursion && evm.interpreter.Depth() > 0 { + if evm.config.NoRecursion && depth > 0 { return nil, address, gas, nil } diff --git a/core/vm/lightclient/v1/ics23_proof.go b/core/vm/lightclient/v1/ics23_proof.go new file mode 100644 index 00000000000..cd4f340fbe5 --- /dev/null +++ b/core/vm/lightclient/v1/ics23_proof.go @@ -0,0 +1,107 @@ +package v1 + +import ( + "fmt" + + "github.com/bnb-chain/ics23" + "github.com/tendermint/tendermint/crypto/merkle" +) + +const ( + ProofOpIAVLCommitment = "ics23:iavl" + ProofOpSimpleMerkleCommitment = "ics23:simple" +) + +// CommitmentOp implements merkle.ProofOperator by wrapping an ics23 CommitmentProof +// It also contains a Key field to determine which key the proof is proving. +// NOTE: CommitmentProof currently can either be ExistenceProof or NonexistenceProof +// +// Type and Spec are classified by the kind of merkle proof it represents allowing +// the code to be reused by more types. Spec is never on the wire, but mapped from type in the code. +type CommitmentOp struct { + Type string + Spec *ics23.ProofSpec + Key []byte + Proof *ics23.CommitmentProof +} + +var _ merkle.ProofOperator = CommitmentOp{} + +// CommitmentOpDecoder takes a merkle.ProofOp and attempts to decode it into a CommitmentOp ProofOperator +// The proofOp.Data is just a marshalled CommitmentProof. The Key of the CommitmentOp is extracted +// from the unmarshalled proof. +func CommitmentOpDecoder(pop merkle.ProofOp) (merkle.ProofOperator, error) { + var spec *ics23.ProofSpec + switch pop.Type { + case ProofOpIAVLCommitment: + spec = ics23.IavlSpec + case ProofOpSimpleMerkleCommitment: + spec = ics23.TendermintSpec + default: + return nil, fmt.Errorf("unexpected ProofOp.Type; got %s, want supported ics23 subtypes 'ProofOpIAVLCommitment' or 'ProofOpSimpleMerkleCommitment'", pop.Type) + } + + proof := &ics23.CommitmentProof{} + err := proof.Unmarshal(pop.Data) + if err != nil { + return nil, err + } + + op := CommitmentOp{ + Type: pop.Type, + Key: pop.Key, + Spec: spec, + Proof: proof, + } + return op, nil +} + +func (op CommitmentOp) GetKey() []byte { + return op.Key +} + +// Run takes in a list of arguments and attempts to run the proof op against these arguments. +// Returns the root wrapped in [][]byte if the proof op succeeds with given args. If not, +// it will return an error. +// +// CommitmentOp will accept args of length 1 or length 0 +// If length 1 args is passed in, then CommitmentOp will attempt to prove the existence of the key +// with the value provided by args[0] using the embedded CommitmentProof and return the CommitmentRoot of the proof. +// If length 0 args is passed in, then CommitmentOp will attempt to prove the absence of the key +// in the CommitmentOp and return the CommitmentRoot of the proof. +func (op CommitmentOp) Run(args [][]byte) ([][]byte, error) { + if _, ok := op.Proof.Proof.(*ics23.CommitmentProof_Exist); !ok { + return nil, fmt.Errorf("only exist proof supported") + } + + // calculate root from proof + root, err := op.Proof.Calculate() + if err != nil { + return nil, fmt.Errorf("could not calculate root for proof: %v", err) + } + if len(args) != 1 { + return nil, fmt.Errorf("args must be length 1, got: %d", len(args)) + } + + // Args is length 1, verify existence of key with value args[0] + if !ics23.VerifyMembership(op.Spec, root, op.Proof, op.Key, args[0]) { + return nil, fmt.Errorf("proof did not verify existence of key %s with given value %x", op.Key, args[0]) + } + + return [][]byte{root}, nil +} + +// ProofOp implements ProofOperator interface and converts a CommitmentOp +// into a merkle.ProofOp format that can later be decoded by CommitmentOpDecoder +// back into a CommitmentOp for proof verification +func (op CommitmentOp) ProofOp() merkle.ProofOp { + bz, err := op.Proof.Marshal() + if err != nil { + panic(err.Error()) + } + return merkle.ProofOp{ + Type: op.Type, + Key: op.Key, + Data: bz, + } +} diff --git a/core/vm/lightclient/multistoreproof.go b/core/vm/lightclient/v1/multistoreproof.go similarity index 87% rename from core/vm/lightclient/multistoreproof.go rename to core/vm/lightclient/v1/multistoreproof.go index fd00c2f1401..a55b6838da5 100644 --- a/core/vm/lightclient/multistoreproof.go +++ b/core/vm/lightclient/v1/multistoreproof.go @@ -1,9 +1,9 @@ -package lightclient +package v1 import ( "bytes" "fmt" - + "github.com/ledgerwatch/erigon/core/vm/lightclient/iavl" iavl2 "github.com/ledgerwatch/erigon/core/vm/lightclient/iavl" "github.com/tendermint/tendermint/crypto/merkle" cmn "github.com/tendermint/tendermint/libs/common" @@ -136,3 +136,14 @@ func DefaultProofRuntime() (prt *merkle.ProofRuntime) { prt.RegisterOpDecoder(ProofOpMultiStore, MultiStoreProofOpDecoder) return } + +func Ics23CompatibleProofRuntime() (prt *merkle.ProofRuntime) { + prt = merkle.NewProofRuntime() + prt.RegisterOpDecoder(merkle.ProofOpSimpleValue, merkle.SimpleValueOpDecoder) + prt.RegisterOpDecoder(iavl.ProofOpIAVLValue, iavl.IAVLValueOpDecoder) + prt.RegisterOpDecoder(iavl.ProofOpIAVLAbsence, iavl.IAVLAbsenceOpDecoder) + prt.RegisterOpDecoder(ProofOpMultiStore, MultiStoreProofOpDecoder) + prt.RegisterOpDecoder(ProofOpIAVLCommitment, CommitmentOpDecoder) + prt.RegisterOpDecoder(ProofOpSimpleMerkleCommitment, CommitmentOpDecoder) + return +} diff --git a/core/vm/lightclient/rootmultistore.go b/core/vm/lightclient/v1/rootmultistore.go similarity index 98% rename from core/vm/lightclient/rootmultistore.go rename to core/vm/lightclient/v1/rootmultistore.go index d0e016c0e7b..c0f32f1b9f7 100644 --- a/core/vm/lightclient/rootmultistore.go +++ b/core/vm/lightclient/v1/rootmultistore.go @@ -1,8 +1,7 @@ -package lightclient +package v1 import ( "fmt" - "github.com/tendermint/tendermint/crypto/merkle" "github.com/tendermint/tendermint/crypto/tmhash" ) diff --git a/core/vm/lightclient/types.go b/core/vm/lightclient/v1/types.go similarity index 85% rename from core/vm/lightclient/types.go rename to core/vm/lightclient/v1/types.go index cd5c5944b82..afa478c85f5 100644 --- a/core/vm/lightclient/types.go +++ b/core/vm/lightclient/v1/types.go @@ -1,10 +1,9 @@ -package lightclient +package v1 import ( "bytes" "encoding/binary" "fmt" - "github.com/tendermint/tendermint/crypto/ed25519" "github.com/tendermint/tendermint/crypto/merkle" lerr "github.com/tendermint/tendermint/lite/errors" @@ -130,7 +129,7 @@ func (cs ConsensusState) EncodeConsensusState() ([]byte, error) { } func (cs *ConsensusState) ApplyHeader(header *Header) (bool, error) { - if uint64(header.Height) < cs.Height { + if uint64(header.Height) <= cs.Height { return false, fmt.Errorf("header height < consensus height (%d < %d)", header.Height, cs.Height) } @@ -209,32 +208,57 @@ func DecodeHeader(input []byte) (*Header, error) { return &header, nil } +type KeyVerifier func(string) error + type KeyValueMerkleProof struct { Key []byte Value []byte StoreName string AppHash []byte Proof *merkle.Proof - verifiers []merkle.ProofOpVerifier + + keyVerifier KeyVerifier + proofOpsVerifier merkle.ProofOpsVerifier + verifiers []merkle.ProofOpVerifier + proofRuntime *merkle.ProofRuntime +} + +func (kvmp *KeyValueMerkleProof) SetProofRuntime(prt *merkle.ProofRuntime) { + kvmp.proofRuntime = prt } func (kvmp *KeyValueMerkleProof) SetVerifiers(verifiers []merkle.ProofOpVerifier) { kvmp.verifiers = verifiers } +func (kvmp *KeyValueMerkleProof) SetOpsVerifier(verifier merkle.ProofOpsVerifier) { + kvmp.proofOpsVerifier = verifier +} + +func (kvmp *KeyValueMerkleProof) SetKeyVerifier(keyChecker KeyVerifier) { + kvmp.keyVerifier = keyChecker +} + func (kvmp *KeyValueMerkleProof) Validate() bool { - prt := DefaultProofRuntime() + if kvmp.keyVerifier != nil { + if err := kvmp.keyVerifier(kvmp.StoreName); err != nil { + return false + } + if err := kvmp.keyVerifier(string(kvmp.Key)); err != nil { + return false + } + } kp := merkle.KeyPath{} kp = kp.AppendKey([]byte(kvmp.StoreName), merkle.KeyEncodingURL) kp = kp.AppendKey(kvmp.Key, merkle.KeyEncodingURL) if len(kvmp.Value) == 0 { - err := prt.VerifyAbsence(kvmp.Proof, kvmp.AppHash, kp.String(), kvmp.verifiers...) + err := kvmp.proofRuntime.VerifyAbsence(kvmp.Proof, kvmp.AppHash, kp.String(), kvmp.verifiers...) return err == nil } - err := prt.VerifyValue(kvmp.Proof, kvmp.AppHash, kp.String(), kvmp.Value, kvmp.verifiers...) + err := kvmp.proofRuntime.VerifyValue(kvmp.Proof, kvmp.AppHash, kp.String(), kvmp.Value, kvmp.proofOpsVerifier, kvmp.verifiers...) return err == nil } @@ -245,8 +269,9 @@ func DecodeKeyValueMerkleProof(input []byte) (*KeyValueMerkleProof, error) { inputLength := uint64(len(input)) pos := uint64(0) - if inputLength <= storeNameLengthBytesLength+keyLengthBytesLength+valueLengthBytesLength+appHashLength { - return nil, fmt.Errorf("input length should be no less than %d", storeNameLengthBytesLength+keyLengthBytesLength+valueLengthBytesLength+appHashLength) + fixedSize := storeNameLengthBytesLength + keyLengthBytesLength + valueLengthBytesLength + appHashLength + if inputLength <= fixedSize { + return nil, fmt.Errorf("input length should be no less than %d", fixedSize) } storeName := string(bytes.Trim(input[pos:pos+storeNameLengthBytesLength], "\x00")) pos += storeNameLengthBytesLength @@ -254,7 +279,8 @@ func DecodeKeyValueMerkleProof(input []byte) (*KeyValueMerkleProof, error) { keyLength := binary.BigEndian.Uint64(input[pos+keyLengthBytesLength-8 : pos+keyLengthBytesLength]) pos += keyLengthBytesLength - if inputLength <= storeNameLengthBytesLength+keyLengthBytesLength+keyLength+valueLengthBytesLength { + fixedSize = storeNameLengthBytesLength + keyLengthBytesLength + valueLengthBytesLength + if inputLength <= fixedSize+keyLength || fixedSize+keyLength < fixedSize { return nil, fmt.Errorf("invalid input, keyLength %d is too long", keyLength) } key := input[pos : pos+keyLength] @@ -263,7 +289,10 @@ func DecodeKeyValueMerkleProof(input []byte) (*KeyValueMerkleProof, error) { valueLength := binary.BigEndian.Uint64(input[pos+valueLengthBytesLength-8 : pos+valueLengthBytesLength]) pos += valueLengthBytesLength - if inputLength <= storeNameLengthBytesLength+keyLengthBytesLength+keyLength+valueLengthBytesLength+valueLength+appHashLength { + fixedSize = storeNameLengthBytesLength + keyLengthBytesLength + valueLengthBytesLength + appHashLength + if inputLength <= fixedSize+keyLength+valueLength || + fixedSize+keyLength < fixedSize || + fixedSize+keyLength+valueLength < valueLength { return nil, fmt.Errorf("invalid input, valueLength %d is too long", valueLength) } value := input[pos : pos+valueLength] diff --git a/core/vm/lightclient/utils.go b/core/vm/lightclient/v1/utils.go similarity index 99% rename from core/vm/lightclient/utils.go rename to core/vm/lightclient/v1/utils.go index 20da6a1347b..685b6a12809 100644 --- a/core/vm/lightclient/utils.go +++ b/core/vm/lightclient/v1/utils.go @@ -1,4 +1,4 @@ -package lightclient +package v1 /* import ( diff --git a/core/vm/lightclient/wire.go b/core/vm/lightclient/v1/wire.go similarity index 92% rename from core/vm/lightclient/wire.go rename to core/vm/lightclient/v1/wire.go index 460dfce1de7..3570ae9351f 100644 --- a/core/vm/lightclient/wire.go +++ b/core/vm/lightclient/v1/wire.go @@ -1,4 +1,4 @@ -package lightclient +package v1 import ( "github.com/tendermint/go-amino" diff --git a/core/vm/lightclient/v2/lightclient.go b/core/vm/lightclient/v2/lightclient.go new file mode 100644 index 00000000000..888bff4a9d1 --- /dev/null +++ b/core/vm/lightclient/v2/lightclient.go @@ -0,0 +1,233 @@ +// Package v2 is used for tendermint v0.34.22 and its compatible version. +package v2 + +import ( + "bytes" + "encoding/binary" + "fmt" + + "github.com/cometbft/cometbft/crypto/ed25519" + "github.com/cometbft/cometbft/light" + tmproto "github.com/cometbft/cometbft/proto/tendermint/types" + "github.com/cometbft/cometbft/types" +) + +const ( + uint64TypeLength uint64 = 8 + consensusStateLengthBytesLength uint64 = 32 + validateResultMetaDataLength uint64 = 32 + + chainIDLength uint64 = 32 + heightLength uint64 = 8 + validatorSetHashLength uint64 = 32 + validatorPubkeyLength uint64 = 32 + validatorVotingPowerLength uint64 = 8 + relayerAddressLength uint64 = 20 + relayerBlsKeyLength uint64 = 48 + singleValidatorBytesLength uint64 = validatorPubkeyLength + validatorVotingPowerLength + relayerAddressLength + relayerBlsKeyLength + maxConsensusStateLength uint64 = chainIDLength + heightLength + validatorSetHashLength + 99*singleValidatorBytesLength // Maximum validator quantity 99 +) + +type ConsensusState struct { + ChainID string + Height uint64 + NextValidatorSetHash []byte + ValidatorSet *types.ValidatorSet +} + +// output: +// | chainID | height | nextValidatorSetHash | [{validator pubkey, voting power, relayer address, relayer bls pubkey}] | +// | 32 bytes | 8 bytes | 32 bytes | [{32 bytes, 8 bytes, 20 bytes, 48 bytes}] | +func (cs ConsensusState) EncodeConsensusState() ([]byte, error) { + validatorSetLength := uint64(len(cs.ValidatorSet.Validators)) + serializeLength := chainIDLength + heightLength + validatorSetHashLength + validatorSetLength*singleValidatorBytesLength + if serializeLength > maxConsensusStateLength { + return nil, fmt.Errorf("too many validators %d, consensus state bytes should not exceed %d", len(cs.ValidatorSet.Validators), maxConsensusStateLength) + } + + encodingBytes := make([]byte, serializeLength) + + pos := uint64(0) + if uint64(len(cs.ChainID)) > chainIDLength { + return nil, fmt.Errorf("chainID length should be no more than 32") + } + copy(encodingBytes[pos:pos+chainIDLength], cs.ChainID) + pos += chainIDLength + + binary.BigEndian.PutUint64(encodingBytes[pos:pos+heightLength], cs.Height) + pos += heightLength + + copy(encodingBytes[pos:pos+validatorSetHashLength], cs.NextValidatorSetHash) + pos += validatorSetHashLength + + for index := uint64(0); index < validatorSetLength; index++ { + validator := cs.ValidatorSet.Validators[index] + pubkey, ok := validator.PubKey.(ed25519.PubKey) + if !ok { + return nil, fmt.Errorf("invalid pubkey type") + } + + copy(encodingBytes[pos:pos+validatorPubkeyLength], pubkey[:]) + pos += validatorPubkeyLength + + binary.BigEndian.PutUint64(encodingBytes[pos:pos+validatorVotingPowerLength], uint64(validator.VotingPower)) + pos += validatorVotingPowerLength + + copy(encodingBytes[pos:pos+relayerAddressLength], validator.RelayerAddress) + pos += relayerAddressLength + + copy(encodingBytes[pos:pos+relayerBlsKeyLength], validator.BlsKey) + pos += relayerBlsKeyLength + } + + return encodingBytes, nil +} + +func (cs *ConsensusState) ApplyLightBlock(block *types.LightBlock) (bool, error) { + if uint64(block.Height) <= cs.Height { + return false, fmt.Errorf("block height <= consensus height (%d < %d)", block.Height, cs.Height) + } + + if err := block.ValidateBasic(cs.ChainID); err != nil { + return false, err + } + + if cs.Height == uint64(block.Height-1) { + if !bytes.Equal(cs.NextValidatorSetHash, block.ValidatorsHash) { + return false, fmt.Errorf("validators hash mismatch, expected: %s, real: %s", cs.NextValidatorSetHash, block.ValidatorsHash) + } + err := block.ValidatorSet.VerifyCommitLight(cs.ChainID, block.Commit.BlockID, block.Height, block.Commit) + if err != nil { + return false, err + } + } else { + // Ensure that +`trustLevel` (default 1/3) or more of last trusted validators signed correctly. + err := cs.ValidatorSet.VerifyCommitLightTrusting(cs.ChainID, block.Commit, light.DefaultTrustLevel) + if err != nil { + return false, err + } + + // Ensure that +2/3 of new validators signed correctly. + // + // NOTE: this should always be the last check because untrustedVals can be + // intentionally made very large to DOS the light client. not the case for + // VerifyAdjacent, where validator set is known in advance. + err = block.ValidatorSet.VerifyCommitLight(cs.ChainID, block.Commit.BlockID, block.Height, block.Commit) + if err != nil { + return false, err + } + } + + // update consensus state + cs.Height = uint64(block.Height) + cs.NextValidatorSetHash = block.NextValidatorsHash + cs.ValidatorSet = block.ValidatorSet + + return !(bytes.Equal(cs.ValidatorSet.Hash(), block.ValidatorsHash)), nil +} + +// input: +// | chainID | height | nextValidatorSetHash | [{validator pubkey, voting power, relayer address, relayer bls pubkey}] | +// | 32 bytes | 8 bytes | 32 bytes | [{32 bytes, 8 bytes, 20 bytes, 48 bytes}] | +func DecodeConsensusState(input []byte) (ConsensusState, error) { + minimumLength := chainIDLength + heightLength + validatorSetHashLength + inputLen := uint64(len(input)) + if inputLen <= minimumLength || (inputLen-minimumLength)%singleValidatorBytesLength != 0 { + return ConsensusState{}, fmt.Errorf("expected input size %d+%d*N, actual input size: %d", minimumLength, singleValidatorBytesLength, inputLen) + } + + pos := uint64(0) + chainID := string(bytes.Trim(input[pos:pos+chainIDLength], "\x00")) + pos += chainIDLength + + height := binary.BigEndian.Uint64(input[pos : pos+heightLength]) + pos += heightLength + + nextValidatorSetHash := input[pos : pos+validatorSetHashLength] + pos += validatorSetHashLength + + validatorSetLength := (inputLen - minimumLength) / singleValidatorBytesLength + validatorSetBytes := input[pos:] + validatorSet := make([]*types.Validator, 0, validatorSetLength) + for index := uint64(0); index < validatorSetLength; index++ { + validatorBytes := validatorSetBytes[singleValidatorBytesLength*index : singleValidatorBytesLength*(index+1)] + + pos = 0 + pubkey := ed25519.PubKey(make([]byte, ed25519.PubKeySize)) + copy(pubkey[:], validatorBytes[:validatorPubkeyLength]) + pos += validatorPubkeyLength + + votingPower := int64(binary.BigEndian.Uint64(validatorBytes[pos : pos+validatorVotingPowerLength])) + pos += validatorVotingPowerLength + + relayerAddress := make([]byte, relayerAddressLength) + copy(relayerAddress, validatorBytes[pos:pos+relayerAddressLength]) + pos += relayerAddressLength + + relayerBlsKey := make([]byte, relayerBlsKeyLength) + copy(relayerBlsKey, validatorBytes[pos:]) + + validator := types.NewValidator(pubkey, votingPower) + validator.SetRelayerAddress(relayerAddress) + validator.SetBlsKey(relayerBlsKey) + validatorSet = append(validatorSet, validator) + } + + consensusState := ConsensusState{ + ChainID: chainID, + Height: height, + NextValidatorSetHash: nextValidatorSetHash, + ValidatorSet: &types.ValidatorSet{ + Validators: validatorSet, + }, + } + + return consensusState, nil +} + +// input: +// consensus state length | consensus state | light block | +// 32 bytes | | | +func DecodeLightBlockValidationInput(input []byte) (*ConsensusState, *types.LightBlock, error) { + if uint64(len(input)) <= consensusStateLengthBytesLength { + return nil, nil, fmt.Errorf("invalid input") + } + + csLen := binary.BigEndian.Uint64(input[consensusStateLengthBytesLength-uint64TypeLength : consensusStateLengthBytesLength]) + if uint64(len(input)) <= consensusStateLengthBytesLength+csLen { + return nil, nil, fmt.Errorf("expected payload size %d, actual size: %d", consensusStateLengthBytesLength+csLen, len(input)) + } + + cs, err := DecodeConsensusState(input[consensusStateLengthBytesLength : consensusStateLengthBytesLength+csLen]) + if err != nil { + return nil, nil, err + } + + var lbpb tmproto.LightBlock + err = lbpb.Unmarshal(input[consensusStateLengthBytesLength+csLen:]) + if err != nil { + return nil, nil, err + } + block, err := types.LightBlockFromProto(&lbpb) + if err != nil { + return nil, nil, err + } + + return &cs, block, nil +} + +// output: +// | validatorSetChanged | empty | consensusStateBytesLength | new consensusState | +// | 1 byte | 23 bytes | 8 bytes | | +func EncodeLightBlockValidationResult(validatorSetChanged bool, consensusStateBytes []byte) []byte { + lengthBytes := make([]byte, validateResultMetaDataLength) + if validatorSetChanged { + copy(lengthBytes[:1], []byte{0x01}) + } + + consensusStateBytesLength := uint64(len(consensusStateBytes)) + binary.BigEndian.PutUint64(lengthBytes[validateResultMetaDataLength-uint64TypeLength:], consensusStateBytesLength) + + result := append(lengthBytes, consensusStateBytes...) + return result +} diff --git a/core/vm/lightclient/v2/lightclient_test.go b/core/vm/lightclient/v2/lightclient_test.go new file mode 100644 index 00000000000..7519ad2a19a --- /dev/null +++ b/core/vm/lightclient/v2/lightclient_test.go @@ -0,0 +1,174 @@ +// Package v2 is used for tendermint v0.34.22 and its compatible version. +package v2 + +import ( + "bytes" + "encoding/hex" + "testing" + + "github.com/stretchr/testify/require" + + "github.com/cometbft/cometbft/crypto/ed25519" + tmproto "github.com/cometbft/cometbft/proto/tendermint/types" + "github.com/cometbft/cometbft/types" +) + +type validatorInfo struct { + pubKey string + votingPower int64 + relayerAddress string + relayerBlsKey string +} + +var testcases = []struct { + chainID string + height uint64 + nextValidatorSetHash string + vals []validatorInfo + consensusStateBytes string +}{ + { + chainID: "chain_9000-121", + height: 1, + nextValidatorSetHash: "0CE856B1DC9CDCF3BF2478291CF02C62AEEB3679889E9866931BF1FB05A10EDA", + vals: []validatorInfo{ + { + pubKey: "c3d9a1082f42ca161402f8668f8e39ec9e30092affd8d3262267ac7e248a959e", + votingPower: int64(10000), + relayerAddress: "B32d0723583040F3A16D1380D1e6AA874cD1bdF7", + relayerBlsKey: "a60afe627fd78b19e07e07e19d446009dd53a18c6c8744176a5d851a762bbb51198e7e006f2a6ea7225661a61ecd832d", + }, + }, + consensusStateBytes: "636861696e5f393030302d31323100000000000000000000000000000000000000000000000000010ce856b1dc9cdcf3bf2478291cf02c62aeeb3679889e9866931bf1fb05a10edac3d9a1082f42ca161402f8668f8e39ec9e30092affd8d3262267ac7e248a959e0000000000002710b32d0723583040f3a16d1380d1e6aa874cd1bdf7a60afe627fd78b19e07e07e19d446009dd53a18c6c8744176a5d851a762bbb51198e7e006f2a6ea7225661a61ecd832d", + }, + { + chainID: "chain_9000-121", + height: 1, + nextValidatorSetHash: "A5F1AF4874227F1CDBE5240259A365AD86484A4255BFD65E2A0222D733FCDBC3", + vals: []validatorInfo{ + { + pubKey: "20cc466ee9412ddd49e0fff04cdb41bade2b7622f08b6bdacac94d4de03bdb97", + votingPower: int64(10000), + relayerAddress: "d5e63aeee6e6fa122a6a23a6e0fca87701ba1541", + relayerBlsKey: "aa2d28cbcd1ea3a63479f6fb260a3d755853e6a78cfa6252584fee97b2ec84a9d572ee4a5d3bc1558bb98a4b370fb861", + }, + { + pubKey: "6b0b523ee91ad18a63d63f21e0c40a83ef15963f4260574ca5159fd90a1c5270", + votingPower: int64(10000), + relayerAddress: "6fd1ceb5a48579f322605220d4325bd9ff90d5fa", + relayerBlsKey: "b31e74a881fc78681e3dfa440978d2b8be0708a1cbbca2c660866216975fdaf0e9038d9b7ccbf9731f43956dba7f2451", + }, + { + pubKey: "919606ae20bf5d248ee353821754bcdb456fd3950618fda3e32d3d0fb990eeda", + votingPower: int64(10000), + relayerAddress: "97376a436bbf54e0f6949b57aa821a90a749920a", + relayerBlsKey: "b32979580ea04984a2be033599c20c7a0c9a8d121b57f94ee05f5eda5b36c38f6e354c89328b92cdd1de33b64d3a0867", + }, + }, + consensusStateBytes: "636861696e5f393030302d3132310000000000000000000000000000000000000000000000000001a5f1af4874227f1cdbe5240259a365ad86484a4255bfd65e2a0222d733fcdbc320cc466ee9412ddd49e0fff04cdb41bade2b7622f08b6bdacac94d4de03bdb970000000000002710d5e63aeee6e6fa122a6a23a6e0fca87701ba1541aa2d28cbcd1ea3a63479f6fb260a3d755853e6a78cfa6252584fee97b2ec84a9d572ee4a5d3bc1558bb98a4b370fb8616b0b523ee91ad18a63d63f21e0c40a83ef15963f4260574ca5159fd90a1c527000000000000027106fd1ceb5a48579f322605220d4325bd9ff90d5fab31e74a881fc78681e3dfa440978d2b8be0708a1cbbca2c660866216975fdaf0e9038d9b7ccbf9731f43956dba7f2451919606ae20bf5d248ee353821754bcdb456fd3950618fda3e32d3d0fb990eeda000000000000271097376a436bbf54e0f6949b57aa821a90a749920ab32979580ea04984a2be033599c20c7a0c9a8d121b57f94ee05f5eda5b36c38f6e354c89328b92cdd1de33b64d3a0867", + }, +} + +func TestEncodeConsensusState(t *testing.T) { + for i := 0; i < len(testcases); i++ { + testcase := testcases[i] + + var validatorSet []*types.Validator + + for j := 0; j < len(testcase.vals); j++ { + valInfo := testcase.vals[j] + + pubKeyBytes, err := hex.DecodeString(valInfo.pubKey) + require.NoError(t, err) + relayerAddress, err := hex.DecodeString(valInfo.relayerAddress) + require.NoError(t, err) + relayerBlsKey, err := hex.DecodeString(valInfo.relayerBlsKey) + require.NoError(t, err) + + pubkey := ed25519.PubKey(make([]byte, ed25519.PubKeySize)) + copy(pubkey[:], pubKeyBytes) + validator := types.NewValidator(pubkey, valInfo.votingPower) + validator.SetRelayerAddress(relayerAddress) + validator.SetBlsKey(relayerBlsKey) + validatorSet = append(validatorSet, validator) + } + + nextValidatorHash, err := hex.DecodeString(testcase.nextValidatorSetHash) + require.NoError(t, err) + + consensusState := ConsensusState{ + ChainID: testcase.chainID, + Height: testcase.height, + NextValidatorSetHash: nextValidatorHash, + ValidatorSet: &types.ValidatorSet{ + Validators: validatorSet, + }, + } + + csBytes, err := consensusState.EncodeConsensusState() + require.NoError(t, err) + + expectCsBytes, err := hex.DecodeString(testcase.consensusStateBytes) + require.NoError(t, err) + + if !bytes.Equal(csBytes, expectCsBytes) { + t.Fatalf("Consensus state mimatch, expect: %s, real:%s\n", testcase.consensusStateBytes, hex.EncodeToString(csBytes)) + } + } +} + +func TestDecodeConsensusState(t *testing.T) { + for i := 0; i < len(testcases); i++ { + testcase := testcases[i] + + csBytes, err := hex.DecodeString(testcase.consensusStateBytes) + require.NoError(t, err) + + cs, err := DecodeConsensusState(csBytes) + require.NoError(t, err) + + if cs.ChainID != testcase.chainID { + t.Fatalf("Chain ID mimatch, expect: %s, real:%s\n", testcase.chainID, cs.ChainID) + } + + if cs.Height != testcase.height { + t.Fatalf("Height mimatch, expect: %d, real:%d\n", testcase.height, cs.Height) + } + + nextValidatorSetHashBytes, err := hex.DecodeString(testcase.nextValidatorSetHash) + if err != nil { + t.Fatalf("Decode next validator set hash failed: %v\n", err) + } + + if !bytes.Equal(cs.NextValidatorSetHash, nextValidatorSetHashBytes) { + t.Fatalf("Next validator set hash mimatch, expect: %s, real:%s\n", testcase.nextValidatorSetHash, hex.EncodeToString(cs.NextValidatorSetHash)) + } + } +} + +func TestConsensusStateApplyLightBlock(t *testing.T) { + csBytes, err := hex.DecodeString("677265656e6669656c645f393030302d3132310000000000000000000000000000000000000000013c350cd55b99dc6c2b7da9bef5410fbfb869fede858e7b95bf7ca294e228bb40e33f6e876d63791ebd05ff617a1b4f4ad1aa2ce65e3c3a9cdfb33e0ffa7e8423000000000098968015154514f68ce65a0d9eecc578c0ab12da0a2a28a0805521b5b7ae56eb3fb24555efbfe59e1622bfe9f7be8c9022e9b3f2442739c1ce870b9adee169afe60f674edd7c86451c5363d89052fde8351895eeea166ce5373c36e31b518ed191d0c599aa0f5b0000000000989680432f6c4908a9aa5f3444421f466b11645235c99b831b2a2de9e504d7ea299e52a202ce529808618eb3bfc0addf13d8c5f2df821d81e18f9bc61583510b322d067d46323b0a572635c06a049c0a2a929e3c8184a50cf6a8b95708c25834ade456f399015a0000000000989680864cb9828254d712f8e59b164fc6a9402dc4e6c59065e38cff24f5323c8c5da888a0f97e5ee4ba1e11b0674b0a0d06204c1dfa247c370cd4be3e799fc4f6f48d977ac7ca") + require.NoError(t, err) + t.Logf("cs length: %d\n", len(csBytes)) + blockBytes, err := hex.DecodeString("0aeb060adb030a02080b1213677265656e6669656c645f393030302d3132311802220c08b2d7f3a10610e8d2adb3032a480a20ec6ecb5db4ffb17fabe40c60ca7b8441e9c5d77585d0831186f3c37aa16e9c15122408011220a2ab9e1eb9ea52812f413526e424b326aff2f258a56e00d690db9f805b60fe7e32200f40aeff672e8309b7b0aefbb9a1ae3d4299b5c445b7d54e8ff398488467f0053a20e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b85542203c350cd55b99dc6c2b7da9bef5410fbfb869fede858e7b95bf7ca294e228bb404a203c350cd55b99dc6c2b7da9bef5410fbfb869fede858e7b95bf7ca294e228bb405220294d8fbd0b94b767a7eba9840f299a3586da7fe6b5dead3b7eecba193c400f935a20bc50557c12d7392b0d07d75df0b61232d48f86a74fdea6d1485d9be6317d268c6220e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b8556a20e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b85572146699336aa109d1beab3946198c8e59f3b2cbd92f7a4065e3cd89e315ca39d87dee92835b98f8b8ec0861d6d9bb2c60156df5d375b3ceb1fbe71af6a244907d62548a694165caa660fec7a9b4e7b9198191361c71be0b128a0308021a480a20726abd0fdbfb6f779b0483e6e4b4b6f12241f6ea2bf374233ab1a316692b6415122408011220159f10ff15a8b58fc67a92ffd7f33c8cd407d4ce81b04ca79177dfd00ca19a67226808021214050cff76cc632760ba9db796c046004c900967361a0c08b3d7f3a10610808cadba03224080713027ffb776a702d78fd0406205c629ba473e1f8d6af646190f6eb9262cd67d69be90d10e597b91e06d7298eb6fa4b8f1eb7752ebf352a1f51560294548042268080212146699336aa109d1beab3946198c8e59f3b2cbd92f1a0c08b3d7f3a10610b087c1c00322405e2ddb70acfe4904438be3d9f4206c0ace905ac4fc306a42cfc9e86268950a0fbfd6ec5f526d3e41a3ef52bf9f9f358e3cb4c3feac76c762fa3651c1244fe004226808021214c55765fd2d0570e869f6ac22e7f2916a35ea300d1a0c08b3d7f3a10610f0b3d492032240ca17898bd22232fc9374e1188636ee321a396444a5b1a79f7628e4a11f265734b2ab50caf21e8092c55d701248e82b2f011426cb35ba22043b497a6b4661930612a0050aa8010a14050cff76cc632760ba9db796c046004c9009673612220a20e33f6e876d63791ebd05ff617a1b4f4ad1aa2ce65e3c3a9cdfb33e0ffa7e84231880ade2042080a6bbf6ffffffffff012a30a0805521b5b7ae56eb3fb24555efbfe59e1622bfe9f7be8c9022e9b3f2442739c1ce870b9adee169afe60f674edd7c86321415154514f68ce65a0d9eecc578c0ab12da0a2a283a14ee7a2a6a44d427f6949eeb8f12ea9fbb2501da880aa2010a146699336aa109d1beab3946198c8e59f3b2cbd92f12220a20451c5363d89052fde8351895eeea166ce5373c36e31b518ed191d0c599aa0f5b1880ade2042080ade2042a30831b2a2de9e504d7ea299e52a202ce529808618eb3bfc0addf13d8c5f2df821d81e18f9bc61583510b322d067d46323b3214432f6c4908a9aa5f3444421f466b11645235c99b3a14a0a7769429468054e19059af4867da0a495567e50aa2010a14c55765fd2d0570e869f6ac22e7f2916a35ea300d12220a200a572635c06a049c0a2a929e3c8184a50cf6a8b95708c25834ade456f399015a1880ade2042080ade2042a309065e38cff24f5323c8c5da888a0f97e5ee4ba1e11b0674b0a0d06204c1dfa247c370cd4be3e799fc4f6f48d977ac7ca3214864cb9828254d712f8e59b164fc6a9402dc4e6c53a143139916d97df0c589312b89950b6ab9795f34d1a12a8010a14050cff76cc632760ba9db796c046004c9009673612220a20e33f6e876d63791ebd05ff617a1b4f4ad1aa2ce65e3c3a9cdfb33e0ffa7e84231880ade2042080a6bbf6ffffffffff012a30a0805521b5b7ae56eb3fb24555efbfe59e1622bfe9f7be8c9022e9b3f2442739c1ce870b9adee169afe60f674edd7c86321415154514f68ce65a0d9eecc578c0ab12da0a2a283a14ee7a2a6a44d427f6949eeb8f12ea9fbb2501da88") + require.NoError(t, err) + + var lbpb tmproto.LightBlock + err = lbpb.Unmarshal(blockBytes) + require.NoError(t, err) + block, err := types.LightBlockFromProto(&lbpb) + require.NoError(t, err) + + cs, err := DecodeConsensusState(csBytes) + require.NoError(t, err) + validatorSetChanged, err := cs.ApplyLightBlock(block) + require.NoError(t, err) + + if cs.Height != 2 { + t.Fatalf("Height is unexpected, expected: 2, actual: %d\n", cs.Height) + } + + if validatorSetChanged { + t.Fatalf("Validator set has exchanaged which is not expected.\n") + } +} diff --git a/crypto/kzg/kzg.go b/crypto/kzg/kzg.go new file mode 100644 index 00000000000..b90e60052d6 --- /dev/null +++ b/crypto/kzg/kzg.go @@ -0,0 +1,113 @@ +package kzg + +import ( + "crypto/sha256" + "errors" + "fmt" + "math/big" + "sync" + + gokzg4844 "github.com/crate-crypto/go-kzg-4844" +) + +const ( + BlobCommitmentVersionKZG uint8 = 0x01 + FieldElementsPerBlob int = 4096 +) + +type VersionedHash [32]byte +type Root [32]byte +type Slot uint64 + +type BlobsSidecar struct { + BeaconBlockRoot Root + BeaconBlockSlot Slot + Blobs []gokzg4844.Blob + Proofs []gokzg4844.KZGProof +} + +const ( + BlobTxType = 5 + PrecompileInputLength = 192 + BlobVersionedHashesOffset = 258 // position of blob_versioned_hashes offset in a serialized blob tx, see TxPeekBlobVersionedHashes +) + +var ( + errInvalidInputLength = errors.New("invalid input length") +) + +// The value that gets returned when the `verify_kzg_proof“ precompile is called +var precompileReturnValue [64]byte + +var gCryptoCtx gokzg4844.Context +var initCryptoCtx sync.Once + +// InitializeCrypytoCtx initializes the global context object returned via CryptoCtx +func InitializeCrypytoCtx() { + initCryptoCtx.Do(func() { + // Initialize context to match the configurations that the + // specs are using. + ctx, err := gokzg4844.NewContext4096Insecure1337() + if err != nil { + panic(fmt.Sprintf("could not create context, err : %v", err)) + } + gCryptoCtx = *ctx + // Initialize the precompile return value + new(big.Int).SetUint64(gokzg4844.ScalarsPerBlob).FillBytes(precompileReturnValue[:32]) + copy(precompileReturnValue[32:], gokzg4844.BlsModulus[:]) + }) +} + +// CryptoCtx returns a context object stores all of the necessary configurations +// to allow one to create and verify blob proofs. +// This function is expensive to run if the crypto context isn't initialized, so it is recommended to +// pre-initialize by calling InitializeCryptoCtx +func CrpytoCtx() gokzg4844.Context { + InitializeCrypytoCtx() + return gCryptoCtx +} + +// PointEvaluationPrecompile implements point_evaluation_precompile from EIP-4844 +func PointEvaluationPrecompile(input []byte) ([]byte, error) { + if len(input) != PrecompileInputLength { + return nil, errInvalidInputLength + } + // versioned hash: first 32 bytes + var versionedHash [32]byte + copy(versionedHash[:], input[:32]) + + var x, y [32]byte + // Evaluation point: next 32 bytes + copy(x[:], input[32:64]) + // Expected output: next 32 bytes + copy(y[:], input[64:96]) + + // input kzg point: next 48 bytes + var dataKZG [48]byte + copy(dataKZG[:], input[96:144]) + if KZGToVersionedHash(gokzg4844.KZGCommitment(dataKZG)) != VersionedHash(versionedHash) { + return nil, errors.New("mismatched versioned hash") + } + + // Quotient kzg: next 48 bytes + var quotientKZG [48]byte + copy(quotientKZG[:], input[144:PrecompileInputLength]) + + cryptoCtx := CrpytoCtx() + err := cryptoCtx.VerifyKZGProof(dataKZG, x, y, quotientKZG) + if err != nil { + return nil, fmt.Errorf("verify_kzg_proof error: %v", err) + } + + result := precompileReturnValue // copy the value + + return result[:], nil +} + +// KZGToVersionedHash implements kzg_to_versioned_hash from EIP-4844 +func KZGToVersionedHash(kzg gokzg4844.KZGCommitment) VersionedHash { + h := sha256.Sum256(kzg[:]) + h[0] = BlobCommitmentVersionKZG + + return VersionedHash(h) +} diff --git a/crypto/signature_nocgo.go b/crypto/signature_nocgo.go index 338ee4b2482..0edc7afd68e 100644 --- a/crypto/signature_nocgo.go +++ b/crypto/signature_nocgo.go @@ -23,37 +23,48 @@ import ( "crypto/elliptic" "errors" "fmt" - "math/big" "github.com/btcsuite/btcd/btcec" + btc_ecdsa "github.com/btcsuite/btcd/btcec/v2/ecdsa" ) // Ecrecover returns the uncompressed public key that created the given signature. func Ecrecover(hash, sig []byte) ([]byte, error) { - pub, err := SigToPub(hash, sig) + pub, err := sigToPub(hash, sig) if err != nil { return nil, err } - bytes := (*btcec.PublicKey)(pub).SerializeUncompressed() + bytes := pub.SerializeUncompressed() return bytes, err } -// SigToPub returns the public key that created the given signature. -func SigToPub(hash, sig []byte) (*ecdsa.PublicKey, error) { +func sigToPub(hash, sig []byte) (*btcec.PublicKey, error) { + if len(sig) != SignatureLength { + return nil, errors.New("invalid signature") + } // Convert to btcec input format with 'recovery id' v at the beginning. btcsig := make([]byte, SignatureLength) - btcsig[0] = sig[64] + 27 + btcsig[0] = sig[RecoveryIDOffset] + 27 copy(btcsig[1:], sig) - pub, _, err := btcec.RecoverCompact(btcec.S256(), btcsig, hash) - return (*ecdsa.PublicKey)(pub), err + pub, _, err := btc_ecdsa.RecoverCompact(btcsig, hash) + return pub, err +} + +// SigToPub returns the public key that created the given signature. +func SigToPub(hash, sig []byte) (*ecdsa.PublicKey, error) { + pub, err := sigToPub(hash, sig) + if err != nil { + return nil, err + } + return pub.ToECDSA(), nil } // Sign calculates an ECDSA signature. // // This function is susceptible to chosen plaintext attacks that can leak // information about the private key that is used for signing. Callers must -// be aware that the given hash cannot be chosen by an adversery. Common +// be aware that the given hash cannot be chosen by an adversary. Common // solution is to hash any input before calculating the signature. // // The produced signature is in the [R || S || V] format where V is 0 or 1. @@ -64,14 +75,20 @@ func Sign(hash []byte, prv *ecdsa.PrivateKey) ([]byte, error) { if prv.Curve != btcec.S256() { return nil, fmt.Errorf("private key curve is not secp256k1") } - sig, err := btcec.SignCompact(btcec.S256(), (*btcec.PrivateKey)(prv), hash, false) + // ecdsa.PrivateKey -> btcec.PrivateKey + var priv btcec.PrivateKey + if overflow := priv.Key.SetByteSlice(prv.D.Bytes()); overflow || priv.Key.IsZero() { + return nil, fmt.Errorf("invalid private key") + } + defer priv.Zero() + sig, err := btc_ecdsa.SignCompact(&priv, hash, false) // ref uncompressed pubkey if err != nil { return nil, err } // Convert to Ethereum signature format with 'recovery id' v at the end. v := sig[0] - 27 copy(sig, sig[1:]) - sig[64] = v + sig[RecoveryIDOffset] = v return sig, nil } @@ -82,13 +99,20 @@ func VerifySignature(pubkey, hash, signature []byte) bool { if len(signature) != 64 { return false } - sig := &btcec.Signature{R: new(big.Int).SetBytes(signature[:32]), S: new(big.Int).SetBytes(signature[32:])} - key, err := btcec.ParsePubKey(pubkey, btcec.S256()) + var r, s btcec.ModNScalar + if r.SetByteSlice(signature[:32]) { + return false // overflow + } + if s.SetByteSlice(signature[32:]) { + return false + } + sig := btc_ecdsa.NewSignature(&r, &s) + key, err := btcec.ParsePubKey(pubkey) if err != nil { return false } // Reject malleable signatures. libsecp256k1 does this check but btcec doesn't. - if sig.S.Cmp(secp256k1halfN.ToBig()) > 0 { + if s.IsOverHalfOrder() { return false } return sig.Verify(hash, key) @@ -99,16 +123,26 @@ func DecompressPubkey(pubkey []byte) (*ecdsa.PublicKey, error) { if len(pubkey) != 33 { return nil, errors.New("invalid compressed public key length") } - key, err := btcec.ParsePubKey(pubkey, btcec.S256()) + key, err := btcec.ParsePubKey(pubkey) if err != nil { return nil, err } return key.ToECDSA(), nil } -// CompressPubkey encodes a public key to the 33-byte compressed format. +// CompressPubkey encodes a public key to the 33-byte compressed format. The +// provided PublicKey must be valid. Namely, the coordinates must not be larger +// than 32 bytes each, they must be less than the field prime, and it must be a +// point on the secp256k1 curve. This is the case for a PublicKey constructed by +// elliptic.Unmarshal (see UnmarshalPubkey), or by ToECDSA and ecdsa.GenerateKey +// when constructing a PrivateKey. func CompressPubkey(pubkey *ecdsa.PublicKey) []byte { - return (*btcec.PublicKey)(pubkey).SerializeCompressed() + // NOTE: the coordinates may be validated with + // btcec.ParsePubKey(FromECDSAPub(pubkey)) + var x, y btcec.FieldVal + x.SetByteSlice(pubkey.X.Bytes()) + y.SetByteSlice(pubkey.Y.Bytes()) + return btcec.NewPublicKey(&x, &y).SerializeCompressed() } // S256 returns an instance of the secp256k1 curve. diff --git a/dataflow/states.go b/dataflow/states.go new file mode 100644 index 00000000000..8eab162c6a3 --- /dev/null +++ b/dataflow/states.go @@ -0,0 +1,106 @@ +package dataflow + +import ( + "fmt" + "io" + "sync" + + "github.com/google/btree" +) + +var BlockBodyDownloadStates *States = NewStates(64 * 1024) + +const ( + BlockBodyCleared byte = iota + BlockBodyExpired + BlockBodyRequested + BlockBodyReceived + BlockBodyEvicted + BlockBodySkipped // Delivery requested but was skipped due to limitation on the size of the response + BlockBodyEmpty // Identified as empty and no need to be requested + BlockBodyPrefetched + BlockBodyInDb +) + +type SnapshotItem struct { + id uint64 + state byte +} + +type States struct { + lock sync.Mutex + window int + ids []uint64 + states []byte + snapshot *btree.BTreeG[SnapshotItem] + snapshotTick int + idx int +} + +func NewStates(window int) *States { + s := &States{ + window: window, + ids: make([]uint64, window), + states: make([]byte, window), + snapshot: btree.NewG[SnapshotItem](16, func(a, b SnapshotItem) bool { + return a.id < b.id + }), + idx: 0, + } + return s +} + +func (s *States) AddChange(id uint64, state byte) { + s.lock.Lock() + defer s.lock.Unlock() + if s.idx >= s.window { + s.makeSnapshot() + } + i := s.idx + s.idx++ + s.ids[i] = id + s.states[i] = state +} + +func (s *States) makeSnapshot() { + newSnapshot := map[uint64]byte{} + // snapshotTime is now time of the latest change + s.snapshotTick += s.idx + // Proceed backwards + for i := s.idx - 1; i >= 0; i-- { + if _, ok := newSnapshot[s.ids[i]]; !ok { + newSnapshot[s.ids[i]] = s.states[i] + } + } + for id, state := range newSnapshot { + if state == 0 { + s.snapshot.Delete(SnapshotItem{id: id}) + } else { + s.snapshot.ReplaceOrInsert(SnapshotItem{id: id, state: state}) + } + } + s.idx = 0 +} + +func (s *States) ChangesSince(startTick int, w io.Writer) { + s.lock.Lock() + defer s.lock.Unlock() + var startI int + var tick int + if startTick <= s.snapshotTick { + // Include snapshot + fmt.Fprintf(w, "snapshot %d\n", s.snapshotTick) + s.snapshot.Ascend(func(a SnapshotItem) bool { + fmt.Fprintf(w, "%d,%d\n", a.id, a.state) + return true + }) + tick = s.snapshotTick + 1 + } else { + startI = startTick - s.snapshotTick + tick = startTick + } + fmt.Fprintf(w, "changes %d\n", tick) + for i := startI; i < s.idx; i++ { + fmt.Fprintf(w, "%d,%d\n", s.ids[i], s.states[i]) + } +} diff --git a/diagnostics/block_body_download.go b/diagnostics/block_body_download.go new file mode 100644 index 00000000000..c60fa1b9bab --- /dev/null +++ b/diagnostics/block_body_download.go @@ -0,0 +1,34 @@ +package diagnostics + +import ( + "fmt" + "io" + "net/http" + "strconv" + + "github.com/ledgerwatch/erigon/dataflow" +) + +func SetupBlockBodyDownload() { + http.HandleFunc("/debug/metrics/block_body_download", func(w http.ResponseWriter, r *http.Request) { + w.Header().Set("Access-Control-Allow-Origin", "*") + writeBlockBodyDownload(w, r) + }) +} + +func writeBlockBodyDownload(w io.Writer, r *http.Request) { + if err := r.ParseForm(); err != nil { + fmt.Fprintf(w, "ERROR: parsing arguments: %v\n", err) + return + } + sinceTickStr := r.Form.Get("sincetick") + var tick int64 + if sinceTickStr != "" { + var err error + if tick, err = strconv.ParseInt(sinceTickStr, 10, 64); err != nil { + fmt.Fprintf(w, "ERROR: parsing sincemilli: %v\n", err) + } + } + fmt.Fprintf(w, "SUCCESS\n") + dataflow.BlockBodyDownloadStates.ChangesSince(int(tick), w) +} diff --git a/diagnostics/cmd_line.go b/diagnostics/cmd_line.go new file mode 100644 index 00000000000..067861d7ba7 --- /dev/null +++ b/diagnostics/cmd_line.go @@ -0,0 +1,22 @@ +package diagnostics + +import ( + "fmt" + "io" + "net/http" + "os" +) + +func SetupCmdLineAccess() { + http.HandleFunc("/debug/metrics/cmdline", func(w http.ResponseWriter, r *http.Request) { + w.Header().Set("Access-Control-Allow-Origin", "*") + writeCmdLine(w) + }) +} + +func writeCmdLine(w io.Writer) { + fmt.Fprintf(w, "SUCCESS\n") + for _, arg := range os.Args { + fmt.Fprintf(w, "%s\n", arg) + } +} diff --git a/diagnostics/logs_access.go b/diagnostics/logs_access.go index 7c988b83124..58bfe69b15b 100644 --- a/diagnostics/logs_access.go +++ b/diagnostics/logs_access.go @@ -17,6 +17,12 @@ import ( func SetupLogsAccess(ctx *cli.Context) { dirPath := ctx.String(logging.LogDirPathFlag.Name) + if dirPath == "" { + datadir := ctx.String("datadir") + if datadir != "" { + dirPath = filepath.Join(datadir, "logs") + } + } if dirPath == "" { return } diff --git a/diagnostics/version.go b/diagnostics/version.go new file mode 100644 index 00000000000..a8b97e73d2e --- /dev/null +++ b/diagnostics/version.go @@ -0,0 +1,25 @@ +package diagnostics + +import ( + "fmt" + "io" + "net/http" + + "github.com/ledgerwatch/erigon/params" +) + +const Version = 1 + +func SetupVersionAccess() { + http.HandleFunc("/debug/metrics/version", func(w http.ResponseWriter, r *http.Request) { + w.Header().Set("Access-Control-Allow-Origin", "*") + writeVersion(w) + }) +} + +func writeVersion(w io.Writer) { + fmt.Fprintf(w, "SUCCESS\n") + fmt.Fprintf(w, "%d\n", Version) + fmt.Fprintf(w, "%s\n", params.VersionWithMeta) + fmt.Fprintf(w, "%s\n", params.GitCommit) +} diff --git a/docker-compose.yml b/docker-compose.yml index a7ea8b9eeea..bf5982c9b4a 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -71,7 +71,7 @@ services: prometheus: - image: prom/prometheus:v2.42.0 + image: prom/prometheus:v2.43.0 user: ${DOCKER_UID:-1000}:${DOCKER_GID:-1000} # Uses erigon user from Dockerfile command: --log.level=warn --config.file=/etc/prometheus/prometheus.yml --storage.tsdb.path=/prometheus --storage.tsdb.retention.time=150d --web.console.libraries=/usr/share/prometheus/console_libraries --web.console.templates=/usr/share/prometheus/consoles ports: [ "9090:9090" ] @@ -81,7 +81,7 @@ services: restart: unless-stopped grafana: - image: grafana/grafana:9.3.6 + image: grafana/grafana:9.4.7 user: "472:0" # required for grafana version >= 7.3 ports: [ "3000:3000" ] volumes: diff --git a/eth/backend.go b/eth/backend.go index 9ac659a7080..562beb8ad58 100644 --- a/eth/backend.go +++ b/eth/backend.go @@ -32,6 +32,12 @@ import ( "time" "github.com/holiman/uint256" + "github.com/ledgerwatch/log/v3" + "golang.org/x/exp/slices" + "google.golang.org/grpc" + "google.golang.org/grpc/credentials" + "google.golang.org/protobuf/types/known/emptypb" + "github.com/ledgerwatch/erigon-lib/chain" libcommon "github.com/ledgerwatch/erigon-lib/common" "github.com/ledgerwatch/erigon-lib/common/datadir" @@ -49,31 +55,19 @@ import ( "github.com/ledgerwatch/erigon-lib/kv" "github.com/ledgerwatch/erigon-lib/kv/kvcache" "github.com/ledgerwatch/erigon-lib/kv/kvcfg" - "github.com/ledgerwatch/erigon-lib/kv/memdb" "github.com/ledgerwatch/erigon-lib/kv/remotedbserver" libstate "github.com/ledgerwatch/erigon-lib/state" txpool2 "github.com/ledgerwatch/erigon-lib/txpool" "github.com/ledgerwatch/erigon-lib/txpool/txpooluitl" types2 "github.com/ledgerwatch/erigon-lib/types" - "github.com/ledgerwatch/erigon/core/systemcontracts" - "github.com/ledgerwatch/erigon/p2p/enode" - "github.com/ledgerwatch/log/v3" - "golang.org/x/exp/slices" - "google.golang.org/grpc" - "google.golang.org/grpc/credentials" - "google.golang.org/protobuf/types/known/emptypb" - - "github.com/ledgerwatch/erigon/core/state/historyv2read" - "github.com/ledgerwatch/erigon/core/state/temporal" - "github.com/ledgerwatch/erigon/core/types/accounts" "github.com/ledgerwatch/erigon/cl/clparams" + "github.com/ledgerwatch/erigon/cmd/caplin-phase1/caplin1" clcore "github.com/ledgerwatch/erigon/cmd/erigon-cl/core" - "github.com/ledgerwatch/erigon/cmd/lightclient/lightclient" + "github.com/ledgerwatch/erigon/cmd/erigon-cl/execution_client" "github.com/ledgerwatch/erigon/cmd/rpcdaemon/cli" "github.com/ledgerwatch/erigon/cmd/rpcdaemon/commands" "github.com/ledgerwatch/erigon/cmd/sentinel/sentinel" - "github.com/ledgerwatch/erigon/cmd/sentinel/sentinel/handshake" "github.com/ledgerwatch/erigon/cmd/sentinel/sentinel/service" "github.com/ledgerwatch/erigon/cmd/sentry/sentry" "github.com/ledgerwatch/erigon/common/debug" @@ -85,7 +79,11 @@ import ( "github.com/ledgerwatch/erigon/consensus/serenity" "github.com/ledgerwatch/erigon/core" "github.com/ledgerwatch/erigon/core/rawdb" + "github.com/ledgerwatch/erigon/core/state/historyv2read" + "github.com/ledgerwatch/erigon/core/state/temporal" + "github.com/ledgerwatch/erigon/core/systemcontracts" "github.com/ledgerwatch/erigon/core/types" + "github.com/ledgerwatch/erigon/core/types/accounts" "github.com/ledgerwatch/erigon/core/vm" "github.com/ledgerwatch/erigon/crypto" "github.com/ledgerwatch/erigon/eth/ethconfig" @@ -99,6 +97,7 @@ import ( "github.com/ledgerwatch/erigon/ethstats" "github.com/ledgerwatch/erigon/node" "github.com/ledgerwatch/erigon/p2p" + "github.com/ledgerwatch/erigon/p2p/enode" "github.com/ledgerwatch/erigon/params" "github.com/ledgerwatch/erigon/rpc" "github.com/ledgerwatch/erigon/turbo/engineapi" @@ -117,7 +116,6 @@ type Config = ethconfig.Config // Ethereum implements the Ethereum full node service. type Ethereum struct { config *ethconfig.Config - log log.Logger // DB interfaces chainDB kv.RwDB @@ -190,7 +188,7 @@ func splitAddrIntoHostAndPort(addr string) (host string, port int, err error) { // New creates a new Ethereum object (including the // initialisation of the common Ethereum object) -func New(stack *node.Node, config *ethconfig.Config, logger log.Logger) (*Ethereum, error) { +func New(stack *node.Node, config *ethconfig.Config) (*Ethereum, error) { if config.Miner.GasPrice == nil || config.Miner.GasPrice.Cmp(libcommon.Big0) <= 0 { log.Warn("Sanitizing invalid miner gas price", "provided", config.Miner.GasPrice, "updated", ethconfig.Defaults.Miner.GasPrice) config.Miner.GasPrice = new(big.Int).Set(ethconfig.Defaults.Miner.GasPrice) @@ -203,7 +201,7 @@ func New(stack *node.Node, config *ethconfig.Config, logger log.Logger) (*Ethere } // Assemble the Ethereum object - chainKv, err := node.OpenDatabase(stack.Config(), logger, kv.ChainDB) + chainKv, err := node.OpenDatabase(stack.Config(), kv.ChainDB) if err != nil { return nil, err } @@ -288,7 +286,6 @@ func New(stack *node.Node, config *ethconfig.Config, logger log.Logger) (*Ethere sentryCtx: ctx, sentryCancel: ctxCancel, config: config, - log: logger, chainDB: chainKv, networkID: config.NetworkID, etherbase: config.Miner.Etherbase, @@ -447,7 +444,6 @@ func New(stack *node.Node, config *ethconfig.Config, logger log.Logger) (*Ethere if chainConfig.Clique != nil { consensusConfig = &config.Clique } else if chainConfig.Aura != nil { - config.Aura.Etherbase = config.Miner.Etherbase consensusConfig = &config.Aura } else if chainConfig.Parlia != nil { consensusConfig = &config.Parlia @@ -456,7 +452,7 @@ func New(stack *node.Node, config *ethconfig.Config, logger log.Logger) (*Ethere } else { consensusConfig = &config.Ethash } - backend.engine = ethconsensusconfig.CreateConsensusEngine(chainConfig, logger, consensusConfig, config.Miner.Notify, config.Miner.Noverify, config.HeimdallgRPCAddress, config.HeimdallURL, config.WithoutHeimdall, stack.DataDir(), allSnapshots, false /* readonly */, backend.chainDB) + backend.engine = ethconsensusconfig.CreateConsensusEngine(chainConfig, consensusConfig, config.Miner.Notify, config.Miner.Noverify, config.HeimdallgRPCAddress, config.HeimdallURL, config.WithoutHeimdall, stack.DataDir(), allSnapshots, false /* readonly */, backend.chainDB) backend.forkValidator = engineapi.NewForkValidator(currentBlockNumber, inMemoryExecution, tmpdir) backend.sentriesClient, err = sentry.NewMultiClient( @@ -471,6 +467,7 @@ func New(stack *node.Node, config *ethconfig.Config, logger log.Logger) (*Ethere blockReader, stack.Config().SentryLogPeerInfo, backend.forkValidator, + config.DropUselessPeers, ) if err != nil { return nil, err @@ -566,7 +563,7 @@ func New(stack *node.Node, config *ethconfig.Config, logger log.Logger) (*Ethere } // If we choose not to run a consensus layer, run our embedded. - if !config.ExternalCL && clparams.EmbeddedSupported(config.NetworkID) { + if config.InternalCL && clparams.EmbeddedSupported(config.NetworkID) { genesisCfg, networkCfg, beaconCfg := clparams.GetConfigsByNetwork(clparams.NetworkType(config.NetworkID)) if err != nil { return nil, err @@ -579,27 +576,19 @@ func New(stack *node.Node, config *ethconfig.Config, logger log.Logger) (*Ethere NetworkConfig: networkCfg, BeaconConfig: beaconCfg, TmpDir: tmpdir, - }, chainKv, &service.ServerConfig{Network: "tcp", Addr: fmt.Sprintf("%s:%d", config.SentinelAddr, config.SentinelPort)}, creds, nil, handshake.LightClientRule) + }, chainKv, &service.ServerConfig{Network: "tcp", Addr: fmt.Sprintf("%s:%d", config.SentinelAddr, config.SentinelPort)}, creds, nil) if err != nil { return nil, err } - - lc, err := lightclient.NewLightClient(ctx, memdb.New(tmpdir), genesisCfg, beaconCfg, ethBackendRPC, nil, client, currentBlockNumber, false) - if err != nil { - return nil, err - } - bs, err := clcore.RetrieveBeaconState(ctx, beaconCfg, genesisCfg, + engine := execution_client.NewExecutionEnginePhase1FromServer(ctx, ethBackendRPC) + state, err := clcore.RetrieveBeaconState(ctx, beaconCfg, genesisCfg, clparams.GetCheckpointSyncEndpoint(clparams.NetworkType(config.NetworkID))) if err != nil { return nil, err } - if err := lc.BootstrapCheckpoint(ctx, bs.FinalizedCheckpoint().Root); err != nil { - return nil, err - } - - go lc.Start() + go caplin1.RunCaplinPhase1(ctx, client, beaconCfg, genesisCfg, engine, state) } if currentBlock == nil { @@ -992,7 +981,7 @@ func (s *Ethereum) setUpBlockReader(ctx context.Context, dirs datadir.Dirs, snCo if err != nil { return nil, nil, nil, err } - go downloader3.MainLoop(ctx, s.downloader, true) + s.downloader.MainLoopInBackground(ctx, true) bittorrentServer, err := downloader3.NewGrpcServer(s.downloader) if err != nil { return nil, nil, nil, fmt.Errorf("new server: %w", err) diff --git a/eth/ethconfig/config.go b/eth/ethconfig/config.go index b8a4c1e95fe..87c4a40fd11 100644 --- a/eth/ethconfig/config.go +++ b/eth/ethconfig/config.go @@ -101,6 +101,7 @@ var Defaults = Config{ KeepBlocks: false, Produce: true, }, + DropUselessPeers: false, } func init() { @@ -241,7 +242,7 @@ type Config struct { // Ethstats service Ethstats string // Consensus layer - ExternalCL bool + InternalCL bool LightClientDiscoveryAddr string LightClientDiscoveryPort uint64 LightClientDiscoveryTCPPort uint64 @@ -249,6 +250,8 @@ type Config struct { SentinelPort uint64 OverrideShanghaiTime *big.Int `toml:",omitempty"` + + DropUselessPeers bool } type Sync struct { diff --git a/eth/ethconfig/estimate/esitmated_ram.go b/eth/ethconfig/estimate/esitmated_ram.go index 2798d3cb1b2..7487fcc2fb9 100644 --- a/eth/ethconfig/estimate/esitmated_ram.go +++ b/eth/ethconfig/estimate/esitmated_ram.go @@ -1,11 +1,13 @@ package estimate import ( + "os" "runtime" "github.com/c2h5oh/datasize" "github.com/ledgerwatch/erigon-lib/common/cmp" "github.com/pbnjay/memory" + "github.com/shirou/gopsutil/v3/docker" ) type estimatedRamPerWorker datasize.ByteSize @@ -13,7 +15,7 @@ type estimatedRamPerWorker datasize.ByteSize // Workers - return max workers amount based on total Memory/CPU's and estimated RAM per worker func (r estimatedRamPerWorker) Workers() int { // 50% of TotalMemory. Better don't count on 100% because OOM Killer may have aggressive defaults and other software may need RAM - maxWorkersForGivenMemory := (memory.TotalMemory() / 2) / uint64(r) + maxWorkersForGivenMemory := (totalMemory() / 2) / uint64(r) return cmp.Min(AlmostAllCPUs(), int(maxWorkersForGivenMemory)) } func (r estimatedRamPerWorker) WorkersHalf() int { return cmp.Max(1, r.Workers()/2) } @@ -30,3 +32,29 @@ const ( func AlmostAllCPUs() int { return cmp.Max(1, runtime.GOMAXPROCS(-1)-1) } +func totalMemory() uint64 { + mem := memory.TotalMemory() + + if cgroupsMemLimit, ok := cgroupsMemoryLimit(); ok { + mem = cmp.Min(mem, cgroupsMemLimit) + } + + return mem +} + +// apply limit from docker if can, treat errors as "not available or maybe non-docker environment +// supports only cgroups v1, for v2 see: https://github.com/shirou/gopsutil/issues/1416 +func cgroupsMemoryLimit() (mem uint64, ok bool) { + hostname, err := os.Hostname() + if err != nil { + return 0, false + } + cgmem, err := docker.CgroupMemDocker(hostname) + if err != nil { + return 0, false + } + if cgmem == nil || cgmem.MemLimitInBytes <= 0 { + return 0, false + } + return cgmem.MemLimitInBytes, true +} diff --git a/eth/ethconfig/gen_config.go b/eth/ethconfig/gen_config.go index 502603d1dba..ff557ae08d7 100644 --- a/eth/ethconfig/gen_config.go +++ b/eth/ethconfig/gen_config.go @@ -8,10 +8,10 @@ import ( "github.com/c2h5oh/datasize" "github.com/ledgerwatch/erigon-lib/chain" libcommon "github.com/ledgerwatch/erigon-lib/common" + "github.com/ledgerwatch/erigon/consensus/ethash/ethashcfg" + "github.com/ledgerwatch/erigon/core/types" + "github.com/ledgerwatch/erigon/eth/gasprice/gaspricecfg" - "github.com/ledgerwatch/erigon/consensus/ethash" - "github.com/ledgerwatch/erigon/core" - "github.com/ledgerwatch/erigon/eth/gasprice" "github.com/ledgerwatch/erigon/ethdb/prune" "github.com/ledgerwatch/erigon/params" ) @@ -19,7 +19,7 @@ import ( // MarshalTOML marshals as TOML. func (c Config) MarshalTOML() (interface{}, error) { type Config struct { - Genesis *core.Genesis `toml:",omitempty"` + Genesis *types.Genesis `toml:",omitempty"` NetworkID uint64 EthDiscoveryURLs []string P2PEnabled bool @@ -32,12 +32,11 @@ func (c Config) MarshalTOML() (interface{}, error) { ExternalSnapshotDownloaderAddr string Whitelist map[uint64]libcommon.Hash `toml:"-"` Miner params.MiningConfig - Ethash ethash.Config + Ethash ethashcfg.Config Clique params.ConsensusSnapshotConfig Aura chain.AuRaConfig - Parlia chain.ParliaConfig - TxPool core.TxPoolConfig - GPO gasprice.Config + TxPool DeprecatedTxPoolConfig + GPO gaspricecfg.Config RPCGasCap uint64 `toml:",omitempty"` RPCTxFeeCap float64 `toml:",omitempty"` StateStream bool @@ -60,7 +59,6 @@ func (c Config) MarshalTOML() (interface{}, error) { enc.Ethash = c.Ethash enc.Clique = c.Clique enc.Aura = c.Aura - enc.Parlia = c.Parlia enc.TxPool = c.DeprecatedTxPool enc.GPO = c.GPO enc.RPCGasCap = c.RPCGasCap @@ -72,7 +70,7 @@ func (c Config) MarshalTOML() (interface{}, error) { // UnmarshalTOML unmarshals from TOML. func (c *Config) UnmarshalTOML(unmarshal func(interface{}) error) error { type Config struct { - Genesis *core.Genesis `toml:",omitempty"` + Genesis *types.Genesis `toml:",omitempty"` NetworkID *uint64 EthDiscoveryURLs []string P2PEnabled *bool @@ -85,12 +83,11 @@ func (c *Config) UnmarshalTOML(unmarshal func(interface{}) error) error { ExternalSnapshotDownloaderAddr *string Whitelist map[uint64]libcommon.Hash `toml:"-"` Miner *params.MiningConfig - Ethash *ethash.Config + Ethash *ethashcfg.Config Clique *params.ConsensusSnapshotConfig Aura *chain.AuRaConfig - Parlia *chain.ParliaConfig - TxPool *core.TxPoolConfig - GPO *gasprice.Config + TxPool *DeprecatedTxPoolConfig + GPO *gaspricecfg.Config RPCGasCap *uint64 `toml:",omitempty"` RPCTxFeeCap *float64 `toml:",omitempty"` StateStream *bool @@ -146,9 +143,6 @@ func (c *Config) UnmarshalTOML(unmarshal func(interface{}) error) error { if dec.Aura != nil { c.Aura = *dec.Aura } - if dec.Parlia != nil { - c.Parlia = *dec.Parlia - } if dec.TxPool != nil { c.DeprecatedTxPool = *dec.TxPool } diff --git a/eth/ethconsensusconfig/config.go b/eth/ethconsensusconfig/config.go index 1ae814745ea..11c95f8feec 100644 --- a/eth/ethconsensusconfig/config.go +++ b/eth/ethconsensusconfig/config.go @@ -3,15 +3,14 @@ package ethconsensusconfig import ( "path/filepath" - "github.com/ledgerwatch/erigon-lib/chain" - "github.com/ledgerwatch/erigon-lib/kv" - "github.com/davecgh/go-spew/spew" "github.com/ledgerwatch/log/v3" + "github.com/ledgerwatch/erigon-lib/chain" + "github.com/ledgerwatch/erigon-lib/kv" + "github.com/ledgerwatch/erigon/consensus" "github.com/ledgerwatch/erigon/consensus/aura" - "github.com/ledgerwatch/erigon/consensus/aura/consensusconfig" "github.com/ledgerwatch/erigon/consensus/bor" "github.com/ledgerwatch/erigon/consensus/bor/contract" "github.com/ledgerwatch/erigon/consensus/bor/heimdall" @@ -20,29 +19,30 @@ import ( "github.com/ledgerwatch/erigon/consensus/clique" "github.com/ledgerwatch/erigon/consensus/db" "github.com/ledgerwatch/erigon/consensus/ethash" + "github.com/ledgerwatch/erigon/consensus/ethash/ethashcfg" "github.com/ledgerwatch/erigon/consensus/parlia" "github.com/ledgerwatch/erigon/consensus/serenity" "github.com/ledgerwatch/erigon/params" "github.com/ledgerwatch/erigon/turbo/snapshotsync" ) -func CreateConsensusEngine(chainConfig *chain.Config, logger log.Logger, config interface{}, notify []string, noverify bool, HeimdallgRPCAddress string, HeimdallURL string, WithoutHeimdall bool, datadir string, snapshots *snapshotsync.RoSnapshots, readonly bool, chainDb ...kv.RwDB) consensus.Engine { +func CreateConsensusEngine(chainConfig *chain.Config, config interface{}, notify []string, noverify bool, HeimdallgRPCAddress string, HeimdallURL string, WithoutHeimdall bool, datadir string, snapshots *snapshotsync.RoSnapshots, readonly bool, chainDb ...kv.RwDB) consensus.Engine { var eng consensus.Engine switch consensusCfg := config.(type) { - case *ethash.Config: + case *ethashcfg.Config: switch consensusCfg.PowMode { - case ethash.ModeFake: + case ethashcfg.ModeFake: log.Warn("Ethash used in fake mode") eng = ethash.NewFaker() - case ethash.ModeTest: + case ethashcfg.ModeTest: log.Warn("Ethash used in test mode") eng = ethash.NewTester(nil, noverify) - case ethash.ModeShared: + case ethashcfg.ModeShared: log.Warn("Ethash used in shared mode") eng = ethash.NewShared() default: - eng = ethash.New(ethash.Config{ + eng = ethash.New(ethashcfg.Config{ CachesInMem: consensusCfg.CachesInMem, CachesLockMmap: consensusCfg.CachesLockMmap, DatasetDir: consensusCfg.DatasetDir, @@ -56,15 +56,13 @@ func CreateConsensusEngine(chainConfig *chain.Config, logger log.Logger, config if consensusCfg.DBPath == "" { consensusCfg.DBPath = filepath.Join(datadir, "clique", "db") } - eng = clique.New(chainConfig, consensusCfg, db.OpenDatabase(consensusCfg.DBPath, logger, consensusCfg.InMemory, readonly)) + eng = clique.New(chainConfig, consensusCfg, db.OpenDatabase(consensusCfg.DBPath, consensusCfg.InMemory, readonly)) } case *chain.AuRaConfig: if chainConfig.Aura != nil { - if consensusCfg.DBPath == "" { - consensusCfg.DBPath = filepath.Join(datadir, "aura") - } + dbPath := filepath.Join(datadir, "aura") var err error - eng, err = aura.NewAuRa(chainConfig.Aura, db.OpenDatabase(consensusCfg.DBPath, logger, consensusCfg.InMemory, readonly), chainConfig.Aura.Etherbase, consensusconfig.GetConfigByChain(chainConfig.ChainName)) + eng, err = aura.NewAuRa(chainConfig.Aura, db.OpenDatabase(dbPath, false, readonly)) if err != nil { panic(err) } @@ -74,7 +72,7 @@ func CreateConsensusEngine(chainConfig *chain.Config, logger log.Logger, config if consensusCfg.DBPath == "" { consensusCfg.DBPath = filepath.Join(datadir, "parlia") } - eng = parlia.New(chainConfig, db.OpenDatabase(consensusCfg.DBPath, logger, consensusCfg.InMemory, readonly), snapshots, chainDb[0]) + eng = parlia.New(chainConfig, db.OpenDatabase(consensusCfg.DBPath, consensusCfg.InMemory, readonly), snapshots, chainDb[0]) } case *chain.BorConfig: // If Matic bor consensus is requested, set it up @@ -84,7 +82,7 @@ func CreateConsensusEngine(chainConfig *chain.Config, logger log.Logger, config genesisContractsClient := contract.NewGenesisContractsClient(chainConfig, chainConfig.Bor.ValidatorContract, chainConfig.Bor.StateReceiverContract) spanner := span.NewChainSpanner(contract.ValidatorSet(), chainConfig) borDbPath := filepath.Join(datadir, "bor") // bor consensus path: datadir/bor - db := db.OpenDatabase(borDbPath, logger, false, readonly) + db := db.OpenDatabase(borDbPath, false, readonly) var heimdallClient bor.IHeimdallClient if WithoutHeimdall { diff --git a/eth/gasprice/feehistory.go b/eth/gasprice/feehistory.go index 246f00a0440..c2a31cf86aa 100644 --- a/eth/gasprice/feehistory.go +++ b/eth/gasprice/feehistory.go @@ -135,42 +135,66 @@ func (oracle *Oracle) processBlock(bf *blockFees, percentiles []float64) { // also returned if requested and available. // Note: an error is only returned if retrieving the head header has failed. If there are no // retrievable blocks in the specified range then zero block count is returned with no error. -func (oracle *Oracle) resolveBlockRange(ctx context.Context, lastBlock rpc.BlockNumber, blocks, maxHistory int) (*types.Block, []*types.Receipt, uint64, int, error) { +func (oracle *Oracle) resolveBlockRange(ctx context.Context, reqEnd rpc.BlockNumber, blocks, maxHistory int) (*types.Block, []*types.Receipt, uint64, int, error) { var ( - headBlock rpc.BlockNumber + headBlock *types.Header pendingBlock *types.Block pendingReceipts types.Receipts + err error ) - // query either pending block or head header and set headBlock - if lastBlock == rpc.PendingBlockNumber { - if pendingBlock, pendingReceipts = oracle.backend.PendingBlockAndReceipts(); pendingBlock != nil { - lastBlock = rpc.BlockNumber(pendingBlock.NumberU64()) - headBlock = lastBlock - 1 - } else { - // pending block not supported by backend, process until latest block - lastBlock = rpc.LatestBlockNumber - blocks-- - if blocks == 0 { - return nil, nil, 0, 0, nil + + // Get the chain's current head. + if headBlock, err = oracle.backend.HeaderByNumber(ctx, rpc.LatestBlockNumber); err != nil { + return nil, nil, 0, 0, err + } + head := rpc.BlockNumber(headBlock.Number.Uint64()) + // Fail if request block is beyond the chain's current head. + if head < reqEnd { + return nil, nil, 0, 0, fmt.Errorf("%w: requested %d, head %d", ErrRequestBeyondHead, reqEnd, head) + } + + // Resolve block tag. + if reqEnd < 0 { + var ( + resolved *types.Header + err error + ) + switch reqEnd { + case rpc.PendingBlockNumber: + if pendingBlock, pendingReceipts = oracle.backend.PendingBlockAndReceipts(); pendingBlock != nil { + resolved = pendingBlock.Header() + } else { + // Pending block not supported by backend, process only until latest block. + resolved = headBlock + + // Update total blocks to return to account for this. + blocks-- } + case rpc.LatestBlockNumber: + // Retrieved above. + resolved = headBlock + case rpc.SafeBlockNumber: + resolved, err = oracle.backend.HeaderByNumber(ctx, rpc.SafeBlockNumber) + case rpc.FinalizedBlockNumber: + resolved, err = oracle.backend.HeaderByNumber(ctx, rpc.FinalizedBlockNumber) + case rpc.EarliestBlockNumber: + resolved, err = oracle.backend.HeaderByNumber(ctx, rpc.EarliestBlockNumber) } - } - if pendingBlock == nil { - // if pending block is not fetched then we retrieve the head header to get the head block number - if latestHeader, err := oracle.backend.HeaderByNumber(ctx, rpc.LatestBlockNumber); err == nil { - headBlock = rpc.BlockNumber(latestHeader.Number.Uint64()) - } else { + if resolved == nil || err != nil { return nil, nil, 0, 0, err } + // Absolute number resolved. + reqEnd = rpc.BlockNumber(resolved.Number.Uint64()) } - if lastBlock == rpc.LatestBlockNumber { - lastBlock = headBlock - } else if pendingBlock == nil && lastBlock > headBlock { - return nil, nil, 0, 0, fmt.Errorf("%w: requested %d, head %d", ErrRequestBeyondHead, lastBlock, headBlock) + + // If there are no blocks to return, short circuit. + if blocks == 0 { + return nil, nil, 0, 0, nil } + if maxHistory != 0 { // limit retrieval to the given number of latest blocks - if tooOldCount := int64(headBlock) - int64(maxHistory) - int64(lastBlock) + int64(blocks); tooOldCount > 0 { + if tooOldCount := int64(headBlock.Number.Uint64()) - int64(maxHistory) - int64(reqEnd) + int64(blocks); tooOldCount > 0 { // tooOldCount is the number of requested blocks that are too old to be served if int64(blocks) > tooOldCount { blocks -= int(tooOldCount) @@ -180,10 +204,10 @@ func (oracle *Oracle) resolveBlockRange(ctx context.Context, lastBlock rpc.Block } } // ensure not trying to retrieve before genesis - if rpc.BlockNumber(blocks) > lastBlock+1 { - blocks = int(lastBlock + 1) + if rpc.BlockNumber(blocks) > reqEnd+1 { + blocks = int(reqEnd + 1) } - return pendingBlock, pendingReceipts, uint64(lastBlock), blocks, nil + return pendingBlock, pendingReceipts, uint64(reqEnd), blocks, nil } // FeeHistory returns data relevant for fee estimation based on the specified range of blocks. diff --git a/eth/stagedsync/README.md b/eth/stagedsync/README.md index c0ff154ed5b..e2c0ba436a2 100644 --- a/eth/stagedsync/README.md +++ b/eth/stagedsync/README.md @@ -71,7 +71,11 @@ Most of the stages can work offline though it isn't implemented in the current v We can add/remove stages, so exact stage numbers may change - but order and names stay the same. -### Stage 1: [Download Headers Stage](/eth/stagedsync/stage_headers.go) +### Stage 1: [Snapshots](/eth/stagedsync/stage_snapshots.go) + +Download Snapshots + +### Stage 2: [Download Headers Stage](/eth/stagedsync/stage_headers.go) During this stage we download all the headers between the local HEAD and our peer's head. @@ -81,17 +85,21 @@ Most of the unwinds are initiated on this stage due to the chain reorgs. This stage promotes local HEAD pointer. -### Stage 2: [Block Hashes](/eth/stagedsync/stage_blockhashes.go) +### Stage 3: [Cumulative Index](/eth/stagedsync/stage_cumulative_index.go) + +Calculate how much gas has been used up to each block. + +### Stage 4: [Block Hashes](/eth/stagedsync/stage_blockhashes.go) Creates an index of blockHash -> blockNumber extracted from the headers for faster lookups and making the sync friendlier for HDDs. -### Stage 4: [Download Block Bodies Stage](/eth/stagedsync/stage_bodies.go) +### Stage 5: [Download Block Bodies Stage](/eth/stagedsync/stage_bodies.go) At that stage, we download bodies for block headers that we already downloaded. That is the most intensive stage for the network connection, the vast majority of data is downloaded here. -### Stage 5: [Recover Senders Stage](/eth/stagedsync/stage_senders.go) +### Stage 6: [Recover Senders Stage](/eth/stagedsync/stage_senders.go) This stage recovers and stores senders for each transaction in each downloaded block. @@ -99,7 +107,7 @@ This is also a CPU intensive stage and also benefits from multi-core CPUs. This stage doesn't use any network connection. -### Stage 6: [Execute Blocks Stage](/eth/stagedsync/stage_execute.go) +### Stage 7: [Execute Blocks Stage](/eth/stagedsync/stage_execute.go) During this stage, we execute block-by-block everything that we downloaded before. @@ -113,23 +121,16 @@ This stage is disk intensive. This stage can spawn unwinds if the block execution fails. -### Stage 7: [Transpile marked VM contracts to TEVM](/eth/stagedsync/stage_tevm.go) - -[TODO] - -### Stage 8: [Generate Hashed State Stage](/eth/stagedsync/stage_hashstate.go) +### Stage 8: [Transpile marked VM contracts to TEVM](/eth/stagedsync/stage_tevm.go) -Erigon during execution uses Plain state storage. +Translation each marked for translation contract (from EVM to TEVM) -> Plain State: Instead of the normal (we call it "Hashed State") where accounts and storage items are addressed as `keccak256(address)`, in the plain state them are addressed by the `address` itself. -Though, to make sure that some APIs work and keep the compatibility with the other clients, we generate Hashed state as well. +### Stage 9: [VerkleTrie](/eth/stagedsync/stage_verkle_trie.go) -If the hashed state is not empty, then we are looking at the History ChangeSets and update only the items that were changed. - -This stage doesn't use a network connection. +[TODO] -### Stage 9: [Compute State Root Stage](/eth/stagedsync/stage_interhashes.go) +### Stage 10: [Compute State Root Stage](/eth/stagedsync/stage_interhashes.go) This stage build the Merkle trie and checks the root hash for the current state. @@ -143,13 +144,22 @@ If the root hash doesn't match, it initiates an unwind one block backwards. This stage doesn't use a network connection. -### Stage 10: [Generate call traces index](/eth/stagedsync/stage_call_traces.go) +### Stage 11: [Generate Hashed State Stage](/eth/stagedsync/stage_hashstate.go) + +Erigon during execution uses Plain state storage. + +> Plain State: Instead of the normal (we call it "Hashed State") where accounts and storage items are addressed as `keccak256(address)`, in the plain state them are addressed by the `address` itself. + +Though, to make sure that some APIs work and keep the compatibility with the other clients, we generate Hashed state as well. + +If the hashed state is not empty, then we are looking at the History ChangeSets and update only the items that were changed. + +This stage doesn't use a network connection. -[TODO] -### Stages [11, 12](/eth/stagedsync/stage_indexes.go), [13](/eth/stagedsync/stage_log_index.go), and [14](/eth/stagedsync/stage_txlookup.go): Generate Indexes +### Stages [12, 13](/eth/stagedsync/stage_indexes.go), [14](/eth/stagedsync/stage_log_index.go), [15](/eth/stagedsync/stage_call_traces.go) and [16](/eth/stagedsync/stage_txlookup.go): Generate Indexes -There are 4 indexes that are generated during sync. +There are 5 indexes that are generated during sync. They might be disabled because they aren't used for all the APIs. @@ -167,11 +177,15 @@ This index stores the mapping from the storage item address to the list of block This index sets up a link from the [TODO] to [TODO]. +**Call traces index** + +[TODO] + **Tx Lookup Index** This index sets up a link from the transaction hash to the block number. -### Stage 15: [Transaction Pool Stage](/eth/stagedsync/stage_txpool.go) +### Stage 16: [Transaction Pool Stage](/eth/stagedsync/stage_txpool.go) During this stage we start the transaction pool or update its state. For instance, we remove the transactions from the blocks we have downloaded from the pool. @@ -179,6 +193,6 @@ On unwinds, we add the transactions from the blocks we unwind, back to the pool. This stage doesn't use a network connection. -### Stage 16: Finish +### Stage 17: Finish This stage sets the current block number that is then used by [RPC calls](../../cmd/rpcdaemon/README.md), such as [`eth_blockNumber`](../../README.md). diff --git a/eth/stagedsync/exec3.go b/eth/stagedsync/exec3.go index c9c96745b4a..93ec7604a7a 100644 --- a/eth/stagedsync/exec3.go +++ b/eth/stagedsync/exec3.go @@ -2,7 +2,6 @@ package stagedsync import ( "bytes" - "container/heap" "context" "encoding/binary" "errors" @@ -11,6 +10,7 @@ import ( "path/filepath" "runtime" "sync" + "sync/atomic" "time" "github.com/VictoriaMetrics/metrics" @@ -26,13 +26,14 @@ import ( "github.com/ledgerwatch/erigon-lib/kv/rawdbv3" libstate "github.com/ledgerwatch/erigon-lib/state" state2 "github.com/ledgerwatch/erigon-lib/state" + "github.com/ledgerwatch/erigon/common/math" + "github.com/ledgerwatch/erigon/core/state/temporal" "github.com/ledgerwatch/log/v3" "github.com/torquem-ch/mdbx-go/mdbx" - atomic2 "go.uber.org/atomic" + "golang.org/x/sync/errgroup" "github.com/ledgerwatch/erigon/cmd/state/exec22" "github.com/ledgerwatch/erigon/cmd/state/exec3" - "github.com/ledgerwatch/erigon/common/math" "github.com/ledgerwatch/erigon/consensus" "github.com/ledgerwatch/erigon/core" "github.com/ledgerwatch/erigon/core/rawdb" @@ -46,6 +47,8 @@ import ( ) var ExecStepsInDB = metrics.NewCounter(`exec_steps_in_db`) //nolint +var ExecRepeats = metrics.NewCounter(`exec_repeats`) //nolint +var ExecTriggers = metrics.NewCounter(`exec_triggers`) //nolint func NewProgress(prevOutputBlockNum, commitThreshold uint64, workersCount int, logPrefix string) *Progress { return &Progress{prevTime: time.Now(), prevOutputBlockNum: prevOutputBlockNum, commitThreshold: commitThreshold, workersCount: workersCount, logPrefix: logPrefix} @@ -62,12 +65,11 @@ type Progress struct { logPrefix string } -func (p *Progress) Log(rs *state.StateV3, rwsLen int, queueSize, doneCount, inputBlockNum, outputBlockNum, outTxNum, repeatCount uint64, resultsSize uint64, resultCh chan *exec22.TxTask, idxStepsAmountInDB float64) { +func (p *Progress) Log(rs *state.StateV3, in *exec22.QueueWithRetry, rws *exec22.ResultsQueue, doneCount, inputBlockNum, outputBlockNum, outTxNum, repeatCount uint64, idxStepsAmountInDB float64) { ExecStepsInDB.Set(uint64(idxStepsAmountInDB * 100)) var m runtime.MemStats dbg.ReadMemStats(&m) sizeEstimate := rs.SizeEstimate() - queueLen := rs.QueueLen() currentTime := time.Now() interval := currentTime.Sub(p.prevTime) speedTx := float64(doneCount-p.prevCount) / (float64(interval) / float64(time.Second)) @@ -81,13 +83,12 @@ func (p *Progress) Log(rs *state.StateV3, rwsLen int, queueSize, doneCount, inpu "blk", outputBlockNum, //"blk/s", fmt.Sprintf("%.1f", speedBlock), "tx/s", fmt.Sprintf("%.1f", speedTx), - "pipe", fmt.Sprintf("%d/%d->%d/%d->%d/%d", queueLen, queueSize, rwsLen, queueSize, len(resultCh), cap(resultCh)), - "resultsSize", common.ByteCount(resultsSize), + "pipe", fmt.Sprintf("(%d+%d)->%d/%d->%d/%d", in.NewTasksLen(), in.RetriesLen(), rws.ResultChLen(), rws.ResultChCap(), rws.Len(), rws.Limit()), "repeatRatio", fmt.Sprintf("%.2f%%", repeatRatio), "workers", p.workersCount, "buffer", fmt.Sprintf("%s/%s", common.ByteCount(sizeEstimate), common.ByteCount(p.commitThreshold)), "idxStepsInDB", fmt.Sprintf("%.2f", idxStepsAmountInDB), - "inBlk", inputBlockNum, + //"inBlk", inputBlockNum, "step", fmt.Sprintf("%.1f", float64(outTxNum)/float64(ethconfig.HistoryV3AggregationStep)), "alloc", common.ByteCount(m.Alloc), "sys", common.ByteCount(m.Sys), ) @@ -106,11 +107,16 @@ func (p *Progress) Log(rs *state.StateV3, rwsLen int, queueSize, doneCount, inpu func ExecV3(ctx context.Context, execStage *StageState, u Unwinder, workerCount int, cfg ExecuteBlockCfg, applyTx kv.RwTx, - parallel bool, rs *state.StateV3, logPrefix string, - logger log.Logger, + parallel bool, logPrefix string, maxBlockNum uint64, ) error { - batchSize, chainDb := cfg.batchSize, cfg.db + batchSize := cfg.batchSize + chainDb := cfg.db + //TODO: re-think - how it must work + if casted, ok := chainDb.(*temporal.DB); ok { + chainDb = casted.InternalDB() + } + blockReader := cfg.blockReader agg, engine := cfg.agg, cfg.engine chainConfig, genesis := cfg.chainConfig, cfg.genesis @@ -132,7 +138,10 @@ func ExecV3(ctx context.Context, var block, stageProgress uint64 var maxTxNum uint64 - var outputTxNum = atomic2.NewUint64(0) + outputTxNum := atomic.Uint64{} + blockComplete := atomic.Bool{} + blockComplete.Store(true) + var inputTxNum uint64 if execStage.BlockNumber > 0 { stageProgress = execStage.BlockNumber @@ -157,7 +166,7 @@ func ExecV3(ctx context.Context, return err } outputTxNum.Store(_outputTxNum) - outputTxNum.Inc() + outputTxNum.Add(1) inputTxNum = outputTxNum.Load() } } else { @@ -173,7 +182,7 @@ func ExecV3(ctx context.Context, return err } outputTxNum.Store(_outputTxNum) - outputTxNum.Inc() + outputTxNum.Add(1) inputTxNum = outputTxNum.Load() } return nil @@ -184,24 +193,28 @@ func ExecV3(ctx context.Context, agg.SetTxNum(inputTxNum) var outputBlockNum = syncMetrics[stages.Execution] - var inputBlockNum = atomic2.NewUint64(0) + inputBlockNum := &atomic.Uint64{} var count uint64 - var repeatCount, triggerCount = atomic2.NewUint64(0), atomic2.NewUint64(0) - var resultsSize = atomic2.NewInt64(0) var lock sync.RWMutex - queueSize := workerCount // workerCount * 4 // when wait cond can be moved inside txs loop - execWorkers, applyWorker, resultCh, stopWorkers, waitWorkers := exec3.NewWorkersPool(lock.RLocker(), ctx, parallel, chainDb, rs, blockReader, chainConfig, logger, genesis, engine, workerCount+1) + rs := state.NewStateV3(cfg.dirs.Tmp) + + //TODO: owner of `resultCh` is main goroutine, but owner of `retryQueue` is applyLoop. + // Now rwLoop closing both (because applyLoop we completely restart) + // Maybe need split channels? Maybe don't exit from ApplyLoop? Maybe current way is also ok? + + // input queue + in := exec22.NewQueueWithRetry(100_000) + defer in.Close() + + rwsConsumed := make(chan struct{}, 1) + defer close(rwsConsumed) + + execWorkers, applyWorker, rws, stopWorkers, waitWorkers := exec3.NewWorkersPool(lock.RLocker(), ctx, parallel, chainDb, rs, in, blockReader, chainConfig, genesis, engine, workerCount+1) defer stopWorkers() applyWorker.DiscardReadList() - rws := &exec22.TxTaskQueue{} - heap.Init(rws) - var rwsLock sync.Mutex - rwsReceiveCond := sync.NewCond(&rwsLock) - commitThreshold := batchSize.Bytes() - resultsThreshold := int64(batchSize.Bytes()) progress := NewProgress(block, commitThreshold, workerCount, execStage.LogPrefix()) logEvery := time.NewTicker(20 * time.Second) defer logEvery.Stop() @@ -220,61 +233,31 @@ func ExecV3(ctx context.Context, applyWorker.ResetTx(tx) - notifyReceived := func() { rwsReceiveCond.Signal() } - var t time.Time var lastBlockNum uint64 - drainF := func(txTask *exec22.TxTask) (added int64) { - rwsLock.Lock() - defer rwsLock.Unlock() - added += txTask.ResultsSize - heap.Push(rws, txTask) - - for { - select { - case txTask, ok := <-resultCh: - if !ok { - return added - } - added += txTask.ResultsSize - heap.Push(rws, txTask) - default: // we are inside mutex section, can't block here - return added - } - } - } for outputTxNum.Load() <= maxTxNum { - select { - case <-ctx.Done(): - return ctx.Err() - case txTask, ok := <-resultCh: - if !ok { - return nil - } - added := drainF(txTask) - resultsSize.Add(added) + if err := rws.Drain(ctx); err != nil { + return err } - processedResultSize, processedTxNum, conflicts, processedBlockNum, err := func() (processedResultSize int64, processedTxNum, conflicts, processedBlockNum uint64, err error) { - rwsLock.Lock() - defer rwsLock.Unlock() - return processResultQueue(rws, outputTxNum.Load(), rs, agg, tx, triggerCount, notifyReceived, applyWorker) + processedTxNum, conflicts, triggers, processedBlockNum, stoppedAtBlockEnd, err := func() (processedTxNum uint64, conflicts, triggers int, processedBlockNum uint64, stopedAtBlockEnd bool, err error) { + it := rws.Iter() + defer it.Close() + return processResultQueue(in, it, outputTxNum.Load(), rs, agg, tx, rwsConsumed, applyWorker, true, false) }() if err != nil { return err } - resultsSize.Add(-processedResultSize) - repeatCount.Add(conflicts) + + ExecRepeats.Add(conflicts) + ExecTriggers.Add(triggers) if processedBlockNum > lastBlockNum { outputBlockNum.Set(processedBlockNum) - if lastBlockNum > 0 { - core.BlockExecutionTimer.UpdateDuration(t) - } lastBlockNum = processedBlockNum - t = time.Now() } if processedTxNum > 0 { outputTxNum.Store(processedTxNum) + blockComplete.Store(stoppedAtBlockEnd) } } @@ -291,7 +274,7 @@ func ExecV3(ctx context.Context, var rwLoopErrCh chan error - var rwLoopWg sync.WaitGroup + var rwLoopG *errgroup.Group if parallel { // `rwLoop` lives longer than `applyLoop` rwLoop := func(ctx context.Context) error { @@ -319,29 +302,25 @@ func ExecV3(ctx context.Context, return ctx.Err() case <-logEvery.C: - rwsLock.Lock() - rwsLen := rws.Len() - rwsLock.Unlock() + if list := agg.SlowContextsList(); len(list) > 0 { + log.Info("[dbg] Active agg ctx", "list", list) + } stepsInDB := rawdbhelpers.IdxStepsCountV3(tx) - progress.Log(rs, rwsLen, uint64(queueSize), rs.DoneCount(), inputBlockNum.Load(), outputBlockNum.Get(), outputTxNum.Load(), repeatCount.Load(), uint64(resultsSize.Load()), resultCh, stepsInDB) + progress.Log(rs, in, rws, rs.DoneCount(), inputBlockNum.Load(), outputBlockNum.Get(), outputTxNum.Load(), ExecRepeats.Get(), stepsInDB) + if agg.HasBackgroundFilesBuild() { + log.Info(fmt.Sprintf("[%s] Background files build", logPrefix), "progress", agg.BackgroundProgress()) + } case <-pruneEvery.C: if rs.SizeEstimate() < commitThreshold { - // too much steps in db will slow-down everything: flush and prune - // it means better spend time for pruning, before flushing more data to db - // also better do it now - instead of before Commit() - because Commit does block execution - stepsInDB := rawdbhelpers.IdxStepsCountV3(tx) - if stepsInDB > 5 && rs.SizeEstimate() < uint64(float64(commitThreshold)*0.2) { - if err = agg.Prune(ctx, ethconfig.HistoryV3AggregationStep*2); err != nil { // prune part of retired data, before commit - panic(err) + if agg.CanPrune(tx) { + if err = agg.Prune(ctx, ethconfig.HistoryV3AggregationStep*10); err != nil { // prune part of retired data, before commit + return err + } + } else { + if err = agg.Flush(ctx, tx); err != nil { + return err } - } - - if err = agg.Flush(ctx, tx); err != nil { - return err - } - if err = agg.PruneWithTiemout(ctx, 1*time.Second); err != nil { - return err } break } @@ -349,68 +328,51 @@ func ExecV3(ctx context.Context, cancelApplyCtx() applyLoopWg.Wait() - var t1, t2, t3, t4 time.Duration + var t0, t1, t2, t3, t4 time.Duration commitStart := time.Now() - log.Info("Committing...") + log.Info("Committing...", "blockComplete.Load()", blockComplete.Load()) if err := func() error { - rwsLock.Lock() - defer rwsLock.Unlock() - // Drain results (and process) channel because read sets do not carry over - for { - var drained bool - for !drained { - select { - case txTask, ok := <-resultCh: - if !ok { - return nil - } - resultsSize.Add(txTask.ResultsSize) - heap.Push(rws, txTask) - default: - drained = true - } - } + //Drain results (and process) channel because read sets do not carry over + for !blockComplete.Load() { + rws.DrainNonBlocking() applyWorker.ResetTx(tx) - processedResultSize, processedTxNum, conflicts, processedBlockNum, err := processResultQueue(rws, outputTxNum.Load(), rs, agg, tx, triggerCount, func() {}, applyWorker) + + resIt := rws.Iter() + processedTxNum, conflicts, triggers, processedBlockNum, stoppedAtBlockEnd, err := processResultQueue(in, resIt, outputTxNum.Load(), rs, agg, tx, nil, applyWorker, false, true) if err != nil { return err } - resultsSize.Add(-processedResultSize) - repeatCount.Add(conflicts) + resIt.Close() //TODO: in defer + + ExecRepeats.Add(conflicts) + ExecTriggers.Add(triggers) if processedBlockNum > 0 { outputBlockNum.Set(processedBlockNum) } if processedTxNum > 0 { outputTxNum.Store(processedTxNum) - } - - if rws.Len() == 0 { - break + blockComplete.Store(stoppedAtBlockEnd) } } - rwsReceiveCond.Signal() + t0 = time.Since(commitStart) lock.Lock() // This is to prevent workers from starting work on any new txTask defer lock.Unlock() - DrainLoop: // Drain results channel because read sets do not carry over - for { - select { - case txTask, ok := <-resultCh: - if !ok { - return nil - } - rs.AddWork(txTask) - default: - break DrainLoop - } + select { + case rwsConsumed <- struct{}{}: + default: } - // Drain results queue as well - for rws.Len() > 0 { - txTask := heap.Pop(rws).(*exec22.TxTask) - resultsSize.Add(-txTask.ResultsSize) - rs.AddWork(txTask) - } + // Drain results channel because read sets do not carry over + rws.DropResults(func(txTask *exec22.TxTask) { + rs.ReTry(txTask, in) + }) + + //lastTxNumInDb, _ := rawdbv3.TxNums.Max(tx, outputBlockNum.Get()) + //if lastTxNumInDb != outputTxNum.Load()-1 { + // panic(fmt.Sprintf("assert: %d != %d", lastTxNumInDb, outputTxNum.Load())) + //} + t1 = time.Since(commitStart) tt := time.Now() if err := rs.Flush(ctx, tx, logPrefix, logEvery); err != nil { @@ -453,7 +415,7 @@ func ExecV3(ctx context.Context, applyLoopWg.Add(1) go applyLoop(applyCtx, rwLoopErrCh) - log.Info("Committed", "time", time.Since(commitStart), "drain", t1, "rs.flush", t2, "agg.flush", t3, "tx.commit", t4) + log.Info("Committed", "time", time.Since(commitStart), "drain", t0, "drain_and_lock", t1, "rs.flush", t2, "agg.flush", t3, "tx.commit", t4) } } if err = rs.Flush(ctx, tx, logPrefix, logEvery); err != nil { @@ -465,32 +427,22 @@ func ExecV3(ctx context.Context, if err = execStage.Update(tx, outputBlockNum.Get()); err != nil { return err } - //if err = execStage.Update(tx, stageProgress); err != nil { - // panic(err) - //} if err = tx.Commit(); err != nil { return err } return nil } - rwLoopErrCh = make(chan error, 1) - - defer rwLoopWg.Wait() - rwLoopCtx, rwLoopCancel := context.WithCancel(ctx) - defer rwLoopCancel() - rwLoopWg.Add(1) - go func() { - defer close(rwLoopErrCh) - defer rwLoopWg.Done() - + rwLoopCtx, rwLoopCtxCancel := context.WithCancel(ctx) + defer rwLoopCtxCancel() + rwLoopG, rwLoopCtx = errgroup.WithContext(rwLoopCtx) + defer rwLoopG.Wait() + rwLoopG.Go(func() error { + defer rws.Close() + defer in.Close() defer applyLoopWg.Wait() - defer rs.Finish() - - if err := rwLoop(rwLoopCtx); err != nil { - rwLoopErrCh <- err - } - }() + return rwLoop(rwLoopCtx) + }) } if block < blockSnapshots.BlocksAvailable() { @@ -526,6 +478,9 @@ func ExecV3(ctx context.Context, _, isPoSa := cfg.engine.(consensus.PoSA) //isBor := cfg.chainConfig.Bor != nil + slowDownLimit := time.NewTicker(time.Second) + defer slowDownLimit.Stop() + var b *types.Block var blockNum uint64 var err error @@ -537,7 +492,7 @@ Loop: return err } if b == nil { - // TODO: panic here and see that overall prodcess deadlock + // TODO: panic here and see that overall process deadlock return fmt.Errorf("nil block %d", blockNum) } txs := b.Transactions() @@ -552,7 +507,7 @@ Loop: defer getHashFnMute.Unlock() return f(n) } - blockContext := core.NewEVMBlockContext(header, getHashFn, engine, nil /* author */) + blockContext := core.NewEVMBlockContext(header, getHashFn, engine, nil /* author */, nil /*excessDataGas*/) if parallel { select { @@ -560,23 +515,27 @@ Loop: if err != nil { return err } + case <-ctx.Done(): + return ctx.Err() default: } func() { - needWait := rs.QueueLen() > queueSize - if !needWait { - return - } - rwsLock.Lock() - defer rwsLock.Unlock() - for rs.QueueLen() > queueSize || rws.Len() > queueSize || resultsSize.Load() >= resultsThreshold || rs.SizeEstimate() >= commitThreshold { + for rws.Len() > rws.Limit() || rs.SizeEstimate() >= commitThreshold { select { case <-ctx.Done(): return - default: + case _, ok := <-rwsConsumed: + if !ok { + return + } + case <-slowDownLimit.C: + //log.Warn("skip", "rws.Len()", rws.Len(), "rws.Limit()", rws.Limit(), "rws.ResultChLen()", rws.ResultChLen()) + //if tt := rws.Dbg(); tt != nil { + // log.Warn("fst", "n", tt.TxNum, "in.len()", in.Len(), "out", outputTxNum.Load(), "in.NewTasksLen", in.NewTasksLen()) + //} + return } - rwsReceiveCond.Wait() } }() } @@ -606,7 +565,7 @@ Loop: txTask.Tx = txs[txIndex] txTask.TxAsMessage, err = txTask.Tx.AsMessage(signer, header.BaseFee, txTask.Rules) if err != nil { - panic(err) + return err } if sender, ok := txs[txIndex].GetSender(); ok { @@ -624,10 +583,10 @@ Loop: if parallel { if txTask.TxIndex >= 0 && txTask.TxIndex < len(txs) { if ok := rs.RegisterSender(txTask); ok { - rs.AddWork(txTask) + rs.AddWork(ctx, txTask, in) } } else { - rs.AddWork(txTask) + rs.AddWork(ctx, txTask, in) } } else { count++ @@ -664,8 +623,8 @@ Loop: if err := rs.ApplyState(applyTx, txTask, agg); err != nil { return fmt.Errorf("StateV3.Apply: %w", err) } - triggerCount.Add(rs.CommitTxNum(txTask.Sender, txTask.TxNum)) - outputTxNum.Inc() + ExecTriggers.Add(rs.CommitTxNum(txTask.Sender, txTask.TxNum, in)) + outputTxNum.Add(1) if err := rs.ApplyHistory(txTask, agg); err != nil { return fmt.Errorf("StateV3.Apply: %w", err) @@ -681,7 +640,7 @@ Loop: select { case <-logEvery.C: stepsInDB := rawdbhelpers.IdxStepsCountV3(applyTx) - progress.Log(rs, rws.Len(), uint64(queueSize), count, inputBlockNum.Load(), outputBlockNum.Get(), outputTxNum.Load(), repeatCount.Load(), uint64(resultsSize.Load()), resultCh, stepsInDB) + progress.Log(rs, in, rws, count, inputBlockNum.Load(), outputBlockNum.Get(), outputTxNum.Load(), ExecRepeats.Get(), stepsInDB) if rs.SizeEstimate() < commitThreshold { break } @@ -718,7 +677,7 @@ Loop: } if blockSnapshots.Cfg().Produce { - agg.BuildFilesInBackground() + agg.BuildFilesInBackground(outputTxNum.Load()) } select { case <-ctx.Done(): @@ -728,10 +687,9 @@ Loop: } if parallel { - if err := <-rwLoopErrCh; err != nil { + if err := rwLoopG.Wait(); err != nil { return err } - rwLoopWg.Wait() waitWorkers() } else { if err = rs.Flush(ctx, applyTx, logPrefix, logEvery); err != nil { @@ -746,7 +704,7 @@ Loop: } if blockSnapshots.Cfg().Produce { - agg.BuildFilesInBackground() + agg.BuildFilesInBackground(outputTxNum.Load()) } if !useExternalTx && applyTx != nil { @@ -775,48 +733,56 @@ func blockWithSenders(db kv.RoDB, tx kv.Tx, blockReader services.BlockReader, bl return b, nil } -func processResultQueue(rws *exec22.TxTaskQueue, outputTxNumIn uint64, rs *state.StateV3, agg *state2.AggregatorV3, applyTx kv.Tx, triggerCount *atomic2.Uint64, onSuccess func(), applyWorker *exec3.Worker) (resultSize int64, outputTxNum, conflicts, processedBlockNum uint64, err error) { +func processResultQueue(in *exec22.QueueWithRetry, rws *exec22.ResultsQueueIter, outputTxNumIn uint64, rs *state.StateV3, agg *state2.AggregatorV3, applyTx kv.Tx, backPressure chan struct{}, applyWorker *exec3.Worker, canRetry, forceStopAtBlockEnd bool) (outputTxNum uint64, conflicts, triggers int, processedBlockNum uint64, stopedAtBlockEnd bool, err error) { var i int outputTxNum = outputTxNumIn - for rws.Len() > 0 && (*rws)[0].TxNum == outputTxNum { - txTask := heap.Pop(rws).(*exec22.TxTask) - resultSize += txTask.ResultsSize + for rws.HasNext(outputTxNum) { + txTask := rws.PopNext() if txTask.Error != nil || !rs.ReadsValid(txTask.ReadLists) { conflicts++ - if i > 0 { + if i > 0 && canRetry { //send to re-exex - rs.AddWork(txTask) + rs.ReTry(txTask, in) continue } // resolve first conflict right here: it's faster and conflict-free applyWorker.RunTxTask(txTask) if txTask.Error != nil { - return resultSize, outputTxNum, conflicts, processedBlockNum, txTask.Error + return outputTxNum, conflicts, triggers, processedBlockNum, false, txTask.Error } i++ } if err := rs.ApplyState(applyTx, txTask, agg); err != nil { - return resultSize, outputTxNum, conflicts, processedBlockNum, fmt.Errorf("StateV3.Apply: %w", err) + return outputTxNum, conflicts, triggers, processedBlockNum, false, fmt.Errorf("StateV3.Apply: %w", err) } - triggerCount.Add(rs.CommitTxNum(txTask.Sender, txTask.TxNum)) + triggers += rs.CommitTxNum(txTask.Sender, txTask.TxNum, in) outputTxNum++ - onSuccess() + if backPressure != nil { + select { + case backPressure <- struct{}{}: + default: + } + } if err := rs.ApplyHistory(txTask, agg); err != nil { - return resultSize, outputTxNum, conflicts, processedBlockNum, fmt.Errorf("StateV3.Apply: %w", err) + return outputTxNum, conflicts, triggers, processedBlockNum, false, fmt.Errorf("StateV3.Apply: %w", err) } //fmt.Printf("Applied %d block %d txIndex %d\n", txTask.TxNum, txTask.BlockNum, txTask.TxIndex) processedBlockNum = txTask.BlockNum + stopedAtBlockEnd = txTask.Final + if forceStopAtBlockEnd && txTask.Final { + break + } } - return resultSize, outputTxNum, conflicts, processedBlockNum, nil + return } func reconstituteStep(last bool, workerCount int, ctx context.Context, db kv.RwDB, txNum uint64, dirs datadir.Dirs, as *libstate.AggregatorStep, chainDb kv.RwDB, blockReader services.FullBlockReader, - chainConfig *chain.Config, logger log.Logger, genesis *core.Genesis, engine consensus.Engine, + chainConfig *chain.Config, logger log.Logger, genesis *types.Genesis, engine consensus.Engine, batchSize datasize.ByteSize, s *StageState, blockNum uint64, total uint64, ) error { var startOk, endOk bool @@ -856,8 +822,6 @@ func reconstituteStep(last bool, var maxTxNum = startTxNum - workCh := make(chan *exec22.TxTask, workerCount*4) - rs := state.NewReconState(workCh) scanWorker := exec3.NewScanWorker(txNum, as) t := time.Now() @@ -885,7 +849,6 @@ func reconstituteStep(last bool, } bitmap := scanWorker.Bitmap() - var wg sync.WaitGroup logEvery := time.NewTicker(logInterval) defer logEvery.Stop() @@ -913,6 +876,16 @@ func reconstituteStep(last bool, return err } } + g, reconstWorkersCtx := errgroup.WithContext(ctx) + defer g.Wait() + workCh := make(chan *exec22.TxTask, workerCount*4) + defer func() { + fmt.Printf("close1\n") + safeCloseTxTaskCh(workCh) + }() + + rs := state.NewReconState(workCh) + prevCount := rs.DoneCount() for i := 0; i < workerCount; i++ { var localAs *libstate.AggregatorStep if i == 0 { @@ -920,27 +893,56 @@ func reconstituteStep(last bool, } else { localAs = as.Clone() } - reconWorkers[i] = exec3.NewReconWorker(lock.RLocker(), &wg, rs, localAs, blockReader, chainConfig, logger, genesis, engine, chainTxs[i]) + reconWorkers[i] = exec3.NewReconWorker(lock.RLocker(), reconstWorkersCtx, rs, localAs, blockReader, chainConfig, logger, genesis, engine, chainTxs[i]) reconWorkers[i].SetTx(roTxs[i]) reconWorkers[i].SetChainTx(chainTxs[i]) } - wg.Add(workerCount) rollbackCount := uint64(0) - prevCount := rs.DoneCount() + for i := 0; i < workerCount; i++ { - go reconWorkers[i].Run() + i := i + g.Go(func() error { return reconWorkers[i].Run() }) } commitThreshold := batchSize.Bytes() prevRollbackCount := uint64(0) prevTime := time.Now() - reconDone := make(chan struct{}) - //var bn uint64 - go func() { + reconDone := make(chan struct{}, 1) + + defer close(reconDone) + + commit := func(ctx context.Context) error { + t := time.Now() + lock.Lock() + defer lock.Unlock() + for i := 0; i < workerCount; i++ { + roTxs[i].Rollback() + } + if err := db.Update(ctx, func(tx kv.RwTx) error { + if err := rs.Flush(tx); err != nil { + return err + } + return nil + }); err != nil { + return err + } + for i := 0; i < workerCount; i++ { + var err error + if roTxs[i], err = db.BeginRo(ctx); err != nil { + return err + } + reconWorkers[i].SetTx(roTxs[i]) + } + log.Info(fmt.Sprintf("[%s] State reconstitution, commit", s.LogPrefix()), "took", time.Since(t)) + return nil + } + g.Go(func() error { for { select { - case <-reconDone: - return + case <-reconDone: // success finish path + return nil + case <-reconstWorkersCtx.Done(): // force-stop path + return reconstWorkersCtx.Err() case <-logEvery.C: var m runtime.MemStats dbg.ReadMemStats(&m) @@ -967,37 +969,13 @@ func reconstituteStep(last bool, "buffer", fmt.Sprintf("%s/%s", common.ByteCount(sizeEstimate), common.ByteCount(commitThreshold)), "alloc", common.ByteCount(m.Alloc), "sys", common.ByteCount(m.Sys)) if sizeEstimate >= commitThreshold { - t := time.Now() - if err := func() error { - lock.Lock() - defer lock.Unlock() - for i := 0; i < workerCount; i++ { - roTxs[i].Rollback() - } - if err := db.Update(ctx, func(tx kv.RwTx) error { - if err := rs.Flush(tx); err != nil { - return err - } - return nil - }); err != nil { - return err - } - for i := 0; i < workerCount; i++ { - var err error - if roTxs[i], err = db.BeginRo(ctx); err != nil { - return err - } - reconWorkers[i].SetTx(roTxs[i]) - } - return nil - }(); err != nil { - panic(err) + if err := commit(reconstWorkersCtx); err != nil { + return err } - log.Info(fmt.Sprintf("[%s] State reconstitution, commit", s.LogPrefix()), "took", time.Since(t)) } } } - }() + }) var inputTxNum = startTxNum var b *types.Block @@ -1017,84 +995,99 @@ func reconstituteStep(last bool, return h } - var err error // avoid declare global mutable variable - for bn := startBlockNum; bn <= endBlockNum; bn++ { - t = time.Now() - b, err = blockWithSenders(chainDb, nil, blockReader, bn) - if err != nil { - return err - } - if b == nil { - fmt.Printf("could not find block %d\n", bn) - panic("") - } - txs := b.Transactions() - header := b.HeaderNoCopy() - skipAnalysis := core.SkipAnalysis(chainConfig, bn) - signer := *types.MakeSigner(chainConfig, bn) - - f := core.GetHashFn(header, getHeaderFunc) - getHashFnMute := &sync.Mutex{} - getHashFn := func(n uint64) common.Hash { - getHashFnMute.Lock() - defer getHashFnMute.Unlock() - return f(n) - } - blockContext := core.NewEVMBlockContext(header, getHashFn, engine, nil /* author */) - rules := chainConfig.Rules(bn, b.Time()) - - for txIndex := -1; txIndex <= len(txs); txIndex++ { - if bitmap.Contains(inputTxNum) { - binary.BigEndian.PutUint64(txKey[:], inputTxNum) - txTask := &exec22.TxTask{ - BlockNum: bn, - Header: header, - Coinbase: b.Coinbase(), - Uncles: b.Uncles(), - Rules: rules, - TxNum: inputTxNum, - Txs: txs, - TxIndex: txIndex, - BlockHash: b.Hash(), - SkipAnalysis: skipAnalysis, - Final: txIndex == len(txs), - GetHashFn: getHashFn, - EvmBlockContext: blockContext, - Withdrawals: b.Withdrawals(), + if err := func() (err error) { + defer func() { + close(workCh) + reconDone <- struct{}{} // Complete logging and committing go-routine + if waitErr := g.Wait(); waitErr != nil { + if err == nil { + err = waitErr } - if txIndex >= 0 && txIndex < len(txs) { - txTask.Tx = txs[txIndex] - txTask.TxAsMessage, err = txTask.Tx.AsMessage(signer, header.BaseFee, txTask.Rules) - if err != nil { - return err + return + } + }() + + for bn := startBlockNum; bn <= endBlockNum; bn++ { + t = time.Now() + b, err = blockWithSenders(chainDb, nil, blockReader, bn) + if err != nil { + return err + } + if b == nil { + return fmt.Errorf("could not find block %d\n", bn) + } + txs := b.Transactions() + header := b.HeaderNoCopy() + skipAnalysis := core.SkipAnalysis(chainConfig, bn) + signer := *types.MakeSigner(chainConfig, bn) + + f := core.GetHashFn(header, getHeaderFunc) + getHashFnMute := &sync.Mutex{} + getHashFn := func(n uint64) common.Hash { + getHashFnMute.Lock() + defer getHashFnMute.Unlock() + return f(n) + } + blockContext := core.NewEVMBlockContext(header, getHashFn, engine, nil /* author */, nil /*excessDataGas*/) + rules := chainConfig.Rules(bn, b.Time()) + + for txIndex := -1; txIndex <= len(txs); txIndex++ { + if bitmap.Contains(inputTxNum) { + binary.BigEndian.PutUint64(txKey[:], inputTxNum) + txTask := &exec22.TxTask{ + BlockNum: bn, + Header: header, + Coinbase: b.Coinbase(), + Uncles: b.Uncles(), + Rules: rules, + TxNum: inputTxNum, + Txs: txs, + TxIndex: txIndex, + BlockHash: b.Hash(), + SkipAnalysis: skipAnalysis, + Final: txIndex == len(txs), + GetHashFn: getHashFn, + EvmBlockContext: blockContext, + Withdrawals: b.Withdrawals(), } - if sender, ok := txs[txIndex].GetSender(); ok { - txTask.Sender = &sender + if txIndex >= 0 && txIndex < len(txs) { + txTask.Tx = txs[txIndex] + txTask.TxAsMessage, err = txTask.Tx.AsMessage(signer, header.BaseFee, txTask.Rules) + if err != nil { + return err + } + if sender, ok := txs[txIndex].GetSender(); ok { + txTask.Sender = &sender + } + } else { + txTask.Txs = txs + } + + select { + case workCh <- txTask: + case <-reconstWorkersCtx.Done(): + // if ctx canceled, then maybe it's because of error in errgroup + // + // errgroup doesn't play with pattern where some 1 goroutine-producer is outside of errgroup + // but RwTx doesn't allow move between goroutines + return g.Wait() } - } else { - txTask.Txs = txs } - workCh <- txTask + inputTxNum++ } - inputTxNum++ - } - core.BlockExecutionTimer.UpdateDuration(t) - syncMetrics[stages.Execution].Set(bn) - select { - case <-ctx.Done(): - return ctx.Err() - default: + syncMetrics[stages.Execution].Set(bn) } + return err + }(); err != nil { + return err } - close(workCh) - wg.Wait() - reconDone <- struct{}{} // Complete logging and committing go-routine + for i := 0; i < workerCount; i++ { roTxs[i].Rollback() } if err := db.Update(ctx, func(tx kv.RwTx) error { - if err = rs.Flush(tx); err != nil { + if err := rs.Flush(tx); err != nil { return err } return nil @@ -1109,49 +1102,56 @@ func reconstituteStep(last bool, plainContractCollector := etl.NewCollector(fmt.Sprintf("%s recon plainContract", s.LogPrefix()), dirs.Tmp, etl.NewSortableBuffer(etl.BufferOptimalSize)) defer plainContractCollector.Close() var transposedKey []byte - if err = db.View(ctx, func(roTx kv.Tx) error { - kv.ReadAhead(ctx, db, atomic2.NewBool(false), kv.PlainStateR, nil, math.MaxUint32) - if err = roTx.ForEach(kv.PlainStateR, nil, func(k, v []byte) error { + + if err := db.View(ctx, func(roTx kv.Tx) error { + clear := kv.ReadAhead(ctx, db, &atomic.Bool{}, kv.PlainStateR, nil, math.MaxUint32) + defer clear() + if err := roTx.ForEach(kv.PlainStateR, nil, func(k, v []byte) error { transposedKey = append(transposedKey[:0], k[8:]...) transposedKey = append(transposedKey, k[:8]...) return plainStateCollector.Collect(transposedKey, v) }); err != nil { return err } - kv.ReadAhead(ctx, db, atomic2.NewBool(false), kv.PlainStateD, nil, math.MaxUint32) - if err = roTx.ForEach(kv.PlainStateD, nil, func(k, v []byte) error { + clear2 := kv.ReadAhead(ctx, db, &atomic.Bool{}, kv.PlainStateD, nil, math.MaxUint32) + defer clear2() + if err := roTx.ForEach(kv.PlainStateD, nil, func(k, v []byte) error { transposedKey = append(transposedKey[:0], v...) transposedKey = append(transposedKey, k...) return plainStateCollector.Collect(transposedKey, nil) }); err != nil { return err } - kv.ReadAhead(ctx, db, atomic2.NewBool(false), kv.CodeR, nil, math.MaxUint32) - if err = roTx.ForEach(kv.CodeR, nil, func(k, v []byte) error { + clear3 := kv.ReadAhead(ctx, db, &atomic.Bool{}, kv.CodeR, nil, math.MaxUint32) + defer clear3() + if err := roTx.ForEach(kv.CodeR, nil, func(k, v []byte) error { transposedKey = append(transposedKey[:0], k[8:]...) transposedKey = append(transposedKey, k[:8]...) return codeCollector.Collect(transposedKey, v) }); err != nil { return err } - kv.ReadAhead(ctx, db, atomic2.NewBool(false), kv.CodeD, nil, math.MaxUint32) - if err = roTx.ForEach(kv.CodeD, nil, func(k, v []byte) error { + clear4 := kv.ReadAhead(ctx, db, &atomic.Bool{}, kv.CodeD, nil, math.MaxUint32) + defer clear4() + if err := roTx.ForEach(kv.CodeD, nil, func(k, v []byte) error { transposedKey = append(transposedKey[:0], v...) transposedKey = append(transposedKey, k...) return codeCollector.Collect(transposedKey, nil) }); err != nil { return err } - kv.ReadAhead(ctx, db, atomic2.NewBool(false), kv.PlainContractR, nil, math.MaxUint32) - if err = roTx.ForEach(kv.PlainContractR, nil, func(k, v []byte) error { + clear5 := kv.ReadAhead(ctx, db, &atomic.Bool{}, kv.PlainContractR, nil, math.MaxUint32) + defer clear5() + if err := roTx.ForEach(kv.PlainContractR, nil, func(k, v []byte) error { transposedKey = append(transposedKey[:0], k[8:]...) transposedKey = append(transposedKey, k[:8]...) return plainContractCollector.Collect(transposedKey, v) }); err != nil { return err } - kv.ReadAhead(ctx, db, atomic2.NewBool(false), kv.PlainContractD, nil, math.MaxUint32) - if err = roTx.ForEach(kv.PlainContractD, nil, func(k, v []byte) error { + clear6 := kv.ReadAhead(ctx, db, &atomic.Bool{}, kv.PlainContractD, nil, math.MaxUint32) + defer clear6() + if err := roTx.ForEach(kv.PlainContractD, nil, func(k, v []byte) error { transposedKey = append(transposedKey[:0], v...) transposedKey = append(transposedKey, k...) return plainContractCollector.Collect(transposedKey, nil) @@ -1162,33 +1162,33 @@ func reconstituteStep(last bool, }); err != nil { return err } - if err = db.Update(ctx, func(tx kv.RwTx) error { - if err = tx.ClearBucket(kv.PlainStateR); err != nil { + if err := db.Update(ctx, func(tx kv.RwTx) error { + if err := tx.ClearBucket(kv.PlainStateR); err != nil { return err } - if err = tx.ClearBucket(kv.PlainStateD); err != nil { + if err := tx.ClearBucket(kv.PlainStateD); err != nil { return err } - if err = tx.ClearBucket(kv.CodeR); err != nil { + if err := tx.ClearBucket(kv.CodeR); err != nil { return err } - if err = tx.ClearBucket(kv.CodeD); err != nil { + if err := tx.ClearBucket(kv.CodeD); err != nil { return err } - if err = tx.ClearBucket(kv.PlainContractR); err != nil { + if err := tx.ClearBucket(kv.PlainContractR); err != nil { return err } - if err = tx.ClearBucket(kv.PlainContractD); err != nil { + if err := tx.ClearBucket(kv.PlainContractD); err != nil { return err } return nil }); err != nil { return err } - if err = chainDb.Update(ctx, func(tx kv.RwTx) error { + if err := chainDb.Update(ctx, func(tx kv.RwTx) error { var lastKey []byte var lastVal []byte - if err = plainStateCollector.Load(tx, kv.PlainState, func(k, v []byte, table etl.CurrentTableReader, next etl.LoadNextFunc) error { + if err := plainStateCollector.Load(tx, kv.PlainState, func(k, v []byte, table etl.CurrentTableReader, next etl.LoadNextFunc) error { if !bytes.Equal(k[:len(k)-8], lastKey) { if lastKey != nil { if e := next(lastKey, lastKey, lastVal); e != nil { @@ -1197,7 +1197,11 @@ func reconstituteStep(last bool, } lastKey = append(lastKey[:0], k[:len(k)-8]...) } - lastVal = append(lastVal[:0], v...) + if v == nil { // `nil` value means delete, `empty value []byte{}` means empty value + lastVal = nil + } else { + lastVal = append(lastVal[:0], v...) + } return nil }, etl.TransformArgs{}); err != nil { return err @@ -1216,7 +1220,7 @@ func reconstituteStep(last bool, } lastKey = nil lastVal = nil - if err = codeCollector.Load(tx, kv.Code, func(k, v []byte, table etl.CurrentTableReader, next etl.LoadNextFunc) error { + if err := codeCollector.Load(tx, kv.Code, func(k, v []byte, table etl.CurrentTableReader, next etl.LoadNextFunc) error { if !bytes.Equal(k[:len(k)-8], lastKey) { if lastKey != nil { if e := next(lastKey, lastKey, lastVal); e != nil { @@ -1225,7 +1229,11 @@ func reconstituteStep(last bool, } lastKey = append(lastKey[:0], k[:len(k)-8]...) } - lastVal = append(lastVal[:0], v...) + if v == nil { + lastVal = nil + } else { + lastVal = append(lastVal[:0], v...) + } return nil }, etl.TransformArgs{}); err != nil { return err @@ -1244,7 +1252,7 @@ func reconstituteStep(last bool, } lastKey = nil lastVal = nil - if err = plainContractCollector.Load(tx, kv.PlainContractCode, func(k, v []byte, table etl.CurrentTableReader, next etl.LoadNextFunc) error { + if err := plainContractCollector.Load(tx, kv.PlainContractCode, func(k, v []byte, table etl.CurrentTableReader, next etl.LoadNextFunc) error { if !bytes.Equal(k[:len(k)-8], lastKey) { if lastKey != nil { if e := next(lastKey, lastKey, lastVal); e != nil { @@ -1253,7 +1261,11 @@ func reconstituteStep(last bool, } lastKey = append(lastKey[:0], k[:len(k)-8]...) } - lastVal = append(lastVal[:0], v...) + if v == nil { + lastVal = nil + } else { + lastVal = append(lastVal[:0], v...) + } return nil }, etl.TransformArgs{}); err != nil { return err @@ -1278,10 +1290,22 @@ func reconstituteStep(last bool, return nil } +func safeCloseTxTaskCh(ch chan *exec22.TxTask) { + if ch == nil { + return + } + select { + case <-ch: + // Channel was already closed + default: + close(ch) + } +} + func ReconstituteState(ctx context.Context, s *StageState, dirs datadir.Dirs, workerCount int, batchSize datasize.ByteSize, chainDb kv.RwDB, blockReader services.FullBlockReader, logger log.Logger, agg *state2.AggregatorV3, engine consensus.Engine, - chainConfig *chain.Config, genesis *core.Genesis) (err error) { + chainConfig *chain.Config, genesis *types.Genesis) (err error) { startTime := time.Now() defer agg.EnableMadvNormal().DisableReadAhead() blockSnapshots := blockReader.(WithSnapshots).Snapshots() @@ -1313,7 +1337,8 @@ func ReconstituteState(ctx context.Context, s *StageState, dirs datadir.Dirs, wo return err } if !ok { - return fmt.Errorf("blockNum for mininmaxTxNum=%d not found", toTxNum) + lastBn, lastTn, _ := rawdbv3.TxNums.Last(tx) + return fmt.Errorf("blockNum for mininmaxTxNum=%d not found. See lastBlockNum=%d,lastTxNum=%d", toTxNum, lastBn, lastTn) } if blockNum == 0 { return fmt.Errorf("not enough transactions in the history data") @@ -1365,17 +1390,23 @@ func ReconstituteState(ctx context.Context, s *StageState, dirs datadir.Dirs, wo fillWorker := exec3.NewFillWorker(txNum, aggSteps[len(aggSteps)-1]) t := time.Now() - fillWorker.FillAccounts(plainStateCollector) + if err := fillWorker.FillAccounts(plainStateCollector); err != nil { + return err + } if time.Since(t) > 5*time.Second { log.Info(fmt.Sprintf("[%s] Filled accounts", s.LogPrefix()), "took", time.Since(t)) } t = time.Now() - fillWorker.FillStorage(plainStateCollector) + if err := fillWorker.FillStorage(plainStateCollector); err != nil { + return err + } if time.Since(t) > 5*time.Second { log.Info(fmt.Sprintf("[%s] Filled storage", s.LogPrefix()), "took", time.Since(t)) } t = time.Now() - fillWorker.FillCode(codeCollector, plainContractCollector) + if err := fillWorker.FillCode(codeCollector, plainContractCollector); err != nil { + return err + } if time.Since(t) > 5*time.Second { log.Info(fmt.Sprintf("[%s] Filled code", s.LogPrefix()), "took", time.Since(t)) } diff --git a/eth/stagedsync/stage_bodies.go b/eth/stagedsync/stage_bodies.go index 24914bc67da..34fd58c1dfb 100644 --- a/eth/stagedsync/stage_bodies.go +++ b/eth/stagedsync/stage_bodies.go @@ -14,6 +14,7 @@ import ( "github.com/ledgerwatch/log/v3" "github.com/ledgerwatch/erigon/core/rawdb" + "github.com/ledgerwatch/erigon/dataflow" "github.com/ledgerwatch/erigon/eth/stagedsync/stages" "github.com/ledgerwatch/erigon/turbo/adapter" "github.com/ledgerwatch/erigon/turbo/services" @@ -129,39 +130,14 @@ func BodiesForward( prevProgress := bodyProgress var noProgressCount uint = 0 // How many time the progress was printed without actual progress var totalDelivered uint64 = 0 + cr := ChainReader{Cfg: cfg.chanConfig, Db: tx} loopBody := func() (bool, error) { - // always check if a new request is needed at the start of the loop - // this will check for timed out old requests and attempt to send them again - start := time.Now() - currentTime := uint64(time.Now().Unix()) - req, err = cfg.bd.RequestMoreBodies(tx, cfg.blockReader, currentTime, cfg.blockPropagator) - if err != nil { - return false, fmt.Errorf("request more bodies: %w", err) - } - d1 += time.Since(start) - - peer = [64]byte{} - sentToPeer = false - - if req != nil { - start := time.Now() - peer, sentToPeer = cfg.bodyReqSend(ctx, req) - d2 += time.Since(start) - } - if req != nil && sentToPeer { - start := time.Now() - currentTime := uint64(time.Now().Unix()) - cfg.bd.RequestSent(req, currentTime+uint64(timeout), peer) - d3 += time.Since(start) - } - // loopCount is used here to ensure we don't get caught in a constant loop of making requests // having some time out so requesting again and cycling like that forever. We'll cap it // and break the loop so we can see if there are any records to actually process further down // then come back here again in the next cycle - loopCount := 0 - for req != nil && sentToPeer { + for loopCount := 0; loopCount == 0 || (req != nil && sentToPeer && loopCount < requestLoopCutOff); loopCount++ { start := time.Now() currentTime := uint64(time.Now().Unix()) req, err = cfg.bd.RequestMoreBodies(tx, cfg.blockReader, currentTime, cfg.blockPropagator) @@ -181,14 +157,9 @@ func BodiesForward( cfg.bd.RequestSent(req, currentTime+uint64(timeout), peer) d3 += time.Since(start) } - - loopCount++ - if loopCount >= requestLoopCutOff { - break - } } - start = time.Now() + start := time.Now() requestedLow, delivered, err := cfg.bd.GetDeliveries(tx) if err != nil { return false, err @@ -196,7 +167,6 @@ func BodiesForward( totalDelivered += delivered d4 += time.Since(start) start = time.Now() - cr := ChainReader{Cfg: cfg.chanConfig, Db: tx} toProcess := cfg.bd.NextProcessingCount() @@ -246,6 +216,9 @@ func BodiesForward( return false, err } } + if ok { + dataflow.BlockBodyDownloadStates.AddChange(blockHeight, dataflow.BlockBodyCleared) + } if blockHeight > bodyProgress { bodyProgress = blockHeight @@ -296,14 +269,11 @@ func BodiesForward( } // kick off the loop and check for any reason to stop and break early - for !stopped { - shouldBreak, err := loopBody() - if err != nil { + var shouldBreak bool + for !stopped && !shouldBreak { + if shouldBreak, err = loopBody(); err != nil { return err } - if shouldBreak { - break - } } // remove the temporary bucket for bodies stage diff --git a/eth/stagedsync/stage_cumulative_index.go b/eth/stagedsync/stage_cumulative_index.go index c9f9f01941d..23fbc6aa7e6 100644 --- a/eth/stagedsync/stage_cumulative_index.go +++ b/eth/stagedsync/stage_cumulative_index.go @@ -34,7 +34,7 @@ func SpawnStageCumulativeIndex(cfg CumulativeIndexCfg, s *StageState, tx kv.RwTx if !useExternalTx { var err error - tx, err = cfg.db.BeginRw(context.Background()) + tx, err = cfg.db.BeginRw(ctx) if err != nil { return err } @@ -102,6 +102,8 @@ func SpawnStageCumulativeIndex(cfg CumulativeIndexCfg, s *StageState, tx kv.RwTx // Check for logs select { + case <-ctx.Done(): + return ctx.Err() case <-logEvery.C: log.Info(fmt.Sprintf("[%s] Wrote Cumulative Index", s.LogPrefix()), "gasUsed", cumulativeGasUsed.String(), "now", currentBlockNumber, "blk/sec", float64(currentBlockNumber-prevProgress)/float64(logInterval/time.Second)) diff --git a/eth/stagedsync/stage_execute.go b/eth/stagedsync/stage_execute.go index f5998b7aa76..2eca369fd16 100644 --- a/eth/stagedsync/stage_execute.go +++ b/eth/stagedsync/stage_execute.go @@ -85,7 +85,7 @@ type ExecuteBlockCfg struct { dirs datadir.Dirs historyV3 bool syncCfg ethconfig.Sync - genesis *core.Genesis + genesis *types.Genesis agg *libstate.AggregatorV3 } @@ -105,7 +105,7 @@ func StageExecuteBlocksCfg( dirs datadir.Dirs, blockReader services.FullBlockReader, hd headerDownloader, - genesis *core.Genesis, + genesis *types.Genesis, syncCfg ethconfig.Sync, agg *libstate.AggregatorV3, ) ExecuteBlockCfg { @@ -170,11 +170,11 @@ func executeBlock( getHashFn := core.GetHashFn(block.Header(), getHeader) if isPoSa { - execRs, err = core.ExecuteBlockEphemerallyForBSC(cfg.chainConfig, &vmConfig, getHashFn, cfg.engine, block, stateReader, stateWriter, EpochReaderImpl{tx: tx}, ChainReaderImpl{config: cfg.chainConfig, tx: tx, blockReader: cfg.blockReader}, getTracer) + execRs, err = core.ExecuteBlockEphemerallyForBSC(cfg.chainConfig, &vmConfig, getHashFn, cfg.engine, block, stateReader, stateWriter, ChainReaderImpl{config: cfg.chainConfig, tx: tx, blockReader: cfg.blockReader}, getTracer) } else if isBor { - execRs, err = core.ExecuteBlockEphemerallyBor(cfg.chainConfig, &vmConfig, getHashFn, cfg.engine, block, stateReader, stateWriter, EpochReaderImpl{tx: tx}, ChainReaderImpl{config: cfg.chainConfig, tx: tx, blockReader: cfg.blockReader}, getTracer) + execRs, err = core.ExecuteBlockEphemerallyBor(cfg.chainConfig, &vmConfig, getHashFn, cfg.engine, block, stateReader, stateWriter, ChainReaderImpl{config: cfg.chainConfig, tx: tx, blockReader: cfg.blockReader}, getTracer) } else { - execRs, err = core.ExecuteBlockEphemerally(cfg.chainConfig, &vmConfig, getHashFn, cfg.engine, block, stateReader, stateWriter, EpochReaderImpl{tx: tx}, ChainReaderImpl{config: cfg.chainConfig, tx: tx, blockReader: cfg.blockReader}, getTracer) + execRs, err = core.ExecuteBlockEphemerally(cfg.chainConfig, &vmConfig, getHashFn, cfg.engine, block, stateReader, stateWriter, ChainReaderImpl{config: cfg.chainConfig, tx: tx, blockReader: cfg.blockReader}, getTracer) } if err != nil { return err @@ -281,10 +281,9 @@ func ExecBlockV3(s *StageState, u Unwinder, tx kv.RwTx, toBlock uint64, ctx cont if to > s.BlockNumber+16 { log.Info(fmt.Sprintf("[%s] Blocks execution", logPrefix), "from", s.BlockNumber, "to", to) } - rs := state.NewStateV3() parallel := initialCycle && tx == nil - if err := ExecV3(ctx, s, u, workersCount, cfg, tx, parallel, rs, logPrefix, - log.New(), to); err != nil { + if err := ExecV3(ctx, s, u, workersCount, cfg, tx, parallel, logPrefix, + to); err != nil { return fmt.Errorf("ExecV3: %w", err) } return nil @@ -312,7 +311,7 @@ func reconstituteBlock(agg *libstate.AggregatorV3, db kv.RoDB, tx kv.Tx) (n uint func unwindExec3(u *UnwindState, s *StageState, tx kv.RwTx, ctx context.Context, cfg ExecuteBlockCfg, accumulator *shards.Accumulator) (err error) { cfg.agg.SetLogPrefix(s.LogPrefix()) - rs := state.NewStateV3() + rs := state.NewStateV3(cfg.dirs.Tmp) // unwind all txs of u.UnwindPoint block. 1 txn in begin/end of block - system txs txNum, err := rawdbv3.TxNums.Min(tx, u.UnwindPoint+1) if err != nil { diff --git a/eth/stagedsync/stage_headers.go b/eth/stagedsync/stage_headers.go index 2747058d052..b2087efa73c 100644 --- a/eth/stagedsync/stage_headers.go +++ b/eth/stagedsync/stage_headers.go @@ -859,7 +859,7 @@ Loop: } // Load headers into the database var inSync bool - if inSync, err = cfg.hd.InsertHeaders(headerInserter.NewFeedHeaderFunc(tx, cfg.blockReader), cfg.chainConfig.TerminalTotalDifficulty, logPrefix, logEvery.C, uint64(currentTime.Unix())); err != nil { + if inSync, err = cfg.hd.InsertHeaders(headerInserter.NewFeedHeaderFunc(tx, cfg.blockReader, cfg.hd.Engine, cfg.chainConfig, cfg.hd.ConsensusHeaderReader), cfg.chainConfig.TerminalTotalDifficulty, logPrefix, logEvery.C, uint64(currentTime.Unix())); err != nil { return err } @@ -1149,26 +1149,6 @@ func (cr ChainReaderImpl) GetTd(hash libcommon.Hash, number uint64) *big.Int { return td } -type EpochReaderImpl struct { - tx kv.RwTx -} - -func (cr EpochReaderImpl) GetEpoch(hash libcommon.Hash, number uint64) ([]byte, error) { - return rawdb.ReadEpoch(cr.tx, number, hash) -} -func (cr EpochReaderImpl) PutEpoch(hash libcommon.Hash, number uint64, proof []byte) error { - return rawdb.WriteEpoch(cr.tx, number, hash, proof) -} -func (cr EpochReaderImpl) GetPendingEpoch(hash libcommon.Hash, number uint64) ([]byte, error) { - return rawdb.ReadPendingEpoch(cr.tx, number, hash) -} -func (cr EpochReaderImpl) PutPendingEpoch(hash libcommon.Hash, number uint64, proof []byte) error { - return rawdb.WritePendingEpoch(cr.tx, number, hash, proof) -} -func (cr EpochReaderImpl) FindBeforeOrEqualNumber(number uint64) (blockNum uint64, blockHash libcommon.Hash, transitionProof []byte, err error) { - return rawdb.FindEpochBeforeOrEqualNumber(cr.tx, number) -} - func HeadersPrune(p *PruneState, tx kv.RwTx, cfg HeadersCfg, ctx context.Context) (err error) { useExternalTx := tx != nil if !useExternalTx { diff --git a/eth/stagedsync/stage_mining_exec.go b/eth/stagedsync/stage_mining_exec.go index 98bacc2c16a..d1b160bf818 100644 --- a/eth/stagedsync/stage_mining_exec.go +++ b/eth/stagedsync/stage_mining_exec.go @@ -172,8 +172,12 @@ func SpawnMiningExecStage(s *StageState, tx kv.RwTx, cfg MiningExecCfg, quit <-c } var err error - _, current.Txs, current.Receipts, err = core.FinalizeBlockExecution(cfg.engine, stateReader, current.Header, current.Txs, current.Uncles, stateWriter, - &cfg.chainConfig, ibs, current.Receipts, current.Withdrawals, EpochReaderImpl{tx: tx}, ChainReaderImpl{config: &cfg.chainConfig, tx: tx, blockReader: cfg.blockReader}, true) + parentHeader := getHeader(current.Header.ParentHash, current.Header.Number.Uint64()-1) + var excessDataGas *big.Int + if parentHeader != nil { + excessDataGas = parentHeader.ExcessDataGas + } + _, current.Txs, current.Receipts, err = core.FinalizeBlockExecution(cfg.engine, stateReader, current.Header, current.Txs, current.Uncles, stateWriter, &cfg.chainConfig, ibs, current.Receipts, current.Withdrawals, ChainReaderImpl{config: &cfg.chainConfig, tx: tx, blockReader: cfg.blockReader}, true, excessDataGas) if err != nil { return err } @@ -376,12 +380,14 @@ func addTransactionsToMiningBlock(logPrefix string, current *MiningBlock, chainC var coalescedLogs types.Logs noop := state.NewNoopWriter() + parentHeader := getHeader(header.ParentHash, header.Number.Uint64()-1) + var miningCommitTx = func(txn types.Transaction, coinbase libcommon.Address, vmConfig *vm.Config, chainConfig chain.Config, ibs *state.IntraBlockState, current *MiningBlock) ([]*types.Log, error) { ibs.Prepare(txn.Hash(), libcommon.Hash{}, tcount) gasSnap := gasPool.Gas() snap := ibs.Snapshot() log.Debug("addTransactionsToMiningBlock", "txn hash", txn.Hash()) - receipt, _, err := core.ApplyTransaction(&chainConfig, core.GetHashFn(header, getHeader), engine, &coinbase, gasPool, ibs, noop, header, txn, &header.GasUsed, *vmConfig) + receipt, _, err := core.ApplyTransaction(&chainConfig, core.GetHashFn(header, getHeader), engine, &coinbase, gasPool, ibs, noop, header, txn, &header.GasUsed, *vmConfig, parentHeader.ExcessDataGas) if err != nil { ibs.RevertToSnapshot(snap) gasPool = new(core.GasPool).AddGas(gasSnap) // restore gasPool as well as ibs diff --git a/eth/stagedsync/stage_snapshots.go b/eth/stagedsync/stage_snapshots.go index 2117844804d..afa31e7dd19 100644 --- a/eth/stagedsync/stage_snapshots.go +++ b/eth/stagedsync/stage_snapshots.go @@ -10,6 +10,8 @@ import ( "time" "github.com/holiman/uint256" + "github.com/ledgerwatch/log/v3" + "github.com/ledgerwatch/erigon-lib/chain" libcommon "github.com/ledgerwatch/erigon-lib/common" "github.com/ledgerwatch/erigon-lib/common/cmp" @@ -22,6 +24,7 @@ import ( "github.com/ledgerwatch/erigon-lib/kv/kvcfg" "github.com/ledgerwatch/erigon-lib/kv/rawdbv3" "github.com/ledgerwatch/erigon-lib/state" + "github.com/ledgerwatch/erigon/consensus" "github.com/ledgerwatch/erigon/consensus/parlia" "github.com/ledgerwatch/erigon/core/rawdb" @@ -31,7 +34,6 @@ import ( "github.com/ledgerwatch/erigon/turbo/services" "github.com/ledgerwatch/erigon/turbo/snapshotsync" "github.com/ledgerwatch/erigon/turbo/snapshotsync/snapcfg" - "github.com/ledgerwatch/log/v3" ) type SnapshotsCfg struct { @@ -164,6 +166,8 @@ func DownloadAndIndexSnapshotsIfNeed(s *StageState, ctx context.Context, tx kv.R } if cfg.historyV3 { + cfg.agg.CleanDir() + indexWorkers := estimate.IndexSnapshot.Workers() if err := cfg.agg.BuildMissedIndices(ctx, indexWorkers); err != nil { return err @@ -534,7 +538,7 @@ func SnapshotsPrune(s *PruneState, cfg SnapshotsCfg, ctx context.Context, tx kv. } br.RetireBlocksInBackground(ctx, s.ForwardProgress, log.LvlDebug) - cfg.agg.BuildFilesInBackground() + //cfg.agg.BuildFilesInBackground() } if !useExternalTx { diff --git a/eth/tracers/internal/tracetest/calltrace_test.go b/eth/tracers/internal/tracetest/calltrace_test.go index 26009ae8c25..9c3c5ab005d 100644 --- a/eth/tracers/internal/tracetest/calltrace_test.go +++ b/eth/tracers/internal/tracetest/calltrace_test.go @@ -28,7 +28,9 @@ import ( "github.com/holiman/uint256" "github.com/ledgerwatch/erigon-lib/chain" libcommon "github.com/ledgerwatch/erigon-lib/common" - "github.com/ledgerwatch/erigon-lib/kv/memdb" + "github.com/ledgerwatch/erigon-lib/common/hexutility" + "github.com/ledgerwatch/erigon/turbo/stages" + "github.com/stretchr/testify/require" "github.com/ledgerwatch/erigon/common" "github.com/ledgerwatch/erigon/common/hexutil" @@ -60,7 +62,7 @@ type callContext struct { type callLog struct { Address libcommon.Address `json:"address"` Topics []libcommon.Hash `json:"topics"` - Data hexutil.Bytes `json:"data"` + Data hexutility.Bytes `json:"data"` } // callTrace is the result of a callTracer run. @@ -69,8 +71,8 @@ type callTrace struct { Gas *hexutil.Uint64 `json:"gas"` GasUsed *hexutil.Uint64 `json:"gasUsed"` To libcommon.Address `json:"to,omitempty"` - Input hexutil.Bytes `json:"input"` - Output hexutil.Bytes `json:"output,omitempty"` + Input hexutility.Bytes `json:"input"` + Output hexutility.Bytes `json:"output,omitempty"` Error string `json:"error,omitempty"` Revertal string `json:"revertReason,omitempty"` Calls []callTrace `json:"calls,omitempty"` @@ -82,7 +84,7 @@ type callTrace struct { // callTracerTest defines a single test to check the call tracer against. type callTracerTest struct { - Genesis *core.Genesis `json:"genesis"` + Genesis *types.Genesis `json:"genesis"` Context *callContext `json:"context"` Input string `json:"input"` TracerConfig json.RawMessage `json:"tracerConfig"` @@ -147,10 +149,13 @@ func testCallTracer(tracerName string, dirPath string, t *testing.T) { Difficulty: (*big.Int)(test.Context.Difficulty), GasLimit: uint64(test.Context.GasLimit), } - _, dbTx = memdb.NewTestTx(t) - rules = test.Genesis.Config.Rules(context.BlockNumber, context.Time) - statedb, _ = tests.MakePreState(rules, dbTx, test.Genesis.Alloc, uint64(test.Context.Number)) + rules = test.Genesis.Config.Rules(context.BlockNumber, context.Time) ) + m := stages.Mock(t) + dbTx, err := m.DB.BeginRw(m.Ctx) + require.NoError(t, err) + defer dbTx.Rollback() + statedb, _ := tests.MakePreState(rules, dbTx, test.Genesis.Alloc, uint64(test.Context.Number)) if test.Genesis.BaseFee != nil { context.BaseFee, _ = uint256.FromBig(test.Genesis.BaseFee) } @@ -222,12 +227,12 @@ func BenchmarkTracers(b *testing.B) { if err := json.Unmarshal(blob, test); err != nil { b.Fatalf("failed to parse testcase: %v", err) } - benchTracer("callTracer", test, b) + benchTracer(b, "callTracer", test) }) } } -func benchTracer(tracerName string, test *callTracerTest, b *testing.B) { +func benchTracer(b *testing.B, tracerName string, test *callTracerTest) { // Configure a blockchain with the given prestate tx, err := types.DecodeTransaction(rlp.NewStream(bytes.NewReader(common.FromHex(test.Input)), 0)) if err != nil { @@ -253,7 +258,10 @@ func benchTracer(tracerName string, test *callTracerTest, b *testing.B) { Difficulty: (*big.Int)(test.Context.Difficulty), GasLimit: uint64(test.Context.GasLimit), } - _, dbTx := memdb.NewTestTx(b) + m := stages.Mock(b) + dbTx, err := m.DB.BeginRw(m.Ctx) + require.NoError(b, err) + defer dbTx.Rollback() statedb, _ := tests.MakePreState(rules, dbTx, test.Genesis.Alloc, uint64(test.Context.Number)) b.ReportAllocs() @@ -315,18 +323,22 @@ func TestZeroValueToNotExitCall(t *testing.T) { byte(vm.DUP1), byte(vm.PUSH1), 0xff, byte(vm.GAS), // value=0,address=0xff, gas=GAS byte(vm.CALL), } - var alloc = core.GenesisAlloc{ - to: core.GenesisAccount{ + var alloc = types.GenesisAlloc{ + to: types.GenesisAccount{ Nonce: 1, Code: code, }, - origin: core.GenesisAccount{ + origin: types.GenesisAccount{ Nonce: 0, Balance: big.NewInt(500000000000000), }, } rules := params.MainnetChainConfig.Rules(context.BlockNumber, context.Time) - _, dbTx := memdb.NewTestTx(t) + m := stages.Mock(t) + dbTx, err := m.DB.BeginRw(m.Ctx) + require.NoError(t, err) + defer dbTx.Rollback() + statedb, _ := tests.MakePreState(rules, dbTx, alloc, context.BlockNumber) // Create the tracer, the EVM environment and run it tracer, err := tracers.New("callTracer", nil, nil) diff --git a/eth/tracers/internal/tracetest/prestate_test.go b/eth/tracers/internal/tracetest/prestate_test.go index 987aee88d75..f6bd6ebb1e6 100644 --- a/eth/tracers/internal/tracetest/prestate_test.go +++ b/eth/tracers/internal/tracetest/prestate_test.go @@ -27,7 +27,8 @@ import ( "github.com/holiman/uint256" libcommon "github.com/ledgerwatch/erigon-lib/common" - "github.com/ledgerwatch/erigon-lib/kv/memdb" + "github.com/ledgerwatch/erigon/turbo/stages" + "github.com/stretchr/testify/require" "github.com/ledgerwatch/erigon/common" "github.com/ledgerwatch/erigon/core" @@ -112,10 +113,13 @@ func testPrestateDiffTracer(tracerName string, dirPath string, t *testing.T) { Difficulty: (*big.Int)(test.Context.Difficulty), GasLimit: uint64(test.Context.GasLimit), } - _, dbTx = memdb.NewTestTx(t) - rules = test.Genesis.Config.Rules(context.BlockNumber, context.Time) - statedb, _ = tests.MakePreState(rules, dbTx, test.Genesis.Alloc, context.BlockNumber) + rules = test.Genesis.Config.Rules(context.BlockNumber, context.Time) ) + m := stages.Mock(t) + dbTx, err := m.DB.BeginRw(m.Ctx) + require.NoError(t, err) + defer dbTx.Rollback() + statedb, _ := tests.MakePreState(rules, dbTx, test.Genesis.Alloc, context.BlockNumber) if test.Genesis.BaseFee != nil { context.BaseFee, _ = uint256.FromBig(test.Genesis.BaseFee) } diff --git a/eth/tracers/logger/gen_structlog.go b/eth/tracers/logger/gen_structlog.go index 15d82751044..fa9de16a7b4 100644 --- a/eth/tracers/logger/gen_structlog.go +++ b/eth/tracers/logger/gen_structlog.go @@ -5,8 +5,8 @@ import ( "math/big" libcommon "github.com/ledgerwatch/erigon-lib/common" + "github.com/ledgerwatch/erigon-lib/common/hexutility" - "github.com/ledgerwatch/erigon/common/hexutil" "github.com/ledgerwatch/erigon/common/math" "github.com/ledgerwatch/erigon/core/vm" ) @@ -20,11 +20,11 @@ func (s StructLog) MarshalJSON() ([]byte, error) { Op vm.OpCode `json:"op"` Gas math.HexOrDecimal64 `json:"gas"` GasCost math.HexOrDecimal64 `json:"gasCost"` - Memory hexutil.Bytes `json:"memory"` + Memory hexutility.Bytes `json:"memory"` MemorySize int `json:"memSize"` Stack []*math.HexOrDecimal256 `json:"stack"` ReturnStack []math.HexOrDecimal64 `json:"returnStack"` - ReturnData hexutil.Bytes `json:"returnData"` + ReturnData hexutility.Bytes `json:"returnData"` Storage map[libcommon.Hash]libcommon.Hash `json:"-"` Depth int `json:"depth"` RefundCounter uint64 `json:"refund"` @@ -62,10 +62,10 @@ func (s *StructLog) UnmarshalJSON(input []byte) error { Op *vm.OpCode `json:"op"` Gas *math.HexOrDecimal64 `json:"gas"` GasCost *math.HexOrDecimal64 `json:"gasCost"` - Memory *hexutil.Bytes `json:"memory"` + Memory *hexutility.Bytes `json:"memory"` MemorySize *int `json:"memSize"` Stack []*math.HexOrDecimal256 `json:"stack"` - ReturnData *hexutil.Bytes `json:"returnData"` + ReturnData *hexutility.Bytes `json:"returnData"` Storage map[libcommon.Hash]libcommon.Hash `json:"-"` Depth *int `json:"depth"` RefundCounter *uint64 `json:"refund"` diff --git a/eth/tracers/logger/logger.go b/eth/tracers/logger/logger.go index 97934e51cc0..3beb7e7d96c 100644 --- a/eth/tracers/logger/logger.go +++ b/eth/tracers/logger/logger.go @@ -11,10 +11,11 @@ import ( "strings" "github.com/holiman/uint256" + "github.com/ledgerwatch/erigon-lib/chain" libcommon "github.com/ledgerwatch/erigon-lib/common" + "github.com/ledgerwatch/erigon-lib/common/hexutility" - "github.com/ledgerwatch/erigon/common/hexutil" "github.com/ledgerwatch/erigon/common/math" "github.com/ledgerwatch/erigon/core/types" "github.com/ledgerwatch/erigon/core/vm" @@ -70,8 +71,8 @@ type structLogMarshaling struct { Stack []*math.HexOrDecimal256 Gas math.HexOrDecimal64 GasCost math.HexOrDecimal64 - Memory hexutil.Bytes - ReturnData hexutil.Bytes + Memory hexutility.Bytes + ReturnData hexutility.Bytes OpName string `json:"opName"` // adds call to OpName() in MarshalJSON ErrorString string `json:"error"` // adds call to ErrorString() in MarshalJSON } diff --git a/eth/tracers/native/call.go b/eth/tracers/native/call.go index 59982d23ec5..4a70838bd00 100644 --- a/eth/tracers/native/call.go +++ b/eth/tracers/native/call.go @@ -23,7 +23,9 @@ import ( "sync/atomic" "github.com/holiman/uint256" + libcommon "github.com/ledgerwatch/erigon-lib/common" + "github.com/ledgerwatch/erigon-lib/common/hexutility" "github.com/ledgerwatch/erigon/accounts/abi" "github.com/ledgerwatch/erigon/common" @@ -41,7 +43,7 @@ func init() { type callLog struct { Address libcommon.Address `json:"address"` Topics []libcommon.Hash `json:"topics"` - Data hexutil.Bytes `json:"data"` + Data hexutility.Bytes `json:"data"` } type callFrame struct { @@ -96,8 +98,8 @@ type callFrameMarshaling struct { Gas hexutil.Uint64 GasUsed hexutil.Uint64 Value *hexutil.Big - Input hexutil.Bytes - Output hexutil.Bytes + Input hexutility.Bytes + Output hexutility.Bytes } type callTracer struct { @@ -181,7 +183,7 @@ func (t *callTracer) CaptureState(pc uint64, op vm.OpCode, gas, cost uint64, sco } data := scope.Memory.GetCopy(int64(mStart.Uint64()), int64(mSize.Uint64())) - log := callLog{Address: scope.Contract.Address(), Topics: topics, Data: hexutil.Bytes(data)} + log := callLog{Address: scope.Contract.Address(), Topics: topics, Data: hexutility.Bytes(data)} t.callstack[len(t.callstack)-1].Logs = append(t.callstack[len(t.callstack)-1].Logs, log) } } diff --git a/eth/tracers/native/gen_account_json.go b/eth/tracers/native/gen_account_json.go index ec2f40728b1..d4f00b2a4e2 100644 --- a/eth/tracers/native/gen_account_json.go +++ b/eth/tracers/native/gen_account_json.go @@ -7,6 +7,7 @@ import ( "math/big" libcommon "github.com/ledgerwatch/erigon-lib/common" + "github.com/ledgerwatch/erigon-lib/common/hexutility" "github.com/ledgerwatch/erigon/common/hexutil" ) @@ -17,7 +18,7 @@ var _ = (*accountMarshaling)(nil) func (a account) MarshalJSON() ([]byte, error) { type account struct { Balance *hexutil.Big `json:"balance,omitempty"` - Code hexutil.Bytes `json:"code,omitempty"` + Code hexutility.Bytes `json:"code,omitempty"` Nonce uint64 `json:"nonce,omitempty"` Storage map[libcommon.Hash]libcommon.Hash `json:"storage,omitempty"` } @@ -33,7 +34,7 @@ func (a account) MarshalJSON() ([]byte, error) { func (a *account) UnmarshalJSON(input []byte) error { type account struct { Balance *hexutil.Big `json:"balance,omitempty"` - Code *hexutil.Bytes `json:"code,omitempty"` + Code *hexutility.Bytes `json:"code,omitempty"` Nonce *uint64 `json:"nonce,omitempty"` Storage map[libcommon.Hash]libcommon.Hash `json:"storage,omitempty"` } diff --git a/eth/tracers/native/gen_callframe_json.go b/eth/tracers/native/gen_callframe_json.go index ac3cfc9386c..9a49f0f7cc5 100644 --- a/eth/tracers/native/gen_callframe_json.go +++ b/eth/tracers/native/gen_callframe_json.go @@ -7,6 +7,7 @@ import ( "math/big" libcommon "github.com/ledgerwatch/erigon-lib/common" + "github.com/ledgerwatch/erigon-lib/common/hexutility" "github.com/ledgerwatch/erigon/common/hexutil" "github.com/ledgerwatch/erigon/core/vm" @@ -22,8 +23,8 @@ func (c callFrame) MarshalJSON() ([]byte, error) { Gas hexutil.Uint64 `json:"gas"` GasUsed hexutil.Uint64 `json:"gasUsed"` To libcommon.Address `json:"to,omitempty" rlp:"optional"` - Input hexutil.Bytes `json:"input" rlp:"optional"` - Output hexutil.Bytes `json:"output,omitempty" rlp:"optional"` + Input hexutility.Bytes `json:"input" rlp:"optional"` + Output hexutility.Bytes `json:"output,omitempty" rlp:"optional"` Error string `json:"error,omitempty" rlp:"optional"` Revertal string `json:"revertReason,omitempty"` Calls []callFrame `json:"calls,omitempty" rlp:"optional"` @@ -56,8 +57,8 @@ func (c *callFrame) UnmarshalJSON(input []byte) error { Gas *hexutil.Uint64 `json:"gas"` GasUsed *hexutil.Uint64 `json:"gasUsed"` To *libcommon.Address `json:"to,omitempty" rlp:"optional"` - Input *hexutil.Bytes `json:"input" rlp:"optional"` - Output *hexutil.Bytes `json:"output,omitempty" rlp:"optional"` + Input *hexutility.Bytes `json:"input" rlp:"optional"` + Output *hexutility.Bytes `json:"output,omitempty" rlp:"optional"` Error *string `json:"error,omitempty" rlp:"optional"` Revertal *string `json:"revertReason,omitempty"` Calls []callFrame `json:"calls,omitempty" rlp:"optional"` diff --git a/eth/tracers/native/prestate.go b/eth/tracers/native/prestate.go index 89c497d50a8..3bce65a17d0 100644 --- a/eth/tracers/native/prestate.go +++ b/eth/tracers/native/prestate.go @@ -23,7 +23,9 @@ import ( "sync/atomic" "github.com/holiman/uint256" + libcommon "github.com/ledgerwatch/erigon-lib/common" + "github.com/ledgerwatch/erigon-lib/common/hexutility" "github.com/ledgerwatch/erigon/common/hexutil" "github.com/ledgerwatch/erigon/core/vm" @@ -52,7 +54,7 @@ func (a *account) exists() bool { type accountMarshaling struct { Balance *hexutil.Big - Code hexutil.Bytes + Code hexutility.Bytes } type prestateTracer struct { diff --git a/eth/tracers/tracers_test.go b/eth/tracers/tracers_test.go index 6e4deaa2f35..3ec95a9152a 100644 --- a/eth/tracers/tracers_test.go +++ b/eth/tracers/tracers_test.go @@ -24,8 +24,6 @@ import ( "testing" libcommon "github.com/ledgerwatch/erigon-lib/common" - "github.com/ledgerwatch/erigon-lib/kv/memdb" - "github.com/ledgerwatch/erigon/common/hexutil" "github.com/ledgerwatch/erigon/core" "github.com/ledgerwatch/erigon/core/types" @@ -34,6 +32,8 @@ import ( "github.com/ledgerwatch/erigon/crypto" "github.com/ledgerwatch/erigon/params" "github.com/ledgerwatch/erigon/tests" + "github.com/ledgerwatch/erigon/turbo/stages" + "github.com/stretchr/testify/require" "github.com/holiman/uint256" @@ -80,22 +80,25 @@ func TestPrestateTracerCreate2(t *testing.T) { GasLimit: uint64(6000000), } context.BaseFee = uint256.NewInt(0) - alloc := core.GenesisAlloc{} + alloc := types.GenesisAlloc{} // The code pushes 'deadbeef' into memory, then the other params, and calls CREATE2, then returns // the address - alloc[libcommon.HexToAddress("0x00000000000000000000000000000000deadbeef")] = core.GenesisAccount{ + alloc[libcommon.HexToAddress("0x00000000000000000000000000000000deadbeef")] = types.GenesisAccount{ Nonce: 1, Code: hexutil.MustDecode("0x63deadbeef60005263cafebabe6004601c6000F560005260206000F3"), Balance: big.NewInt(1), } - alloc[origin] = core.GenesisAccount{ + alloc[origin] = types.GenesisAccount{ Nonce: 1, Code: []byte{}, Balance: big.NewInt(500000000000000), } - _, tx := memdb.NewTestTx(t) + m := stages.Mock(t) + tx, err := m.DB.BeginRw(m.Ctx) + require.NoError(t, err) + defer tx.Rollback() rules := params.AllProtocolChanges.Rules(context.BlockNumber, context.Time) statedb, _ := tests.MakePreState(rules, tx, alloc, context.BlockNumber) diff --git a/ethdb/privateapi/ethbackend.go b/ethdb/privateapi/ethbackend.go index 1f9ae3c7c11..7fad85f3f53 100644 --- a/ethdb/privateapi/ethbackend.go +++ b/ethdb/privateapi/ethbackend.go @@ -296,8 +296,57 @@ func (s *EthBackendServer) checkWithdrawalsPresence(time uint64, withdrawals []* return nil } -func (s *EthBackendServer) EngineGetBlobsBundleV1(ctx context.Context, in *remote.EngineGetBlobsBundleRequest) (*types2.BlobsBundleV1, error) { - return nil, fmt.Errorf("EngineGetBlobsBundleV1: not implemented yet") +func (s *EthBackendServer) EngineGetBlobsBundleV1(ctx context.Context, req *remote.EngineGetBlobsBundleRequest) (*types2.BlobsBundleV1, error) { + if !s.proposing { + return nil, fmt.Errorf("execution layer not running as a proposer. enable proposer by taking out the --proposer.disable flag on startup") + } + + if s.config.TerminalTotalDifficulty == nil { + return nil, fmt.Errorf("not a proof-of-stake chain") + } + + log.Debug("[GetBlobsBundleV1] acquiring lock") + s.lock.Lock() + defer s.lock.Unlock() + log.Debug("[GetBlobsBundleV1] lock acquired") + + builder, ok := s.builders[req.PayloadId] + if !ok { + log.Warn("Payload not stored", "payloadId", req.PayloadId) + return nil, &UnknownPayloadErr + } + + block, err := builder.Stop() + if err != nil { + log.Error("Failed to build PoS block", "err", err) + return nil, err + } + + blobsBundle := &types2.BlobsBundleV1{ + BlockHash: gointerfaces.ConvertHashToH256(block.Block.Header().Hash()), + } + for i, tx := range block.Block.Transactions() { + if tx.Type() != types.BlobTxType { + continue + } + blobtx, ok := tx.(*types.BlobTxWrapper) + if !ok { + return nil, fmt.Errorf("expected blob transaction to be type BlobTxWrapper, got: %T", blobtx) + } + versionedHashes, kzgs, blobs, proofs := blobtx.GetDataHashes(), blobtx.BlobKzgs, blobtx.Blobs, blobtx.Proofs + lenCheck := len(versionedHashes) + if lenCheck != len(kzgs) || lenCheck != len(blobs) || lenCheck != len(blobtx.Proofs) { + return nil, fmt.Errorf("tx %d in block %s has inconsistent blobs (%d) / kzgs (%d) / proofs (%d)"+ + " / versioned hashes (%d)", i, block.Block.Hash(), len(blobs), len(kzgs), len(proofs), lenCheck) + } + for _, blob := range blobs { + blobsBundle.Blobs = append(blobsBundle.Blobs, blob[:]) + } + for _, kzg := range kzgs { + blobsBundle.Kzgs = append(blobsBundle.Kzgs, kzg[:]) + } + } + return blobsBundle, nil } // EngineNewPayload validates and possibly executes payload @@ -680,6 +729,7 @@ func (s *EthBackendServer) EngineForkChoiceUpdated(ctx context.Context, req *rem // First check if we're already building a block with the requested parameters if reflect.DeepEqual(s.lastParameters, ¶m) { + log.Info("[ForkChoiceUpdated] duplicate build request") return &remote.EngineForkChoiceUpdatedResponse{ PayloadStatus: &remote.EnginePayloadStatus{ Status: remote.EngineStatus_VALID, @@ -697,7 +747,7 @@ func (s *EthBackendServer) EngineForkChoiceUpdated(ctx context.Context, req *rem s.lastParameters = ¶m s.builders[s.payloadId] = builder.NewBlockBuilder(s.builderFunc, ¶m) - log.Debug("BlockBuilder added", "payload", s.payloadId) + log.Info("[ForkChoiceUpdated] BlockBuilder added", "payload", s.payloadId) return &remote.EngineForkChoiceUpdatedResponse{ PayloadStatus: &remote.EnginePayloadStatus{ @@ -713,6 +763,7 @@ func (s *EthBackendServer) EngineGetPayloadBodiesByHashV1(ctx context.Context, r if err != nil { return nil, err } + defer tx.Rollback() bodies := make([]*types2.ExecutionPayloadBodyV1, len(request.Hashes)) @@ -738,6 +789,7 @@ func (s *EthBackendServer) EngineGetPayloadBodiesByRangeV1(ctx context.Context, if err != nil { return nil, err } + defer tx.Rollback() bodies := make([]*types2.ExecutionPayloadBodyV1, 0, request.Count) diff --git a/go.mod b/go.mod index 1ad84dbfa15..ad80b8b4191 100644 --- a/go.mod +++ b/go.mod @@ -1,18 +1,18 @@ module github.com/ledgerwatch/erigon -go 1.18 +go 1.19 require ( - github.com/ledgerwatch/erigon-lib v0.0.0-20230305180029-3d69e5177fc4 + github.com/ledgerwatch/erigon-lib v0.0.0-20230330024812-ae99e29d013b github.com/ledgerwatch/erigon-snapshot v1.1.1-0.20230306083105-1391330d62a3 github.com/ledgerwatch/log/v3 v3.7.0 github.com/ledgerwatch/secp256k1 v1.0.0 github.com/ledgerwatch/trackerslist v1.1.0 // indirect - github.com/torquem-ch/mdbx-go v0.27.8 + github.com/torquem-ch/mdbx-go v0.27.10 ) require ( - github.com/99designs/gqlgen v0.17.25 + github.com/99designs/gqlgen v0.17.27 github.com/Giulio2002/bls v0.0.0-20230217173148-c87a29266b6c github.com/RoaringBitmap/roaring v1.2.3 github.com/VictoriaMetrics/fastcache v1.12.1 @@ -20,55 +20,63 @@ require ( github.com/anacrolix/sync v0.4.0 github.com/anacrolix/torrent v1.48.1-0.20230219022425-e8971ea0f1bf github.com/benesch/cgosymbolizer v0.0.0-20190515212042-bec6fe6e597b + github.com/bnb-chain/ics23 v0.1.0 github.com/btcsuite/btcd v0.22.0-beta - github.com/btcsuite/btcd/btcec/v2 v2.2.1 + github.com/btcsuite/btcd/btcec/v2 v2.3.2 github.com/c2h5oh/datasize v0.0.0-20220606134207-859f65c6625b - github.com/consensys/gnark-crypto v0.4.1-0.20210426202927-39ac3d4b3f1f + github.com/cometbft/cometbft v0.37.1 + github.com/consensys/gnark-crypto v0.10.0 github.com/crate-crypto/go-ipa v0.0.0-20221111143132-9aa5d42120bc + github.com/crate-crypto/go-kzg-4844 v0.0.0-20230405223534-4364e2f9d209 github.com/davecgh/go-spew v1.1.1 github.com/deckarep/golang-set v1.8.0 - github.com/deckarep/golang-set/v2 v2.1.0 - github.com/docker/docker v20.10.17+incompatible - github.com/dop251/goja v0.0.0-20220405120441-9037c2b61cbf + github.com/deckarep/golang-set/v2 v2.3.0 + github.com/docker/docker v20.10.19+incompatible + github.com/dop251/goja v0.0.0-20230122112309-96b1610dd4f7 github.com/edsrzf/mmap-go v1.1.0 github.com/emicklei/dot v1.0.0 github.com/emirpasic/gods v1.18.1 github.com/fjl/gencodec v0.0.0-20220412091415-8bb9e558978c github.com/gballet/go-verkle v0.0.0-20221121182333-31427a1f2d35 - github.com/goccy/go-json v0.9.7 + github.com/goccy/go-json v0.9.11 github.com/gofrs/flock v0.8.1 github.com/golang-jwt/jwt/v4 v4.5.0 github.com/golang/mock v1.6.0 github.com/golang/snappy v0.0.4 github.com/google/btree v1.1.2 - github.com/google/gofuzz v1.1.1-0.20200604201612-c04b05f3adfa + github.com/google/gofuzz v1.2.0 github.com/gorilla/websocket v1.5.0 - github.com/grpc-ecosystem/go-grpc-middleware v1.3.0 + github.com/grpc-ecosystem/go-grpc-middleware v1.4.0 github.com/hashicorp/golang-lru v0.5.5-0.20210104140557-80c98217689d - github.com/hashicorp/golang-lru/v2 v2.0.1 - github.com/holiman/uint256 v1.2.1 + github.com/hashicorp/golang-lru/v2 v2.0.2 + github.com/holiman/uint256 v1.2.2 github.com/huandu/xstrings v1.4.0 github.com/huin/goupnp v1.1.0 github.com/jackpal/go-nat-pmp v1.0.2 github.com/json-iterator/go v1.1.12 github.com/julienschmidt/httprouter v1.3.0 github.com/kevinburke/go-bindata v3.21.0+incompatible - github.com/libp2p/go-libp2p v0.25.1 - github.com/libp2p/go-libp2p-pubsub v0.9.1-0.20230221111042-3dbc2fd5baca + github.com/libp2p/go-libp2p v0.26.2 + github.com/libp2p/go-libp2p-pubsub v0.9.3 github.com/maticnetwork/crand v1.0.2 github.com/maticnetwork/polyproto v0.0.2 + github.com/minio/sha256-simd v1.0.0 github.com/multiformats/go-multiaddr v0.8.0 github.com/nxadm/tail v1.4.9-0.20211216163028-4472660a31a6 github.com/pbnjay/memory v0.0.0-20210728143218-7b4eea64cf58 github.com/pelletier/go-toml v1.9.5 github.com/pelletier/go-toml/v2 v2.0.7 github.com/pion/stun v0.4.0 + github.com/pkg/errors v0.9.1 + github.com/prometheus/client_golang v1.14.0 github.com/protolambda/eth2-shuffle v1.1.0 - github.com/prysmaticlabs/fastssz v0.0.0-20220628121656-93dfe28febab + github.com/protolambda/ztyp v0.2.2 github.com/prysmaticlabs/go-bitfield v0.0.0-20210809151128-385d8c5e3fb7 github.com/prysmaticlabs/gohashtree v0.0.2-alpha + github.com/prysmaticlabs/prysm/v4 v4.0.3 github.com/quasilyte/go-ruleguard/dsl v0.3.22 github.com/rs/cors v1.8.3 + github.com/shirou/gopsutil/v3 v3.23.3 github.com/spf13/cobra v1.6.1 github.com/spf13/pflag v1.0.5 github.com/stretchr/testify v1.8.2 @@ -78,24 +86,25 @@ require ( github.com/tidwall/btree v1.6.0 github.com/ugorji/go/codec v1.1.13 github.com/ugorji/go/codec/codecgen v1.1.13 - github.com/urfave/cli/v2 v2.24.4 + github.com/urfave/cli/v2 v2.25.0 github.com/valyala/fastjson v1.6.4 github.com/vektah/gqlparser/v2 v2.5.1 + github.com/willf/bitset v1.1.10 github.com/xsleonard/go-merkle v1.1.0 - go.uber.org/atomic v1.10.0 go.uber.org/zap v1.24.0 - golang.org/x/crypto v0.6.0 - golang.org/x/exp v0.0.0-20230224173230-c95f2b4c22f2 - golang.org/x/net v0.7.0 + golang.org/x/crypto v0.8.0 + golang.org/x/exp v0.0.0-20230321023759-10a507213a29 + golang.org/x/net v0.9.0 golang.org/x/sync v0.1.0 - golang.org/x/sys v0.5.0 + golang.org/x/sys v0.7.0 golang.org/x/time v0.3.0 - google.golang.org/grpc v1.53.0 - google.golang.org/grpc/cmd/protoc-gen-go-grpc v1.2.0 - google.golang.org/protobuf v1.28.1 + google.golang.org/grpc v1.54.0 + google.golang.org/grpc/cmd/protoc-gen-go-grpc v1.3.0 + google.golang.org/protobuf v1.30.0 gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c + gopkg.in/natefinch/lumberjack.v2 v2.2.1 gopkg.in/yaml.v2 v2.4.0 - modernc.org/sqlite v1.21.0 + modernc.org/sqlite v1.21.1 pgregory.net/rapid v0.5.5 ) @@ -112,7 +121,7 @@ require ( github.com/anacrolix/log v0.13.2-0.20221123232138-02e2764801c3 // indirect github.com/anacrolix/missinggo v1.3.0 // indirect github.com/anacrolix/missinggo/perf v1.0.0 // indirect - github.com/anacrolix/missinggo/v2 v2.7.0 // indirect + github.com/anacrolix/missinggo/v2 v2.7.1 // indirect github.com/anacrolix/mmsg v1.0.0 // indirect github.com/anacrolix/multiless v0.3.0 // indirect github.com/anacrolix/stm v0.4.0 // indirect @@ -122,35 +131,45 @@ require ( github.com/benbjohnson/clock v1.3.0 // indirect github.com/benbjohnson/immutable v0.3.0 // indirect github.com/beorn7/perks v1.0.1 // indirect - github.com/bits-and-blooms/bitset v1.2.2 // indirect + github.com/bits-and-blooms/bitset v1.5.0 // indirect github.com/bradfitz/iter v0.0.0-20191230175014-e8f45d346db8 // indirect + github.com/cespare/xxhash v1.1.0 // indirect github.com/cespare/xxhash/v2 v2.2.0 // indirect + github.com/consensys/bavard v0.1.13 // indirect github.com/containerd/cgroups v1.1.0 // indirect github.com/coreos/go-systemd/v22 v22.5.0 // indirect + github.com/cosmos/gogoproto v1.4.1 // indirect github.com/cpuguy83/go-md2man/v2 v2.0.2 // indirect github.com/davidlazar/go-crypto v0.0.0-20200604182044-b73af7476f6c // indirect github.com/decred/dcrd/dcrec/secp256k1/v4 v4.1.0 // indirect - github.com/dlclark/regexp2 v1.4.1-0.20201116162257-a2a8dda75c91 // indirect + github.com/dgraph-io/ristretto v0.0.4-0.20210318174700-74754f61e018 // indirect + github.com/dlclark/regexp2 v1.7.0 // indirect github.com/docker/go-units v0.5.0 // indirect github.com/dustin/go-humanize v1.0.1 // indirect github.com/elastic/gosigar v0.14.2 // indirect + github.com/ethereum/go-ethereum v1.11.3 // indirect + github.com/ferranbt/fastssz v0.0.0-20210905181407-59cf6761a7d5 // indirect github.com/flynn/noise v1.0.0 // indirect github.com/francoispqt/gojay v1.2.13 // indirect - github.com/fsnotify/fsnotify v1.5.4 // indirect + github.com/fsnotify/fsnotify v1.6.0 // indirect github.com/garslo/gogen v0.0.0-20170307003452-d6ebae628c7c // indirect - github.com/go-kit/kit v0.10.0 // indirect + github.com/go-kit/kit v0.12.0 // indirect + github.com/go-kit/log v0.2.1 // indirect github.com/go-logfmt/logfmt v0.5.1 // indirect github.com/go-logr/logr v1.2.3 // indirect github.com/go-logr/stdr v1.2.2 // indirect + github.com/go-ole/go-ole v1.2.6 // indirect github.com/go-sourcemap/sourcemap v2.1.3+incompatible // indirect github.com/go-stack/stack v1.8.1 // indirect github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0 // indirect github.com/godbus/dbus/v5 v5.1.0 // indirect github.com/gogo/protobuf v1.3.2 // indirect - github.com/golang/protobuf v1.5.2 // indirect + github.com/golang/protobuf v1.5.3 // indirect github.com/google/gopacket v1.1.19 // indirect github.com/google/pprof v0.0.0-20230207041349-798e818bf904 // indirect github.com/google/uuid v1.3.0 // indirect + github.com/gtank/merlin v0.1.1 // indirect + github.com/herumi/bls-eth-go-binary v0.0.0-20210917013441-d37c07cfda4e // indirect github.com/ianlancetaylor/cgosymbolizer v0.0.0-20220405231054-a1ae3e4bba26 // indirect github.com/inconshreveable/mousetrap v1.0.1 // indirect github.com/ipfs/go-cid v0.3.2 // indirect @@ -173,7 +192,7 @@ require ( github.com/libp2p/go-reuseport v0.2.0 // indirect github.com/libp2p/go-yamux/v4 v4.0.0 // indirect github.com/lispad/go-generics-tools v1.1.0 // indirect - github.com/magiconair/properties v1.8.6 // indirect + github.com/lufia/plan9stats v0.0.0-20211012122336-39d0f177ccd0 // indirect github.com/marten-seemann/tcp v0.0.0-20210406111302-dfbc87cc63fd // indirect github.com/mattn/go-colorable v0.1.13 // indirect github.com/mattn/go-isatty v0.0.17 // indirect @@ -181,10 +200,12 @@ require ( github.com/miekg/dns v1.1.50 // indirect github.com/mikioh/tcpinfo v0.0.0-20190314235526-30a79bb1804b // indirect github.com/mikioh/tcpopt v0.0.0-20190314235656-172688c1accc // indirect - github.com/minio/sha256-simd v1.0.0 // indirect + github.com/mimoo/StrobeGo v0.0.0-20210601165009-122bf33a46e0 // indirect github.com/mitchellh/mapstructure v1.5.0 // indirect + github.com/mmcloughlin/addchain v0.4.0 // indirect github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect github.com/modern-go/reflect2 v1.0.2 // indirect + github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826 // indirect github.com/mr-tron/base58 v1.2.0 // indirect github.com/mschoch/smat v0.2.0 // indirect github.com/multiformats/go-base32 v0.1.0 // indirect @@ -198,6 +219,7 @@ require ( github.com/multiformats/go-varint v0.0.7 // indirect github.com/onsi/ginkgo/v2 v2.8.0 // indirect github.com/opencontainers/runtime-spec v1.0.2 // indirect + github.com/petermattis/goid v0.0.0-20180202154549-b0b1615b78e5 // indirect github.com/pion/datachannel v1.5.2 // indirect github.com/pion/dtls/v2 v2.2.4 // indirect github.com/pion/ice/v2 v2.2.6 // indirect @@ -215,38 +237,47 @@ require ( github.com/pion/turn/v2 v2.0.8 // indirect github.com/pion/udp v0.1.4 // indirect github.com/pion/webrtc/v3 v3.1.42 // indirect - github.com/pkg/errors v0.9.1 // indirect github.com/pmezard/go-difflib v1.0.0 // indirect - github.com/prometheus/client_golang v1.14.0 // indirect + github.com/power-devops/perfstat v0.0.0-20210106213030-5aafc221ea8c // indirect github.com/prometheus/client_model v0.3.0 // indirect github.com/prometheus/common v0.39.0 // indirect github.com/prometheus/procfs v0.9.0 // indirect + github.com/prysmaticlabs/eth2-types v0.0.0-20210303084904-c9735a06829d // indirect + github.com/prysmaticlabs/fastssz v0.0.0-20220628121656-93dfe28febab // indirect + github.com/prysmaticlabs/prysm v0.0.0-20220124113610-e26cde5e091b // indirect github.com/quic-go/qpack v0.4.0 // indirect - github.com/quic-go/qtls-go1-18 v0.2.0 // indirect - github.com/quic-go/qtls-go1-19 v0.2.0 // indirect - github.com/quic-go/qtls-go1-20 v0.1.0 // indirect - github.com/quic-go/quic-go v0.32.0 // indirect - github.com/quic-go/webtransport-go v0.5.1 // indirect + github.com/quic-go/qtls-go1-19 v0.2.1 // indirect + github.com/quic-go/qtls-go1-20 v0.1.1 // indirect + github.com/quic-go/quic-go v0.33.0 // indirect + github.com/quic-go/webtransport-go v0.5.2 // indirect github.com/raulk/go-watchdog v1.3.0 // indirect + github.com/rcrowley/go-metrics v0.0.0-20201227073835-cf1acfcdf475 // indirect github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec // indirect github.com/rogpeppe/go-internal v1.9.0 // indirect github.com/rs/dnscache v0.0.0-20211102005908-e0241e321417 // indirect github.com/russross/blackfriday/v2 v2.1.0 // indirect + github.com/sasha-s/go-deadlock v0.3.1 // indirect + github.com/shoenig/go-m1cpu v0.1.4 // indirect + github.com/sirupsen/logrus v1.9.0 // indirect github.com/spaolacci/murmur3 v1.1.0 // indirect github.com/supranational/blst v0.3.10 // indirect + github.com/tklauser/go-sysconf v0.3.11 // indirect + github.com/tklauser/numcpus v0.6.0 // indirect github.com/valyala/fastrand v1.1.0 // indirect github.com/valyala/histogram v1.2.0 // indirect github.com/xrash/smetrics v0.0.0-20201216005158-039620a65673 // indirect + github.com/yusufpapurcu/wmi v1.2.2 // indirect go.etcd.io/bbolt v1.3.6 // indirect - go.opentelemetry.io/otel v1.8.0 // indirect - go.opentelemetry.io/otel/trace v1.8.0 // indirect + go.opentelemetry.io/otel v1.11.0 // indirect + go.opentelemetry.io/otel/trace v1.11.0 // indirect + go.uber.org/atomic v1.10.0 // indirect go.uber.org/dig v1.16.1 // indirect go.uber.org/fx v1.19.1 // indirect go.uber.org/multierr v1.9.0 // indirect - golang.org/x/mod v0.8.0 // indirect - golang.org/x/text v0.7.0 // indirect - golang.org/x/tools v0.6.0 // indirect - google.golang.org/genproto v0.0.0-20230202175211-008b39050e57 // indirect + golang.org/x/mod v0.9.0 // indirect + golang.org/x/text v0.9.0 // indirect + golang.org/x/tools v0.7.0 // indirect + google.golang.org/genproto v0.0.0-20230306155012-7f2fa6fef1f4 // indirect gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect gotest.tools/v3 v3.3.0 // indirect @@ -261,6 +292,11 @@ require ( modernc.org/strutil v1.1.3 // indirect modernc.org/token v1.1.0 // indirect nhooyr.io/websocket v1.8.7 // indirect + rsc.io/tmplfunc v0.0.3 // indirect ) -replace github.com/tendermint/tendermint => github.com/bnb-chain/tendermint v0.31.12 +replace ( + github.com/cometbft/cometbft => github.com/bnb-chain/greenfield-tendermint v0.0.0-20230417032003-4cda1f296fb2 + github.com/ledgerwatch/erigon-lib => github.com/chainstack/erigon-lib v0.0.0-20230426134128-a2ae5fb02bbb + github.com/tendermint/tendermint => github.com/bnb-chain/tendermint v0.31.15 +) diff --git a/go.sum b/go.sum index 900aaba7fb1..704fa191da5 100644 --- a/go.sum +++ b/go.sum @@ -1,41 +1,107 @@ +cloud.google.com/go v0.16.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= cloud.google.com/go v0.31.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= cloud.google.com/go v0.37.0/go.mod h1:TS1dMSSfndXH133OKGwekG838Om/cQT0BUHV3HcBgoo= +cloud.google.com/go v0.38.0/go.mod h1:990N+gfupTy94rShfmMCWGDn0LpTmnzTp2qbd1dvSRU= +cloud.google.com/go v0.43.0/go.mod h1:BOSR3VbTLkk6FDC/TcffxP4NF/FFBGA5ku+jvKOP7pg= +cloud.google.com/go v0.44.1/go.mod h1:iSa0KzasP4Uvy3f1mN/7PiObzGgflwredwwASm/v6AU= +cloud.google.com/go v0.44.2/go.mod h1:60680Gw3Yr4ikxnPRS/oxxkBccT6SA1yMk63TGekxKY= +cloud.google.com/go v0.45.1/go.mod h1:RpBamKRgapWJb87xiFSdk4g1CME7QZg3uwTez+TSTjc= +cloud.google.com/go v0.46.3/go.mod h1:a6bKKbmY7er1mI7TEI4lsAkts/mkhTSZK8w33B4RAg0= +cloud.google.com/go v0.50.0/go.mod h1:r9sluTvynVuxRIOHXQEHMFffphuXHOMZMycpNR5e6To= +cloud.google.com/go v0.51.0/go.mod h1:hWtGJ6gnXH+KgDv+V0zFGDvpi07n3z8ZNj3T1RW0Gcw= +cloud.google.com/go v0.52.0/go.mod h1:pXajvRH/6o3+F9jDHZWQ5PbGhn+o8w9qiu/CffaVdO4= +cloud.google.com/go v0.53.0/go.mod h1:fp/UouUEsRkN6ryDKNW/Upv/JBKnv6WDthjR6+vze6M= +cloud.google.com/go v0.54.0/go.mod h1:1rq2OEkV3YMf6n/9ZvGWI3GWw0VoqH/1x2nd8Is/bPc= +cloud.google.com/go v0.56.0/go.mod h1:jr7tqZxxKOVYizybht9+26Z/gUq7tiRzu+ACVAMbKVk= +cloud.google.com/go v0.57.0/go.mod h1:oXiQ6Rzq3RAkkY7N6t3TcE6jE+CIBBbA36lwQ1JyzZs= +cloud.google.com/go v0.62.0/go.mod h1:jmCYTdRCQuc1PHIIJ/maLInMho30T/Y0M4hTdTShOYc= +cloud.google.com/go v0.65.0/go.mod h1:O5N8zS7uWy9vkA9vayVHs65eM1ubvY4h553ofrNHObY= +cloud.google.com/go/bigquery v1.0.1/go.mod h1:i/xbL2UlR5RvWAURpBYZTtm/cXjCha9lbfbpx4poX+o= +cloud.google.com/go/bigquery v1.3.0/go.mod h1:PjpwJnslEMmckchkHFfq+HTD2DmtT67aNFKH1/VBDHE= +cloud.google.com/go/bigquery v1.4.0/go.mod h1:S8dzgnTigyfTmLBfrtrhyYhwRxG72rYxvftPBK2Dvzc= +cloud.google.com/go/bigquery v1.5.0/go.mod h1:snEHRnqQbz117VIFhE8bmtwIDY80NLUZUMb4Nv6dBIg= +cloud.google.com/go/bigquery v1.7.0/go.mod h1://okPTzCYNXSlb24MZs83e2Do+h+VXtc4gLoIoXIAPc= +cloud.google.com/go/bigquery v1.8.0/go.mod h1:J5hqkt3O0uAFnINi6JXValWIb1v0goeZM77hZzJN/fQ= +cloud.google.com/go/bigtable v1.2.0/go.mod h1:JcVAOl45lrTmQfLj7T6TxyMzIN/3FGGcFm+2xVAli2o= +cloud.google.com/go/datastore v1.0.0/go.mod h1:LXYbyblFSglQ5pkeyhO+Qmw7ukd3C+pD7TKLgZqpHYE= +cloud.google.com/go/datastore v1.1.0/go.mod h1:umbIZjpQpHh4hmRpGhH4tLFup+FVzqBi1b3c64qFpCk= +cloud.google.com/go/pubsub v1.0.1/go.mod h1:R0Gpsv3s54REJCy4fxDixWD93lHJMoZTyQ2kNxGRt3I= +cloud.google.com/go/pubsub v1.1.0/go.mod h1:EwwdRX2sKPjnvnqCa270oGRyludottCI76h+R3AArQw= +cloud.google.com/go/pubsub v1.2.0/go.mod h1:jhfEVHT8odbXTkndysNHCcx0awwzvfOlguIAii9o8iA= +cloud.google.com/go/pubsub v1.3.1/go.mod h1:i+ucay31+CNRpDW4Lu78I4xXG+O1r/MAHgjpRVR+TSU= +cloud.google.com/go/storage v1.0.0/go.mod h1:IhtSnM/ZTZV8YYJWCY8RULGVqBDmpoyjwiyrjsg+URw= +cloud.google.com/go/storage v1.5.0/go.mod h1:tpKbwo567HUNpVclU5sGELwQWBDZ8gh0ZeosJ0Rtdos= +cloud.google.com/go/storage v1.6.0/go.mod h1:N7U0C8pVQ/+NIKOBQyamJIeKQKkZ+mxpohlUTyfDhBk= +cloud.google.com/go/storage v1.8.0/go.mod h1:Wv1Oy7z6Yz3DshWRJFhqM/UCfaWIRTdp0RXyy7KQOVs= +cloud.google.com/go/storage v1.10.0/go.mod h1:FLPqc6j+Ki4BU591ie1oL6qBQGu2Bl/tZ9ullr3+Kg0= +collectd.org v0.3.0/go.mod h1:A/8DzQBkF6abtvrT2j/AU/4tiBgJWYyh0y/oB/4MlWE= +contrib.go.opencensus.io/exporter/jaeger v0.2.1/go.mod h1:Y8IsLgdxqh1QxYxPC5IgXVmBaeLUeQFfBeBi9PbeZd0= crawshaw.io/iox v0.0.0-20181124134642-c51c3df30797 h1:yDf7ARQc637HoxDho7xjqdvO5ZA2Yb+xzv/fOnnvZzw= crawshaw.io/iox v0.0.0-20181124134642-c51c3df30797/go.mod h1:sXBiorCo8c46JlQV3oXPKINnZ8mcqnye1EkVkqsectk= crawshaw.io/sqlite v0.3.2/go.mod h1:igAO5JulrQ1DbdZdtVq48mnZUBAPOeFzer7VhDWNtW4= crawshaw.io/sqlite v0.3.3-0.20220618202545-d1964889ea3c h1:wvzox0eLO6CKQAMcOqz7oH3UFqMpMmK7kwmwV+22HIs= crawshaw.io/sqlite v0.3.3-0.20220618202545-d1964889ea3c/go.mod h1:igAO5JulrQ1DbdZdtVq48mnZUBAPOeFzer7VhDWNtW4= dmitri.shuralyov.com/app/changes v0.0.0-20180602232624-0a106ad413e3/go.mod h1:Yl+fi1br7+Rr3LqpNJf1/uxUdtRUV+Tnj0o93V2B9MU= +dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU= dmitri.shuralyov.com/html/belt v0.0.0-20180602232347-f7d459c86be0/go.mod h1:JLBrvjyP0v+ecvNYvCpyZgu5/xkfAUhi6wJj28eUfSU= dmitri.shuralyov.com/service/change v0.0.0-20181023043359-a85b471d5412/go.mod h1:a1inKt/atXimZ4Mv927x+r7UpyzRUf4emIoiiSC2TN4= dmitri.shuralyov.com/state v0.0.0-20180228185332-28bcc343414c/go.mod h1:0PRwlb0D6DFvNNtx+9ybjezNCa8XF0xaYcETyp6rHWU= filippo.io/edwards25519 v1.0.0-rc.1 h1:m0VOOB23frXZvAOK44usCgLWvtsxIoMCTBGJZlpmGfU= git.apache.org/thrift.git v0.0.0-20180902110319-2566ecd5d999/go.mod h1:fPE2ZNJGynbRyZ4dJvy6G277gSllfV2HJqblrnkyeyg= -github.com/99designs/gqlgen v0.17.25 h1:5CAocr5i+dqY0lUR+Xu0InU81Ax/g+xsxKwOU8Glqy0= -github.com/99designs/gqlgen v0.17.25/go.mod h1:i4rEatMrzzu6RXaHydq1nmEPZkb3bKQsnxNRHS4DQB4= +github.com/99designs/gqlgen v0.17.27 h1:XPsaZiWY1lL2qqVYtBt37GzkyX7bBiVvda7k1buC/Ao= +github.com/99designs/gqlgen v0.17.27/go.mod h1:i4rEatMrzzu6RXaHydq1nmEPZkb3bKQsnxNRHS4DQB4= +github.com/AndreasBriese/bbloom v0.0.0-20190306092124-e2d15f34fcf9/go.mod h1:bOvUY6CB00SOBii9/FifXqc0awNKxLFCL/+pkDPuyl8= +github.com/AndreasBriese/bbloom v0.0.0-20190825152654-46b345b51c96/go.mod h1:bOvUY6CB00SOBii9/FifXqc0awNKxLFCL/+pkDPuyl8= +github.com/Azure/azure-pipeline-go v0.2.1/go.mod h1:UGSo8XybXnIGZ3epmeBw7Jdz+HiUVpqIlpz/HKHylF4= +github.com/Azure/azure-pipeline-go v0.2.2/go.mod h1:4rQ/NZncSvGqNkkOsNpOU1tgoNuIlp9AfUH5G1tvCHc= +github.com/Azure/azure-storage-blob-go v0.7.0/go.mod h1:f9YQKtsG1nMisotuTPpO0tjNuEjKRYAcJU8/ydDI++4= +github.com/Azure/go-autorest/autorest v0.9.0/go.mod h1:xyHB1BMZT0cuDHU7I0+g046+BFDTQ8rEZB0s4Yfa6bI= +github.com/Azure/go-autorest/autorest/adal v0.5.0/go.mod h1:8Z9fGy2MpX0PvDjB1pEgQTmVqjGhiHBW7RJJEciWzS0= +github.com/Azure/go-autorest/autorest/adal v0.8.0/go.mod h1:Z6vX6WXXuyieHAXwMj0S6HY6e6wcHn37qQMBQlvY3lc= +github.com/Azure/go-autorest/autorest/date v0.1.0/go.mod h1:plvfp3oPSKwf2DNjlBjWF/7vwR+cUD/ELuzDCXwHUVA= +github.com/Azure/go-autorest/autorest/date v0.2.0/go.mod h1:vcORJHLJEh643/Ioh9+vPmf1Ij9AEBM5FuBIXLmIy0g= +github.com/Azure/go-autorest/autorest/mocks v0.1.0/go.mod h1:OTyCOPRA2IgIlWxVYxBee2F5Gr4kF2zd2J5cFRaIDN0= +github.com/Azure/go-autorest/autorest/mocks v0.2.0/go.mod h1:OTyCOPRA2IgIlWxVYxBee2F5Gr4kF2zd2J5cFRaIDN0= +github.com/Azure/go-autorest/autorest/mocks v0.3.0/go.mod h1:a8FDP3DYzQ4RYfVAxAN3SVSiiO77gL2j2ronKKP0syM= +github.com/Azure/go-autorest/logger v0.1.0/go.mod h1:oExouG+K6PryycPJfVSxi/koC6LSNgds39diKLz7Vrc= +github.com/Azure/go-autorest/tracing v0.5.0/go.mod h1:r/s2XiOKccPW3HrqB+W0TQzfbtp2fGCgRFtBroKn4Dk= github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= +github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo= +github.com/ChainSafe/go-schnorrkel v0.0.0-20200405005733-88cbf1b4c40d h1:nalkkPQcITbvhmL4+C4cKA87NW0tfm3Kl9VXRoPywFg= +github.com/DATA-DOG/go-sqlmock v1.3.3/go.mod h1:f/Ixk793poVmq4qj/V1dPUg2JEAKC73Q5eFN3EC/SaM= github.com/Giulio2002/bls v0.0.0-20230217173148-c87a29266b6c h1:Die1JC9Eiec1trMccXTTVgdE11KYHPec1Z76AP3bSlE= github.com/Giulio2002/bls v0.0.0-20230217173148-c87a29266b6c/go.mod h1:o6qWofeW8A1XImbo3eHbC/wXnw/dasu0YuHEtdrjYzw= github.com/Knetic/govaluate v3.0.1-0.20171022003610-9aa49832a739+incompatible/go.mod h1:r7JcOSlj0wfOMncg0iLm8Leh48TZaKVeNIfJntJ2wa0= +github.com/NYTimes/gziphandler v0.0.0-20170623195520-56545f4a5d46/go.mod h1:3wb06e3pkSAbeQ52E9H9iFoQsEEwGN64994WTCIhntQ= +github.com/OneOfOne/xxhash v1.2.2 h1:KMrpdQIwFcEqXDklaen+P1axHaj9BSKzvpUUfnHldSE= +github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU= +github.com/PuerkitoBio/purell v1.0.0/go.mod h1:c11w/QuzBsJSee3cPx9rAFu61PvFxuPbtSwDGJws/X0= +github.com/PuerkitoBio/urlesc v0.0.0-20160726150825-5bd2802263f2/go.mod h1:uGdkoq3SwY9Y+13GIhn11/XLaGBb4BfwItxLd5jeuXE= github.com/RoaringBitmap/roaring v0.4.7/go.mod h1:8khRDP4HmeXns4xIj9oGrKSz7XTQiJx2zgh7AcNke4w= github.com/RoaringBitmap/roaring v0.4.17/go.mod h1:D3qVegWTmfCaX4Bl5CrBE9hfrSrrXIr8KVNvRsDi1NI= github.com/RoaringBitmap/roaring v0.4.23/go.mod h1:D0gp8kJQgE1A4LQ5wFLggQEyvDi06Mq5mKs52e1TwOo= github.com/RoaringBitmap/roaring v1.2.3 h1:yqreLINqIrX22ErkKI0vY47/ivtJr6n+kMhVOVmhWBY= github.com/RoaringBitmap/roaring v1.2.3/go.mod h1:plvDsJQpxOC5bw8LRteu/MLWHsHez/3y6cubLI4/1yE= github.com/Shopify/sarama v1.19.0/go.mod h1:FVkBWblsNy7DGZRfXLU0O9RCGt5g3g3yEuWXgklEdEo= +github.com/Shopify/sarama v1.26.1/go.mod h1:NbSGBSSndYaIhRcBtY9V0U7AyH+x71bG668AuWys/yU= github.com/Shopify/toxiproxy v2.1.4+incompatible/go.mod h1:OXgGpZ6Cli1/URJOF1DMxUHB2q5Ap20/P/eIdh4G0pI= +github.com/StackExchange/wmi v0.0.0-20180116203802-5d049714c4a6/go.mod h1:3eOhrUMpNV+6aFIbp5/iudMxNCF27Vw2OZgy4xEx0Fg= +github.com/StackExchange/wmi v0.0.0-20210224194228-fe8f1750fd46/go.mod h1:3eOhrUMpNV+6aFIbp5/iudMxNCF27Vw2OZgy4xEx0Fg= +github.com/VictoriaMetrics/fastcache v1.6.0/go.mod h1:0qHz5QP0GMX4pfmMA/zt5RgfNuXJrTP0zS7DqpHGGTw= github.com/VictoriaMetrics/fastcache v1.12.1 h1:i0mICQuojGDL3KblA7wUNlY5lOK6a4bwt3uRKnkZU40= github.com/VictoriaMetrics/fastcache v1.12.1/go.mod h1:tX04vaqcNoQeGLD+ra5pU5sWkuxnzWhEzLwhP9w653o= github.com/VictoriaMetrics/metrics v1.23.1 h1:/j8DzeJBxSpL2qSIdqnRFLvQQhbJyJbbEi22yMm7oL0= github.com/VictoriaMetrics/metrics v1.23.1/go.mod h1:rAr/llLpEnAdTehiNlUxKgnjcOuROSzpw0GvjpEbvFc= +github.com/VividCortex/gohistogram v1.0.0 h1:6+hBz+qvs0JOrrNhhmR7lFxo5sINxBCGXrdtl/UvroE= github.com/VividCortex/gohistogram v1.0.0/go.mod h1:Pf5mBqqDxYaXu3hDrrU+w6nw50o/4+TcAqDqk/vUH7g= github.com/aead/siphash v1.0.1/go.mod h1:Nywa3cDsYNNK3gaciGTWPwHt0wlpNV15vwmswBAUSII= github.com/afex/hystrix-go v0.0.0-20180502004556-fa1af6a1f4f5/go.mod h1:SkGFH1ia65gfNATL8TAiHDNxPzPdmEL5uirI2Uyuz6c= github.com/agnivade/levenshtein v1.0.1/go.mod h1:CURSv5d9Uaml+FovSIICkLbAUZ9S4RqaHDIsdSBg7lM= github.com/agnivade/levenshtein v1.1.1 h1:QY8M92nrzkmr798gCo3kmMyqXFzdQVpxLlGPRBij0P8= github.com/agnivade/levenshtein v1.1.1/go.mod h1:veldBMzWxcCG2ZvUTKD2kJNRdCk5hVbJomOvKkmgYbo= +github.com/ajstarks/svgo v0.0.0-20180226025133-644b8db467af/go.mod h1:K08gAheRH3/J6wwsYMMT4xOr94bZjxIelGM0+d/wbFw= github.com/ajwerner/btree v0.0.0-20211221152037-f427b3e689c0 h1:byYvvbfSo3+9efR4IeReh77gVs4PnNDR3AMOE9NJ7a0= github.com/ajwerner/btree v0.0.0-20211221152037-f427b3e689c0/go.mod h1:q37NoqncT41qKc048STsifIt69LfUJ8SrWWcz/yam5k= github.com/alecthomas/assert/v2 v2.0.0-alpha3 h1:pcHeMvQ3OMstAWgaeaXIAL8uzB9xMm2zlxt+/4ml8lk= @@ -46,8 +112,10 @@ github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuy github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= github.com/alecthomas/units v0.0.0-20190717042225-c3de453c63f4/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= -github.com/allegro/bigcache v1.2.1-0.20190218064605-e24eb225f156 h1:eMwmnE/GDgah4HI848JfFxHt+iPb26b4zyfspmqY0/8= +github.com/alecthomas/units v0.0.0-20190924025748-f65c72e2690d/go.mod h1:rBZYJk541a8SKzHPHnH3zbiI+7dagKZ0cgpgrD7Fyho= github.com/allegro/bigcache v1.2.1-0.20190218064605-e24eb225f156/go.mod h1:Cb/ax3seSYIx7SuZdm2G2xzfwmv3TPSk2ucNfQESPXM= +github.com/allegro/bigcache v1.2.1 h1:hg1sY1raCwic3Vnsvje6TT7/pnZba83LeFck5NrFKSc= +github.com/allegro/bigcache v1.2.1/go.mod h1:Cb/ax3seSYIx7SuZdm2G2xzfwmv3TPSk2ucNfQESPXM= github.com/anacrolix/chansync v0.3.0 h1:lRu9tbeuw3wl+PhMu/r+JJCRu5ArFXIluOgdF0ao6/U= github.com/anacrolix/chansync v0.3.0/go.mod h1:DZsatdsdXxD0WiwcGl0nJVwyjCKMDv+knl1q2iBjA2k= github.com/anacrolix/dht/v2 v2.19.2-0.20221121215055-066ad8494444 h1:8V0K09lrGoeT2KRJNOtspA7q+OMxGwQqK/Ug0IiaaRE= @@ -80,8 +148,8 @@ github.com/anacrolix/missinggo/perf v1.0.0/go.mod h1:ljAFWkBuzkO12MQclXzZrosP5ur github.com/anacrolix/missinggo/v2 v2.2.0/go.mod h1:o0jgJoYOyaoYQ4E2ZMISVa9c88BbUBVQQW4QeRkNCGY= github.com/anacrolix/missinggo/v2 v2.5.1/go.mod h1:WEjqh2rmKECd0t1VhQkLGTdIWXO6f6NLjp5GlMZ+6FA= github.com/anacrolix/missinggo/v2 v2.5.2/go.mod h1:yNvsLrtZYRYCOI+KRH/JM8TodHjtIE/bjOGhQaLOWIE= -github.com/anacrolix/missinggo/v2 v2.7.0 h1:4fzOAAn/VCvfWGviLmh64MPMttrlYew81JdPO7nSHvI= -github.com/anacrolix/missinggo/v2 v2.7.0/go.mod h1:2IZIvmRTizALNYFYXsPR7ofXPzJgyBpKZ4kMqMEICkI= +github.com/anacrolix/missinggo/v2 v2.7.1 h1:Y+wL0JC6D2icpwhDpcrRM4THQB/uFcPNYUtZMbYvQgI= +github.com/anacrolix/missinggo/v2 v2.7.1/go.mod h1:2IZIvmRTizALNYFYXsPR7ofXPzJgyBpKZ4kMqMEICkI= github.com/anacrolix/mmsg v0.0.0-20180515031531-a4a3ba1fc8bb/go.mod h1:x2/ErsYUmT77kezS63+wzZp8E3byYB0gzirM/WMBLfw= github.com/anacrolix/mmsg v1.0.0 h1:btC7YLjOn29aTUAExJiVUhQOuf/8rhm+/nWCMAnL3Hg= github.com/anacrolix/mmsg v1.0.0/go.mod h1:x8kRaJY/dCrY9Al0PEcj1mb/uFHwP6GCJ9fLl4thEPc= @@ -106,19 +174,39 @@ github.com/anacrolix/utp v0.1.0/go.mod h1:MDwc+vsGEq7RMw6lr2GKOEqjWny5hO5OZXRVNa github.com/andreyvit/diff v0.0.0-20170406064948-c7f18ee00883 h1:bvNMNQO63//z+xNgfBlViaCIJKLlCJ6/fmUseuG0wVQ= github.com/andreyvit/diff v0.0.0-20170406064948-c7f18ee00883/go.mod h1:rCTlJbsFo29Kk6CurOXKm700vrz8f0KW0JNfpkRJY/8= github.com/anmitsu/go-shlex v0.0.0-20161002113705-648efa622239/go.mod h1:2FmKhYUyUczH0OGQWaF5ceTx0UBShxjsH6f8oGKYe2c= +github.com/antihax/optional v1.0.0/go.mod h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kdvxnR2qWY= +github.com/apache/arrow/go/arrow v0.0.0-20191024131854-af6fa24be0db/go.mod h1:VTxUBvSJ3s3eHAg65PNgrsn5BtqCRPdmyXh6rAfdxN0= github.com/apache/thrift v0.12.0/go.mod h1:cp2SuWMxlEZw2r+iP2GNCdIi4C1qmUzdZFSVb+bacwQ= github.com/apache/thrift v0.13.0/go.mod h1:cp2SuWMxlEZw2r+iP2GNCdIi4C1qmUzdZFSVb+bacwQ= github.com/arbovm/levenshtein v0.0.0-20160628152529-48b4e1c0c4d0 h1:jfIu9sQUG6Ig+0+Ap1h4unLjW6YQJpKZVmUzxsD4E/Q= github.com/arbovm/levenshtein v0.0.0-20160628152529-48b4e1c0c4d0/go.mod h1:t2tdKJDJF9BV14lnkjHmOQgcvEKgtqs5a1N3LNdJhGE= +github.com/aristanetworks/fsnotify v1.4.2/go.mod h1:D/rtu7LpjYM8tRJphJ0hUBYpjai8SfX+aSNsWDTq/Ks= +github.com/aristanetworks/glog v0.0.0-20191112221043-67e8567f59f3/go.mod h1:KASm+qXFKs/xjSoWn30NrWBBvdTTQq+UjkhjEJHfSFA= +github.com/aristanetworks/goarista v0.0.0-20200521140103-6c3304613b30/go.mod h1:QZe5Yh80Hp1b6JxQdpfSEEe8X7hTyTEZSosSrFf/oJE= +github.com/aristanetworks/splunk-hec-go v0.3.3/go.mod h1:1VHO9r17b0K7WmOlLb9nTk/2YanvOEnLMUgsFrxBROc= github.com/armon/circbuf v0.0.0-20150827004946-bbbad097214e/go.mod h1:3U/XgcO3hCbHZ8TKRvWD2dDTCfh9M9ya+I9JpbB7O8o= +github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5doyWs3UAsr3K4I6qtAmlQcZDesFNEHPZAzj8= github.com/armon/go-metrics v0.0.0-20180917152333-f0300d1749da/go.mod h1:Q73ZrmVTwzkszR9V5SSuryQ31EELlFMUz1kKyl939pY= github.com/armon/go-radix v0.0.0-20180808171621-7fddfc383310/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8= github.com/aryann/difflib v0.0.0-20170710044230-e206f873d14a/go.mod h1:DAHtR1m6lCRdSC2Tm3DSWRPvIPr6xNKyeHdqDQSQT+A= github.com/aws/aws-lambda-go v1.13.3/go.mod h1:4UKl9IzQMoD+QF79YdCuzCwp8VbmG4VAQwij/eHl5CU= github.com/aws/aws-sdk-go v1.27.0/go.mod h1:KmX6BPdI08NWTb3/sm4ZGu5ShLoqVDhKgpiN924inxo= github.com/aws/aws-sdk-go-v2 v0.18.0/go.mod h1:JWVYvqSMppoMJC0x5wdwiImzgXTI9FuZwxzkQq9wy+g= +github.com/aws/aws-sdk-go-v2 v1.2.0/go.mod h1:zEQs02YRBw1DjK0PoJv3ygDYOFTre1ejlJWl8FwAuQo= +github.com/aws/aws-sdk-go-v2/config v1.1.1/go.mod h1:0XsVy9lBI/BCXm+2Tuvt39YmdHwS5unDQmxZOYe8F5Y= +github.com/aws/aws-sdk-go-v2/credentials v1.1.1/go.mod h1:mM2iIjwl7LULWtS6JCACyInboHirisUUdkBPoTHMOUo= +github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.0.2/go.mod h1:3hGg3PpiEjHnrkrlasTfxFqUsZ2GCk/fMUn4CbKgSkM= +github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.0.2/go.mod h1:45MfaXZ0cNbeuT0KQ1XJylq8A6+OpVV2E5kvY/Kq+u8= +github.com/aws/aws-sdk-go-v2/service/route53 v1.1.1/go.mod h1:rLiOUrPLW/Er5kRcQ7NkwbjlijluLsrIbu/iyl35RO4= +github.com/aws/aws-sdk-go-v2/service/sso v1.1.1/go.mod h1:SuZJxklHxLAXgLTc1iFXbEWkXs7QRTQpCLGaKIprQW0= +github.com/aws/aws-sdk-go-v2/service/sts v1.1.1/go.mod h1:Wi0EBZwiz/K44YliU0EKxqTCJGUfYTWXrrBwkq736bM= +github.com/aws/smithy-go v1.1.0/go.mod h1:EzMw8dbp/YJL4A5/sbhGddag+NPT7q084agLbB9LgIw= github.com/bahlo/generic-list-go v0.2.0 h1:5sz/EEAK+ls5wF+NeqDpk5+iNdMDXrh3z3nPnH1Wvgk= github.com/bahlo/generic-list-go v0.2.0/go.mod h1:2KvAjgMlE5NNynlg/5iLrrCCZ2+5xWbdbCW3pNTGyYg= +github.com/bazelbuild/rules_go v0.23.2 h1:Wxu7JjqnF78cKZbsBsARLSXx/jlGaSLCnUV3mTlyHvM= +github.com/bazelbuild/rules_go v0.23.2/go.mod h1:MC23Dc/wkXEyk3Wpq6lCqz0ZAYOZDw2DR5y3N1q2i7M= +github.com/benbjohnson/clock v1.0.2/go.mod h1:bGMdMPoPVvcYyt1gHDf4J2KE153Yf9BuiUKYMaxlTDM= +github.com/benbjohnson/clock v1.0.3/go.mod h1:bGMdMPoPVvcYyt1gHDf4J2KE153Yf9BuiUKYMaxlTDM= github.com/benbjohnson/clock v1.1.0/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA= github.com/benbjohnson/clock v1.3.0 h1:ip6w0uFQkncKQ979AypyG0ER7mqUSBdKLOgAle/AT8A= github.com/benbjohnson/clock v1.3.0/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA= @@ -133,23 +221,35 @@ github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM= github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw= github.com/bgentry/speakeasy v0.1.0/go.mod h1:+zsyZBPWlz7T6j88CTgSN5bM796AkVf0kBD4zp0CCIs= github.com/bits-and-blooms/bitset v1.2.0/go.mod h1:gIdJ4wp64HaoK2YrL1Q5/N7Y16edYb8uY+O0FJTyyDA= -github.com/bits-and-blooms/bitset v1.2.2 h1:J5gbX05GpMdBjCvQ9MteIg2KKDExr7DrgK+Yc15FvIk= -github.com/bits-and-blooms/bitset v1.2.2/go.mod h1:gIdJ4wp64HaoK2YrL1Q5/N7Y16edYb8uY+O0FJTyyDA= -github.com/bnb-chain/tendermint v0.31.12 h1:g+blWaXkRw6iHa56lcRfRzPXHgURCWPmgIvaGBSV7Zc= -github.com/bnb-chain/tendermint v0.31.12/go.mod h1:j6XU7CArrhQ+9XBMRwdIz63iUxdVwSrZ8f7vP7gcCqg= +github.com/bits-and-blooms/bitset v1.5.0 h1:NpE8frKRLGHIcEzkR+gZhiioW1+WbYV6fKwD6ZIpQT8= +github.com/bits-and-blooms/bitset v1.5.0/go.mod h1:gIdJ4wp64HaoK2YrL1Q5/N7Y16edYb8uY+O0FJTyyDA= +github.com/bmizerany/pat v0.0.0-20170815010413-6226ea591a40/go.mod h1:8rLXio+WjiTceGBHIoTvn60HIbs7Hm7bcHjyrSqYB9c= +github.com/bnb-chain/greenfield-tendermint v0.0.0-20230417032003-4cda1f296fb2 h1:jubavYCs/mCFj/g6Utl+l4SfpykdBdWJFPsvb9FcEXU= +github.com/bnb-chain/greenfield-tendermint v0.0.0-20230417032003-4cda1f296fb2/go.mod h1:9q11eHNRY9FDwFH+4pompzPNGv//Z3VcfvkELaHJPMs= +github.com/bnb-chain/ics23 v0.1.0 h1:DvjGOts2FBfbxB48384CYD1LbcrfjThFz8kowY/7KxU= +github.com/bnb-chain/ics23 v0.1.0/go.mod h1:cU6lTGolbbLFsGCgceNB2AzplH1xecLp6+KXvxM32nI= +github.com/bnb-chain/tendermint v0.31.15 h1:Xyn/Hifb/7X4E1zSuMdnZdMSoM2Fx6cZuKCNnqIxbNU= +github.com/bnb-chain/tendermint v0.31.15/go.mod h1:cmt8HHmQUSVaWQ/hoTefRxsh5X3ERaM1zCUIR0DPbFU= +github.com/boltdb/bolt v1.3.1/go.mod h1:clJnj/oiGkjum5o1McbSZDSLxVThjynRyGBgiAx27Ps= github.com/bradfitz/go-smtpd v0.0.0-20170404230938-deb6d6237625/go.mod h1:HYsPBTaaSFSlLx/70C2HPIMNZpVV8+vt/A+FMnYP11g= +github.com/bradfitz/gomemcache v0.0.0-20170208213004-1952afaa557d/go.mod h1:PmM6Mmwb0LSuEubjR8N7PtNe1KxZLtOUHtbeikc5h60= github.com/bradfitz/iter v0.0.0-20140124041915-454541ec3da2/go.mod h1:PyRFw1Lt2wKX4ZVSQ2mk+PeDa1rxyObEDlApuIsUKuo= github.com/bradfitz/iter v0.0.0-20190303215204-33e6a9893b0c/go.mod h1:PyRFw1Lt2wKX4ZVSQ2mk+PeDa1rxyObEDlApuIsUKuo= github.com/bradfitz/iter v0.0.0-20191230175014-e8f45d346db8 h1:GKTyiRCL6zVf5wWaqKnf+7Qs6GbEPfd4iMOitWzXJx8= github.com/bradfitz/iter v0.0.0-20191230175014-e8f45d346db8/go.mod h1:spo1JLcs67NmW1aVLEgtA8Yy1elc+X8y5SRW1sFW4Og= +github.com/btcsuite/btcd v0.0.0-20190213025234-306aecffea32/go.mod h1:DrZx5ec/dmnfpw9KyYoQyYo7d0KEvTkk/5M/vbZjAr8= +github.com/btcsuite/btcd v0.0.0-20190523000118-16327141da8c/go.mod h1:3J08xEfcugPacsc34/LKRU2yO7YmuT8yt28J8k2+rrI= github.com/btcsuite/btcd v0.20.1-beta/go.mod h1:wVuoA8VJLEcwgqHBwHmzLRazpKxTv13Px/pDuV7OomQ= +github.com/btcsuite/btcd v0.21.0-beta/go.mod h1:ZSWyehm27aAuS9bvkATT+Xte3hjHZ+MRgMY/8NJ7K94= github.com/btcsuite/btcd v0.22.0-beta h1:LTDpDKUM5EeOFBPM8IXpinEcmZ6FWfNZbE3lfrfdnWo= github.com/btcsuite/btcd v0.22.0-beta/go.mod h1:9n5ntfhhHQBIhUvlhDvD3Qg6fRUj4jkN0VB8L8svzOA= -github.com/btcsuite/btcd/btcec/v2 v2.2.1 h1:xP60mv8fvp+0khmrN0zTdPC3cNm24rfeE6lh2R/Yv3E= -github.com/btcsuite/btcd/btcec/v2 v2.2.1/go.mod h1:9/CSmJxmuvqzX9Wh2fXMWToLOHhPd11lSPuIupwTkI8= +github.com/btcsuite/btcd/btcec/v2 v2.3.2 h1:5n0X6hX0Zk+6omWcihdYvdAlGf2DfasC0GMf7DClJ3U= +github.com/btcsuite/btcd/btcec/v2 v2.3.2/go.mod h1:zYzJ8etWJQIv1Ogk7OzpWjowwOdXY1W/17j2MW85J04= +github.com/btcsuite/btcd/btcutil v1.1.3 h1:xfbtw8lwpp0G6NwSHb+UE67ryTFHJAiNuipusjXSohQ= github.com/btcsuite/btclog v0.0.0-20170628155309-84c8d2346e9f/go.mod h1:TdznJufoqS23FtqVCzL0ZqgP5MqXbb4fg/WgDys70nA= +github.com/btcsuite/btcutil v0.0.0-20190207003914-4c204d697803/go.mod h1:+5NJ2+qvTyV9exUAL/rxXi3DcLg2Ts+ymUAY5y4NvMg= github.com/btcsuite/btcutil v0.0.0-20190425235716-9e5f4b9a998d/go.mod h1:+5NJ2+qvTyV9exUAL/rxXi3DcLg2Ts+ymUAY5y4NvMg= -github.com/btcsuite/btcutil v1.0.3-0.20201208143702-a53e38424cce h1:YtWJF7RHm2pYCvA5t0RPmAaLUhREsKuKd+SLhxFbFeQ= +github.com/btcsuite/btcutil v1.0.2/go.mod h1:j9HUFwoQRsZL3V4n+qG+CUnEGHOarIxfC3Le2Yhbcts= github.com/btcsuite/btcutil v1.0.3-0.20201208143702-a53e38424cce/go.mod h1:0DVlHczLPewLcPGEIeUEzfOJhqGPQ0mJJRDBtD307+o= github.com/btcsuite/go-socks v0.0.0-20170105172521-4720035b7bfd/go.mod h1:HHNXQzUsZCxOoE+CPiyCTO6x34Zs86zZUiwtpXoGdtg= github.com/btcsuite/goleveldb v0.0.0-20160330041536-7834afc9e8cd/go.mod h1:F+uVaaLLH7j4eDXPRvw78tMflu7Ie2bzYOH4Y8rRKBY= @@ -159,114 +259,197 @@ github.com/btcsuite/snappy-go v1.0.0/go.mod h1:8woku9dyThutzjeg+3xrA5iCpBRH8XEEg github.com/btcsuite/websocket v0.0.0-20150119174127-31079b680792/go.mod h1:ghJtEyQwv5/p4Mg4C0fgbePVuGr935/5ddU9Z3TmDRY= github.com/btcsuite/winsvc v1.0.0/go.mod h1:jsenWakMcC0zFBFurPLEAyrnc/teJEM1O46fmI40EZs= github.com/buger/jsonparser v0.0.0-20181115193947-bf1c66bbce23/go.mod h1:bbYlZJ7hK1yFx9hf58LP0zeX7UjIGs20ufpu3evjr+s= +github.com/c-bata/go-prompt v0.2.2/go.mod h1:VzqtzE2ksDBcdln8G7mk2RX9QyGjH+OVqOCSiVIqS34= github.com/c2h5oh/datasize v0.0.0-20220606134207-859f65c6625b h1:6+ZFm0flnudZzdSE0JxlhR2hKnGPcNB35BjQf4RYQDY= github.com/c2h5oh/datasize v0.0.0-20220606134207-859f65c6625b/go.mod h1:S/7n9copUssQ56c7aAgHqftWO4LTf4xY6CGWt8Bc+3M= github.com/casbin/casbin/v2 v2.1.2/go.mod h1:YcPU1XXisHhLzuxH9coDNf2FbKpjGlbCg3n9yuLkIJQ= github.com/cenkalti/backoff v2.2.1+incompatible/go.mod h1:90ReRw6GdpyfrHakVjL/QHaoyV4aDUVVkXQJJJ3NXXM= github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= +github.com/cespare/cp v0.1.0/go.mod h1:SOGHArjBr4JWaSDEVpWpo/hNg6RoKrls6Oh40hiwW+s= +github.com/cespare/cp v1.1.1/go.mod h1:SOGHArjBr4JWaSDEVpWpo/hNg6RoKrls6Oh40hiwW+s= +github.com/cespare/xxhash v1.1.0 h1:a6HrQnmkObjyL+Gs60czilIUGqrzKutQD6XZog3p+ko= +github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc= github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= github.com/cespare/xxhash/v2 v2.2.0 h1:DC2CZ1Ep5Y4k3ZQ899DldepgrayRUGE6BBZ/cd9Cj44= github.com/cespare/xxhash/v2 v2.2.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= +github.com/chainstack/erigon-lib v0.0.0-20230426134128-a2ae5fb02bbb h1:xOy4O4wUIxgjpgmt06nQ/OKGKzvVxzMSls2Gys5ssaQ= +github.com/chainstack/erigon-lib v0.0.0-20230426134128-a2ae5fb02bbb/go.mod h1:D05f9OXc/2cnYxCyBexlu5HeIeQW9GKXynyWYzJ1F5I= +github.com/cheekybits/genny v1.0.0/go.mod h1:+tQajlRqAUrPI7DOSpB0XAqZYtQakVtB7wXkRAgjxjQ= +github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI= +github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI= +github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU= github.com/cilium/ebpf v0.2.0/go.mod h1:To2CFviqOWL/M0gIMsvSMlqe7em/l1ALkX1PyjrX2Qs= github.com/clbanning/x2j v0.0.0-20191024224557-825249438eec/go.mod h1:jMjuTZXRI4dUb/I5gc9Hdhagfvm9+RyrPryS/auMzxE= github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= +github.com/cloudflare/cloudflare-go v0.14.0/go.mod h1:EnwdgGMaFOruiPZRFSgn+TsQ3hQ7C/YWzIGLeu5c304= github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc= +github.com/cncf/udpa/go v0.0.0-20201120205902-5459f2c99403/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk= +github.com/cncf/xds/go v0.0.0-20210312221358-fbca930ec8ed/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= github.com/cockroachdb/datadriven v0.0.0-20190809214429-80d97fb3cbaa/go.mod h1:zn76sxSg3SzpJ0PPJaLDCu+Bu0Lg3sKTORVIj19EIF8= github.com/codahale/hdrhistogram v0.0.0-20161010025455-3a0bb77429bd/go.mod h1:sE/e/2PUdi/liOCUjSTXgM1o87ZssimdTWN964YiIeI= +github.com/cometbft/cometbft-db v0.7.0 h1:uBjbrBx4QzU0zOEnU8KxoDl18dMNgDh+zZRUE0ucsbo= github.com/consensys/bavard v0.1.8-0.20210406032232-f3452dc9b572/go.mod h1:Bpd0/3mZuaj6Sj+PqrmIquiOKy397AKGThQPaGzNXAQ= -github.com/consensys/gnark-crypto v0.4.1-0.20210426202927-39ac3d4b3f1f h1:C43yEtQ6NIf4ftFXD/V55gnGFgPbMQobd//YlnLjUJ8= +github.com/consensys/bavard v0.1.13 h1:oLhMLOFGTLdlda/kma4VOJazblc7IM5y5QPd2A/YjhQ= +github.com/consensys/bavard v0.1.13/go.mod h1:9ItSMtA/dXMAiL7BG6bqW2m3NdSEObYWoH223nGHukI= github.com/consensys/gnark-crypto v0.4.1-0.20210426202927-39ac3d4b3f1f/go.mod h1:815PAHg3wvysy0SyIqanF8gZ0Y1wjk/hrDHD/iT88+Q= +github.com/consensys/gnark-crypto v0.10.0 h1:zRh22SR7o4K35SoNqouS9J/TKHTyU2QWaj5ldehyXtA= +github.com/consensys/gnark-crypto v0.10.0/go.mod h1:Iq/P3HHl0ElSjsg2E1gsMwhAyxnxoKK5nVyZKd+/KhU= github.com/containerd/cgroups v0.0.0-20201119153540-4cbc285b3327/go.mod h1:ZJeTFisyysqgcCdecO57Dj79RfL0LNeGiFUqLYQRYLE= github.com/containerd/cgroups v1.1.0 h1:v8rEWFl6EoqHB+swVNjVoCJE8o3jX7e8nqBGPLaDFBM= github.com/containerd/cgroups v1.1.0/go.mod h1:6ppBcbh/NOOUU+dMKrykgaBnK9lCIBxHqJDGwsa1mIw= +github.com/coreos/etcd v3.3.10+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE= +github.com/coreos/go-etcd v2.0.0+incompatible/go.mod h1:Jez6KQU2B/sWsbdaef3ED8NzMklzPG4d5KIOhIy30Tk= github.com/coreos/go-semver v0.2.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk= +github.com/coreos/go-semver v0.3.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk= github.com/coreos/go-systemd v0.0.0-20180511133405-39ca1b05acc7/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4= github.com/coreos/go-systemd v0.0.0-20181012123002-c6f51f82210d/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4= +github.com/coreos/go-systemd v0.0.0-20191104093116-d3cd4ed1dbcf/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4= github.com/coreos/go-systemd/v22 v22.1.0/go.mod h1:xO0FLkIi5MaZafQlIrOotqXZ90ih+1atmu1JpKERPPk= github.com/coreos/go-systemd/v22 v22.5.0 h1:RrqgGjYQKalulkV8NGVIfkXQf6YYmOyiJKk8iXXhfZs= github.com/coreos/go-systemd/v22 v22.5.0/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc= github.com/coreos/pkg v0.0.0-20160727233714-3ac0863d7acf/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA= +github.com/cosmos/go-bip39 v0.0.0-20180819234021-555e2067c45d h1:49RLWk1j44Xu4fjHb6JFYmeUnDORVwHNkDxaQ0ctCVU= +github.com/cosmos/gogoproto v1.4.1 h1:WoyH+0/jbCTzpKNvyav5FL1ZTWsp1im1MxEpJEzKUB8= +github.com/cosmos/gogoproto v1.4.1/go.mod h1:Ac9lzL4vFpBMcptJROQ6dQ4M3pOEK5Z/l0Q9p+LoCr4= +github.com/cpuguy83/go-md2man v1.0.10/go.mod h1:SmD6nW6nTyfqj6ABTjUi3V3JVMnlJmwcJI5acqYI6dE= github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU= github.com/cpuguy83/go-md2man/v2 v2.0.0/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU= github.com/cpuguy83/go-md2man/v2 v2.0.2 h1:p1EgwI/C7NhT0JmVkwCD2ZBK8j4aeHQX2pMHHBfMQ6w= github.com/cpuguy83/go-md2man/v2 v2.0.2/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= github.com/crate-crypto/go-ipa v0.0.0-20221111143132-9aa5d42120bc h1:mtR7MuscVeP/s0/ERWA2uSr5QOrRYy1pdvZqG1USfXI= github.com/crate-crypto/go-ipa v0.0.0-20221111143132-9aa5d42120bc/go.mod h1:gFnFS95y8HstDP6P9pPwzrxOOC5TRDkwbM+ao15ChAI= +github.com/crate-crypto/go-kzg-4844 v0.0.0-20230405223534-4364e2f9d209 h1:OnTdosxWDRxchZa7uOT8zz1sm3TZQdCiqtj69wYGnH8= +github.com/crate-crypto/go-kzg-4844 v0.0.0-20230405223534-4364e2f9d209/go.mod h1:bsF9NlLDLBdRmnU0hiImPGjwoDSrjLRXKAP9vVT6IsI= +github.com/creachadair/taskgroup v0.3.2 h1:zlfutDS+5XG40AOxcHDSThxKzns8Tnr9jnr6VqkYlkM= github.com/creack/pty v1.1.7/go.mod h1:lj5s0c3V2DBrqTV7llrYr5NG6My20zk30Fl46Y7DoTY= github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= +github.com/cyberdelia/templates v0.0.0-20141128023046-ca7fffd4298c/go.mod h1:GyV+0YP4qX0UQ7r2MoYZ+AvYDp12OF5yg4q8rGnyNh4= +github.com/d4l3k/messagediff v1.2.1 h1:ZcAIMYsUg0EAp9X+tt8/enBE/Q8Yd5kzPynLyKptt9U= +github.com/d4l3k/messagediff v1.2.1/go.mod h1:Oozbb1TVXFac9FtSIxHBMnBCq2qeH/2KkEQxENCrlLo= +github.com/dave/jennifer v1.2.0/go.mod h1:fIb+770HOpJ2fmN9EPPKOqm1vMGhB+TwXKMZhrIygKg= github.com/davecgh/go-spew v0.0.0-20171005155431-ecdeabc65495/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/davidlazar/go-crypto v0.0.0-20170701192655-dcfb0a7ac018/go.mod h1:rQYf4tfk5sSwFsnDg3qYaBxSjsD9S8+59vW0dKUgme4= github.com/davidlazar/go-crypto v0.0.0-20200604182044-b73af7476f6c h1:pFUpOrbxDR6AkioZ1ySsx5yxlDQZ8stG2b88gTPxgJU= github.com/davidlazar/go-crypto v0.0.0-20200604182044-b73af7476f6c/go.mod h1:6UhI8N9EjYm1c2odKpFpAYeR8dsBeM7PtzQhRgxRr9U= +github.com/deckarep/golang-set v0.0.0-20180603214616-504e848d77ea/go.mod h1:93vsz/8Wt4joVM7c2AVqh+YRMiUSc14yDtF28KmMOgQ= +github.com/deckarep/golang-set v1.7.1/go.mod h1:93vsz/8Wt4joVM7c2AVqh+YRMiUSc14yDtF28KmMOgQ= github.com/deckarep/golang-set v1.8.0 h1:sk9/l/KqpunDwP7pSjUg0keiOOLEnOBHzykLrsPppp4= github.com/deckarep/golang-set v1.8.0/go.mod h1:5nI87KwE7wgsBU1F4GKAw2Qod7p5kyS383rP6+o6qqo= -github.com/deckarep/golang-set/v2 v2.1.0 h1:g47V4Or+DUdzbs8FxCCmgb6VYd+ptPAngjM6dtGktsI= -github.com/deckarep/golang-set/v2 v2.1.0/go.mod h1:VAky9rY/yGXJOLEDv3OMci+7wtDpOF4IN+y82NBOac4= +github.com/deckarep/golang-set/v2 v2.3.0 h1:qs18EKUfHm2X9fA50Mr/M5hccg2tNnVqsiBImnyDs0g= +github.com/deckarep/golang-set/v2 v2.3.0/go.mod h1:VAky9rY/yGXJOLEDv3OMci+7wtDpOF4IN+y82NBOac4= github.com/decred/dcrd/crypto/blake256 v1.0.0 h1:/8DMNYp9SGi5f0w7uCm6d6M4OU2rGFK09Y2A4Xv7EE0= github.com/decred/dcrd/dcrec/secp256k1/v4 v4.1.0 h1:HbphB4TFFXpv7MNrT52FGrrgVXF1owhMVTHFZIlnvd4= github.com/decred/dcrd/dcrec/secp256k1/v4 v4.1.0/go.mod h1:DZGJHZMqrU4JJqFAWUS2UO1+lbSKsdiOoYi9Zzey7Fc= github.com/decred/dcrd/lru v1.0.0/go.mod h1:mxKOwFd7lFjN2GZYsiz/ecgqR6kkYAl+0pz0tEMk218= +github.com/deepmap/oapi-codegen v1.6.0/go.mod h1:ryDa9AgbELGeB+YEXE1dR53yAjHwFvE9iAUlWl9Al3M= +github.com/deepmap/oapi-codegen v1.8.2/go.mod h1:YLgSKSDv/bZQB7N4ws6luhozi3cEdRktEqrX88CvjIw= +github.com/dgraph-io/badger v1.6.1/go.mod h1:FRmFw3uxvcpa8zG3Rxs0th+hCLIuaQg8HlNV5bjgnuU= +github.com/dgraph-io/badger v1.6.2 h1:mNw0qs90GVgGGWylh0umH5iag1j6n/PeJtNvL6KY/x8= +github.com/dgraph-io/badger v1.6.2/go.mod h1:JW2yswe3V058sS0kZ2h/AXeDSqFjxnZcRrVH//y2UQE= +github.com/dgraph-io/badger/v2 v2.2007.4 h1:TRWBQg8UrlUhaFdco01nO2uXwzKS7zd+HVdwV/GHc4o= +github.com/dgraph-io/ristretto v0.0.2/go.mod h1:KPxhHT9ZxKefz+PCeOGsrHpl1qZ7i70dGTu2u+Ahh6E= +github.com/dgraph-io/ristretto v0.0.4-0.20210318174700-74754f61e018 h1:cNcG4c2n5xanQzp2hMyxDxPYVQmZ91y4WN6fJFlndLo= +github.com/dgraph-io/ristretto v0.0.4-0.20210318174700-74754f61e018/go.mod h1:MIonLggsKgZLUSt414ExgwNtlOL5MuEoAJP514mwGe8= github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ= +github.com/dgryski/go-bitstream v0.0.0-20180413035011-3522498ce2c8/go.mod h1:VMaSuZ+SZcx/wljOQKvp5srsbCiKDEb6K2wC4+PiBmQ= +github.com/dgryski/go-farm v0.0.0-20190423205320-6a90982ecee2 h1:tdlZCpZ/P9DhczCTSixgIKmwPv6+wP5DGjqLYw5SUiA= +github.com/dgryski/go-farm v0.0.0-20190423205320-6a90982ecee2/go.mod h1:SqUrOPUnsFjfmXRMNPybcSiG0BgUW2AuFH8PAnS2iTw= +github.com/dgryski/go-sip13 v0.0.0-20181026042036-e10d5fee7954/go.mod h1:vAd38F8PWV+bWy6jNmig1y/TA+kYO4g3RSRF0IAv0no= github.com/dgryski/trifles v0.0.0-20200323201526-dd97f9abfb48 h1:fRzb/w+pyskVMQ+UbP35JkH8yB7MYb4q/qhBarqZE6g= github.com/dgryski/trifles v0.0.0-20200323201526-dd97f9abfb48/go.mod h1:if7Fbed8SFyPtHLHbg49SI7NAdJiC5WIA09pe59rfAA= -github.com/dlclark/regexp2 v1.4.1-0.20201116162257-a2a8dda75c91 h1:Izz0+t1Z5nI16/II7vuEo/nHjodOg0p7+OiDpjX5t1E= github.com/dlclark/regexp2 v1.4.1-0.20201116162257-a2a8dda75c91/go.mod h1:2pZnwuY/m+8K6iRw6wQdMtk+rH5tNGR1i55kozfMjCc= -github.com/docker/docker v20.10.17+incompatible h1:JYCuMrWaVNophQTOrMMoSwudOVEfcegoZZrleKc1xwE= -github.com/docker/docker v20.10.17+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= +github.com/dlclark/regexp2 v1.7.0 h1:7lJfhqlPssTb1WQx4yvTHN0uElPEv52sbaECrAQxjAo= +github.com/dlclark/regexp2 v1.7.0/go.mod h1:DHkYz0B9wPfa6wondMfaivmHpzrQ3v9q8cnmRbL6yW8= +github.com/docker/docker v1.4.2-0.20180625184442-8e610b2b55bf/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= +github.com/docker/docker v20.10.19+incompatible h1:lzEmjivyNHFHMNAFLXORMBXyGIhw/UP4DvJwvyKYq64= +github.com/docker/docker v20.10.19+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= github.com/docker/go-units v0.4.0/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk= github.com/docker/go-units v0.5.0 h1:69rxXcBk27SvSaaxTtLh/8llcHD8vYHT7WSdRZ/jvr4= github.com/docker/go-units v0.5.0/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk= +github.com/docker/spdystream v0.0.0-20160310174837-449fdfce4d96/go.mod h1:Qh8CwZgvJUkLughtfhJv5dyTYa91l1fOUCrgjqmcifM= github.com/docopt/docopt-go v0.0.0-20180111231733-ee0de3bc6815/go.mod h1:WwZ+bS3ebgob9U8Nd0kOddGdZWjyMGR8Wziv+TBNwSE= -github.com/dop251/goja v0.0.0-20220405120441-9037c2b61cbf h1:Yt+4K30SdjOkRoRRm3vYNQgR+/ZIy0RmeUDZo7Y8zeQ= -github.com/dop251/goja v0.0.0-20220405120441-9037c2b61cbf/go.mod h1:R9ET47fwRVRPZnOGvHxxhuZcbrMCuiqOz3Rlrh4KSnk= +github.com/dop251/goja v0.0.0-20211011172007-d99e4b8cbf48/go.mod h1:R9ET47fwRVRPZnOGvHxxhuZcbrMCuiqOz3Rlrh4KSnk= +github.com/dop251/goja v0.0.0-20211022113120-dc8c55024d06/go.mod h1:R9ET47fwRVRPZnOGvHxxhuZcbrMCuiqOz3Rlrh4KSnk= +github.com/dop251/goja v0.0.0-20230122112309-96b1610dd4f7 h1:kgvzE5wLsLa7XKfV85VZl40QXaMCaeFtHpPwJ8fhotY= +github.com/dop251/goja v0.0.0-20230122112309-96b1610dd4f7/go.mod h1:yRkwfj0CBpOGre+TwBsqPV0IH0Pk73e4PXJOeNDboGs= github.com/dop251/goja_nodejs v0.0.0-20210225215109-d91c329300e7/go.mod h1:hn7BA7c8pLvoGndExHudxTDKZ84Pyvv+90pbBjbTz0Y= +github.com/dop251/goja_nodejs v0.0.0-20211022123610-8dd9abb0616d/go.mod h1:DngW8aVqWbuLRMHItjPUyqdj+HWPvnQe8V8y1nDpIbM= github.com/dustin/go-humanize v0.0.0-20171111073723-bb3d318650d4/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk= github.com/dustin/go-humanize v0.0.0-20180421182945-02af3965c54e/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk= github.com/dustin/go-humanize v1.0.0/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk= github.com/dustin/go-humanize v1.0.1 h1:GzkhY7T5VNhEkwH0PVJgjz+fX1rhBrR7pRT3mDkpeCY= github.com/dustin/go-humanize v1.0.1/go.mod h1:Mu1zIs6XwVuF/gI1OepvI0qD18qycQx+mFykh5fBlto= github.com/eapache/go-resiliency v1.1.0/go.mod h1:kFI+JgMyC7bLPUVY133qvEBtVayf5mFgVsvEsIPBvNs= +github.com/eapache/go-resiliency v1.2.0/go.mod h1:kFI+JgMyC7bLPUVY133qvEBtVayf5mFgVsvEsIPBvNs= github.com/eapache/go-xerial-snappy v0.0.0-20180814174437-776d5712da21/go.mod h1:+020luEh2TKB4/GOp8oxxtq0Daoen/Cii55CzbTV6DU= github.com/eapache/queue v1.1.0/go.mod h1:6eCeP0CKFpHLu8blIFXhExK/dRa7WDZfr6jVFPTqq+I= +github.com/eclipse/paho.mqtt.golang v1.2.0/go.mod h1:H9keYFcgq3Qr5OUJm/JZI/i6U7joQ8SYLhZwfeOo6Ts= github.com/edsrzf/mmap-go v1.0.0/go.mod h1:YO35OhQPt3KJa3ryjFM5Bs14WD66h8eGKpfaBNrHW5M= github.com/edsrzf/mmap-go v1.1.0 h1:6EUwBLQ/Mcr1EYLE4Tn1VdW1A4ckqCQWZBw8Hr0kjpQ= github.com/edsrzf/mmap-go v1.1.0/go.mod h1:19H/e8pUPLicwkyNgOykDXkJ9F0MHE+Z52B8EIth78Q= github.com/elastic/gosigar v0.12.0/go.mod h1:iXRIGg2tLnu7LBdpqzyQfGDEidKCfWcCMS0WKyPWoMs= github.com/elastic/gosigar v0.14.2 h1:Dg80n8cr90OZ7x+bAax/QjoW/XqTI11RmA79ZwIm9/4= github.com/elastic/gosigar v0.14.2/go.mod h1:iXRIGg2tLnu7LBdpqzyQfGDEidKCfWcCMS0WKyPWoMs= +github.com/elazarl/goproxy v0.0.0-20180725130230-947c36da3153/go.mod h1:/Zj4wYkgs4iZTTu3o/KG3Itv/qCCa8VVMlb3i9OVuzc= +github.com/emicklei/dot v0.11.0/go.mod h1:DeV7GvQtIw4h2u73RKBkkFdvVAz0D9fzeJrgPW6gy/s= github.com/emicklei/dot v1.0.0 h1:yyObALINBOuI1GdCRwVea2IPtGtVgh0NQgJDrE03Tqc= github.com/emicklei/dot v1.0.0/go.mod h1:DeV7GvQtIw4h2u73RKBkkFdvVAz0D9fzeJrgPW6gy/s= +github.com/emicklei/go-restful v0.0.0-20170410110728-ff4f55a20633/go.mod h1:otzb+WCGbkyDHkqmQmT5YD2WR4BBwUdeQoFo8l/7tVs= github.com/emirpasic/gods v1.18.1 h1:FXtiHYKDGKCW2KzwZKx0iC0PQmdlorYgdFG9jPXJ1Bc= github.com/emirpasic/gods v1.18.1/go.mod h1:8tpGGwCnJ5H4r6BWwaV6OrWmMoPhUl5jm/FMNAnJvWQ= github.com/envoyproxy/go-control-plane v0.6.9/go.mod h1:SBwIajubJHhxtWwsL9s8ss4safvEdbitLhGGK48rN6g= github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98= +github.com/envoyproxy/go-control-plane v0.9.9-0.20201210154907-fd9021fe5dad/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk= +github.com/envoyproxy/go-control-plane v0.9.9-0.20210512163311-63b5d3c536b0/go.mod h1:hliV/p42l8fGbc6Y9bQ70uLwIvmJyVE5k4iMKlh8wCQ= github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= +github.com/ethereum/go-ethereum v1.10.13/go.mod h1:W3yfrFyL9C1pHcwY5hmRHVDaorTiQxhYBkKyu5mEDHw= +github.com/ethereum/go-ethereum v1.11.3 h1:uuBkYUJW9aY5JYi3+sqLHz+XWyo5fmn/ab9XcbtVDTU= +github.com/ethereum/go-ethereum v1.11.3/go.mod h1:rBUvAl5cdVrAei9q5lgOU7RSEuPJk1nlBDnS/YSoKQE= +github.com/evanphx/json-patch v4.2.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk= github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4= +github.com/fatih/color v1.9.0/go.mod h1:eQcE1qtQxscV5RaZvpXrrb8Drkc3/DdQ+uUYCNjL+zU= +github.com/ferranbt/fastssz v0.0.0-20210120143747-11b9eff30ea9/go.mod h1:DyEu2iuLBnb/T51BlsiO3yLYdJC6UbGMrIkqK1KmQxM= +github.com/ferranbt/fastssz v0.0.0-20210905181407-59cf6761a7d5 h1:6dVcS0LktRSyEEgldFY4N9J17WjUoiJStttH+RZj0Wo= +github.com/ferranbt/fastssz v0.0.0-20210905181407-59cf6761a7d5/go.mod h1:S8yiDeAXy8f88W4Ul+0dBMPx49S05byYbmZD6Uv94K4= github.com/fjl/gencodec v0.0.0-20220412091415-8bb9e558978c h1:CndMRAH4JIwxbW8KYq6Q+cGWcGHz0FjGR3QqcInWcW0= github.com/fjl/gencodec v0.0.0-20220412091415-8bb9e558978c/go.mod h1:AzA8Lj6YtixmJWL+wkKoBGsLWy9gFrAzi4g+5bCKwpY= +github.com/fjl/memsize v0.0.0-20190710130421-bcb5799ab5e5/go.mod h1:VvhXpOYNQvB+uIk2RvXzuaQtkQJzzIx6lSBe1xv7hi0= github.com/flynn/go-shlex v0.0.0-20150515145356-3f9db97f8568/go.mod h1:xEzjJPgXI435gkrCt3MPfRiAkVrwSbHsst4LCFVfpJc= github.com/flynn/noise v1.0.0 h1:DlTHqmzmvcEiKj+4RYo/imoswx/4r6iBlCMfVtrMXpQ= github.com/flynn/noise v1.0.0/go.mod h1:xbMo+0i6+IGbYdJhF31t2eR1BIU0CYc12+BNAKwUTag= +github.com/fogleman/gg v1.2.1-0.20190220221249-0403632d5b90/go.mod h1:R/bRT+9gY/C5z7JzPU0zXsXHKM4/ayA+zqcVNZzPa1k= +github.com/fortytw2/leaktest v1.3.0 h1:u8491cBMTQ8ft8aeV+adlcytMZylmA5nnwwkRZjI8vw= +github.com/fortytw2/leaktest v1.3.0/go.mod h1:jDsjWgpAGjm2CA7WthBh/CdZYEPF31XHquHwclZch5g= github.com/francoispqt/gojay v1.2.13 h1:d2m3sFjloqoIUQU3TsHBgj6qg/BVGlTBeHDUmyJnXKk= github.com/francoispqt/gojay v1.2.13/go.mod h1:ehT5mTG4ua4581f1++1WLG0vPdaA9HaiDsoyrBGkyDY= github.com/franela/goblin v0.0.0-20200105215937-c9ffbefa60db/go.mod h1:7dvUGVsVBjqR7JHJk0brhHOZYGmfBYOrK0ZhYMEtBr4= github.com/franela/goreq v0.0.0-20171204163338-bcd34c9993f8/go.mod h1:ZhphrRTfi2rbfLwlschooIH4+wKKDR4Pdxhh+TRoA20= +github.com/frankban/quicktest v1.7.2/go.mod h1:jaStnuzAqU1AJdCO0l53JDCJrVDKcS03DbaAcR7Ks/o= github.com/frankban/quicktest v1.9.0/go.mod h1:ui7WezCLWMWxVWr1GETZY3smRy0G4KWq9vcPtJmFl7Y= github.com/frankban/quicktest v1.14.4 h1:g2rn0vABPOOXmZUj+vbmUp0lPoXEMuhTpIluN0XL9UY= github.com/frankban/quicktest v1.14.4/go.mod h1:4ptaffx2x8+WTWXmUCuVU6aPUX1/Mz7zb5vbUoiM6w0= +github.com/fsnotify/fsnotify v1.4.3-0.20170329110642-4da3e2cfbabc/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ= github.com/fsnotify/fsnotify v1.5.1/go.mod h1:T3375wBYaZdLLcVNkcVbzGHY7f1l/uK5T5Ai1i3InKU= -github.com/fsnotify/fsnotify v1.5.4 h1:jRbGcIw6P2Meqdwuo0H1p6JVLbL5DHKAKlYndzMwVZI= -github.com/fsnotify/fsnotify v1.5.4/go.mod h1:OVB6XrOHzAwXMpEM7uPOzcehqUV2UqJxmVXmkdnm1bU= +github.com/fsnotify/fsnotify v1.6.0 h1:n+5WquG0fcWoWp6xPWfHdbskMCQaFnG6PfBrh1Ky4HY= +github.com/fsnotify/fsnotify v1.6.0/go.mod h1:sl3t1tCWJFWoRz9R8WJCbQihKKwmorjAbSClcnxKAGw= github.com/garslo/gogen v0.0.0-20170307003452-d6ebae628c7c h1:uYNKzPntb8c6DKvP9EfrBjkLkU7pM4lM+uuHSIa8UtU= github.com/garslo/gogen v0.0.0-20170307003452-d6ebae628c7c/go.mod h1:Q0X6pkwTILDlzrGEckF6HKjXe48EgsY/l7K7vhY4MW8= +github.com/garyburd/redigo v1.1.1-0.20170914051019-70e1b1943d4f/go.mod h1:NR3MbYisc3/PwhQ00EMzDiPmrwpPxAn5GI05/YaO1SY= +github.com/garyburd/redigo v1.6.0/go.mod h1:NR3MbYisc3/PwhQ00EMzDiPmrwpPxAn5GI05/YaO1SY= +github.com/gballet/go-libpcsclite v0.0.0-20190607065134-2772fd86a8ff/go.mod h1:x7DCsMOv1taUwEWCzT4cmDeAkigA5/QCwUodaVOe8Ww= +github.com/gballet/go-libpcsclite v0.0.0-20191108122812-4678299bea08/go.mod h1:x7DCsMOv1taUwEWCzT4cmDeAkigA5/QCwUodaVOe8Ww= github.com/gballet/go-verkle v0.0.0-20221121182333-31427a1f2d35 h1:I8QswD9gf3VEpr7bpepKKOm7ChxFITIG+oc1I5/S0no= github.com/gballet/go-verkle v0.0.0-20221121182333-31427a1f2d35/go.mod h1:DMDd04jjQgdynaAwbEgiRERIGpC8fDjx0+y06an7Psg= +github.com/getkin/kin-openapi v0.53.0/go.mod h1:7Yn5whZr5kJi6t+kShccXS8ae1APpYTW6yheSwk8Yi4= +github.com/getkin/kin-openapi v0.61.0/go.mod h1:7Yn5whZr5kJi6t+kShccXS8ae1APpYTW6yheSwk8Yi4= +github.com/ghodss/yaml v0.0.0-20150909031657-73d445a93680/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= github.com/gin-contrib/sse v0.1.0 h1:Y/yl/+YNO8GZSjAhjMsSuLt29uWRFHdHYUb5lYOV9qE= github.com/gin-contrib/sse v0.1.0/go.mod h1:RHrZQHXnP2xjPF+u1gW/2HnVO7nvIa9PG3Gm+fLHvGI= @@ -279,50 +462,75 @@ github.com/glycerine/go-unsnap-stream v0.0.0-20190901134440-81cf024a9e0a/go.mod github.com/glycerine/goconvey v0.0.0-20180728074245-46e3a41ad493/go.mod h1:Ogl1Tioa0aV7gstGFO7KhffUsb9M4ydbEbbxpcEDc24= github.com/glycerine/goconvey v0.0.0-20190315024820-982ee783a72e/go.mod h1:Ogl1Tioa0aV7gstGFO7KhffUsb9M4ydbEbbxpcEDc24= github.com/glycerine/goconvey v0.0.0-20190410193231-58a59202ab31/go.mod h1:Ogl1Tioa0aV7gstGFO7KhffUsb9M4ydbEbbxpcEDc24= +github.com/go-chi/chi/v5 v5.0.0/go.mod h1:BBug9lr0cqtdAhsu6R4AAdvufI0/XBzAQSsUqJpoZOs= github.com/go-errors/errors v1.0.1/go.mod h1:f4zRHt4oKfwPJE5k8C9vpYG+aDHdBFUsgrm6/TyX73Q= +github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU= +github.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= +github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= github.com/go-kit/kit v0.9.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= -github.com/go-kit/kit v0.10.0 h1:dXFJfIHVvUcpSgDOV+Ne6t7jXri8Tfv2uOLHUZ2XNuo= github.com/go-kit/kit v0.10.0/go.mod h1:xUsJbQ/Fp4kEt7AFgCuvyX4a71u8h9jB8tj/ORgOZ7o= +github.com/go-kit/kit v0.12.0 h1:e4o3o3IsBfAKQh5Qbbiqyfu97Ku7jrO/JbohvztANh4= +github.com/go-kit/kit v0.12.0/go.mod h1:lHd+EkCZPIwYItmGDDRdhinkzX2A1sj+M9biaEaizzs= +github.com/go-kit/log v0.1.0/go.mod h1:zbhenjAZHb184qTLMA9ZjW7ThYL0H2mk7Q6pNt4vbaY= +github.com/go-kit/log v0.2.1 h1:MRVx0/zhvdseW+Gza6N9rVzU/IVzaeE1SFI4raAhmBU= +github.com/go-kit/log v0.2.1/go.mod h1:NwTd00d/i8cPZ3xOwwiv2PO5MOcx78fFErGNcVmBjv0= github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE= github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk= github.com/go-logfmt/logfmt v0.5.0/go.mod h1:wCYkCAKZfumFQihp8CzCvQ3paCTfi41vtzG1KdI/P7A= github.com/go-logfmt/logfmt v0.5.1 h1:otpy5pqBCBZ1ng9RQ0dPu4PN7ba75Y/aA+UpowDyNVA= github.com/go-logfmt/logfmt v0.5.1/go.mod h1:WYhtIu8zTZfxdn5+rREduYbwxfcBr/Vr6KEVveWlfTs= +github.com/go-logr/logr v0.1.0/go.mod h1:ixOQHD9gLJUVQQ2ZOR7zLEifBX6tGkNJF4QyIY7sIas= +github.com/go-logr/logr v0.2.0/go.mod h1:z6/tIYblkpsD+a4lm/fGIIU9mZ+XfAiaFtq7xTgseGU= +github.com/go-logr/logr v0.2.1/go.mod h1:z6/tIYblkpsD+a4lm/fGIIU9mZ+XfAiaFtq7xTgseGU= github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= github.com/go-logr/logr v1.2.3 h1:2DntVwHkVopvECVRSlL5PSo9eG+cAkDCuckLubN+rq0= github.com/go-logr/logr v1.2.3/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag= github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE= +github.com/go-ole/go-ole v1.2.1/go.mod h1:7FAglXiTm7HKlQRDeOQ6ZNUHidzCWXuZWq/1dTyBNF8= +github.com/go-ole/go-ole v1.2.5/go.mod h1:pprOEPIfldk/42T2oK7lQ4v4JSDwmV0As9GaiUsvbm0= +github.com/go-ole/go-ole v1.2.6 h1:/Fpf6oFPoeFik9ty7siob0G6Ke8QvQEuVcuChpwXzpY= +github.com/go-ole/go-ole v1.2.6/go.mod h1:pprOEPIfldk/42T2oK7lQ4v4JSDwmV0As9GaiUsvbm0= +github.com/go-openapi/jsonpointer v0.0.0-20160704185906-46af16f9f7b1/go.mod h1:+35s3my2LFTysnkMfxsJBAMHj/DoqoB9knIWoYG/Vk0= +github.com/go-openapi/jsonpointer v0.19.5/go.mod h1:Pl9vOtqEWErmShwVjC8pYs9cog34VGT37dQOVbmoatg= +github.com/go-openapi/jsonreference v0.0.0-20160704190145-13c6e3589ad9/go.mod h1:W3Z9FmVs9qj+KR4zFKmDPGiLdk1D9Rlm7cyMvf57TTg= +github.com/go-openapi/spec v0.0.0-20160808142527-6aced65f8501/go.mod h1:J8+jY1nAiCcj+friV/PDoE1/3eeccG9LYBs0tYvLOWc= +github.com/go-openapi/swag v0.0.0-20160704191624-1d0bd113de87/go.mod h1:DXUve3Dpr1UfpPtxFw+EFuQ41HhCWZfha5jSVRG7C7I= +github.com/go-openapi/swag v0.19.5/go.mod h1:POnQmlKehdgb5mhVOsnJFsivZCEZ/vjK9gh66Z9tfKk= github.com/go-playground/assert/v2 v2.0.1/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4= -github.com/go-playground/locales v0.13.0 h1:HyWk6mgj5qFqCT5fjGBuRArbVDfE4hi8+e8ceBS/t7Q= github.com/go-playground/locales v0.13.0/go.mod h1:taPMhCMXrRLJO55olJkUXHZBHCxTMfnGwq/HNwmWNS8= -github.com/go-playground/universal-translator v0.17.0 h1:icxd5fm+REJzpZx7ZfpaD876Lmtgy7VtROAbHHXk8no= +github.com/go-playground/locales v0.14.0 h1:u50s323jtVGugKlcYeyzC0etD1HifMjqmJqb8WugfUU= github.com/go-playground/universal-translator v0.17.0/go.mod h1:UkSxE5sNxxRwHyU+Scu5vgOQjsIJAF8j9muTVoKLVtA= -github.com/go-playground/validator/v10 v10.2.0 h1:KgJ0snyC2R9VXYN2rneOtQcw5aHQB1Vv0sFl1UcHBOY= +github.com/go-playground/universal-translator v0.18.0 h1:82dyy6p4OuJq4/CByFNOn/jYrnRPArHwAcmLoJZxyho= github.com/go-playground/validator/v10 v10.2.0/go.mod h1:uOYAAleCW8F/7oMFd6aG0GOhaH6EGOAJShg8Id5JGkI= +github.com/go-playground/validator/v10 v10.11.1 h1:prmOlTVv+YjZjmRmNSF3VmspqJIxJWXmqUsHwfTRRkQ= github.com/go-sourcemap/sourcemap v2.1.3+incompatible h1:W1iEw64niKVGogNgBN3ePyLFfuisuzeidWPMPWmECqU= github.com/go-sourcemap/sourcemap v2.1.3+incompatible/go.mod h1:F8jJfvm2KbVjc5NqelyYJmf/v5J0dwNLS2mL4sNA1Jg= github.com/go-sql-driver/mysql v1.4.0/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w= +github.com/go-sql-driver/mysql v1.4.1/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w= +github.com/go-stack/stack v1.6.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= github.com/go-stack/stack v1.8.1 h1:ntEHSVwIt7PNXNpgPmVfMrNhLtgjlmnZha2kOpuRiDw= github.com/go-stack/stack v1.8.1/go.mod h1:dcoOX6HbPZSZptuspn9bctJ+N/CnF5gGygcUP3XYfe4= github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0 h1:p104kn46Q8WdvHunIJ9dAyjPVtrBPhSr3KT2yUst43I= github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0/go.mod h1:fyg7847qk6SyHyPtNmDHnmrv/HOrqktSC+C9fM+CJOE= +github.com/go-yaml/yaml v2.1.0+incompatible/go.mod h1:w2MrLa16VYP0jy6N7M5kHaCkaLENm+P+Tv+MfurjSw0= github.com/gobwas/httphead v0.0.0-20180130184737-2c6c146eadee h1:s+21KNqlpePfkah2I+gwHF8xmJWRjooY+5248k6m4A0= github.com/gobwas/httphead v0.0.0-20180130184737-2c6c146eadee/go.mod h1:L0fX3K22YWvt/FAX9NnzrNzcI4wNYi9Yku4O0LKYflo= github.com/gobwas/pool v0.2.0 h1:QEmUOlnSjWtnpRGHF3SauEiOsy82Cup83Vf2LcMlnc8= github.com/gobwas/pool v0.2.0/go.mod h1:q8bcK0KcYlCgd9e7WYLm9LpyS+YeLd8JVDW6WezmKEw= github.com/gobwas/ws v1.0.2 h1:CoAavW/wd/kulfZmSIBt6p24n4j7tHgNVCjsfHVNUbo= github.com/gobwas/ws v1.0.2/go.mod h1:szmBTxLgaFppYjEmNtny/v3w89xOydFnnZMcgRRu/EM= -github.com/goccy/go-json v0.9.7 h1:IcB+Aqpx/iMHu5Yooh7jEzJk1JZ7Pjtmys2ukPr7EeM= -github.com/goccy/go-json v0.9.7/go.mod h1:6MelG93GURQebXPDq3khkgXZkazVtN9CRI+MGFi0w8I= +github.com/goccy/go-json v0.9.11 h1:/pAaQDLHEoCq/5FFmSKBswWmK6H0e8g4159Kc/X/nqk= +github.com/goccy/go-json v0.9.11/go.mod h1:6MelG93GURQebXPDq3khkgXZkazVtN9CRI+MGFi0w8I= github.com/godbus/dbus/v5 v5.0.3/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= github.com/godbus/dbus/v5 v5.1.0 h1:4KLkAxT3aOY8Li4FRJe/KvhoNFFxo0m6fNuFUO8QJUk= github.com/godbus/dbus/v5 v5.1.0/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= github.com/gofrs/flock v0.8.1 h1:+gYjHKf32LDeiEEFhQaotPbLuUXjY5ZqxKgXy7n59aw= github.com/gofrs/flock v0.8.1/go.mod h1:F1TvTiK9OcQqauNUHlbJvyl9Qa1QvF/gOUDKA14jxHU= +github.com/gofrs/uuid v3.3.0+incompatible/go.mod h1:b2aQJv3Z4Fp6yNu3cdSllBxTCLRxnplIgP/c0N/04lM= github.com/gogo/googleapis v1.1.0/go.mod h1:gf4bu3Q80BeJ6H1S1vYPm8/ELATdvryBaNFGgqEef3s= github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= github.com/gogo/protobuf v1.2.0/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= @@ -330,66 +538,113 @@ 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 v3.2.2+incompatible/go.mod h1:8pz2t5EyA70fFQQSrl6XZXzqecmYZeUEB8OUGHkxJ+I= github.com/golang-jwt/jwt/v4 v4.5.0 h1:7cYmW1XlMY7h7ii7UhUyChSgS5wUJEnm9uZVTGqOWzg= github.com/golang-jwt/jwt/v4 v4.5.0/go.mod h1:m21LjoU+eqJr34lmDMbreY2eSTRJ1cv77w39/MY0Ch0= +github.com/golang/freetype v0.0.0-20170609003504-e2365dfdc4a0/go.mod h1:E/TSTwGwJL78qG/PmXZO1EjYhfJinVAhrmmHX6Z8B9k= +github.com/golang/gddo v0.0.0-20200528160355-8d077c1d8f4c/go.mod h1:sam69Hju0uq+5uvLJUMDlsKlQ21Vrs1Kd/1YFPNYdOU= +github.com/golang/geo v0.0.0-20190916061304-5b978397cfec/go.mod h1:QZ0nwyI2jOfgRAoBvP+ab5aRr7c9x7lhGEJrKvBwjWI= github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= github.com/golang/groupcache v0.0.0-20160516000752-02826c3e7903/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= +github.com/golang/groupcache v0.0.0-20191227052852-215e87163ea7/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= +github.com/golang/lint v0.0.0-20170918230701-e5d664eb928e/go.mod h1:tluoj9z5200jBnyusfRPU2LqT6J+DAorxEvtC7LHB+E= github.com/golang/lint v0.0.0-20180702182130-06c8688daad7/go.mod h1:tluoj9z5200jBnyusfRPU2LqT6J+DAorxEvtC7LHB+E= github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= github.com/golang/mock v1.2.0/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= +github.com/golang/mock v1.3.1/go.mod h1:sBzyDLLjw3U8JLTeZvSv8jJB+tU5PVekmnlKIyFUx0Y= +github.com/golang/mock v1.4.0/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= +github.com/golang/mock v1.4.1/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= +github.com/golang/mock v1.4.3/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= +github.com/golang/mock v1.4.4/go.mod h1:l3mdAwkq5BuhzHwde/uurv3sEJeZMXNpwsxVWU71h+4= github.com/golang/mock v1.6.0 h1:ErTB+efbowRARo13NNdxyJji2egdxLGQhRaY+DUumQc= github.com/golang/mock v1.6.0/go.mod h1:p6yTPP+5HYm5mzsMV8JkE6ZKdX+/wYM6Hr+LicevLPs= +github.com/golang/protobuf v0.0.0-20161109072736-4bd1920723d7/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.3.3/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw= +github.com/golang/protobuf v1.3.4/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw= github.com/golang/protobuf v1.3.5/go.mod h1:6O5/vntMXwX2lRkT1hjjk0nAC1IDOTvTlVgjlRvqsdk= github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8= github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA= github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs= github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w= github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0= +github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QDs8UjoX8= github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= +github.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= -github.com/golang/protobuf v1.5.2 h1:ROPKBNFfQgOUMifHyP+KYbvpjbdoFNs+aK7DXlji0Tw= github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= +github.com/golang/protobuf v1.5.3 h1:KhyjKVUg7Usr/dYsdSqoFveMYd5ko72D+zANwlG1mmg= +github.com/golang/protobuf v1.5.3/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= +github.com/golang/snappy v0.0.0-20170215233205-553a64147049/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= github.com/golang/snappy v0.0.0-20180518054509-2e65f85255db/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= github.com/golang/snappy v0.0.1/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= +github.com/golang/snappy v0.0.3/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= github.com/golang/snappy v0.0.4 h1:yAGX7huGHXlcLOEtBnF4w7FQwA26wojNCwOYAEhLjQM= github.com/golang/snappy v0.0.4/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= +github.com/golangci/lint-1 v0.0.0-20181222135242-d2cdd8c08219/go.mod h1:/X8TswGSh1pIozq4ZwCfxS0WA5JGXguxk94ar/4c87Y= github.com/google/btree v0.0.0-20180124185431-e89373fe6b4a/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= github.com/google/btree v1.1.2 h1:xf4v41cLI2Z6FxbKm+8Bu+m8ifhj15JuZ9sa0jZCMUU= github.com/google/btree v1.1.2/go.mod h1:qOPhT0dTNdNzV6Z/lhRX0YXUafgPLFUh+gZMl761Gm4= +github.com/google/flatbuffers v1.11.0/go.mod h1:1AeVuKshWv4vARoZatz6mlQ0JxURH0Kv5+zNeJKJCa8= +github.com/google/go-cmp v0.1.1-0.20171103154506-982329095285/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.4.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.3/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38= github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/google/go-github v17.0.0+incompatible/go.mod h1:zLgOLi98H3fifZn+44m+umXrS52loVEgC2AApnigrVQ= github.com/google/go-querystring v1.0.0/go.mod h1:odCYkC5MyYFN7vkCjXpyrEuKhc/BUO6wN/zVPAxq5ck= github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= -github.com/google/gofuzz v1.1.1-0.20200604201612-c04b05f3adfa h1:Q75Upo5UN4JbPFURXZ8nLKYUvF85dyFRop/vQ0Rv+64= +github.com/google/gofuzz v1.1.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= github.com/google/gofuzz v1.1.1-0.20200604201612-c04b05f3adfa/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= +github.com/google/gofuzz v1.2.0 h1:xRy4A+RhZaiKjJ1bPfwQ8sedCA+YS2YcCHW6ec7JMi0= +github.com/google/gofuzz v1.2.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= github.com/google/gopacket v1.1.17/go.mod h1:UdDNZ1OO62aGYVnPhxT1U6aI7ukYtA/kB8vaU0diBUM= github.com/google/gopacket v1.1.19 h1:ves8RnFZPGiFnTS0uPQStjwru6uO6h+nlr9j6fL7kF8= github.com/google/gopacket v1.1.19/go.mod h1:iJ8V8n6KS+z2U1A8pUwu8bW5SyEMkXJB8Yo/Vo+TKTo= github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs= +github.com/google/martian/v3 v3.0.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0= +github.com/google/orderedcode v0.0.1 h1:UzfcAexk9Vhv8+9pNOgRu41f16lHq725vPwnSeiG/Us= github.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= +github.com/google/pprof v0.0.0-20190515194954-54271f7e092f/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= +github.com/google/pprof v0.0.0-20191218002539-d4f498aebedc/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= +github.com/google/pprof v0.0.0-20200212024743-f11f1df84d12/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= +github.com/google/pprof v0.0.0-20200229191704-1ebb73c60ed3/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= +github.com/google/pprof v0.0.0-20200430221834-fc25d7d30c6d/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= +github.com/google/pprof v0.0.0-20200708004538-1a94d8640e99/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= github.com/google/pprof v0.0.0-20230207041349-798e818bf904 h1:4/hN5RUoecvl+RmJRE2YxKWtnnQls6rQjjW5oV7qg2U= github.com/google/pprof v0.0.0-20230207041349-798e818bf904/go.mod h1:uglQLonpP8qtYCYyzA+8c/9qtqgA3qsXGYqCPKARAFg= github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= +github.com/google/subcommands v1.2.0/go.mod h1:ZjhPrFU+Olkh9WazFPsl27BQ4UPiG37m3yTrtFlrHVk= github.com/google/uuid v1.0.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/google/uuid v1.1.5/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/google/uuid v1.2.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I= github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/googleapis/gax-go v2.0.0+incompatible/go.mod h1:SFVmujtThgffbyetf+mdk2eWhX2bMyUtNHzFKcPA9HY= github.com/googleapis/gax-go/v2 v2.0.3/go.mod h1:LLvjysVCY1JZeum8Z6l8qUty8fiNwE08qbEPm1M08qg= +github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg= +github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk= +github.com/googleapis/gnostic v0.0.0-20170729233727-0c5108395e2d/go.mod h1:sJBsCZ4ayReDTBIg8b9dl28c5xFWyhBTVRp3pOg5EKY= +github.com/googleapis/gnostic v0.1.0/go.mod h1:sJBsCZ4ayReDTBIg8b9dl28c5xFWyhBTVRp3pOg5EKY= +github.com/gophercloud/gophercloud v0.1.0/go.mod h1:vxM41WHh5uqHVBMZHzuwNOHh8XEoIEcSTewFxm1c5g8= github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY= github.com/gopherjs/gopherjs v0.0.0-20181103185306-d547d1d9531e/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY= github.com/gopherjs/gopherjs v0.0.0-20190309154008-847fc94819f9/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY= @@ -397,20 +652,35 @@ github.com/gopherjs/gopherjs v0.0.0-20190910122728-9d188e94fb99/go.mod h1:wJfORR github.com/gorilla/context v1.1.1/go.mod h1:kBGZzfjB9CEq2AlWe17Uuf7NDRt0dE0s8S51q0aT7Yg= github.com/gorilla/mux v1.6.2/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs= github.com/gorilla/mux v1.7.3/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs= +github.com/gorilla/mux v1.8.0/go.mod h1:DVbg23sWSpFRCP0SfiEN6jmj59UnW/n46BH5rLB71So= github.com/gorilla/websocket v0.0.0-20170926233335-4201258b820c/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ= github.com/gorilla/websocket v1.4.1/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= +github.com/gorilla/websocket v1.4.2/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= github.com/gorilla/websocket v1.5.0 h1:PPwGk2jz7EePpoHN/+ClbZu8SPxiqlu12wZP/3sWmnc= github.com/gorilla/websocket v1.5.0/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= +github.com/graph-gophers/graphql-go v0.0.0-20201113091052-beb923fada29/go.mod h1:9CQHMSxwO4MprSdzoIEobiHpoLtHm77vfxsvsIN5Vuc= +github.com/gregjones/httpcache v0.0.0-20170920190843-316c5e0ff04e/go.mod h1:FecbI9+v66THATjSRHfNgh1IVFe/9kFxbXtjV0ctIMA= github.com/gregjones/httpcache v0.0.0-20180305231024-9cad4c3443a7/go.mod h1:FecbI9+v66THATjSRHfNgh1IVFe/9kFxbXtjV0ctIMA= github.com/grpc-ecosystem/go-grpc-middleware v1.0.1-0.20190118093823-f849b5445de4/go.mod h1:FiyG127CGDf3tlThmgyCl78X/SZQqEOJBCDaAfeWzPs= -github.com/grpc-ecosystem/go-grpc-middleware v1.3.0 h1:+9834+KizmvFV7pXQGSXQTsaWhq2GjuNUt0aUU0YBYw= -github.com/grpc-ecosystem/go-grpc-middleware v1.3.0/go.mod h1:z0ButlSOZa5vEBq9m2m2hlwIgKw+rp3sdCBRoJY+30Y= +github.com/grpc-ecosystem/go-grpc-middleware v1.2.2/go.mod h1:EaizFBKfUKtMIF5iaDEhniwNedqGo9FuLFzppDr3uwI= +github.com/grpc-ecosystem/go-grpc-middleware v1.4.0 h1:UH//fgunKIs4JdUbpDl1VZCDaL56wXCB/5+wF6uHfaI= +github.com/grpc-ecosystem/go-grpc-middleware v1.4.0/go.mod h1:g5qyo/la0ALbONm6Vbp88Yd8NsDy6rZz+RcrMPxvld8= github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0/go.mod h1:8NvIoxWQoOIhqOTXgfV/d3M/q6VIi02HzZEHgUlZvzk= github.com/grpc-ecosystem/grpc-gateway v1.5.0/go.mod h1:RSKVYQBd5MCa4OVpNdGskqpgL2+G+NZTnrVHpWWfpdw= github.com/grpc-ecosystem/grpc-gateway v1.9.5/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY= +github.com/grpc-ecosystem/grpc-gateway v1.16.0 h1:gmcG1KaJ57LophUzW0Hy8NmPhnMZb4M0+kPpLofRdBo= +github.com/grpc-ecosystem/grpc-gateway v1.16.0/go.mod h1:BDjrQk3hbvj6Nolgz8mAMFbcEtjT1g+wF4CSlocrBnw= +github.com/grpc-ecosystem/grpc-gateway/v2 v2.0.1/go.mod h1:oVMjMN64nzEcepv1kdZKgx1qNYt4Ro0Gqefiq2JWdis= +github.com/grpc-ecosystem/grpc-gateway/v2 v2.7.0 h1:BZHcxBETFHIdVyhyEfOvn/RdU/QGdLI4y34qQGjGWO0= +github.com/gtank/merlin v0.1.1 h1:eQ90iG7K9pOhtereWsmyRJ6RAwcP4tHTDBHXNg+u5is= +github.com/gtank/merlin v0.1.1/go.mod h1:T86dnYJhcGOh5BjZFCJWTDeTK7XW8uE+E21Cy/bIQ+s= +github.com/gtank/ristretto255 v0.1.2 h1:JEqUCPA1NvLq5DwYtuzigd7ss8fwbYay9fi4/5uMzcc= +github.com/gxed/hashland/keccakpg v0.0.1/go.mod h1:kRzw3HkwxFU1mpmPP8v1WyQzwdGfmKFJ6tItnhQ67kU= +github.com/gxed/hashland/murmur3 v0.0.1/go.mod h1:KjXop02n4/ckmZSnY2+HKcLud/tcmvhST0bie/0lS48= github.com/hashicorp/consul/api v1.3.0/go.mod h1:MmDNSzIMUjNpY/mQ398R4bk2FnqQLoPndWW5VkKPlCE= github.com/hashicorp/consul/sdk v0.3.0/go.mod h1:VKf9jXwCTEY1QZP2MOLRhb5i/I/ssyNV1vwHyQBF0x8= github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= +github.com/hashicorp/go-bexpr v0.1.10/go.mod h1:oxlubA2vC/gFVfX1A6JGp7ls7uCDlfJn732ehYYg+g0= github.com/hashicorp/go-cleanhttp v0.5.1/go.mod h1:JpRdi6/HCYpAwUzNwuwqhbovhLtngrth3wmdIIUrZ80= github.com/hashicorp/go-immutable-radix v1.0.0/go.mod h1:0y9vanUI8NX6FsYoO3zeMjhV/C5i9g4Q3DwcSNZ4P60= github.com/hashicorp/go-msgpack v0.5.3/go.mod h1:ahLV/dePpqEmjfWmKiqvPkv/twdG7iPBM1vqhUKIvfM= @@ -420,21 +690,30 @@ github.com/hashicorp/go-sockaddr v1.0.0/go.mod h1:7Xibr9yA9JjQq1JpNB2Vw7kxv8xerX github.com/hashicorp/go-syslog v1.0.0/go.mod h1:qPfqrKkXGihmCqbJM2mZgkZGvKG1dFdvsLplgctolz4= github.com/hashicorp/go-uuid v1.0.0/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= github.com/hashicorp/go-uuid v1.0.1/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= +github.com/hashicorp/go-uuid v1.0.2/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= github.com/hashicorp/go-version v1.2.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= github.com/hashicorp/go.net v0.0.1/go.mod h1:hjKkEWcCURg++eb33jQU7oqQcI9XDCnUzHA0oac0k90= github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= +github.com/hashicorp/golang-lru v0.5.4/go.mod h1:iADmTwqILo4mZ8BN3D2Q6+9jd8WM5uGBxy+E8yxSoD4= github.com/hashicorp/golang-lru v0.5.5-0.20210104140557-80c98217689d h1:dg1dEPuWpEqDnvIw251EVy4zlP8gWbsGj4BsUKCRpYs= github.com/hashicorp/golang-lru v0.5.5-0.20210104140557-80c98217689d/go.mod h1:iADmTwqILo4mZ8BN3D2Q6+9jd8WM5uGBxy+E8yxSoD4= -github.com/hashicorp/golang-lru/v2 v2.0.1 h1:5pv5N1lT1fjLg2VQ5KWc7kmucp2x/kvFOnxuVTqZ6x4= -github.com/hashicorp/golang-lru/v2 v2.0.1/go.mod h1:QeFd9opnmA6QUJc5vARoKUSoFhyfM2/ZepoAG6RGpeM= +github.com/hashicorp/golang-lru/v2 v2.0.2 h1:Dwmkdr5Nc/oBiXgJS3CDHNhJtIHkuZ3DZF5twqnfBdU= +github.com/hashicorp/golang-lru/v2 v2.0.2/go.mod h1:QeFd9opnmA6QUJc5vARoKUSoFhyfM2/ZepoAG6RGpeM= +github.com/hashicorp/hcl v0.0.0-20170914154624-68e816d1c783/go.mod h1:oZtUIOe8dh44I2q6ScRibXws4Ajl+d+nod3AaR9vL5w= +github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ= github.com/hashicorp/logutils v1.0.0/go.mod h1:QIAnNjmIWmVIIkWDTG1z5v++HQmx9WQRO+LraFDTW64= github.com/hashicorp/mdns v1.0.0/go.mod h1:tL+uN++7HEJ6SQLQ2/p+z2pH24WQKWjBPkE0mNTz8vQ= github.com/hashicorp/memberlist v0.1.3/go.mod h1:ajVTdAv/9Im8oMAAj5G31PhhMCZJV2pPBoIllUwCN7I= github.com/hashicorp/serf v0.8.2/go.mod h1:6hOLApaqBFA1NXqRQAsxw9QxuDEvNxSQRwA/JwenrHc= +github.com/herumi/bls-eth-go-binary v0.0.0-20210130185500-57372fb27371/go.mod h1:luAnRm3OsMQeokhGzpYmc0ZKwawY7o87PUEP11Z7r7U= +github.com/herumi/bls-eth-go-binary v0.0.0-20210917013441-d37c07cfda4e h1:wCMygKUQhmcQAjlk2Gquzq6dLmyMv2kF+llRspoRgrk= +github.com/herumi/bls-eth-go-binary v0.0.0-20210917013441-d37c07cfda4e/go.mod h1:luAnRm3OsMQeokhGzpYmc0ZKwawY7o87PUEP11Z7r7U= github.com/hexops/gotextdiff v1.0.3 h1:gitA9+qJrrTCsiCl7+kh75nPqQt1cx4ZkudSTLoUqJM= -github.com/holiman/uint256 v1.2.1 h1:XRtyuda/zw2l+Bq/38n5XUoEF72aSOu/77Thd9pPp2o= -github.com/holiman/uint256 v1.2.1/go.mod h1:y4ga/t+u+Xwd7CpDgZESaRcWy0I7XMlTMA25ApIH5Jw= +github.com/holiman/bloomfilter/v2 v2.0.3/go.mod h1:zpoh+gs7qcpqrHr3dB55AMiJwo0iURXE7ZOP9L9hSkA= +github.com/holiman/uint256 v1.2.0/go.mod h1:y4ga/t+u+Xwd7CpDgZESaRcWy0I7XMlTMA25ApIH5Jw= +github.com/holiman/uint256 v1.2.2 h1:TXKcSGc2WaxPD2+bmzAsVthL4+pEN0YwXcL5qED83vk= +github.com/holiman/uint256 v1.2.2/go.mod h1:SC8Ryt4n+UBbPbIBKaG9zbbDlp4jOru9xFZmPzLUTxw= github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= github.com/huandu/xstrings v1.0.0/go.mod h1:4qWG/gcEcfX4z/mBDHJ++3ReCw9ibxbsNJbcucJdbSo= github.com/huandu/xstrings v1.2.0/go.mod h1:DvyZB1rfVYsBIigL8HwpZgxHwXozlTgGqn63UyNX5k4= @@ -445,61 +724,140 @@ github.com/huandu/xstrings v1.4.0 h1:D17IlohoQq4UcpqD7fDk80P7l+lwAmlFaBHgOipl2FU github.com/huandu/xstrings v1.4.0/go.mod h1:y5/lhBue+AyNmUVz9RLU9xbLR0o4KIIExikq4ovT0aE= github.com/hudl/fargo v1.3.0/go.mod h1:y3CKSmjA+wD2gak7sUSXTAoopbhU08POFhmITJgmKTg= github.com/huin/goupnp v1.0.0/go.mod h1:n9v9KO1tAxYH82qOn+UTIFQDmx5n1Zxd/ClZDMX7Bnc= +github.com/huin/goupnp v1.0.2/go.mod h1:0dxJBVBHqTMjIUMkESDTNgOOx/Mw5wYIfyFmdzSamkM= github.com/huin/goupnp v1.1.0 h1:gEe0Dp/lZmPZiDFzJJaOfUpOvv2MKUkoBX8lDrn9vKU= github.com/huin/goupnp v1.1.0/go.mod h1:gnGPsThkYa7bFi/KWmEysQRf48l2dvR5bxr2OFckNX8= github.com/huin/goutil v0.0.0-20170803182201-1ca381bf3150/go.mod h1:PpLOETDnJ0o3iZrZfqZzyLl6l7F3c6L1oWn7OICBi6o= +github.com/ianlancetaylor/cgosymbolizer v0.0.0-20200424224625-be1b05b0b279/go.mod h1:a5aratAVTWyz+nJMmDsN8O4XTfaLfdAsB1ysCmZX5Bw= github.com/ianlancetaylor/cgosymbolizer v0.0.0-20220405231054-a1ae3e4bba26 h1:UT3hQ6+5hwqUT83cKhKlY5I0W/kqsl6lpn3iFb3Gtqs= github.com/ianlancetaylor/cgosymbolizer v0.0.0-20220405231054-a1ae3e4bba26/go.mod h1:DvXTE/K/RtHehxU8/GtDs4vFtfw64jJ3PaCnFri8CRg= +github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= +github.com/imdario/mergo v0.3.5/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA= +github.com/inconshreveable/log15 v0.0.0-20170622235902-74a0988b5f80/go.mod h1:cOaXtrgN4ScfRrD9Bre7U1thNq5RtJ8ZoP4iXVGRj6o= github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= github.com/inconshreveable/mousetrap v1.0.1 h1:U3uMjPSQEBMNp1lFxmllqCPM6P5u/Xq7Pgzkat/bFNc= github.com/inconshreveable/mousetrap v1.0.1/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw= +github.com/influxdata/flux v0.65.1/go.mod h1:J754/zds0vvpfwuq7Gc2wRdVwEodfpCFM7mYlOw2LqY= +github.com/influxdata/influxdb v1.8.3/go.mod h1:JugdFhsvvI8gadxOI6noqNeeBHvWNTbfYGtiAn+2jhI= +github.com/influxdata/influxdb-client-go/v2 v2.4.0/go.mod h1:vLNHdxTJkIf2mSLvGrpj8TCcISApPoXkaxP8g9uRlW8= github.com/influxdata/influxdb1-client v0.0.0-20191209144304-8bf82d3c094d/go.mod h1:qj24IKcXYK6Iy9ceXlo3Tc+vtHo9lIhSX5JddghvEPo= +github.com/influxdata/influxql v1.1.1-0.20200828144457-65d3ef77d385/go.mod h1:gHp9y86a/pxhjJ+zMjNXiQAA197Xk9wLxaz+fGG+kWk= +github.com/influxdata/line-protocol v0.0.0-20180522152040-32c6aa80de5e/go.mod h1:4kt73NQhadE3daL3WhR5EJ/J2ocX0PZzwxQ0gXJ7oFE= +github.com/influxdata/line-protocol v0.0.0-20200327222509-2487e7298839/go.mod h1:xaLFMmpvUxqXtVkUJfg9QmT88cDaCJ3ZKgdZ78oO8Qo= +github.com/influxdata/line-protocol v0.0.0-20210311194329-9aa0e372d097/go.mod h1:xaLFMmpvUxqXtVkUJfg9QmT88cDaCJ3ZKgdZ78oO8Qo= +github.com/influxdata/promql/v2 v2.12.0/go.mod h1:fxOPu+DY0bqCTCECchSRtWfc+0X19ybifQhZoQNF5D8= +github.com/influxdata/roaring v0.4.13-0.20180809181101-fc520f41fab6/go.mod h1:bSgUQ7q5ZLSO+bKBGqJiCBGAl+9DxyW63zLTujjUlOE= +github.com/influxdata/tdigest v0.0.0-20181121200506-bf2b5ad3c0a9/go.mod h1:Js0mqiSBE6Ffsg94weZZ2c+v/ciT8QRHFOap7EKDrR0= +github.com/influxdata/usage-client v0.0.0-20160829180054-6d3895376368/go.mod h1:Wbbw6tYNvwa5dlB6304Sd+82Z3f7PmVZHVKU637d4po= +github.com/ipfs/go-cid v0.0.1/go.mod h1:GHWU/WuQdMPmIosc4Yn1bcCT7dSeX4lBafM7iqUPQvM= +github.com/ipfs/go-cid v0.0.2/go.mod h1:GHWU/WuQdMPmIosc4Yn1bcCT7dSeX4lBafM7iqUPQvM= +github.com/ipfs/go-cid v0.0.3/go.mod h1:GHWU/WuQdMPmIosc4Yn1bcCT7dSeX4lBafM7iqUPQvM= +github.com/ipfs/go-cid v0.0.4/go.mod h1:4LLaPOQwmk5z9LBgQnpkivrx8BJjUyGwTXCd5Xfj6+M= +github.com/ipfs/go-cid v0.0.5/go.mod h1:plgt+Y5MnOey4vO4UlUazGqdbEXuFYitED67FexhXog= +github.com/ipfs/go-cid v0.0.7/go.mod h1:6Ux9z5e+HpkQdckYoX1PG/6xqKspzlEIR5SDmgqgC/I= github.com/ipfs/go-cid v0.3.2 h1:OGgOd+JCFM+y1DjWPmVH+2/4POtpDzwcr7VgnB7mZXc= github.com/ipfs/go-cid v0.3.2/go.mod h1:gQ8pKqT/sUxGY+tIwy1RPpAojYu7jAyCp5Tz1svoupw= +github.com/ipfs/go-datastore v0.4.1/go.mod h1:SX/xMIKoCszPqp+z9JhPYCmoOoXTvaa13XEbGtsFUhA= +github.com/ipfs/go-datastore v0.4.4/go.mod h1:SX/xMIKoCszPqp+z9JhPYCmoOoXTvaa13XEbGtsFUhA= +github.com/ipfs/go-datastore v0.5.0/go.mod h1:9zhEApYMTl17C8YDp7JmU7sQZi2/wqiYh73hakZ90Bk= github.com/ipfs/go-detect-race v0.0.1 h1:qX/xay2W3E4Q1U7d9lNs1sU9nvguX0a7319XbyQ6cOk= github.com/ipfs/go-detect-race v0.0.1/go.mod h1:8BNT7shDZPo99Q74BpGMK+4D8Mn4j46UU0LZ723meps= +github.com/ipfs/go-ds-badger v0.2.3/go.mod h1:pEYw0rgg3FIrywKKnL+Snr+w/LjJZVMTBRn4FS6UHUk= +github.com/ipfs/go-ds-badger v0.3.0/go.mod h1:1ke6mXNqeV8K3y5Ak2bAA0osoTfmxUdupVCGm4QUIek= +github.com/ipfs/go-ds-leveldb v0.4.2/go.mod h1:jpbku/YqBSsBc1qgME8BkWS4AxzF2cEu1Ii2r79Hh9s= +github.com/ipfs/go-ds-leveldb v0.5.0/go.mod h1:d3XG9RUDzQ6V4SHi8+Xgj9j1XuEk1z82lquxrVbml/Q= +github.com/ipfs/go-ipfs-delay v0.0.0-20181109222059-70721b86a9a8/go.mod h1:8SP1YXK1M1kXuc4KJZINY3TQQ03J2rwBG9QfXmbRPrw= +github.com/ipfs/go-ipfs-util v0.0.2/go.mod h1:CbPtkWJzjLdEcezDns2XYaehFVNXG9zrdrtMecczcsQ= +github.com/ipfs/go-log v0.0.1/go.mod h1:kL1d2/hzSpI0thNYjiKfjanbVNU+IIGA/WnNESY9leM= +github.com/ipfs/go-log v1.0.2/go.mod h1:1MNjMxe0u6xvJZgeqbJ8vdo2TKaGwZ1a0Bpza+sr2Sk= +github.com/ipfs/go-log v1.0.3/go.mod h1:OsLySYkwIbiSUR/yBTdv1qPtcE4FW3WPWk/ewz9Ru+A= +github.com/ipfs/go-log v1.0.4/go.mod h1:oDCg2FkjogeFOhqqb+N39l2RpTNPL6F/StPkB3kPgcs= +github.com/ipfs/go-log v1.0.5/go.mod h1:j0b8ZoR+7+R99LD9jZ6+AJsrzkPbSXbZfGakb5JPtIo= +github.com/ipfs/go-log/v2 v2.0.2/go.mod h1:O7P1lJt27vWHhOwQmcFEvlmo49ry2VY2+JfBWFaa9+0= +github.com/ipfs/go-log/v2 v2.0.3/go.mod h1:O7P1lJt27vWHhOwQmcFEvlmo49ry2VY2+JfBWFaa9+0= +github.com/ipfs/go-log/v2 v2.0.5/go.mod h1:eZs4Xt4ZUJQFM3DlanGhy7TkwwawCZcSByscwkWG+dw= +github.com/ipfs/go-log/v2 v2.1.1/go.mod h1:2v2nsGfZsvvAJz13SyFzf9ObaqwHiHxsPLEHntrv9KM= +github.com/ipfs/go-log/v2 v2.1.3/go.mod h1:/8d0SH3Su5Ooc31QlL1WysJhvyOTDCjcCZ9Axpmri6g= +github.com/ipfs/go-log/v2 v2.3.0/go.mod h1:QqGoj30OTpnKaG/LKTGTxoP2mmQtjVMEnK72gynbe/g= +github.com/ipfs/go-log/v2 v2.4.0/go.mod h1:nPZnh7Cj7lwS3LpRU5Mwr2ol1c2gXIEXuF6aywqrtmo= github.com/ipfs/go-log/v2 v2.5.1 h1:1XdUzF7048prq4aBjDQQ4SL5RxftpRGdXhNRwKSAlcY= github.com/ipfs/go-log/v2 v2.5.1/go.mod h1:prSpmC1Gpllc9UYWxDiZDreBYw7zp4Iqp1kOLU9U5UI= +github.com/jackpal/go-nat-pmp v1.0.2-0.20160603034137-1fa385a6f458/go.mod h1:QPH045xvCAeXUZOxsnwmrtiCoxIr9eob+4orBN1SBKc= github.com/jackpal/go-nat-pmp v1.0.2 h1:KzKSgb7qkJvOUTqYl9/Hg/me3pWgBmERKrTGD7BdWus= github.com/jackpal/go-nat-pmp v1.0.2/go.mod h1:QPH045xvCAeXUZOxsnwmrtiCoxIr9eob+4orBN1SBKc= +github.com/jbenet/go-cienv v0.1.0/go.mod h1:TqNnHUmJgXau0nCzC7kXWeotg3J9W34CUv5Djy1+FlA= +github.com/jbenet/go-temp-err-catcher v0.0.0-20150120210811-aac704a3f4f2/go.mod h1:8GXXJV31xl8whumTzdZsTt3RnUIiPqzkyf7mxToRCMs= github.com/jbenet/go-temp-err-catcher v0.1.0 h1:zpb3ZH6wIE8Shj2sKS+khgRvf7T7RABoLk/+KKHggpk= github.com/jbenet/go-temp-err-catcher v0.1.0/go.mod h1:0kJRvmDZXNMIiJirNPEYfhpPwbGVtZVWC34vc5WLsDk= +github.com/jbenet/goprocess v0.0.0-20160826012719-b497e2f366b8/go.mod h1:Ly/wlsjFq/qrU3Rar62tu1gASgGw6chQbSh/XgIIXCY= +github.com/jbenet/goprocess v0.1.3/go.mod h1:5yspPrukOVuOLORacaBi858NqyClJPQxYZlqdZVfqY4= +github.com/jbenet/goprocess v0.1.4/go.mod h1:5yspPrukOVuOLORacaBi858NqyClJPQxYZlqdZVfqY4= +github.com/jcmturner/gofork v1.0.0/go.mod h1:MK8+TM0La+2rjBD4jE12Kj1pCCxK7d2LK/UM3ncEo0o= +github.com/jedisct1/go-minisign v0.0.0-20190909160543-45766022959e/go.mod h1:G1CVv03EnqU1wYL2dFwXxW2An0az9JTl/ZsqXQeBlkU= github.com/jellevandenhooff/dkim v0.0.0-20150330215556-f50fe3d243e1/go.mod h1:E0B/fFc00Y+Rasa88328GlI/XbtyysCtTHZS8h7IrBU= github.com/jessevdk/go-flags v0.0.0-20141203071132-1679536dcc89/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI= github.com/jessevdk/go-flags v1.4.0/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI= github.com/jmespath/go-jmespath v0.0.0-20180206201540-c2b33e8439af/go.mod h1:Nht3zPeWKUH0NzdCt2Blrr5ys8VGpn0CEB0cQHVjt7k= +github.com/jmespath/go-jmespath v0.4.0/go.mod h1:T8mJZnbsbmF+m6zOOFylbeCJqk5+pHWvzYPziyZiYoo= +github.com/jmespath/go-jmespath/internal/testify v1.5.1/go.mod h1:L3OGu8Wl2/fWfCI6z80xFu9LTZmf1ZRjMHUOPmWr69U= +github.com/jmhodges/levigo v1.0.0 h1:q5EC36kV79HWeTBWsod3mG11EgStG3qArTKcvlksN1U= github.com/jonboulle/clockwork v0.1.0/go.mod h1:Ii8DK3G1RaLaWxj9trq07+26W01tbo22gdxWY5EU2bo= +github.com/joonix/log v0.0.0-20200409080653-9c1d2ceb5f1d/go.mod h1:fS54ONkjDV71zS9CDx3V9K21gJg7byKSvI4ajuWFNJw= +github.com/jpillora/backoff v1.0.0/go.mod h1:J/6gKK9jxlEcS3zixgDgUAsiuZ7yrSoa/FX5e0EB2j4= github.com/jrick/logrotate v1.0.0/go.mod h1:LNinyqDIJnpAur+b8yyulnQw/wDuN1+BYKlTRt3OuAQ= github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU= github.com/json-iterator/go v1.1.7/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= github.com/json-iterator/go v1.1.8/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= github.com/json-iterator/go v1.1.9/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= +github.com/json-iterator/go v1.1.10/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= +github.com/json-iterator/go v1.1.11/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM= github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo= github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU= +github.com/jstemmer/go-junit-report v0.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/XSXhF0NWZEnDohbsk= +github.com/jsternberg/zap-logfmt v1.0.0/go.mod h1:uvPs/4X51zdkcm5jXl5SYoN+4RK21K8mysFmDaM/h+o= github.com/jtolds/gls v4.2.1+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU= github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU= +github.com/juju/ansiterm v0.0.0-20180109212912-720a0952cc2a/go.mod h1:UJSiEoRfvx3hP73CvoARgeLjaIOjybY9vj8PUPPFGeU= github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w= github.com/julienschmidt/httprouter v1.3.0 h1:U0609e9tgbseu3rBINet9P48AI/D3oJs4dN7jwJOQ1U= github.com/julienschmidt/httprouter v1.3.0/go.mod h1:JR6WtHb+2LUe8TCKY3cZOxFyyO8IZAc4RVcycCCAKdM= +github.com/jung-kurt/gofpdf v1.0.3-0.20190309125859-24315acbbda5/go.mod h1:7Id9E/uU8ce6rXgefFLlgrJj/GYY22cpxn+r32jIOes= +github.com/jwilder/encoding v0.0.0-20170811194829-b4e1701a28ef/go.mod h1:Ct9fl0F6iIOGgxJ5npU/IUOhOhqlVrGjyIZc8/MagT0= +github.com/k0kubun/go-ansi v0.0.0-20180517002512-3bf9e2903213/go.mod h1:vNUNkEQ1e29fT/6vq2aBdFsgNPmy8qMdSay1npru+Sw= +github.com/kami-zh/go-capturer v0.0.0-20171211120116-e492ea43421d/go.mod h1:P2viExyCEfeWGU259JnaQ34Inuec4R38JCyBx2edgD0= +github.com/karalabe/usb v0.0.0-20211005121534-4c5740d64559/go.mod h1:Od972xHfMJowv7NGVDiWVxk2zxnWgjLlJzE+F4F7AGU= github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51 h1:Z9n2FFNUXsshfwJMBgNA0RU6/i7WVaAegv3PtuIHPMs= github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51/go.mod h1:CzGEWj7cYgsdH8dAjBGEr58BoE7ScuLd+fwFZ44+/x8= github.com/kevinburke/go-bindata v3.21.0+incompatible h1:baK7hwFJDlAHrOqmE9U3u8tow1Uc5ihN9E/b7djcK2g= github.com/kevinburke/go-bindata v3.21.0+incompatible/go.mod h1:/pEEZ72flUW2p0yi30bslSp9YqD9pysLxunQDdb2CPM= +github.com/kevinms/leakybucket-go v0.0.0-20200115003610-082473db97ca/go.mod h1:ph+C5vpnCcQvKBwJwKLTK3JLNGnBXYlG7m7JjoC/zYA= github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvWXihfKN4Q= github.com/kisielk/errcheck v1.2.0/go.mod h1:/BMXB+zMLi60iA8Vv6Ksmxu/1UDYcXs4uQLJ+jE2L00= github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8= github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= github.com/kkdai/bstream v0.0.0-20161212061736-f391b8402d23/go.mod h1:J+Gs4SYgM6CZQHDETBtE9HaSEkGmuNXF86RwHhHUvq4= +github.com/klauspost/compress v1.4.0/go.mod h1:RyIbtBH6LamlWaDj8nUwkbUhJ87Yi3uG0guNDohfE1A= +github.com/klauspost/compress v1.9.8/go.mod h1:RyIbtBH6LamlWaDj8nUwkbUhJ87Yi3uG0guNDohfE1A= +github.com/klauspost/compress v1.10.1/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs= github.com/klauspost/compress v1.10.3/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs= +github.com/klauspost/compress v1.11.7/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs= github.com/klauspost/compress v1.15.15 h1:EF27CXIuDsYJ6mmvtBRlEuB2UVOqHG1tAXgZ7yIO+lw= github.com/klauspost/compress v1.15.15/go.mod h1:ZcK2JAFqKOpnBlxcLsJzYfrS9X1akm9fHZNnD9+Vo/4= +github.com/klauspost/cpuid v0.0.0-20170728055534-ae7887de9fa5/go.mod h1:Pj4uuM528wm8OyEC2QMXAi2YiTZ96dNQPGgoMS4s3ek= +github.com/klauspost/cpuid v1.2.3/go.mod h1:Pj4uuM528wm8OyEC2QMXAi2YiTZ96dNQPGgoMS4s3ek= github.com/klauspost/cpuid/v2 v2.0.4/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg= github.com/klauspost/cpuid/v2 v2.0.9/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg= github.com/klauspost/cpuid/v2 v2.2.3 h1:sxCkb+qR91z4vsqw4vGGZlDgPz3G7gjaLyK3V8y70BU= github.com/klauspost/cpuid/v2 v2.2.3/go.mod h1:RVVoqg1df56z8g3pUjL/3lE5UfnlrJX8tyFgg4nqhuY= +github.com/klauspost/crc32 v0.0.0-20161016154125-cb6bfca970f6/go.mod h1:+ZoRqAPRLkC4NPOvfYeR5KNOrY6TD+/sAC3HXPZgDYg= +github.com/klauspost/pgzip v1.0.2-0.20170402124221-0bf5dcad4ada/go.mod h1:Ch1tH69qFZu15pkjo5kYi6mth2Zzwzt50oCQKQE9RUs= +github.com/klauspost/reedsolomon v1.9.3/go.mod h1:CwCi+NUr9pqSVktrkN+Ondf06rkhYZ/pcNv7fu+8Un4= github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= +github.com/konsorten/go-windows-terminal-sequences v1.0.2/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= +github.com/konsorten/go-windows-terminal-sequences v1.0.3/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= github.com/koron/go-ssdp v0.0.0-20191105050749-2e1c40ed0b5d/go.mod h1:5Ky9EC2xfoUKUor0Hjgi2BJhCSXJfMOFlmyYrVKGQMk= +github.com/koron/go-ssdp v0.0.2/go.mod h1:XoLfkAiA2KeZsYh4DbHxD7h3nR2AZNqVQOa+LJuqPYs= github.com/koron/go-ssdp v0.0.3 h1:JivLMY45N76b4p/vsWGOKewBQu6uf39y8l+AQ7sDKx8= github.com/koron/go-ssdp v0.0.3/go.mod h1:b2MxI6yh02pKrsyNoQUsk4+YNikaGhe4894J+Q5lDvA= github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc= @@ -514,11 +872,12 @@ github.com/kr/pty v1.1.3/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= -github.com/kylelemons/godebug v0.0.0-20170224010052-a616ab194758 h1:0D5M2HQSGD3PYPwICLl+/9oulQauOuETfgFvhBDffs0= +github.com/kylelemons/godebug v1.1.0 h1:RPNrshWIDI6G2gRW9EHilWtl7Z6Sb1BR0xunSBf0SNc= +github.com/kylelemons/godebug v1.1.0/go.mod h1:9/0rRGxNHcop5bhtWyNeEfOS8JIWk580+fNqagV/RAw= +github.com/labstack/echo/v4 v4.2.1/go.mod h1:AA49e0DZ8kk5jTOOCKNuPR6oTnBS0dYiM4FW1e6jwpg= +github.com/labstack/gommon v0.3.0/go.mod h1:MULnywXg0yavhxWKc+lOruYdAhDwPK9wf0OL7NoOu+k= github.com/leanovate/gopter v0.2.9 h1:fQjYxZaynp97ozCzfOyOuAGOU4aU/z37zf/tOujFk7c= github.com/leanovate/gopter v0.2.9/go.mod h1:U2L/78B+KVFIx2VmW6onHJQzXtFb+p5y3y2Sh+Jxxv8= -github.com/ledgerwatch/erigon-lib v0.0.0-20230305180029-3d69e5177fc4 h1:ZTYSqbza9J+Nuc/XdJJlzSWapol0/8GE1aiHuHLpnrA= -github.com/ledgerwatch/erigon-lib v0.0.0-20230305180029-3d69e5177fc4/go.mod h1:xcrJLJiNfthKFectsWBUtRJK9d6XtjiyQRGVeImRYRs= github.com/ledgerwatch/erigon-snapshot v1.1.1-0.20230306083105-1391330d62a3 h1:tfzawK1gIIgRjVZeANXOr0Ziu+kqCIBuKMe0TXfl5Aw= github.com/ledgerwatch/erigon-snapshot v1.1.1-0.20230306083105-1391330d62a3/go.mod h1:3AuPxZc85jkehh/HA9h8gabv5MSi3kb/ddtzBsTVJFo= github.com/ledgerwatch/log/v3 v3.7.0 h1:aFPEZdwZx4jzA3+/Pf8wNDN5tCI0cIolq/kfvgcM+og= @@ -527,68 +886,207 @@ github.com/ledgerwatch/secp256k1 v1.0.0 h1:Usvz87YoTG0uePIV8woOof5cQnLXGYa162rFf github.com/ledgerwatch/secp256k1 v1.0.0/go.mod h1:SPmqJFciiF/Q0mPt2jVs2dTr/1TZBTIA+kPMmKgBAak= github.com/ledgerwatch/trackerslist v1.1.0 h1:eKhgeURD9x/J3qzMnL6C0e0cLy6Ld7Ck/VR/yF+7cZQ= github.com/ledgerwatch/trackerslist v1.1.0/go.mod h1:wWU/V810cpsEl//o49ebwAWf0BL0WOJiu/577L4IVok= -github.com/leodido/go-urn v1.2.0 h1:hpXL4XnriNwQ/ABnpepYM/1vCLWNDfUNts8dX3xTG6Y= github.com/leodido/go-urn v1.2.0/go.mod h1:+8+nEpDfqqsY+g338gtMEUOtuK+4dEMhiQEgxpxOKII= +github.com/leodido/go-urn v1.2.1 h1:BqpAaACuzVSgi/VLzGZIobT2z4v53pjosyNd9Yv6n/w= +github.com/lib/pq v1.0.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo= +github.com/lib/pq v1.10.7 h1:p7ZhMD+KsSRozJr34udlUrhboJwWAgCg34+/ZZNvZZw= +github.com/libp2p/go-addr-util v0.0.2/go.mod h1:Ecd6Fb3yIuLzq4bD7VcywcVSBtefcAwnUISBM3WG15E= +github.com/libp2p/go-addr-util v0.1.0/go.mod h1:6I3ZYuFr2O/9D+SoyM0zEw0EF3YkldtTX406BpdQMqw= +github.com/libp2p/go-buffer-pool v0.0.1/go.mod h1:xtyIz9PMobb13WaxR6Zo1Pd1zXJKYg0a8KiIvDp3TzQ= +github.com/libp2p/go-buffer-pool v0.0.2/go.mod h1:MvaB6xw5vOrDl8rYZGLFdKAuk/hRoRZd1Vi32+RXyFM= github.com/libp2p/go-buffer-pool v0.1.0 h1:oK4mSFcQz7cTQIfqbe4MIj9gLW+mnanjyFtc6cdF0Y8= github.com/libp2p/go-buffer-pool v0.1.0/go.mod h1:N+vh8gMqimBzdKkSMVuydVDq+UV5QTWy5HSiZacSbPg= github.com/libp2p/go-cidranger v1.1.0 h1:ewPN8EZ0dd1LSnrtuwd4709PXVcITVeuwbag38yPW7c= github.com/libp2p/go-cidranger v1.1.0/go.mod h1:KWZTfSr+r9qEo9OkI9/SIEeAtw+NNoU0dXIXt15Okic= +github.com/libp2p/go-conn-security-multistream v0.2.0/go.mod h1:hZN4MjlNetKD3Rq5Jb/P5ohUnFLNzEAR4DLSzpn2QLU= +github.com/libp2p/go-conn-security-multistream v0.2.1/go.mod h1:cR1d8gA0Hr59Fj6NhaTpFhJZrjSYuNmhpT2r25zYR70= +github.com/libp2p/go-conn-security-multistream v0.3.0/go.mod h1:EEP47t4fw/bTelVmEzIDqSe69hO/ip52xBEhZMLWAHM= +github.com/libp2p/go-eventbus v0.2.1/go.mod h1:jc2S4SoEVPP48H9Wpzm5aiGwUCBMfGhVhhBjyhhCJs8= +github.com/libp2p/go-flow-metrics v0.0.1/go.mod h1:Iv1GH0sG8DtYN3SVJ2eG221wMiNpZxBdp967ls1g+k8= +github.com/libp2p/go-flow-metrics v0.0.3/go.mod h1:HeoSNUrOJVK1jEpDqVEiUOIXqhbnS27omG0uWU5slZs= github.com/libp2p/go-flow-metrics v0.1.0 h1:0iPhMI8PskQwzh57jB9WxIuIOQ0r+15PChFGkx3Q3WM= github.com/libp2p/go-flow-metrics v0.1.0/go.mod h1:4Xi8MX8wj5aWNDAZttg6UPmc0ZrnFNsMtpsYUClFtro= -github.com/libp2p/go-libp2p v0.25.1 h1:YK+YDCHpYyTvitKWVxa5PfElgIpOONU01X5UcLEwJGA= -github.com/libp2p/go-libp2p v0.25.1/go.mod h1:xnK9/1d9+jeQCVvi/f1g12KqtVi/jP/SijtKV1hML3g= +github.com/libp2p/go-libp2p v0.17.0/go.mod h1:Fkin50rsGdv5mm5BshBUtPRZknt9esfmYXBOYcwOTgw= +github.com/libp2p/go-libp2p v0.26.2 h1:eHEoW/696FP7/6DxOvcrKfTD6Bi0DExxiMSZUJxswA0= +github.com/libp2p/go-libp2p v0.26.2/go.mod h1:x75BN32YbwuY0Awm2Uix4d4KOz+/4piInkp4Wr3yOo8= +github.com/libp2p/go-libp2p-asn-util v0.1.0/go.mod h1:wu+AnM9Ii2KgO5jMmS1rz9dvzTdj8BXqsPR9HR0XB7I= github.com/libp2p/go-libp2p-asn-util v0.2.0 h1:rg3+Os8jbnO5DxkC7K/Utdi+DkY3q/d1/1q+8WeNAsw= github.com/libp2p/go-libp2p-asn-util v0.2.0/go.mod h1:WoaWxbHKBymSN41hWSq/lGKJEca7TNm58+gGJi2WsLI= -github.com/libp2p/go-libp2p-pubsub v0.9.1-0.20230221111042-3dbc2fd5baca h1:oZfjXSBxZqteGMAcyaX+3wVQqM8k0f5r/Pi9BDU8058= -github.com/libp2p/go-libp2p-pubsub v0.9.1-0.20230221111042-3dbc2fd5baca/go.mod h1:RYA7aM9jIic5VV47WXu4GkcRxRhrdElWf8xtyli+Dzc= +github.com/libp2p/go-libp2p-autonat v0.7.0/go.mod h1:uPvPn6J7cN+LCfFwW5tpOYvAz5NvPTc4iBamTV/WDMg= +github.com/libp2p/go-libp2p-blankhost v0.2.0/go.mod h1:eduNKXGTioTuQAUcZ5epXi9vMl+t4d8ugUBRQ4SqaNQ= +github.com/libp2p/go-libp2p-blankhost v0.3.0/go.mod h1:urPC+7U01nCGgJ3ZsV8jdwTp6Ji9ID0dMTvq+aJ+nZU= +github.com/libp2p/go-libp2p-circuit v0.4.0/go.mod h1:t/ktoFIUzM6uLQ+o1G6NuBl2ANhBKN9Bc8jRIk31MoA= +github.com/libp2p/go-libp2p-connmgr v0.2.4/go.mod h1:YV0b/RIm8NGPnnNWM7hG9Q38OeQiQfKhHCCs1++ufn0= +github.com/libp2p/go-libp2p-core v0.0.1/go.mod h1:g/VxnTZ/1ygHxH3dKok7Vno1VfpvGcGip57wjTU4fco= +github.com/libp2p/go-libp2p-core v0.2.0/go.mod h1:X0eyB0Gy93v0DZtSYbEM7RnMChm9Uv3j7yRXjO77xSI= +github.com/libp2p/go-libp2p-core v0.3.0/go.mod h1:ACp3DmS3/N64c2jDzcV429ukDpicbL6+TrrxANBjPGw= +github.com/libp2p/go-libp2p-core v0.3.1/go.mod h1:thvWy0hvaSBhnVBaW37BvzgVV68OUhgJJLAa6almrII= +github.com/libp2p/go-libp2p-core v0.5.0/go.mod h1:49XGI+kc38oGVwqSBhDEwytaAxgZasHhFfQKibzTls0= +github.com/libp2p/go-libp2p-core v0.5.1/go.mod h1:uN7L2D4EvPCvzSH5SrhR72UWbnSGpt5/a35Sm4upn4Y= +github.com/libp2p/go-libp2p-core v0.5.4/go.mod h1:uN7L2D4EvPCvzSH5SrhR72UWbnSGpt5/a35Sm4upn4Y= +github.com/libp2p/go-libp2p-core v0.5.5/go.mod h1:vj3awlOr9+GMZJFH9s4mpt9RHHgGqeHCopzbYKZdRjM= +github.com/libp2p/go-libp2p-core v0.5.7/go.mod h1:txwbVEhHEXikXn9gfC7/UDDw7rkxuX0bJvM49Ykaswo= +github.com/libp2p/go-libp2p-core v0.6.0/go.mod h1:txwbVEhHEXikXn9gfC7/UDDw7rkxuX0bJvM49Ykaswo= +github.com/libp2p/go-libp2p-core v0.7.0/go.mod h1:FfewUH/YpvWbEB+ZY9AQRQ4TAD8sJBt/G1rVvhz5XT8= +github.com/libp2p/go-libp2p-core v0.8.0/go.mod h1:FfewUH/YpvWbEB+ZY9AQRQ4TAD8sJBt/G1rVvhz5XT8= +github.com/libp2p/go-libp2p-core v0.8.1/go.mod h1:FfewUH/YpvWbEB+ZY9AQRQ4TAD8sJBt/G1rVvhz5XT8= +github.com/libp2p/go-libp2p-core v0.8.2/go.mod h1:FfewUH/YpvWbEB+ZY9AQRQ4TAD8sJBt/G1rVvhz5XT8= +github.com/libp2p/go-libp2p-core v0.8.6/go.mod h1:dgHr0l0hIKfWpGpqAMbpo19pen9wJfdCGv51mTmdpmM= +github.com/libp2p/go-libp2p-core v0.9.0/go.mod h1:ESsbz31oC3C1AvMJoGx26RTuCkNhmkSRCqZ0kQtJ2/8= +github.com/libp2p/go-libp2p-core v0.10.0/go.mod h1:ECdxehoYosLYHgDDFa2N4yE8Y7aQRAMf0sX9mf2sbGg= +github.com/libp2p/go-libp2p-core v0.11.0/go.mod h1:ECdxehoYosLYHgDDFa2N4yE8Y7aQRAMf0sX9mf2sbGg= +github.com/libp2p/go-libp2p-core v0.12.0/go.mod h1:ECdxehoYosLYHgDDFa2N4yE8Y7aQRAMf0sX9mf2sbGg= +github.com/libp2p/go-libp2p-core v0.13.0/go.mod h1:ECdxehoYosLYHgDDFa2N4yE8Y7aQRAMf0sX9mf2sbGg= +github.com/libp2p/go-libp2p-discovery v0.6.0/go.mod h1:/u1voHt0tKIe5oIA1RHBKQLVCWPna2dXmPNHc2zR9S8= +github.com/libp2p/go-libp2p-loggables v0.1.0/go.mod h1:EyumB2Y6PrYjr55Q3/tiJ/o3xoDasoRYM7nOzEpoa90= +github.com/libp2p/go-libp2p-mplex v0.2.1/go.mod h1:SC99Rxs8Vuzrf/6WhmH41kNn13TiYdAWNYHrwImKLnE= +github.com/libp2p/go-libp2p-mplex v0.2.3/go.mod h1:CK3p2+9qH9x+7ER/gWWDYJ3QW5ZxWDkm+dVvjfuG3ek= +github.com/libp2p/go-libp2p-mplex v0.4.1/go.mod h1:cmy+3GfqfM1PceHTLL7zQzAAYaryDu6iPSC+CIb094g= +github.com/libp2p/go-libp2p-nat v0.1.0/go.mod h1:DQzAG+QbDYjN1/C3B6vXucLtz3u9rEonLVPtZVzQqks= +github.com/libp2p/go-libp2p-netutil v0.1.0/go.mod h1:3Qv/aDqtMLTUyQeundkKsA+YCThNdbQD54k3TqjpbFU= +github.com/libp2p/go-libp2p-noise v0.3.0/go.mod h1:JNjHbociDJKHD64KTkzGnzqJ0FEV5gHJa6AB00kbCNQ= +github.com/libp2p/go-libp2p-peerstore v0.2.6/go.mod h1:ss/TWTgHZTMpsU/oKVVPQCGuDHItOpf2W8RxAi50P2s= +github.com/libp2p/go-libp2p-peerstore v0.4.0/go.mod h1:rDJUFyzEWPpXpEwywkcTYYzDHlwza8riYMaUzaN6hX0= +github.com/libp2p/go-libp2p-peerstore v0.6.0/go.mod h1:DGEmKdXrcYpK9Jha3sS7MhqYdInxJy84bIPtSu65bKc= +github.com/libp2p/go-libp2p-pnet v0.2.0/go.mod h1:Qqvq6JH/oMZGwqs3N1Fqhv8NVhrdYcO0BW4wssv21LA= +github.com/libp2p/go-libp2p-pubsub v0.6.1/go.mod h1:nJv87QM2cU0w45KPR1rZicq+FmFIOD16zmT+ep1nOmg= +github.com/libp2p/go-libp2p-pubsub v0.9.3 h1:ihcz9oIBMaCK9kcx+yHWm3mLAFBMAUsM4ux42aikDxo= +github.com/libp2p/go-libp2p-pubsub v0.9.3/go.mod h1:RYA7aM9jIic5VV47WXu4GkcRxRhrdElWf8xtyli+Dzc= +github.com/libp2p/go-libp2p-quic-transport v0.13.0/go.mod h1:39/ZWJ1TW/jx1iFkKzzUg00W6tDJh73FC0xYudjr7Hc= +github.com/libp2p/go-libp2p-quic-transport v0.15.2/go.mod h1:wv4uGwjcqe8Mhjj7N/Ic0aKjA+/10UnMlSzLO0yRpYQ= +github.com/libp2p/go-libp2p-swarm v0.3.0/go.mod h1:hdv95GWCTmzkgeJpP+GK/9D9puJegb7H57B5hWQR5Kk= +github.com/libp2p/go-libp2p-swarm v0.8.0/go.mod h1:sOMp6dPuqco0r0GHTzfVheVBh6UEL0L1lXUZ5ot2Fvc= +github.com/libp2p/go-libp2p-swarm v0.9.0/go.mod h1:2f8d8uxTJmpeqHF/1ujjdXZp+98nNIbujVOMEZxCbZ8= +github.com/libp2p/go-libp2p-testing v0.0.3/go.mod h1:gvchhf3FQOtBdr+eFUABet5a4MBLK8jM3V4Zghvmi+E= +github.com/libp2p/go-libp2p-testing v0.1.1/go.mod h1:xaZWMJrPUM5GlDBxCeGUi7kI4eqnjVyavGroI2nxEM0= +github.com/libp2p/go-libp2p-testing v0.1.2-0.20200422005655-8775583591d8/go.mod h1:Qy8sAncLKpwXtS2dSnDOP8ktexIAHKu+J+pnZOFZLTc= +github.com/libp2p/go-libp2p-testing v0.3.0/go.mod h1:efZkql4UZ7OVsEfaxNHZPzIehtsBXMrXnCfJIgDti5g= +github.com/libp2p/go-libp2p-testing v0.4.0/go.mod h1:Q+PFXYoiYFN5CAEG2w3gLPEzotlKsNSbKQ/lImlOWF0= +github.com/libp2p/go-libp2p-testing v0.4.2/go.mod h1:Q+PFXYoiYFN5CAEG2w3gLPEzotlKsNSbKQ/lImlOWF0= +github.com/libp2p/go-libp2p-testing v0.5.0/go.mod h1:QBk8fqIL1XNcno/l3/hhaIEn4aLRijpYOR+zVjjlh+A= +github.com/libp2p/go-libp2p-testing v0.6.0/go.mod h1:QBk8fqIL1XNcno/l3/hhaIEn4aLRijpYOR+zVjjlh+A= github.com/libp2p/go-libp2p-testing v0.12.0 h1:EPvBb4kKMWO29qP4mZGyhVzUyR25dvfUIK5WDu6iPUA= +github.com/libp2p/go-libp2p-tls v0.3.0/go.mod h1:fwF5X6PWGxm6IDRwF3V8AVCCj/hOd5oFlg+wo2FxJDY= +github.com/libp2p/go-libp2p-tls v0.3.1/go.mod h1:fwF5X6PWGxm6IDRwF3V8AVCCj/hOd5oFlg+wo2FxJDY= +github.com/libp2p/go-libp2p-transport-upgrader v0.2.0/go.mod h1:mQcrHj4asu6ArfSoMuyojOdjx73Q47cYD7s5+gZOlns= +github.com/libp2p/go-libp2p-transport-upgrader v0.3.0/go.mod h1:i+SKzbRnvXdVbU3D1dwydnTmKRPXiAR/fyvi1dXuL4o= +github.com/libp2p/go-libp2p-transport-upgrader v0.4.3/go.mod h1:bpkldbOWXMrXhpZbSV1mQxTrefOg2Fi+k1ClDSA4ppw= +github.com/libp2p/go-libp2p-transport-upgrader v0.5.0/go.mod h1:Rc+XODlB3yce7dvFV4q/RmyJGsFcCZRkeZMu/Zdg0mo= +github.com/libp2p/go-libp2p-transport-upgrader v0.6.0/go.mod h1:1e07y1ZSZdHo9HPbuU8IztM1Cj+DR5twgycb4pnRzRo= +github.com/libp2p/go-libp2p-yamux v0.4.0/go.mod h1:+DWDjtFMzoAwYLVkNZftoucn7PelNoy5nm3tZ3/Zw30= +github.com/libp2p/go-libp2p-yamux v0.5.0/go.mod h1:AyR8k5EzyM2QN9Bbdg6X1SkVVuqLwTGf0L4DFq9g6po= +github.com/libp2p/go-libp2p-yamux v0.7.0/go.mod h1:fMyA0CsPfHkIuBU0wjRGrCjTBFiXTXxG0k5M4ETv+08= +github.com/libp2p/go-maddr-filter v0.0.5/go.mod h1:Jk+36PMfIqCJhAnaASRH83bdAvfDRp/w6ENFaC9bG+M= +github.com/libp2p/go-maddr-filter v0.1.0/go.mod h1:VzZhTXkMucEGGEOSKddrwGiOv0tUhgnKqNEmIAz/bPU= +github.com/libp2p/go-mplex v0.1.0/go.mod h1:SXgmdki2kwCUlCCbfGLEgHjC4pFqhTp0ZoV6aiKgxDU= +github.com/libp2p/go-mplex v0.1.2/go.mod h1:Xgz2RDCi3co0LeZfgjm4OgUF15+sVR8SRcu3SFXI1lk= +github.com/libp2p/go-mplex v0.3.0/go.mod h1:0Oy/A9PQlwBytDRp4wSkFnzHYDKcpLot35JQ6msjvYQ= github.com/libp2p/go-mplex v0.7.0 h1:BDhFZdlk5tbr0oyFq/xv/NPGfjbnrsDam1EvutpBDbY= github.com/libp2p/go-mplex v0.7.0/go.mod h1:rW8ThnRcYWft/Jb2jeORBmPd6xuG3dGxWN/W168L9EU= +github.com/libp2p/go-msgio v0.0.4/go.mod h1:63lBBgOTDKQL6EWazRMCwXsEeEeK9O2Cd+0+6OOuipQ= +github.com/libp2p/go-msgio v0.0.6/go.mod h1:4ecVB6d9f4BDSL5fqvPiC4A3KivjWn+Venn/1ALLMWA= +github.com/libp2p/go-msgio v0.1.0/go.mod h1:eNlv2vy9V2X/kNldcZ+SShFE++o2Yjxwx6RAYsmgJnE= github.com/libp2p/go-msgio v0.3.0 h1:mf3Z8B1xcFN314sWX+2vOTShIE0Mmn2TXn3YCUQGNj0= github.com/libp2p/go-msgio v0.3.0/go.mod h1:nyRM819GmVaF9LX3l03RMh10QdOroF++NBbxAb0mmDM= github.com/libp2p/go-nat v0.1.0 h1:MfVsH6DLcpa04Xr+p8hmVRG4juse0s3J8HyNWYHffXg= github.com/libp2p/go-nat v0.1.0/go.mod h1:X7teVkwRHNInVNWQiO/tAiAVRwSr5zoRz4YSTC3uRBM= github.com/libp2p/go-netroute v0.1.2/go.mod h1:jZLDV+1PE8y5XxBySEBgbuVAXbhtuHSdmLPL2n9MKbk= +github.com/libp2p/go-netroute v0.1.3/go.mod h1:jZLDV+1PE8y5XxBySEBgbuVAXbhtuHSdmLPL2n9MKbk= +github.com/libp2p/go-netroute v0.1.5/go.mod h1:V1SR3AaECRkEQCoFFzYwVYWvYIEtlxx89+O3qcpCl4A= +github.com/libp2p/go-netroute v0.1.6/go.mod h1:AqhkMh0VuWmfgtxKPp3Oc1LdU5QSWS7wl0QLhSZqXxQ= github.com/libp2p/go-netroute v0.2.1 h1:V8kVrpD8GK0Riv15/7VN6RbUQ3URNZVosw7H2v9tksU= github.com/libp2p/go-netroute v0.2.1/go.mod h1:hraioZr0fhBjG0ZRXJJ6Zj2IVEVNx6tDTFQfSmcq7mQ= +github.com/libp2p/go-openssl v0.0.4/go.mod h1:unDrJpgy3oFr+rqXsarWifmJuNnJR4chtO1HmaZjggc= +github.com/libp2p/go-openssl v0.0.5/go.mod h1:unDrJpgy3oFr+rqXsarWifmJuNnJR4chtO1HmaZjggc= +github.com/libp2p/go-openssl v0.0.7/go.mod h1:unDrJpgy3oFr+rqXsarWifmJuNnJR4chtO1HmaZjggc= +github.com/libp2p/go-reuseport v0.0.1/go.mod h1:jn6RmB1ufnQwl0Q1f+YxAj8isJgDCQzaaxIFYDhcYEA= +github.com/libp2p/go-reuseport v0.1.0/go.mod h1:bQVn9hmfcTaoo0c9v5pBhOarsU1eNOBZdaAd2hzXRKU= github.com/libp2p/go-reuseport v0.2.0 h1:18PRvIMlpY6ZK85nIAicSBuXXvrYoSw3dsBAR7zc560= github.com/libp2p/go-reuseport v0.2.0/go.mod h1:bvVho6eLMm6Bz5hmU0LYN3ixd3nPPvtIlaURZZgOY4k= +github.com/libp2p/go-reuseport-transport v0.0.3/go.mod h1:Spv+MPft1exxARzP2Sruj2Wb5JSyHNncjf1Oi2dEbzM= +github.com/libp2p/go-reuseport-transport v0.1.0/go.mod h1:vev0C0uMkzriDY59yFHD9v+ujJvYmDQVLowvAjEOmfw= github.com/libp2p/go-sockaddr v0.0.2/go.mod h1:syPvOmNs24S3dFVGJA1/mrqdeijPxLV2Le3BRLKd68k= +github.com/libp2p/go-sockaddr v0.1.0/go.mod h1:syPvOmNs24S3dFVGJA1/mrqdeijPxLV2Le3BRLKd68k= +github.com/libp2p/go-sockaddr v0.1.1/go.mod h1:syPvOmNs24S3dFVGJA1/mrqdeijPxLV2Le3BRLKd68k= +github.com/libp2p/go-stream-muxer-multistream v0.3.0/go.mod h1:yDh8abSIzmZtqtOt64gFJUXEryejzNb0lisTt+fAMJA= +github.com/libp2p/go-tcp-transport v0.2.0/go.mod h1:vX2U0CnWimU4h0SGSEsg++AzvBcroCGYw28kh94oLe0= +github.com/libp2p/go-tcp-transport v0.4.0/go.mod h1:0y52Rwrn4076xdJYu/51/qJIdxz+EWDAOG2S45sV3VI= +github.com/libp2p/go-ws-transport v0.5.0/go.mod h1:I2juo1dNTbl8BKSBYo98XY85kU2xds1iamArLvl8kNg= +github.com/libp2p/go-yamux v1.4.0/go.mod h1:fr7aVgmdNGJK+N1g+b6DW6VxzbRCjCOejR/hkmpooHE= +github.com/libp2p/go-yamux v1.4.1/go.mod h1:fr7aVgmdNGJK+N1g+b6DW6VxzbRCjCOejR/hkmpooHE= +github.com/libp2p/go-yamux/v2 v2.3.0/go.mod h1:iTU+lOIn/2h0AgKcL49clNTwfEw+WSfDYrXe05EyKIs= github.com/libp2p/go-yamux/v4 v4.0.0 h1:+Y80dV2Yx/kv7Y7JKu0LECyVdMXm1VUoko+VQ9rBfZQ= github.com/libp2p/go-yamux/v4 v4.0.0/go.mod h1:NWjl8ZTLOGlozrXSOZ/HlfG++39iKNnM5wwmtQP1YB4= +github.com/libp2p/zeroconf/v2 v2.1.1/go.mod h1:fuJqLnUwZTshS3U/bMRJ3+ow/v9oid1n0DmyYyNO1Xs= github.com/lightstep/lightstep-tracer-common/golang/gogo v0.0.0-20190605223551-bc2310a04743/go.mod h1:qklhhLq1aX+mtWk9cPHPzaBjWImj5ULL6C7HFJtXQMM= github.com/lightstep/lightstep-tracer-go v0.18.1/go.mod h1:jlF1pusYV4pidLvZ+XD0UBX0ZE6WURAspgAczcDHrL4= github.com/lispad/go-generics-tools v1.1.0 h1:mbSgcxdFVmpoyso1X/MJHXbSbSL3dD+qhRryyxk+/XY= github.com/lispad/go-generics-tools v1.1.0/go.mod h1:2csd1EJljo/gy5qG4khXol7ivCPptNjG5Uv2X8MgK84= +github.com/logrusorgru/aurora v2.0.3+incompatible/go.mod h1:7rIyQOR62GCctdiQpZ/zOJlFyk6y+94wXzv6RNZgaR4= +github.com/lucas-clemente/quic-go v0.23.0/go.mod h1:paZuzjXCE5mj6sikVLMvqXk8lJV2AsqtJ6bDhjEfxx0= +github.com/lucas-clemente/quic-go v0.24.0/go.mod h1:paZuzjXCE5mj6sikVLMvqXk8lJV2AsqtJ6bDhjEfxx0= +github.com/lufia/plan9stats v0.0.0-20211012122336-39d0f177ccd0 h1:6E+4a0GO5zZEnZ81pIr0yLvtUWk2if982qA3F3QD6H4= +github.com/lufia/plan9stats v0.0.0-20211012122336-39d0f177ccd0/go.mod h1:zJYVVT2jmtg6P3p1VtQj7WsuWi/y4VnjVBn7F8KPB3I= +github.com/lunixbochs/vtclean v0.0.0-20180621232353-2d01aacdc34a/go.mod h1:pHhQNgMf3btfWnGBVipUOjRYhoOsdGqdm/+2c2E2WMI= github.com/lunixbochs/vtclean v1.0.0/go.mod h1:pHhQNgMf3btfWnGBVipUOjRYhoOsdGqdm/+2c2E2WMI= github.com/lyft/protoc-gen-validate v0.0.13/go.mod h1:XbGvPuh87YZc5TdIa2/I4pLk0QoUACkjt2znoq26NVQ= -github.com/magiconair/properties v1.8.6 h1:5ibWZ6iY0NctNGWo87LalDlEZ6R41TqbbDamhfG/Qzo= -github.com/magiconair/properties v1.8.6/go.mod h1:y3VJvCyxH9uVvJTWEGAELF3aiYNyPKd5NZ3oSwXrF60= +github.com/magiconair/properties v1.7.4-0.20170902060319-8d7837e64d3c/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ= +github.com/magiconair/properties v1.8.0/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ= +github.com/mailru/easyjson v0.0.0-20160728113105-d5b7844b561a/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= +github.com/mailru/easyjson v0.0.0-20180823135443-60711f1a8329/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= github.com/mailru/easyjson v0.0.0-20190312143242-1de009706dbe/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= +github.com/mailru/easyjson v0.0.0-20190614124828-94de47d64c63/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= +github.com/mailru/easyjson v0.0.0-20190626092158-b2ccc519800e/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= +github.com/manifoldco/promptui v0.7.0/go.mod h1:n4zTdgP0vr0S3w7/O/g98U+e0gwLScEXGwov2nIKuGQ= +github.com/marten-seemann/qpack v0.2.1/go.mod h1:F7Gl5L1jIgN1D11ucXefiuJS9UMVP2opoCp2jDKb7wc= +github.com/marten-seemann/qtls-go1-15 v0.1.4/go.mod h1:GyFwywLKkRt+6mfU99csTEY1joMZz5vmB1WNZH3P81I= +github.com/marten-seemann/qtls-go1-16 v0.1.4/go.mod h1:gNpI2Ol+lRS3WwSOtIUUtRwZEQMXjYK+dQSBFbethAk= +github.com/marten-seemann/qtls-go1-17 v0.1.0/go.mod h1:fz4HIxByo+LlWcreM4CZOYNuz3taBQ8rN2X6FqvaWo8= github.com/marten-seemann/tcp v0.0.0-20210406111302-dfbc87cc63fd h1:br0buuQ854V8u83wA0rVZ8ttrq5CpaPZdvrK0LP2lOk= github.com/marten-seemann/tcp v0.0.0-20210406111302-dfbc87cc63fd/go.mod h1:QuCEs1Nt24+FYQEqAAncTDPJIuGs+LxK1MCiFL25pMU= github.com/maticnetwork/crand v1.0.2 h1:Af0tAivC8zrxXDpGWNWVT/0s1fOz8w0eRbahZgURS8I= github.com/maticnetwork/crand v1.0.2/go.mod h1:/NRNL3bj2eYdqpWmoIP5puxndTpi0XRxpj5ZKxfHjyg= github.com/maticnetwork/polyproto v0.0.2 h1:cPxuxbIDItdwGnucc3lZB58U8Zfe1mH73PWTGd15554= github.com/maticnetwork/polyproto v0.0.2/go.mod h1:e1mU2EXSwEpn5jM7GfNwu3AupsV6WAGoPFFfswXOF0o= +github.com/matryer/moq v0.0.0-20190312154309-6cfb0558e1bd/go.mod h1:9ELz6aaclSIGnZBoaSLZ3NAl1VTufbOrXBPvtcy6WiQ= github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU= +github.com/mattn/go-colorable v0.0.10-0.20170816031813-ad5389df28cd/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU= +github.com/mattn/go-colorable v0.1.1/go.mod h1:FuOcm+DKB9mbwrcAfNl7/TZVBZ6rcnceauSikq3lYCQ= +github.com/mattn/go-colorable v0.1.2/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE= +github.com/mattn/go-colorable v0.1.4/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE= +github.com/mattn/go-colorable v0.1.7/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc= +github.com/mattn/go-colorable v0.1.8/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc= github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA= github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg= +github.com/mattn/go-ieproxy v0.0.0-20190610004146-91bb50d98149/go.mod h1:31jz6HNzdxOmlERGGEc4v/dMssOfmp2p5bT/okiKFFc= +github.com/mattn/go-ieproxy v0.0.0-20190702010315-6dee0af9227d/go.mod h1:31jz6HNzdxOmlERGGEc4v/dMssOfmp2p5bT/okiKFFc= +github.com/mattn/go-isatty v0.0.2/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4= github.com/mattn/go-isatty v0.0.3/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4= github.com/mattn/go-isatty v0.0.4/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4= +github.com/mattn/go-isatty v0.0.5/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s= +github.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s= +github.com/mattn/go-isatty v0.0.9/go.mod h1:YNRxwqDuOph6SZLI9vUUz6OYw3QyUt7WiY2yME+cCiQ= +github.com/mattn/go-isatty v0.0.11/go.mod h1:PhnuNfih5lzO57/f3n+odYbM4JtupLOxQOAqxQCu2WE= github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU= +github.com/mattn/go-isatty v0.0.13/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU= github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94= github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM= github.com/mattn/go-isatty v0.0.17 h1:BTarxUcIeDqL27Mc+vyvdWYSL28zpIhv3RoTdsLMPng= github.com/mattn/go-isatty v0.0.17/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM= github.com/mattn/go-runewidth v0.0.2/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU= +github.com/mattn/go-runewidth v0.0.3/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU= +github.com/mattn/go-runewidth v0.0.9/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI= +github.com/mattn/go-sqlite3 v1.11.0/go.mod h1:FPy6KqzDD04eiIsT53CuJW3U88zkxoIYsOqkbpncsNc= github.com/mattn/go-sqlite3 v1.14.16 h1:yOQRA0RpS5PFz/oikGwBEqvAWhWg5ufRz4ETLjwpU1Y= +github.com/mattn/go-tty v0.0.0-20180907095812-13ff1204f104/go.mod h1:XPvLUNfbS4fJH25nqRHfWLMa1ONC8Amw+mIA639KxkE= github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0= github.com/matttproud/golang_protobuf_extensions v1.0.4 h1:mmDVorXM7PCGKw94cs5zkfA9PSy5pEvNWRP0ET0TIVo= github.com/matttproud/golang_protobuf_extensions v1.0.4/go.mod h1:BSXmuO+STAnVfrANrmjBb36TMTDstsz7MSK+HVaYKv4= +github.com/mgutz/ansi v0.0.0-20170206155736-9520e82c474b/go.mod h1:01TrycV0kFyexm33Z7vhZRXopbI8J3TDReVlkTgMUxE= github.com/microcosm-cc/bluemonday v1.0.1/go.mod h1:hsXNsILzKxV+sX77C5b8FSuKF00vh2OMYv+xgHpAMF4= github.com/miekg/dns v1.0.14/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3Nrg= github.com/miekg/dns v1.1.41/go.mod h1:p6aan82bvRIyn+zDIv9xYNUpwa73JcSh9BKwknJysuI= +github.com/miekg/dns v1.1.43/go.mod h1:+evo5L0630/F6ca/Z9+GAqzhjGyn8/c+TBaOyfEl0V4= github.com/miekg/dns v1.1.50 h1:DQUfb9uc6smULcREF09Uc+/Gd46YWqJd5DbpPE9xkcA= github.com/miekg/dns v1.1.50/go.mod h1:e3IlAVfNqAllflbibAZEWOXOQ+Ynzk/dDozDxY7XnME= github.com/mikioh/tcp v0.0.0-20190314235350-803a9b46060c h1:bzE/A84HN25pxAuk9Eej1Kz9OUelF97nAc82bDquQI8= @@ -597,19 +1095,37 @@ github.com/mikioh/tcpinfo v0.0.0-20190314235526-30a79bb1804b h1:z78hV3sbSMAUoyUM github.com/mikioh/tcpinfo v0.0.0-20190314235526-30a79bb1804b/go.mod h1:lxPUiZwKoFL8DUUmalo2yJJUCxbPKtm8OKfqr2/FTNU= github.com/mikioh/tcpopt v0.0.0-20190314235656-172688c1accc h1:PTfri+PuQmWDqERdnNMiD9ZejrlswWrCpBEZgWOiTrc= github.com/mikioh/tcpopt v0.0.0-20190314235656-172688c1accc/go.mod h1:cGKTAVKx4SxOuR/czcZ/E2RSJ3sfHs8FpHhQ5CWMf9s= +github.com/mimoo/StrobeGo v0.0.0-20181016162300-f8f6d4d2b643/go.mod h1:43+3pMjjKimDBf5Kr4ZFNGbLql1zKkbImw+fZbw3geM= +github.com/mimoo/StrobeGo v0.0.0-20210601165009-122bf33a46e0 h1:QRUSJEgZn2Snx0EmT/QLXibWjSUDjKWvXIT19NBVp94= +github.com/mimoo/StrobeGo v0.0.0-20210601165009-122bf33a46e0/go.mod h1:43+3pMjjKimDBf5Kr4ZFNGbLql1zKkbImw+fZbw3geM= github.com/minio/blake2b-simd v0.0.0-20160723061019-3f5f724cb5b1/go.mod h1:pD8RvIylQ358TN4wwqatJ8rNavkEINozVn9DtGI3dfQ= +github.com/minio/highwayhash v1.0.1/go.mod h1:BQskDq+xkJ12lmlUUi7U0M5Swg3EWR+dLTk+kldvVxY= +github.com/minio/highwayhash v1.0.2 h1:Aak5U0nElisjDCfPSG79Tgzkn2gl66NxOMspRrKnA/g= +github.com/minio/sha256-simd v0.0.0-20190131020904-2d45a736cd16/go.mod h1:2FMWW+8GMoPweT6+pI63m9YE3Lmw4J71hV56Chs1E/U= +github.com/minio/sha256-simd v0.0.0-20190328051042-05b4dd3047e5/go.mod h1:2FMWW+8GMoPweT6+pI63m9YE3Lmw4J71hV56Chs1E/U= +github.com/minio/sha256-simd v0.1.0/go.mod h1:2FMWW+8GMoPweT6+pI63m9YE3Lmw4J71hV56Chs1E/U= github.com/minio/sha256-simd v0.1.1-0.20190913151208-6de447530771/go.mod h1:B5e1o+1/KgNmWrSQK08Y6Z1Vb5pwIktudl0J58iy0KM= +github.com/minio/sha256-simd v0.1.1/go.mod h1:B5e1o+1/KgNmWrSQK08Y6Z1Vb5pwIktudl0J58iy0KM= github.com/minio/sha256-simd v1.0.0 h1:v1ta+49hkWZyvaKwrQB8elexRqm6Y0aMLjCNsrYxo6g= github.com/minio/sha256-simd v1.0.0/go.mod h1:OuYzVNI5vcoYIAmbIvHPl3N3jUzVedXbKy5RFepssQM= github.com/mitchellh/cli v1.0.0/go.mod h1:hNIlj7HEI86fIcpObd7a0FcrxTWetlwJDGcceTlRvqc= +github.com/mitchellh/colorstring v0.0.0-20190213212951-d06e56a500db/go.mod h1:l0dey0ia/Uv7NcFFVbCLtqEBQbrT4OCwCSKTEv6enCw= github.com/mitchellh/go-homedir v1.0.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= +github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= github.com/mitchellh/go-testing-interface v1.0.0/go.mod h1:kRemZodwjscx+RGhAo8eIhFbs2+BFgRtFPeD/KE+zxI= github.com/mitchellh/gox v0.4.0/go.mod h1:Sd9lOJ0+aimLBi73mGofS1ycjY8lL3uZM3JPS42BGNg= github.com/mitchellh/iochan v1.0.0/go.mod h1:JwYml1nuB7xOzsp52dPpHFffvOCDupsG0QubkSMEySY= github.com/mitchellh/mapstructure v0.0.0-20160808181253-ca63d7c062ee/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= +github.com/mitchellh/mapstructure v0.0.0-20170523030023-d0303fe80992/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= +github.com/mitchellh/mapstructure v1.3.2/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= +github.com/mitchellh/mapstructure v1.4.1/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= github.com/mitchellh/mapstructure v1.5.0 h1:jeMsZIYE/09sWLaz43PL7Gy6RuMjD2eJVyuac5Z2hdY= github.com/mitchellh/mapstructure v1.5.0/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= +github.com/mitchellh/pointerstructure v1.2.0/go.mod h1:BRAsLI5zgXmw97Lf6s25bs8ohIXc3tViBH44KcwB2g4= +github.com/mmcloughlin/addchain v0.4.0 h1:SobOdjm2xLj1KkXN5/n0xTIWyZA2+s99UCY1iPfkHRY= +github.com/mmcloughlin/addchain v0.4.0/go.mod h1:A86O+tHqZLMNO4w6ZZ4FlVQEadcoqkyU72HC5wJ4RlU= +github.com/mmcloughlin/profile v0.1.1/go.mod h1:IhHD7q1ooxgwTgjxQYkACGA77oFTDdFVejUS1/tS/qU= github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg= github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= @@ -617,37 +1133,77 @@ github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lN github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M= github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk= +github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826 h1:RWengNIwukTxcDr9M+97sNutRR1RKhG96O6jWumTTnw= +github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826/go.mod h1:TaXosZuwdSHYgviHp1DAtfrULt5eUgsSMsZf+YrPgl8= +github.com/mr-tron/base58 v1.1.0/go.mod h1:xcD2VGqlgYjBdcBLw+TuYLr8afG+Hj8g2eTVqeSzSU8= +github.com/mr-tron/base58 v1.1.1/go.mod h1:xcD2VGqlgYjBdcBLw+TuYLr8afG+Hj8g2eTVqeSzSU8= github.com/mr-tron/base58 v1.1.2/go.mod h1:BinMc/sQntlIE1frQmRFPUoPA1Zkr8VRgBdjWI2mNwc= +github.com/mr-tron/base58 v1.1.3/go.mod h1:BinMc/sQntlIE1frQmRFPUoPA1Zkr8VRgBdjWI2mNwc= github.com/mr-tron/base58 v1.2.0 h1:T/HDJBh4ZCPbU39/+c3rRvE0uKBQlU27+QI8LJ4t64o= github.com/mr-tron/base58 v1.2.0/go.mod h1:BinMc/sQntlIE1frQmRFPUoPA1Zkr8VRgBdjWI2mNwc= github.com/mschoch/smat v0.0.0-20160514031455-90eadee771ae/go.mod h1:qAyveg+e4CE+eKJXWVjKXM4ck2QobLqTDytGJbLLhJg= github.com/mschoch/smat v0.2.0 h1:8imxQsjDm8yFEAVBe7azKmKSgzSkZXDuKkSq9374khM= github.com/mschoch/smat v0.2.0/go.mod h1:kc9mz7DoBKqDyiRL7VZN8KvXQMWeTaVnttLRXOlotKw= +github.com/multiformats/go-base32 v0.0.3/go.mod h1:pLiuGC8y0QR3Ue4Zug5UzK9LjgbkL8NSQj0zQ5Nz/AA= github.com/multiformats/go-base32 v0.1.0 h1:pVx9xoSPqEIQG8o+UbAe7DNi51oej1NtK+aGkbLYxPE= github.com/multiformats/go-base32 v0.1.0/go.mod h1:Kj3tFY6zNr+ABYMqeUNeGvkIC/UYgtWibDcT0rExnbI= +github.com/multiformats/go-base36 v0.1.0/go.mod h1:kFGE83c6s80PklsHO9sRn2NCoffoRdUUOENyW/Vv6sM= github.com/multiformats/go-base36 v0.2.0 h1:lFsAbNOGeKtuKozrtBsAkSVhv1p9D0/qedU9rQyccr0= github.com/multiformats/go-base36 v0.2.0/go.mod h1:qvnKE++v+2MWCfePClUEjE78Z7P2a1UV0xHgWc0hkp4= +github.com/multiformats/go-multiaddr v0.0.1/go.mod h1:xKVEak1K9cS1VdmPZW3LSIb6lgmoS58qz/pzqmAxV44= +github.com/multiformats/go-multiaddr v0.0.2/go.mod h1:xKVEak1K9cS1VdmPZW3LSIb6lgmoS58qz/pzqmAxV44= +github.com/multiformats/go-multiaddr v0.0.4/go.mod h1:xKVEak1K9cS1VdmPZW3LSIb6lgmoS58qz/pzqmAxV44= github.com/multiformats/go-multiaddr v0.1.1/go.mod h1:aMKBKNEYmzmDmxfX88/vz+J5IU55txyt0p4aiWVohjo= github.com/multiformats/go-multiaddr v0.2.0/go.mod h1:0nO36NvPpyV4QzvTLi/lafl2y95ncPj0vFwVF6k6wJ4= +github.com/multiformats/go-multiaddr v0.2.1/go.mod h1:s/Apk6IyxfvMjDafnhJgJ3/46z7tZ04iMk5wP4QMGGE= +github.com/multiformats/go-multiaddr v0.2.2/go.mod h1:NtfXiOtHvghW9KojvtySjH5y0u0xW5UouOmQQrn6a3Y= +github.com/multiformats/go-multiaddr v0.3.0/go.mod h1:dF9kph9wfJ+3VLAaeBqo9Of8x4fJxp6ggJGteB8HQTI= +github.com/multiformats/go-multiaddr v0.3.1/go.mod h1:uPbspcUPd5AfaP6ql3ujFY+QWzmBD8uLLL4bXW0XfGc= +github.com/multiformats/go-multiaddr v0.3.3/go.mod h1:lCKNGP1EQ1eZ35Za2wlqnabm9xQkib3fyB+nZXHLag0= +github.com/multiformats/go-multiaddr v0.4.0/go.mod h1:YcpyLH8ZPudLxQlemYBPhSm0/oCXAT8Z4mzFpyoPyRc= github.com/multiformats/go-multiaddr v0.8.0 h1:aqjksEcqK+iD/Foe1RRFsGZh8+XFiGo7FgUCZlpv3LU= github.com/multiformats/go-multiaddr v0.8.0/go.mod h1:Fs50eBDWvZu+l3/9S6xAE7ZYj6yhxlvaVZjakWN7xRs= github.com/multiformats/go-multiaddr-dns v0.3.1 h1:QgQgR+LQVt3NPTjbrLLpsaT2ufAA2y0Mkk+QRVJbW3A= github.com/multiformats/go-multiaddr-dns v0.3.1/go.mod h1:G/245BRQ6FJGmryJCrOuTdB37AMA5AMOVuO6NY3JwTk= github.com/multiformats/go-multiaddr-fmt v0.1.0 h1:WLEFClPycPkp4fnIzoFoV9FVd49/eQsuaL3/CWe167E= github.com/multiformats/go-multiaddr-fmt v0.1.0/go.mod h1:hGtDIW4PU4BqJ50gW2quDuPVjyWNZxToGUh/HwTZYJo= +github.com/multiformats/go-multiaddr-net v0.1.2/go.mod h1:QsWt3XK/3hwvNxZJp92iMQKME1qHfpYmyIjFVsSOY6Y= +github.com/multiformats/go-multiaddr-net v0.1.3/go.mod h1:ilNnaM9HbmVFqsb/qcNysjCu4PVONlrBZpHIrw/qQuA= +github.com/multiformats/go-multiaddr-net v0.1.4/go.mod h1:ilNnaM9HbmVFqsb/qcNysjCu4PVONlrBZpHIrw/qQuA= +github.com/multiformats/go-multiaddr-net v0.1.5/go.mod h1:ilNnaM9HbmVFqsb/qcNysjCu4PVONlrBZpHIrw/qQuA= +github.com/multiformats/go-multiaddr-net v0.2.0/go.mod h1:gGdH3UXny6U3cKKYCvpXI5rnK7YaOIEOPVDI9tsJbEA= +github.com/multiformats/go-multibase v0.0.1/go.mod h1:bja2MqRZ3ggyXtZSEDKpl0uO/gviWFaSteVbWT51qgs= +github.com/multiformats/go-multibase v0.0.3/go.mod h1:5+1R4eQrT3PkYZ24C3W2Ue2tPwIdYQD509ZjSb5y9Oc= github.com/multiformats/go-multibase v0.1.1 h1:3ASCDsuLX8+j4kx58qnJ4YFq/JWTJpCyDW27ztsVTOI= github.com/multiformats/go-multibase v0.1.1/go.mod h1:ZEjHE+IsUrgp5mhlEAYjMtZwK1k4haNkcaPg9aoe1a8= github.com/multiformats/go-multicodec v0.8.0 h1:evBmgkbSQux+Ds2IgfhkO38Dl2GDtRW8/Rp6YiSHX/Q= github.com/multiformats/go-multicodec v0.8.0/go.mod h1:GUC8upxSBE4oG+q3kWZRw/+6yC1BqO550bjhWsJbZlw= +github.com/multiformats/go-multihash v0.0.1/go.mod h1:w/5tugSrLEbWqlcgJabL3oHFKTwfvkofsjW2Qa1ct4U= +github.com/multiformats/go-multihash v0.0.5/go.mod h1:lt/HCbqlQwlPBz7lv0sQCdtfcMtlJvakRUn/0Ual8po= github.com/multiformats/go-multihash v0.0.8/go.mod h1:YSLudS+Pi8NHE7o6tb3D8vrpKa63epEDmG8nTduyAew= +github.com/multiformats/go-multihash v0.0.10/go.mod h1:YSLudS+Pi8NHE7o6tb3D8vrpKa63epEDmG8nTduyAew= +github.com/multiformats/go-multihash v0.0.13/go.mod h1:VdAWLKTwram9oKAatUcLxBNUjdtcVwxObEQBtRfuyjc= +github.com/multiformats/go-multihash v0.0.14/go.mod h1:VdAWLKTwram9oKAatUcLxBNUjdtcVwxObEQBtRfuyjc= +github.com/multiformats/go-multihash v0.0.15/go.mod h1:D6aZrWNLFTV/ynMpKsNtB40mJzmCl4jb1alC0OvHiHg= github.com/multiformats/go-multihash v0.2.1 h1:aem8ZT0VA2nCHHk7bPJ1BjUbHNciqZC/d16Vve9l108= github.com/multiformats/go-multihash v0.2.1/go.mod h1:WxoMcYG85AZVQUyRyo9s4wULvW5qrI9vb2Lt6evduFc= +github.com/multiformats/go-multistream v0.1.1/go.mod h1:KmHZ40hzVxiaiwlj3MEbYgK9JFk2/9UktWZAF54Du38= +github.com/multiformats/go-multistream v0.2.1/go.mod h1:5GZPQZbkWOLOn3J2y4Y99vVW7vOfsAflxARk3x14o6k= +github.com/multiformats/go-multistream v0.2.2/go.mod h1:UIcnm7Zuo8HKG+HkWgfQsGL+/MIEhyTqbODbIUwSXKs= github.com/multiformats/go-multistream v0.4.1 h1:rFy0Iiyn3YT0asivDUIR05leAdwZq3de4741sbiSdfo= github.com/multiformats/go-multistream v0.4.1/go.mod h1:Mz5eykRVAjJWckE2U78c6xqdtyNUEhKSM0Lwar2p77Q= github.com/multiformats/go-varint v0.0.1/go.mod h1:3Ls8CIEsrijN6+B7PbrXRPxHRPuXSrVKRY101jdMZYE= +github.com/multiformats/go-varint v0.0.2/go.mod h1:3Ls8CIEsrijN6+B7PbrXRPxHRPuXSrVKRY101jdMZYE= +github.com/multiformats/go-varint v0.0.5/go.mod h1:3Ls8CIEsrijN6+B7PbrXRPxHRPuXSrVKRY101jdMZYE= +github.com/multiformats/go-varint v0.0.6/go.mod h1:3Ls8CIEsrijN6+B7PbrXRPxHRPuXSrVKRY101jdMZYE= github.com/multiformats/go-varint v0.0.7 h1:sWSGR+f/eu5ABZA2ZpYKBILXTTs9JWpdEM/nEGOHFS8= github.com/multiformats/go-varint v0.0.7/go.mod h1:r8PUYw/fD/SjBCiKOoDlGF6QawOELpZAu9eioSos/OU= +github.com/munnerz/goautoneg v0.0.0-20120707110453-a547fc61f48d/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ= github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= +github.com/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= +github.com/mxk/go-flowrate v0.0.0-20140419014527-cca7078d478f/go.mod h1:ZdcZmHo+o7JKHSa8/e818NopupXU1YMK5fe1lsApnBw= +github.com/naoina/go-stringutil v0.1.0/go.mod h1:XJ2SJL9jCtBh+P9q5btrd/Ylo8XwT/h1USek5+NqSA0= +github.com/naoina/toml v0.1.2-0.20170918210437-9fafd6967416/go.mod h1:NBIhNtsFMo3G2szEBne+bO4gS192HuIYRqfvOWb4i1E= github.com/nats-io/jwt v0.3.0/go.mod h1:fRYCDE99xlTsqUzISS1Bi75UBJ6ljOJQOAAu5VglpSg= github.com/nats-io/jwt v0.3.2/go.mod h1:/euKqTS1ZD+zzjYrY7pseZrTtWQSjujC7xjPc8wL6eU= github.com/nats-io/nats-server/v2 v2.1.2/go.mod h1:Afk+wRZqkMQs/p45uXdrVLuab3gwv3Z8C4HTBu8GD/k= @@ -663,28 +1219,44 @@ github.com/nxadm/tail v1.4.9-0.20211216163028-4472660a31a6 h1:iZ5rEHU561k2tdi/at github.com/nxadm/tail v1.4.9-0.20211216163028-4472660a31a6/go.mod h1:A+9rV4WFp4DKg1Ym1v6YtCrJ2vvlt1ZA/iml0CNuu2A= github.com/oklog/oklog v0.3.2/go.mod h1:FCV+B7mhrz4o+ueLpx+KqkyXRGMWOYEvfiXtdGtbWGs= github.com/oklog/run v1.0.0/go.mod h1:dlhp/R75TPv97u0XWUtDeV/lRKWPKSdTuV0TZvrmrQA= +github.com/oklog/ulid v1.3.1/go.mod h1:CirwcVhetQ6Lv90oh/F+FBtV6XMibvdAFo93nm5qn4U= github.com/olekukonko/tablewriter v0.0.0-20170122224234-a0225b3f23b5/go.mod h1:vsDQFd/mU46D+Z4whnwzcISnGGzXWMclvtLoiIKAKIo= +github.com/olekukonko/tablewriter v0.0.5/go.mod h1:hPp6KlRPjbx+hW8ykQs1w3UBbZlj6HuIJcUGPhkA7kY= +github.com/onsi/ginkgo v0.0.0-20170829012221-11459a886d9c/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= github.com/onsi/ginkgo v1.7.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= +github.com/onsi/ginkgo v1.10.1/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= +github.com/onsi/ginkgo v1.11.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= +github.com/onsi/ginkgo v1.12.0/go.mod h1:oUhWkIvk5aDxtKvDDuw8gItl8pKl42LzjC9KZE0HfGg= github.com/onsi/ginkgo v1.12.1/go.mod h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108oapk= +github.com/onsi/ginkgo v1.14.0/go.mod h1:iSB4RoI2tjJc9BBv4NKIKWKya62Rps+oPG/Lv9klQyY= +github.com/onsi/ginkgo v1.16.2/go.mod h1:CObGmKUOKaSC0RjmoAK7tKyn4Azo5P2IWuoMnvwxz1E= github.com/onsi/ginkgo v1.16.4/go.mod h1:dX+/inL/fNMqNlz0e9LfyB9TswhZpCVdJM/Z6Vvnwo0= github.com/onsi/ginkgo v1.16.5 h1:8xi0RTUf59SOSfEtZMvwTvXYMzG4gV23XVHOZiXNtnE= github.com/onsi/ginkgo v1.16.5/go.mod h1:+E8gABHa3K6zRBolWtd+ROzc/U5bkGt0FwiG042wbpU= github.com/onsi/ginkgo/v2 v2.8.0 h1:pAM+oBNPrpXRs+E/8spkeGx9QgekbRVyr74EUvRVOUI= github.com/onsi/ginkgo/v2 v2.8.0/go.mod h1:6JsQiECmxCa3V5st74AL/AmsV482EDdVrGaVW6z3oYU= +github.com/onsi/gomega v0.0.0-20170829124025-dcabb60a477c/go.mod h1:C1qb7wdrVGGVU+Z6iS04AVkA3Q65CEZX59MT0QO5uiA= github.com/onsi/gomega v1.4.1/go.mod h1:C1qb7wdrVGGVU+Z6iS04AVkA3Q65CEZX59MT0QO5uiA= github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= +github.com/onsi/gomega v1.7.0/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY= +github.com/onsi/gomega v1.9.0/go.mod h1:Ho0h+IUsWyvy1OpqCwxlQ/21gkhVunqlU8fDGcoTdcA= github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo= +github.com/onsi/gomega v1.13.0/go.mod h1:lRk9szgn8TxENtWd0Tp4c3wjlRfMTMH27I+3Je41yGY= github.com/onsi/gomega v1.17.0/go.mod h1:HnhC7FXeEQY45zxNK3PPoIUhzk/80Xly9PcubAlGdZY= github.com/onsi/gomega v1.25.0 h1:Vw7br2PCDYijJHSfBOWhov+8cAnUf8MfMaIOV323l6Y= github.com/op/go-logging v0.0.0-20160315200505-970db520ece7/go.mod h1:HzydrMdWErDVzsI23lYNej1Htcns9BCg93Dk0bBINWk= +github.com/openconfig/gnmi v0.0.0-20190823184014-89b2bf29312c/go.mod h1:t+O9It+LKzfOAhKTT5O0ehDix+MTqbtT0T9t+7zzOvc= +github.com/openconfig/reference v0.0.0-20190727015836-8dfd928c9696/go.mod h1:ym2A+zigScwkSEb/cVQB0/ZMpU3rqiH6X7WRRsxgOGw= github.com/opencontainers/runtime-spec v1.0.2 h1:UfAcuLBJB9Coz72x1hgl8O5RVzTdNiaglX6v2DM6FI0= github.com/opencontainers/runtime-spec v1.0.2/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0= github.com/opentracing-contrib/go-observer v0.0.0-20170622124052-a52f23424492/go.mod h1:Ngi6UdF0k5OKD5t5wlmGhe/EDKPoUM3BXZSSfIuJbis= github.com/opentracing/basictracer-go v1.0.0/go.mod h1:QfBfYuafItcjQuMwinw9GhYKwFXS9KnPs5lxoYwgW74= github.com/opentracing/opentracing-go v1.0.2/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o= +github.com/opentracing/opentracing-go v1.0.3-0.20180606204148-bd9c31933947/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o= github.com/opentracing/opentracing-go v1.1.0/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o= +github.com/opentracing/opentracing-go v1.2.0/go.mod h1:GxEUsuufX4nBwe+T+Wl9TAgYrxe9dPLANfrWvHYVTgc= github.com/openzipkin-contrib/zipkin-go-opentracing v0.4.5/go.mod h1:/wsWhb9smxSfWAKL3wpBW7V8scJMt8N8gnaMCS9E/cA= github.com/openzipkin/zipkin-go v0.1.1/go.mod h1:NtoC/o8u3JlF1lSlyPNswIbeQH9bJTmOf0Erfk+hxe8= github.com/openzipkin/zipkin-go v0.1.6/go.mod h1:QgAqvLzwWbR/WpD4A3cGpPtJrZXNIiJc5AZX7/PBEpw= @@ -692,17 +1264,29 @@ github.com/openzipkin/zipkin-go v0.2.1/go.mod h1:NaW6tEwdmWMaCDZzg8sh+IBNOxHMPnh github.com/openzipkin/zipkin-go v0.2.2/go.mod h1:NaW6tEwdmWMaCDZzg8sh+IBNOxHMPnhQw8ySjnjRyN4= github.com/pact-foundation/pact-go v1.0.4/go.mod h1:uExwJY4kCzNPcHRj+hCR/HBbOOIwwtUjcrb0b5/5kLM= github.com/pascaldekloe/goe v0.0.0-20180627143212-57f6aae5913c/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc= +github.com/patrickmn/go-cache v2.1.0+incompatible/go.mod h1:3Qf8kWWT7OJRJbdiICTKqZju1ZixQ/KpMGzzAfe6+WQ= +github.com/paulbellamy/ratecounter v0.2.0/go.mod h1:Hfx1hDpSGoqxkVVpBi/IlYD7kChlfo5C6hzIHwPqfFE= github.com/pbnjay/memory v0.0.0-20210728143218-7b4eea64cf58 h1:onHthvaw9LFnH4t2DcNVpwGmV9E1BkGknEliJkfwQj0= github.com/pbnjay/memory v0.0.0-20210728143218-7b4eea64cf58/go.mod h1:DXv8WO4yhMYhSNPKjeNKa5WY9YCIEBRbNzFFPJbWO6Y= github.com/pborman/uuid v1.2.0/go.mod h1:X/NO0urCmaxf9VXbdlT7C2Yzkj2IKimNn4k+gtPdI/k= +github.com/pborman/uuid v1.2.1/go.mod h1:X/NO0urCmaxf9VXbdlT7C2Yzkj2IKimNn4k+gtPdI/k= +github.com/pelletier/go-toml v1.0.1-0.20170904195809-1d6b12b7cb29/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic= +github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic= github.com/pelletier/go-toml v1.9.5 h1:4yBQzkHv+7BHq2PQUZF3Mx0IYxG7LsP222s7Agd3ve8= github.com/pelletier/go-toml v1.9.5/go.mod h1:u1nR/EPcESfeI/szUZKdtJ0xRNbUoANCkoOuaOx1Y+c= github.com/pelletier/go-toml/v2 v2.0.7 h1:muncTPStnKRos5dpVKULv2FVd4bMOhNePj9CjgDb8Us= github.com/pelletier/go-toml/v2 v2.0.7/go.mod h1:eumQOmlWiOPt5WriQQqoM5y18pDHwha2N+QD+EUNTek= github.com/performancecopilot/speed v3.0.0+incompatible/go.mod h1:/CLtqpZ5gBg1M9iaPbIdPPGyKcA8hKdoy6hAWba7Yac= +github.com/peterbourgon/diskv v2.0.1+incompatible/go.mod h1:uqqh8zWWbv1HBMNONnaR/tNboyR3/BZd58JJSHlUSCU= +github.com/peterh/liner v1.0.1-0.20180619022028-8c1271fcf47f/go.mod h1:xIteQHvHuaLYG9IFj6mSxM0fCKrs34IrEQUhOYuGPHc= +github.com/peterh/liner v1.1.1-0.20190123174540-a2c9a5303de7/go.mod h1:CRroGNssyjTd/qIG2FyxByd2S8JEAZXBl4qUrZf8GS0= +github.com/peterh/liner v1.2.0/go.mod h1:CRroGNssyjTd/qIG2FyxByd2S8JEAZXBl4qUrZf8GS0= +github.com/petermattis/goid v0.0.0-20180202154549-b0b1615b78e5 h1:q2e307iGHPdTGp0hoxKjt1H5pDo6utceo3dQVK3I5XQ= +github.com/petermattis/goid v0.0.0-20180202154549-b0b1615b78e5/go.mod h1:jvVRKCrJTQWu0XVbaOlby/2lO20uSCHEMzzplHXte1o= github.com/philhofer/fwd v1.0.0/go.mod h1:gk3iGcWd9+svBvR0sR+KPcfE+RNWozjowpeBVG3ZVNU= github.com/pierrec/lz4 v1.0.2-0.20190131084431-473cd7ce01a1/go.mod h1:3/3N9NVKO0jef7pBehbT1qWhCMrIgbYNnFAZCqQ5LRc= github.com/pierrec/lz4 v2.0.5+incompatible/go.mod h1:pdkljMzZIN41W+lC3N2tnIh5sFi+IEE17M5jbnwPHcY= +github.com/pierrec/lz4 v2.4.1+incompatible/go.mod h1:pdkljMzZIN41W+lC3N2tnIh5sFi+IEE17M5jbnwPHcY= github.com/pion/datachannel v1.5.2 h1:piB93s8LGmbECrpO84DnkIVWasRMk3IimbcXkTQLE6E= github.com/pion/datachannel v1.5.2/go.mod h1:FTGQWaHrdCwIJ1rw6xBIfZVkslikjShim5yr05XFuCQ= github.com/pion/dtls/v2 v2.1.3/go.mod h1:o6+WvyLDAlXF7YiPB/RlskRoeK+/JtuaZa5emwQcWus= @@ -753,15 +1337,23 @@ github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINE github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/profile v1.2.1/go.mod h1:hJw3o1OdXxsrSjjVksARp5W95eeEaEfptyVZyv6JUPA= +github.com/pkg/term v0.0.0-20180730021639-bffc007b7fd5/go.mod h1:eCbImbZ95eXtAUIbLAuAVnBnwf83mjf6QIVH8SHYwqQ= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/posener/complete v1.1.1/go.mod h1:em0nMJCgc9GFtwrmVmEMR/ZL6WyhyjMBndrE9hABlRI= +github.com/power-devops/perfstat v0.0.0-20210106213030-5aafc221ea8c h1:ncq/mPwQF4JjgDlrVEn3C11VoGHZN7m8qihwgMEtzYw= +github.com/power-devops/perfstat v0.0.0-20210106213030-5aafc221ea8c/go.mod h1:OmDBASR4679mdNQnz2pUhc2G8CO2JrUAVFDRBDP/hJE= github.com/prometheus/client_golang v0.8.0/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw= github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw= github.com/prometheus/client_golang v0.9.3-0.20190127221311-3c4408c8b829/go.mod h1:p2iRAGwDERtqlqzRXnrOVns+ignqQo//hLXqYxZYVNs= github.com/prometheus/client_golang v1.0.0/go.mod h1:db9x61etRT2tGnBNRi70OPL5FsnadC4Ky3P0J6CfImo= github.com/prometheus/client_golang v1.3.0/go.mod h1:hJaj2vgQTGQmVCsAACORcieXFeDPbaTKGT+JTgUa3og= +github.com/prometheus/client_golang v1.4.1/go.mod h1:e9GMxYsXl05ICDXkRhurwBS4Q3OK1iX/F2sw+iXX5zU= github.com/prometheus/client_golang v1.5.1/go.mod h1:e9GMxYsXl05ICDXkRhurwBS4Q3OK1iX/F2sw+iXX5zU= +github.com/prometheus/client_golang v1.7.1/go.mod h1:PY5Wy2awLA44sXw4AOSfFBetzPP4j5+D6mVACh+pe2M= +github.com/prometheus/client_golang v1.9.0/go.mod h1:FqZLKOZnGdFAhOK4nqGHa7D66IdsO+O441Eve7ptJDU= +github.com/prometheus/client_golang v1.10.0/go.mod h1:WJM3cc3yu7XKBKa/I8WeZm+V3eltZnBwfENSU7mdogU= +github.com/prometheus/client_golang v1.11.0/go.mod h1:Z6t4BnS23TR94PD6BsDNk8yVqroYurpAkEiz0P2BEV0= github.com/prometheus/client_golang v1.14.0 h1:nJdhIvne2eSX/XRAFV9PcvFFRbrjbcTUj0VP62TMhnw= github.com/prometheus/client_golang v1.14.0/go.mod h1:8vpkKitgIVNcqrRBWh1C4TIUQgYNtG/XQE4E/Zae36Y= github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= @@ -773,10 +1365,17 @@ github.com/prometheus/client_model v0.2.0/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6T github.com/prometheus/client_model v0.3.0 h1:UBgGFHqYdG/TPFD1B1ogZywDqEkwp3fBMvqdiQ7Xew4= github.com/prometheus/client_model v0.3.0/go.mod h1:LDGWKZIo7rky3hgvBe+caln+Dr3dPggB5dvjtD7w9+w= github.com/prometheus/common v0.0.0-20180801064454-c7de2306084e/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro= +github.com/prometheus/common v0.0.0-20181113130724-41aa239b4cce/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro= github.com/prometheus/common v0.2.0/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= github.com/prometheus/common v0.4.1/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= +github.com/prometheus/common v0.6.0/go.mod h1:eBmuwkDJBwy6iBfxCBob6t6dR6ENT/y+J+Zk0j9GMYc= github.com/prometheus/common v0.7.0/go.mod h1:DjGbpBbp5NYNiECxcL/VnbXCCaQpKd3tt26CguLLsqA= github.com/prometheus/common v0.9.1/go.mod h1:yhUN8i9wzaXS3w1O07YhxHEBxD+W35wd8bs7vj7HSQ4= +github.com/prometheus/common v0.10.0/go.mod h1:Tlit/dnDKsSWFlCLTWaA1cyBgKHSMdTB80sz/V91rCo= +github.com/prometheus/common v0.15.0/go.mod h1:U+gB1OBLb1lF3O42bTCL+FK18tX9Oar16Clt/msog/s= +github.com/prometheus/common v0.18.0/go.mod h1:U+gB1OBLb1lF3O42bTCL+FK18tX9Oar16Clt/msog/s= +github.com/prometheus/common v0.26.0/go.mod h1:M7rCNAaPfAosfx8veZJCuw84e35h3Cfd9VFqTh1DIvc= +github.com/prometheus/common v0.30.0/go.mod h1:vu+V0TpY+O6vW9J44gczi3Ap/oXXR10b+M/gUGO4Hls= github.com/prometheus/common v0.39.0 h1:oOyhkDq05hPZKItWVBkJ6g6AtGxi+fy7F4JvUV8uhsI= github.com/prometheus/common v0.39.0/go.mod h1:6XBZ7lYdLCbkAVhwRsWTZn+IN5AB9F/NXd5w0BbEX0Y= github.com/prometheus/procfs v0.0.0-20180725123919-05ee40e3a273/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= @@ -784,43 +1383,68 @@ github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R github.com/prometheus/procfs v0.0.0-20190117184657-bf6a532e95b1/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA= github.com/prometheus/procfs v0.0.8/go.mod h1:7Qr8sr6344vo1JqZ6HhLceV9o3AJ1Ff+GxbHq6oeK9A= +github.com/prometheus/procfs v0.0.10/go.mod h1:7Qr8sr6344vo1JqZ6HhLceV9o3AJ1Ff+GxbHq6oeK9A= github.com/prometheus/procfs v0.0.11/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4OA4YeYWdaU= +github.com/prometheus/procfs v0.1.3/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4OA4YeYWdaU= +github.com/prometheus/procfs v0.2.0/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4OA4YeYWdaU= +github.com/prometheus/procfs v0.6.0/go.mod h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1xBZuNvfVA= +github.com/prometheus/procfs v0.7.3/go.mod h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1xBZuNvfVA= github.com/prometheus/procfs v0.9.0 h1:wzCHvIvM5SxWqYvwgVL7yJY8Lz3PKn49KQtpgMYJfhI= github.com/prometheus/procfs v0.9.0/go.mod h1:+pB4zwohETzFnmlpe6yd2lSc+0/46IYZRB/chUwxUZY= +github.com/prometheus/prom2json v1.3.0/go.mod h1:rMN7m0ApCowcoDlypBHlkNbp5eJQf/+1isKykIP5ZnM= +github.com/prometheus/tsdb v0.7.1/go.mod h1:qhTCs0VvXwvX/y3TZrWD7rabWM+ijKTux40TwIPHuXU= +github.com/prometheus/tsdb v0.10.0/go.mod h1:oi49uRhEe9dPUTlS3JRZOwJuVi6tmh10QSgwXEyGCt4= github.com/protolambda/eth2-shuffle v1.1.0 h1:gixIBI84IeugTwwHXm8vej1bSSEhueBCSryA4lAKRLU= github.com/protolambda/eth2-shuffle v1.1.0/go.mod h1:FhA2c0tN15LTC+4T9DNVm+55S7uXTTjQ8TQnBuXlkF8= +github.com/protolambda/ztyp v0.2.2 h1:rVcL3vBu9W/aV646zF6caLS/dyn9BN8NYiuJzicLNyY= +github.com/protolambda/ztyp v0.2.2/go.mod h1:9bYgKGqg3wJqT9ac1gI2hnVb0STQq7p/1lapqrqY1dU= +github.com/prysmaticlabs/eth2-types v0.0.0-20210303084904-c9735a06829d h1:1dN7YAqMN3oAJ0LceWcyv/U4jHLh+5urnSnr4br6zg4= +github.com/prysmaticlabs/eth2-types v0.0.0-20210303084904-c9735a06829d/go.mod h1:kOmQ/zdobQf7HUohDTifDNFEZfNaSCIY5fkONPL+dWU= github.com/prysmaticlabs/fastssz v0.0.0-20220628121656-93dfe28febab h1:Y3PcvUrnneMWLuypZpwPz8P70/DQsz6KgV9JveKpyZs= github.com/prysmaticlabs/fastssz v0.0.0-20220628121656-93dfe28febab/go.mod h1:MA5zShstUwCQaE9faGHgCGvEWUbG87p4SAXINhmCkvg= +github.com/prysmaticlabs/go-bitfield v0.0.0-20210108222456-8e92c3709aa0/go.mod h1:hCwmef+4qXWjv0jLDbQdWnL0Ol7cS7/lCSS26WR+u6s= github.com/prysmaticlabs/go-bitfield v0.0.0-20210809151128-385d8c5e3fb7 h1:0tVE4tdWQK9ZpYygoV7+vS6QkDvQVySboMVEIxBJmXw= github.com/prysmaticlabs/go-bitfield v0.0.0-20210809151128-385d8c5e3fb7/go.mod h1:wmuf/mdK4VMD+jA9ThwcUKjg3a2XWM9cVfFYjDyY4j4= github.com/prysmaticlabs/gohashtree v0.0.2-alpha h1:hk5ZsDQuSkyUMhTd55qB396P1+dtyIKiSwMmYE/hyEU= github.com/prysmaticlabs/gohashtree v0.0.2-alpha/go.mod h1:4pWaT30XoEx1j8KNJf3TV+E3mQkaufn7mf+jRNb/Fuk= +github.com/prysmaticlabs/prombbolt v0.0.0-20210126082820-9b7adba6db7c/go.mod h1:ZRws458tYHS/Zs936OQ6oCrL+Ict5O4Xpwve1UQ6C9M= +github.com/prysmaticlabs/protoc-gen-go-cast v0.0.0-20211014160335-757fae4f38c6/go.mod h1:ZVEbRdnMkGhp/pu35zq4SXxtvUwWK0J1MATtekZpH2Y= +github.com/prysmaticlabs/prysm v0.0.0-20220124113610-e26cde5e091b h1:XULhE6PdzCYSe5OEVFhuixNqL3mYVOq/3M+SUGnKr1Y= +github.com/prysmaticlabs/prysm v0.0.0-20220124113610-e26cde5e091b/go.mod h1:bFzDfaj4xtisRey9RPkMJOhOJVwmtH3FChV7NPKV1Nk= +github.com/prysmaticlabs/prysm/v4 v4.0.3 h1:w4jkMQjgI4NyIdxny2GBDH1UMVS3tcnlh6obQewkKDM= +github.com/prysmaticlabs/prysm/v4 v4.0.3/go.mod h1:WkVcqMkQQtKcxL+yho4jzkXaKQW93+60tnuLj1vNrXU= github.com/quasilyte/go-ruleguard/dsl v0.3.22 h1:wd8zkOhSNr+I+8Qeciml08ivDt1pSXe60+5DqOpCjPE= github.com/quasilyte/go-ruleguard/dsl v0.3.22/go.mod h1:KeCP03KrjuSO0H1kTuZQCWlQPulDV6YMIXmpQss17rU= github.com/quic-go/qpack v0.4.0 h1:Cr9BXA1sQS2SmDUWjSofMPNKmvF6IiIfDRmgU0w1ZCo= github.com/quic-go/qpack v0.4.0/go.mod h1:UZVnYIfi5GRk+zI9UMaCPsmZ2xKJP7XBUvVyT1Knj9A= -github.com/quic-go/qtls-go1-18 v0.2.0 h1:5ViXqBZ90wpUcZS0ge79rf029yx0dYB0McyPJwqqj7U= -github.com/quic-go/qtls-go1-18 v0.2.0/go.mod h1:moGulGHK7o6O8lSPSZNoOwcLvJKJ85vVNc7oJFD65bc= -github.com/quic-go/qtls-go1-19 v0.2.0 h1:Cvn2WdhyViFUHoOqK52i51k4nDX8EwIh5VJiVM4nttk= -github.com/quic-go/qtls-go1-19 v0.2.0/go.mod h1:ySOI96ew8lnoKPtSqx2BlI5wCpUVPT05RMAlajtnyOI= -github.com/quic-go/qtls-go1-20 v0.1.0 h1:d1PK3ErFy9t7zxKsG3NXBJXZjp/kMLoIb3y/kV54oAI= -github.com/quic-go/qtls-go1-20 v0.1.0/go.mod h1:JKtK6mjbAVcUTN/9jZpvLbGxvdWIKS8uT7EiStoU1SM= -github.com/quic-go/quic-go v0.32.0 h1:lY02md31s1JgPiiyfqJijpu/UX/Iun304FI3yUqX7tA= -github.com/quic-go/quic-go v0.32.0/go.mod h1:/fCsKANhQIeD5l76c2JFU+07gVE3KaA0FP+0zMWwfwo= -github.com/quic-go/webtransport-go v0.5.1 h1:1eVb7WDWCRoaeTtFHpFBJ6WDN1bSrPrRoW6tZgSw0Ow= -github.com/quic-go/webtransport-go v0.5.1/go.mod h1:OhmmgJIzTTqXK5xvtuX0oBpLV2GkLWNDA+UeTGJXErU= +github.com/quic-go/qtls-go1-19 v0.2.1 h1:aJcKNMkH5ASEJB9FXNeZCyTEIHU1J7MmHyz1Q1TSG1A= +github.com/quic-go/qtls-go1-19 v0.2.1/go.mod h1:ySOI96ew8lnoKPtSqx2BlI5wCpUVPT05RMAlajtnyOI= +github.com/quic-go/qtls-go1-20 v0.1.1 h1:KbChDlg82d3IHqaj2bn6GfKRj84Per2VGf5XV3wSwQk= +github.com/quic-go/qtls-go1-20 v0.1.1/go.mod h1:JKtK6mjbAVcUTN/9jZpvLbGxvdWIKS8uT7EiStoU1SM= +github.com/quic-go/quic-go v0.33.0 h1:ItNoTDN/Fm/zBlq769lLJc8ECe9gYaW40veHCCco7y0= +github.com/quic-go/quic-go v0.33.0/go.mod h1:YMuhaAV9/jIu0XclDXwZPAsP/2Kgr5yMYhe9oxhhOFA= +github.com/quic-go/webtransport-go v0.5.2 h1:GA6Bl6oZY+g/flt00Pnu0XtivSD8vukOu3lYhJjnGEk= +github.com/quic-go/webtransport-go v0.5.2/go.mod h1:OhmmgJIzTTqXK5xvtuX0oBpLV2GkLWNDA+UeTGJXErU= +github.com/r3labs/sse v0.0.0-20210224172625-26fe804710bc/go.mod h1:S8xSOnV3CgpNrWd0GQ/OoQfMtlg2uPRSuTzcSGrzwK8= github.com/raulk/go-watchdog v1.3.0 h1:oUmdlHxdkXRJlwfG0O9omj8ukerm8MEQavSiDTEtBsk= github.com/raulk/go-watchdog v1.3.0/go.mod h1:fIvOnLbF0b0ZwkB9YU4mOW9Did//4vPZtDqv66NfsMU= github.com/rcrowley/go-metrics v0.0.0-20181016184325-3113b8401b8a/go.mod h1:bCqnVzQkZxMG4s8nGwiZ5l3QUCyqpo9Y+/ZMZ9VjZe4= +github.com/rcrowley/go-metrics v0.0.0-20190826022208-cac0b30c2563/go.mod h1:bCqnVzQkZxMG4s8nGwiZ5l3QUCyqpo9Y+/ZMZ9VjZe4= +github.com/rcrowley/go-metrics v0.0.0-20201227073835-cf1acfcdf475 h1:N/ElC8H3+5XpJzTSTfLsJV/mx9Q9g7kxmchpfZyxgzM= +github.com/rcrowley/go-metrics v0.0.0-20201227073835-cf1acfcdf475/go.mod h1:bCqnVzQkZxMG4s8nGwiZ5l3QUCyqpo9Y+/ZMZ9VjZe4= github.com/remyoudompheng/bigfft v0.0.0-20200410134404-eec4a21b6bb0/go.mod h1:qqbHyh8v60DhA7CoWK5oRCqLrMHRGoxYCSS9EjAz6Eo= github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec h1:W09IVJc94icq4NjY3clb7Lk8O1qJ8BdBEF8z0ibU0rE= github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec/go.mod h1:qqbHyh8v60DhA7CoWK5oRCqLrMHRGoxYCSS9EjAz6Eo= +github.com/retailnext/hllpp v1.0.1-0.20180308014038-101a6d2f8b52/go.mod h1:RDpi1RftBQPUCDRw6SmxeaREsAaRKnOclghuzp/WRzc= +github.com/rjeczalik/notify v0.9.1/go.mod h1:rKwnCoCGeuQnwBtTSPL9Dad03Vh2n40ePRrjvIXnJho= github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6SoW27p1b0cqNHllgS5HIMJraePCO15w5zCzIWYg= +github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ= github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= github.com/rogpeppe/go-internal v1.6.1/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTEfhy4qGm1nDQc= github.com/rogpeppe/go-internal v1.8.0/go.mod h1:WmiCO8CzOY8rg0OYDC4/i/2WRWAB6poM+XZ2dLUbcbE= github.com/rogpeppe/go-internal v1.9.0 h1:73kH8U+JUqXU8lRuOHeVHaa/SZPifC7BkcraZVejAe8= github.com/rogpeppe/go-internal v1.9.0/go.mod h1:WtVeX8xhTBvf0smdhujwtBcq4Qrzq/fJaraNFVN+nFs= +github.com/rs/cors v1.7.0/go.mod h1:gFx+x8UowdsKA9AchylcLynDq+nNFfI8FkUZdN/jGCU= github.com/rs/cors v1.8.3 h1:O+qNyWn7Z+F9M0ILBHgMVPuB1xTOucVd5gtaYyXBpRo= github.com/rs/cors v1.8.3/go.mod h1:XyqrcTp5zjWr1wsJ8PIRZssZ8b/WMcMf71DJnit4EMU= github.com/rs/dnscache v0.0.0-20211102005908-e0241e321417 h1:Lt9DzQALzHoDwMBGJ6v8ObDPR0dzr2a6sXTB1Fq7IHs= @@ -833,11 +1457,24 @@ github.com/ryanuber/columnize v0.0.0-20160712163229-9b3edd62028f/go.mod h1:sm1tb github.com/ryszard/goskiplist v0.0.0-20150312221310-2dfbae5fcf46 h1:GHRpF1pTW19a8tTFrMLUcfWwyC0pnifVo2ClaLq+hP8= github.com/ryszard/goskiplist v0.0.0-20150312221310-2dfbae5fcf46/go.mod h1:uAQ5PCi+MFsC7HjREoAz1BU+Mq60+05gifQSsHSDG/8= github.com/samuel/go-zookeeper v0.0.0-20190923202752-2cc03de413da/go.mod h1:gi+0XIa01GRL2eRQVjQkKGqKF3SF9vZR/HnPullcV2E= +github.com/sasha-s/go-deadlock v0.3.1 h1:sqv7fDNShgjcaxkO0JNcOAlr8B9+cV5Ey/OB71efZx0= +github.com/sasha-s/go-deadlock v0.3.1/go.mod h1:F73l+cr82YSh10GxyRI6qZiCgK64VaZjwesgfQ1/iLM= +github.com/satori/go.uuid v1.2.0/go.mod h1:dA0hQrYB0VpLJoorglMZABFdXlWrHn1NEOzdhQKdks0= +github.com/schollz/progressbar/v3 v3.3.4/go.mod h1:Rp5lZwpgtYmlvmGo1FyDwXMqagyRBQYSDwzlP9QDu84= github.com/sclevine/agouti v3.0.0+incompatible/go.mod h1:b4WX9W9L1sfQKXeJf1mUTLZKJ48R1S7H23Ji7oFO5Bw= github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529/go.mod h1:DxrIzT+xaE7yg65j358z/aeFdxmN0P9QXhEzd20vsDc= +github.com/segmentio/kafka-go v0.1.0/go.mod h1:X6itGqS9L4jDletMsxZ7Dz+JFWxM6JHfPOCvTvk+EJo= +github.com/segmentio/kafka-go v0.2.0/go.mod h1:X6itGqS9L4jDletMsxZ7Dz+JFWxM6JHfPOCvTvk+EJo= github.com/sergi/go-diff v1.0.0/go.mod h1:0CfEIISq7TuYL3j771MWULgwwjU+GofnZX9QAmXWZgo= github.com/sergi/go-diff v1.1.0 h1:we8PVUC3FE2uYfodKH/nBHMSetSfHDR6scGdBi+erh0= github.com/sergi/go-diff v1.1.0/go.mod h1:STckp+ISIX8hZLjrqAeVduY0gWCT9IjLuqbuNXdaHfM= +github.com/shirou/gopsutil v3.21.4-0.20210419000835-c7a38de76ee5+incompatible/go.mod h1:5b4v6he4MtMOwMlS0TUMTu2PcXUg8+E1lC7eC3UO/RA= +github.com/shirou/gopsutil/v3 v3.23.3 h1:Syt5vVZXUDXPEXpIBt5ziWsJ4LdSAAxF4l/xZeQgSEE= +github.com/shirou/gopsutil/v3 v3.23.3/go.mod h1:lSBNN6t3+D6W5e5nXTxc8KIMMVxAcS+6IJlffjRRlMU= +github.com/shoenig/go-m1cpu v0.1.4 h1:SZPIgRM2sEF9NJy50mRHu9PKGwxyyTTJIWvCtgVbozs= +github.com/shoenig/go-m1cpu v0.1.4/go.mod h1:Wwvst4LR89UxjeFtLRMrpgRiyY4xPsejnVZym39dbAQ= +github.com/shoenig/test v0.6.3 h1:GVXWJFk9PiOjN0KoJ7VrJGH6uLPnqxR7/fe3HUPfE0c= +github.com/shoenig/test v0.6.3/go.mod h1:byHiCGXqrVaflBLAMq/srcZIHynQPQgeyvkvXnjqq0k= github.com/shurcooL/component v0.0.0-20170202220835-f88ec8f54cc4/go.mod h1:XhFIlyj5a1fBNx5aJTbKoIq0mNaPvOagO+HjB3EtxrY= github.com/shurcooL/events v0.0.0-20181021180414-410e4ca65f48/go.mod h1:5u70Mqkb5O5cxEA8nxTsgrgLehJeAw6Oc4Ab1c/P1HM= github.com/shurcooL/github_flavored_markdown v0.0.0-20181002035957-2122de532470/go.mod h1:2dOwnU2uBioM+SGy2aZoq1f/Sd1l9OkAeAUvjSyvgU0= @@ -863,25 +1500,47 @@ github.com/shurcooL/users v0.0.0-20180125191416-49c67e49c537/go.mod h1:QJTqeLYED github.com/shurcooL/webdavfs v0.0.0-20170829043945-18c3829fa133/go.mod h1:hKmq5kWdCj2z2KEozexVbfEZIWiTjhE0+UjmZgPqehw= github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo= github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE= +github.com/sirupsen/logrus v1.6.0/go.mod h1:7uNnSEd1DgxDLC74fIahvMZmmYsHGZGEOFrfsX/uA88= github.com/sirupsen/logrus v1.7.0/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0= +github.com/sirupsen/logrus v1.9.0 h1:trlNQbNUG3OdDrDil03MCb1H2o9nJ1x4/5LYw7byDE0= +github.com/sirupsen/logrus v1.9.0/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ= github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc= github.com/smartystreets/assertions v0.0.0-20190215210624-980c5ac6f3ac/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc= github.com/smartystreets/goconvey v0.0.0-20181108003508-044398e4856c/go.mod h1:XDJAKZRPZ1CvBcN2aX5YOUTYGHki24fSF0Iv48Ibg0s= github.com/smartystreets/goconvey v0.0.0-20190306220146-200a235640ff/go.mod h1:KSQcGKpxUMHk3nbYzs/tIBAM2iDooCn0BmttHOJEbLs= github.com/smartystreets/goconvey v1.6.4/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA= +github.com/smola/gocompat v0.2.0/go.mod h1:1B0MlxbmoZNo3h8guHp8HztB3BSYR5itql9qtVc0ypY= github.com/soheilhy/cmux v0.1.4/go.mod h1:IM3LyeVVIOuxMH7sFAkER9+bJ4dT7Ms6E4xg4kGIyLM= github.com/sony/gobreaker v0.4.1/go.mod h1:ZKptC7FHNvhBz7dN2LGjPVBz2sZJmc0/PkyDJOjmxWY= github.com/sourcegraph/annotate v0.0.0-20160123013949-f4cad6c6324d/go.mod h1:UdhH50NIW0fCiwBSr0co2m7BnFLdv4fQTgdqdJTHFeE= github.com/sourcegraph/syntaxhighlight v0.0.0-20170531221838-bd320f5d308e/go.mod h1:HuIsMU8RRBOtsCgI77wP899iHVBQpCmg4ErYMZB+2IA= +github.com/spacemonkeygo/openssl v0.0.0-20181017203307-c2dcc5cca94a/go.mod h1:7AyxJNCJ7SBZ1MfVQCWD6Uqo2oubI2Eq2y2eqf+A5r0= +github.com/spacemonkeygo/spacelog v0.0.0-20180420211403-2296661a0572/go.mod h1:w0SWMsp6j9O/dk4/ZpIhL+3CkG8ofA2vuv7k+ltqUMc= +github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA= github.com/spaolacci/murmur3 v1.1.0 h1:7c1g84S4BPRrfL5Xrdp6fOJ206sU9y293DDHaoy0bLI= github.com/spaolacci/murmur3 v1.1.0/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA= +github.com/spf13/afero v0.0.0-20170901052352-ee1bd8ee15a1/go.mod h1:j4pytiNVoe2o6bmDsKpLACNPDBIoEAkihy7loJ1B0CQ= +github.com/spf13/afero v1.1.2/go.mod h1:j4pytiNVoe2o6bmDsKpLACNPDBIoEAkihy7loJ1B0CQ= +github.com/spf13/afero v1.2.2/go.mod h1:9ZxEEn6pIJ8Rxe320qSDBk6AsU0r9pR7Q4OcevTdifk= +github.com/spf13/cast v1.1.0/go.mod h1:r2rcYCSwa1IExKTDiTfzaxqT2FNHs8hODu4LnUfgKEg= +github.com/spf13/cast v1.3.0/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE= github.com/spf13/cobra v0.0.3/go.mod h1:1l0Ry5zgKvJasoi3XT1TypsSe7PqH0Sj9dhYf7v3XqQ= +github.com/spf13/cobra v0.0.5/go.mod h1:3K3wKZymM7VvHMDS9+Akkh4K60UwM26emMESw8tLCHU= github.com/spf13/cobra v1.6.1 h1:o94oiPyS4KD1mPy2fmcYYHHfCxLqYjJOhGsCHFZtEzA= github.com/spf13/cobra v1.6.1/go.mod h1:IOw/AERYS7UzyrGinqmz6HLUo219MORXGxhbaJUqzrY= +github.com/spf13/jwalterweatherman v0.0.0-20170901151539-12bd96e66386/go.mod h1:cQK4TGJAtQXfYWX+Ddv3mKDzgVb68N+wFjFa4jdeBTo= +github.com/spf13/jwalterweatherman v1.0.0/go.mod h1:cQK4TGJAtQXfYWX+Ddv3mKDzgVb68N+wFjFa4jdeBTo= +github.com/spf13/pflag v0.0.0-20170130214245-9ff6c6923cff/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= +github.com/spf13/pflag v1.0.1-0.20170901120850-7aff26db30c1/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= github.com/spf13/pflag v1.0.1/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA= github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= +github.com/spf13/viper v1.0.0/go.mod h1:A8kyI5cUJhb8N+3pkfONlcEcZbueH6nhAm0Fq7SrnBM= +github.com/spf13/viper v1.3.2/go.mod h1:ZiWeW+zYFKm7srdB9IoDzzZXaJaI5eL9QjNiN/DMA2s= +github.com/src-d/envconfig v1.0.0/go.mod h1:Q9YQZ7BKITldTBnoxsE5gOeB5y66RyPXeue/R4aaNBc= +github.com/status-im/keycard-go v0.0.0-20190316090335-8537d3370df4/go.mod h1:RZLeN1LMWmRsyYjvAu+I6Dm9QmlDaIIt+Y+4Kd7Tp+Q= +github.com/status-im/keycard-go v0.0.0-20200402102358-957c09536969/go.mod h1:RZLeN1LMWmRsyYjvAu+I6Dm9QmlDaIIt+Y+4Kd7Tp+Q= github.com/streadway/amqp v0.0.0-20190404075320-75d898a42a94/go.mod h1:AZpEONHx3DKn8O/DFsRAY58/XVQiIPMTMB1SddzLXVw= github.com/streadway/amqp v0.0.0-20190827072141-edfb9018d271/go.mod h1:AZpEONHx3DKn8O/DFsRAY58/XVQiIPMTMB1SddzLXVw= github.com/streadway/handy v0.0.0-20190108123426-d5acb3125c2a/go.mod h1:qNTQ5P5JnDBl6z3cMAg/SywNDC5ABu5ApDIw6lUbRmI= @@ -889,6 +1548,7 @@ github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+ github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo= +github.com/stretchr/testify v1.2.0/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= github.com/stretchr/testify v1.2.1/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= @@ -901,9 +1561,16 @@ github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= github.com/stretchr/testify v1.8.2 h1:+h33VjcLVPDHtOdpUCuF+7gSuG3yGIftsP1YvFihtJ8= github.com/stretchr/testify v1.8.2/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= +github.com/supranational/blst v0.3.5/go.mod h1:jZJtfjgudtNl4en1tzwPIV3KjUnQUvG3/j+w+fVonLw= github.com/supranational/blst v0.3.10 h1:CMciDZ/h4pXDDXQASe8ZGTNKUiVNxVVA5hpci2Uuhuk= github.com/supranational/blst v0.3.10/go.mod h1:jZJtfjgudtNl4en1tzwPIV3KjUnQUvG3/j+w+fVonLw= +github.com/syndtr/goleveldb v1.0.0/go.mod h1:ZVVdQEZoIme9iO1Ch2Jdy24qqXrMMOU6lpPAyBWyWuQ= +github.com/syndtr/goleveldb v1.0.1-0.20210819022825-2ae1ddf74ef7/go.mod h1:q4W45IWZaF22tdD+VEXcAWRA037jwmWEB5VWYORlTpc= +github.com/syndtr/goleveldb v1.0.1-0.20220721030215-126854af5e6d h1:vfofYNRScrDdvS342BElfbETmL1Aiz3i2t0zfRj16Hs= github.com/tarm/serial v0.0.0-20180830185346-98f6abe2eb07/go.mod h1:kDXzergiv9cbyO7IOYJZWg1U88JhDg3PB6klq9Hg2pA= +github.com/tecbot/gorocksdb v0.0.0-20191217155057-f0fad39f321c h1:g+WoO5jjkqGAzHWCjJB1zZfXPIAaDpzXIEJ0eS6B5Ok= +github.com/templexxx/cpufeat v0.0.0-20180724012125-cef66df7f161/go.mod h1:wM7WEvslTq+iOEAMDLSzhVuOt5BRZ05WirO+b09GHQU= +github.com/templexxx/xor v0.0.0-20191217153810-f85b25db303b/go.mod h1:5XA7W9S6mni3h5uvOC75dA3m9CCCaS83lltmc0ukdi4= github.com/tendermint/go-amino v0.14.1 h1:o2WudxNfdLNBwMyl2dqOJxiro5rfrEaU0Ugs6offJMk= github.com/tendermint/go-amino v0.14.1/go.mod h1:i/UKE5Uocn+argJJBb12qTZsCDBcAYMbR92AaJVmKso= github.com/thomaso-mirodin/intmath v0.0.0-20160323211736-5dc6d854e46e h1:cR8/SYRgyQCt5cNCMniB/ZScMkhI9nk8U5C7SbISXjo= @@ -913,11 +1580,23 @@ github.com/tidwall/btree v1.6.0/go.mod h1:twD9XRA5jj9VUQGELzDO4HPQTNJsoWWfYEL+EU github.com/tinylib/msgp v1.0.2/go.mod h1:+d+yLhGm8mzTaHzB+wgMYrodPfmZrzkirds8fDWklFE= github.com/tinylib/msgp v1.1.0/go.mod h1:+d+yLhGm8mzTaHzB+wgMYrodPfmZrzkirds8fDWklFE= github.com/tinylib/msgp v1.1.2/go.mod h1:+d+yLhGm8mzTaHzB+wgMYrodPfmZrzkirds8fDWklFE= +github.com/tjfoc/gmsm v1.3.0/go.mod h1:HaUcFuY0auTiaHB9MHFGCPx5IaLhTUd2atbCFBQXn9w= +github.com/tklauser/go-sysconf v0.3.5/go.mod h1:MkWzOF4RMCshBAMXuhXJs64Rte09mITnppBXY/rYEFI= +github.com/tklauser/go-sysconf v0.3.11 h1:89WgdJhk5SNwJfu+GKyYveZ4IaJ7xAkecBo+KdJV0CM= +github.com/tklauser/go-sysconf v0.3.11/go.mod h1:GqXfhXY3kiPa0nAXPDIQIWzJbMCB7AmcWpGR8lSZfqI= +github.com/tklauser/numcpus v0.2.2/go.mod h1:x3qojaO3uyYt0i56EW/VUYs7uBvdl2fkfZFu0T9wgjM= +github.com/tklauser/numcpus v0.6.0 h1:kebhY2Qt+3U6RNK7UqpYNA+tJ23IBEGKkB7JQBfDYms= +github.com/tklauser/numcpus v0.6.0/go.mod h1:FEZLMke0lhOUG6w2JadTzp0a+Nl8PF/GFkQ5UVIcaL4= github.com/tmc/grpc-websocket-proxy v0.0.0-20170815181823-89b8d40f7ca8/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U= -github.com/torquem-ch/mdbx-go v0.27.8 h1:rqGmgT2g4S/nKlfmFhLcQUKGQYV6OSog1tT+HHi7LME= -github.com/torquem-ch/mdbx-go v0.27.8/go.mod h1:T2fsoJDVppxfAPTLd1svUgH1kpPmeXdPESmroSHcL1E= +github.com/torquem-ch/mdbx-go v0.27.10 h1:iwb8Wn9gse4MEYIltAna+pxMPCY7hA1/5LLN/Qrcsx0= +github.com/torquem-ch/mdbx-go v0.27.10/go.mod h1:T2fsoJDVppxfAPTLd1svUgH1kpPmeXdPESmroSHcL1E= +github.com/trailofbits/go-mutexasserts v0.0.0-20200708152505-19999e7d3cef/go.mod h1:+SV/613m53DNAmlXPTWGZhIyt4E/qDvn9g/lOPRiy0A= +github.com/tyler-smith/go-bip39 v1.0.1-0.20181017060643-dbb3b84ba2ef/go.mod h1:sJ5fKU0s6JVwZjjcUEX2zFOnvq0ASQ2K9Zr6cf67kNs= +github.com/tyler-smith/go-bip39 v1.1.0/go.mod h1:gUYDtqQw1JS3ZJ8UWVcGTGqqr6YIN3CWg+kkNaLt55U= +github.com/uber/jaeger-client-go v2.25.0+incompatible/go.mod h1:WVhlPFC8FDjOFMMWRy2pZqQJSXxYSwNYOkTr/Z6d3Kk= github.com/ugorji/go v1.1.7/go.mod h1:kZn38zHttfInRq0xu/PH0az30d+z6vm202qpg1oXVMw= github.com/ugorji/go v1.1.13/go.mod h1:jxau1n+/wyTGLQoCkjok9r5zFa/FxT6eI5HiHKQszjc= +github.com/ugorji/go/codec v0.0.0-20181204163529-d75b2dcb6bc8/go.mod h1:VFNgLljTbGfSG7qAOspJ7OScBnGdDN/yBr0sguwnwf0= github.com/ugorji/go/codec v1.1.7/go.mod h1:Ax+UKWsSmolVDwsd+7N3ZtXu+yMGCf907BLYF3GoBXY= github.com/ugorji/go/codec v1.1.13 h1:013LbFhocBoIqgHeIHKlV4JWYhqogATYWZhIcH0WHn4= github.com/ugorji/go/codec v1.1.13/go.mod h1:oNVt3Dq+FO91WNQ/9JnHKQP2QJxTzoN7wCBFCq1OeuU= @@ -926,62 +1605,110 @@ github.com/ugorji/go/codec/codecgen v1.1.13/go.mod h1:EhCxlc7Crov+HLygD4+hBCitXN github.com/urfave/cli v1.20.0/go.mod h1:70zkFmudgCuE/ngEzBv17Jvp/497gISqfk5gWijbERA= github.com/urfave/cli v1.22.1/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0= github.com/urfave/cli v1.22.2/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0= -github.com/urfave/cli/v2 v2.24.4 h1:0gyJJEBYtCV87zI/x2nZCPyDxD51K6xM8SkwjHFCNEU= -github.com/urfave/cli/v2 v2.24.4/go.mod h1:GHupkWPMM0M/sj1a2b4wUrWBPzazNrIjouW6fmdJLxc= +github.com/urfave/cli/v2 v2.3.0/go.mod h1:LJmUH05zAU44vOAcrfzZQKsZbVcdbOG8rtL3/XcUArI= +github.com/urfave/cli/v2 v2.25.0 h1:ykdZKuQey2zq0yin/l7JOm9Mh+pg72ngYMeB0ABn6q8= +github.com/urfave/cli/v2 v2.25.0/go.mod h1:GHupkWPMM0M/sj1a2b4wUrWBPzazNrIjouW6fmdJLxc= +github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc= github.com/valyala/fastjson v1.6.4 h1:uAUNq9Z6ymTgGhcm0UynUAB6tlbakBrz6CQFax3BXVQ= github.com/valyala/fastjson v1.6.4/go.mod h1:CLCAqky6SMuOcxStkYQvblddUtoRxhYMGLrsQns1aXY= github.com/valyala/fastrand v1.1.0 h1:f+5HkLW4rsgzdNoleUOB69hyT9IlD2ZQh9GyDMfb5G8= github.com/valyala/fastrand v1.1.0/go.mod h1:HWqCzkrkg6QXT8V2EXWvXCoow7vLwOFN002oeRzjapQ= +github.com/valyala/fasttemplate v1.0.1/go.mod h1:UQGH1tvbgY+Nz5t2n7tXsz52dQxojPUpymEIMZ47gx8= +github.com/valyala/fasttemplate v1.2.1/go.mod h1:KHLXt3tVN2HBp8eijSv/kGJopbvo7S+qRAEEKiv+SiQ= github.com/valyala/histogram v1.2.0 h1:wyYGAZZt3CpwUiIb9AU/Zbllg1llXyrtApRS815OLoQ= github.com/valyala/histogram v1.2.0/go.mod h1:Hb4kBwb4UxsaNbbbh+RRz8ZR6pdodR57tzWUS3BUzXY= github.com/vektah/gqlparser/v2 v2.5.1 h1:ZGu+bquAY23jsxDRcYpWjttRZrUz07LbiY77gUOHcr4= github.com/vektah/gqlparser/v2 v2.5.1/go.mod h1:mPgqFBu/woKTVYWyNk8cO3kh4S/f4aRFZrvOnp3hmCs= github.com/viant/assertly v0.4.8/go.mod h1:aGifi++jvCrUaklKEKT0BU95igDNaqkvz+49uaYMPRU= github.com/viant/toolbox v0.24.0/go.mod h1:OxMCG57V0PXuIP2HNQrtJf2CjqdmbrOx5EkMILuUhzM= +github.com/wealdtech/go-bytesutil v1.1.1/go.mod h1:jENeMqeTEU8FNZyDFRVc7KqBdRKSnJ9CCh26TcuNb9s= +github.com/wealdtech/go-eth2-types/v2 v2.5.2/go.mod h1:8lkNUbgklSQ4LZ2oMSuxSdR7WwJW3L9ge1dcoCVyzws= +github.com/wealdtech/go-eth2-util v1.6.3/go.mod h1:0hFMj/qtio288oZFHmAbCnPQ9OB3c4WFzs5NVPKTY4k= +github.com/wealdtech/go-eth2-wallet-encryptor-keystorev4 v1.1.3/go.mod h1:qiIimacW5NhVRy8o+YxWo9YrecXqDAKKbL0+sOa0SJ4= +github.com/wealdtech/go-eth2-wallet-types/v2 v2.8.2/go.mod h1:k6kmiKWSWBTd4OxFifTEkPaBLhZspnO2KFD5XJY9nqg= +github.com/wercker/journalhook v0.0.0-20180428041537-5d0a5ae867b3/go.mod h1:XCsSkdKK4gwBMNrOCZWww0pX6AOt+2gYc5Z6jBRrNVg= +github.com/whyrusleeping/go-keyspace v0.0.0-20160322163242-5b898ac5add1/go.mod h1:8UvriyWtv5Q5EOgjHaSseUEdkQfvwFv1I/In/O2M9gc= +github.com/whyrusleeping/go-logging v0.0.0-20170515211332-0457bb6b88fc/go.mod h1:bopw91TMyo8J3tvftk8xmU2kPmlrt4nScJQZU2hE5EM= +github.com/whyrusleeping/mdns v0.0.0-20190826153040-b9b60ed33aa9/go.mod h1:j4l84WPFclQPj320J9gp0XwNKBb3U0zt5CBqjPp22G4= +github.com/whyrusleeping/multiaddr-filter v0.0.0-20160516205228-e903e4adabd7/go.mod h1:X2c0RVCI1eSUFI8eLcY3c0423ykwiUdxLJtkDvruhjI= +github.com/whyrusleeping/timecache v0.0.0-20160911033111-cfcb2f1abfee/go.mod h1:m2aV4LZI4Aez7dP5PMyVKEHhUyEJ/RjmPEDOpDvudHg= +github.com/willf/bitset v1.1.3/go.mod h1:RjeCKbqT1RxIR/KWY6phxZiaY1IyutSBfGjNPySAYV4= github.com/willf/bitset v1.1.9/go.mod h1:RjeCKbqT1RxIR/KWY6phxZiaY1IyutSBfGjNPySAYV4= +github.com/willf/bitset v1.1.10 h1:NotGKqX0KwQ72NUzqrjZq5ipPNDQex9lo3WpaS8L2sc= github.com/willf/bitset v1.1.10/go.mod h1:RjeCKbqT1RxIR/KWY6phxZiaY1IyutSBfGjNPySAYV4= +github.com/x-cray/logrus-prefixed-formatter v0.5.2/go.mod h1:2duySbKsL6M18s5GU7VPsoEPHyzalCE06qoARUCeBBE= +github.com/xdg/scram v0.0.0-20180814205039-7eeb5667e42c/go.mod h1:lB8K/P019DLNhemzwFU4jHLhdvlE6uDZjXFejJXr49I= +github.com/xdg/stringprep v1.0.0/go.mod h1:Jhud4/sHMO4oL310DaZAKk9ZaJ08SJfe+sJh0HrGL1Y= github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU= +github.com/xlab/treeprint v0.0.0-20180616005107-d6fb6747feb6/go.mod h1:ce1O1j6UtZfjr22oyGxGLbauSBp2YVXpARAosm7dHBg= +github.com/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77/go.mod h1:aYKd//L2LvnjZzWKhF00oedf4jCCReLcmhLdhm1A27Q= github.com/xrash/smetrics v0.0.0-20201216005158-039620a65673 h1:bAn7/zixMGCfxrRTfdpNzjtPYqr8smhKouy9mxVdGPU= github.com/xrash/smetrics v0.0.0-20201216005158-039620a65673/go.mod h1:N3UwUGtsrSj3ccvlPHLoLsHnpR27oXr4ZE984MbSER8= github.com/xsleonard/go-merkle v1.1.0 h1:fHe1fuhJjGH22ZzVTAH0jqHLhTGhOq3wQjJN+8P0jQg= github.com/xsleonard/go-merkle v1.1.0/go.mod h1:cW4z+UZ/4f2n9IJgIiyDCdYguchoDyDAPmpuOWGxdGg= +github.com/xtaci/kcp-go v5.4.20+incompatible/go.mod h1:bN6vIwHQbfHaHtFpEssmWsN45a+AZwO7eyRCmEIbtvE= +github.com/xtaci/lossyconn v0.0.0-20190602105132-8df528c0c9ae/go.mod h1:gXtu8J62kEgmN++bm9BVICuT/e8yiLI2KFobd/TRFsE= +github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= +github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= +github.com/yuin/goldmark v1.4.1/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= +github.com/yusufpapurcu/wmi v1.2.2 h1:KBNDSne4vP5mbSWnJbO+51IMOXJB67QiYCSBrubbPRg= +github.com/yusufpapurcu/wmi v1.2.2/go.mod h1:SBZ9tNy3G9/m5Oi98Zks0QjeHVDvuK0qfxQmPyzfmi0= go.etcd.io/bbolt v1.3.3/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU= +go.etcd.io/bbolt v1.3.5/go.mod h1:G5EMThwa9y8QZGBClrRx5EY+Yw9kAhnjy3bSjsnlVTQ= go.etcd.io/bbolt v1.3.6 h1:/ecaJf0sk1l4l6V4awd65v2C3ILy7MSj+s/x1ADCIMU= go.etcd.io/bbolt v1.3.6/go.mod h1:qXsaaIqmgQH0T+OPdb99Bf+PKfBBQVAdyD6TY9G8XM4= go.etcd.io/etcd v0.0.0-20191023171146-3cf2f69b5738/go.mod h1:dnLIgRNXwCJa5e+c6mIZCrds/GIG4ncV9HhK5PX7jPg= go.opencensus.io v0.18.0/go.mod h1:vKdFvxhtzZ9onBp9VKHK8z/sRpBMnKAsufL7wlDrCOA= go.opencensus.io v0.20.1/go.mod h1:6WKK9ahsWS3RSO+PY9ZHZUfv2irvY6gN279GOPZjmmk= go.opencensus.io v0.20.2/go.mod h1:6WKK9ahsWS3RSO+PY9ZHZUfv2irvY6gN279GOPZjmmk= +go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU= +go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8= go.opencensus.io v0.22.2/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= go.opencensus.io v0.22.3/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= -go.opentelemetry.io/otel v1.8.0 h1:zcvBFizPbpa1q7FehvFiHbQwGzmPILebO0tyqIR5Djg= -go.opentelemetry.io/otel v1.8.0/go.mod h1:2pkj+iMj0o03Y+cW6/m8Y4WkRdYN3AvCXCnzRMp9yvM= -go.opentelemetry.io/otel/trace v1.8.0 h1:cSy0DF9eGI5WIfNwZ1q2iUyGj00tGzP24dE1lOlHrfY= -go.opentelemetry.io/otel/trace v1.8.0/go.mod h1:0Bt3PXY8w+3pheS3hQUt+wow8b1ojPaTBoTCh2zIFI4= +go.opencensus.io v0.22.4/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= +go.opencensus.io v0.23.0/go.mod h1:XItmlyltB5F7CS4xOC1DcqMoFqwtC6OG2xF7mCv7P7E= +go.opentelemetry.io/otel v1.11.0 h1:kfToEGMDq6TrVrJ9Vht84Y8y9enykSZzDDZglV0kIEk= +go.opentelemetry.io/otel v1.11.0/go.mod h1:H2KtuEphyMvlhZ+F7tg9GRhAOe60moNx61Ex+WmiKkk= +go.opentelemetry.io/otel/trace v1.11.0 h1:20U/Vj42SX+mASlXLmSGBg6jpI1jQtv682lZtTAOVFI= +go.opentelemetry.io/otel/trace v1.11.0/go.mod h1:nyYjis9jy0gytE9LXGU+/m1sHTKbRY0fX0hulNNDP1U= +go.opentelemetry.io/proto/otlp v0.7.0/go.mod h1:PqfVotwruBrMGOCsRd/89rSnXhoiJIqeYNgFYFoEGnI= go.uber.org/atomic v1.3.2/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= go.uber.org/atomic v1.5.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ= +go.uber.org/atomic v1.6.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ= go.uber.org/atomic v1.7.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc= +go.uber.org/atomic v1.9.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc= go.uber.org/atomic v1.10.0 h1:9qC72Qh0+3MqyJbAn8YU5xVq1frD8bn3JtD2oXtafVQ= go.uber.org/atomic v1.10.0/go.mod h1:LUxbIzbOniOlMKjJjyPfpl4v+PKK2cNJn91OQbhoJI0= +go.uber.org/automaxprocs v1.3.0/go.mod h1:9CWT6lKIep8U41DDaPiH6eFscnTyjfTANNQNx6LrIcA= go.uber.org/dig v1.16.1 h1:+alNIBsl0qfY0j6epRubp/9obgtrObRAc5aD+6jbWY8= go.uber.org/dig v1.16.1/go.mod h1:557JTAUZT5bUK0SvCwikmLPPtdQhfvLYtO5tJgQSbnk= go.uber.org/fx v1.19.1 h1:JwYIYAQzXBuBBwSZ1/tn/95pnQO/Sp3yE8lWj9eSAzI= go.uber.org/fx v1.19.1/go.mod h1:bGK+AEy7XUwTBkqCsK/vDyFF0JJOA6X5KWpNC0e6qTA= +go.uber.org/goleak v1.0.0/go.mod h1:8a7PlsEVH3e/a/GLqe5IIrQx6GzcnRmZEufDUTk4A7A= +go.uber.org/goleak v1.1.10/go.mod h1:8a7PlsEVH3e/a/GLqe5IIrQx6GzcnRmZEufDUTk4A7A= go.uber.org/goleak v1.1.11-0.20210813005559-691160354723/go.mod h1:cwTWslyiVhfpKIDGSZEM2HlOvcqm+tG4zioyIeLoqMQ= go.uber.org/goleak v1.1.12 h1:gZAh5/EyT/HQwlpkCy6wTpqfH9H8Lz8zbm3dZh+OyzA= go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0= go.uber.org/multierr v1.3.0/go.mod h1:VgVr7evmIr6uPjLBxg28wmKNXyqE9akIJ5XnfpiKl+4= +go.uber.org/multierr v1.5.0/go.mod h1:FeouvMocqHpRaaGuG9EjoKcStLC43Zu/fmqdUMPcKYU= go.uber.org/multierr v1.6.0/go.mod h1:cdWPpRnG4AhwMwsgIHip0KRBQjJy5kYEpYjJxpXp9iU= +go.uber.org/multierr v1.7.0/go.mod h1:7EAYxJLBy9rStEaz58O2t4Uvip6FSURkq8/ppBp95ak= go.uber.org/multierr v1.9.0 h1:7fIwc/ZtS0q++VgcfqFDxSBZVv/Xo49/SYnDFupUwlI= go.uber.org/multierr v1.9.0/go.mod h1:X2jQV1h+kxSjClGpnseKVIxpmcjrj7MNnI0bnlfKTVQ= go.uber.org/tools v0.0.0-20190618225709-2cfd321de3ee/go.mod h1:vJERXedbb3MVM5f9Ejo0C68/HhF8uaILCdgjnY+goOA= +go.uber.org/zap v1.9.1/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q= go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q= go.uber.org/zap v1.13.0/go.mod h1:zwrFLgMcdUuIBviXEYEH1YKNaOBnKXsx2IPda5bBwHM= +go.uber.org/zap v1.14.1/go.mod h1:Mb2vm2krFEG5DV0W9qcHBYFtp/Wku1cvYaqPsS/WYfc= +go.uber.org/zap v1.15.0/go.mod h1:Mb2vm2krFEG5DV0W9qcHBYFtp/Wku1cvYaqPsS/WYfc= +go.uber.org/zap v1.16.0/go.mod h1:MA8QOfq0BHJwdXa996Y4dYkAqRKB8/1K1QMMZVaNZjQ= +go.uber.org/zap v1.18.1/go.mod h1:xg/QME4nWcxGxrpdeYfq7UvYrLh66cuVKdrbD1XF/NI= +go.uber.org/zap v1.19.0/go.mod h1:xg/QME4nWcxGxrpdeYfq7UvYrLh66cuVKdrbD1XF/NI= go.uber.org/zap v1.19.1/go.mod h1:j3DNczoxDZroyBnOT1L/Q79cfUMGZxlv/9dzN7SM1rI= go.uber.org/zap v1.24.0 h1:FiJd5l1UOLj0wCgbSE0rwwXHzEdAZS6hiiSnxJN/D60= go.uber.org/zap v1.24.0/go.mod h1:2kMP+WWQ8aoFoedH3T2sq6iJ2yDWpHbP0f6MQbS9Gkg= @@ -991,42 +1718,87 @@ golang.org/x/crypto v0.0.0-20170930174604-9419663f5a44/go.mod h1:6SG95UA2DQfeDnf golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20181029021203-45a5f77698d3/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20181030102418-4d3f4d9ffa16/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= +golang.org/x/crypto v0.0.0-20181203042331-505ab145d0a9/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= +golang.org/x/crypto v0.0.0-20190211182817-74369b46fc67/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= +golang.org/x/crypto v0.0.0-20190225124518-7f87c0fbb88b/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20190313024323-a1f597ede03a/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= +golang.org/x/crypto v0.0.0-20190426145343-a29dc8fdc734/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20190611184440-5c40567a22f8/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20190618222545-ea8f1a30c443/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20190701094942-4def268fd1a4/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20190909091759-094676da4a83/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20191219195013-becbf705a915/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20200115085410-6d4e4cb37c7d/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= +golang.org/x/crypto v0.0.0-20200204104054-c9f3fb736b72/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= +golang.org/x/crypto v0.0.0-20200220183623-bac4c82f6975/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= +golang.org/x/crypto v0.0.0-20200221231518-2aa609cf4a9d/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20200510223506-06a226fb4e37/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20200602180216-279210d13fed/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= +golang.org/x/crypto v0.0.0-20200820211705-5c72a883971a/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= +golang.org/x/crypto v0.0.0-20201221181555-eec23a3978ad/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I= +golang.org/x/crypto v0.0.0-20210220033148-5ea612d1eb83/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I= golang.org/x/crypto v0.0.0-20210322153248-0c34fe9e7dc2/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4= +golang.org/x/crypto v0.0.0-20210506145944-38f3c27a63bf/go.mod h1:P+XmwS30IXTQdn5tA2iutPOUgjI07+tq3H3K9MVA1s8= +golang.org/x/crypto v0.0.0-20210813211128-0a44fdfbc16e/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= +golang.org/x/crypto v0.0.0-20211117183948-ae814b36b871/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= golang.org/x/crypto v0.0.0-20220131195533-30dcbda58838/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= golang.org/x/crypto v0.0.0-20220427172511-eb4f295cb31f/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= golang.org/x/crypto v0.0.0-20220516162934-403b01795ae8/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= golang.org/x/crypto v0.5.0/go.mod h1:NK/OQwhpMQP3MwtdjgLlYHnH9ebylxKWv3e0fK+mkQU= -golang.org/x/crypto v0.6.0 h1:qfktjS5LUO+fFKeJXZ+ikTRijMmljikvG68fpMMruSc= -golang.org/x/crypto v0.6.0/go.mod h1:OFC/31mSvZgRz0V1QTNCzfAI1aIRzbiufJtkMIlEp58= +golang.org/x/crypto v0.8.0 h1:pd9TJtTueMTVQXzk8E2XESSMQDj/U7OUu0PqJqPXQjQ= +golang.org/x/crypto v0.8.0/go.mod h1:mRqEX+O9/h5TFCrQhkgjo2yKi0yYA+9ecGkdQoHrywE= +golang.org/x/exp v0.0.0-20180321215751-8460e604b9de/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= +golang.org/x/exp v0.0.0-20180807140117-3d87b88a115f/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= -golang.org/x/exp v0.0.0-20230224173230-c95f2b4c22f2 h1:Jvc7gsqn21cJHCmAWx0LiimpP18LZmUxkT5Mp7EZ1mI= -golang.org/x/exp v0.0.0-20230224173230-c95f2b4c22f2/go.mod h1:CxIveKay+FTh1D0yPZemJVgC/95VzuuOLq5Qi4xnoYc= +golang.org/x/exp v0.0.0-20190125153040-c74c464bbbf2/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= +golang.org/x/exp v0.0.0-20190829153037-c13cbed26979/go.mod h1:86+5VVa7VpoJ4kLfm080zCjGlMRFzhUhsZKEZO7MGek= +golang.org/x/exp v0.0.0-20191030013958-a1ab85dbe136/go.mod h1:JXzH8nQsPlswgeRAPE3MuO9GYsAcnJvJ4vnMwN/5qkY= +golang.org/x/exp v0.0.0-20191129062945-2f5052295587/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= +golang.org/x/exp v0.0.0-20191227195350-da58074b4299/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= +golang.org/x/exp v0.0.0-20200119233911-0405dc783f0a/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= +golang.org/x/exp v0.0.0-20200207192155-f17229e696bd/go.mod h1:J/WKrq2StrnmMY6+EHIKF9dgMWnmCNThgcyBT1FY9mM= +golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6/go.mod h1:3jZMyOhIsHpP37uCMkUooju7aAi5cS1Q23tOzKc+0MU= +golang.org/x/exp v0.0.0-20200331195152-e8c3332aa8e5/go.mod h1:4M0jN8W1tt0AVLNr8HDosyJCDCDuyL9N9+3m7wDWgKw= +golang.org/x/exp v0.0.0-20200513190911-00229845015e/go.mod h1:4M0jN8W1tt0AVLNr8HDosyJCDCDuyL9N9+3m7wDWgKw= +golang.org/x/exp v0.0.0-20230321023759-10a507213a29 h1:ooxPy7fPvB4kwsA2h+iBNHkAbp/4JxTSwCmvdjEYmug= +golang.org/x/exp v0.0.0-20230321023759-10a507213a29/go.mod h1:CxIveKay+FTh1D0yPZemJVgC/95VzuuOLq5Qi4xnoYc= +golang.org/x/image v0.0.0-20180708004352-c73c2afc3b81/go.mod h1:ux5Hcp/YLpHSI86hEcLt0YII63i6oz57MZXIpbrjZUs= +golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js= +golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= golang.org/x/lint v0.0.0-20180702182130-06c8688daad7/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU= golang.org/x/lint v0.0.0-20190301231843-5614ed5bae6f/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= +golang.org/x/lint v0.0.0-20190409202823-959b441ac422/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= +golang.org/x/lint v0.0.0-20190909230951-414d861bb4ac/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= +golang.org/x/lint v0.0.0-20191125180803-fdd1cda4f05f/go.mod h1:5qLYkcX4OjUUV8bRuDixDT3tpyyb+LUpUlRWLxfhWrs= +golang.org/x/lint v0.0.0-20200130185559-910be7a94367/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= golang.org/x/lint v0.0.0-20200302205851-738671d3881b/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= +golang.org/x/lint v0.0.0-20201208152925-83fdc39ff7b5/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= +golang.org/x/mobile v0.0.0-20190312151609-d3739f865fa6/go.mod h1:z+o9i4GpDbdi3rU15maQ/Ox0txvL9dWGYEHz965HBQE= +golang.org/x/mobile v0.0.0-20190719004257-d2bd2a29d028/go.mod h1:E/iHnbuqvinMTCcRqshq8CkpyQDoeVncDDYHnLhea+o= golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc= +golang.org/x/mod v0.1.0/go.mod h1:0QHyrYULN0/3qlju5TqG8bIK38QM8yzMo5ekMj3DlcY= golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg= +golang.org/x/mod v0.1.1-0.20191107180719-034126e5016b/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg= golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +golang.org/x/mod v0.5.1/go.mod h1:5OXOZSfqPIIbmVBIIKWRFfZjPR0E5r58TLhUjH0a2Ro= golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= -golang.org/x/mod v0.8.0 h1:LUYupSeNrTNCGzR/hVBk2NHZO4hXcVaW1k4Qx7rjPx8= -golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= +golang.org/x/mod v0.9.0 h1:KENHtAZL2y3NLMYZeHY9DW8HW8V+kQyJsY/V9JlKvCs= +golang.org/x/mod v0.9.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= +golang.org/x/net v0.0.0-20170114055629-f2499483f923/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180524181706-dfa909b99c79/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180719180050-a680a1efc54d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= @@ -1042,22 +1814,53 @@ golang.org/x/net v0.0.0-20181220203305-927f97764cc3/go.mod h1:mL1N/T3taQHkDXs73r golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190125091013-d26f9f9a57f3/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190227160552-c95aed5357e7/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190313220215-9f648a60d977/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190501004415-9ce7a6920f09/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190503192946-f4e77d36d62c/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks= golang.org/x/net v0.0.0-20190613194153-d28f0bde5980/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20190628185345-da137c7871d7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20190724013045-ca1201d0de80/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20190813141303-74dc4d7220e7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20191004110552-13f9640d40b9/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20191116160921-f9c825593386/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20191209160850-c0dbc17a3553/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200114155413-6afb5195e5aa/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200202094626-16171245cfb2/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200222125558-5a598a2470a0/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200301022130-244492dfa37a/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200324143707-d3edc9973b7e/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= +golang.org/x/net v0.0.0-20200421231249-e086a090c8fd/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= +golang.org/x/net v0.0.0-20200501053045-e0ff5e5a1de5/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= +golang.org/x/net v0.0.0-20200506145744-7e3656a0809f/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= +golang.org/x/net v0.0.0-20200513185701-a91f0712d120/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= golang.org/x/net v0.0.0-20200520004742-59133d7f0dd7/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= +golang.org/x/net v0.0.0-20200520182314-0ba52f642ac2/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= +golang.org/x/net v0.0.0-20200625001655-4c5254603344/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= +golang.org/x/net v0.0.0-20200707034311-ab3426394381/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= +golang.org/x/net v0.0.0-20200813134508-3edf25e44fcc/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= +golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= +golang.org/x/net v0.0.0-20200904194848-62affa334b73/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= +golang.org/x/net v0.0.0-20201110031124-69a78807bb2b/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= golang.org/x/net v0.0.0-20201201195509-5d6afe98e0b7/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= golang.org/x/net v0.0.0-20210119194325-5f4716e94777/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= +golang.org/x/net v0.0.0-20210220033124-5f55cee0dc0d/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= +golang.org/x/net v0.0.0-20210316092652-d523dce5a7f4/go.mod h1:RBQZq4jEuRlivfhVLdyRGr576XBO4/greRjx4P4O3yc= golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM= +golang.org/x/net v0.0.0-20210423184538-5f58ad60dda6/go.mod h1:OJAsFXCWl8Ukc7SiCT/9KSuxbyM7479/AVlXFRxuMCk= golang.org/x/net v0.0.0-20210428140749-89ef3d95e781/go.mod h1:OJAsFXCWl8Ukc7SiCT/9KSuxbyM7479/AVlXFRxuMCk= +golang.org/x/net v0.0.0-20210525063256-abc453219eb5/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20210726213435-c6fcb2dbf985/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= +golang.org/x/net v0.0.0-20210805182204-aaa1db679c0d/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= +golang.org/x/net v0.0.0-20210813160813-60bc85c4be6d/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= +golang.org/x/net v0.0.0-20211015210444-4f30a5c0130f/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20211201190559-0a0e4e1bb54c/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20220127200216-cd36cc0744dd/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= @@ -1067,24 +1870,35 @@ golang.org/x/net v0.0.0-20220531201128-c960675eff93/go.mod h1:XRhObCWvk6IyKnWLug golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= golang.org/x/net v0.1.0/go.mod h1:Cx3nUiGt4eDBEyega/BKRp+/AlGL8hYe7U9odMt2Cco= golang.org/x/net v0.5.0/go.mod h1:DivGGAXEgPSlEBzxGzZI+ZLohi+xUj054jfeKui00ws= -golang.org/x/net v0.7.0 h1:rJrUqqhjsgNp7KqAIc25s9pZnjU7TUcSY7HcVZjdn1g= -golang.org/x/net v0.7.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= +golang.org/x/net v0.9.0 h1:aWJ/m6xSmxWBx+V0XRHTlrYrPG56jKsLdTFmsSsCzOM= +golang.org/x/net v0.9.0/go.mod h1:d48xBJpPfHeWQsugry2m+kC02ZBRGRgulfHnEXEuWns= +golang.org/x/oauth2 v0.0.0-20170912212905-13449ad91cb2/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= 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= golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= +golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= +golang.org/x/oauth2 v0.0.0-20191202225959-858c2ad4c8b6/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= +golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= +golang.org/x/oauth2 v0.0.0-20200902213428-5d25da1a8d43/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= +golang.org/x/oauth2 v0.0.0-20210514164344-f6687ab2804c/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= golang.org/x/perf v0.0.0-20180704124530-6e6d33e29852/go.mod h1:JLpeXjPJfIyPr5TlbXLkXWLhP8nz10XfvxElABhCtcw= +golang.org/x/sync v0.0.0-20170517211232-f52d1811a629/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20200317015054-43a5402ce75a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= 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 h1:wsuoTGHzEhffawBOhz5CYhcrV4IdKZbEyZjBMuTp12o= golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sys v0.0.0-20170830134202-bb24a47a89ea/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= 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= @@ -1095,123 +1909,292 @@ golang.org/x/sys v0.0.0-20181029174526-d69651ed3497/go.mod h1:STP8DvDyc/dI5b8T5h golang.org/x/sys v0.0.0-20181107165924-66b7b1311ac8/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20181122145206-62eef0e2fa9b/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20181205085412-a5c9d58dba9a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190130150945-aca44879d564/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190209173611-3b5209105503/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190219092855-153ac476189d/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190228124157-a34e9553db1e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190316082340-a2f829d7f35f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190405154228-4b34438f7a67/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190502145724-3ef323f4f1fd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190507160741-ecd444e8653b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190606165138-5da285871e9c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190624142023-c5567b49c5d0/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190626221950-04f50cda93cb/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190726091711-fc99dfbffb4e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190813064441-fde4db37ae7a/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190826190057-c7b8b68b1456/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190904154756-749cb33beabd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190916202348-b4ddaad3f8a3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191001151750-bb3f8db39f24/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191005200804-aed5e4c7ecf9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191022100944-742c48ecaeb7/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191120155948-bd437916bb0e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191204072324-ce4227a45e2e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191206220618-eeba5f6aabab/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191220142924-d4481acd189f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191228213918-04cbcbbfeed8/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200106162015-b016eb3dc98e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200107162124-548cf772de50/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200113162924-86b910548bc1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200122134326-e047566fdf82/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200124204421-9fbb57f87de9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200202164722-d101bd2416d5/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200212091648-12a6c2dcc1e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200219091948-cb0a6d8edb6c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200302150141-5c8b2ff67527/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200331124033-c3d80250170d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200413165638-669c56c373c4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200420163511-1957bb5e6d1f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200501052902-10377860bb8e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200511232937-7e40ca221e25/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200515095857-1151b9dac4a9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200519105757-fe76b779f299/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200523222454-059865788121/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200602225109-6fdc65e7d980/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200615200032-f1bc736245b1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200625212154-ddb9806d33ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200803210538-64077c9b5642/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200814200057-3d37ad5750ed/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200826173525-f9321e4c35a6/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200905004654-be1d3432aa8f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200923182605-d9f96fdee20d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20201204225414-ed752295db88/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20201214210602-f9fddec55a1e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210112080510-489259a85091/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210119212857-b64e53b001e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210303074136-134d130e1a04/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210309074719-68d13333faf2/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210315160823-c6e025ad8005/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210316164454-77fc1eacc6aa/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210317225723-c4fcb01b228e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210320140829-1e4c9ba3b0c4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210324051608-47abb6519492/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210420205809-ac73e9fd8988/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210426080607-c94f62235c83/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210511113859-b0526f3d8744/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210603081109-ebe580a85c40/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210816183151-1e6c022a8912/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20211019181941-9d821ace8654/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20211020174200-9d6173849985/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20211025201205-69cdffdb9359/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20211124211545-fe61309f8881/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220412211240-33da011f77ad/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220608164250-635b8c9b7f68/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220704084225-05e143d24a9e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220908164124-27713097b956/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.2.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.3.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.4.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.5.0 h1:MUK/U/4lj1t1oPg0HfuXDN/Z1wv31ZJ/YcPiGccS4DU= golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.7.0 h1:3jlCCIQZPdOYu1h8BkNvLz8Kgwtae2cagcG/VamtZRU= +golang.org/x/sys v0.7.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +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= golang.org/x/term v0.1.0/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/term v0.4.0/go.mod h1:9P2UbLfCdcvo3p/nzKvsmas4TnlujnuoV9hGgYzW1lQ= +golang.org/x/text v0.0.0-20160726164857-2910a502d2bf/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +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= golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/text v0.3.4/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= golang.org/x/text v0.4.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= golang.org/x/text v0.6.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= -golang.org/x/text v0.7.0 h1:4BRB4x83lYWy72KwLD/qYDuTu7q9PjSagHvijDw7cLo= -golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= +golang.org/x/text v0.9.0 h1:2sjJmO8cDvYveuX97RDLsxlyUxLl+GHoLxBiRdHllBE= +golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= +golang.org/x/time v0.0.0-20170424234030-8be79e1e0910/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= 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= golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= +golang.org/x/time v0.0.0-20201208040808-7e3f01d25324/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= +golang.org/x/time v0.0.0-20210220033141-f8bda1e9f3ba/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.3.0 h1:rg5rLMjNzMS1RkNLzCG38eapWhnYLFYXDXj2gOlr8j4= golang.org/x/time v0.3.0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20180525024113-a5b4c53f6e8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20180828015842-6cd1fcedba52/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20181011042414-1f849cf54d09/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20181030000716-a0a13e073c7b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20181030221726-6c7e314b6563/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20181130052023-1c3d964395ce/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20190206041539-40960b6deb8e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY= golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +golang.org/x/tools v0.0.0-20190312151545-0bb0c0a6e846/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= golang.org/x/tools v0.0.0-20190312170243-e65039ee4138/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= golang.org/x/tools v0.0.0-20190328211700-ab21143f2384/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +golang.org/x/tools v0.0.0-20190425150028-36563e24a262/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= +golang.org/x/tools v0.0.0-20190506145303-2d16b83fe98c/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= +golang.org/x/tools v0.0.0-20190606124116-d0a3d012864b/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= golang.org/x/tools v0.0.0-20190621195816-6e04913cbbac/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= +golang.org/x/tools v0.0.0-20190628153133-6cdbf07be9d0/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= +golang.org/x/tools v0.0.0-20190816200558-6889da9d5479/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20190911174233-4f2ddba30aff/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191012152004-8de300cfc20a/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191029041327-9cc4af7d6b2c/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191029190741-b9c20aec41a5/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191108193012-7d206e10da11/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191113191852-77e3bb0ad9e7/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191115202509-3a792d9c32b2/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191125144606-a911d9008d1f/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191130070609-6e064ea0cf2d/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191216173652-a0e659d51361/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20191227053925-7b8e75db28f4/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= golang.org/x/tools v0.0.0-20200103221440-774c71fcf114/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200108203644-89082a384178/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200117161641-43d50277825c/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200122220014-bf1340f18c4a/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= golang.org/x/tools v0.0.0-20200130002326-2f3ba24bd6e7/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200204074204-1cc6d1ef6c74/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200207183749-b753a1ba74fa/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200212150539-ea181f53ac56/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200221224223-e1da425f72fd/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200224181240-023911ca70b2/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200227222343-706bc42d1f0d/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200304193943-95d2e580d8eb/go.mod h1:o4KQGtdN14AW+yjsvvwRTJJuXz8XRtIHtEnmAXLyFUw= +golang.org/x/tools v0.0.0-20200312045724-11d5b4c81c7d/go.mod h1:o4KQGtdN14AW+yjsvvwRTJJuXz8XRtIHtEnmAXLyFUw= +golang.org/x/tools v0.0.0-20200331025713-a30bf2db82d4/go.mod h1:Sl4aGygMT6LrqrWclx+PTx3U+LnKx/seiNR+3G19Ar8= +golang.org/x/tools v0.0.0-20200501065659-ab2804fb9c9d/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= +golang.org/x/tools v0.0.0-20200512131952-2bc93b1c0c88/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= +golang.org/x/tools v0.0.0-20200515010526-7d3b6ebf133d/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= +golang.org/x/tools v0.0.0-20200618134242-20370b0cb4b2/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= +golang.org/x/tools v0.0.0-20200729194436-6467de6f59a7/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= +golang.org/x/tools v0.0.0-20200804011535-6c149bb5ef0d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= +golang.org/x/tools v0.0.0-20200825202427-b303f430e36d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= +golang.org/x/tools v0.0.0-20200904185747-39188db58858/go.mod h1:Cj7w3i3Rnn0Xh82ur9kSqwfTHTeVxaDqrfMjpcNT6bE= golang.org/x/tools v0.0.0-20201224043029-2b0845dc783e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.1.0/go.mod h1:xkSsbof2nBLbhDlRMhhhyNLN/zl3eTqcnHD5viDpcZ0= golang.org/x/tools v0.1.1/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.6-0.20210726203631-07bc1bf47fb2/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= +golang.org/x/tools v0.1.8/go.mod h1:nABZi5QlRsZVlzPpHl034qft6wpY4eDcsTt5AaioBiU= golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= -golang.org/x/tools v0.6.0 h1:BOw41kyTf3PuCW1pVQf8+Cyg8pMlkYB1oo9iJ6D/lKM= -golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU= +golang.org/x/tools v0.7.0 h1:W4OVu8VVOaIO0yzWMNdepAulS7YfoS3Zabrm8DOXXU4= +golang.org/x/tools v0.7.0/go.mod h1:4pg6aUX35JBAogB10C9AtvVL+qowtN4pT3CGSQex14s= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +gonum.org/v1/gonum v0.0.0-20180816165407-929014505bf4/go.mod h1:Y+Yx5eoAFn32cQvJDxZx5Dpnq+c3wtXuadVZAcxbbBo= +gonum.org/v1/gonum v0.0.0-20181121035319-3f7ecaa7e8ca/go.mod h1:Y+Yx5eoAFn32cQvJDxZx5Dpnq+c3wtXuadVZAcxbbBo= +gonum.org/v1/gonum v0.6.0/go.mod h1:9mxDZsDKxgMAuccQkewq682L+0eCu4dCN2yonUJTCLU= +gonum.org/v1/netlib v0.0.0-20181029234149-ec6d1f5cefe6/go.mod h1:wa6Ws7BG/ESfp6dHfk7C6KdzKA7wR7u/rKwOGE66zvw= +gonum.org/v1/netlib v0.0.0-20190313105609-8cb42192e0e0/go.mod h1:wa6Ws7BG/ESfp6dHfk7C6KdzKA7wR7u/rKwOGE66zvw= +gonum.org/v1/plot v0.0.0-20190515093506-e2840ee46a6b/go.mod h1:Wt8AAjI+ypCyYX3nZBvf6cAIx93T+c/OS2HFAYskSZc= +google.golang.org/api v0.0.0-20170921000349-586095a6e407/go.mod h1:4mhQ8q/RsB7i+udVvVy5NUi08OU8ZlA0gRVgrF7VFY0= google.golang.org/api v0.0.0-20180910000450-7ca32eb868bf/go.mod h1:4mhQ8q/RsB7i+udVvVy5NUi08OU8ZlA0gRVgrF7VFY0= google.golang.org/api v0.0.0-20181030000543-1d582fd0359e/go.mod h1:4mhQ8q/RsB7i+udVvVy5NUi08OU8ZlA0gRVgrF7VFY0= google.golang.org/api v0.1.0/go.mod h1:UGEZY7KEX120AnNLIHFMKIo4obdJhkp2tPbaPlQx13Y= google.golang.org/api v0.3.1/go.mod h1:6wY9I6uQWHQ8EM57III9mq/AjF+i8G65rmVagqKMtkk= +google.golang.org/api v0.4.0/go.mod h1:8k5glujaEP+g9n7WNsDg8QP6cUVNI86fCNMcbazEtwE= +google.golang.org/api v0.7.0/go.mod h1:WtwebWUNSVBH/HAw79HIFXZNqEvBhG+Ra+ax0hx3E3M= +google.golang.org/api v0.8.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg= +google.golang.org/api v0.9.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg= +google.golang.org/api v0.13.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI= +google.golang.org/api v0.14.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI= +google.golang.org/api v0.15.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI= +google.golang.org/api v0.17.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= +google.golang.org/api v0.18.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= +google.golang.org/api v0.19.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= +google.golang.org/api v0.20.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= +google.golang.org/api v0.22.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= +google.golang.org/api v0.24.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0MncE= +google.golang.org/api v0.28.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0MncE= +google.golang.org/api v0.29.0/go.mod h1:Lcubydp8VUV7KeIHD9z2Bys/sm/vGKnG1UHuDBSrHWM= +google.golang.org/api v0.30.0/go.mod h1:QGmEvQ87FHZNiUVJkT14jQNYJ4ZJjdRF23ZXz5138Fc= +google.golang.org/api v0.34.0/go.mod h1:/XrVsuzM0rZmrsbjJutiuftIzeuTQcEeaYcSk/mQ1dg= google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= google.golang.org/appengine v1.2.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= google.golang.org/appengine v1.3.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= +google.golang.org/appengine v1.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= +google.golang.org/appengine v1.6.1/go.mod h1:i06prIuMbXzDqacNJfV5OdTW448YApPu5ww/cMBSeb0= +google.golang.org/appengine v1.6.5/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= +google.golang.org/appengine v1.6.6/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= +google.golang.org/appengine v1.6.7/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= +google.golang.org/genproto v0.0.0-20170918111702-1e559d0a00ee/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= google.golang.org/genproto v0.0.0-20180831171423-11092d34479b/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= google.golang.org/genproto v0.0.0-20181029155118-b69ba1387ce2/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= google.golang.org/genproto v0.0.0-20181202183823-bd91e49a0898/go.mod h1:7Ep/1NZk928CDR8SjdVbjWNpdIf6nzjE3BTgJDr2Atg= google.golang.org/genproto v0.0.0-20190306203927-b5d61aea6440/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= google.golang.org/genproto v0.0.0-20190307195333-5fe7a883aa19/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= +google.golang.org/genproto v0.0.0-20190418145605-e7d98fc518a7/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= google.golang.org/genproto v0.0.0-20190425155659-357c62f0e4bb/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= +google.golang.org/genproto v0.0.0-20190502173448-54afdca5d873/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= +google.golang.org/genproto v0.0.0-20190522204451-c2c4e71fbf69/go.mod h1:z3L6/3dTEVtUr6QSP8miRzeRqwQOioJ9I66odjN4I7s= google.golang.org/genproto v0.0.0-20190530194941-fb225487d101/go.mod h1:z3L6/3dTEVtUr6QSP8miRzeRqwQOioJ9I66odjN4I7s= +google.golang.org/genproto v0.0.0-20190716160619-c506a9f90610/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= +google.golang.org/genproto v0.0.0-20190801165951-fa694d86fc64/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= +google.golang.org/genproto v0.0.0-20190911173649-1774047e7e51/go.mod h1:IbNlFCBrqXvoKpeg0TB2l7cyZUmoaFKYIwrEpbDKLA8= +google.golang.org/genproto v0.0.0-20191108220845-16a3f7862a1a/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= +google.golang.org/genproto v0.0.0-20191115194625-c23dd37a84c9/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= +google.golang.org/genproto v0.0.0-20191216164720-4f79533eabd1/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= +google.golang.org/genproto v0.0.0-20191230161307-f3c370f40bfb/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= +google.golang.org/genproto v0.0.0-20200108215221-bd8f9a0ef82f/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= +google.golang.org/genproto v0.0.0-20200115191322-ca5a22157cba/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= +google.golang.org/genproto v0.0.0-20200122232147-0452cf42e150/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= +google.golang.org/genproto v0.0.0-20200204135345-fa8e72b47b90/go.mod h1:GmwEX6Z4W5gMy59cAlVYjN9JhxgbQH6Gn+gFDQe2lzA= +google.golang.org/genproto v0.0.0-20200212174721-66ed5ce911ce/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200218151345-dad8c97a84f5/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200224152610-e50cd9704f63/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200228133532-8c2c7df3a383/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200305110556-506484158171/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200312145019-da6875a35672/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200331122359-1ee6d9798940/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= google.golang.org/genproto v0.0.0-20200423170343-7949de9c1215/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= -google.golang.org/genproto v0.0.0-20230202175211-008b39050e57 h1:vArvWooPH749rNHpBGgVl+U9B9dATjiEhJzcWGlovNs= -google.golang.org/genproto v0.0.0-20230202175211-008b39050e57/go.mod h1:RGgjbofJ8xD9Sq1VVhDM1Vok1vRONV+rg+CjzG4SZKM= +google.golang.org/genproto v0.0.0-20200430143042-b979b6f78d84/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200511104702-f5ebc3bea380/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200513103714-09dca8ec2884/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200515170657-fc4c6c6a6587/go.mod h1:YsZOwe1myG/8QRHRsmBRE1LrgQY60beZKjly0O1fX9U= +google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo= +google.golang.org/genproto v0.0.0-20200618031413-b414f8b61790/go.mod h1:jDfRM7FcilCzHH/e9qn6dsT145K34l5v+OpcnNgKAAA= +google.golang.org/genproto v0.0.0-20200729003335-053ba62fc06f/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20200804131852-c06518451d9c/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20200825200019-8632dd797987/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20200904004341-0bd0a958aa1d/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20201019141844-1ed22bb0c154/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20210426193834-eac7f76ac494/go.mod h1:P3QM42oQyzQSnHPnZ/vqoCdDmzH28fzWByN9asMeM8A= +google.golang.org/genproto v0.0.0-20230306155012-7f2fa6fef1f4 h1:DdoeryqhaXp1LtT/emMP1BRJPHHKFi5akj/nbx/zNTA= +google.golang.org/genproto v0.0.0-20230306155012-7f2fa6fef1f4/go.mod h1:NWraEVixdDnqcqQ30jipen1STv2r/n24Wb7twVTGR4s= +google.golang.org/grpc v1.2.1-0.20170921194603-d4b75ebd4f9f/go.mod h1:yo6s7OP7yaDglbqo1J04qKzAhqBH6lvTonzMVmEdcZw= google.golang.org/grpc v1.14.0/go.mod h1:yo6s7OP7yaDglbqo1J04qKzAhqBH6lvTonzMVmEdcZw= google.golang.org/grpc v1.16.0/go.mod h1:0JHn/cJsOMiMfNA9+DeHDlAU7KAAB5GDlYFpa9MZMio= google.golang.org/grpc v1.17.0/go.mod h1:6QZJwpn2B+Zp71q/5VxRsJ6NXXVCE5NRUHRo+f3cWCs= @@ -1219,46 +2202,80 @@ google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZi google.golang.org/grpc v1.20.0/go.mod h1:chYK+tFQF0nDUGJgXMSgLCQk3phJEuONr2DCgLDdAQM= google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38= google.golang.org/grpc v1.21.0/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM= +google.golang.org/grpc v1.21.1/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM= google.golang.org/grpc v1.22.1/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= google.golang.org/grpc v1.23.1/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY= google.golang.org/grpc v1.26.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= +google.golang.org/grpc v1.27.1/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= +google.golang.org/grpc v1.28.0/go.mod h1:rpkK4SK4GF4Ach/+MFLZUBavHOvF2JJB5uozKKal+60= +google.golang.org/grpc v1.28.1/go.mod h1:rpkK4SK4GF4Ach/+MFLZUBavHOvF2JJB5uozKKal+60= google.golang.org/grpc v1.29.1/go.mod h1:itym6AZVZYACWQqET3MqgPpjcuV5QH3BxFS3IjizoKk= -google.golang.org/grpc v1.53.0 h1:LAv2ds7cmFV/XTS3XG1NneeENYrXGmorPxsBbptIjNc= -google.golang.org/grpc v1.53.0/go.mod h1:OnIrk0ipVdj4N5d9IUoFUx72/VlD7+jUsHwZgwSMQpw= -google.golang.org/grpc/cmd/protoc-gen-go-grpc v1.2.0 h1:TLkBREm4nIsEcexnCjgQd5GQWaHcqMzwQV0TX9pq8S0= -google.golang.org/grpc/cmd/protoc-gen-go-grpc v1.2.0/go.mod h1:DNq5QpG7LJqD2AamLZ7zvKE0DEpVl2BSEVjFycAAjRY= +google.golang.org/grpc v1.30.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak= +google.golang.org/grpc v1.31.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak= +google.golang.org/grpc v1.31.1/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak= +google.golang.org/grpc v1.33.1/go.mod h1:fr5YgcSWrqhRRxogOsw7RzIpsmvOZ6IcH4kBYTpR3n0= +google.golang.org/grpc v1.33.2/go.mod h1:JMHMWHQWaTccqQQlmk3MJZS+GWXOdAesneDmEnv2fbc= +google.golang.org/grpc v1.36.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU= +google.golang.org/grpc v1.36.1/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU= +google.golang.org/grpc v1.40.0/go.mod h1:ogyxbiOoUXAkP+4+xa6PZSE9DZgIHtSpzjDTB9KAK34= +google.golang.org/grpc v1.54.0 h1:EhTqbhiYeixwWQtAEZAxmV9MGqcjEU2mFx52xCzNyag= +google.golang.org/grpc v1.54.0/go.mod h1:PUSEXI6iWghWaB6lXM4knEgpJNu2qUcKfDtNci3EC2g= +google.golang.org/grpc/cmd/protoc-gen-go-grpc v1.0.0/go.mod h1:6Kw0yEErY5E/yWrBtf03jp27GLLJujG4z/JK95pnjjw= +google.golang.org/grpc/cmd/protoc-gen-go-grpc v1.3.0 h1:rNBFJjBCOgVr9pWD7rs/knKL4FRTKgpZmsRfV214zcA= +google.golang.org/grpc/cmd/protoc-gen-go-grpc v1.3.0/go.mod h1:Dk1tviKTvMCz5tvh7t+fh94dhmQVHuCt2OzJB3CTW9Y= google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM= google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miEFZTKqfCUM6K7xSMQL9OKL/b6hQv+e19PK+JZNE= google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo= +google.golang.org/protobuf v1.22.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= +google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= +google.golang.org/protobuf v1.24.0/go.mod h1:r/3tXBNzIEhYS9I1OUVjXDlt8tc493IdKGjtUeSXeh4= +google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c= google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= google.golang.org/protobuf v1.27.1/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= -google.golang.org/protobuf v1.28.1 h1:d0NfwRgPtno5B1Wa6L2DAG+KivqkdutMf1UhdNx175w= -google.golang.org/protobuf v1.28.1/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= +google.golang.org/protobuf v1.30.0 h1:kPPoIgf3TsEvrm0PFe15JQ+570QVxYzEvvHqChK+cng= +google.golang.org/protobuf v1.30.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw= +gopkg.in/bsm/ratelimit.v1 v1.0.0-20160220154919-db14e161995a/go.mod h1:KF9sEfUPAXdG8Oev9e99iLGnl2uJMjc5B+4y3O7x610= +gopkg.in/cenkalti/backoff.v1 v1.1.0/go.mod h1:J6Vskwqd+OMVJl8C33mmtxTBs2gyzfv7UDAkHu8BrjI= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= gopkg.in/cheggaaa/pb.v1 v1.0.25/go.mod h1:V/YB90LKu/1FcN3WVnfiiE5oMCibMjukxqG/qStrOgw= +gopkg.in/d4l3k/messagediff.v1 v1.2.1/go.mod h1:EUzikiKadqXWcD1AzJLagx0j/BeeWGtn++04Xniyg44= gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI= gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys= gopkg.in/gcfg.v1 v1.2.3/go.mod h1:yesOnuUOFQAhST5vPY4nbZsb/huCgGGXlipJsBn0b3o= gopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw= +gopkg.in/jcmturner/aescts.v1 v1.0.1/go.mod h1:nsR8qBOg+OucoIW+WMhB3GspUQXq9XorLnQb9XtvcOo= +gopkg.in/jcmturner/dnsutils.v1 v1.0.1/go.mod h1:m3v+5svpVOhtFAP/wSz+yzh4Mc0Fg7eRhxkJMWSIz9Q= +gopkg.in/jcmturner/goidentity.v3 v3.0.0/go.mod h1:oG2kH0IvSYNIu80dVAyu/yoefjq1mNfM5bm88whjWx4= +gopkg.in/jcmturner/gokrb5.v7 v7.5.0/go.mod h1:l8VISx+WGYp+Fp7KRbsiUuXTTOnxIc3Tuvyavf11/WM= +gopkg.in/jcmturner/rpc.v1 v1.1.0/go.mod h1:YIdkC4XfD6GXbzje11McwsDuOlZQSb9W4vfLvuNnlv8= +gopkg.in/natefinch/lumberjack.v2 v2.2.1 h1:bBRl1b0OH9s/DuPhuXpNl+VtCaJXFZ5/uEFST95x9zc= +gopkg.in/natefinch/lumberjack.v2 v2.2.1/go.mod h1:YD8tP3GAjkrDg1eZH7EGmyESg/lsYskCTPBJVb9jqSc= +gopkg.in/natefinch/npipe.v2 v2.0.0-20160621034901-c1b8fa8bdcce/go.mod h1:5AcXVHNjg+BDxry382+8OKon8SEWiKktQR07RKPsv1c= +gopkg.in/olebedev/go-duktape.v3 v3.0.0-20200619000410-60c24ae608a6/go.mod h1:uAJfkITjFhyEEuUfm7bsmCZRbW5WRq8s9EY8HZ6hCns= +gopkg.in/redis.v4 v4.2.4/go.mod h1:8KREHdypkCEojGKQcjMqAODMICIVwZAONWq8RowTITA= gopkg.in/resty.v1 v1.12.0/go.mod h1:mDo4pnntr5jdWRML875a/NmxYqAlA73dVijT2AXvQQo= +gopkg.in/src-d/go-cli.v0 v0.0.0-20181105080154-d492247bbc0d/go.mod h1:z+K8VcOYVYcSwSjGebuDL6176A1XskgbtNl64NSg+n8= +gopkg.in/src-d/go-log.v1 v1.0.1/go.mod h1:GN34hKP0g305ysm2/hctJ0Y8nWP3zxXXJ8GFabTyABE= gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ= gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw= +gopkg.in/urfave/cli.v1 v1.20.0/go.mod h1:vuBzUtMdQeixQj8LVd+/98pzhxNGQoyuPBlsXHOQNO0= gopkg.in/warnings.v0 v0.1.2/go.mod h1:jksf8JmL6Qr/oQM2OXTHunEvvTAsrWBLb6OOjuVWRNI= gopkg.in/yaml.v2 v2.0.0-20170812160011-eb3733d160e7/go.mod h1:JAlM8MvJe8wmxCU4Bli9HhUf9+ttbYbLASfIpnQbh74= gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.2.3/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.5/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= @@ -1269,15 +2286,31 @@ gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +gotest.tools v2.2.0+incompatible/go.mod h1:DsYFclhRJ6vuDpmuTbkuFWG+y2sxOXAzmJt81HFBacw= gotest.tools/v3 v3.3.0 h1:MfDY1b1/0xN1CyMlQDac0ziEy9zJQd9CXBRRDHw2jJo= gotest.tools/v3 v3.3.0/go.mod h1:Mcr9QNxkg0uMvy/YElmo4SpXgJKWgQvYrT7Kw5RzJ1A= grpc.go4.org v0.0.0-20170609214715-11d0a25b4919/go.mod h1:77eQGdRu53HpSqPFJFmuJdjuHRquDANNeA4x7B8WQ9o= honnef.co/go/tools v0.0.0-20180728063816-88497007e858/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= +honnef.co/go/tools v0.0.0-20190418001031-e561f6794a2a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg= +honnef.co/go/tools v0.0.1-2020.1.3/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k= +honnef.co/go/tools v0.0.1-2020.1.4/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k= honnef.co/go/tools v0.1.3/go.mod h1:NgwopIslSNH47DimFoV78dnkksY2EFtX0ajyb3K/las= +k8s.io/api v0.18.3/go.mod h1:UOaMwERbqJMfeeeHc8XJKawj4P9TgDRnViIqqBeH2QA= +k8s.io/apimachinery v0.18.3/go.mod h1:OaXp26zu/5J7p0f92ASynJa1pZo06YlV9fG7BoWbCko= +k8s.io/client-go v0.18.3/go.mod h1:4a/dpQEvzAhT1BbuWW09qvIaGw6Gbu1gZYiQZIi1DMw= +k8s.io/gengo v0.0.0-20190128074634-0689ccc1d7d6/go.mod h1:ezvh/TsK7cY6rbqRK0oQQ8IAqLxYwwyPxAX1Pzy0ii0= +k8s.io/klog v0.0.0-20181102134211-b9b56d5dfc92/go.mod h1:Gq+BEi5rUBO/HRz0bTSXDUcqjScdoY3a9IHpCEIOOfk= +k8s.io/klog v0.3.0/go.mod h1:Gq+BEi5rUBO/HRz0bTSXDUcqjScdoY3a9IHpCEIOOfk= +k8s.io/klog v1.0.0/go.mod h1:4Bi6QPql/J/LkTDqv7R/cd3hPo4k2DG6Ptcz060Ez5I= +k8s.io/klog/v2 v2.0.0/go.mod h1:PBfzABfn139FHAV07az/IF9Wp1bkk3vpT2XSJ76fSDE= +k8s.io/klog/v2 v2.3.0/go.mod h1:Od+F08eJP+W3HUb4pSrPpgp9DGU4GzlpG/TmITuYh/Y= +k8s.io/kube-openapi v0.0.0-20200410145947-61e04a5be9a6/go.mod h1:GRQhZsXIAJ1xR0C9bd8UpWHZ5plfAS9fzPjJuQ6JL3E= +k8s.io/utils v0.0.0-20200324210504-a9aa75ae1b89/go.mod h1:sZAwmy6armz5eXlNoLmJcl4F1QuKu7sr+mFQ0byX7Ew= +k8s.io/utils v0.0.0-20200520001619-278ece378a50/go.mod h1:jPW/WVKK9YHAvNhRxK0md/EJ228hCsBRufyofKtW8HA= lukechampine.com/blake3 v1.1.7 h1:GgRMhmdsuK8+ii6UZFDL8Nb+VyMwadAgcJyfYHxG6n0= lukechampine.com/blake3 v1.1.7/go.mod h1:tkKEOtDkNtklkXtLNEOGNq5tcV90tJiA1vAA12R78LA= lukechampine.com/uint128 v1.2.0 h1:mBi/5l91vocEN8otkC5bDLhi2KdCticRiwbdB0O+rjI= @@ -1296,8 +2329,8 @@ modernc.org/memory v1.5.0 h1:N+/8c5rE6EqugZwHii4IFsaJ7MUhoWX07J5tC/iI5Ds= modernc.org/memory v1.5.0/go.mod h1:PkUhL0Mugw21sHPeskwZW4D6VscE/GQJOnIpCnW6pSU= modernc.org/opt v0.1.3 h1:3XOZf2yznlhC+ibLltsDGzABUGVx8J6pnFMS3E4dcq4= modernc.org/opt v0.1.3/go.mod h1:WdSiB5evDcignE70guQKxYUl14mgWtbClRi5wmkkTX0= -modernc.org/sqlite v1.21.0 h1:4aP4MdUf15i3R3M2mx6Q90WHKz3nZLoz96zlB6tNdow= -modernc.org/sqlite v1.21.0/go.mod h1:XwQ0wZPIh1iKb5mkvCJ3szzbhk+tykC8ZWqTRTgYRwI= +modernc.org/sqlite v1.21.1 h1:GyDFqNnESLOhwwDRaHGdp2jKLDzpyT/rNLglX3ZkMSU= +modernc.org/sqlite v1.21.1/go.mod h1:XwQ0wZPIh1iKb5mkvCJ3szzbhk+tykC8ZWqTRTgYRwI= modernc.org/strutil v1.1.3 h1:fNMm+oJklMGYfU9Ylcywl0CO5O6nTfaowNsh2wpPjzY= modernc.org/strutil v1.1.3/go.mod h1:MEHNA7PdEnEwLvspRMtWTNnp2nnyvMfkimT1NKNAGbw= modernc.org/tcl v1.15.1 h1:mOQwiEK4p7HruMZcwKTZPw/aqtGM4aY00uzWhlKKYws= @@ -1308,7 +2341,16 @@ nhooyr.io/websocket v1.8.7 h1:usjR2uOr/zjjkVMy0lW+PPohFok7PCow5sDjLgX4P4g= nhooyr.io/websocket v1.8.7/go.mod h1:B70DZP8IakI65RVQ51MsWP/8jndNma26DVA/nFSCgW0= pgregory.net/rapid v0.5.5 h1:jkgx1TjbQPD/feRoK+S/mXw9e1uj6WilpHrXJowi6oA= pgregory.net/rapid v0.5.5/go.mod h1:PY5XlDGj0+V1FCq0o192FdRhpKHGTRIWBgqjDBTrq04= +rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8= +rsc.io/pdf v0.1.1/go.mod h1:n8OzWcQ6Sp37PL01nO98y4iUCRdTGarVfzxY20ICaU4= +rsc.io/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0= +rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA= +rsc.io/tmplfunc v0.0.3 h1:53XFQh69AfOa8Tw0Jm7t+GV7KZhOi6jzsCzTtKbMvzU= +rsc.io/tmplfunc v0.0.3/go.mod h1:AG3sTPzElb1Io3Yg4voV9AGZJuleGAwaVRxL9M49PhA= +sigs.k8s.io/structured-merge-diff/v3 v3.0.0-20200116222232-67a7b8c61874/go.mod h1:PlARxl6Hbt/+BC80dRLi1qAmnMqwqDg62YvvVkZjemw= +sigs.k8s.io/structured-merge-diff/v3 v3.0.0/go.mod h1:PlARxl6Hbt/+BC80dRLi1qAmnMqwqDg62YvvVkZjemw= sigs.k8s.io/yaml v1.1.0/go.mod h1:UJmg0vDUVViEyp3mgSv9WPwZCDxu4rQW1olrI1uml+o= +sigs.k8s.io/yaml v1.2.0/go.mod h1:yfXDCHCao9+ENCvLSE62v9VSji2MKu5jeNfTrofGhJc= sourcegraph.com/sourcegraph/appdash v0.0.0-20190731080439-ebfcffb1b5c0/go.mod h1:hI742Nqp5OhwiqlzhgfbWU4mW4yO10fP+LoT9WOswdU= sourcegraph.com/sourcegraph/go-diff v0.5.0/go.mod h1:kuch7UrkMzY0X+p9CRK03kfuPQ2zzQcaEFbx8wA8rck= sourcegraph.com/sqs/pbtypes v0.0.0-20180604144634-d3ebe8f20ae4/go.mod h1:ketZ/q3QxT9HOBeFhu6RdvsftgpsbFHBF5Cas6cDKZ0= diff --git a/interfaces.go b/interfaces.go index 9c46a3b763c..1f6126f33a7 100644 --- a/interfaces.go +++ b/interfaces.go @@ -116,16 +116,18 @@ type ChainSyncReader interface { // CallMsg contains parameters for contract calls. type CallMsg struct { - From libcommon.Address // the sender of the 'transaction' - To *libcommon.Address // the destination contract (nil for contract creation) - Gas uint64 // if 0, the call executes with near-infinite gas - GasPrice *uint256.Int // wei <-> gas exchange ratio - Value *uint256.Int // amount of wei sent along with the call - Data []byte // input data, usually an ABI-encoded contract method invocation + From libcommon.Address // the sender of the 'transaction' + To *libcommon.Address // the destination contract (nil for contract creation) + Gas uint64 // if 0, the call executes with near-infinite gas + MaxFeePerDataGas *uint256.Int // EIP-4844 max_fee_per_data_gas + GasPrice *uint256.Int // wei <-> gas exchange ratio + Value *uint256.Int // amount of wei sent along with the call + Data []byte // input data, usually an ABI-encoded contract method invocation FeeCap *uint256.Int // EIP-1559 fee cap per gas. Tip *uint256.Int // EIP-1559 tip per gas. AccessList types2.AccessList // EIP-2930 access list. + DataHashes []libcommon.Hash // EIP-4844 versioned data hashes. } // A ContractCaller provides contract calls, essentially transactions that are executed by diff --git a/node/node.go b/node/node.go index 5647a02fdd7..722298ee665 100644 --- a/node/node.go +++ b/node/node.go @@ -284,7 +284,7 @@ func (n *Node) DataDir() string { return n.config.Dirs.DataDir } -func OpenDatabase(config *nodecfg.Config, logger log.Logger, label kv.Label) (kv.RwDB, error) { +func OpenDatabase(config *nodecfg.Config, label kv.Label) (kv.RwDB, error) { var name string switch label { case kv.ChainDB: @@ -309,14 +309,14 @@ func OpenDatabase(config *nodecfg.Config, logger log.Logger, label kv.Label) (kv roTxLimit = int64(config.Http.DBReadConcurrency) } roTxsLimiter := semaphore.NewWeighted(roTxLimit) // 1 less than max to allow unlocking to happen - opts := mdbx.NewMDBX(logger). + opts := mdbx.NewMDBX(log.Root()). Path(dbPath).Label(label). DBVerbosity(config.DatabaseVerbosity).RoTxsLimiter(roTxsLimiter) if exclusive { opts = opts.Exclusive() } if label == kv.ChainDB { - opts = opts.PageSize(config.MdbxPageSize.Bytes()).MapSize(8 * datasize.TB) + opts = opts.PageSize(config.MdbxPageSize.Bytes()).MapSize(config.MdbxDBSizeLimit) } else { opts = opts.GrowthStep(16 * datasize.MB) } diff --git a/node/node_test.go b/node/node_test.go index 3be75b5a4a7..1cb528474fe 100644 --- a/node/node_test.go +++ b/node/node_test.go @@ -28,7 +28,6 @@ import ( "github.com/ledgerwatch/erigon/crypto" "github.com/ledgerwatch/erigon/node/nodecfg" "github.com/ledgerwatch/erigon/p2p" - "github.com/ledgerwatch/log/v3" "github.com/stretchr/testify/require" ) @@ -146,7 +145,7 @@ func TestNodeCloseClosesDB(t *testing.T) { stack, _ := New(testNodeConfig(t)) defer stack.Close() - db, err := OpenDatabase(stack.Config(), log.New(), kv.SentryDB) + db, err := OpenDatabase(stack.Config(), kv.SentryDB) if err != nil { t.Fatal("can't open DB:", err) } @@ -177,7 +176,7 @@ func TestNodeOpenDatabaseFromLifecycleStart(t *testing.T) { var db kv.RwDB stack.RegisterLifecycle(&InstrumentedService{ startHook: func() { - db, err = OpenDatabase(stack.Config(), log.New(), kv.SentryDB) + db, err = OpenDatabase(stack.Config(), kv.SentryDB) if err != nil { t.Fatal("can't open DB:", err) } @@ -202,7 +201,7 @@ func TestNodeOpenDatabaseFromLifecycleStop(t *testing.T) { stack.RegisterLifecycle(&InstrumentedService{ stopHook: func() { - db, err := OpenDatabase(stack.Config(), log.New(), kv.ChainDB) + db, err := OpenDatabase(stack.Config(), kv.ChainDB) if err != nil { t.Fatal("can't open DB:", err) } diff --git a/node/nodecfg/config.go b/node/nodecfg/config.go index 96d52302146..cdb353e6acd 100644 --- a/node/nodecfg/config.go +++ b/node/nodecfg/config.go @@ -163,7 +163,8 @@ type Config struct { TLSKeyFile string TLSCACert string - MdbxPageSize datasize.ByteSize + MdbxPageSize datasize.ByteSize + MdbxDBSizeLimit datasize.ByteSize // HealthCheck enables standard grpc health check HealthCheck bool diff --git a/p2p/enode/nodedb.go b/p2p/enode/nodedb.go index cde82c9dac1..e3d5d1b9368 100644 --- a/p2p/enode/nodedb.go +++ b/p2p/enode/nodedb.go @@ -102,7 +102,7 @@ func bucketsConfig(_ kv.TableCfg) kv.TableCfg { func newMemoryDB(logger log.Logger, tmpDir string) (*DB, error) { db := &DB{quit: make(chan struct{})} var err error - db.kv, err = mdbx.NewMDBX(logger).InMem(tmpDir).Label(kv.SentryDB).WithTableCfg(bucketsConfig).Open() + db.kv, err = mdbx.NewMDBX(logger).InMem(tmpDir).Label(kv.SentryDB).WithTableCfg(bucketsConfig).MapSize(1 * datasize.GB).Open() if err != nil { return nil, err } diff --git a/params/bootnodes.go b/params/bootnodes.go index f9060eb4dee..b2bad918af4 100644 --- a/params/bootnodes.go +++ b/params/bootnodes.go @@ -73,6 +73,7 @@ var BscBootnodes = []string{ "enode://28b1d16562dac280dacaaf45d54516b85bc6c994252a9825c5cc4e080d3e53446d05f63ba495ea7d44d6c316b54cd92b245c5c328c37da24605c4a93a0d099c4@34.246.65.14:30311", "enode://5a7b996048d1b0a07683a949662c87c09b55247ce774aeee10bb886892e586e3c604564393292e38ef43c023ee9981e1f8b335766ec4f0f256e57f8640b079d5@35.73.137.11:30311", } + var SepoliaStaticPeers = []string{ // from https://github.com/ledgerwatch/erigon/issues/6134#issuecomment-1354923418 "enode://8ae4559db1b1e160be8cc46018d7db123ed6d03fbbfe481da5ec05f71f0aa4d5f4b02ad059127096aa994568706a0d02933984083b87c5e1e3de2b7692444d37@35.161.233.158:46855", @@ -90,6 +91,11 @@ var SepoliaStaticPeers = []string{ "enode://66158b31eecff939f220b291d2b448edbfe94f1d4c992d9395b5d476e55e54b5abd11d3ee44daf1e18ee27b910ef99cdf6f19775eb4820ebe4f77d7aa948e3b6@51.195.63.10:55198", "enode://bf94acbd51170bf075cacb9f149b21ff46354d659ab434a0d40688f776e1e1556bc62be2dc2867ba513844268c0dc8240099a6b60efe1713fbc25da7fdeb6ff1@3.82.105.139:30303", "enode://41329e5ceb51cdddbe6a475db00b682505768b71ff8ee37d2d3500ca1b78918f9fad57d6006dd9f79cd418437dbcf87ec2fd58d60710f925cb17da05a51197cf@65.21.34.60:30303", + "enode://4e5e92199ee224a01932a377160aa432f31d0b351f84ab413a8e0a42f4f36476f8fb1cbe914af0d9aef0d51665c214cf653c651c4bbd9d5550a934f241f1682b@138.197.51.181:30303", + "enode://143e11fb766781d22d92a2e33f8f104cddae4411a122295ed1fdb6638de96a6ce65f5b7c964ba3763bba27961738fef7d3ecc739268f3e5e771fb4c87b6234ba@146.190.1.103:30303", + "enode://8b61dc2d06c3f96fddcbebb0efb29d60d3598650275dc469c22229d3e5620369b0d3dedafd929835fe7f489618f19f456fe7c0df572bf2d914a9f4e006f783a9@170.64.250.88:30303", + "enode://10d62eff032205fcef19497f35ca8477bea0eadfff6d769a147e895d8b2b8f8ae6341630c645c30f5df6e67547c03494ced3d9c5764e8622a26587b083b028e8@139.59.49.206:30303", + "enode://9e9492e2e8836114cc75f5b929784f4f46c324ad01daf87d956f98b3b6c5fcba95524d6e5cf9861dc96a2c8a171ea7105bb554a197455058de185fa870970c7c@138.68.123.152:30303", } var BscStaticPeers = []string{ @@ -186,13 +192,6 @@ var ChapelStaticPeers = []string{ var RialtoBootnodes = []string{} var RialtoStaticPeers = ChapelStaticPeers -var SokolBootnodes = []string{ - "enode://f11a0f80939b49a28bf99581da9b351a592ec1504b9d32a7dfda79b36510a891e96631239c4166e5c73368c21e9bb3241e7fd6929b899772e5a8fe9a7b7c3af6@45.77.52.149:30303", - "enode://e08adce358fc26dfbe1f24ee578dceaa29575ca44a39d9041203131db5135aceba6241840a9b57b1540eeaf7b4eff1aead28a74641be43342c35af454abb31b3@199.247.18.10:30313", - "enode://f1a5100a81cb73163ae450c584d06b1f644aa4fad4486c6aeb4c384b343c54bb66c744aa5f133af66ea1b25f0f4a454f04878f3e96ee4cd2390c047396d6357b@209.97.158.4:30303", - "enode://f11a0f80939b49a28bf99581da9b351a592ec1504b9d32a7dfda79b36510a891e96631239c4166e5c73368c21e9bb3241e7fd6929b899772e5a8fe9a7b7c3af6@45.77.52.149:30303", -} - var V5Bootnodes = []string{ // Teku team's bootnode "enr:-KG4QOtcP9X1FbIMOe17QNMKqDxCpm14jcX5tiOE4_TyMrFqbmhPZHK_ZPG2Gxb1GE2xdtodOfx9-cgvNtxnRyHEmC0ghGV0aDKQ9aX9QgAAAAD__________4JpZIJ2NIJpcIQDE8KdiXNlY3AyNTZrMaEDhpehBDbZjM_L9ek699Y7vhUJ-eAdMyQW_Fil522Y0fODdGNwgiMog3VkcIIjKA", @@ -278,8 +277,6 @@ func BootnodeURLsOfChain(chain string) []string { return ChapelBootnodes case networkname.RialtoChainName: return RialtoBootnodes - case networkname.SokolChainName: - return SokolBootnodes case networkname.MumbaiChainName: return MumbaiBootnodes case networkname.BorMainnetChainName: diff --git a/params/chainspecs/bsc.json b/params/chainspecs/bsc.json index da944f274c0..254388101d1 100644 --- a/params/chainspecs/bsc.json +++ b/params/chainspecs/bsc.json @@ -1,28 +1,28 @@ { - "ChainName": "bsc", - "chainId": 56, - "consensus": "parlia", - "homesteadBlock": 0, - "eip150Block": 0, - "eip150Hash": "0x0000000000000000000000000000000000000000000000000000000000000000", - "eip155Block": 0, - "byzantiumBlock": 0, - "constantinopleBlock": 0, - "petersburgBlock": 0, - "istanbulBlock": 0, - "muirGlacierBlock": 0, - "ramanujanBlock": 0, - "nielsBlock": 0, - "mirrorSyncBlock": 5184000, - "brunoBlock": 13082000, - "eulerBlock": 18907621, - "nanoBlock": 21962149, - "moranBlock": 22107423, - "gibbsBlock": 23846001, - "parlia": { - "DBPath": "", - "InMemory": false, - "period": 3, - "epoch": 200 - } + "ChainName": "bsc", + "chainId": 56, + "consensus": "parlia", + "homesteadBlock": 0, + "eip150Block": 0, + "eip155Block": 0, + "byzantiumBlock": 0, + "constantinopleBlock": 0, + "petersburgBlock": 0, + "istanbulBlock": 0, + "muirGlacierBlock": 0, + "ramanujanBlock": 0, + "nielsBlock": 0, + "mirrorSyncBlock": 5184000, + "brunoBlock": 13082000, + "eulerBlock": 18907621, + "nanoBlock": 21962149, + "moranBlock": 22107423, + "gibbsBlock": 23846001, + "planckBlock": 27281024, + "parlia": { + "DBPath": "", + "InMemory": false, + "period": 3, + "epoch": 200 + } } \ No newline at end of file diff --git a/params/chainspecs/chapel.json b/params/chainspecs/chapel.json index 78cd5f30775..bdf76d5cd41 100644 --- a/params/chainspecs/chapel.json +++ b/params/chainspecs/chapel.json @@ -4,7 +4,6 @@ "consensus": "parlia", "homesteadBlock": 0, "eip150Block": 0, - "eip150Hash": "0x0000000000000000000000000000000000000000000000000000000000000000", "eip155Block": 0, "byzantiumBlock": 0, "constantinopleBlock": 0, @@ -19,10 +18,12 @@ "gibbsBlock": 22800220, "nanoBlock": 23482428, "moranBlock": 23603940, + "planckBlock": 28196022, + "lubanBlock": 29295050, "parlia": { "DBPath": "", "InMemory": false, "period": 3, "epoch": 200 } -} +} \ No newline at end of file diff --git a/params/chainspecs/chiado.json b/params/chainspecs/chiado.json index e1c6ab4d57b..de2e2f64f58 100644 --- a/params/chainspecs/chiado.json +++ b/params/chainspecs/chiado.json @@ -10,7 +10,6 @@ "constantinopleBlock": 0, "petersburgBlock": 0, "istanbulBlock": 0, - "posdaoBlock": 0, "berlinBlock": 0, "londonBlock": 0, "eip1559FeeCollectorTransition": 0, @@ -18,8 +17,37 @@ "terminalTotalDifficulty": 231707791542740786049188744689299064356246512, "terminalTotalDifficultyPassed": true, "aura": { - "DBPath": "", - "InMemory": false, - "Etherbase": "0x0000000000000000000000000000000000000000" + "stepDuration": 5, + "blockReward": 0, + "maximumUncleCountTransition": 0, + "maximumUncleCount": 0, + "validators": { + "multi": { + "0": { + "list": ["0x14747a698Ec1227e6753026C08B29b4d5D3bC484"] + }, + "67334": { + "list": [ + "0x14747a698Ec1227e6753026C08B29b4d5D3bC484", + "0x56D421c0AC39976E89fa400d34ca6579417B84cA", + "0x5CD99ac2F0F8C25a1e670F6BaB19D52Aad69D875", + "0x60F1CF46B42Df059b98Acf67C1dD7771b100e124", + "0x655e97bA0f63A56c2b56EB3e84f7bf42b20Bae14", + "0x755B6259938D140626301c0B6026c1C00C9eD5d9", + "0xa8010da9Cb0AC018C86A06301963853CC371a18c" + ] + } + } + }, + "blockRewardContractAddress": "0x2000000000000000000000000000000000000001", + "blockRewardContractTransition": 0, + "randomnessContractAddress": { + "0": "0x3000000000000000000000000000000000000001" + }, + "posdaoTransition": 0, + "blockGasLimitContractTransitions": { + "0": "0x4000000000000000000000000000000000000001" + }, + "registrar": "0x6000000000000000000000000000000000000000" } } diff --git a/params/chainspecs/gnosis.json b/params/chainspecs/gnosis.json index 7f1d730684e..65568965b4b 100644 --- a/params/chainspecs/gnosis.json +++ b/params/chainspecs/gnosis.json @@ -10,7 +10,6 @@ "constantinopleBlock": 1604400, "petersburgBlock": 2508800, "istanbulBlock": 7298030, - "posdaoBlock": 9186425, "berlinBlock": 16101500, "londonBlock": 19040000, "eip1559FeeCollectorTransition": 19040000, @@ -18,8 +17,39 @@ "terminalTotalDifficulty": 8626000000000000000000058750000000000000000000, "terminalTotalDifficultyPassed": true, "aura": { - "DBPath": "", - "InMemory": false, - "Etherbase": "0x0000000000000000000000000000000000000000" + "stepDuration": 5, + "blockReward": 0, + "maximumUncleCountTransition": 0, + "maximumUncleCount": 0, + "validators": { + "multi": { + "0": { + "list": [ + "0xcace5b3c29211740e595850e80478416ee77ca21" + ] + }, + "1300": { + "safeContract": "0x22e1229a2c5b95a60983b5577f745a603284f535" + }, + "9186425": { + "contract": "0xB87BE9f7196F2AE084Ca1DE6af5264292976e013" + } + } + }, + "blockRewardContractAddress": "0x867305d19606aadba405ce534e303d0e225f9556", + "blockRewardContractTransition": 1310, + "blockRewardContractTransitions": { + "9186425": "0x481c034c6d9441db23ea48de68bcae812c5d39ba" + }, + "randomnessContractAddress": { + "9186425": "0x5870b0527DeDB1cFBD9534343Feda1a41Ce47766" + }, + "posdaoTransition": 9186425, + "registrar": "0x6B53721D4f2Fb9514B85f5C49b197D857e36Cf03", + "rewriteBytecode": { + "21735000": { + "0xf8D1677c8a0c961938bf2f9aDc3F3CFDA759A9d9": "0x6080604052600436106101b35763ffffffff60e060020a60003504166305d2035b81146101b857806306fdde03146101e1578063095ea7b31461026b5780630b26cf661461028f57806318160ddd146102b257806323b872dd146102d957806330adf81f14610303578063313ce567146103185780633644e5151461034357806339509351146103585780634000aea01461037c57806340c10f19146103ad57806342966c68146103d157806354fd4d50146103e957806366188463146103fe57806369ffa08a1461042257806370a0823114610449578063715018a61461046a578063726600ce1461047f5780637d64bcb4146104a05780637ecebe00146104b5578063859ba28c146104d65780638da5cb5b146105175780638fcbaf0c1461054857806395d89b4114610586578063a457c2d71461059b578063a9059cbb146105bf578063b753a98c146105e3578063bb35783b14610607578063c6a1dedf14610631578063cd59658314610646578063d505accf1461065b578063d73dd62314610694578063dd62ed3e146106b8578063f2d5d56b146106df578063f2fde38b14610703578063ff9e884d14610724575b600080fd5b3480156101c457600080fd5b506101cd61074b565b604080519115158252519081900360200190f35b3480156101ed57600080fd5b506101f661076c565b6040805160208082528351818301528351919283929083019185019080838360005b83811015610230578181015183820152602001610218565b50505050905090810190601f16801561025d5780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b34801561027757600080fd5b506101cd600160a060020a03600435166024356107fa565b34801561029b57600080fd5b506102b0600160a060020a0360043516610810565b005b3480156102be57600080fd5b506102c761086a565b60408051918252519081900360200190f35b3480156102e557600080fd5b506101cd600160a060020a0360043581169060243516604435610870565b34801561030f57600080fd5b506102c7610a38565b34801561032457600080fd5b5061032d610a5c565b6040805160ff9092168252519081900360200190f35b34801561034f57600080fd5b506102c7610a65565b34801561036457600080fd5b506101cd600160a060020a0360043516602435610a6b565b34801561038857600080fd5b506101cd60048035600160a060020a0316906024803591604435918201910135610aac565b3480156103b957600080fd5b506101cd600160a060020a0360043516602435610bbd565b3480156103dd57600080fd5b506102b0600435610cc8565b3480156103f557600080fd5b506101f6610cd5565b34801561040a57600080fd5b506101cd600160a060020a0360043516602435610d0c565b34801561042e57600080fd5b506102b0600160a060020a0360043581169060243516610de9565b34801561045557600080fd5b506102c7600160a060020a0360043516610e0e565b34801561047657600080fd5b506102b0610e29565b34801561048b57600080fd5b506101cd600160a060020a0360043516610e40565b3480156104ac57600080fd5b506101cd610e54565b3480156104c157600080fd5b506102c7600160a060020a0360043516610e5b565b3480156104e257600080fd5b506104eb610e6d565b6040805167ffffffffffffffff9485168152928416602084015292168183015290519081900360600190f35b34801561052357600080fd5b5061052c610e78565b60408051600160a060020a039092168252519081900360200190f35b34801561055457600080fd5b506102b0600160a060020a0360043581169060243516604435606435608435151560ff60a4351660c43560e435610e87565b34801561059257600080fd5b506101f6610fc5565b3480156105a757600080fd5b506101cd600160a060020a036004351660243561101f565b3480156105cb57600080fd5b506101cd600160a060020a0360043516602435611032565b3480156105ef57600080fd5b506102b0600160a060020a0360043516602435611054565b34801561061357600080fd5b506102b0600160a060020a0360043581169060243516604435611064565b34801561063d57600080fd5b506102c7611075565b34801561065257600080fd5b5061052c611099565b34801561066757600080fd5b506102b0600160a060020a036004358116906024351660443560643560ff6084351660a43560c4356110a8565b3480156106a057600080fd5b506101cd600160a060020a0360043516602435611184565b3480156106c457600080fd5b506102c7600160a060020a036004358116906024351661120b565b3480156106eb57600080fd5b506102b0600160a060020a0360043516602435611236565b34801561070f57600080fd5b506102b0600160a060020a0360043516611241565b34801561073057600080fd5b506102c7600160a060020a0360043581169060243516611261565b60065474010000000000000000000000000000000000000000900460ff1681565b6000805460408051602060026001851615610100026000190190941693909304601f810184900484028201840190925281815292918301828280156107f25780601f106107c7576101008083540402835291602001916107f2565b820191906000526020600020905b8154815290600101906020018083116107d557829003601f168201915b505050505081565b600061080733848461127e565b50600192915050565b600654600160a060020a0316331461082757600080fd5b610830816112c0565b151561083b57600080fd5b6007805473ffffffffffffffffffffffffffffffffffffffff1916600160a060020a0392909216919091179055565b60045490565b600080600160a060020a038516151561088857600080fd5b600160a060020a038416151561089d57600080fd5b600160a060020a0385166000908152600360205260409020546108c6908463ffffffff6112c816565b600160a060020a0380871660009081526003602052604080822093909355908616815220546108fb908463ffffffff6112da16565b600160a060020a038086166000818152600360209081526040918290209490945580518781529051919392891692600080516020611d7283398151915292918290030190a3600160a060020a0385163314610a225761095a853361120b565b905060001981146109c457610975818463ffffffff6112c816565b600160a060020a038616600081815260056020908152604080832033808552908352928190208590558051948552519193600080516020611d92833981519152929081900390910190a3610a22565b600160a060020a0385166000908152600a602090815260408083203384529091529020541580610a175750600160a060020a0385166000908152600a602090815260408083203384529091529020544211155b1515610a2257600080fd5b610a2d8585856112ed565b506001949350505050565b7f6e71edae12b1b97f4d1f60370fef10105fa2faae0126114a169c64845d6126c981565b60025460ff1681565b60085481565b336000818152600560209081526040808320600160a060020a03871684529091528120549091610807918590610aa7908663ffffffff6112da16565b61127e565b600084600160a060020a03811615801590610ad05750600160a060020a0381163014155b1515610adb57600080fd5b610ae58686611324565b1515610af057600080fd5b85600160a060020a031633600160a060020a03167fe19260aff97b920c7df27010903aeb9c8d2be5d310a2c67824cf3f15396e4c16878787604051808481526020018060200182810382528484828181526020019250808284376040519201829003965090945050505050a3610b65866112c0565b15610bb157610ba633878787878080601f01602080910402602001604051908101604052809392919081815260200183838082843750611330945050505050565b1515610bb157600080fd5b50600195945050505050565b600654600090600160a060020a03163314610bd757600080fd5b60065474010000000000000000000000000000000000000000900460ff1615610bff57600080fd5b600454610c12908363ffffffff6112da16565b600455600160a060020a038316600090815260036020526040902054610c3e908363ffffffff6112da16565b600160a060020a038416600081815260036020908152604091829020939093558051858152905191927f0f6798a560793a54c3bcfe86a93cde1e73087d944c0ea20544137d412139688592918290030190a2604080518381529051600160a060020a03851691600091600080516020611d728339815191529181900360200190a350600192915050565b610cd233826114ad565b50565b60408051808201909152600181527f3100000000000000000000000000000000000000000000000000000000000000602082015281565b336000908152600560209081526040808320600160a060020a0386168452909152812054808310610d6057336000908152600560209081526040808320600160a060020a0388168452909152812055610d95565b610d70818463ffffffff6112c816565b336000908152600560209081526040808320600160a060020a03891684529091529020555b336000818152600560209081526040808320600160a060020a038916808552908352928190205481519081529051929392600080516020611d92833981519152929181900390910190a35060019392505050565b600654600160a060020a03163314610e0057600080fd5b610e0a828261159c565b5050565b600160a060020a031660009081526003602052604090205490565b600654600160a060020a031633146101b357600080fd5b600754600160a060020a0390811691161490565b6000806000fd5b60096020526000908152604090205481565b600260056000909192565b600654600160a060020a031681565b600080861580610e975750864211155b1515610ea257600080fd5b604080517fea2aa0a1be11a07ed86d755c93467f4f82362b452371d1ba94d1715123511acb6020820152600160a060020a03808d16828401528b166060820152608081018a905260a0810189905287151560c0808301919091528251808303909101815260e0909101909152610f17906115da565b9150610f25828686866116e1565b600160a060020a038b8116911614610f3c57600080fd5b600160a060020a038a1660009081526009602052604090208054600181019091558814610f6857600080fd5b85610f74576000610f78565b6000195b905085610f86576000610f88565b865b600160a060020a03808c166000908152600a60209081526040808320938e1683529290522055610fb98a8a836118e3565b50505050505050505050565b60018054604080516020600284861615610100026000190190941693909304601f810184900484028201840190925281815292918301828280156107f25780601f106107c7576101008083540402835291602001916107f2565b600061102b8383610d0c565b9392505050565b600061103e8383611324565b151561104957600080fd5b6108073384846112ed565b61105f338383610870565b505050565b61106f838383610870565b50505050565b7fea2aa0a1be11a07ed86d755c93467f4f82362b452371d1ba94d1715123511acb81565b600754600160a060020a031690565b600080428610156110b857600080fd5b600160a060020a03808a1660008181526009602090815260409182902080546001810190915582517f6e71edae12b1b97f4d1f60370fef10105fa2faae0126114a169c64845d6126c99281019290925281830193909352928b166060840152608083018a905260a0830182905260c08084018a90528151808503909101815260e090930190529250611149906115da565b9050611157818686866116e1565b600160a060020a038a811691161461116e57600080fd5b61117989898961127e565b505050505050505050565b336000908152600560209081526040808320600160a060020a03861684529091528120546111b8908363ffffffff6112da16565b336000818152600560209081526040808320600160a060020a038916808552908352928190208590558051948552519193600080516020611d92833981519152929081900390910190a350600192915050565b600160a060020a03918216600090815260056020908152604080832093909416825291909152205490565b61105f823383610870565b600654600160a060020a0316331461125857600080fd5b610cd281611a3e565b600a60209081526000928352604080842090915290825290205481565b6112898383836118e3565b60001981141561105f57600160a060020a038084166000908152600a60209081526040808320938616835292905290812055505050565b6000903b1190565b6000828211156112d457fe5b50900390565b818101828110156112e757fe5b92915050565b6112f682610e40565b1561105f5760408051600081526020810190915261131990849084908490611330565b151561105f57600080fd5b600061102b8383611abc565b600083600160a060020a031663a4c0ed3660e060020a028685856040516024018084600160a060020a0316600160a060020a0316815260200183815260200180602001828103825283818151815260200191508051906020019080838360005b838110156113a8578181015183820152602001611390565b50505050905090810190601f1680156113d55780820380516001836020036101000a031916815260200191505b5060408051601f198184030181529181526020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff00000000000000000000000000000000000000000000000000000000909916989098178852518151919790965086955093509150819050838360005b8381101561146357818101518382015260200161144b565b50505050905090810190601f1680156114905780820380516001836020036101000a031916815260200191505b509150506000604051808303816000865af1979650505050505050565b600160a060020a0382166000908152600360205260409020548111156114d257600080fd5b600160a060020a0382166000908152600360205260409020546114fb908263ffffffff6112c816565b600160a060020a038316600090815260036020526040902055600454611527908263ffffffff6112c816565b600455604080518281529051600160a060020a038416917fcc16f5dbb4873280815c1ee09dbd06736cffcc184412cf7a71a0fdb75d397ca5919081900360200190a2604080518281529051600091600160a060020a03851691600080516020611d728339815191529181900360200190a35050565b80600160a060020a03811615156115b257600080fd5b600160a060020a03831615156115d0576115cb82611b8b565b61105f565b61105f8383611b97565b6000600854826040518082805190602001908083835b6020831061160f5780518252601f1990920191602091820191016115f0565b51815160209384036101000a6000190180199092169116179052604080519290940182900382207f190100000000000000000000000000000000000000000000000000000000000083830152602283019790975260428083019790975283518083039097018752606290910192839052855192945084935085019190508083835b602083106116af5780518252601f199092019160209182019101611690565b5181516020939093036101000a6000190180199091169216919091179052604051920182900390912095945050505050565b6000808460ff16601b14806116f957508460ff16601c145b1515611775576040805160e560020a62461bcd02815260206004820152602260248201527f45434453413a20696e76616c6964207369676e6174757265202776272076616c60448201527f7565000000000000000000000000000000000000000000000000000000000000606482015290519081900360840190fd5b7f7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a0831115611813576040805160e560020a62461bcd02815260206004820152602260248201527f45434453413a20696e76616c6964207369676e6174757265202773272076616c60448201527f7565000000000000000000000000000000000000000000000000000000000000606482015290519081900360840190fd5b60408051600080825260208083018085528a905260ff8916838501526060830188905260808301879052925160019360a0808501949193601f19840193928390039091019190865af115801561186d573d6000803e3d6000fd5b5050604051601f190151915050600160a060020a03811615156118da576040805160e560020a62461bcd02815260206004820152601860248201527f45434453413a20696e76616c6964207369676e61747572650000000000000000604482015290519081900360640190fd5b95945050505050565b600160a060020a0383161515611968576040805160e560020a62461bcd028152602060048201526024808201527f45524332303a20617070726f76652066726f6d20746865207a65726f2061646460448201527f7265737300000000000000000000000000000000000000000000000000000000606482015290519081900360840190fd5b600160a060020a03821615156119ee576040805160e560020a62461bcd02815260206004820152602260248201527f45524332303a20617070726f766520746f20746865207a65726f20616464726560448201527f7373000000000000000000000000000000000000000000000000000000000000606482015290519081900360840190fd5b600160a060020a0380841660008181526005602090815260408083209487168084529482529182902085905581518581529151600080516020611d928339815191529281900390910190a3505050565b600160a060020a0381161515611a5357600080fd5b600654604051600160a060020a038084169216907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a36006805473ffffffffffffffffffffffffffffffffffffffff1916600160a060020a0392909216919091179055565b33600090815260036020526040812054821115611ad857600080fd5b600160a060020a0383161515611aed57600080fd5b33600090815260036020526040902054611b0d908363ffffffff6112c816565b3360009081526003602052604080822092909255600160a060020a03851681522054611b3f908363ffffffff6112da16565b600160a060020a038416600081815260036020908152604091829020939093558051858152905191923392600080516020611d728339815191529281900390910190a350600192915050565b3031610e0a8282611c44565b604080517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015290518391600091600160a060020a038416916370a0823191602480830192602092919082900301818787803b158015611bfc57600080fd5b505af1158015611c10573d6000803e3d6000fd5b505050506040513d6020811015611c2657600080fd5b5051905061106f600160a060020a038516848363ffffffff611cac16565b604051600160a060020a0383169082156108fc029083906000818181858888f193505050501515610e0a578082611c79611d41565b600160a060020a039091168152604051908190036020019082f080158015611ca5573d6000803e3d6000fd5b5050505050565b82600160a060020a031663a9059cbb83836040518363ffffffff1660e060020a0281526004018083600160a060020a0316600160a060020a0316815260200182815260200192505050600060405180830381600087803b158015611d0f57600080fd5b505af1158015611d23573d6000803e3d6000fd5b505050503d1561105f5760206000803e600051151561105f57600080fd5b604051602180611d51833901905600608060405260405160208060218339810160405251600160a060020a038116ff00ddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925a165627a7a72305820b96bb0733a3e45fdddafa592f51114d0cf16cad047ad60b9b91ae91eb772c6940029" + } + } } } diff --git a/params/chainspecs/mainnet.json b/params/chainspecs/mainnet.json index 53c4920b92e..f8070f1a13d 100644 --- a/params/chainspecs/mainnet.json +++ b/params/chainspecs/mainnet.json @@ -19,5 +19,6 @@ "grayGlacierBlock": 15050000, "terminalTotalDifficulty": 58750000000000000000000, "terminalTotalDifficultyPassed": true, + "shanghaiTime": 1681338455, "ethash": {} } diff --git a/params/chainspecs/rialto.json b/params/chainspecs/rialto.json index 9f5b7936cb1..9a9396077b8 100644 --- a/params/chainspecs/rialto.json +++ b/params/chainspecs/rialto.json @@ -1,26 +1,25 @@ { - "ChainName": "rialto", - "chainId": 1417, - "consensus": "parlia", - "homesteadBlock": 0, - "eip150Block": 0, - "eip150Hash": "0x0000000000000000000000000000000000000000000000000000000000000000", - "eip155Block": 0, - "byzantiumBlock": 0, - "constantinopleBlock": 0, - "petersburgBlock": 0, - "istanbulBlock": 0, - "muirGlacierBlock": 0, - "ramanujanBlock": 400, - "nielsBlock": 0, - "mirrorSyncBlock": 400, - "brunoBlock": 400, - "eulerBlock": 400, - "gibbsBlock": 400, - "parlia": { - "DBPath": "", - "InMemory": false, - "period": 3, - "epoch": 200 - } -} + "ChainName": "rialto", + "chainId": 1417, + "consensus": "parlia", + "homesteadBlock": 0, + "eip150Block": 0, + "eip155Block": 0, + "byzantiumBlock": 0, + "constantinopleBlock": 0, + "petersburgBlock": 0, + "istanbulBlock": 0, + "muirGlacierBlock": 0, + "ramanujanBlock": 400, + "nielsBlock": 0, + "mirrorSyncBlock": 400, + "brunoBlock": 400, + "eulerBlock": 400, + "gibbsBlock": 400, + "parlia": { + "DBPath": "", + "InMemory": false, + "period": 3, + "epoch": 200 + } +} \ No newline at end of file diff --git a/params/chainspecs/ropsten.json b/params/chainspecs/ropsten.json new file mode 100644 index 00000000000..17172dd40f4 --- /dev/null +++ b/params/chainspecs/ropsten.json @@ -0,0 +1,17 @@ +{ + "ChainName": "ropsten", + "chainId": 3, + "consensus": "ethash", + "homesteadBlock": 0, + "eip150Block": 0, + "eip155Block": 10, + "byzantiumBlock": 1700000, + "constantinopleBlock": 4230000, + "petersburgBlock": 4939394, + "istanbulBlock": 6485846, + "muirGlacierBlock": 7117117, + "berlinBlock": 9812189, + "londonBlock": 10499401, + "terminalTotalDifficulty": 50000000000000000, + "ethash": {} +} \ No newline at end of file diff --git a/params/chainspecs/sokol.json b/params/chainspecs/sokol.json deleted file mode 100644 index a69ecba07e3..00000000000 --- a/params/chainspecs/sokol.json +++ /dev/null @@ -1,19 +0,0 @@ -{ - "ChainName": "sokol", - "chainId": 77, - "consensus": "aura", - "homesteadBlock": 0, - "eip150Block": 0, - "eip150Hash": "0x0000000000000000000000000000000000000000000000000000000000000000", - "eip155Block": 0, - "byzantiumBlock": 0, - "constantinopleBlock": 6464300, - "petersburgBlock": 7026400, - "istanbulBlock": 12095200, - "berlinBlock": 21050600, - "aura": { - "DBPath": "", - "InMemory": false, - "Etherbase": "0x0000000000000000000000000000000000000000" - } -} diff --git a/params/config.go b/params/config.go index 083f6101ab4..762581e0dd4 100644 --- a/params/config.go +++ b/params/config.go @@ -25,7 +25,6 @@ import ( "github.com/ledgerwatch/erigon-lib/chain" libcommon "github.com/ledgerwatch/erigon-lib/common" - "github.com/ledgerwatch/erigon-lib/common/hexutility" "github.com/ledgerwatch/erigon/common/paths" "github.com/ledgerwatch/erigon/params/networkname" @@ -55,7 +54,6 @@ var ( SepoliaGenesisHash = libcommon.HexToHash("0x25a5cc106eea7138acab33231d7160d69cb777ee0c2c553fcddf5138993e6dd9") RinkebyGenesisHash = libcommon.HexToHash("0x6341fd3daf94b748c72ced5a5b26028f2474f5f00d824504e4fa37a75767e177") GoerliGenesisHash = libcommon.HexToHash("0xbf7e331f7f7c1dd2e05159666b3bf8bc7a8a3a9eb1d518969eab529dd9b88c1a") - SokolGenesisHash = libcommon.HexToHash("0x5b28c1bfd3a15230c9a46b399cd0f9a6920d432e85381cc6a140b06e8410112f") BSCGenesisHash = libcommon.HexToHash("0x0d21840abff46b96c84b2ac9e10e4f5cdaeb5693cb665db62a2f3b02d2d57b5b") ChapelGenesisHash = libcommon.HexToHash("0x6d3c66c5357ec91d5c43af47e234a939b22557cbb552dc45bebbceeed90fbe34") RialtoGenesisHash = libcommon.HexToHash("0xee835a629f9cf5510b48b6ba41d69e0ff7d6ef10f977166ef939db41f59f5501") @@ -67,11 +65,6 @@ var ( ) var ( - SokolGenesisEpochProof = hexutility.FromHex("0xf91a8c80b91a87f91a84f9020da00000000000000000000000000000000000000000000000000000000000000000a01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347940000000000000000000000000000000000000000a0fad4af258fd11939fae0c6c6eec9d340b1caac0b0196fd9a1bc3f489c5bf00b3a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421b9010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000830200008083663be080808080b8410000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000f91871b914c26060604052600436106100fc576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff16806303aca79214610101578063108552691461016457806340a141ff1461019d57806340c9cdeb146101d65780634110a489146101ff57806345199e0a1461025757806349285b58146102c15780634d238c8e14610316578063752862111461034f578063900eb5a8146103645780639a573786146103c7578063a26a47d21461041c578063ae4b1b5b14610449578063b3f05b971461049e578063b7ab4db5146104cb578063d3e848f114610535578063fa81b2001461058a578063facd743b146105df575b600080fd5b341561010c57600080fd5b6101226004808035906020019091905050610630565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b341561016f57600080fd5b61019b600480803573ffffffffffffffffffffffffffffffffffffffff1690602001909190505061066f565b005b34156101a857600080fd5b6101d4600480803573ffffffffffffffffffffffffffffffffffffffff16906020019091905050610807565b005b34156101e157600080fd5b6101e9610bb7565b6040518082815260200191505060405180910390f35b341561020a57600080fd5b610236600480803573ffffffffffffffffffffffffffffffffffffffff16906020019091905050610bbd565b60405180831515151581526020018281526020019250505060405180910390f35b341561026257600080fd5b61026a610bee565b6040518080602001828103825283818151815260200191508051906020019060200280838360005b838110156102ad578082015181840152602081019050610292565b505050509050019250505060405180910390f35b34156102cc57600080fd5b6102d4610c82565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b341561032157600080fd5b61034d600480803573ffffffffffffffffffffffffffffffffffffffff16906020019091905050610d32565b005b341561035a57600080fd5b610362610fcc565b005b341561036f57600080fd5b61038560048080359060200190919050506110fc565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b34156103d257600080fd5b6103da61113b565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b341561042757600080fd5b61042f6111eb565b604051808215151515815260200191505060405180910390f35b341561045457600080fd5b61045c6111fe565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b34156104a957600080fd5b6104b1611224565b604051808215151515815260200191505060405180910390f35b34156104d657600080fd5b6104de611237565b6040518080602001828103825283818151815260200191508051906020019060200280838360005b83811015610521578082015181840152602081019050610506565b505050509050019250505060405180910390f35b341561054057600080fd5b6105486112cb565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b341561059557600080fd5b61059d6112f1565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b34156105ea57600080fd5b610616600480803573ffffffffffffffffffffffffffffffffffffffff16906020019091905050611317565b604051808215151515815260200191505060405180910390f35b60078181548110151561063f57fe5b90600052602060002090016000915054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b600460029054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161415156106cb57600080fd5b600460019054906101000a900460ff161515156106e757600080fd5b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161415151561072357600080fd5b80600a60006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055506001600460016101000a81548160ff0219169083151502179055507f600bcf04a13e752d1e3670a5a9f1c21177ca2a93c6f5391d4f1298d098097c22600a60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390a150565b600080600061081461113b565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614151561084d57600080fd5b83600960008273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060000160009054906101000a900460ff1615156108a957600080fd5b600960008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600101549350600160078054905003925060078381548110151561090857fe5b906000526020600020900160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1691508160078581548110151561094657fe5b906000526020600020900160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555083600960008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600101819055506007838154811015156109e557fe5b906000526020600020900160006101000a81549073ffffffffffffffffffffffffffffffffffffffff02191690556000600780549050111515610a2757600080fd5b6007805480919060019003610a3c9190611370565b506000600960008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600101819055506000600960008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060000160006101000a81548160ff0219169083151502179055506000600460006101000a81548160ff0219169083151502179055506001430340600019167f55252fa6eee4741b4e24a74a70e9c11fd2c2281df8d6ea13126ff845f7825c89600760405180806020018281038252838181548152602001915080548015610ba257602002820191906000526020600020905b8160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019060010190808311610b58575b50509250505060405180910390a25050505050565b60085481565b60096020528060005260406000206000915090508060000160009054906101000a900460ff16908060010154905082565b610bf661139c565b6007805480602002602001604051908101604052809291908181526020018280548015610c7857602002820191906000526020600020905b8160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019060010190808311610c2e575b5050505050905090565b6000600a60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166349285b586000604051602001526040518163ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401602060405180830381600087803b1515610d1257600080fd5b6102c65a03f11515610d2357600080fd5b50505060405180519050905090565b610d3a61113b565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141515610d7357600080fd5b80600960008273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060000160009054906101000a900460ff16151515610dd057600080fd5b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1614151515610e0c57600080fd5b6040805190810160405280600115158152602001600780549050815250600960008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008201518160000160006101000a81548160ff0219169083151502179055506020820151816001015590505060078054806001018281610ea991906113b0565b9160005260206000209001600084909190916101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550506000600460006101000a81548160ff0219169083151502179055506001430340600019167f55252fa6eee4741b4e24a74a70e9c11fd2c2281df8d6ea13126ff845f7825c89600760405180806020018281038252838181548152602001915080548015610fba57602002820191906000526020600020905b8160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019060010190808311610f70575b50509250505060405180910390a25050565b600560009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161480156110365750600460009054906101000a900460ff16155b151561104157600080fd5b6001600460006101000a81548160ff0219169083151502179055506007600690805461106e9291906113dc565b506006805490506008819055507f8564cd629b15f47dc310d45bcbfc9bcf5420b0d51bf0659a16c67f91d27632536110a4611237565b6040518080602001828103825283818151815260200191508051906020019060200280838360005b838110156110e75780820151818401526020810190506110cc565b505050509050019250505060405180910390a1565b60068181548110151561110b57fe5b90600052602060002090016000915054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b6000600a60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16639a5737866000604051602001526040518163ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401602060405180830381600087803b15156111cb57600080fd5b6102c65a03f115156111dc57600080fd5b50505060405180519050905090565b600460019054906101000a900460ff1681565b600a60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b600460009054906101000a900460ff1681565b61123f61139c565b60068054806020026020016040519081016040528092919081815260200182805480156112c157602002820191906000526020600020905b8160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019060010190808311611277575b5050505050905090565b600560009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b600460029054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b6000600960008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060000160009054906101000a900460ff169050919050565b81548183558181151161139757818360005260206000209182019101611396919061142e565b5b505050565b602060405190810160405280600081525090565b8154818355818115116113d7578183600052602060002091820191016113d6919061142e565b5b505050565b82805482825590600052602060002090810192821561141d5760005260206000209182015b8281111561141c578254825591600101919060010190611401565b5b50905061142a9190611453565b5090565b61145091905b8082111561144c576000816000905550600101611434565b5090565b90565b61149391905b8082111561148f57600081816101000a81549073ffffffffffffffffffffffffffffffffffffffff021916905550600101611459565b5090565b905600a165627a7a7230582036ea35935c8246b68074adece2eab70c40e69a0193c08a6277ce06e5b25188510029b86bf869a033aa5d69545785694b808840be50c182dad2ec3636dfccbe6572fb69828742c0b846f8440101a0663ce0d171e545a26aa67e4ca66f72ba96bb48287dbcc03beea282867f80d44ba01f0e7726926cb43c03a0abf48197dba78522ec8ba1b158e2aa30da7d2a2c6f9eb8f3f8f1a08023c0d95fc2364e0bf7593f5ff32e1db8ef9f4b41c0bd474eae62d1af896e99808080a0b47b4f0b3e73b5edc8f9a9da1cbcfed562eb06bf54619b6aefeadebf5b3604c280a0da6ec08940a924cb08c947dd56cdb40076b29a6f0ea4dba4e2d02d9a9a72431b80a030cc4138c9e74b6cf79d624b4b5612c0fd888e91f55316cfee7d1694e1a90c0b80a0c5d54b915b56a888eee4e6eeb3141e778f9b674d1d322962eed900f02c29990aa017256b36ef47f907c6b1378a2636942ce894c17075e56fc054d4283f6846659e808080a03340bbaeafcda3a8672eb83099231dbbfab8dae02a1e8ec2f7180538fac207e080b838f7a03868bdfa8727775661e4ccf117824a175a33f8703d728c04488fbfffcafda9f99594e8ddc5c7a2d2f0d7a9798459c0104fdf5e987acab853f851808080a07bb75cabebdcbd1dbb4331054636d0c6d7a2b08483b9e04df057395a7434c9e080808080808080a0e61e567237b49c44d8f906ceea49027260b4010c10a547b38d8b131b9d3b6f848080808080b853f851808080a0a87d9bb950836582673aa0eecc0ff64aac607870637a2dd2012b8b1b31981f698080a08da6d5c36a404670c553a2c9052df7cd604f04e3863c4c7b9e0027bfd54206d680808080808080808080b86bf869a02080c7b7ae81a58eb98d9c78de4a1fd7fd9535fc953ed2be602daaa41767312ab846f8448080a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421a0c5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470b8d3f8d1a0dc277c93a9f9dcee99aac9b8ba3cfa4c51821998522469c37715644e8fbac0bfa0ab8cdb808c8303bb61fb48e276217be9770fa83ecf3f90f2234d558885f5abf1808080a0fe137c3a474fbde41d89a59dd76da4c55bf696b86d3af64a55632f76cf30786780808080a06301b39b2ea8a44df8b0356120db64b788e71f52e1d7a6309d0d2e5b86fee7cb80a0da5d8b08dea0c5a4799c0f44d8a24d7cdf209f9b7a5588c1ecafb5361f6b9f07a01b7779e149cadf24d4ffb77ca7e11314b8db7097e4d70b2a173493153ca2e5a0808080a3e2a02052222313e28459528d920b65115c16c04f3efc82aaedc97be59f3f377c0d3f0180") -) - -var ( - SokolGenesisStateRoot = libcommon.HexToHash("0xfad4af258fd11939fae0c6c6eec9d340b1caac0b0196fd9a1bc3f489c5bf00b3") GnosisGenesisStateRoot = libcommon.HexToHash("0x40cf4430ecaa733787d1a65154a3b9efb560c95d9e324a23b97f0609b539133b") ChiadoGenesisStateRoot = libcommon.HexToHash("0x9ec3eaf4e6188dfbdd6ade76eaa88289b57c63c9a2cde8d35291d5a29e143d31") ) @@ -95,8 +88,6 @@ var ( RialtoChainConfig = readChainSpec("chainspecs/rialto.json") - SokolChainConfig = readChainSpec("chainspecs/sokol.json") - // AllProtocolChanges contains every protocol change (EIPs) introduced // and accepted by the Ethereum core developers into the main net protocol. AllProtocolChanges = &chain.Config{ @@ -222,8 +213,6 @@ func ChainConfigByChainName(chain string) *chain.Config { return RinkebyChainConfig case networkname.GoerliChainName: return GoerliChainConfig - case networkname.SokolChainName: - return SokolChainConfig case networkname.BSCChainName: return BSCChainConfig case networkname.ChapelChainName: @@ -255,8 +244,6 @@ func GenesisHashByChainName(chain string) *libcommon.Hash { return &RinkebyGenesisHash case networkname.GoerliChainName: return &GoerliGenesisHash - case networkname.SokolChainName: - return &SokolGenesisHash case networkname.BSCChainName: return &BSCGenesisHash case networkname.ChapelChainName: @@ -288,8 +275,6 @@ func ChainConfigByGenesisHash(genesisHash libcommon.Hash) *chain.Config { return RinkebyChainConfig case genesisHash == GoerliGenesisHash: return GoerliChainConfig - case genesisHash == SokolGenesisHash: - return SokolChainConfig case genesisHash == BSCGenesisHash: return BSCChainConfig case genesisHash == ChapelGenesisHash: diff --git a/params/mining.go b/params/mining.go index 34d47d38c37..d5e0d8cc868 100644 --- a/params/mining.go +++ b/params/mining.go @@ -6,8 +6,7 @@ import ( "time" libcommon "github.com/ledgerwatch/erigon-lib/common" - - "github.com/ledgerwatch/erigon/common/hexutil" + "github.com/ledgerwatch/erigon-lib/common/hexutility" ) // MiningConfig is the configuration parameters of mining. @@ -18,7 +17,7 @@ type MiningConfig struct { Etherbase libcommon.Address `toml:",omitempty"` // Public address for block mining rewards SigKey *ecdsa.PrivateKey // ECDSA private key for signing blocks Notify []string `toml:",omitempty"` // HTTP URL list to be notified of new work packages(only useful in ethash). - ExtraData hexutil.Bytes `toml:",omitempty"` // Block extra data set by the miner + ExtraData hexutility.Bytes `toml:",omitempty"` // Block extra data set by the miner GasLimit uint64 // Target gas limit for mined blocks. GasPrice *big.Int // Minimum gas price for mining a transaction Recommit time.Duration // The time interval for miner to re-create mining work. diff --git a/params/networkname/network_name.go b/params/networkname/network_name.go index 49aa02866aa..2e3b381d5f2 100644 --- a/params/networkname/network_name.go +++ b/params/networkname/network_name.go @@ -6,7 +6,6 @@ const ( RinkebyChainName = "rinkeby" GoerliChainName = "goerli" DevChainName = "dev" - SokolChainName = "sokol" BSCChainName = "bsc" ChapelChainName = "chapel" RialtoChainName = "rialto" @@ -22,7 +21,6 @@ var All = []string{ SepoliaChainName, RinkebyChainName, GoerliChainName, - SokolChainName, BSCChainName, ChapelChainName, //RialtoChainName, diff --git a/params/protocol_params.go b/params/protocol_params.go index a09f2a69bb3..87cbf978776 100644 --- a/params/protocol_params.go +++ b/params/protocol_params.go @@ -132,8 +132,9 @@ const ( // Precompiled contract gas prices - TendermintHeaderValidateGas uint64 = 3000 // Gas for validate tendermiint consensus state - IAVLMerkleProofValidateGas uint64 = 3000 // Gas for validate merkle proof + TendermintHeaderValidateGas uint64 = 3000 // Gas for validate tendermiint consensus state + IAVLMerkleProofValidateGas uint64 = 3000 // Gas for validate merkle proof + CometBFTLightBlockValidateGas uint64 = 3000 // Gas for validate cometBFT light block EcrecoverGas uint64 = 3000 // Elliptic curve sender recovery gas price Sha256BaseGas uint64 = 60 // Base price for a SHA256 operation @@ -143,6 +144,9 @@ const ( IdentityBaseGas uint64 = 15 // Base price for a data copy operation IdentityPerWordGas uint64 = 3 // Per-work price for a data copy operation + BlsSignatureVerifyBaseGas uint64 = 1000 // base price for a BLS signature verify operation + BlsSignatureVerifyPerKeyGas uint64 = 3500 // Per-key price for a BLS signature verify operation + Bn256AddGasByzantium uint64 = 500 // Byzantium gas needed for an elliptic curve addition Bn256AddGasIstanbul uint64 = 150 // Gas needed for an elliptic curve addition Bn256ScalarMulGasByzantium uint64 = 40000 // Byzantium gas needed for an elliptic curve scalar multiplication diff --git a/params/version.go b/params/version.go index 40aeaf048b6..927c488281e 100644 --- a/params/version.go +++ b/params/version.go @@ -32,7 +32,7 @@ var ( // see https://calver.org const ( VersionMajor = 2 // Major version component of the current release - VersionMinor = 40 // Minor version component of the current release + VersionMinor = 43 // Minor version component of the current release VersionMicro = 0 // Patch version component of the current release VersionModifier = "dev" // Modifier component of the current release VersionKeyCreated = "ErigonVersionCreated" diff --git a/tests/block_test_util.go b/tests/block_test_util.go index 2a96086bd6c..bb10d47b38c 100644 --- a/tests/block_test_util.go +++ b/tests/block_test_util.go @@ -27,8 +27,10 @@ import ( "testing" "github.com/holiman/uint256" + "github.com/ledgerwatch/erigon-lib/chain" libcommon "github.com/ledgerwatch/erigon-lib/common" + "github.com/ledgerwatch/erigon-lib/common/hexutility" "github.com/ledgerwatch/erigon-lib/kv" "github.com/ledgerwatch/erigon/common" @@ -95,7 +97,7 @@ type btHeader struct { } type btHeaderMarshaling struct { - ExtraData hexutil.Bytes + ExtraData hexutility.Bytes Number *math.HexOrDecimal256 Difficulty *math.HexOrDecimal256 GasLimit math.HexOrDecimal64 diff --git a/tests/fuzzers/secp256k1/secp_fuzzer.go b/tests/fuzzers/secp256k1/secp_fuzzer.go index a6c7be0ec00..efc84f5d81d 100644 --- a/tests/fuzzers/secp256k1/secp_fuzzer.go +++ b/tests/fuzzers/secp256k1/secp_fuzzer.go @@ -16,6 +16,8 @@ // build +gofuzz +// build +gofuzz + package secp256k1 import ( @@ -44,7 +46,7 @@ func Fuzz(input []byte) int { resBX, resBY := curveB.Add(x1, y1, x2, y2) if resAX.Cmp(resBX) != 0 || resAY.Cmp(resBY) != 0 { fmt.Printf("%s %s %s %s\n", x1, y1, x2, y2) - panic(fmt.Sprintf("Addition failed: erigon: %s %s btcd: %s %s", resAX, resAY, resBX, resBY)) + panic(fmt.Sprintf("Addition failed: geth: %s %s btcd: %s %s", resAX, resAY, resBX, resBY)) } return 0 } diff --git a/tests/gen_btheader.go b/tests/gen_btheader.go index 41722bf16e1..b6187760f75 100644 --- a/tests/gen_btheader.go +++ b/tests/gen_btheader.go @@ -7,8 +7,8 @@ import ( "math/big" libcommon "github.com/ledgerwatch/erigon-lib/common" + "github.com/ledgerwatch/erigon-lib/common/hexutility" - "github.com/ledgerwatch/erigon/common/hexutil" "github.com/ledgerwatch/erigon/common/math" "github.com/ledgerwatch/erigon/core/types" ) @@ -29,7 +29,7 @@ func (b btHeader) MarshalJSON() ([]byte, error) { StateRoot libcommon.Hash TransactionsTrie libcommon.Hash UncleHash libcommon.Hash - ExtraData hexutil.Bytes + ExtraData hexutility.Bytes Difficulty *math.HexOrDecimal256 GasLimit math.HexOrDecimal64 GasUsed math.HexOrDecimal64 @@ -71,7 +71,7 @@ func (b *btHeader) UnmarshalJSON(input []byte) error { StateRoot *libcommon.Hash TransactionsTrie *libcommon.Hash UncleHash *libcommon.Hash - ExtraData *hexutil.Bytes + ExtraData *hexutility.Bytes Difficulty *math.HexOrDecimal256 GasLimit *math.HexOrDecimal64 GasUsed *math.HexOrDecimal64 diff --git a/tests/state_test_util.go b/tests/state_test_util.go index 65c247edd9c..0644db0a496 100644 --- a/tests/state_test_util.go +++ b/tests/state_test_util.go @@ -26,15 +26,16 @@ import ( "strings" "github.com/holiman/uint256" + "golang.org/x/crypto/sha3" + "github.com/ledgerwatch/erigon-lib/chain" libcommon "github.com/ledgerwatch/erigon-lib/common" + "github.com/ledgerwatch/erigon-lib/common/hexutility" "github.com/ledgerwatch/erigon-lib/common/length" "github.com/ledgerwatch/erigon-lib/kv" types2 "github.com/ledgerwatch/erigon-lib/types" - "golang.org/x/crypto/sha3" "github.com/ledgerwatch/erigon/common" - "github.com/ledgerwatch/erigon/common/hexutil" "github.com/ledgerwatch/erigon/common/math" "github.com/ledgerwatch/erigon/core" "github.com/ledgerwatch/erigon/core/state" @@ -65,14 +66,14 @@ type stJSON struct { Env stEnv `json:"env"` Pre core.GenesisAlloc `json:"pre"` Tx stTransactionMarshaling `json:"transaction"` - Out hexutil.Bytes `json:"out"` + Out hexutility.Bytes `json:"out"` Post map[string][]stPostState `json:"post"` } type stPostState struct { Root common.UnprefixedHash `json:"hash"` Logs common.UnprefixedHash `json:"logs"` - Tx hexutil.Bytes `json:"txbytes"` + Tx hexutility.Bytes `json:"txbytes"` ExpectException string `json:"expectException"` Indexes struct { Data int `json:"data"` @@ -100,7 +101,7 @@ type stTransactionMarshaling struct { MaxPriorityFeePerGas *math.HexOrDecimal256 `json:"maxPriorityFeePerGas"` Nonce math.HexOrDecimal64 `json:"nonce"` GasLimit []math.HexOrDecimal64 `json:"gasLimit"` - PrivateKey hexutil.Bytes `json:"secretKey"` + PrivateKey hexutility.Bytes `json:"secretKey"` To string `json:"to"` Data []string `json:"data"` Value []string `json:"value"` @@ -467,7 +468,9 @@ func toMessage(tx stTransactionMarshaling, ps stPostState, baseFee *big.Int) (co data, accessList, false, /* checkNonce */ - false /* isFree */) + false, /* isFree */ + uint256.NewInt(tipCap.Uint64()), + ) return msg, nil } diff --git a/tests/statedb_chain_test.go b/tests/statedb_chain_test.go index a10e348a9ce..feb4439c987 100644 --- a/tests/statedb_chain_test.go +++ b/tests/statedb_chain_test.go @@ -17,6 +17,7 @@ package tests import ( + "context" "math/big" "testing" @@ -25,8 +26,6 @@ import ( libcommon "github.com/ledgerwatch/erigon-lib/common" "github.com/stretchr/testify/require" - "github.com/ledgerwatch/erigon/ethdb/olddb" - "github.com/ledgerwatch/erigon/accounts/abi/bind" "github.com/ledgerwatch/erigon/accounts/abi/bind/backends" "github.com/ledgerwatch/erigon/core" @@ -43,7 +42,7 @@ func TestSelfDestructReceive(t *testing.T) { key, _ = crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291") address = crypto.PubkeyToAddress(key.PublicKey) funds = big.NewInt(1000000000) - gspec = &core.Genesis{ + gspec = &types.Genesis{ Config: &chain.Config{ ChainID: big.NewInt(1), HomesteadBlock: new(big.Int), @@ -52,7 +51,7 @@ func TestSelfDestructReceive(t *testing.T) { TangerineWhistleBlock: new(big.Int), SpuriousDragonBlock: new(big.Int), }, - Alloc: core.GenesisAlloc{ + Alloc: types.GenesisAlloc{ address: {Balance: funds}, }, } @@ -61,8 +60,6 @@ func TestSelfDestructReceive(t *testing.T) { ) m := stages.MockWithGenesis(t, gspec, key, false) - db := olddb.NewObjectDatabase(m.DB) - defer db.Close() contractBackend := backends.NewTestSimulatedBackendWithConfig(t, gspec.Alloc, gspec.Config, gspec.GasLimit) transactOpts, err := bind.NewKeyedTransactorWithChainID(key, m.ChainConfig.ChainID) @@ -77,23 +74,23 @@ func TestSelfDestructReceive(t *testing.T) { // The second block is empty and is only used to force the newly created blockchain object to reload the trie // from the database. chain, err := core.GenerateChain(m.ChainConfig, m.Genesis, m.Engine, m.DB, 2, func(i int, block *core.BlockGen) { - var tx types.Transaction + var txn types.Transaction switch i { case 0: - contractAddress, tx, selfDestructorContract, err = contracts.DeploySelfDestructor(transactOpts, contractBackend) + contractAddress, txn, selfDestructorContract, err = contracts.DeploySelfDestructor(transactOpts, contractBackend) if err != nil { t.Fatal(err) } - block.AddTx(tx) - tx, err = selfDestructorContract.SelfDestruct(transactOpts) + block.AddTx(txn) + txn, err = selfDestructorContract.SelfDestruct(transactOpts) if err != nil { t.Fatal(err) } - block.AddTx(tx) + block.AddTx(txn) // Send 1 wei to contract after self-destruction - tx, err = types.SignTx(types.NewTransaction(block.TxNonce(address), contractAddress, uint256.NewInt(1000), 21000, uint256.NewInt(1), nil), *signer, key) - block.AddTx(tx) + txn, err = types.SignTx(types.NewTransaction(block.TxNonce(address), contractAddress, uint256.NewInt(1000), 21000, uint256.NewInt(1), nil), *signer, key) + block.AddTx(txn) } contractBackend.Commit() }, false /* intermediateHashes */) @@ -101,7 +98,13 @@ func TestSelfDestructReceive(t *testing.T) { t.Fatalf("generate blocks: %v", err) } - st := state.New(state.NewPlainStateReader(db)) + tx, err := m.DB.BeginRo(context.Background()) + if err != nil { + panic(err) + } + defer tx.Rollback() + + st := state.New(m.NewStateReader(tx)) if !st.Exist(address) { t.Error("expected account to exist") } @@ -122,7 +125,12 @@ func TestSelfDestructReceive(t *testing.T) { // and that means that the state of the accounts written in the first block was correct. // This test checks that the storage root of the account is properly set to the root of the empty tree - st = state.New(state.NewPlainStateReader(db)) + tx, err = m.DB.BeginRo(context.Background()) + if err != nil { + panic(err) + } + defer tx.Rollback() + st = state.New(m.NewStateReader(tx)) if !st.Exist(address) { t.Error("expected account to exist") } diff --git a/tests/statedb_insert_chain_transaction_test.go b/tests/statedb_insert_chain_transaction_test.go index e50d28bd8e1..85370133169 100644 --- a/tests/statedb_insert_chain_transaction_test.go +++ b/tests/statedb_insert_chain_transaction_test.go @@ -77,7 +77,7 @@ func TestInsertIncorrectStateRootDifferentAccounts(t *testing.T) { require.NoError(t, err) defer tx.Rollback() - st := state.New(state.NewPlainStateReader(tx)) + st := state.New(m.NewStateReader(tx)) if !st.Exist(to) { t.Error("expected account to exist") } @@ -145,7 +145,7 @@ func TestInsertIncorrectStateRootSameAccount(t *testing.T) { require.NoError(t, err) defer tx.Rollback() - st := state.New(state.NewPlainStateReader(tx)) + st := state.New(m.NewStateReader(tx)) if !st.Exist(to) { t.Error("expected account to exist") } @@ -207,7 +207,7 @@ func TestInsertIncorrectStateRootSameAccountSameAmount(t *testing.T) { require.NoError(t, err) defer tx.Rollback() - st := state.New(state.NewPlainStateReader(tx)) + st := state.New(m.NewStateReader(tx)) if !st.Exist(to) { t.Error("expected account to exist") } @@ -269,7 +269,7 @@ func TestInsertIncorrectStateRootAllFundsRoot(t *testing.T) { require.NoError(t, err) defer tx.Rollback() - st := state.New(state.NewPlainStateReader(tx)) + st := state.New(m.NewStateReader(tx)) if !st.Exist(to) { t.Error("expected account to exist") } @@ -331,7 +331,7 @@ func TestInsertIncorrectStateRootAllFunds(t *testing.T) { require.NoError(t, err) defer tx.Rollback() - st := state.New(state.NewPlainStateReader(tx)) + st := state.New(m.NewStateReader(tx)) if !st.Exist(to) { t.Error("expected account to exist") } @@ -372,7 +372,7 @@ func TestAccountDeployIncorrectRoot(t *testing.T) { t.Fatal(err) } err = m.DB.View(context.Background(), func(tx kv.Tx) error { - st := state.New(state.NewPlainStateReader(tx)) + st := state.New(m.NewStateReader(tx)) if !st.Exist(from) { t.Error("expected account to exist") } @@ -395,7 +395,7 @@ func TestAccountDeployIncorrectRoot(t *testing.T) { } err = m.DB.View(context.Background(), func(tx kv.Tx) error { - st := state.New(state.NewPlainStateReader(tx)) + st := state.New(m.NewStateReader(tx)) if !st.Exist(from) { t.Error("expected account to exist") } @@ -413,7 +413,7 @@ func TestAccountDeployIncorrectRoot(t *testing.T) { } err = m.DB.View(context.Background(), func(tx kv.Tx) error { - st := state.New(state.NewPlainStateReader(tx)) + st := state.New(m.NewStateReader(tx)) if !st.Exist(from) { t.Error("expected account to exist") } @@ -459,7 +459,7 @@ func TestAccountCreateIncorrectRoot(t *testing.T) { } err = m.DB.View(context.Background(), func(tx kv.Tx) error { - st := state.New(state.NewPlainStateReader(tx)) + st := state.New(m.NewStateReader(tx)) if !st.Exist(from) { t.Error("expected account to exist") } @@ -477,7 +477,7 @@ func TestAccountCreateIncorrectRoot(t *testing.T) { t.Fatal(err) } err = m.DB.View(context.Background(), func(tx kv.Tx) error { - st := state.New(state.NewPlainStateReader(tx)) + st := state.New(m.NewStateReader(tx)) if !st.Exist(from) { t.Error("expected account to exist") } @@ -543,7 +543,7 @@ func TestAccountUpdateIncorrectRoot(t *testing.T) { } err = m.DB.View(context.Background(), func(tx kv.Tx) error { - st := state.New(state.NewPlainStateReader(tx)) + st := state.New(m.NewStateReader(tx)) if !st.Exist(from) { t.Error("expected account to exist") } @@ -562,7 +562,7 @@ func TestAccountUpdateIncorrectRoot(t *testing.T) { } err = m.DB.View(context.Background(), func(tx kv.Tx) error { - st := state.New(state.NewPlainStateReader(tx)) + st := state.New(m.NewStateReader(tx)) if !st.Exist(from) { t.Error("expected account to exist") } @@ -632,7 +632,7 @@ func TestAccountDeleteIncorrectRoot(t *testing.T) { } err = m.DB.View(context.Background(), func(tx kv.Tx) error { - st := state.New(state.NewPlainStateReader(tx)) + st := state.New(m.NewStateReader(tx)) if !st.Exist(from) { t.Error("expected account to exist") } @@ -650,7 +650,7 @@ func TestAccountDeleteIncorrectRoot(t *testing.T) { } err = m.DB.View(context.Background(), func(tx kv.Tx) error { - st := state.New(state.NewPlainStateReader(tx)) + st := state.New(m.NewStateReader(tx)) if !st.Exist(from) { t.Error("expected account to exist") } diff --git a/tests/testdata b/tests/testdata deleted file mode 160000 index b6247b008e9..00000000000 --- a/tests/testdata +++ /dev/null @@ -1 +0,0 @@ -Subproject commit b6247b008e934adf981a9d0d5f903477004f9d7d diff --git a/tests/transaction_test_util.go b/tests/transaction_test_util.go index 5eee06e75cc..f2d063650b8 100644 --- a/tests/transaction_test_util.go +++ b/tests/transaction_test_util.go @@ -23,10 +23,11 @@ import ( "math/big" "github.com/holiman/uint256" + "github.com/ledgerwatch/erigon-lib/chain" libcommon "github.com/ledgerwatch/erigon-lib/common" + "github.com/ledgerwatch/erigon-lib/common/hexutility" - "github.com/ledgerwatch/erigon/common/hexutil" "github.com/ledgerwatch/erigon/common/math" "github.com/ledgerwatch/erigon/core" "github.com/ledgerwatch/erigon/core/types" @@ -35,8 +36,8 @@ import ( // TransactionTest checks RLP decoding and sender derivation of transactions. type TransactionTest struct { - RLP hexutil.Bytes `json:"txbytes"` - Forks ttForks `json:"result"` + RLP hexutility.Bytes `json:"txbytes"` + Forks ttForks `json:"result"` } type ttForks struct { @@ -60,7 +61,7 @@ type ttFork struct { } func (tt *TransactionTest) Run(chainID *big.Int) error { - validateTx := func(rlpData hexutil.Bytes, signer types.Signer, rules *chain.Rules) (*libcommon.Address, *libcommon.Hash, uint64, error) { + validateTx := func(rlpData hexutility.Bytes, signer types.Signer, rules *chain.Rules) (*libcommon.Address, *libcommon.Hash, uint64, error) { tx, err := types.DecodeTransaction(rlp.NewStream(bytes.NewReader(rlpData), 0)) if err != nil { return nil, nil, 0, err diff --git a/turbo/adapter/ethapi/api.go b/turbo/adapter/ethapi/api.go index 43c36e4343b..863309d46e7 100644 --- a/turbo/adapter/ethapi/api.go +++ b/turbo/adapter/ethapi/api.go @@ -43,9 +43,10 @@ type CallArgs struct { GasPrice *hexutil.Big `json:"gasPrice"` MaxPriorityFeePerGas *hexutil.Big `json:"maxPriorityFeePerGas"` MaxFeePerGas *hexutil.Big `json:"maxFeePerGas"` + MaxFeePerDataGas *hexutil.Big `json:"maxFeePerDataGas"` Value *hexutil.Big `json:"value"` Nonce *hexutil.Uint64 `json:"nonce"` - Data *hexutil.Bytes `json:"data"` + Data *hexutility.Bytes `json:"data"` AccessList *types2.AccessList `json:"accessList"` ChainID *hexutil.Big `json:"chainId,omitempty"` } @@ -81,9 +82,10 @@ func (args *CallArgs) ToMessage(globalGasCap uint64, baseFee *uint256.Int) (type } var ( - gasPrice *uint256.Int - gasFeeCap *uint256.Int - gasTipCap *uint256.Int + gasPrice *uint256.Int + gasFeeCap *uint256.Int + gasTipCap *uint256.Int + maxFeePerDataGas *uint256.Int ) if baseFee == nil { // If there's no basefee, then it must be a non-1559 execution @@ -127,6 +129,9 @@ func (args *CallArgs) ToMessage(globalGasCap uint64, baseFee *uint256.Int) (type gasPrice = math.U256Min(new(uint256.Int).Add(gasTipCap, baseFee), gasFeeCap) } } + if args.MaxFeePerDataGas != nil { + maxFeePerDataGas.SetFromBig(args.MaxFeePerDataGas.ToInt()) + } } value := new(uint256.Int) @@ -145,7 +150,7 @@ func (args *CallArgs) ToMessage(globalGasCap uint64, baseFee *uint256.Int) (type accessList = *args.AccessList } - msg := types.NewMessage(addr, args.To, 0, value, gas, gasPrice, gasFeeCap, gasTipCap, data, accessList, false /* checkNonce */, false /* isFree */) + msg := types.NewMessage(addr, args.To, 0, value, gas, gasPrice, gasFeeCap, gasTipCap, data, accessList, false /* checkNonce */, false /* isFree */, maxFeePerDataGas) return msg, nil } @@ -157,7 +162,7 @@ func (args *CallArgs) ToMessage(globalGasCap uint64, baseFee *uint256.Int) (type // message. type Account struct { Nonce *hexutil.Uint64 `json:"nonce"` - Code *hexutil.Bytes `json:"code"` + Code *hexutility.Bytes `json:"code"` Balance **hexutil.Big `json:"balance"` State *map[libcommon.Hash]uint256.Int `json:"state"` StateDiff *map[libcommon.Hash]uint256.Int `json:"stateDiff"` @@ -267,7 +272,7 @@ func RPCMarshalHeader(head *types.Header) map[string]interface{} { "stateRoot": head.Root, "miner": head.Coinbase, "difficulty": (*hexutil.Big)(head.Difficulty), - "extraData": hexutil.Bytes(head.Extra), + "extraData": hexutility.Bytes(head.Extra), "size": hexutil.Uint64(head.Size()), "gasLimit": hexutil.Uint64(head.GasLimit), "gasUsed": hexutil.Uint64(head.GasUsed), @@ -374,8 +379,9 @@ type RPCTransaction struct { GasPrice *hexutil.Big `json:"gasPrice,omitempty"` Tip *hexutil.Big `json:"maxPriorityFeePerGas,omitempty"` FeeCap *hexutil.Big `json:"maxFeePerGas,omitempty"` + MaxFeePerDataGas *hexutil.Big `json:"maxFeePerDataGas,omitempty"` Hash libcommon.Hash `json:"hash"` - Input hexutil.Bytes `json:"input"` + Input hexutility.Bytes `json:"input"` Nonce hexutil.Uint64 `json:"nonce"` To *libcommon.Address `json:"to"` TransactionIndex *hexutil.Uint64 `json:"transactionIndex"` @@ -400,7 +406,7 @@ func newRPCTransaction(tx types.Transaction, blockHash libcommon.Hash, blockNumb Type: hexutil.Uint64(tx.Type()), Gas: hexutil.Uint64(tx.GetGas()), Hash: tx.Hash(), - Input: hexutil.Bytes(tx.GetData()), + Input: hexutility.Bytes(tx.GetData()), Nonce: hexutil.Uint64(tx.GetNonce()), To: tx.GetTo(), Value: (*hexutil.Big)(tx.GetValue().ToBig()), @@ -441,6 +447,7 @@ func newRPCTransaction(tx types.Transaction, blockHash libcommon.Hash, blockNumb } else { result.GasPrice = nil } + // case *types.SignedBlobTx: // TODO } signer := types.LatestSignerForChainID(chainId.ToBig()) var err error @@ -466,7 +473,7 @@ func newRPCBorTransaction(opaqueTx types.Transaction, txHash libcommon.Hash, blo GasPrice: (*hexutil.Big)(tx.GasPrice.ToBig()), Gas: hexutil.Uint64(tx.GetGas()), Hash: txHash, - Input: hexutil.Bytes(tx.GetData()), + Input: hexutility.Bytes(tx.GetData()), Nonce: hexutil.Uint64(tx.GetNonce()), From: libcommon.Address{}, To: tx.GetTo(), diff --git a/turbo/app/import.go b/turbo/app/import.go index 9838af1a2e7..379d922c6f3 100644 --- a/turbo/app/import.go +++ b/turbo/app/import.go @@ -52,15 +52,13 @@ func importChain(ctx *cli.Context) error { utils.Fatalf("This command requires an argument.") } - logger := log.New(ctx) - nodeCfg := turboNode.NewNodConfigUrfave(ctx) ethCfg := turboNode.NewEthConfigUrfave(ctx, nodeCfg) stack := makeConfigNode(nodeCfg) defer stack.Close() - ethereum, err := eth.New(stack, ethCfg, logger) + ethereum, err := eth.New(stack, ethCfg) if err != nil { return err } diff --git a/turbo/app/init.go b/turbo/app/init.go index 9c7f516d51e..6327b75870a 100644 --- a/turbo/app/init.go +++ b/turbo/app/init.go @@ -54,7 +54,7 @@ func initGenesis(ctx *cli.Context) error { stack := MakeConfigNodeDefault(ctx) defer stack.Close() - chaindb, err := node.OpenDatabase(stack.Config(), log.New(ctx), kv.ChainDB) + chaindb, err := node.OpenDatabase(stack.Config(), kv.ChainDB) if err != nil { utils.Fatalf("Failed to open database: %v", err) } diff --git a/turbo/app/snapshots.go b/turbo/app/snapshots.go index 03bcff9db8f..2bd3879805f 100644 --- a/turbo/app/snapshots.go +++ b/turbo/app/snapshots.go @@ -355,6 +355,7 @@ func doRetireCommand(cliCtx *cli.Context) error { return err } agg.SetWorkers(estimate.CompressSnapshot.Workers()) + agg.CleanDir() if to == 0 { var forwardProgress uint64 @@ -373,7 +374,7 @@ func doRetireCommand(cliCtx *cli.Context) error { if err := br.RetireBlocks(ctx, i, i+every, log.LvlInfo); err != nil { panic(err) } - if err := db.Update(ctx, func(tx kv.RwTx) error { + if err := db.UpdateNosync(ctx, func(tx kv.RwTx) error { if err := rawdb.WriteSnapshots(tx, br.Snapshots().Files(), agg.Files()); err != nil { return err } @@ -394,7 +395,7 @@ func doRetireCommand(cliCtx *cli.Context) error { log.Info("Prune state history") for i := 0; i < 1024; i++ { - if err := db.Update(ctx, func(tx kv.RwTx) error { + if err := db.UpdateNosync(ctx, func(tx kv.RwTx) error { agg.SetTx(tx) if err = agg.Prune(ctx, ethconfig.HistoryV3AggregationStep/10); err != nil { return err @@ -411,9 +412,10 @@ func doRetireCommand(cliCtx *cli.Context) error { return err } + var lastTxNum uint64 if err := db.View(ctx, func(tx kv.Tx) error { execProgress, _ := stages.GetStageProgress(tx, stages.Execution) - lastTxNum, err := rawdbv3.TxNums.Max(tx, execProgress) + lastTxNum, err = rawdbv3.TxNums.Max(tx, execProgress) if err != nil { return err } @@ -424,14 +426,14 @@ func doRetireCommand(cliCtx *cli.Context) error { } log.Info("Build state history snapshots") - if err = agg.BuildFiles(ctx, db); err != nil { + if err = agg.BuildFiles(lastTxNum); err != nil { return err } + if err = agg.MergeLoop(ctx, estimate.CompressSnapshot.Workers()); err != nil { return err } - - if err := db.Update(ctx, func(tx kv.RwTx) error { + if err := db.UpdateNosync(ctx, func(tx kv.RwTx) error { return rawdb.WriteSnapshots(tx, snapshots.Files(), agg.Files()) }); err != nil { return err @@ -439,7 +441,7 @@ func doRetireCommand(cliCtx *cli.Context) error { log.Info("Prune state history") for i := 0; i < 1024; i++ { - if err := db.Update(ctx, func(tx kv.RwTx) error { + if err := db.UpdateNosync(ctx, func(tx kv.RwTx) error { agg.SetTx(tx) if err = agg.Prune(ctx, ethconfig.HistoryV3AggregationStep/10); err != nil { return err @@ -449,6 +451,11 @@ func doRetireCommand(cliCtx *cli.Context) error { return err } } + if err := db.Update(ctx, func(tx kv.RwTx) error { + return rawdb.WriteSnapshots(tx, snapshots.Files(), agg.Files()) + }); err != nil { + return err + } return nil } diff --git a/turbo/app/support.go b/turbo/app/support.go index 02473457f30..ef0faa613c8 100644 --- a/turbo/app/support.go +++ b/turbo/app/support.go @@ -1,17 +1,38 @@ package app import ( + "bufio" + "bytes" + "context" + "crypto/tls" + "crypto/x509" + "encoding/binary" + "fmt" "io" "net/http" "os" "os/signal" - "path" "syscall" "time" - "github.com/ledgerwatch/erigon/cmd/utils" "github.com/ledgerwatch/log/v3" "github.com/urfave/cli/v2" + "golang.org/x/net/http2" +) + +var ( + diagnosticsURLFlag = cli.StringFlag{ + Name: "diagnostics.url", + Usage: "URL of the diagnostics system provided by the support team, include unique session PIN", + } + metricsURLsFlag = cli.StringSliceFlag{ + Name: "metrics.urls", + Usage: "Comma separated list of URLs to the metrics endpoints thats are being diagnosed", + } + insecureFlag = cli.BoolFlag{ + Name: "insecure", + Usage: "Allows communication with diagnostics system using self-signed TLS certificates", + } ) var supportCommand = cli.Command{ @@ -20,8 +41,9 @@ var supportCommand = cli.Command{ Usage: "Connect Erigon instance to a diagnostics system for support", ArgsUsage: "--diagnostics.url --metrics.url ", Flags: []cli.Flag{ - &utils.MetricsURLsFlag, - &utils.DiagnosticsURLFlag, + &metricsURLsFlag, + &diagnosticsURLFlag, + &insecureFlag, }, Category: "SUPPORT COMMANDS", Description: ` @@ -29,42 +51,138 @@ The support command connects a running Erigon instances to a diagnostics system by the URL.`, } -func connectDiagnostics(ctx *cli.Context) error { +const Version = 1 + +func connectDiagnostics(cliCtx *cli.Context) error { sigs := make(chan os.Signal, 1) - interruptCh := make(chan bool, 1) signal.Notify(sigs, syscall.SIGINT, syscall.SIGTERM) + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() + + metricsURLs := cliCtx.StringSlice(metricsURLsFlag.Name) + metricsURL := metricsURLs[0] // TODO: Generalise + + diagnosticsUrl := cliCtx.String(diagnosticsURLFlag.Name) + + // Create a pool with the server certificate since it is not signed + // by a known CA + certPool := x509.NewCertPool() + + // Create TLS configuration with the certificate of the server + insecure := cliCtx.Bool(insecureFlag.Name) + tlsConfig := &tls.Config{ + RootCAs: certPool, + InsecureSkipVerify: insecure, //nolint:gosec + } + + // Perform the requests in a loop (reconnect) + for { + if err := tunnel(ctx, cancel, sigs, tlsConfig, diagnosticsUrl, metricsURL); err != nil { + return err + } + select { + case <-ctx.Done(): + // Quit immediately if the context was cancelled (by Ctrl-C or TERM signal) + return nil + default: + } + log.Info("Reconnecting in 1 second...") + timer := time.NewTimer(1 * time.Second) + <-timer.C + } +} + +var successLine = []byte("SUCCESS") + +// tunnel operates the tunnel from diagnostics system to the metrics URL for one http/2 request +// needs to be called repeatedly to implement re-connect logic +func tunnel(ctx context.Context, cancel context.CancelFunc, sigs chan os.Signal, tlsConfig *tls.Config, diagnosticsUrl string, metricsURL string) error { + diagnosticsClient := &http.Client{Transport: &http2.Transport{TLSClientConfig: tlsConfig}} + defer diagnosticsClient.CloseIdleConnections() + metricsClient := &http.Client{} + defer metricsClient.CloseIdleConnections() + // Create a request object to send to the server + reader, writer := io.Pipe() + ctx1, cancel1 := context.WithCancel(ctx) + defer cancel1() go func() { - <-sigs - interruptCh <- true - }() - interrupt := false - pollInterval := 500 * time.Millisecond - pollEvery := time.NewTicker(pollInterval) - defer pollEvery.Stop() - client := &http.Client{} - defer client.CloseIdleConnections() - diagnosticsUrl := ctx.String(utils.DiagnosticsURLFlag.Name) - giveRequestsUrl := path.Join(diagnosticsUrl, "giveRequests") - for !interrupt { select { - case interrupt = <-interruptCh: - log.Info("interrupted, please wait for cleanup") - case <-pollEvery.C: - pollResponse, err := client.Get(giveRequestsUrl) - if err != nil { - log.Error("Polling problem", "err", err) - } else if pollResponse.StatusCode != http.StatusOK { - log.Error("Polling problem", "status", pollResponse.Status) - } else { - buf := make([]byte, pollResponse.ContentLength) - if _, err = io.ReadFull(pollResponse.Body, buf); err != nil { - log.Error("Reading polling response", "err", err) - } - log.Info("Polling response", "resp", string(buf)) + case <-sigs: + cancel() + case <-ctx1.Done(): + } + reader.Close() + writer.Close() + }() + req, err := http.NewRequestWithContext(ctx1, http.MethodPost, diagnosticsUrl, reader) + if err != nil { + return err + } + + // Create a connection + // Apply given context to the sent request + resp, err := diagnosticsClient.Do(req) + if err != nil { + return err + } + defer resp.Body.Close() + defer writer.Close() + + // Apply the connection context on the request context + var metricsBuf bytes.Buffer + r := bufio.NewReaderSize(resp.Body, 4096) + line, isPrefix, err := r.ReadLine() + if err != nil { + return fmt.Errorf("reading first line: %v", err) + } + if isPrefix { + return fmt.Errorf("request too long") + } + if !bytes.Equal(line, successLine) { + return fmt.Errorf("connecting to diagnostics system, first line [%s]", line) + } + var versionBytes [8]byte + binary.BigEndian.PutUint64(versionBytes[:], Version) + if _, err = writer.Write(versionBytes[:]); err != nil { + return fmt.Errorf("sending version: %v", err) + } + + log.Info("Connected") + + for line, isPrefix, err = r.ReadLine(); err == nil && !isPrefix; line, isPrefix, err = r.ReadLine() { + metricsBuf.Reset() + metricsResponse, err := metricsClient.Get(metricsURL + string(line)) + if err != nil { + fmt.Fprintf(&metricsBuf, "ERROR: Requesting metrics url [%s], query [%s], err: %v", metricsURL, line, err) + } else { + // Buffer the metrics response, and relay it back to the diagnostics system, prepending with the size + if _, err := io.Copy(&metricsBuf, metricsResponse.Body); err != nil { + metricsBuf.Reset() + fmt.Fprintf(&metricsBuf, "ERROR: Extracting metrics url [%s], query [%s], err: %v", metricsURL, line, err) } - pollResponse.Body.Close() + metricsResponse.Body.Close() + } + var sizeBuf [4]byte + binary.BigEndian.PutUint32(sizeBuf[:], uint32(metricsBuf.Len())) + if _, err = writer.Write(sizeBuf[:]); err != nil { + log.Error("Problem relaying metrics prefix len", "url", metricsURL, "query", line, "err", err) + break + } + if _, err = writer.Write(metricsBuf.Bytes()); err != nil { + log.Error("Problem relaying", "url", metricsURL, "query", line, "err", err) + break } } + if err != nil { + select { + case <-ctx.Done(): + default: + log.Error("Breaking connection", "err", err) + } + } + if isPrefix { + log.Error("Request too long, circuit breaker") + } return nil } diff --git a/turbo/cli/default_flags.go b/turbo/cli/default_flags.go index 687409b18cf..58570bbda9e 100644 --- a/turbo/cli/default_flags.go +++ b/turbo/cli/default_flags.go @@ -12,7 +12,7 @@ var DefaultFlags = []cli.Flag{ &utils.DataDirFlag, &utils.EthashDatasetDirFlag, &utils.SnapshotFlag, - &utils.ExternalConsensusFlag, + &utils.InternalConsensusFlag, &utils.TxPoolDisableFlag, &utils.TxPoolLocalsFlag, &utils.TxPoolNoLocalsFlag, @@ -85,6 +85,7 @@ var DefaultFlags = []cli.Flag{ &utils.SnapKeepBlocksFlag, &utils.SnapStopFlag, &utils.DbPageSizeFlag, + &utils.DbSizeLimitFlag, &utils.TorrentPortFlag, &utils.TorrentMaxPeersFlag, &utils.TorrentConnsPerFileFlag, @@ -134,6 +135,7 @@ var DefaultFlags = []cli.Flag{ &utils.MinerSigningKeyFileFlag, &utils.SentryAddrFlag, &utils.SentryLogPeerInfoFlag, + &utils.SentryDropUselessPeers, &utils.DownloaderAddrFlag, &utils.DisableIPV4, &utils.DisableIPV6, diff --git a/turbo/cli/flags.go b/turbo/cli/flags.go index d8a944aa401..3489aadb9a7 100644 --- a/turbo/cli/flags.go +++ b/turbo/cli/flags.go @@ -2,7 +2,6 @@ package cli import ( "fmt" - "strings" "time" libcommon "github.com/ledgerwatch/erigon-lib/common" @@ -208,7 +207,7 @@ func ApplyFlagsForEthConfig(ctx *cli.Context, cfg *ethconfig.Config) { ctx.Uint64(PruneReceiptBeforeFlag.Name), ctx.Uint64(PruneTxIndexBeforeFlag.Name), ctx.Uint64(PruneCallTracesBeforeFlag.Name), - strings.Split(ctx.String(ExperimentsFlag.Name), ","), + utils.SplitAndTrim(ctx.String(ExperimentsFlag.Name)), ) if err != nil { utils.Fatalf(fmt.Sprintf("error while parsing mode: %v", err)) @@ -363,10 +362,10 @@ func setEmbeddedRpcDaemon(ctx *cli.Context, cfg *nodecfg.Config) { AuthRpcPort: ctx.Int(utils.AuthRpcPort.Name), JWTSecretPath: jwtSecretPath, TraceRequests: ctx.Bool(utils.HTTPTraceFlag.Name), - HttpCORSDomain: strings.Split(ctx.String(utils.HTTPCORSDomainFlag.Name), ","), - HttpVirtualHost: strings.Split(ctx.String(utils.HTTPVirtualHostsFlag.Name), ","), - AuthRpcVirtualHost: strings.Split(ctx.String(utils.AuthRpcVirtualHostsFlag.Name), ","), - API: strings.Split(apis, ","), + HttpCORSDomain: utils.SplitAndTrim(ctx.String(utils.HTTPCORSDomainFlag.Name)), + HttpVirtualHost: utils.SplitAndTrim(ctx.String(utils.HTTPVirtualHostsFlag.Name)), + AuthRpcVirtualHost: utils.SplitAndTrim(ctx.String(utils.AuthRpcVirtualHostsFlag.Name)), + API: utils.SplitAndTrim(apis), HTTPTimeouts: rpccfg.HTTPTimeouts{ ReadTimeout: ctx.Duration(HTTPReadTimeoutFlag.Name), WriteTimeout: ctx.Duration(HTTPWriteTimeoutFlag.Name), diff --git a/turbo/debug/flags.go b/turbo/debug/flags.go index 19bbdbe4dd4..fcafe071da6 100644 --- a/turbo/debug/flags.go +++ b/turbo/debug/flags.go @@ -80,7 +80,7 @@ func SetupCobra(cmd *cobra.Command) error { RaiseFdLimit() flags := cmd.Flags() - _ = logging.GetLoggerCmd("debug", cmd) + logging.SetupLoggerCmd("erigon", cmd) traceFile, err := flags.GetString(traceFlag.Name) if err != nil { @@ -144,7 +144,7 @@ func SetupCobra(cmd *cobra.Command) error { func Setup(ctx *cli.Context) error { RaiseFdLimit() - _ = logging.GetLoggerCtx("debug", ctx) + logging.SetupLoggerCtx("erigon", ctx) if traceFile := ctx.String(traceFlag.Name); traceFile != "" { if err := Handler.StartGoTrace(traceFile); err != nil { @@ -166,6 +166,9 @@ func Setup(ctx *cli.Context) error { exp.Setup(address) diagnostics.SetupLogsAccess(ctx) diagnostics.SetupDbAccess(ctx) + diagnostics.SetupCmdLineAccess() + diagnostics.SetupVersionAccess() + diagnostics.SetupBlockBodyDownload() } // pprof server diff --git a/turbo/logging/flags.go b/turbo/logging/flags.go index a5ce6658118..bf070e2fe1e 100644 --- a/turbo/logging/flags.go +++ b/turbo/logging/flags.go @@ -41,7 +41,7 @@ var ( LogDirVerbosityFlag = cli.StringFlag{ Name: "log.dir.verbosity", Usage: "Set the log verbosity for logs stored to disk", - Value: log.LvlDebug.String(), + Value: log.LvlInfo.String(), } ) diff --git a/turbo/logging/logging.go b/turbo/logging/logging.go index 597a1263610..09b03863d7f 100644 --- a/turbo/logging/logging.go +++ b/turbo/logging/logging.go @@ -4,14 +4,16 @@ import ( "flag" "os" "path" + "path/filepath" "strconv" "github.com/ledgerwatch/log/v3" "github.com/spf13/cobra" "github.com/urfave/cli/v2" + "gopkg.in/natefinch/lumberjack.v2" ) -func GetLoggerCtx(filePrefix string, ctx *cli.Context) log.Logger { +func SetupLoggerCtx(filePrefix string, ctx *cli.Context) { var consoleJson = ctx.Bool(LogJsonFlag.Name) || ctx.Bool(LogConsoleJsonFlag.Name) var dirJson = ctx.Bool(LogDirJsonFlag.Name) @@ -26,14 +28,20 @@ func GetLoggerCtx(filePrefix string, ctx *cli.Context) log.Logger { dirLevel, dErr := tryGetLogLevel(ctx.String(LogDirVerbosityFlag.Name)) if dErr != nil { - dirLevel = log.LvlDebug + dirLevel = log.LvlInfo } dirPath := ctx.String(LogDirPathFlag.Name) - return initSeparatedLogging(filePrefix, dirPath, consoleLevel, dirLevel, consoleJson, dirJson) + if dirPath == "" { + datadir := ctx.String("datadir") + if datadir != "" { + dirPath = filepath.Join(datadir, "logs") + } + } + initSeparatedLogging(filePrefix, dirPath, consoleLevel, dirLevel, consoleJson, dirJson) } -func GetLoggerCmd(filePrefix string, cmd *cobra.Command) log.Logger { +func SetupLoggerCmd(filePrefix string, cmd *cobra.Command) { logJsonVal, ljerr := cmd.Flags().GetBool(LogJsonFlag.Name) if ljerr != nil { @@ -62,14 +70,20 @@ func GetLoggerCmd(filePrefix string, cmd *cobra.Command) log.Logger { dirLevel, dErr := tryGetLogLevel(cmd.Flags().Lookup(LogDirVerbosityFlag.Name).Value.String()) if dErr != nil { - dirLevel = log.LvlDebug + dirLevel = log.LvlInfo } dirPath := cmd.Flags().Lookup(LogDirPathFlag.Name).Value.String() - return initSeparatedLogging(filePrefix, dirPath, consoleLevel, dirLevel, consoleJson, dirJson) + if dirPath == "" { + datadir := cmd.Flags().Lookup("datadir").Value.String() + if datadir != "" { + dirPath = filepath.Join(datadir, "logs") + } + } + initSeparatedLogging(filePrefix, dirPath, consoleLevel, dirLevel, consoleJson, dirJson) } -func GetLogger(filePrefix string) log.Logger { +func SetupLogger(filePrefix string) { var logConsoleVerbosity = flag.String(LogConsoleVerbosityFlag.Name, "", LogConsoleVerbosityFlag.Usage) var logDirVerbosity = flag.String(LogDirVerbosityFlag.Name, "", LogDirVerbosityFlag.Usage) var logDirPath = flag.String(LogDirPathFlag.Name, "", LogDirPathFlag.Usage) @@ -93,10 +107,10 @@ func GetLogger(filePrefix string) log.Logger { dirLevel, dErr := tryGetLogLevel(*logDirVerbosity) if dErr != nil { - dirLevel = log.LvlDebug + dirLevel = log.LvlInfo } - return initSeparatedLogging(filePrefix, *logDirPath, consoleLevel, dirLevel, consoleJson, *dirJson) + initSeparatedLogging(filePrefix, *logDirPath, consoleLevel, dirLevel, consoleJson, *dirJson) } func initSeparatedLogging( @@ -105,7 +119,7 @@ func initSeparatedLogging( consoleLevel log.Lvl, dirLevel log.Lvl, consoleJson bool, - dirJson bool) log.Logger { + dirJson bool) { logger := log.Root() @@ -117,36 +131,31 @@ func initSeparatedLogging( if len(dirPath) == 0 { logger.Warn("no log dir set, console logging only") - return logger + return } err := os.MkdirAll(dirPath, 0764) if err != nil { logger.Warn("failed to create log dir, console logging only") - return logger + return } - dirFormat := log.LogfmtFormat() + dirFormat := log.TerminalFormatNoColor() if dirJson { dirFormat = log.JsonFormat() } - userLog, err := log.FileHandler(path.Join(dirPath, filePrefix+"-user.log"), dirFormat, 1<<27) // 128Mb - if err != nil { - logger.Warn("failed to open user log, console logging only") - return logger - } - errLog, err := log.FileHandler(path.Join(dirPath, filePrefix+"-error.log"), dirFormat, 1<<27) // 128Mb - if err != nil { - logger.Warn("failed to open error log, console logging only") - return logger + lumberjack := &lumberjack.Logger{ + Filename: path.Join(dirPath, filePrefix+".log"), + MaxSize: 100, // megabytes + MaxBackups: 3, + MaxAge: 28, //days } + userLog := log.StreamHandler(lumberjack, dirFormat) - mux := log.MultiHandler(logger.GetHandler(), log.LvlFilterHandler(dirLevel, userLog), log.LvlFilterHandler(log.LvlError, errLog)) + mux := log.MultiHandler(logger.GetHandler(), log.LvlFilterHandler(dirLevel, userLog)) log.Root().SetHandler(mux) - logger.SetHandler(mux) logger.Info("logging to file system", "log dir", dirPath, "file prefix", filePrefix, "log level", dirLevel, "json", dirJson) - return logger } func tryGetLogLevel(s string) (log.Lvl, error) { diff --git a/turbo/node/node.go b/turbo/node/node.go index b74d6c48557..d89f6c71b19 100644 --- a/turbo/node/node.go +++ b/turbo/node/node.go @@ -102,7 +102,6 @@ func NewEthConfigUrfave(ctx *cli.Context, nodeConfig *nodecfg.Config) *ethconfig func New( nodeConfig *nodecfg.Config, ethConfig *ethconfig.Config, - logger log.Logger, ) (*ErigonNode, error) { //prepareBuckets(optionalParams.CustomBuckets) node, err := node.New(nodeConfig) @@ -110,7 +109,7 @@ func New( utils.Fatalf("Failed to create Erigon node: %v", err) } - ethereum, err := eth.New(node, ethConfig, logger) + ethereum, err := eth.New(node, ethConfig) if err != nil { return nil, err } diff --git a/turbo/rpchelper/interface.go b/turbo/rpchelper/interface.go index 9daee67c168..80583eae7b7 100644 --- a/turbo/rpchelper/interface.go +++ b/turbo/rpchelper/interface.go @@ -28,6 +28,7 @@ type ApiBackend interface { EngineNewPayload(ctx context.Context, payload *types2.ExecutionPayload) (*remote.EnginePayloadStatus, error) EngineForkchoiceUpdated(ctx context.Context, request *remote.EngineForkChoiceUpdatedRequest) (*remote.EngineForkChoiceUpdatedResponse, error) EngineGetPayload(ctx context.Context, payloadId uint64) (*remote.EngineGetPayloadResponse, error) + EngineGetBlobsBundleV1(ctx context.Context, payloadId uint64) (*types2.BlobsBundleV1, error) NodeInfo(ctx context.Context, limit uint32) ([]p2p.NodeInfo, error) Peers(ctx context.Context) ([]*p2p.PeerInfo, error) PendingBlock(ctx context.Context) (*types.Block, error) diff --git a/turbo/shards/state_change_accumulator.go b/turbo/shards/state_change_accumulator.go index 7d698b8760b..321337f722b 100644 --- a/turbo/shards/state_change_accumulator.go +++ b/turbo/shards/state_change_accumulator.go @@ -36,7 +36,7 @@ func (a *Accumulator) SendAndReset(ctx context.Context, c StateChangeConsumer, p if a == nil || c == nil || len(a.changes) == 0 { return } - sc := &remote.StateChangeBatch{StateVersionID: a.plainStateID, ChangeBatch: a.changes, PendingBlockBaseFee: pendingBaseFee, BlockGasLimit: blockGasLimit} + sc := &remote.StateChangeBatch{StateVersionId: a.plainStateID, ChangeBatch: a.changes, PendingBlockBaseFee: pendingBaseFee, BlockGasLimit: blockGasLimit} c.SendStateChanges(ctx, sc) a.Reset(0) // reset here for GC, but there will be another Reset with correct viewID } diff --git a/turbo/snapshotsync/block_reader.go b/turbo/snapshotsync/block_reader.go index e49823a0cf9..ccd820952bd 100644 --- a/turbo/snapshotsync/block_reader.go +++ b/turbo/snapshotsync/block_reader.go @@ -465,6 +465,7 @@ func (back *BlockReaderWithSnapshots) bodyFromSnapshot(blockHeight uint64, sn *B body := new(types.Body) body.Uncles = b.Uncles + body.Withdrawals = b.Withdrawals var txsAmount uint32 if b.TxAmount >= 2 { txsAmount = b.TxAmount - 2 diff --git a/turbo/snapshotsync/block_snapshots.go b/turbo/snapshotsync/block_snapshots.go index c7a4c119c1b..20ca42a4ef2 100644 --- a/turbo/snapshotsync/block_snapshots.go +++ b/turbo/snapshotsync/block_snapshots.go @@ -862,8 +862,8 @@ func (s *RoSnapshots) ViewTxs(blockNum uint64, f func(sn *TxnSegment) error) (fo } func buildIdx(ctx context.Context, sn snaptype.FileInfo, chainID uint256.Int, tmpDir string, p *background.Progress, lvl log.Lvl) error { - _, fName := filepath.Split(sn.Path) - log.Debug("[snapshots] build idx", "file", fName) + //_, fName := filepath.Split(sn.Path) + //log.Debug("[snapshots] build idx", "file", fName) switch sn.T { case snaptype.Headers: if err := HeadersIdx(ctx, sn.Path, sn.From, tmpDir, p, lvl); err != nil { @@ -885,8 +885,7 @@ func buildIdx(ctx context.Context, sn snaptype.FileInfo, chainID uint256.Int, tm func BuildMissedIndices(logPrefix string, ctx context.Context, dirs datadir.Dirs, chainID uint256.Int, workers int) error { dir, tmpDir := dirs.Snap, dirs.Tmp //log.Log(lvl, "[snapshots] Build indices", "from", min) - logEvery := time.NewTicker(20 * time.Second) - defer logEvery.Stop() + segments, _, err := Segments(dir) if err != nil { return err @@ -920,6 +919,8 @@ func BuildMissedIndices(logPrefix string, ctx context.Context, dirs datadir.Dirs g.Wait() }() + logEvery := time.NewTicker(20 * time.Second) + defer logEvery.Stop() for { select { case <-finish: @@ -1793,8 +1794,6 @@ RETRY: return fmt.Errorf("txnHash2BlockNumIdx: %w", err) } - p.Processed.Store(p.Total.Load()) - return nil } @@ -2027,7 +2026,6 @@ func (m *Merger) Merge(ctx context.Context, snapshots *RoSnapshots, mergeRanges } logEvery := time.NewTicker(30 * time.Second) defer logEvery.Stop() - log.Log(m.lvl, "[snapshots] Merge segments", "ranges", fmt.Sprintf("%v", mergeRanges)) for _, r := range mergeRanges { toMerge, err := m.filesByRange(snapshots, r.from, r.to) if err != nil { @@ -2090,14 +2088,6 @@ func (m *Merger) merge(ctx context.Context, toMerge []string, targetFile string, if err := f.AddWord(word); err != nil { return err } - select { - case <-ctx.Done(): - return ctx.Err() - case <-logEvery.C: - _, fName := filepath.Split(targetFile) - log.Info("[snapshots] Merge", "progress", fmt.Sprintf("%.2f%%", 100*float64(f.Count())/float64(expectedTotal)), "to", fName) - default: - } } return nil }); err != nil { diff --git a/turbo/stages/blockchain_test.go b/turbo/stages/blockchain_test.go index e349fd9f4a5..dbc654b3ef4 100644 --- a/turbo/stages/blockchain_test.go +++ b/turbo/stages/blockchain_test.go @@ -928,7 +928,7 @@ func TestEIP161AccountRemoval(t *testing.T) { t.Fatal(err) } err = m.DB.View(context.Background(), func(tx kv.Tx) error { - if st := state.New(state.NewPlainStateReader(tx)); !st.Exist(theAddr) { + if st := state.New(m.NewStateReader(tx)); !st.Exist(theAddr) { t.Error("expected account to exist") } return nil @@ -939,8 +939,8 @@ func TestEIP161AccountRemoval(t *testing.T) { if err = m.InsertChain(chain.Slice(1, 2)); err != nil { t.Fatal(err) } - err = m.DB.View(context.Background(), func(tx kv.Tx) error { - if st := state.New(state.NewPlainStateReader(tx)); st.Exist(theAddr) { + err = m.DB.View(m.Ctx, func(tx kv.Tx) error { + if st := state.New(m.NewStateReader(tx)); st.Exist(theAddr) { t.Error("account should not exist") } return nil @@ -951,8 +951,8 @@ func TestEIP161AccountRemoval(t *testing.T) { if err = m.InsertChain(chain.Slice(2, 3)); err != nil { t.Fatal(err) } - err = m.DB.View(context.Background(), func(tx kv.Tx) error { - if st := state.New(state.NewPlainStateReader(tx)); st.Exist(theAddr) { + err = m.DB.View(m.Ctx, func(tx kv.Tx) error { + if st := state.New(m.NewStateReader(tx)); st.Exist(theAddr) { t.Error("account should not exist") } return nil @@ -1017,7 +1017,7 @@ func TestDoubleAccountRemoval(t *testing.T) { }) assert.NoError(t, err) - tx, err := m.DB.BeginRo(context.Background()) + tx, err := m.DB.BeginRo(m.Ctx) if err != nil { t.Fatalf("read only db tx to read state: %v", err) } @@ -1074,7 +1074,7 @@ func TestBlockchainHeaderchainReorgConsistency(t *testing.T) { t.Fatalf("block %d: failed to insert into chain: %v", i, err) } - if err := m2.DB.View(context.Background(), func(tx kv.Tx) error { + if err := m2.DB.View(m2.Ctx, func(tx kv.Tx) error { b, h := rawdb.ReadCurrentBlock(tx), rawdb.ReadCurrentHeader(tx) if b.Hash() != h.Hash() { t.Errorf("block %d: current block/header mismatch: block #%d [%x…], header #%d [%x…]", i, b.Number(), b.Hash().Bytes()[:4], h.Number, h.Hash().Bytes()[:4]) @@ -1385,7 +1385,7 @@ func TestDeleteRecreateSlots(t *testing.T) { if err := m.InsertChain(chain); err != nil { t.Fatalf("failed to insert into chain: %v", err) } - err = m.DB.View(context.Background(), func(tx kv.Tx) error { + err = m.DB.View(m.Ctx, func(tx kv.Tx) error { statedb := state.New(m.NewHistoryStateReader(2, tx)) // If all is correct, then slot 1 and 2 are zero @@ -1503,7 +1503,7 @@ func TestCVE2020_26265(t *testing.T) { if err := m.InsertChain(chain); err != nil { t.Fatalf("failed to insert into chain: %v", err) } - err = m.DB.View(context.Background(), func(tx kv.Tx) error { + err = m.DB.View(m.Ctx, func(tx kv.Tx) error { reader := m.NewHistoryStateReader(2, tx) statedb := state.New(reader) @@ -1570,7 +1570,7 @@ func TestDeleteRecreateAccount(t *testing.T) { if err := m.InsertChain(chain); err != nil { t.Fatalf("failed to insert into chain: %v", err) } - err = m.DB.View(context.Background(), func(tx kv.Tx) error { + err = m.DB.View(m.Ctx, func(tx kv.Tx) error { statedb := state.New(m.NewHistoryStateReader(2, tx)) // If all is correct, then both slots are zero @@ -1880,7 +1880,7 @@ func TestInitThenFailCreateContract(t *testing.T) { t.Fatalf("generate blocks: %v", err) } - err = m.DB.View(context.Background(), func(tx kv.Tx) error { + err = m.DB.View(m.Ctx, func(tx kv.Tx) error { // Import the canonical chain statedb := state.New(m.NewHistoryStateReader(2, tx)) @@ -1978,7 +1978,7 @@ func TestEIP2718Transition(t *testing.T) { t.Fatalf("failed to insert into chain: %v", err) } - tx, err := m.DB.BeginRo(context.Background()) + tx, err := m.DB.BeginRo(m.Ctx) if err != nil { t.Fatal(err) } @@ -2088,7 +2088,7 @@ func TestEIP1559Transition(t *testing.T) { t.Fatalf("incorrect amount of gas spent: expected %d, got %d", expectedGas, block.GasUsed()) } - err = m.DB.View(context.Background(), func(tx kv.Tx) error { + err = m.DB.View(m.Ctx, func(tx kv.Tx) error { statedb := state.New(m.NewHistoryStateReader(1, tx)) // 3: Ensure that miner received only the tx's tip. @@ -2129,7 +2129,7 @@ func TestEIP1559Transition(t *testing.T) { } block = chain.Blocks[0] - err = m.DB.View(context.Background(), func(tx kv.Tx) error { + err = m.DB.View(m.Ctx, func(tx kv.Tx) error { statedb := state.New(m.NewHistoryStateReader(1, tx)) effectiveTip := block.Transactions()[0].GetPrice().Uint64() - block.BaseFee().Uint64() diff --git a/turbo/stages/bodydownload/body_algos.go b/turbo/stages/bodydownload/body_algos.go index 3f055c24912..b80f83ce6cd 100644 --- a/turbo/stages/bodydownload/body_algos.go +++ b/turbo/stages/bodydownload/body_algos.go @@ -16,6 +16,7 @@ import ( "github.com/ledgerwatch/erigon/core/rawdb" "github.com/ledgerwatch/erigon/core/types" + "github.com/ledgerwatch/erigon/dataflow" "github.com/ledgerwatch/erigon/eth/stagedsync/stages" "github.com/ledgerwatch/erigon/turbo/adapter" "github.com/ledgerwatch/erigon/turbo/services" @@ -88,6 +89,7 @@ func (bd *BodyDownload) RequestMoreBodies(tx kv.RwTx, blockReader services.FullB continue } bd.peerMap[req.peerID]++ + dataflow.BlockBodyDownloadStates.AddChange(blockNum, dataflow.BlockBodyExpired) delete(bd.requests, blockNum) } @@ -147,12 +149,14 @@ func (bd *BodyDownload) RequestMoreBodies(tx kv.RwTx, blockReader services.FullB body.Withdrawals = make([]*types.Withdrawal, 0) } bd.addBodyToCache(blockNum, body) + dataflow.BlockBodyDownloadStates.AddChange(blockNum, dataflow.BlockBodyEmpty) request = false } else { // Perhaps we already have this block block := rawdb.ReadBlock(tx, hash, blockNum) if block != nil { bd.addBodyToCache(blockNum, block.RawBody()) + dataflow.BlockBodyDownloadStates.AddChange(blockNum, dataflow.BlockBodyInDb) request = false } } @@ -192,6 +196,7 @@ func (bd *BodyDownload) checkPrefetchedBlock(hash libcommon.Hash, tx kv.RwTx, bl bd.deliveriesH[blockNum] = header // make sure we have the body in the bucket for later use + dataflow.BlockBodyDownloadStates.AddChange(blockNum, dataflow.BlockBodyPrefetched) bd.addBodyToCache(blockNum, body) // Calculate the TD of the block (it's not imported yet, so block.Td is not valid) @@ -215,6 +220,7 @@ func (bd *BodyDownload) RequestSent(bodyReq *BodyRequest, timeWithTimeout uint64 //} for _, num := range bodyReq.BlockNums { bd.requests[num] = bodyReq + dataflow.BlockBodyDownloadStates.AddChange(num, dataflow.BlockBodyRequested) } bodyReq.waitUntil = timeWithTimeout bodyReq.peerID = peer @@ -317,11 +323,16 @@ Loop: bd.addBodyToCache(blockNum, &types.RawBody{Transactions: txs[i], Uncles: uncles[i], Withdrawals: withdrawals[i]}) bd.delivered.Add(blockNum) delivered++ + dataflow.BlockBodyDownloadStates.AddChange(blockNum, dataflow.BlockBodyReceived) } // Clean up the requests //var clearedNums []uint64 for blockNum := range toClean { delete(bd.requests, blockNum) + if !bd.delivered.Contains(blockNum) { + // Delivery was requested but was skipped due to the limitation on the size of the response + dataflow.BlockBodyDownloadStates.AddChange(blockNum, dataflow.BlockBodySkipped) + } //clearedNums = append(clearedNums, blockNum) } //sort.Slice(deliveredNums, func(i, j int) bool { return deliveredNums[i] < deliveredNums[j] }) @@ -417,6 +428,7 @@ func (bd *BodyDownload) addBodyToCache(key uint64, body *types.RawBody) { item, _ := bd.bodyCache.DeleteMax() bd.bodyCacheSize -= item.payloadSize delete(bd.requests, item.blockNum) + dataflow.BlockBodyDownloadStates.AddChange(item.blockNum, dataflow.BlockBodyEvicted) } } diff --git a/turbo/stages/chain_makers_test.go b/turbo/stages/chain_makers_test.go index 98658800212..825669fb99d 100644 --- a/turbo/stages/chain_makers_test.go +++ b/turbo/stages/chain_makers_test.go @@ -106,7 +106,7 @@ func TestGenerateChain(t *testing.T) { } defer tx.Rollback() - st := state.New(state.NewPlainStateReader(tx)) + st := state.New(m.NewStateReader(tx)) if big.NewInt(5).Cmp(current(m.DB).Number()) != 0 { t.Errorf("wrong block number: %d", current(m.DB).Number()) } diff --git a/turbo/stages/headerdownload/header_algo_test.go b/turbo/stages/headerdownload/header_algo_test.go index 8b168bbd709..ea6b3d95980 100644 --- a/turbo/stages/headerdownload/header_algo_test.go +++ b/turbo/stages/headerdownload/header_algo_test.go @@ -54,11 +54,11 @@ func TestInserter1(t *testing.T) { } h2Hash := h2.Hash() data1, _ := rlp.EncodeToBytes(&h1) - if _, err = hi.FeedHeaderPoW(tx, snapshotsync.NewBlockReaderWithSnapshots(m.BlockSnapshots, m.TransactionsV3), &h1, data1, h1Hash, 1); err != nil { + if _, err = hi.FeedHeaderPoW(tx, snapshotsync.NewBlockReaderWithSnapshots(m.BlockSnapshots, m.TransactionsV3), &h1, data1, h1Hash, 1, nil, *chainConfig, nil); err != nil { t.Errorf("feed empty header 1: %v", err) } data2, _ := rlp.EncodeToBytes(&h2) - if _, err = hi.FeedHeaderPoW(tx, snapshotsync.NewBlockReaderWithSnapshots(m.BlockSnapshots, m.TransactionsV3), &h2, data2, h2Hash, 2); err != nil { + if _, err = hi.FeedHeaderPoW(tx, snapshotsync.NewBlockReaderWithSnapshots(m.BlockSnapshots, m.TransactionsV3), &h2, data2, h2Hash, 2, nil, *chainConfig, nil); err != nil { t.Errorf("feed empty header 2: %v", err) } } diff --git a/turbo/stages/headerdownload/header_algos.go b/turbo/stages/headerdownload/header_algos.go index 07aec41d2c3..a6c2adf533c 100644 --- a/turbo/stages/headerdownload/header_algos.go +++ b/turbo/stages/headerdownload/header_algos.go @@ -14,6 +14,7 @@ import ( "strings" "time" + "github.com/ledgerwatch/erigon-lib/chain" libcommon "github.com/ledgerwatch/erigon-lib/common" "github.com/ledgerwatch/erigon-lib/etl" "github.com/ledgerwatch/erigon-lib/kv" @@ -497,7 +498,7 @@ func (hd *HeaderDownload) RequestSkeleton() *HeaderRequest { } func (hd *HeaderDownload) VerifyHeader(header *types.Header) error { - return hd.engine.VerifyHeader(hd.consensusHeaderReader, header, true /* seal */) + return hd.Engine.VerifyHeader(hd.ConsensusHeaderReader, header, true /* seal */) } type FeedHeaderFunc = func(header *types.Header, headerRaw []byte, hash libcommon.Hash, blockHeight uint64) (td *big.Int, err error) @@ -785,9 +786,9 @@ func (hd *HeaderDownload) addHeaderAsLink(h ChainSegmentHeader, persisted bool) return link } -func (hi *HeaderInserter) NewFeedHeaderFunc(db kv.StatelessRwTx, headerReader services.HeaderReader) FeedHeaderFunc { +func (hi *HeaderInserter) NewFeedHeaderFunc(db kv.StatelessRwTx, headerReader services.HeaderReader, engine consensus.Engine, config chain.Config, consensusHeaderReader consensus.ChainHeaderReader) FeedHeaderFunc { return func(header *types.Header, headerRaw []byte, hash libcommon.Hash, blockHeight uint64) (*big.Int, error) { - return hi.FeedHeaderPoW(db, headerReader, header, headerRaw, hash, blockHeight) + return hi.FeedHeaderPoW(db, headerReader, header, headerRaw, hash, blockHeight, engine, config, consensusHeaderReader) } } @@ -844,7 +845,7 @@ func (hi *HeaderInserter) ForkingPoint(db kv.StatelessRwTx, header, parent *type return } -func (hi *HeaderInserter) FeedHeaderPoW(db kv.StatelessRwTx, headerReader services.HeaderReader, header *types.Header, headerRaw []byte, hash libcommon.Hash, blockHeight uint64) (td *big.Int, err error) { +func (hi *HeaderInserter) FeedHeaderPoW(db kv.StatelessRwTx, headerReader services.HeaderReader, header *types.Header, headerRaw []byte, hash libcommon.Hash, blockHeight uint64, engine consensus.Engine, config chain.Config, consensusHeaderReader consensus.ChainHeaderReader) (td *big.Int, err error) { if hash == hi.prevHash { // Skip duplicates return nil, nil @@ -857,6 +858,7 @@ func (hi *HeaderInserter) FeedHeaderPoW(db kv.StatelessRwTx, headerReader servic // Already inserted, skip return nil, nil } + // Load parent header parent, err := headerReader.Header(context.Background(), db, header.ParentHash, blockHeight-1) if err != nil { @@ -866,15 +868,38 @@ func (hi *HeaderInserter) FeedHeaderPoW(db kv.StatelessRwTx, headerReader servic // Fail on headers without parent return nil, fmt.Errorf("could not find parent with hash %x and height %d for header %x %d", header.ParentHash, blockHeight-1, hash, blockHeight) } - // Parent's total difficulty - parentTd, err := rawdb.ReadTd(db, header.ParentHash, blockHeight-1) - if err != nil || parentTd == nil { - return nil, fmt.Errorf("[%s] parent's total difficulty not found with hash %x and height %d for header %x %d: %v", hi.logPrefix, header.ParentHash, blockHeight-1, hash, blockHeight, err) + + isWithFastFinality := true + reorgFunc := func() (bool, error) { + if p, ok := engine.(consensus.PoSA); ok { + justifiedNumber, curJustifiedNumber := uint64(0), uint64(0) + if config.IsPlato(header.Number.Uint64()) { + if justifiedNumberGot, _, err := p.GetJustifiedNumberAndHash(consensusHeaderReader, header); err == nil { + justifiedNumber = justifiedNumberGot + } + } + if config.IsPlato(hi.highest) { + if justifiedNumberGot, _, err := p.GetJustifiedNumberAndHash(consensusHeaderReader, header); err == nil { + curJustifiedNumber = justifiedNumberGot + } + } + if justifiedNumber == curJustifiedNumber { + // Parent's total difficulty + parentTd, err := rawdb.ReadTd(db, header.ParentHash, blockHeight-1) + if err != nil || parentTd == nil { + return false, fmt.Errorf("[%s] parent's total difficulty not found with hash %x and height %d for header %x %d: %v", hi.logPrefix, header.ParentHash, blockHeight-1, hash, blockHeight, err) + } + // Calculate total difficulty of this header using parent's total difficulty + td = new(big.Int).Add(parentTd, header.Difficulty) + isWithFastFinality = false + return td.Cmp(hi.localTd) > 0, nil + } + return justifiedNumber > curJustifiedNumber, nil + } + return false, nil } - // Calculate total difficulty of this header using parent's total difficulty - td = new(big.Int).Add(parentTd, header.Difficulty) // Now we can decide wether this header will create a change in the canonical head - if td.Cmp(hi.localTd) > 0 { + if reorg, err := reorgFunc(); err == nil && reorg { hi.newCanonical = true forkingPoint, err := hi.ForkingPoint(db, header, parent) if err != nil { @@ -890,8 +915,11 @@ func (hi *HeaderInserter) FeedHeaderPoW(db kv.StatelessRwTx, headerReader servic hi.unwind = true } // This makes sure we end up choosing the chain with the max total difficulty - hi.localTd.Set(td) + if !isWithFastFinality { + hi.localTd.Set(td) + } } + if err = rawdb.WriteTd(db, hash, blockHeight, td); err != nil { return nil, fmt.Errorf("[%s] failed to WriteTd: %w", hi.logPrefix, err) } @@ -1066,7 +1094,7 @@ func (hd *HeaderDownload) SetFirstPoSHeight(blockHeight uint64) { func (hd *HeaderDownload) SetHeaderReader(headerReader consensus.ChainHeaderReader) { hd.lock.Lock() defer hd.lock.Unlock() - hd.consensusHeaderReader = headerReader + hd.ConsensusHeaderReader = headerReader } func (hd *HeaderDownload) AfterInitialCycle() { diff --git a/turbo/stages/headerdownload/header_data_struct.go b/turbo/stages/headerdownload/header_data_struct.go index a1266990ee0..7b11b3bc311 100644 --- a/turbo/stages/headerdownload/header_data_struct.go +++ b/turbo/stages/headerdownload/header_data_struct.go @@ -8,8 +8,8 @@ import ( "time" "github.com/google/btree" - lru "github.com/hashicorp/golang-lru" - libcommon "github.com/ledgerwatch/erigon-lib/common" + lru "github.com/hashicorp/golang-lru/v2" + "github.com/ledgerwatch/erigon-lib/common" "github.com/ledgerwatch/erigon-lib/etl" "github.com/ledgerwatch/erigon/consensus" @@ -36,9 +36,9 @@ const ( type Link struct { header *types.Header headerRaw []byte - fChild *Link // Pointer to the first child, further children can be found by following `next` pointers to the siblings - next *Link // Pointer to the next sibling, or nil if there are no siblings - hash libcommon.Hash // Hash of the header + fChild *Link // Pointer to the first child, further children can be found by following `next` pointers to the siblings + next *Link // Pointer to the next sibling, or nil if there are no siblings + hash common.Hash // Hash of the header blockHeight uint64 persisted bool // Whether this link comes from the database record verified bool // Ancestor of pre-verified header or verified by consensus engine @@ -105,8 +105,8 @@ func (lq *LinkQueue) Pop() interface{} { // more than one pointer. type Anchor struct { peerID [64]byte - fLink *Link // Links attached immediately to this anchor (pointer to the first one, the rest can be found by following `next` fields) - parentHash libcommon.Hash // Hash of the header this anchor can be connected to (to disappear) + fLink *Link // Links attached immediately to this anchor (pointer to the first one, the rest can be found by following `next` fields) + parentHash common.Hash // Hash of the header this anchor can be connected to (to disappear) blockHeight uint64 nextRetryTime time.Time // Zero when anchor has just been created, otherwise time when anchor needs to be check to see if retry is needed timeouts int // Number of timeout that this anchor has experiences - after certain threshold, it gets invalidated @@ -115,7 +115,7 @@ type Anchor struct { type ChainSegmentHeader struct { HeaderRaw rlp.RawValue Header *types.Header - Hash libcommon.Hash + Hash common.Hash Number uint64 } @@ -149,7 +149,7 @@ type PeerPenalty struct { // Request for chain segment starting with hash and going to its parent, etc, with length headers in total type HeaderRequest struct { - Hash libcommon.Hash + Hash common.Hash Number uint64 Length uint64 Skip uint64 @@ -162,12 +162,12 @@ type PenaltyItem struct { Penalty Penalty } type Announce struct { - Hash libcommon.Hash + Hash common.Hash Number uint64 } type VerifySealFunc func(header *types.Header) error -type CalcDifficultyFunc func(childTimestamp uint64, parentTime uint64, parentDifficulty, parentNumber *big.Int, parentHash, parentUncleHash libcommon.Hash) *big.Int +type CalcDifficultyFunc func(childTimestamp uint64, parentTime uint64, parentDifficulty, parentNumber *big.Int, parentHash, parentUncleHash common.Hash) *big.Int // InsertQueue keeps the links before they are inserted in the database // It priorities them by block height (the lowest block height on the top), @@ -227,10 +227,10 @@ type Stats struct { } type HeaderDownload struct { - badHeaders map[libcommon.Hash]struct{} - anchors map[libcommon.Hash]*Anchor // Mapping from parentHash to collection of anchors - links map[libcommon.Hash]*Link // Links by header hash - engine consensus.Engine + badHeaders map[common.Hash]struct{} + anchors map[common.Hash]*Anchor // Mapping from parentHash to collection of anchors + links map[common.Hash]*Link // Links by header hash + Engine consensus.Engine insertQueue InsertQueue // Priority queue of non-persisted links that need to be verified and can be inserted seenAnnounces *SeenAnnounces // External announcement hashes, after header verification if hash is in this set - will broadcast it further persistedLinkQueue LinkQueue // Priority queue of persisted links used to limit their number @@ -251,7 +251,7 @@ type HeaderDownload struct { trace bool stats Stats - consensusHeaderReader consensus.ChainHeaderReader + ConsensusHeaderReader consensus.ChainHeaderReader headerReader services.HeaderReader // Proof of Stake (PoS) @@ -259,17 +259,17 @@ type HeaderDownload struct { requestId int posAnchor *Anchor posStatus SyncStatus - posSync bool // Whether the chain is syncing in the PoS mode - headersCollector *etl.Collector // ETL collector for headers - BeaconRequestList *engineapi.RequestList // Requests from ethbackend to staged sync - PayloadStatusCh chan engineapi.PayloadStatus // Responses (validation/execution status) - ShutdownCh chan struct{} // Channel to signal shutdown - pendingPayloadHash libcommon.Hash // Header whose status we still should send to PayloadStatusCh - pendingPayloadStatus *engineapi.PayloadStatus // Alternatively, there can be an already prepared response to send to PayloadStatusCh - unsettledForkChoice *engineapi.ForkChoiceMessage // Forkchoice to process after unwind - unsettledHeadHeight uint64 // Height of unsettledForkChoice.headBlockHash - posDownloaderTip libcommon.Hash // See https://hackmd.io/GDc0maGsQeKfP8o2C7L52w - badPoSHeaders map[libcommon.Hash]libcommon.Hash // Invalid Tip -> Last Valid Ancestor + posSync bool // Whether the chain is syncing in the PoS mode + headersCollector *etl.Collector // ETL collector for headers + BeaconRequestList *engineapi.RequestList // Requests from ethbackend to staged sync + PayloadStatusCh chan engineapi.PayloadStatus // Responses (validation/execution status) + ShutdownCh chan struct{} // Channel to signal shutdown + pendingPayloadHash common.Hash // Header whose status we still should send to PayloadStatusCh + pendingPayloadStatus *engineapi.PayloadStatus // Alternatively, there can be an already prepared response to send to PayloadStatusCh + unsettledForkChoice *engineapi.ForkChoiceMessage // Forkchoice to process after unwind + unsettledHeadHeight uint64 // Height of unsettledForkChoice.headBlockHash + posDownloaderTip common.Hash // See https://hackmd.io/GDc0maGsQeKfP8o2C7L52w + badPoSHeaders map[common.Hash]common.Hash // Invalid Tip -> Last Valid Ancestor } // HeaderRecord encapsulates two forms of the same header - raw RLP encoding (to avoid duplicated decodings and encodings), and parsed value types.Header @@ -287,13 +287,13 @@ func NewHeaderDownload( persistentLinkLimit := linkLimit / 16 hd := &HeaderDownload{ initialCycle: true, - badHeaders: make(map[libcommon.Hash]struct{}), - anchors: make(map[libcommon.Hash]*Anchor), + badHeaders: make(map[common.Hash]struct{}), + anchors: make(map[common.Hash]*Anchor), persistedLinkLimit: persistentLinkLimit, linkLimit: linkLimit - persistentLinkLimit, anchorLimit: anchorLimit, - engine: engine, - links: make(map[libcommon.Hash]*Link), + Engine: engine, + links: make(map[common.Hash]*Link), anchorTree: btree.NewG[*Anchor](32, func(a, b *Anchor) bool { return a.blockHeight < b.blockHeight }), seenAnnounces: NewSeenAnnounces(), DeliveryNotify: make(chan struct{}, 1), @@ -302,7 +302,7 @@ func NewHeaderDownload( PayloadStatusCh: make(chan engineapi.PayloadStatus, 1), ShutdownCh: make(chan struct{}), headerReader: headerReader, - badPoSHeaders: make(map[libcommon.Hash]libcommon.Hash), + badPoSHeaders: make(map[common.Hash]common.Hash), } heap.Init(&hd.persistedLinkQueue) heap.Init(&hd.linkQueue) @@ -371,14 +371,14 @@ func (hd *HeaderDownload) moveLinkToQueue(link *Link, queueId QueueID) { type HeaderInserter struct { localTd *big.Int logPrefix string - prevHash libcommon.Hash // Hash of previously seen header - to filter out potential duplicates - highestHash libcommon.Hash + prevHash common.Hash // Hash of previously seen header - to filter out potential duplicates + highestHash common.Hash newCanonical bool unwind bool unwindPoint uint64 highest uint64 highestTimestamp uint64 - canonicalCache *lru.Cache + canonicalCache *lru.Cache[uint64, common.Hash] headerReader services.HeaderAndCanonicalReader } @@ -389,24 +389,24 @@ func NewHeaderInserter(logPrefix string, localTd *big.Int, headerProgress uint64 unwindPoint: headerProgress, headerReader: headerReader, } - hi.canonicalCache, _ = lru.New(1000) + hi.canonicalCache, _ = lru.New[uint64, common.Hash](1000) return hi } // SeenAnnounces - external announcement hashes, after header verification if hash is in this set - will broadcast it further type SeenAnnounces struct { - hashes *lru.Cache + hashes *lru.Cache[common.Hash, struct{}] } func NewSeenAnnounces() *SeenAnnounces { - cache, err := lru.New(1000) + cache, err := lru.New[common.Hash, struct{}](1000) if err != nil { panic("error creating prefetching cache for blocks") } return &SeenAnnounces{hashes: cache} } -func (s *SeenAnnounces) Pop(hash libcommon.Hash) bool { +func (s *SeenAnnounces) Pop(hash common.Hash) bool { _, ok := s.hashes.Get(hash) if ok { s.hashes.Remove(hash) @@ -414,11 +414,11 @@ func (s *SeenAnnounces) Pop(hash libcommon.Hash) bool { return ok } -func (s SeenAnnounces) Seen(hash libcommon.Hash) bool { +func (s SeenAnnounces) Seen(hash common.Hash) bool { _, ok := s.hashes.Get(hash) return ok } -func (s *SeenAnnounces) Add(b libcommon.Hash) { +func (s *SeenAnnounces) Add(b common.Hash) { s.hashes.ContainsOrAdd(b, struct{}{}) } diff --git a/turbo/stages/mock_sentry.go b/turbo/stages/mock_sentry.go index f3da029aecb..535f611063b 100644 --- a/turbo/stages/mock_sentry.go +++ b/turbo/stages/mock_sentry.go @@ -27,12 +27,15 @@ import ( "github.com/ledgerwatch/erigon-lib/kv/remotedbserver" libstate "github.com/ledgerwatch/erigon-lib/state" "github.com/ledgerwatch/erigon-lib/txpool" + "github.com/ledgerwatch/erigon-lib/txpool/txpoolcfg" types2 "github.com/ledgerwatch/erigon-lib/types" - "github.com/ledgerwatch/erigon/core/systemcontracts" - "github.com/ledgerwatch/erigon/turbo/rpchelper" + "github.com/ledgerwatch/erigon/turbo/trie" "github.com/ledgerwatch/log/v3" "google.golang.org/protobuf/types/known/emptypb" + "github.com/ledgerwatch/erigon/core/systemcontracts" + "github.com/ledgerwatch/erigon/turbo/rpchelper" + "github.com/ledgerwatch/erigon/core/state/historyv2read" "github.com/ledgerwatch/erigon/core/state/temporal" "github.com/ledgerwatch/erigon/core/types/accounts" @@ -65,12 +68,12 @@ type MockSentry struct { proto_sentry.UnimplementedSentryServer Ctx context.Context Log log.Logger - t *testing.T + tb testing.TB cancel context.CancelFunc DB kv.RwDB Dirs datadir.Dirs Engine consensus.Engine - gspec *core.Genesis + gspec *types.Genesis ChainConfig *chain.Config Sync *stagedsync.Sync MiningSync *stagedsync.Sync @@ -201,23 +204,23 @@ func (ms *MockSentry) NodeInfo(context.Context, *emptypb.Empty) (*ptypes.NodeInf return nil, nil } -func MockWithGenesis(t *testing.T, gspec *core.Genesis, key *ecdsa.PrivateKey, withPosDownloader bool) *MockSentry { - return MockWithGenesisPruneMode(t, gspec, key, prune.DefaultMode, withPosDownloader) +func MockWithGenesis(tb testing.TB, gspec *types.Genesis, key *ecdsa.PrivateKey, withPosDownloader bool) *MockSentry { + return MockWithGenesisPruneMode(tb, gspec, key, prune.DefaultMode, withPosDownloader) } -func MockWithGenesisEngine(t *testing.T, gspec *core.Genesis, engine consensus.Engine, withPosDownloader bool) *MockSentry { +func MockWithGenesisEngine(tb testing.TB, gspec *types.Genesis, engine consensus.Engine, withPosDownloader bool) *MockSentry { key, _ := crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291") - return MockWithEverything(t, gspec, key, prune.DefaultMode, engine, false, withPosDownloader) + return MockWithEverything(tb, gspec, key, prune.DefaultMode, engine, false, withPosDownloader) } -func MockWithGenesisPruneMode(t *testing.T, gspec *core.Genesis, key *ecdsa.PrivateKey, prune prune.Mode, withPosDownloader bool) *MockSentry { - return MockWithEverything(t, gspec, key, prune, ethash.NewFaker(), false, withPosDownloader) +func MockWithGenesisPruneMode(tb testing.TB, gspec *types.Genesis, key *ecdsa.PrivateKey, prune prune.Mode, withPosDownloader bool) *MockSentry { + return MockWithEverything(tb, gspec, key, prune, ethash.NewFaker(), false, withPosDownloader) } -func MockWithEverything(t *testing.T, gspec *core.Genesis, key *ecdsa.PrivateKey, prune prune.Mode, engine consensus.Engine, withTxPool bool, withPosDownloader bool) *MockSentry { +func MockWithEverything(tb testing.TB, gspec *types.Genesis, key *ecdsa.PrivateKey, prune prune.Mode, engine consensus.Engine, withTxPool bool, withPosDownloader bool) *MockSentry { var tmpdir string - if t != nil { - tmpdir = t.TempDir() + if tb != nil { + tmpdir = tb.TempDir() } else { tmpdir = os.TempDir() } @@ -233,8 +236,8 @@ func MockWithEverything(t *testing.T, gspec *core.Genesis, key *ecdsa.PrivateKey cfg.DeprecatedTxPool.StartOnInit = true var db kv.RwDB - if t != nil { - db = memdb.NewTestDB(t) + if tb != nil { + db = memdb.NewTestDB(tb) } else { db = memdb.New(tmpdir) } @@ -267,7 +270,7 @@ func MockWithEverything(t *testing.T, gspec *core.Genesis, key *ecdsa.PrivateKey allSnapshots := snapshotsync.NewRoSnapshots(ethconfig.Defaults.Snapshot, dirs.Snap) mock := &MockSentry{ Ctx: ctx, cancel: ctxCancel, DB: db, agg: agg, - t: t, + tb: tb, Log: log.New(), Dirs: dirs, Engine: engine, @@ -286,8 +289,8 @@ func MockWithEverything(t *testing.T, gspec *core.Genesis, key *ecdsa.PrivateKey HistoryV3: cfg.HistoryV3, TransactionsV3: cfg.TransactionsV3, } - if t != nil { - t.Cleanup(mock.Close) + if tb != nil { + tb.Cleanup(mock.Close) } blockReader := snapshotsync.NewBlockReaderWithSnapshots(mock.BlockSnapshots, mock.TransactionsV3) @@ -304,10 +307,10 @@ func MockWithEverything(t *testing.T, gspec *core.Genesis, key *ecdsa.PrivateKey blockPropagator := func(Ctx context.Context, header *types.Header, body *types.RawBody, td *big.Int) {} if !cfg.DeprecatedTxPool.Disable { - poolCfg := txpool.DefaultConfig + poolCfg := txpoolcfg.DefaultConfig newTxs := make(chan types2.Announcements, 1024) - if t != nil { - t.Cleanup(func() { + if tb != nil { + tb.Cleanup(func() { close(newTxs) }) } @@ -315,7 +318,7 @@ func MockWithEverything(t *testing.T, gspec *core.Genesis, key *ecdsa.PrivateKey shanghaiTime := mock.ChainConfig.ShanghaiTime mock.TxPool, err = txpool.New(newTxs, mock.DB, poolCfg, kvcache.NewDummy(), *chainID, shanghaiTime) if err != nil { - t.Fatal(err) + tb.Fatal(err) } mock.txPoolDB = memdb.NewPoolDB(tmpdir) @@ -337,8 +340,8 @@ func MockWithEverything(t *testing.T, gspec *core.Genesis, key *ecdsa.PrivateKey // Committed genesis will be shared between download and mock sentry _, mock.Genesis, err = core.CommitGenesisBlock(mock.DB, gspec, "") if _, ok := err.(*chain.ConfigCompatError); err != nil && !ok { - if t != nil { - t.Fatal(err) + if tb != nil { + tb.Fatal(err) } else { panic(err) } @@ -379,12 +382,13 @@ func MockWithEverything(t *testing.T, gspec *core.Genesis, key *ecdsa.PrivateKey blockReader, false, forkValidator, + cfg.DropUselessPeers, ) mock.sentriesClient.IsMock = true if err != nil { - if t != nil { - t.Fatal(err) + if tb != nil { + tb.Fatal(err) } else { panic(err) } @@ -512,18 +516,18 @@ func MockWithEverything(t *testing.T, gspec *core.Genesis, key *ecdsa.PrivateKey } // Mock is convenience function to create a mock with some pre-set values -func Mock(t *testing.T) *MockSentry { +func Mock(tb testing.TB) *MockSentry { funds := big.NewInt(1 * params.Ether) key, _ := crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291") address := crypto.PubkeyToAddress(key.PublicKey) chainConfig := params.TestChainConfig - gspec := &core.Genesis{ + gspec := &types.Genesis{ Config: chainConfig, - Alloc: core.GenesisAlloc{ + Alloc: types.GenesisAlloc{ address: {Balance: funds}, }, } - return MockWithGenesis(t, gspec, key, false) + return MockWithGenesis(tb, gspec, key, false) } func MockWithTxPool(t *testing.T) *MockSentry { @@ -531,9 +535,9 @@ func MockWithTxPool(t *testing.T) *MockSentry { key, _ := crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291") address := crypto.PubkeyToAddress(key.PublicKey) chainConfig := params.TestChainConfig - gspec := &core.Genesis{ + gspec := &types.Genesis{ Config: chainConfig, - Alloc: core.GenesisAlloc{ + Alloc: types.GenesisAlloc{ address: {Balance: funds}, }, } @@ -547,9 +551,9 @@ func MockWithZeroTTD(t *testing.T, withPosDownloader bool) *MockSentry { address := crypto.PubkeyToAddress(key.PublicKey) chainConfig := params.AllProtocolChanges chainConfig.TerminalTotalDifficulty = libcommon.Big0 - gspec := &core.Genesis{ + gspec := &types.Genesis{ Config: chainConfig, - Alloc: core.GenesisAlloc{ + Alloc: types.GenesisAlloc{ address: {Balance: funds}, }, } @@ -563,19 +567,19 @@ func MockWithZeroTTDGnosis(t *testing.T, withPosDownloader bool) *MockSentry { chainConfig := params.TestChainAuraConfig chainConfig.TerminalTotalDifficulty = libcommon.Big0 chainConfig.TerminalTotalDifficultyPassed = true - gspec := &core.Genesis{ + gspec := &types.Genesis{ Config: chainConfig, - Alloc: core.GenesisAlloc{ + Alloc: types.GenesisAlloc{ address: {Balance: funds}, }, } - engine := ethconsensusconfig.CreateConsensusEngine(chainConfig, log.New(), chainConfig.Aura, nil, true, "", "", true, "", nil, false /* readonly */, nil) + engine := ethconsensusconfig.CreateConsensusEngine(chainConfig, chainConfig.Aura, nil, true, "", "", true, "", nil, false /* readonly */, nil) return MockWithGenesisEngine(t, gspec, engine, withPosDownloader) } func (ms *MockSentry) EnableLogs() { log.Root().SetHandler(log.LvlFilterHandler(log.LvlInfo, log.StderrHandler)) - ms.t.Cleanup(func() { + ms.tb.Cleanup(func() { log.Root().SetHandler(log.Root().GetHandler()) }) } @@ -765,6 +769,17 @@ func (ms *MockSentry) NewStateReader(tx kv.Tx) state.StateReader { return state.NewPlainStateReader(tx) } +func (ms *MockSentry) NewStateWriter(tx kv.RwTx, blockNum uint64) state.StateWriter { + return state.NewPlainStateWriter(tx, tx, blockNum) +} + +func (ms *MockSentry) CalcStateRoot(tx kv.Tx) libcommon.Hash { + h, err := trie.CalcRoot("test", tx) + if err != nil { + panic(err) + } + return h +} func (ms *MockSentry) HistoryV3Components() *libstate.AggregatorV3 { return ms.agg } diff --git a/turbo/transactions/call.go b/turbo/transactions/call.go index d1ceaeadcad..f2399e8c5d8 100644 --- a/turbo/transactions/call.go +++ b/turbo/transactions/call.go @@ -3,6 +3,7 @@ package transactions import ( "context" "fmt" + "math/big" "time" "github.com/holiman/uint256" @@ -107,7 +108,15 @@ func DoCall( } func NewEVMBlockContext(engine consensus.EngineReader, header *types.Header, requireCanonical bool, tx kv.Tx, headerReader services.HeaderReader) evmtypes.BlockContext { - return core.NewEVMBlockContext(header, MakeHeaderGetter(requireCanonical, tx, headerReader), engine, nil /* author */) + var excessDataGas *big.Int + parentHeader, err := headerReader.HeaderByHash(context.Background(), tx, header.ParentHash) + if err != nil { + // TODO(eip-4844): Do we need to propagate this error? + log.Error("Can't get parent block's header:", err) + } else if parentHeader != nil { + excessDataGas = parentHeader.ExcessDataGas + } + return core.NewEVMBlockContext(header, MakeHeaderGetter(requireCanonical, tx, headerReader), engine, nil /* author */, excessDataGas) } func MakeHeaderGetter(requireCanonical bool, tx kv.Tx, headerReader services.HeaderReader) func(uint64) libcommon.Hash { diff --git a/turbo/transactions/tracing.go b/turbo/transactions/tracing.go index 9ec1844a18f..a1ac24d56a6 100644 --- a/turbo/transactions/tracing.go +++ b/turbo/transactions/tracing.go @@ -6,6 +6,7 @@ import ( "encoding/json" "errors" "fmt" + "math/big" "time" jsoniter "github.com/json-iterator/go" @@ -25,6 +26,7 @@ import ( "github.com/ledgerwatch/erigon/eth/tracers/logger" "github.com/ledgerwatch/erigon/turbo/rpchelper" "github.com/ledgerwatch/erigon/turbo/services" + "github.com/ledgerwatch/log/v3" ) type BlockGetter interface { @@ -53,7 +55,16 @@ func ComputeTxEnv(ctx context.Context, engine consensus.EngineReader, block *typ return h } header := block.HeaderNoCopy() - BlockContext := core.NewEVMBlockContext(header, core.GetHashFn(header, getHeader), engine, nil) + parentHeader, err := headerReader.HeaderByHash(ctx, dbtx, header.ParentHash) + if err != nil { + // TODO(eip-4844): Do we need to propagate this error? + log.Error("Can't get parent block's header:", err) + } + var excessDataGas *big.Int + if parentHeader != nil { + excessDataGas = parentHeader.ExcessDataGas + } + BlockContext := core.NewEVMBlockContext(header, core.GetHashFn(header, getHeader), engine, nil, excessDataGas) // Recompute transactions up to the target index. signer := types.MakeSigner(cfg, block.NumberU64()) @@ -64,7 +75,7 @@ func ComputeTxEnv(ctx context.Context, engine consensus.EngineReader, block *typ msg, _ := txn.AsMessage(*signer, block.BaseFee(), rules) if msg.FeeCap().IsZero() && engine != nil { syscall := func(contract libcommon.Address, data []byte) ([]byte, error) { - return core.SysCallContract(contract, data, *cfg, statedb, header, engine, true /* constCall */) + return core.SysCallContract(contract, data, *cfg, statedb, header, engine, true /* constCall */, excessDataGas) } msg.SetIsFree(engine.IsServiceTransaction(msg.From(), syscall)) } @@ -77,7 +88,7 @@ func ComputeTxEnv(ctx context.Context, engine consensus.EngineReader, block *typ consensusHeaderReader := stagedsync.NewChainReaderImpl(cfg, dbtx, nil) - core.InitializeBlockExecution(engine.(consensus.Engine), consensusHeaderReader, nil, header, block.Transactions(), block.Uncles(), cfg, statedb) + core.InitializeBlockExecution(engine.(consensus.Engine), consensusHeaderReader, header, block.Transactions(), block.Uncles(), cfg, statedb, excessDataGas) for idx, txn := range block.Transactions() { select { @@ -91,7 +102,7 @@ func ComputeTxEnv(ctx context.Context, engine consensus.EngineReader, block *typ msg, _ := txn.AsMessage(*signer, block.BaseFee(), rules) if msg.FeeCap().IsZero() && engine != nil { syscall := func(contract libcommon.Address, data []byte) ([]byte, error) { - return core.SysCallContract(contract, data, *cfg, statedb, header, engine, true /* constCall */) + return core.SysCallContract(contract, data, *cfg, statedb, header, engine, true /* constCall */, excessDataGas) } msg.SetIsFree(engine.IsServiceTransaction(msg.From(), syscall)) } diff --git a/turbo/trie/gen_struct_step.go b/turbo/trie/gen_struct_step.go index 0ae491b0ca2..856726cdd83 100644 --- a/turbo/trie/gen_struct_step.go +++ b/turbo/trie/gen_struct_step.go @@ -41,6 +41,7 @@ type structInfoReceiver interface { topHash() []byte topHashes(prefix []byte, branches, children uint16) []byte printTopHashes(prefix []byte, branches, children uint16) + setProofElement(pe *proofElement) } // hashCollector gets called whenever there might be a need to create intermediate hash record @@ -99,7 +100,10 @@ func (GenStructStepHashData) GenStructStepData() {} // Whenever a `BRANCH` or `BRANCHHASH` opcode is emitted, the set of digits is taken from the corresponding `groups` item, which is // then removed from the slice. This signifies the usage of the number of the stack items by the `BRANCH` or `BRANCHHASH` opcode. // DESCRIBED: docs/programmers_guide/guide.md#separation-of-keys-and-the-structure -func GenStructStep( + +// GenStructStepEx is extended to support optional generation of an Account Proof during trie_root.go CalcTrieRoot(). +// The wrapper below calls it with nil/false defaults so that other callers do not need to be modified. +func GenStructStepEx( retain func(prefix []byte) bool, curr, succ []byte, e structInfoReceiver, @@ -109,6 +113,8 @@ func GenStructStep( hasTree []uint16, hasHash []uint16, trace bool, + retainProof func(prefix []byte) *proofElement, + cutoff bool, ) ([]uint16, []uint16, []uint16, error) { for precLen, buildExtensions := calcPrecLen(groups), false; precLen >= 0; precLen, buildExtensions = calcPrecLen(groups), true { var precExists = len(groups) > 0 @@ -145,6 +151,20 @@ func GenStructStep( } //fmt.Printf("groups is now %x,%d,%b\n", extraDigit, maxLen, groups) + // retainIfProving will call setProofElement to a new proof element + // it is the caller's responsibility set the proof element to nil after the + // next element invocation. This function returns whether a proof is needed + // for this node. + retainIfProving := func(key []byte) bool { + if retainProof != nil { + if pe := retainProof(key); pe != nil { + e.setProofElement(pe) + return true + } + } + return false + } + if !buildExtensions { switch v := data.(type) { case *GenStructStepHashData: @@ -164,10 +184,14 @@ func GenStructStep( } buildExtensions = true case *GenStructStepAccountData: - if retain(curr[:maxLen]) { + proving := retainIfProving(curr[:len(curr)-1]) + if proving || retain(curr[:maxLen]) { if err := e.accountLeaf(remainderLen, curr, &v.Balance, v.Nonce, v.Incarnation, v.FieldSet, codeSizeUncached); err != nil { return nil, nil, nil, err } + if proving { + e.setProofElement(nil) + } } else { if err := e.accountLeafHash(remainderLen, curr, &v.Balance, v.Nonce, v.Incarnation, v.FieldSet); err != nil { return nil, nil, nil, err @@ -175,10 +199,14 @@ func GenStructStep( } case *GenStructStepLeafData: /* building leafs */ - if retain(curr[:maxLen]) { + proving := retainIfProving(curr[:len(curr)-1]) + if proving || retain(curr[:maxLen]) { if err := e.leaf(remainderLen, curr, v.Value); err != nil { return nil, nil, nil, err } + if proving { + e.setProofElement(nil) + } } else { if err := e.leafHash(remainderLen, curr, v.Value); err != nil { return nil, nil, nil, err @@ -218,10 +246,14 @@ func GenStructStep( fmt.Printf("Extension: %x, %b, %b, %b\n", curr[remainderStart:remainderStart+remainderLen], hasHash, hasTree, groups) } /* building extensions */ - if retain(curr[:maxLen]) { + proving := retainIfProving(curr[:remainderStart]) + if proving || retain(curr[:maxLen]) { if err := e.extension(curr[remainderStart : remainderStart+remainderLen]); err != nil { return nil, nil, nil, err } + if proving { + e.setProofElement(nil) + } } else { if err := e.extensionHash(curr[remainderStart : remainderStart+remainderLen]); err != nil { return nil, nil, nil, err @@ -270,10 +302,14 @@ func GenStructStep( if trace { e.printTopHashes(curr[:maxLen], 0, groups[maxLen]) } - if retain(curr[:maxLen]) { + proving := retainIfProving(curr[:maxLen]) + if proving || retain(curr[:maxLen]) { if err := e.branch(groups[maxLen]); err != nil { return nil, nil, nil, err } + if proving { + e.setProofElement(nil) + } } else { if err := e.branchHash(groups[maxLen]); err != nil { return nil, nil, nil, err @@ -305,6 +341,19 @@ func GenStructStep( } return nil, nil, nil, nil } +func GenStructStep( + retain func(prefix []byte) bool, + curr, succ []byte, + e structInfoReceiver, + h HashCollector2, + data GenStructStepData, + groups []uint16, + hasTree []uint16, + hasHash []uint16, + trace bool, +) ([]uint16, []uint16, []uint16, error) { + return GenStructStepEx(retain, curr, succ, e, h, data, groups, hasTree, hasHash, trace, nil, false) +} func GenStructStepOld( retain func(prefix []byte) bool, diff --git a/turbo/trie/hashbuilder.go b/turbo/trie/hashbuilder.go index 32659a80ee5..5a38ffde99c 100644 --- a/turbo/trie/hashbuilder.go +++ b/turbo/trie/hashbuilder.go @@ -41,6 +41,11 @@ type HashBuilder struct { trace bool // Set to true when HashBuilder is required to print trace information for diagnostics topHashesCopy []byte + + // proofElement is set when the next element computation should have its RLP + // encoding retained. Additionally, the account root storage hash and storage + // values are stored into this field when set and in the relavent codepath. + proofElement *proofElement } // NewHashBuilder creates a new HashBuilder @@ -61,6 +66,13 @@ func (hb *HashBuilder) Reset() { hb.nodeStack = hb.nodeStack[:0] } hb.topHashesCopy = hb.topHashesCopy[:0] + hb.proofElement = nil +} + +// setProofElement sets the proofElement field in which the relevant methods +// will check and additionally write the proof bytes to during trie computation. +func (hb *HashBuilder) setProofElement(pe *proofElement) { + hb.proofElement = pe } func (hb *HashBuilder) leaf(length int, keyHex []byte, val rlphacks.RlpSerializable) error { @@ -72,6 +84,9 @@ func (hb *HashBuilder) leaf(length int, keyHex []byte, val rlphacks.RlpSerializa } key := keyHex[len(keyHex)-length:] s := &shortNode{Key: common.CopyBytes(key), Val: valueNode(common.CopyBytes(val.RawBytes()))} + if hb.proofElement != nil { + hb.proofElement.storageValue = new(uint256.Int).SetBytes(val.RawBytes()) + } hb.nodeStack = append(hb.nodeStack, s) if err := hb.leafHashWithKeyVal(key, val); err != nil { return err @@ -148,6 +163,10 @@ func (hb *HashBuilder) completeLeafHash(kp, kl, compactLen int, key []byte, comp writer = hb.sha reader = hb.sha } + // Collect a copy of the hash input if needed for an eth_getProof + if hb.proofElement != nil { + writer = io.MultiWriter(writer, &hb.proofElement.proof) + } if _, err := writer.Write(hb.lenPrefix[:pt]); err != nil { return err @@ -220,7 +239,7 @@ func (hb *HashBuilder) accountLeaf(length int, keyHex []byte, balance *uint256.I var accountCode codeNode if fieldSet&uint32(8) != 0 { copy(hb.acc.CodeHash[:], hb.hashStack[len(hb.hashStack)-popped*hashStackStride-length2.Hash:len(hb.hashStack)-popped*hashStackStride]) - ok := false + var ok bool if !bytes.Equal(hb.acc.CodeHash[:], EmptyCodeHash[:]) { stackTop := hb.nodeStack[len(hb.nodeStack)-popped-1] if stackTop != nil { // if we don't have any stack top it might be okay because we didn't resolve the code yet (stateful resolver) @@ -233,6 +252,12 @@ func (hb *HashBuilder) accountLeaf(length int, keyHex []byte, balance *uint256.I } popped++ } + + if hb.proofElement != nil { + // The storageRoot is not stored with the account info, therefore + // we capture it with the account proof element + hb.proofElement.storageRoot = hb.acc.Root + } var accCopy accounts.Account accCopy.Copy(&hb.acc) @@ -363,6 +388,11 @@ func (hb *HashBuilder) extension(key []byte) error { } func (hb *HashBuilder) extensionHash(key []byte) error { + writer := io.Writer(hb.sha) + if hb.proofElement != nil { + writer = io.MultiWriter(hb.sha, &hb.proofElement.proof) + } + if hb.trace { fmt.Printf("EXTENSIONHASH %x\n", key) } @@ -399,31 +429,32 @@ func (hb *HashBuilder) extensionHash(key []byte) error { totalLen := kp + kl + 33 pt := rlphacks.GenerateStructLen(hb.lenPrefix[:], totalLen) hb.sha.Reset() - if _, err := hb.sha.Write(hb.lenPrefix[:pt]); err != nil { + if _, err := writer.Write(hb.lenPrefix[:pt]); err != nil { return err } - if _, err := hb.sha.Write(hb.keyPrefix[:kp]); err != nil { + if _, err := writer.Write(hb.keyPrefix[:kp]); err != nil { return err } hb.b[0] = compact0 - if _, err := hb.sha.Write(hb.b[:]); err != nil { + if _, err := writer.Write(hb.b[:]); err != nil { return err } for i := 1; i < compactLen; i++ { hb.b[0] = key[ni]*16 + key[ni+1] - if _, err := hb.sha.Write(hb.b[:]); err != nil { + if _, err := writer.Write(hb.b[:]); err != nil { return err } ni += 2 } //capture := common.CopyBytes(branchHash[:length2.Hash+1]) - if _, err := hb.sha.Write(branchHash[:length2.Hash+1]); err != nil { + if _, err := writer.Write(branchHash[:length2.Hash+1]); err != nil { return err } // Replace previous hash with the new one if _, err := hb.sha.Read(hb.hashStack[len(hb.hashStack)-length2.Hash:]); err != nil { return err } + hb.hashStack[len(hb.hashStack)-hashStackStride] = 0x80 + length2.Hash //fmt.Printf("extensionHash [%x]=>[%x]\nHash [%x]\n", key, capture, hb.hashStack[len(hb.hashStack)-hashStackStride:len(hb.hashStack)]) if _, ok := hb.nodeStack[len(hb.nodeStack)-1].(*fullNode); ok { @@ -472,6 +503,11 @@ func (hb *HashBuilder) branch(set uint16) error { } func (hb *HashBuilder) branchHash(set uint16) error { + writer := io.Writer(hb.sha) + if hb.proofElement != nil { + writer = io.MultiWriter(hb.sha, &hb.proofElement.proof) + } + if hb.trace { fmt.Printf("BRANCHHASH (%b)\n", set) } @@ -496,7 +532,7 @@ func (hb *HashBuilder) branchHash(set uint16) error { } hb.sha.Reset() pt := rlphacks.GenerateStructLen(hb.lenPrefix[:], totalSize) - if _, err := hb.sha.Write(hb.lenPrefix[:pt]); err != nil { + if _, err := writer.Write(hb.lenPrefix[:pt]); err != nil { return err } // Output hasState hashes or embedded RLPs @@ -506,21 +542,21 @@ func (hb *HashBuilder) branchHash(set uint16) error { for digit := uint(0); digit < 17; digit++ { if ((1 << digit) & set) != 0 { if hashes[hashStackStride*i] == byte(0x80+length2.Hash) { - if _, err := hb.sha.Write(hashes[hashStackStride*i : hashStackStride*i+hashStackStride]); err != nil { + if _, err := writer.Write(hashes[hashStackStride*i : hashStackStride*i+hashStackStride]); err != nil { return err } //fmt.Printf("%x: [%x]\n", digit, hashes[hashStackStride*i:hashStackStride*i+hashStackStride]) } else { // Embedded node size := int(hashes[hashStackStride*i]) - rlp.EmptyListCode - if _, err := hb.sha.Write(hashes[hashStackStride*i : hashStackStride*i+size+1]); err != nil { + if _, err := writer.Write(hashes[hashStackStride*i : hashStackStride*i+size+1]); err != nil { return err } //fmt.Printf("%x: embedded [%x]\n", digit, hashes[hashStackStride*i:hashStackStride*i+size+1]) } i++ } else { - if _, err := hb.sha.Write(hb.b[:]); err != nil { + if _, err := writer.Write(hb.b[:]); err != nil { return err } //fmt.Printf("%x: empty\n", digit) @@ -531,6 +567,7 @@ func (hb *HashBuilder) branchHash(set uint16) error { if _, err := hb.sha.Read(hb.hashStack[len(hb.hashStack)-length2.Hash:]); err != nil { return err } + //fmt.Printf("} [%x]\n", hb.hashStack[len(hb.hashStack)-hashStackStride:]) if hashStackStride*len(hb.nodeStack) > len(hb.hashStack) { diff --git a/turbo/trie/retain_list.go b/turbo/trie/retain_list.go index 959fdd52bcb..7f9c7a4c1c9 100644 --- a/turbo/trie/retain_list.go +++ b/turbo/trie/retain_list.go @@ -18,10 +18,15 @@ package trie import ( "bytes" + "encoding/binary" "fmt" "sort" + "github.com/holiman/uint256" libcommon "github.com/ledgerwatch/erigon-lib/common" + "github.com/ledgerwatch/erigon/common" + "github.com/ledgerwatch/erigon/common/hexutil" + "github.com/ledgerwatch/erigon/core/types/accounts" ) type RetainDecider interface { @@ -31,10 +36,167 @@ type RetainDecider interface { type RetainDeciderWithMarker interface { RetainDecider - AddKeyWithMarker(key []byte, marker bool) + // AddKeyWithMarker adds a key in KEY encoding with marker and returns the + // nibble encoded key. + AddKeyWithMarker(key []byte, marker bool) []byte RetainWithMarker(prefix []byte) (retain bool, nextMarkedKey []byte) } +// ProofRetainer is a wrapper around the RetainList passed to the trie builder. +// It is responsible for aggregating proof values from the trie computation and +// will return a valid accounts.AccProofresult after the trie root hash +// calculation has completed. +type ProofRetainer struct { + rl *RetainList + addr libcommon.Address + acc *accounts.Account + accHexKey []byte + storageKeys []libcommon.Hash + storageHexKeys [][]byte + proofs []*proofElement +} + +// NewProofRetainer creates a new ProofRetainer instance for a given account and +// set of storage keys. The trie keys corresponding to the account key, and its +// storage keys are added to the given RetainList. The ProofRetainer should be +// set onto the FlatDBTrieLoader via SetProofRetainer before performing its Load +// operation in order to appropriately collect the proof elements. +func NewProofRetainer(addr libcommon.Address, a *accounts.Account, storageKeys []libcommon.Hash, rl *RetainList) (*ProofRetainer, error) { + addrHash, err := common.HashData(addr[:]) + if err != nil { + return nil, err + } + accHexKey := rl.AddKey(addrHash[:]) + + storageHexKeys := make([][]byte, len(storageKeys)) + for i, sk := range storageKeys { + storageHash, err := common.HashData(sk[:]) + if err != nil { + return nil, err + } + + var compactEncoded [72]byte + copy(compactEncoded[:32], addrHash[:]) + binary.BigEndian.PutUint64(compactEncoded[32:40], a.Incarnation) + copy(compactEncoded[40:], storageHash[:]) + storageHexKeys[i] = rl.AddKey(compactEncoded[:]) + } + + return &ProofRetainer{ + rl: rl, + addr: addr, + acc: a, + accHexKey: accHexKey, + storageKeys: storageKeys, + storageHexKeys: storageHexKeys, + }, nil +} + +// ProofElement requests a new proof element for a given prefix. This proof +// element is retained by the ProofRetainer, and will be utilized to compute the +// proof after the trie computation has completed. The prefix is the standard +// nibble encoded prefix used in the rest of the trie computations. +func (pr *ProofRetainer) ProofElement(prefix []byte) *proofElement { + if !pr.rl.Retain(prefix) { + return nil + } + + switch { + case bytes.HasPrefix(pr.accHexKey, prefix): + // This prefix is a node between the account and the root + case bytes.HasPrefix(prefix, pr.accHexKey): + // This prefix is the account or one of its storage nodes + default: + // we do not need a proof element for this prefix + return nil + } + + pe := &proofElement{ + hexKey: append([]byte{}, prefix...), + } + // Since we do a depth-first traversal, reverse the proof elements so that + // they are ordered correctly root -> node -> ... -> leaf as dictated by + // EIP-1186 + pr.proofs = append([]*proofElement{pe}, pr.proofs...) + return pe +} + +// ProofResult may be invoked only after the Load function of the +// FlatDBTrieLoader has successfully executed. It will populate the Address, +// Balance, Nonce, and CodeHash from the account data supplied in the +// constructor, the StorageHash, storageKey values, and proof elements are +// supplied by the Load operation of the trie construction. +func (pr *ProofRetainer) ProofResult() (*accounts.AccProofResult, error) { + result := &accounts.AccProofResult{ + Address: pr.addr, + Balance: (*hexutil.Big)(pr.acc.Balance.ToBig()), + Nonce: hexutil.Uint64(pr.acc.Nonce), + CodeHash: pr.acc.CodeHash, + } + + for _, pe := range pr.proofs { + if !bytes.HasPrefix(pr.accHexKey, pe.hexKey) { + continue + } + result.AccountProof = append(result.AccountProof, pe.proof.Bytes()) + if pe.storageRoot != (libcommon.Hash{}) { + result.StorageHash = pe.storageRoot + } + } + + if result.StorageHash == (libcommon.Hash{}) { + return nil, fmt.Errorf("did not find storage root in proof elements") + } + + result.StorageProof = make([]accounts.StorProofResult, len(pr.storageKeys)) + for i, sk := range pr.storageKeys { + result.StorageProof[i].Key = sk + hexKey := pr.storageHexKeys[i] + for _, pe := range pr.proofs { + if len(pe.hexKey) <= 2*32 { + // Ignore the proof elements above the storage tree (64 bytes, as nibble + // encoded) + continue + } + if !bytes.HasPrefix(hexKey, pe.hexKey) { + continue + } + if pe.storageValue != nil { + result.StorageProof[i].Value = (*hexutil.Big)(pe.storageValue.ToBig()) + } + + result.StorageProof[i].Proof = append(result.StorageProof[i].Proof, pe.proof.Bytes()) + } + + if result.StorageProof[i].Value == nil { + return nil, fmt.Errorf("no storage value for storage key 0x%x set", sk) + } + } + + return result, nil +} + +// proofElement represent a node or leaf in the trie and its +// corresponding RLP encoding. We store the elements individually when +// aggregating as multiple keys (in particular storage keys) may need to +// reference the same proof elements in their Merkle proof. +type proofElement struct { + // key is the hex encoded key indicating the path of the + // element in the proof. + hexKey []byte + + // buf is used to store the proof bytes + proof bytes.Buffer + + // storageRoot stores the storage root if this is writing + // an account leaf + storageRoot libcommon.Hash + + // storageValue stores the value of the particular storage + // key if this writer is for a storage key + storageValue *uint256.Int +} + // RetainList encapsulates the list of keys that are required to be fully available, or loaded // (by using `BRANCH` opcode instead of `HASHER`) after processing of the sequence of key-value // pairs @@ -65,11 +227,11 @@ func (rl *RetainList) Swap(i, j int) { } // AddKey adds a new key (in KEY encoding) to the list -func (rl *RetainList) AddKey(key []byte) { - rl.AddKeyWithMarker(key, false) +func (rl *RetainList) AddKey(key []byte) []byte { + return rl.AddKeyWithMarker(key, false) } -func (rl *RetainList) AddKeyWithMarker(key []byte, marker bool) { +func (rl *RetainList) AddKeyWithMarker(key []byte, marker bool) []byte { var nibbles = make([]byte, 2*len(key)) for i, b := range key { nibbles[i*2] = b / 16 @@ -77,6 +239,7 @@ func (rl *RetainList) AddKeyWithMarker(key []byte, marker bool) { } rl.AddHex(nibbles) rl.markers = append(rl.markers, marker) + return nibbles } // AddHex adds a new key (in HEX encoding) to the list diff --git a/turbo/trie/retain_list_test.go b/turbo/trie/retain_list_test.go new file mode 100644 index 00000000000..2bfa948e673 --- /dev/null +++ b/turbo/trie/retain_list_test.go @@ -0,0 +1,106 @@ +package trie + +import ( + "testing" + + "github.com/holiman/uint256" + libcommon "github.com/ledgerwatch/erigon-lib/common" + "github.com/ledgerwatch/erigon/core/types/accounts" + "github.com/stretchr/testify/require" +) + +func TestProofRetainerConstruction(t *testing.T) { + rl := NewRetainList(0) + pr, err := NewProofRetainer( + libcommon.Address{0x1}, + &accounts.Account{ + Initialised: true, + Nonce: 2, + Balance: *uint256.NewInt(6e9), + CodeHash: libcommon.Hash{3}, + Incarnation: 3, + }, + []libcommon.Hash{{1}, {2}, {3}}, + rl, + ) + require.NoError(t, err) + require.Len(t, rl.hexes, 4) + + validKeys := [][]byte{ + pr.storageHexKeys[2][:], + pr.storageHexKeys[2][:98], + pr.storageHexKeys[2][:95], + pr.storageHexKeys[1][:], + pr.storageHexKeys[1][:90], + pr.storageHexKeys[0][:], + pr.storageHexKeys[0][:85], + pr.accHexKey[:], + pr.accHexKey[:15], + {}, + } + + invalidKeys := [][]byte{ + pr.accHexKey[1:16], + pr.storageHexKeys[0][12:80], + pr.storageHexKeys[2][19:90], + } + + for _, key := range validKeys { + pe := pr.ProofElement(key) + require.NotNil(t, pe) + require.Equal(t, pe.hexKey, key) + switch len(key) { + case 64: // Account leaf key + pe.storageRoot = libcommon.Hash{3} + case 144: // Storage leaf key + pe.storageValue = uint256.NewInt(5) + } + pe.proof.Write(key) + } + for _, key := range invalidKeys { + pe := pr.ProofElement(key) + require.Nil(t, pe) + } + require.Equal(t, len(validKeys), len(pr.proofs)) + + accProof, err := pr.ProofResult() + require.NoError(t, err) + + require.Len(t, accProof.AccountProof, 3) + require.Equal(t, []byte(nil), []byte(accProof.AccountProof[0])) + require.Equal(t, validKeys[8], []byte(accProof.AccountProof[1])) + require.Equal(t, validKeys[7], []byte(accProof.AccountProof[2])) + + require.Len(t, accProof.StorageProof, 3) + require.Equal(t, accProof.StorageProof[0].Key, libcommon.Hash{1}) + require.Len(t, accProof.StorageProof[0].Proof, 2) + require.Equal(t, validKeys[6], []byte(accProof.StorageProof[0].Proof[0])) + require.Equal(t, validKeys[5], []byte(accProof.StorageProof[0].Proof[1])) + + require.Equal(t, accProof.StorageProof[1].Key, libcommon.Hash{2}) + require.Len(t, accProof.StorageProof[1].Proof, 2) + require.Equal(t, validKeys[4], []byte(accProof.StorageProof[1].Proof[0])) + require.Equal(t, validKeys[3], []byte(accProof.StorageProof[1].Proof[1])) + + require.Equal(t, accProof.StorageProof[2].Key, libcommon.Hash{3}) + require.Len(t, accProof.StorageProof[2].Proof, 3) + require.Equal(t, validKeys[2], []byte(accProof.StorageProof[2].Proof[0])) + require.Equal(t, validKeys[1], []byte(accProof.StorageProof[2].Proof[1])) + require.Equal(t, validKeys[0], []byte(accProof.StorageProof[2].Proof[2])) + + t.Run("missingStorageRoot", func(t *testing.T) { + oldStorageHash := pr.proofs[2].storageRoot + pr.proofs[2].storageRoot = libcommon.Hash{} + defer func() { pr.proofs[2].storageRoot = oldStorageHash }() + _, err := pr.ProofResult() + require.Error(t, err, "did not find storage root in proof elements") + }) + + t.Run("missingStorageValue", func(t *testing.T) { + oldKey := pr.proofs[4].storageValue + pr.proofs[4].storageValue = nil + defer func() { pr.proofs[4].storageValue = oldKey }() + _, err := pr.ProofResult() + require.Error(t, err, "no storage value for storage key 0x%x", validKeys[4]) + }) +} diff --git a/turbo/trie/trie_root.go b/turbo/trie/trie_root.go index a155031ffdd..8f513e154d4 100644 --- a/turbo/trie/trie_root.go +++ b/turbo/trie/trie_root.go @@ -9,6 +9,7 @@ import ( "time" libcommon "github.com/ledgerwatch/erigon-lib/common" + "github.com/ledgerwatch/erigon-lib/common/length" length2 "github.com/ledgerwatch/erigon-lib/common/length" "github.com/ledgerwatch/erigon-lib/kv" "github.com/ledgerwatch/log/v3" @@ -73,7 +74,7 @@ Then delete this account (SELFDESTRUCT). // FlatDBTrieLoader reads state and intermediate trie hashes in order equal to "Preorder trie traversal" // (Preorder - visit Root, visit Left, visit Right) // -// It produces stream of values and send this stream to `defaultReceiver` +// It produces stream of values and send this stream to `receiver` // It skips storage with incorrect incarnations // // Each intermediate hash key firstly pass to RetainDecider, only if it returns "false" - such AccTrie can be used. @@ -89,10 +90,9 @@ type FlatDBTrieLoader struct { // Account item buffer accountValue accounts.Account - receiver StreamReceiver - defaultReceiver *RootHashAggregator - hc HashCollector2 - shc StorageHashCollector2 + receiver *RootHashAggregator + hc HashCollector2 + shc StorageHashCollector2 } // RootHashAggregator - calculates Merkle trie root hash from incoming data stream @@ -125,22 +125,10 @@ type RootHashAggregator struct { a accounts.Account leafData GenStructStepLeafData accData GenStructStepAccountData -} -type StreamReceiver interface { - Receive( - itemType StreamItem, - accountKey []byte, - storageKey []byte, - accountValue *accounts.Account, - storageValue []byte, - hash []byte, - hasTree bool, - cutoff int, - ) error - - Result() SubTries - Root() libcommon.Hash + // Used to construct an Account proof while calculating the tree root. + proofRetainer *ProofRetainer + cutoff bool } func NewRootHashAggregator() *RootHashAggregator { @@ -149,31 +137,32 @@ func NewRootHashAggregator() *RootHashAggregator { } } -func NewFlatDBTrieLoader(logPrefix string) *FlatDBTrieLoader { - return &FlatDBTrieLoader{ - logPrefix: logPrefix, - defaultReceiver: NewRootHashAggregator(), - } -} - -// Reset prepares the loader for reuse -func (l *FlatDBTrieLoader) Reset(rd RetainDeciderWithMarker, hc HashCollector2, shc StorageHashCollector2, trace bool) error { - l.defaultReceiver.Reset(hc, shc, trace) - l.hc = hc - l.shc = shc - l.receiver = l.defaultReceiver - l.trace = trace - l.ihSeek, l.accSeek, l.storageSeek, l.kHex, l.kHexS = make([]byte, 0, 128), make([]byte, 0, 128), make([]byte, 0, 128), make([]byte, 0, 128), make([]byte, 0, 128) - l.rd = rd - if l.trace { +func NewFlatDBTrieLoader(logPrefix string, rd RetainDeciderWithMarker, hc HashCollector2, shc StorageHashCollector2, trace bool) *FlatDBTrieLoader { + if trace { fmt.Printf("----------\n") fmt.Printf("CalcTrieRoot\n") } - return nil + return &FlatDBTrieLoader{ + logPrefix: logPrefix, + receiver: &RootHashAggregator{ + hb: NewHashBuilder(false), + hc: hc, + shc: shc, + trace: trace, + }, + ihSeek: make([]byte, 0, 128), + accSeek: make([]byte, 0, 128), + storageSeek: make([]byte, 0, 128), + kHex: make([]byte, 0, 128), + kHexS: make([]byte, 0, 128), + rd: rd, + hc: hc, + shc: shc, + } } -func (l *FlatDBTrieLoader) SetStreamReceiver(receiver StreamReceiver) { - l.receiver = receiver +func (l *FlatDBTrieLoader) SetProofRetainer(pr *ProofRetainer) { + l.receiver.proofRetainer = pr } // CalcTrieRoot algo: @@ -198,7 +187,7 @@ func (l *FlatDBTrieLoader) SetStreamReceiver(receiver StreamReceiver) { // SkipAccounts: // use(AccTrie) // } -func (l *FlatDBTrieLoader) CalcTrieRoot(tx kv.Tx, prefix []byte, quit <-chan struct{}) (libcommon.Hash, error) { +func (l *FlatDBTrieLoader) CalcTrieRoot(tx kv.Tx, quit <-chan struct{}) (libcommon.Hash, error) { accC, err := tx.Cursor(kv.HashedAccounts) if err != nil { @@ -231,7 +220,7 @@ func (l *FlatDBTrieLoader) CalcTrieRoot(tx kv.Tx, prefix []byte, quit <-chan str defer ss.Close() logEvery := time.NewTicker(30 * time.Second) defer logEvery.Stop() - for ihK, ihV, hasTree, err := accTrie.AtPrefix(prefix); ; ihK, ihV, hasTree, err = accTrie.Next() { // no loop termination is at he end of loop + for ihK, ihV, hasTree, err := accTrie.AtPrefix(nil); ; ihK, ihV, hasTree, err = accTrie.Next() { // no loop termination is at he end of loop if err != nil { return EmptyRoot, err } @@ -243,7 +232,7 @@ func (l *FlatDBTrieLoader) CalcTrieRoot(tx kv.Tx, prefix []byte, quit <-chan str if err1 != nil { return EmptyRoot, err1 } - if keyIsBefore(ihK, kHex) || !bytes.HasPrefix(kHex, prefix) { // read all accounts until next AccTrie + if keyIsBefore(ihK, kHex) || !bytes.HasPrefix(kHex, nil) { // read all accounts until next AccTrie break } if err = l.accountValue.DecodeForStorage(v); err != nil { @@ -310,7 +299,7 @@ func (l *FlatDBTrieLoader) CalcTrieRoot(tx kv.Tx, prefix []byte, quit <-chan str } } - if err := l.receiver.Receive(CutoffStreamItem, nil, nil, nil, nil, nil, false, len(prefix)); err != nil { + if err := l.receiver.Receive(CutoffStreamItem, nil, nil, nil, nil, nil, false, 0); err != nil { return EmptyRoot, err } return l.receiver.Root(), nil @@ -330,27 +319,6 @@ func (r *RootHashAggregator) RetainNothing(_ []byte) bool { return false } -func (r *RootHashAggregator) Reset(hc HashCollector2, shc StorageHashCollector2, trace bool) { - r.hc = hc - r.shc = shc - r.curr.Reset() - r.succ.Reset() - r.value = nil - r.groups = r.groups[:0] - r.hasTree = r.hasTree[:0] - r.hasHash = r.hasHash[:0] - r.a.Reset() - r.hb.Reset() - r.wasIH = false - r.currStorage.Reset() - r.succStorage.Reset() - r.valueStorage = nil - r.wasIHStorage = false - r.root = libcommon.Hash{} - r.trace = trace - r.hb.trace = trace -} - func (r *RootHashAggregator) Receive(itemType StreamItem, accountKey []byte, storageKey []byte, @@ -371,6 +339,7 @@ func (r *RootHashAggregator) Receive(itemType StreamItem, // fmt.Printf("1: %d, %x, %x, %x\n", itemType, accountKey, storageKey, hash) // //} //} + // switch itemType { case StorageStreamItem: @@ -482,6 +451,10 @@ func (r *RootHashAggregator) Receive(itemType StreamItem, r.accData.FieldSet |= AccountFieldStorageOnly } } + + // Used for optional GetProof calculation to trigger inclusion of the top-level node + r.cutoff = true + if r.curr.Len() > 0 { if err := r.genStructAccount(); err != nil { return err @@ -525,10 +498,6 @@ func (r *RootHashAggregator) Receive(itemType StreamItem, // } // } -func (r *RootHashAggregator) Result() SubTries { - panic("don't call me") -} - func (r *RootHashAggregator) Root() libcommon.Hash { return r.root } @@ -566,13 +535,32 @@ func (r *RootHashAggregator) genStructStorage() error { r.leafData.Value = rlphacks.RlpSerializableBytes(r.valueStorage) data = &r.leafData } - r.groupsStorage, r.hasTreeStorage, r.hasHashStorage, err = GenStructStep(r.RetainNothing, r.currStorage.Bytes(), r.succStorage.Bytes(), r.hb, func(keyHex []byte, hasState, hasTree, hasHash uint16, hashes, rootHash []byte) error { + var wantProof func(_ []byte) *proofElement + if r.proofRetainer != nil { + var fullKey [2 * (length.Hash + length.Incarnation + length.Hash)]byte + for i, b := range r.currAccK { + fullKey[i*2] = b / 16 + fullKey[i*2+1] = b % 16 + } + for i, b := range binary.BigEndian.AppendUint64(nil, r.a.Incarnation) { + fullKey[2*length.Hash+i*2] = b / 16 + fullKey[2*length.Hash+i*2+1] = b % 16 + } + baseKeyLen := 2 * (length.Hash + length.Incarnation) + wantProof = func(prefix []byte) *proofElement { + copy(fullKey[baseKeyLen:], prefix) + return r.proofRetainer.ProofElement(fullKey[:baseKeyLen+len(prefix)]) + } + } + r.groupsStorage, r.hasTreeStorage, r.hasHashStorage, err = GenStructStepEx(r.RetainNothing, r.currStorage.Bytes(), r.succStorage.Bytes(), r.hb, func(keyHex []byte, hasState, hasTree, hasHash uint16, hashes, rootHash []byte) error { if r.shc == nil { return nil } return r.shc(r.currAccK, keyHex, hasState, hasTree, hasHash, hashes, rootHash) }, data, r.groupsStorage, r.hasTreeStorage, r.hasHashStorage, r.trace, + wantProof, + r.cutoff, ) if err != nil { return err @@ -634,14 +622,21 @@ func (r *RootHashAggregator) genStructAccount() error { r.currStorage.Reset() r.succStorage.Reset() var err error - if r.groups, r.hasTree, r.hasHash, err = GenStructStep(r.RetainNothing, r.curr.Bytes(), r.succ.Bytes(), r.hb, func(keyHex []byte, hasState, hasTree, hasHash uint16, hashes, rootHash []byte) error { + + var wantProof func(_ []byte) *proofElement + if r.proofRetainer != nil { + wantProof = r.proofRetainer.ProofElement + } + if r.groups, r.hasTree, r.hasHash, err = GenStructStepEx(r.RetainNothing, r.curr.Bytes(), r.succ.Bytes(), r.hb, func(keyHex []byte, hasState, hasTree, hasHash uint16, hashes, rootHash []byte) error { if r.hc == nil { return nil } return r.hc(keyHex, hasState, hasTree, hasHash, hashes, rootHash) }, data, r.groups, r.hasTree, r.hasHash, - false, - //r.trace, + //false, + r.trace, + wantProof, + r.cutoff, ); err != nil { return err } @@ -1488,12 +1483,9 @@ func CastTrieNodeValue(hashes, rootHash []byte) []libcommon.Hash { // CalcRoot is a combination of `ResolveStateTrie` and `UpdateStateTrie` // DESCRIBED: docs/programmers_guide/guide.md#organising-ethereum-state-into-a-merkle-tree func CalcRoot(logPrefix string, tx kv.Tx) (libcommon.Hash, error) { - loader := NewFlatDBTrieLoader(logPrefix) - if err := loader.Reset(NewRetainList(0), nil, nil, false); err != nil { - return EmptyRoot, err - } + loader := NewFlatDBTrieLoader(logPrefix, NewRetainList(0), nil, nil, false) - h, err := loader.CalcTrieRoot(tx, nil, nil) + h, err := loader.CalcTrieRoot(tx, nil) if err != nil { return EmptyRoot, err }